(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
Require Export BinNums.
Equalities OrdersFacts GenericMinMax Bool NAxioms NMaxMin NProperties.
Require BinNatDef.
(**********************************************************************)
(** * Binary natural numbers, operations and properties *)
(**********************************************************************)
(** The type [N] and its constructors [N0] and [Npos] are now defined in [BinNums.v] *)
(** Every definitions and properties about binary natural numbers are placed in a module [N] for qualification purpose. *)
Local Open Scope N_scope.
(** Every definitions and early properties about positive numbers are placed in a module [N] for qualification purpose. *)
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 }.

(* Specifications: *)
Theorem peano_rect_succ P a f n :
peano_rect P a f (succ n) = f n (peano_rect P a f n).