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 *)
End N.
Bind Scope N_scope with N.t N.
(** Exportation of notations *)
Numeral Notation N N.of_uint N.to_uint : N_scope.
Infix "+" := N.add : N_scope.
Infix "-" := N.sub : N_scope.
Infix "*" := N.mul : N_scope.
Infix "^" := N.pow : N_scope.
Infix "?=" := N.compare (at level 70, no associativity) : N_scope.
Infix "<=" := N.le : N_scope.
Infix "<" := N.lt : N_scope.
Infix ">=" := N.ge : N_scope.
Infix ">" := N.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.
Infix "=?" := N.eqb (at level 70, no associativity) : N_scope.
Infix "<=?" := N.leb (at level 70, no associativity) : N_scope.
Infix "<?" := N.ltb (at level 70, no associativity) : N_scope.
Infix "/" := N.div : N_scope.
Infix "mod" := N.modulo (at level 40, no associativity) : N_scope.
Notation "( p | q )" := (N.divide p q) (at level 0) : N_scope.
(** Compatibility notations *)
Notation N_rect := N_rect (only parsing).
Notation N_rec := N_rec (only parsing).
Notation N_ind := N_ind (only parsing).
Notation N0 := N0 (only parsing).
Notation Npos := N.pos (only parsing).
Notation Ndouble_plus_one := N.succ_double (only parsing).
Notation Nplus := N.add (only parsing).
Notation Nminus := N.sub (only parsing).
Notation Nmult := N.mul (only parsing).
Notation nat_of_N := N.to_nat (only parsing).
Notation N_of_nat := N.of_nat (only parsing).
Notation Nrect := N.peano_rect (only parsing).
Notation Nrect_base := N.peano_rect_base (only parsing).
Notation Nrect_step := N.peano_rect_succ (only parsing).
Notation Nind := N.peano_ind (only parsing).
Notation Nrec := N.peano_rec (only parsing).
Notation Nrec_base := N.peano_rec_base (only parsing).
Notation Nrec_succ := N.peano_rec_succ (only parsing).
Notation Npred_minus := N.pred_sub (only parsing).
Notation Ppred_N_spec := N.pos_pred_spec (only parsing).
Notation Ppred_Nsucc := N.pos_pred_succ (only parsing).
Notation Nplus_0_l := N.add_0_l (only parsing).
Notation Nplus_0_r := N.add_0_r (only parsing).
Notation Nplus_comm := N.add_comm (only parsing).
Notation Nplus_assoc := N.add_assoc (only parsing).
Notation Nplus_succ := N.add_succ_l (only parsing).
Notation Nsucc_0 := N.succ_0_discr (only parsing).
Notation Nminus_N0_Nle := N.sub_0_le (only parsing).
Notation Nminus_0_r := N.sub_0_r (only parsing).
Notation Nminus_succ_r:= N.sub_succ_r (only parsing).
Notation Nmult_0_l := N.mul_0_l (only parsing).
Notation Nmult_1_l := N.mul_1_l (only parsing).
Notation Nmult_1_r := N.mul_1_r (only parsing).
Notation Nmult_comm := N.mul_comm (only parsing).
Notation Nmult_assoc := N.mul_assoc (only parsing).
Notation Nmult_plus_distr_r := N.mul_add_distr_r (only parsing).
Notation Nle_0 := N.le_0_l (only parsing).
Notation Ncompare_Eq_eq := N.compare_eq (only parsing).
Notation Ncompare_eq_correct := N.compare_eq_iff (only parsing).
Notation Nle_lteq := N.lt_eq_cases (only parsing).
Notation Ncompare_0 := N.compare_0_r (only parsing).
Notation Ndouble_div2 := N.div2_double (only parsing).
Notation Ndouble_plus_one_div2 := N.div2_succ_double (only parsing).
Notation Ndouble_plus_one_inj := N.succ_double_inj (only parsing).
Notation Nlt_not_eq := N.lt_neq (only parsing).
Notation Ngt_Nlt := N.gt_lt (only parsing).
(** More complex compatibility facts, expressed as lemmas (to preserve scopes for instance) *)
Proof (proj1 (N.add_cancel_l m p n)).
Proof (eq_trans (N.mul_succ_l n m) (N.add_comm _ _)).

Lemma Nmult_plus_distr_l n m p : p * (n + m) = p * n + p * m.