I was going through the book Software foundations to learn Coq and I got stuck on Numbers. In this Type definition
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
How does O becomes 0 when we use it in definition of
Definition pred (n : nat) : nat :=
match n with
| O => O
| S n' => n'
end.
I only understood that O represents natural numbers and S takes a natural number and return another natural number. What I do not get is when our defined nat data type is used in pred definition how does O represent 0? And how does S n' patter match gives us predecessor of n.
The Peano numbers
natrepresents the natural numbers via the unary numeral system. The inhabitants (values) of thenattype areO,S O,S (S O),S (S (S O)), ...,S (S (S (S ... O)...).We interpret the symbol
Oas the natural number zero. AndSrepresents a single "tick" in unary representation, i.e. we interpretSas a constructor (it has nothing to do with object-oriented programming) which takes a natural number and yields the next natural number.The predecessor function
predis actually is not a very well-behaved function in a sense.First of all, there is no predecessor of zero when we are talking about the natural numbers. But all functions in Coq must return a value, so if we want to keep the type of
pred(which isnat -> nat) we must do something aboutpred O. It feels natural to just returnOand get it over with. This gives us the first branch of the pattern-mathing expression (O => O).Next, what do we return when we call
predon the number representing 1? Let's recall that we write 1 in Coq asS O. This is easy --pred (S O)should returnO. Now let's try 2:pred (S (S O))should returnS O. You see the pattern here? If we have a bunch ofS's in front of anO, we strip oneSoff -- simple as that. The second branch of the pattern-matching expression (S n' => n') does exactly this: it takes a (non-zero) number of the formS n'and turns it inton'(not changing the original, of course).Let me give an example. Let's calculate the predecessor of the number 3 step-by-step:
Unfold the definition of
pred, substituteS (S (S O))forn:S (S (S O))has formS n'(it starts withS), so we take the 2nd branch, bindingn'toS (S O). How do we check that we didn't make a mistake here? If we substitute the definition ofn'intoS n'we should get back the originaln:S n'=S (S (S O))=n.Now, we just return
n':As expected, we got 2 as the result!
Notations
There is a distinction between 0,
0, andO. The first zero (0) is a meta-level numeral for the natural number zero (it's how we designate zero in our metalanguage, e.g. English in this case).0is a notation forO, in other words0is syntactic sugar forO. As the Coq reference manual says (§1.2.4):It's easy to illustrate:
You can overload numerals, here is an example with integers:
Upshot: the same notation can be tied to different terms. Coq defines some default notations, e.g. for such ubiquitous things as numbers.
If you wanted to define your own type to represent the natural numbers (
my_nat) with possibly different names forOandS(likestopandtick), you'd have to write a plugin to map Coq numerals onto the terms ofmy_nat(see here).