Peano Arithmetic
How many natural numbers are there?
In one sense, there are infinitely many of them. In this sense we think in particular objects like \(1,2,3,\ldots\). In another, more abstract, sense, number is a concept rather than a collection of entities. If you insist on concreteness, then it can be said that there is one and only one number. And one single number and a tiny one-argument function are all we need.
The set of natural numbers \(\mathbb{N}\) is defined as follows:1
- \(0 \in \mathbb{N}\).
- \(\forall x. x\in \mathbb{N} \to s(x) \in \mathbb{N}\).
- \(\neg\exists x\in\mathbb{N}. s(x) = 0\).
- \(\forall x,y\in\mathbb{N}. s(x) = s(y) \to x = y\).
- Let \(\phi\) be a unary predicate:
-
This is a version of Peano Axioms that omits the axioms on equality and differs from the original by taking 0, rather than 1, as the base case. ↩
This gives all the non-negative whole numbers there are. Now we define two familiar operations:
- \(\forall x. x+0=x\).
- \(\forall x,y. x+s(y) = s(x + y)\).
- \(\forall x. x\cdot 0=x\).
- \(\forall x,y. x\cdot s(y) = x\cdot y + x\).
Our task is to do some arithmetic on computer. But we do not have numbers
themselves as we are used to. For instance when you want to compute the value of
\(2+5\), you will not be able to type 2+5 into Python console. The numeral 2
will just be a name for the value \(s(s(0))\). In
this respect typing 2+5 will be like typing "two" + "five", which would not
give what you expect (it gives “twofive”, by the way).
In constructing the system of numbers to be represented and processed by the
computer, we agree that None is the object that the numeral 0 names. The
return value of the successor function \(s\) will be represented by wrapping a
pair of parentheses around its argument. To give you the initial feel for the
system our naming scheme will be:
0will nameNone1will name(None,)2will name((None,),)
As Python’s int type, which represents the whole numbers, will already be in
place, we need to be careful not to mix these two types. For this purpose, we
define a new type peano as follows:
A Python object p is of type peano if,
- it is
None, or, - it is a 1-tuple whose sole member is of
peanotype.
Now some exercises.
Write a module1 peano which implements the following functions:
| Name and type | Description |
|---|---|
zero :: -> peano |
Constructor for the zero of the system, i.e., returns None |
succ :: peano -> peano |
Constructor for the rest |
zerop :: peano -> bool |
Check whether the given peano object is zero (in the peano sense).2 |
peanop:: obj -> bool |
Check whether the argument is peano. |
to_int :: peano -> int |
Conversion |
from_int :: int -> peano |
ditto |
peano_add :: peano, peano -> peano |
Addition |
peano_mult :: peano, peano -> peano |
Multiplication |
Here are the rules of the game:
- All your functions must be recursively defined (no
while,proc, whatever). - Defining
to_intandfrom_int, and using+,-,==,<=, and so on, for operations onpeanos is NOT valid.
-
If we are not already in the module business, “write a module” means create a
peano.pyfile and define your functions there. Later on you can import your function names withfrom peano import peano_add, peano_mult, and so on. ↩ -
We follow the
LISPconvention of naming predicates by attaching apat the end of the corresponding property. The programmatic way to inquire about someone’s mood is to applyhappypto him/her. ↩
All the exercises that follow are bound by the same criteria as above: use
recursion and don’t cheat via ints.
Define functions peano_eq and peano_lt for equality and less-than comparison
of peano objects.
Define a function peano_power that raises its first argument to the power of the second, all in peano type.
Define two function pred and sub for predecessor and subtraction,
respectively. As we are modeling the natural numbers, the predecessor of zero is
zero, and subtraction is truncated at zero. For example, sub(from_int(3),
from_int(5)) should return from_int(0), not from_int(-2).
Define a function divmod which takes two peano objects a and b and
returns a pair of peano objects (q, r) such that q is the quotient of a
divided by b and r is the remainder. You can assume that b is not zero.