1.9 The natural numbers
The rules we have introduced so far do not allow us to construct any infinite types.
The simplest infinite type we can think of (and one which is of course also extremely useful) is the type β:π° of natural numbers
.
The elements of β are constructed using 0:β and the successor operation πππΌπΌ:βββ.
When denoting natural numbers, we adopt the usual decimal notation 1:β‘πππΌπΌ(0), 2:β‘πππΌπΌ(1), 3:β‘πππΌπΌ(2), β¦.
The essential property of the natural numbers is that we can define functions by recursion and perform proofs by induction β where now the words βrecursionβ and βinductionβ have a more familiar meaning.
To construct a non-dependent function f:ββC out of the natural numbers by recursion, it is enough to provide a starting point c0:C and a βnext stepβ function cs:ββCβC.
This gives rise to f with the defining equations
f(0) | :β‘c0, | ||
f(πππΌπΌ(n)) | :β‘cs(n,f(n)). |
We say that f is defined by primitive recursion.
As an example, we look at how to define a function on natural numbers which doubles its argument. In this case we have C:β‘β. We first need to supply the value of π½πππ»π πΎ(0), which is easy: we put c0:β‘0. Next, to compute the value of π½πππ»π πΎ(πππΌπΌ(n)) for a natural number n, we first compute the value of π½πππ»π πΎ(n) and then perform the successor operation twice. This is captured by the recurrence cs(n,y):β‘πππΌπΌ(πππΌπΌ(y)). Note that the second argument y of cs stands for the result of the recursive call π½πππ»π πΎ(n).
Defining π½πππ»π πΎ:βββ by primitive recursion in this way, therefore, we obtain the defining equations:
π½πππ»π πΎ(0) | :β‘0 | ||
π½πππ»π πΎ(πππΌπΌ(n)) | :β‘πππΌπΌ(πππΌπΌ(π½πππ»π πΎ(n))). |
This indeed has the correct computational behavior: for example, we have
π½πππ»π πΎ(2) | β‘π½πππ»π πΎ(πππΌπΌ(πππΌπΌ(0))) | ||
β‘cs(πππΌπΌ(0),π½πππ»π πΎ(πππΌπΌ(0))) | |||
β‘πππΌπΌ(πππΌπΌ(π½πππ»π πΎ(πππΌπΌ(0)))) | |||
β‘πππΌπΌ(πππΌπΌ(cs(0,π½πππ»π πΎ(0)))) | |||
β‘πππΌπΌ(πππΌπΌ(πππΌπΌ(πππΌπΌ(π½πππ»π πΎ(0))))) | |||
β‘πππΌπΌ(πππΌπΌ(πππΌπΌ(πππΌπΌ(c0)))) | |||
β‘πππΌπΌ(πππΌπΌ(πππΌπΌ(πππΌπΌ(0)))) | |||
β‘4. |
We can define multi-variable functions by primitive recursion as well, by currying and allowing C to be a function type.
For example, we define addition πΊπ½π½:βββββ with C:β‘βββ and the following βstarting pointβ and βnext stepβ data:
c0 | :βββ | ||
c0(n) | :β‘n | ||
cs | :ββ(βββ)β(βββ) | ||
cs(m,g)(n) | :β‘πππΌπΌ(g(n)). |
We thus obtain πΊπ½π½:βββββ satisfying the definitional equalities
πΊπ½π½(0,n) | β‘n | ||
πΊπ½π½(πππΌπΌ(m),n) | β‘πππΌπΌ(πΊπ½π½(m,n)). |
As usual, we write πΊπ½π½(m,n) as m+n. The reader is invited to verify that 2+2β‘4.
As in previous cases, we can package the principle of primitive recursion into a recursor:
ππΎπΌβ:β(C:π°)Cβ(ββCβC)βββC |
with the defining equations
ππΎπΌβ(C,c0,cs,0) | :β‘c0, | ||
ππΎπΌβ(C,c0,cs,πππΌπΌ(n)) | :β‘cs(n,ππΎπΌβ(C,c0,cs,n)). |
Using ππΎπΌβ we can present π½πππ»π πΎ and πΊπ½π½ as follows:
π½πππ»π πΎ | :β‘ππΎπΌβ(β,β0,Ξ»n.Ξ»y.πππΌπΌ(πππΌπΌ(y))) | (1) | ||
πΊπ½π½ | :β‘ππΎπΌβ(βββ,Ξ»n.n,Ξ»n.Ξ»g.Ξ»m.πππΌπΌ(g(m))). | (2) |
Of course, all functions definable only using the primitive recursion principle will be computable.
(The presence of higher function types β that is, functions with other functions as arguments β does, however, mean we can define more than the usual primitive recursive functions; see e.g. http://planetmath.org/node/87563Exercise 1.10.)
This is appropriate in constructive mathematics;
in Β§3.4 (http://planetmath.org/34classicalvsintuitionisticlogic),Β§3.8 (http://planetmath.org/38theaxiomofchoice) we will see how to augment type theory
so that we can define more general mathematical functions.
We now follow the same approach as for other types, generalizing primitive recursion to dependent functions to obtain an induction principle. Thus, assume as given a family C:ββπ°, an element c0:C(0), and a function cs:β(n:β)C(n)βC(πππΌπΌ(n)); then we can construct f:β(n:β)C(n) with the defining equations:
f(0) | :β‘c0, | ||
f(πππΌπΌ(n)) | :β‘cs(n,f(n)). |
We can also package this into a single function
πππ½β:β(C:ββπ°)C(0)β(β(n:β)C(n)βC(πππΌπΌ(n)))ββ(n:β)C(n) |
with the defining equations
πππ½β(C,c0,cs,0) | :β‘c0, | ||
πππ½β(C,c0,cs,πππΌπΌ(n)) | :β‘cs(n,πππ½β(C,c0,cs,n)). |
Here we finally see the connection to the classical notion of proof by induction.
Recall that in type theory we represent propositions by types, and proving a proposition by inhabiting the corresponding type.
In particular, a property of natural numbers is represented by a family of types P:ββπ°.
From this point of view, the above induction principle says that if we can prove P(0), and if for any n we can prove P(πππΌπΌ(n)) assuming P(n), then we have P(n) for all n.
This is, of course, exactly the usual principle of proof by induction on natural numbers.
As an example, consider how we might represent an explicit proof that + is associative. (We will not actually write out proofs in this style, but it serves as a useful example for understanding how induction is represented formally in type theory.) To derive
πΊππππΌ:βi,j,k:βi+(j+k)=(i+j)+k, |
it is sufficient to supply
πΊππππΌ0:βj,k:ββ0+(j+k)=(0+j)+k |
and
πΊππππΌs:βi:β(βj,k:βi+(j+k)=(i+j)+k)ββj,k:βπππΌπΌ(i)+(j+k)=(πππΌπΌ(i)+j)+k. |
To derive πΊππππΌ0, recall that 0+nβ‘n, and hence 0+(j+k)β‘j+kβ‘(0+j)+k. Hence we can just set
πΊππππΌ0(j,k):β‘ππΎπΏπ j+k. |
For πΊππππΌs, recall that the definition of + gives πππΌπΌ(m)+nβ‘πππΌπΌ(m+n), and hence
πππΌπΌ(i)+(j+k) | β‘πππΌπΌ(i+(j+k))ββ | ||
Thus, the output type of is equivalently .
But its input (the βinductive hypothesisβ)
yields , so it suffices to invoke the fact that if two natural numbers are equal, then so are their successors.
(We will prove this obvious fact in Lemma 1 (http://planetmath.org/22functionsarefunctors#Thmlem1), using the induction principle of identity types.)
We call this latter fact
, so we can define
Putting these together with , we obtain a proof of associativity.
Title | 1.9 The natural numbers |
---|---|
\metatable |