## Algebra of Programming in Agda

Dependent Types for Relational Program Derivation

Shin-Cheng Mu, Hsiang-Shang Ko, and Patrik Jansson

To appear in Journal of Functional Programming

## Terms

Algebra of Programming A semi-formal approach to deriving functional programs from relational specifications.

Agda A dependently-typed functional programming language being actively developed.

Dependent types A family of type systems capable of expressing various correctness properties.

## In this introductory presentation

introductory serving as an introduction to a subject or topic [...] intended to persuade someone to purchase something for the first time

— Oxford American Dictionaries I will (casually) introduce how squiggolists treat algorithm design, and report an experiment that faithfully encodesAoP-style derivations in Agda.

By “faithfully” I mean correctness of a derivation is guaranteed by Agda’s type system, while certain degree of readability is retained.

## Inductive datatypes

The most natural datatypes in functional programming are inductive datatypes.

data N : Set where zero : N

suc : N → N

data [ ] (A : Set) : Set where [ ] : [ A ]

:: : A → [ A ] → [ A ]

## Pattern matching

Functions on inductive datatypes can be defined by pattern matching.

+ : N → N → N zero + n = n

(suc m) + n = suc (m + n) sum : [ N ] → N

sum [ ] = zero

sum (x :: xs) = x + sum xs

## Fold

The pattern of inductive definitions is captured in a higher-order function foldr .

foldr : (A → B → B) → B → [ A ] → B foldr f e [ ] = e

foldr f e (x :: xs) = f x (foldr f e xs) Then alternatively sum can be defined as foldr + zero.

## The Fold-Fusion Theorem

It is natural to state theorems about functional programs. One of the most useful theorems is the Fold-Fusion Theorem.

Theorem (Fold-Fusion)

Let f : A → B → B, e : B, g : A → C → C , and h : B → C . If h (f x y ) = g x (h y ),

then

h · foldr f e = foldr g (h e).

## Proof of the Fold-Fusion Theorem

The theorem can be inductively proved by simple equational reasoning.

Base case.

h (foldr f e [ ])

= { definition of foldr } h e

= { definition of foldr } foldr g (h e) [ ].

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Inductive case

h (foldr f e (x :: xs))

= { fusion condition } g x (h (foldr f e xs))

= { induction hypothesis } g x (foldr g (h e) xs)

= { definition of foldr } foldr g (h e) (x :: xs).

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Inductive case

h (foldr f e (x :: xs))

= { definition of foldr } h (f x (foldr f e xs))

= { induction hypothesis } g x (foldr g (h e) xs)

= { definition of foldr } foldr g (h e) (x :: xs).

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Inductive case

h (foldr f e (x :: xs))

= { definition of foldr } h (f x (foldr f e xs))

= { fusion condition } g x (h (foldr f e xs))

= { definition of foldr } foldr g (h e) (x :: xs).

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Inductive case

h (foldr f e (x :: xs))

= { definition of foldr } h (f x (foldr f e xs))

= { fusion condition } g x (h (foldr f e xs))

= { induction hypothesis } g x (foldr g (h e) xs)

## Inductive case

h (foldr f e (x :: xs))

= { definition of foldr } h (f x (foldr f e xs))

= { fusion condition } g x (h (foldr f e xs))

= { induction hypothesis } g x (foldr g (h e) xs)

= { definition of foldr } foldr g (h e) (x :: xs).

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Sketch of a derivation of radix sort

Gibbons, J. 1999.A Pointless Derivation of Radix Sort. J. Funct. Program. 9, 3 (May. 1999), 339–346.

The function

mktree : [ Composite → Field ] →

[ Composite ] → Tree [ Composite ] receives a significance order of fields and classifies the input list first by the most significant field, and for each bucket classifies the elements by the second-most significant field, and so on.

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Sketch of a derivation of radix sort

Gibbons, J. 1999.A Pointless Derivation of Radix Sort. J. Funct. Program. 9, 3 (May. 1999), 339–346.

Imagine a datatype Composite consisting of a fixed number of Field s, where the type Field is finite and totally-ordered.

mktree : [ Composite → Field ] →

[ Composite ] → Tree [ Composite ] receives a significance order of fields and classifies the input list first by the most significant field, and for each bucket classifies the elements by the second-most significant field, and so on.

## Sketch of a derivation of radix sort

Gibbons, J. 1999.A Pointless Derivation of Radix Sort. J. Funct. Program. 9, 3 (May. 1999), 339–346.

