aboutsummaryrefslogtreecommitdiffhomepage
path: root/theories/Numbers
diff options
context:
space:
mode:
authorGravatar emakarov <emakarov@85f007b7-540e-0410-9357-904b9bb8a0f7>2007-09-21 13:22:41 +0000
committerGravatar emakarov <emakarov@85f007b7-540e-0410-9357-904b9bb8a0f7>2007-09-21 13:22:41 +0000
commit090c9939616ac7be55b66290bae3c3429d659bdc (patch)
tree704a5e0e8e18f26e9b30d8d096afe1de7187b401 /theories/Numbers
parent4dc76691537c57cb8344e82d6bb493360ae12aaa (diff)
Update on theories/Numbers. Natural numbers are mostly complete,
need to make NZOrdAxiomsSig a subtype of NAxiomsSig. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@10132 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'theories/Numbers')
-rw-r--r--theories/Numbers/Integer/Abstract/ZAxioms.v160
-rw-r--r--theories/Numbers/Integer/Abstract/ZBase.v (renamed from theories/Numbers/Integer/Axioms/ZBase.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZDec.v (renamed from theories/Numbers/Integer/Axioms/ZDec.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZDomain.v (renamed from theories/Numbers/Integer/Axioms/ZDomain.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZOrder.v (renamed from theories/Numbers/Integer/Axioms/ZOrder.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZPlus.v (renamed from theories/Numbers/Integer/Axioms/ZPlus.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZPlusOrder.v (renamed from theories/Numbers/Integer/Axioms/ZPlusOrder.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZPred.v (renamed from theories/Numbers/Integer/Axioms/ZPred.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZTimes.v (renamed from theories/Numbers/Integer/Axioms/ZTimes.v)0
-rw-r--r--theories/Numbers/Integer/Abstract/ZTimesOrder.v (renamed from theories/Numbers/Integer/Axioms/ZTimesOrder.v)0
-rw-r--r--theories/Numbers/Integer/BigInts/EZBase.v167
-rw-r--r--theories/Numbers/Integer/BigInts/Zeqmod.v48
-rw-r--r--theories/Numbers/Integer/Binary/ZBinary.v204
-rw-r--r--theories/Numbers/NatInt/Makefile4
-rw-r--r--theories/Numbers/NatInt/NZAxioms.v72
-rw-r--r--theories/Numbers/NatInt/NZBase.v82
-rw-r--r--theories/Numbers/NatInt/NZOrdRing.v26
-rw-r--r--theories/Numbers/NatInt/NZOrder.g219
-rw-r--r--theories/Numbers/NatInt/NZOrder.v538
-rw-r--r--theories/Numbers/NatInt/NZOrder1.v423
-rw-r--r--theories/Numbers/NatInt/NZPlus.v91
-rw-r--r--theories/Numbers/NatInt/NZPlusOrder.v73
-rw-r--r--theories/Numbers/NatInt/NZRing.v45
-rw-r--r--theories/Numbers/NatInt/NZTimes.v74
-rw-r--r--theories/Numbers/NatInt/NZTimesOrder.v315
-rw-r--r--theories/Numbers/Natural/Abstract/NBase.v214
-rw-r--r--theories/Numbers/Natural/Abstract/NDepRec.v (renamed from theories/Numbers/Natural/Axioms/NDepRec.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NDomain.v (renamed from theories/Numbers/Natural/Axioms/NDomain.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NIso.v (renamed from theories/Numbers/Natural/Axioms/NIso.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NMinus.v164
-rw-r--r--theories/Numbers/Natural/Abstract/NMiscFunct.v (renamed from theories/Numbers/Natural/Axioms/NMiscFunct.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NOrder.v (renamed from theories/Numbers/Natural/Axioms/NOrder.v)196
-rw-r--r--theories/Numbers/Natural/Abstract/NOtherInd.v (renamed from theories/Numbers/Natural/Axioms/NOtherInd.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NPlus.v (renamed from theories/Numbers/Natural/Axioms/NPlus.v)63
-rw-r--r--theories/Numbers/Natural/Abstract/NPlusOrder.v (renamed from theories/Numbers/Natural/Axioms/NPlusOrder.v)2
-rw-r--r--theories/Numbers/Natural/Abstract/NPred.v (renamed from theories/Numbers/Natural/Axioms/NPred.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NStrongRec.v (renamed from theories/Numbers/Natural/Axioms/NStrongRec.v)0
-rw-r--r--theories/Numbers/Natural/Abstract/NTimes.v (renamed from theories/Numbers/Natural/Axioms/NTimes.v)63
-rw-r--r--theories/Numbers/Natural/Abstract/NTimesOrder.v133
-rw-r--r--theories/Numbers/Natural/Axioms/NBase.v196
-rw-r--r--theories/Numbers/Natural/Axioms/NLeibniz.v4
-rw-r--r--theories/Numbers/Natural/Axioms/NMinus.v88
-rw-r--r--theories/Numbers/Natural/Axioms/NRec.v259
-rw-r--r--theories/Numbers/Natural/Axioms/NTimesOrder.v70
-rw-r--r--theories/Numbers/Natural/Binary/NBinary.v177
-rw-r--r--theories/Numbers/Natural/Peano/NPeano.v208
-rw-r--r--theories/Numbers/NumPrelude.v21
47 files changed, 3504 insertions, 895 deletions
diff --git a/theories/Numbers/Integer/Abstract/ZAxioms.v b/theories/Numbers/Integer/Abstract/ZAxioms.v
new file mode 100644
index 000000000..4019b4774
--- /dev/null
+++ b/theories/Numbers/Integer/Abstract/ZAxioms.v
@@ -0,0 +1,160 @@
+Require Export NumPrelude.
+Require Export NZAxioms.
+
+Set Implicit Arguments.
+
+Module Type ZAxiomsSig.
+
+Parameter Inline Z : Set.
+Parameter Inline ZE : Z -> Z -> Prop.
+Parameter Inline Z0 : Z.
+Parameter Inline Zsucc : Z -> Z.
+Parameter Inline Zpred : Z -> Z.
+Parameter Inline Zplus : Z -> Z -> Z.
+Parameter Inline Zminus : Z -> Z -> Z.
+Parameter Inline Ztimes : Z -> Z -> Z.
+Parameter Inline Zlt : Z -> Z -> Prop.
+Parameter Inline Zle : Z -> Z -> Prop.
+
+Delimit Scope IntScope with Int.
+Open Local Scope IntScope.
+Notation "x == y" := (ZE x y) (at level 70, no associativity) : IntScope.
+Notation "x ~= y" := (~ ZE x y) (at level 70, no associativity) : IntScope.
+Notation "0" := Z0 : IntScope.
+Notation "'S'" := Zsucc : IntScope.
+Notation "'P'" := Zpred : IntScope.
+Notation "1" := (S 0) : IntScope.
+Notation "x + y" := (Zplus x y) : IntScope.
+Notation "x - y" := (Zminus x y) : IntScope.
+Notation "x * y" := (Ztimes x y) : IntScope.
+Notation "x < y" := (Zlt x y) : IntScope.
+Notation "x <= y" := (Zle x y) : IntScope.
+Notation "x > y" := (Zlt y x) (only parsing) : IntScope.
+Notation "x >= y" := (Zle y x) (only parsing) : IntScope.
+
+Axiom ZE_equiv : equiv Z ZE.
+
+Add Relation Z ZE
+ reflexivity proved by (proj1 ZE_equiv)
+ symmetry proved by (proj2 (proj2 ZE_equiv))
+ transitivity proved by (proj1 (proj2 ZE_equiv))
+as ZE_rel.
+
+Add Morphism Zsucc with signature ZE ==> ZE as Zsucc_wd.
+Add Morphism Zpred with signature ZE ==> ZE as Zpred_wd.
+Add Morphism Zplus with signature ZE ==> ZE ==> ZE as Zplus_wd.
+Add Morphism Zminus with signature ZE ==> ZE ==> ZE as Zminus_wd.
+Add Morphism Ztimes with signature ZE ==> ZE ==> ZE as Ztimes_wd.
+Add Morphism Zlt with signature ZE ==> ZE ==> iff as Zlt_wd.
+Add Morphism Zle with signature ZE ==> ZE ==> iff as Zle_wd.
+
+Axiom S_inj : forall x y : Z, S x == S y -> x == y.
+Axiom S_P : forall x : Z, S (P x) == x.
+
+Axiom induction :
+ forall Q : Z -> Prop,
+ pred_wd E Q -> Q 0 ->
+ (forall x, Q x -> Q (S x)) ->
+ (forall x, Q x -> Q (P x)) -> forall x, Q x.
+
+End IntSignature.
+
+Module IntProperties (Import IntModule : IntSignature).
+Module Export ZDomainPropertiesModule := ZDomainProperties ZDomainModule.
+Open Local Scope IntScope.
+
+Ltac induct n :=
+ try intros until n;
+ pattern n; apply induction; clear n;
+ [unfold NumPrelude.pred_wd;
+ let n := fresh "n" in
+ let m := fresh "m" in
+ let H := fresh "H" in intros n m H; qmorphism n m | | |].
+
+Theorem P_inj : forall x y, P x == P y -> x == y.
+Proof.
+intros x y H.
+setoid_replace x with (S (P x)); [| symmetry; apply S_P].
+setoid_replace y with (S (P y)); [| symmetry; apply S_P].
+now rewrite H.
+Qed.
+
+Theorem P_S : forall x, P (S x) == x.
+Proof.
+intro x.
+apply S_inj.
+now rewrite S_P.
+Qed.
+
+(* The following tactics are intended for replacing a certain
+occurrence of a term t in the goal by (S (P t)) or by (P (S t)).
+Unfortunately, this cannot be done by setoid_replace tactic for two
+reasons. First, it seems impossible to do rewriting when one side of
+the equation in question (S_P or P_S) is a variable, due to bug 1604.
+This does not work even when the predicate is an identifier (e.g.,
+when one tries to rewrite (Q x) into (Q (S (P x)))). Second, the
+setoid_rewrite tactic, like the ordinary rewrite tactic, does not
+allow specifying the exact occurrence of the term to be rewritten. Now
+while not in the setoid context, this occurrence can be specified
+using the pattern tactic, it does not work with setoids, since pattern
+creates a lambda abstractuion, and setoid_rewrite does not work with
+them. *)
+
+Ltac rewrite_SP t set_tac repl thm :=
+let x := fresh "x" in
+set_tac x t;
+setoid_replace x with (repl x); [| symmetry; apply thm];
+unfold x; clear x.
+
+Tactic Notation "rewrite_S_P" constr(t) :=
+rewrite_SP t ltac:(fun x t => (set (x := t))) (fun x => (S (P x))) S_P.
+
+Tactic Notation "rewrite_S_P" constr(t) "at" integer(k) :=
+rewrite_SP t ltac:(fun x t => (set (x := t) in |-* at k)) (fun x => (S (P x))) S_P.
+
+Tactic Notation "rewrite_P_S" constr(t) :=
+rewrite_SP t ltac:(fun x t => (set (x := t))) (fun x => (P (S x))) P_S.
+
+Tactic Notation "rewrite_P_S" constr(t) "at" integer(k) :=
+rewrite_SP t ltac:(fun x t => (set (x := t) in |-* at k)) (fun x => (P (S x))) P_S.
+
+(* One can add tactic notations for replacements in assumptions rather
+than in the goal. For the reason of many possible variants, the core
+of the tactic is factored out. *)
+
+Section Induction.
+
+Variable Q : Z -> Prop.
+Hypothesis Q_wd : pred_wd E Q.
+
+Add Morphism Q with signature E ==> iff as Q_morph.
+Proof Q_wd.
+
+Theorem induction_n :
+ forall n, Q n ->
+ (forall m, Q m -> Q (S m)) ->
+ (forall m, Q m -> Q (P m)) -> forall m, Q m.
+Proof.
+induct n.
+intros; now apply induction.
+intros n IH H1 H2 H3; apply IH; try assumption. apply H3 in H1; now rewrite P_S in H1.
+intros n IH H1 H2 H3; apply IH; try assumption. apply H2 in H1; now rewrite S_P in H1.
+Qed.
+
+End Induction.
+
+Ltac induct_n k n :=
+ try intros until k;
+ pattern k; apply induction_n with (n := n); clear k;
+ [unfold NumPrelude.pred_wd;
+ let n := fresh "n" in
+ let m := fresh "m" in
+ let H := fresh "H" in intros n m H; qmorphism n m | | |].
+
+End IntProperties.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Integer/Axioms/ZBase.v b/theories/Numbers/Integer/Abstract/ZBase.v
index e0b753d4e..e0b753d4e 100644
--- a/theories/Numbers/Integer/Axioms/ZBase.v
+++ b/theories/Numbers/Integer/Abstract/ZBase.v
diff --git a/theories/Numbers/Integer/Axioms/ZDec.v b/theories/Numbers/Integer/Abstract/ZDec.v
index 9a7aaa099..9a7aaa099 100644
--- a/theories/Numbers/Integer/Axioms/ZDec.v
+++ b/theories/Numbers/Integer/Abstract/ZDec.v
diff --git a/theories/Numbers/Integer/Axioms/ZDomain.v b/theories/Numbers/Integer/Abstract/ZDomain.v
index 028128cf7..028128cf7 100644
--- a/theories/Numbers/Integer/Axioms/ZDomain.v
+++ b/theories/Numbers/Integer/Abstract/ZDomain.v
diff --git a/theories/Numbers/Integer/Axioms/ZOrder.v b/theories/Numbers/Integer/Abstract/ZOrder.v
index cc834b442..cc834b442 100644
--- a/theories/Numbers/Integer/Axioms/ZOrder.v
+++ b/theories/Numbers/Integer/Abstract/ZOrder.v
diff --git a/theories/Numbers/Integer/Axioms/ZPlus.v b/theories/Numbers/Integer/Abstract/ZPlus.v
index 624f85f04..624f85f04 100644
--- a/theories/Numbers/Integer/Axioms/ZPlus.v
+++ b/theories/Numbers/Integer/Abstract/ZPlus.v
diff --git a/theories/Numbers/Integer/Axioms/ZPlusOrder.v b/theories/Numbers/Integer/Abstract/ZPlusOrder.v
index 95f0fa8c6..95f0fa8c6 100644
--- a/theories/Numbers/Integer/Axioms/ZPlusOrder.v
+++ b/theories/Numbers/Integer/Abstract/ZPlusOrder.v
diff --git a/theories/Numbers/Integer/Axioms/ZPred.v b/theories/Numbers/Integer/Abstract/ZPred.v
index ffcb2dea8..ffcb2dea8 100644
--- a/theories/Numbers/Integer/Axioms/ZPred.v
+++ b/theories/Numbers/Integer/Abstract/ZPred.v
diff --git a/theories/Numbers/Integer/Axioms/ZTimes.v b/theories/Numbers/Integer/Abstract/ZTimes.v
index 38311aa2b..38311aa2b 100644
--- a/theories/Numbers/Integer/Axioms/ZTimes.v
+++ b/theories/Numbers/Integer/Abstract/ZTimes.v
diff --git a/theories/Numbers/Integer/Axioms/ZTimesOrder.v b/theories/Numbers/Integer/Abstract/ZTimesOrder.v
index 055342bcc..055342bcc 100644
--- a/theories/Numbers/Integer/Axioms/ZTimesOrder.v
+++ b/theories/Numbers/Integer/Abstract/ZTimesOrder.v
diff --git a/theories/Numbers/Integer/BigInts/EZBase.v b/theories/Numbers/Integer/BigInts/EZBase.v
new file mode 100644
index 000000000..f5c19c611
--- /dev/null
+++ b/theories/Numbers/Integer/BigInts/EZBase.v
@@ -0,0 +1,167 @@
+Require Export ZBase.
+(*Require Import BigN.*)
+Require Import NMake.
+Require Import ZnZ.
+Require Import Basic_type.
+Require Import ZAux.
+Require Import Zeqmod.
+Require Import ZArith.
+
+Module EZBaseMod (Import EffIntsMod : W0Type) <: ZBaseSig.
+Open Local Scope Z_scope.
+
+Definition Z := EffIntsMod.w.
+
+Definition w_op := EffIntsMod.w_op.
+Definition w_spec := EffIntsMod.w_spec.
+Definition to_Z := w_op.(znz_to_Z).
+Definition of_Z := znz_of_Z w_op.
+Definition wB := base w_op.(znz_digits).
+
+Theorem Zpow_gt_1 : forall n m : BinInt.Z, 0 < n -> 1 < m -> 1 < m ^ n.
+Proof.
+intros n m H1 H2.
+replace 1 with (m ^ 0) by apply Zpower_exp_0.
+apply Zpower_lt_monotone; auto with zarith.
+Qed.
+
+Theorem wB_gt_1 : 1 < wB.
+Proof.
+unfold wB, base. apply Zpow_gt_1; unfold Zlt; auto with zarith.
+Qed.
+
+Theorem wB_gt_0 : 0 < wB.
+Proof.
+pose proof wB_gt_1; auto with zarith.
+Qed.
+
+Notation "[| x |]" := (to_Z x) (at level 0, x at level 99).
+
+Theorem to_Z_spec : forall x : Z, 0 <= [|x|] < wB.
+Proof w_spec.(spec_to_Z).
+
+Definition ZE (n m : Z) := [|n|] = [|m|].
+
+Notation "x == y" := (ZE x y) (at level 70) : IntScope.
+Notation "x ~= y" := (~ ZE x y) (at level 70) : IntScope.
+Open Local Scope IntScope.
+
+Theorem ZE_equiv : equiv Z ZE.
+Proof.
+unfold equiv, reflexive, symmetric, transitive, ZE; repeat split; intros; auto.
+now transitivity [|y|].
+Qed.
+
+Add Relation Z ZE
+ reflexivity proved by (proj1 ZE_equiv)
+ symmetry proved by (proj2 (proj2 ZE_equiv))
+ transitivity proved by (proj1 (proj2 ZE_equiv))
+as ZE_rel.
+
+Definition Z0 := w_op.(znz_0).
+Definition Zsucc := w_op.(znz_succ).
+
+Notation "0" := Z0 : IntScope.
+Notation "'S'" := Zsucc : IntScope.
+Notation "1" := (S 0) : IntScope.
+
+Theorem Zsucc_spec : forall n : Z, [|S n|] = ([|n|] + 1) mod wB.
+Proof w_spec.(spec_succ).
+
+Add Morphism Zsucc with signature ZE ==> ZE as Zsucc_wd.
+Proof.
+unfold ZE; intros n m H. do 2 rewrite Zsucc_spec. now rewrite H.
+Qed.
+
+Theorem Zsucc_inj : forall x y : Z, S x == S y -> x == y.
+Proof.
+intros x y H; unfold ZE in *; do 2 rewrite Zsucc_spec in H.
+apply <- Zplus_eqmod_compat_r in H.
+do 2 rewrite Zmod_def_small in H; now try apply to_Z_spec.
+apply wB_gt_0.
+Qed.
+
+Lemma of_Z_0 : of_Z 0 == Z0.
+Proof.
+unfold ZE, to_Z, of_Z. rewrite znz_of_Z_correct.
+symmetry; apply w_spec.(spec_0).
+exact w_spec. split; [auto with zarith |apply wB_gt_0].
+Qed.
+
+Section Induction.
+
+Variable A : Z -> Prop.
+Hypothesis A_wd : predicate_wd ZE A.
+Hypothesis A0 : A 0.
+Hypothesis AS : forall n : Z, A n <-> A (S n). (* In fact, it's enought to have only -> *)
+
+Add Morphism A with signature ZE ==> iff as A_morph.
+Proof A_wd.
+
+Let B (n : BinInt.Z) := A (of_Z n).
+
+Lemma B0 : B 0.
+Proof.
+unfold B. now rewrite of_Z_0.
+Qed.
+
+Lemma BS : forall n : BinInt.Z, 0 <= n -> n < wB - 1 -> B n -> B (n + 1).
+Proof.
+intros n H1 H2 H3.
+unfold B in *. apply -> AS in H3.
+setoid_replace (of_Z (n + 1)) with (S (of_Z n)) using relation ZE. assumption.
+unfold ZE. rewrite Zsucc_spec.
+unfold to_Z, of_Z. rewrite znz_of_Z_correct. rewrite znz_of_Z_correct.
+symmetry; apply Zmod_def_small; auto with zarith.
+exact w_spec.
+unfold wB in *; auto with zarith.
+exact w_spec.
+unfold wB in *; auto with zarith.
+Qed.
+
+Lemma Zbounded_induction :
+ (forall Q : BinInt.Z -> Prop, forall b : BinInt.Z,
+ Q 0 ->
+ (forall n, 0 <= n -> n < b - 1 -> Q n -> Q (n + 1)) ->
+ forall n, 0 <= n -> n < b -> Q n)%Z.
+Proof.
+intros Q b Q0 QS.
+set (Q' := fun n => (n < b /\ Q n) \/ (b <= n)).
+assert (H : forall n, 0 <= n -> Q' n).
+apply natlike_rec2; unfold Q'.
+destruct (Zle_or_lt b 0) as [H | H]. now right. left; now split.
+intros n H IH. destruct IH as [[IH1 IH2] | IH].
+destruct (Zle_or_lt (b - 1) n) as [H1 | H1].
+right; auto with zarith.
+left. split; [auto with zarith | now apply (QS n)].
+right; auto with zarith.
+unfold Q' in *; intros n H1 H2. destruct (H n H1) as [[H3 H4] | H3].
+assumption. apply Zle_not_lt in H3. false_hyp H2 H3.
+Qed.
+
+Lemma B_holds : forall n : BinInt.Z, 0 <= n < wB -> B n.
+Proof.
+intros n [H1 H2].
+apply Zbounded_induction with wB.
+apply B0. apply BS. assumption. assumption.
+Qed.
+
+Theorem Zinduction : forall n : Z, A n.
+Proof.
+intro n. setoid_replace n with (of_Z (to_Z n)) using relation ZE.
+apply B_holds. apply to_Z_spec.
+unfold ZE, to_Z, of_Z; rewrite znz_of_Z_correct.
+reflexivity.
+exact w_spec.
+apply to_Z_spec.
+Qed.
+
+End Induction.
+
+End EZBaseMod.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Integer/BigInts/Zeqmod.v b/theories/Numbers/Integer/BigInts/Zeqmod.v
new file mode 100644
index 000000000..ca3286211
--- /dev/null
+++ b/theories/Numbers/Integer/BigInts/Zeqmod.v
@@ -0,0 +1,48 @@
+Require Import ZArith.
+Require Import ZAux.
+
+Open Local Scope Z_scope.
+Notation "x == y '[' 'mod' z ']'" := ((x mod z) = (y mod z))
+ (at level 70, no associativity) : Z_scope.
+
+Theorem Zeqmod_refl : forall p n : Z, n == n [mod p].
+Proof.
+reflexivity.
+Qed.
+
+Theorem Zeqmod_symm : forall p n m : Z, n == m [mod p] -> m == n [mod p].
+Proof.
+now symmetry.
+Qed.
+
+Theorem Zeqmod_trans :
+ forall p n m k : Z, n == m [mod p] -> m == k [mod p] -> n == k [mod p].
+Proof.
+intros p n m k H1 H2; now transitivity (m mod p).
+Qed.
+
+Theorem Zplus_eqmod_compat_l :
+ forall p n m k : Z, 0 < p -> (n == m [mod p] <-> k + n == k + m [mod p]).
+intros p n m k H1.
+assert (LR : forall n' m' k' : Z, n' == m' [mod p] -> k' + n' == k' + m' [mod p]).
+intros n' m' k' H2.
+pattern ((k' + n') mod p); rewrite Zmod_plus; [| assumption].
+pattern ((k' + m') mod p); rewrite Zmod_plus; [| assumption].
+rewrite H2. apply Zeqmod_refl.
+split; [apply LR |].
+intro H2. apply (LR (k + n) (k + m) (-k)) in H2.
+do 2 rewrite Zplus_assoc in H2. rewrite Zplus_opp_l in H2.
+now do 2 rewrite Zplus_0_l in H2.
+Qed.
+
+Theorem Zplus_eqmod_compat_r :
+ forall p n m k : Z, 0 < p -> (n == m [mod p] <-> n + k == m + k [mod p]).
+intros p n m k; rewrite (Zplus_comm n k); rewrite (Zplus_comm m k);
+apply Zplus_eqmod_compat_l.
+Qed.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Integer/Binary/ZBinary.v b/theories/Numbers/Integer/Binary/ZBinary.v
new file mode 100644
index 000000000..217d08850
--- /dev/null
+++ b/theories/Numbers/Integer/Binary/ZBinary.v
@@ -0,0 +1,204 @@
+Require Import ZTimesOrder.
+Require Import ZArith.
+
+Open Local Scope Z_scope.
+Module Export ZBinDomain <: ZDomainSignature.
+Delimit Scope IntScope with Int.
+(* Is this really necessary? Without it, applying ZDomainProperties
+functor to this module produces an error since the functor opens the
+scope. *)
+
+Definition Z := Z.
+Definition E := (@eq Z).
+Definition e := Zeq_bool.
+
+Theorem E_equiv_e : forall x y : Z, E x y <-> e x y.
+Proof.
+intros x y; unfold E, e, Zeq_bool; split; intro H.
+rewrite H; now rewrite Zcompare_refl.
+rewrite eq_true_unfold_pos in H.
+assert (H1 : (x ?= y) = Eq).
+case_eq (x ?= y); intro H1; rewrite H1 in H; simpl in H;
+[reflexivity | discriminate H | discriminate H].
+now apply Zcompare_Eq_eq.
+Qed.
+
+Theorem E_equiv : equiv Z E.
+Proof.
+apply eq_equiv with (A := Z). (* It does not work without "with (A := Z)" though it looks like it should *)
+Qed.
+
+Add Relation Z E
+ reflexivity proved by (proj1 E_equiv)
+ symmetry proved by (proj2 (proj2 E_equiv))
+ transitivity proved by (proj1 (proj2 E_equiv))
+as E_rel.
+
+End ZBinDomain.
+
+Module Export ZBinInt <: IntSignature.
+Module Export ZDomainModule := ZBinDomain.
+
+Definition O := 0.
+Definition S := Zsucc'.
+Definition P := Zpred'.
+
+Add Morphism S with signature E ==> E as S_wd.
+Proof.
+intros; unfold E; congruence.
+Qed.
+
+Add Morphism P with signature E ==> E as P_wd.
+Proof.
+intros; unfold E; congruence.
+Qed.
+
+Theorem S_inj : forall x y : Z, S x = S y -> x = y.
+Proof.
+exact Zsucc'_inj.
+Qed.
+
+Theorem S_P : forall x : Z, S (P x) = x.
+Proof.
+exact Zsucc'_pred'.
+Qed.
+
+Theorem induction :
+ forall Q : Z -> Prop,
+ pred_wd E Q -> Q 0 ->
+ (forall x, Q x -> Q (S x)) ->
+ (forall x, Q x -> Q (P x)) -> forall x, Q x.
+Proof.
+intros; now apply Zind.
+Qed.
+
+End ZBinInt.
+
+Module Export ZBinPlus <: ZPlusSignature.
+Module Export IntModule := ZBinInt.
+
+Definition plus := Zplus.
+Definition minus := Zminus.
+Definition uminus := Zopp.
+
+Add Morphism plus with signature E ==> E ==> E as plus_wd.
+Proof.
+intros; congruence.
+Qed.
+
+Add Morphism minus with signature E ==> E ==> E as minus_wd.
+Proof.
+intros; congruence.
+Qed.
+
+Add Morphism uminus with signature E ==> E as uminus_wd.
+Proof.
+intros; congruence.
+Qed.
+
+Theorem plus_0 : forall n, 0 + n = n.
+Proof.
+exact Zplus_0_l.
+Qed.
+
+Theorem plus_S : forall n m, (S n) + m = S (n + m).
+Proof.
+intros; do 2 rewrite <- Zsucc_succ'; apply Zplus_succ_l.
+Qed.
+
+Theorem minus_0 : forall n, n - 0 = n.
+Proof.
+exact Zminus_0_r.
+Qed.
+
+Theorem minus_S : forall n m, n - (S m) = P (n - m).
+Proof.
+intros; rewrite <- Zsucc_succ'; rewrite <- Zpred_pred';
+apply Zminus_succ_r.
+Qed.
+
+Theorem uminus_0 : - 0 = 0.
+Proof.
+reflexivity.
+Qed.
+
+Theorem uminus_S : forall n, - (S n) = P (- n).
+Admitted.
+
+End ZBinPlus.
+
+Module Export ZBinTimes <: ZTimesSignature.
+Module Export ZPlusModule := ZBinPlus.
+
+Definition times := Zmult.
+
+Add Morphism times with signature E ==> E ==> E as times_wd.
+Proof.
+congruence.
+Qed.
+
+Theorem times_0 : forall n, n * 0 = 0.
+Proof.
+exact Zmult_0_r.
+Qed.
+
+Theorem times_S : forall n m, n * (S m) = n * m + n.
+Proof.
+intros; rewrite <- Zsucc_succ'; apply Zmult_succ_r.
+Qed.
+
+End ZBinTimes.
+
+Module Export ZBinOrder <: ZOrderSignature.
+Module Export IntModule := ZBinInt.
+
+Definition lt := Zlt_bool.
+Definition le := Zle_bool.
+
+Add Morphism lt with signature E ==> E ==> eq_bool as lt_wd.
+Proof.
+congruence.
+Qed.
+
+Add Morphism le with signature E ==> E ==> eq_bool as le_wd.
+Proof.
+congruence.
+Qed.
+
+Theorem le_lt : forall n m, le n m <-> lt n m \/ n = m.
+Proof.
+intros; unfold lt, le, Zlt_bool, Zle_bool.
+case_eq (n ?= m); intro H.
+apply Zcompare_Eq_eq in H; rewrite H; now split; intro; [right |].
+now split; intro; [left |].
+split; intro H1. now idtac.
+destruct H1 as [H1 | H1].
+assumption. unfold E in H1; rewrite H1 in H. now rewrite Zcompare_refl in H.
+Qed.
+
+Theorem lt_irr : forall n, ~ (lt n n).
+Proof.
+intro n; rewrite eq_true_unfold_pos; intro H.
+assert (H1 : (Zlt n n)).
+change (if true then (Zlt n n) else (Zge n n)). rewrite <- H.
+unfold lt. apply Zlt_cases.
+false_hyp H1 Zlt_irrefl.
+Qed.
+
+Theorem lt_S : forall n m, lt n (S m) <-> le n m.
+Proof.
+intros; unfold lt, le, S; do 2 rewrite eq_true_unfold_pos.
+rewrite <- Zsucc_succ'; rewrite <- Zlt_is_lt_bool; rewrite <- Zle_is_le_bool.
+split; intro; [now apply Zlt_succ_le | now apply Zle_lt_succ].
+Qed.
+
+End ZBinOrder.
+
+Module Export ZTimesOrderPropertiesModule :=
+ ZTimesOrderProperties ZBinTimes ZBinOrder.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/Makefile b/theories/Numbers/NatInt/Makefile
new file mode 100644
index 000000000..e23d8dee2
--- /dev/null
+++ b/theories/Numbers/NatInt/Makefile
@@ -0,0 +1,4 @@
+.SUFFIXES: .v .vo .vi .g .html .tex .g.tex .g.html
+
+.v.vo:
+ coqtop -boot -compile $*
diff --git a/theories/Numbers/NatInt/NZAxioms.v b/theories/Numbers/NatInt/NZAxioms.v
new file mode 100644
index 000000000..fa0bd21a3
--- /dev/null
+++ b/theories/Numbers/NatInt/NZAxioms.v
@@ -0,0 +1,72 @@
+Require Export NumPrelude.
+
+Module Type NZAxiomsSig.
+
+Parameter Inline NZ : Set.
+Parameter Inline NZE : NZ -> NZ -> Prop.
+Parameter Inline NZ0 : NZ.
+Parameter Inline NZsucc : NZ -> NZ.
+Parameter Inline NZpred : NZ -> NZ.
+Parameter Inline NZplus : NZ -> NZ -> NZ.
+Parameter Inline NZtimes : NZ -> NZ -> NZ.
+
+Axiom NZE_equiv : equiv NZ NZE.
+Add Relation NZ NZE
+ reflexivity proved by (proj1 NZE_equiv)
+ symmetry proved by (proj2 (proj2 NZE_equiv))
+ transitivity proved by (proj1 (proj2 NZE_equiv))
+as NZE_rel.
+
+Add Morphism NZsucc with signature NZE ==> NZE as NZsucc_wd.
+Add Morphism NZpred with signature NZE ==> NZE as NZpred_wd.
+Add Morphism NZplus with signature NZE ==> NZE ==> NZE as NZplus_wd.
+Add Morphism NZtimes with signature NZE ==> NZE ==> NZE as NZtimes_wd.
+
+Delimit Scope NatIntScope with NatInt.
+Open Local Scope NatIntScope.
+Notation "x == y" := (NZE x y) (at level 70) : NatIntScope.
+Notation "x ~= y" := (~ NZE x y) (at level 70) : NatIntScope.
+Notation "0" := NZ0 : NatIntScope.
+Notation "'S'" := NZsucc : NatIntScope.
+Notation "'P'" := NZpred : NatIntScope.
+Notation "1" := (S 0) : NatIntScope.
+Notation "x + y" := (NZplus x y) : NatIntScope.
+Notation "x * y" := (NZtimes x y) : NatIntScope.
+
+Axiom NZpred_succ : forall n : NZ, P (S n) == n.
+
+Axiom NZinduction :
+ forall A : NZ -> Prop, predicate_wd NZE A ->
+ A 0 -> (forall n : NZ, A n <-> A (S n)) -> forall n : NZ, A n.
+
+Axiom NZplus_0_l : forall n : NZ, 0 + n == n.
+Axiom NZplus_succ_l : forall n m : NZ, (S n) + m == S (n + m).
+
+Axiom NZtimes_0_r : forall n : NZ, n * 0 == 0.
+Axiom NZtimes_succ_r : forall n m : NZ, n * (S m) == n * m + n.
+
+End NZAxiomsSig.
+
+Module Type NZOrdAxiomsSig.
+Declare Module Export NZAxiomsMod : NZAxiomsSig.
+Open Local Scope NatIntScope.
+
+Parameter Inline NZlt : NZ -> NZ -> Prop.
+Parameter Inline NZle : NZ -> NZ -> Prop.
+
+Add Morphism NZlt with signature NZE ==> NZE ==> iff as NZlt_wd.
+Add Morphism NZle with signature NZE ==> NZE ==> iff as NZle_wd.
+
+Notation "x < y" := (NZlt x y) : NatIntScope.
+Notation "x <= y" := (NZle x y) : NatIntScope.
+
+Axiom NZle_lt_or_eq : forall n m : NZ, n <= m <-> n < m \/ n == m.
+Axiom NZlt_irrefl : forall n : NZ, ~ (n < n).
+Axiom NZlt_succ_le : forall n m : NZ, n < S m <-> n <= m.
+End NZOrdAxiomsSig.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZBase.v b/theories/Numbers/NatInt/NZBase.v
new file mode 100644
index 000000000..64cf68489
--- /dev/null
+++ b/theories/Numbers/NatInt/NZBase.v
@@ -0,0 +1,82 @@
+Require Import NZAxioms.
+
+Module NZBasePropFunct (Import NZAxiomsMod : NZAxiomsSig).
+Open Local Scope NatIntScope.
+
+Theorem NZneq_symm : forall n m : NZ, n ~= m -> m ~= n.
+Proof.
+intros n m H1 H2; symmetry in H2; false_hyp H2 H1.
+Qed.
+
+Theorem NZE_stepl : forall x y z : NZ, x == y -> x == z -> z == y.
+Proof.
+intros x y z H1 H2; now rewrite <- H1.
+Qed.
+
+Declare Left Step NZE_stepl.
+(* The right step lemma is just the transitivity of NZE *)
+Declare Right Step (proj1 (proj2 NZE_equiv)).
+
+Theorem NZsucc_inj : forall n1 n2 : NZ, S n1 == S n2 -> n1 == n2.
+Proof.
+intros n1 n2 H.
+apply NZpred_wd in H. now do 2 rewrite NZpred_succ in H.
+Qed.
+
+(* The following theorem is useful as an equivalence for proving
+bidirectional induction steps *)
+Theorem NZsucc_inj_wd : forall n1 n2 : NZ, S n1 == S n2 <-> n1 == n2.
+Proof.
+intros; split.
+apply NZsucc_inj.
+apply NZsucc_wd.
+Qed.
+
+Theorem NZsucc_inj_wd_neg : forall n m : NZ, S n ~= S m <-> n ~= m.
+Proof.
+intros; now rewrite NZsucc_inj_wd.
+Qed.
+
+(* We cannot prove that the predecessor is injective, nor that it is
+left-inverse to the successor at this point *)
+
+Section CentralInduction.
+
+Variable A : NZ -> Prop.
+(* FIXME: declaring "A : predicate NZ" leads to the error during the
+declaration of the morphism below because the "predicate NZ" is not
+recognized as a type of function. Maybe it should do "eval hnf" or
+something like this. The same goes for "relation". *)
+
+Hypothesis A_wd : predicate_wd NZE A.
+
+Add Morphism A with signature NZE ==> iff as A_morph.
+Proof A_wd.
+
+Theorem NZcentral_induction :
+ forall z : NZ, A z ->
+ (forall n : NZ, A n <-> A (S n)) ->
+ forall n : NZ, A n.
+Proof.
+intros z Base Step; revert Base; pattern z; apply NZinduction.
+solve_predicate_wd.
+intro; now apply NZinduction.
+intro; pose proof (Step n); tauto.
+Qed.
+
+End CentralInduction.
+
+Tactic Notation "NZinduct" ident(n) :=
+ induction_maker n ltac:(apply NZinduction).
+
+Tactic Notation "NZinduct" ident(n) constr(z) :=
+ induction_maker n ltac:(apply NZcentral_induction with (z := z)).
+
+End NZBasePropFunct.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
+
diff --git a/theories/Numbers/NatInt/NZOrdRing.v b/theories/Numbers/NatInt/NZOrdRing.v
new file mode 100644
index 000000000..f35e030e1
--- /dev/null
+++ b/theories/Numbers/NatInt/NZOrdRing.v
@@ -0,0 +1,26 @@
+Require Export NZAxioms.
+Require Import NZTimes.
+
+Module Type NZOrdAxiomsSig.
+Declare Module Export NZAxiomsMod : NZAxiomsSig.
+Open Local Scope NatIntScope.
+
+Parameter Inline NZlt : NZ -> NZ -> Prop.
+Parameter Inline NZle : NZ -> NZ -> Prop.
+
+Add Morphism NZlt with signature NZE ==> NZE ==> iff as NZlt_wd.
+Add Morphism NZle with signature NZE ==> NZE ==> iff as NZle_wd.
+
+Notation "x < y" := (NZlt x y) : NatIntScope.
+Notation "x <= y" := (NZle x y) : NatIntScope.
+
+Axiom NZle_lt_or_eq : forall n m : NZ, n <= m <-> n < m \/ n == m.
+Axiom NZlt_irrefl : forall n : NZ, ~ (n < n).
+Axiom NZlt_succ_le : forall n m : NZ, n < S m <-> n <= m.
+End NZOrdAxiomsSig.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZOrder.g b/theories/Numbers/NatInt/NZOrder.g
new file mode 100644
index 000000000..fd7cf608a
--- /dev/null
+++ b/theories/Numbers/NatInt/NZOrder.g
@@ -0,0 +1,219 @@
+Require Export NZBase.
+
+Module Type NZOrderSig.
+Declare Module Export NZBaseMod : NZBaseSig.
+Open Local Scope NatIntScope.
+
+Parameter Inline NZlt : NZ -> NZ -> Prop.
+Parameter Inline NZle : NZ -> NZ -> Prop.
+
+Add Morphism NZlt with signature NZE ==> NZE ==> iff as NZlt_wd.
+Add Morphism NZle with signature NZE ==> NZE ==> iff as NZle_wd.
+
+Notation "x < y" := (NZlt x y) : NatIntScope.
+Notation "x <= y" := (NZle x y) : NatIntScope.
+
+Axiom NZle_lt_or_eq : forall n m : NZ, n <= m <-> n < m \/ n == m.
+Axiom NZlt_irrefl : forall n : NZ, ~ (n < n).
+Axiom NZlt_succ_le : forall n m : NZ, n < S m <-> n <= m.
+End NZOrderSig.
+
+Module NZOrderPropFunct (Import NZOrderMod : NZOrderSig).
+Module Export NZBasePropMod := NZBasePropFunct NZBaseMod.
+Open Local Scope NatIntScope.
+
+Ltac NZle_intro1 := rewrite NZle_lt_or_eq; left.
+Ltac NZle_intro2 := rewrite NZle_lt_or_eq; right.
+Ltac NZle_elim H := rewrite NZle_lt_or_eq in H; destruct H as [H | H].
+
+Lemma NZlt_stepl : forall x y z : NZ, x < y -> x == z -> z < y.
+
+Lemma NZlt_stepr : forall x y z : NZ, x < y -> y == z -> x < z.
+
+Lemma NZle_stepl : forall x y z : NZ, x <= y -> x == z -> z <= y.
+
+Lemma NZle_stepr : forall x y z : NZ, x <= y -> y == z -> x <= z.
+
+Declare Left Step NZlt_stepl.
+Declare Right Step NZlt_stepr.
+Declare Left Step NZle_stepl.
+Declare Right Step NZle_stepr.
+
+Theorem NZlt_le_incl : forall n m : NZ, n < m -> n <= m.
+
+Theorem NZlt_neq : forall n m : NZ, n < m -> n ~= m.
+
+Theorem NZle_refl : forall n : NZ, n <= n.
+
+Theorem NZlt_succ_r : forall n : NZ, n < S n.
+
+Theorem NZle_succ_r : forall n : NZ, n <= S n.
+
+Theorem NZlt_lt_succ : forall n m : NZ, n < m -> n < S m.
+
+Theorem NZle_le_succ : forall n m : NZ, n <= m -> n <= S m.
+
+Theorem NZle_succ_le_or_eq_succ : forall n m : NZ, n <= S m <-> n <= m \/ n == S m.
+
+(* The following theorem is a special case of neq_succ_iter_l below,
+but we prove it independently *)
+
+Theorem neq_succ_l : forall n : NZ, S n ~= n.
+
+Theorem nlt_succ_l : forall n : NZ, ~ S n < n.
+
+Theorem nle_succ_l : forall n : NZ, ~ S n <= n.
+
+Theorem NZlt_le_succ : forall n m : NZ, n < m <-> S n <= m.
+
+Theorem NZlt_succ_lt : forall n m : NZ, S n < m -> n < m.
+
+Theorem NZle_succ_le : forall n m : NZ, S n <= m -> n <= m.
+
+Theorem NZsucc_lt_mono : forall n m : NZ, n < m <-> S n < S m.
+
+Theorem NZsucc_le_mono : forall n m : NZ, n <= m <-> S n <= S m.
+
+Theorem NZlt_lt_false : forall n m, n < m -> m < n -> False.
+
+Theorem NZlt_asymm : forall n m, n < m -> ~ m < n.
+
+Theorem NZlt_trans : forall n m p : NZ, n < m -> m < p -> n < p.
+
+Theorem NZle_trans : forall n m p : NZ, n <= m -> m <= p -> n <= p.
+
+Theorem NZle_lt_trans : forall n m p : NZ, n <= m -> m < p -> n < p.
+
+Theorem NZlt_le_trans : forall n m p : NZ, n < m -> m <= p -> n < p.
+
+Theorem NZle_antisymm : forall n m : NZ, n <= m -> m <= n -> n == m.
+
+(** Trichotomy, decidability, and double negation elimination *)
+
+Theorem NZlt_trichotomy : forall n m : NZ, n < m \/ n == m \/ m < n.
+
+Theorem NZle_lt_dec : forall n m : NZ, n <= m \/ m < n.
+
+Theorem NZle_nlt : forall n m : NZ, n <= m <-> ~ m < n.
+
+Theorem NZlt_dec : forall n m : NZ, n < m \/ ~ n < m.
+
+Theorem NZlt_dne : forall n m, ~ ~ n < m <-> n < m.
+
+Theorem nle_lt : forall n m : NZ, ~ n <= m <-> m < n.
+
+Theorem NZle_dec : forall n m : NZ, n <= m \/ ~ n <= m.
+
+Theorem NZle_dne : forall n m : NZ, ~ ~ n <= m <-> n <= m.
+
+Theorem NZlt_nlt_succ : forall n m : NZ, n < m <-> ~ m < S n.
+
+(* The difference between integers and natural numbers is that for
+every integer there is a predecessor, which is not true for natural
+numbers. However, for both classes, every number that is bigger than
+some other number has a predecessor. The proof of this fact by regular
+induction does not go through, so we need to use strong
+(course-of-value) induction. *)
+
+Lemma NZlt_exists_pred_strong :
+ forall z n m : NZ, z < m -> m <= n -> exists k : NZ, m == S k /\ z <= k.
+
+Theorem NZlt_exists_pred :
+ forall z n : NZ, z < n -> exists k : NZ, n == S k /\ z <= k.
+
+(** A corollary of having an order is that NZ is infinite *)
+
+(* This section about infinity of NZ relies on the type nat and can be
+safely removed *)
+
+Definition NZsucc_iter (n : nat) (m : NZ) :=
+ nat_rec (fun _ => NZ) m (fun _ l => S l) n.
+
+Theorem NZlt_succ_iter_r :
+ forall (n : nat) (m : NZ), m < NZsucc_iter (Datatypes.S n) m.
+
+Theorem neq_succ_iter_l :
+ forall (n : nat) (m : NZ), NZsucc_iter (Datatypes.S n) m ~= m.
+
+(* End of the section about the infinity of NZ *)
+
+(** Stronger variant of induction with assumptions n >= 0 (n < 0)
+in the induction step *)
+
+Section Induction.
+
+Variable A : NZ -> Prop.
+Hypothesis A_wd : predicate_wd NZE A.
+
+Add Morphism A with signature NZE ==> iff as A_morph.
+Proof A_wd.
+
+Section Center.
+
+Variable z : NZ. (* A z is the basis of induction *)
+
+Section RightInduction.
+
+Let A' (n : NZ) := forall m : NZ, z <= m -> m < n -> A m.
+
+Add Morphism A' with signature NZE ==> iff as A'_pos_wd.
+Proof.
+unfold A'; solve_predicate_wd.
+Qed.
+
+Theorem right_induction :
+ A z -> (forall n : NZ, z <= n -> A n -> A (S n)) -> forall n : NZ, z <= n -> A n.
+
+End RightInduction.
+
+Section LeftInduction.
+
+Let A' (n : NZ) := forall m : NZ, m <= z -> n <= m -> A m.
+
+Add Morphism A' with signature NZE ==> iff as A'_neg_wd.
+Proof.
+unfold A'; solve_predicate_wd.
+Qed.
+
+Theorem NZleft_induction :
+ A z -> (forall n : NZ, n < z -> A (S n) -> A n) -> forall n : NZ, n <= z -> A n.
+
+End LeftInduction.
+
+Theorem central_induction :
+ A z ->
+ (forall n : NZ, z <= n -> A n -> A (S n)) ->
+ (forall n : NZ, n < z -> A (S n) -> A n) ->
+ forall n : NZ, A n.
+
+End Center.
+
+Theorem induction_0 :
+ A 0 ->
+ (forall n : NZ, 0 <= n -> A n -> A (S n)) ->
+ (forall n : NZ, n < 0 -> A (S n) -> A n) ->
+ forall n : NZ, A n.
+
+(** Elimintation principle for < *)
+
+Theorem NZlt_ind : forall (n : NZ),
+ A (S n) ->
+ (forall m : NZ, n < m -> A m -> A (S m)) ->
+ forall m : NZ, n < m -> A m.
+
+(** Elimintation principle for <= *)
+
+Theorem NZle_ind : forall (n : NZ),
+ A n ->
+ (forall m : NZ, n <= m -> A m -> A (S m)) ->
+ forall m : NZ, n <= m -> A m.
+
+End Induction.
+
+End NZOrderPropFunct.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZOrder.v b/theories/Numbers/NatInt/NZOrder.v
new file mode 100644
index 000000000..f5b757a20
--- /dev/null
+++ b/theories/Numbers/NatInt/NZOrder.v
@@ -0,0 +1,538 @@
+Require Import NZAxioms.
+Require Import NZTimes.
+
+Module NZOrderPropFunct (Import NZOrdAxiomsMod : NZOrdAxiomsSig).
+Module Export NZTimesPropMod := NZTimesPropFunct NZAxiomsMod.
+Open Local Scope NatIntScope.
+
+Ltac le_less := rewrite NZle_lt_or_eq; left; try assumption.
+Ltac le_equal := rewrite NZle_lt_or_eq; right; try reflexivity; try assumption.
+Ltac le_elim H := rewrite NZle_lt_or_eq in H; destruct H as [H | H].
+
+Lemma NZlt_stepl : forall x y z : NZ, x < y -> x == z -> z < y.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Lemma NZlt_stepr : forall x y z : NZ, x < y -> y == z -> x < z.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Lemma NZle_stepl : forall x y z : NZ, x <= y -> x == z -> z <= y.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Lemma NZle_stepr : forall x y z : NZ, x <= y -> y == z -> x <= z.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Declare Left Step NZlt_stepl.
+Declare Right Step NZlt_stepr.
+Declare Left Step NZle_stepl.
+Declare Right Step NZle_stepr.
+
+Theorem NZlt_le_incl : forall n m : NZ, n < m -> n <= m.
+Proof.
+intros; now le_less.
+Qed.
+
+Theorem NZlt_neq : forall n m : NZ, n < m -> n ~= m.
+Proof.
+intros n m H1 H2; rewrite H2 in H1; false_hyp H1 NZlt_irrefl.
+Qed.
+
+Theorem NZle_refl : forall n : NZ, n <= n.
+Proof.
+intro; now le_equal.
+Qed.
+
+Theorem NZlt_succ_r : forall n : NZ, n < S n.
+Proof.
+intro n. rewrite NZlt_succ_le. now le_equal.
+Qed.
+
+Theorem NZle_succ_r : forall n : NZ, n <= S n.
+Proof.
+intro; le_less; apply NZlt_succ_r.
+Qed.
+
+Theorem NZlt_lt_succ : forall n m : NZ, n < m -> n < S m.
+Proof.
+intros. rewrite NZlt_succ_le. now le_less.
+Qed.
+
+Theorem NZle_le_succ : forall n m : NZ, n <= m -> n <= S m.
+Proof.
+intros n m H; rewrite <- NZlt_succ_le in H; now le_less.
+Qed.
+
+Theorem NZle_succ_le_or_eq_succ : forall n m : NZ, n <= S m <-> n <= m \/ n == S m.
+Proof.
+intros n m; rewrite NZle_lt_or_eq. now rewrite NZlt_succ_le.
+Qed.
+
+(* The following theorem is a special case of neq_succ_iter_l below,
+but we prove it independently *)
+
+Theorem NZneq_succ_l : forall n : NZ, S n ~= n.
+Proof.
+intros n H. pose proof (NZlt_succ_r n) as H1. rewrite H in H1.
+false_hyp H1 NZlt_irrefl.
+Qed.
+
+Theorem NZnlt_succ_l : forall n : NZ, ~ S n < n.
+Proof.
+intros n H; apply NZlt_lt_succ in H. false_hyp H NZlt_irrefl.
+Qed.
+
+Theorem NZnle_succ_l : forall n : NZ, ~ S n <= n.
+Proof.
+intros n H; le_elim H.
+false_hyp H NZnlt_succ_l. false_hyp H NZneq_succ_l.
+Qed.
+
+Theorem NZlt_le_succ : forall n m : NZ, n < m <-> S n <= m.
+Proof.
+intro n; NZinduct m n.
+rewrite_false (n < n) NZlt_irrefl. now rewrite_false (S n <= n) NZnle_succ_l.
+intro m. rewrite NZlt_succ_le. rewrite NZle_succ_le_or_eq_succ.
+rewrite NZsucc_inj_wd. rewrite (NZle_lt_or_eq n m).
+rewrite or_cancel_r.
+apply NZlt_neq.
+intros H1 H2; rewrite H2 in H1; false_hyp H1 NZnle_succ_l.
+reflexivity.
+Qed.
+
+Theorem NZlt_succ_lt : forall n m : NZ, S n < m -> n < m.
+Proof.
+intros n m H; apply <- NZlt_le_succ; now le_less.
+Qed.
+
+Theorem NZle_succ_le : forall n m : NZ, S n <= m -> n <= m.
+Proof.
+intros n m H; le_less; now apply <- NZlt_le_succ.
+Qed.
+
+Theorem NZsucc_lt_mono : forall n m : NZ, n < m <-> S n < S m.
+Proof.
+intros n m. rewrite NZlt_le_succ. symmetry. apply NZlt_succ_le.
+Qed.
+
+Theorem NZsucc_le_mono : forall n m : NZ, n <= m <-> S n <= S m.
+Proof.
+intros n m. do 2 rewrite NZle_lt_or_eq.
+rewrite <- NZsucc_lt_mono; now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZlt_lt_false : forall n m, n < m -> m < n -> False.
+Proof.
+intros n m; NZinduct n m.
+intros H _; false_hyp H NZlt_irrefl.
+intro n; split; intros H H1 H2.
+apply NZlt_succ_lt in H1. apply -> NZlt_succ_le in H2. le_elim H2.
+now apply H. rewrite H2 in H1; false_hyp H1 NZlt_irrefl.
+apply NZlt_lt_succ in H2. apply -> NZlt_le_succ in H1. le_elim H1.
+now apply H. rewrite H1 in H2; false_hyp H2 NZlt_irrefl.
+Qed.
+
+Theorem NZlt_asymm : forall n m, n < m -> ~ m < n.
+Proof.
+intros n m; unfold not; apply NZlt_lt_false.
+Qed.
+
+Theorem NZlt_trans : forall n m p : NZ, n < m -> m < p -> n < p.
+Proof.
+intros n m p; NZinduct p m.
+intros _ H; false_hyp H NZlt_irrefl.
+intro p. do 2 rewrite NZlt_succ_le.
+split; intros H H1 H2.
+le_less; le_elim H2; [now apply H | now rewrite H2 in H1].
+assert (n <= p) as H3. apply H. assumption. now le_less.
+le_elim H3. assumption. rewrite <- H3 in H2. elimtype False.
+now apply (NZlt_lt_false n m).
+Qed.
+
+Theorem NZle_trans : forall n m p : NZ, n <= m -> m <= p -> n <= p.
+Proof.
+intros n m p H1 H2; le_elim H1.
+le_elim H2. le_less; now apply NZlt_trans with (m := m).
+le_less; now rewrite <- H2. now rewrite H1.
+Qed.
+
+Theorem NZle_lt_trans : forall n m p : NZ, n <= m -> m < p -> n < p.
+Proof.
+intros n m p H1 H2; le_elim H1.
+now apply NZlt_trans with (m := m). now rewrite H1.
+Qed.
+
+Theorem NZlt_le_trans : forall n m p : NZ, n < m -> m <= p -> n < p.
+Proof.
+intros n m p H1 H2; le_elim H2.
+now apply NZlt_trans with (m := m). now rewrite <- H2.
+Qed.
+
+Theorem NZle_antisymm : forall n m : NZ, n <= m -> m <= n -> n == m.
+Proof.
+intros n m H1 H2; now (le_elim H1; le_elim H2);
+[elimtype False; apply (NZlt_lt_false n m) | | |].
+Qed.
+
+(** Trichotomy, decidability, and double negation elimination *)
+
+Theorem NZlt_trichotomy : forall n m : NZ, n < m \/ n == m \/ m < n.
+Proof.
+intros n m; NZinduct n m.
+right; now left.
+intro n; rewrite NZlt_succ_le. stepr ((S n < m \/ S n == m) \/ m <= n) by tauto.
+rewrite <- (NZle_lt_or_eq (S n) m). symmetry (n == m).
+stepl (n < m \/ m < n \/ m == n) by tauto. rewrite <- NZle_lt_or_eq.
+apply or_iff_compat_r. apply NZlt_le_succ.
+Qed.
+
+Theorem NZE_dec : forall n m : NZ, n == m \/ n ~= m.
+Proof.
+intros n m; destruct (NZlt_trichotomy n m) as [H | [H | H]].
+right; intro H1; rewrite H1 in H; false_hyp H NZlt_irrefl.
+now left.
+right; intro H1; rewrite H1 in H; false_hyp H NZlt_irrefl.
+Qed.
+
+Theorem NZE_dne : forall n m, ~ ~ n == m <-> n == m.
+Proof.
+intros n m; split; intro H.
+destruct (NZE_dec n m) as [H1 | H1].
+assumption. false_hyp H1 H.
+intro H1; now apply H1.
+Qed.
+
+Theorem NZneq_lt_or_gt : forall n m : NZ, n ~= m <-> n < m \/ m < n.
+Proof.
+intros n m; split.
+pose proof (NZlt_trichotomy n m); tauto.
+intros H H1; destruct H as [H | H]; rewrite H1 in H; false_hyp H NZlt_irrefl.
+Qed.
+
+Theorem NZle_lt_dec : forall n m : NZ, n <= m \/ m < n.
+Proof.
+intros n m; destruct (NZlt_trichotomy n m) as [H | [H | H]].
+left; now le_less. left; now le_equal. now right.
+Qed.
+
+Theorem NZle_nlt : forall n m : NZ, n <= m <-> ~ m < n.
+Proof.
+intros n m. split; intro H; [intro H1 |].
+eapply NZle_lt_trans in H; [| eassumption ..]. false_hyp H NZlt_irrefl.
+destruct (NZle_lt_dec n m) as [H1 | H1].
+assumption. false_hyp H1 H.
+Qed.
+
+Theorem NZlt_dec : forall n m : NZ, n < m \/ ~ n < m.
+Proof.
+intros n m; destruct (NZle_lt_dec m n);
+[right; now apply -> NZle_nlt | now left].
+Qed.
+
+Theorem NZlt_dne : forall n m, ~ ~ n < m <-> n < m.
+Proof.
+intros n m; split; intro H;
+[destruct (NZlt_dec n m) as [H1 | H1]; [assumption | false_hyp H1 H] |
+intro H1; false_hyp H H1].
+Qed.
+
+Theorem NZnle_lt : forall n m : NZ, ~ n <= m <-> m < n.
+Proof.
+intros n m. rewrite NZle_nlt. apply NZlt_dne.
+Qed.
+
+Theorem NZle_dec : forall n m : NZ, n <= m \/ ~ n <= m.
+Proof.
+intros n m; destruct (NZle_lt_dec n m);
+[now left | right; now apply <- NZnle_lt].
+Qed.
+
+Theorem NZle_dne : forall n m : NZ, ~ ~ n <= m <-> n <= m.
+Proof.
+intros n m; split; intro H;
+[destruct (NZle_dec n m) as [H1 | H1]; [assumption | false_hyp H1 H] |
+intro H1; false_hyp H H1].
+Qed.
+
+Theorem NZlt_nlt_succ : forall n m : NZ, n < m <-> ~ m < S n.
+Proof.
+intros n m; rewrite NZlt_succ_le; symmetry; apply NZnle_lt.
+Qed.
+
+(* The difference between integers and natural numbers is that for
+every integer there is a predecessor, which is not true for natural
+numbers. However, for both classes, every number that is bigger than
+some other number has a predecessor. The proof of this fact by regular
+induction does not go through, so we need to use strong
+(course-of-value) induction. *)
+
+Lemma NZlt_exists_pred_strong :
+ forall z n m : NZ, z < m -> m <= n -> exists k : NZ, m == S k /\ z <= k.
+Proof.
+intro z; NZinduct n z.
+intros m H1 H2; apply <- NZnle_lt in H1; false_hyp H2 H1.
+intro n; split; intros IH m H1 H2.
+apply -> NZle_succ_le_or_eq_succ in H2; destruct H2 as [H2 | H2].
+now apply IH. exists n. now split; [| rewrite <- NZlt_succ_le; rewrite <- H2].
+apply IH. assumption. now apply NZle_le_succ.
+Qed.
+
+Theorem NZlt_exists_pred :
+ forall z n : NZ, z < n -> exists k : NZ, n == S k /\ z <= k.
+Proof.
+intros z n H; apply NZlt_exists_pred_strong with (z := z) (n := n).
+assumption. apply NZle_refl.
+Qed.
+
+(** A corollary of having an order is that NZ is infinite *)
+
+(* This section about infinity of NZ relies on the type nat and can be
+safely removed *)
+
+Definition NZsucc_iter (n : nat) (m : NZ) :=
+ nat_rec (fun _ => NZ) m (fun _ l => S l) n.
+
+Theorem NZlt_succ_iter_r :
+ forall (n : nat) (m : NZ), m < NZsucc_iter (Datatypes.S n) m.
+Proof.
+intros n m; induction n as [| n IH]; simpl in *.
+apply NZlt_succ_r. now apply NZlt_lt_succ.
+Qed.
+
+Theorem NZneq_succ_iter_l :
+ forall (n : nat) (m : NZ), NZsucc_iter (Datatypes.S n) m ~= m.
+Proof.
+intros n m H. pose proof (NZlt_succ_iter_r n m) as H1. rewrite H in H1.
+false_hyp H1 NZlt_irrefl.
+Qed.
+
+(* End of the section about the infinity of NZ *)
+
+(** Stronger variant of induction with assumptions n >= 0 (n < 0)
+in the induction step *)
+
+Section Induction.
+
+Variable A : NZ -> Prop.
+Hypothesis A_wd : predicate_wd NZE A.
+
+Add Morphism A with signature NZE ==> iff as A_morph.
+Proof A_wd.
+
+Section Center.
+
+Variable z : NZ. (* A z is the basis of induction *)
+
+Section RightInduction.
+
+Let A' (n : NZ) := forall m : NZ, z <= m -> m < n -> A m.
+Let right_step := forall n : NZ, z <= n -> A n -> A (S n).
+Let right_step' := forall n : NZ, z <= n -> A' n -> A n.
+Let right_step'' := forall n : NZ, A' n <-> A' (S n).
+
+Lemma NZrs_rs' : A z -> right_step -> right_step'.
+Proof.
+intros Az RS n H1 H2.
+le_elim H1. apply NZlt_exists_pred in H1. destruct H1 as [k [H3 H4]].
+rewrite H3. apply RS; [assumption | apply H2; [assumption | rewrite H3; apply NZlt_succ_r]].
+rewrite <- H1; apply Az.
+Qed.
+
+Lemma NZrs'_rs'' : right_step' -> right_step''.
+Proof.
+intros RS' n; split; intros H1 m H2 H3.
+apply -> NZlt_succ_le in H3; le_elim H3;
+[now apply H1 | rewrite H3 in *; now apply RS'].
+apply H1; [assumption | now apply NZlt_lt_succ].
+Qed.
+
+Lemma NZrbase : A' z.
+Proof.
+intros m H1 H2. apply -> NZle_nlt in H1. false_hyp H2 H1.
+Qed.
+
+Lemma NZA'A_right : (forall n : NZ, A' n) -> forall n : NZ, z <= n -> A n.
+Proof.
+intros H1 n H2. apply H1 with (n := S n); [assumption | apply NZlt_succ_r].
+Qed.
+
+Theorem NZstrong_right_induction: right_step' -> forall n : NZ, z <= n -> A n.
+Proof.
+intro RS'; apply NZA'A_right; unfold A'; NZinduct n z;
+[apply NZrbase | apply NZrs'_rs''; apply RS'].
+Qed.
+
+Theorem NZright_induction : A z -> right_step -> forall n : NZ, z <= n -> A n.
+Proof.
+intros Az RS; apply NZstrong_right_induction; now apply NZrs_rs'.
+Qed.
+
+End RightInduction.
+
+Section LeftInduction.
+
+Let A' (n : NZ) := forall m : NZ, m <= z -> n <= m -> A m.
+Let left_step := forall n : NZ, n < z -> A (S n) -> A n.
+Let left_step' := forall n : NZ, n <= z -> A' (S n) -> A n.
+Let left_step'' := forall n : NZ, A' n <-> A' (S n).
+
+Lemma NZls_ls' : A z -> left_step -> left_step'.
+Proof.
+intros Az LS n H1 H2. le_elim H1.
+apply LS; [assumption | apply H2; [now apply -> NZlt_le_succ | now le_equal]].
+rewrite H1; apply Az.
+Qed.
+
+Lemma NZls'_ls'' : left_step' -> left_step''.
+Proof.
+intros LS' n; split; intros H1 m H2 H3.
+apply NZle_succ_le in H3. now apply H1.
+le_elim H3.
+apply -> NZlt_le_succ in H3. now apply H1.
+rewrite <- H3 in *; now apply LS'.
+Qed.
+
+Lemma NZlbase : A' (S z).
+Proof.
+intros m H1 H2. apply <- NZlt_le_succ in H2.
+apply -> NZle_nlt in H1. false_hyp H2 H1.
+Qed.
+
+Lemma NZA'A_left : (forall n : NZ, A' n) -> forall n : NZ, n <= z -> A n.
+Proof.
+intros H1 n H2. apply H1 with (n := n); [assumption | now le_equal].
+Qed.
+
+Theorem NZstrong_left_induction: left_step' -> forall n : NZ, n <= z -> A n.
+Proof.
+intro LS'; apply NZA'A_left; unfold A'; NZinduct n (S z);
+[apply NZlbase | apply NZls'_ls''; apply LS'].
+Qed.
+
+Theorem NZleft_induction : A z -> left_step -> forall n : NZ, n <= z -> A n.
+Proof.
+intros Az LS; apply NZstrong_left_induction; now apply NZls_ls'.
+Qed.
+
+End LeftInduction.
+
+Theorem NZorder_induction :
+ A z ->
+ (forall n : NZ, z <= n -> A n -> A (S n)) ->
+ (forall n : NZ, n < z -> A (S n) -> A n) ->
+ forall n : NZ, A n.
+Proof.
+intros Az RS LS n.
+destruct (NZlt_trichotomy n z) as [H | [H | H]].
+now apply NZleft_induction; [| | le_less].
+now rewrite H.
+now apply NZright_induction; [| | le_less].
+Qed.
+
+Theorem NZright_induction' :
+ (forall n : NZ, n <= z -> A n) ->
+ (forall n : NZ, z <= n -> A n -> A (S n)) ->
+ forall n : NZ, A n.
+Proof.
+intros L R n.
+destruct (NZlt_trichotomy n z) as [H | [H | H]].
+apply L; now le_less.
+apply L; now le_equal.
+apply NZright_induction. apply L; now le_equal. assumption. now le_less.
+Qed.
+
+Theorem NZstrong_right_induction' :
+ (forall n : NZ, n <= z -> A n) ->
+ (forall n : NZ, z <= n -> (forall m : NZ, z <= m -> m < n -> A m) -> A n) ->
+ forall n : NZ, A n.
+Proof.
+intros L R n.
+destruct (NZlt_trichotomy n z) as [H | [H | H]].
+apply L; now le_less.
+apply L; now le_equal.
+apply NZstrong_right_induction. assumption. now le_less.
+Qed.
+
+End Center.
+
+Theorem NZorder_induction_0 :
+ A 0 ->
+ (forall n : NZ, 0 <= n -> A n -> A (S n)) ->
+ (forall n : NZ, n < 0 -> A (S n) -> A n) ->
+ forall n : NZ, A n.
+Proof (NZorder_induction 0).
+
+(** Elimintation principle for < *)
+
+Theorem NZlt_ind : forall (n : NZ),
+ A (S n) ->
+ (forall m : NZ, n < m -> A m -> A (S m)) ->
+ forall m : NZ, n < m -> A m.
+Proof.
+intros n H1 H2 m H3.
+apply NZright_induction with (S n); [assumption | | now apply -> NZlt_le_succ].
+intros; apply H2; try assumption. now apply <- NZlt_le_succ.
+Qed.
+
+(** Elimintation principle for <= *)
+
+Theorem NZle_ind : forall (n : NZ),
+ A n ->
+ (forall m : NZ, n <= m -> A m -> A (S m)) ->
+ forall m : NZ, n <= m -> A m.
+Proof.
+intros n H1 H2 m H3.
+now apply NZright_induction with n.
+Qed.
+
+End Induction.
+
+Tactic Notation "NZord_induct" ident(n) :=
+ induction_maker n ltac:(apply NZorder_induction_0).
+
+Tactic Notation "NZord_induct" ident(n) constr(z) :=
+ induction_maker n ltac:(apply NZorder_induction with z).
+
+Section WF.
+
+Variable z : NZ.
+
+Let R (n m : NZ) := z <= n /\ n < m.
+
+Add Morphism R with signature NZE ==> NZE ==> iff as R_wd.
+Proof.
+intros x1 x2 H1 x3 x4 H2; unfold R; rewrite H1; now rewrite H2.
+Qed.
+
+Lemma NZAcc_lt_wd : predicate_wd NZE (Acc R).
+Proof.
+unfold predicate_wd, fun_wd.
+intros x1 x2 H; split; intro H1; destruct H1 as [H2];
+constructor; intros; apply H2; now (rewrite H || rewrite <- H).
+Qed.
+
+Theorem NZlt_wf : well_founded R.
+Proof.
+unfold well_founded.
+apply NZstrong_right_induction' with (z := z).
+apply NZAcc_lt_wd.
+intros n H; constructor; intros y [H1 H2].
+apply <- NZnle_lt in H2. elim H2. now apply NZle_trans with z.
+intros n H1 H2; constructor; intros m [H3 H4]. now apply H2.
+Qed.
+
+End WF.
+
+End NZOrderPropFunct.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZOrder1.v b/theories/Numbers/NatInt/NZOrder1.v
new file mode 100644
index 000000000..6a15ddc6a
--- /dev/null
+++ b/theories/Numbers/NatInt/NZOrder1.v
@@ -0,0 +1,423 @@
+Require Export NZBase.
+
+Module Type NZOrderSig.
+Declare Module Export NZBaseMod : NZBaseSig.
+
+Parameter Inline NZlt : NZ -> NZ -> Prop.
+Parameter Inline NZle : NZ -> NZ -> Prop.
+
+Axiom NZlt_wd : rel_wd NZE NZE NZlt.
+Axiom NZle_wd : rel_wd NZE NZE NZle.
+
+Notation "x < y" := (NZlt x y).
+Notation "x <= y" := (NZle x y).
+
+Axiom NZle__lt_or_eq : forall n m : NZ, n <= m <-> n < m \/ n == m.
+Axiom NZlt_irrefl : forall n : NZ, ~ (n < n).
+Axiom NZlt_succ__le : forall n m : NZ, n < S m <-> n <= m.
+End NZOrderSig.
+
+Module NZOrderPropFunct (Import NZOrderMod : NZOrderSig).
+Module Export NZBasePropMod := NZBasePropFunct NZBaseMod.
+
+Ltac NZle_intro1 := rewrite NZle__lt_or_eq; left.
+Ltac NZle_intro2 := rewrite NZle__lt_or_eq; right.
+Ltac NZle_elim H := rewrite NZle__lt_or_eq in H; destruct H as [H | H].
+
+Add Morphism NZlt with signature NZE ==> NZE ==> iff as NZlt_morph.
+Proof.
+exact NZlt_wd.
+Qed.
+
+Add Morphism NZle with signature NZE ==> NZE ==> iff as NZle_morph.
+Proof.
+exact NZle_wd.
+Qed.
+
+Lemma NZlt_stepl : forall x y z : NZ, x < y -> x == z -> z < y.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Lemma NZlt_stepr : forall x y z : NZ, x < y -> y == z -> x < z.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Lemma NZle_stepl : forall x y z : NZ, x <= y -> x == z -> z <= y.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Lemma NZle_stepr : forall x y z : NZ, x <= y -> y == z -> x <= z.
+Proof.
+intros x y z H1 H2; now rewrite <- H2.
+Qed.
+
+Declare Left Step NZlt_stepl.
+Declare Right Step NZlt_stepr.
+Declare Left Step NZle_stepl.
+Declare Right Step NZle_stepr.
+
+Theorem NZlt_le_incl : forall n m : NZ, n < m -> n <= m.
+Proof.
+intros; now NZle_intro1.
+Qed.
+
+Theorem NZlt_neq : forall n m : NZ, n < m -> n ~= m.
+Proof.
+intros n m H1 H2; rewrite H2 in H1; false_hyp H1 NZlt_irrefl.
+Qed.
+
+Theorem NZle_refl : forall n : NZ, n <= n.
+Proof.
+intro; now NZle_intro2.
+Qed.
+
+Theorem NZlt_succ_r : forall n : NZ, n < S n.
+Proof.
+intro n. rewrite NZlt_succ__le. now NZle_intro2.
+Qed.
+
+Theorem NZle_succ_r : forall n : NZ, n <= S n.
+Proof.
+intro; NZle_intro1; apply NZlt_succ_r.
+Qed.
+
+Theorem NZlt__lt_succ : forall n m : NZ, n < m -> n < S m.
+Proof.
+intros. rewrite NZlt_succ__le. now NZle_intro1.
+Qed.
+
+Theorem NZle__le_succ : forall n m : NZ, n <= m -> n <= S m.
+Proof.
+intros n m H; rewrite <- NZlt_succ__le in H; now NZle_intro1.
+Qed.
+
+Theorem NZle_succ__le_or_eq_succ : forall n m : NZ, n <= S m <-> n <= m \/ n == S m.
+Proof.
+intros n m; rewrite NZle__lt_or_eq. now rewrite NZlt_succ__le.
+Qed.
+
+(** A corollary of having an order is that NZ is infinite *)
+
+(* This section about infinity of NZ relies on the type nat and can be
+safely removed *)
+
+Definition succ_iter (n : nat) (m : NZ) :=
+ nat_rec (fun _ => NZ) m (fun _ l => S l) n.
+
+Theorem NZlt_succ_iter_r :
+ forall (n : nat) (m : NZ), m < succ_iter (Datatypes.S n) m.
+Proof.
+intros n m; induction n as [| n IH]; simpl in *.
+apply NZlt_succ_r. now apply NZlt__lt_succ.
+Qed.
+
+Theorem NZneq_succ_iter_l :
+ forall (n : nat) (m : NZ), succ_iter (Datatypes.S n) m ~= m.
+Proof.
+intros n m H. pose proof (NZlt_succ_iter_r n m) as H1. rewrite H in H1.
+false_hyp H1 NZlt_irrefl.
+Qed.
+
+(* End of the section about the infinity of NZ *)
+
+(* The following theorem is a special case of NZneq_succ_iter_l, but we
+prove it independently *)
+
+Theorem NZneq_succ_l : forall n : NZ, S n ~= n.
+Proof.
+intros n H. pose proof (NZlt_succ_r n) as H1. rewrite H in H1.
+false_hyp H1 NZlt_irrefl.
+Qed.
+
+Theorem NZnlt_succ_l : forall n : NZ, ~ S n < n.
+Proof.
+intros n H; apply NZlt__lt_succ in H. false_hyp H NZlt_irrefl.
+Qed.
+
+Theorem NZnle_succ_l : forall n : NZ, ~ S n <= n.
+Proof.
+intros n H; NZle_elim H.
+false_hyp H NZnlt_succ_l. false_hyp H NZneq_succ_l.
+Qed.
+
+Theorem NZlt__le_succ : forall n m : NZ, n < m <-> S n <= m.
+Proof.
+intro n; NZinduct_center m n.
+rewrite_false (n < n) NZlt_irrefl. now rewrite_false (S n <= n) NZnle_succ_l.
+intro m. rewrite NZlt_succ__le. rewrite NZle_succ__le_or_eq_succ.
+rewrite NZsucc_inj_wd. rewrite (NZle__lt_or_eq n m).
+rewrite or_cancel_r.
+apply NZlt_neq.
+intros H1 H2; rewrite H2 in H1; false_hyp H1 NZnle_succ_l.
+reflexivity.
+Qed.
+
+Theorem NZlt_succ__lt : forall n m : NZ, S n < m -> n < m.
+Proof.
+intros n m H; apply <- NZlt__le_succ; now NZle_intro1.
+Qed.
+
+Theorem NZle_succ__le : forall n m : NZ, S n <= m -> n <= m.
+Proof.
+intros n m H; NZle_intro1; now apply <- NZlt__le_succ.
+Qed.
+
+Theorem NZsucc_lt_mono : forall n m : NZ, n < m <-> S n < S m.
+Proof.
+intros n m. rewrite NZlt__le_succ. symmetry. apply NZlt_succ__le.
+Qed.
+
+Theorem NZsucc_le_mono : forall n m : NZ, n <= m <-> S n <= S m.
+Proof.
+intros n m. do 2 rewrite NZle__lt_or_eq.
+rewrite <- NZsucc_lt_mono; now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZlt_lt_false : forall n m, n < m -> m < n -> False.
+Proof.
+intros n m; NZinduct_center n m.
+intros H _; false_hyp H NZlt_irrefl.
+intro n; split; intros H H1 H2.
+apply NZlt_succ__lt in H1. apply -> NZlt_succ__le in H2. NZle_elim H2.
+now apply H. rewrite H2 in H1; false_hyp H1 NZlt_irrefl.
+apply NZlt__lt_succ in H2. apply -> NZlt__le_succ in H1. NZle_elim H1.
+now apply H. rewrite H1 in H2; false_hyp H2 NZlt_irrefl.
+Qed.
+
+Theorem NZlt_asymm : forall n m, n < m -> ~ m < n.
+Proof.
+intros n m; unfold not; apply NZlt_lt_false.
+Qed.
+
+Theorem NZlt_trans : forall n m p : NZ, n < m -> m < p -> n < p.
+Proof.
+intros n m p; NZinduct_center p m.
+intros _ H; false_hyp H NZlt_irrefl.
+intro p. do 2 rewrite NZlt_succ__le.
+split; intros H H1 H2.
+NZle_intro1; NZle_elim H2; [now apply H | now rewrite H2 in H1].
+assert (n <= p) as H3. apply H. assumption. now NZle_intro1.
+NZle_elim H3. assumption. rewrite <- H3 in H2. elimtype False.
+now apply (NZlt_lt_false n m).
+Qed.
+
+Theorem NZle_trans : forall n m p : NZ, n <= m -> m <= p -> n <= p.
+Proof.
+intros n m p H1 H2; NZle_elim H1.
+NZle_elim H2. NZle_intro1; now apply NZlt_trans with (m := m).
+NZle_intro1; now rewrite <- H2. now rewrite H1.
+Qed.
+
+Theorem NZle_lt_trans : forall n m p : NZ, n <= m -> m < p -> n < p.
+Proof.
+intros n m p H1 H2; NZle_elim H1.
+now apply NZlt_trans with (m := m). now rewrite H1.
+Qed.
+
+Theorem NZlt_le_trans : forall n m p : NZ, n < m -> m <= p -> n < p.
+Proof.
+intros n m p H1 H2; NZle_elim H2.
+now apply NZlt_trans with (m := m). now rewrite <- H2.
+Qed.
+
+Theorem NZle_antisym : forall n m : NZ, n <= m -> m <= n -> n == m.
+Proof.
+intros n m H1 H2; now (NZle_elim H1; NZle_elim H2);
+[elimtype False; apply (NZlt_lt_false n m) | | |].
+Qed.
+
+(** Trichotomy, decidability, and double negation elimination *)
+
+Theorem NZlt_trichotomy : forall n m : NZ, n < m \/ n == m \/ m < n.
+Proof.
+intros n m; NZinduct_center n m.
+right; now left.
+intro n; rewrite NZlt_succ__le. stepr ((S n < m \/ S n == m) \/ m <= n) by tauto.
+rewrite <- (NZle__lt_or_eq (S n) m). symmetry (n == m).
+stepl (n < m \/ m < n \/ m == n) by tauto. rewrite <- NZle__lt_or_eq.
+apply or_iff_compat_r. apply NZlt__le_succ.
+Qed.
+
+Theorem NZle_lt_dec : forall n m : NZ, n <= m \/ m < n.
+Proof.
+intros n m; destruct (NZlt_trichotomy n m) as [H | [H | H]].
+left; now NZle_intro1. left; now NZle_intro2. now right.
+Qed.
+
+Theorem NZle_nlt : forall n m : NZ, n <= m <-> ~ m < n.
+Proof.
+intros n m. split; intro H; [intro H1 |].
+eapply NZle_lt_trans in H; [| eassumption ..]. false_hyp H NZlt_irrefl.
+destruct (NZle_lt_dec n m) as [H1 | H1].
+assumption. false_hyp H1 H.
+Qed.
+
+Theorem NZlt_dec : forall n m : NZ, n < m \/ ~ n < m.
+Proof.
+intros n m; destruct (NZle_lt_dec m n);
+[right; now apply -> NZle_nlt | now left].
+Qed.
+
+Theorem NZlt_dne : forall n m, ~ ~ n < m <-> n < m.
+Proof.
+intros n m; split; intro H;
+[destruct (NZlt_dec n m) as [H1 | H1]; [assumption | false_hyp H1 H] |
+intro H1; false_hyp H H1].
+Qed.
+
+Theorem NZnle_lt : forall n m : NZ, ~ n <= m <-> m < n.
+Proof.
+intros n m. rewrite NZle_nlt. apply NZlt_dne.
+Qed.
+
+Theorem NZle_dec : forall n m : NZ, n <= m \/ ~ n <= m.
+Proof.
+intros n m; destruct (NZle_lt_dec n m);
+[now left | right; now apply <- NZnle_lt].
+Qed.
+
+Theorem NZle_dne : forall n m : NZ, ~ ~ n <= m <-> n <= m.
+Proof.
+intros n m; split; intro H;
+[destruct (NZle_dec n m) as [H1 | H1]; [assumption | false_hyp H1 H] |
+intro H1; false_hyp H H1].
+Qed.
+
+Theorem NZlt__nlt_succ : forall n m : NZ, n < m <-> ~ m < S n.
+Proof.
+intros n m; rewrite NZlt_succ__le; symmetry; apply NZnle_lt.
+Qed.
+
+(** Stronger variant of induction with assumptions n >= 0 (n <= 0)
+in the induction step *)
+
+Section Induction.
+
+Variable A : Z -> Prop.
+Hypothesis Q_wd : predicate_wd NZE A.
+
+Add Morphism A with signature NZE ==> iff as Q_morph.
+Proof Q_wd.
+
+Section Center.
+
+Variable z : Z. (* A z is the basis of induction *)
+
+Section RightInduction.
+
+Let Q' := fun n : Z => forall m : NZ, z <= m -> m < n -> A m.
+
+Add Morphism Q' with signature NZE ==> iff as Q'_pos_wd.
+Proof.
+intros x1 x2 H; unfold Q'; qmorphism x1 x2.
+Qed.
+
+Theorem NZright_induction :
+ A z -> (forall n : NZ, z <= n -> A n -> A (S n)) -> forall n : NZ, z <= n -> A n.
+Proof.
+intros Qz QS k k_ge_z.
+assert (H : forall n : NZ, Q' n). induct_n n z; unfold Q'.
+intros m H1 H2. apply -> le_gt in H1; false_hyp H2 H1.
+intros n IH m H2 H3.
+rewrite NZlt_succ in H3; Zle_elim H3. now apply IH.
+Zle_elim H2. rewrite_succ_pred m.
+apply QS. now apply -> lt_n_m_pred. apply IH. now apply -> lt_n_m_pred.
+rewrite H3; apply NZlt_pred_l. now rewrite <- H2.
+intros n IH m H2 H3. apply IH. assumption. now apply lt_n_predm.
+pose proof (H (S k)) as H1; unfold Q' in H1. apply H1.
+apply k_ge_z. apply NZlt_succ_r.
+Qed.
+
+End RightInduction.
+
+Section LeftInduction.
+
+Let Q' := fun n : Z => forall m : NZ, m <= z -> n < m -> A m.
+
+Add Morphism Q' with signature NZE ==> iff as Q'_neg_wd.
+Proof.
+intros x1 x2 H; unfold Q'; qmorphism x1 x2.
+Qed.
+
+Theorem NZleft_induction :
+ A z -> (forall n : NZ, n <= z -> A n -> A (P n)) -> forall n : NZ, n <= z -> A n.
+Proof.
+intros Qz QP k k_le_z.
+assert (H : forall n : NZ, Q' n). induct_n n z; unfold Q'.
+intros m H1 H2. apply -> le_gt in H1; false_hyp H2 H1.
+intros n IH m H2 H3. apply IH. assumption. now apply lt_succ__lt.
+intros n IH m H2 H3.
+rewrite NZlt_pred in H3; Zle_elim H3. now apply IH.
+Zle_elim H2. rewrite_pred_succ m.
+apply QP. now apply -> lt_n_m_succ. apply IH. now apply -> lt_n_m_succ.
+rewrite H3; apply NZlt_succ_r. now rewrite H2.
+pose proof (H (P k)) as H1; unfold Q' in H1. apply H1.
+apply k_le_z. apply NZlt_pred_l.
+Qed.
+
+End LeftInduction.
+
+Theorem NZinduction_ord_n :
+ A z ->
+ (forall n : NZ, z <= n -> A n -> A (S n)) ->
+ (forall n : NZ, n <= z -> A n -> A (P n)) ->
+ forall n : NZ, A n.
+Proof.
+intros Qz QS QP n.
+destruct (lt_total n z) as [H | [H | H]].
+now apply left_induction; [| | Zle_intro1].
+now rewrite H.
+now apply right_induction; [| | Zle_intro1].
+Qed.
+
+End Center.
+
+Theorem NZinduction_ord :
+ A 0 ->
+ (forall n : NZ, 0 <= n -> A n -> A (S n)) ->
+ (forall n : NZ, n <= 0 -> A n -> A (P n)) ->
+ forall n : NZ, A n.
+Proof (induction_ord_n 0).
+
+Theorem NZlt_ind : forall (n : Z),
+ A (S n) ->
+ (forall m : Z, n < m -> A m -> A (S m)) ->
+ forall m : Z, n < m -> A m.
+Proof.
+intros n H1 H2 m H3.
+apply right_induction with (S n). assumption.
+intros; apply H2; try assumption. now apply <- lt_n_m_succ.
+now apply -> lt_n_m_succ.
+Qed.
+
+Theorem NZle_ind : forall (n : Z),
+ A n ->
+ (forall m : Z, n <= m -> A m -> A (S m)) ->
+ forall m : Z, n <= m -> A m.
+Proof.
+intros n H1 H2 m H3.
+now apply right_induction with n.
+Qed.
+
+End Induction.
+
+Ltac induct_ord n :=
+ try intros until n;
+ pattern n; apply induction_ord; clear n;
+ [unfold NumPrelude.predicate_wd;
+ let n := fresh "n" in
+ let m := fresh "m" in
+ let H := fresh "H" in intros n m H; qmorphism n m | | |].
+
+End ZOrderProperties.
+
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZPlus.v b/theories/Numbers/NatInt/NZPlus.v
new file mode 100644
index 000000000..d333274ba
--- /dev/null
+++ b/theories/Numbers/NatInt/NZPlus.v
@@ -0,0 +1,91 @@
+Require Import NZAxioms.
+Require Import NZBase.
+
+Module NZPlusPropFunct (Import NZAxiomsMod : NZAxiomsSig).
+Module Export NZBasePropMod := NZBasePropFunct NZAxiomsMod.
+Open Local Scope NatIntScope.
+
+(** If H1 : t1 == u1 and H2 : t2 == u2 then "add_equations H1 H2 as H3"
+adds the hypothesis H3 : t1 + t2 == u1 + u2 *)
+Tactic Notation "add_equations" constr(H1) constr(H2) "as" ident(H3) :=
+match (type of H1) with
+| ?t1 == ?u1 => match (type of H2) with
+ | ?t2 == ?u2 => assert (H3 : t1 + t2 == u1 + u2); [now apply NZplus_wd |]
+ | _ => fail 2 ":" H2 "is not an equation"
+ end
+| _ => fail 1 ":" H1 "is not an equation"
+end.
+
+Theorem NZplus_0_r : forall n : NZ, n + 0 == n.
+Proof.
+NZinduct n. now rewrite NZplus_0_l.
+intro. rewrite NZplus_succ_l. now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZplus_succ_r : forall n m : NZ, n + S m == S (n + m).
+Proof.
+intros n m; NZinduct n.
+now do 2 rewrite NZplus_0_l.
+intro. repeat rewrite NZplus_succ_l. now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZplus_comm : forall n m : NZ, n + m == m + n.
+Proof.
+intros n m; NZinduct n.
+rewrite NZplus_0_l; now rewrite NZplus_0_r.
+intros n. rewrite NZplus_succ_l; rewrite NZplus_succ_r. now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZplus_1_l : forall n : NZ, 1 + n == S n.
+Proof.
+intro n; rewrite NZplus_succ_l; now rewrite NZplus_0_l.
+Qed.
+
+Theorem NZplus_1_r : forall n : NZ, n + 1 == S n.
+Proof.
+intro n; rewrite NZplus_comm; apply NZplus_1_l.
+Qed.
+
+Theorem NZplus_assoc : forall n m p : NZ, n + (m + p) == (n + m) + p.
+Proof.
+intros n m p; NZinduct n.
+now do 2 rewrite NZplus_0_l.
+intro. do 3 rewrite NZplus_succ_l. now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZplus_shuffle1 : forall n m p q : NZ, (n + m) + (p + q) == (n + p) + (m + q).
+Proof.
+intros n m p q.
+rewrite <- (NZplus_assoc n m (p + q)). rewrite (NZplus_comm m (p + q)).
+rewrite <- (NZplus_assoc p q m). rewrite (NZplus_assoc n p (q + m)).
+now rewrite (NZplus_comm q m).
+Qed.
+
+Theorem NZplus_shuffle2 : forall n m p q : NZ, (n + m) + (p + q) == (n + q) + (m + p).
+Proof.
+intros n m p q.
+rewrite <- (NZplus_assoc n m (p + q)). rewrite (NZplus_assoc m p q).
+rewrite (NZplus_comm (m + p) q). now rewrite <- (NZplus_assoc n q (m + p)).
+Qed.
+
+Theorem NZplus_cancel_l : forall n m p : NZ, p + n == p + m <-> n == m.
+Proof.
+intros n m p; NZinduct p.
+now do 2 rewrite NZplus_0_l.
+intro p. do 2 rewrite NZplus_succ_l. now rewrite NZsucc_inj_wd.
+Qed.
+
+Theorem NZplus_cancel_r : forall n m p : NZ, n + p == m + p <-> n == m.
+Proof.
+intros n m p. rewrite (NZplus_comm n p); rewrite (NZplus_comm m p).
+apply NZplus_cancel_l.
+Qed.
+
+End NZPlusPropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZPlusOrder.v b/theories/Numbers/NatInt/NZPlusOrder.v
new file mode 100644
index 000000000..f43b549e2
--- /dev/null
+++ b/theories/Numbers/NatInt/NZPlusOrder.v
@@ -0,0 +1,73 @@
+Require Export NZPlus.
+Require Export NZOrder.
+
+Module NZPlusOrderPropFunct
+ (Import NZPlusMod : NZPlusSig)
+ (Import NZOrderMod : NZOrderSig with Module NZBaseMod := NZPlusMod.NZBaseMod).
+
+Module Export NZPlusPropMod := NZPlusPropFunct NZPlusMod.
+Module Export NZOrderPropMod := NZOrderPropFunct NZOrderMod.
+Open Local Scope NatIntScope.
+
+Theorem NZplus_lt_mono_l : forall n m p, n < m <-> p + n < p + m.
+Proof.
+intros n m p; NZinduct p.
+now do 2 rewrite NZplus_0_l.
+intro p. do 2 rewrite NZplus_succ_l. now rewrite <- NZsucc_lt_mono.
+Qed.
+
+Theorem NZplus_lt_mono_r : forall n m p, n < m <-> n + p < m + p.
+Proof.
+intros n m p.
+rewrite (NZplus_comm n p); rewrite (NZplus_comm m p); apply NZplus_lt_mono_l.
+Qed.
+
+Theorem NZplus_lt_mono : forall n m p q, n < m -> p < q -> n + p < m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZlt_trans with (m + p);
+[now apply -> NZplus_lt_mono_r | now apply -> NZplus_lt_mono_l].
+Qed.
+
+Theorem NZplus_le_mono_l : forall n m p, n <= m <-> p + n <= p + m.
+Proof.
+intros n m p; NZinduct p.
+now do 2 rewrite NZplus_0_l.
+intro p. do 2 rewrite NZplus_succ_l. now rewrite <- NZsucc_le_mono.
+Qed.
+
+Theorem NZplus_le_mono_r : forall n m p, n <= m <-> n + p <= m + p.
+Proof.
+intros n m p.
+rewrite (NZplus_comm n p); rewrite (NZplus_comm m p); apply NZplus_le_mono_l.
+Qed.
+
+Theorem NZplus_le_mono : forall n m p q, n <= m -> p <= q -> n + p <= m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZle_trans with (m + p);
+[now apply -> NZplus_le_mono_r | now apply -> NZplus_le_mono_l].
+Qed.
+
+Theorem NZplus_lt_le_mono : forall n m p q, n < m -> p <= q -> n + p < m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZlt_le_trans with (m + p);
+[now apply -> NZplus_lt_mono_r | now apply -> NZplus_le_mono_l].
+Qed.
+
+Theorem NZplus_le_lt_mono : forall n m p q, n <= m -> p < q -> n + p < m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZle_lt_trans with (m + p);
+[now apply -> NZplus_le_mono_r | now apply -> NZplus_lt_mono_l].
+Qed.
+
+End NZPlusOrderPropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZRing.v b/theories/Numbers/NatInt/NZRing.v
new file mode 100644
index 000000000..2425224b8
--- /dev/null
+++ b/theories/Numbers/NatInt/NZRing.v
@@ -0,0 +1,45 @@
+Require Export NumPrelude.
+
+Module Type NZRingSig.
+
+Parameter Inline NZ : Set.
+Parameter Inline NZE : NZ -> NZ -> Prop.
+Parameter Inline NZ0 : NZ.
+Parameter Inline NZsucc : NZ -> NZ.
+Parameter Inline NZplus : NZ -> NZ -> NZ.
+Parameter Inline NZtimes : NZ -> NZ -> NZ.
+
+Axiom NZE_equiv : equiv NZ NZE.
+Add Relation NZ NZE
+ reflexivity proved by (proj1 NZE_equiv)
+ symmetry proved by (proj2 (proj2 NZE_equiv))
+ transitivity proved by (proj1 (proj2 NZE_equiv))
+as NZE_rel.
+
+Add Morphism NZsucc with signature NZE ==> NZE as NZsucc_wd.
+Add Morphism NZplus with signature NZE ==> NZE ==> NZE as NZplus_wd.
+Add Morphism NZtimes with signature NZE ==> NZE ==> NZE as NZtimes_wd.
+
+Delimit Scope NatIntScope with NatInt.
+Open Local Scope NatIntScope.
+Notation "x == y" := (NZE x y) (at level 70) : NatIntScope.
+Notation "x ~= y" := (~ NZE x y) (at level 70) : NatIntScope.
+Notation "0" := NZ0 : NatIntScope.
+Notation "'S'" := NZsucc.
+Notation "1" := (S 0) : NatIntScope.
+Notation "x + y" := (NZplus x y) : NatIntScope.
+Notation "x * y" := (NZtimes x y) : NatIntScope.
+
+Axiom NZsucc_inj : forall n1 n2 : NZ, S n1 == S n2 -> n1 == n2.
+
+Axiom NZinduction :
+ forall A : NZ -> Prop, predicate_wd NZE A ->
+ A 0 -> (forall n : NZ, A n <-> A (S n)) -> forall n : NZ, A n.
+
+Axiom NZplus_0_l : forall n : NZ, 0 + n == n.
+Axiom NZplus_succ_l : forall n m : NZ, (S n) + m == S (n + m).
+
+Axiom NZtimes_0_r : forall n : NZ, n * 0 == 0.
+Axiom NZtimes_succ_r : forall n m : NZ, n * (S m) == n * m + n.
+
+End NZRingSig.
diff --git a/theories/Numbers/NatInt/NZTimes.v b/theories/Numbers/NatInt/NZTimes.v
new file mode 100644
index 000000000..ca78ced69
--- /dev/null
+++ b/theories/Numbers/NatInt/NZTimes.v
@@ -0,0 +1,74 @@
+Require Import NZAxioms.
+Require Import NZPlus.
+
+Module NZTimesPropFunct (Import NZAxiomsMod : NZAxiomsSig).
+Module Export NZPlusPropMod := NZPlusPropFunct NZAxiomsMod.
+Open Local Scope NatIntScope.
+
+Theorem NZtimes_0_l : forall n : NZ, 0 * n == 0.
+Proof.
+NZinduct n.
+now rewrite NZtimes_0_r.
+intro. rewrite NZtimes_succ_r. now rewrite NZplus_0_r.
+Qed.
+
+Theorem NZtimes_succ_l : forall n m : NZ, (S n) * m == n * m + m.
+Proof.
+intros n m; NZinduct m.
+do 2 rewrite NZtimes_0_r; now rewrite NZplus_0_l.
+intro m. do 2 rewrite NZtimes_succ_r. do 2 rewrite NZplus_succ_r.
+rewrite NZsucc_inj_wd. rewrite <- (NZplus_assoc (n * m) n m).
+rewrite (NZplus_comm n m). rewrite NZplus_assoc.
+now rewrite NZplus_cancel_r.
+Qed.
+
+Theorem NZtimes_comm : forall n m : NZ, n * m == m * n.
+Proof.
+intros n m; NZinduct n.
+rewrite NZtimes_0_l; now rewrite NZtimes_0_r.
+intro. rewrite NZtimes_succ_l; rewrite NZtimes_succ_r. now rewrite NZplus_cancel_r.
+Qed.
+
+Theorem NZtimes_plus_distr_r : forall n m p : NZ, (n + m) * p == n * p + m * p.
+Proof.
+intros n m p; NZinduct n.
+rewrite NZtimes_0_l. now do 2 rewrite NZplus_0_l.
+intro n. rewrite NZplus_succ_l. do 2 rewrite NZtimes_succ_l.
+rewrite <- (NZplus_assoc (n * p) p (m * p)).
+rewrite (NZplus_comm p (m * p)). rewrite (NZplus_assoc (n * p) (m * p) p).
+now rewrite NZplus_cancel_r.
+Qed.
+
+Theorem NZtimes_plus_distr_l : forall n m p : NZ, n * (m + p) == n * m + n * p.
+Proof.
+intros n m p.
+rewrite (NZtimes_comm n (m + p)). rewrite (NZtimes_comm n m).
+rewrite (NZtimes_comm n p). apply NZtimes_plus_distr_r.
+Qed.
+
+Theorem NZtimes_assoc : forall n m p : NZ, n * (m * p) == (n * m) * p.
+Proof.
+intros n m p; NZinduct n.
+now do 3 rewrite NZtimes_0_l.
+intro n. do 2 rewrite NZtimes_succ_l. rewrite NZtimes_plus_distr_r.
+now rewrite NZplus_cancel_r.
+Qed.
+
+Theorem NZtimes_1_l : forall n : NZ, 1 * n == n.
+Proof.
+intro n. rewrite NZtimes_succ_l; rewrite NZtimes_0_l. now rewrite NZplus_0_l.
+Qed.
+
+Theorem NZtimes_1_r : forall n : NZ, n * 1 == n.
+Proof.
+intro n; rewrite NZtimes_comm; apply NZtimes_1_l.
+Qed.
+
+End NZTimesPropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/NatInt/NZTimesOrder.v b/theories/Numbers/NatInt/NZTimesOrder.v
new file mode 100644
index 000000000..95275f8c0
--- /dev/null
+++ b/theories/Numbers/NatInt/NZTimesOrder.v
@@ -0,0 +1,315 @@
+Require Import NZAxioms.
+Require Import NZOrder.
+
+Module NZTimesOrderPropFunct (Import NZOrdAxiomsMod : NZOrdAxiomsSig).
+Module Export NZOrderPropMod := NZOrderPropFunct NZOrdAxiomsMod.
+Open Local Scope NatIntScope.
+
+(** Addition and order *)
+
+Theorem NZplus_lt_mono_l : forall n m p : NZ, n < m <-> p + n < p + m.
+Proof.
+intros n m p; NZinduct p.
+now do 2 rewrite NZplus_0_l.
+intro p. do 2 rewrite NZplus_succ_l. now rewrite <- NZsucc_lt_mono.
+Qed.
+
+Theorem NZplus_lt_mono_r : forall n m p : NZ, n < m <-> n + p < m + p.
+Proof.
+intros n m p.
+rewrite (NZplus_comm n p); rewrite (NZplus_comm m p); apply NZplus_lt_mono_l.
+Qed.
+
+Theorem NZplus_lt_mono : forall n m p q : NZ, n < m -> p < q -> n + p < m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZlt_trans with (m + p);
+[now apply -> NZplus_lt_mono_r | now apply -> NZplus_lt_mono_l].
+Qed.
+
+Theorem NZplus_le_mono_l : forall n m p : NZ, n <= m <-> p + n <= p + m.
+Proof.
+intros n m p; NZinduct p.
+now do 2 rewrite NZplus_0_l.
+intro p. do 2 rewrite NZplus_succ_l. now rewrite <- NZsucc_le_mono.
+Qed.
+
+Theorem NZplus_le_mono_r : forall n m p : NZ, n <= m <-> n + p <= m + p.
+Proof.
+intros n m p.
+rewrite (NZplus_comm n p); rewrite (NZplus_comm m p); apply NZplus_le_mono_l.
+Qed.
+
+Theorem NZplus_le_mono : forall n m p q : NZ, n <= m -> p <= q -> n + p <= m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZle_trans with (m + p);
+[now apply -> NZplus_le_mono_r | now apply -> NZplus_le_mono_l].
+Qed.
+
+Theorem NZplus_lt_le_mono : forall n m p q : NZ, n < m -> p <= q -> n + p < m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZlt_le_trans with (m + p);
+[now apply -> NZplus_lt_mono_r | now apply -> NZplus_le_mono_l].
+Qed.
+
+Theorem NZplus_le_lt_mono : forall n m p q : NZ, n <= m -> p < q -> n + p < m + q.
+Proof.
+intros n m p q H1 H2.
+apply NZle_lt_trans with (m + p);
+[now apply -> NZplus_le_mono_r | now apply -> NZplus_lt_mono_l].
+Qed.
+
+Theorem NZplus_le_lt_mono_opp : forall n m p q : NZ, n <= m -> p + m < q + n -> p < q.
+Proof.
+intros n m p q H1 H2. destruct (NZle_lt_dec q p); [| assumption].
+pose proof (NZplus_le_mono q p n m H H1) as H3. apply <- NZnle_lt in H2.
+false_hyp H3 H2.
+Qed.
+
+Theorem NZplus_lt_inv : forall n m p q : NZ, n + m < p + q -> n < p \/ m < q.
+Proof.
+intros n m p q H;
+destruct (NZle_lt_dec p n) as [H1 | H1].
+destruct (NZle_lt_dec q m) as [H2 | H2].
+pose proof (NZplus_le_mono p n q m H1 H2) as H3. apply -> NZle_nlt in H3.
+false_hyp H H3.
+now right. now left.
+Qed.
+
+Theorem NZplus_lt_inv_0 : forall n m : NZ, n + m < 0 -> n < 0 \/ m < 0.
+Proof.
+intros n m H; apply NZplus_lt_inv; now rewrite NZplus_0_l.
+Qed.
+
+Theorem NZplus_gt_inv_0 : forall n m : NZ, 0 < n + m -> 0 < n \/ 0 < m.
+Proof.
+intros n m H; apply NZplus_lt_inv; now rewrite NZplus_0_l.
+Qed.
+
+(** Multiplication and order *)
+
+Theorem NZtimes_lt_pred :
+ forall p q n m : NZ, S p == q -> (p * n < p * m <-> q * n + m < q * m + n).
+Proof.
+intros p q n m H. rewrite <- H. do 2 rewrite NZtimes_succ_l.
+rewrite <- (NZplus_assoc (p * n) n m).
+rewrite <- (NZplus_assoc (p * m) m n).
+rewrite (NZplus_comm n m). now rewrite <- NZplus_lt_mono_r.
+Qed.
+
+Theorem NZtimes_lt_mono_pos_l : forall p n m : NZ, 0 < p -> (n < m <-> p * n < p * m).
+Proof.
+NZord_induct p.
+intros n m H; false_hyp H NZlt_irrefl.
+intros p H IH n m H1. do 2 rewrite NZtimes_succ_l.
+le_elim H. assert (LR : forall n m : NZ, n < m -> p * n + n < p * m + m).
+intros n1 m1 H2. apply NZplus_lt_mono; [now apply -> IH | assumption].
+split; [apply LR |]. intro H2. apply -> NZlt_dne; intro H3.
+apply <- NZle_nlt in H3. le_elim H3.
+apply NZlt_asymm in H2. apply H2. now apply LR.
+rewrite H3 in H2; false_hyp H2 NZlt_irrefl.
+rewrite <- H; do 2 rewrite NZtimes_0_l; now do 2 rewrite NZplus_0_l.
+intros p H1 _ n m H2. apply NZlt_asymm in H1. false_hyp H2 H1.
+Qed.
+
+Theorem NZtimes_lt_mono_pos_r : forall p n m : NZ, 0 < p -> (n < m <-> n * p < m * p).
+Proof.
+intros p n m.
+rewrite (NZtimes_comm n p); rewrite (NZtimes_comm m p). now apply NZtimes_lt_mono_pos_l.
+Qed.
+
+Theorem NZtimes_lt_mono_neg_l : forall p n m : NZ, p < 0 -> (n < m <-> p * m < p * n).
+Proof.
+NZord_induct p.
+intros n m H; false_hyp H NZlt_irrefl.
+intros p H1 _ n m H2. apply NZlt_succ_lt in H2. apply <- NZnle_lt in H2. false_hyp H1 H2.
+intros p H IH n m H1. apply -> NZlt_le_succ in H.
+le_elim H. assert (LR : forall n m : NZ, n < m -> p * m < p * n).
+intros n1 m1 H2. apply (NZplus_le_lt_mono_opp n1 m1).
+now le_less. do 2 rewrite <- NZtimes_succ_l. now apply -> IH.
+split; [apply LR |]. intro H2. apply -> NZlt_dne; intro H3.
+apply <- NZle_nlt in H3. le_elim H3.
+apply NZlt_asymm in H2. apply H2. now apply LR.
+rewrite H3 in H2; false_hyp H2 NZlt_irrefl.
+rewrite (NZtimes_lt_pred p (S p)); [reflexivity |].
+rewrite H; do 2 rewrite NZtimes_0_l; now do 2 rewrite NZplus_0_l.
+Qed.
+
+Theorem NZtimes_lt_mono_neg_r : forall p n m : NZ, p < 0 -> (n < m <-> m * p < n * p).
+Proof.
+intros p n m.
+rewrite (NZtimes_comm n p); rewrite (NZtimes_comm m p). now apply NZtimes_lt_mono_neg_l.
+Qed.
+
+Theorem NZtimes_le_mono_nonneg_l : forall n m p : NZ, 0 <= p -> n <= m -> p * n <= p * m.
+Proof.
+intros n m p H1 H2. le_elim H1.
+le_elim H2. le_less. now apply -> NZtimes_lt_mono_pos_l.
+le_equal; now rewrite H2.
+le_equal; rewrite <- H1; now do 2 rewrite NZtimes_0_l.
+Qed.
+
+Theorem NZtimes_le_mono_nonpos_l : forall n m p : NZ, p <= 0 -> n <= m -> p * m <= p * n.
+Proof.
+intros n m p H1 H2. le_elim H1.
+le_elim H2. le_less. now apply -> NZtimes_lt_mono_neg_l.
+le_equal; now rewrite H2.
+le_equal; rewrite H1; now do 2 rewrite NZtimes_0_l.
+Qed.
+
+Theorem NZtimes_le_mono_nonneg_r : forall n m p : NZ, 0 <= p -> n <= m -> n * p <= m * p.
+Proof.
+intros n m p H1 H2; rewrite (NZtimes_comm n p); rewrite (NZtimes_comm m p);
+now apply NZtimes_le_mono_nonneg_l.
+Qed.
+
+Theorem NZtimes_le_mono_nonpos_r : forall n m p : NZ, p <= 0 -> n <= m -> m * p <= n * p.
+Proof.
+intros n m p H1 H2; rewrite (NZtimes_comm n p); rewrite (NZtimes_comm m p);
+now apply NZtimes_le_mono_nonpos_l.
+Qed.
+
+Theorem NZtimes_cancel_l : forall n m p : NZ, p ~= 0 -> (p * n == p * m <-> n == m).
+Proof.
+intros n m p H; split; intro H1.
+destruct (NZlt_trichotomy p 0) as [H2 | [H2 | H2]].
+apply -> NZE_dne; intro H3. apply -> NZneq_lt_or_gt in H3. destruct H3 as [H3 | H3].
+assert (H4 : p * m < p * n); [now apply -> NZtimes_lt_mono_neg_l |].
+rewrite H1 in H4; false_hyp H4 NZlt_irrefl.
+assert (H4 : p * n < p * m); [now apply -> NZtimes_lt_mono_neg_l |].
+rewrite H1 in H4; false_hyp H4 NZlt_irrefl.
+false_hyp H2 H.
+apply -> NZE_dne; intro H3. apply -> NZneq_lt_or_gt in H3. destruct H3 as [H3 | H3].
+assert (H4 : p * n < p * m); [now apply -> NZtimes_lt_mono_pos_l |].
+rewrite H1 in H4; false_hyp H4 NZlt_irrefl.
+assert (H4 : p * m < p * n); [now apply -> NZtimes_lt_mono_pos_l |].
+rewrite H1 in H4; false_hyp H4 NZlt_irrefl.
+now rewrite H1.
+Qed.
+
+Theorem NZtimes_le_mono_pos_l : forall n m p : NZ, 0 < p -> (n <= m <-> p * n <= p * m).
+Proof.
+intros n m p H; do 2 rewrite NZle_lt_or_eq.
+rewrite (NZtimes_lt_mono_pos_l p n m); [assumption |].
+now rewrite -> (NZtimes_cancel_l n m p);
+[intro H1; rewrite H1 in H; false_hyp H NZlt_irrefl |].
+Qed.
+
+Theorem NZtimes_le_mono_pos_r : forall n m p : NZ, 0 < p -> (n <= m <-> n * p <= m * p).
+Proof.
+intros n m p. rewrite (NZtimes_comm n p); rewrite (NZtimes_comm m p);
+apply NZtimes_le_mono_pos_l.
+Qed.
+
+Theorem NZtimes_le_mono_neg_l : forall n m p : NZ, p < 0 -> (n <= m <-> p * m <= p * n).
+Proof.
+intros n m p H; do 2 rewrite NZle_lt_or_eq.
+rewrite (NZtimes_lt_mono_neg_l p n m); [assumption |].
+rewrite -> (NZtimes_cancel_l m n p);
+[intro H1; rewrite H1 in H; false_hyp H NZlt_irrefl |].
+now setoid_replace (n == m) with (m == n) using relation iff by (split; now intro).
+Qed.
+
+Theorem NZtimes_le_mono_neg_r : forall n m p : NZ, p < 0 -> (n <= m <-> m * p <= n * p).
+Proof.
+intros n m p. rewrite (NZtimes_comm n p); rewrite (NZtimes_comm m p);
+apply NZtimes_le_mono_neg_l.
+Qed.
+
+Theorem NZtimes_lt_mono :
+ forall n m p q : NZ, 0 <= n -> n < m -> 0 <= p -> p < q -> n * p < m * q.
+Proof.
+intros n m p q H1 H2 H3 H4.
+apply NZle_lt_trans with (m * p).
+apply NZtimes_le_mono_nonneg_r; [assumption | now le_less].
+apply -> NZtimes_lt_mono_pos_l; [assumption | now apply NZle_lt_trans with n].
+Qed.
+
+(* There are still many variants of the theorem above. One can assume 0 < n
+or 0 < p or n <= m or p <= q. *)
+
+Theorem NZtimes_le_mono :
+ forall n m p q : NZ, 0 <= n -> n <= m -> 0 <= p -> p <= q -> n * p <= m * q.
+Proof.
+intros n m p q H1 H2 H3 H4.
+le_elim H2; le_elim H4.
+le_less; now apply NZtimes_lt_mono.
+rewrite <- H4; apply NZtimes_le_mono_nonneg_r; [assumption | now le_less].
+rewrite <- H2; apply NZtimes_le_mono_nonneg_l; [assumption | now le_less].
+rewrite H2; rewrite H4; now le_equal.
+Qed.
+
+Theorem NZtimes_pos_pos : forall n m : NZ, 0 < n -> 0 < m -> 0 < n * m.
+Proof.
+intros n m H1 H2.
+rewrite <- (NZtimes_0_l m). now apply -> NZtimes_lt_mono_pos_r.
+Qed.
+
+Theorem NZtimes_nonneg_nonneg : forall n m : NZ, 0 <= n -> 0 <= m -> 0 <= n * m.
+Proof.
+intros n m H1 H2.
+rewrite <- (NZtimes_0_l m). now apply NZtimes_le_mono_nonneg_r.
+Qed.
+
+Theorem NZtimes_neg_neg : forall n m : NZ, n < 0 -> m < 0 -> 0 < n * m.
+Proof.
+intros n m H1 H2.
+rewrite <- (NZtimes_0_l m). now apply -> NZtimes_lt_mono_neg_r.
+Qed.
+
+Theorem NZtimes_nonpos_nonpos : forall n m : NZ, n <= 0 -> m <= 0 -> 0 <= n * m.
+Proof.
+intros n m H1 H2.
+rewrite <- (NZtimes_0_l m). now apply NZtimes_le_mono_nonpos_r.
+Qed.
+
+Theorem NZtimes_pos_neg : forall n m : NZ, 0 < n -> m < 0 -> n * m < 0.
+Proof.
+intros n m H1 H2.
+rewrite <- (NZtimes_0_l m). now apply -> NZtimes_lt_mono_neg_r.
+Qed.
+
+Theorem NZtimes_nonneg_nonpos : forall n m : NZ, 0 <= n -> m <= 0 -> n * m <= 0.
+Proof.
+intros n m H1 H2.
+rewrite <- (NZtimes_0_l m). now apply NZtimes_le_mono_nonpos_r.
+Qed.
+
+Theorem NZtimes_neg_pos : forall n m : NZ, n < 0 -> 0 < m -> n * m < 0.
+Proof.
+intros; rewrite NZtimes_comm; now apply NZtimes_pos_neg.
+Qed.
+
+Theorem NZtimes_nonpos_nonneg : forall n m : NZ, n <= 0 -> 0 <= m -> n * m <= 0.
+Proof.
+intros; rewrite NZtimes_comm; now apply NZtimes_nonneg_nonpos.
+Qed.
+
+Theorem NZtimes_eq_0 : forall n m : NZ, n * m == 0 -> n == 0 \/ m == 0.
+Proof.
+intros n m H; destruct (NZlt_trichotomy n 0) as [H1 | [H1 | H1]];
+destruct (NZlt_trichotomy m 0) as [H2 | [H2 | H2]];
+try (now right); try (now left).
+elimtype False; now apply (NZlt_neq 0 (n * m)); [apply NZtimes_neg_neg |].
+elimtype False; now apply (NZlt_neq (n * m) 0); [apply NZtimes_neg_pos |].
+elimtype False; now apply (NZlt_neq (n * m) 0); [apply NZtimes_pos_neg |].
+elimtype False; now apply (NZlt_neq 0 (n * m)); [apply NZtimes_pos_pos |].
+Qed.
+
+Theorem NZtimes_neq_0 : forall n m : NZ, n ~= 0 /\ m ~= 0 <-> n * m ~= 0.
+Proof.
+intros n m; split; intro H.
+intro H1; apply NZtimes_eq_0 in H1. tauto.
+split; intro H1; rewrite H1 in H;
+(rewrite NZtimes_0_l in H || rewrite NZtimes_0_r in H); now apply H.
+Qed.
+
+End NZTimesOrderPropFunct.
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Natural/Abstract/NBase.v b/theories/Numbers/Natural/Abstract/NBase.v
new file mode 100644
index 000000000..b8940027c
--- /dev/null
+++ b/theories/Numbers/Natural/Abstract/NBase.v
@@ -0,0 +1,214 @@
+Require Export NAxioms.
+Require Import NZTimesOrder. (* The last property functor on NZ, which subsumes all others *)
+
+Module NBasePropFunct (Import NAxiomsMod : NAxiomsSig).
+Open Local Scope NatScope.
+
+(* We call the last property functor on NZ, which includes all the previous
+ones, to get all properties of NZ at once. This way we will include them
+only one time. *)
+
+Module NZOrdAxiomsMod := NNZFunct NAxiomsMod.
+Module Export NZTimesOrderMod := NZTimesOrderPropFunct NZOrdAxiomsMod.
+
+(* Here we probably need to re-prove all axioms declared in NAxioms.v to
+make sure that the definitions like N, S and plus are unfolded in them,
+since unfolding is done only inside a functor. In fact, we'll do it in the
+files that prove the corresponding properties. In those files, we will also
+rename properties proved in NZ files by removing NZ from their names. In
+this way, one only has to consult, for example, NPlus.v to see all
+available properties for plus (i.e., one does not have to go to NAxioms.v
+and NZPlus.v). *)
+
+Theorem E_equiv : equiv N E.
+Proof E_equiv.
+
+Theorem induction :
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n : N, A n -> A (S n)) -> forall n : N, A n.
+Proof induction.
+
+Theorem pred_0 : P 0 == 0.
+Proof pred_0.
+
+Theorem pred_succ : forall n : N, P (S n) == n.
+Proof pred_succ.
+
+Theorem neq_symm : forall n m : N, n ~= m -> m ~= n.
+Proof NZneq_symm.
+
+Theorem succ_inj : forall n1 n2 : N, S n1 == S n2 -> n1 == n2.
+Proof NZsucc_inj.
+
+Theorem succ_inj_wd : forall n1 n2 : N, S n1 == S n2 <-> n1 == n2.
+Proof NZsucc_inj_wd.
+
+Theorem succ_inj_wd_neg : forall n m : N, S n ~= S m <-> n ~= m.
+Proof NZsucc_inj_wd_neg.
+
+(* The theorems NZinduction, NZcentral_induction and the tactic NZinduct
+refer to bidirectional induction, which is not so useful on natural
+numbers. Therefore, we define a new induction tactic for natural numbers.
+We do not have to call "Declare Left Step" and "Declare Right Step"
+commands again, since the data for stepl and stepr tactics is inherited
+from NZ. *)
+
+Tactic Notation "induct" ident(n) := induction_maker n ltac:(apply induction).
+(* FIXME: "Ltac induct n := induction_maker n ltac:(apply induction)" does not work (bug 1703) *)
+
+(* Now we add properties peculiar to natural numbers *)
+
+Theorem nondep_induction :
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n : N, A (S n)) -> forall n : N, A n.
+Proof.
+intros; apply induction; auto.
+Qed.
+
+Tactic Notation "nondep_induct" ident(n) :=
+ induction_maker n ltac:(apply nondep_induction).
+
+(* The fact "forall n : N, S n ~= 0" can be proved either by building a
+function (using recursion) that maps 0 ans S n to two provably different
+terms, or from the axioms of order *)
+
+Theorem neq_succ_0 : forall n : N, S n ~= 0.
+Proof.
+intros n H. apply nlt_0_r with n. rewrite <- H.
+apply <- lt_succ_le. apply <- le_lt_or_eq. now right.
+Qed.
+
+Theorem neq_0 : ~ forall n, n == 0.
+Proof.
+intro H; apply (neq_succ_0 0). apply H.
+Qed.
+
+Theorem neq_0_succ : forall n, n ~= 0 <-> exists m, n == S m.
+Proof.
+nondep_induct n. split; intro H;
+[now elim H | destruct H as [m H]; symmetry in H; false_hyp H neq_succ_0].
+intro n; split; intro H; [now exists n | apply neq_succ_0].
+Qed.
+
+Theorem zero_or_succ : forall n, n == 0 \/ exists m, n == S m.
+Proof.
+nondep_induct n; [now left | intros n; right; now exists n].
+Qed.
+
+Theorem eq_pred_0 : forall n : N, P n == 0 <-> n == 0 \/ n == 1.
+Proof.
+nondep_induct n.
+rewrite pred_0. setoid_replace (0 == 1) with False using relation iff. tauto.
+split; intro H; [symmetry in H; false_hyp H neq_succ_0 | elim H].
+intro n. rewrite pred_succ. rewrite_false (S n == 0) neq_succ_0.
+rewrite succ_inj_wd. tauto.
+Qed.
+
+Theorem succ_pred : forall n : N, n ~= 0 -> S (P n) == n.
+Proof.
+nondep_induct n.
+intro H; elimtype False; now apply H.
+intros; now rewrite pred_succ.
+Qed.
+
+Theorem pred_inj : forall n m : N, n ~= 0 -> m ~= 0 -> P n == P m -> n == m.
+Proof.
+intros n m; nondep_induct n.
+intros H; elimtype False; now apply H.
+intros n H1; nondep_induct m.
+intros H; elimtype False; now apply H.
+intros m H2 H3. do 2 rewrite pred_succ in H3. now apply succ_wd.
+Qed.
+
+(* The following induction principle is useful for reasoning about, e.g.,
+Fibonacci numbers *)
+
+Section PairInduction.
+
+Variable A : N -> Prop.
+Hypothesis A_wd : predicate_wd E A.
+
+Add Morphism A with signature E ==> iff as A_morph.
+Proof.
+exact A_wd.
+Qed.
+
+Theorem pair_induction :
+ A 0 -> A 1 ->
+ (forall n, A n -> A (S n) -> A (S (S n))) -> forall n, A n.
+Proof.
+intros until 3.
+assert (D : forall n, A n /\ A (S n)); [ |intro n; exact (proj1 (D n))].
+induct n; [ | intros n [IH1 IH2]]; auto.
+Qed.
+
+End PairInduction.
+
+Tactic Notation "pair_induct" ident(n) := induction_maker n ltac:(apply pair_induction).
+
+(* The following is useful for reasoning about, e.g., Ackermann function *)
+Section TwoDimensionalInduction.
+
+Variable R : N -> N -> Prop.
+Hypothesis R_wd : rel_wd E E R.
+
+Add Morphism R with signature E ==> E ==> iff as R_morph.
+Proof.
+exact R_wd.
+Qed.
+
+Theorem two_dim_induction :
+ R 0 0 ->
+ (forall n m, R n m -> R n (S m)) ->
+ (forall n, (forall m, R n m) -> R (S n) 0) -> forall n m, R n m.
+Proof.
+intros H1 H2 H3. induct n.
+induct m.
+exact H1. exact (H2 0).
+intros n IH. induct m.
+now apply H3. exact (H2 (S n)).
+Qed.
+
+End TwoDimensionalInduction.
+
+Tactic Notation "two_dim_induct" ident(n) ident(m) :=
+ try intros until n;
+ try intros until m;
+ pattern n, m; apply two_dim_induction; clear n m;
+ [solve_rel_wd | | | ].
+
+Section DoubleInduction.
+
+Variable R : N -> N -> Prop.
+Hypothesis R_wd : rel_wd E E R.
+
+Add Morphism R with signature E ==> E ==> iff as R_morph1.
+Proof.
+exact R_wd.
+Qed.
+
+Theorem double_induction :
+ (forall m : N, R 0 m) ->
+ (forall n : N, R (S n) 0) ->
+ (forall n m : N, R n m -> R (S n) (S m)) -> forall n m : N, R n m.
+Proof.
+intros H1 H2 H3; induct n; auto.
+intros n IH; nondep_induct m; auto.
+Qed.
+
+End DoubleInduction.
+
+Tactic Notation "double_induct" ident(n) ident(m) :=
+ try intros until n;
+ try intros until m;
+ pattern n, m; apply double_induction; clear n m;
+ [solve_rel_wd | | | ].
+
+End NBasePropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Natural/Axioms/NDepRec.v b/theories/Numbers/Natural/Abstract/NDepRec.v
index 9ad0b4650..9ad0b4650 100644
--- a/theories/Numbers/Natural/Axioms/NDepRec.v
+++ b/theories/Numbers/Natural/Abstract/NDepRec.v
diff --git a/theories/Numbers/Natural/Axioms/NDomain.v b/theories/Numbers/Natural/Abstract/NDomain.v
index a95c94ca0..a95c94ca0 100644
--- a/theories/Numbers/Natural/Axioms/NDomain.v
+++ b/theories/Numbers/Natural/Abstract/NDomain.v
diff --git a/theories/Numbers/Natural/Axioms/NIso.v b/theories/Numbers/Natural/Abstract/NIso.v
index 9ee79022e..9ee79022e 100644
--- a/theories/Numbers/Natural/Axioms/NIso.v
+++ b/theories/Numbers/Natural/Abstract/NIso.v
diff --git a/theories/Numbers/Natural/Abstract/NMinus.v b/theories/Numbers/Natural/Abstract/NMinus.v
new file mode 100644
index 000000000..0af5c22fd
--- /dev/null
+++ b/theories/Numbers/Natural/Abstract/NMinus.v
@@ -0,0 +1,164 @@
+Require Export NTimesOrder.
+
+Module NMinusPropFunct (Import NAxiomsMod : NAxiomsSig).
+Module Export NTimesOrderPropMod := NTimesOrderPropFunct NAxiomsMod.
+Open Local Scope NatScope.
+
+Theorem minus_0_r : forall n : N, n - 0 == n.
+Proof minus_0_r.
+
+Theorem minus_succ_r : forall n m : N, n - (S m) == P (n - m).
+Proof minus_succ_r.
+
+Theorem minus_1_r : forall n : N, n - 1 == P n.
+Proof.
+intro n; rewrite minus_succ_r; now rewrite minus_0_r.
+Qed.
+
+Theorem minus_0_l : forall n : N, 0 - n == 0.
+Proof.
+induct n.
+apply minus_0_r.
+intros n IH; rewrite minus_succ_r; rewrite IH. now apply pred_0.
+Qed.
+
+Theorem minus_succ : forall n m : N, S n - S m == n - m.
+Proof.
+intro n; induct m.
+rewrite minus_succ_r. do 2 rewrite minus_0_r. now rewrite pred_succ.
+intros m IH. rewrite minus_succ_r. rewrite IH. now rewrite minus_succ_r.
+Qed.
+
+Theorem minus_diag : forall n : N, n - n == 0.
+Proof.
+induct n. apply minus_0_r. intros n IH; rewrite minus_succ; now rewrite IH.
+Qed.
+
+Theorem minus_gt : forall n m : N, n > m -> n - m ~= 0.
+Proof.
+intros n m H; elim H using lt_ind_rel; clear n m H.
+solve_rel_wd.
+intro; rewrite minus_0_r; apply neq_succ_0.
+intros; now rewrite minus_succ.
+Qed.
+
+Theorem plus_minus_assoc : forall n m p : N, p <= m -> n + (m - p) == (n + m) - p.
+Proof.
+intros n m p; induct p.
+intro; now do 2 rewrite minus_0_r.
+intros p IH H. do 2 rewrite minus_succ_r.
+rewrite <- IH; [now apply le_succ_le |].
+rewrite plus_pred_r. apply minus_gt. now apply <- lt_le_succ.
+reflexivity.
+Qed.
+
+Theorem minus_succ_l : forall n m : N, n <= m -> S m - n == S (m - n).
+Proof.
+intros n m H. rewrite <- (plus_1_l m). rewrite <- (plus_1_l (m - n)).
+symmetry; now apply plus_minus_assoc.
+Qed.
+
+Theorem plus_minus : forall n m : N, (n + m) - m == n.
+Proof.
+intros n m. rewrite <- plus_minus_assoc. apply le_refl.
+rewrite minus_diag; now rewrite plus_0_r.
+Qed.
+
+Theorem minus_plus : forall n m : N, n <= m -> (m - n) + n == m.
+Proof.
+intros n m H. rewrite plus_comm. rewrite plus_minus_assoc; [assumption |].
+rewrite plus_comm. apply plus_minus.
+Qed.
+
+Theorem plus_minus_eq : forall n m p : N, m + p == n -> n - m == p.
+Proof.
+intros n m p H. symmetry.
+assert (H1 : m + p - m == n - m). now rewrite H.
+rewrite plus_comm in H1. now rewrite plus_minus in H1.
+Qed.
+
+(* This could be proved by adding m to both sides. Then the proof would
+use plus_minus_assoc and le_minus_0, which is proven below. *)
+Theorem plus_minus_eq_nz : forall n m p : N, p ~= 0 -> n - m == p -> m + p == n.
+Proof.
+intros n m p H; double_induct n m.
+intros m H1; rewrite minus_0_l in H1. symmetry in H1; false_hyp H1 H.
+intro n; rewrite minus_0_r; now rewrite plus_0_l.
+intros n m IH H1. rewrite minus_succ in H1. apply IH in H1.
+rewrite plus_succ_l; now apply succ_wd.
+Qed.
+
+Theorem minus_plus_distr : forall n m p : N, n - (m + p) == (n - m) - p.
+Proof.
+intros n m; induct p.
+rewrite plus_0_r; now rewrite minus_0_r.
+intros p IH. rewrite plus_succ_r; do 2 rewrite minus_succ_r. now rewrite IH.
+Qed.
+
+Theorem plus_minus_swap : forall n m p : N, p <= n -> n + m - p == n - p + m.
+Proof.
+intros n m p H.
+rewrite (plus_comm n m).
+rewrite <- plus_minus_assoc; [assumption |].
+now rewrite (plus_comm m (n - p)).
+Qed.
+
+(** Minus and order *)
+
+Theorem le_minus_l : forall n m : N, n - m <= n.
+Proof.
+intro n; induct m.
+rewrite minus_0_r; le_equal.
+intros m IH. rewrite minus_succ_r.
+apply le_trans with (n - m); [apply le_pred_l | assumption].
+Qed.
+
+Theorem le_minus_0 : forall n m : N, n <= m <-> n - m == 0.
+Proof.
+double_induct n m.
+intro m; split; intro; [apply minus_0_l | apply le_0_l].
+intro m; rewrite minus_0_r; split; intro H;
+[false_hyp H nle_succ_0 | false_hyp H neq_succ_0].
+intros n m H. rewrite <- succ_le_mono. now rewrite minus_succ.
+Qed.
+
+(** Minus and times *)
+
+Theorem times_pred_r : forall n m : N, n * (P m) == n * m - n.
+Proof.
+intro n; nondep_induct m.
+now rewrite pred_0, times_0_r, minus_0_l.
+intro m; rewrite pred_succ, times_succ_r, <- plus_minus_assoc.
+le_equal.
+now rewrite minus_diag, plus_0_r.
+Qed.
+
+Theorem times_minus_distr_r : forall n m p : N, (n - m) * p == n * p - m * p.
+Proof.
+intros n m p; induct n.
+now rewrite minus_0_l, times_0_l, minus_0_l.
+intros n IH. destruct (le_lt_dec m n) as [H | H].
+rewrite minus_succ_l; [assumption |]. do 2 rewrite times_succ_l.
+rewrite (plus_comm ((n - m) * p) p), (plus_comm (n * p) p).
+rewrite <- (plus_minus_assoc p (n * p) (m * p)); [now apply times_le_mono_r |].
+now apply <- plus_cancel_l.
+assert (H1 : S n <= m); [now apply -> lt_le_succ |].
+setoid_replace (S n - m) with 0 by now apply -> le_minus_0.
+setoid_replace ((S n * p) - m * p) with 0 by (apply -> le_minus_0; now apply times_le_mono_r).
+apply times_0_l.
+Qed.
+
+Theorem times_minus_distr_l : forall n m p : N, p * (n - m) == p * n - p * m.
+Proof.
+intros n m p; rewrite (times_comm p (n - m)), (times_comm p n), (times_comm p m).
+apply times_minus_distr_r.
+Qed.
+
+End NMinusPropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Natural/Axioms/NMiscFunct.v b/theories/Numbers/Natural/Abstract/NMiscFunct.v
index 82a922453..82a922453 100644
--- a/theories/Numbers/Natural/Axioms/NMiscFunct.v
+++ b/theories/Numbers/Natural/Abstract/NMiscFunct.v
diff --git a/theories/Numbers/Natural/Axioms/NOrder.v b/theories/Numbers/Natural/Abstract/NOrder.v
index b4f363901..773f5d97e 100644
--- a/theories/Numbers/Natural/Axioms/NOrder.v
+++ b/theories/Numbers/Natural/Abstract/NOrder.v
@@ -1,76 +1,26 @@
-Require Export NBase.
-Require Import NZOrder.
+Require Export NTimes.
-Module Type NOrderSig.
-Declare Module Export NBaseMod : NBaseSig.
+Module NOrderPropFunct (Import NAxiomsMod : NAxiomsSig).
+Module Export NTimesPropMod := NTimesPropFunct NAxiomsMod.
Open Local Scope NatScope.
-Parameter Inline lt : N -> N -> Prop.
-Parameter Inline le : N -> N -> Prop.
+(* The tactics le_less, le_equal and le_elim are inherited from NZOrder.v *)
-Notation "x < y" := (lt x y) : NatScope.
-Notation "x <= y" := (le x y) : NatScope.
-Notation "x > y" := (lt y x) (only parsing) : NatScope.
-Notation "x >= y" := (le y x) (only parsing) : NatScope.
+(* Axioms *)
-Add Morphism lt with signature E ==> E ==> iff as lt_wd.
-Add Morphism le with signature E ==> E ==> iff as le_wd.
+Theorem le_lt_or_eq : forall x y, x <= y <-> x < y \/ x == y.
+Proof le_lt_or_eq.
-Axiom le_lt_or_eq : forall x y, x <= y <-> x < y \/ x == y.
-Axiom nlt_0_r : forall x, ~ (x < 0).
-Axiom lt_succ_le : forall x y, x < S y <-> x <= y.
+Theorem nlt_0_r : forall x, ~ (x < 0).
+Proof nlt_0_r.
-End NOrderSig.
+Theorem lt_succ_le : forall x y, x < S y <-> x <= y.
+Proof lt_succ_le.
-Module NOrderPropFunct (Import NOrderModule : NOrderSig).
-Module Export NBasePropMod := NBasePropFunct NBaseMod.
-Open Local Scope NatScope.
-
-Ltac le_intro1 := rewrite le_lt_or_eq; left.
-Ltac le_intro2 := rewrite le_lt_or_eq; right.
-Ltac le_elim H := rewrite le_lt_or_eq in H; destruct H as [H | H].
-
-Theorem lt_succ_lt : forall n m : N, S n < m -> n < m.
-Proof.
-intro n; induct m.
-intro H; false_hyp H nlt_0_r.
-intros m IH H. apply <- lt_succ_le. apply -> lt_succ_le in H. le_elim H.
-le_intro1; now apply IH.
-rewrite <- H; le_intro1. apply <- lt_succ_le; now le_intro2.
-Qed.
+(* Renaming theorems from NZOrder.v *)
Theorem lt_irrefl : forall n : N, ~ (n < n).
-Proof.
-induct n.
-apply nlt_0_r.
-intros n IH H. apply -> lt_succ_le in H; le_elim H.
-apply lt_succ_lt in H; now apply IH.
-assert (n < S n) by (apply <- lt_succ_le; now le_intro2).
-rewrite H in *; now apply IH.
-Qed.
-
-Module NZOrderMod <: NZOrderSig.
-Module NZBaseMod := NZBaseMod.
-
-Definition NZlt := lt.
-Definition NZle := le.
-
-Add Morphism NZlt with signature E ==> E ==> iff as NZlt_wd.
-Proof lt_wd.
-
-Add Morphism NZle with signature E ==> E ==> iff as NZle_wd.
-Proof le_wd.
-
-Definition NZle_lt_or_eq := le_lt_or_eq.
-Definition NZlt_succ_le := lt_succ_le.
-Definition NZlt_succ_lt := lt_succ_lt.
-Definition NZlt_irrefl := lt_irrefl.
-
-End NZOrderMod.
-
-Module Export NZOrderPropMod := NZOrderPropFunct NZOrderMod.
-
-(* Renaming theorems from NZOrder.v *)
+Proof NZOrdAxiomsMod.NZlt_irrefl.
Theorem lt_le_incl : forall n m : N, n < m -> n <= m.
Proof NZlt_le_incl.
@@ -108,6 +58,9 @@ Proof NZnle_succ_l.
Theorem lt_le_succ : forall n m : N, n < m <-> S n <= m.
Proof NZlt_le_succ.
+Theorem lt_succ_lt : forall n m : N, S n < m -> n < m.
+Proof NZlt_succ_lt.
+
Theorem le_succ_le : forall n m : N, S n <= m -> n <= m.
Proof NZle_succ_le.
@@ -196,13 +149,13 @@ Theorem left_induction :
forall n : N, n <= z -> A n.
Proof NZleft_induction.
-Theorem central_induction :
+Theorem order_induction :
forall A : N -> Prop, predicate_wd E A ->
forall z : N, A z ->
(forall n : N, z <= n -> A n -> A (S n)) ->
(forall n : N, n < z -> A (S n) -> A n) ->
forall n : N, A n.
-Proof NZcentral_induction.
+Proof NZorder_induction.
Theorem right_induction' :
forall A : N -> Prop, predicate_wd E A ->
@@ -245,7 +198,7 @@ Proof NZle_ind.
Theorem le_0_l : forall n : N, 0 <= n.
Proof.
induct n.
-now le_intro2.
+now le_equal.
intros; now apply le_le_succ.
Qed.
@@ -254,9 +207,11 @@ Proof.
intros n H; apply <- lt_le_succ in H; false_hyp H nlt_0_r.
Qed.
-Theorem le_0_eq_0 : forall n, n <= 0 -> n == 0.
+Theorem le_0_eq_0 : forall n, n <= 0 <-> n == 0.
Proof.
-intros n H; le_elim H; [false_hyp H nlt_0_r | assumption].
+intros n; split; intro H.
+le_elim H; [false_hyp H nlt_0_r | assumption].
+le_equal.
Qed.
Theorem lt_0_succ : forall n, 0 < S n.
@@ -271,9 +226,11 @@ trivial.
intros n IH H. apply IH; now apply lt_succ_lt.
Qed.
-Theorem neq_0_lt_0 : forall n, 0 ~= n -> 0 < n.
+Theorem neq_0_lt_0 : forall n, n ~= 0 <-> 0 < n.
Proof.
-nondep_induct n. intro H; now elim H. intros; apply lt_0_succ.
+nondep_induct n.
+split; intro H; [now elim H | intro; now apply lt_irrefl with 0].
+intro n; split; intro H; [apply lt_0_succ | apply neq_succ_0].
Qed.
Lemma Acc_nonneg_lt : forall n : N,
@@ -309,7 +266,7 @@ intros Base Step; induct n.
intros; apply Base.
intros n IH m H. elim H using le_ind.
solve_predicate_wd.
-apply Step; [| apply IH]; now le_intro2.
+apply Step; [| apply IH]; now le_equal.
intros k H1 H2. apply le_succ_le in H1. auto.
Qed.
@@ -329,6 +286,103 @@ Qed.
End RelElim.
+(** Predecessor and order *)
+
+Theorem succ_pred_pos : forall n : N, 0 < n -> S (P n) == n.
+Proof.
+intros n H; apply succ_pred; intro H1; rewrite H1 in H.
+false_hyp H lt_irrefl.
+Qed.
+
+Theorem le_pred_l : forall n : N, P n <= n.
+Proof.
+nondep_induct n.
+rewrite pred_0; le_equal.
+intros; rewrite pred_succ; apply le_succ_r.
+Qed.
+
+Theorem lt_pred_l : forall n : N, n ~= 0 -> P n < n.
+Proof.
+nondep_induct n.
+intro H; elimtype False; now apply H.
+intros; rewrite pred_succ; apply lt_succ_r.
+Qed.
+
+Theorem le_le_pred : forall n m : N, n <= m -> P n <= m.
+Proof.
+intros n m H; apply le_trans with n. apply le_pred_l. assumption.
+Qed.
+
+Theorem lt_lt_pred : forall n m : N, n < m -> P n < m.
+Proof.
+intros n m H; apply le_lt_trans with n. apply le_pred_l. assumption.
+Qed.
+
+Theorem lt_le_pred : forall n m : N, n < m -> n <= P m. (* Converse is false for n == m == 0 *)
+Proof.
+intro n; nondep_induct m.
+intro H; false_hyp H nlt_0_r.
+intros m IH. rewrite pred_succ; now apply -> lt_succ_le.
+Qed.
+
+Theorem lt_pred_le : forall n m : N, P n < m -> n <= m. (* Converse is false for n == m == 0 *)
+Proof.
+intros n m; nondep_induct n.
+rewrite pred_0; intro H; le_less.
+intros n IH. rewrite pred_succ in IH. now apply -> lt_le_succ.
+Qed.
+
+Theorem lt_pred_lt : forall n m : N, n < P m -> n < m.
+Proof.
+intros n m H; apply lt_le_trans with (P m); [assumption | apply le_pred_l].
+Qed.
+
+Theorem le_pred_le : forall n m : N, n <= P m -> n <= m.
+Proof.
+intros n m H; apply le_trans with (P m); [assumption | apply le_pred_l].
+Qed.
+
+Theorem pred_le_mono : forall n m : N, n <= m -> P n <= P m. (* Converse is false for n == 1, m == 0 *)
+Proof.
+intros n m H; elim H using le_ind_rel.
+solve_rel_wd.
+intro; rewrite pred_0; apply le_0_l.
+intros p q H1 _; now do 2 rewrite pred_succ.
+Qed.
+
+Theorem pred_lt_mono : forall n m : N, n ~= 0 -> (n < m <-> P n < P m).
+Proof.
+intros n m H1; split; intro H2.
+assert (m ~= 0). apply <- neq_0_lt_0. now apply lt_lt_0 with n.
+now rewrite <- (succ_pred n) in H2; rewrite <- (succ_pred m) in H2;
+[apply <- succ_lt_mono | | |].
+assert (m ~= 0). apply <- neq_0_lt_0. apply lt_lt_0 with (P n).
+apply lt_le_trans with (P m). assumption. apply le_pred_l.
+apply -> succ_lt_mono in H2. now do 2 rewrite succ_pred in H2.
+Qed.
+
+Theorem lt_succ_lt_pred : forall n m : N, S n < m <-> n < P m.
+Proof.
+intros n m. rewrite pred_lt_mono. apply neq_succ_0. now rewrite pred_succ.
+Qed.
+
+Theorem le_succ_le_pred : forall n m : N, S n <= m -> n <= P m. (* Converse is false for n == m == 0 *)
+Proof.
+intros n m H. apply lt_le_pred. now apply <- lt_le_succ.
+Qed.
+
+Theorem lt_pred_lt_succ : forall n m : N, P n < m -> n < S m. (* Converse is false for n == m == 0 *)
+Proof.
+intros n m H. apply <- lt_succ_le. now apply lt_pred_le.
+Qed.
+
+Theorem le_pred_le_succ : forall n m : N, P n <= m <-> n <= S m.
+Proof.
+intros n m; nondep_induct n.
+rewrite pred_0. split; intro H; apply le_0_l.
+intro n. rewrite pred_succ. apply succ_le_mono.
+Qed.
+
End NOrderPropFunct.
diff --git a/theories/Numbers/Natural/Axioms/NOtherInd.v b/theories/Numbers/Natural/Abstract/NOtherInd.v
index 9b01e5143..9b01e5143 100644
--- a/theories/Numbers/Natural/Axioms/NOtherInd.v
+++ b/theories/Numbers/Natural/Abstract/NOtherInd.v
diff --git a/theories/Numbers/Natural/Axioms/NPlus.v b/theories/Numbers/Natural/Abstract/NPlus.v
index 5f5a88bca..67a2766ba 100644
--- a/theories/Numbers/Natural/Axioms/NPlus.v
+++ b/theories/Numbers/Natural/Abstract/NPlus.v
@@ -1,50 +1,14 @@
-Require Import NZPlus.
Require Export NBase.
-Module Type NPlusSig.
-
-Declare Module Export NBaseMod : NBaseSig.
+Module NPlusPropFunct (Import NAxiomsMod : NAxiomsSig).
+Module Export NBasePropMod := NBasePropFunct NAxiomsMod.
Open Local Scope NatScope.
-Parameter Inline plus : N -> N -> N.
-
-Notation "x + y" := (plus x y) : NatScope.
-
-Add Morphism plus with signature E ==> E ==> E as plus_wd.
-
-Axiom plus_0_l : forall n : N, 0 + n == n.
-Axiom plus_succ_l : forall n m : N, (S n) + m == S (n + m).
-
-End NPlusSig.
-
-Module NPlusPropFunct (Import NPlusMod : NPlusSig).
-Module Export NBasePropMod := NBasePropFunct NBaseMod.
-Open Local Scope NatScope.
-
-(*Theorem plus_wd : fun2_wd E E E plus.
-Proof plus_wd.
-
Theorem plus_0_l : forall n : N, 0 + n == n.
Proof plus_0_l.
Theorem plus_succ_l : forall n m : N, (S n) + m == S (n + m).
-Proof plus_succ_l.*)
-
-Module NZPlusMod <: NZPlusSig.
-
-Module NZBaseMod <: NZBaseSig := NZBaseMod.
-
-Definition NZplus := plus.
-
-(* Axioms*)
-Add Morphism NZplus with signature E ==> E ==> E as NZplus_wd.
-Proof plus_wd.
-Definition NZplus_0_l := plus_0_l.
-Definition NZplus_succ_l := plus_succ_l.
-
-End NZPlusMod.
-
-Module Export NZPlusPropMod := NZPlusPropFunct NZPlusMod.
+Proof plus_succ_l.
(** Theorems that are valid for both natural numbers and integers *)
@@ -86,8 +50,8 @@ intros n m; induct n.
(* The next command does not work with the axiom plus_0_l from NPlusSig *)
rewrite plus_0_l. intuition reflexivity.
intros n IH. rewrite plus_succ_l.
-rewrite_false (S (n + m) == 0) succ_neq_0.
-rewrite_false (S n == 0) succ_neq_0. tauto.
+rewrite_false (S (n + m) == 0) neq_succ_0.
+rewrite_false (S n == 0) neq_succ_0. tauto.
Qed.
Theorem plus_eq_succ :
@@ -98,7 +62,7 @@ intros n m; nondep_induct n.
split; intro H.
destruct H as [p H]. rewrite plus_0_l in H; right; now exists p.
destruct H as [[n' H] | [m' H]].
-symmetry in H; false_hyp H succ_neq_0.
+symmetry in H; false_hyp H neq_succ_0.
exists m'; now rewrite plus_0_l.
intro n; split; intro H.
left; now exists n.
@@ -120,11 +84,24 @@ Qed.
Theorem succ_plus_discr : forall n m : N, m ~= S (n + m).
Proof.
intro n; induct m.
-apply neq_symm. apply succ_neq_0.
+apply neq_symm. apply neq_succ_0.
intros m IH H. apply succ_inj in H. rewrite plus_succ_r in H.
unfold not in IH; now apply IH.
Qed.
+Theorem plus_pred_l : forall n m : N, n ~= 0 -> P n + m == P (n + m).
+Proof.
+intros n m; nondep_induct n.
+intro H; now elim H.
+intros n IH; rewrite plus_succ_l; now do 2 rewrite pred_succ.
+Qed.
+
+Theorem plus_pred_r : forall n m : N, m ~= 0 -> n + P m == P (n + m).
+Proof.
+intros n m H; rewrite (plus_comm n (P m));
+rewrite (plus_comm n m); now apply plus_pred_l.
+Qed.
+
(* One could define n <= m as exists p : N, p + n == m. Then we have
dichotomy:
diff --git a/theories/Numbers/Natural/Axioms/NPlusOrder.v b/theories/Numbers/Natural/Abstract/NPlusOrder.v
index c3e8cb663..df4c94614 100644
--- a/theories/Numbers/Natural/Axioms/NPlusOrder.v
+++ b/theories/Numbers/Natural/Abstract/NPlusOrder.v
@@ -4,7 +4,7 @@ Require Import NZPlusOrder.
Module NPlusOrderPropFunct
(Import NPlusMod : NPlusSig)
- (Import NOrderMod : NOrderSig with Module NBaseMod := NPlusMod.NBaseMod).
+ (Import NOrderMod : NOrderSig with Module NAxiomsMod := NPlusMod.NAxiomsMod).
Module Export NPlusPropMod := NPlusPropFunct NPlusMod.
Module Export NOrderPropMod := NOrderPropFunct NOrderMod.
Module Export NZPlusOrderPropMod := NZPlusOrderPropFunct NZPlusMod NZOrderMod.
diff --git a/theories/Numbers/Natural/Axioms/NPred.v b/theories/Numbers/Natural/Abstract/NPred.v
index 711d6b883..711d6b883 100644
--- a/theories/Numbers/Natural/Axioms/NPred.v
+++ b/theories/Numbers/Natural/Abstract/NPred.v
diff --git a/theories/Numbers/Natural/Axioms/NStrongRec.v b/theories/Numbers/Natural/Abstract/NStrongRec.v
index c35a6693b..c35a6693b 100644
--- a/theories/Numbers/Natural/Axioms/NStrongRec.v
+++ b/theories/Numbers/Natural/Abstract/NStrongRec.v
diff --git a/theories/Numbers/Natural/Axioms/NTimes.v b/theories/Numbers/Natural/Abstract/NTimes.v
index 94bd8d26e..7d42a812c 100644
--- a/theories/Numbers/Natural/Axioms/NTimes.v
+++ b/theories/Numbers/Natural/Abstract/NTimes.v
@@ -2,63 +2,16 @@ Require Export Ring.
(* Since we define a ring below, it should be possible to call the tactic
ring in the modules that use this module. Hence Export, not Import. *)
Require Export NPlus.
-Require Import NZTimes.
-Module Type NTimesSig.
-Declare Module Export NPlusMod : NPlusSig.
+Module NTimesPropFunct (Import NAxiomsMod : NAxiomsSig).
+Module Export NPlusPropMod := NPlusPropFunct NAxiomsMod.
Open Local Scope NatScope.
-Parameter Inline times : N -> N -> N.
-
-Notation "x * y" := (times x y) : NatScope.
-
-Add Morphism times with signature E ==> E ==> E as times_wd.
-
-Axiom times_0_r : forall n, n * 0 == 0.
-Axiom times_succ_r : forall n m, n * (S m) == n * m + n.
-
-(* Here recursion is done on the second argument to conform to the
-usual definition of ordinal multiplication in set theory, which is not
-commutative. It seems, however, that this definition in set theory is
-unfortunate for two reasons. First, multiplication A * B of two ordinals A
-and B can be defined as (an order type of) the cartesian product B x A
-(not A x B) ordered lexicographically. For example, omega * 2 =
-2 x omega = {(0,0) < (0,1) < (0,2) < ... < (1,0) < (1,1) < (1,2) < ...},
-while 2 * omega = omega x 2 = {(0,0) < (0,1) < (1,0) < (1,1) < (2,0) <
-(2,1) < ...} = omega. Secondly, the way the product 2 * 3 is said in
-French (deux fois trois) and Russian (dvazhdy tri) implies 3 + 3, not
-2 + 2 + 2. So it would possibly be more reasonable to define multiplication
-(here as well as in set theory) by recursion on the first argument. *)
-
-End NTimesSig.
-
-Module NTimesPropFunct (Import NTimesMod : NTimesSig).
-Module Export NPlusPropMod := NPlusPropFunct NPlusMod.
-Open Local Scope NatScope.
-
-(*Theorem times_wd : fun2_wd E E E times.
-Proof times_wd.
-
Theorem times_0_r : forall n, n * 0 == 0.
Proof times_0_r.
Theorem times_succ_r : forall n m, n * (S m) == n * m + n.
-Proof times_succ_r.*)
-
-Module NZTimesMod <: NZTimesSig.
-Module NZPlusMod <: NZPlusSig := NZPlusMod.
-Definition NZtimes := times.
-
-(* Axioms *)
-
-Add Morphism NZtimes with signature E ==> E ==> E as NZtimes_wd.
-Proof times_wd.
-Definition NZtimes_0_r := times_0_r.
-Definition NZtimes_succ_r := times_succ_r.
-
-End NZTimesMod.
-
-Module Export NZTimesPropMod := NZTimesPropFunct NZTimesMod.
+Proof times_succ_r.
(** Theorems that are valid for both natural numbers and integers *)
@@ -110,19 +63,19 @@ intros; now left.
intros; now left.
intros; now right.
intros m IH H1. rewrite times_succ_l in H1.
-rewrite plus_succ_r in H1. now apply succ_neq_0 in H1.
+rewrite plus_succ_r in H1. now apply neq_succ_0 in H1.
Qed.
Theorem times_eq_1 : forall n m, n * m == 1 -> n == 1 /\ m == 1.
Proof.
intros n m; induct n.
-intro H; rewrite times_0_l in H; symmetry in H; false_hyp H succ_neq_0.
+intro H; rewrite times_0_l in H; symmetry in H; false_hyp H neq_succ_0.
intros n IH H. rewrite times_succ_l in H. apply plus_eq_1 in H.
destruct H as [[H1 H2] | [H1 H2]].
-apply IH in H1. destruct H1 as [_ H1]. rewrite H1 in H2; false_hyp H2 succ_neq_0.
+apply IH in H1. destruct H1 as [_ H1]. rewrite H1 in H2; false_hyp H2 neq_succ_0.
apply times_eq_0 in H1. destruct H1 as [H1 | H1].
rewrite H1; now split.
-rewrite H2 in H1; false_hyp H1 succ_neq_0.
+rewrite H2 in H1; false_hyp H1 neq_succ_0.
Qed.
(* In proving the correctness of the definition of multiplication on
@@ -144,7 +97,7 @@ Theorem plus_times_repl_pair : forall a n m n' m' u v,
a * n + u == a * m + v -> n + m' == n' + m -> a * n' + u == a * m' + v.
Proof.
intros a n m n' m' u v H1 H2.
-apply (times_wd a a) in H2; [| reflexivity].
+apply (@times_wd a a) in H2; [| reflexivity].
do 2 rewrite times_plus_distr_l in H2.
symmetry in H2; add_equations H1 H2 as H3.
stepl (a * n + (u + a * n' + a * m)) in H3 by ring.
diff --git a/theories/Numbers/Natural/Abstract/NTimesOrder.v b/theories/Numbers/Natural/Abstract/NTimesOrder.v
new file mode 100644
index 000000000..19b9e0ae4
--- /dev/null
+++ b/theories/Numbers/Natural/Abstract/NTimesOrder.v
@@ -0,0 +1,133 @@
+Require Export NOrder.
+
+Module NTimesOrderPropFunct (Import NAxiomsMod : NAxiomsSig).
+Module Export NOrderPropMod := NOrderPropFunct NAxiomsMod.
+Open Local Scope NatScope.
+
+Theorem plus_lt_mono_l : forall n m p : N, n < m <-> p + n < p + m.
+Proof NZplus_lt_mono_l.
+
+Theorem plus_lt_mono_r : forall n m p : N, n < m <-> n + p < m + p.
+Proof NZplus_lt_mono_r.
+
+Theorem plus_lt_mono : forall n m p q : N, n < m -> p < q -> n + p < m + q.
+Proof NZplus_lt_mono.
+
+Theorem plus_le_mono_l : forall n m p : N, n <= m <-> p + n <= p + m.
+Proof NZplus_le_mono_l.
+
+Theorem plus_le_mono_r : forall n m p : N, n <= m <-> n + p <= m + p.
+Proof NZplus_le_mono_r.
+
+Theorem plus_le_mono : forall n m p q : N, n <= m -> p <= q -> n + p <= m + q.
+Proof NZplus_le_mono.
+
+Theorem plus_lt_le_mono : forall n m p q : N, n < m -> p <= q -> n + p < m + q.
+Proof NZplus_lt_le_mono.
+
+Theorem plus_le_lt_mono : forall n m p q : N, n <= m -> p < q -> n + p < m + q.
+Proof NZplus_le_lt_mono.
+
+Theorem plus_le_lt_mono_opp : forall n m p q : N, n <= m -> p + m < q + n -> p < q.
+Proof NZplus_le_lt_mono_opp.
+
+Theorem plus_lt_inv : forall n m p q : N, n + m < p + q -> n < p \/ m < q.
+Proof NZplus_lt_inv.
+
+Theorem plus_gt_inv_0 : forall n m : N, 0 < n + m -> 0 < n \/ 0 < m.
+Proof NZplus_gt_inv_0.
+
+(** Theorems true for natural numbers *)
+
+Theorem le_plus_r : forall n m : N, n <= n + m.
+Proof.
+intro n; induct m.
+rewrite plus_0_r; le_equal.
+intros m IH. rewrite plus_succ_r; now apply le_le_succ.
+Qed.
+
+Theorem lt_plus_r : forall n m : N, m ~= 0 -> n < n + m.
+Proof.
+intro n; nondep_induct m.
+intro H; elimtype False; now apply H.
+intros. rewrite plus_succ_r. apply <- lt_succ_le. apply le_plus_r.
+Qed.
+
+Theorem lt_lt_plus : forall n m p : N, n < m -> n < m + p.
+Proof.
+intros n m p H; rewrite <- (plus_0_r n).
+apply plus_lt_le_mono; [assumption | apply le_0_l].
+Qed.
+
+(* The following property is similar to plus_repl_pair in NPlus.v
+and is used to prove the correctness of the definition of order
+on integers constructed from pairs of natural numbers *)
+
+Theorem plus_lt_repl_pair : forall n m n' m' u v,
+ n + u < m + v -> n + m' == n' + m -> n' + u < m' + v.
+Proof.
+intros n m n' m' u v H1 H2.
+symmetry in H2. assert (H3 : n' + m <= n + m'); [now le_equal |].
+assert (H4 : n + u + (n' + m) < m + v + (n + m')); [now apply plus_lt_le_mono |].
+stepl (n + (m + (n' + u))) in H4 by ring. stepr (n + (m + (m' + v))) in H4 by ring.
+now do 2 apply <- plus_lt_mono_l in H4.
+Qed.
+
+(** Multiplication and order *)
+
+Theorem times_lt_pred :
+ forall p q n m : N, S p == q -> (p * n < p * m <-> q * n + m < q * m + n).
+Proof NZtimes_lt_pred.
+
+Theorem times_lt_mono_pos_l : forall p n m : N, 0 < p -> (n < m <-> p * n < p * m).
+Proof NZtimes_lt_mono_pos_l.
+
+Theorem times_lt_mono_pos_r : forall p n m : N, 0 < p -> (n < m <-> n * p < m * p).
+Proof NZtimes_lt_mono_pos_r.
+
+Theorem times_le_mono_l : forall n m p : N, n <= m -> p * n <= p * m.
+Proof.
+intros; apply NZtimes_le_mono_nonneg_l. apply le_0_l. assumption.
+Qed.
+
+Theorem times_le_mono_r : forall n m p : N, n <= m -> n * p <= m * p.
+Proof.
+intros; apply NZtimes_le_mono_nonneg_r. apply le_0_l. assumption.
+Qed.
+
+Theorem times_cancel_l : forall n m p : N, p ~= 0 -> (p * n == p * m <-> n == m).
+Proof NZtimes_cancel_l.
+
+Theorem times_le_mono_pos_l : forall n m p : N, 0 < p -> (n <= m <-> p * n <= p * m).
+Proof NZtimes_le_mono_pos_l.
+
+Theorem times_le_mono_pos_r : forall n m p : N, 0 < p -> (n <= m <-> n * p <= m * p).
+Proof NZtimes_le_mono_pos_r.
+
+Theorem times_lt_mono : forall n m p q : N, n < m -> p < q -> n * p < m * q.
+Proof.
+intros; apply NZtimes_lt_mono; try assumption; apply le_0_l.
+Qed.
+
+Theorem times_le_mono : forall n m p q : N, n <= m -> p <= q -> n * p <= m * q.
+Proof.
+intros; apply NZtimes_le_mono; try assumption; apply le_0_l.
+Qed.
+
+Theorem times_pos_pos : forall n m : N, 0 < n -> 0 < m -> 0 < n * m.
+Proof NZtimes_pos_pos.
+
+Theorem times_eq_0 : forall n m : N, n * m == 0 -> n == 0 \/ m == 0.
+Proof NZtimes_eq_0.
+
+Theorem times_neq_0 : forall n m : N, n ~= 0 /\ m ~= 0 <-> n * m ~= 0.
+Proof NZtimes_neq_0.
+
+End NTimesOrderPropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)
diff --git a/theories/Numbers/Natural/Axioms/NBase.v b/theories/Numbers/Natural/Axioms/NBase.v
deleted file mode 100644
index fd483265d..000000000
--- a/theories/Numbers/Natural/Axioms/NBase.v
+++ /dev/null
@@ -1,196 +0,0 @@
-Require Export NumPrelude.
-Require Import NZBase.
-
-Module Type NBaseSig.
-
-Parameter Inline N : Set.
-Parameter Inline E : N -> N -> Prop.
-Parameter Inline O : N.
-Parameter Inline S : N -> N.
-
-Delimit Scope NatScope with Nat.
-Open Local Scope NatScope.
-
-Notation "x == y" := (E x y) (at level 70) : NatScope.
-Notation "x ~= y" := (~ E x y) (at level 70) : NatScope.
-Notation "0" := O : NatScope.
-Notation "1" := (S O) : NatScope.
-
-Axiom E_equiv : equiv N E.
-Add Relation N E
- reflexivity proved by (proj1 E_equiv)
- symmetry proved by (proj2 (proj2 E_equiv))
- transitivity proved by (proj1 (proj2 E_equiv))
-as E_rel.
-
-Add Morphism S with signature E ==> E as S_wd.
-
-Axiom succ_inj : forall n1 n2 : N, S n1 == S n2 -> n1 == n2.
-Axiom succ_neq_0 : forall n : N, S n ~= 0.
-
-Axiom induction :
- forall A : N -> Prop, predicate_wd E A ->
- A 0 -> (forall n : N, A n -> A (S n)) -> forall n : N, A n.
-
-End NBaseSig.
-
-Module NBasePropFunct (Import NBaseMod : NBaseSig).
-Open Local Scope NatScope.
-
-(*Theorem E_equiv : equiv N E.
-Proof E_equiv.
-
-Theorem succ_inj_wd : forall n1 n2 : N, S n1 == S n2 <-> n1 == n2.
-Proof succ_inj_wd.
-
-Theorem succ_neq_0 : forall n : N, S n ~= 0.
-Proof succ_neq_0.
-
-Theorem induction :
- forall A : N -> Prop, predicate_wd E A ->
- A 0 -> (forall n : N, A n -> A (S n)) -> forall n : N, A n.
-Proof induction.*)
-
-Module NZBaseMod <: NZBaseSig.
-Definition NZ := N.
-Definition NZE := E.
-Definition NZ0 := 0.
-Definition NZsucc := S.
-
-(* Axioms *)
-Definition NZE_equiv := E_equiv.
-Definition NZsucc_inj := succ_inj.
-
-Add Relation NZ NZE
- reflexivity proved by (proj1 NZE_equiv)
- symmetry proved by (proj2 (proj2 NZE_equiv))
- transitivity proved by (proj1 (proj2 NZE_equiv))
-as NZE_rel.
-
-Add Morphism NZsucc with signature NZE ==> NZE as NZsucc_wd.
-Proof S_wd.
-
-Theorem NZinduction :
- forall A : N -> Prop, predicate_wd E A ->
- A 0 -> (forall n : N, A n <-> A (S n)) -> forall n : N, A n.
-Proof.
-intros A A_wd Base Step.
-apply induction; try assumption.
-intros; now apply -> Step.
-Qed.
-
-End NZBaseMod.
-
-Module Export NZBasePropMod := NZBasePropFunct NZBaseMod.
-
-Theorem neq_symm : forall n m : N, n ~= m -> m ~= n.
-Proof NZneq_symm.
-
-Theorem succ_inj_wd_neg : forall n m : N, S n ~= S m <-> n ~= m.
-Proof NZsucc_inj_wd_neg.
-
-Ltac induct n := induction_maker n ltac:(apply induction).
-
-Theorem nondep_induction :
- forall A : N -> Prop, predicate_wd E A ->
- A 0 -> (forall n : N, A (S n)) -> forall n : N, A n.
-Proof.
-intros; apply induction; auto.
-Qed.
-
-Ltac nondep_induct n := induction_maker n ltac:(apply nondep_induction).
-
-Theorem neq_0 : ~ forall n, n == 0.
-Proof.
-intro H; apply (succ_neq_0 0). apply H.
-Qed.
-
-Theorem neq_0_succ : forall n, n ~= 0 <-> exists m, n == S m.
-Proof.
-nondep_induct n. split; intro H;
-[now elim H | destruct H as [m H]; symmetry in H; false_hyp H succ_neq_0].
-intro n; split; intro H; [now exists n | apply succ_neq_0].
-Qed.
-
-Theorem zero_or_succ : forall n, n == 0 \/ exists m, n == S m.
-Proof.
-nondep_induct n; [now left | intros n; right; now exists n].
-Qed.
-
-(* The following is useful for reasoning about, e.g., Fibonacci numbers *)
-Section DoubleInduction.
-
-Variable A : N -> Prop.
-Hypothesis A_wd : predicate_wd E A.
-
-Add Morphism A with signature E ==> iff as A_morph.
-Proof.
-exact A_wd.
-Qed.
-
-Theorem double_induction :
- A 0 -> A 1 ->
- (forall n, A n -> A (S n) -> A (S (S n))) -> forall n, A n.
-Proof.
-intros until 3.
-assert (D : forall n, A n /\ A (S n)); [ |intro n; exact (proj1 (D n))].
-induct n; [ | intros n [IH1 IH2]]; auto.
-Qed.
-
-End DoubleInduction.
-
-Ltac double_induct n := induction_maker n ltac:(apply double_induction).
-
-(* The following is useful for reasoning about, e.g., Ackermann function *)
-Section TwoDimensionalInduction.
-
-Variable R : N -> N -> Prop.
-Hypothesis R_wd : rel_wd E E R.
-
-Add Morphism R with signature E ==> E ==> iff as R_morph.
-Proof.
-exact R_wd.
-Qed.
-
-Theorem two_dim_induction :
- R 0 0 ->
- (forall n m, R n m -> R n (S m)) ->
- (forall n, (forall m, R n m) -> R (S n) 0) -> forall n m, R n m.
-Proof.
-intros H1 H2 H3. induct n.
-induct m.
-exact H1. exact (H2 0).
-intros n IH. induct m.
-now apply H3. exact (H2 (S n)).
-Qed.
-
-End TwoDimensionalInduction.
-
-Ltac two_dim_induct n m :=
- try intros until n;
- try intros until m;
- pattern n, m; apply two_dim_induction; clear n m;
- [unfold rel_wd; unfold fun2_wd;
- let x1 := fresh "x" in
- let y1 := fresh "y" in
- let H1 := fresh "H" in
- let x2 := fresh "x" in
- let y2 := fresh "y" in
- let H2 := fresh "H" in
- intros x1 y1 H1 x2 y2 H2;
- qsetoid_rewrite H1;
- qiff x2 y2 H2 | | | ].
-(* This is not a very efficient approach because qsetoid_rewrite uses
-qiff to take the formula apart in order to make it quantifier-free,
-and then qiff is called again and takes the formula apart for the
-second time. It is better to analyze the formula once and generalize
-qiff to take a list of equalities that it has to rewrite. *)
-
-End NBasePropFunct.
-
-
-(*
- Local Variables:
- tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
- End:
-*)
diff --git a/theories/Numbers/Natural/Axioms/NLeibniz.v b/theories/Numbers/Natural/Axioms/NLeibniz.v
deleted file mode 100644
index d9c4718aa..000000000
--- a/theories/Numbers/Natural/Axioms/NLeibniz.v
+++ /dev/null
@@ -1,4 +0,0 @@
-(* This file proves or redefines properties that are true for Leibniz
-equality. For example, it removes the premise predicate_wd from
-induction theorems. *)
-
diff --git a/theories/Numbers/Natural/Axioms/NMinus.v b/theories/Numbers/Natural/Axioms/NMinus.v
deleted file mode 100644
index 2bac3c5c3..000000000
--- a/theories/Numbers/Natural/Axioms/NMinus.v
+++ /dev/null
@@ -1,88 +0,0 @@
-Require Export NPlusOrder.
-
-Module Type NMinusSignature.
-Declare Module Export NPredModule : NPredSignature.
-Open Local Scope NatScope.
-
-Parameter Inline minus : N -> N -> N.
-
-Notation "x - y" := (minus x y) : NatScope.
-
-Add Morphism minus with signature E ==> E ==> E as minus_wd.
-
-Axiom minus_0_r : forall n, n - 0 == n.
-Axiom minus_succ_r : forall n m, n - (S m) == P (n - m).
-
-End NMinusSignature.
-
-Module NMinusProperties (Import NMinusModule : NMinusSignature)
- (Import NPlusMod : NPlusSig with
- Module NBaseMod := NMinusModule.NPredModule.NBaseMod)
- (Import NOrderModule : NOrderSig with
- Module NBaseMod := NMinusModule.NPredModule.NBaseMod).
-Module Export NPlusOrderPropertiesModule :=
- NPlusOrderProperties NPlusMod NOrderModule.
-Open Local Scope NatScope.
-
-Theorem minus_1_r : forall n, n - 1 == P n.
-Proof.
-intro n; rewrite minus_succ_r; now rewrite minus_0_r.
-Qed.
-
-Theorem minus_0_l : forall n, 0 - n == 0.
-Proof.
-induct n.
-apply minus_0_r.
-intros n IH; rewrite minus_succ_r; rewrite IH. now apply pred_0.
-Qed.
-
-Theorem minus_comm_succ : forall n m, S n - S m == n - m.
-Proof.
-intro n; induct m.
-rewrite minus_succ_r. do 2 rewrite minus_0_r. now rewrite pred_succ.
-intros m IH. rewrite minus_succ_r. rewrite IH. now rewrite minus_succ_r.
-Qed.
-
-Theorem minus_succ_l : forall n m, n <= m -> S m - n == S (m - n).
-Proof.
-intros n m H; pattern n, m; apply le_ind_rel.
-unfold rel_wd. intros x x' H1 y y' H2; rewrite H1; now rewrite H2.
-intros; now do 2 rewrite minus_0_r.
-clear n m H. intros n m H1 H2.
-now do 2 rewrite minus_comm_succ. assumption.
-Qed.
-
-Theorem minus_le : forall n m, n <= m -> n - m == 0.
-Proof.
-intros n m H; pattern n, m; apply le_ind_rel.
-unfold rel_wd; intros x x' H1 y y' H2; rewrite H1; now rewrite H2.
-apply minus_0_l.
-clear n m H; intros n m H1 H2. now rewrite minus_comm_succ.
-assumption.
-Qed.
-
-Theorem minus_diag : forall n, n - n == 0.
-Proof.
-intro n; apply minus_le; apply le_refl.
-Qed.
-
-Theorem minus_plus : forall n m, n <= m -> (m - n) + n == m.
-Proof.
-intros n m H; pattern n, m; apply le_ind_rel.
-unfold rel_wd; intros x x' H1 y y' H2; rewrite H1; now rewrite H2.
-intro; rewrite minus_0_r; now rewrite plus_0_r.
-clear n m H. intros n m _ H2. rewrite minus_comm_succ. rewrite plus_succ_r.
-now rewrite H2.
-assumption.
-Qed.
-
-End NMinusProperties.
-
-
-
-
-(*
- Local Variables:
- tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
- End:
-*)
diff --git a/theories/Numbers/Natural/Axioms/NRec.v b/theories/Numbers/Natural/Axioms/NRec.v
deleted file mode 100644
index d74660c4a..000000000
--- a/theories/Numbers/Natural/Axioms/NRec.v
+++ /dev/null
@@ -1,259 +0,0 @@
-Parameter Inline recursion : forall A : Set, A -> (N -> A -> A) -> N -> A.
-
-Implicit Arguments recursion [A].
-
-(* Suppose the codomain A has a setoid equality relation EA. If A is a
-function space C -> D, it makes sense to consider extensional
-functional equality as EA. Indeed, suppose, for example, that we say
-[Definition g (x : N) : C -> D := (recursion ... x ...)]. We would
-like to show that the function g of two arguments is well-defined.
-This requirement is the same as the requirement that the functions of
-one argument (g x) and (g x') are extensionally equal whenever x ==
-x', i.e.,
-
-forall x x' : N, x == x' -> eq_fun (g x) (g x'),
-
-which is the same as
-
-forall x x' : N, x == x' -> forall y y' : C, EC y y' -> ED (g x y) (g x' y')
-
-where EC and ED are setoid equalities on C and D, respectively.
-
-Now, if we consider EA to be extensional equality on the function
-space, we cannot require that EA is reflexive. Indeed, reflexivity of
-EA:
-
-forall f : C -> D, eq_fun f f
-
-or
-
-forall f : C -> D, forall x x', EC x x' -> ED (f x) (f x')
-
-means that every function f ; C -> D is well-defined, which is in
-general false. We can expect that EA is symmetric and transitive,
-i.e., that EA is a partial equivalence relation (PER). However, there
-seems to be no need to require this in the following axioms.
-
-When we defined a function by recursion, the arguments of this
-function may occur in the recursion's base case a, the counter x, or
-the step function f. For example, in the following definition:
-
-Definition plus (x y : N) := recursion y (fun _ p => S p) x.
-
-one argument becomes the base case and the other becomes the counter.
-
-In the definitions of times:
-
-Definition times (x y : N) := recursion 0 (fun x p => plus y p) x.
-
-the argument y occurs in the step function. Thus it makes sense to
-formulate an axiom saying that (recursion a f x) is equal to
-(recursion a' f' x') whenever (EA a a'), x == x', and eq_fun2 f f'. We
-need to vary all three arguments; for example, claiming that
-(recursion a f x) equals (recursion a' f x') with the same f whenever
-(EA a a') and x == x' is not enough to prove well-defidedness of
-multiplication defined above.
-
-This leads to the axioms given below. There is a question if it is
-possible to formulate simpler axioms that would imply this statement
-for any implementation. Indeed, the proof seems to have to proceed by
-straighforward induction on x. The difficulty is that we cannot prove
-(EA (recursion a f x) (recursion a' f' x')) using the induction axioms
-above because recursion is not declared to be a setoid morphism:
-that's what we are proving! Therefore, this has to be proved by
-induction inside each particular implementation. *)
-
-Axiom recursion_wd : forall (A : Set) (EA : relation A),
- forall a a' : A, EA a a' ->
- forall f f' : N -> A -> A, eq_fun2 E EA EA f f' ->
- forall x x' : N, x == x' ->
- EA (recursion a f x) (recursion a' f' x').
-
-(* Can we instead declare recursion as a morphism? It does not seem
-so. For this, we need to register the relation EA, and for this we
-need to declare it as a variable in a section. But information about
-morhisms is lost when sections are closed. *)
-
-(* When the function recursion is polymorphic on the codomain A, there
-seems no other option than to return the given base case a when the
-counter is 0. Therefore, we can formulate the following axioms with
-Leibniz equality. *)
-
-Axiom recursion_0 :
- forall (A : Set) (a : A) (f : N -> A -> A), recursion a f 0 = a.
-
-Axiom recursion_succ :
- forall (A : Set) (EA : relation A) (a : A) (f : N -> A -> A),
- EA a a -> fun2_wd E EA EA f ->
- forall n : N, EA (recursion a f (S n)) (f n (recursion a f n)).
-
-(* It may be possible to formulate recursion_0 and recursion_succ as follows:
-Axiom recursion_0 :
- forall (a : A) (f : N -> A -> A),
- EA a a -> forall x : N, x == 0 -> EA (recursion a f x) a.
-
-Axiom recursion_succ :
- forall (a : A) (f : N -> A -> A),
- EA a a -> fun2_wd E EA EA f ->
- forall n m : N, n == S m -> EA (recursion a f n) (f m (recursion a f m)).
-
-Then it is possible to prove recursion_wd (see IotherInd.v). This
-raises some questions:
-
-(1) Can the axioms recursion_wd, recursion_0 and recursion_succ (both
-variants) proved for all reasonable implementations?
-
-(2) Can these axioms be proved without assuming that EA is symmetric
-and transitive? In OtherInd.v, recursion_wd can be proved from
-recursion_0 and recursion_succ by assuming symmetry and transitivity.
-
-(2) Which variant requires proving less for each implementation? Can
-it be that proving all three axioms about recursion has some common
-parts which have to be repeated? *)
-
-Implicit Arguments recursion_wd [A].
-Implicit Arguments recursion_0 [A].
-Implicit Arguments recursion_succ [A].
-
-Definition if_zero (A : Set) (a b : A) (n : N) : A :=
- recursion a (fun _ _ => b) n.
-
-Add Morphism if_zero with signature LE_succet ==> LE_succet ==> E ==> LE_succet as if_zero_wd.
-Proof.
-unfold LE_succet.
-intros; unfold if_zero; now apply recursion_wd with (EA := (@eq A));
-[| unfold eq_fun2; now intros |].
-Qed.
-
-Theorem if_zero_0 : forall (A : Set) (a b : A), if_zero A a b 0 = a.
-Proof.
-unfold if_zero; intros; now rewrite recursion_0.
-Qed.
-
-Theorem if_zero_succ : forall (A : Set) (a b : A) (n : N), if_zero A a b (S n) = b.
-Proof.
-intros; unfold if_zero.
-now rewrite (recursion_succ (@eq A)); [| | unfold fun2_wd; now intros].
-Qed.
-
-Implicit Arguments if_zero [A].
-
-(* To prove this statement, we need to provably different terms,
-e.g., true and false *)
-Theorem succ_0 : forall n, ~ S n == 0.
-Proof.
-intros n H.
-assert (true = false); [| discriminate].
-replace true with (if_zero false true (S n)) by apply if_zero_succ.
-pattern false at 2; replace false with (if_zero false true 0) by apply if_zero_0.
-change (LE_succet bool (if_zero false true (S n)) (if_zero false true 0)).
-rewrite H. unfold LE_succet. reflexivity.
-Qed.
-
-Theorem succ_inj : forall m n, S m == S n -> m == n.
-Proof.
-intros m n H.
-setoid_replace m with (A (S m)) by (symmetry; apply pred_succ).
-setoid_replace n with (A (S n)) by (symmetry; apply pred_succ).
-now apply pred_wd.
-Qed.
-
-(* The following section is devoted to defining a function that, given
-two numbers whose some equals 1, decides which number equals 1. The
-main property of the function is also proved .*)
-
-(* First prove a theorem with ordinary disjunction *)
-Theorem plus_eq_1 :
- forall m n : N, m + n == 1 -> (m == 0 /\ n == 1) \/ (m == 1 /\ n == 0).
-induct m.
-intros n H; rewrite plus_0_l in H; left; now split.
-intros n IH m H; rewrite plus_succ_l in H; apply succ_inj in H;
-apply plus_eq_0 in H; destruct H as [H1 H2];
-now right; split; [apply succ_wd |].
-Qed.
-
-Definition plus_eq_1_dec (m n : N) : bool := recursion true (fun _ _ => false) m.
-
-Theorem plus_eq_1_dec_step_wd : fun2_wd E eq_bool eq_bool (fun _ _ => false).
-Proof.
-unfold fun2_wd; intros. unfold eq_bool. reflexivity.
-Qed.
-
-Add Morphism plus_eq_1_dec with signature E ==> E ==> eq_bool as plus_eq_1_dec_wd.
-Proof.
-unfold fun2_wd, plus_eq_1_dec.
-intros x x' Exx' y y' Eyy'.
-apply recursion_wd with (EA := eq_bool).
-unfold eq_bool; reflexivity.
-unfold eq_fun2; unfold eq_bool; reflexivity.
-assumption.
-Qed.
-
-Theorem plus_eq_1_dec_0 : forall n : N, plus_eq_1_dec 0 n = true.
-Proof.
-intro n. unfold plus_eq_1_dec.
-now apply recursion_0.
-Qed.
-
-Theorem plus_eq_1_dec_succ : forall m n : N, plus_eq_1_dec (S n) m = false.
-Proof.
-intros n m. unfold plus_eq_1_dec.
-now rewrite (recursion_succ eq_bool);
-[| unfold eq_bool | apply plus_eq_1_dec_step_wd].
-Qed.
-
-Theorem plus_eq_1_dec_correct :
- forall m n : N, m + n == 1 ->
- (plus_eq_1_dec m n = true -> m == 0 /\ n == 1) /\
- (plus_eq_1_dec m n = false -> m == 1 /\ n == 0).
-Proof.
-intros m n; induct m.
-intro H. rewrite plus_0_l in H.
-rewrite plus_eq_1_dec_0.
-split; [intros; now split | intro H1; discriminate H1].
-intros m _ H. rewrite plus_eq_1_dec_succ.
-split; [intro H1; discriminate | intros _ ].
-rewrite plus_succ_l in H. apply succ_inj in H.
-apply plus_eq_0 in H; split; [apply succ_wd | ]; tauto.
-Qed.
-
-Definition times_eq_0_dec (n m : N) : bool :=
- recursion true (fun _ _ => recursion false (fun _ _ => false) m) n.
-
-Lemma times_eq_0_dec_wd_step :
- forall y y', y == y' ->
- eq_bool (recursion false (fun _ _ => false) y)
- (recursion false (fun _ _ => false) y').
-Proof.
-intros y y' Eyy'.
-apply recursion_wd with (EA := eq_bool).
-now unfold eq_bool.
-unfold eq_fun2. intros. now unfold eq_bool.
-assumption.
-Qed.
-
-Add Morphism times_eq_0_dec with signature E ==> E ==> eq_bool
-as times_eq_0_dec_wd.
-unfold fun2_wd, times_eq_0_dec.
-intros x x' Exx' y y' Eyy'.
-apply recursion_wd with (EA := eq_bool).
-now unfold eq_bool.
-unfold eq_fun2; intros. now apply times_eq_0_dec_wd_step.
-assumption.
-Qed.
-
-Theorem times_eq_0_dec_correct :
- forall n m, n * m == 0 ->
- (times_eq_0_dec n m = true -> n == 0) /\
- (times_eq_0_dec n m = false -> m == 0).
-Proof.
-nondep_induct n; nondep_induct m; unfold times_eq_0_dec.
-rewrite recursion_0; split; now intros.
-intro n; rewrite recursion_0; split; now intros.
-intro; rewrite recursion_0; rewrite (recursion_succ eq_bool);
-[split; now intros | now unfold eq_bool | unfold fun2_wd; unfold eq_bool; now intros].
-intro m; rewrite (recursion_succ eq_bool).
-rewrite times_succ_l. rewrite plus_succ_r. intro H; now apply succ_0 in H.
-now unfold eq_bool.
-unfold fun2_wd; intros; now unfold eq_bool.
-Qed.
diff --git a/theories/Numbers/Natural/Axioms/NTimesOrder.v b/theories/Numbers/Natural/Axioms/NTimesOrder.v
deleted file mode 100644
index 3e7c3f2b2..000000000
--- a/theories/Numbers/Natural/Axioms/NTimesOrder.v
+++ /dev/null
@@ -1,70 +0,0 @@
-Require Export NTimes.
-Require Export NPlusOrder.
-
-Module NTimesOrderProperties (Import NTimesMod : NTimesSig)
- (Import NOrderModule : NOrderSig with
- Module NBaseMod := NTimesMod.NPlusMod.NBaseMod).
-Module Export NTimesPropertiesModule := NTimesPropFunct NTimesMod.
-Module Export NPlusOrderPropertiesModule :=
- NPlusOrderProperties NTimesMod.NPlusMod NOrderModule.
-Open Local Scope NatScope.
-
-Lemma times_succ_lt_compat_l : forall n m p, m < p -> S n * m < S n * p.
-Proof.
-intros n m p; induct n.
-now do 2 rewrite times_1_l.
-intros x IH H.
-rewrite times_succ_l.
-set (k := S x * m); rewrite times_succ_l; unfold k; clear k.
-apply plus_lt_compat; [apply IH; assumption | assumption].
-Qed.
-
-Lemma times_succ_lt_compat_r : forall n m p, m < p -> m * (S n) < p * (S n).
-Proof.
-intros n m p H.
-set (k := (p * (S n))); rewrite times_comm; unfold k; clear k.
-set (k := ((S n) * m)); rewrite times_comm; unfold k; clear k.
-now apply times_succ_lt_compat_l.
-Qed.
-
-Lemma times_lt_compat_l : forall m n p, n < m -> 0 < p -> p * n < p * m.
-Proof.
-intros n m p H1 H2.
-apply (lt_exists_pred p) in H2.
-destruct H2 as [q H]. repeat rewrite H.
-now apply times_succ_lt_compat_l.
-Qed.
-
-Lemma times_lt_compat_r : forall n m p, n < m -> 0 < p -> n * p < m * p.
-Proof.
-intros n m p H1 H2.
-apply (lt_exists_pred p) in H2.
-destruct H2 as [q H]. repeat rewrite H.
-now apply times_succ_lt_compat_r.
-Qed.
-
-Lemma times_positive : forall n m, 0 < n -> 0 < m -> 0 < n * m.
-Proof.
-intros n m H1 H2.
-rewrite <- (times_0_l m); now apply times_lt_compat_r.
-Qed.
-
-Lemma times_lt_compat : forall n m p q, n < m -> p < q -> n * p < m * q.
-Proof.
-intros n m p q; induct n.
-intros; rewrite times_0_l; apply times_positive;
-[assumption | apply lt_positive with (n := p); assumption].
-intros x IH H1 H2.
-apply lt_trans with (m := ((S x) * q)).
-now apply times_succ_lt_compat_l; assumption.
-now apply times_lt_compat_r; [| apply lt_positive with (n := p)].
-Qed.
-
-End NTimesOrderProperties.
-
-
-(*
- Local Variables:
- tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
- End:
-*)
diff --git a/theories/Numbers/Natural/Binary/NBinary.v b/theories/Numbers/Natural/Binary/NBinary.v
index 46973db7f..165c1211f 100644
--- a/theories/Numbers/Natural/Binary/NBinary.v
+++ b/theories/Numbers/Natural/Binary/NBinary.v
@@ -1,30 +1,44 @@
Require Import NArith.
-Require Import Ndec.
+Require Import NMinus.
-Require Export NDepRec.
-Require Export NTimesOrder.
-Require Export NMinus.
-Require Export NMiscFunct.
+Module NBinaryAxiomsMod <: NAxiomsSig.
Open Local Scope N_scope.
-Module NBinaryDomain : NDomainEqSignature
- with Definition N := N
- with Definition E := (@eq N)
- with Definition e := Neqb.
-
Definition N := N.
Definition E := (@eq N).
-Definition e := Neqb.
+Definition O := 0.
+Definition S := Nsucc.
-Theorem E_equiv_e : forall x y : N, E x y <-> e x y.
-Proof.
-unfold E, e; intros x y; split; intro H;
-[rewrite H; now rewrite Neqb_correct |
-apply Neqb_complete; now inversion H].
-Qed.
+(*Definition Npred (n : N) := match n with
+| 0 => 0
+| Npos p => match p with
+ | xH => 0
+ | _ => Npos (Ppred p)
+ end
+end.*)
-Definition E_equiv : equiv N E := eq_equiv N.
+Definition P := Npred.
+Definition plus := Nplus.
+Definition minus := Nminus.
+
+(*Definition minus (n m : N) :=
+match n, m with
+| N0, _ => N0
+| n, N0 => n
+| Npos n', Npos m' =>
+ match Pminus_mask n' m' with
+ | IsPos p => Npos p
+ | _ => N0
+ end
+end.*)
+
+Definition times := Nmult.
+Definition lt := Nlt.
+Definition le := Nle.
+
+Theorem E_equiv : equiv N E.
+Proof (eq_equiv N).
Add Relation N E
reflexivity proved by (proj1 E_equiv)
@@ -32,24 +46,102 @@ Add Relation N E
transitivity proved by (proj1 (proj2 E_equiv))
as E_rel.
-End NBinaryDomain.
+Add Morphism S with signature E ==> E as succ_wd.
+Proof.
+congruence.
+Qed.
-Module BinaryNat <: NBaseSig.
-Module Export NDomainModule := NBinaryDomain.
+Add Morphism P with signature E ==> E as pred_wd.
+Proof.
+congruence.
+Qed.
-Definition O := N0.
-Definition S := Nsucc.
+Add Morphism plus with signature E ==> E ==> E as plus_wd.
+Proof.
+congruence.
+Qed.
-Add Morphism S with signature E ==> E as succ_wd.
+Add Morphism minus with signature E ==> E ==> E as minus_wd.
+Proof.
+congruence.
+Qed.
+
+Add Morphism times with signature E ==> E ==> E as times_wd.
Proof.
congruence.
Qed.
+Add Morphism lt with signature E ==> E ==> iff as lt_wd.
+Proof.
+unfold E; intros x1 x2 H1 y1 y2 H2; rewrite H1; now rewrite H2.
+Qed.
+
+Add Morphism le with signature E ==> E ==> iff as le_wd.
+Proof.
+unfold E; intros x1 x2 H1 y1 y2 H2; rewrite H1; now rewrite H2.
+Qed.
+
Theorem induction :
- forall P : N -> Prop, predicate_wd E P ->
- P 0 -> (forall n, P n -> P (S n)) -> forall n, P n.
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n, A n -> A (Nsucc n)) -> forall n, A n.
+Proof.
+intros A predicate_wd; apply Nind.
+Qed.
+
+Theorem pred_0 : Npred 0 = 0.
+Proof.
+reflexivity.
+Qed.
+
+Theorem pred_succ : forall n : N, Npred (Nsucc n) = n.
+Proof.
+destruct n as [| p]; simpl. reflexivity.
+case_eq (Psucc p); try (intros q H; rewrite <- H; now rewrite Ppred_succ).
+intro H; false_hyp H Psucc_not_one.
+Qed.
+
+Theorem plus_0_l : forall n : N, 0 + n = n.
+Proof Nplus_0_l.
+
+Theorem plus_succ_l : forall n m : N, (Nsucc n) + m = Nsucc (n + m).
+Proof Nplus_succ.
+
+Theorem minus_0_r : forall n : N, n - 0 = n.
+Proof Nminus_0_r.
+
+Theorem minus_succ_r : forall n m : N, n - (S m) = P (n - m).
+Proof Nminus_succ_r.
+
+Theorem times_0_r : forall n : N, n * 0 = 0.
+Proof.
+intro n; rewrite Nmult_comm; apply Nmult_0_l.
+Qed.
+
+Theorem times_succ_r : forall n m : N, n * (Nsucc m) = n * m + n.
+Proof.
+intros n m; rewrite Nmult_comm, Nmult_Sn_m.
+now rewrite Nplus_comm, Nmult_comm.
+Qed.
+
+Theorem le_lt_or_eq : forall n m : N, n <= m <-> n < m \/ n = m.
+Proof.
+intros n m.
+assert (H : (n ?= m) = Eq <-> n = m).
+split; intro H; [now apply Ncompare_Eq_eq | rewrite H; apply Ncompare_refl].
+unfold Nle, Nlt. rewrite <- H.
+destruct (n ?= m); split; intro H1; (try discriminate); try (now left); try now right.
+now elim H1. destruct H1; discriminate.
+Qed.
+
+Theorem nlt_0_r : forall n : N, ~ (n < 0).
Proof.
-intros P predicate_wd; apply Nind.
+unfold Nlt; destruct n as [| p]; simpl; discriminate.
+Qed.
+
+Theorem lt_succ_le : forall n m : N, n < (S m) <-> n <= m.
+Proof.
+intros x y. rewrite le_lt_or_eq.
+unfold Nlt, Nle, S; apply Ncompare_n_Sm.
Qed.
Definition recursion (A : Set) (a : A) (f : N -> A -> A) (n : N) :=
@@ -82,7 +174,7 @@ Qed.
Theorem recursion_succ :
forall (A : Set) (EA : relation A) (a : A) (f : N -> A -> A),
EA a a -> fun2_wd E EA EA f ->
- forall n : N, EA (recursion a f (S n)) (f n (recursion a f n)).
+ forall n : N, EA (recursion a f (Nsucc n)) (f n (recursion a f n)).
Proof.
unfold E, recursion, Nrec, fun2_wd; intros A EA a f EAaa f_wd n; pattern n; apply Nind.
rewrite Nrect_step; rewrite Nrect_base; now apply f_wd.
@@ -90,8 +182,11 @@ clear n; intro n; do 2 rewrite Nrect_step; intro IH. apply f_wd; [reflexivity|].
now rewrite Nrect_step.
Qed.
-End BinaryNat.
+End NBinaryAxiomsMod.
+Module Export NBinaryMinusPropMod := NMinusPropFunct NBinaryAxiomsMod.
+
+(*
Module NBinaryDepRec <: NDepRecSignature.
Module Export NDomainModule := NBinaryDomain.
Module Export NBaseMod := BinaryNat.
@@ -124,16 +219,6 @@ Proof.
unfold E; congruence.
Qed.
-Theorem plus_0_l : forall n, 0 + n = n.
-Proof.
-exact Nplus_0_l.
-Qed.
-
-Theorem plus_succ_l : forall n m, (S n) + m = S (n + m).
-Proof.
-exact Nplus_succ.
-Qed.
-
End NBinaryPlus.
Module NBinaryTimes <: NTimesSig.
@@ -146,16 +231,6 @@ Proof.
unfold E; congruence.
Qed.
-Theorem times_0_r : forall n, n * 0 = 0.
-Proof.
-intro n; rewrite Nmult_comm; apply Nmult_0_l.
-Qed.
-
-Theorem times_succ_r : forall n m, n * (S m) = n * m + n.
-Proof.
-intros n m; rewrite Nmult_comm; rewrite Nmult_succn_m.
-rewrite Nplus_comm; now rewrite Nmult_comm.
-Qed.
End NBinaryTimes.
@@ -195,7 +270,7 @@ assert (H1 : lt x (S y) <-> Ncompare x (S y) = Lt);
[unfold lt, comp_bool; destruct (x ?= S y); simpl; split; now intro |].
assert (H2 : lt x y <-> Ncompare x y = Lt);
[unfold lt, comp_bool; destruct (x ?= y); simpl; split; now intro |].
-pose proof (Ncompare_n_succm x y) as H. tauto.
+pose proof (Ncompare_n_Sm m x y) as H. tauto.
Qed.
End NBinaryOrder.
@@ -227,7 +302,7 @@ end.
*)
(* Eval compute in (binlog 1000000000000000000). *) (* Works very fast *)
-
+*)
(*
Local Variables:
tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
diff --git a/theories/Numbers/Natural/Peano/NPeano.v b/theories/Numbers/Natural/Peano/NPeano.v
index 0240f29b1..aa5ac99cf 100644
--- a/theories/Numbers/Natural/Peano/NPeano.v
+++ b/theories/Numbers/Natural/Peano/NPeano.v
@@ -1,66 +1,165 @@
-(*Require Import Minus.*)
-
-Require Export NPlus.
-(*Require Export NDepRec.
-Require Export NTimesOrder.
-Require Export NMinus.
-Require Export NMiscFunct.*)
-
-(* First we define the functions that will be suppled as
-implementations. The parameters in module types, to which these
-functions are going to be assigned, are declared Inline,
-so in the properties functors the definitions are going to
-be unfolded and the theorems proved in these functors
-will contain these functions in their statements. *)
-
-(* Decidable equality *)
-Fixpoint e (x y : nat) {struct x} : bool :=
-match x, y with
-| 0, 0 => true
-| S x', S y' => e x' y'
-| _, _ => false
-end.
+Require Import Arith.
+Require Import NMinus.
-(* The boolean < function can be defined as follows using the
-standard library:
+Module NPeanoAxiomsMod <: NAxiomsSig.
-fun n m => proj1_sig (nat_lt_ge_bool n m)
+Definition N := nat.
+Definition E := (@eq nat).
+Definition O := 0.
+Definition S := S.
+Definition P := pred.
+Definition plus := plus.
+Definition minus := minus.
+Definition times := mult.
+Definition lt := lt.
+Definition le := le.
+Definition recursion : forall A : Set, A -> (N -> A -> A) -> N -> A :=
+ fun A : Set => nat_rec (fun _ => A).
+Implicit Arguments recursion [A].
-However, this definition seems too complex. First, there are many
-functions involved: nat_lt_ge_bool is defined (in Coq.Arith.Bool_nat)
-using bool_of_sumbool and
+Theorem E_equiv : equiv nat E.
+Proof (eq_equiv nat).
-lt_ge_dec : forall x y : nat, {x < y} + {x >= y},
+Add Relation nat E
+ reflexivity proved by (proj1 E_equiv)
+ symmetry proved by (proj2 (proj2 E_equiv))
+ transitivity proved by (proj1 (proj2 E_equiv))
+as E_rel.
-where the latter function is defined using sumbool_not and
+(* If we say "Add Relation nat (@eq nat)" instead of "Add Relation nat E"
+then the theorem generated for succ_wd below is forall x, succ x = succ x,
+which does not match the axioms in NAxiomsSig *)
-le_lt_dec : forall n m : nat, {n <= m} + {m < n}.
+Add Morphism S with signature E ==> E as succ_wd.
+Proof.
+congruence.
+Qed.
-Second, this definition is not the most efficient, especially since
-le_lt_dec is proved using tactics, not by giving the explicit proof
-term. *)
+Add Morphism P with signature E ==> E as pred_wd.
+Proof.
+congruence.
+Qed.
-Fixpoint lt (n m : nat) {struct n} : bool :=
-match n, m with
-| _, 0 => false
-| 0, S _ => true
-| S n', S m' => lt n' m'
-end.
+Add Morphism plus with signature E ==> E ==> E as plus_wd.
+Proof.
+congruence.
+Qed.
-Fixpoint le (n m : nat) {struct n} : bool :=
-match n, m with
-| 0, _ => true
-| S n', S m' => le n' m'
-| S _, 0 => false
-end.
+Add Morphism minus with signature E ==> E ==> E as minus_wd.
+Proof.
+congruence.
+Qed.
-Delimit Scope NatScope with Nat.
-Open Scope NatScope.
+Add Morphism times with signature E ==> E ==> E as times_wd.
+Proof.
+congruence.
+Qed.
-Module NPeanoBaseMod <: NBaseSig.
+Add Morphism lt with signature E ==> E ==> iff as lt_wd.
+Proof.
+unfold E; intros x1 x2 H1 y1 y2 H2; rewrite H1; now rewrite H2.
+Qed.
-Theorem E_equiv : equiv nat (@eq nat).
-Proof (eq_equiv nat).
+Add Morphism le with signature E ==> E ==> iff as le_wd.
+Proof.
+unfold E; intros x1 x2 H1 y1 y2 H2; rewrite H1; now rewrite H2.
+Qed.
+
+Theorem induction :
+ forall A : nat -> Prop, predicate_wd (@eq nat) A ->
+ A 0 -> (forall n : nat, A n -> A (S n)) -> forall n : nat, A n.
+Proof.
+intros; now apply nat_ind.
+Qed.
+
+Theorem pred_0 : pred 0 = 0.
+Proof.
+reflexivity.
+Qed.
+
+Theorem pred_succ : forall n : nat, pred (S n) = n.
+Proof.
+reflexivity.
+Qed.
+
+Theorem plus_0_l : forall n : nat, 0 + n = n.
+Proof.
+reflexivity.
+Qed.
+
+Theorem plus_succ_l : forall n m : nat, (S n) + m = S (n + m).
+Proof.
+reflexivity.
+Qed.
+
+Theorem minus_0_r : forall n : nat, n - 0 = n.
+Proof.
+intro n; now destruct n.
+Qed.
+
+Theorem minus_succ_r : forall n m : nat, n - (S m) = pred (n - m).
+Proof.
+intros n m; induction n m using nat_double_ind; simpl; auto. apply minus_0_r.
+Qed.
+
+Theorem times_0_r : forall n : nat, n * 0 = 0.
+Proof.
+exact mult_0_r.
+Qed.
+
+Theorem times_succ_r : forall n m : nat, n * (S m) = n * m + n.
+Proof.
+intros n m; symmetry; apply mult_n_Sm.
+Qed.
+
+Theorem le_lt_or_eq : forall n m : nat, n <= m <-> n < m \/ n = m.
+Proof.
+intros n m; split.
+apply le_lt_or_eq.
+intro H; destruct H as [H | H].
+now apply lt_le_weak. rewrite H; apply le_refl.
+Qed.
+
+Theorem nlt_0_r : forall n : nat, ~ (n < 0).
+Proof.
+exact lt_n_O.
+Qed.
+
+Theorem lt_succ_le : forall n m : nat, n < S m <-> n <= m.
+Proof.
+intros n m; split; [apply lt_n_Sm_le | apply le_lt_n_Sm].
+Qed.
+
+Theorem recursion_wd : forall (A : Set) (EA : relation A),
+ forall a a' : A, EA a a' ->
+ forall f f' : N -> A -> A, eq_fun2 (@eq nat) EA EA f f' ->
+ forall n n' : N, n = n' ->
+ EA (recursion a f n) (recursion a' f' n').
+Proof.
+unfold eq_fun2; induction n; intros n' Enn'; rewrite <- Enn' in *; simpl; auto.
+Qed.
+
+Theorem recursion_0 :
+ forall (A : Set) (a : A) (f : N -> A -> A), recursion a f 0 = a.
+Proof.
+reflexivity.
+Qed.
+
+Theorem recursion_succ :
+ forall (A : Set) (EA : relation A) (a : A) (f : N -> A -> A),
+ EA a a -> fun2_wd (@eq nat) EA EA f ->
+ forall n : N, EA (recursion a f (S n)) (f n (recursion a f n)).
+Proof.
+unfold eq_fun2; induction n; simpl; auto.
+Qed.
+
+End NPeanoAxiomsMod.
+
+(* Now we apply the largest property functor *)
+
+Module Export NPeanoMinusPropMod := NMinusPropFunct NPeanoAxiomsMod.
+
+(*
Theorem succ_wd : fun_wd (@eq nat) (@eq nat) S.
Proof.
@@ -77,12 +176,6 @@ Proof.
intros n H; simplify_eq H.
Qed.
-Theorem induction :
- forall A : nat -> Prop, predicate_wd (@eq nat) A ->
- A 0 -> (forall n : nat, A n -> A (S n)) -> forall n : nat, A n.
-Proof.
-intros; now apply nat_ind.
-Qed.
Definition N := nat.
Definition E := (@eq nat).
@@ -318,6 +411,7 @@ Qed.
Add Ring SR : semi_ring (decidable e_implies_E).
Goal forall x y : nat, x + y = y + x. intros. ring.*)
+*)
(*
diff --git a/theories/Numbers/NumPrelude.v b/theories/Numbers/NumPrelude.v
index fd9e9aa8b..6d3ad55a9 100644
--- a/theories/Numbers/NumPrelude.v
+++ b/theories/Numbers/NumPrelude.v
@@ -134,6 +134,23 @@ let y := fresh "y" in
let H := fresh "H" in
intros x y H; qiff x y H.
+Ltac solve_rel_wd :=
+unfold rel_wd, fun2_wd;
+let x1 := fresh "x" in
+let y1 := fresh "y" in
+let H1 := fresh "H" in
+let x2 := fresh "x" in
+let y2 := fresh "y" in
+let H2 := fresh "H" in
+ intros x1 y1 H1 x2 y2 H2;
+ qsetoid_rewrite H1;
+ qiff x2 y2 H2.
+(* The tactic solve_rel_wd is not very efficient because qsetoid_rewrite
+uses qiff to take the formula apart in order to make it quantifier-free,
+and then qiff is called again and takes the formula apart for the second
+time. It is better to analyze the formula once and generalize qiff to take
+a list of equalities that it has to rewrite. *)
+
(* The following tactic uses solve_predicate_wd to solve the goals
relating to well-defidedness that are produced by applying induction.
We declare it to take the tactic that applies the induction theorem
@@ -205,6 +222,10 @@ Ltac rewrite_false P H :=
setoid_replace P with False using relation iff;
[| apply -> neg_false; apply H].
+Ltac rewrite_true P H :=
+setoid_replace P with True using relation iff;
+[| split; intro; [constructor | apply H]].
+
Tactic Notation "symmetry" constr(Eq) :=
lazymatch Eq with
| ?E ?t1 ?t2 => setoid_replace (E t1 t2) with (E t2 t1) using relation iff;