Module N
<: NAxiomsSig
<: UsualOrderedTypeFull
<: UsualDecidableTypeFull
<: TotalOrder.
(** Definitions of operations, now in a separate file *)
Include BinNatDef.N.
(** When including property functors, only inline t eq zero one two *)
Set Inline Level 30.
(** Logical predicates *)
Definition eq := @Logic.eq N.
Definition eq_equiv := @eq_equivalence N.
Definition lt x y := (x ?= y) = Lt.
Definition gt x y := (x ?= y) = Gt.
Definition le x y := (x ?= y) <> Gt.
Definition ge x y := (x ?= y) <> Lt.
Infix "<=" := le : N_scope.
Infix "<" := lt : N_scope.
Infix ">=" := ge : N_scope.
Infix ">" := gt : N_scope.
Notation "x <= y <= z" := (x <= y /\ y <= z) : N_scope.
Notation "x <= y < z" := (x <= y /\ y < z) : N_scope.
Notation "x < y < z" := (x < y /\ y < z) : N_scope.
Notation "x < y <= z" := (x < y /\ y <= z) : N_scope.
Definition divide p q := exists r, q = r*p.
Notation "( p | q )" := (divide p q) (at level 0) : N_scope.
Definition Even n := exists m, n = 2*m.
Definition Odd n := exists m, n = 2*m+1.
(** Proofs of morphisms, obvious since eq is Leibniz *)
Local Obligation Tactic := simpl_relation.
Program Definition succ_wd : Proper (eq==>eq) succ := _.
Program Definition pred_wd : Proper (eq==>eq) pred := _.
Program Definition add_wd : Proper (eq==>eq==>eq) add := _.
Program Definition sub_wd : Proper (eq==>eq==>eq) sub := _.
Program Definition mul_wd : Proper (eq==>eq==>eq) mul := _.
Program Definition lt_wd : Proper (eq==>eq==>iff) lt := _.
Program Definition div_wd : Proper (eq==>eq==>eq) div := _.
Program Definition mod_wd : Proper (eq==>eq==>eq) modulo := _.
Program Definition pow_wd : Proper (eq==>eq==>eq) pow := _.
Program Definition testbit_wd : Proper (eq==>eq==>Logic.eq) testbit := _.
(** Decidability of equality. *)
Definition eq_dec : forall n m : N, { n = m } + { n <> m }.
Definition peano_ind (P : N -> Prop) := peano_rect P.
Definition peano_rec (P : N -> Set) := peano_rect P.
(** Generic induction / recursion *)
Definition recursion {A} : A -> (N -> A -> A) -> N -> A :=
peano_rect (fun _ => A).
Instance recursion_wd {A} (Aeq : relation A) :
Proper (Aeq==>(Logic.eq==>Aeq==>Aeq)==>Logic.eq==>Aeq) recursion.
(** Specification of constants *)
(** Properties of successor and predecessor *)
(** Specification of addition *)
(** Specification of subtraction. *)
(** Specification of multiplication *)
(** Specification of boolean comparisons. *)
(** Basic properties of comparison *)
(** Some more advanced properties of comparison and orders, including [compare_spec] and [lt_irrefl] and [lt_eq_cases]. *)
Include BoolOrderFacts.
(** Specification of minimum and maximum *)
(** Specification of lt and le. *)
(** We can now derive all properties of basic functions and orders, and use these properties for proving the specs of more advanced functions. *)
Include NBasicProp <+ UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties.
(** Properties of [double] and [succ_double] *)
(** 0 is the least natural number *)
(** Specifications of power *)
(** Specification of square *)
(** Specification of Base-2 logarithm *)
(** Specification of parity functions *)
(** Specification of the euclidean division *)
Definition div_mod a b : b<>0 -> a = b * (a/b) + (a mod b).
(** Specification of square root *)
(** Specification of gcd *)
(** The first component of ggcd is gcd *)
(** The other components of ggcd are indeed the correct factors. *)
(** We can use this fact to prove a part of the gcd correctness *)
(** We now prove directly that gcd is the greatest amongst common divisors *)
(** Correctness proofs for shifts *)
Definition div2_spec a : div2 a = shiftr a 1.
(** Semantics of bitwise operations *)
(** Instantiation of generic properties of advanced functions (pow, sqrt, log2, div, gcd, ...) *)
Include NExtraProp.
(** In generic statements, the predicates [lt] and [le] have been favored, whereas [gt] and [ge] don't even exist in the abstract layers. The use of [gt] and [ge] is hence not recommended. We provide here the bare minimal results to related them with [lt] and [le]. *)
(** Auxiliary results about right shift on positive numbers, used in BinInt *)

Lemma pred_div2_up p : Pos.pred_N (Pos.div2_up p) = div2 (Pos.pred_N p).