Imagine a datatype Composite consisting of a fixed number of Field s, where the type Field is finite and totally-ordered.

The function

mktree : [ Composite → Field ] →

[ Composite ] → Tree [ Composite ] receives a significance order of fields and classifies the input list first by the most significant field, and for each bucket classifies the elements by the second-most significant field, and so on.

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Sketch of a derivation of radix sort

It is apparent that

treesort : [ Composite → Field ] → [ Composite ] → [ Composite ] treesort ds = flatten · mktree ds

correctly sorts a list, where flatten : Tree A → [ A ] collects elements stored in the leaves in order.

treesort = (flatten ·) · mktree.

The Fold-Fusion Theorem is now applicable and radix sort is immediately derived. Moreover, the fusion condition is a statement of stability.

## Sketch of a derivation of radix sort

It is apparent that

treesort : [ Composite → Field ] → [ Composite ] → [ Composite ] treesort ds = flatten · mktree ds

correctly sorts a list, where flatten : Tree A → [ A ] collects elements stored in the leaves in order.

By writing mktree as a (higher-order) fold, we get treesort = (flatten ·) · mktree.

The Fold-Fusion Theorem is now applicable and radix sort is immediately derived. Moreover, the fusion condition is a statement of stability.

## Richard Bird

Unlike other formalisms, functional programming offers a unique opportunity to exploit a compositional approach to Algorithm Design, and to demonstrate the

effectiveness of the mathematics of program construction in the presentation of many algorithms[.]

Functional Algorithm Design. Sci. Comput. Program. 26, 1-3 (May. 1996), 15–31.

## Relations

Relations can be regarded as potentially partial and

non-deterministic functions. Then the usual deterministic, total functions become a special case.

A relation R mapping values of A to values of B is denoted by R : B ← A. We write “b R a” if R maps a to b.

For example, ≤ : N ← N maps a natural number to itself or a smaller natural number, and ∈ : A ← ℘ A maps a set of A’s to one of its elements.

## Operators on relations

Relation composition c (R · S ) a ≡ ∃b. c R b ∧ b S a
Converse a R^{◦} b ≡ b R a

Power transpose ΛR a = { b | b R a } Meet b (R ∩ S ) a ≡ b R a ∧ b S a

Join b (R ∪ S ) a ≡ b R a ∨ b S a

Product relator (b, d ) (R × S ) (a, c) ≡ b R a ∧ d S c Left/right division Division introduces a form of universal

quantification into the relational language. We will skip its definition and expand relations defined with division to pointwise formulas in this presentation.

## Relational fold

Relational fold is a generalisation of functional fold, and the former can be defined in terms of the latter.

Given R : B ← A × B and s : ℘ B, define

foldR R s = ∈ · foldr (Λ(R · (id × ∈))) s, where id is the identity function. Its type is B ← [ A ].

## An operational explanation

foldR R s = ∈ · foldr (Λ(R · (id × ∈))) s The set s records possible base cases.

Given a new element a : A and an inductively-computed set

bs : ℘ B, id × ∈ chooses an element b from bs and then R (a, b) is non-deterministically computed. All results that can be generated from such a process are collected by the Λ operator into a set.

Finally ∈ takes one result from the inductively-computed set.

Compare this procedure with the powerset (subset) construction that converts a non-deterministic finite automaton into a deterministic one.

## Example: subsequence

The relation

subseq : [ A ] ← [ A ]

subseq = foldR (outr ∪ cons) nil

maps a list to one of its subsequences, where nil = {[ ]} and outr : B ← A × B

outr (a, b) = b cons : [ A ] ← A × [ A ] cons (x , xs) = x :: xs.

## Example: orderedness

The relation

ordered : [ A ] ← [ A ]

ordered = foldR (cons · lbound ) nil

maps a list to itself if it is increasingly sorted, where lbound maps a pair (x , xs) to itself if x is a lower bound of xs.

If a relation R satisfies R ⊆ id , it is called a coreflexive relation or a coreflexive for short. Coreflexives are used in specifications to filter out those values with some particular property. One can see that both ordered and lbound are coreflexives.

## The activity-selection problem

