1.9 The natural numbers

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

c

0

:

C

and a “next step” function

c

s

:

ℕ

→

C

→

C

.
This gives rise to

f

with the defining equations

f

⁢

(

0

)

:

≡

c

0

,

f

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

n

)

)

:

≡

c

s

(

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

c

0

:

≡

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

c

s

(

n

,

y

)

:

≡

𝗌𝗎𝖼𝖼

(

𝗌𝗎𝖼𝖼

(

y

)

)

.
Note that the second argument

y

of

c

s

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

)

)

)

≡

c

s

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

0

)

,

𝖽𝗈𝗎𝖻𝗅𝖾

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

0

)

)

)

≡

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝖽𝗈𝗎𝖻𝗅𝖾

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

0

)

)

)

)

≡

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

c

s

⁢

(

0

,

𝖽𝗈𝗎𝖻𝗅𝖾

⁢

(

0

)

)

)

)

≡

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝖽𝗈𝗎𝖻𝗅𝖾

⁢

(

0

)

)

)

)

)

≡

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

c

0

)

)

)

)

≡

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

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:

c

0

:

ℕ

→

ℕ

c

0

⁢

(

n

)

:

≡

n

c

s

:

ℕ

→

(

ℕ

→

ℕ

)

→

(

ℕ

→

ℕ

)

c

s

⁢

(

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

,

c

0

,

c

s

,

0

)

:

≡

c

0

,

𝗋𝖾𝖼

ℕ

⁢

(

C

,

c

0

,

c

s

,

𝗌𝗎𝖼𝖼

⁢

(

n

)

)

:

≡

c

s

(

n

,

𝗋𝖾𝖼

ℕ

(

C

,

c

0

,

c

s

,

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/87563

Exercise 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

c

0

:

C

⁢

(

0

)

, and a function

c

s

:

∏

(

n

:

ℕ

)

C

⁢

(

n

)

→

C

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

n

)

)

; then we can construct

f

:

∏

(

n

:

ℕ

)

C

⁢

(

n

)

with the defining equations:

f

⁢

(

0

)

:

≡

c

0

,

f

⁢

(

𝗌𝗎𝖼𝖼

⁢

(

n

)

)

:

≡

c

s

(

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

,

c

0

,

c

s

,

0

)

:

≡

c

0

,

𝗂𝗇𝖽

ℕ

⁢

(

C

,

c

0

,

c

s

,

𝗌𝗎𝖼𝖼

⁢

(

n

)

)

:

≡

c

s

(

n

,

𝗂𝗇𝖽

ℕ

(

C

,

c

0

,

c

s

,

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

)

)

and

(

𝗌𝗎𝖼𝖼

⁢

(

i

)

+

j

)

+

k

≡

𝗌𝗎𝖼𝖼

⁢

(

(

i

+

j

)

+

k

)

.

Thus, the output type of

𝖺𝗌𝗌𝗈𝖼

s

is equivalently

𝗌𝗎𝖼𝖼

⁢

(

i

+

(

j

+

k

)

)

=

𝗌𝗎𝖼𝖼

⁢

(

(

i

+

j

)

+

k

)

.
But its input (the “

inductive hypothesis

”)
yields

i

+

(

j

+

k

)

=

(

i

+

j

)

+

k

, 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

𝖺𝗉

𝗌𝗎𝖼𝖼

:

(

m

=

ℕ

n

)

→

(

𝗌𝗎𝖼𝖼

(

m

)

=

ℕ

𝗌𝗎𝖼𝖼

(

n

)

)

, so we can define

𝖺𝗌𝗌𝗈𝖼

s

(

i

,

h

,

j

,

k

)

:

≡

𝖺𝗉

𝗌𝗎𝖼𝖼

(

h

(

j

,

k

)

)

.

Putting these together with

𝗂𝗇𝖽

ℕ

, we obtain a proof of associativity.

Title

1.9 The natural numbers

\metatable

Generated on Thu Feb 8 19:32:49 2018 by

LaTeXML