diff options
-rw-r--r-- | plugins/micromega/RMicromega.v | 6 | ||||
-rw-r--r-- | plugins/nsatz/Nsatz.v | 12 | ||||
-rw-r--r-- | plugins/omega/OmegaLemmas.v | 7 | ||||
-rw-r--r-- | theories/Arith/Wf_nat.v | 17 | ||||
-rw-r--r-- | theories/Bool/Bool.v | 10 | ||||
-rw-r--r-- | theories/NArith/BinNat.v | 161 | ||||
-rw-r--r-- | theories/NArith/Ndigits.v | 688 | ||||
-rw-r--r-- | theories/NArith/Nnat.v | 332 | ||||
-rw-r--r-- | theories/Numbers/Rational/BigQ/QMake.v | 2 | ||||
-rw-r--r-- | theories/PArith/BinPos.v | 394 | ||||
-rw-r--r-- | theories/PArith/Pminmax.v | 8 | ||||
-rw-r--r-- | theories/PArith/Pnat.v | 511 | ||||
-rw-r--r-- | theories/Reals/RIneq.v | 41 | ||||
-rw-r--r-- | theories/Reals/Rfunctions.v | 249 | ||||
-rw-r--r-- | theories/ZArith/BinInt.v | 317 | ||||
-rw-r--r-- | theories/ZArith/Wf_Z.v | 28 | ||||
-rw-r--r-- | theories/ZArith/Zabs.v | 2 | ||||
-rw-r--r-- | theories/ZArith/Zcompare.v | 415 | ||||
-rw-r--r-- | theories/ZArith/Zdiv_def.v | 2 | ||||
-rw-r--r-- | theories/ZArith/Zlog_def.v | 50 | ||||
-rw-r--r-- | theories/ZArith/Zlogarithm.v | 23 | ||||
-rw-r--r-- | theories/ZArith/Zmisc.v | 56 | ||||
-rw-r--r-- | theories/ZArith/Znat.v | 287 | ||||
-rw-r--r-- | theories/ZArith/Zpow_def.v | 44 | ||||
-rw-r--r-- | theories/ZArith/Zpower.v | 2 |
25 files changed, 1753 insertions, 1911 deletions
diff --git a/plugins/micromega/RMicromega.v b/plugins/micromega/RMicromega.v index 2b6ef8c5d..3f29a4fcf 100644 --- a/plugins/micromega/RMicromega.v +++ b/plugins/micromega/RMicromega.v @@ -67,7 +67,7 @@ Lemma RZSORaddon : SORaddon R0 R1 Rplus Rmult Rminus Ropp (@eq R) Rle (* ring elements *) 0%Z 1%Z Zplus Zmult Zminus Zopp (* coefficients *) Zeq_bool Zle_bool - IZR Nnat.nat_of_N pow. + IZR nat_of_N pow. Proof. constructor. constructor ; intros ; try reflexivity. @@ -94,7 +94,7 @@ Definition INZ (n:N) : R := | Npos p => IZR (Zpos p) end. -Definition Reval_expr := eval_pexpr Rplus Rmult Rminus Ropp IZR Nnat.nat_of_N pow. +Definition Reval_expr := eval_pexpr Rplus Rmult Rminus Ropp IZR nat_of_N pow. Definition Reval_op2 (o:Op2) : R -> R -> Prop := @@ -112,7 +112,7 @@ Definition Reval_formula (e: PolEnv R) (ff : Formula Z) := let (lhs,o,rhs) := ff in Reval_op2 o (Reval_expr e lhs) (Reval_expr e rhs). Definition Reval_formula' := - eval_formula Rplus Rmult Rminus Ropp (@eq R) Rle Rlt IZR Nnat.nat_of_N pow. + eval_formula Rplus Rmult Rminus Ropp (@eq R) Rle Rlt IZR nat_of_N pow. Lemma Reval_formula_compat : forall env f, Reval_formula env f <-> Reval_formula' env f. Proof. diff --git a/plugins/nsatz/Nsatz.v b/plugins/nsatz/Nsatz.v index aa32b386c..e8e02f2ca 100644 --- a/plugins/nsatz/Nsatz.v +++ b/plugins/nsatz/Nsatz.v @@ -142,12 +142,12 @@ Definition check (lpe:list PEZ) (qe:PEZ) (certif: list (list PEZ) * list PEZ) := Definition PhiR : list R -> PolZ -> R := (Pphi 0 ring_plus ring_mult (gen_phiZ 0 1 ring_plus ring_mult ring_opp)). -Definition pow (r : R) (n : nat) := pow_N 1 ring_mult r (Nnat.N_of_nat n). +Definition pow (r : R) (n : nat) := pow_N 1 ring_mult r (N_of_nat n). Definition PEevalR : list R -> PEZ -> R := PEeval 0 ring_plus ring_mult ring_sub ring_opp (gen_phiZ 0 1 ring_plus ring_mult ring_opp) - Nnat.nat_of_N pow. + nat_of_N pow. Lemma P0Z_correct : forall l, PhiR l P0Z = 0. Proof. trivial. Qed. @@ -177,8 +177,8 @@ Proof. Qed. Lemma R_power_theory - : power_theory 1 ring_mult ring_eq Nnat.nat_of_N pow. -apply mkpow_th. unfold pow. intros. rewrite Nnat.N_of_nat_of_N. ring. Qed. + : power_theory 1 ring_mult ring_eq nat_of_N pow. +apply mkpow_th. unfold pow. intros. rewrite Nnat.N_of_nat_of_N. ring. Qed. Lemma norm_correct : forall (l : list R) (pe : PEZ), PEevalR l pe == PhiR l (norm pe). @@ -288,7 +288,7 @@ Fixpoint interpret3 t fv {struct t}: R := | (PEopp t1) => let v1 := interpret3 t1 fv in (ring_opp v1) | (PEpow t1 t2) => - let v1 := interpret3 t1 fv in pow v1 (Nnat.nat_of_N t2) + let v1 := interpret3 t1 fv in pow v1 (nat_of_N t2) | (PEc t1) => (IZR1 t1) | (PEX n) => List.nth (pred (nat_of_P n)) fv 0 end. @@ -484,7 +484,7 @@ Ltac nsatz_domain_generic radicalmax info lparam lvar tacsimpl Rd := tacsimpl; repeat (split;[assumption|idtac]); exact I | simpl in Hg2; tacsimpl; - apply Rdomain_pow with (interpret3 _ Rd c fv) (Nnat.nat_of_N r); auto with domain; + apply Rdomain_pow with (interpret3 _ Rd c fv) (nat_of_N r); auto with domain; tacsimpl; apply domain_axiom_one_zero || (simpl) || idtac "could not prove discrimination result" ] diff --git a/plugins/omega/OmegaLemmas.v b/plugins/omega/OmegaLemmas.v index ff433bbd8..5b6f4670f 100644 --- a/plugins/omega/OmegaLemmas.v +++ b/plugins/omega/OmegaLemmas.v @@ -298,3 +298,10 @@ Definition fast_Zred_factor5 (x y : Z) (P : Z -> Prop) Definition fast_Zred_factor6 (x : Z) (P : Z -> Prop) (H : P (x + 0)) := eq_ind_r P H (Zred_factor6 x). + +Theorem intro_Z : + forall n:nat, exists y : Z, Z_of_nat n = y /\ 0 <= y * 1 + 0. +Proof. + intros n; exists (Z_of_nat n); split; trivial. + rewrite Zmult_1_r, Zplus_0_r. apply Zle_0_nat. +Qed. diff --git a/theories/Arith/Wf_nat.v b/theories/Arith/Wf_nat.v index c16a13dfb..d3d7b5835 100644 --- a/theories/Arith/Wf_nat.v +++ b/theories/Arith/Wf_nat.v @@ -270,7 +270,18 @@ Theorem iter_nat_plus : forall (n m:nat) (A:Type) (f:A -> A) (x:A), iter_nat (n + m) A f x = iter_nat n A f (iter_nat m A f x). Proof. - simple induction n; - [ simpl in |- *; auto with arith - | intros; simpl in |- *; apply f_equal with (f := f); apply H ]. + induction n; simpl; trivial. + intros. now f_equal. +Qed. + +(** Preservation of invariants : if [f : A->A] preserves the invariant [Inv], + then the iterates of [f] also preserve it. *) + +Theorem iter_nat_invariant : + forall (n:nat) (A:Type) (f:A -> A) (Inv:A -> Prop), + (forall x:A, Inv x -> Inv (f x)) -> + forall x:A, Inv x -> Inv (iter_nat n A f x). +Proof. + induction n; simpl; trivial. + intros A f Inv Hf x Hx. apply Hf, IHn; trivial. Qed. diff --git a/theories/Bool/Bool.v b/theories/Bool/Bool.v index b13369368..f4649be04 100644 --- a/theories/Bool/Bool.v +++ b/theories/Bool/Bool.v @@ -257,6 +257,11 @@ Proof. intros. apply orb_false_iff; trivial. Qed. +Lemma orb_diag : forall b, b || b = b. +Proof. + destr_bool. +Qed. + (** [true] is a zero for [orb] *) Lemma orb_true_r : forall b:bool, b || true = true. @@ -362,6 +367,11 @@ Qed. Notation andb_b_false := andb_false_r (only parsing). Notation andb_false_b := andb_false_l (only parsing). +Lemma andb_diag : forall b, b && b = b. +Proof. + destr_bool. +Qed. + (** [true] is neutral for [andb] *) Lemma andb_true_r : forall b:bool, b && true = b. diff --git a/theories/NArith/BinNat.v b/theories/NArith/BinNat.v index eb89fb20d..51c5b462b 100644 --- a/theories/NArith/BinNat.v +++ b/theories/NArith/BinNat.v @@ -152,6 +152,20 @@ Definition Nmax (n n' : N) := match Ncompare n n' with | Gt => n end. +(** Translation from [N] to [nat] and back. *) + +Definition nat_of_N (a:N) := + match a with + | N0 => O + | Npos p => nat_of_P p + end. + +Definition N_of_nat (n:nat) := + match n with + | O => N0 + | S n' => Npos (P_of_succ_nat n') + end. + (** Decidability of equality. *) Definition N_eq_dec : forall n m : N, { n = m } + { n <> m }. @@ -229,7 +243,7 @@ Qed. Theorem Npred_succ : forall n : N, Npred (Nsucc n) = n. Proof. -destruct n as [| p]; simpl. reflexivity. +intros [| p]; simpl. reflexivity. case_eq (Psucc p); try (intros q H; rewrite <- H; now rewrite Ppred_succ). intro H; false_hyp H Psucc_not_one. Qed. @@ -249,7 +263,7 @@ Qed. Theorem Nplus_comm : forall n m:N, n + m = m + n. Proof. intros. -destruct n; destruct m; simpl in |- *; try reflexivity. +destruct n; destruct m; simpl; try reflexivity. rewrite Pplus_comm; reflexivity. Qed. @@ -259,51 +273,49 @@ intros. destruct n; try reflexivity. destruct m; try reflexivity. destruct p; try reflexivity. -simpl in |- *; rewrite Pplus_assoc; reflexivity. +simpl; rewrite Pplus_assoc; reflexivity. Qed. Theorem Nplus_succ : forall n m:N, Nsucc n + m = Nsucc (n + m). Proof. -destruct n; destruct m. - simpl in |- *; reflexivity. - unfold Nsucc, Nplus in |- *; rewrite <- Pplus_one_succ_l; reflexivity. - simpl in |- *; reflexivity. - simpl in |- *; rewrite Pplus_succ_permute_l; reflexivity. +destruct n, m. + simpl; reflexivity. + unfold Nsucc, Nplus; rewrite <- Pplus_one_succ_l; reflexivity. + simpl; reflexivity. + simpl; rewrite Pplus_succ_permute_l; reflexivity. Qed. Theorem Nsucc_0 : forall n : N, Nsucc n <> N0. Proof. -intro n; elim n; simpl Nsucc; intros; discriminate. +now destruct n. Qed. Theorem Nsucc_inj : forall n m:N, Nsucc n = Nsucc m -> n = m. Proof. -destruct n; destruct m; simpl in |- *; intro H; reflexivity || injection H; - clear H; intro H. - symmetry in H; contradiction Psucc_not_one with p. - contradiction Psucc_not_one with p. - rewrite Psucc_inj with (1 := H); reflexivity. +intros [|p] [|q] H; simpl in *; trivial; injection H; clear H; intro H. + now elim (Psucc_not_one q). + now elim (Psucc_not_one p). + apply Psucc_inj in H. now f_equal. Qed. Theorem Nplus_reg_l : forall n m p:N, n + m = n + p -> m = p. Proof. -intro n; pattern n in |- *; apply Nind; clear n; simpl in |- *. + induction n using Nind. trivial. - intros n IHn m p H0; do 2 rewrite Nplus_succ in H0. - apply IHn; apply Nsucc_inj; assumption. + intros m p H; rewrite 2 Nplus_succ in H. + apply Nsucc_inj in H. now apply IHn. Qed. (** Properties of subtraction. *) Lemma Nminus_N0_Nle : forall n n' : N, n - n' = N0 <-> n <= n'. Proof. -destruct n as [| p]; destruct n' as [| q]; unfold Nle; simpl; -split; intro H; try discriminate; try reflexivity. +intros [| p] [| q]; unfold Nle; simpl; +split; intro H; try easy. now elim H. -intro H1; apply Pminus_mask_Gt in H1. destruct H1 as [h [H1 _]]. -rewrite H1 in H; discriminate. -case_eq (Pcompare p q Eq); intro H1; rewrite H1 in H; try now elim H. -assert (H2 : p = q); [now apply Pcompare_Eq_eq |]. now rewrite H2, Pminus_mask_diag. +contradict H. now destruct (Pminus_mask_Gt _ _ H) as (h & -> & _). +destruct (Pcompare_spec p q); try now elim H. +subst. now rewrite Pminus_mask_diag. now rewrite Pminus_mask_Lt. Qed. @@ -314,10 +326,15 @@ Qed. Theorem Nminus_succ_r : forall n m : N, n - (Nsucc m) = Npred (n - m). Proof. -destruct n as [| p]; destruct m as [| q]; try reflexivity. +intros [|p] [|q]; trivial. now destruct p. simpl. rewrite Pminus_mask_succ_r, Pminus_mask_carry_spec. -now destruct (Pminus_mask p q) as [| r |]; [| destruct r |]. +now destruct (Pminus_mask p q) as [|[r|r|]|]. +Qed. + +Theorem Npred_minus : forall n, Npred n = Nminus n (Npos 1). +Proof. + intros [|[p|p|]]; trivial. Qed. (** Properties of multiplication *) @@ -334,21 +351,17 @@ Qed. Theorem Nmult_Sn_m : forall n m : N, (Nsucc n) * m = m + n * m. Proof. -destruct n as [| n]; destruct m as [| m]; simpl; auto. -rewrite Pmult_Sn_m; reflexivity. +intros [|n] [|m]; simpl; trivial. now rewrite Pmult_Sn_m. Qed. Theorem Nmult_1_r : forall n:N, n * Npos 1%positive = n. Proof. -destruct n; simpl in |- *; try reflexivity. -rewrite Pmult_1_r; reflexivity. +intros [|n]; simpl; trivial. now rewrite Pmult_1_r. Qed. Theorem Nmult_comm : forall n m:N, n * m = m * n. Proof. -intros. -destruct n; destruct m; simpl in |- *; try reflexivity. -rewrite Pmult_comm; reflexivity. +intros [|n] [|m]; simpl; trivial. now rewrite Pmult_comm. Qed. Theorem Nmult_assoc : forall n m p:N, n * (m * p) = n * m * p. @@ -357,7 +370,7 @@ intros. destruct n; try reflexivity. destruct m; try reflexivity. destruct p; try reflexivity. -simpl in |- *; rewrite Pmult_assoc; reflexivity. +simpl; rewrite Pmult_assoc; reflexivity. Qed. Theorem Nmult_plus_distr_r : forall n m p:N, (n + m) * p = n * p + m * p. @@ -365,7 +378,7 @@ Proof. intros. destruct n; try reflexivity. destruct m; destruct p; try reflexivity. -simpl in |- *; rewrite Pmult_plus_distr_r; reflexivity. +simpl; rewrite Pmult_plus_distr_r; reflexivity. Qed. Theorem Nmult_plus_distr_l : forall n m p:N, p * (n + m) = p * n + p * m. @@ -400,7 +413,7 @@ Qed. Theorem Ncompare_Eq_eq : forall n m:N, (n ?= m) = Eq -> n = m. Proof. -destruct n as [| n]; destruct m as [| m]; simpl in |- *; intro H; +destruct n as [| n]; destruct m as [| m]; simpl; intro H; reflexivity || (try discriminate H). rewrite (Pcompare_Eq_eq n m H); reflexivity. Qed. @@ -509,22 +522,6 @@ Proof. now apply (Pplus_lt_mono_l p). Qed. -Lemma Nmult_lt_mono_l : forall n m p, N0<n -> m<p -> n*m<n*p. -Proof. - intros [|n] m p. discriminate. intros _. - destruct m, p; try discriminate. auto. - simpl. - apply Pmult_lt_mono_l. -Qed. - -Lemma Nmult_le_mono_l : forall n m p, m<=p -> n*m<=n*p. -Proof. - intros [|n] m p. intros _ H. discriminate. - intros. apply Nle_lteq. apply Nle_lteq in H. destruct H; [left|right]. - now apply Nmult_lt_mono_l. - congruence. -Qed. - (** 0 is the least natural number *) Theorem Ncompare_0 : forall n : N, Ncompare n N0 <> Lt. @@ -567,9 +564,10 @@ Qed. (** Power *) Definition Npow n p := - match p with - | N0 => Npos 1 - | Npos p => Piter_op Nmult p n + match p, n with + | N0, _ => Npos 1 + | _, N0 => N0 + | Npos p, Npos q => Npos (Ppow q p) end. Infix "^" := Npow : N_scope. @@ -579,53 +577,32 @@ Proof. reflexivity. Qed. Lemma Npow_succ_r : forall n p, n^(Nsucc p) = n * n^p. Proof. - intros n p; destruct p; simpl. - now rewrite Nmult_1_r. - apply Piter_op_succ. apply Nmult_assoc. + intros [|q] [|p]; simpl; trivial; f_equal. + apply Ppow_succ_r. Qed. (** Base-2 logarithm *) -Fixpoint Plog2_N (p:positive) : N := - match p with - | p~0 => Nsucc (Plog2_N p) - | p~1 => Nsucc (Plog2_N p) - | 1 => N0 - end%positive. - Definition Nlog2 n := match n with - | N0 => N0 - | Npos p => Plog2_N p + | N0 => N0 + | Npos 1 => N0 + | Npos (p~0) => Npos (Psize_pos p) + | Npos (p~1) => Npos (Psize_pos p) end. -Lemma Plog2_N_spec : forall p, - (Npos 2)^(Plog2_N p) <= Npos p < (Npos 2)^(Nsucc (Plog2_N p)). -Proof. - induction p; simpl; try rewrite 2 Npow_succ_r. - (* p~1 *) - change (Npos p~1) with (Nsucc (Npos 2 * Npos p)). - split; destruct IHp as [LE LT]. - apply Nle_trans with (Npos 2 * Npos p). - now apply Nmult_le_mono_l. - apply Nle_lteq. left. - apply Ncompare_n_Sm. now right. - apply Nle_succ_l. apply Nle_succ_l in LT. - change (Nsucc (Nsucc (Npos 2 * Npos p))) with (Npos 2 * (Nsucc (Npos p))). - now apply Nmult_le_mono_l. - (* p~0 *) - change (Npos p~0) with (Npos 2 * Npos p). - split; destruct IHp. - now apply Nmult_le_mono_l. - now apply Nmult_lt_mono_l. - (* 1 *) - now split. -Qed. - Lemma Nlog2_spec : forall n, N0 < n -> (Npos 2)^(Nlog2 n) <= n < (Npos 2)^(Nsucc (Nlog2 n)). Proof. - intros [|n] Hn. discriminate. apply Plog2_N_spec. + intros [|[p|p|]] H; discriminate H || clear H; simpl; split. + eapply Nle_trans with (Npos (p~0)). + apply Psize_pos_le. + apply Nle_lteq; left. exact (Pcompare_p_Sp (p~0)). + apply Psize_pos_gt. + apply Psize_pos_le. + apply Psize_pos_gt. + discriminate. + reflexivity. Qed. Lemma Nlog2_nonpos : forall n, n<=N0 -> Nlog2 n = N0. @@ -643,8 +620,8 @@ Definition Neven n := end. Definition Nodd n := negb (Neven n). -Local Notation "1" := (Npos xH) : N_scope. -Local Notation "2" := (Npos (xO xH)) : N_scope. +Local Notation "1" := (Npos 1) : N_scope. +Local Notation "2" := (Npos 2) : N_scope. Lemma Neven_spec : forall n, Neven n = true <-> exists m, n=2*m. Proof. diff --git a/theories/NArith/Ndigits.v b/theories/NArith/Ndigits.v index 1992268ab..98e88c6a2 100644 --- a/theories/NArith/Ndigits.v +++ b/theories/NArith/Ndigits.v @@ -6,308 +6,542 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -Require Import Bool Setoid Bvector BinPos BinNat. +Require Import Bool Morphisms Setoid Bvector BinPos BinNat Wf_nat + Pnat Nnat Ndiv_def. + +Local Open Scope positive_scope. (** Operation over bits of a [N] number. *) -(** [xor] *) +(** Logical [or] *) + +Fixpoint Por (p q : positive) : positive := + match p, q with + | 1, q~0 => q~1 + | 1, _ => q + | p~0, 1 => p~1 + | _, 1 => p + | p~0, q~0 => (Por p q)~0 + | p~0, q~1 => (Por p q)~1 + | p~1, q~0 => (Por p q)~1 + | p~1, q~1 => (Por p q)~1 + end. -Fixpoint Pxor (p1 p2:positive) : N := - match p1, p2 with - | xH, xH => N0 - | xH, xO p2 => Npos (xI p2) - | xH, xI p2 => Npos (xO p2) - | xO p1, xH => Npos (xI p1) - | xO p1, xO p2 => Ndouble (Pxor p1 p2) - | xO p1, xI p2 => Ndouble_plus_one (Pxor p1 p2) - | xI p1, xH => Npos (xO p1) - | xI p1, xO p2 => Ndouble_plus_one (Pxor p1 p2) - | xI p1, xI p2 => Ndouble (Pxor p1 p2) +Definition Nor n m := + match n, m with + | N0, _ => m + | _, N0 => n + | Npos p, Npos q => Npos (Por p q) + end. + +(** Logical [and] *) + +Fixpoint Pand (p q : positive) : N := + match p, q with + | 1, q~0 => N0 + | 1, _ => Npos 1 + | p~0, 1 => N0 + | _, 1 => Npos 1 + | p~0, q~0 => Ndouble (Pand p q) + | p~0, q~1 => Ndouble (Pand p q) + | p~1, q~0 => Ndouble (Pand p q) + | p~1, q~1 => Ndouble_plus_one (Pand p q) end. -Definition Nxor (n n':N) := - match n, n' with - | N0, _ => n' +Definition Nand n m := + match n, m with + | N0, _ => N0 + | _, N0 => N0 + | Npos p, Npos q => Pand p q + end. + +(** Logical [diff] *) + +Fixpoint Pdiff (p q:positive) : N := + match p, q with + | 1, q~0 => Npos 1 + | 1, _ => N0 + | _~0, 1 => Npos p + | p~1, 1 => Npos (p~0) + | p~0, q~0 => Ndouble (Pdiff p q) + | p~0, q~1 => Ndouble (Pdiff p q) + | p~1, q~1 => Ndouble (Pdiff p q) + | p~1, q~0 => Ndouble_plus_one (Pdiff p q) + end. + +Fixpoint Ndiff n m := + match n, m with + | N0, _ => N0 | _, N0 => n - | Npos p, Npos p' => Pxor p p' + | Npos p, Npos q => Pdiff p q + end. + +(** [xor] *) + +Fixpoint Pxor (p q:positive) : N := + match p, q with + | 1, 1 => N0 + | 1, q~0 => Npos (q~1) + | 1, q~1 => Npos (q~0) + | p~0, 1 => Npos (p~1) + | p~0, q~0 => Ndouble (Pxor p q) + | p~0, q~1 => Ndouble_plus_one (Pxor p q) + | p~1, 1 => Npos (p~0) + | p~1, q~0 => Ndouble_plus_one (Pxor p q) + | p~1, q~1 => Ndouble (Pxor p q) + end. + +Definition Nxor (n m:N) := + match n, m with + | N0, _ => m + | _, N0 => n + | Npos p, Npos q => Pxor p q + end. + +(** For proving properties of these operations, we will use + an equivalence with functional streams of bit, cf [eqf] below *) + +(** Shift *) + +Definition Nshiftl_nat (a:N)(n:nat) := iter_nat n _ Ndouble a. + +Definition Nshiftr_nat (a:N)(n:nat) := iter_nat n _ Ndiv2 a. + +Definition Nshiftr a n := + match n with + | N0 => a + | Npos p => iter_pos p _ Ndiv2 a + end. + +Definition Nshiftl a n := + match a, n with + | _, N0 => a + | N0, _ => a + | Npos p, Npos q => Npos (iter_pos q _ xO p) end. -Lemma Nxor_neutral_left : forall n:N, Nxor N0 n = n. +(** Checking whether a particular bit is set on not *) + +Fixpoint Pbit (p:positive) : nat -> bool := + match p with + | 1 => fun n => match n with + | O => true + | S _ => false + end + | p~0 => fun n => match n with + | O => false + | S n' => Pbit p n' + end + | p~1 => fun n => match n with + | O => true + | S n' => Pbit p n' + end + end. + +Definition Nbit (a:N) := + match a with + | N0 => fun _ => false + | Npos p => Pbit p + end. + +(** Same, but with index in N *) + +Fixpoint Ptestbit p n := + match p, n with + | p~0, N0 => false + | _, N0 => true + | 1, _ => false + | p~0, _ => Ptestbit p (Npred n) + | p~1, _ => Ptestbit p (Npred n) + end. + +Definition Ntestbit a n := + match a with + | N0 => false + | Npos p => Ptestbit p n + end. + +Local Close Scope positive_scope. +Local Open Scope N_scope. + +(** Equivalence of Pbit and Ptestbit *) + +Lemma Ptestbit_Pbit : + forall p n, Ptestbit p (N_of_nat n) = Pbit p n. Proof. - trivial. + induction p as [p IH|p IH| ]; intros n; simpl. + rewrite <- N_of_pred, IH; destruct n; trivial. + rewrite <- N_of_pred, IH; destruct n; trivial. + destruct n; trivial. Qed. -Lemma Nxor_neutral_right : forall n:N, Nxor n N0 = n. +Lemma Ntestbit_Nbit : forall a n, Ntestbit a (N_of_nat n) = Nbit a n. Proof. - destruct n; trivial. + destruct a. trivial. apply Ptestbit_Pbit. Qed. -Lemma Nxor_comm : forall n n':N, Nxor n n' = Nxor n' n. +Lemma Pbit_Ptestbit : + forall p n, Pbit p (nat_of_N n) = Ptestbit p n. Proof. - destruct n; destruct n'; simpl; auto. - generalize p0; clear p0; induction p as [p Hrecp| p Hrecp| ]; simpl; - auto. - destruct p0; trivial; rewrite Hrecp; trivial. - destruct p0; trivial; rewrite Hrecp; trivial. - destruct p0 as [p| p| ]; simpl; auto. + intros; now rewrite <- Ptestbit_Pbit, N_of_nat_of_N. Qed. -Lemma Nxor_nilpotent : forall n:N, Nxor n n = N0. +Lemma Nbit_Ntestbit : + forall a n, Nbit a (nat_of_N n) = Ntestbit a n. Proof. - destruct n; trivial. - simpl. induction p as [p IHp| p IHp| ]; trivial. - simpl. rewrite IHp; reflexivity. - simpl. rewrite IHp; reflexivity. + destruct a. trivial. apply Pbit_Ptestbit. Qed. -(** Checking whether a particular bit is set on not *) +(** Equivalence of shifts, N and nat versions *) -Fixpoint Pbit (p:positive) : nat -> bool := - match p with - | xH => fun n:nat => match n with - | O => true - | S _ => false - end - | xO p => - fun n:nat => match n with - | O => false - | S n' => Pbit p n' - end - | xI p => fun n:nat => match n with - | O => true - | S n' => Pbit p n' - end - end. +Lemma Nshiftr_nat_equiv : + forall a n, Nshiftr_nat a (nat_of_N n) = Nshiftr a n. +Proof. + intros a [|n]; simpl; unfold Nshiftr_nat. + trivial. + symmetry. apply iter_nat_of_P. +Qed. -Definition Nbit (a:N) := - match a with - | N0 => fun _ => false - | Npos p => Pbit p - end. +Lemma Nshiftr_equiv_nat : + forall a n, Nshiftr a (N_of_nat n) = Nshiftr_nat a n. +Proof. + intros. now rewrite <- Nshiftr_nat_equiv, nat_of_N_of_nat. +Qed. + +Lemma Nshiftl_nat_equiv : + forall a n, Nshiftl_nat a (nat_of_N n) = Nshiftl a n. +Proof. + intros [|a] [|n]; simpl; unfold Nshiftl_nat; trivial. + apply iter_nat_invariant; intros; now subst. + rewrite <- iter_nat_of_P. symmetry. now apply iter_pos_swap_gen. +Qed. + +Lemma Nshiftl_equiv_nat : + forall a n, Nshiftl a (N_of_nat n) = Nshiftl_nat a n. +Proof. + intros. now rewrite <- Nshiftl_nat_equiv, nat_of_N_of_nat. +Qed. + +(** Correctness proofs for shifts *) -(** Auxiliary results about streams of bits *) +Lemma Nshiftl_mult_pow : forall a n, Nshiftl a n = a * 2^n. +Proof. + intros [|a] [|n]; simpl; trivial. + now rewrite Pmult_1_r. + f_equal. + set (f x := Pmult x a). + rewrite Pmult_comm. fold (f (2^n))%positive. + change a with (f xH). + unfold Ppow. symmetry. now apply iter_pos_swap_gen. +Qed. + +(* +Lemma Nshiftr_div_pow : forall a n, Nshiftr a n = a / 2^n. +*) + +(** Equality over functional streams of bits *) Definition eqf (f g:nat -> bool) := forall n:nat, f n = g n. -Lemma eqf_sym : forall f f':nat -> bool, eqf f f' -> eqf f' f. +Instance eqf_equiv : Equivalence eqf. +Proof. + split; congruence. +Qed. + +Local Infix "==" := eqf (at level 70, no associativity). + +(** If two numbers produce the same stream of bits, they are equal. *) + +Local Notation Step H := (fun n => H (S n)). + +Lemma Pbit_faithful_0 : forall p, ~(Pbit p == (fun _ => false)). Proof. - unfold eqf. intros. rewrite H. reflexivity. + induction p as [p IHp|p IHp| ]; intros H; try discriminate (H O). + apply (IHp (Step H)). Qed. -Lemma eqf_refl : forall f:nat -> bool, eqf f f. +Lemma Pbit_faithful : forall p p', Pbit p == Pbit p' -> p = p'. Proof. - unfold eqf. trivial. + induction p as [p IHp|p IHp| ]; intros [p'|p'|] H; trivial; + try discriminate (H O). + f_equal. apply (IHp _ (Step H)). + destruct (Pbit_faithful_0 _ (Step H)). + f_equal. apply (IHp _ (Step H)). + symmetry in H. destruct (Pbit_faithful_0 _ (Step H)). Qed. -Lemma eqf_trans : - forall f f' f'':nat -> bool, eqf f f' -> eqf f' f'' -> eqf f f''. +Lemma Nbit_faithful : forall n n', Nbit n == Nbit n' -> n = n'. Proof. - unfold eqf. intros. rewrite H. exact (H0 n). + intros [|p] [|p'] H; trivial. + symmetry in H. destruct (Pbit_faithful_0 _ H). + destruct (Pbit_faithful_0 _ H). + f_equal. apply Pbit_faithful, H. Qed. +Lemma Nbit_faithful_iff : forall n n', Nbit n == Nbit n' <-> n = n'. +Proof. + split. apply Nbit_faithful. intros; now subst. +Qed. + + +(** Bit operations for functional streams of bits *) + +Definition orf (f g:nat -> bool) (n:nat) := (f n) || (g n). +Definition andf (f g:nat -> bool) (n:nat) := (f n) && (g n). +Definition difff (f g:nat -> bool) (n:nat) := (f n) && negb (g n). Definition xorf (f g:nat -> bool) (n:nat) := xorb (f n) (g n). -Lemma xorf_eq : - forall f f', eqf (xorf f f') (fun n => false) -> eqf f f'. +Instance eqf_orf : Proper (eqf==>eqf==>eqf) orf. Proof. - unfold eqf, xorf. intros. apply xorb_eq, H. + unfold orf. congruence. Qed. -Lemma xorf_assoc : - forall f f' f'', - eqf (xorf (xorf f f') f'') (xorf f (xorf f' f'')). +Instance eqf_andf : Proper (eqf==>eqf==>eqf) andf. Proof. - unfold eqf, xorf. intros. apply xorb_assoc. + unfold andf. congruence. Qed. -Lemma eqf_xorf : - forall f f' f'' f''', - eqf f f' -> eqf f'' f''' -> eqf (xorf f f'') (xorf f' f'''). +Instance eqf_difff : Proper (eqf==>eqf==>eqf) difff. Proof. - unfold eqf, xorf. intros. rewrite H. rewrite H0. reflexivity. + unfold difff. congruence. Qed. -(** End of auxilliary results *) +Instance eqf_xorf : Proper (eqf==>eqf==>eqf) xorf. +Proof. + unfold xorf. congruence. +Qed. -(** This part is aimed at proving that if two numbers produce - the same stream of bits, then they are equal. *) +(** We now describe the semantics of [Nxor] and other bitwise + operations in terms of bit streams. *) -Lemma Nbit_faithful_1 : forall a:N, eqf (Nbit N0) (Nbit a) -> N0 = a. +Lemma Pxor_semantics : forall p p', + Nbit (Pxor p p') == xorf (Pbit p) (Pbit p'). Proof. - destruct a. trivial. - induction p as [p IHp| p IHp| ]; intro H. - absurd (N0 = Npos p). discriminate. - exact (IHp (fun n => H (S n))). - absurd (N0 = Npos p). discriminate. - exact (IHp (fun n => H (S n))). - absurd (false = true). discriminate. - exact (H 0). + induction p as [p IHp|p IHp|]; intros [p'|p'|] [|n]; trivial; simpl; + (specialize (IHp p'); destruct Pxor; trivial; apply (IHp n)) || + (unfold xorf; now rewrite ?xorb_false_l, ?xorb_false_r). Qed. -Lemma Nbit_faithful_2 : - forall a:N, eqf (Nbit (Npos 1)) (Nbit a) -> Npos 1 = a. +Lemma Nxor_semantics : forall a a', + Nbit (Nxor a a') == xorf (Nbit a) (Nbit a'). Proof. - destruct a. intros. absurd (true = false). discriminate. - exact (H 0). - destruct p. intro H. absurd (N0 = Npos p). discriminate. - exact (Nbit_faithful_1 (Npos p) (fun n:nat => H (S n))). - intros. absurd (true = false). discriminate. - exact (H 0). - trivial. + intros [|p] [|p'] n; simpl; unfold xorf; trivial. + now rewrite xorb_false_l. + now rewrite xorb_false_r. + apply Pxor_semantics. Qed. -Lemma Nbit_faithful_3 : - forall (a:N) (p:positive), - (forall p':positive, eqf (Nbit (Npos p)) (Nbit (Npos p')) -> p = p') -> - eqf (Nbit (Npos (xO p))) (Nbit a) -> Npos (xO p) = a. +Lemma Por_semantics : forall p p', + Pbit (Por p p') == orf (Pbit p) (Pbit p'). Proof. - destruct a; intros. cut (eqf (Nbit N0) (Nbit (Npos (xO p)))). - intro. rewrite (Nbit_faithful_1 (Npos (xO p)) H1). reflexivity. - unfold eqf. intro. unfold eqf in H0. rewrite H0. reflexivity. - destruct p. discriminate (H0 O). - rewrite (H p (fun n => H0 (S n))). reflexivity. - discriminate (H0 0). + induction p as [p IHp|p IHp|]; intros [p'|p'|] [|n]; trivial; + unfold orf; apply (IHp p' n) || now rewrite orb_false_r. Qed. -Lemma Nbit_faithful_4 : - forall (a:N) (p:positive), - (forall p':positive, eqf (Nbit (Npos p)) (Nbit (Npos p')) -> p = p') -> - eqf (Nbit (Npos (xI p))) (Nbit a) -> Npos (xI p) = a. +Lemma Nor_semantics : forall a a', + Nbit (Nor a a') == orf (Nbit a) (Nbit a'). Proof. - destruct a; intros. cut (eqf (Nbit N0) (Nbit (Npos (xI p)))). - intro. rewrite (Nbit_faithful_1 (Npos (xI p)) H1). reflexivity. - intro. rewrite H0. reflexivity. - destruct p. rewrite (H p (fun n:nat => H0 (S n))). reflexivity. - discriminate (H0 0). - cut (eqf (Nbit (Npos 1)) (Nbit (Npos (xI p0)))). - intro. discriminate (Nbit_faithful_1 (Npos p0) (fun n:nat => H1 (S n))). - intro. rewrite H0. reflexivity. + intros [|p] [|p'] n; simpl; unfold orf; trivial. + now rewrite orb_false_r. + apply Por_semantics. Qed. -Lemma Nbit_faithful : forall a a':N, eqf (Nbit a) (Nbit a') -> a = a'. +Lemma Pand_semantics : forall p p', + Nbit (Pand p p') == andf (Pbit p) (Pbit p'). Proof. - destruct a. exact Nbit_faithful_1. - induction p. intros a' H. apply Nbit_faithful_4. intros. - assert (Npos p = Npos p') by exact (IHp (Npos p') H0). - inversion H1. reflexivity. - assumption. - intros. apply Nbit_faithful_3. intros. - assert (Npos p = Npos p') by exact (IHp (Npos p') H0). - inversion H1. reflexivity. - assumption. - exact Nbit_faithful_2. + induction p as [p IHp|p IHp|]; intros [p'|p'|] [|n]; trivial; simpl; + (specialize (IHp p'); destruct Pand; trivial; apply (IHp n)) || + (unfold andf; now rewrite andb_false_r). Qed. -(** We now describe the semantics of [Nxor] in terms of bit streams. *) +Lemma Nand_semantics : forall a a', + Nbit (Nand a a') == andf (Nbit a) (Nbit a'). +Proof. + intros [|p] [|p'] n; simpl; unfold andf; trivial. + now rewrite andb_false_r. + apply Pand_semantics. +Qed. -Lemma Nxor_sem_1 : forall a':N, Nbit (Nxor N0 a') 0 = Nbit a' 0. +Lemma Pdiff_semantics : forall p p', + Nbit (Pdiff p p') == difff (Pbit p) (Pbit p'). Proof. - trivial. + induction p as [p IHp|p IHp|]; intros [p'|p'|] [|n]; trivial; simpl; + (specialize (IHp p'); destruct Pdiff; trivial; apply (IHp n)) || + (unfold difff; simpl; now rewrite andb_true_r). Qed. -Lemma Nxor_sem_2 : - forall a':N, Nbit (Nxor (Npos 1) a') 0 = negb (Nbit a' 0). +Lemma Ndiff_semantics : forall a a', + Nbit (Ndiff a a') == difff (Nbit a) (Nbit a'). Proof. - intro. destruct a'. trivial. - destruct p; trivial. + intros [|p] [|p'] n; simpl; unfold difff; trivial. + simpl. now rewrite andb_true_r. + apply Pdiff_semantics. Qed. -Lemma Nxor_sem_3 : - forall (p:positive) (a':N), - Nbit (Nxor (Npos (xO p)) a') 0 = Nbit a' 0. +Hint Rewrite Nxor_semantics Nor_semantics + Nand_semantics Ndiff_semantics : bitwise_semantics. + +Ltac bitwise_semantics := + apply Nbit_faithful; autorewrite with bitwise_semantics; + intro n; unfold xorf, orf, andf, difff. + +(** Now, we can easily deduce properties of [Nxor] and others + from properties of [xorb] and others. *) + +Lemma Nxor_eq : forall a a', Nxor a a' = 0 -> a = a'. Proof. - intros. destruct a'. trivial. - simpl. destruct p0; trivial. - destruct (Pxor p p0); trivial. - destruct (Pxor p p0); trivial. + intros a a' H. bitwise_semantics. apply xorb_eq. + rewrite <- Nbit_faithful_iff, Nxor_semantics in H. apply H. Qed. -Lemma Nxor_sem_4 : - forall (p:positive) (a':N), - Nbit (Nxor (Npos (xI p)) a') 0 = negb (Nbit a' 0). +Lemma Nxor_nilpotent : forall a, Nxor a a = 0. Proof. - intros. destruct a'. trivial. - simpl. destruct p0; trivial. - destruct (Pxor p p0); trivial. - destruct (Pxor p p0); trivial. + intros. bitwise_semantics. apply xorb_nilpotent. Qed. -Lemma Nxor_sem_5 : - forall a a':N, Nbit (Nxor a a') 0 = xorf (Nbit a) (Nbit a') 0. +Lemma Nxor_0_l : forall n, Nxor 0 n = n. Proof. - destruct a; intro. change (Nbit a' 0 = xorb false (Nbit a' 0)). rewrite false_xorb. trivial. - destruct p. apply Nxor_sem_4. - change (Nbit (Nxor (Npos (xO p)) a') 0 = xorb false (Nbit a' 0)). - rewrite false_xorb. apply Nxor_sem_3. apply Nxor_sem_2. + trivial. Qed. +Notation Nxor_neutral_left := Nxor_0_l (only parsing). -Lemma Nxor_sem_6 : - forall n:nat, - (forall a a':N, Nbit (Nxor a a') n = xorf (Nbit a) (Nbit a') n) -> - forall a a':N, - Nbit (Nxor a a') (S n) = xorf (Nbit a) (Nbit a') (S n). +Lemma Nxor_0_r : forall n, Nxor n 0 = n. Proof. - intros. -(* pose proof (fun p1 p2 => H (Npos p1) (Npos p2)) as H'. clear H. rename H' into H.*) - generalize (fun p1 p2 => H (Npos p1) (Npos p2)); clear H; intro H. - unfold xorf in *. - destruct a as [|p]. simpl Nbit; rewrite false_xorb. reflexivity. - destruct a' as [|p0]. - simpl Nbit; rewrite xorb_false. reflexivity. - destruct p. destruct p0; simpl Nbit in *. - rewrite <- H; simpl; case (Pxor p p0); trivial. - rewrite <- H; simpl; case (Pxor p p0); trivial. - rewrite xorb_false. reflexivity. - destruct p0; simpl Nbit in *. - rewrite <- H; simpl; case (Pxor p p0); trivial. - rewrite <- H; simpl; case (Pxor p p0); trivial. - rewrite xorb_false. reflexivity. - simpl Nbit. rewrite false_xorb. destruct p0; trivial. -Qed. - -Lemma Nxor_semantics : - forall a a':N, eqf (Nbit (Nxor a a')) (xorf (Nbit a) (Nbit a')). -Proof. - unfold eqf. intros; generalize a, a'. induction n. - apply Nxor_sem_5. apply Nxor_sem_6; assumption. -Qed. - -(** Consequences: - - only equal numbers lead to a null xor - - xor is associative -*) + destruct n; trivial. +Qed. +Notation Nxor_neutral_right := Nxor_0_r (only parsing). -Lemma Nxor_eq : forall a a':N, Nxor a a' = N0 -> a = a'. +Lemma Nxor_comm : forall a a', Nxor a a' = Nxor a' a. Proof. - intros. apply Nbit_faithful, xorf_eq. apply eqf_trans with (f' := Nbit (Nxor a a')). - apply eqf_sym, Nxor_semantics. - rewrite H. unfold eqf. trivial. + intros. bitwise_semantics. apply xorb_comm. Qed. Lemma Nxor_assoc : - forall a a' a'':N, Nxor (Nxor a a') a'' = Nxor a (Nxor a' a''). -Proof. - intros. apply Nbit_faithful. - apply eqf_trans with (xorf (xorf (Nbit a) (Nbit a')) (Nbit a'')). - apply eqf_trans with (xorf (Nbit (Nxor a a')) (Nbit a'')). - apply Nxor_semantics. - apply eqf_xorf. apply Nxor_semantics. - apply eqf_refl. - apply eqf_trans with (xorf (Nbit a) (xorf (Nbit a') (Nbit a''))). - apply xorf_assoc. - apply eqf_trans with (xorf (Nbit a) (Nbit (Nxor a' a''))). - apply eqf_xorf. apply eqf_refl. - apply eqf_sym, Nxor_semantics. - apply eqf_sym, Nxor_semantics. + forall a a' a'', Nxor (Nxor a a') a'' = Nxor a (Nxor a' a''). +Proof. + intros. bitwise_semantics. apply xorb_assoc. +Qed. + +Lemma Nor_0_l : forall n, Nor 0 n = n. +Proof. + trivial. +Qed. + +Lemma Nor_0_r : forall n, Nor n 0 = n. +Proof. + destruct n; trivial. +Qed. + +Lemma Nor_comm : forall a a', Nor a a' = Nor a' a. +Proof. + intros. bitwise_semantics. apply orb_comm. +Qed. + +Lemma Nor_assoc : + forall a a' a'', Nor a (Nor a' a'') = Nor (Nor a a') a''. +Proof. + intros. bitwise_semantics. apply orb_assoc. +Qed. + +Lemma Nor_diag : forall a, Nor a a = a. +Proof. + intros. bitwise_semantics. apply orb_diag. +Qed. + +Lemma Nand_0_l : forall n, Nand 0 n = 0. +Proof. + trivial. +Qed. + +Lemma Nand_0_r : forall n, Nand n 0 = 0. +Proof. + destruct n; trivial. +Qed. + +Lemma Nand_comm : forall a a', Nand a a' = Nand a' a. +Proof. + intros. bitwise_semantics. apply andb_comm. +Qed. + +Lemma Nand_assoc : + forall a a' a'', Nand a (Nand a' a'') = Nand (Nand a a') a''. +Proof. + intros. bitwise_semantics. apply andb_assoc. +Qed. + +Lemma Nand_diag : forall a, Nand a a = a. +Proof. + intros. bitwise_semantics. apply andb_diag. +Qed. + +Lemma Ndiff_0_l : forall n, Ndiff 0 n = 0. +Proof. + trivial. Qed. +Lemma Ndiff_0_r : forall n, Ndiff n 0 = n. +Proof. + destruct n; trivial. +Qed. + +Lemma Ndiff_diag : forall a, Ndiff a a = 0. +Proof. + intros. bitwise_semantics. apply andb_negb_r. +Qed. + +Lemma Nor_and_distr_l : forall a b c, + Nor (Nand a b) c = Nand (Nor a c) (Nor b c). +Proof. + intros. bitwise_semantics. apply orb_andb_distrib_l. +Qed. + +Lemma Nor_and_distr_r : forall a b c, + Nor a (Nand b c) = Nand (Nor a b) (Nor a c). +Proof. + intros. bitwise_semantics. apply orb_andb_distrib_r. +Qed. + +Lemma Nand_or_distr_l : forall a b c, + Nand (Nor a b) c = Nor (Nand a c) (Nand b c). +Proof. + intros. bitwise_semantics. apply andb_orb_distrib_l. +Qed. + +Lemma Nand_or_distr_r : forall a b c, + Nand a (Nor b c) = Nor (Nand a b) (Nand a c). +Proof. + intros. bitwise_semantics. apply andb_orb_distrib_r. +Qed. + +Lemma Ndiff_diff_l : forall a b c, + Ndiff (Ndiff a b) c = Ndiff a (Nor b c). +Proof. + intros. bitwise_semantics. now rewrite negb_orb, andb_assoc. +Qed. + +Lemma Nor_diff_and : forall a b, + Nor (Ndiff a b) (Nand a b) = a. +Proof. + intros. bitwise_semantics. + now rewrite <- andb_orb_distrib_r, orb_comm, orb_negb_r, andb_true_r. +Qed. + +Lemma Nand_diff : forall a b, + Nand (Ndiff a b) b = 0. +Proof. + intros. bitwise_semantics. + now rewrite <-andb_assoc, (andb_comm (negb _)), andb_negb_r, andb_false_r. +Qed. + +Local Close Scope N_scope. + (** Checking whether a number is odd, i.e. if its lower bit is set. *) Definition Nbit0 (n:N) := match n with | N0 => false - | Npos (xO _) => false + | Npos (_~0) => false | _ => true end. @@ -358,7 +592,7 @@ Qed. Lemma Nxor_bit0 : forall a a':N, Nbit0 (Nxor a a') = xorb (Nbit0 a) (Nbit0 a'). Proof. - intros. rewrite <- Nbit0_correct, (Nxor_semantics a a' 0). + intros. rewrite <- Nbit0_correct, (Nxor_semantics a a' O). unfold xorf. rewrite Nbit0_correct, Nbit0_correct. reflexivity. Qed. @@ -554,7 +788,7 @@ Qed. (** Number of digits in a number *) Definition Nsize (n:N) : nat := match n with - | N0 => 0%nat + | N0 => O | Npos p => Psize p end. @@ -719,18 +953,40 @@ induction n; simpl in *; intros; destruct p; auto with arith. inversion H; inversion H1. Qed. -(** Xor is the same in the two worlds. *) +(** Binary bitwise operations are the same in the two worlds. *) Lemma Nxor_BVxor : forall n (bv bv' : Bvector n), Bv2N _ (BVxor _ bv bv') = Nxor (Bv2N _ bv) (Bv2N _ bv'). Proof. -induction n. -intros. +induction n; intros bv bv'. +rewrite (V0_eq _ bv), (V0_eq _ bv'); simpl; auto. +rewrite (VSn_eq _ _ bv), (VSn_eq _ _ bv'); simpl; auto. +rewrite IHn. +destruct (Vhead bool n bv), (Vhead bool n bv'), + (Bv2N n (Vtail bool n bv)), (Bv2N n (Vtail bool n bv')); + simpl; auto. +Qed. + +Lemma Nor_BVor : forall n (bv bv' : Bvector n), + Bv2N _ (BVor _ bv bv') = Nor (Bv2N _ bv) (Bv2N _ bv'). +Proof. +induction n; intros bv bv'. rewrite (V0_eq _ bv), (V0_eq _ bv'); simpl; auto. -intros. rewrite (VSn_eq _ _ bv), (VSn_eq _ _ bv'); simpl; auto. rewrite IHn. -destruct (Vhead bool n bv); destruct (Vhead bool n bv'); - destruct (Bv2N n (Vtail bool n bv)); destruct (Bv2N n (Vtail bool n bv')); simpl; auto. +destruct (Vhead bool n bv), (Vhead bool n bv'), + (Bv2N n (Vtail bool n bv)), (Bv2N n (Vtail bool n bv')); + simpl; auto. Qed. +Lemma Nand_BVand : forall n (bv bv' : Bvector n), + Bv2N _ (BVand _ bv bv') = Nand (Bv2N _ bv) (Bv2N _ bv'). +Proof. +induction n; intros bv bv'. +rewrite (V0_eq _ bv), (V0_eq _ bv'); simpl; auto. +rewrite (VSn_eq _ _ bv), (VSn_eq _ _ bv'); simpl; auto. +rewrite IHn. +destruct (Vhead bool n bv), (Vhead bool n bv'), + (Bv2N n (Vtail bool n bv)), (Bv2N n (Vtail bool n bv')); + simpl; auto. +Qed. diff --git a/theories/NArith/Nnat.v b/theories/NArith/Nnat.v index 93fdfff7a..05ca4a550 100644 --- a/theories/NArith/Nnat.v +++ b/theories/NArith/Nnat.v @@ -6,149 +6,86 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -Require Import Arith_base. -Require Import Compare_dec. -Require Import Sumbool. -Require Import Div2. -Require Import Min. -Require Import Max. -Require Import BinPos. -Require Import BinNat. -Require Import BinInt. -Require Import Pnat. -Require Import Znat. - -(** Translation from [N] to [nat] and back. *) - -Definition nat_of_N (a:N) := - match a with - | N0 => 0%nat - | Npos p => nat_of_P p - end. - -Definition N_of_nat (n:nat) := - match n with - | O => N0 - | S n' => Npos (P_of_succ_nat n') - end. +Require Import Arith_base Compare_dec Sumbool Div2 Min Max. +Require Import BinPos BinNat Pnat. Lemma N_of_nat_of_N : forall a:N, N_of_nat (nat_of_N a) = a. Proof. destruct a as [| p]. reflexivity. - simpl in |- *. elim (ZL4 p). intros n H. rewrite H. simpl in |- *. - rewrite <- nat_of_P_o_P_of_succ_nat_eq_succ in H. + simpl. elim (nat_of_P_is_S p). intros n H. rewrite H. simpl. + rewrite <- nat_of_P_of_succ_nat in H. rewrite nat_of_P_inj with (1 := H). reflexivity. Qed. Lemma nat_of_N_of_nat : forall n:nat, nat_of_N (N_of_nat n) = n. Proof. induction n. trivial. - intros. simpl in |- *. apply nat_of_P_o_P_of_succ_nat_eq_succ. + intros. simpl. apply nat_of_P_of_succ_nat. Qed. -(** Interaction of this translation and usual operations. *) - -Lemma nat_of_Ndouble : forall a, nat_of_N (Ndouble a) = 2*(nat_of_N a). +Lemma nat_of_N_inj : forall n n', nat_of_N n = nat_of_N n' -> n = n'. Proof. - destruct a; simpl nat_of_N; auto. - apply nat_of_P_xO. + intros n n' H. + rewrite <- (N_of_nat_of_N n), <- (N_of_nat_of_N n'). now f_equal. Qed. -Lemma N_of_double : forall n, N_of_nat (2*n) = Ndouble (N_of_nat n). +Lemma N_of_nat_inj : forall n n', N_of_nat n = N_of_nat n' -> n = n'. Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - rewrite <- nat_of_Ndouble. - apply N_of_nat_of_N. + intros n n' H. + rewrite <- (nat_of_N_of_nat n), <- (nat_of_N_of_nat n'). now f_equal. Qed. -Lemma nat_of_Ndouble_plus_one : - forall a, nat_of_N (Ndouble_plus_one a) = S (2*(nat_of_N a)). +Hint Rewrite nat_of_N_of_nat N_of_nat_of_N : Nnat. + +(** Interaction of this translation and usual operations. *) + +Lemma nat_of_Ndouble : forall a, nat_of_N (Ndouble a) = 2*(nat_of_N a). Proof. - destruct a; simpl nat_of_N; auto. - apply nat_of_P_xI. + destruct a; simpl nat_of_N; trivial. apply nat_of_P_xO. Qed. -Lemma N_of_double_plus_one : - forall n, N_of_nat (S (2*n)) = Ndouble_plus_one (N_of_nat n). +Lemma nat_of_Ndouble_plus_one : + forall a, nat_of_N (Ndouble_plus_one a) = S (2*(nat_of_N a)). Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - rewrite <- nat_of_Ndouble_plus_one. - apply N_of_nat_of_N. + destruct a; simpl nat_of_N; trivial. apply nat_of_P_xI. Qed. Lemma nat_of_Nsucc : forall a, nat_of_N (Nsucc a) = S (nat_of_N a). Proof. destruct a; simpl. apply nat_of_P_xH. - apply nat_of_P_succ_morphism. -Qed. - -Lemma N_of_S : forall n, N_of_nat (S n) = Nsucc (N_of_nat n). -Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - rewrite <- nat_of_Nsucc. - apply N_of_nat_of_N. + apply Psucc_S. Qed. Lemma nat_of_Nplus : forall a a', nat_of_N (Nplus a a') = (nat_of_N a)+(nat_of_N a'). Proof. destruct a; destruct a'; simpl; auto. - apply nat_of_P_plus_morphism. + apply Pplus_plus. Qed. -Lemma N_of_plus : - forall n n', N_of_nat (n+n') = Nplus (N_of_nat n) (N_of_nat n'). +Lemma nat_of_Nmult : + forall a a', nat_of_N (Nmult a a') = (nat_of_N a)*(nat_of_N a'). Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - pattern n' at 1; rewrite <- (nat_of_N_of_nat n'). - rewrite <- nat_of_Nplus. - apply N_of_nat_of_N. + destruct a; destruct a'; simpl; auto. + apply Pmult_mult. Qed. Lemma nat_of_Nminus : forall a a', nat_of_N (Nminus a a') = ((nat_of_N a)-(nat_of_N a'))%nat. Proof. - destruct a; destruct a'; simpl; auto with arith. - case_eq (Pcompare p p0 Eq); simpl; intros. - rewrite (Pcompare_Eq_eq _ _ H); auto with arith. - rewrite Pminus_mask_diag. simpl. apply minus_n_n. - rewrite Pminus_mask_Lt. pose proof (nat_of_P_lt_Lt_compare_morphism _ _ H). simpl. - symmetry; apply not_le_minus_0. auto with arith. assumption. - pose proof (Pminus_mask_Gt p p0 H) as H1. destruct H1 as [q [H1 _]]. rewrite H1; simpl. - replace q with (Pminus p p0) by (unfold Pminus; now rewrite H1). - apply nat_of_P_minus_morphism; auto. -Qed. - -Lemma N_of_minus : - forall n n', N_of_nat (n-n') = Nminus (N_of_nat n) (N_of_nat n'). -Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - pattern n' at 1; rewrite <- (nat_of_N_of_nat n'). - rewrite <- nat_of_Nminus. - apply N_of_nat_of_N. -Qed. - -Lemma nat_of_Nmult : - forall a a', nat_of_N (Nmult a a') = (nat_of_N a)*(nat_of_N a'). -Proof. - destruct a; destruct a'; simpl; auto. - apply nat_of_P_mult_morphism. + intros [|a] [|a']; simpl; auto with arith. + destruct (Pcompare_spec a a'). + subst. now rewrite Pminus_mask_diag, <- minus_n_n. + rewrite Pminus_mask_Lt by trivial. apply Plt_lt in H. + simpl; symmetry; apply not_le_minus_0; auto with arith. + destruct (Pminus_mask_Gt a a' (ZC2 _ _ H)) as (q & -> & Hq & _). + simpl. apply plus_minus. now rewrite <- Hq, Pplus_plus. Qed. -Lemma N_of_mult : - forall n n', N_of_nat (n*n') = Nmult (N_of_nat n) (N_of_nat n'). +Lemma nat_of_Npred : forall a, nat_of_N (Npred a) = pred (nat_of_N a). Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - pattern n' at 1; rewrite <- (nat_of_N_of_nat n'). - rewrite <- nat_of_Nmult. - apply N_of_nat_of_N. + intros. rewrite pred_of_minus, Npred_minus. apply nat_of_Nminus. Qed. Lemma nat_of_Ndiv2 : @@ -162,205 +99,92 @@ Proof. rewrite div2_double; auto. Qed. -Lemma N_of_div2 : - forall n, N_of_nat (div2 n) = Ndiv2 (N_of_nat n). -Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - rewrite <- nat_of_Ndiv2. - apply N_of_nat_of_N. -Qed. - Lemma nat_of_Ncompare : forall a a', Ncompare a a' = nat_compare (nat_of_N a) (nat_of_N a'). Proof. - destruct a; destruct a'; simpl. - reflexivity. - assert (NZ : 0 < nat_of_P p) by auto using lt_O_nat_of_P. - destruct nat_of_P; [inversion NZ|auto]. - assert (NZ : 0 < nat_of_P p) by auto using lt_O_nat_of_P. - destruct nat_of_P; [inversion NZ|auto]. - apply nat_of_P_compare_morphism. -Qed. - -Lemma N_of_nat_compare : - forall n n', nat_compare n n' = Ncompare (N_of_nat n) (N_of_nat n'). -Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - pattern n' at 1; rewrite <- (nat_of_N_of_nat n'). - symmetry; apply nat_of_Ncompare. -Qed. - -Lemma nat_of_Nmin : - forall a a', nat_of_N (Nmin a a') = min (nat_of_N a) (nat_of_N a'). -Proof. - intros; unfold Nmin; rewrite nat_of_Ncompare. - rewrite nat_compare_equiv; unfold nat_compare_alt. - destruct (lt_eq_lt_dec (nat_of_N a) (nat_of_N a')) as [[|]|]; - simpl; intros; symmetry; auto with arith. - apply min_l; rewrite e; auto with arith. -Qed. - -Lemma N_of_min : - forall n n', N_of_nat (min n n') = Nmin (N_of_nat n) (N_of_nat n'). -Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - pattern n' at 1; rewrite <- (nat_of_N_of_nat n'). - rewrite <- nat_of_Nmin. - apply N_of_nat_of_N. + destruct a; destruct a'; simpl; trivial. + now destruct (nat_of_P_is_S p) as (n,->). + now destruct (nat_of_P_is_S p) as (n,->). + apply Pcompare_nat_compare. Qed. Lemma nat_of_Nmax : forall a a', nat_of_N (Nmax a a') = max (nat_of_N a) (nat_of_N a'). Proof. - intros; unfold Nmax; rewrite nat_of_Ncompare. - rewrite nat_compare_equiv; unfold nat_compare_alt. - destruct (lt_eq_lt_dec (nat_of_N a) (nat_of_N a')) as [[|]|]; - simpl; intros; symmetry; auto with arith. - apply max_r; rewrite e; auto with arith. -Qed. - -Lemma N_of_max : - forall n n', N_of_nat (max n n') = Nmax (N_of_nat n) (N_of_nat n'). -Proof. - intros. - pattern n at 1; rewrite <- (nat_of_N_of_nat n). - pattern n' at 1; rewrite <- (nat_of_N_of_nat n'). - rewrite <- nat_of_Nmax. - apply N_of_nat_of_N. + intros; unfold Nmax; rewrite nat_of_Ncompare. symmetry. + case nat_compare_spec; intros H; try rewrite H; auto with arith. Qed. -(** Properties concerning [Z_of_N] *) - -Lemma Z_of_nat_of_N : forall n:N, Z_of_nat (nat_of_N n) = Z_of_N n. -Proof. - destruct n; simpl; auto; symmetry; apply Zpos_eq_Z_of_nat_o_nat_of_P. -Qed. - -Lemma Z_of_N_eq : forall n m, n = m -> Z_of_N n = Z_of_N m. -Proof. - intros; f_equal; assumption. -Qed. - -Lemma Z_of_N_eq_rev : forall n m, Z_of_N n = Z_of_N m -> n = m. -Proof. - intros [|n] [|m]; simpl; intros; try discriminate; congruence. -Qed. - -Lemma Z_of_N_eq_iff : forall n m, n = m <-> Z_of_N n = Z_of_N m. -Proof. - split; [apply Z_of_N_eq | apply Z_of_N_eq_rev]. -Qed. - -Lemma Z_of_N_le : forall n m, (n<=m)%N -> (Z_of_N n <= Z_of_N m)%Z. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. - -Lemma Z_of_N_le_rev : forall n m, (Z_of_N n <= Z_of_N m)%Z -> (n<=m)%N. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. - -Lemma Z_of_N_le_iff : forall n m, (n<=m)%N <-> (Z_of_N n <= Z_of_N m)%Z. -Proof. - split; [apply Z_of_N_le | apply Z_of_N_le_rev]. -Qed. - -Lemma Z_of_N_lt : forall n m, (n<m)%N -> (Z_of_N n < Z_of_N m)%Z. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. - -Lemma Z_of_N_lt_rev : forall n m, (Z_of_N n < Z_of_N m)%Z -> (n<m)%N. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. - -Lemma Z_of_N_lt_iff : forall n m, (n<m)%N <-> (Z_of_N n < Z_of_N m)%Z. -Proof. - split; [apply Z_of_N_lt | apply Z_of_N_lt_rev]. -Qed. - -Lemma Z_of_N_ge : forall n m, (n>=m)%N -> (Z_of_N n >= Z_of_N m)%Z. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. - -Lemma Z_of_N_ge_rev : forall n m, (Z_of_N n >= Z_of_N m)%Z -> (n>=m)%N. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. - -Lemma Z_of_N_ge_iff : forall n m, (n>=m)%N <-> (Z_of_N n >= Z_of_N m)%Z. -Proof. - split; [apply Z_of_N_ge | apply Z_of_N_ge_rev]. -Qed. - -Lemma Z_of_N_gt : forall n m, (n>m)%N -> (Z_of_N n > Z_of_N m)%Z. +Lemma nat_of_Nmin : + forall a a', nat_of_N (Nmin a a') = min (nat_of_N a) (nat_of_N a'). Proof. - intros [|n] [|m]; simpl; auto. + intros; unfold Nmin; rewrite nat_of_Ncompare. symmetry. + case nat_compare_spec; intros H; try rewrite H; auto with arith. Qed. -Lemma Z_of_N_gt_rev : forall n m, (Z_of_N n > Z_of_N m)%Z -> (n>m)%N. -Proof. - intros [|n] [|m]; simpl; auto. -Qed. +Hint Rewrite nat_of_Ndouble nat_of_Ndouble_plus_one + nat_of_Nsucc nat_of_Nplus nat_of_Nmult nat_of_Nminus + nat_of_Npred nat_of_Ndiv2 nat_of_Nmax nat_of_Nmin : Nnat. -Lemma Z_of_N_gt_iff : forall n m, (n>m)%N <-> (Z_of_N n > Z_of_N m)%Z. +Lemma N_of_double : forall n, N_of_nat (2*n) = Ndouble (N_of_nat n). Proof. - split; [apply Z_of_N_gt | apply Z_of_N_gt_rev]. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_of_nat : forall n:nat, Z_of_N (N_of_nat n) = Z_of_nat n. +Lemma N_of_double_plus_one : + forall n, N_of_nat (S (2*n)) = Ndouble_plus_one (N_of_nat n). Proof. - destruct n; simpl; auto. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_pos : forall p:positive, Z_of_N (Npos p) = Zpos p. +Lemma N_of_S : forall n, N_of_nat (S n) = Nsucc (N_of_nat n). Proof. - destruct p; simpl; auto. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_abs : forall z:Z, Z_of_N (Zabs_N z) = Zabs z. +Lemma N_of_pred : forall n, N_of_nat (pred n) = Npred (N_of_nat n). Proof. - destruct z; simpl; auto. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_le_0 : forall n, (0 <= Z_of_N n)%Z. +Lemma N_of_plus : + forall n n', N_of_nat (n+n') = Nplus (N_of_nat n) (N_of_nat n'). Proof. - destruct n; intro; discriminate. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_plus : forall n m:N, Z_of_N (n+m) = (Z_of_N n + Z_of_N m)%Z. +Lemma N_of_minus : + forall n n', N_of_nat (n-n') = Nminus (N_of_nat n) (N_of_nat n'). Proof. - destruct n; destruct m; auto. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_mult : forall n m:N, Z_of_N (n*m) = (Z_of_N n * Z_of_N m)%Z. +Lemma N_of_mult : + forall n n', N_of_nat (n*n') = Nmult (N_of_nat n) (N_of_nat n'). Proof. - destruct n; destruct m; auto. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_minus : forall n m:N, Z_of_N (n-m) = Zmax 0 (Z_of_N n - Z_of_N m). +Lemma N_of_div2 : + forall n, N_of_nat (div2 n) = Ndiv2 (N_of_nat n). Proof. - intros; do 3 rewrite <- Z_of_nat_of_N; rewrite nat_of_Nminus; apply inj_minus. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_succ : forall n:N, Z_of_N (Nsucc n) = Zsucc (Z_of_N n). +Lemma N_of_nat_compare : + forall n n', nat_compare n n' = Ncompare (N_of_nat n) (N_of_nat n'). Proof. - intros; do 2 rewrite <- Z_of_nat_of_N; rewrite nat_of_Nsucc; apply inj_S. + intros. rewrite nat_of_Ncompare. now autorewrite with Nnat. Qed. -Lemma Z_of_N_min : forall n m:N, Z_of_N (Nmin n m) = Zmin (Z_of_N n) (Z_of_N m). +Lemma N_of_min : + forall n n', N_of_nat (min n n') = Nmin (N_of_nat n) (N_of_nat n'). Proof. - intros; do 3 rewrite <- Z_of_nat_of_N; rewrite nat_of_Nmin; apply inj_min. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. -Lemma Z_of_N_max : forall n m:N, Z_of_N (Nmax n m) = Zmax (Z_of_N n) (Z_of_N m). +Lemma N_of_max : + forall n n', N_of_nat (max n n') = Nmax (N_of_nat n) (N_of_nat n'). Proof. - intros; do 3 rewrite <- Z_of_nat_of_N; rewrite nat_of_Nmax; apply inj_max. + intros. apply nat_of_N_inj. now autorewrite with Nnat. Qed. - diff --git a/theories/Numbers/Rational/BigQ/QMake.v b/theories/Numbers/Rational/BigQ/QMake.v index 6bb9c2ac4..e944750d8 100644 --- a/theories/Numbers/Rational/BigQ/QMake.v +++ b/theories/Numbers/Rational/BigQ/QMake.v @@ -1274,7 +1274,7 @@ Module Make (N:NType)(Z:ZType)(Import NZ:NType_ZType N Z) <: QType. apply Qred_complete; apply spec_power_pos; auto. induction p using Pind. simpl; ring. - rewrite nat_of_P_succ_morphism; simpl Qcpower. + rewrite Psucc_S; simpl Qcpower. rewrite <- IHp; clear IHp. unfold Qcmult, Q2Qc. apply Qc_decomp; intros _ _; unfold this. diff --git a/theories/PArith/BinPos.v b/theories/PArith/BinPos.v index c42f9cceb..cb6030e26 100644 --- a/theories/PArith/BinPos.v +++ b/theories/PArith/BinPos.v @@ -11,8 +11,7 @@ Unset Boxed Definitions. Declare ML Module "z_syntax_plugin". -(**********************************************************************) -(** Binary positive numbers *) +(** * Binary positive numbers *) (** Original development by Pierre Crégut, CNET, Lannion, France *) @@ -42,13 +41,16 @@ Notation "p ~ 1" := (xI p) Notation "p ~ 0" := (xO p) (at level 7, left associativity, format "p '~' '0'") : positive_scope. -Open Local Scope positive_scope. +Local Open Scope positive_scope. (* In the current file, [xH] cannot yet be written as [1], since the interpretation of positive numerical constants is not available yet. We fix this here with an ad-hoc temporary notation. *) -Notation Local "1" := xH (at level 7). +Local Notation "1" := xH (at level 7). + + +(** * Operations over positive numbers *) (** Successor *) @@ -224,6 +226,24 @@ Fixpoint Pmult (x y:positive) : positive := Infix "*" := Pmult : positive_scope. +(** Iteration over a positive number *) + +Fixpoint iter_pos (n:positive) (A:Type) (f:A -> A) (x:A) : A := + match n with + | xH => f x + | xO n' => iter_pos n' A f (iter_pos n' A f x) + | xI n' => f (iter_pos n' A f (iter_pos n' A f x)) + end. + +(** Power *) + +Definition Ppow (x y:positive) := iter_pos y _ (Pmult x) 1. + +(** Another possible definition is : Piter_op Pmult y x + but for some reason, this is quite slower on powers of two. *) + +Infix "^" := Ppow : positive_scope. + (** Division by 2 rounded below but for 1 *) Definition Pdiv2 (z:positive) := @@ -235,6 +255,24 @@ Definition Pdiv2 (z:positive) := Infix "/" := Pdiv2 : positive_scope. +(** Number of digits in a positive number *) + +Fixpoint Psize (p:positive) : nat := + match p with + | 1 => S O + | p~1 => S (Psize p) + | p~0 => S (Psize p) + end. + +(** Same, with positive output *) + +Fixpoint Psize_pos (p:positive) : positive := + match p with + | 1 => 1 + | p~1 => Psucc (Psize_pos p) + | p~0 => Psucc (Psize_pos p) + end. + (** Comparison on binary positive numbers *) Fixpoint Pcompare (x y:positive) (r:comparison) {struct y} : comparison := @@ -278,7 +316,6 @@ Definition Pmax (p p' : positive) := match Pcompare p p' Eq with | Gt => p end. -(********************************************************************) (** Boolean equality *) Fixpoint Peqb (x y : positive) {struct y} : bool := @@ -289,7 +326,9 @@ Fixpoint Peqb (x y : positive) {struct y} : bool := | _, _ => false end. -(**********************************************************************) + +(** * Properties of operations over positive numbers *) + (** Decidability of equality on binary positive numbers *) Lemma positive_eq_dec : forall x y: positive, {x = y} + {x <> y}. @@ -759,6 +798,61 @@ Proof. rewrite Pplus_assoc, Pplus_diag. simpl. now rewrite Pplus_comm. Qed. +(** Properties of [iter_pos] *) + +Lemma iter_pos_swap_gen : forall A B (f:A->B)(g:A->A)(h:B->B), + (forall a, f (g a) = h (f a)) -> forall p a, + f (iter_pos p A g a) = iter_pos p B h (f a). +Proof. + induction p; simpl; intros; now rewrite ?H, ?IHp. +Qed. + +Theorem iter_pos_swap : + forall p (A:Type) (f:A -> A) (x:A), + iter_pos p A f (f x) = f (iter_pos p A f x). +Proof. + intros. symmetry. now apply iter_pos_swap_gen. +Qed. + +Theorem iter_pos_succ : + forall p (A:Type) (f:A -> A) (x:A), + iter_pos (Psucc p) A f x = f (iter_pos p A f x). +Proof. + induction p as [p IHp|p IHp|]; intros; simpl; trivial. + now rewrite !IHp, iter_pos_swap. +Qed. + +Theorem iter_pos_plus : + forall p q (A:Type) (f:A -> A) (x:A), + iter_pos (p+q) A f x = iter_pos p A f (iter_pos q A f x). +Proof. + induction p using Pind; intros. + now rewrite <- Pplus_one_succ_l, iter_pos_succ. + now rewrite Pplus_succ_permute_l, !iter_pos_succ, IHp. +Qed. + +Theorem iter_pos_invariant : + forall (p:positive) (A:Type) (f:A -> A) (Inv:A -> Prop), + (forall x:A, Inv x -> Inv (f x)) -> + forall x:A, Inv x -> Inv (iter_pos p A f x). +Proof. + induction p as [p IHp|p IHp|]; simpl; trivial. + intros A f Inv H x H0. apply H, IHp, IHp; trivial. + intros A f Inv H x H0. apply IHp, IHp; trivial. +Qed. + +(** Properties of power *) + +Lemma Ppow_1_r : forall p, p^1 = p. +Proof. + intros p. unfold Ppow. simpl. now rewrite Pmult_comm. +Qed. + +Lemma Ppow_succ_r : forall p q, p^(Psucc q) = p * p^q. +Proof. + intros. unfold Ppow. now rewrite iter_pos_succ. +Qed. + (*********************************************************************) (** Properties of boolean equality *) @@ -924,7 +1018,6 @@ Proof. apply ZC1; auto. Qed. - (** Comparison and the successor *) Lemma Pcompare_p_Sp : forall p : positive, (p ?= Psucc p) Eq = Lt. @@ -958,6 +1051,29 @@ Proof. destruct (Pcompare_Lt_eq_Lt p q); auto. Qed. +Lemma Pcompare_succ_succ : + forall n m, (Psucc n ?= Psucc m) Eq = (n ?= m) Eq. +Proof. + assert (AUX : forall n m, (Psucc n ?= Psucc m) Eq = (n ?= m) Eq -> + (Psucc n ?= m) Lt = (n ?= m) Gt). + intros n m IH. + case_eq ((n ?= m) Gt); intros H. + elim (proj1 (Pcompare_not_Eq n m) H). + apply Pcompare_Lt_eq_Lt, Pcompare_p_Sq. rewrite IH. + now apply Pcompare_Gt_Lt. + apply Pcompare_eq_Gt, ZC2, Pcompare_p_Sq. apply Pcompare_Gt_Gt in H. + destruct H; [left; now apply ZC1|now right]. + (* main *) + induction n; destruct m; simpl; trivial. + now apply AUX. + generalize (Psucc_not_one n); destruct (Psucc n); intuition. + change Gt with (CompOpp Lt); rewrite <- Pcompare_antisym. + rewrite AUX, Pcompare_antisym; trivial. now rewrite ZC4, IHn, <- ZC4. + now destruct n. + apply Pcompare_p_Sq; destruct m; auto. + now destruct m. +Qed. + (** 1 is the least positive number *) Lemma Pcompare_1 : forall p, ~ (p ?= 1) Eq = Lt. @@ -965,7 +1081,7 @@ Proof. destruct p; discriminate. Qed. -(** Properties of the strict order on positive numbers *) +(** Properties of the order on positive numbers *) Lemma Plt_1 : forall p, ~ p < 1. Proof. @@ -984,15 +1100,12 @@ Qed. Lemma Psucc_lt_compat : forall n m, n < m <-> Psucc n < Psucc m. Proof. - unfold Plt. induction n; destruct m; simpl; auto; split; try easy; intros. - now apply Pcompare_Lt_eq_Lt, Pcompare_p_Sq, IHn, Pcompare_Gt_Lt. - now apply Pcompare_eq_Lt, IHn, Pcompare_p_Sq, Pcompare_Lt_eq_Lt. - destruct (Psucc n); discriminate. - now apply Pcompare_eq_Lt, Pcompare_p_Sq, Pcompare_Lt_eq_Lt. - now apply Pcompare_Lt_eq_Lt, Pcompare_p_Sq, Pcompare_Gt_Lt. - destruct n; discriminate. - apply Plt_1_succ. - destruct m; auto. + unfold Plt. intros. rewrite Pcompare_succ_succ. apply iff_refl. +Qed. + +Lemma Psucc_le_compat : forall n m, n <= m <-> Psucc n <= Psucc m. +Proof. + unfold Ple. intros. rewrite Pcompare_succ_succ. apply iff_refl. Qed. Lemma Plt_irrefl : forall p : positive, ~ p < p. @@ -1025,52 +1138,149 @@ Proof. destruct ((p ?= q) Eq); intuition; discriminate. Qed. -Lemma Ple_refl : forall p, Ple p p. +Lemma Ple_refl : forall p, p <= p. Proof. intros. unfold Ple. rewrite Pcompare_refl_id. discriminate. Qed. -(** Strict order and operations *) +Lemma Ple_lt_trans : forall n m p, n <= m -> m < p -> n < p. +Proof. + intros n m p H H'. + apply Ple_lteq in H. destruct H. + now apply Plt_trans with m. now subst. +Qed. + +Lemma Plt_le_trans : forall n m p, n < m -> m <= p -> n < p. +Proof. + intros n m p H H'. + apply Ple_lteq in H'. destruct H'. + now apply Plt_trans with m. now subst. +Qed. + +Lemma Ple_trans : forall n m p, n <= m -> m <= p -> n <= p. +Proof. + intros n m p H H'. + apply Ple_lteq in H. destruct H. + apply Ple_lteq; left. now apply Plt_le_trans with m. + now subst. +Qed. + +Lemma Plt_succ_r : forall p q, p < Psucc q <-> p <= q. +Proof. + intros. eapply iff_trans; [eapply Pcompare_p_Sq|eapply iff_sym, Ple_lteq]. +Qed. + +Lemma Ple_succ_l : forall n m, Psucc n <= m <-> n < m. +Proof. + intros. apply iff_sym. + eapply iff_trans; [eapply Psucc_lt_compat|eapply Plt_succ_r]. +Qed. + +(** Comparison and addition *) + +Lemma Pplus_compare_mono_l : forall p q r, (p+q ?= p+r) Eq = (q ?= r) Eq. +Proof. + induction p using Pind; intros q r. + rewrite <- 2 Pplus_one_succ_l. apply Pcompare_succ_succ. + now rewrite 2 Pplus_succ_permute_l, Pcompare_succ_succ. +Qed. + +Lemma Pplus_compare_mono_r : forall p q r, (q+p ?= r+p) Eq = (q ?= r) Eq. +Proof. + intros. rewrite 2 (Pplus_comm _ p). apply Pplus_compare_mono_l. +Qed. + +(** Order and addition *) Lemma Pplus_lt_mono_l : forall p q r, q<r <-> p+q < p+r. Proof. - induction p using Prect. - intros q r. rewrite <- 2 Pplus_one_succ_l. apply Psucc_lt_compat. - intros q r. rewrite 2 Pplus_succ_permute_l. - eapply iff_trans; [ eapply IHp | eapply Psucc_lt_compat ]. + intros. unfold Plt. rewrite Pplus_compare_mono_l. apply iff_refl. +Qed. + +Lemma Pplus_lt_mono_r : forall p q r, q<r <-> q+p < r+p. +Proof. + intros. unfold Plt. rewrite Pplus_compare_mono_r. apply iff_refl. Qed. Lemma Pplus_lt_mono : forall p q r s, p<q -> r<s -> p+r<q+s. Proof. intros. apply Plt_trans with (p+s). now apply Pplus_lt_mono_l. - rewrite (Pplus_comm p), (Pplus_comm q). now apply Pplus_lt_mono_l. + now apply Pplus_lt_mono_r. +Qed. + +Lemma Pplus_le_mono_l : forall p q r, q<=r <-> p+q<=p+r. +Proof. + intros. unfold Ple. rewrite Pplus_compare_mono_l. apply iff_refl. +Qed. + +Lemma Pplus_le_mono_r : forall p q r, q<=r <-> q+p<=r+p. +Proof. + intros. unfold Ple. rewrite Pplus_compare_mono_r. apply iff_refl. +Qed. + +Lemma Pplus_le_mono : forall p q r s, p<=q -> r<=s -> p+r <= q+s. +Proof. + intros. apply Ple_trans with (p+s). + now apply Pplus_le_mono_l. + now apply Pplus_le_mono_r. +Qed. + +(** Comparison and multiplication *) + +Lemma Pmult_compare_mono_l : forall p q r, (p*q ?= p*r) Eq = (q ?= r) Eq. +Proof. + induction p; simpl; trivial. intros q r. specialize (IHp q r). + case_eq ((q ?= r) Eq); intros H; rewrite H in IHp. + apply Pcompare_Eq_eq in H. subst. apply Pcompare_refl. + now apply Pplus_lt_mono. + apply ZC2, Pplus_lt_mono; now apply ZC1. +Qed. + +Lemma Pmult_compare_mono_r : forall p q r, (q*p ?= r*p) Eq = (q ?= r) Eq. +Proof. + intros. rewrite 2 (Pmult_comm _ p). apply Pmult_compare_mono_l. Qed. +(** Order and multiplication *) + Lemma Pmult_lt_mono_l : forall p q r, q<r <-> p*q < p*r. Proof. - assert (IMPL : forall p q r, q<r -> p*q < p*r). - induction p using Prect; auto. - intros q r H. rewrite 2 Pmult_Sn_m. - apply Pplus_lt_mono; auto. - split; auto. - intros H. - destruct (Pcompare_spec q r) as [EQ|LT|GT]; trivial. - rewrite EQ in H. elim (Plt_irrefl _ H). - apply (IMPL p) in GT. - elim (Plt_irrefl (p*q)). eapply Plt_trans; eauto. + intros. unfold Plt. rewrite Pmult_compare_mono_l. apply iff_refl. +Qed. + +Lemma Pmult_lt_mono_r : forall p q r, q<r <-> q*p < r*p. +Proof. + intros. unfold Plt. rewrite Pmult_compare_mono_r. apply iff_refl. Qed. Lemma Pmult_lt_mono : forall p q r s, p<q -> r<s -> p*r < q*s. Proof. intros. apply Plt_trans with (p*s). now apply Pmult_lt_mono_l. - rewrite (Pmult_comm p), (Pmult_comm q). now apply Pmult_lt_mono_l. + now apply Pmult_lt_mono_r. +Qed. + +Lemma Pmult_le_mono_l : forall p q r, q<=r <-> p*q<=p*r. +Proof. + intros. unfold Ple. rewrite Pmult_compare_mono_l. apply iff_refl. +Qed. + +Lemma Pmult_le_mono_r : forall p q r, q<=r <-> q*p<=r*p. +Proof. + intros. unfold Ple. rewrite Pmult_compare_mono_r. apply iff_refl. +Qed. + +Lemma Pmult_le_mono : forall p q r s, p<=q -> r<=s -> p*r <= q*s. +Proof. + intros. apply Ple_trans with (p*s). + now apply Pmult_le_mono_l. + now apply Pmult_le_mono_r. Qed. Lemma Plt_plus_r : forall p q, p < p+q. Proof. - induction q using Prect. + induction q using Pind. rewrite <- Pplus_one_succ_r. apply Pcompare_p_Sp. apply Plt_trans with (p+q); auto. apply Pplus_lt_mono_l, Pcompare_p_Sp. @@ -1217,18 +1427,23 @@ Proof. Qed. Theorem Pplus_minus : - forall p q:positive, (p ?= q) Eq = Gt -> q + (p - q) = p. + forall p q:positive, (p ?= q) Eq = Gt -> q+(p-q) = p. Proof. intros p q H; destruct (Pminus_mask_Gt p q H) as (r & U & V & _). unfold Pminus; rewrite U; simpl; auto. Qed. +Theorem Pplus_minus_lt : forall p q, q<p -> q+(p-q) = p. +Proof. + intros p q H. apply Pplus_minus. apply ZC2, H. +Qed. + Lemma Pplus_minus_eq : forall p q, p+q-q = p. Proof. intros. apply Pplus_reg_l with q. - rewrite Pplus_minus. + rewrite Pplus_minus_lt. apply Pplus_comm. - now rewrite ZC4, Pplus_comm, Plt_plus_r. + rewrite Pplus_comm. apply Plt_plus_r. Qed. Lemma Pmult_minus_distr_l : forall p q r, r<q -> p*(q-r) = p*q-p*r. @@ -1236,21 +1451,52 @@ Proof. intros p q r H. apply Pplus_reg_l with (p*r). rewrite <- Pmult_plus_distr_l. - rewrite Pplus_minus. - symmetry. apply Pplus_minus. - apply (Pmult_lt_mono_l p) in H. - now rewrite ZC4, H. - now rewrite ZC4, H. + rewrite Pplus_minus_lt; trivial. + symmetry. apply Pplus_minus_lt; trivial. + now apply Pmult_lt_mono_l. +Qed. + +Lemma Pminus_lt_mono_l : + forall p q r, q<p -> p<r -> r-p < r-q. +Proof. + intros p q r Hqp Hpr. + apply (Pplus_lt_mono_l p). + rewrite Pplus_minus_lt by trivial. + apply Ple_lt_trans with (q+(r-q)). + rewrite Pplus_minus_lt by (now apply Plt_trans with p). + apply Ple_refl. + now apply Pplus_lt_mono_r. +Qed. + +Lemma Pminus_compare_mono_l : + forall p q r, q<p -> r<p -> (p-q ?= p-r) Eq = (r ?= q) Eq. +Proof. + intros p q r Hqp Hrp. + case (Pcompare_spec r q); intros H. subst. apply Pcompare_refl. + apply Pminus_lt_mono_l; trivial. + apply ZC2, Pminus_lt_mono_l; trivial. +Qed. + +Lemma Pminus_compare_mono_r : + forall p q r, p<q -> p<r -> (q-p ?= r-p) Eq = (q ?= r) Eq. +Proof. + intros. + rewrite <- (Pplus_compare_mono_l p), 2 Pplus_minus_lt; trivial. +Qed. + +Lemma Pminus_lt_mono_r : + forall p q r, q<p -> r<q -> q-r < p-r. +Proof. + intros. unfold Plt. rewrite Pminus_compare_mono_r; trivial. + now apply Plt_trans with q. Qed. Lemma Pminus_decr : forall n m, m<n -> n-m < n. Proof. intros n m LT. apply Pplus_lt_mono_l with m. - rewrite Pplus_minus. - rewrite Pplus_comm. - apply Plt_plus_r. - now rewrite ZC4, LT. + rewrite Pplus_minus_lt; trivial. + rewrite Pplus_comm. apply Plt_plus_r. Qed. Lemma Pminus_xI_xI : forall n m, m<n -> n~1 - m~1 = (n-m)~0. @@ -1260,6 +1506,34 @@ Proof. now rewrite ZC4, H. Qed. +Lemma Pplus_minus_assoc : forall p q r, r<q -> p+(q-r) = p+q-r. +Proof. + intros p q r H. + apply Pplus_reg_l with r. + rewrite Pplus_assoc, (Pplus_comm r), <- Pplus_assoc. + rewrite !Pplus_minus_lt; trivial. + rewrite Pplus_comm. apply Plt_trans with q; trivial using Plt_plus_r. +Qed. + +Lemma Pminus_plus_distr : forall p q r, q+r < p -> p-(q+r) = p-q-r. +Proof. + intros p q r H. + assert (q < p) + by (apply Plt_trans with (q+r); trivial using Plt_plus_r). + apply Pplus_reg_l with (q+r). + rewrite Pplus_minus_lt, <- Pplus_assoc, !Pplus_minus_lt; trivial. + apply (Pplus_lt_mono_l q). rewrite Pplus_minus_lt; trivial. +Qed. + +Lemma Pminus_minus_distr : forall p q r, r<q -> q-r < p -> p-(q-r) = p+r-q. +Proof. + intros p q r H H'. + apply Pplus_reg_l with (r+(q-r)). + rewrite <- Pplus_assoc, !Pplus_minus_lt; trivial using Pplus_comm. + rewrite Pplus_comm, <- (Pplus_minus_lt q r); trivial. + now apply Pplus_lt_mono_l. +Qed. + (** When x<y, the substraction of x by y returns 1 *) Lemma Pminus_mask_Lt : forall p q:positive, p<q -> Pminus_mask p q = IsNeg. @@ -1284,14 +1558,7 @@ Proof. intros; unfold Pminus; rewrite Pminus_mask_diag; auto. Qed. -(** Number of digits in a number *) - -Fixpoint Psize (p:positive) : nat := - match p with - | 1 => S O - | p~1 => S (Psize p) - | p~0 => S (Psize p) - end. +(** Results concerning [Psize] and [Psize_pos] *) Lemma Psize_monotone : forall p q, p<q -> (Psize p <= Psize q)%nat. Proof. @@ -1301,3 +1568,18 @@ Proof. intros; generalize (Pcompare_Gt_Lt _ _ H); auto. intros; destruct (Pcompare_Lt_Lt _ _ H); auto; subst; auto. Qed. + +Local Notation "2" := (1~0) : positive_scope. + +Lemma Psize_pos_gt : forall p, p < 2^(Psize_pos p). +Proof. + induction p; simpl; try rewrite Ppow_succ_r; try easy. + apply Ple_succ_l in IHp. now apply Ple_succ_l. +Qed. + +Lemma Psize_pos_le : forall p, 2^(Psize_pos p) <= p~0. +Proof. + induction p; simpl; try rewrite Ppow_succ_r; try easy. + apply Pmult_le_mono_l. + apply Ple_lteq; left. rewrite xI_succ_xO. apply Plt_succ_r, IHp. +Qed. diff --git a/theories/PArith/Pminmax.v b/theories/PArith/Pminmax.v index 2f753a4c9..6fe6435a0 100644 --- a/theories/PArith/Pminmax.v +++ b/theories/PArith/Pminmax.v @@ -83,7 +83,7 @@ Lemma succ_max_distr : Proof. intros. symmetry. apply max_monotone. intros x x'. unfold Ple. - rewrite 2 nat_of_P_compare_morphism, 2 nat_of_P_succ_morphism. + rewrite 2 Pcompare_nat_compare, 2 Psucc_S. simpl; auto. Qed. @@ -91,7 +91,7 @@ Lemma succ_min_distr : forall n m, Psucc (Pmin n m) = Pmin (Psucc n) (Psucc m). Proof. intros. symmetry. apply min_monotone. intros x x'. unfold Ple. - rewrite 2 nat_of_P_compare_morphism, 2 nat_of_P_succ_morphism. + rewrite 2 Pcompare_nat_compare, 2 Psucc_S. simpl; auto. Qed. @@ -99,7 +99,7 @@ Lemma plus_max_distr_l : forall n m p, Pmax (p + n) (p + m) = p + Pmax n m. Proof. intros. apply max_monotone. intros x x'. unfold Ple. - rewrite 2 nat_of_P_compare_morphism, 2 nat_of_P_plus_morphism. + rewrite 2 Pcompare_nat_compare, 2 Pplus_plus. rewrite <- 2 Compare_dec.nat_compare_le. auto with arith. Qed. @@ -113,7 +113,7 @@ Lemma plus_min_distr_l : forall n m p, Pmin (p + n) (p + m) = p + Pmin n m. Proof. intros. apply min_monotone. intros x x'. unfold Ple. - rewrite 2 nat_of_P_compare_morphism, 2 nat_of_P_plus_morphism. + rewrite 2 Pcompare_nat_compare, 2 Pplus_plus. rewrite <- 2 Compare_dec.nat_compare_le. auto with arith. Qed. diff --git a/theories/PArith/Pnat.v b/theories/PArith/Pnat.v index b3f2493b2..590217d5d 100644 --- a/theories/PArith/Pnat.v +++ b/theories/PArith/Pnat.v @@ -7,332 +7,199 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -Require Import BinPos. +Require Import BinPos Le Lt Gt Plus Mult Minus Compare_dec Wf_nat. -(**********************************************************************) -(** Properties of the injection from binary positive numbers to Peano - natural numbers *) +(** Properties of the injection from binary positive numbers + to Peano natural numbers *) (** Original development by Pierre Crégut, CNET, Lannion, France *) -Require Import Le. -Require Import Lt. -Require Import Gt. -Require Import Plus. -Require Import Mult. -Require Import Minus. -Require Import Compare_dec. - Local Open Scope positive_scope. Local Open Scope nat_scope. -(** [nat_of_P] is a morphism for addition *) - -Lemma Pmult_nat_succ_morphism : - forall (p:positive) (n:nat), Pmult_nat (Psucc p) n = n + Pmult_nat p n. -Proof. -intro x; induction x as [p IHp| p IHp| ]; simpl in |- *; auto; intro m; - rewrite IHp; rewrite plus_assoc; trivial. -Qed. +(** [Pmult_nat] in term of [nat_of_P] *) -Lemma nat_of_P_succ_morphism : - forall p:positive, nat_of_P (Psucc p) = S (nat_of_P p). +Lemma Pmult_nat_mult : forall p n, + Pmult_nat p n = nat_of_P p * n. Proof. - intro; change (S (nat_of_P p)) with (1 + nat_of_P p) in |- *; - unfold nat_of_P in |- *; apply Pmult_nat_succ_morphism. + induction p; intros n. + unfold nat_of_P. simpl. f_equal. rewrite 2 IHp. + rewrite <- mult_assoc. f_equal. simpl. now rewrite <- plus_n_O. + unfold nat_of_P. simpl. rewrite 2 IHp. + rewrite <- mult_assoc. f_equal. simpl. now rewrite <- plus_n_O. + simpl. now rewrite <- plus_n_O. Qed. -Theorem Pmult_nat_plus_carry_morphism : - forall (p q:positive) (n:nat), - Pmult_nat (Pplus_carry p q) n = n + Pmult_nat (p + q) n. -Proof. -intro x; induction x as [p IHp| p IHp| ]; intro y; - [ destruct y as [p0| p0| ] - | destruct y as [p0| p0| ] - | destruct y as [p| p| ] ]; simpl in |- *; auto with arith; - intro m; - [ rewrite IHp; rewrite plus_assoc; trivial with arith - | rewrite IHp; rewrite plus_assoc; trivial with arith - | rewrite Pmult_nat_succ_morphism; rewrite plus_assoc; trivial with arith - | rewrite Pmult_nat_succ_morphism; apply plus_assoc_reverse ]. -Qed. +(** [nat_of_P] is a morphism for successor, addition, multiplication *) -Theorem nat_of_P_plus_carry_morphism : - forall p q:positive, nat_of_P (Pplus_carry p q) = S (nat_of_P (p + q)). +Lemma Psucc_S : forall p, nat_of_P (Psucc p) = S (nat_of_P p). Proof. -intros; unfold nat_of_P in |- *; rewrite Pmult_nat_plus_carry_morphism; - simpl in |- *; trivial with arith. + induction p; unfold nat_of_P; simpl; trivial. + now rewrite !Pmult_nat_mult, IHp. Qed. -Theorem Pmult_nat_l_plus_morphism : - forall (p q:positive) (n:nat), - Pmult_nat (p + q) n = Pmult_nat p n + Pmult_nat q n. +Theorem Pplus_plus : + forall p q, nat_of_P (p + q) = nat_of_P p + nat_of_P q. Proof. -intro x; induction x as [p IHp| p IHp| ]; intro y; - [ destruct y as [p0| p0| ] - | destruct y as [p0| p0| ] - | destruct y as [p| p| ] ]; simpl in |- *; auto with arith; - [ intros m; rewrite Pmult_nat_plus_carry_morphism; rewrite IHp; - rewrite plus_assoc_reverse; rewrite plus_assoc_reverse; - rewrite (plus_permute m (Pmult_nat p (m + m))); - trivial with arith - | intros m; rewrite IHp; apply plus_assoc - | intros m; rewrite Pmult_nat_succ_morphism; - rewrite (plus_comm (m + Pmult_nat p (m + m))); - apply plus_assoc_reverse - | intros m; rewrite IHp; apply plus_permute - | intros m; rewrite Pmult_nat_succ_morphism; apply plus_assoc_reverse ]. + induction p using Pind; intros q. + now rewrite <- Pplus_one_succ_l, Psucc_S. + now rewrite Pplus_succ_permute_l, !Psucc_S, IHp. Qed. -Theorem nat_of_P_plus_morphism : - forall p q:positive, nat_of_P (p + q) = nat_of_P p + nat_of_P q. +Theorem Pmult_mult : + forall p q, nat_of_P (p * q) = nat_of_P p * nat_of_P q. Proof. -intros x y; exact (Pmult_nat_l_plus_morphism x y 1). + induction p using Pind; simpl; intros; trivial. + now rewrite Pmult_Sn_m, Pplus_plus, IHp, Psucc_S. Qed. -(** [Pmult_nat] is a morphism for addition *) +(** Mapping of xH, xO and xI through [nat_of_P] *) -Lemma Pmult_nat_r_plus_morphism : - forall (p:positive) (n:nat), - Pmult_nat p (n + n) = Pmult_nat p n + Pmult_nat p n. +Lemma nat_of_P_xH : nat_of_P 1 = 1. Proof. -intro y; induction y as [p H| p H| ]; intro m; - [ simpl in |- *; rewrite H; rewrite plus_assoc_reverse; - rewrite (plus_permute m (Pmult_nat p (m + m))); - rewrite plus_assoc_reverse; auto with arith - | simpl in |- *; rewrite H; auto with arith - | simpl in |- *; trivial with arith ]. + reflexivity. Qed. -Lemma ZL6 : forall p:positive, Pmult_nat p 2 = nat_of_P p + nat_of_P p. +Lemma nat_of_P_xO : forall p, nat_of_P (xO p) = 2 * nat_of_P p. Proof. -intro p; change 2 with (1 + 1) in |- *; rewrite Pmult_nat_r_plus_morphism; - trivial. + intros. exact (Pmult_mult 2 p). Qed. -(** [nat_of_P] is a morphism for multiplication *) - -Theorem nat_of_P_mult_morphism : - forall p q:positive, nat_of_P (p * q) = nat_of_P p * nat_of_P q. +Lemma nat_of_P_xI : forall p, nat_of_P (xI p) = S (2 * nat_of_P p). Proof. -intros x y; induction x as [x' H| x' H| ]; - [ change (xI x' * y)%positive with (y + xO (x' * y))%positive in |- *; - rewrite nat_of_P_plus_morphism; unfold nat_of_P at 2 3 in |- *; - simpl in |- *; do 2 rewrite ZL6; rewrite H; rewrite mult_plus_distr_r; - reflexivity - | unfold nat_of_P at 1 2 in |- *; simpl in |- *; do 2 rewrite ZL6; rewrite H; - rewrite mult_plus_distr_r; reflexivity - | simpl in |- *; rewrite <- plus_n_O; reflexivity ]. + intros. now rewrite xI_succ_xO, Psucc_S, nat_of_P_xO. Qed. (** [nat_of_P] maps to the strictly positive subset of [nat] *) -Lemma ZL4 : forall p:positive, exists h : nat, nat_of_P p = S h. +Lemma nat_of_P_is_S : forall p, exists n, nat_of_P p = S n. Proof. -intro y; induction y as [p H| p H| ]; - [ destruct H as [x H1]; exists (S x + S x); unfold nat_of_P in |- *; - simpl in |- *; change 2 with (1 + 1) in |- *; - rewrite Pmult_nat_r_plus_morphism; unfold nat_of_P in H1; - rewrite H1; auto with arith - | destruct H as [x H2]; exists (x + S x); unfold nat_of_P in |- *; - simpl in |- *; change 2 with (1 + 1) in |- *; - rewrite Pmult_nat_r_plus_morphism; unfold nat_of_P in H2; - rewrite H2; auto with arith - | exists 0; auto with arith ]. +induction p as [p (h,IH)| p (h,IH)| ]; unfold nat_of_P; simpl. + exists (S h * 2). now rewrite Pmult_nat_mult, IH. + exists (S (h*2)). now rewrite Pmult_nat_mult,IH. + now exists 0. Qed. -(** Extra lemmas on [lt] on Peano natural numbers *) - -Lemma ZL7 : forall n m:nat, n < m -> n + n < m + m. -Proof. -intros m n H; apply lt_trans with (m := m + n); - [ apply plus_lt_compat_l with (1 := H) - | rewrite (plus_comm m n); apply plus_lt_compat_l with (1 := H) ]. -Qed. +(** [nat_of_P] is strictly positive *) -Lemma ZL8 : forall n m:nat, n < m -> S (n + n) < m + m. +Lemma nat_of_P_pos : forall p, 0 < nat_of_P p. Proof. -intros m n H; apply le_lt_trans with (m := m + n); - [ change (m + m < m + n) in |- *; apply plus_lt_compat_l with (1 := H) - | rewrite (plus_comm m n); apply plus_lt_compat_l with (1 := H) ]. + intros p. destruct (nat_of_P_is_S p) as (n,->). auto with arith. Qed. -(** [nat_of_P] is a morphism from [positive] to [nat] for [lt] (expressed - from [compare] on [positive]) +(** [nat_of_P] is a morphism for comparison *) - Part 1: [lt] on [positive] is finer than [lt] on [nat] -*) - -Lemma nat_of_P_lt_Lt_compare_morphism : - forall p q:positive, (p ?= q) Eq = Lt -> nat_of_P p < nat_of_P q. +Lemma Pcompare_nat_compare : forall p q, + (p ?= q) Eq = nat_compare (nat_of_P p) (nat_of_P q). Proof. -intro x; induction x as [p H| p H| ]; intro y; destruct y as [q| q| ]; - intro H2; - [ unfold nat_of_P in |- *; simpl in |- *; apply lt_n_S; do 2 rewrite ZL6; - apply ZL7; apply H; simpl in H2; assumption - | unfold nat_of_P in |- *; simpl in |- *; do 2 rewrite ZL6; apply ZL8; - apply H; simpl in H2; apply Pcompare_Gt_Lt; assumption - | simpl in |- *; discriminate H2 - | simpl in |- *; unfold nat_of_P in |- *; simpl in |- *; do 2 rewrite ZL6; - elim (Pcompare_Lt_Lt p q H2); - [ intros H3; apply lt_S; apply ZL7; apply H; apply H3 - | intros E; rewrite E; apply lt_n_Sn ] - | simpl in |- *; unfold nat_of_P in |- *; simpl in |- *; do 2 rewrite ZL6; - apply ZL7; apply H; assumption - | simpl in |- *; discriminate H2 - | unfold nat_of_P in |- *; simpl in |- *; apply lt_n_S; rewrite ZL6; - elim (ZL4 q); intros h H3; rewrite H3; simpl in |- *; - apply lt_O_Sn - | unfold nat_of_P in |- *; simpl in |- *; rewrite ZL6; elim (ZL4 q); - intros h H3; rewrite H3; simpl in |- *; rewrite <- plus_n_Sm; - apply lt_n_S; apply lt_O_Sn - | simpl in |- *; discriminate H2 ]. + induction p as [ |p IH] using Pind; intros q. + destruct (Psucc_pred q) as [Hq|Hq]; [now subst|]. + rewrite <- Hq, Plt_1_succ, Psucc_S, nat_of_P_xH, nat_compare_S. + symmetry. apply nat_compare_lt, nat_of_P_pos. + destruct (Psucc_pred q) as [Hq|Hq]; [subst|]. + rewrite ZC4, Plt_1_succ, Psucc_S. simpl. + symmetry. apply nat_compare_gt, nat_of_P_pos. + now rewrite <- Hq, 2 Psucc_S, Pcompare_succ_succ, IH. Qed. -(** [nat_of_P] is a morphism from [positive] to [nat] for [gt] (expressed - from [compare] on [positive]) +(** [nat_of_P] is hence injective *) - Part 1: [gt] on [positive] is finer than [gt] on [nat] -*) - -Lemma nat_of_P_gt_Gt_compare_morphism : - forall p q:positive, (p ?= q) Eq = Gt -> nat_of_P p > nat_of_P q. +Lemma nat_of_P_inj_iff : forall p q, nat_of_P p = nat_of_P q <-> p = q. Proof. -intros p q GT. unfold gt. -apply nat_of_P_lt_Lt_compare_morphism. -change ((q ?= p) (CompOpp Eq) = CompOpp Gt). -rewrite <- Pcompare_antisym, GT; auto. + intros. + eapply iff_trans; [eapply iff_sym|eapply Pcompare_eq_iff]. + rewrite Pcompare_nat_compare. + apply nat_compare_eq_iff. Qed. -(** [nat_of_P] is a morphism for [Pcompare] and [nat_compare] *) - -Lemma nat_of_P_compare_morphism : forall p q, - (p ?= q) Eq = nat_compare (nat_of_P p) (nat_of_P q). +Lemma nat_of_P_inj : forall p q, nat_of_P p = nat_of_P q -> p = q. Proof. - intros p q; symmetry. - destruct ((p ?= q) Eq) as [ | | ]_eqn. - rewrite (Pcompare_Eq_eq p q); auto. - apply <- nat_compare_eq_iff; auto. - apply -> nat_compare_lt. apply nat_of_P_lt_Lt_compare_morphism; auto. - apply -> nat_compare_gt. apply nat_of_P_gt_Gt_compare_morphism; auto. + intros. now apply nat_of_P_inj_iff. Qed. -(** [nat_of_P] is hence injective. *) +(** [nat_of_P] is a morphism for [lt], [le], etc *) -Lemma nat_of_P_inj : forall p q:positive, nat_of_P p = nat_of_P q -> p = q. +Lemma Plt_lt : forall p q, Plt p q <-> nat_of_P p < nat_of_P q. Proof. -intros. -apply Pcompare_Eq_eq. -rewrite nat_of_P_compare_morphism. -apply <- nat_compare_eq_iff; auto. + intros. unfold Plt. rewrite Pcompare_nat_compare. + apply iff_sym, nat_compare_lt. Qed. -(** Stating this bidirectionally lets us reason equationally with it: *) - -Lemma nat_of_P_inj_iff : forall p q, nat_of_P p = nat_of_P q <-> p = q. +Lemma Ple_le : forall p q, Ple p q <-> nat_of_P p <= nat_of_P q. Proof. - split; intro. now apply nat_of_P_inj. now subst. + intros. unfold Ple. rewrite Pcompare_nat_compare. + apply iff_sym, nat_compare_le. Qed. -(** [nat_of_P] is a morphism from [positive] to [nat] for [lt] (expressed - from [compare] on [positive]) - - Part 2: [lt] on [nat] is finer than [lt] on [positive] -*) - -Lemma nat_of_P_lt_Lt_compare_complement_morphism : - forall p q:positive, nat_of_P p < nat_of_P q -> (p ?= q) Eq = Lt. +Lemma Pgt_gt : forall p q, Pgt p q <-> nat_of_P p > nat_of_P q. Proof. - intros. rewrite nat_of_P_compare_morphism. - apply -> nat_compare_lt; auto. + intros. unfold Pgt. rewrite Pcompare_nat_compare. + apply iff_sym, nat_compare_gt. Qed. -(** Again, stating this bidirectionally lets us reason equationally with it: *) - -Lemma Plt_lt : forall p q, Plt p q <-> lt (nat_of_P p) (nat_of_P q). +Lemma Pge_ge : forall p q, Pge p q <-> nat_of_P p >= nat_of_P q. Proof. - intros. unfold Plt. rewrite nat_of_P_compare_morphism. - apply iff_sym, nat_compare_lt. + intros. unfold Pge. rewrite Pcompare_nat_compare. + apply iff_sym, nat_compare_ge. Qed. -(** And the same for Ple *) +(** [nat_of_P] is a morphism for subtraction *) -Lemma Ple_le : forall p q, Ple p q <-> le (nat_of_P p) (nat_of_P q). +Theorem Pminus_minus : + forall p q, Plt q p -> nat_of_P (p - q) = nat_of_P p - nat_of_P q. Proof. - intros. unfold Ple. rewrite nat_of_P_compare_morphism. - apply iff_sym, nat_compare_le. + intros x y H; apply plus_reg_l with (nat_of_P y); rewrite le_plus_minus_r. + rewrite <- Pplus_plus, Pplus_minus. trivial. now apply ZC2. + now apply lt_le_weak, Plt_lt. Qed. -(** [nat_of_P] is a morphism from [positive] to [nat] for [gt] (expressed - from [compare] on [positive]) - - Part 2: [gt] on [nat] is finer than [gt] on [positive] -*) +(** Results about [Pmult_nat], many are old intermediate results *) -Lemma nat_of_P_gt_Gt_compare_complement_morphism : - forall p q:positive, nat_of_P p > nat_of_P q -> (p ?= q) Eq = Gt. +Lemma Pmult_nat_succ_morphism : + forall p n, Pmult_nat (Psucc p) n = n + Pmult_nat p n. Proof. - intros. rewrite nat_of_P_compare_morphism. - apply -> nat_compare_gt; auto. -Qed. - - -(** [nat_of_P] is strictly positive *) - -Lemma le_Pmult_nat : forall (p:positive) (n:nat), n <= Pmult_nat p n. -induction p; simpl in |- *; auto with arith. -intro m; apply le_trans with (m + m); auto with arith. -Qed. - -Lemma lt_O_nat_of_P : forall p:positive, 0 < nat_of_P p. -intro; unfold nat_of_P in |- *; apply lt_le_trans with 1; auto with arith. -apply le_Pmult_nat. + intros. now rewrite !Pmult_nat_mult, Psucc_S. Qed. -(** Pmult_nat permutes with multiplication *) - -Lemma Pmult_nat_mult_permute : - forall (p:positive) (n m:nat), Pmult_nat p (m * n) = m * Pmult_nat p n. +Theorem Pmult_nat_l_plus_morphism : + forall p q n, Pmult_nat (p + q) n = Pmult_nat p n + Pmult_nat q n. Proof. - simple induction p. intros. simpl in |- *. rewrite mult_plus_distr_l. rewrite <- (mult_plus_distr_l m n n). - rewrite (H (n + n) m). reflexivity. - intros. simpl in |- *. rewrite <- (mult_plus_distr_l m n n). apply H. - trivial. + intros. rewrite !Pmult_nat_mult, Pplus_plus. apply mult_plus_distr_r. Qed. -Lemma Pmult_nat_2_mult_2_permute : - forall p:positive, Pmult_nat p 2 = 2 * Pmult_nat p 1. +Theorem Pmult_nat_plus_carry_morphism : + forall p q n, Pmult_nat (Pplus_carry p q) n = n + Pmult_nat (p + q) n. Proof. - intros. rewrite <- Pmult_nat_mult_permute. reflexivity. + intros. now rewrite Pplus_carry_spec, Pmult_nat_succ_morphism. Qed. -Lemma Pmult_nat_4_mult_2_permute : - forall p:positive, Pmult_nat p 4 = 2 * Pmult_nat p 2. +Lemma Pmult_nat_r_plus_morphism : + forall p n, Pmult_nat p (n + n) = Pmult_nat p n + Pmult_nat p n. Proof. - intros. rewrite <- Pmult_nat_mult_permute. reflexivity. + intros. rewrite !Pmult_nat_mult. apply mult_plus_distr_l. Qed. -(** Mapping of xH, xO and xI through [nat_of_P] *) - -Lemma nat_of_P_xH : nat_of_P 1 = 1. +Lemma ZL6 : forall p, Pmult_nat p 2 = nat_of_P p + nat_of_P p. Proof. - reflexivity. + intros. rewrite Pmult_nat_mult, mult_comm. simpl. now rewrite <- plus_n_O. Qed. -Lemma nat_of_P_xO : forall p:positive, nat_of_P (xO p) = 2 * nat_of_P p. +Lemma le_Pmult_nat : forall p n, n <= Pmult_nat p n. Proof. - intros. - change 2 with (nat_of_P 2). - rewrite <- nat_of_P_mult_morphism. - f_equal. + intros. rewrite Pmult_nat_mult. + apply le_trans with (1*n). now rewrite mult_1_l. + apply mult_le_compat_r. apply nat_of_P_pos. Qed. -Lemma nat_of_P_xI : forall p:positive, nat_of_P (xI p) = S (2 * nat_of_P p). +(** [nat_of_P] is a morphism for [iter_pos] and [iter_nat] *) + +Theorem iter_nat_of_P : + forall p (A:Type) (f:A->A) (x:A), + iter_pos p A f x = iter_nat (nat_of_P p) A f x. Proof. - intros. - change 2 with (nat_of_P 2). - rewrite <- nat_of_P_mult_morphism, <- nat_of_P_succ_morphism. - f_equal. + induction p as [p IH|p IH| ]; intros A f x; simpl; trivial. + f_equal. now rewrite 2 IH, <- iter_nat_plus, <- ZL6. + now rewrite 2 IH, <- iter_nat_plus, <- ZL6. Qed. (**********************************************************************) @@ -341,143 +208,63 @@ Qed. (** Composition of [P_of_succ_nat] and [nat_of_P] is successor on [nat] *) -Theorem nat_of_P_o_P_of_succ_nat_eq_succ : - forall n:nat, nat_of_P (P_of_succ_nat n) = S n. -Proof. -induction n as [|n H]. -reflexivity. -simpl; rewrite nat_of_P_succ_morphism, H; auto. -Qed. - -(** Miscellaneous lemmas on [P_of_succ_nat] *) - -Lemma ZL3 : - forall n:nat, Psucc (P_of_succ_nat (n + n)) = xO (P_of_succ_nat n). +Theorem nat_of_P_of_succ_nat : + forall n, nat_of_P (P_of_succ_nat n) = S n. Proof. -induction n as [| n H]; simpl; - [ auto with arith - | rewrite plus_comm; simpl; rewrite H; - rewrite xO_succ_permute; auto with arith ]. -Qed. - -Lemma ZL5 : forall n:nat, P_of_succ_nat (S n + S n) = xI (P_of_succ_nat n). -Proof. -induction n as [| n H]; simpl; - [ auto with arith - | rewrite <- plus_n_Sm; simpl; simpl in H; rewrite H; - auto with arith ]. +induction n as [|n H]; trivial; simpl; now rewrite Psucc_S, H. Qed. (** Composition of [nat_of_P] and [P_of_succ_nat] is successor on [positive] *) -Theorem P_of_succ_nat_o_nat_of_P_eq_succ : - forall p:positive, P_of_succ_nat (nat_of_P p) = Psucc p. +Theorem P_of_succ_nat_of_P : + forall p, P_of_succ_nat (nat_of_P p) = Psucc p. Proof. intros. -apply nat_of_P_inj. -rewrite nat_of_P_o_P_of_succ_nat_eq_succ, nat_of_P_succ_morphism; auto. +apply nat_of_P_inj. now rewrite nat_of_P_of_succ_nat, Psucc_S. Qed. (** Composition of [nat_of_P], [P_of_succ_nat] and [Ppred] is identity on [positive] *) -Theorem pred_o_P_of_succ_nat_o_nat_of_P_eq_id : - forall p:positive, Ppred (P_of_succ_nat (nat_of_P p)) = p. +Theorem Ppred_of_succ_nat_of_P : + forall p, Ppred (P_of_succ_nat (nat_of_P p)) = p. Proof. -intros; rewrite P_of_succ_nat_o_nat_of_P_eq_succ, Ppred_succ; auto. +intros; rewrite P_of_succ_nat_of_P, Ppred_succ; auto. Qed. (**********************************************************************) -(** Extra properties of the injection from binary positive numbers to Peano - natural numbers *) - -(** [nat_of_P] is a morphism for subtraction on positive numbers *) - -Theorem nat_of_P_minus_morphism : - forall p q:positive, - (p ?= q) Eq = Gt -> nat_of_P (p - q) = nat_of_P p - nat_of_P q. -Proof. -intros x y H; apply plus_reg_l with (nat_of_P y); rewrite le_plus_minus_r; - [ rewrite <- nat_of_P_plus_morphism; rewrite Pplus_minus; auto with arith - | apply lt_le_weak; exact (nat_of_P_gt_Gt_compare_morphism x y H) ]. -Qed. - - -Lemma ZL16 : forall p q:positive, nat_of_P p - nat_of_P q < nat_of_P p. -Proof. -intros p q; elim (ZL4 p); elim (ZL4 q); intros h H1 i H2; rewrite H1; - rewrite H2; simpl in |- *; unfold lt in |- *; apply le_n_S; - apply le_minus. -Qed. - -Lemma ZL17 : forall p q:positive, nat_of_P p < nat_of_P (p + q). -Proof. -intros p q; rewrite nat_of_P_plus_morphism; unfold lt in |- *; elim (ZL4 q); - intros k H; rewrite H; rewrite plus_comm; simpl in |- *; - apply le_n_S; apply le_plus_r. -Qed. - -(** Comparison and subtraction *) - -Lemma Pcompare_minus_r : - forall p q r:positive, - (q ?= p) Eq = Lt -> - (r ?= p) Eq = Gt -> - (r ?= q) Eq = Gt -> (r - p ?= r - q) Eq = Lt. -Proof. -intros; apply nat_of_P_lt_Lt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ apply plus_lt_reg_l with (p := nat_of_P q); rewrite le_plus_minus_r; - [ rewrite plus_comm; apply plus_lt_reg_l with (p := nat_of_P p); - rewrite plus_assoc; rewrite le_plus_minus_r; - [ rewrite (plus_comm (nat_of_P p)); apply plus_lt_compat_l; - apply nat_of_P_lt_Lt_compare_morphism; - assumption - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption ] - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; apply ZC1; - assumption ] - | assumption ] - | assumption ]. -Qed. - -Lemma Pcompare_minus_l : - forall p q r:positive, - (q ?= p) Eq = Lt -> - (p ?= r) Eq = Gt -> - (q ?= r) Eq = Gt -> (q - r ?= p - r) Eq = Lt. -Proof. -intros p q z; intros; apply nat_of_P_lt_Lt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ unfold gt in |- *; apply plus_lt_reg_l with (p := nat_of_P z); - rewrite le_plus_minus_r; - [ rewrite le_plus_minus_r; - [ apply nat_of_P_lt_Lt_compare_morphism; assumption - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption ] - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; apply ZC1; - assumption ] - | assumption ] - | assumption ]. -Qed. - -(** Distributivity of multiplication over subtraction *) - -Theorem Pmult_minus_distr_l : - forall p q r:positive, - (q ?= r) Eq = Gt -> - (p * (q - r) = p * q - p * r)%positive. -Proof. -intros x y z H; apply nat_of_P_inj; rewrite nat_of_P_mult_morphism; - rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ do 2 rewrite nat_of_P_mult_morphism; - do 3 rewrite (mult_comm (nat_of_P x)); apply mult_minus_distr_r - | apply nat_of_P_gt_Gt_compare_complement_morphism; - do 2 rewrite nat_of_P_mult_morphism; unfold gt in |- *; - elim (ZL4 x); intros h H1; rewrite H1; apply mult_S_lt_compat_l; - exact (nat_of_P_gt_Gt_compare_morphism y z H) ] - | assumption ]. -Qed. +(** Extra properties of the injection from binary positive numbers + to Peano natural numbers *) + +(** Old names and old-style lemmas *) + +Notation nat_of_P_succ_morphism := Psucc_S (only parsing). +Notation nat_of_P_plus_morphism := Pplus_plus (only parsing). +Notation nat_of_P_mult_morphism := Pmult_mult (only parsing). +Notation nat_of_P_compare_morphism := Pcompare_nat_compare (only parsing). +Notation lt_O_nat_of_P := nat_of_P_pos (only parsing). +Notation ZL4 := nat_of_P_is_S (only parsing). +Notation nat_of_P_o_P_of_succ_nat_eq_succ := nat_of_P_of_succ_nat (only parsing). +Notation P_of_succ_nat_o_nat_of_P_eq_succ := P_of_succ_nat_of_P (only parsing). +Notation pred_o_P_of_succ_nat_o_nat_of_P_eq_id := Ppred_of_succ_nat_of_P + (only parsing). + +Definition nat_of_P_minus_morphism p q : + (p ?= q) Eq = Gt -> nat_of_P (p - q) = nat_of_P p - nat_of_P q + := fun H => Pminus_minus p q (ZC1 _ _ H). + +Definition nat_of_P_lt_Lt_compare_morphism p q : + (p ?= q) Eq = Lt -> nat_of_P p < nat_of_P q + := proj1 (Plt_lt p q). + +Definition nat_of_P_gt_Gt_compare_morphism p q : + (p ?= q) Eq = Gt -> nat_of_P p > nat_of_P q + := proj1 (Pgt_gt p q). + +Definition nat_of_P_lt_Lt_compare_complement_morphism p q : + nat_of_P p < nat_of_P q -> (p ?= q) Eq = Lt + := proj2 (Plt_lt p q). + +Definition nat_of_P_gt_Gt_compare_complement_morphism p q : + nat_of_P p > nat_of_P q -> (p ?= q) Eq = Gt + := proj2 (Pgt_gt p q). diff --git a/theories/Reals/RIneq.v b/theories/Reals/RIneq.v index 154541164..de41fd3f6 100644 --- a/theories/Reals/RIneq.v +++ b/theories/Reals/RIneq.v @@ -1601,7 +1601,7 @@ Lemma pos_INR_nat_of_P : forall p:positive, 0 < INR (nat_of_P p). Proof. intro; apply lt_0_INR. simpl in |- *; auto with real. - apply lt_O_nat_of_P. + apply nat_of_P_pos. Qed. Hint Resolve pos_INR_nat_of_P: real. @@ -1710,38 +1710,31 @@ Qed. Lemma INR_IZR_INZ : forall n:nat, INR n = IZR (Z_of_nat n). Proof. simple induction n; auto with real. - intros; simpl in |- *; rewrite nat_of_P_o_P_of_succ_nat_eq_succ; + intros; simpl in |- *; rewrite nat_of_P_of_succ_nat; auto with real. Qed. Lemma plus_IZR_NEG_POS : forall p q:positive, IZR (Zpos p + Zneg q) = IZR (Zpos p) + IZR (Zneg q). Proof. - intros. - case (lt_eq_lt_dec (nat_of_P p) (nat_of_P q)). - intros [H| H]; simpl in |- *. - rewrite nat_of_P_lt_Lt_compare_complement_morphism; simpl in |- *; trivial. - rewrite (nat_of_P_minus_morphism q p). - rewrite minus_INR; auto with arith; ring. - apply ZC2; apply nat_of_P_lt_Lt_compare_complement_morphism; trivial. - rewrite (nat_of_P_inj p q); trivial. - rewrite Pcompare_refl; simpl in |- *; auto with real. - intro H; simpl in |- *. - rewrite nat_of_P_gt_Gt_compare_complement_morphism; simpl in |- *; - auto with arith. - rewrite (nat_of_P_minus_morphism p q). - rewrite minus_INR; auto with arith; ring. - apply ZC2; apply nat_of_P_lt_Lt_compare_complement_morphism; trivial. + intros p q; simpl. case Pcompare_spec; intros H; simpl. + subst. ring. + rewrite Pminus_minus by trivial. + rewrite minus_INR by (now apply lt_le_weak, Plt_lt). + ring. + rewrite Pminus_minus by trivial. + rewrite minus_INR by (now apply lt_le_weak, Plt_lt). + ring. Qed. (**********) Lemma plus_IZR : forall n m:Z, IZR (n + m) = IZR n + IZR m. Proof. intro z; destruct z; intro t; destruct t; intros; auto with real. - simpl in |- *; intros; rewrite nat_of_P_plus_morphism; auto with real. + simpl; intros; rewrite Pplus_plus; auto with real. apply plus_IZR_NEG_POS. rewrite Zplus_comm; rewrite Rplus_comm; apply plus_IZR_NEG_POS. - simpl in |- *; intros; rewrite nat_of_P_plus_morphism; rewrite plus_INR; + simpl; intros; rewrite Pplus_plus; rewrite plus_INR; auto with real. Qed. @@ -1749,14 +1742,14 @@ Qed. Lemma mult_IZR : forall n m:Z, IZR (n * m) = IZR n * IZR m. Proof. intros z t; case z; case t; simpl in |- *; auto with real. - intros t1 z1; rewrite nat_of_P_mult_morphism; auto with real. - intros t1 z1; rewrite nat_of_P_mult_morphism; auto with real. + intros t1 z1; rewrite Pmult_mult; auto with real. + intros t1 z1; rewrite Pmult_mult; auto with real. rewrite Rmult_comm. rewrite Ropp_mult_distr_l_reverse; auto with real. apply Ropp_eq_compat; rewrite mult_comm; auto with real. - intros t1 z1; rewrite nat_of_P_mult_morphism; auto with real. + intros t1 z1; rewrite Pmult_mult; auto with real. rewrite Ropp_mult_distr_l_reverse; auto with real. - intros t1 z1; rewrite nat_of_P_mult_morphism; auto with real. + intros t1 z1; rewrite Pmult_mult; auto with real. rewrite Rmult_opp_opp; auto with real. Qed. @@ -1764,7 +1757,7 @@ Lemma pow_IZR : forall z n, pow (IZR z) n = IZR (Zpower z (Z_of_nat n)). Proof. intros z [|n];simpl;trivial. rewrite Zpower_pos_nat. - rewrite nat_of_P_o_P_of_succ_nat_eq_succ. unfold Zpower_nat;simpl. + rewrite nat_of_P_of_succ_nat. unfold Zpower_nat;simpl. rewrite mult_IZR. induction n;simpl;trivial. rewrite mult_IZR;ring[IHn]. diff --git a/theories/Reals/Rfunctions.v b/theories/Reals/Rfunctions.v index a2fe4f80f..525eff688 100644 --- a/theories/Reals/Rfunctions.v +++ b/theories/Reals/Rfunctions.v @@ -34,7 +34,7 @@ Open Local Scope R_scope. (*********) Lemma INR_fact_neq_0 : forall n:nat, INR (fact n) <> 0. Proof. - intro; red in |- *; intro; apply (not_O_INR (fact n) (fact_neq_0 n)); + intro; red; intro; apply (not_O_INR (fact n) (fact_neq_0 n)); assumption. Qed. @@ -49,7 +49,7 @@ Lemma simpl_fact : forall n:nat, / INR (fact (S n)) * / / INR (fact n) = / INR (S n). Proof. intro; rewrite (Rinv_involutive (INR (fact n)) (INR_fact_neq_0 n)); - unfold fact at 1 in |- *; cbv beta iota in |- *; fold fact in |- *; + unfold fact at 1; cbv beta iota; fold fact; rewrite (mult_INR (S n) (fact n)); rewrite (Rinv_mult_distr (INR (S n)) (INR (fact n))). rewrite (Rmult_assoc (/ INR (S n)) (/ INR (fact n)) (INR (fact n))); @@ -73,20 +73,20 @@ Qed. Lemma pow_1 : forall x:R, x ^ 1 = x. Proof. - simpl in |- *; auto with real. + simpl; auto with real. Qed. Lemma pow_add : forall (x:R) (n m:nat), x ^ (n + m) = x ^ n * x ^ m. Proof. - intros x n; elim n; simpl in |- *; auto with real. + intros x n; elim n; simpl; auto with real. intros n0 H' m; rewrite H'; auto with real. Qed. Lemma pow_nonzero : forall (x:R) (n:nat), x <> 0 -> x ^ n <> 0. Proof. - intro; simple induction n; simpl in |- *. - intro; red in |- *; intro; apply R1_neq_R0; assumption. - intros; red in |- *; intro; elim (Rmult_integral x (x ^ n0) H1). + intro; simple induction n; simpl. + intro; red; intro; apply R1_neq_R0; assumption. + intros; red; intro; elim (Rmult_integral x (x ^ n0) H1). intro; auto. apply H; assumption. Qed. @@ -96,24 +96,24 @@ Hint Resolve pow_O pow_1 pow_add pow_nonzero: real. Lemma pow_RN_plus : forall (x:R) (n m:nat), x <> 0 -> x ^ n = x ^ (n + m) * / x ^ m. Proof. - intros x n; elim n; simpl in |- *; auto with real. + intros x n; elim n; simpl; auto with real. intros n0 H' m H'0. rewrite Rmult_assoc; rewrite <- H'; auto. Qed. Lemma pow_lt : forall (x:R) (n:nat), 0 < x -> 0 < x ^ n. Proof. - intros x n; elim n; simpl in |- *; auto with real. + intros x n; elim n; simpl; auto with real. intros n0 H' H'0; replace 0 with (x * 0); auto with real. Qed. Hint Resolve pow_lt: real. Lemma Rlt_pow_R1 : forall (x:R) (n:nat), 1 < x -> (0 < n)%nat -> 1 < x ^ n. Proof. - intros x n; elim n; simpl in |- *; auto with real. + intros x n; elim n; simpl; auto with real. intros H' H'0; exfalso; omega. intros n0; case n0. - simpl in |- *; rewrite Rmult_1_r; auto. + simpl; rewrite Rmult_1_r; auto. intros n1 H' H'0 H'1. replace 1 with (1 * 1); auto with real. apply Rlt_trans with (r2 := x * 1); auto with real. @@ -127,7 +127,7 @@ Lemma Rlt_pow : forall (x:R) (n m:nat), 1 < x -> (n < m)%nat -> x ^ n < x ^ m. Proof. intros x n m H' H'0; replace m with (m - n + n)%nat. rewrite pow_add. - pattern (x ^ n) at 1 in |- *; replace (x ^ n) with (1 * x ^ n); + pattern (x ^ n) at 1; replace (x ^ n) with (1 * x ^ n); auto with real. apply Rminus_lt. repeat rewrite (fun y:R => Rmult_comm y (x ^ n)); @@ -147,14 +147,14 @@ Hint Resolve Rlt_pow: real. (*********) Lemma tech_pow_Rmult : forall (x:R) (n:nat), x * x ^ n = x ^ S n. Proof. - simple induction n; simpl in |- *; trivial. + simple induction n; simpl; trivial. Qed. (*********) Lemma tech_pow_Rplus : forall (x:R) (a n:nat), x ^ a + INR n * x ^ a = INR (S n) * x ^ a. Proof. - intros; pattern (x ^ a) at 1 in |- *; + intros; pattern (x ^ a) at 1; rewrite <- (let (H1, H2) := Rmult_ne (x ^ a) in H1); rewrite (Rmult_comm (INR n) (x ^ a)); rewrite <- (Rmult_plus_distr_l (x ^ a) 1 (INR n)); @@ -165,29 +165,29 @@ Qed. Lemma poly : forall (n:nat) (x:R), 0 < x -> 1 + INR n * x <= (1 + x) ^ n. Proof. intros; elim n. - simpl in |- *; cut (1 + 0 * x = 1). - intro; rewrite H0; unfold Rle in |- *; right; reflexivity. + simpl; cut (1 + 0 * x = 1). + intro; rewrite H0; unfold Rle; right; reflexivity. ring. - intros; unfold pow in |- *; fold pow in |- *; + intros; unfold pow; fold pow; apply (Rle_trans (1 + INR (S n0) * x) ((1 + x) * (1 + INR n0 * x)) ((1 + x) * (1 + x) ^ n0)). cut ((1 + x) * (1 + INR n0 * x) = 1 + INR (S n0) * x + INR n0 * (x * x)). - intro; rewrite H1; pattern (1 + INR (S n0) * x) at 1 in |- *; + intro; rewrite H1; pattern (1 + INR (S n0) * x) at 1; rewrite <- (let (H1, H2) := Rplus_ne (1 + INR (S n0) * x) in H1); apply Rplus_le_compat_l; elim n0; intros. - simpl in |- *; rewrite Rmult_0_l; unfold Rle in |- *; right; auto. - unfold Rle in |- *; left; generalize Rmult_gt_0_compat; unfold Rgt in |- *; - intro; fold (Rsqr x) in |- *; + simpl; rewrite Rmult_0_l; unfold Rle; right; auto. + unfold Rle; left; generalize Rmult_gt_0_compat; unfold Rgt; + intro; fold (Rsqr x); apply (H3 (INR (S n1)) (Rsqr x) (lt_INR_0 (S n1) (lt_O_Sn n1))); fold (x > 0) in H; apply (Rlt_0_sqr x (Rlt_dichotomy_converse x 0 (or_intror (x < 0) H))). rewrite (S_INR n0); ring. unfold Rle in H0; elim H0; intro. - unfold Rle in |- *; left; apply Rmult_lt_compat_l. + unfold Rle; left; apply Rmult_lt_compat_l. rewrite Rplus_comm; apply (Rle_lt_0_plus_1 x (Rlt_le 0 x H)). assumption. - rewrite H1; unfold Rle in |- *; right; trivial. + rewrite H1; unfold Rle; right; trivial. Qed. Lemma Power_monotonic : @@ -195,12 +195,12 @@ Lemma Power_monotonic : Rabs x > 1 -> (m <= n)%nat -> Rabs (x ^ m) <= Rabs (x ^ n). Proof. intros x m n H; induction n as [| n Hrecn]; intros; inversion H0. - unfold Rle in |- *; right; reflexivity. - unfold Rle in |- *; right; reflexivity. + unfold Rle; right; reflexivity. + unfold Rle; right; reflexivity. apply (Rle_trans (Rabs (x ^ m)) (Rabs (x ^ n)) (Rabs (x ^ S n))). apply Hrecn; assumption. - simpl in |- *; rewrite Rabs_mult. - pattern (Rabs (x ^ n)) at 1 in |- *. + simpl; rewrite Rabs_mult. + pattern (Rabs (x ^ n)) at 1. rewrite <- Rmult_1_r. rewrite (Rmult_comm (Rabs x) (Rabs (x ^ n))). apply Rmult_le_compat_l. @@ -211,7 +211,7 @@ Qed. Lemma RPow_abs : forall (x:R) (n:nat), Rabs x ^ n = Rabs (x ^ n). Proof. - intro; simple induction n; simpl in |- *. + intro; simple induction n; simpl. apply sym_eq; apply Rabs_pos_eq; apply Rlt_le; apply Rlt_0_1. intros; rewrite H; apply sym_eq; apply Rabs_mult. Qed. @@ -231,16 +231,16 @@ Proof. rewrite <- RPow_abs; cut (Rabs x = 1 + (Rabs x - 1)). intro; rewrite H3; apply (Rge_trans ((1 + (Rabs x - 1)) ^ x0) (1 + INR x0 * (Rabs x - 1)) b). - apply Rle_ge; apply poly; fold (Rabs x - 1 > 0) in |- *; apply Rgt_minus; + apply Rle_ge; apply poly; fold (Rabs x - 1 > 0); apply Rgt_minus; assumption. apply (Rge_trans (1 + INR x0 * (Rabs x - 1)) (INR x0 * (Rabs x - 1)) b). apply Rle_ge; apply Rlt_le; rewrite (Rplus_comm 1 (INR x0 * (Rabs x - 1))); - pattern (INR x0 * (Rabs x - 1)) at 1 in |- *; + pattern (INR x0 * (Rabs x - 1)) at 1; rewrite <- (let (H1, H2) := Rplus_ne (INR x0 * (Rabs x - 1)) in H1); apply Rplus_lt_compat_l; apply Rlt_0_1. cut (b = b * / (Rabs x - 1) * (Rabs x - 1)). intros; rewrite H4; apply Rmult_ge_compat_r. - apply Rge_minus; unfold Rge in |- *; left; assumption. + apply Rge_minus; unfold Rge; left; assumption. assumption. rewrite Rmult_assoc; rewrite Rinv_l. ring. @@ -252,26 +252,26 @@ Proof. apply (Rge_trans (INR x0) (IZR (up (b * / (Rabs x - 1)))) (b * / (Rabs x - 1))). rewrite INR_IZR_INZ; apply IZR_ge; omega. - unfold Rge in |- *; left; assumption. + unfold Rge; left; assumption. exists 0%nat; apply (Rge_trans (INR 0) (IZR (up (b * / (Rabs x - 1)))) (b * / (Rabs x - 1))). - rewrite INR_IZR_INZ; apply IZR_ge; simpl in |- *; omega. - unfold Rge in |- *; left; assumption. + rewrite INR_IZR_INZ; apply IZR_ge; simpl; omega. + unfold Rge; left; assumption. omega. Qed. Lemma pow_ne_zero : forall n:nat, n <> 0%nat -> 0 ^ n = 0. Proof. simple induction n. - simpl in |- *; auto. + simpl; auto. intros; elim H; reflexivity. - intros; simpl in |- *; apply Rmult_0_l. + intros; simpl; apply Rmult_0_l. Qed. Lemma Rinv_pow : forall (x:R) (n:nat), x <> 0 -> / x ^ n = (/ x) ^ n. Proof. - intros; elim n; simpl in |- *. + intros; elim n; simpl. apply Rinv_1. intro m; intro; rewrite Rinv_mult_distr. rewrite H0; reflexivity; assumption. @@ -305,7 +305,7 @@ Proof. rewrite <- Rabs_Rinv. rewrite Rinv_pow. apply (Rlt_le_trans (/ y) (/ y + 1) (Rabs ((/ x) ^ n))). - pattern (/ y) at 1 in |- *. + pattern (/ y) at 1. rewrite <- (let (H1, H2) := Rplus_ne (/ y) in H1). apply Rplus_lt_compat_l. apply Rlt_0_1. @@ -319,17 +319,17 @@ Proof. apply pow_nonzero. assumption. apply Rlt_dichotomy_converse. - right; unfold Rgt in |- *; assumption. + right; unfold Rgt; assumption. rewrite <- (Rinv_involutive 1). rewrite Rabs_Rinv. - unfold Rgt in |- *; apply Rinv_lt_contravar. + unfold Rgt; apply Rinv_lt_contravar. apply Rmult_lt_0_compat. apply Rabs_pos_lt. assumption. rewrite Rinv_1; apply Rlt_0_1. rewrite Rinv_1; assumption. assumption. - red in |- *; intro; apply R1_neq_R0; assumption. + red; intro; apply R1_neq_R0; assumption. Qed. Lemma pow_R1 : forall (r:R) (n:nat), r ^ n = 1 -> Rabs r = 1 \/ n = 0%nat. @@ -343,7 +343,7 @@ Proof. cut (Rabs r <> 0); [ intros Eq2 | apply Rabs_no_R0 ]; auto. absurd (Rabs (/ r) ^ 0 < Rabs (/ r) ^ S n0); auto. replace (Rabs (/ r) ^ S n0) with 1. - simpl in |- *; apply Rlt_irrefl; auto. + simpl; apply Rlt_irrefl; auto. rewrite Rabs_Rinv; auto. rewrite <- Rinv_pow; auto. rewrite RPow_abs; auto. @@ -354,16 +354,16 @@ Proof. case (Rabs_pos r); auto. intros H'3; case Eq2; auto. rewrite Rmult_1_r; rewrite Rinv_r; auto with real. - red in |- *; intro; absurd (r ^ S n0 = 1); auto. - simpl in |- *; rewrite H; rewrite Rmult_0_l; auto with real. + red; intro; absurd (r ^ S n0 = 1); auto. + simpl; rewrite H; rewrite Rmult_0_l; auto with real. generalize H'; case n; auto. intros n0 H'0. cut (r <> 0); [ intros Eq1 | auto with real ]. cut (Rabs r <> 0); [ intros Eq2 | apply Rabs_no_R0 ]; auto. absurd (Rabs r ^ 0 < Rabs r ^ S n0); auto with real arith. - repeat rewrite RPow_abs; rewrite H'0; simpl in |- *; auto with real. - red in |- *; intro; absurd (r ^ S n0 = 1); auto. - simpl in |- *; rewrite H; rewrite Rmult_0_l; auto with real. + repeat rewrite RPow_abs; rewrite H'0; simpl; auto with real. + red; intro; absurd (r ^ S n0 = 1); auto. + simpl; rewrite H; rewrite Rmult_0_l; auto with real. Qed. Lemma pow_Rsqr : forall (x:R) (n:nat), x ^ (2 * n) = Rsqr x ^ n. @@ -373,15 +373,15 @@ Proof. replace (2 * S n)%nat with (S (S (2 * n))). replace (x ^ S (S (2 * n))) with (x * x * x ^ (2 * n)). rewrite Hrecn; reflexivity. - simpl in |- *; ring. + simpl; ring. ring. Qed. Lemma pow_le : forall (a:R) (n:nat), 0 <= a -> 0 <= a ^ n. Proof. intros; induction n as [| n Hrecn]. - simpl in |- *; left; apply Rlt_0_1. - simpl in |- *; apply Rmult_le_pos; assumption. + simpl; left; apply Rlt_0_1. + simpl; apply Rmult_le_pos; assumption. Qed. (**********) @@ -390,36 +390,36 @@ Proof. intro; induction n as [| n Hrecn]. reflexivity. replace (2 * S n)%nat with (2 + 2 * n)%nat by ring. - rewrite pow_add; rewrite Hrecn; simpl in |- *; ring. + rewrite pow_add; rewrite Hrecn; simpl; ring. Qed. (**********) Lemma pow_1_odd : forall n:nat, (-1) ^ S (2 * n) = -1. Proof. intro; replace (S (2 * n)) with (2 * n + 1)%nat by ring. - rewrite pow_add; rewrite pow_1_even; simpl in |- *; ring. + rewrite pow_add; rewrite pow_1_even; simpl; ring. Qed. (**********) Lemma pow_1_abs : forall n:nat, Rabs ((-1) ^ n) = 1. Proof. intro; induction n as [| n Hrecn]. - simpl in |- *; apply Rabs_R1. + simpl; apply Rabs_R1. replace (S n) with (n + 1)%nat; [ rewrite pow_add | ring ]. rewrite Rabs_mult. - rewrite Hrecn; rewrite Rmult_1_l; simpl in |- *; rewrite Rmult_1_r; + rewrite Hrecn; rewrite Rmult_1_l; simpl; rewrite Rmult_1_r; rewrite Rabs_Ropp; apply Rabs_R1. Qed. Lemma pow_mult : forall (x:R) (n1 n2:nat), x ^ (n1 * n2) = (x ^ n1) ^ n2. Proof. intros; induction n2 as [| n2 Hrecn2]. - simpl in |- *; replace (n1 * 0)%nat with 0%nat; [ reflexivity | ring ]. + simpl; replace (n1 * 0)%nat with 0%nat; [ reflexivity | ring ]. replace (n1 * S n2)%nat with (n1 * n2 + n1)%nat. replace (S n2) with (n2 + 1)%nat by ring. do 2 rewrite pow_add. rewrite Hrecn2. - simpl in |- *. + simpl. ring. ring. Qed. @@ -429,7 +429,7 @@ Proof. intros. induction n as [| n Hrecn]. right; reflexivity. - simpl in |- *. + simpl. elim H; intros. apply Rle_trans with (y * x ^ n). do 2 rewrite <- (Rmult_comm (x ^ n)). @@ -446,7 +446,7 @@ Proof. intros. induction k as [| k Hreck]. right; reflexivity. - simpl in |- *. + simpl. apply Rle_trans with (x * 1). rewrite Rmult_1_r; assumption. apply Rmult_le_compat_l. @@ -461,33 +461,33 @@ Proof. replace n with (n - m + m)%nat. rewrite pow_add. rewrite Rmult_comm. - pattern (x ^ m) at 1 in |- *; rewrite <- Rmult_1_r. + pattern (x ^ m) at 1; rewrite <- Rmult_1_r. apply Rmult_le_compat_l. apply pow_le; left; apply Rlt_le_trans with 1; [ apply Rlt_0_1 | assumption ]. apply pow_R1_Rle; assumption. rewrite plus_comm. - symmetry in |- *; apply le_plus_minus; assumption. + symmetry ; apply le_plus_minus; assumption. Qed. Lemma pow1 : forall n:nat, 1 ^ n = 1. Proof. intro; induction n as [| n Hrecn]. reflexivity. - simpl in |- *; rewrite Hrecn; rewrite Rmult_1_r; reflexivity. + simpl; rewrite Hrecn; rewrite Rmult_1_r; reflexivity. Qed. Lemma pow_Rabs : forall (x:R) (n:nat), x ^ n <= Rabs x ^ n. Proof. intros; induction n as [| n Hrecn]. right; reflexivity. - simpl in |- *; case (Rcase_abs x); intro. + simpl; case (Rcase_abs x); intro. apply Rle_trans with (Rabs (x * x ^ n)). apply RRle_abs. rewrite Rabs_mult. apply Rmult_le_compat_l. apply Rabs_pos. - right; symmetry in |- *; apply RPow_abs. - pattern (Rabs x) at 1 in |- *; rewrite (Rabs_right x r); + right; symmetry ; apply RPow_abs. + pattern (Rabs x) at 1; rewrite (Rabs_right x r); apply Rmult_le_compat_l. apply Rge_le; exact r. apply Hrecn. @@ -500,7 +500,7 @@ Proof. apply pow_Rabs. induction n as [| n Hrecn]. right; reflexivity. - simpl in |- *; apply Rle_trans with (x * Rabs y ^ n). + simpl; apply Rle_trans with (x * Rabs y ^ n). do 2 rewrite <- (Rmult_comm (Rabs y ^ n)). apply Rmult_le_compat_l. apply pow_le; apply Rabs_pos. @@ -517,7 +517,7 @@ Qed. (*i Due to L.Thery i*) Ltac case_eq name := - generalize (refl_equal name); pattern name at -1 in |- *; case name. + generalize (refl_equal name); pattern name at -1; case name. Definition powerRZ (x:R) (n:Z) := match n with @@ -531,7 +531,7 @@ Infix Local "^Z" := powerRZ (at level 30, right associativity) : R_scope. Lemma Zpower_NR0 : forall (x:Z) (n:nat), (0 <= x)%Z -> (0 <= Zpower_nat x n)%Z. Proof. - induction n; unfold Zpower_nat in |- *; simpl in |- *; auto with zarith. + induction n; unfold Zpower_nat; simpl; auto with zarith. Qed. Lemma powerRZ_O : forall x:R, x ^Z 0 = 1. @@ -541,60 +541,45 @@ Qed. Lemma powerRZ_1 : forall x:R, x ^Z Zsucc 0 = x. Proof. - simpl in |- *; auto with real. + simpl; auto with real. Qed. Lemma powerRZ_NOR : forall (x:R) (z:Z), x <> 0 -> x ^Z z <> 0. Proof. - destruct z; simpl in |- *; auto with real. + destruct z; simpl; auto with real. Qed. Lemma powerRZ_add : forall (x:R) (n m:Z), x <> 0 -> x ^Z (n + m) = x ^Z n * x ^Z m. Proof. - intro x; destruct n as [| n1| n1]; destruct m as [| m1| m1]; simpl in |- *; + intro x; destruct n as [| n1| n1]; destruct m as [| m1| m1]; simpl; auto with real. (* POS/POS *) - rewrite nat_of_P_plus_morphism; auto with real. + rewrite Pplus_plus; auto with real. (* POS/NEG *) - case_eq ((n1 ?= m1)%positive Datatypes.Eq); simpl in |- *; auto with real. - intros H' H'0; rewrite Pcompare_Eq_eq with (1 := H'); auto with real. - intros H' H'0; rewrite (nat_of_P_minus_morphism m1 n1); auto with real. - rewrite (pow_RN_plus x (nat_of_P m1 - nat_of_P n1) (nat_of_P n1)); - auto with real. - rewrite plus_comm; rewrite le_plus_minus_r; auto with real. - rewrite Rinv_mult_distr; auto with real. - rewrite Rinv_involutive; auto with real. - apply lt_le_weak. - apply nat_of_P_lt_Lt_compare_morphism; auto. - apply ZC2; auto. - intros H' H'0; rewrite (nat_of_P_minus_morphism n1 m1); auto with real. - rewrite (pow_RN_plus x (nat_of_P n1 - nat_of_P m1) (nat_of_P m1)); - auto with real. - rewrite plus_comm; rewrite le_plus_minus_r; auto with real. - apply lt_le_weak. - change (nat_of_P n1 > nat_of_P m1)%nat in |- *. - apply nat_of_P_gt_Gt_compare_morphism; auto. + case Pcompare_spec; intros; simpl. + subst; auto with real. + rewrite Pminus_minus by trivial. + rewrite (pow_RN_plus x _ (nat_of_P n1)) by auto with real. + rewrite plus_comm, le_plus_minus_r by (now apply lt_le_weak, Plt_lt). + rewrite Rinv_mult_distr, Rinv_involutive; auto with real. + rewrite Pminus_minus by trivial. + rewrite (pow_RN_plus x _ (nat_of_P m1)) by auto with real. + rewrite plus_comm, le_plus_minus_r by (now apply lt_le_weak, Plt_lt). + reflexivity. (* NEG/POS *) - case_eq ((n1 ?= m1)%positive Datatypes.Eq); simpl in |- *; auto with real. - intros H' H'0; rewrite Pcompare_Eq_eq with (1 := H'); auto with real. - intros H' H'0; rewrite (nat_of_P_minus_morphism m1 n1); auto with real. - rewrite (pow_RN_plus x (nat_of_P m1 - nat_of_P n1) (nat_of_P n1)); - auto with real. - rewrite plus_comm; rewrite le_plus_minus_r; auto with real. - apply lt_le_weak. - apply nat_of_P_lt_Lt_compare_morphism; auto. - apply ZC2; auto. - intros H' H'0; rewrite (nat_of_P_minus_morphism n1 m1); auto with real. - rewrite (pow_RN_plus x (nat_of_P n1 - nat_of_P m1) (nat_of_P m1)); - auto with real. - rewrite plus_comm; rewrite le_plus_minus_r; auto with real. - rewrite Rinv_mult_distr; auto with real. - apply lt_le_weak. - change (nat_of_P n1 > nat_of_P m1)%nat in |- *. - apply nat_of_P_gt_Gt_compare_morphism; auto. + case Pcompare_spec; intros; simpl. + subst; auto with real. + rewrite Pminus_minus by trivial. + rewrite (pow_RN_plus x _ (nat_of_P n1)) by auto with real. + rewrite plus_comm, le_plus_minus_r by (now apply lt_le_weak, Plt_lt). + auto with real. + rewrite Pminus_minus by trivial. + rewrite (pow_RN_plus x _ (nat_of_P m1)) by auto with real. + rewrite plus_comm, le_plus_minus_r by (now apply lt_le_weak, Plt_lt). + rewrite Rinv_mult_distr, Rinv_involutive; auto with real. (* NEG/NEG *) - rewrite nat_of_P_plus_morphism; auto with real. + rewrite Pplus_plus; auto with real. intros H'; rewrite pow_add; auto with real. apply Rinv_mult_distr; auto. apply pow_nonzero; auto. @@ -605,16 +590,16 @@ Hint Resolve powerRZ_O powerRZ_1 powerRZ_NOR powerRZ_add: real. Lemma Zpower_nat_powerRZ : forall n m:nat, IZR (Zpower_nat (Z_of_nat n) m) = INR n ^Z Z_of_nat m. Proof. - intros n m; elim m; simpl in |- *; auto with real. - intros m1 H'; rewrite nat_of_P_o_P_of_succ_nat_eq_succ; simpl in |- *. + intros n m; elim m; simpl; auto with real. + intros m1 H'; rewrite nat_of_P_of_succ_nat; simpl. replace (Zpower_nat (Z_of_nat n) (S m1)) with (Z_of_nat n * Zpower_nat (Z_of_nat n) m1)%Z. rewrite mult_IZR; auto with real. - repeat rewrite <- INR_IZR_INZ; simpl in |- *. - rewrite H'; simpl in |- *. - case m1; simpl in |- *; auto with real. - intros m2; rewrite nat_of_P_o_P_of_succ_nat_eq_succ; auto. - unfold Zpower_nat in |- *; auto. + repeat rewrite <- INR_IZR_INZ; simpl. + rewrite H'; simpl. + case m1; simpl; auto with real. + intros m2; rewrite nat_of_P_of_succ_nat; auto. + unfold Zpower_nat; auto. Qed. Lemma Zpower_pos_powerRZ : @@ -631,7 +616,7 @@ Qed. Lemma powerRZ_lt : forall (x:R) (z:Z), 0 < x -> 0 < x ^Z z. Proof. - intros x z; case z; simpl in |- *; auto with real. + intros x z; case z; simpl; auto with real. Qed. Hint Resolve powerRZ_lt: real. @@ -644,19 +629,19 @@ Hint Resolve powerRZ_le: real. Lemma Zpower_nat_powerRZ_absolu : forall n m:Z, (0 <= m)%Z -> IZR (Zpower_nat n (Zabs_nat m)) = IZR n ^Z m. Proof. - intros n m; case m; simpl in |- *; auto with zarith. - intros p H'; elim (nat_of_P p); simpl in |- *; auto with zarith. - intros n0 H'0; rewrite <- H'0; simpl in |- *; auto with zarith. + intros n m; case m; simpl; auto with zarith. + intros p H'; elim (nat_of_P p); simpl; auto with zarith. + intros n0 H'0; rewrite <- H'0; simpl; auto with zarith. rewrite <- mult_IZR; auto. intros p H'; absurd (0 <= Zneg p)%Z; auto with zarith. Qed. Lemma powerRZ_R1 : forall n:Z, 1 ^Z n = 1. Proof. - intros n; case n; simpl in |- *; auto. - intros p; elim (nat_of_P p); simpl in |- *; auto; intros n0 H'; rewrite H'; + intros n; case n; simpl; auto. + intros p; elim (nat_of_P p); simpl; auto; intros n0 H'; rewrite H'; ring. - intros p; elim (nat_of_P p); simpl in |- *. + intros p; elim (nat_of_P p); simpl. exact Rinv_1. intros n1 H'; rewrite Rinv_mult_distr; try rewrite Rinv_1; try rewrite H'; auto with real. @@ -708,10 +693,10 @@ Lemma GP_finite : forall (x:R) (n:nat), sum_f_R0 (fun n:nat => x ^ n) n * (x - 1) = x ^ (n + 1) - 1. Proof. - intros; induction n as [| n Hrecn]; simpl in |- *. + intros; induction n as [| n Hrecn]; simpl. ring. rewrite Rmult_plus_distr_r; rewrite Hrecn; cut ((n + 1)%nat = S n). - intro H; rewrite H; simpl in |- *; ring. + intro H; rewrite H; simpl; ring. omega. Qed. @@ -719,8 +704,8 @@ Lemma sum_f_R0_triangle : forall (x:nat -> R) (n:nat), Rabs (sum_f_R0 x n) <= sum_f_R0 (fun i:nat => Rabs (x i)) n. Proof. - intro; simple induction n; simpl in |- *. - unfold Rle in |- *; right; reflexivity. + intro; simple induction n; simpl. + unfold Rle; right; reflexivity. intro m; intro; apply (Rle_trans (Rabs (sum_f_R0 x m + x (S m))) @@ -742,16 +727,16 @@ Definition R_dist (x y:R) : R := Rabs (x - y). (*********) Lemma R_dist_pos : forall x y:R, R_dist x y >= 0. Proof. - intros; unfold R_dist in |- *; unfold Rabs in |- *; case (Rcase_abs (x - y)); + intros; unfold R_dist; unfold Rabs; case (Rcase_abs (x - y)); intro l. - unfold Rge in |- *; left; apply (Ropp_gt_lt_0_contravar (x - y) l). + unfold Rge; left; apply (Ropp_gt_lt_0_contravar (x - y) l). trivial. Qed. (*********) Lemma R_dist_sym : forall x y:R, R_dist x y = R_dist y x. Proof. - unfold R_dist in |- *; intros; split_Rabs; try ring. + unfold R_dist; intros; split_Rabs; try ring. generalize (Ropp_gt_lt_0_contravar (y - x) r); intro; rewrite (Ropp_minus_distr y x) in H; generalize (Rlt_asym (x - y) 0 r0); intro; unfold Rgt in H; exfalso; auto. @@ -763,7 +748,7 @@ Qed. (*********) Lemma R_dist_refl : forall x y:R, R_dist x y = 0 <-> x = y. Proof. - unfold R_dist in |- *; intros; split_Rabs; split; intros. + unfold R_dist; intros; split_Rabs; split; intros. rewrite (Ropp_minus_distr x y) in H; apply sym_eq; apply (Rminus_diag_uniq y x H). rewrite (Ropp_minus_distr x y); generalize (sym_eq H); intro; @@ -774,13 +759,13 @@ Qed. Lemma R_dist_eq : forall x:R, R_dist x x = 0. Proof. - unfold R_dist in |- *; intros; split_Rabs; intros; ring. + unfold R_dist; intros; split_Rabs; intros; ring. Qed. (***********) Lemma R_dist_tri : forall x y z:R, R_dist x y <= R_dist x z + R_dist z y. Proof. - intros; unfold R_dist in |- *; replace (x - y) with (x - z + (z - y)); + intros; unfold R_dist; replace (x - y) with (x - z + (z - y)); [ apply (Rabs_triang (x - z) (z - y)) | ring ]. Qed. @@ -788,7 +773,7 @@ Qed. Lemma R_dist_plus : forall a b c d:R, R_dist (a + c) (b + d) <= R_dist a b + R_dist c d. Proof. - intros; unfold R_dist in |- *; + intros; unfold R_dist; replace (a + c - (b + d)) with (a - b + (c - d)). exact (Rabs_triang (a - b) (c - d)). ring. diff --git a/theories/ZArith/BinInt.v b/theories/ZArith/BinInt.v index c39edf30f..b99a28d5f 100644 --- a/theories/ZArith/BinInt.v +++ b/theories/ZArith/BinInt.v @@ -11,11 +11,8 @@ (** Binary Integers (Pierre Crégut, CNET, Lannion, France) *) (***********************************************************) -Require Export BinPos. -Require Export Pnat. -Require Import BinNat. -Require Import Plus. -Require Import Mult. +Require Export BinPos Pnat. +Require Import BinNat Plus Mult. Unset Boxed Definitions. @@ -209,10 +206,10 @@ Proof. intros P H0 Hs Hp z; destruct z. assumption. apply Pind with (P := fun p => P (Zpos p)). - change (P (Zsucc' Z0)) in |- *; apply Hs; apply H0. + change (P (Zsucc' Z0)); apply Hs; apply H0. intro n; exact (Hs (Zpos n)). apply Pind with (P := fun p => P (Zneg p)). - change (P (Zpred' Z0)) in |- *; apply Hp; apply H0. + change (P (Zpred' Z0)); apply Hp; apply H0. intro n; exact (Hp (Zneg n)). Qed. @@ -245,7 +242,7 @@ Qed. Theorem Zopp_inj : forall n m:Z, - n = - m -> n = m. Proof. - intros x y; case x; case y; simpl in |- *; intros; + intros x y; case x; case y; simpl; intros; [ trivial | discriminate H | discriminate H @@ -286,11 +283,10 @@ Qed. Theorem Zplus_comm : forall n m:Z, n + m = m + n. Proof. - intro x; induction x as [| p| p]; intro y; destruct y as [| q| q]; - simpl in |- *; try reflexivity. + induction n as [|p|p]; intros [|q|q]; simpl; try reflexivity. rewrite Pplus_comm; reflexivity. - rewrite ZC4; destruct ((q ?= p)%positive Eq); reflexivity. - rewrite ZC4; destruct ((q ?= p)%positive Eq); reflexivity. + rewrite ZC4. now case Pcompare_spec. + rewrite ZC4; now case Pcompare_spec. rewrite Pplus_comm; reflexivity. Qed. @@ -299,7 +295,7 @@ Qed. Theorem Zopp_plus_distr : forall n m:Z, - (n + m) = - n + - m. Proof. intro x; destruct x as [| p| p]; intro y; destruct y as [| q| q]; - simpl in |- *; reflexivity || destruct ((p ?= q)%positive Eq); + simpl; reflexivity || destruct ((p ?= q)%positive Eq); reflexivity. Qed. @@ -312,7 +308,7 @@ Qed. Theorem Zplus_opp_r : forall n:Z, n + - n = Z0. Proof. - intro x; destruct x as [| p| p]; simpl in |- *; + intro x; destruct x as [| p| p]; simpl; [ reflexivity | rewrite (Pcompare_refl p); reflexivity | rewrite (Pcompare_refl p); reflexivity ]. @@ -330,159 +326,54 @@ Hint Local Resolve Zplus_0_l Zplus_0_r. Lemma weak_assoc : forall (p q:positive) (n:Z), Zpos p + (Zpos q + n) = Zpos p + Zpos q + n. Proof. - intros x y z'; case z'; - [ auto with arith - | intros z; simpl in |- *; rewrite Pplus_assoc; auto with arith - | intros z; simpl in |- *; ElimPcompare y z; intros E0; rewrite E0; - ElimPcompare (x + y)%positive z; intros E1; rewrite E1; - [ absurd ((x + y ?= z)%positive Eq = Eq); - [ (* Case 1 *) - rewrite nat_of_P_gt_Gt_compare_complement_morphism; - [ discriminate - | rewrite nat_of_P_plus_morphism; rewrite (Pcompare_Eq_eq y z E0); - elim (ZL4 x); intros k E2; rewrite E2; - simpl in |- *; unfold gt, lt in |- *; - apply le_n_S; apply le_plus_r ] - | assumption ] - | absurd ((x + y ?= z)%positive Eq = Lt); - [ (* Case 2 *) - rewrite nat_of_P_gt_Gt_compare_complement_morphism; - [ discriminate - | rewrite nat_of_P_plus_morphism; rewrite (Pcompare_Eq_eq y z E0); - elim (ZL4 x); intros k E2; rewrite E2; - simpl in |- *; unfold gt, lt in |- *; - apply le_n_S; apply le_plus_r ] - | assumption ] - | rewrite (Pcompare_Eq_eq y z E0); - (* Case 3 *) - elim (Pminus_mask_Gt (x + z) z); - [ intros t H; elim H; intros H1 H2; elim H2; intros H3 H4; - unfold Pminus in |- *; rewrite H1; cut (x = t); - [ intros E; rewrite E; auto with arith - | apply Pplus_reg_r with (r := z); rewrite <- H3; - rewrite Pplus_comm; trivial with arith ] - | pattern z at 1 in |- *; rewrite <- (Pcompare_Eq_eq y z E0); - assumption ] - | elim (Pminus_mask_Gt z y); - [ (* Case 4 *) - intros k H; elim H; intros H1 H2; elim H2; intros H3 H4; - unfold Pminus at 1 in |- *; rewrite H1; cut (x = k); - [ intros E; rewrite E; rewrite (Pcompare_refl k); - trivial with arith - | apply Pplus_reg_r with (r := y); rewrite (Pplus_comm k y); - rewrite H3; apply Pcompare_Eq_eq; assumption ] - | apply ZC2; assumption ] - | elim (Pminus_mask_Gt z y); - [ (* Case 5 *) - intros k H; elim H; intros H1 H2; elim H2; intros H3 H4; - unfold Pminus at 1 3 5 in |- *; rewrite H1; - cut ((x ?= k)%positive Eq = Lt); - [ intros E2; rewrite E2; elim (Pminus_mask_Gt k x); - [ intros i H5; elim H5; intros H6 H7; elim H7; intros H8 H9; - elim (Pminus_mask_Gt z (x + y)); - [ intros j H10; elim H10; intros H11 H12; elim H12; - intros H13 H14; unfold Pminus in |- *; - rewrite H6; rewrite H11; cut (i = j); - [ intros E; rewrite E; auto with arith - | apply (Pplus_reg_l (x + y)); rewrite H13; - rewrite (Pplus_comm x y); rewrite <- Pplus_assoc; - rewrite H8; assumption ] - | apply ZC2; assumption ] - | apply ZC2; assumption ] - | apply nat_of_P_lt_Lt_compare_complement_morphism; - apply plus_lt_reg_l with (p := nat_of_P y); - do 2 rewrite <- nat_of_P_plus_morphism; - apply nat_of_P_lt_Lt_compare_morphism; - rewrite H3; rewrite Pplus_comm; assumption ] - | apply ZC2; assumption ] - | elim (Pminus_mask_Gt z y); - [ (* Case 6 *) - intros k H; elim H; intros H1 H2; elim H2; intros H3 H4; - elim (Pminus_mask_Gt (x + y) z); - [ intros i H5; elim H5; intros H6 H7; elim H7; intros H8 H9; - unfold Pminus in |- *; rewrite H1; rewrite H6; - cut ((x ?= k)%positive Eq = Gt); - [ intros H10; elim (Pminus_mask_Gt 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 (Pplus_reg_l (z + k)); rewrite <- (Pplus_assoc z k j); - rewrite H14; rewrite (Pplus_comm z k); - rewrite <- Pplus_assoc; rewrite H8; - rewrite (Pplus_comm x y); rewrite Pplus_assoc; - rewrite (Pplus_comm k y); rewrite H3; - trivial with arith ] - | apply nat_of_P_gt_Gt_compare_complement_morphism; - unfold lt, gt in |- *; - apply plus_lt_reg_l with (p := nat_of_P y); - do 2 rewrite <- nat_of_P_plus_morphism; - apply nat_of_P_lt_Lt_compare_morphism; - rewrite H3; rewrite Pplus_comm; apply ZC1; - assumption ] - | assumption ] - | apply ZC2; assumption ] - | absurd ((x + y ?= z)%positive Eq = Eq); - [ (* Case 7 *) - rewrite nat_of_P_gt_Gt_compare_complement_morphism; - [ discriminate - | rewrite nat_of_P_plus_morphism; unfold gt in |- *; - apply lt_le_trans with (m := nat_of_P y); - [ apply nat_of_P_lt_Lt_compare_morphism; apply ZC1; assumption - | apply le_plus_r ] ] - | assumption ] - | absurd ((x + y ?= z)%positive Eq = Lt); - [ (* Case 8 *) - rewrite nat_of_P_gt_Gt_compare_complement_morphism; - [ discriminate - | unfold gt in |- *; apply lt_le_trans with (m := nat_of_P y); - [ exact (nat_of_P_gt_Gt_compare_morphism y z E0) - | rewrite nat_of_P_plus_morphism; apply le_plus_r ] ] - | assumption ] - | elim Pminus_mask_Gt with (1 := E0); intros k H1; - (* Case 9 *) - elim Pminus_mask_Gt 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 Pminus in |- *; rewrite H3; rewrite H7; - cut ((x + k)%positive = i); - [ intros E; rewrite E; auto with arith - | apply (Pplus_reg_l z); rewrite (Pplus_comm x k); rewrite Pplus_assoc; - rewrite H5; rewrite H9; rewrite Pplus_comm; - trivial with arith ] ] ]. -Qed. - -Hint Local Resolve weak_assoc. + intros x y [|z|z]; simpl; trivial. + now rewrite Pplus_assoc. + case (Pcompare_spec y z); intros E0. + (* y = z *) + subst. + assert (H := Plt_plus_r z x). rewrite Pplus_comm in H. apply ZC2 in H. + now rewrite H, Pplus_minus_eq. + (* y < z *) + assert (Hz : (z = (z-y)+y)%positive). + rewrite Pplus_comm, Pplus_minus_lt; trivial. + pattern z at 4. rewrite Hz, Pplus_compare_mono_r. + case Pcompare_spec; intros E1; trivial; f_equal. + symmetry. rewrite Pplus_comm. apply Pminus_plus_distr. + rewrite Hz, Pplus_comm. now apply Pplus_lt_mono_r. + apply Pminus_minus_distr; trivial. + (* z < y *) + assert (LT : (z < x + y)%positive). + rewrite Pplus_comm. apply Plt_trans with y; trivial using Plt_plus_r. + apply ZC2 in LT. rewrite LT. f_equal. + now apply Pplus_minus_assoc. +Qed. Theorem Zplus_assoc : forall n m p:Z, n + (m + p) = n + m + p. Proof. - intros x y z; case x; case y; case z; auto with arith; intros; - [ rewrite (Zplus_comm (Zneg p0)); rewrite weak_assoc; - rewrite (Zplus_comm (Zpos p1 + Zneg p0)); rewrite weak_assoc; - rewrite (Zplus_comm (Zpos p1)); trivial with arith - | apply Zopp_inj; do 4 rewrite Zopp_plus_distr; do 2 rewrite Zopp_neg; - rewrite Zplus_comm; rewrite <- weak_assoc; - rewrite (Zplus_comm (- Zpos p1)); - rewrite (Zplus_comm (Zpos p0 + - Zpos p1)); rewrite (weak_assoc p); - rewrite weak_assoc; rewrite (Zplus_comm (Zpos p0)); - trivial with arith - | rewrite Zplus_comm; rewrite (Zplus_comm (Zpos p0) (Zpos p)); - rewrite <- weak_assoc; rewrite Zplus_comm; rewrite (Zplus_comm (Zpos p0)); - trivial with arith - | apply Zopp_inj; do 4 rewrite Zopp_plus_distr; do 2 rewrite Zopp_neg; - rewrite (Zplus_comm (- Zpos p0)); rewrite weak_assoc; - rewrite (Zplus_comm (Zpos p1 + - Zpos p0)); rewrite weak_assoc; - rewrite (Zplus_comm (Zpos p)); trivial with arith - | apply Zopp_inj; do 4 rewrite Zopp_plus_distr; do 2 rewrite Zopp_neg; - apply weak_assoc - | apply Zopp_inj; do 4 rewrite Zopp_plus_distr; do 2 rewrite Zopp_neg; - apply weak_assoc ]. + intros [|x|x] [|y|y] [|z|z]; trivial. + apply weak_assoc. + apply weak_assoc. + now rewrite !Zplus_0_r. + rewrite 2 (Zplus_comm _ (Zpos z)), 2 weak_assoc. + f_equal; apply Zplus_comm. + apply Zopp_inj. rewrite !Zopp_plus_distr, !Zopp_neg. + rewrite 2 (Zplus_comm (-Zpos x)), 2 (Zplus_comm _ (Zpos z)). + now rewrite weak_assoc. + now rewrite !Zplus_0_r. + rewrite 2 (Zplus_comm (Zneg x)), 2 (Zplus_comm _ (Zpos z)). + now rewrite weak_assoc. + apply Zopp_inj. rewrite !Zopp_plus_distr, !Zopp_neg. + rewrite 2 (Zplus_comm _ (Zpos z)), 2 weak_assoc. + f_equal; apply Zplus_comm. + apply Zopp_inj. rewrite !Zopp_plus_distr, !Zopp_neg. + apply weak_assoc. + apply Zopp_inj. rewrite !Zopp_plus_distr, !Zopp_neg. + apply weak_assoc. Qed. - Lemma Zplus_assoc_reverse : forall n m p:Z, n + m + p = n + (m + p). Proof. - intros; symmetry in |- *; apply Zplus_assoc. + intros; symmetry ; apply Zplus_assoc. Qed. (** ** Associativity mixed with commutativity *) @@ -498,7 +389,7 @@ Qed. Theorem Zplus_reg_l : forall n m p:Z, n + m = n + p -> m = p. intros n m p H; cut (- n + (n + m) = - n + (n + p)); [ do 2 rewrite Zplus_assoc; rewrite (Zplus_comm (- n) n); - rewrite Zplus_opp_r; simpl in |- *; trivial with arith + rewrite Zplus_opp_r; simpl; trivial with arith | rewrite H; trivial with arith ]. Qed. @@ -506,21 +397,21 @@ Qed. Lemma Zplus_succ_l : forall n m:Z, Zsucc n + m = Zsucc (n + m). Proof. - intros x y; unfold Zsucc in |- *; rewrite (Zplus_comm (x + y)); + intros x y; unfold Zsucc; rewrite (Zplus_comm (x + y)); rewrite Zplus_assoc; rewrite (Zplus_comm (Zpos 1)); trivial with arith. Qed. Lemma Zplus_succ_r_reverse : forall n m:Z, Zsucc (n + m) = n + Zsucc m. Proof. - intros n m; unfold Zsucc in |- *; rewrite Zplus_assoc; trivial with arith. + intros n m; unfold Zsucc; rewrite Zplus_assoc; trivial with arith. Qed. Notation Zplus_succ_r := Zplus_succ_r_reverse (only parsing). Lemma Zplus_succ_comm : forall n m:Z, Zsucc n + m = n + Zsucc m. Proof. - unfold Zsucc in |- *; intros n m; rewrite <- Zplus_assoc; + unfold Zsucc; intros n m; rewrite <- Zplus_assoc; rewrite (Zplus_comm (Zpos 1)); trivial with arith. Qed. @@ -528,7 +419,7 @@ Qed. Lemma Zplus_0_r_reverse : forall n:Z, n = n + Z0. Proof. - symmetry in |- *; apply Zplus_0_r. + symmetry ; apply Zplus_0_r. Qed. Lemma Zplus_0_simpl_l : forall n m:Z, n + Z0 = m -> n = m. @@ -561,7 +452,7 @@ Qed. Theorem Zsucc_discr : forall n:Z, n <> Zsucc n. Proof. intros n; cut (Z0 <> Zpos 1); - [ unfold not in |- *; intros H1 H2; apply H1; apply (Zplus_reg_l n); + [ unfold not; intros H1 H2; apply H1; apply (Zplus_reg_l n); rewrite Zplus_0_r; exact H2 | discriminate ]. Qed. @@ -569,7 +460,7 @@ Qed. Theorem Zpos_succ_morphism : forall p:positive, Zpos (Psucc p) = Zsucc (Zpos p). Proof. - intro; rewrite Pplus_one_succ_r; unfold Zsucc in |- *; simpl in |- *; + intro; rewrite Pplus_one_succ_r; unfold Zsucc; simpl; trivial with arith. Qed. @@ -577,7 +468,7 @@ Qed. Theorem Zsucc_pred : forall n:Z, n = Zsucc (Zpred n). Proof. - intros n; unfold Zsucc, Zpred in |- *; rewrite <- Zplus_assoc; simpl in |- *; + intros n; unfold Zsucc, Zpred; rewrite <- Zplus_assoc; simpl; rewrite Zplus_0_r; trivial with arith. Qed. @@ -585,14 +476,14 @@ Hint Immediate Zsucc_pred: zarith. Theorem Zpred_succ : forall n:Z, n = Zpred (Zsucc n). Proof. - intros m; unfold Zpred, Zsucc in |- *; rewrite <- Zplus_assoc; simpl in |- *; + intros m; unfold Zpred, Zsucc; rewrite <- Zplus_assoc; simpl; rewrite Zplus_comm; auto with arith. Qed. Theorem Zsucc_inj : forall n m:Z, Zsucc n = Zsucc m -> n = m. Proof. intros n m H. - change (Zneg 1 + Zpos 1 + n = Zneg 1 + Zpos 1 + m) in |- *; + change (Zneg 1 + Zpos 1 + n = Zneg 1 + Zpos 1 + m); do 2 rewrite <- Zplus_assoc; do 2 rewrite (Zplus_comm (Zpos 1)); unfold Zsucc in H; rewrite H; trivial with arith. Qed. @@ -640,10 +531,10 @@ Qed. Theorem Zsucc'_discr : forall n:Z, n <> Zsucc' n. Proof. - intro x; destruct x; simpl in |- *. + intro x; destruct x; simpl. discriminate. injection; apply Psucc_discr. - destruct p; simpl in |- *. + destruct p; simpl. discriminate. intro H; symmetry in H; injection H; apply double_moins_un_xO_discr. discriminate. @@ -658,7 +549,7 @@ Qed. Lemma Zsucc_inj_contrapositive : forall n m:Z, n <> m -> Zsucc n <> Zsucc m. Proof. - unfold not in |- *; intros n m H1 H2; apply H1; apply Zsucc_inj; assumption. + unfold not; intros n m H1 H2; apply H1; apply Zsucc_inj; assumption. Qed. (**********************************************************************) @@ -668,23 +559,23 @@ Qed. Lemma Zminus_0_r : forall n:Z, n - Z0 = n. Proof. - intro; unfold Zminus in |- *; simpl in |- *; rewrite Zplus_0_r; + intro; unfold Zminus; simpl; rewrite Zplus_0_r; trivial with arith. Qed. Lemma Zminus_0_l_reverse : forall n:Z, n = n - Z0. Proof. - intro; symmetry in |- *; apply Zminus_0_r. + intro; symmetry ; apply Zminus_0_r. Qed. Lemma Zminus_diag : forall n:Z, n - n = Z0. Proof. - intro; unfold Zminus in |- *; rewrite Zplus_opp_r; trivial with arith. + intro; unfold Zminus; rewrite Zplus_opp_r; trivial with arith. Qed. Lemma Zminus_diag_reverse : forall n:Z, Z0 = n - n. Proof. - intro; symmetry in |- *; apply Zminus_diag. + intro; symmetry ; apply Zminus_diag. Qed. @@ -697,7 +588,7 @@ Qed. Lemma Zminus_succ_l : forall n m:Z, Zsucc (n - m) = Zsucc n - m. Proof. - intros n m; unfold Zminus, Zsucc in |- *; rewrite (Zplus_comm n (- m)); + intros n m; unfold Zminus, Zsucc; rewrite (Zplus_comm n (- m)); rewrite <- Zplus_assoc; apply Zplus_comm. Qed. @@ -708,7 +599,7 @@ Qed. Lemma Zplus_minus_eq : forall n m p:Z, n = m + p -> p = n - m. Proof. - intros n m p H; unfold Zminus in |- *; apply (Zplus_reg_l m); + intros n m p H; unfold Zminus; apply (Zplus_reg_l m); rewrite (Zplus_comm m (n + - m)); rewrite <- Zplus_assoc; rewrite Zplus_opp_l; rewrite Zplus_0_r; rewrite H; trivial with arith. @@ -716,32 +607,32 @@ Qed. Lemma Zminus_plus : forall n m:Z, n + m - n = m. Proof. - intros n m; unfold Zminus in |- *; rewrite (Zplus_comm n m); + intros n m; unfold Zminus; rewrite (Zplus_comm n m); rewrite <- Zplus_assoc; rewrite Zplus_opp_r; apply Zplus_0_r. Qed. Lemma Zplus_minus : forall n m:Z, n + (m - n) = m. Proof. - unfold Zminus in |- *; intros n m; rewrite Zplus_permute; rewrite Zplus_opp_r; + unfold Zminus; intros n m; rewrite Zplus_permute; rewrite Zplus_opp_r; apply Zplus_0_r. Qed. Lemma Zminus_plus_simpl_l : forall n m p:Z, p + n - (p + m) = n - m. Proof. - intros n m p; unfold Zminus in |- *; rewrite Zopp_plus_distr; + intros n m p; unfold Zminus; rewrite Zopp_plus_distr; rewrite Zplus_assoc; rewrite (Zplus_comm p); rewrite <- (Zplus_assoc n p); rewrite Zplus_opp_r; rewrite Zplus_0_r; trivial with arith. Qed. Lemma Zminus_plus_simpl_l_reverse : forall n m p:Z, n - m = p + n - (p + m). Proof. - intros; symmetry in |- *; apply Zminus_plus_simpl_l. + intros; symmetry ; apply Zminus_plus_simpl_l. Qed. Lemma Zminus_plus_simpl_r : forall n m p:Z, n + p - (m + p) = n - m. Proof. intros x y n. - unfold Zminus in |- *. + unfold Zminus. rewrite Zopp_plus_distr. rewrite (Zplus_comm (- y) (- n)). rewrite Zplus_assoc. @@ -765,7 +656,7 @@ Qed. Lemma Zeq_minus : forall n m:Z, n = m -> n - m = Z0. Proof. - intros x y H; rewrite H; symmetry in |- *; apply Zminus_diag_reverse. + intros x y H; rewrite H; symmetry ; apply Zminus_diag_reverse. Qed. Lemma Zminus_eq : forall n m:Z, n - m = Z0 -> n = m. @@ -792,7 +683,7 @@ Qed. Theorem Zmult_1_r : forall n:Z, n * Zpos 1 = n. Proof. - intro x; destruct x; simpl in |- *; try rewrite Pmult_1_r; reflexivity. + intro x; destruct x; simpl; try rewrite Pmult_1_r; reflexivity. Qed. (** ** Zero property of multiplication *) @@ -818,7 +709,7 @@ Qed. Theorem Zmult_comm : forall n m:Z, n * m = m * n. Proof. - intros x y; destruct x as [| p| p]; destruct y as [| q| q]; simpl in |- *; + intros x y; destruct x as [| p| p]; destruct y as [| q| q]; simpl; try rewrite (Pmult_comm p q); reflexivity. Qed. @@ -826,7 +717,7 @@ Qed. Theorem Zmult_assoc : forall n m p:Z, n * (m * p) = n * m * p. Proof. - intros x y z; destruct x; destruct y; destruct z; simpl in |- *; + intros x y z; destruct x; destruct y; destruct z; simpl; try rewrite Pmult_assoc; reflexivity. Qed. @@ -856,7 +747,7 @@ Qed. Theorem Zmult_integral : forall n m:Z, n * m = Z0 -> n = Z0 \/ m = Z0. Proof. - intros x y; destruct x; destruct y; auto; simpl in |- *; intro H; + intros x y; destruct x; destruct y; auto; simpl; intro H; discriminate H. Qed. @@ -898,7 +789,7 @@ Qed. Lemma Zopp_mult_distr_l_reverse : forall n m:Z, - n * m = - (n * m). Proof. - intros x y; symmetry in |- *; apply Zopp_mult_distr_l. + intros x y; symmetry ; apply Zopp_mult_distr_l. Qed. Theorem Zmult_opp_comm : forall n m:Z, - n * m = n * - m. @@ -922,34 +813,18 @@ Qed. Lemma weak_Zmult_plus_distr_r : forall (p:positive) (n m:Z), Zpos p * (n + m) = Zpos p * n + Zpos p * m. Proof. - intros x y' z'; case y'; case z'; auto with arith; intros y z; - (simpl in |- *; rewrite Pmult_plus_distr_l; trivial with arith) || - (simpl in |- *; ElimPcompare z y; intros E0; rewrite E0; - [ rewrite (Pcompare_Eq_eq z y E0); rewrite (Pcompare_refl (x * y)); - trivial with arith - | cut ((x * z ?= x * y)%positive Eq = Lt); - [ intros E; rewrite E; rewrite Pmult_minus_distr_l; - [ trivial with arith | apply ZC2; assumption ] - | apply nat_of_P_lt_Lt_compare_complement_morphism; - do 2 rewrite nat_of_P_mult_morphism; elim (ZL4 x); - intros h H1; rewrite H1; apply mult_S_lt_compat_l; - exact (nat_of_P_lt_Lt_compare_morphism z y E0) ] - | cut ((x * z ?= x * y)%positive Eq = Gt); - [ intros E; rewrite E; rewrite Pmult_minus_distr_l; auto with arith - | apply nat_of_P_gt_Gt_compare_complement_morphism; unfold gt in |- *; - do 2 rewrite nat_of_P_mult_morphism; elim (ZL4 x); - intros h H1; rewrite H1; apply mult_S_lt_compat_l; - exact (nat_of_P_gt_Gt_compare_morphism z y E0) ] ]). + intros x [ |y|y] [ |z|z]; simpl; trivial; f_equal; + apply Pmult_plus_distr_l || rewrite Pmult_compare_mono_l; + case_eq ((y ?= z) Eq)%positive; intros H; trivial; + rewrite Pmult_minus_distr_l; trivial; now apply ZC1. Qed. Theorem Zmult_plus_distr_r : forall n m p:Z, n * (m + p) = n * m + n * p. Proof. - intros x y z; case x; - [ auto with arith - | intros x'; apply weak_Zmult_plus_distr_r - | intros p; apply Zopp_inj; rewrite Zopp_plus_distr; - do 3 rewrite <- Zopp_mult_distr_l_reverse; rewrite Zopp_neg; - apply weak_Zmult_plus_distr_r ]. + intros [|x|x] y z. trivial. + apply weak_Zmult_plus_distr_r. + apply Zopp_inj; rewrite Zopp_plus_distr, !Zopp_mult_distr_l, !Zopp_neg. + apply weak_Zmult_plus_distr_r. Qed. Theorem Zmult_plus_distr_l : forall n m p:Z, (n + m) * p = n * p + m * p. @@ -962,7 +837,7 @@ Qed. Lemma Zmult_minus_distr_r : forall n m p:Z, (n - m) * p = n * p - m * p. Proof. - intros x y z; unfold Zminus in |- *. + intros x y z; unfold Zminus. rewrite <- Zopp_mult_distr_l_reverse. apply Zmult_plus_distr_l. Qed. @@ -1002,7 +877,7 @@ Qed. Lemma Zplus_diag_eq_mult_2 : forall n:Z, n + n = n * Zpos 2. Proof. - intros x; pattern x at 1 2 in |- *; rewrite <- (Zmult_1_r x); + intros x; pattern x at 1 2; rewrite <- (Zmult_1_r x); rewrite <- Zmult_plus_distr_r; reflexivity. Qed. @@ -1010,25 +885,25 @@ Qed. Lemma Zmult_succ_r : forall n m:Z, n * Zsucc m = n * m + n. Proof. - intros n m; unfold Zsucc in |- *; rewrite Zmult_plus_distr_r; + intros n m; unfold Zsucc; rewrite Zmult_plus_distr_r; rewrite (Zmult_comm n (Zpos 1)); rewrite Zmult_1_l; trivial with arith. Qed. Lemma Zmult_succ_r_reverse : forall n m:Z, n * m + n = n * Zsucc m. Proof. - intros; symmetry in |- *; apply Zmult_succ_r. + intros; symmetry ; apply Zmult_succ_r. Qed. Lemma Zmult_succ_l : forall n m:Z, Zsucc n * m = n * m + m. Proof. - intros n m; unfold Zsucc in |- *; rewrite Zmult_plus_distr_l; + intros n m; unfold Zsucc; rewrite Zmult_plus_distr_l; rewrite Zmult_1_l; trivial with arith. Qed. Lemma Zmult_succ_l_reverse : forall n m:Z, n * m + m = Zsucc n * m. Proof. - intros; symmetry in |- *; apply Zmult_succ_l. + intros; symmetry; apply Zmult_succ_l. Qed. @@ -1166,8 +1041,6 @@ Definition Z_of_nat (x:nat) := | S y => Zpos (P_of_succ_nat y) end. -Require Import BinNat. - Definition Zabs_N (z:Z) := match z with | Z0 => 0%N diff --git a/theories/ZArith/Wf_Z.v b/theories/ZArith/Wf_Z.v index 4a401a2fe..a6a25541d 100644 --- a/theories/ZArith/Wf_Z.v +++ b/theories/ZArith/Wf_Z.v @@ -37,8 +37,8 @@ Lemma Z_of_nat_complete : Proof. intro x; destruct x; intros; [ exists 0%nat; auto with arith - | specialize (ZL4 p); intros Hp; elim Hp; intros; exists (S x); intros; - simpl in |- *; specialize (nat_of_P_o_P_of_succ_nat_eq_succ x); + | specialize (nat_of_P_is_S p); intros Hp; elim Hp; intros; exists (S x); intros; + simpl in |- *; specialize (nat_of_P_of_succ_nat x); intro Hx0; rewrite <- H0 in Hx0; apply f_equal with (f := Zpos); apply nat_of_P_inj; auto with arith | absurd (0 <= Zneg p); @@ -47,7 +47,7 @@ Proof. | assumption ] ]. Qed. -Lemma ZL4_inf : forall y:positive, {h : nat | nat_of_P y = S h}. +Lemma nat_of_P_is_S_inf : forall y:positive, {h : nat | nat_of_P y = S h}. Proof. intro y; induction y as [p H| p H1| ]; [ elim H; intros x H1; exists (S x + S x)%nat; unfold nat_of_P in |- *; @@ -59,13 +59,15 @@ Proof. | exists 0%nat; auto with arith ]. Qed. +Notation ZL4_inf := nat_of_P_is_S_inf (only parsing). + Lemma Z_of_nat_complete_inf : forall x:Z, 0 <= x -> {n : nat | x = Z_of_nat n}. Proof. intro x; destruct x; intros; [ exists 0%nat; auto with arith - | specialize (ZL4_inf p); intros Hp; elim Hp; intros x0 H0; exists (S x0); - intros; simpl in |- *; specialize (nat_of_P_o_P_of_succ_nat_eq_succ x0); + | specialize (nat_of_P_is_S_inf p); intros Hp; elim Hp; intros x0 H0; exists (S x0); + intros; simpl in |- *; specialize (nat_of_P_of_succ_nat x0); intro Hx0; rewrite <- H0 in Hx0; apply f_equal with (f := Zpos); apply nat_of_P_inj; auto with arith | absurd (0 <= Zneg p); @@ -127,20 +129,18 @@ Section Efficient_Rec. Let R_wf : well_founded R. Proof. - set - (f := - fun z => + set (f z := match z with | Zpos p => nat_of_P p | Z0 => 0%nat | Zneg _ => 0%nat - end) in *. + end). apply well_founded_lt_compat with f. - unfold R, f in |- *; clear f R. - intros x y; case x; intros; elim H; clear H. - case y; intros; apply lt_O_nat_of_P || inversion H0. - case y; intros; apply nat_of_P_lt_Lt_compare_morphism || inversion H0; auto. - intros; elim H; auto. + unfold R, f; clear f R. + intros [|x|x] [|y|y] (H,H'); + try (now elim H); try (discriminate H'). + apply nat_of_P_pos. + now apply Plt_lt. Qed. Lemma natlike_rec2 : diff --git a/theories/ZArith/Zabs.v b/theories/ZArith/Zabs.v index 8543652c6..a90b5bd69 100644 --- a/theories/ZArith/Zabs.v +++ b/theories/ZArith/Zabs.v @@ -125,7 +125,7 @@ Qed. Theorem Zabs_nat_Z_of_nat: forall n, Zabs_nat (Z_of_nat n) = n. Proof. destruct n; simpl; auto. - apply nat_of_P_o_P_of_succ_nat_eq_succ. + apply nat_of_P_of_succ_nat. Qed. Lemma Zabs_nat_mult: forall n m:Z, Zabs_nat (n*m) = (Zabs_nat n * Zabs_nat m)%nat. diff --git a/theories/ZArith/Zcompare.v b/theories/ZArith/Zcompare.v index 5e7441462..10f07a864 100644 --- a/theories/ZArith/Zcompare.v +++ b/theories/ZArith/Zcompare.v @@ -13,32 +13,26 @@ (** Binary Integers (Pierre Crégut, CNET, Lannion, France) *) (**********************************************************************) -Require Export BinPos. -Require Export BinInt. -Require Import Lt. -Require Import Gt. -Require Import Plus. -Require Import Mult. +Require Export BinPos BinInt. +Require Import Lt Gt Plus Mult. -Open Local Scope Z_scope. +Local Open Scope Z_scope. (***************************) (** * Comparison on integers *) Lemma Zcompare_refl : forall n:Z, (n ?= n) = Eq. Proof. - intro x; destruct x as [| p| p]; simpl in |- *; - [ reflexivity | apply Pcompare_refl | rewrite Pcompare_refl; reflexivity ]. + destruct n as [|p|p]; simpl; trivial. + apply Pcompare_refl. + apply CompOpp_iff, Pcompare_refl. Qed. Lemma Zcompare_Eq_eq : forall n m:Z, (n ?= m) = Eq -> n = m. Proof. - intros x y; destruct x as [| x'| x']; destruct y as [| y'| y']; simpl in |- *; - intro H; reflexivity || (try discriminate H); - [ rewrite (Pcompare_Eq_eq x' y' H); reflexivity - | rewrite (Pcompare_Eq_eq x' y'); - [ reflexivity - | destruct ((x' ?= y')%positive Eq); reflexivity || discriminate ] ]. + intros [|x|x] [|y|y] H; simpl in *; try easy; f_equal. + now apply Pcompare_Eq_eq. + apply CompOpp_iff in H. now apply Pcompare_Eq_eq. Qed. Ltac destr_zcompare := @@ -52,45 +46,40 @@ Ltac destr_zcompare := Lemma Zcompare_Eq_iff_eq : forall n m:Z, (n ?= m) = Eq <-> n = m. Proof. - intros x y; split; intro E; - [ apply Zcompare_Eq_eq; assumption | rewrite E; apply Zcompare_refl ]. + intros x y; split; intro E; subst. + now apply Zcompare_Eq_eq. now apply Zcompare_refl. Qed. Lemma Zcompare_antisym : forall n m:Z, CompOpp (n ?= m) = (m ?= n). Proof. - intros x y; destruct x; destruct y; simpl in |- *; - reflexivity || discriminate H || rewrite Pcompare_antisym; - reflexivity. + intros [|x|x] [|y|y]; simpl; try easy; f_equal; apply Pcompare_antisym. Qed. -Lemma Zcompare_Gt_Lt_antisym : forall n m:Z, (n ?= m) = Gt <-> (m ?= n) = Lt. +Lemma Zcompare_spec : forall n m, CompSpec eq Zlt n m (n ?= m). Proof. - intros x y. - rewrite <- Zcompare_antisym. change Gt with (CompOpp Lt). - split. - auto using CompOpp_inj. - intros; f_equal; auto. + intros. + destruct (n?=m) as [ ]_eqn:H; constructor; trivial. + now apply Zcompare_Eq_eq. + red; now rewrite <- Zcompare_antisym, H. Qed. -Lemma Zcompare_spec : forall n m, CompSpec eq Zlt n m (n ?= m). +Lemma Zcompare_Gt_Lt_antisym : forall n m:Z, (n ?= m) = Gt <-> (m ?= n) = Lt. Proof. - intros. - destruct (n?=m) as [ ]_eqn:H; constructor; auto. - apply Zcompare_Eq_eq; auto. - red; rewrite <- Zcompare_antisym, H; auto. + intros x y. + rewrite <- Zcompare_antisym. change Gt with (CompOpp Lt). + split. + auto using CompOpp_inj. + intros; f_equal; auto. Qed. - (** * Transitivity of comparison *) Lemma Zcompare_Lt_trans : forall n m p:Z, (n ?= m) = Lt -> (m ?= p) = Lt -> (n ?= p) = Lt. Proof. - intros x y z; case x; case y; case z; simpl; - try discriminate; auto with arith. - intros; eapply Plt_trans; eauto. - intros p q r; rewrite 3 Pcompare_antisym; simpl. - intros; eapply Plt_trans; eauto. + intros n m p; destruct n,m,p; simpl; try discriminate; trivial. + eapply Plt_trans; eauto. + rewrite 3 Pcompare_antisym; simpl. intros; eapply Plt_trans; eauto. Qed. Lemma Zcompare_Gt_trans : @@ -107,281 +96,105 @@ Qed. Lemma Zcompare_opp : forall n m:Z, (n ?= m) = (- m ?= - n). Proof. - intros x y; case x; case y; simpl in |- *; auto with arith; intros; - rewrite <- ZC4; trivial with arith. + destruct n, m; simpl; trivial; intros; now rewrite <- ZC4. Qed. -Hint Local Resolve Pcompare_refl. - (** * Comparison first-order specification *) Lemma Zcompare_Gt_spec : - forall n m:Z, (n ?= m) = Gt -> exists h : positive, n + - m = Zpos h. -Proof. - intros x y; case x; case y; - [ simpl in |- *; intros H; discriminate H - | simpl in |- *; intros p H; discriminate H - | intros p H; exists p; simpl in |- *; auto with arith - | intros p H; exists p; simpl in |- *; auto with arith - | intros q p H; exists (p - q)%positive; unfold Zplus, Zopp in |- *; - unfold Zcompare in H; rewrite H; trivial with arith - | intros q p H; exists (p + q)%positive; simpl in |- *; trivial with arith - | simpl in |- *; intros p H; discriminate H - | simpl in |- *; intros q p H; discriminate H - | unfold Zcompare in |- *; intros q p; rewrite <- ZC4; intros H; - exists (q - p)%positive; simpl in |- *; rewrite (ZC1 q p H); - trivial with arith ]. + forall n m:Z, (n ?= m) = Gt -> exists h, n + - m = Zpos h. +Proof. + intros [|p|p] [|q|q]; simpl; try discriminate. + now exists q. + now exists p. + intros GT. exists (p-q)%positive. now rewrite GT. + now exists (p+q)%positive. + intros LT. apply CompOpp_iff in LT. simpl in LT. + exists (q-p)%positive. now rewrite LT. Qed. (** * Comparison and addition *) -Lemma weaken_Zcompare_Zplus_compatible : - (forall (n m:Z) (p:positive), (Zpos p + n ?= Zpos p + m) = (n ?= m)) -> - forall n m p:Z, (p + n ?= p + m) = (n ?= m). -Proof. - intros H x y z; destruct z; - [ reflexivity - | apply H - | rewrite (Zcompare_opp x y); rewrite Zcompare_opp; - do 2 rewrite Zopp_plus_distr; rewrite Zopp_neg; - apply H ]. -Qed. - -Hint Local Resolve ZC4. +Local Hint Resolve Pcompare_refl. -Lemma weak_Zcompare_Zplus_compatible : +Lemma weak_Zcompare_plus_compat : forall (n m:Z) (p:positive), (Zpos p + n ?= Zpos p + m) = (n ?= m). Proof. - intros x y z; case x; case y; simpl in |- *; auto with arith; - [ intros p; apply nat_of_P_lt_Lt_compare_complement_morphism; apply ZL17 - | intros p; ElimPcompare z p; intros E; rewrite E; auto with arith; - apply nat_of_P_gt_Gt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ unfold gt in |- *; apply ZL16 | assumption ] - | intros p; ElimPcompare z p; intros E; auto with arith; - apply nat_of_P_gt_Gt_compare_complement_morphism; - unfold gt in |- *; apply ZL17 - | intros p q; ElimPcompare q p; intros E; rewrite E; - [ rewrite (Pcompare_Eq_eq q p E); apply Pcompare_refl - | apply nat_of_P_lt_Lt_compare_complement_morphism; - do 2 rewrite nat_of_P_plus_morphism; apply plus_lt_compat_l; - apply nat_of_P_lt_Lt_compare_morphism with (1 := E) - | apply nat_of_P_gt_Gt_compare_complement_morphism; unfold gt in |- *; - do 2 rewrite nat_of_P_plus_morphism; apply plus_lt_compat_l; - exact (nat_of_P_gt_Gt_compare_morphism q p E) ] - | intros p q; ElimPcompare z p; intros E; rewrite E; auto with arith; - apply nat_of_P_gt_Gt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ unfold gt in |- *; apply lt_trans with (m := nat_of_P z); - [ apply ZL16 | apply ZL17 ] - | assumption ] - | intros p; ElimPcompare z p; intros E; rewrite E; auto with arith; - simpl in |- *; apply nat_of_P_lt_Lt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; [ apply ZL16 | assumption ] - | intros p q; ElimPcompare z q; intros E; rewrite E; auto with arith; - simpl in |- *; apply nat_of_P_lt_Lt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ apply lt_trans with (m := nat_of_P 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 ((q ?= p)%positive Eq = Lt); - [ rewrite <- (Pcompare_Eq_eq z q E0); - rewrite <- (Pcompare_Eq_eq z p E1); rewrite (Pcompare_refl z); - discriminate - | assumption ] - | absurd ((q ?= p)%positive Eq = Gt); - [ rewrite <- (Pcompare_Eq_eq z q E0); - rewrite <- (Pcompare_Eq_eq z p E1); rewrite (Pcompare_refl z); - discriminate - | assumption ] - | absurd ((z ?= p)%positive Eq = Lt); - [ rewrite (Pcompare_Eq_eq z q E0); rewrite <- (Pcompare_Eq_eq q p E2); - rewrite (Pcompare_refl q); discriminate - | assumption ] - | absurd ((z ?= p)%positive Eq = Lt); - [ rewrite (Pcompare_Eq_eq z q E0); rewrite E2; discriminate - | assumption ] - | absurd ((z ?= p)%positive Eq = Gt); - [ rewrite (Pcompare_Eq_eq z q E0); rewrite <- (Pcompare_Eq_eq q p E2); - rewrite (Pcompare_refl q); discriminate - | assumption ] - | absurd ((z ?= p)%positive Eq = Gt); - [ rewrite (Pcompare_Eq_eq z q E0); rewrite E2; discriminate - | assumption ] - | absurd ((z ?= q)%positive Eq = Lt); - [ rewrite (Pcompare_Eq_eq z p E1); rewrite (Pcompare_Eq_eq q p E2); - rewrite (Pcompare_refl p); discriminate - | assumption ] - | absurd ((p ?= q)%positive Eq = Gt); - [ rewrite <- (Pcompare_Eq_eq z p E1); rewrite E0; discriminate - | apply ZC2; assumption ] - | simpl in |- *; rewrite (Pcompare_Eq_eq q p E2); - rewrite (Pcompare_refl (p - z)); auto with arith - | simpl in |- *; rewrite <- ZC4; - apply nat_of_P_gt_Gt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ unfold gt in |- *; apply plus_lt_reg_l with (p := nat_of_P z); - rewrite le_plus_minus_r; - [ rewrite le_plus_minus_r; - [ apply nat_of_P_lt_Lt_compare_morphism; assumption - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - assumption ] - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - assumption ] - | apply ZC2; assumption ] - | apply ZC2; assumption ] - | simpl in |- *; rewrite <- ZC4; - apply nat_of_P_lt_Lt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ apply plus_lt_reg_l with (p := nat_of_P z); - rewrite le_plus_minus_r; - [ rewrite le_plus_minus_r; - [ apply nat_of_P_lt_Lt_compare_morphism; apply ZC1; - assumption - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - assumption ] - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - assumption ] - | apply ZC2; assumption ] - | apply ZC2; assumption ] - | absurd ((z ?= q)%positive Eq = Lt); - [ rewrite (Pcompare_Eq_eq q p E2); rewrite E1; discriminate - | assumption ] - | absurd ((q ?= p)%positive Eq = Lt); - [ cut ((q ?= p)%positive Eq = Gt); - [ intros E; rewrite E; discriminate - | apply nat_of_P_gt_Gt_compare_complement_morphism; - unfold gt in |- *; apply lt_trans with (m := nat_of_P z); - [ apply nat_of_P_lt_Lt_compare_morphism; apply ZC1; assumption - | apply nat_of_P_lt_Lt_compare_morphism; assumption ] ] - | assumption ] - | absurd ((z ?= q)%positive Eq = Gt); - [ rewrite (Pcompare_Eq_eq z p E1); rewrite (Pcompare_Eq_eq q p E2); - rewrite (Pcompare_refl p); discriminate - | assumption ] - | absurd ((z ?= q)%positive Eq = Gt); - [ rewrite (Pcompare_Eq_eq z p E1); rewrite ZC1; - [ discriminate | assumption ] - | assumption ] - | absurd ((z ?= q)%positive Eq = Gt); - [ rewrite (Pcompare_Eq_eq q p E2); rewrite E1; discriminate - | assumption ] - | absurd ((q ?= p)%positive Eq = Gt); - [ rewrite ZC1; - [ discriminate - | apply nat_of_P_gt_Gt_compare_complement_morphism; - unfold gt in |- *; apply lt_trans with (m := nat_of_P z); - [ apply nat_of_P_lt_Lt_compare_morphism; apply ZC1; assumption - | apply nat_of_P_lt_Lt_compare_morphism; assumption ] ] - | assumption ] - | simpl in |- *; rewrite (Pcompare_Eq_eq q p E2); apply Pcompare_refl - | simpl in |- *; apply nat_of_P_gt_Gt_compare_complement_morphism; - unfold gt in |- *; rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ apply plus_lt_reg_l with (p := nat_of_P p); - rewrite le_plus_minus_r; - [ rewrite plus_comm; apply plus_lt_reg_l with (p := nat_of_P q); - rewrite plus_assoc; rewrite le_plus_minus_r; - [ rewrite (plus_comm (nat_of_P q)); apply plus_lt_compat_l; - apply nat_of_P_lt_Lt_compare_morphism; - assumption - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption ] - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption ] - | assumption ] - | assumption ] - | simpl in |- *; apply nat_of_P_lt_Lt_compare_complement_morphism; - rewrite nat_of_P_minus_morphism; - [ rewrite nat_of_P_minus_morphism; - [ apply plus_lt_reg_l with (p := nat_of_P q); - rewrite le_plus_minus_r; - [ rewrite plus_comm; apply plus_lt_reg_l with (p := nat_of_P p); - rewrite plus_assoc; rewrite le_plus_minus_r; - [ rewrite (plus_comm (nat_of_P p)); apply plus_lt_compat_l; - apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption ] - | apply lt_le_weak; apply nat_of_P_lt_Lt_compare_morphism; - apply ZC1; assumption ] - | assumption ] - | assumption ] ] ]. + intros [|x|x] [|y|y] z; simpl; trivial; try apply ZC2; + try apply Plt_plus_r. + case Pcompare_spec; intros E0; trivial; try apply ZC2; + now apply Pminus_decr. + apply Pplus_compare_mono_l. + case Pcompare_spec; intros E0; trivial; try apply ZC2. + apply Plt_trans with z. now apply Pminus_decr. apply Plt_plus_r. + case Pcompare_spec; intros E0; trivial; try apply ZC2. + now apply Pminus_decr. + case Pcompare_spec; intros E0; trivial; try apply ZC2. + apply Plt_trans with z. now apply Pminus_decr. apply Plt_plus_r. + case Pcompare_spec; intros E0; simpl; subst. + now case Pcompare_spec. + case Pcompare_spec; intros E1; simpl; subst; trivial. + now rewrite <- ZC4. + f_equal. + apply Pminus_compare_mono_r; trivial. + rewrite <- ZC4. symmetry. now apply Plt_trans with z. + case Pcompare_spec; intros E1; simpl; subst; trivial. + now rewrite E0. + symmetry. apply CompOpp_iff. now apply Plt_trans with z. + rewrite <- ZC4. + apply Pminus_compare_mono_l; trivial. Qed. Lemma Zcompare_plus_compat : forall n m p:Z, (p + n ?= p + m) = (n ?= m). Proof. - exact (weaken_Zcompare_Zplus_compatible weak_Zcompare_Zplus_compatible). + intros x y [|z|z]; trivial. + apply weak_Zcompare_plus_compat. + rewrite (Zcompare_opp x y), Zcompare_opp, 2 Zopp_plus_distr, Zopp_neg. + apply weak_Zcompare_plus_compat. Qed. Lemma Zplus_compare_compat : forall (r:comparison) (n m p q:Z), (n ?= m) = r -> (p ?= q) = r -> (n + p ?= m + q) = r. Proof. - intros r x y z t; case r; - [ intros H1 H2; elim (Zcompare_Eq_iff_eq x y); elim (Zcompare_Eq_iff_eq z t); - intros H3 H4 H5 H6; rewrite H3; - [ rewrite H5; - [ elim (Zcompare_Eq_iff_eq (y + t) (y + t)); auto with arith - | auto with arith ] - | auto with arith ] - | intros H1 H2; elim (Zcompare_Gt_Lt_antisym (y + t) (x + z)); intros H3 H4; - apply H3; apply Zcompare_Gt_trans with (m := y + z); - [ rewrite Zcompare_plus_compat; elim (Zcompare_Gt_Lt_antisym t z); - auto with arith - | do 2 rewrite <- (Zplus_comm z); rewrite Zcompare_plus_compat; - elim (Zcompare_Gt_Lt_antisym y x); auto with arith ] - | intros H1 H2; apply Zcompare_Gt_trans with (m := x + t); - [ rewrite Zcompare_plus_compat; assumption - | do 2 rewrite <- (Zplus_comm t); rewrite Zcompare_plus_compat; - assumption ] ]. + intros [ | | ] x y z t H H'. + apply Zcompare_Eq_eq in H. apply Zcompare_Eq_eq in H'. subst. + apply Zcompare_refl. + apply Zcompare_Lt_trans with (y+z). + now rewrite 2 (Zplus_comm _ z), Zcompare_plus_compat. + now rewrite Zcompare_plus_compat. + apply Zcompare_Gt_trans with (y+z). + now rewrite 2 (Zplus_comm _ z), Zcompare_plus_compat. + now rewrite Zcompare_plus_compat. Qed. Lemma Zcompare_succ_Gt : forall n:Z, (Zsucc n ?= n) = Gt. Proof. - intro x; unfold Zsucc in |- *; pattern x at 2 in |- *; - rewrite <- (Zplus_0_r x); rewrite Zcompare_plus_compat; - reflexivity. -Qed. - -Lemma Zcompare_Gt_not_Lt : forall n m:Z, (n ?= m) = Gt <-> (n ?= m + 1) <> Lt. -Proof. - intros x y; split; - [ intro H; elim_compare x (y + 1); - [ intro H1; rewrite H1; discriminate - | intros H1; elim Zcompare_Gt_spec with (1 := H); intros h H2; - absurd ((nat_of_P h > 0)%nat /\ (nat_of_P h < 1)%nat); - [ unfold not in |- *; intros H3; elim H3; intros H4 H5; - absurd (nat_of_P h > 0)%nat; - [ unfold gt in |- *; 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 (nat_of_P h < nat_of_P 1)%nat in |- *; - apply nat_of_P_lt_Lt_compare_morphism; - change ((Zpos h ?= 1) = Lt) in |- *; rewrite <- H2; - rewrite <- (fun m n:Z => Zcompare_plus_compat m n y); - rewrite (Zplus_comm x); rewrite Zplus_assoc; - rewrite Zplus_opp_r; simpl in |- *; exact H1 ] ] - | intros H1; rewrite H1; discriminate ] - | intros H; elim_compare x (y + 1); - [ intros H1; elim (Zcompare_Eq_iff_eq x (y + 1)); intros H2 H3; - rewrite (H2 H1); exact (Zcompare_succ_Gt y) - | intros H1; absurd ((x ?= y + 1) = Lt); assumption - | intros H1; apply Zcompare_Gt_trans with (m := Zsucc y); - [ exact H1 | exact (Zcompare_succ_Gt y) ] ] ]. + intro x; unfold Zsucc; pattern x at 2; rewrite <- (Zplus_0_r x); + now rewrite Zcompare_plus_compat. +Qed. + +Lemma Zcompare_Gt_not_Lt : forall n m:Z, (n ?= m) = Gt <-> (n ?= m+1) <> Lt. +Proof. + intros x y; split; intros H. + (* -> *) + destruct (Zcompare_Gt_spec _ _ H) as (h,EQ). + replace x with (y+Zpos h) by (rewrite <- EQ; apply Zplus_minus). + rewrite Zcompare_plus_compat. apply Plt_1. + (* <- *) + assert (H' := Zcompare_succ_Gt y). + destruct (Zcompare_spec x (y+1)) as [->|LT|GT]; trivial. + now elim H. + apply Zcompare_Gt_Lt_antisym in GT. + apply Zcompare_Gt_trans with (y+1); trivial. Qed. (** * Successor and comparison *) Lemma Zcompare_succ_compat : forall n m:Z, (Zsucc n ?= Zsucc m) = (n ?= m). Proof. - intros n m; unfold Zsucc in |- *; do 2 rewrite (fun t:Z => Zplus_comm t 1); - rewrite Zcompare_plus_compat; auto with arith. + intros n m; unfold Zsucc; + now rewrite 2 (Zplus_comm _ 1), Zcompare_plus_compat. Qed. (** * Multiplication and comparison *) @@ -389,28 +202,13 @@ Qed. Lemma Zcompare_mult_compat : forall (p:positive) (n m:Z), (Zpos p * n ?= Zpos p * m) = (n ?= m). Proof. - intros x; induction x as [p H| p H| ]; - [ intros y z; cut (Zpos (xI p) = Zpos p + Zpos p + 1); - [ intros E; rewrite E; do 4 rewrite Zmult_plus_distr_l; - do 2 rewrite Zmult_1_l; apply Zplus_compare_compat; - [ apply Zplus_compare_compat; apply H | trivial with arith ] - | simpl in |- *; rewrite (Pplus_diag p); trivial with arith ] - | intros y z; cut (Zpos (xO p) = Zpos p + Zpos p); - [ intros E; rewrite E; do 2 rewrite Zmult_plus_distr_l; - apply Zplus_compare_compat; apply H - | simpl in |- *; rewrite (Pplus_diag p); trivial with arith ] - | intros y z; do 2 rewrite Zmult_1_l; trivial with arith ]. + intros p [|n|n] [|m|m]; simpl; trivial. + apply Pmult_compare_mono_l. + f_equal. apply Pmult_compare_mono_l. Qed. - (** * Reverting [x ?= y] to trichotomy *) -Lemma rename : - forall (A:Type) (P:A -> Prop) (x:A), (forall y:A, x = y -> P y) -> P x. -Proof. - auto with arith. -Qed. - Lemma Zcompare_elim : forall (c1 c2 c3:Prop) (n m:Z), (n = m -> c1) -> @@ -421,11 +219,9 @@ Lemma Zcompare_elim : | Gt => c3 end. Proof. - intros c1 c2 c3 x y; intros. - apply rename with (x := x ?= y); intro r; elim r; - [ intro; apply H; apply (Zcompare_Eq_eq x y); assumption - | unfold Zlt in H0; assumption - | unfold Zgt in H1; assumption ]. + intros c1 c2 c3 x y EQ LT GT; intros. + case Zcompare_spec; auto. + intro H. apply GT. red. now rewrite <- Zcompare_antisym, H. Qed. Lemma Zcompare_eq_case : @@ -450,8 +246,8 @@ Lemma Zcompare_egal_dec : (n > m -> p > q) -> (n ?= m) = (p ?= q). Proof. intros x1 y1 x2 y2. - unfold Zgt in |- *; unfold Zlt in |- *; case (x1 ?= y1); case (x2 ?= y2); - auto with arith; symmetry in |- *; auto with arith. + unfold Zgt; unfold Zlt; case (x1 ?= y1); case (x2 ?= y2); + auto with arith; symmetry; auto with arith. Qed. (** * Relating [x ?= y] to [Zle], [Zlt], [Zge] or [Zgt] *) @@ -464,7 +260,7 @@ Lemma Zle_compare : | Gt => False end. Proof. - intros x y; unfold Zle in |- *; elim (x ?= y); auto with arith. + intros x y; unfold Zle; elim (x ?= y); auto with arith. Qed. Lemma Zlt_compare : @@ -487,7 +283,7 @@ Lemma Zge_compare : | Gt => True end. Proof. - intros x y; unfold Zge in |- *; elim (x ?= y); auto with arith. + intros x y; unfold Zge; elim (x ?= y); auto. Qed. Lemma Zgt_compare : @@ -498,8 +294,7 @@ Lemma Zgt_compare : | Gt => True end. Proof. - intros x y; unfold Zgt in |- *; elim (x ?= y); intros; - discriminate || trivial with arith. + intros x y; unfold Zgt; now elim (x ?= y). Qed. (*********************) @@ -517,7 +312,7 @@ Qed. Lemma Zmult_compare_compat_r : forall n m p:Z, p > 0 -> (n ?= m) = (n * p ?= m * p). Proof. - intros x y z H; rewrite (Zmult_comm x z); rewrite (Zmult_comm y z); + intros x y z H; rewrite 2 (Zmult_comm _ z); apply Zmult_compare_compat_l; assumption. Qed. diff --git a/theories/ZArith/Zdiv_def.v b/theories/ZArith/Zdiv_def.v index 0e71bb4c3..a45d433c8 100644 --- a/theories/ZArith/Zdiv_def.v +++ b/theories/ZArith/Zdiv_def.v @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -Require Import BinPos BinNat BinInt Zbool Zcompare Zorder Zabs Nnat Ndiv_def. +Require Import BinPos BinNat BinInt Zbool Zcompare Zorder Zabs Znat Ndiv_def. Local Open Scope Z_scope. (** * Definitions of divisions for binary integers *) diff --git a/theories/ZArith/Zlog_def.v b/theories/ZArith/Zlog_def.v index 588b33037..44983f691 100644 --- a/theories/ZArith/Zlog_def.v +++ b/theories/ZArith/Zlog_def.v @@ -12,55 +12,27 @@ Local Open Scope Z_scope. (** Definition of Zlog2 *) -Fixpoint Plog2_Z (p:positive) : Z := - match p with - | 1 => Z0 - | p~0 => Zsucc (Plog2_Z p) - | p~1 => Zsucc (Plog2_Z p) - end%positive. - Definition Zlog2 z := match z with - | Zpos p => Plog2_Z p + | Zpos (p~1) => Zpos (Psize_pos p) + | Zpos (p~0) => Zpos (Psize_pos p) | _ => 0 end. -Lemma Plog2_Z_nonneg : forall p, 0 <= Plog2_Z p. -Proof. - induction p; simpl; auto with zarith. -Qed. - -Lemma Plog2_Z_spec : forall p, - 2^(Plog2_Z p) <= Zpos p < 2^(Zsucc (Plog2_Z p)). -Proof. - induction p; simpl; - try rewrite 2 Zpower_succ_r; auto using Plog2_Z_nonneg with zarith. - (* p~1 *) - change (Zpos p~1) with (Zsucc (2 * Zpos p)). - split; destruct IHp as [LE LT]. - apply Zle_trans with (2 * Zpos p). - now apply Zmult_le_compat_l. - apply Zle_succ. - apply Zle_succ_l. apply Zle_succ_l in LT. - replace (Zsucc (Zsucc (2 * Zpos p))) with (2 * (Zsucc (Zpos p))). - now apply Zmult_le_compat_l. - simpl. now rewrite Pplus_one_succ_r. - (* p~0 *) - change (Zpos p~0) with (2 * Zpos p). - split; destruct IHp. - now apply Zmult_le_compat_l. - now apply Zmult_lt_compat_l. - (* 1 *) - now split. -Qed. - Lemma Zlog2_spec : forall n, 0 < n -> 2^(Zlog2 n) <= n < 2^(Zsucc (Zlog2 n)). Proof. - intros [|p|p] Hn; try discriminate. apply Plog2_Z_spec. + intros [|[p|p|]|] Hn; split; try easy; unfold Zlog2; + rewrite <- ?Zpos_succ_morphism, Zpower_Ppow. + eapply Zle_trans with (Zpos (p~0)). + apply Psize_pos_le. + apply Zlt_le_weak. exact (Pcompare_p_Sp (p~0)). + apply Psize_pos_gt. + apply Psize_pos_le. + apply Psize_pos_gt. Qed. Lemma Zlog2_nonpos : forall n, n<=0 -> Zlog2 n = 0. Proof. - intros [|p|p] Hn. reflexivity. now destruct Hn. reflexivity. + intros [|p|p] H; trivial; now destruct H. Qed. diff --git a/theories/ZArith/Zlogarithm.v b/theories/ZArith/Zlogarithm.v index ddb1eed9f..b80e96c2a 100644 --- a/theories/ZArith/Zlogarithm.v +++ b/theories/ZArith/Zlogarithm.v @@ -7,9 +7,12 @@ (************************************************************************) (**********************************************************************) + (** The integer logarithms with base 2. - There are three logarithms, + NOTA: This file is deprecated, please use Zlog2 defined in Zlog_def. + + There are three logarithms defined here, depending on the rounding of the real 2-based logarithm: - [Log_inf]: [y = (Log_inf x) iff 2^y <= x < 2^(y+1)] i.e. [Log_inf x] is the biggest integer that is smaller than [Log x] @@ -25,9 +28,12 @@ Section Log_pos. (* Log of positive integers *) (** First we build [log_inf] and [log_sup] *) - (** [log_inf] is exactly the same as the new [Plog2_Z] *) - - Definition log_inf : positive -> Z := Eval red in Plog2_Z. + Fixpoint log_inf (p:positive) : Z := + match p with + | xH => 0 (* 1 *) + | xO q => Zsucc (log_inf q) (* 2n *) + | xI q => Zsucc (log_inf q) (* 2n+1 *) + end. Fixpoint log_sup (p:positive) : Z := match p with @@ -38,8 +44,15 @@ Section Log_pos. (* Log of positive integers *) Hint Unfold log_inf log_sup. + Lemma Psize_log_inf : forall p, Zpos (Psize_pos p) = Zsucc (log_inf p). + Proof. + induction p; simpl; now rewrite ?Zpos_succ_morphism, ?IHp. + Qed. + Lemma Zlog2_log_inf : forall p, Zlog2 (Zpos p) = log_inf p. - Proof. reflexivity. Qed. + Proof. + unfold Zlog2. destruct p; simpl; trivial; apply Psize_log_inf. + Qed. Lemma Zlog2_up_log_sup : forall p, Z.log2_up (Zpos p) = log_sup p. Proof. diff --git a/theories/ZArith/Zmisc.v b/theories/ZArith/Zmisc.v index b4bd470ab..f6b038cbd 100644 --- a/theories/ZArith/Zmisc.v +++ b/theories/ZArith/Zmisc.v @@ -18,13 +18,6 @@ Open Local Scope Z_scope. (** [n]th iteration of the function [f] *) -Fixpoint iter_pos (n:positive) (A:Type) (f:A -> A) (x:A) : A := - match n with - | xH => f x - | xO n' => iter_pos n' A f (iter_pos n' A f x) - | xI n' => f (iter_pos n' A f (iter_pos n' A f x)) - end. - Definition iter (n:Z) (A:Type) (f:A -> A) (x:A) := match n with | Z0 => x @@ -32,58 +25,9 @@ Definition iter (n:Z) (A:Type) (f:A -> A) (x:A) := | Zneg p => x end. -Theorem iter_nat_of_P : - forall (p:positive) (A:Type) (f:A -> A) (x:A), - iter_pos p A f x = iter_nat (nat_of_P p) A f x. -Proof. - intro n; induction n as [p H| p H| ]; - [ intros; simpl in |- *; rewrite (H A f x); - rewrite (H A f (iter_nat (nat_of_P p) A f x)); - rewrite (ZL6 p); symmetry in |- *; apply f_equal with (f := f); - apply iter_nat_plus - | intros; unfold nat_of_P in |- *; simpl in |- *; rewrite (H A f x); - rewrite (H A f (iter_nat (nat_of_P p) A f x)); - rewrite (ZL6 p); symmetry in |- *; apply iter_nat_plus - | simpl in |- *; auto with arith ]. -Qed. - Lemma iter_nat_of_Z : forall n A f x, 0 <= n -> iter n A f x = iter_nat (Zabs_nat n) A f x. intros n A f x; case n; auto. intros p _; unfold iter, Zabs_nat; apply iter_nat_of_P. intros p abs; case abs; trivial. Qed. - -Theorem iter_pos_plus : - forall (p q:positive) (A:Type) (f:A -> A) (x:A), - iter_pos (p + q) A f x = iter_pos p A f (iter_pos q A f x). -Proof. - intros n m; intros. - rewrite (iter_nat_of_P m A f x). - rewrite (iter_nat_of_P n A f (iter_nat (nat_of_P m) A f x)). - rewrite (iter_nat_of_P (n + m) A f x). - rewrite (nat_of_P_plus_morphism n m). - apply iter_nat_plus. -Qed. - -(** Preservation of invariants : if [f : A->A] preserves the invariant [Inv], - then the iterates of [f] also preserve it. *) - -Theorem iter_nat_invariant : - forall (n:nat) (A:Type) (f:A -> A) (Inv:A -> Prop), - (forall x:A, Inv x -> Inv (f x)) -> - forall x:A, Inv x -> Inv (iter_nat n A f x). -Proof. - simple induction n; intros; - [ trivial with arith - | simpl in |- *; apply H0 with (x := iter_nat n0 A f x); apply H; - trivial with arith ]. -Qed. - -Theorem iter_pos_invariant : - forall (p:positive) (A:Type) (f:A -> A) (Inv:A -> Prop), - (forall x:A, Inv x -> Inv (f x)) -> - forall x:A, Inv x -> Inv (iter_pos p A f x). -Proof. - intros; rewrite iter_nat_of_P; apply iter_nat_invariant; trivial with arith. -Qed. diff --git a/theories/ZArith/Znat.v b/theories/ZArith/Znat.v index c7e6d5750..5f4a6e38d 100644 --- a/theories/ZArith/Znat.v +++ b/theories/ZArith/Znat.v @@ -10,14 +10,8 @@ (** Binary Integers (Pierre Crégut, CNET, Lannion, France) *) Require Export Arith_base. -Require Import BinPos. -Require Import BinInt. -Require Import Zcompare. -Require Import Zorder. -Require Import Decidable. -Require Import Peano_dec. -Require Import Min Max. -Require Export Compare_dec. +Require Import BinPos BinInt BinNat Zcompare Zorder. +Require Import Decidable Peano_dec Min Max Compare_dec. Open Local Scope Z_scope. @@ -26,46 +20,49 @@ Definition neq (x y:nat) := x <> y. (************************************************) (** Properties of the injection from nat into Z *) +Lemma Zpos_P_of_succ_nat : forall n:nat, + Zpos (P_of_succ_nat n) = Zsucc (Z_of_nat n). +Proof. + intros [|n]. trivial. apply Zpos_succ_morphism. +Qed. + (** Injection and successor *) -Theorem inj_0 : Z_of_nat 0 = 0%Z. +Theorem inj_0 : Z_of_nat 0 = 0. Proof. reflexivity. Qed. Theorem inj_S : forall n:nat, Z_of_nat (S n) = Zsucc (Z_of_nat n). Proof. - intro y; induction y as [| n H]; - [ unfold Zsucc in |- *; simpl in |- *; trivial with arith - | change (Zpos (Psucc (P_of_succ_nat n)) = Zsucc (Z_of_nat (S n))) in |- *; - rewrite Zpos_succ_morphism; trivial with arith ]. + exact Zpos_P_of_succ_nat. +Qed. + +(** Injection and comparison *) + +Theorem inj_compare : forall n m:nat, + (Z_of_nat n ?= Z_of_nat m) = nat_compare n m. +Proof. + induction n; destruct m; trivial. + rewrite 2 inj_S, Zcompare_succ_compat. now simpl. Qed. (** Injection and equality. *) Theorem inj_eq : forall n m:nat, n = m -> Z_of_nat n = Z_of_nat m. Proof. - intros x y H; rewrite H; trivial with arith. + intros; subst; trivial. Qed. -Theorem inj_neq : forall n m:nat, neq n m -> Zne (Z_of_nat n) (Z_of_nat m). +Theorem inj_eq_rev : forall n m:nat, Z_of_nat n = Z_of_nat m -> n = m. Proof. - unfold neq, Zne, not in |- *; 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 <- nat_of_P_o_P_of_succ_nat_eq_succ; - intros E; rewrite E; auto with arith ]. + intros n m H. apply nat_compare_eq. + now rewrite <- inj_compare, H, Zcompare_refl. Qed. -Theorem inj_eq_rev : forall n m:nat, Z_of_nat n = Z_of_nat m -> n = m. +Theorem inj_neq : forall n m:nat, neq n m -> Zne (Z_of_nat n) (Z_of_nat m). Proof. - intros x y H. - destruct (eq_nat_dec x y) as [H'|H']; auto. - exfalso. - exact (inj_neq _ _ H' H). + unfold neq, Zne. intros n m H. contradict H. now apply inj_eq_rev. Qed. Theorem inj_eq_iff : forall n m:nat, n=m <-> Z_of_nat n = Z_of_nat m. @@ -73,17 +70,9 @@ Proof. split; [apply inj_eq | apply inj_eq_rev]. Qed. +(** Injection and order *) -(** Injection and order relations: *) - -Theorem inj_compare : forall n m:nat, - (Z_of_nat n ?= Z_of_nat m) = nat_compare n m. -Proof. - induction n; destruct m; trivial. - rewrite 2 inj_S, Zcompare_succ_compat. now simpl. -Qed. - -(* Both ways ... *) +(** Both ways ... *) Theorem inj_le_iff : forall n m:nat, (n<=m)%nat <-> Z_of_nat n <= Z_of_nat m. Proof. @@ -137,50 +126,43 @@ Proof. apply inj_gt_iff. Qed. Theorem inj_plus : forall n m:nat, Z_of_nat (n + m) = Z_of_nat n + Z_of_nat m. Proof. - intro x; induction x as [| n H]; intro y; destruct y as [| m]; - [ simpl in |- *; trivial with arith - | simpl in |- *; trivial with arith - | simpl in |- *; rewrite <- plus_n_O; trivial with arith - | change (Z_of_nat (S (n + S m)) = Z_of_nat (S n) + Z_of_nat (S m)) in |- *; - rewrite inj_S; rewrite H; do 2 rewrite inj_S; rewrite Zplus_succ_l; - trivial with arith ]. + induction n as [|n IH]; intros [|m]; simpl; trivial. + rewrite <- plus_n_O; trivial. + change (Z_of_nat (S (n + S m)) = Z_of_nat (S n) + Z_of_nat (S m)). + now rewrite inj_S, IH, 2 inj_S, Zplus_succ_l. Qed. Theorem inj_mult : forall n m:nat, Z_of_nat (n * m) = Z_of_nat n * Z_of_nat m. Proof. - intro x; induction x as [| n H]; - [ simpl in |- *; trivial with arith - | intro y; rewrite inj_S; rewrite <- Zmult_succ_l_reverse; rewrite <- H; - rewrite <- inj_plus; simpl in |- *; rewrite plus_comm; - trivial with arith ]. + induction n as [|n IH]; intros m; trivial. + rewrite inj_S, Zmult_succ_l, <- IH, <- inj_plus. + simpl. now rewrite plus_comm. Qed. Theorem inj_minus1 : forall n m:nat, (m <= n)%nat -> Z_of_nat (n - m) = Z_of_nat n - Z_of_nat m. Proof. - intros x y H; apply (Zplus_reg_l (Z_of_nat y)); unfold Zminus in |- *; - rewrite Zplus_permute; rewrite Zplus_opp_r; rewrite <- inj_plus; - rewrite <- (le_plus_minus y x H); rewrite Zplus_0_r; - trivial with arith. + intros n m H. + apply (Zplus_reg_l (Z_of_nat m)); unfold Zminus. + rewrite Zplus_permute, Zplus_opp_r, <- inj_plus, Zplus_0_r. + f_equal. symmetry. now apply le_plus_minus. Qed. Theorem inj_minus2 : forall n m:nat, (m > n)%nat -> Z_of_nat (n - m) = 0. Proof. - intros x y H; rewrite not_le_minus_0; - [ trivial with arith | apply gt_not_le; assumption ]. + intros. rewrite not_le_minus_0; auto with arith. Qed. Theorem inj_minus : forall n m:nat, Z_of_nat (minus n m) = Zmax 0 (Z_of_nat n - Z_of_nat m). Proof. - intros. - unfold Zmax. + intros n m. unfold Zmax. destruct (le_lt_dec m n) as [H|H]. - + (* m <= n *) rewrite inj_minus1; trivial. apply inj_le, Zle_minus_le_0 in H. revert H. unfold Zle. case Zcompare_spec; intuition. - + (* n < m *) rewrite inj_minus2; trivial. apply inj_lt, Zlt_gt in H. apply (Zplus_gt_compat_r _ _ (- Z_of_nat m)) in H. @@ -192,59 +174,170 @@ Theorem inj_min : forall n m:nat, Z_of_nat (min n m) = Zmin (Z_of_nat n) (Z_of_nat m). Proof. intros n m. unfold Zmin. rewrite inj_compare. - case nat_compare_spec; intros; f_equal. - subst. apply min_idempotent. - apply min_l. auto with arith. - apply min_r. auto with arith. + case nat_compare_spec; intros; f_equal; subst; auto with arith. Qed. Theorem inj_max : forall n m:nat, Z_of_nat (max n m) = Zmax (Z_of_nat n) (Z_of_nat m). Proof. intros n m. unfold Zmax. rewrite inj_compare. - case nat_compare_spec; intros; f_equal. - subst. apply max_idempotent. - apply max_r. auto with arith. - apply max_l. auto with arith. + case nat_compare_spec; intros; f_equal; subst; auto with arith. Qed. (** Composition of injections **) -Theorem Zpos_eq_Z_of_nat_o_nat_of_P : - forall p:positive, Zpos p = Z_of_nat (nat_of_P p). +Lemma Z_of_nat_of_P : forall p, Z_of_nat (nat_of_P p) = Zpos p. Proof. - intros x; elim x; simpl in |- *; auto. - intros p H; rewrite ZL6. - apply f_equal with (f := Zpos). - apply nat_of_P_inj. - rewrite nat_of_P_o_P_of_succ_nat_eq_succ; unfold nat_of_P in |- *; - simpl in |- *. - rewrite ZL6; auto. - intros p H; unfold nat_of_P in |- *; simpl in |- *. - rewrite ZL6; simpl in |- *. - rewrite inj_plus; repeat rewrite <- H. - rewrite Zpos_xO; simpl in |- *; rewrite Pplus_diag; reflexivity. + intros p. destruct (nat_of_P_is_S p) as (n,H). rewrite H. + simpl. f_equal. rewrite <- (nat_of_P_of_succ_nat n) in H. + symmetry. now apply nat_of_P_inj. Qed. -(** Misc *) +(** For compatibility *) +Definition Zpos_eq_Z_of_nat_o_nat_of_P p := eq_sym (Z_of_nat_of_P p). -Theorem intro_Z : - forall n:nat, exists y : Z, Z_of_nat n = y /\ 0 <= y * 1 + 0. +(******************************************************************) +(** Properties of the injection from N into Z *) + +Lemma Z_of_nat_of_N : forall n, Z_of_nat (nat_of_N n) = Z_of_N n. Proof. - intros x; exists (Z_of_nat x); split; - [ trivial with arith - | rewrite Zmult_comm; rewrite Zmult_1_l; rewrite Zplus_0_r; - unfold Zle in |- *; elim x; intros; simpl in |- *; - discriminate ]. + intros [|n]. trivial. + simpl. apply Z_of_nat_of_P. Qed. -Lemma Zpos_P_of_succ_nat : forall n:nat, - Zpos (P_of_succ_nat n) = Zsucc (Z_of_nat n). +Lemma Z_of_N_of_nat : forall n, Z_of_N (N_of_nat n) = Z_of_nat n. +Proof. + now destruct n. +Qed. + +Lemma Z_of_N_eq : forall n m, n = m -> Z_of_N n = Z_of_N m. +Proof. + intros; f_equal; assumption. +Qed. + +Lemma Z_of_N_eq_rev : forall n m, Z_of_N n = Z_of_N m -> n = m. +Proof. + intros [|n] [|m]; simpl; congruence. +Qed. + +Lemma Z_of_N_eq_iff : forall n m, n = m <-> Z_of_N n = Z_of_N m. +Proof. + split; [apply Z_of_N_eq | apply Z_of_N_eq_rev]. +Qed. + +Lemma Z_of_N_compare : forall n m, + Zcompare (Z_of_N n) (Z_of_N m) = Ncompare n m. +Proof. + intros [|n] [|m]; trivial. +Qed. + +Lemma Z_of_N_le_iff : forall n m, (n<=m)%N <-> Z_of_N n <= Z_of_N m. +Proof. + intros. unfold Zle. now rewrite Z_of_N_compare. +Qed. + +Lemma Z_of_N_le : forall n m, (n<=m)%N -> Z_of_N n <= Z_of_N m. +Proof. + apply Z_of_N_le_iff. +Qed. + +Lemma Z_of_N_le_rev : forall n m, Z_of_N n <= Z_of_N m -> (n<=m)%N. +Proof. + apply Z_of_N_le_iff. +Qed. + +Lemma Z_of_N_lt_iff : forall n m, (n<m)%N <-> Z_of_N n < Z_of_N m. +Proof. + intros. unfold Zlt. now rewrite Z_of_N_compare. +Qed. + +Lemma Z_of_N_lt : forall n m, (n<m)%N -> Z_of_N n < Z_of_N m. +Proof. + apply Z_of_N_lt_iff. +Qed. + +Lemma Z_of_N_lt_rev : forall n m, Z_of_N n < Z_of_N m -> (n<m)%N. +Proof. + apply Z_of_N_lt_iff. +Qed. + +Lemma Z_of_N_ge_iff : forall n m, (n>=m)%N <-> Z_of_N n >= Z_of_N m. +Proof. + intros. unfold Zge. now rewrite Z_of_N_compare. +Qed. + +Lemma Z_of_N_ge : forall n m, (n>=m)%N -> Z_of_N n >= Z_of_N m. +Proof. + apply Z_of_N_ge_iff. +Qed. + +Lemma Z_of_N_ge_rev : forall n m, Z_of_N n >= Z_of_N m -> (n>=m)%N. +Proof. + apply Z_of_N_ge_iff. +Qed. + +Lemma Z_of_N_gt_iff : forall n m, (n>m)%N <-> Z_of_N n > Z_of_N m. +Proof. + intros. unfold Zgt. now rewrite Z_of_N_compare. +Qed. + +Lemma Z_of_N_gt : forall n m, (n>m)%N -> Z_of_N n > Z_of_N m. +Proof. + apply Z_of_N_gt_iff. +Qed. + +Lemma Z_of_N_gt_rev : forall n m, Z_of_N n > Z_of_N m -> (n>m)%N. +Proof. + apply Z_of_N_gt_iff. +Qed. + +Lemma Z_of_N_pos : forall p:positive, Z_of_N (Npos p) = Zpos p. +Proof. + reflexivity. +Qed. + +Lemma Z_of_N_abs : forall z:Z, Z_of_N (Zabs_N z) = Zabs z. +Proof. + now destruct z. +Qed. + +Lemma Z_of_N_le_0 : forall n, 0 <= Z_of_N n. +Proof. + now destruct n. +Qed. + +Lemma Z_of_N_plus : forall n m, Z_of_N (n+m) = Z_of_N n + Z_of_N m. +Proof. + now destruct n, m. +Qed. + +Lemma Z_of_N_mult : forall n m, Z_of_N (n*m) = Z_of_N n * Z_of_N m. +Proof. + now destruct n, m. +Qed. + +Lemma Z_of_N_minus : forall n m, Z_of_N (n-m) = Zmax 0 (Z_of_N n - Z_of_N m). +Proof. + intros [|n] [|m]; simpl; trivial. + case Pcompare_spec; intros H. + subst. now rewrite Pminus_mask_diag. + rewrite Pminus_mask_Lt; trivial. + unfold Pminus. + destruct (Pminus_mask_Gt n m (ZC2 _ _ H)) as (q & -> & _); trivial. +Qed. + +Lemma Z_of_N_succ : forall n, Z_of_N (Nsucc n) = Zsucc (Z_of_N n). +Proof. + intros [|n]; simpl; trivial. now rewrite Zpos_succ_morphism. +Qed. + +Lemma Z_of_N_min : forall n m, Z_of_N (Nmin n m) = Zmin (Z_of_N n) (Z_of_N m). +Proof. + intros. unfold Zmin, Nmin. rewrite Z_of_N_compare. now case Ncompare. +Qed. + +Lemma Z_of_N_max : forall n m, Z_of_N (Nmax n m) = Zmax (Z_of_N n) (Z_of_N m). Proof. - intros. - unfold Z_of_nat. - destruct n. - simpl; auto. - simpl (P_of_succ_nat (S n)). - apply Zpos_succ_morphism. + intros. unfold Zmax, Nmax. rewrite Z_of_N_compare. + case Ncompare_spec; intros; subst; trivial. Qed. diff --git a/theories/ZArith/Zpow_def.v b/theories/ZArith/Zpow_def.v index 96d05760b..7121393bc 100644 --- a/theories/ZArith/Zpow_def.v +++ b/theories/ZArith/Zpow_def.v @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -Require Import BinInt Zmisc Ring_theory. +Require Import BinInt BinNat Ring_theory. Local Open Scope Z_scope. @@ -49,23 +49,38 @@ Proof. induction p; simpl; intros; rewrite ?IHp, ?Zmult_assoc; trivial. Qed. -(** An alternative Zpower *) +Lemma Zpower_Ppow : forall p q, (Zpos p)^(Zpos q) = Zpos (p^q). +Proof. + intros. unfold Ppow, Zpower, Zpower_pos. + symmetry. now apply iter_pos_swap_gen. +Qed. + +Lemma Zpower_Npow : forall n m, + (Z_of_N n)^(Z_of_N m) = Z_of_N (n^m). +Proof. + intros [|n] [|m]; simpl; trivial. + unfold Zpower_pos. generalize 1. induction m; simpl; trivial. + apply Zpower_Ppow. +Qed. -(** This Zpower_opt is extensionnaly equal to Zpower in ZArith, - but not convertible with it, and quicker : the number of - multiplications is logarithmic instead of linear. +(** An alternative Zpower *) - TODO: We should try someday to replace Zpower with this Zpower_opt. +(** This Zpower_alt is extensionnaly equal to Zpower in ZArith, + but not convertible with it. The number of + multiplications is logarithmic instead of linear, but + these multiplications are bigger. Experimentally, it seems + that Zpower_alt is slightly quicker than Zpower on average, + but can be quite slower on powers of 2. *) -Definition Zpower_opt n m := +Definition Zpower_alt n m := match m with | Z0 => 1 | Zpos p => Piter_op Zmult p n | Zneg p => 0 end. -Infix "^^" := Zpower_opt (at level 30, right associativity) : Z_scope. +Infix "^^" := Zpower_alt (at level 30, right associativity) : Z_scope. Lemma iter_pos_mult_acc : forall f, (forall x y:Z, (f x)*y = f (x*y)) -> @@ -92,7 +107,7 @@ Qed. Lemma Zpower_equiv : forall a b, a^^b = a^b. Proof. intros a [|p|p]; trivial. - unfold Zpower_opt, Zpower, Zpower_pos. + unfold Zpower_alt, Zpower, Zpower_pos. revert a. induction p; simpl; intros. f_equal. @@ -105,17 +120,22 @@ Proof. now rewrite Zmult_1_r. Qed. -Lemma Zpower_opt_0_r : forall n, n^^0 = 1. +Lemma Zpower_alt_0_r : forall n, n^^0 = 1. Proof. reflexivity. Qed. -Lemma Zpower_opt_succ_r : forall a b, 0<=b -> a^^(Zsucc b) = a * a^^b. +Lemma Zpower_alt_succ_r : forall a b, 0<=b -> a^^(Zsucc b) = a * a^^b. Proof. intros a [|b|b] Hb; [ | |now elim Hb]; simpl. now rewrite Zmult_1_r. rewrite <- Pplus_one_succ_r. apply Piter_op_succ. apply Zmult_assoc. Qed. -Lemma Zpower_opt_neg_r : forall a b, b<0 -> a^^b = 0. +Lemma Zpower_alt_neg_r : forall a b, b<0 -> a^^b = 0. Proof. now destruct b. Qed. + +Lemma Zpower_alt_Ppow : forall p q, (Zpos p)^^(Zpos q) = Zpos (p^q). +Proof. + intros. now rewrite Zpower_equiv, Zpower_Ppow. +Qed. diff --git a/theories/ZArith/Zpower.v b/theories/ZArith/Zpower.v index e08b7ebc3..c021b01a9 100644 --- a/theories/ZArith/Zpower.v +++ b/theories/ZArith/Zpower.v @@ -55,7 +55,7 @@ Proof. rewrite (Zpower_pos_nat z n). rewrite (Zpower_pos_nat z m). rewrite (Zpower_pos_nat z (n + m)). - rewrite (nat_of_P_plus_morphism n m). + rewrite (Pplus_plus n m). apply Zpower_nat_is_exp. Qed. |