Suppose we have a set S = {a1, a2, . . . , an} of n proposed activities that
wish to use a resource, such as a lecture hall, which can be used by only
one activity at a time. Each activity a_{i} has a start time s_{i} and a finish
time fi, where 0 ≤ si< fi < ∞. If selected, activity ai takes place during
the half-open time interval [si, fi). Activities ai and aj are compatible if
the intervals [s_{i}, f_{i}) and [s_{j}, f_{j}) do not overlap (i.e., a_{i} and a_{j} are
compatible if si ≥ fj or sj≥ fi). The activity-selection problem is to
select a maximum-size subset of mutually compatible activities.

Cormen, T. H., Leiserson, C. E., Rivest, R. L., and Stein, C. 2001Introduction to Algorithms. MIT Press.

If the activities are decreasingly sorted by finish time, there is a simple algorithm.

## Maximum

Given an order R : A ← A, the relation max R : A ← ℘ A maps a set to one of its maximum elements with respect to R:

max R = ∈ ∩ (R^{◦}/3).

Expanding the point-free definition,

x (max R) s ≡ x ∈ s ∧ ∀y . y ∈ s ⇒ y R x .

## Specification

We can give a relational specification for the activity-selection problem:

max ≤_{`}· Λ(mutex · subseq).

Generate an arbitrary plan by subseq.

Ensure the plan is legitimate by the coreflexive mutex . Collect all such plans by the Λ operator.

Choose one of the longest plans by max ≤_{`}.

Any function contained in this relation is considered a correct implementation.

## The Greedy Theorem

Theorem (Bird and de Moor)

Let R : A ← A be a preorder and S : A ← FA be monotonic on R, i.e.,

S · FR ⊆ R · S . Then

max R · Λ([S ]) ⊇ ([max R · ΛS ]).

Bird, R. and de Moor, O. 1997Algebra of Programming. Prentice-Hall, Inc.

## Specialisation to lists

Corollary

Let R : A ← A be a preorder, S : A ← B × A be monotonic on R, i.e.,

S · (id × R) ⊆ R · S , and s : ℘ A be a set. Then

max R · Λ(foldR S s) ⊇ foldR (max R · ΛS ) (Λ(max R) s).

## Fusing mutex · subseq into a fold

The coreflexive mutex is defined by

mutex = foldR (cons · compatible) nil where the coreflexive compatible lets a pair (x , xs) of type

Activity × [ Activity ] go through if x does not overlap with any of the activities in xs.

By relational fold-fusion, mutex · subseq can be fused into foldR R nil if we can find a relation R such that

mutex · (outr ∪ cons) = R · (id × mutex ).

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Synthesis of R

We calculate:

mutex · (outr ∪ cons)

= { product relator; catamorphisms }

(outr · (id × mutex )) ∪ (cons · compatible · (id × mutex ))

= { composition distributes over join } (outr ∪ (cons · compatible)) · (id × mutex ).

So mutex · subseq = foldR (outr ∪ (cons · compatible)) nil .

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Synthesis of R

We calculate:

mutex · (outr ∪ cons)

= { composition distributes over join } (mutex · outr ) ∪ (mutex · cons)

= { composition distributes over join } (outr ∪ (cons · compatible)) · (id × mutex ).

So mutex · subseq = foldR (outr ∪ (cons · compatible)) nil .

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Synthesis of R

We calculate:

mutex · (outr ∪ cons)

= { composition distributes over join } (mutex · outr ) ∪ (mutex · cons)

= { product relator; catamorphisms }

(outr · (id × mutex )) ∪ (cons · compatible · (id × mutex ))

So mutex · subseq = foldR (outr ∪ (cons · compatible)) nil .

## Synthesis of R

We calculate:

mutex · (outr ∪ cons)

= { composition distributes over join } (mutex · outr ) ∪ (mutex · cons)

= { product relator; catamorphisms }

(outr · (id × mutex )) ∪ (cons · compatible · (id × mutex ))

= { composition distributes over join } (outr ∪ (cons · compatible)) · (id × mutex ).

So mutex · subseq = foldR (outr ∪ (cons · compatible)) nil .

## Checking the monotonicity condition

Now we wish to apply the Greedy Theorem. That means we need to check the monotonicity condition

