### Revision : the inductive type of natural numbers ###

In Coq, a new data type can be introduced via the mecanism of *inductive definition* (very similar to the algebraic types in OCaml). For instance, the type `nat` of natural numbers is introduced in the Coq standard library (cf. file [Init/Datatypes.v](https://coq.inria.fr/stdlib/Coq.Init.Datatypes.html)) via the following inductive definition:

```coq

Inductivenat:Set:=

|O:nat

|S:nat->nat.

```

This definition adds to the current environment three new constants:

- the type `nat : Set` (where `Set` is an alias for the lowest of `Type` universes);

- the constructor `O : nat`

- the constructor `S : nat -> nat`

Beware, the constructor for zero is `O` internally (the letter O), even if the system also accepts later numerical notations : `0` for `O`, `1` for `(S O)`, `2` for `(S (S O))`, etc.

### Induction principles ###

The former inductive definition also generates automatically a few induction principles. In practice, the mostly used is :

```coq

nat_ind:

forallP:nat->Prop,

P0->(foralln:nat,Pn->P(Sn))->foralln:nat,P

```

which is used internally by the `induction` tactic.

Other handy tactics on such an inductive type :

-`simpl` : applies computation rules.

-`rewrite` : see [td1bis.md](td1bis.md).

-`injection` : all inductive constructors are injective, from `H : S x = S y` then `injection H` provides `x = y`.

-`discriminate` : all inductive constructors are orthogonal, from `H : S x = O` then `discriminate H` or just `discriminate` proves `False` (hence anything).

-`f_equal` : proves a goal `f x = f y`, as long as sub-goal `x = y` could then be proved. Sort of dual to `injection`, except that it works for any function `f`, not only for inductive constructors.

### Exercise 1 : Addition ###

In Coq, the addition of natural numbers is defined via a `Fixpoint` (similar to the `let rec` of OCaml). See [Init/Nat.v](https://coq.inria.fr/stdlib/Coq.Init.Nat.html) :

```coq

Fixpointadd(nm:nat):nat:=

matchnwith

|O=>m

|Sp=>S(addpm)

end.

```

Note that the recursive call is done here on a first argument `p` which is stricly lower than `n`. Only such a *structural decrease* is allowed, Coq will refuse the definitions where it cannot verify this property, in order to avoid non-terminating computations.

The system uses the notation `n + m` to shorten the term `Nat.add n m`.

Show the following lemmas on addtion (basic equalities, then associativity and commutativity). Which egalities are "definitional" (obtained by mere computation and reflexivity, tactics `simpl` and `reflexivity`) ? For the other equalities, proceed by induction over `n`, thanks to the `induction` tactic.

```coq

Lemmaadd_0_l:foralln,0+n=n.

Lemmaadd_succ_l:forallnm,Sn+m=S(n+m).

Lemmaadd_0_r:foralln,n+0=n.

Lemmaadd_succ_r:forallnm,n+Sm=S(n+m).

Lemmaadd_assoc:forallnmp,(n+m)+p=n+(m+p).

Lemmaadd_comm:forallnm,n+m=m+n.

```

### Exercise 2 : Multiplication ###

In Coq, the multiplication is defined by :

```coq

Fixpointmul(nm:nat):nat:=

matchnwith

|O=>O

|Sp=>m+mulpm

end.

```

The system uses the notation `n * m` to shorten `mul n m`.

Just as for addition, prove the following lemmas:

```coq

Lemmamul_0_l:foralln,0*n=0.

Lemmamul_succ_l:forallnm,Sn*m=m+n*m.

Lemmamul_0_r:foralln,n*0=0.

Lemmamul_succ_r:forallnm,n*Sm=n+n*m.

Lemmamul_distr:forallnmp,(n+m)*p=n*p+m*p.

Lemmamul_assoc:forallnmp,(n*m)*p=n*(m*p).

Lemmamul_comm:forallnm,n*m=m*n.

```

### Exercise 3 : an order relation on numbers ###

Here is one possible way to define the large inequality on `nat` numbers:

```coq

Definitionle(nm:nat):=existsp,n+p=m.

Infix"<=":=le.

```

Show that this predicate `le` is indeed an order relation:

```coq

Lemmale_refl:foralln,n<=n.

Lemmale_trans:forallnmp,n<=m->m<=p->n<=p.

Lemmale_antisym:forallnm,n<=m->m<=n->n=m.

```

Note : this `le` definition is not the one used in the Coq standard library (cf. [Init/Peano.v](https://coq.inria.fr/stdlib/Coq.Init.Peano.html)), which is based on an inductive predicate. But we could prove later than these two definitions are equivalent.

### Epilogue ###

When launching Coq, the definition of `nat` numbers is directly available, as well as the previous operations in *qualified* version, for instance `Nat.add` for `+`. Some older names are also available : `plus`, `mult` but they are considered deprecated. The proofs about `nat` numbers and their operations are not available initially, they should be loaded via `Require Import Arith`. This command provides for instance `Nat.add_assoc` and many other proofs, including many lemmas of this TP. The `Search` command allows to search through all these available lemmas. Moreover, some other powerful tactics may help later, for instance `auto`, `lia` (formerly `omega`) or `ring`.