aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2003-11-12 19:26:26 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2003-11-12 19:26:26 +0000
commitaca0bb7546310d87146d27f16b1e98699a23e085 (patch)
tree4eb12f65e66e6acf9361e72488a59ea141c762c7
parentce0730a894791ea19a2ac372a63c94a141102cf8 (diff)
Restructuration ZArith
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@4879 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--Makefile2
-rw-r--r--contrib/omega/OmegaLemmas.v2
-rw-r--r--theories/ZArith/BinInt.v998
-rw-r--r--theories/ZArith/ZArith_base.v7
-rw-r--r--theories/ZArith/Zcompare.v480
-rw-r--r--theories/ZArith/Zcomplements.v43
-rw-r--r--theories/ZArith/Zhints.v5
-rw-r--r--theories/ZArith/Znat.v138
-rw-r--r--theories/ZArith/Zsyntax.v2
-rw-r--r--theories/ZArith/auxiliary.v125
-rw-r--r--theories/ZArith/fast_integer.v1578
-rw-r--r--theories/ZArith/zarith_aux.v6
12 files changed, 1704 insertions, 1682 deletions
diff --git a/Makefile b/Makefile
index c2c39cbc4..2552ec23b 100644
--- a/Makefile
+++ b/Makefile
@@ -585,9 +585,11 @@ NARITHVO=\
theories/NArith/NArith.vo
ZARITHVO=\
+ theories/ZArith/BinInt.vo \
theories/ZArith/Wf_Z.vo theories/ZArith/Zsyntax.vo \
theories/ZArith/ZArith.vo theories/ZArith/auxiliary.vo \
theories/ZArith/ZArith_dec.vo theories/ZArith/fast_integer.vo \
+ theories/ZArith/Zcompare.vo theories/ZArith/Znat.vo \
theories/ZArith/Zmisc.vo theories/ZArith/zarith_aux.vo \
theories/ZArith/Zorder.vo theories/ZArith/Zabs.vo \
theories/ZArith/Zmin.vo theories/ZArith/Zeven.vo \
diff --git a/contrib/omega/OmegaLemmas.v b/contrib/omega/OmegaLemmas.v
index 98922f3fd..c29224069 100644
--- a/contrib/omega/OmegaLemmas.v
+++ b/contrib/omega/OmegaLemmas.v
@@ -78,7 +78,7 @@ Lemma OMEGA8:
Intros x y H1 H2 H3; Elim (Zle_lt_or_eq ZERO x H1); [
Intros H4; Absurd (Zlt ZERO x); [
- Change (Zge ZERO x); Apply Zle_ge; Apply (Zsimpl_le_plus_l y);
+ Change (Zge ZERO x); Apply Zle_ge; Apply Zsimpl_le_plus_l with y;
Rewrite -> H3; Rewrite Zplus_inverse_r; Rewrite Zero_right; Assumption
| Assumption]
| Intros H4; Rewrite -> H4; Trivial with arith].
diff --git a/theories/ZArith/BinInt.v b/theories/ZArith/BinInt.v
new file mode 100644
index 000000000..f7600c7e9
--- /dev/null
+++ b/theories/ZArith/BinInt.v
@@ -0,0 +1,998 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+(***********************************************************)
+(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
+(***********************************************************)
+
+Require Export BinPos.
+Require BinNat.
+Require Plus.
+Require Mult.
+
+(**********************************************************************)
+(** Binary integer numbers *)
+
+Inductive Z : Set :=
+ ZERO : Z | POS : positive -> Z | NEG : positive -> Z.
+
+(** Declare Scope Z_scope with Key Z *)
+Delimits Scope Z_scope with Z.
+
+(** Automatically open scope positive_scope for the constructors of Z *)
+Bind Scope Z_scope with Z.
+Arguments Scope POS [ positive_scope ].
+Arguments Scope NEG [ positive_scope ].
+
+(** Subtraction of positive into Z *)
+
+Definition Zdouble_plus_one [x:Z] :=
+ Cases x of
+ | ZERO => (POS xH)
+ | (POS p) => (POS (xI p))
+ | (NEG p) => (NEG (double_moins_un p))
+ end.
+
+Definition Zdouble_minus_one [x:Z] :=
+ Cases x of
+ | ZERO => (NEG xH)
+ | (NEG p) => (NEG (xI p))
+ | (POS p) => (POS (double_moins_un p))
+ end.
+
+Definition Zdouble [x:Z] :=
+ Cases x of
+ | ZERO => ZERO
+ | (POS p) => (POS (xO p))
+ | (NEG p) => (NEG (xO p))
+ end.
+
+Fixpoint ZPminus [x,y:positive] : Z :=
+ Cases x y of
+ | (xI x') (xI y') => (Zdouble (ZPminus x' y'))
+ | (xI x') (xO y') => (Zdouble_plus_one (ZPminus x' y'))
+ | (xI x') xH => (POS (xO x'))
+ | (xO x') (xI y') => (Zdouble_minus_one (ZPminus x' y'))
+ | (xO x') (xO y') => (Zdouble (ZPminus x' y'))
+ | (xO x') xH => (POS (double_moins_un x'))
+ | xH (xI y') => (NEG (xO y'))
+ | xH (xO y') => (NEG (double_moins_un y'))
+ | xH xH => ZERO
+ end.
+
+(** Addition on integers *)
+
+Definition Zplus := [x,y:Z]
+ Cases x y of
+ ZERO y => y
+ | x ZERO => x
+ | (POS x') (POS y') => (POS (add x' y'))
+ | (POS x') (NEG y') =>
+ Cases (compare x' y' EGAL) of
+ | EGAL => ZERO
+ | INFERIEUR => (NEG (true_sub y' x'))
+ | SUPERIEUR => (POS (true_sub x' y'))
+ end
+ | (NEG x') (POS y') =>
+ Cases (compare x' y' EGAL) of
+ | EGAL => ZERO
+ | INFERIEUR => (POS (true_sub y' x'))
+ | SUPERIEUR => (NEG (true_sub x' y'))
+ end
+ | (NEG x') (NEG y') => (NEG (add x' y'))
+ end.
+
+V8Infix "+" Zplus : Z_scope.
+
+(** Opposite *)
+
+Definition Zopp := [x:Z]
+ Cases x of
+ ZERO => ZERO
+ | (POS x) => (NEG x)
+ | (NEG x) => (POS x)
+ end.
+
+V8Notation "- x" := (Zopp x) : Z_scope.
+
+(** Successor on integers *)
+
+Definition Zs := [x:Z](Zplus x (POS xH)).
+
+(** Predecessor on integers *)
+
+Definition Zpred := [x:Z](Zplus x (NEG xH)).
+
+(** Subtraction on integers *)
+
+Definition Zminus := [m,n:Z](Zplus m (Zopp n)).
+
+V8Infix "-" Zminus : Z_scope.
+
+(** Multiplication on integers *)
+
+Definition Zmult := [x,y:Z]
+ Cases x y of
+ | ZERO _ => ZERO
+ | _ ZERO => ZERO
+ | (POS x') (POS y') => (POS (times x' y'))
+ | (POS x') (NEG y') => (NEG (times x' y'))
+ | (NEG x') (POS y') => (NEG (times x' y'))
+ | (NEG x') (NEG y') => (POS (times x' y'))
+ end.
+
+V8Infix "*" Zmult : Z_scope.
+
+(** Comparison of integers *)
+
+Definition Zcompare := [x,y:Z]
+ Cases x y of
+ | ZERO ZERO => EGAL
+ | ZERO (POS y') => INFERIEUR
+ | ZERO (NEG y') => SUPERIEUR
+ | (POS x') ZERO => SUPERIEUR
+ | (POS x') (POS y') => (compare x' y' EGAL)
+ | (POS x') (NEG y') => SUPERIEUR
+ | (NEG x') ZERO => INFERIEUR
+ | (NEG x') (POS y') => INFERIEUR
+ | (NEG x') (NEG y') => (Op (compare x' y' EGAL))
+ end.
+
+V8Infix "?=" Zcompare (at level 70, no associativity) : Z_scope.
+
+Tactic Definition ElimCompare com1 com2:=
+ Case (Dcompare (Zcompare com1 com2)); [ Idtac |
+ Let x = FreshId "H" In Intro x; Case x; Clear x ].
+
+(** Sign function *)
+
+Definition Zsgn [z:Z] : Z :=
+ Cases z of
+ ZERO => ZERO
+ | (POS p) => (POS xH)
+ | (NEG p) => (NEG xH)
+ end.
+
+(** Direct, easier to handle variants of successor and addition *)
+
+Definition Zsucc' [x:Z] :=
+ Cases x of
+ | ZERO => (POS xH)
+ | (POS x') => (POS (add_un x'))
+ | (NEG x') => (ZPminus xH x')
+ end.
+
+Definition Zpred' [x:Z] :=
+ Cases x of
+ | ZERO => (NEG xH)
+ | (POS x') => (ZPminus x' xH)
+ | (NEG x') => (NEG (add_un x'))
+ end.
+
+Definition Zplus' := [x,y:Z]
+ Cases x y of
+ ZERO y => y
+ | x ZERO => x
+ | (POS x') (POS y') => (POS (add x' y'))
+ | (POS x') (NEG y') => (ZPminus x' y')
+ | (NEG x') (POS y') => (ZPminus y' x')
+ | (NEG x') (NEG y') => (NEG (add x' y'))
+ end.
+
+Open Local Scope Z_scope.
+
+(**********************************************************************)
+(** Inductive specification of Z *)
+
+Theorem Zind : (P:(Z ->Prop))
+ (P ZERO) -> ((x:Z)(P x) ->(P (Zsucc' x))) -> ((x:Z)(P x) ->(P (Zpred' x))) ->
+ (z:Z)(P z).
+Proof.
+Intros P H0 Hs Hp z; NewDestruct z.
+ Assumption.
+ Apply Pind with P:=[p](P (POS p)).
+ Change (P (Zsucc' ZERO)); Apply Hs; Apply H0.
+ Intro n; Exact (Hs (POS n)).
+ Apply Pind with P:=[p](P (NEG p)).
+ Change (P (Zpred' ZERO)); Apply Hp; Apply H0.
+ Intro n; Exact (Hp (NEG n)).
+Qed.
+
+(**********************************************************************)
+(** Properties of opposite on binary integer numbers *)
+
+Theorem Zopp_NEG : (x:positive) (Zopp (NEG x)) = (POS x).
+Proof.
+Reflexivity.
+Qed.
+
+(** [opp] is involutive *)
+
+Theorem Zopp_Zopp: (x:Z) (Zopp (Zopp x)) = x.
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+
+(** Injectivity of the opposite *)
+
+Theorem Zopp_intro : (x,y:Z) (Zopp x) = (Zopp y) -> x = y.
+Proof.
+Intros x y;Case x;Case y;Simpl;Intros; [
+ Trivial | Discriminate H | Discriminate H | Discriminate H
+| Simplify_eq H; Intro E; Rewrite E; Trivial
+| Discriminate H | Discriminate H | Discriminate H
+| Simplify_eq H; Intro E; Rewrite E; Trivial ].
+Qed.
+
+(**********************************************************************)
+(* Properties of the direct definition of successor and predecessor *)
+
+Lemma Zpred'_succ' : (x:Z)(Zpred' (Zsucc' x))=x.
+Proof.
+Intro x; NewDestruct x; Simpl.
+ Reflexivity.
+NewDestruct p; Simpl; Try Rewrite double_moins_un_add_un_xI; Reflexivity.
+NewDestruct p; Simpl; Try Rewrite is_double_moins_un; Reflexivity.
+Qed.
+
+Lemma Zsucc'_discr : (x:Z)x<>(Zsucc' x).
+Proof.
+Intro x; NewDestruct x; Simpl.
+ Discriminate.
+ Injection; Apply add_un_discr.
+ NewDestruct p; Simpl.
+ Discriminate.
+ Intro H; Symmetry in H; Injection H; Apply double_moins_un_xO_discr.
+ Discriminate.
+Qed.
+
+(**********************************************************************)
+(** Other properties of binary integer numbers *)
+
+Hints Local Resolve compare_convert_O.
+
+Lemma ZL0 : (S (S O))=(plus (S O) (S O)).
+Proof.
+Reflexivity.
+Qed.
+
+(**********************************************************************)
+(** Properties of the addition on integers *)
+
+(** zero is left neutral for addition *)
+
+Theorem Zero_left: (x:Z) (Zplus ZERO x) = x.
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+
+(** zero is right neutral for addition *)
+
+Theorem Zero_right: (x:Z) (Zplus x ZERO) = x.
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+
+(** addition is commutative *)
+
+Theorem Zplus_sym: (x,y:Z) (Zplus x y) = (Zplus y x).
+Proof.
+Intro x;NewInduction x as [|p|p];Intro y; NewDestruct y as [|q|q];Simpl;Try Reflexivity.
+ Rewrite add_sym; Reflexivity.
+ Rewrite ZC4; NewDestruct (compare q p EGAL); Reflexivity.
+ Rewrite ZC4; NewDestruct (compare q p EGAL); Reflexivity.
+ Rewrite add_sym; Reflexivity.
+Qed.
+
+(** opposite distributes over addition *)
+
+Theorem Zopp_Zplus:
+ (x,y:Z) (Zopp (Zplus x y)) = (Zplus (Zopp x) (Zopp y)).
+Proof.
+Intro x; NewDestruct x as [|p|p]; Intro y; NewDestruct y as [|q|q]; Simpl;
+ Reflexivity Orelse NewDestruct (compare p q EGAL); Reflexivity.
+Qed.
+
+(** opposite is inverse for addition *)
+
+Theorem Zplus_inverse_r: (x:Z) (Zplus x (Zopp x)) = ZERO.
+Proof.
+Intro x; NewDestruct x as [|p|p]; Simpl; [
+ Reflexivity
+| Rewrite (convert_compare_EGAL p); Reflexivity
+| Rewrite (convert_compare_EGAL p); Reflexivity ].
+Qed.
+
+Theorem Zplus_inverse_l: (x:Z) (Zplus (Zopp x) x) = ZERO.
+Proof.
+Intro; Rewrite Zplus_sym; Apply Zplus_inverse_r.
+Qed.
+
+Hints Local Resolve Zero_left Zero_right.
+
+(** addition is associative *)
+
+Lemma weak_assoc :
+ (x,y:positive)(z:Z) (Zplus (POS x) (Zplus (POS y) z))=
+ (Zplus (Zplus (POS x) (POS y)) z).
+Proof.
+Intros x y z';Case z'; [
+ Auto with arith
+| Intros z;Simpl; Rewrite add_assoc;Auto with arith
+| Intros z; Simpl; ElimPcompare y z;
+ Intros E0;Rewrite E0;
+ ElimPcompare '(add x y) 'z;Intros E1;Rewrite E1; [
+ Absurd (compare (add x y) z EGAL)=EGAL; [ (* Case 1 *)
+ Rewrite convert_compare_SUPERIEUR; [
+ Discriminate
+ | Rewrite convert_add; Rewrite (compare_convert_EGAL y z E0);
+ Elim (ZL4 x);Intros k E2;Rewrite E2; Simpl; Unfold gt lt; Apply le_n_S;
+ Apply le_plus_r ]
+ | Assumption ]
+ | Absurd (compare (add x y) z EGAL)=INFERIEUR; [ (* Case 2 *)
+ Rewrite convert_compare_SUPERIEUR; [
+ Discriminate
+ | Rewrite convert_add; Rewrite (compare_convert_EGAL y z E0);
+ Elim (ZL4 x);Intros k E2;Rewrite E2; Simpl; Unfold gt lt; Apply le_n_S;
+ Apply le_plus_r]
+ | Assumption ]
+ | Rewrite (compare_convert_EGAL y z E0); (* Case 3 *)
+ Elim (sub_pos_SUPERIEUR (add x z) z);[
+ Intros t H; Elim H;Intros H1 H2;Elim H2;Intros H3 H4;
+ Unfold true_sub; Rewrite H1; Cut x=t; [
+ Intros E;Rewrite E;Auto with arith
+ | Apply simpl_add_r with z:=z; Rewrite <- H3; Rewrite add_sym; Trivial with arith ]
+ | Pattern 1 z; Rewrite <- (compare_convert_EGAL y z E0); Assumption ]
+ | Elim (sub_pos_SUPERIEUR z y); [ (* Case 4 *)
+ Intros k H;Elim H;Intros H1 H2;Elim H2;Intros H3 H4; Unfold 1 true_sub;
+ Rewrite H1; Cut x=k; [
+ Intros E;Rewrite E; Rewrite (convert_compare_EGAL k); Trivial with arith
+ | Apply simpl_add_r with z:=y; Rewrite (add_sym k y); Rewrite H3;
+ Apply compare_convert_EGAL; Assumption ]
+ | Apply ZC2;Assumption]
+ | Elim (sub_pos_SUPERIEUR z y); [ (* Case 5 *)
+ Intros k H;Elim H;Intros H1 H2;Elim H2;Intros H3 H4;
+ Unfold 1 3 5 true_sub; Rewrite H1;
+ Cut (compare x k EGAL)=INFERIEUR; [
+ Intros E2;Rewrite E2; Elim (sub_pos_SUPERIEUR k x); [
+ Intros i H5;Elim H5;Intros H6 H7;Elim H7;Intros H8 H9;
+ Elim (sub_pos_SUPERIEUR z (add x y)); [
+ Intros j H10;Elim H10;Intros H11 H12;Elim H12;Intros H13 H14;
+ Unfold true_sub ;Rewrite H6;Rewrite H11; Cut i=j; [
+ Intros E;Rewrite E;Auto with arith
+ | Apply (simpl_add_l (add x y)); Rewrite H13;
+ Rewrite (add_sym x y); Rewrite <- add_assoc; Rewrite H8;
+ Assumption ]
+ | Apply ZC2; Assumption]
+ | Apply ZC2;Assumption]
+ | Apply convert_compare_INFERIEUR;
+ Apply simpl_lt_plus_l with p:=(convert y);
+ Do 2 Rewrite <- convert_add; Apply compare_convert_INFERIEUR;
+ Rewrite H3; Rewrite add_sym; Assumption ]
+ | Apply ZC2; Assumption ]
+ | Elim (sub_pos_SUPERIEUR z y); [ (* Case 6 *)
+ Intros k H;Elim H;Intros H1 H2;Elim H2;Intros H3 H4;
+ Elim (sub_pos_SUPERIEUR (add x y) z); [
+ Intros i H5;Elim H5;Intros H6 H7;Elim H7;Intros H8 H9;
+ Unfold true_sub; Rewrite H1;Rewrite H6;
+ Cut (compare x k EGAL)=SUPERIEUR; [
+ Intros H10;Elim (sub_pos_SUPERIEUR x k H10);
+ Intros j H11;Elim H11;Intros H12 H13;Elim H13;Intros H14 H15;
+ Rewrite H10; Rewrite H12; Cut i=j; [
+ Intros H16;Rewrite H16;Auto with arith
+ | Apply (simpl_add_l (add z k)); Rewrite <- (add_assoc z k j);
+ Rewrite H14; Rewrite (add_sym z k); Rewrite <- add_assoc;
+ Rewrite H8; Rewrite (add_sym x y); Rewrite add_assoc;
+ Rewrite (add_sym k y); Rewrite H3; Trivial with arith]
+ | Apply convert_compare_SUPERIEUR; Unfold lt gt;
+ Apply simpl_lt_plus_l with p:=(convert y);
+ Do 2 Rewrite <- convert_add; Apply compare_convert_INFERIEUR;
+ Rewrite H3; Rewrite add_sym; Apply ZC1; Assumption ]
+ | Assumption ]
+ | Apply ZC2;Assumption ]
+ | Absurd (compare (add x y) z EGAL)=EGAL; [ (* Case 7 *)
+ Rewrite convert_compare_SUPERIEUR; [
+ Discriminate
+ | Rewrite convert_add; Unfold gt;Apply lt_le_trans with m:=(convert y);[
+ Apply compare_convert_INFERIEUR; Apply ZC1; Assumption
+ | Apply le_plus_r]]
+ | Assumption ]
+ | Absurd (compare (add x y) z EGAL)=INFERIEUR; [ (* Case 8 *)
+ Rewrite convert_compare_SUPERIEUR; [
+ Discriminate
+ | Unfold gt; Apply lt_le_trans with m:=(convert y);[
+ Exact (compare_convert_SUPERIEUR y z E0)
+ | Rewrite convert_add; Apply le_plus_r]]
+ | Assumption ]
+ | Elim sub_pos_SUPERIEUR with 1:=E0;Intros k H1; (* Case 9 *)
+ Elim sub_pos_SUPERIEUR with 1:=E1; Intros i H2;Elim H1;Intros H3 H4;
+ Elim H4;Intros H5 H6; Elim H2;Intros H7 H8;Elim H8;Intros H9 H10;
+ Unfold true_sub ;Rewrite H3;Rewrite H7; Cut (add x k)=i; [
+ Intros E;Rewrite E;Auto with arith
+ | Apply (simpl_add_l z);Rewrite (add_sym x k);
+ Rewrite add_assoc; Rewrite H5;Rewrite H9;
+ Rewrite add_sym; Trivial with arith ]]].
+Qed.
+
+Hints Local Resolve weak_assoc.
+
+Theorem Zplus_assoc :
+ (n,m,p:Z) (Zplus n (Zplus m p))= (Zplus (Zplus n m) p).
+Proof.
+Intros x y z;Case x;Case y;Case z;Auto with arith; Intros; [
+ Rewrite (Zplus_sym (NEG p0)); Rewrite weak_assoc;
+ Rewrite (Zplus_sym (Zplus (POS p1) (NEG p0))); Rewrite weak_assoc;
+ Rewrite (Zplus_sym (POS p1)); Trivial with arith
+| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus;
+ Do 2 Rewrite Zopp_NEG; Rewrite Zplus_sym; Rewrite <- weak_assoc;
+ Rewrite (Zplus_sym (Zopp (POS p1)));
+ Rewrite (Zplus_sym (Zplus (POS p0) (Zopp (POS p1))));
+ Rewrite (weak_assoc p); Rewrite weak_assoc; Rewrite (Zplus_sym (POS p0));
+ Trivial with arith
+| Rewrite Zplus_sym; Rewrite (Zplus_sym (POS p0) (POS p));
+ Rewrite <- weak_assoc; Rewrite Zplus_sym; Rewrite (Zplus_sym (POS p0));
+ Trivial with arith
+| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus;
+ Do 2 Rewrite Zopp_NEG; Rewrite (Zplus_sym (Zopp (POS p0)));
+ Rewrite weak_assoc; Rewrite (Zplus_sym (Zplus (POS p1) (Zopp (POS p0))));
+ Rewrite weak_assoc;Rewrite (Zplus_sym (POS p)); Trivial with arith
+| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus; Do 2 Rewrite Zopp_NEG;
+ Apply weak_assoc
+| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus; Do 2 Rewrite Zopp_NEG;
+ Apply weak_assoc]
+.
+Qed.
+
+V7only [Notation Zplus_assoc_l := Zplus_assoc.].
+
+Lemma Zplus_assoc_r : (n,m,p:Z)(Zplus (Zplus n m) p) =(Zplus n (Zplus m p)).
+Proof.
+Intros; Symmetry; Apply Zplus_assoc.
+Qed.
+
+(** Associativity mixed with commutativity *)
+
+Theorem Zplus_permute : (n,m,p:Z) (Zplus n (Zplus m p))=(Zplus m (Zplus n p)).
+Proof.
+Intros n m p;
+Rewrite Zplus_sym;Rewrite <- Zplus_assoc; Rewrite (Zplus_sym p n); Trivial with arith.
+Qed.
+
+(** addition simplifies *)
+
+Theorem Zsimpl_plus_l : (n,m,p:Z)(Zplus n m)=(Zplus n p)->m=p.
+Intros n m p H; Cut (Zplus (Zopp n) (Zplus n m))=(Zplus (Zopp n) (Zplus n p));[
+ Do 2 Rewrite -> Zplus_assoc; Rewrite -> (Zplus_sym (Zopp n) n);
+ Rewrite -> Zplus_inverse_r;Simpl; Trivial with arith
+| Rewrite -> H; Trivial with arith ].
+Qed.
+
+(** addition and successor permutes *)
+
+Lemma Zplus_S_n: (x,y:Z) (Zplus (Zs x) y) = (Zs (Zplus x y)).
+Proof.
+Intros x y; Unfold Zs; Rewrite (Zplus_sym (Zplus x y)); Rewrite Zplus_assoc;
+Rewrite (Zplus_sym (POS xH)); Trivial with arith.
+Qed.
+
+Lemma Zplus_n_Sm : (n,m:Z) (Zs (Zplus n m))=(Zplus n (Zs m)).
+Proof.
+Intros n m; Unfold Zs; Rewrite Zplus_assoc; Trivial with arith.
+Qed.
+
+Lemma Zplus_Snm_nSm : (n,m:Z)(Zplus (Zs n) m)=(Zplus n (Zs m)).
+Proof.
+Unfold Zs ;Intros n m; Rewrite <- Zplus_assoc; Rewrite (Zplus_sym (POS xH));
+Trivial with arith.
+Qed.
+
+(** Misc properties, usually redundant or non natural *)
+
+Lemma Zplus_n_O : (n:Z) n=(Zplus n ZERO).
+Proof.
+Symmetry; Apply Zero_right.
+Qed.
+
+Lemma Zplus_unit_left : (n,m:Z) (Zplus n ZERO)=m -> n=m.
+Proof.
+Intros n m; Rewrite Zero_right; Intro; Assumption.
+Qed.
+
+Lemma Zplus_unit_right : (n,m:Z) n=(Zplus m ZERO) -> n=m.
+Proof.
+Intros n m; Rewrite Zero_right; Intro; Assumption.
+Qed.
+
+Lemma Zplus_simpl : (x,y,z,t:Z) x=y -> z=t -> (Zplus x z)=(Zplus y t).
+Proof.
+Intros; Rewrite H; Rewrite H0; Reflexivity.
+Qed.
+
+Lemma Zplus_Zopp_expand : (x,y,z:Z)
+ (Zplus x (Zopp y))=(Zplus (Zplus x (Zopp z)) (Zplus z (Zopp y))).
+Proof.
+Intros x y z.
+Rewrite <- (Zplus_assoc x).
+Rewrite (Zplus_assoc (Zopp z)).
+Rewrite Zplus_inverse_l.
+Reflexivity.
+Qed.
+
+(**********************************************************************)
+(** Properties of successor and predecessor on binary integer numbers *)
+
+Theorem Zn_Sn : (x:Z) ~ x=(Zs x).
+Proof.
+Intros n;Cut ~ZERO=(POS xH);[
+ Unfold not ;Intros H1 H2;Apply H1;Apply (Zsimpl_plus_l n);Rewrite Zero_right;
+ Exact H2
+| Discriminate ].
+Qed.
+
+Theorem add_un_Zs : (x:positive) (POS (add_un x)) = (Zs (POS x)).
+Proof.
+Intro; Rewrite -> ZL12; Unfold Zs; Simpl; Trivial with arith.
+Qed.
+
+(** successor and predecessor are inverse functions *)
+
+Theorem Zs_pred : (n:Z) n=(Zs (Zpred n)).
+Proof.
+Intros n; Unfold Zs Zpred ;Rewrite <- Zplus_assoc; Simpl; Rewrite Zero_right;
+Trivial with arith.
+Qed.
+
+Hints Immediate Zs_pred : zarith.
+
+Theorem Zpred_Sn : (x:Z) x=(Zpred (Zs x)).
+Proof.
+Intros m; Unfold Zpred Zs; Rewrite <- Zplus_assoc; Simpl;
+Rewrite Zplus_sym; Auto with arith.
+Qed.
+
+Theorem Zeq_add_S : (n,m:Z) (Zs n)=(Zs m) -> n=m.
+Proof.
+Intros n m H.
+Change (Zplus (Zplus (NEG xH) (POS xH)) n)=
+ (Zplus (Zplus (NEG xH) (POS xH)) m);
+Do 2 Rewrite <- Zplus_assoc; Do 2 Rewrite (Zplus_sym (POS xH));
+Unfold Zs in H;Rewrite H; Trivial with arith.
+Qed.
+
+(** Misc properties, usually redundant or non natural *)
+
+Lemma Zeq_S : (n,m:Z) n=m -> (Zs n)=(Zs m).
+Proof.
+Intros n m H; Rewrite H; Reflexivity.
+Qed.
+
+Lemma Znot_eq_S : (n,m:Z) ~(n=m) -> ~((Zs n)=(Zs m)).
+Proof.
+Unfold not ;Intros n m H1 H2;Apply H1;Apply Zeq_add_S; Assumption.
+Qed.
+
+(**********************************************************************)
+(** Properties of subtraction on binary integer numbers *)
+
+Lemma Zminus_0_r : (x:Z) (Zminus x ZERO)=x.
+Proof.
+Intro; Unfold Zminus; Simpl;Rewrite Zero_right; Trivial with arith.
+Qed.
+
+Lemma Zminus_n_O : (x:Z) x=(Zminus x ZERO).
+Proof.
+Intro; Symmetry; Apply Zminus_0_r.
+Qed.
+
+Lemma Zminus_diag : (n:Z)(Zminus n n)=ZERO.
+Proof.
+Intro; Unfold Zminus; Rewrite Zplus_inverse_r; Trivial with arith.
+Qed.
+
+Lemma Zminus_n_n : (n:Z)(ZERO=(Zminus n n)).
+Proof.
+Intro; Symmetry; Apply Zminus_diag.
+Qed.
+
+Lemma Zplus_minus : (x,y,z:Z)(x=(Zplus y z))->(z=(Zminus x y)).
+Proof.
+Intros n m p H;Unfold Zminus;Apply (Zsimpl_plus_l m);
+Rewrite (Zplus_sym m (Zplus n (Zopp m))); Rewrite <- Zplus_assoc;
+Rewrite Zplus_inverse_l; Rewrite Zero_right; Rewrite H; Trivial with arith.
+Qed.
+
+Lemma Zminus_plus : (x,y:Z)(Zminus (Zplus x y) x)=y.
+Proof.
+Intros n m;Unfold Zminus ;Rewrite -> (Zplus_sym n m);Rewrite <- Zplus_assoc;
+Rewrite -> Zplus_inverse_r; Apply Zero_right.
+Qed.
+
+Lemma Zle_plus_minus : (n,m:Z) (Zplus n (Zminus m n))=m.
+Proof.
+Unfold Zminus; Intros n m; Rewrite Zplus_permute; Rewrite Zplus_inverse_r;
+Apply Zero_right.
+Qed.
+
+Lemma Zminus_Sn_m : (n,m:Z)((Zs (Zminus n m))=(Zminus (Zs n) m)).
+Proof.
+Intros n m;Unfold Zminus Zs; Rewrite (Zplus_sym n (Zopp m));
+Rewrite <- Zplus_assoc;Apply Zplus_sym.
+Qed.
+
+Lemma Zminus_plus_simpl_l :
+ (x,y,z:Z)(Zminus (Zplus z x) (Zplus z y))=(Zminus x y).
+Proof.
+Intros n m p;Unfold Zminus; Rewrite Zopp_Zplus; Rewrite Zplus_assoc;
+Rewrite (Zplus_sym p); Rewrite <- (Zplus_assoc n p); Rewrite Zplus_inverse_r;
+Rewrite Zero_right; Trivial with arith.
+Qed.
+
+Lemma Zminus_plus_simpl :
+ (x,y,z:Z)((Zminus x y)=(Zminus (Zplus z x) (Zplus z y))).
+Proof.
+Intros; Symmetry; Apply Zminus_plus_simpl_l.
+Qed.
+
+Lemma Zminus_Zplus_compatible :
+ (x,y,z:Z) (Zminus (Zplus x z) (Zplus y z)) = (Zminus x y).
+Intros x y n.
+Unfold Zminus.
+Rewrite -> Zopp_Zplus.
+Rewrite -> (Zplus_sym (Zopp y) (Zopp n)).
+Rewrite -> Zplus_assoc.
+Rewrite <- (Zplus_assoc x n (Zopp n)).
+Rewrite -> (Zplus_inverse_r n).
+Rewrite <- Zplus_n_O.
+Reflexivity.
+Qed.
+
+(** Misc redundant properties *)
+
+V7only [Set Implicit Arguments.].
+
+Lemma Zeq_Zminus : (x,y:Z)x=y -> (Zminus x y)=ZERO.
+Proof.
+Intros x y H; Rewrite H; Symmetry; Apply Zminus_n_n.
+Qed.
+
+Lemma Zminus_Zeq : (x,y:Z)(Zminus x y)=ZERO -> x=y.
+Proof.
+Intros x y H; Rewrite <- (Zle_plus_minus y x); Rewrite H; Apply Zero_right.
+Qed.
+
+V7only [Unset Implicit Arguments.].
+
+(**********************************************************************)
+(** Properties of multiplication on binary integer numbers *)
+
+(** One is neutral for multiplication *)
+
+Theorem Zmult_1_n : (n:Z)(Zmult (POS xH) n)=n.
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+V7only [Notation Zmult_one := Zmult_1_n.].
+
+Theorem Zmult_n_1 : (n:Z)(Zmult n (POS xH))=n.
+Proof.
+Intro x; NewDestruct x; Simpl; Try Rewrite times_x_1; Reflexivity.
+Qed.
+
+(** Zero is absorbant for multiplication *)
+
+Theorem Zero_mult_left: (x:Z) (Zmult ZERO x) = ZERO.
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+
+Theorem Zero_mult_right: (x:Z) (Zmult x ZERO) = ZERO.
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+
+Hints Local Resolve Zero_mult_left Zero_mult_right.
+
+Lemma Zmult_n_O : (n:Z) ZERO=(Zmult n ZERO).
+Proof.
+Intro x; NewDestruct x; Reflexivity.
+Qed.
+
+(** Commutativity of multiplication *)
+
+Theorem Zmult_sym : (x,y:Z) (Zmult x y) = (Zmult y x).
+Proof.
+Intros x y; NewDestruct x as [|p|p]; NewDestruct y as [|q|q]; Simpl;
+ Try Rewrite (times_sym p q); Reflexivity.
+Qed.
+
+(** Associativity of multiplication *)
+
+Theorem Zmult_assoc :
+ (x,y,z:Z) (Zmult x (Zmult y z))= (Zmult (Zmult x y) z).
+Proof.
+Intros x y z; NewDestruct x; NewDestruct y; NewDestruct z; Simpl;
+ Try Rewrite times_assoc; Reflexivity.
+Qed.
+V7only [Notation Zmult_assoc_l := Zmult_assoc.].
+
+Lemma Zmult_assoc_r : (n,m,p:Z)((Zmult (Zmult n m) p) = (Zmult n (Zmult m p))).
+Proof.
+Intros n m p; Rewrite Zmult_assoc; Trivial with arith.
+Qed.
+
+(** Associativity mixed with commutativity *)
+
+Theorem Zmult_permute : (n,m,p:Z)(Zmult n (Zmult m p)) = (Zmult m (Zmult n p)).
+Proof.
+Intros x y z; Rewrite -> (Zmult_assoc y x z); Rewrite -> (Zmult_sym y x).
+Apply Zmult_assoc.
+Qed.
+
+(** Z is integral *)
+
+Theorem Zmult_eq: (x,y:Z) ~(x=ZERO) -> (Zmult y x) = ZERO -> y = ZERO.
+Proof.
+Intros x y; NewDestruct x as [|p|p].
+ Intro H; Absurd ZERO=ZERO; Trivial.
+ Intros _ H; NewDestruct y as [|q|q]; Reflexivity Orelse Discriminate.
+ Intros _ H; NewDestruct y as [|q|q]; Reflexivity Orelse Discriminate.
+Qed.
+
+V7only [Set Implicit Arguments.].
+
+Theorem Zmult_zero : (x,y:Z)(Zmult x y)=ZERO -> x=ZERO \/ y=ZERO.
+Proof.
+Intros x y; NewDestruct x; NewDestruct y; Auto; Simpl; Intro H; Discriminate H.
+Qed.
+
+V7only [Unset Implicit Arguments.].
+
+(** Multiplication and Opposite *)
+
+Theorem Zopp_Zmult_l : (x,y:Z)(Zopp (Zmult x y)) = (Zmult (Zopp x) y).
+Proof.
+Intros x y; NewDestruct x; NewDestruct y; Reflexivity.
+Qed.
+
+Theorem Zopp_Zmult_r : (x,y:Z)(Zopp (Zmult x y)) = (Zmult x (Zopp y)).
+Intros x y; Rewrite (Zmult_sym x y); Rewrite Zopp_Zmult_l; Apply Zmult_sym.
+Qed.
+
+Theorem Zopp_Zmult: (x,y:Z) (Zmult (Zopp x) y) = (Zopp (Zmult x y)).
+Proof.
+Intros x y; Symmetry; Apply Zopp_Zmult_l.
+Qed.
+
+Theorem Zmult_Zopp_left : (x,y:Z)(Zmult (Zopp x) y) = (Zmult x (Zopp y)).
+Intros x y; Rewrite Zopp_Zmult; Rewrite Zopp_Zmult_r; Trivial with arith.
+Qed.
+
+Theorem Zmult_Zopp_Zopp: (x,y:Z) (Zmult (Zopp x) (Zopp y)) = (Zmult x y).
+Proof.
+Intros x y; NewDestruct x; NewDestruct y; Reflexivity.
+Qed.
+
+Theorem Zopp_one : (x:Z)(Zopp x)=(Zmult x (NEG xH)).
+Intro x; NewInduction x; Intros; Rewrite Zmult_sym; Auto with arith.
+Qed.
+
+(** Distributivity of multiplication over addition *)
+
+Lemma weak_Zmult_plus_distr_r:
+ (x:positive)(y,z:Z)
+ (Zmult (POS x) (Zplus y z)) = (Zplus (Zmult (POS x) y) (Zmult (POS x) z)).
+Proof.
+Intros x y' z';Case y';Case z';Auto with arith;Intros y z;
+ (Simpl; Rewrite times_add_distr; Trivial with arith)
+Orelse
+ (Simpl; ElimPcompare z y; Intros E0;Rewrite E0; [
+ Rewrite (compare_convert_EGAL z y E0);
+ Rewrite (convert_compare_EGAL (times x y)); Trivial with arith
+ | Cut (compare (times x z) (times x y) EGAL)=INFERIEUR; [
+ Intros E;Rewrite E; Rewrite times_true_sub_distr; [
+ Trivial with arith
+ | Apply ZC2;Assumption ]
+ | Apply convert_compare_INFERIEUR;Do 2 Rewrite times_convert;
+ Elim (ZL4 x);Intros h H1;Rewrite H1;Apply lt_mult_left;
+ Exact (compare_convert_INFERIEUR z y E0)]
+ | Cut (compare (times x z) (times x y) EGAL)=SUPERIEUR; [
+ Intros E;Rewrite E; Rewrite times_true_sub_distr; Auto with arith
+ | Apply convert_compare_SUPERIEUR; Unfold gt; Do 2 Rewrite times_convert;
+ Elim (ZL4 x);Intros h H1;Rewrite H1;Apply lt_mult_left;
+ Exact (compare_convert_SUPERIEUR z y E0) ]]).
+Qed.
+
+Theorem Zmult_plus_distr_r:
+ (x,y,z:Z) (Zmult x (Zplus y z)) = (Zplus (Zmult x y) (Zmult x z)).
+Proof.
+Intros x y z; Case x; [
+ Auto with arith
+| Intros x';Apply weak_Zmult_plus_distr_r
+| Intros p; Apply Zopp_intro; Rewrite Zopp_Zplus;
+ Do 3 Rewrite <- Zopp_Zmult; Rewrite Zopp_NEG;
+ Apply weak_Zmult_plus_distr_r ].
+Qed.
+
+Lemma Zmult_plus_distr_l :
+ (n,m,p:Z)((Zmult (Zplus n m) p)=(Zplus (Zmult n p) (Zmult m p))).
+Proof.
+Intros n m p;Rewrite Zmult_sym;Rewrite Zmult_plus_distr_r;
+Do 2 Rewrite -> (Zmult_sym p); Trivial with arith.
+Qed.
+
+(** Distributivity of multiplication over subtraction *)
+
+Lemma Zmult_Zminus_distr_l :
+ (x,y,z:Z)((Zmult (Zminus x y) z)=(Zminus (Zmult x z) (Zmult y z))).
+Proof.
+Intros x y z; Unfold Zminus.
+Rewrite <- Zopp_Zmult.
+Apply Zmult_plus_distr_l.
+Qed.
+
+V7only [Notation Zmult_minus_distr := Zmult_Zminus_distr_l.].
+
+Lemma Zmult_Zminus_distr_r :
+ (x,y,z:Z)(Zmult z (Zminus x y)) = (Zminus (Zmult z x) (Zmult z y)).
+Proof.
+Intros x y z; Rewrite (Zmult_sym z (Zminus x y)).
+Rewrite (Zmult_sym z x).
+Rewrite (Zmult_sym z y).
+Apply Zmult_Zminus_distr_l.
+Qed.
+
+(** Simplification of multiplication for non-zero integers *)
+V7only [Set Implicit Arguments.].
+
+Lemma Zmult_reg_left : (x,y,z:Z) z<>ZERO -> (Zmult z x)=(Zmult z y) -> x=y.
+Proof.
+Intros x y z H H0.
+Generalize (Zeq_Zminus H0).
+Intro.
+Apply Zminus_Zeq.
+Rewrite <- Zmult_Zminus_distr_r in H1.
+Clear H0; NewDestruct (Zmult_zero H1).
+Contradiction.
+Trivial.
+Qed.
+
+Lemma Zmult_reg_right : (x,y,z:Z) z<>ZERO -> (Zmult x z)=(Zmult y z) -> x=y.
+Proof.
+Intros x y z Hz.
+Rewrite (Zmult_sym x z).
+Rewrite (Zmult_sym y z).
+Intro; Apply Zmult_reg_left with z; Assumption.
+Qed.
+V7only [Unset Implicit Arguments.].
+
+(** Addition and multiplication by 2 *)
+
+Lemma Zplus_Zmult_2 : (x:Z) (Zplus x x) = (Zmult x (POS (xO xH))).
+Proof.
+Intros x; Pattern 1 2 x ; Rewrite <- (Zmult_n_1 x);
+Rewrite <- Zmult_plus_distr_r; Reflexivity.
+Qed.
+
+(** Multiplication and successor *)
+
+Lemma Zmult_succ_r : (n,m:Z) (Zmult n (Zs m))=(Zplus (Zmult n m) n).
+Proof.
+Intros n m;Unfold Zs; Rewrite Zmult_plus_distr_r;
+Rewrite (Zmult_sym n (POS xH));Rewrite Zmult_one; Trivial with arith.
+Qed.
+
+Lemma Zmult_n_Sm : (n,m:Z) (Zplus (Zmult n m) n)=(Zmult n (Zs m)).
+Proof.
+Intros; Symmetry; Apply Zmult_succ_r.
+Qed.
+
+Lemma Zmult_succ_l : (n,m:Z) (Zmult (Zs n) m)=(Zplus (Zmult n m) m).
+Proof.
+Intros n m; Unfold Zs; Rewrite Zmult_plus_distr_l; Rewrite Zmult_1_n;
+Trivial with arith.
+Qed.
+
+Lemma Zmult_Sm_n : (n,m:Z) (Zplus (Zmult n m) m)=(Zmult (Zs n) m).
+Proof.
+Intros; Symmetry; Apply Zmult_succ_l.
+Qed.
+
+(** Misc redundant properties *)
+
+Lemma Z_eq_mult:
+ (x,y:Z) y = ZERO -> (Zmult y x) = ZERO.
+Intros x y H; Rewrite H; Auto with arith.
+Qed.
+
+(**********************************************************************)
+(** Relating binary positive numbers and binary integers *)
+
+Lemma POS_xI : (p:positive) (POS (xI p))=(Zplus (Zmult (POS (xO xH)) (POS p)) (POS xH)).
+Proof.
+Intro; Apply refl_equal.
+Qed.
+
+Lemma POS_xO : (p:positive) (POS (xO p))=(Zmult (POS (xO xH)) (POS p)).
+Proof.
+Intro; Apply refl_equal.
+Qed.
+
+Lemma NEG_xI : (p:positive) (NEG (xI p))=(Zminus (Zmult (POS (xO xH)) (NEG p)) (POS xH)).
+Proof.
+Intro; Apply refl_equal.
+Qed.
+
+Lemma NEG_xO : (p:positive) (NEG (xO p))=(Zmult (POS (xO xH)) (NEG p)).
+Proof.
+Reflexivity.
+Qed.
+
+Lemma POS_add : (p,p':positive)(POS (add p p'))=(Zplus (POS p) (POS p')).
+Proof.
+Intros p p'; NewDestruct p; NewDestruct p'; Reflexivity.
+Qed.
+
+Lemma NEG_add : (p,p':positive)(NEG (add p p'))=(Zplus (NEG p) (NEG p')).
+Proof.
+Intros p p'; NewDestruct p; NewDestruct p'; Reflexivity.
+Qed.
+
+(**********************************************************************)
+(** Order relations *)
+
+Definition Zlt := [x,y:Z](Zcompare x y) = INFERIEUR.
+Definition Zgt := [x,y:Z](Zcompare x y) = SUPERIEUR.
+Definition Zle := [x,y:Z]~(Zcompare x y) = SUPERIEUR.
+Definition Zge := [x,y:Z]~(Zcompare x y) = INFERIEUR.
+Definition Zne := [x,y:Z] ~(x=y).
+
+V8Infix "<=" Zle : Z_scope.
+V8Infix "<" Zlt : Z_scope.
+V8Infix ">=" Zge : Z_scope.
+V8Infix ">" Zgt : Z_scope.
+
+V8Notation "x <= y <= z" := (Zle x y)/\(Zle y z) :Z_scope.
+V8Notation "x <= y < z" := (Zle x y)/\(Zlt y z) :Z_scope.
+V8Notation "x < y < z" := (Zlt x y)/\(Zlt y z) :Z_scope.
+V8Notation "x < y <= z" := (Zlt x y)/\(Zle y z) :Z_scope.
+
+(**********************************************************************)
+(** Absolute value on integers *)
+
+Definition absolu [x:Z] : nat :=
+ Cases x of
+ ZERO => O
+ | (POS p) => (convert p)
+ | (NEG p) => (convert p)
+ end.
+
+Definition Zabs [z:Z] : Z :=
+ Cases z of
+ ZERO => ZERO
+ | (POS p) => (POS p)
+ | (NEG p) => (POS p)
+ end.
+
+(**********************************************************************)
+(** From [nat] to [Z] *)
+
+Definition inject_nat :=
+ [x:nat]Cases x of
+ O => ZERO
+ | (S y) => (POS (anti_convert y))
+ end.
+
+Require BinNat.
+
+Definition entier_of_Z :=
+ [z:Z]Cases z of ZERO => Nul | (POS p) => (Pos p) | (NEG p) => (Pos p) end.
+
+Definition Z_of_entier :=
+ [x:entier]Cases x of Nul => ZERO | (Pos p) => (POS p) end.
diff --git a/theories/ZArith/ZArith_base.v b/theories/ZArith/ZArith_base.v
index 3ef24e61e..7123e3449 100644
--- a/theories/ZArith/ZArith_base.v
+++ b/theories/ZArith/ZArith_base.v
@@ -12,12 +12,19 @@
These are the basic modules, required by [Omega] and [Ring] for instance.
The full library is [ZArith]. *)
+V7only [
Require Export fast_integer.
Require Export zarith_aux.
+].
+Require Export BinPos.
+Require Export BinNat.
+Require Export BinInt.
+Require Export Zcompare.
Require Export Zorder.
Require Export Zeven.
Require Export Zmin.
Require Export Zabs.
+Require Export Znat.
Require Export auxiliary.
Require Export Zsyntax.
Require Export ZArith_dec.
diff --git a/theories/ZArith/Zcompare.v b/theories/ZArith/Zcompare.v
new file mode 100644
index 000000000..89f89868e
--- /dev/null
+++ b/theories/ZArith/Zcompare.v
@@ -0,0 +1,480 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $$ i*)
+
+Require Export BinPos.
+Require Export BinInt.
+Require Zsyntax.
+Require Lt.
+Require Gt.
+Require Plus.
+Require Mult.
+
+Open Local Scope Z_scope.
+
+(**********************************************************************)
+(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
+(**********************************************************************)
+
+(**********************************************************************)
+(** Comparison on integers *)
+
+Lemma Zcompare_x_x : (x:Z) (Zcompare x x) = EGAL.
+Proof.
+Intro x; NewDestruct x as [|p|p]; Simpl; [ Reflexivity | Apply convert_compare_EGAL
+ | Rewrite convert_compare_EGAL; Reflexivity ].
+Qed.
+
+Lemma Zcompare_EGAL_eq : (x,y:Z) (Zcompare x y) = EGAL -> x = y.
+Proof.
+Intros x y; NewDestruct x as [|x'|x'];NewDestruct y as [|y'|y'];Simpl;Intro H; Reflexivity Orelse Try Discriminate H; [
+ Rewrite (compare_convert_EGAL x' y' H); Reflexivity
+ | Rewrite (compare_convert_EGAL x' y'); [
+ Reflexivity
+ | NewDestruct (compare x' y' EGAL);
+ Reflexivity Orelse Discriminate]].
+Qed.
+
+Lemma Zcompare_EGAL : (x,y:Z) (Zcompare x y) = EGAL <-> x = y.
+Proof.
+Intros x y;Split; Intro E; [ Apply Zcompare_EGAL_eq; Assumption
+ | Rewrite E; Apply Zcompare_x_x ].
+Qed.
+
+Lemma Zcompare_ANTISYM :
+ (x,y:Z) (Zcompare x y) = SUPERIEUR <-> (Zcompare y x) = INFERIEUR.
+Proof.
+Intros x y;Split; [
+ Case x;Case y;Simpl;Intros;(Trivial with arith Orelse Discriminate H Orelse
+ (Apply ZC1; Assumption) Orelse
+ (Cut (compare p p0 EGAL)=SUPERIEUR; [
+ Intros H1;Rewrite H1;Auto with arith
+ | Apply ZC2; Generalize H ; Case (compare p0 p EGAL);
+ Trivial with arith Orelse (Intros H2;Discriminate H2)]))
+| Case x;Case y;Simpl;Intros;(Trivial with arith Orelse Discriminate H Orelse
+ (Apply ZC2; Assumption) Orelse
+ (Cut (compare p0 p EGAL)=INFERIEUR; [
+ Intros H1;Rewrite H1;Auto with arith
+ | Apply ZC1; Generalize H ; Case (compare p p0 EGAL);
+ Trivial with arith Orelse (Intros H2;Discriminate H2)]))].
+Qed.
+
+(** Transitivity of comparison *)
+
+Lemma Zcompare_trans_SUPERIEUR :
+ (x,y,z:Z) (Zcompare x y) = SUPERIEUR ->
+ (Zcompare y z) = SUPERIEUR ->
+ (Zcompare x z) = SUPERIEUR.
+Proof.
+Intros x y z;Case x;Case y;Case z; Simpl;
+Try (Intros; Discriminate H Orelse Discriminate H0);
+Auto with arith; [
+ Intros p q r H H0;Apply convert_compare_SUPERIEUR; Unfold gt;
+ Apply lt_trans with m:=(convert q);
+ Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
+| Intros p q r; Do 3 Rewrite <- ZC4; Intros H H0;
+ Apply convert_compare_SUPERIEUR;Unfold gt;Apply lt_trans with m:=(convert q);
+ Apply compare_convert_INFERIEUR;Apply ZC1;Assumption ].
+Qed.
+
+(** Comparison and opposite *)
+
+Lemma Zcompare_Zopp :
+ (x,y:Z) (Zcompare x y) = (Zcompare (Zopp y) (Zopp x)).
+Proof.
+(Intros x y;Case x;Case y;Simpl;Auto with arith);
+Intros;Rewrite <- ZC4;Trivial with arith.
+Qed.
+
+Hints Local Resolve convert_compare_EGAL.
+
+(** Comparison first-order specification *)
+
+Lemma SUPERIEUR_POS :
+ (x,y:Z) (Zcompare x y) = SUPERIEUR ->
+ (EX h:positive |(Zplus x (Zopp y)) = (POS h)).
+Proof.
+Intros x y;Case x;Case y; [
+ Simpl; Intros H; Discriminate H
+| Simpl; Intros p H; Discriminate H
+| Intros p H; Exists p; Simpl; Auto with arith
+| Intros p H; Exists p; Simpl; Auto with arith
+| Intros q p H; Exists (true_sub p q); Unfold Zplus Zopp;
+ Unfold Zcompare in H; Rewrite H; Trivial with arith
+| Intros q p H; Exists (add p q); Simpl; Trivial with arith
+| Simpl; Intros p H; Discriminate H
+| Simpl; Intros q p H; Discriminate H
+| Unfold Zcompare; Intros q p; Rewrite <- ZC4; Intros H; Exists (true_sub q p);
+ Simpl; Rewrite (ZC1 q p H); Trivial with arith].
+Qed.
+
+(** Comparison and addition *)
+
+Lemma weaken_Zcompare_Zplus_compatible :
+ ((n,m:Z) (p:positive)
+ (Zcompare (Zplus (POS p) n) (Zplus (POS p) m)) = (Zcompare n m)) ->
+ (x,y,z:Z) (Zcompare (Zplus z x) (Zplus z y)) = (Zcompare x y).
+Proof.
+Intros H x y z; NewDestruct z; [
+ Reflexivity
+| Apply H
+| Rewrite (Zcompare_Zopp x y); Rewrite Zcompare_Zopp;
+ Do 2 Rewrite Zopp_Zplus; Rewrite Zopp_NEG; Apply H ].
+Qed.
+
+Hints Local Resolve ZC4.
+
+Lemma weak_Zcompare_Zplus_compatible :
+ (x,y:Z) (z:positive)
+ (Zcompare (Zplus (POS z) x) (Zplus (POS z) y)) = (Zcompare x y).
+Proof.
+Intros x y z;Case x;Case y;Simpl;Auto with arith; [
+ Intros p;Apply convert_compare_INFERIEUR; Apply ZL17
+| Intros p;ElimPcompare z p;Intros E;Rewrite E;Auto with arith;
+ Apply convert_compare_SUPERIEUR; Rewrite true_sub_convert; [ Unfold gt ;
+ Apply ZL16 | Assumption ]
+| Intros p;ElimPcompare z p;
+ Intros E;Auto with arith; Apply convert_compare_SUPERIEUR;
+ Unfold gt;Apply ZL17
+| Intros p q;
+ ElimPcompare q p;
+ Intros E;Rewrite E;[
+ Rewrite (compare_convert_EGAL q p E); Apply convert_compare_EGAL
+ | Apply convert_compare_INFERIEUR;Do 2 Rewrite convert_add;Apply lt_reg_l;
+ Apply compare_convert_INFERIEUR with 1:=E
+ | Apply convert_compare_SUPERIEUR;Unfold gt ;Do 2 Rewrite convert_add;
+ Apply lt_reg_l;Exact (compare_convert_SUPERIEUR q p E) ]
+| Intros p q;
+ ElimPcompare z p;
+ Intros E;Rewrite E;Auto with arith;
+ Apply convert_compare_SUPERIEUR; Rewrite true_sub_convert; [
+ Unfold gt; Apply lt_trans with m:=(convert z); [Apply ZL16 | Apply ZL17]
+ | Assumption ]
+| Intros p;ElimPcompare z p;Intros E;Rewrite E;Auto with arith; Simpl;
+ Apply convert_compare_INFERIEUR;Rewrite true_sub_convert;[Apply ZL16|
+ Assumption]
+| Intros p q;
+ ElimPcompare z q;
+ Intros E;Rewrite E;Auto with arith; Simpl;Apply convert_compare_INFERIEUR;
+ Rewrite true_sub_convert;[
+ Apply lt_trans with m:=(convert z) ;[Apply ZL16|Apply ZL17]
+ | Assumption]
+| Intros p q; ElimPcompare z q; Intros E0;Rewrite E0;
+ ElimPcompare z p; Intros E1;Rewrite E1; ElimPcompare q p;
+ Intros E2;Rewrite E2;Auto with arith; [
+ Absurd (compare q p EGAL)=INFERIEUR; [
+ Rewrite <- (compare_convert_EGAL z q E0);
+ Rewrite <- (compare_convert_EGAL z p E1);
+ Rewrite (convert_compare_EGAL z); Discriminate
+ | Assumption ]
+ | Absurd (compare q p EGAL)=SUPERIEUR; [
+ Rewrite <- (compare_convert_EGAL z q E0);
+ Rewrite <- (compare_convert_EGAL z p E1);
+ Rewrite (convert_compare_EGAL z);Discriminate
+ | Assumption]
+ | Absurd (compare z p EGAL)=INFERIEUR; [
+ Rewrite (compare_convert_EGAL z q E0);
+ Rewrite <- (compare_convert_EGAL q p E2);
+ Rewrite (convert_compare_EGAL q);Discriminate
+ | Assumption ]
+ | Absurd (compare z p EGAL)=INFERIEUR; [
+ Rewrite (compare_convert_EGAL z q E0); Rewrite E2;Discriminate
+ | Assumption]
+ | Absurd (compare z p EGAL)=SUPERIEUR;[
+ Rewrite (compare_convert_EGAL z q E0);
+ Rewrite <- (compare_convert_EGAL q p E2);
+ Rewrite (convert_compare_EGAL q);Discriminate
+ | Assumption]
+ | Absurd (compare z p EGAL)=SUPERIEUR;[
+ Rewrite (compare_convert_EGAL z q E0);Rewrite E2;Discriminate
+ | Assumption]
+ | Absurd (compare z q EGAL)=INFERIEUR;[
+ Rewrite (compare_convert_EGAL z p E1);
+ Rewrite (compare_convert_EGAL q p E2);
+ Rewrite (convert_compare_EGAL p); Discriminate
+ | Assumption]
+ | Absurd (compare p q EGAL)=SUPERIEUR; [
+ Rewrite <- (compare_convert_EGAL z p E1);
+ Rewrite E0; Discriminate
+ | Apply ZC2;Assumption ]
+ | Simpl; Rewrite (compare_convert_EGAL q p E2);
+ Rewrite (convert_compare_EGAL (true_sub p z)); Auto with arith
+ | Simpl; Rewrite <- ZC4; Apply convert_compare_SUPERIEUR;
+ Rewrite true_sub_convert; [
+ Rewrite true_sub_convert; [
+ Unfold gt; Apply simpl_lt_plus_l with p:=(convert z);
+ Rewrite le_plus_minus_r; [
+ Rewrite le_plus_minus_r; [
+ Apply compare_convert_INFERIEUR;Assumption
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
+ | Apply ZC2;Assumption ]
+ | Apply ZC2;Assumption ]
+ | Simpl; Rewrite <- ZC4; Apply convert_compare_INFERIEUR;
+ Rewrite true_sub_convert; [
+ Rewrite true_sub_convert; [
+ Apply simpl_lt_plus_l with p:=(convert z);
+ Rewrite le_plus_minus_r; [
+ Rewrite le_plus_minus_r; [
+ Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
+ | Apply ZC2;Assumption]
+ | Apply ZC2;Assumption ]
+ | Absurd (compare z q EGAL)=INFERIEUR; [
+ Rewrite (compare_convert_EGAL q p E2);Rewrite E1;Discriminate
+ | Assumption ]
+ | Absurd (compare q p EGAL)=INFERIEUR; [
+ Cut (compare q p EGAL)=SUPERIEUR; [
+ Intros E;Rewrite E;Discriminate
+ | Apply convert_compare_SUPERIEUR; Unfold gt;
+ Apply lt_trans with m:=(convert z); [
+ Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
+ | Apply compare_convert_INFERIEUR;Assumption ]]
+ | Assumption ]
+ | Absurd (compare z q EGAL)=SUPERIEUR; [
+ Rewrite (compare_convert_EGAL z p E1);
+ Rewrite (compare_convert_EGAL q p E2);
+ Rewrite (convert_compare_EGAL p); Discriminate
+ | Assumption ]
+ | Absurd (compare z q EGAL)=SUPERIEUR; [
+ Rewrite (compare_convert_EGAL z p E1);
+ Rewrite ZC1; [Discriminate | Assumption ]
+ | Assumption ]
+ | Absurd (compare z q EGAL)=SUPERIEUR; [
+ Rewrite (compare_convert_EGAL q p E2); Rewrite E1; Discriminate
+ | Assumption ]
+ | Absurd (compare q p EGAL)=SUPERIEUR; [
+ Rewrite ZC1; [
+ Discriminate
+ | Apply convert_compare_SUPERIEUR; Unfold gt;
+ Apply lt_trans with m:=(convert z); [
+ Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
+ | Apply compare_convert_INFERIEUR;Assumption ]]
+ | Assumption ]
+ | Simpl; Rewrite (compare_convert_EGAL q p E2); Apply convert_compare_EGAL
+ | Simpl; Apply convert_compare_SUPERIEUR; Unfold gt;
+ Rewrite true_sub_convert; [
+ Rewrite true_sub_convert; [
+ Apply simpl_lt_plus_l with p:=(convert p); Rewrite le_plus_minus_r; [
+ Rewrite plus_sym; Apply simpl_lt_plus_l with p:=(convert q);
+ Rewrite plus_assoc_l; Rewrite le_plus_minus_r; [
+ Rewrite (plus_sym (convert q)); Apply lt_reg_l;
+ Apply compare_convert_INFERIEUR;Assumption
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;
+ Apply ZC1;Assumption ]
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Apply ZC1;
+ Assumption ]
+ | Assumption ]
+ | Assumption ]
+ | Simpl; Apply convert_compare_INFERIEUR; Rewrite true_sub_convert; [
+ Rewrite true_sub_convert; [
+ Apply simpl_lt_plus_l with p:=(convert q); Rewrite le_plus_minus_r; [
+ Rewrite plus_sym; Apply simpl_lt_plus_l with p:=(convert p);
+ Rewrite plus_assoc_l; Rewrite le_plus_minus_r; [
+ Rewrite (plus_sym (convert p)); Apply lt_reg_l;
+ Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
+ | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Apply ZC1;
+ Assumption ]
+ | Apply lt_le_weak;Apply compare_convert_INFERIEUR;Apply ZC1;Assumption]
+ | Assumption]
+ | Assumption]]].
+Qed.
+
+Lemma Zcompare_Zplus_compatible :
+ (x,y,z:Z) (Zcompare (Zplus z x) (Zplus z y)) = (Zcompare x y).
+Proof.
+Exact (weaken_Zcompare_Zplus_compatible weak_Zcompare_Zplus_compatible).
+Qed.
+
+Lemma Zcompare_Zplus_compatible2 :
+ (r:relation)(x,y,z,t:Z)
+ (Zcompare x y) = r -> (Zcompare z t) = r ->
+ (Zcompare (Zplus x z) (Zplus y t)) = r.
+Proof.
+Intros r x y z t; Case r; [
+ Intros H1 H2; Elim (Zcompare_EGAL x y); Elim (Zcompare_EGAL z t);
+ Intros H3 H4 H5 H6; Rewrite H3; [
+ Rewrite H5; [ Elim (Zcompare_EGAL (Zplus y t) (Zplus y t)); Auto with arith | Auto with arith ]
+ | Auto with arith ]
+| Intros H1 H2; Elim (Zcompare_ANTISYM (Zplus y t) (Zplus x z));
+ Intros H3 H4; Apply H3;
+ Apply Zcompare_trans_SUPERIEUR with y:=(Zplus y z) ; [
+ Rewrite Zcompare_Zplus_compatible;
+ Elim (Zcompare_ANTISYM t z); Auto with arith
+ | Do 2 Rewrite <- (Zplus_sym z);
+ Rewrite Zcompare_Zplus_compatible;
+ Elim (Zcompare_ANTISYM y x); Auto with arith]
+| Intros H1 H2;
+ Apply Zcompare_trans_SUPERIEUR with y:=(Zplus x t) ; [
+ Rewrite Zcompare_Zplus_compatible; Assumption
+ | Do 2 Rewrite <- (Zplus_sym t);
+ Rewrite Zcompare_Zplus_compatible; Assumption]].
+Qed.
+
+Lemma Zcompare_Zs_SUPERIEUR : (x:Z)(Zcompare (Zs x) x)=SUPERIEUR.
+Proof.
+Intro x; Unfold Zs; Pattern 2 x; Rewrite <- (Zero_right x);
+Rewrite Zcompare_Zplus_compatible;Reflexivity.
+Qed.
+
+Lemma Zcompare_et_un:
+ (x,y:Z) (Zcompare x y)=SUPERIEUR <->
+ ~(Zcompare x (Zplus y (POS xH)))=INFERIEUR.
+Proof.
+Intros x y; Split; [
+ Intro H; (ElimCompare 'x '(Zplus y (POS xH)));[
+ Intro H1; Rewrite H1; Discriminate
+ | Intros H1; Elim SUPERIEUR_POS with 1:=H; Intros h H2;
+ Absurd (gt (convert h) O) /\ (lt (convert h) (S O)); [
+ Unfold not ;Intros H3;Elim H3;Intros H4 H5; Absurd (gt (convert h) O); [
+ Unfold gt ;Apply le_not_lt; Apply le_S_n; Exact H5
+ | Assumption]
+ | Split; [
+ Elim (ZL4 h); Intros i H3;Rewrite H3; Apply gt_Sn_O
+ | Change (lt (convert h) (convert xH));
+ Apply compare_convert_INFERIEUR;
+ Change (Zcompare (POS h) (POS xH))=INFERIEUR;
+ Rewrite <- H2; Rewrite <- [m,n:Z](Zcompare_Zplus_compatible m n y);
+ Rewrite (Zplus_sym x);Rewrite Zplus_assoc; Rewrite Zplus_inverse_r;
+ Simpl; Exact H1 ]]
+ | Intros H1;Rewrite -> H1;Discriminate ]
+| Intros H; (ElimCompare 'x '(Zplus y (POS xH))); [
+ Intros H1;Elim (Zcompare_EGAL x (Zplus y (POS xH))); Intros H2 H3;
+ Rewrite (H2 H1); Exact (Zcompare_Zs_SUPERIEUR y)
+ | Intros H1;Absurd (Zcompare x (Zplus y (POS xH)))=INFERIEUR;Assumption
+ | Intros H1; Apply Zcompare_trans_SUPERIEUR with y:=(Zs y);
+ [ Exact H1 | Exact (Zcompare_Zs_SUPERIEUR y)]]].
+Qed.
+
+(** Successor and comparison *)
+
+Lemma Zcompare_n_S : (n,m:Z)(Zcompare (Zs n) (Zs m)) = (Zcompare n m).
+Proof.
+Intros n m;Unfold Zs ;Do 2 Rewrite -> [t:Z](Zplus_sym t (POS xH));
+Rewrite -> Zcompare_Zplus_compatible;Auto with arith.
+Qed.
+
+(** Multiplication and comparison *)
+
+Lemma Zcompare_Zmult_compatible :
+ (x:positive)(y,z:Z)
+ (Zcompare (Zmult (POS x) y) (Zmult (POS x) z)) = (Zcompare y z).
+Proof.
+Intros x; NewInduction x as [p H|p H|]; [
+ Intros y z;
+ Cut (POS (xI p))=(Zplus (Zplus (POS p) (POS p)) (POS xH)); [
+ Intros E; Rewrite E; Do 4 Rewrite Zmult_plus_distr_l;
+ Do 2 Rewrite Zmult_one;
+ Apply Zcompare_Zplus_compatible2; [
+ Apply Zcompare_Zplus_compatible2; Apply H
+ | Trivial with arith]
+ | Simpl; Rewrite (add_x_x p); Trivial with arith]
+| Intros y z; Cut (POS (xO p))=(Zplus (POS p) (POS p)); [
+ Intros E; Rewrite E; Do 2 Rewrite Zmult_plus_distr_l;
+ Apply Zcompare_Zplus_compatible2; Apply H
+ | Simpl; Rewrite (add_x_x p); Trivial with arith]
+ | Intros y z; Do 2 Rewrite Zmult_one; Trivial with arith].
+Qed.
+
+
+(** Reverting [x ?= y] to trichotomy *)
+
+Lemma rename : (A:Set)(P:A->Prop)(x:A) ((y:A)(x=y)->(P y)) -> (P x).
+Proof.
+Auto with arith.
+Qed.
+
+Lemma Zcompare_elim :
+ (c1,c2,c3:Prop)(x,y:Z)
+ ((x=y) -> c1) ->(`x<y` -> c2) ->(`x>y`-> c3)
+ -> Cases (Zcompare x y) of EGAL => c1 | INFERIEUR => c2 | SUPERIEUR => c3 end.
+Proof.
+Intros c1 c2 c3 x y; Intros.
+Apply rename with x:=(Zcompare x y); Intro r; Elim r;
+[ Intro; Apply H; Apply (Zcompare_EGAL_eq x y); Assumption
+| Unfold Zlt in H0; Assumption
+| Unfold Zgt in H1; Assumption ].
+Qed.
+
+Lemma Zcompare_eq_case :
+ (c1,c2,c3:Prop)(x,y:Z) c1 -> x=y ->
+ Cases (Zcompare x y) of EGAL => c1 | INFERIEUR => c2 | SUPERIEUR => c3 end.
+Proof.
+Intros c1 c2 c3 x y; Intros.
+Rewrite H0; Rewrite (Zcompare_x_x).
+Assumption.
+Qed.
+
+(** Decompose an egality between two [?=] relations into 3 implications *)
+
+Lemma Zcompare_egal_dec :
+ (x1,y1,x2,y2:Z)
+ (`x1<y1`->`x2<y2`)
+ ->((Zcompare x1 y1)=EGAL -> (Zcompare x2 y2)=EGAL)
+ ->(`x1>y1`->`x2>y2`)->(Zcompare x1 y1)=(Zcompare x2 y2).
+Proof.
+Intros x1 y1 x2 y2.
+Unfold Zgt; Unfold Zlt;
+Case (Zcompare x1 y1); Case (Zcompare x2 y2); Auto with arith; Symmetry; Auto with arith.
+Qed.
+
+(** Relating [x ?= y] to [Zle], [Zlt], [Zge] or [Zgt] *)
+
+Lemma Zle_Zcompare :
+ (x,y:Z)`x<=y` ->
+ Cases (Zcompare x y) of EGAL => True | INFERIEUR => True | SUPERIEUR => False end.
+Proof.
+Intros x y; Unfold Zle; Elim (Zcompare x y); Auto with arith.
+Qed.
+
+Lemma Zlt_Zcompare :
+ (x,y:Z)`x<y` ->
+ Cases (Zcompare x y) of EGAL => False | INFERIEUR => True | SUPERIEUR => False end.
+Proof.
+Intros x y; Unfold Zlt; Elim (Zcompare x y); Intros; Discriminate Orelse Trivial with arith.
+Qed.
+
+Lemma Zge_Zcompare :
+ (x,y:Z)`x>=y`->
+ Cases (Zcompare x y) of EGAL => True | INFERIEUR => False | SUPERIEUR => True end.
+Proof.
+Intros x y; Unfold Zge; Elim (Zcompare x y); Auto with arith.
+Qed.
+
+Lemma Zgt_Zcompare :
+ (x,y:Z)`x>y` ->
+ Cases (Zcompare x y) of EGAL => False | INFERIEUR => False | SUPERIEUR => True end.
+Proof.
+Intros x y; Unfold Zgt; Elim (Zcompare x y); Intros; Discriminate Orelse Trivial with arith.
+Qed.
+
+(**********************************************************************)
+(* Other properties *)
+
+V7only [Set Implicit Arguments.].
+
+Theorem Zcompare_Zmult_left : (x,y,z:Z)`z>0` -> `x ?= y`=`z*x ?= z*y`.
+Proof.
+Intros x y z H; NewDestruct z.
+ Discriminate H.
+ Rewrite Zcompare_Zmult_compatible; Reflexivity.
+ Discriminate H.
+Qed.
+
+Theorem Zcompare_Zmult_right : (x,y,z:Z)` z>0` -> `x ?= y`=`x*z ?= y*z`.
+Proof.
+Intros x y z H;
+Rewrite (Zmult_sym x z);
+Rewrite (Zmult_sym y z);
+Apply Zcompare_Zmult_left; Assumption.
+Qed.
+
+V7only [Unset Implicit Arguments.].
+
diff --git a/theories/ZArith/Zcomplements.v b/theories/ZArith/Zcomplements.v
index d5075ffb6..ef13d1fb2 100644
--- a/theories/ZArith/Zcomplements.v
+++ b/theories/ZArith/Zcomplements.v
@@ -15,31 +15,19 @@ Require Wf_nat.
V7only [Import Z_scope.].
Open Local Scope Z_scope.
-(**********************************************************************)
-(* Properties of comparison on Z *)
-
-Set Implicit Arguments.
-
-Theorem Zcompare_Zmult_right : (x,y,z:Z)` z>0` -> `x ?= y`=`x*z ?= y*z`.
-
-Intros; Apply Zcompare_egal_dec;
-[ Intros; Apply Zlt_Zmult_right; Trivial
-| Intro Hxy; Apply [a,b:Z](let (t1,t2)=(Zcompare_EGAL a b) in t2);
- Rewrite ((let (t1,t2)=(Zcompare_EGAL x y) in t1) Hxy); Trivial
-| Intros; Apply Zgt_Zmult_right; Trivial
+V7only [
+Notation Zcompare_Zmult_right := Zcompare_Zmult_right.
+Notation Zcompare_Zmult_left := Zcompare_Zmult_left.
].
-Qed.
-Theorem Zcompare_Zmult_left : (x,y,z:Z)`z>0` -> `x ?= y`=`z*x ?= z*y`.
-Intros;
-Rewrite (Zmult_sym z x);
-Rewrite (Zmult_sym z y);
-Apply Zcompare_Zmult_right; Assumption.
-Qed.
+V7only [Set Implicit Arguments.].
+(**********************************************************************)
+(** About parity *)
Lemma two_or_two_plus_one : (x:Z) { y:Z | `x = 2*y`}+{ y:Z | `x = 2*y+1`}.
-NewDestruct x.
+Proof.
+Intro x; NewDestruct x.
Left ; Split with ZERO; Reflexivity.
NewDestruct p.
@@ -60,6 +48,7 @@ Left ; Split with (NEG p); Reflexivity.
Right ; Split with `-1`; Reflexivity.
Qed.
+V7only [Unset Implicit Arguments.].
(**********************************************************************)
(** The biggest power of 2 that is stricly less than [a]
@@ -77,6 +66,7 @@ Fixpoint floor_pos [a : positive] : positive :=
Definition floor := [a:positive](POS (floor_pos a)).
Lemma floor_gt0 : (x:positive) `(floor x) > 0`.
+Proof.
Intro.
Compute.
Trivial.
@@ -84,16 +74,17 @@ Qed.
Lemma floor_ok : (a:positive)
`(floor a) <= (POS a) < 2*(floor a)`.
+Proof.
Unfold floor.
-Induction a.
+Intro a; NewInduction a as [p|p|].
-Intro p; Simpl.
+Simpl.
Repeat Rewrite POS_xI.
Rewrite (POS_xO (xO (floor_pos p))).
Rewrite (POS_xO (floor_pos p)).
Omega.
-Intro p; Simpl.
+Simpl.
Repeat Rewrite POS_xI.
Rewrite (POS_xO (xO (floor_pos p))).
Rewrite (POS_xO (floor_pos p)).
@@ -103,12 +94,12 @@ Omega.
Simpl; Omega.
Qed.
-
(**********************************************************************)
(** Two more induction principles over [Z]. *)
Theorem Z_lt_abs_rec : (P: Z -> Set)
((n: Z) ((m: Z) `|m|<|n|` -> (P m)) -> (P n)) -> (p: Z) (P p).
+Proof.
Intros P HP p.
LetTac Q:=[z]`0<=z`->(P z)*(P `-z`).
Cut (Q `|p|`);[Intros|Apply (Z_lt_rec Q);Auto with zarith].
@@ -126,6 +117,7 @@ Qed.
Theorem Z_lt_abs_induction : (P: Z -> Prop)
((n: Z) ((m: Z) `|m|<|n|` -> (P m)) -> (P n)) -> (p: Z) (P p).
+Proof.
Intros P HP p.
LetTac Q:=[z]`0<=z`->(P z) /\ (P `-z`).
Cut (Q `|p|`);[Intros|Apply (Z_lt_induction Q);Auto with zarith].
@@ -140,8 +132,7 @@ Rewrite Zopp_Zopp;Intros.
Elim (H `|m|`);Intros;Auto with zarith.
Elim (Zabs_dec m);Intro eq;Rewrite eq;Trivial.
Qed.
-
-Unset Implicit Arguments.
+V7only [Unset Implicit Arguments.].
(** To do case analysis over the sign of [z] *)
diff --git a/theories/ZArith/Zhints.v b/theories/ZArith/Zhints.v
index 8dc9069a6..6eb668a5a 100644
--- a/theories/ZArith/Zhints.v
+++ b/theories/ZArith/Zhints.v
@@ -27,11 +27,12 @@
(* Lemmas involving positive and compare are not taken into account *)
-Require fast_integer.
+Require BinInt.
Require Zorder.
Require Zmin.
Require Zabs.
-Require zarith_aux.
+Require Zcompare.
+Require Znat.
Require auxiliary.
Require Zsyntax.
Require Zmisc.
diff --git a/theories/ZArith/Znat.v b/theories/ZArith/Znat.v
new file mode 100644
index 000000000..fe53fce90
--- /dev/null
+++ b/theories/ZArith/Znat.v
@@ -0,0 +1,138 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
+
+Require Export Arith.
+Require BinPos.
+Require BinInt.
+Require Zcompare.
+Require Zorder.
+Require Decidable.
+Require Peano_dec.
+Require Export Compare_dec.
+
+Open Local Scope Z_scope.
+
+Definition neq := [x,y:nat] ~(x=y).
+
+(**********************************************************************)
+(** Properties of the injection from nat into Z *)
+
+Theorem inj_S : (y:nat) (inject_nat (S y)) = (Zs (inject_nat y)).
+Proof.
+Intro y; NewInduction y as [|n H]; [
+ Unfold Zs ; Simpl; Trivial with arith
+| Change (POS (add_un (anti_convert n)))=(Zs (inject_nat (S n)));
+ Rewrite add_un_Zs; Trivial with arith].
+Qed.
+
+Theorem inj_plus :
+ (x,y:nat) (inject_nat (plus x y)) = (Zplus (inject_nat x) (inject_nat y)).
+Proof.
+Intro x; NewInduction x as [|n H]; Intro y; NewDestruct y as [|m]; [
+ Simpl; Trivial with arith
+| Simpl; Trivial with arith
+| Simpl; Rewrite <- plus_n_O; Trivial with arith
+| Change (inject_nat (S (plus n (S m))))=
+ (Zplus (inject_nat (S n)) (inject_nat (S m)));
+ Rewrite inj_S; Rewrite H; Do 2 Rewrite inj_S; Rewrite Zplus_S_n; Trivial with arith].
+Qed.
+
+Theorem inj_mult :
+ (x,y:nat) (inject_nat (mult x y)) = (Zmult (inject_nat x) (inject_nat y)).
+Proof.
+Intro x; NewInduction x as [|n H]; [
+ Simpl; Trivial with arith
+| Intro y; Rewrite -> inj_S; Rewrite <- Zmult_Sm_n;
+ Rewrite <- H;Rewrite <- inj_plus; Simpl; Rewrite plus_sym; Trivial with arith].
+Qed.
+
+Theorem inj_neq:
+ (x,y:nat) (neq x y) -> (Zne (inject_nat x) (inject_nat y)).
+Proof.
+Unfold neq Zne not ; Intros x y H1 H2; Apply H1; Generalize H2;
+Case x; Case y; Intros; [
+ Auto with arith
+| Discriminate H0
+| Discriminate H0
+| Simpl in H0; Injection H0; Do 2 Rewrite <- bij1; Intros E; Rewrite E; Auto with arith].
+Qed.
+
+Theorem inj_le:
+ (x,y:nat) (le x y) -> (Zle (inject_nat x) (inject_nat y)).
+Proof.
+Intros x y; Intros H; Elim H; [
+ Unfold Zle ; Elim (Zcompare_EGAL (inject_nat x) (inject_nat x));
+ Intros H1 H2; Rewrite H2; [ Discriminate | Trivial with arith]
+| Intros m H1 H2; Apply Zle_trans with (inject_nat m);
+ [Assumption | Rewrite inj_S; Apply Zle_n_Sn]].
+Qed.
+
+Theorem inj_lt: (x,y:nat) (lt x y) -> (Zlt (inject_nat x) (inject_nat y)).
+Proof.
+Intros x y H; Apply Zgt_lt; Apply Zle_S_gt; Rewrite <- inj_S; Apply inj_le;
+Exact H.
+Qed.
+
+Theorem inj_gt: (x,y:nat) (gt x y) -> (Zgt (inject_nat x) (inject_nat y)).
+Proof.
+Intros x y H; Apply Zlt_gt; Apply inj_lt; Exact H.
+Qed.
+
+Theorem inj_ge: (x,y:nat) (ge x y) -> (Zge (inject_nat x) (inject_nat y)).
+Proof.
+Intros x y H; Apply Zle_ge; Apply inj_le; Apply H.
+Qed.
+
+Theorem inj_eq: (x,y:nat) x=y -> (inject_nat x) = (inject_nat y).
+Proof.
+Intros x y H; Rewrite H; Trivial with arith.
+Qed.
+
+Theorem intro_Z :
+ (x:nat) (EX y:Z | (inject_nat x)=y /\
+ (Zle ZERO (Zplus (Zmult y (POS xH)) ZERO))).
+Proof.
+Intros x; Exists (inject_nat x); Split; [
+ Trivial with arith
+| Rewrite Zmult_sym; Rewrite Zmult_one; Rewrite Zero_right;
+ Unfold Zle ; Elim x; Intros;Simpl; Discriminate ].
+Qed.
+
+Theorem inj_minus1 :
+ (x,y:nat) (le y x) ->
+ (inject_nat (minus x y)) = (Zminus (inject_nat x) (inject_nat y)).
+Proof.
+Intros x y H; Apply (Zsimpl_plus_l (inject_nat y)); Unfold Zminus ;
+Rewrite Zplus_permute; Rewrite Zplus_inverse_r; Rewrite <- inj_plus;
+Rewrite <- (le_plus_minus y x H);Rewrite Zero_right; Trivial with arith.
+Qed.
+
+Theorem inj_minus2: (x,y:nat) (gt y x) -> (inject_nat (minus x y)) = ZERO.
+Proof.
+Intros x y H; Rewrite inj_minus_aux; [ Trivial with arith | Apply gt_not_le; Assumption].
+Qed.
+
+V7only [ (* From Zdivides *) ].
+Theorem POS_inject: (x : positive) (POS x) = (inject_nat (convert x)).
+Proof.
+Intros x; Elim x; Simpl; Auto.
+Intros p H; Rewrite ZL6.
+Apply f_equal with f := POS.
+Apply convert_intro.
+Rewrite bij1; Unfold convert; Simpl.
+Rewrite ZL6; Auto.
+Intros p H; Unfold convert; Simpl.
+Rewrite ZL6; Simpl.
+Rewrite inj_plus; Repeat Rewrite <- H.
+Rewrite POS_xO; Simpl; Rewrite add_x_x; Reflexivity.
+Qed.
+
diff --git a/theories/ZArith/Zsyntax.v b/theories/ZArith/Zsyntax.v
index 001de304b..5c226b3fc 100644
--- a/theories/ZArith/Zsyntax.v
+++ b/theories/ZArith/Zsyntax.v
@@ -8,7 +8,7 @@
(*i $Id$ i*)
-Require Export fast_integer.
+Require Export BinInt.
V7only[
diff --git a/theories/ZArith/auxiliary.v b/theories/ZArith/auxiliary.v
index 745c5c988..0d5becb59 100644
--- a/theories/ZArith/auxiliary.v
+++ b/theories/ZArith/auxiliary.v
@@ -11,116 +11,14 @@
(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
Require Export Arith.
-Require fast_integer.
+Require BinInt.
Require Zorder.
-Require zarith_aux.
Require Decidable.
Require Peano_dec.
Require Export Compare_dec.
Open Local Scope Z_scope.
-Definition neq := [x,y:nat] ~(x=y).
-
-(**********************************************************************)
-(** Properties of the injection from nat into Z *)
-
-Theorem inj_S : (y:nat) (inject_nat (S y)) = (Zs (inject_nat y)).
-Proof.
-Induction y; [
- Unfold Zs ; Simpl; Trivial with arith
-| Intros n; Intros H;
- Change (POS (add_un (anti_convert n)))=(Zs (inject_nat (S n)));
- Rewrite add_un_Zs; Trivial with arith].
-Qed.
-
-Theorem inj_plus :
- (x,y:nat) (inject_nat (plus x y)) = (Zplus (inject_nat x) (inject_nat y)).
-Proof.
-Induction x; Induction y; [
- Simpl; Trivial with arith
-| Simpl; Trivial with arith
-| Simpl; Rewrite <- plus_n_O; Trivial with arith
-| Intros m H1; Change (inject_nat (S (plus n (S m))))=
- (Zplus (inject_nat (S n)) (inject_nat (S m)));
- Rewrite inj_S; Rewrite H; Do 2 Rewrite inj_S; Rewrite Zplus_S_n; Trivial with arith].
-Qed.
-
-Theorem inj_mult :
- (x,y:nat) (inject_nat (mult x y)) = (Zmult (inject_nat x) (inject_nat y)).
-Proof.
-Induction x; [
- Simpl; Trivial with arith
-| Intros n H y; Rewrite -> inj_S; Rewrite <- Zmult_Sm_n;
- Rewrite <- H;Rewrite <- inj_plus; Simpl; Rewrite plus_sym; Trivial with arith].
-Qed.
-
-Theorem inj_neq:
- (x,y:nat) (neq x y) -> (Zne (inject_nat x) (inject_nat y)).
-Proof.
-Unfold neq Zne not ; Intros x y H1 H2; Apply H1; Generalize H2;
-Case x; Case y; Intros; [
- Auto with arith
-| Discriminate H0
-| Discriminate H0
-| Simpl in H0; Injection H0; Do 2 Rewrite <- bij1; Intros E; Rewrite E; Auto with arith].
-Qed.
-
-Theorem inj_le:
- (x,y:nat) (le x y) -> (Zle (inject_nat x) (inject_nat y)).
-Proof.
-Intros x y; Intros H; Elim H; [
- Unfold Zle ; Elim (Zcompare_EGAL (inject_nat x) (inject_nat x));
- Intros H1 H2; Rewrite H2; [ Discriminate | Trivial with arith]
-| Intros m H1 H2; Apply Zle_trans with (inject_nat m);
- [Assumption | Rewrite inj_S; Apply Zle_n_Sn]].
-Qed.
-
-Theorem inj_lt: (x,y:nat) (lt x y) -> (Zlt (inject_nat x) (inject_nat y)).
-Proof.
-Intros x y H; Apply Zgt_lt; Apply Zle_S_gt; Rewrite <- inj_S; Apply inj_le;
-Exact H.
-Qed.
-
-Theorem inj_gt: (x,y:nat) (gt x y) -> (Zgt (inject_nat x) (inject_nat y)).
-Proof.
-Intros x y H; Apply Zlt_gt; Apply inj_lt; Exact H.
-Qed.
-
-Theorem inj_ge: (x,y:nat) (ge x y) -> (Zge (inject_nat x) (inject_nat y)).
-Proof.
-Intros x y H; Apply Zle_ge; Apply inj_le; Apply H.
-Qed.
-
-Theorem inj_eq: (x,y:nat) x=y -> (inject_nat x) = (inject_nat y).
-Proof.
-Intros x y H; Rewrite H; Trivial with arith.
-Qed.
-
-Theorem intro_Z :
- (x:nat) (EX y:Z | (inject_nat x)=y /\
- (Zle ZERO (Zplus (Zmult y (POS xH)) ZERO))).
-Proof.
-Intros x; Exists (inject_nat x); Split; [
- Trivial with arith
-| Rewrite Zmult_sym; Rewrite Zmult_one; Rewrite Zero_right;
- Unfold Zle ; Elim x; Intros;Simpl; Discriminate ].
-Qed.
-
-Theorem inj_minus1 :
- (x,y:nat) (le y x) ->
- (inject_nat (minus x y)) = (Zminus (inject_nat x) (inject_nat y)).
-Proof.
-Intros x y H; Apply (Zsimpl_plus_l (inject_nat y)); Unfold Zminus ;
-Rewrite Zplus_permute; Rewrite Zplus_inverse_r; Rewrite <- inj_plus;
-Rewrite <- (le_plus_minus y x H);Rewrite Zero_right; Trivial with arith.
-Qed.
-
-Theorem inj_minus2: (x,y:nat) (gt y x) -> (inject_nat (minus x y)) = ZERO.
-Proof.
-Intros x y H; Rewrite inj_minus_aux; [ Trivial with arith | Apply gt_not_le; Assumption].
-Qed.
-
(**********************************************************************)
(** Moving terms from one side to the other of an inequality *)
@@ -148,7 +46,7 @@ Qed.
Theorem Zle_left_rev : (x,y:Z) (Zle ZERO (Zplus y (Zopp x)))
-> (Zle x y).
Proof.
-Intros x y H; Apply (Zsimpl_le_plus_r (Zopp x)).
+Intros x y H; Apply Zsimpl_le_plus_r with (Zopp x).
Rewrite Zplus_inverse_r; Trivial.
Qed.
@@ -202,7 +100,7 @@ Rewrite Zplus_inverse_r; Trivial.
Qed.
(**********************************************************************)
-(** Misc lemmas *)
+(** Factorization lemmas *)
Theorem Zred_factor0 : (x:Z) x = (Zmult x (POS xH)).
Intro x; Rewrite (Zmult_n_1 x); Reflexivity.
@@ -251,26 +149,11 @@ Intros x y z H1 H2 H3; Apply Zle_trans with m:=(Zmult y x) ; [
Apply Zlt_le_weak; Apply Zgt_lt; Assumption].
Qed.
-Lemma Zgt_square_simpl:
-(x, y : Z) (Zge x ZERO) -> (Zge y ZERO)
- -> (Zgt (Zmult x x) (Zmult y y)) -> (Zgt x y).
-Intros x y H0 H1 H2.
-Case (dec_Zlt y x).
-Intro; Apply Zlt_gt; Trivial.
-Intros H3; Cut (Zge y x).
-Intros H.
-Elim Zgt_not_le with 1 := H2.
-Apply Zge_le.
-Apply Zge_Zmult_pos_compat; Auto.
-Apply not_Zlt; Trivial.
-Qed.
-
-
Theorem Zmult_le_approx:
(x,y,z:Z) (Zgt x ZERO) -> (Zgt x z) ->
(Zle ZERO (Zplus (Zmult y x) z)) -> (Zle ZERO y).
-Intros x y z H1 H2 H3; Apply Zlt_n_Sm_le; Apply (Zmult_lt x); [
+Intros x y z H1 H2 H3; Apply Zlt_n_Sm_le; Apply Zmult_lt with x; [
Assumption
| Apply Zle_lt_trans with 1:=H3 ; Rewrite <- Zmult_Sm_n;
Apply Zlt_reg_l; Apply Zgt_lt; Assumption].
diff --git a/theories/ZArith/fast_integer.v b/theories/ZArith/fast_integer.v
index 059e79eb3..67675a642 100644
--- a/theories/ZArith/fast_integer.v
+++ b/theories/ZArith/fast_integer.v
@@ -9,19 +9,17 @@
(*i $Id$ i*)
(***********************************************************)
-(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
+(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
(***********************************************************)
-Require Export BinPos.
+Require BinPos.
Require BinNat.
-Require Le.
-Require Lt.
-Require Gt.
-Require Plus.
-Require Mult.
+Require BinInt.
+Require Zcompare.
V7only [
-(* Defs and ppties on positive and entier, previously in fast_integer*)
+(* Defs and ppties on positive, entier and Z, previously in fast_integer *)
+(* For v7 compatibility *)
Notation positive := positive.
Notation xO := xO.
Notation xI := xI.
@@ -49,7 +47,7 @@ Notation INFERIEUR := INFERIEUR.
Notation EGAL := EGAL.
Notation Op := Op.
Notation compare := compare.
-Notation compare_convert := compare_convert1.
+Notation compare_convert1 := compare_convert1.
Notation compare_convert_EGAL := compare_convert_EGAL.
Notation ZLSI := ZLSI.
Notation ZLIS := ZLIS.
@@ -57,6 +55,7 @@ Notation ZLII := ZLII.
Notation ZLSS := ZLSS.
Notation Dcompare := Dcompare.
Notation convert_compare_EGAL := convert_compare_EGAL.
+Notation ZL0 := ZL0.
Notation ZL11 := ZL11.
Notation xI_add_un_xO := xI_add_un_xO.
Notation is_double_moins_un := is_double_moins_un.
@@ -147,1524 +146,45 @@ Notation times1 :=
[x:positive;_:positive->positive;y:positive](times x y).
Notation times1_convert :=
[x,y:positive;_:positive->positive](times_convert x y).
-].
-
-(**********************************************************************)
-(** Binary integer numbers *)
-
-Inductive Z : Set :=
- ZERO : Z | POS : positive -> Z | NEG : positive -> Z.
-
-(** Declare Scope Z_scope with Key Z *)
-Delimits Scope Z_scope with Z.
-
-(** Automatically open scope positive_scope for the constructors of Z *)
-Bind Scope Z_scope with Z.
-Arguments Scope POS [ positive_scope ].
-Arguments Scope NEG [ positive_scope ].
-
-(** Subtraction of positive into Z *)
-
-Definition Zdouble_plus_one [x:Z] :=
- Cases x of
- | ZERO => (POS xH)
- | (POS p) => (POS (xI p))
- | (NEG p) => (NEG (double_moins_un p))
- end.
-
-Definition Zdouble_minus_one [x:Z] :=
- Cases x of
- | ZERO => (NEG xH)
- | (NEG p) => (NEG (xI p))
- | (POS p) => (POS (double_moins_un p))
- end.
-
-Definition Zdouble [x:Z] :=
- Cases x of
- | ZERO => ZERO
- | (POS p) => (POS (xO p))
- | (NEG p) => (NEG (xO p))
- end.
-
-Fixpoint Zsub_pos[x,y:positive]:Z :=
- Cases x y of
- | (xI x') (xI y') => (Zdouble (Zsub_pos x' y'))
- | (xI x') (xO y') => (Zdouble_plus_one (Zsub_pos x' y'))
- | (xI x') xH => (POS (xO x'))
- | (xO x') (xI y') => (Zdouble_minus_one (Zsub_pos x' y'))
- | (xO x') (xO y') => (Zdouble (Zsub_pos x' y'))
- | (xO x') xH => (POS (double_moins_un x'))
- | xH (xI y') => (NEG (xO y'))
- | xH (xO y') => (NEG (double_moins_un y'))
- | xH xH => ZERO
- end.
-
-(** Addition on integers *)
-
-Definition Zplus := [x,y:Z]
- Cases x y of
- ZERO y => y
- | x ZERO => x
- | (POS x') (POS y') => (POS (add x' y'))
- | (POS x') (NEG y') =>
- Cases (compare x' y' EGAL) of
- | EGAL => ZERO
- | INFERIEUR => (NEG (true_sub y' x'))
- | SUPERIEUR => (POS (true_sub x' y'))
- end
- | (NEG x') (POS y') =>
- Cases (compare x' y' EGAL) of
- | EGAL => ZERO
- | INFERIEUR => (POS (true_sub y' x'))
- | SUPERIEUR => (NEG (true_sub x' y'))
- end
- | (NEG x') (NEG y') => (NEG (add x' y'))
- end.
-
-V8Infix "+" Zplus : Z_scope.
-
-(** Opposite *)
-
-Definition Zopp := [x:Z]
- Cases x of
- ZERO => ZERO
- | (POS x) => (NEG x)
- | (NEG x) => (POS x)
- end.
-
-V8Notation "- x" := (Zopp x) : Z_scope.
-
-(** Successor on integers *)
-
-Definition Zs := [x:Z](Zplus x (POS xH)).
-
-(** Predecessor on integers *)
-
-Definition Zpred := [x:Z](Zplus x (NEG xH)).
-
-(** Subtraction on integers *)
-
-Definition Zminus := [m,n:Z](Zplus m (Zopp n)).
-
-V8Infix "-" Zminus : Z_scope.
-
-(** Multiplication on integers *)
-
-Definition Zmult := [x,y:Z]
- Cases x y of
- | ZERO _ => ZERO
- | _ ZERO => ZERO
- | (POS x') (POS y') => (POS (times x' y'))
- | (POS x') (NEG y') => (NEG (times x' y'))
- | (NEG x') (POS y') => (NEG (times x' y'))
- | (NEG x') (NEG y') => (POS (times x' y'))
- end.
-
-V8Infix "*" Zmult : Z_scope.
-
-(** Comparison of integers *)
-
-Definition Zcompare := [x,y:Z]
- Cases x y of
- | ZERO ZERO => EGAL
- | ZERO (POS y') => INFERIEUR
- | ZERO (NEG y') => SUPERIEUR
- | (POS x') ZERO => SUPERIEUR
- | (POS x') (POS y') => (compare x' y' EGAL)
- | (POS x') (NEG y') => SUPERIEUR
- | (NEG x') ZERO => INFERIEUR
- | (NEG x') (POS y') => INFERIEUR
- | (NEG x') (NEG y') => (Op (compare x' y' EGAL))
- end.
-
-V8Infix "?=" Zcompare (at level 70, no associativity) : Z_scope.
-
-Tactic Definition ElimCompare com1 com2:=
- Case (Dcompare (Zcompare com1 com2)); [ Idtac |
- Let x = FreshId "H" In Intro x; Case x; Clear x ].
-
-(** Sign function *)
-
-Definition Zsgn [z:Z] : Z :=
- Cases z of
- ZERO => ZERO
- | (POS p) => (POS xH)
- | (NEG p) => (NEG xH)
- end.
-
-(** Easier to handle variants of successor and addition *)
-
-Definition Zs' [x:Z] :=
- Cases x of
- | ZERO => (POS xH)
- | (POS x') => (POS (add_un x'))
- | (NEG x') => (Zsub_pos xH x')
- end.
-
-Definition Zpred' [x:Z] :=
- Cases x of
- | ZERO => (NEG xH)
- | (POS x') => (Zsub_pos x' xH)
- | (NEG x') => (NEG (add_un x'))
- end.
-
-Definition Zplus' := [x,y:Z]
- Cases x y of
- ZERO y => y
- | x ZERO => x
- | (POS x') (POS y') => (POS (add x' y'))
- | (POS x') (NEG y') => (Zsub_pos x' y')
- | (NEG x') (POS y') => (Zsub_pos y' x')
- | (NEG x') (NEG y') => (NEG (add x' y'))
- end.
-
-Open Local Scope Z_scope.
-
-(**********************************************************************)
-(** Inductive specification of Z *)
-
-Theorem Zind : (P:(Z ->Prop))
- (P ZERO) -> ((x:Z)(P x) ->(P (Zs' x))) -> ((x:Z)(P x) ->(P (Zpred' x))) ->
- (z:Z)(P z).
-Proof.
-Intros P H0 Hs Hp; NewDestruct z.
- Assumption.
- Apply Pind with P:=[p](P (POS p)).
- Change (P (Zs' ZERO)); Apply Hs; Apply H0.
- Intro n; Exact (Hs (POS n)).
- Apply Pind with P:=[p](P (NEG p)).
- Change (P (Zpred' ZERO)); Apply Hp; Apply H0.
- Intro n; Exact (Hp (NEG n)).
-Qed.
-
-(**********************************************************************)
-(** Properties of opposite on binary integer numbers *)
-
-Theorem Zopp_NEG : (x:positive) (Zopp (NEG x)) = (POS x).
-Proof.
-Reflexivity.
-Qed.
-
-(** [opp] is involutive *)
-
-Theorem Zopp_Zopp: (x:Z) (Zopp (Zopp x)) = x.
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-(** Injectivity of the opposite *)
-
-Theorem Zopp_intro : (x,y:Z) (Zopp x) = (Zopp y) -> x = y.
-Proof.
-Intros x y;Case x;Case y;Simpl;Intros; [
- Trivial | Discriminate H | Discriminate H | Discriminate H
-| Simplify_eq H; Intro E; Rewrite E; Trivial
-| Discriminate H | Discriminate H | Discriminate H
-| Simplify_eq H; Intro E; Rewrite E; Trivial ].
-Qed.
-
-(**********************************************************************)
-(** Properties of the double of an integer *)
-
-Lemma Zopp_Zdouble : (x:Z) (Zopp (Zdouble x))=(Zdouble (Zopp x)).
-Proof.
-NewDestruct x as [|p|p]; Reflexivity.
-Qed.
-
-Lemma Zopp_Zdouble_plus_one :
- (x:Z) (Zopp (Zdouble_plus_one x))=(Zdouble_minus_one (Zopp x)).
-Proof.
-NewDestruct x as [|p|p]; Reflexivity.
-Qed.
-
-Lemma Zopp_Zdouble_minus_one :
- (x:Z) (Zopp (Zdouble_minus_one x))=(Zdouble_plus_one (Zopp x)).
-Proof.
-NewDestruct x as [|p|p]; Reflexivity.
-Qed.
-
-Lemma Zdouble_minus_one_spec :
- (x:Z)(Zdouble_minus_one x) = (Zplus (Zdouble x) (NEG xH)).
-Proof.
-NewDestruct x as [|p|p]; Reflexivity Orelse Exact (POS_Zdouble_minus_one p).
-Qed.
-
-Lemma Zdouble_minus_one_add_un_xI :
- (x:positive) (Zdouble_minus_one (POS (add_un x))) = (POS (xI x)).
-Proof.
-NewDestruct x; Simpl; Try Rewrite double_moins_un_add_un_xI; Reflexivity.
-Qed.
-
-(** Permutations *)
-
-Lemma Zdouble_plus_one_Zdouble :
- (x:Z)(Zdouble_plus_one (Zdouble x))=(Zdouble_minus_one (Zdouble_plus_one x)).
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-Lemma Zdouble_plus_one_Zdouble_minus_one :
- (x:Z)(Zdouble_plus_one (Zdouble_minus_one x))=(Zdouble_minus_one (Zdouble x)).
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-Lemma Zdouble_plus_one_spec :
- (x:Z)(Zdouble_plus_one x)=(Zplus (Zdouble x) (POS xH)).
-Proof.
- NewDestruct x; Reflexivity.
-Qed.
-
-Lemma Zdouble_plus_one_Zdouble_minus_one_one :
- (x:Z)(Zdouble_plus_one x)=(Zdouble_minus_one (Zs' x)).
-Proof.
-NewDestruct x; Simpl.
- Reflexivity.
- Rewrite -> double_moins_un_add_un_xI; Reflexivity.
- NewDestruct p; Reflexivity.
-Qed.
-
-Lemma Zdouble_one_one_Zdouble_plus_one:
- (x:Z)(Zdouble (Zs' x)) = (Zs' (Zdouble_plus_one x)).
-Proof.
-NewDestruct x as [|p|p]; Try Reflexivity.
- NewDestruct p; Reflexivity.
-Qed.
-
-(**********************************************************************)
-(** Properties of the subtraction from positive to integers *)
-
-Infix Local 4 "--" Zsub_pos : Z_scope.
-
-Lemma Zsub_pos_x_x : (x:positive) x--x = ZERO.
-Proof.
-NewInduction x as [p IHp|p IHp|]; Simpl; Try Rewrite IHp; Reflexivity.
-Qed.
-
-Lemma Zopp_Zsub_pos : (x,y:positive) (Zopp (x--y)) = y--x.
-Proof.
-NewInduction x as [p IHp|p IHp|]; NewDestruct y as [q|q|]; Simpl;
- Try Rewrite <- IHp; Try Reflexivity.
- Apply Zopp_Zdouble.
- Apply Zopp_Zdouble_plus_one.
- Apply Zopp_Zdouble_minus_one.
- Apply Zopp_Zdouble.
-Qed.
-
-Lemma Zsub_pos_add_un_permute :
- (x,y:positive)(add_un x)--y = (Zs' (x--y)).
-Proof.
-NewInduction x as [x IHx|x|]; NewDestruct y as [y|y|]; Simpl.
- (* xI/xI *)
- Rewrite IHx; Simpl.
- NewDestruct (Zsub_pos x y); Simpl; Try Reflexivity.
- NewDestruct p; Simpl; Try Reflexivity.
- Rewrite double_moins_un_add_un_xI; Reflexivity.
- NewDestruct p; Reflexivity.
- (* xI/xO *)
- Rewrite IHx; Simpl.
- NewDestruct (Zsub_pos x y); Simpl; Try Reflexivity.
- NewDestruct p; Reflexivity.
- Rewrite double_moins_un_add_un_xI; Reflexivity.
- (* xO/xI *)
- NewDestruct (Zsub_pos x y); Simpl; Try Reflexivity.
- NewDestruct p; Simpl; Try Rewrite is_double_moins_un; Reflexivity.
- (* xO/xO *)
- NewDestruct (Zsub_pos x y); Simpl; Reflexivity.
- (* xO/xH *)
- NewDestruct x; Simpl; Try Reflexivity.
- Rewrite is_double_moins_un; Reflexivity.
- (* xH/xI *)
- NewDestruct y; Reflexivity.
- (* xH/xO *)
- NewDestruct y; Reflexivity.
- (* xH/xH *)
- Reflexivity.
-Qed.
-
-Lemma Zsub_pos_add_un_permute_Zopp :
- (x,y:positive) x--(add_un y) = (Zopp (Zs' (Zopp (x--y)))).
-Proof.
-Intros.
-Rewrite Zopp_Zsub_pos; Rewrite <- Zopp_Zsub_pos;
-Rewrite Zsub_pos_add_un_permute; Reflexivity.
-Qed.
-
-Lemma Zsub_pos_double_moins_un_xO_add_un :
- (x,y:positive)(Zsub_pos (double_moins_un x) y) = (Zsub_pos (xO x) (add_un y)).
-Proof.
-NewInduction x as [p IHp|p|]; NewDestruct y as [q|q|]; Simpl;
- Try Rewrite -> IHp; Try Reflexivity.
- Rewrite Zsub_pos_add_un_permute_Zopp;
- Change (xI p) with (add_un (xO p));
- Rewrite Zsub_pos_add_un_permute;
- NewDestruct (Zsub_pos (xO p) q).
- Reflexivity.
- NewDestruct p0; Simpl; Try Rewrite double_moins_un_add_un_xI; Reflexivity.
- NewDestruct p0; Simpl; Try Rewrite is_double_moins_un; Try Reflexivity.
- NewDestruct q; Simpl.
- Rewrite Zdouble_plus_one_Zdouble_minus_one; Reflexivity.
- Rewrite Zdouble_plus_one_Zdouble; Reflexivity.
- Reflexivity.
- Rewrite Zsub_pos_add_un_permute_Zopp; Simpl;
- NewDestruct (Zsub_pos (xO p) q); Simpl.
- Reflexivity.
- NewDestruct p0; Reflexivity.
- Rewrite double_moins_un_add_un_xI; Reflexivity.
- Rewrite Zsub_pos_add_un_permute_Zopp; Simpl;
- NewDestruct q; Simpl; Try Rewrite is_double_moins_un; Reflexivity.
- NewDestruct q; Reflexivity.
-Qed.
-
-Lemma Zdouble_minus_one_Zsub_pos :
- (x,y:positive)(Zdouble_minus_one (Zsub_pos x y))
- = (Zsub_pos (double_moins_un x) (xO y)).
-Proof.
-Intros; Rewrite Zsub_pos_double_moins_un_xO_add_un; Reflexivity.
-Qed.
-
-Lemma Zdouble_plus_one_Zsub_pos :
- (x,y:positive)(Zdouble_plus_one (x--y)) = (xO x)--(double_moins_un y).
-Proof.
-Intros; Rewrite <- Zopp_Zsub_pos with y := (xO x);
-Rewrite <- Zdouble_minus_one_Zsub_pos;
-Rewrite <- Zopp_Zsub_pos with y := y;
-Rewrite <- Zopp_Zdouble_plus_one;
-Rewrite Zopp_Zopp;
-Reflexivity.
-Qed.
-
-Lemma Zsub_pos_xI_double_moins_un :
- (x,y:positive)
- (Zdouble (Zs' (Zsub_pos x y))) = (Zsub_pos (xI x) (double_moins_un y)).
-Proof.
-Intros; Change (xI x) with (add_un (xO x));
-Rewrite -> Zsub_pos_add_un_permute; Rewrite <- Zdouble_plus_one_Zsub_pos.
-Apply Zdouble_one_one_Zdouble_plus_one.
-Qed.
-
-Lemma Zpred'_Zs' : (x:Z)(Zpred' (Zs' x))=x.
-Proof.
-NewDestruct x; Simpl.
- Reflexivity.
-NewDestruct p; Simpl; Try Rewrite double_moins_un_add_un_xI; Reflexivity.
-NewDestruct p; Simpl; Try Rewrite is_double_moins_un; Reflexivity.
-Qed.
-
-Lemma add_un_discr : (x:positive)(add_un x)<>x.
-Proof.
-NewDestruct x; Discriminate.
-Qed.
-
-Lemma double_moins_un_xO_discr : (x:positive)(double_moins_un x)<>(xO x).
-Proof.
-NewDestruct x; Discriminate.
-Qed.
-
-Lemma Z0_Zs'_discr : (x:Z)(Zs' x)<>x.
-Proof.
-NewDestruct x; Simpl.
- Discriminate.
- Injection; Apply add_un_discr.
- NewDestruct p; Simpl.
- Discriminate.
- Injection; Apply double_moins_un_xO_discr.
- Discriminate.
-Qed.
-
-(**********************************************************************)
-(** Other properties of binary integer numbers *)
-
-Hints Local Resolve compare_convert_O.
-
-Lemma ZL0 : (S (S O))=(plus (S O) (S O)).
-Proof.
-Reflexivity.
-Qed.
-
-(**********************************************************************)
-(** Properties of the addition on integers *)
-
-(** zero is left neutral for addition *)
-
-Theorem Zero_left: (x:Z) (Zplus ZERO x) = x.
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-(** zero is right neutral for addition *)
-
-Theorem Zero_right: (x:Z) (Zplus x ZERO) = x.
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-(*
-Lemma Zplus_S'_n: (x,y:Z) (Zplus (Zs' x) y) = (Zs' (Zplus x y)).
-Proof.
-NewInduction x; NewDestruct y; Simpl.
- Reflexivity.
- NewDestruct p; Simpl; Reflexivity.
- NewDestruct p; Try Unfold true_sub; Simpl; Reflexivity.
- Reflexivity.
- Rewrite ZL14bis; Reflexivity.
- Case (Dcompare (compare (add_un p) p0 EGAL)); Intro H; Try Rewrite H.
- Rewrite <- (compare_convert_EGAL ? ? H); Clear H.
- NewDestruct p; Simpl.
- Case (Dcompare (compare p (add_un p) EGAL)); Intro H'; Try Rewrite H'; Try Reflexivity.
- Assert H'' := (compare_convert_EGAL ? ? H').
- Symmetry in H''.
- Elim (add_un_discr p H'').
- Elim H'; Clear H'; Intro H.
- Case (Dcompare (compare p (add_un p) EGAL)); Intro H'; Try Rewrite H'; Try Reflexivity.
- Assert H'' := (compare_convert_EGAL ? ? H').
- Symmetry in H''.
-
- NewDestruct p; Simpl.
-*)
-
-(** opposite is right inverse for addition *)
-
-Theorem Zplus_inverse_r: (x:Z) (Zplus x (Zopp x)) = ZERO.
-Proof.
-NewDestruct x as [|p|p]; Simpl; [
- Reflexivity
-| Rewrite (convert_compare_EGAL p); Reflexivity
-| Rewrite (convert_compare_EGAL p); Reflexivity ].
-Qed.
-
-(** opposite distributes over addition *)
-
-Theorem Zopp_Zplus:
- (x,y:Z) (Zopp (Zplus x y)) = (Zplus (Zopp x) (Zopp y)).
-Proof.
-NewDestruct x as [|p|p]; NewDestruct y as [|q|q]; Simpl;
- Reflexivity Orelse NewDestruct (compare p q EGAL); Reflexivity.
-Qed.
-
-(** addition is commutative *)
-
-Theorem Zplus_sym: (x,y:Z) (Zplus x y) = (Zplus y x).
-Proof.
-NewInduction x as [|p|p];NewDestruct y as [|q|q];Simpl;Try Reflexivity.
- Rewrite add_sym; Reflexivity.
- Rewrite ZC4; NewDestruct (compare q p EGAL); Reflexivity.
- Rewrite ZC4; NewDestruct (compare q p EGAL); Reflexivity.
- Rewrite add_sym; Reflexivity.
-Qed.
-
-(** opposite is left inverse for addition *)
-
-Theorem Zplus_inverse_l: (x:Z) (Zplus (Zopp x) x) = ZERO.
-Proof.
-Intro; Rewrite Zplus_sym; Apply Zplus_inverse_r.
-Qed.
-
-Hints Local Resolve Zero_left Zero_right.
-
-(** addition is associative *)
-
-Theorem weak_assoc :
- (x,y:positive)(z:Z) (Zplus (POS x) (Zplus (POS y) z))=
- (Zplus (Zplus (POS x) (POS y)) z).
-Proof.
-Intros x y z';Case z'; [
- Auto with arith
-| Intros z;Simpl; Rewrite add_assoc;Auto with arith
-| Intros z; Simpl; ElimPcompare y z;
- Intros E0;Rewrite E0;
- ElimPcompare '(add x y) 'z;Intros E1;Rewrite E1; [
- Absurd (compare (add x y) z EGAL)=EGAL; [ (* Case 1 *)
- Rewrite convert_compare_SUPERIEUR; [
- Discriminate
- | Rewrite convert_add; Rewrite (compare_convert_EGAL y z E0);
- Elim (ZL4 x);Intros k E2;Rewrite E2; Simpl; Unfold gt lt; Apply le_n_S;
- Apply le_plus_r ]
- | Assumption ]
- | Absurd (compare (add x y) z EGAL)=INFERIEUR; [ (* Case 2 *)
- Rewrite convert_compare_SUPERIEUR; [
- Discriminate
- | Rewrite convert_add; Rewrite (compare_convert_EGAL y z E0);
- Elim (ZL4 x);Intros k E2;Rewrite E2; Simpl; Unfold gt lt; Apply le_n_S;
- Apply le_plus_r]
- | Assumption ]
- | Rewrite (compare_convert_EGAL y z E0); (* Case 3 *)
- Elim (sub_pos_SUPERIEUR (add x z) z);[
- Intros t H; Elim H;Intros H1 H2;Elim H2;Intros H3 H4;
- Unfold true_sub; Rewrite H1; Cut x=t; [
- Intros E;Rewrite E;Auto with arith
- | Apply simpl_add_r with z:=z; Rewrite <- H3; Rewrite add_sym; Trivial with arith ]
- | Pattern 1 z; Rewrite <- (compare_convert_EGAL y z E0); Assumption ]
- | Elim (sub_pos_SUPERIEUR z y); [ (* Case 4 *)
- Intros k H;Elim H;Intros H1 H2;Elim H2;Intros H3 H4; Unfold 1 true_sub;
- Rewrite H1; Cut x=k; [
- Intros E;Rewrite E; Rewrite (convert_compare_EGAL k); Trivial with arith
- | Apply simpl_add_r with z:=y; Rewrite (add_sym k y); Rewrite H3;
- Apply compare_convert_EGAL; Assumption ]
- | Apply ZC2;Assumption]
- | Elim (sub_pos_SUPERIEUR z y); [ (* Case 5 *)
- Intros k H;Elim H;Intros H1 H2;Elim H2;Intros H3 H4;
- Unfold 1 3 5 true_sub; Rewrite H1;
- Cut (compare x k EGAL)=INFERIEUR; [
- Intros E2;Rewrite E2; Elim (sub_pos_SUPERIEUR k x); [
- Intros i H5;Elim H5;Intros H6 H7;Elim H7;Intros H8 H9;
- Elim (sub_pos_SUPERIEUR z (add x y)); [
- Intros j H10;Elim H10;Intros H11 H12;Elim H12;Intros H13 H14;
- Unfold true_sub ;Rewrite H6;Rewrite H11; Cut i=j; [
- Intros E;Rewrite E;Auto with arith
- | Apply (simpl_add_l (add x y)); Rewrite H13;
- Rewrite (add_sym x y); Rewrite <- add_assoc; Rewrite H8;
- Assumption ]
- | Apply ZC2; Assumption]
- | Apply ZC2;Assumption]
- | Apply convert_compare_INFERIEUR;
- Apply simpl_lt_plus_l with p:=(convert y);
- Do 2 Rewrite <- convert_add; Apply compare_convert_INFERIEUR;
- Rewrite H3; Rewrite add_sym; Assumption ]
- | Apply ZC2; Assumption ]
- | Elim (sub_pos_SUPERIEUR z y); [ (* Case 6 *)
- Intros k H;Elim H;Intros H1 H2;Elim H2;Intros H3 H4;
- Elim (sub_pos_SUPERIEUR (add x y) z); [
- Intros i H5;Elim H5;Intros H6 H7;Elim H7;Intros H8 H9;
- Unfold true_sub; Rewrite H1;Rewrite H6;
- Cut (compare x k EGAL)=SUPERIEUR; [
- Intros H10;Elim (sub_pos_SUPERIEUR x k H10);
- Intros j H11;Elim H11;Intros H12 H13;Elim H13;Intros H14 H15;
- Rewrite H10; Rewrite H12; Cut i=j; [
- Intros H16;Rewrite H16;Auto with arith
- | Apply (simpl_add_l (add z k)); Rewrite <- (add_assoc z k j);
- Rewrite H14; Rewrite (add_sym z k); Rewrite <- add_assoc;
- Rewrite H8; Rewrite (add_sym x y); Rewrite add_assoc;
- Rewrite (add_sym k y); Rewrite H3; Trivial with arith]
- | Apply convert_compare_SUPERIEUR; Unfold lt gt;
- Apply simpl_lt_plus_l with p:=(convert y);
- Do 2 Rewrite <- convert_add; Apply compare_convert_INFERIEUR;
- Rewrite H3; Rewrite add_sym; Apply ZC1; Assumption ]
- | Assumption ]
- | Apply ZC2;Assumption ]
- | Absurd (compare (add x y) z EGAL)=EGAL; [ (* Case 7 *)
- Rewrite convert_compare_SUPERIEUR; [
- Discriminate
- | Rewrite convert_add; Unfold gt;Apply lt_le_trans with m:=(convert y);[
- Apply compare_convert_INFERIEUR; Apply ZC1; Assumption
- | Apply le_plus_r]]
- | Assumption ]
- | Absurd (compare (add x y) z EGAL)=INFERIEUR; [ (* Case 8 *)
- Rewrite convert_compare_SUPERIEUR; [
- Discriminate
- | Unfold gt; Apply lt_le_trans with m:=(convert y);[
- Exact (compare_convert_SUPERIEUR y z E0)
- | Rewrite convert_add; Apply le_plus_r]]
- | Assumption ]
- | Elim sub_pos_SUPERIEUR with 1:=E0;Intros k H1; (* Case 9 *)
- Elim sub_pos_SUPERIEUR with 1:=E1; Intros i H2;Elim H1;Intros H3 H4;
- Elim H4;Intros H5 H6; Elim H2;Intros H7 H8;Elim H8;Intros H9 H10;
- Unfold true_sub ;Rewrite H3;Rewrite H7; Cut (add x k)=i; [
- Intros E;Rewrite E;Auto with arith
- | Apply (simpl_add_l z);Rewrite (add_sym x k);
- Rewrite add_assoc; Rewrite H5;Rewrite H9;
- Rewrite add_sym; Trivial with arith ]]].
-Qed.
-
-Hints Local Resolve weak_assoc.
-
-Theorem Zplus_assoc :
- (n,m,p:Z) (Zplus n (Zplus m p))= (Zplus (Zplus n m) p).
-Proof.
-Intros x y z;Case x;Case y;Case z;Auto with arith; Intros; [
- Rewrite (Zplus_sym (NEG p0)); Rewrite weak_assoc;
- Rewrite (Zplus_sym (Zplus (POS p1) (NEG p0))); Rewrite weak_assoc;
- Rewrite (Zplus_sym (POS p1)); Trivial with arith
-| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus;
- Do 2 Rewrite Zopp_NEG; Rewrite Zplus_sym; Rewrite <- weak_assoc;
- Rewrite (Zplus_sym (Zopp (POS p1)));
- Rewrite (Zplus_sym (Zplus (POS p0) (Zopp (POS p1))));
- Rewrite (weak_assoc p); Rewrite weak_assoc; Rewrite (Zplus_sym (POS p0));
- Trivial with arith
-| Rewrite Zplus_sym; Rewrite (Zplus_sym (POS p0) (POS p));
- Rewrite <- weak_assoc; Rewrite Zplus_sym; Rewrite (Zplus_sym (POS p0));
- Trivial with arith
-| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus;
- Do 2 Rewrite Zopp_NEG; Rewrite (Zplus_sym (Zopp (POS p0)));
- Rewrite weak_assoc; Rewrite (Zplus_sym (Zplus (POS p1) (Zopp (POS p0))));
- Rewrite weak_assoc;Rewrite (Zplus_sym (POS p)); Trivial with arith
-| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus; Do 2 Rewrite Zopp_NEG;
- Apply weak_assoc
-| Apply Zopp_intro; Do 4 Rewrite Zopp_Zplus; Do 2 Rewrite Zopp_NEG;
- Apply weak_assoc]
-.
-Qed.
-
-V7only [Notation Zplus_assoc_l := Zplus_assoc.].
-
-Lemma Zplus_assoc_r : (n,m,p:Z)(Zplus (Zplus n m) p) =(Zplus n (Zplus m p)).
-Proof.
-Intros; Symmetry; Apply Zplus_assoc.
-Qed.
-
-(** Associativity mixed with commutativity *)
-
-Lemma Zplus_permute : (n,m,p:Z) (Zplus n (Zplus m p))=(Zplus m (Zplus n p)).
-Proof.
-Intros n m p;
-Rewrite Zplus_sym;Rewrite <- Zplus_assoc; Rewrite (Zplus_sym p n); Trivial with arith.
-Qed.
-
-(** addition simplifies *)
-
-Lemma Zsimpl_plus_l : (n,m,p:Z)(Zplus n m)=(Zplus n p)->m=p.
-Intros n m p H; Cut (Zplus (Zopp n) (Zplus n m))=(Zplus (Zopp n) (Zplus n p));[
- Do 2 Rewrite -> Zplus_assoc; Rewrite -> (Zplus_sym (Zopp n) n);
- Rewrite -> Zplus_inverse_r;Simpl; Trivial with arith
-| Rewrite -> H; Trivial with arith ].
-Qed.
-
-(** addition and successor permutes *)
-
-Lemma Zplus_S_n: (x,y:Z) (Zplus (Zs x) y) = (Zs (Zplus x y)).
-Proof.
-Intros x y; Unfold Zs; Rewrite (Zplus_sym (Zplus x y)); Rewrite Zplus_assoc;
-Rewrite (Zplus_sym (POS xH)); Trivial with arith.
-Qed.
-
-Lemma Zplus_n_Sm : (n,m:Z) (Zs (Zplus n m))=(Zplus n (Zs m)).
-Proof.
-Intros n m; Unfold Zs; Rewrite Zplus_assoc; Trivial with arith.
-Qed.
-
-Lemma Zplus_Snm_nSm : (n,m:Z)(Zplus (Zs n) m)=(Zplus n (Zs m)).
-Proof.
-Unfold Zs ;Intros n m; Rewrite <- Zplus_assoc; Rewrite (Zplus_sym (POS xH));
-Trivial with arith.
-Qed.
-
-(** Misc properties, usually redundant or non natural *)
-
-Lemma Zplus_n_O : (n:Z) n=(Zplus n ZERO).
-Proof.
-Symmetry; Apply Zero_right.
-Qed.
-
-Lemma Zplus_unit_left : (n,m:Z) (Zplus n ZERO)=m -> n=m.
-Proof.
-Intros n m; Rewrite Zero_right; Intro; Assumption.
-Qed.
-
-Lemma Zplus_unit_right : (n,m:Z) n=(Zplus m ZERO) -> n=m.
-Proof.
-Intros n m; Rewrite Zero_right; Intro; Assumption.
-Qed.
-
-Lemma Zplus_simpl : (x,y,z,t:Z) x=y -> z=t -> (Zplus x z)=(Zplus y t).
-Proof.
-Intros; Rewrite H; Rewrite H0; Reflexivity.
-Qed.
-
-Lemma Zplus_Zopp_expand : (x,y,z:Z)
- (Zplus x (Zopp y))=(Zplus (Zplus x (Zopp z)) (Zplus z (Zopp y))).
-Proof.
-Intros x y z.
-Rewrite <- (Zplus_assoc x).
-Rewrite (Zplus_assoc (Zopp z)).
-Rewrite Zplus_inverse_l.
-Reflexivity.
-Qed.
-
-(**********************************************************************)
-(** Properties of successor and predecessor on binary integer numbers *)
-Theorem Zn_Sn : (x:Z) ~ x=(Zs x).
-Proof.
-Intros n;Cut ~ZERO=(POS xH);[
- Unfold not ;Intros H1 H2;Apply H1;Apply (Zsimpl_plus_l n);Rewrite Zero_right;
- Exact H2
-| Discriminate ].
-Qed.
-
-Theorem add_un_Zs : (x:positive) (POS (add_un x)) = (Zs (POS x)).
-Proof.
-Intro; Rewrite -> ZL12; Unfold Zs; Simpl; Trivial with arith.
-Qed.
-
-(** successor and predecessor are inverse functions *)
-
-Lemma Zs_pred : (n:Z) n=(Zs (Zpred n)).
-Proof.
-Intros n; Unfold Zs Zpred ;Rewrite <- Zplus_assoc; Simpl; Rewrite Zero_right;
-Trivial with arith.
-Qed.
-
-Hints Immediate Zs_pred : zarith.
-
-Theorem Zpred_Sn : (x:Z) x=(Zpred (Zs x)).
-Proof.
-Intros m; Unfold Zpred Zs; Rewrite <- Zplus_assoc; Simpl;
-Rewrite Zplus_sym; Auto with arith.
-Qed.
-
-Theorem Zeq_add_S : (n,m:Z) (Zs n)=(Zs m) -> n=m.
-Proof.
-Intros n m H.
-Change (Zplus (Zplus (NEG xH) (POS xH)) n)=
- (Zplus (Zplus (NEG xH) (POS xH)) m);
-Do 2 Rewrite <- Zplus_assoc; Do 2 Rewrite (Zplus_sym (POS xH));
-Unfold Zs in H;Rewrite H; Trivial with arith.
-Qed.
-
-(** Misc properties, usually redundant or non natural *)
-
-Theorem Zeq_S : (n,m:Z) n=m -> (Zs n)=(Zs m).
-Proof.
-Intros n m H; Rewrite H; Reflexivity.
-Qed.
-
-Theorem Znot_eq_S : (n,m:Z) ~(n=m) -> ~((Zs n)=(Zs m)).
-Proof.
-Unfold not ;Intros n m H1 H2;Apply H1;Apply Zeq_add_S; Assumption.
-Qed.
-
-(**********************************************************************)
-(** Properties of subtraction on binary integer numbers *)
-
-Lemma Zminus_n_O : (x:Z) x=(Zminus x ZERO).
-Proof.
-Intro; Unfold Zminus; Simpl;Rewrite Zero_right; Trivial with arith.
-Qed.
-
-Lemma Zminus_n_n : (n:Z)(ZERO=(Zminus n n)).
-Proof.
-Intro; Unfold Zminus; Rewrite Zplus_inverse_r; Trivial with arith.
-Qed.
-
-Lemma Zplus_minus : (x,y,z:Z)(x=(Zplus y z))->(z=(Zminus x y)).
-Proof.
-Intros n m p H;Unfold Zminus;Apply (Zsimpl_plus_l m);
-Rewrite (Zplus_sym m (Zplus n (Zopp m))); Rewrite <- Zplus_assoc;
-Rewrite Zplus_inverse_l; Rewrite Zero_right; Rewrite H; Trivial with arith.
-Qed.
-
-Lemma Zminus_plus : (x,y:Z)(Zminus (Zplus x y) x)=y.
-Proof.
-Intros n m;Unfold Zminus ;Rewrite -> (Zplus_sym n m);Rewrite <- Zplus_assoc;
-Rewrite -> Zplus_inverse_r; Apply Zero_right.
-Qed.
-
-Lemma Zle_plus_minus : (n,m:Z) (Zplus n (Zminus m n))=m.
-Proof.
-Unfold Zminus; Intros n m; Rewrite Zplus_permute; Rewrite Zplus_inverse_r;
-Apply Zero_right.
-Qed.
-
-Lemma Zminus_Sn_m : (n,m:Z)((Zs (Zminus n m))=(Zminus (Zs n) m)).
-Proof.
-Intros n m;Unfold Zminus Zs; Rewrite (Zplus_sym n (Zopp m));
-Rewrite <- Zplus_assoc;Apply Zplus_sym.
-Qed.
-
-Lemma Zminus_plus_simpl :
- (x,y,z:Z)((Zminus x y)=(Zminus (Zplus z x) (Zplus z y))).
-Proof.
-Intros n m p;Unfold Zminus; Rewrite Zopp_Zplus; Rewrite Zplus_assoc;
-Rewrite (Zplus_sym p); Rewrite <- (Zplus_assoc n p); Rewrite Zplus_inverse_r;
-Rewrite Zero_right; Trivial with arith.
-Qed.
-
-Lemma Zminus_Zplus_compatible :
- (x,y,z:Z) (Zminus (Zplus x z) (Zplus y z)) = (Zminus x y).
-Intros x y n.
-Unfold Zminus.
-Rewrite -> Zopp_Zplus.
-Rewrite -> (Zplus_sym (Zopp y) (Zopp n)).
-Rewrite -> Zplus_assoc.
-Rewrite <- (Zplus_assoc x n (Zopp n)).
-Rewrite -> (Zplus_inverse_r n).
-Rewrite <- Zplus_n_O.
-Reflexivity.
-Qed.
-
-(** Misc redundant properties *)
-
-V7only [Set Implicit Arguments.].
-
-Lemma Zeq_Zminus : (x,y:Z)x=y -> (Zminus x y)=ZERO.
-Proof.
-Intros x y H; Rewrite H; Symmetry; Apply Zminus_n_n.
-Qed.
-
-Lemma Zminus_Zeq : (x,y:Z)(Zminus x y)=ZERO -> x=y.
-Proof.
-Intros x y H; Rewrite <- (Zle_plus_minus y x); Rewrite H; Apply Zero_right.
-Qed.
-
-V7only [Unset Implicit Arguments.].
-
-(**********************************************************************)
-(** Properties of multiplication on binary integer numbers *)
-
-(** One is neutral for multiplication *)
-
-Lemma Zmult_1_n : (n:Z)(Zmult (POS xH) n)=n.
-Proof.
-Intro x; NewDestruct x; Reflexivity.
-Qed.
-V7only [Notation Zmult_one := Zmult_1_n.].
-
-Lemma Zmult_n_1 : (n:Z)(Zmult n (POS xH))=n.
-Proof.
-Intro x; NewDestruct x; Simpl; Try Rewrite times_x_1; Reflexivity.
-Qed.
-
-(** Zero is absorbant for multiplication *)
-
-Theorem Zero_mult_left: (x:Z) (Zmult ZERO x) = ZERO.
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-Theorem Zero_mult_right: (x:Z) (Zmult x ZERO) = ZERO.
-Proof.
-NewDestruct x; Reflexivity.
-Qed.
-
-Hints Local Resolve Zero_mult_left Zero_mult_right.
-
-(** Commutativity of multiplication *)
-
-Theorem Zmult_sym : (x,y:Z) (Zmult x y) = (Zmult y x).
-Proof.
-NewDestruct x as [|p|p]; NewDestruct y as [|q|q]; Simpl;
- Try Rewrite (times_sym p q); Reflexivity.
-Qed.
-
-(** Associativity of multiplication *)
-
-Theorem Zmult_assoc :
- (x,y,z:Z) (Zmult x (Zmult y z))= (Zmult (Zmult x y) z).
-Proof.
-Intros x y z; NewDestruct x; NewDestruct y; NewDestruct z; Simpl;
- Try Rewrite times_assoc; Reflexivity.
-Qed.
-V7only [Notation Zmult_assoc_l := Zmult_assoc.].
-
-Lemma Zmult_assoc_r : (n,m,p:Z)((Zmult (Zmult n m) p) = (Zmult n (Zmult m p))).
-Proof.
-Intros n m p; Rewrite Zmult_assoc; Trivial with arith.
-Qed.
-
-(** Associativity mixed with commutativity *)
-
-Theorem Zmult_permute : (n,m,p:Z)(Zmult n (Zmult m p)) = (Zmult m (Zmult n p)).
-Proof.
-Intros x y z; Rewrite -> (Zmult_assoc y x z); Rewrite -> (Zmult_sym y x).
-Apply Zmult_assoc.
-Qed.
-
-(** Z is integral *)
-
-Theorem Zmult_eq: (x,y:Z) ~(x=ZERO) -> (Zmult y x) = ZERO -> y = ZERO.
-Proof.
-Intros x y; NewDestruct x as [|p|p].
- Intro H; Absurd ZERO=ZERO; Trivial.
- Intros _ H; NewDestruct y as [|q|q]; Reflexivity Orelse Discriminate.
- Intros _ H; NewDestruct y as [|q|q]; Reflexivity Orelse Discriminate.
-Qed.
-
-V7only [Set Implicit Arguments.].
-
-Lemma Zmult_zero : (x,y:Z)(Zmult x y)=ZERO -> x=ZERO \/ y=ZERO.
-Proof.
-NewDestruct x; NewDestruct y; Auto; Simpl; Intro H; Discriminate H.
-Qed.
-
-V7only [Unset Implicit Arguments.].
-
-(** Multiplication and Opposite *)
-
-Theorem Zopp_Zmult: (x,y:Z) (Zmult (Zopp x) y) = (Zopp (Zmult x y)).
-Proof.
-NewDestruct x; NewDestruct y; Reflexivity.
-Qed.
-
-Theorem Zopp_Zmult_r : (x,y:Z)(Zopp (Zmult x y)) = (Zmult x (Zopp y)).
-Intros x y; Rewrite Zmult_sym; Rewrite <- Zopp_Zmult; Apply Zmult_sym.
-Qed.
-
-Theorem Zopp_Zmult_l : (x,y:Z)(Zopp (Zmult x y)) = (Zmult (Zopp x) y).
-Proof.
-Intros x y; Symmetry; Apply Zopp_Zmult.
-Qed.
-
-Theorem Zmult_Zopp_left : (x,y:Z)(Zmult (Zopp x) y) = (Zmult x (Zopp y)).
-Intros; Rewrite Zopp_Zmult; Rewrite Zopp_Zmult_r; Trivial with arith.
-Qed.
-
-Theorem Zmult_Zopp_Zopp: (x,y:Z) (Zmult (Zopp x) (Zopp y)) = (Zmult x y).
-Proof.
-NewDestruct x; NewDestruct y; Reflexivity.
-Qed.
-
-Theorem Zopp_one : (x:Z)(Zopp x)=(Zmult x (NEG xH)).
-Induction x; Intros; Rewrite Zmult_sym; Auto with arith.
-Qed.
-
-(** Distributivity of multiplication over addition *)
-
-Theorem weak_Zmult_plus_distr_r:
- (x:positive)(y,z:Z)
- (Zmult (POS x) (Zplus y z)) = (Zplus (Zmult (POS x) y) (Zmult (POS x) z)).
-Proof.
-Intros x y' z';Case y';Case z';Auto with arith;Intros y z;
- (Simpl; Rewrite times_add_distr; Trivial with arith)
-Orelse
- (Simpl; ElimPcompare z y; Intros E0;Rewrite E0; [
- Rewrite (compare_convert_EGAL z y E0);
- Rewrite (convert_compare_EGAL (times x y)); Trivial with arith
- | Cut (compare (times x z) (times x y) EGAL)=INFERIEUR; [
- Intros E;Rewrite E; Rewrite times_true_sub_distr; [
- Trivial with arith
- | Apply ZC2;Assumption ]
- | Apply convert_compare_INFERIEUR;Do 2 Rewrite times_convert;
- Elim (ZL4 x);Intros h H1;Rewrite H1;Apply lt_mult_left;
- Exact (compare_convert_INFERIEUR z y E0)]
- | Cut (compare (times x z) (times x y) EGAL)=SUPERIEUR; [
- Intros E;Rewrite E; Rewrite times_true_sub_distr; Auto with arith
- | Apply convert_compare_SUPERIEUR; Unfold gt; Do 2 Rewrite times_convert;
- Elim (ZL4 x);Intros h H1;Rewrite H1;Apply lt_mult_left;
- Exact (compare_convert_SUPERIEUR z y E0) ]]).
-Qed.
-
-Theorem Zmult_plus_distr_r:
- (x,y,z:Z) (Zmult x (Zplus y z)) = (Zplus (Zmult x y) (Zmult x z)).
-Proof.
-Intros x y z; Case x; [
- Auto with arith
-| Intros x';Apply weak_Zmult_plus_distr_r
-| Intros p; Apply Zopp_intro; Rewrite Zopp_Zplus;
- Do 3 Rewrite <- Zopp_Zmult; Rewrite Zopp_NEG;
- Apply weak_Zmult_plus_distr_r ].
-Qed.
-
-Lemma Zmult_plus_distr_l :
- (n,m,p:Z)((Zmult (Zplus n m) p)=(Zplus (Zmult n p) (Zmult m p))).
-Proof.
-Intros n m p;Rewrite Zmult_sym;Rewrite Zmult_plus_distr_r;
-Do 2 Rewrite -> (Zmult_sym p); Trivial with arith.
-Qed.
-
-(** Distributivity of multiplication over subtraction *)
-
-Lemma Zmult_Zminus_distr_l :
- (x,y,z:Z)((Zmult (Zminus x y) z)=(Zminus (Zmult x z) (Zmult y z))).
-Proof.
-Intros; Unfold Zminus.
-Rewrite <- Zopp_Zmult.
-Apply Zmult_plus_distr_l.
-Qed.
-
-V7only [Notation Zmult_minus_distr := Zmult_Zminus_distr_l.].
-
-Lemma Zmult_Zminus_distr_r :
- (x,y,z:Z)(Zmult z (Zminus x y)) = (Zminus (Zmult z x) (Zmult z y)).
-Proof.
-Intros; Rewrite (Zmult_sym z (Zminus x y)).
-Rewrite (Zmult_sym z x).
-Rewrite (Zmult_sym z y).
-Apply Zmult_Zminus_distr_l.
-Qed.
-
-(** Simplification of multiplication for non-zero integers *)
-
-Lemma Zmult_reg_left : (x,y,z:Z) z<>ZERO -> (Zmult z x)=(Zmult z y) -> x=y.
-Proof.
-Intros.
-Generalize (Zeq_Zminus H0).
-Intro.
-Apply Zminus_Zeq.
-Rewrite <- Zmult_Zminus_distr_r in H1.
-Clear H0; NewDestruct (Zmult_zero H1).
-Contradiction.
-Trivial.
-Qed.
-
-Lemma Zmult_reg_right : (x,y,z:Z) z<>ZERO -> (Zmult x z)=(Zmult y z) -> x=y.
-Proof.
-Intros x y z Hz.
-Rewrite (Zmult_sym x z).
-Rewrite (Zmult_sym y z).
-Intro; Apply Zmult_reg_left with z; Assumption.
-Qed.
-
-(** Addition and multiplication by 2 *)
-
-Theorem Zplus_Zmult_2 : (x:Z) (Zplus x x) = (Zmult x (POS (xO xH))).
-Proof.
-Intros x; Pattern 1 2 x ; Rewrite <- (Zmult_n_1 x);
-Rewrite <- Zmult_plus_distr_r; Reflexivity.
-Qed.
-
-(** Multiplication and successor *)
-
-Lemma Zmult_n_Sm : (n,m:Z) (Zplus (Zmult n m) n)=(Zmult n (Zs m)).
-Proof.
-Intros n m;Unfold Zs; Rewrite Zmult_plus_distr_r;
-Rewrite (Zmult_sym n (POS xH));Rewrite Zmult_one; Trivial with arith.
-Qed.
-
-Lemma Zmult_Sm_n : (n,m:Z) (Zplus (Zmult n m) m)=(Zmult (Zs n) m).
-Proof.
-Intros n m; Unfold Zs; Rewrite Zmult_plus_distr_l; Rewrite Zmult_1_n;
-Trivial with arith.
-Qed.
-
-(** Misc redundant properties *)
-
-Lemma Zmult_n_O : (n:Z) ZERO=(Zmult n ZERO).
-Proof.
-Intro;Rewrite Zmult_sym;Simpl; Trivial with arith.
-Qed.
-
-Theorem Z_eq_mult:
- (x,y:Z) y = ZERO -> (Zmult y x) = ZERO.
-Intros x y H; Rewrite H; Auto with arith.
-Qed.
-
-(**********************************************************************)
-(** Comparison on integers *)
-
-Lemma Zcompare_x_x : (x:Z) (Zcompare x x) = EGAL.
-Proof.
-NewDestruct x as [|p|p]; Simpl; [ Reflexivity | Apply convert_compare_EGAL
- | Rewrite convert_compare_EGAL; Reflexivity ].
-Qed.
-
-Theorem Zcompare_EGAL_eq : (x,y:Z) (Zcompare x y) = EGAL -> x = y.
-Proof.
-NewDestruct x as [|x'|x'];NewDestruct y as [|y'|y'];Simpl;Intro H; Reflexivity Orelse Try Discriminate H; [
- Rewrite (compare_convert_EGAL x' y' H); Reflexivity
- | Rewrite (compare_convert_EGAL x' y'); [
- Reflexivity
- | NewDestruct (compare x' y' EGAL);
- Reflexivity Orelse Discriminate]].
-Qed.
-
-Theorem Zcompare_EGAL : (x,y:Z) (Zcompare x y) = EGAL <-> x = y.
-Proof.
-Intros x y;Split; Intro E; [ Apply Zcompare_EGAL_eq; Assumption
- | Rewrite E; Apply Zcompare_x_x ].
-Qed.
-
-Theorem Zcompare_ANTISYM :
- (x,y:Z) (Zcompare x y) = SUPERIEUR <-> (Zcompare y x) = INFERIEUR.
-Proof.
-Intros x y;Split; [
- Case x;Case y;Simpl;Intros;(Trivial with arith Orelse Discriminate H Orelse
- (Apply ZC1; Assumption) Orelse
- (Cut (compare p p0 EGAL)=SUPERIEUR; [
- Intros H1;Rewrite H1;Auto with arith
- | Apply ZC2; Generalize H ; Case (compare p0 p EGAL);
- Trivial with arith Orelse (Intros H2;Discriminate H2)]))
-| Case x;Case y;Simpl;Intros;(Trivial with arith Orelse Discriminate H Orelse
- (Apply ZC2; Assumption) Orelse
- (Cut (compare p0 p EGAL)=INFERIEUR; [
- Intros H1;Rewrite H1;Auto with arith
- | Apply ZC1; Generalize H ; Case (compare p p0 EGAL);
- Trivial with arith Orelse (Intros H2;Discriminate H2)]))].
-Qed.
-
-(** Transitivity of comparison *)
-
-Theorem Zcompare_trans_SUPERIEUR :
- (x,y,z:Z) (Zcompare x y) = SUPERIEUR ->
- (Zcompare y z) = SUPERIEUR ->
- (Zcompare x z) = SUPERIEUR.
-Proof.
-Intros x y z;Case x;Case y;Case z; Simpl;
-Try (Intros; Discriminate H Orelse Discriminate H0);
-Auto with arith; [
- Intros p q r H H0;Apply convert_compare_SUPERIEUR; Unfold gt;
- Apply lt_trans with m:=(convert q);
- Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
-| Intros p q r; Do 3 Rewrite <- ZC4; Intros H H0;
- Apply convert_compare_SUPERIEUR;Unfold gt;Apply lt_trans with m:=(convert q);
- Apply compare_convert_INFERIEUR;Apply ZC1;Assumption ].
-Qed.
-
-(** Comparison and opposite *)
-
-Theorem Zcompare_Zopp :
- (x,y:Z) (Zcompare x y) = (Zcompare (Zopp y) (Zopp x)).
-Proof.
-(Intros x y;Case x;Case y;Simpl;Auto with arith);
-Intros;Rewrite <- ZC4;Trivial with arith.
-Qed.
-
-Hints Local Resolve convert_compare_EGAL.
-
-(** Comparison first-order specification *)
-
-Lemma SUPERIEUR_POS :
- (x,y:Z) (Zcompare x y) = SUPERIEUR ->
- (EX h:positive |(Zplus x (Zopp y)) = (POS h)).
-Proof.
-Intros x y;Case x;Case y; [
- Simpl; Intros H; Discriminate H
-| Simpl; Intros p H; Discriminate H
-| Intros p H; Exists p; Simpl; Auto with arith
-| Intros p H; Exists p; Simpl; Auto with arith
-| Intros q p H; Exists (true_sub p q); Unfold Zplus Zopp;
- Unfold Zcompare in H; Rewrite H; Trivial with arith
-| Intros q p H; Exists (add p q); Simpl; Trivial with arith
-| Simpl; Intros p H; Discriminate H
-| Simpl; Intros q p H; Discriminate H
-| Unfold Zcompare; Intros q p; Rewrite <- ZC4; Intros H; Exists (true_sub q p);
- Simpl; Rewrite (ZC1 q p H); Trivial with arith].
-Qed.
-
-(** Comparison and addition *)
-
-Theorem weaken_Zcompare_Zplus_compatible :
- ((x,y:Z) (z:positive)
- (Zcompare (Zplus (POS z) x) (Zplus (POS z) y)) = (Zcompare x y)) ->
- (x,y,z:Z) (Zcompare (Zplus z x) (Zplus z y)) = (Zcompare x y).
-Proof.
-Intro H; NewDestruct z; [
- Reflexivity
-| Apply H
-| Rewrite (Zcompare_Zopp x y); Rewrite Zcompare_Zopp;
- Do 2 Rewrite Zopp_Zplus; Rewrite Zopp_NEG; Apply H ].
-Qed.
-
-Hints Local Resolve ZC4.
-
-Theorem weak_Zcompare_Zplus_compatible :
- (x,y:Z) (z:positive)
- (Zcompare (Zplus (POS z) x) (Zplus (POS z) y)) = (Zcompare x y).
-Proof.
-Intros x y z;Case x;Case y;Simpl;Auto with arith; [
- Intros p;Apply convert_compare_INFERIEUR; Apply ZL17
-| Intros p;ElimPcompare z p;Intros E;Rewrite E;Auto with arith;
- Apply convert_compare_SUPERIEUR; Rewrite true_sub_convert; [ Unfold gt ;
- Apply ZL16 | Assumption ]
-| Intros p;ElimPcompare z p;
- Intros E;Auto with arith; Apply convert_compare_SUPERIEUR;
- Unfold gt;Apply ZL17
-| Intros p q;
- ElimPcompare q p;
- Intros E;Rewrite E;[
- Rewrite (compare_convert_EGAL q p E); Apply convert_compare_EGAL
- | Apply convert_compare_INFERIEUR;Do 2 Rewrite convert_add;Apply lt_reg_l;
- Apply compare_convert_INFERIEUR with 1:=E
- | Apply convert_compare_SUPERIEUR;Unfold gt ;Do 2 Rewrite convert_add;
- Apply lt_reg_l;Exact (compare_convert_SUPERIEUR q p E) ]
-| Intros p q;
- ElimPcompare z p;
- Intros E;Rewrite E;Auto with arith;
- Apply convert_compare_SUPERIEUR; Rewrite true_sub_convert; [
- Unfold gt; Apply lt_trans with m:=(convert z); [Apply ZL16 | Apply ZL17]
- | Assumption ]
-| Intros p;ElimPcompare z p;Intros E;Rewrite E;Auto with arith; Simpl;
- Apply convert_compare_INFERIEUR;Rewrite true_sub_convert;[Apply ZL16|
- Assumption]
-| Intros p q;
- ElimPcompare z q;
- Intros E;Rewrite E;Auto with arith; Simpl;Apply convert_compare_INFERIEUR;
- Rewrite true_sub_convert;[
- Apply lt_trans with m:=(convert z) ;[Apply ZL16|Apply ZL17]
- | Assumption]
-| Intros p q; ElimPcompare z q; Intros E0;Rewrite E0;
- ElimPcompare z p; Intros E1;Rewrite E1; ElimPcompare q p;
- Intros E2;Rewrite E2;Auto with arith; [
- Absurd (compare q p EGAL)=INFERIEUR; [
- Rewrite <- (compare_convert_EGAL z q E0);
- Rewrite <- (compare_convert_EGAL z p E1);
- Rewrite (convert_compare_EGAL z); Discriminate
- | Assumption ]
- | Absurd (compare q p EGAL)=SUPERIEUR; [
- Rewrite <- (compare_convert_EGAL z q E0);
- Rewrite <- (compare_convert_EGAL z p E1);
- Rewrite (convert_compare_EGAL z);Discriminate
- | Assumption]
- | Absurd (compare z p EGAL)=INFERIEUR; [
- Rewrite (compare_convert_EGAL z q E0);
- Rewrite <- (compare_convert_EGAL q p E2);
- Rewrite (convert_compare_EGAL q);Discriminate
- | Assumption ]
- | Absurd (compare z p EGAL)=INFERIEUR; [
- Rewrite (compare_convert_EGAL z q E0); Rewrite E2;Discriminate
- | Assumption]
- | Absurd (compare z p EGAL)=SUPERIEUR;[
- Rewrite (compare_convert_EGAL z q E0);
- Rewrite <- (compare_convert_EGAL q p E2);
- Rewrite (convert_compare_EGAL q);Discriminate
- | Assumption]
- | Absurd (compare z p EGAL)=SUPERIEUR;[
- Rewrite (compare_convert_EGAL z q E0);Rewrite E2;Discriminate
- | Assumption]
- | Absurd (compare z q EGAL)=INFERIEUR;[
- Rewrite (compare_convert_EGAL z p E1);
- Rewrite (compare_convert_EGAL q p E2);
- Rewrite (convert_compare_EGAL p); Discriminate
- | Assumption]
- | Absurd (compare p q EGAL)=SUPERIEUR; [
- Rewrite <- (compare_convert_EGAL z p E1);
- Rewrite E0; Discriminate
- | Apply ZC2;Assumption ]
- | Simpl; Rewrite (compare_convert_EGAL q p E2);
- Rewrite (convert_compare_EGAL (true_sub p z)); Auto with arith
- | Simpl; Rewrite <- ZC4; Apply convert_compare_SUPERIEUR;
- Rewrite true_sub_convert; [
- Rewrite true_sub_convert; [
- Unfold gt; Apply simpl_lt_plus_l with p:=(convert z);
- Rewrite le_plus_minus_r; [
- Rewrite le_plus_minus_r; [
- Apply compare_convert_INFERIEUR;Assumption
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
- | Apply ZC2;Assumption ]
- | Apply ZC2;Assumption ]
- | Simpl; Rewrite <- ZC4; Apply convert_compare_INFERIEUR;
- Rewrite true_sub_convert; [
- Rewrite true_sub_convert; [
- Apply simpl_lt_plus_l with p:=(convert z);
- Rewrite le_plus_minus_r; [
- Rewrite le_plus_minus_r; [
- Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Assumption ]
- | Apply ZC2;Assumption]
- | Apply ZC2;Assumption ]
- | Absurd (compare z q EGAL)=INFERIEUR; [
- Rewrite (compare_convert_EGAL q p E2);Rewrite E1;Discriminate
- | Assumption ]
- | Absurd (compare q p EGAL)=INFERIEUR; [
- Cut (compare q p EGAL)=SUPERIEUR; [
- Intros E;Rewrite E;Discriminate
- | Apply convert_compare_SUPERIEUR; Unfold gt;
- Apply lt_trans with m:=(convert z); [
- Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
- | Apply compare_convert_INFERIEUR;Assumption ]]
- | Assumption ]
- | Absurd (compare z q EGAL)=SUPERIEUR; [
- Rewrite (compare_convert_EGAL z p E1);
- Rewrite (compare_convert_EGAL q p E2);
- Rewrite (convert_compare_EGAL p); Discriminate
- | Assumption ]
- | Absurd (compare z q EGAL)=SUPERIEUR; [
- Rewrite (compare_convert_EGAL z p E1);
- Rewrite ZC1; [Discriminate | Assumption ]
- | Assumption ]
- | Absurd (compare z q EGAL)=SUPERIEUR; [
- Rewrite (compare_convert_EGAL q p E2); Rewrite E1; Discriminate
- | Assumption ]
- | Absurd (compare q p EGAL)=SUPERIEUR; [
- Rewrite ZC1; [
- Discriminate
- | Apply convert_compare_SUPERIEUR; Unfold gt;
- Apply lt_trans with m:=(convert z); [
- Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
- | Apply compare_convert_INFERIEUR;Assumption ]]
- | Assumption ]
- | Simpl; Rewrite (compare_convert_EGAL q p E2); Apply convert_compare_EGAL
- | Simpl; Apply convert_compare_SUPERIEUR; Unfold gt;
- Rewrite true_sub_convert; [
- Rewrite true_sub_convert; [
- Apply simpl_lt_plus_l with p:=(convert p); Rewrite le_plus_minus_r; [
- Rewrite plus_sym; Apply simpl_lt_plus_l with p:=(convert q);
- Rewrite plus_assoc_l; Rewrite le_plus_minus_r; [
- Rewrite (plus_sym (convert q)); Apply lt_reg_l;
- Apply compare_convert_INFERIEUR;Assumption
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;
- Apply ZC1;Assumption ]
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Apply ZC1;
- Assumption ]
- | Assumption ]
- | Assumption ]
- | Simpl; Apply convert_compare_INFERIEUR; Rewrite true_sub_convert; [
- Rewrite true_sub_convert; [
- Apply simpl_lt_plus_l with p:=(convert q); Rewrite le_plus_minus_r; [
- Rewrite plus_sym; Apply simpl_lt_plus_l with p:=(convert p);
- Rewrite plus_assoc_l; Rewrite le_plus_minus_r; [
- Rewrite (plus_sym (convert p)); Apply lt_reg_l;
- Apply compare_convert_INFERIEUR;Apply ZC1;Assumption
- | Apply lt_le_weak; Apply compare_convert_INFERIEUR;Apply ZC1;
- Assumption ]
- | Apply lt_le_weak;Apply compare_convert_INFERIEUR;Apply ZC1;Assumption]
- | Assumption]
- | Assumption]]].
-Qed.
-
-Theorem Zcompare_Zplus_compatible :
- (x,y,z:Z) (Zcompare (Zplus z x) (Zplus z y)) = (Zcompare x y).
-Proof.
-Exact (weaken_Zcompare_Zplus_compatible weak_Zcompare_Zplus_compatible).
-Qed.
-
-Theorem Zcompare_Zplus_compatible2 :
- (r:relation)(x,y,z,t:Z)
- (Zcompare x y) = r -> (Zcompare z t) = r ->
- (Zcompare (Zplus x z) (Zplus y t)) = r.
-Proof.
-Intros r x y z t; Case r; [
- Intros H1 H2; Elim (Zcompare_EGAL x y); Elim (Zcompare_EGAL z t);
- Intros H3 H4 H5 H6; Rewrite H3; [
- Rewrite H5; [ Elim (Zcompare_EGAL (Zplus y t) (Zplus y t)); Auto with arith | Auto with arith ]
- | Auto with arith ]
-| Intros H1 H2; Elim (Zcompare_ANTISYM (Zplus y t) (Zplus x z));
- Intros H3 H4; Apply H3;
- Apply Zcompare_trans_SUPERIEUR with y:=(Zplus y z) ; [
- Rewrite Zcompare_Zplus_compatible;
- Elim (Zcompare_ANTISYM t z); Auto with arith
- | Do 2 Rewrite <- (Zplus_sym z);
- Rewrite Zcompare_Zplus_compatible;
- Elim (Zcompare_ANTISYM y x); Auto with arith]
-| Intros H1 H2;
- Apply Zcompare_trans_SUPERIEUR with y:=(Zplus x t) ; [
- Rewrite Zcompare_Zplus_compatible; Assumption
- | Do 2 Rewrite <- (Zplus_sym t);
- Rewrite Zcompare_Zplus_compatible; Assumption]].
-Qed.
-
-Lemma Zcompare_Zs_SUPERIEUR : (x:Z)(Zcompare (Zs x) x)=SUPERIEUR.
-Proof.
-Intro x; Unfold Zs; Pattern 2 x; Rewrite <- (Zero_right x);
-Rewrite Zcompare_Zplus_compatible;Reflexivity.
-Qed.
-
-Theorem Zcompare_et_un:
- (x,y:Z) (Zcompare x y)=SUPERIEUR <->
- ~(Zcompare x (Zplus y (POS xH)))=INFERIEUR.
-Proof.
-Intros x y; Split; [
- Intro H; (ElimCompare 'x '(Zplus y (POS xH)));[
- Intro H1; Rewrite H1; Discriminate
- | Intros H1; Elim SUPERIEUR_POS with 1:=H; Intros h H2;
- Absurd (gt (convert h) O) /\ (lt (convert h) (S O)); [
- Unfold not ;Intros H3;Elim H3;Intros H4 H5; Absurd (gt (convert h) O); [
- Unfold gt ;Apply le_not_lt; Apply le_S_n; Exact H5
- | Assumption]
- | Split; [
- Elim (ZL4 h); Intros i H3;Rewrite H3; Apply gt_Sn_O
- | Change (lt (convert h) (convert xH));
- Apply compare_convert_INFERIEUR;
- Change (Zcompare (POS h) (POS xH))=INFERIEUR;
- Rewrite <- H2; Rewrite <- [m,n:Z](Zcompare_Zplus_compatible m n y);
- Rewrite (Zplus_sym x);Rewrite Zplus_assoc; Rewrite Zplus_inverse_r;
- Simpl; Exact H1 ]]
- | Intros H1;Rewrite -> H1;Discriminate ]
-| Intros H; (ElimCompare 'x '(Zplus y (POS xH))); [
- Intros H1;Elim (Zcompare_EGAL x (Zplus y (POS xH))); Intros H2 H3;
- Rewrite (H2 H1); Exact (Zcompare_Zs_SUPERIEUR y)
- | Intros H1;Absurd (Zcompare x (Zplus y (POS xH)))=INFERIEUR;Assumption
- | Intros H1; Apply Zcompare_trans_SUPERIEUR with y:=(Zs y);
- [ Exact H1 | Exact (Zcompare_Zs_SUPERIEUR y)]]].
-Qed.
-
-(** Successor and comparison *)
-
-Theorem Zcompare_n_S : (n,m:Z)(Zcompare (Zs n) (Zs m)) = (Zcompare n m).
-Proof.
-Intros n m;Unfold Zs ;Do 2 Rewrite -> [t:Z](Zplus_sym t (POS xH));
-Rewrite -> Zcompare_Zplus_compatible;Auto with arith.
-Qed.
-
-(** Multiplication and comparison *)
-
-Theorem Zcompare_Zmult_compatible :
- (x:positive)(y,z:Z)
- (Zcompare (Zmult (POS x) y) (Zmult (POS x) z)) = (Zcompare y z).
-
-Induction x; [
- Intros p H y z;
- Cut (POS (xI p))=(Zplus (Zplus (POS p) (POS p)) (POS xH)); [
- Intros E; Rewrite E; Do 4 Rewrite Zmult_plus_distr_l;
- Do 2 Rewrite Zmult_one;
- Apply Zcompare_Zplus_compatible2; [
- Apply Zcompare_Zplus_compatible2; Apply H
- | Trivial with arith]
- | Simpl; Rewrite (add_x_x p); Trivial with arith]
-| Intros p H y z; Cut (POS (xO p))=(Zplus (POS p) (POS p)); [
- Intros E; Rewrite E; Do 2 Rewrite Zmult_plus_distr_l;
- Apply Zcompare_Zplus_compatible2; Apply H
- | Simpl; Rewrite (add_x_x p); Trivial with arith]
- | Intros y z; Do 2 Rewrite Zmult_one; Trivial with arith].
-Qed.
-
-(**********************************************************************)
-(** Relating binary positive numbers and binary integers *)
-
-Lemma POS_xI : (p:positive) (POS (xI p))=(Zplus (Zmult (POS (xO xH)) (POS p)) (POS xH)).
-Intro; Apply refl_equal.
-Qed.
-
-Lemma POS_xO : (p:positive) (POS (xO p))=(Zmult (POS (xO xH)) (POS p)).
-Intro; Apply refl_equal.
-Qed.
-
-Lemma NEG_xI : (p:positive) (NEG (xI p))=(Zminus (Zmult (POS (xO xH)) (NEG p)) (POS xH)).
-Intro; Apply refl_equal.
-Qed.
-
-Lemma NEG_xO : (p:positive) (NEG (xO p))=(Zmult (POS (xO xH)) (NEG p)).
-Reflexivity.
-Qed.
-
-Lemma POS_add : (p,p':positive)(POS (add p p'))=(Zplus (POS p) (POS p')).
-NewDestruct p; NewDestruct p'; Reflexivity.
-Qed.
-
-Lemma NEG_add : (p,p':positive)(NEG (add p p'))=(Zplus (NEG p) (NEG p')).
-NewDestruct p; NewDestruct p'; Reflexivity.
-Qed.
-
-(**********************************************************************)
-(** Order relations *)
-
-Definition Zlt := [x,y:Z](Zcompare x y) = INFERIEUR.
-Definition Zgt := [x,y:Z](Zcompare x y) = SUPERIEUR.
-Definition Zle := [x,y:Z]~(Zcompare x y) = SUPERIEUR.
-Definition Zge := [x,y:Z]~(Zcompare x y) = INFERIEUR.
-Definition Zne := [x,y:Z] ~(x=y).
-
-V8Infix "<=" Zle : Z_scope.
-V8Infix "<" Zlt : Z_scope.
-V8Infix ">=" Zge : Z_scope.
-V8Infix ">" Zgt : Z_scope.
-
-V8Notation "x <= y <= z" := (Zle x y)/\(Zle y z) :Z_scope.
-V8Notation "x <= y < z" := (Zle x y)/\(Zlt y z) :Z_scope.
-V8Notation "x < y < z" := (Zlt x y)/\(Zlt y z) :Z_scope.
-V8Notation "x < y <= z" := (Zlt x y)/\(Zle y z) :Z_scope.
-
-(**********************************************************************)
-(** Absolute value on integers *)
-
-Definition absolu [x:Z] : nat :=
- Cases x of
- ZERO => O
- | (POS p) => (convert p)
- | (NEG p) => (convert p)
- end.
-
-Definition Zabs [z:Z] : Z :=
- Cases z of
- ZERO => ZERO
- | (POS p) => (POS p)
- | (NEG p) => (POS p)
- end.
-
-(**********************************************************************)
-(** From [nat] to [Z] *)
-
-Definition inject_nat :=
- [x:nat]Cases x of
- O => ZERO
- | (S y) => (POS (anti_convert y))
- end.
-
-Require BinNat.
-
-Definition entier_of_Z :=
- [z:Z]Cases z of ZERO => Nul | (POS p) => (Pos p) | (NEG p) => (Pos p) end.
-
-Definition Z_of_entier :=
- [x:entier]Cases x of Nul => ZERO | (Pos p) => (POS p) end.
+Notation Z := Z.
+Notation POS := POS.
+Notation NEG := NEG.
+Notation ZERO := ZERO.
+Notation Zero_left := Zero_left.
+Notation Zopp_Zopp := Zopp_Zopp.
+Notation Zero_right := Zero_right.
+Notation Zplus_inverse_r := Zplus_inverse_r.
+Notation Zopp_Zplus := Zopp_Zplus.
+Notation Zplus_sym := Zplus_sym.
+Notation Zplus_inverse_l := Zplus_inverse_l.
+Notation Zopp_intro := Zopp_intro.
+Notation Zopp_NEG := Zopp_NEG.
+Notation weak_assoc := weak_assoc.
+Notation Zplus_assoc := Zplus_assoc.
+Notation Zplus_simpl := Zplus_simpl.
+Notation Zmult_sym := Zmult_sym.
+Notation Zmult_assoc := Zmult_assoc.
+Notation Zmult_one := Zmult_one.
+Notation lt_mult_left := lt_mult_left.
+Notation Zero_mult_left := Zero_mult_left.
+Notation Zero_mult_right := Zero_mult_right.
+Notation Zopp_Zmult := Zopp_Zmult.
+Notation Zmult_Zopp_Zopp := Zmult_Zopp_Zopp.
+Notation weak_Zmult_plus_distr_r := weak_Zmult_plus_distr_r.
+Notation Zmult_plus_distr_r := Zmult_plus_distr_r.
+Notation Zcompare_EGAL := Zcompare_EGAL.
+Notation Zcompare_ANTISYM := Zcompare_ANTISYM.
+Notation le_minus := le_minus.
+Notation Zcompare_Zopp := Zcompare_Zopp.
+Notation weaken_Zcompare_Zplus_compatible := weaken_Zcompare_Zplus_compatible.
+Notation weak_Zcompare_Zplus_compatible := weak_Zcompare_Zplus_compatible.
+Notation Zcompare_Zplus_compatible := Zcompare_Zplus_compatible.
+Notation Zcompare_trans_SUPERIEUR := Zcompare_trans_SUPERIEUR.
+Notation SUPERIEUR_POS := SUPERIEUR_POS.
+Export Datatypes.
+Export BinPos.
+Export BinNat.
+Export BinInt.
+Export Zcompare.
+].
diff --git a/theories/ZArith/zarith_aux.v b/theories/ZArith/zarith_aux.v
index 5338643ac..72a57d0fb 100644
--- a/theories/ZArith/zarith_aux.v
+++ b/theories/ZArith/zarith_aux.v
@@ -7,7 +7,6 @@
(***********************************************************************)
(*i $Id$ i*)
-Require fast_integer.
Require Export Zorder.
Require Export Zmin.
Require Export Zabs.
@@ -133,6 +132,7 @@ Notation Zminus_Sn_m := Zminus_Sn_m.
Notation Zlt_minus := Zlt_minus.
Notation Zlt_O_minus_lt := Zlt_O_minus_lt.
Notation Zmult_plus_distr_l := Zmult_plus_distr_l.
+Notation Zmult_plus_distr := BinInt.Zmult_plus_distr_l.
Notation Zmult_minus_distr := Zmult_minus_distr.
Notation Zmult_assoc_r := Zmult_assoc_r.
Notation Zmult_assoc_l := Zmult_assoc_l.
@@ -141,5 +141,7 @@ Notation Zmult_1_n := Zmult_1_n.
Notation Zmult_n_1 := Zmult_n_1.
Notation Zmult_Sm_n := Zmult_Sm_n.
Notation Zmult_Zplus_distr := Zmult_plus_distr_r.
-Notation Zmult_plus_distr := Zmult_plus_distr_l.
+Export Zorder.
+Export Zmin.
+Export Zabs.
].