(outr ∪ (cons · compatible)) · (id × ≤_{`})

⊆ ≤_{`}· (outr ∪ (cons · compatible)),
which says for two partial plans xs and ys with

length xs ≤ length ys, no matter which complete plan xs^{0} is
computed from xs, there is always a complete plan ys^{0} computed
from ys such that length xs^{0} ≤ length ys^{0}.

This is not true, however.

## Strengthening the order

A typical strategy is to refine the order ≤_{`} to a stronger one. Since
the problematic case happens when the two partial plans under
consideration are of the same length, we define

E = <`∪ (=_{`}∩ (post-compatible\post-compatible))
where post-compatible : Activity ← [ Activity ] maps a plan to a
compatible activity that finishes later than all activities in the plan.

Now the monotonicity condition with respect to E holds and the Greedy Theorem gives us

foldR (max E · Λ(outr ∪ (cons · compatible))) nil.

## Cleaning up

Take a closer look at

max E · Λ(outr ∪ (cons · compatible)).

Given a partial plan xs and an incoming activity x , the relation picks a best plan with respect to E from, depending on whether x is compatible with xs, the set {xs, x :: xs} or the set {xs}.

In the first case x :: xs should be chosen since it is strictly longer than xs. In the second case there is only one candidate.

Since x finishes later than xs, it suffices to check whether x starts later than xs.

## The final program

Define

compatible-cons : Activity → [ Activity ] → [ Activity ] compatible-cons x [ ] = x :: [ ]

compatible-cons x (y :: xs) =

if start x ≥ finish y then x :: y :: xs else y :: xs.

The final program is a simple fold:

foldr compatible-cons [ ].

## The derivation

max ≤_{`}· Λ(mutex · subseq)

= { fusion }

max ≤_{`}· Λ(foldR (outr ∪ (cons · compatible)) nil )

⊇ { strengthening }

max E · Λ(foldR (outr ∪ (cons · compatible)) nil)

⊇ { Greedy Theorem }

foldR (max E · Λ(outr ∪ (cons · compatible))) nil

= { cleaning up }

foldr compatible-cons [ ].

## Donald E. Knuth

Science is knowledge which we understand so well that we can teach it to a computer; and if we don’t fully understand something, it is an art to deal with it. [...] we should continually be striving to transform every art into a science: in the process, we advance the art.

Computer Programming as an Art. Commun. ACM 17, 12 (Dec. 1974), 667–673.

## Curry-Howard correspondence

Observe the following two logic inference rules:

ϕ ∧ ψ

(∧E) ψ

ϕ → ψ ϕ

(→E) ψ

The left one resembles the type of outr : A × B → B, and the right one looks like the types involved in function application.

Curry-Howard correspondence is a family of formal correspondences between logic deduction systems and computational calculi. Its famous slogan is “propositions are types, and proofs are programs”.

Thus writing proofs is no different from writing programs! All we need is an expressive enough programming language.

## Roadmap

We will go through the following:

1 first-order intuitionistic logic,

2 preorder reasoning combinators,

3 modelling of sets and relations,

4 the specification (in detail),

5 the Partial Greedy Theorem, and

6 finally, the derivation.

More complicated proofs cannot be explained in this presentation since more background is required. However it is worth noting that important theorems such as Fold-Fusion Theorem and Greedy Theorem can be proved in an “equational” style close to the proofs in theAoPbook.

## Encoding first-order intuitionistic logic in Agda

absurdity data ⊥ : Set where

truth data > : Set where tt : >

conjunction data × (A B : Set) : Set where , : A → B → A × B

disjunction data ] (A B : Set) : Set where inj1 : A → A ] B

inj_{2} : B → A ] B

implication A → B

## Encoding first-order intuitionistic logic in Agda

exists data ∃ {A : Set} (P : A → Set) : Set where , : (witness : A) → P witness → ∃ P forall (x : A) → P x or ∀ x → P x equality data ≡ {A : Set} : A → A → Set where

refl : {x : A} → x ≡ x For example, the type

(n : N) → (n ≡ zero ] ∃ (λ m → n ≡ suc m)) says every natural number is either zero or a successor of some natural number.

## More on products

In fact, × and ∃ are special cases of the following Σ-type:

data Σ (A : Set) (B : A → Set) : Set where , : (a : A) → B a → Σ A B

which can be seen as a kind of generalised products whose second component’s type depends on the first component. We can define extractor functions

proj1: {A : Set} {B : A → Set} → Σ A B → A proj1 (a , b) = a

proj2: {A : Set} {B : A → Set} → (σ : Σ A B) → B (proj1 σ)
proj_{2} (a , b) = b.

## More on equality

≡ is reflexive by definition, and can be proven to be transitive and symmetric. It is also a congruence with respect to function application.

trans : {A : Set} {x y z : A} → x ≡ y → y ≡ z → x ≡ z trans refl refl = refl

sym : {A : Set} {x y : A} → x ≡ y → y ≡ x sym refl = refl

cong : {A B : Set} (f : A → B) {x y : A} → x ≡ y → f x ≡ f y cong f refl = refl

## Equational reasoning

We can write a chain of equality in Agda as expression1

≡h exp_{1}≡exp_{2} i
expression_{2}

≡h exp_{2}≡exp_{3} i
. . .

≡h exp_{n−1}≡exp_{n} i
expression_{n}

## Equational reasoning

We can write a chain of equality in Agda as expression1

≡h exp_{1}≡exp_{2} i
expression_{2}

≡h exp_{2}≡exp_{3} i
. . .

≡h exp_{n−1}≡exp_{n} i
expression_{n}

## Equational reasoning

We can write a chain of equality in Agda as expression1

≡h exp_{1}≡exp_{2} i
expression_{2}

≡h exp_{2}≡exp_{3} i
. . .

≡h exp_{n−1}≡exp_{n} i
expression_{n}

## Equational reasoning

We can write a chain of equality in Agda as expression1

≡hexp_{1}≡exp_{2} i
expression_{2}

≡h exp_{2}≡exp_{3} i
. . .

≡h exp_{n−1}≡exp_{n} i
expression_{n}

## Equational reasoning

We can write a chain of equality in Agda as expression1

≡h exp_{1}≡exp_{2} i
expression_{2}

≡h exp_{2}≡exp_{3} i
. . .

≡h exp_{n−1}≡exp_{n} i
expression_{n}

## Preorder reasoning combinators

Concretely,

≡h i : {A : Set} (x : A) {y z : A} → x ≡ y → y ≡ z → x ≡ z x ≡h x ≡y i y ≡z = trans x ≡y y ≡z

: {A : Set} (x : A) → x ≡ x x = refl.

The same technique works for any preorder.

## Proving the Fold-Fusion Theorem

foldr -fusion : {A B C : Set}

(h : B → C ) {f : A → B → B} {g : A → C → C } {e : B} → (∀ x y → h (f x y ) ≡ g x (h y )) →

∀ xs → h (foldr f e xs) ≡ foldr g (h e) xs foldr -fusion h {f } {g } {e} fusion-condition [ ] = refl foldr -fusion h {f } {g } {e} fusion-condition (x :: xs) =

h (foldr f e (x :: xs))

≡h refl i

h (f x (foldr f e xs))

≡h fusion-condition x (foldr f e xs) i g x (h (foldr f e xs))

≡h cong (g x) (foldr -fusion h fusion-condition xs) i g x (foldr g (h e) xs)

≡h refl i

foldr g (h e) (x :: xs)

## Modelling sets

A set of A’s can be specified by its characteristic function of type A → Set. Concretely, if s : A → Set, then x : A is considered a member of s if s x has a proof, i.e., there is a term that has type s x . Thus we define

℘ A = A → Set.

For example, define

singleton : {A : Set} → A → ℘ A singleton x = λ y → x ≡ y .

Then singleton x is the set containing a single element x .

## Modelling relations

Set-theoretically, a relation of type B ← A is a subset of A × B, so we may define B ← A as ℘ (A × B) = A × B → Set. But we found the following isomorphic representation more convenient:

B ← A = B → A → Set.

For example, an Agda function is lifted to a relation by the combinator

fun : {A B : Set} → (A → B) → (B ← A) fun f = λ y x → f x ≡ y .

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Operators on relations revisited

( R · S ) c a = ∃ (λ b → c R b × b S a)
converse ^{◦} : {A B : Set} → (B ← A) → (A ← B)

(R ^{◦}) a b = R b a

power transpose Λ : {A B : Set} → (B ← A) → (A → ℘ B) Λ R a = λ b → b R a

join t : {A B : Set} →

(B ← A) → (B ← A) → (B ← A) (R t S ) b a = R b a ] S b a

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Operators on relations revisited

composition · : {A B C : Set} →

(C ← B) → (B ← A) → (C ← A) ( R · S ) c a = ∃ (λ b → c R b × b S a)

power transpose Λ : {A B : Set} → (B ← A) → (A → ℘ B) Λ R a = λ b → b R a

join t : {A B : Set} →

(B ← A) → (B ← A) → (B ← A) (R t S ) b a = R b a ] S b a

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Operators on relations revisited

composition · : {A B C : Set} →

(C ← B) → (B ← A) → (C ← A)
( R · S ) c a = ∃ (λ b → c R b × b S a)
converse ^{◦} : {A B : Set} → (B ← A) → (A ← B)

(R ^{◦}) a b = R b a

join t : {A B : Set} →

(B ← A) → (B ← A) → (B ← A) (R t S ) b a = R b a ] S b a

Warming up Switching to relations Solving an optimisation problem Formalisation in Agda Conclusions

## Operators on relations revisited

composition · : {A B C : Set} →

(C ← B) → (B ← A) → (C ← A)
( R · S ) c a = ∃ (λ b → c R b × b S a)
converse ^{◦} : {A B : Set} → (B ← A) → (A ← B)

(R ^{◦}) a b = R b a

power transpose Λ : {A B : Set} → (B ← A) → (A → ℘ B) Λ R a = λ b → b R a

(R t S ) b a = R b a ] S b a

## Operators on relations revisited

composition · : {A B C : Set} →

(C ← B) → (B ← A) → (C ← A)
( R · S ) c a = ∃ (λ b → c R b × b S a)
converse ^{◦} : {A B : Set} → (B ← A) → (A ← B)

(R ^{◦}) a b = R b a

power transpose Λ : {A B : Set} → (B ← A) → (A → ℘ B) Λ R a = λ b → b R a

join t : {A B : Set} →

(B ← A) → (B ← A) → (B ← A) (R t S ) b a = R b a ] S b a

## Inclusion

We can define set inclusion

⊆ : {A : Set} → ℘ A → ℘ A → Set
s_{1}⊆ s_{2} = ∀ x → (s_{1} x → s_{2} x )
and relational inclusion

v : {A B : Set} → (B ← A) → (B ← A) → Set R v S = ∀ b a → (R b a → S b a).

Both can be shown to be reflexive and transitive, so we can build preorder reasoning combinators for them.

## Encoding the specification

Our goal is to build up the relation

act-sel -spec : [ Activity ] ← [ Activity ]
act-sel -spec = max ≤_{`} • Λ(mutex · subseq).

If we can construct a term of type

∃ (λ f → f · fin-ordered v act-sel -spec · fin-ordered ) where fin-ordered is a coreflexive explicitly stating that the input list is required to be sorted by finish time, the witness to this existential proposition is an algorithm solving the activity-selection problem, correctness guaranteed by the type checker.

## The “maximum” part

Maximum is easily defined:

max : {A : Set} → (A ← A) → (A ← ℘ A)

(max R ) a s = s a × (∀ a^{0} → s a^{0} → a^{0} R a).

In our library it is defined in point-free style.

Assuming ≤ : N ← N is given,

≤_{`} : {A : Set} → ([ A ] ← [ A ])
xs ≤`ys = length xs ≤ length ys.

## Fold, the third time

Define

foldR : {A B : Set} → (B ← A × B) → ℘ B → (B ← [ A ])
foldR R s = ∈ • foldr (Λ(R · (id_{R} × ∈))) s

where • is a special type of composition defined by

• : {A B C : Set} → (C ← ℘ B) → (A → ℘ B) → (C ← A) (R • f ) c a = R c (f a).

The reason we need such composition is due to predicativity, an issue we will ignore in this presentation.

## Subsequence, identically

Define

subseq : {A : Set} → ([ A ] ← [ A ]) subseq = foldR (outr t cons) nil where

cons : {A : Set} → (A ← (A × [ A ])) cons = fun (uncurry :: )

outr : {A B : Set} → (B ← (A × B))
outr = fun proj_{2}

nil : {A : Set} → ℘ A nil = singleton [ ].

## Junctional check

Recall that

mutex = foldR (cons · compatible) nil

where compatible is a coreflexive which, given a pair (x , xs) of type Activity × [ Activity ], checks whether x is disjoint from every activity in xs. The relation fin-ordered has the same structure.

Define

check C = foldR (cons · C ) nil

to capture this pattern. Then mutex = check compatible.

The only component we haven’t constructed is compatible.

## Compatibility between an activity and a plan

Define

compatible-set : ℘ (Activity × [ Activity ]) compatible-set (a , [ ]) = >

compatible-set (a , x :: xs) = disjoint a x × compatible-set (a , xs) where

disjoint : Activity ← Activity

disjoint a x = finish x ≤ start a ] finish a ≤ start x . Then

compatible : (Activity × [ Activity ]) ← (Activity × [ Activity ]) compatible (y , ys) (x , xs) =

(y , ys) ≡ (x , xs) × compatible-set (x , xs).

## The Partial Greedy Theorem

Since the domain of act-sel -spec = max ≤_{`} • Λ(mutex · subseq)
is restricted by the coreflexive fin-ordered , we need a variant of the
Greedy Theorem to deal with partiality of input.

partial -greedy -thm : {A B : Set}

{S : B ← (A × B)} {s : ℘ B} {R : B ← B}

{C : (A × [ A ]) ← (A × [ A ])} {D : (A × B) ← (A × B)} →
R · R v R → C v idR → D v id_{R} →

S · (id_{R}× R) · D v R · S →

(id_{R} × foldR S s) · C v D · (id_{R}× foldR S s) →
foldR (max R • ΛS ) (Λ(max R) s) · check C

v (max R • Λ(foldR S s)) · check C

## The Partial Greedy Theorem

Since the domain of act-sel -spec = max ≤_{`} • Λ(mutex · subseq)
is restricted by the coreflexive fin-ordered , we need a variant of the
Greedy Theorem to deal with partiality of input.

partial -greedy -thm :{A B : Set}

{S : B ← (A × B)} {s : ℘ B} {R : B ← B}

{C : (A × [ A ]) ← (A × [ A ])} {D : (A × B) ← (A × B)} → R · R v R →C v idR →D v idR →

S · (id_{R}× R) · D v R · S →

(id_{R} × foldR S s) · C v D · (id_{R}× foldR S s)→
foldR (max R • ΛS ) (Λ(max R) s) · check C

v (max R • Λ(foldR S s)) · check C

## The Partial Greedy Theorem

Since the domain of act-sel -spec = max ≤_{`} • Λ(mutex · subseq)
is restricted by the coreflexive fin-ordered , we need a variant of the
Greedy Theorem to deal with partiality of input.

partial -greedy -thm :{A B : Set}

{S : B ← (A × B)} {s : ℘ B} {R : B ← B}

{C : (A × [ A ]) ← (A × [ A ])} {D : (A × B) ← (A × B)} → R · R v R →C v idR →D v idR →

S · (id_{R}× R) · D v R · S →

(id_{R} × foldR S s) · C v D · (id_{R}× foldR S s)→
foldR (max R • ΛS ) (Λ(max R) s)· check C

v (max R • Λ(foldR S s))· check C

## The Partial Greedy Theorem

_{`} • Λ(mutex · subseq)
is restricted by the coreflexive fin-ordered , we need a variant of the
Greedy Theorem to deal with partiality of input.

partial -greedy -thm :{A B : Set}

{S : B ← (A × B)} {s : ℘ B} {R : B ← B}

{C : (A × [ A ]) ← (A × [ A ])} {D : (A × B) ← (A × B)} → R · R v R →C v idR →D v idR →

S · (id_{R}× R)· Dv R · S →

(id_{R} × foldR S s) · C v D · (id_{R}× foldR S s)→
foldR (max R • ΛS ) (Λ(max R) s) · check C

v (max R • Λ(foldR S s)) · check C

## The Partial Greedy Theorem

_{`} • Λ(mutex · subseq)
is restricted by the coreflexive fin-ordered , we need a variant of the
Greedy Theorem to deal with partiality of input.

partial -greedy -thm :{A B : Set}

{S : B ← (A × B)} {s : ℘ B} {R : B ← B}

{C : (A × [ A ]) ← (A × [ A ])} {D : (A × B) ← (A × B)} → R · R v R →C v idR →D v idR →

S · (id_{R}× R) · D v R · S →

(id_{R} × foldR S s) · C v D · (id_{R}× foldR S s)→
foldR (max R • ΛS ) (Λ(max R) s) · check C

v (max R • Λ(foldR S s)) · check C

## The main derivation

(Let S = outr t (cons · compatible).) activity -selection-derivation :

∃ (λ f → fun f · fin-ordered v act-sel -spec · fin-ordered ) activity -selection-derivation = ,

(max ≤_{`} • Λ(mutex · subseq)) · fin-ordered

wh comp-monotonic-l (minΛ-cong -w mutex·subseq-is-fold ) i
(max ≤_{`} • Λ(foldR S nil )) · fin-ordered

wh comp-monotonic-l (max-monotonic E-refines-≤`) i (max E • Λ(foldR S nil)) · fin-ordered

. . .

## Applying the Partial Greedy Theorem

(Assume fin-ordered = check fin-ubound .) . . .

(max E • Λ(foldR S nil)) · fin-ordered wh fin-ubound -promotion i

(max E • Λ(foldR (S · fin-ubound) nil)) · fin-ordered

wh partial -greedy -thm E-trans fin-uboundvidR fin-ubound vid_{R}
monotonicity fin-ubound -homo i

foldR (max E • Λ(S · fin-ubound)) (Λ(max E ) nil) · fin-ordered wh comp-monotonic-l (foldR-monotonic v-refl max-E-nil⊇nil) i

foldR (max E • Λ(S · fin-ubound)) nil · fin-ordered . . .

## Cleaning up

. . .

foldR (max E • Λ(S · fin-ubound)) nil · fin-ordered wh comp-monotonic-l algebra-refinement i

foldR (fun (uncurry compatible-cons) · fin-ubound ) nil · fin-ordered wh fin-ubound -demotion i

foldR (fun (uncurry compatible-cons)) nil · fin-ordered wh comp-monotonic-l (foldR-to-foldr compatible-cons []) i

fun (foldr compatible-cons [ ]) · fin-ordered

## Advantages of program derivation

Insights are reified as theorems, which can be discovered, proved, collected, and systematically studied.

These theorems then provide hints and directions to solve other problems.

A derivation is fun to read, shows the connection between the specification and the derived algorithm, and can likely point out why the algorithm works.

Beautiful theories about structures and semantics of programs are built up along with development of program derivation.

## Disadvantages of program derivation

The theory is not yet rich enough to cover all classical textbook algorithms.

The work of laying problems in suitable forms and discovering theorems is extremely hard, and perhaps too abstract for a young field like Algorithm Design.

That perhaps explains partially why the community is shrinking.

Relations are inherently harder to manipulate, since there are a great number of operators and associated laws, and inequational reasoning is less deterministic. Even when we step back to functional derivation, low-level calculations can still be very tedious.

## Jeremy Gibbons

We are interested in extending what can be calculated precisely because we are not that interested in the calculations themselves.

Calculating Functional Programs. In Keiichi Nakata, editor, Proceedings of

ISRG/SERG Research Colloquium. School of Computing and Mathematical Sciences, Oxford Brookes University, November 1997. Technical Report CMS-TR-98-01.

## Advantages of mechanised formalisation

Proving theorems by hand is prone to errors. Automatic theorem proving does not make human readers gain intuition and thus confidence. Machine-assisted theorem proving strikes a balance between the two.

That is, we still write proofs ourselves and become confident about the theorem, while the machine assists us to ensure not a single detail is overlooked, making the proof practically infallible.

## Disadvantages of mechanised formalisation

Formalisation is difficult.

“Not a single detail is overlooked” means every detail needs to be taken care about, including, say, associativity of natural number addition.

Formal proofs are unlikely to be written in the traditional essay-like style and often harder to read.

## Leslie Lamport

The proof style I advocate is a refinement of one, called natural deduction, [..., which] has been viewed primarily as a method of writing proofs in formal logic. What I will describe is a practical method for writing the less formal proofs of ordinary mathematics. It is based on

hierarchical structuring — a successful tool for managing complexity.

How to Write a Proof. American Mathematical Monthly 102, 7 (August–September 1993) 600–608. Also appeared in Global Analysis in Modern Mathematics, Karen Uhlenbeck, editor. Publish or Perish Press, Houston. Also appeared as SRC Research Report 94.

## Robert Pollack

Many people who pursue formal mathematics are seeking the beauty of complete concreteness, which contributes to their own appreciation of the material being

formalised, while to many outside the field formalisation is “just filling in the details” of conventional

mathematics. But “just” might be infeasible unless serious thought is given to representation of both the logic of formalisation and the mathematics being formalised.

How to Believe a Machine-Checked Proof. In G. Sambin and J. Smith, editors, Twenty-Five Years of Constructive Type Theory. Oxford University Press, 1998.

## Immanuel Kant

Now it does indeed seem natural that, as soon as we have left the ground of experience, we should, through careful enquiries, assure ourselves as to the foundations of any building that we propose to erect, not making use of any knowledge that we possess without first

determining whence it has come, and not trusting to principles without knowing their origin.

Critique of Pure Reason, 1929, Trans. N. Kemp Smith, New York: St. Martin’s Press.