geq : N ⇒N ⇒bool
so thatgeq n misT rueif and only if nis greater than or equal tom. [Hint: the best way to do this is to define the functionsgeq nby induction, that is to definegeq0 outright (by induction) and to definegeq(n+ 1) using
geq n.]
4.23. Usinggeq or otherwise show how to define the bounded search func- tion
search : (N ⇒bool)⇒N ⇒N
so that search p nis the smallest l less than n so that (p l) is T rue, and which isnif no suchl exists.
4.24. Give a formal definition of the functionsumf given by
sumf f n m≡df m
X
i=n
(f i)
What is its type? What type has the partial application
sumf id
whereid x≡dfxis the identity function?
4.9
Well-founded types — trees
In this section we look at an example of how to incorporate recursive data types like lists and trees into the system. The mechanism is similar to the Miranda algebraic type mechanism. Martin-L¨of has proposed a general scheme to achieve this; we examine it in full generality in the following chapter.
We call the types well-founded as they are types over which we can define objects by recursion and prove properties by induction, as we did for the natural numbers; informally, for this to be possible we need to be sure that when we make a recursive definition (or an inductive proof) we never encounter an infinite sequence of simplifications, as in the simplification from (n+ 1) to n. If we have one of these infinite sequences, then the function will be defined on none of the values in that sequence, as each value depends upon an earlier value; there is nofoundationto the sequence or the recursion, in other words.
We shall again see that the principles of induction and recursion are embodied by exactly the same rule.
Miranda type definitions for booleans and natural numbers might be given by
bool ::= True | False nat ::= Zero | Succ nat
The example of a general algebraic type which we shall take here is a type of numerical trees, defined by
tree ::= Null |
Bnode nat tree tree
As we mentioned above, accompanying a definition like this we have the two principles of proof by structural induction and definition by primitive recursion.
Definition 4.2 Structural inductionstates that in order to proveP(t) for every tree,t, it is sufficient to prove it outright forNull,
P(Null) and to prove
P(Bnode n u v)
assuming P(u)andP(v), that is assuming the validity of the result for the immediatepredecessors uandvof the node(Bnode n u v).
Compare this with the principle of induction over the natural numbers; we prove the result outright at 0, and prove it at (n+ 1) assuming it is valid at the (immediate) predecessorn.
Definition 4.3 Primitive recursionis a principle of definition for func- tions. In order to define a (total) function
f : tree -> P
we need only supply a starting value, a : P
which will be the value off Nulland a means of defining f (Bnode n u v)
in terms of the previous values(f u)and(f v), the subtreesuandvand the entry at the node,n. We will represent this as a function
4.9. WELL-FOUNDED TYPES — TREES 107
F : nat -> tree -> tree -> P -> P -> P so that
f (Bnode n u v) = F n u v (f u) (f v)
In other words we define the value of(f t)in terms of the values offon thepredecessors oft, together with the components of the node itself. This is similar to the principle of primitive recursion over the natural numbers,
N, where we specify outright the value at 0 and specify how the value at (n+ 1) is computed from the value atn, together withnitself.
As we might expect from what we have seen above, in a constructive set- ting the principles of proof and definition areidentical. The proofs required by structural induction will be objects
a : P(Null) andFof type
(n:nat)->(u:tree)->(v:tree)->P(u)-P(v)->P(Bnode n u v)
The preceding type is enclosed in inverted commas as it is not a Miranda type. In type theory this kind of type, in which the type of the result depends upon the value of an argument, is represented using the dependent function space, thus.
F : (∀n:N)(∀u:tree)(∀v:tree)(P(u)⇒P(v)⇒P(Bnode n u v)) Let us now look at the explicit form taken by the rules for trees. For- mation is simple
Formation Rule fortree
tree is a type(tree F)
There are two kinds of tree. A null node and a non-null node with two immediate predecessors, abinary node, hence Bnode.
Introduction Rules fortree
N ull : tree(tree I1)
n:N u:tree v:tree
(Bnode n u v) :tree (tree I2)
Elimination Rule fortree t:tree c:C[N ull/x] f: (∀n:N).(∀u:tree).(∀v:tree). (C[u/x]⇒C[v/x]⇒C[(Bnode n u v)/x]) trec t c f : C[t/x] (tree E) To make the rule above more readable, we have listed the three hypotheses vertically instead of in a horizontal line. We shall do this where presentation is thus improved.
There are two computation rules for the recursion operator trec; the first eliminates aN ull tree and the second a non-nullBnodetree.
Computation Rules fortree trec N ull c f → c
trec(Bnode n u v)c f → f n u v(trec u c f) (trec v c f)
As an example, we can present the function which sums the contents of a tree. It is defined thus
sumtN ull = 0
sumt(Bnode n u v) = n+ (sumtu) + (sumtv)
If we define
f ≡df λn . λt1. λt2. λs1. λs2.(n+s1+s2) then
λttree.(trec t0f)
defines thesumt function formally.
It behoves us to fit this kind of construction into a uniform framework. Martin-L¨of has done this, and indeed given an infinitary generalisation of the construction; we postpone this until we have given an account of the equality type.
Exercises
4.25. Define the function which returns the left subtree of a tree if it has one, and theN ull tree if not.
4.26. Define the equality function over trees.
4.27. We say that a tree (Bnode n u v) is ordered if and only if all objects in u are smaller than or equal to n, all objects in v are greater than or
4.10. EQUALITY 109