summaryrefslogtreecommitdiff
path: root/theories/QArith
diff options
context:
space:
mode:
Diffstat (limited to 'theories/QArith')
-rw-r--r--theories/QArith/QArith.v2
-rw-r--r--theories/QArith/QArith_base.v183
-rw-r--r--theories/QArith/Qabs.v124
-rw-r--r--theories/QArith/Qcanon.v38
-rw-r--r--theories/QArith/Qfield.v153
-rw-r--r--theories/QArith/Qpower.v239
-rw-r--r--theories/QArith/Qreals.v32
-rw-r--r--theories/QArith/Qreduction.v26
-rw-r--r--theories/QArith/Qring.v97
-rw-r--r--theories/QArith/Qround.v139
10 files changed, 864 insertions, 169 deletions
diff --git a/theories/QArith/QArith.v b/theories/QArith/QArith.v
index 03935e2b..2af65320 100644
--- a/theories/QArith/QArith.v
+++ b/theories/QArith/QArith.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: QArith.v 8883 2006-05-31 21:56:37Z letouzey $ i*)
+(*i $Id: QArith.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
Require Export QArith_base.
Require Export Qring.
diff --git a/theories/QArith/QArith_base.v b/theories/QArith/QArith_base.v
index fc92c678..304fbf77 100644
--- a/theories/QArith/QArith_base.v
+++ b/theories/QArith/QArith_base.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: QArith_base.v 9932 2007-07-02 14:31:33Z notin $ i*)
+(*i $Id: QArith_base.v 10765 2008-04-08 16:15:23Z msozeau $ i*)
Require Export ZArith.
Require Export ZArithRing.
@@ -79,9 +79,9 @@ Qed.
Lemma Qge_alt : forall p q, (p>=q) <-> (p?=q <> Lt).
Proof.
unfold Qle, Qcompare, Zle.
-split; intros; swap H.
+split; intros; contradict H.
rewrite Zcompare_Gt_Lt_antisym; auto.
-rewrite Zcompare_Gt_Lt_antisym in H0; auto.
+rewrite Zcompare_Gt_Lt_antisym in H; auto.
Qed.
Hint Unfold Qeq Qlt Qle: qarith.
@@ -121,7 +121,7 @@ Defined.
Definition Q_Setoid : Setoid_Theory Q Qeq.
Proof.
- split; unfold Qeq in |- *; auto; apply Qeq_trans.
+ split; red; unfold Qeq in |- *; auto; apply Qeq_trans.
Qed.
Add Setoid Q Qeq Q_Setoid as Qsetoid.
@@ -130,6 +130,12 @@ Hint Resolve (Seq_refl Q Qeq Q_Setoid): qarith.
Hint Resolve (Seq_sym Q Qeq Q_Setoid): qarith.
Hint Resolve (Seq_trans Q Qeq Q_Setoid): qarith.
+Theorem Qnot_eq_sym : forall x y, ~x == y -> ~y == x.
+Proof.
+ auto with qarith.
+Qed.
+
+Hint Resolve Qnot_eq_sym : qarith.
(** * Addition, multiplication and opposite *)
@@ -165,6 +171,13 @@ Infix "/" := Qdiv : Q_scope.
Notation " ' x " := (Zpos x) (at level 20, no associativity) : Z_scope.
+Lemma Qmake_Qdiv : forall a b, a#b==inject_Z a/inject_Z ('b).
+Proof.
+intros a b.
+unfold Qeq.
+simpl.
+ring.
+Qed.
(** * Setoid compatibility results *)
@@ -187,7 +200,7 @@ Proof.
unfold Qeq, Qopp; simpl.
Open Scope Z_scope.
intros.
- replace (- Qnum x1 * ' Qden x2) with (- (Qnum x1 * ' Qden x2)) by ring.
+ replace (- Qnum x * ' Qden y) with (- (Qnum x * ' Qden y)) by ring.
rewrite H in |- *; ring.
Close Scope Z_scope.
Qed.
@@ -416,6 +429,11 @@ Qed.
(** * Inverse and division. *)
+Lemma Qinv_involutive : forall q, (/ / q) == q.
+Proof.
+intros [[|n|n] d]; red; simpl; reflexivity.
+Qed.
+
Theorem Qmult_inv_r : forall x, ~ x == 0 -> x*(/x) == 1.
Proof.
intros (x1, x2); unfold Qeq, Qdiv, Qmult; case x1; simpl;
@@ -474,6 +492,8 @@ Proof.
Close Scope Z_scope.
Qed.
+Hint Resolve Qle_trans : qarith.
+
Lemma Qlt_not_eq : forall x y, x<y -> ~ x==y.
Proof.
unfold Qlt, Qeq; auto with zarith.
@@ -552,6 +572,9 @@ Proof.
unfold Qle, Qlt, Qeq; intros; apply Zle_lt_or_eq; auto.
Qed.
+Hint Resolve Qle_not_lt Qlt_not_le Qnot_le_lt Qnot_lt_le
+ Qlt_le_weak Qlt_not_eq Qle_antisym Qle_refl: qartih.
+
(** Some decidability results about orders. *)
Lemma Q_dec : forall x y, {x<y} + {y<x} + {x==y}.
@@ -574,6 +597,8 @@ Proof.
do 2 rewrite <- Zopp_mult_distr_l; omega.
Qed.
+Hint Resolve Qopp_le_compat : qarith.
+
Lemma Qle_minus_iff : forall p q, p <= q <-> 0 <= q+-p.
Proof.
intros (x1,x2) (y1,y2); unfold Qle; simpl.
@@ -641,50 +666,136 @@ Proof.
Close Scope Z_scope.
Qed.
-(** * Rational to the n-th power *)
+Lemma Qmult_le_0_compat : forall a b, 0 <= a -> 0 <= b -> 0 <= a*b.
+Proof.
+intros a b Ha Hb.
+unfold Qle in *.
+simpl in *.
+auto with *.
+Qed.
-Fixpoint Qpower (q:Q)(n:nat) { struct n } : Q :=
- match n with
- | O => 1
- | S n => q * (Qpower q n)
- end.
+Lemma Qinv_le_0_compat : forall a, 0 <= a -> 0 <= /a.
+Proof.
+intros [[|n|n] d] Ha; assumption.
+Qed.
-Notation " q ^ n " := (Qpower q n) : Q_scope.
+Lemma Qle_shift_div_l : forall a b c,
+ 0 < c -> a*c <= b -> a <= b/c.
+Proof.
+intros a b c Hc H.
+apply Qmult_lt_0_le_reg_r with (c).
+ assumption.
+setoid_replace (b/c*c) with (c*(b/c)) by apply Qmult_comm.
+rewrite Qmult_div_r; try assumption.
+auto with *.
+Qed.
-Lemma Qpower_1 : forall n, 1^n == 1.
+Lemma Qle_shift_inv_l : forall a c,
+ 0 < c -> a*c <= 1 -> a <= /c.
Proof.
- induction n; simpl; auto with qarith.
- rewrite IHn; auto with qarith.
+intros a c Hc H.
+setoid_replace (/c) with (1*/c) by (symmetry; apply Qmult_1_l).
+change (a <= 1/c).
+apply Qle_shift_div_l; assumption.
Qed.
-Lemma Qpower_0 : forall n, n<>O -> 0^n == 0.
+Lemma Qle_shift_div_r : forall a b c,
+ 0 < b -> a <= c*b -> a/b <= c.
Proof.
- destruct n; simpl.
- destruct 1; auto.
- intros.
- compute; auto.
+intros a b c Hc H.
+apply Qmult_lt_0_le_reg_r with b.
+ assumption.
+setoid_replace (a/b*b) with (b*(a/b)) by apply Qmult_comm.
+rewrite Qmult_div_r; try assumption.
+auto with *.
Qed.
-Lemma Qpower_pos : forall p n, 0 <= p -> 0 <= p^n.
+Lemma Qle_shift_inv_r : forall b c,
+ 0 < b -> 1 <= c*b -> /b <= c.
Proof.
- induction n; simpl; auto with qarith.
- intros; compute; intro; discriminate.
- intros.
- apply Qle_trans with (0*(p^n)).
- compute; intro; discriminate.
- apply Qmult_le_compat_r; auto.
+intros b c Hc H.
+setoid_replace (/b) with (1*/b) by (symmetry; apply Qmult_1_l).
+change (1/b <= c).
+apply Qle_shift_div_r; assumption.
Qed.
-Lemma Qinv_power_n : forall n p, (1#p)^n == /(inject_Z ('p))^n.
+Lemma Qinv_lt_0_compat : forall a, 0 < a -> 0 < /a.
Proof.
- induction n.
- compute; auto.
- simpl.
- intros; rewrite IHn; clear IHn.
- unfold Qdiv; rewrite Qinv_mult_distr.
- setoid_replace (1#p) with (/ inject_Z ('p)).
- apply Qeq_refl.
- compute; auto.
+intros [[|n|n] d] Ha; assumption.
+Qed.
+
+Lemma Qlt_shift_div_l : forall a b c,
+ 0 < c -> a*c < b -> a < b/c.
+Proof.
+intros a b c Hc H.
+apply Qnot_le_lt.
+intros H0.
+apply (Qlt_not_le _ _ H).
+apply Qmult_lt_0_le_reg_r with (/c).
+ apply Qinv_lt_0_compat.
+ assumption.
+setoid_replace (a*c/c) with (a) by (apply Qdiv_mult_l; auto with *).
+assumption.
+Qed.
+
+Lemma Qlt_shift_inv_l : forall a c,
+ 0 < c -> a*c < 1 -> a < /c.
+Proof.
+intros a c Hc H.
+setoid_replace (/c) with (1*/c) by (symmetry; apply Qmult_1_l).
+change (a < 1/c).
+apply Qlt_shift_div_l; assumption.
+Qed.
+
+Lemma Qlt_shift_div_r : forall a b c,
+ 0 < b -> a < c*b -> a/b < c.
+Proof.
+intros a b c Hc H.
+apply Qnot_le_lt.
+intros H0.
+apply (Qlt_not_le _ _ H).
+apply Qmult_lt_0_le_reg_r with (/b).
+ apply Qinv_lt_0_compat.
+ assumption.
+setoid_replace (c*b/b) with (c) by (apply Qdiv_mult_l; auto with *).
+assumption.
+Qed.
+
+Lemma Qlt_shift_inv_r : forall b c,
+ 0 < b -> 1 < c*b -> /b < c.
+Proof.
+intros b c Hc H.
+setoid_replace (/b) with (1*/b) by (symmetry; apply Qmult_1_l).
+change (1/b < c).
+apply Qlt_shift_div_r; assumption.
Qed.
+(** * Rational to the n-th power *)
+
+Definition Qpower_positive (q:Q)(p:positive) : Q :=
+ pow_pos Qmult q p.
+Add Morphism Qpower_positive with signature Qeq ==> @eq _ ==> Qeq as Qpower_positive_comp.
+Proof.
+intros x1 x2 Hx y.
+unfold Qpower_positive.
+induction y; simpl;
+try rewrite IHy;
+try rewrite Hx;
+reflexivity.
+Qed.
+
+Definition Qpower (q:Q) (z:Z) :=
+ match z with
+ | Zpos p => Qpower_positive q p
+ | Z0 => 1
+ | Zneg p => /Qpower_positive q p
+ end.
+
+Notation " q ^ z " := (Qpower q z) : Q_scope.
+
+Add Morphism Qpower with signature Qeq ==> @eq _ ==> Qeq as Qpower_comp.
+Proof.
+intros x1 x2 Hx [|y|y]; try reflexivity;
+simpl; rewrite Hx; reflexivity.
+Qed.
diff --git a/theories/QArith/Qabs.v b/theories/QArith/Qabs.v
new file mode 100644
index 00000000..e672016e
--- /dev/null
+++ b/theories/QArith/Qabs.v
@@ -0,0 +1,124 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+Require Export QArith.
+Require Export Qreduction.
+
+Hint Resolve Qlt_le_weak : qarith.
+
+Definition Qabs (x:Q) := let (n,d):=x in (Zabs n#d).
+
+Lemma Qabs_case : forall (x:Q) (P : Q -> Type), (0 <= x -> P x) -> (x <= 0 -> P (- x)) -> P (Qabs x).
+Proof.
+intros x P H1 H2.
+destruct x as [[|xn|xn] xd];
+[apply H1|apply H1|apply H2];
+abstract (compute; discriminate).
+Defined.
+
+Add Morphism Qabs with signature Qeq ==> Qeq as Qabs_wd.
+intros [xn xd] [yn yd] H.
+simpl.
+unfold Qeq in *.
+simpl in *.
+change (' yd)%Z with (Zabs (' yd)).
+change (' xd)%Z with (Zabs (' xd)).
+repeat rewrite <- Zabs_Zmult.
+congruence.
+Qed.
+
+Lemma Qabs_pos : forall x, 0 <= x -> Qabs x == x.
+Proof.
+intros x H.
+apply Qabs_case.
+reflexivity.
+intros H0.
+setoid_replace x with 0.
+reflexivity.
+apply Qle_antisym; assumption.
+Qed.
+
+Lemma Qabs_neg : forall x, x <= 0 -> Qabs x == - x.
+Proof.
+intros x H.
+apply Qabs_case.
+intros H0.
+setoid_replace x with 0.
+reflexivity.
+apply Qle_antisym; assumption.
+reflexivity.
+Qed.
+
+Lemma Qabs_nonneg : forall x, 0 <= (Qabs x).
+intros x.
+apply Qabs_case.
+auto.
+apply (Qopp_le_compat x 0).
+Qed.
+
+Lemma Zabs_Qabs : forall n d, (Zabs n#d)==Qabs (n#d).
+Proof.
+intros [|n|n]; reflexivity.
+Qed.
+
+Lemma Qabs_opp : forall x, Qabs (-x) == Qabs x.
+Proof.
+intros x.
+do 2 apply Qabs_case; try (intros; ring);
+(intros H0 H1;
+setoid_replace x with 0;[reflexivity|];
+apply Qle_antisym);try assumption;
+rewrite Qle_minus_iff in *;
+ring_simplify;
+ring_simplify in H1;
+assumption.
+Qed.
+
+Lemma Qabs_triangle : forall x y, Qabs (x+y) <= Qabs x + Qabs y.
+Proof.
+intros [xn xd] [yn yd].
+unfold Qplus.
+unfold Qle.
+simpl.
+apply Zmult_le_compat_r;auto with *.
+change (' yd)%Z with (Zabs (' yd)).
+change (' xd)%Z with (Zabs (' xd)).
+repeat rewrite <- Zabs_Zmult.
+apply Zabs_triangle.
+Qed.
+
+Lemma Qabs_Qmult : forall a b, Qabs (a*b) == (Qabs a)*(Qabs b).
+Proof.
+intros [an ad] [bn bd].
+simpl.
+rewrite Zabs_Zmult.
+reflexivity.
+Qed.
+
+Lemma Qle_Qabs : forall a, a <= Qabs a.
+Proof.
+intros a.
+apply Qabs_case; auto with *.
+intros H.
+apply Qle_trans with 0; try assumption.
+change 0 with (-0).
+apply Qopp_le_compat.
+assumption.
+Qed.
+
+Lemma Qabs_triangle_reverse : forall x y, Qabs x - Qabs y <= Qabs (x - y).
+Proof.
+intros x y.
+rewrite Qle_minus_iff.
+setoid_replace (Qabs (x - y) + - (Qabs x - Qabs y)) with ((Qabs (x - y) + Qabs y) + - Qabs x) by ring.
+rewrite <- Qle_minus_iff.
+setoid_replace (Qabs x) with (Qabs (x-y+y)).
+apply Qabs_triangle.
+apply Qabs_wd.
+ring.
+Qed.
diff --git a/theories/QArith/Qcanon.v b/theories/QArith/Qcanon.v
index 98c5ff9e..42522468 100644
--- a/theories/QArith/Qcanon.v
+++ b/theories/QArith/Qcanon.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Qcanon.v 9245 2006-10-17 12:53:34Z notin $ i*)
+(*i $Id: Qcanon.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
Require Import Field.
Require Import QArith.
@@ -101,6 +101,7 @@ Infix "<=" := Qcle : Qc_scope.
Infix ">" := Qcgt : Qc_scope.
Infix ">=" := Qcge : Qc_scope.
Notation "x <= y <= z" := (x<=y/\y<=z) : Qc_scope.
+Notation "x < y < z" := (x<y/\y<z) : Qc_scope.
Definition Qccompare (p q : Qc) := (Qcompare p q).
Notation "p ?= q" := (Qccompare p q) : Qc_scope.
@@ -139,7 +140,7 @@ Theorem Qc_eq_dec : forall x y:Qc, {x=y} + {x<>y}.
Proof.
intros.
destruct (Qeq_dec x y) as [H|H]; auto.
- right; swap H; subst; auto with qarith.
+ right; contradict H; subst; auto with qarith.
Defined.
(** The addition, multiplication and opposite are defined
@@ -347,7 +348,7 @@ Proof.
unfold Qcle, Qclt; intros; eapply Qlt_le_trans; eauto.
Qed.
-Lemma Qlt_trans : forall x y z, x<y -> y<z -> x<z.
+Lemma Qclt_trans : forall x y z, x<y -> y<z -> x<z.
Proof.
unfold Qclt; intros; eapply Qlt_trans; eauto.
Qed.
@@ -472,7 +473,7 @@ Proof.
compute; auto.
Qed.
-Lemma Qpower_pos : forall p n, 0 <= p -> 0 <= p^n.
+Lemma Qcpower_pos : forall p n, 0 <= p -> 0 <= p^n.
Proof.
induction n; simpl; auto with qarith.
intros; compute; intro; discriminate.
@@ -495,23 +496,6 @@ Proof.
intros _ H; inversion H.
Qed.
-(*
-Definition Qcrt : Ring_Theory Qcplus Qcmult 1 0 Qcopp Qc_eq_bool.
-Proof.
-constructor.
-exact Qcplus_comm.
-exact Qcplus_assoc.
-exact Qcmult_comm.
-exact Qcmult_assoc.
-exact Qcplus_0_l.
-exact Qcmult_1_l.
-exact Qcplus_opp_r.
-exact Qcmult_plus_distr_l.
-unfold Is_true; intros x y; generalize (Qc_eq_bool_correct x y);
- case (Qc_eq_bool x y); auto.
-Qed.
-Add Ring Qc Qcplus Qcmult 1 0 Qcopp Qc_eq_bool Qcrt [ Qcmake ].
-*)
Definition Qcrt : ring_theory 0 1 Qcplus Qcmult Qcminus Qcopp (eq(A:=Qc)).
Proof.
constructor.
@@ -547,4 +531,14 @@ auto.
Qed.
-
+Theorem Qc_decomp: forall x y: Qc,
+ (Qred x = x -> Qred y = y -> (x:Q) = y)-> x = y.
+Proof.
+ intros (q, Hq) (q', Hq'); simpl; intros H.
+ assert (H1 := H Hq Hq').
+ subst q'.
+ assert (Hq = Hq').
+ apply Eqdep_dec.eq_proofs_unicity; auto; intros.
+ repeat decide equality.
+ congruence.
+Qed.
diff --git a/theories/QArith/Qfield.v b/theories/QArith/Qfield.v
new file mode 100644
index 00000000..5d548aea
--- /dev/null
+++ b/theories/QArith/Qfield.v
@@ -0,0 +1,153 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i $Id: Qfield.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
+
+Require Export Field.
+Require Export QArith_base.
+Require Import NArithRing.
+
+(** * field and ring tactics for rational numbers *)
+
+Definition Qeq_bool (x y : Q) :=
+ if Qeq_dec x y then true else false.
+
+Lemma Qeq_bool_correct : forall x y : Q, Qeq_bool x y = true -> x==y.
+Proof.
+ intros x y; unfold Qeq_bool in |- *; case (Qeq_dec x y); simpl in |- *; auto.
+ intros _ H; inversion H.
+Qed.
+
+Lemma Qeq_bool_complete : forall x y : Q, x==y -> Qeq_bool x y = true.
+Proof.
+ intros x y; unfold Qeq_bool in |- *; case (Qeq_dec x y); simpl in |- *; auto.
+Qed.
+
+Definition Qsft : field_theory 0 1 Qplus Qmult Qminus Qopp Qdiv Qinv Qeq.
+Proof.
+ constructor.
+ constructor.
+ exact Qplus_0_l.
+ exact Qplus_comm.
+ exact Qplus_assoc.
+ exact Qmult_1_l.
+ exact Qmult_comm.
+ exact Qmult_assoc.
+ exact Qmult_plus_distr_l.
+ reflexivity.
+ exact Qplus_opp_r.
+ discriminate.
+ reflexivity.
+ intros p Hp.
+ rewrite Qmult_comm.
+ apply Qmult_inv_r.
+ exact Hp.
+Qed.
+
+Lemma Qpower_theory : power_theory 1 Qmult Qeq Z_of_N Qpower.
+Proof.
+constructor.
+intros r [|n];
+reflexivity.
+Qed.
+
+Ltac isQcst t :=
+ match t with
+ | inject_Z ?z => isZcst z
+ | Qmake ?n ?d =>
+ match isZcst n with
+ true => isPcst d
+ | _ => false
+ end
+ | _ => false
+ end.
+
+Ltac Qcst t :=
+ match isQcst t with
+ true => t
+ | _ => NotConstant
+ end.
+
+Ltac Qpow_tac t :=
+ match t with
+ | Z0 => N0
+ | Zpos ?n => Ncst (Npos n)
+ | Z_of_N ?n => Ncst n
+ | NtoZ ?n => Ncst n
+ | _ => NotConstant
+ end.
+
+Add Field Qfield : Qsft
+ (decidable Qeq_bool_correct,
+ completeness Qeq_bool_complete,
+ constants [Qcst],
+ power_tac Qpower_theory [Qpow_tac]).
+
+(** Exemple of use: *)
+
+Section Examples.
+
+Let ex1 : forall x y z : Q, (x+y)*z == (x*z)+(y*z).
+ intros.
+ ring.
+Qed.
+
+Let ex2 : forall x y : Q, x+y == y+x.
+ intros.
+ ring.
+Qed.
+
+Let ex3 : forall x y z : Q, (x+y)+z == x+(y+z).
+ intros.
+ ring.
+Qed.
+
+Let ex4 : (inject_Z 1)+(inject_Z 1)==(inject_Z 2).
+ ring.
+Qed.
+
+Let ex5 : 1+1 == 2#1.
+ ring.
+Qed.
+
+Let ex6 : (1#1)+(1#1) == 2#1.
+ ring.
+Qed.
+
+Let ex7 : forall x : Q, x-x== 0.
+ intro.
+ ring.
+Qed.
+
+Let ex8 : forall x : Q, x^1 == x.
+ intro.
+ ring.
+Qed.
+
+Let ex9 : forall x : Q, x^0 == 1.
+ intro.
+ ring.
+Qed.
+
+Let ex10 : forall x y : Q, ~(y==0) -> (x/y)*y == x.
+intros.
+field.
+auto.
+Qed.
+
+End Examples.
+
+Lemma Qopp_plus : forall a b, -(a+b) == -a + -b.
+Proof.
+ intros; ring.
+Qed.
+
+Lemma Qopp_opp : forall q, - -q==q.
+Proof.
+ intros; ring.
+Qed.
diff --git a/theories/QArith/Qpower.v b/theories/QArith/Qpower.v
new file mode 100644
index 00000000..8672592d
--- /dev/null
+++ b/theories/QArith/Qpower.v
@@ -0,0 +1,239 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+Require Import Zpow_facts Qfield Qreduction.
+
+Lemma Qpower_positive_1 : forall n, Qpower_positive 1 n == 1.
+Proof.
+induction n;
+simpl; try rewrite IHn; reflexivity.
+Qed.
+
+Lemma Qpower_1 : forall n, 1^n == 1.
+Proof.
+ intros [|n|n]; simpl; try rewrite Qpower_positive_1; reflexivity.
+Qed.
+
+Lemma Qpower_positive_0 : forall n, Qpower_positive 0 n == 0.
+Proof.
+induction n;
+simpl; try rewrite IHn; reflexivity.
+Qed.
+
+Lemma Qpower_0 : forall n, (n<>0)%Z -> 0^n == 0.
+Proof.
+ intros [|n|n] Hn; try (elim Hn; reflexivity); simpl;
+ rewrite Qpower_positive_0; reflexivity.
+Qed.
+
+Lemma Qpower_not_0_positive : forall a n, ~a==0 -> ~Qpower_positive a n == 0.
+Proof.
+intros a n X H.
+apply X; clear X.
+induction n; simpl in *; try assumption;
+destruct (Qmult_integral _ _ H);
+try destruct (Qmult_integral _ _ H0); auto.
+Qed.
+
+Lemma Qpower_pos_positive : forall p n, 0 <= p -> 0 <= Qpower_positive p n.
+intros p n Hp.
+induction n; simpl; repeat apply Qmult_le_0_compat;assumption.
+Qed.
+
+Lemma Qpower_pos : forall p n, 0 <= p -> 0 <= p^n.
+Proof.
+ intros p [|n|n] Hp; simpl; try discriminate;
+ try apply Qinv_le_0_compat; apply Qpower_pos_positive; assumption.
+Qed.
+
+Lemma Qmult_power_positive : forall a b n, Qpower_positive (a*b) n == (Qpower_positive a n)*(Qpower_positive b n).
+Proof.
+induction n;
+simpl; repeat rewrite IHn; ring.
+Qed.
+
+Lemma Qmult_power : forall a b n, (a*b)^n == a^n*b^n.
+Proof.
+ intros a b [|n|n]; simpl;
+ try rewrite Qmult_power_positive;
+ try rewrite Qinv_mult_distr;
+ reflexivity.
+Qed.
+
+Lemma Qinv_power_positive : forall a n, Qpower_positive (/a) n == /(Qpower_positive a n).
+Proof.
+induction n;
+simpl; repeat (rewrite IHn || rewrite Qinv_mult_distr); reflexivity.
+Qed.
+
+Lemma Qinv_power : forall a n, (/a)^n == /a^n.
+Proof.
+ intros a [|n|n]; simpl;
+ try rewrite Qinv_power_positive;
+ reflexivity.
+Qed.
+
+Lemma Qdiv_power : forall a b n, (a/b)^n == (a^n/b^n).
+Proof.
+unfold Qdiv.
+intros a b n.
+rewrite Qmult_power.
+rewrite Qinv_power.
+reflexivity.
+Qed.
+
+Lemma Qinv_power_n : forall n p, (1#p)^n == /(inject_Z ('p))^n.
+Proof.
+intros n p.
+rewrite Qmake_Qdiv.
+rewrite Qdiv_power.
+rewrite Qpower_1.
+unfold Qdiv.
+ring.
+Qed.
+
+Lemma Qpower_plus_positive : forall a n m, Qpower_positive a (n+m) == (Qpower_positive a n)*(Qpower_positive a m).
+Proof.
+intros a n m.
+unfold Qpower_positive.
+apply pow_pos_Pplus.
+apply Q_Setoid.
+apply Qmult_comp.
+apply Qmult_comm.
+apply Qmult_assoc.
+Qed.
+
+Lemma Qpower_opp : forall a n, a^(-n) == /a^n.
+Proof.
+intros a [|n|n]; simpl; try reflexivity.
+symmetry; apply Qinv_involutive.
+Qed.
+
+Lemma Qpower_minus_positive : forall a (n m:positive), (Pcompare n m Eq=Gt)%positive -> Qpower_positive a (n-m)%positive == (Qpower_positive a n)/(Qpower_positive a m).
+Proof.
+intros a n m H.
+destruct (Qeq_dec a 0).
+ rewrite q.
+ repeat rewrite Qpower_positive_0.
+ reflexivity.
+rewrite <- (Qdiv_mult_l (Qpower_positive a (n - m)) (Qpower_positive a m)) by
+ (apply Qpower_not_0_positive; assumption).
+apply Qdiv_comp;[|reflexivity].
+rewrite Qmult_comm.
+rewrite <- Qpower_plus_positive.
+rewrite Pplus_minus.
+reflexivity.
+assumption.
+Qed.
+
+Lemma Qpower_plus : forall a n m, ~a==0 -> a^(n+m) == a^n*a^m.
+Proof.
+intros a [|n|n] [|m|m] H; simpl; try ring;
+try rewrite Qpower_plus_positive;
+try apply Qinv_mult_distr; try reflexivity;
+case_eq ((n ?= m)%positive Eq); intros H0; simpl;
+ try rewrite Qpower_minus_positive;
+ try rewrite (Pcompare_Eq_eq _ _ H0);
+ try (field; try split; apply Qpower_not_0_positive);
+ try assumption;
+ apply ZC2;
+ assumption.
+Qed.
+
+Lemma Qpower_plus' : forall a n m, (n+m <> 0)%Z -> a^(n+m) == a^n*a^m.
+Proof.
+intros a n m H.
+destruct (Qeq_dec a 0)as [X|X].
+rewrite X.
+rewrite Qpower_0 by assumption.
+destruct n; destruct m; try (elim H; reflexivity);
+ simpl; repeat rewrite Qpower_positive_0; ring_simplify;
+ reflexivity.
+apply Qpower_plus.
+assumption.
+Qed.
+
+Lemma Qpower_mult_positive : forall a n m, Qpower_positive a (n*m) == Qpower_positive (Qpower_positive a n) m.
+Proof.
+intros a n m.
+induction n using Pind.
+ reflexivity.
+rewrite Pmult_Sn_m.
+rewrite Pplus_one_succ_l.
+do 2 rewrite Qpower_plus_positive.
+rewrite IHn.
+rewrite Qmult_power_positive.
+reflexivity.
+Qed.
+
+Lemma Qpower_mult : forall a n m, a^(n*m) == (a^n)^m.
+Proof.
+intros a [|n|n] [|m|m]; simpl;
+ try rewrite Qpower_positive_1;
+ try rewrite Qpower_mult_positive;
+ try rewrite Qinv_power_positive;
+ try rewrite Qinv_involutive;
+ try reflexivity.
+Qed.
+
+Lemma Zpower_Qpower : forall (a n:Z), (0<=n)%Z -> inject_Z (a^n) == (inject_Z a)^n.
+Proof.
+intros a [|n|n] H;[reflexivity| |elim H; reflexivity].
+induction n using Pind.
+ replace (a^1)%Z with a by ring.
+ ring.
+rewrite Zpos_succ_morphism.
+unfold Zsucc.
+rewrite Zpower_exp; auto with *; try discriminate.
+rewrite Qpower_plus' by discriminate.
+rewrite <- IHn by discriminate.
+replace (a^'n*a^1)%Z with (a^'n*a)%Z by ring.
+ring_simplify.
+reflexivity.
+Qed.
+
+Lemma Qsqr_nonneg : forall a, 0 <= a^2.
+Proof.
+intros a.
+destruct (Qlt_le_dec 0 a) as [A|A].
+apply (Qmult_le_0_compat a a);
+ (apply Qlt_le_weak; assumption).
+setoid_replace (a^2) with ((-a)*(-a)) by ring.
+rewrite Qle_minus_iff in A.
+setoid_replace (0+ - a) with (-a) in A by ring.
+apply Qmult_le_0_compat; assumption.
+Qed.
+
+Theorem Qpower_decomp: forall p x y,
+ Qpower_positive (x #y) p == x ^ Zpos p # (Z2P ((Zpos y) ^ Zpos p)).
+Proof.
+induction p; intros; unfold Qmult; simpl.
+(* xI *)
+rewrite IHp, xI_succ_xO, <-Pplus_diag, Pplus_one_succ_l.
+repeat rewrite Zpower_pos_is_exp.
+red; unfold Qmult, Qnum, Qden, Zpower.
+repeat rewrite Zpos_mult_morphism.
+repeat rewrite Z2P_correct.
+repeat rewrite Zpower_pos_1_r; ring.
+apply Zpower_pos_pos; red; auto.
+repeat apply Zmult_lt_0_compat; auto;
+ apply Zpower_pos_pos; red; auto.
+(* xO *)
+rewrite IHp, <-Pplus_diag.
+repeat rewrite Zpower_pos_is_exp.
+red; unfold Qmult, Qnum, Qden, Zpower.
+repeat rewrite Zpos_mult_morphism.
+repeat rewrite Z2P_correct; try ring.
+apply Zpower_pos_pos; red; auto.
+repeat apply Zmult_lt_0_compat; auto;
+ apply Zpower_pos_pos; red; auto.
+(* xO *)
+unfold Qmult; simpl.
+red; simpl; rewrite Zpower_pos_1_r;
+ rewrite Zpos_mult_morphism; ring.
+Qed.
diff --git a/theories/QArith/Qreals.v b/theories/QArith/Qreals.v
index 6bd161f3..c98cef3f 100644
--- a/theories/QArith/Qreals.v
+++ b/theories/QArith/Qreals.v
@@ -6,24 +6,20 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Qreals.v 9245 2006-10-17 12:53:34Z notin $ i*)
+(*i $Id: Qreals.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
Require Export Rbase.
Require Export QArith_base.
-(** A field tactic for rational numbers. *)
+(** Injection of rational numbers into real numbers. *)
-(** Since field cannot operate on setoid datatypes (yet?),
- we translate Q goals into reals before applying field. *)
+Definition Q2R (x : Q) : R := (IZR (Qnum x) * / IZR (QDen x))%R.
Lemma IZR_nz : forall p : positive, IZR (Zpos p) <> 0%R.
intros; apply not_O_IZR; auto with qarith.
Qed.
-Hint Immediate IZR_nz.
-Hint Resolve Rmult_integral_contrapositive.
-
-Definition Q2R (x : Q) : R := (IZR (Qnum x) * / IZR (QDen x))%R.
+Hint Resolve IZR_nz Rmult_integral_contrapositive.
Lemma eqR_Qeq : forall x y : Q, Q2R x = Q2R y -> x==y.
Proof.
@@ -171,7 +167,7 @@ Lemma Q2R_minus : forall x y : Q, Q2R (x-y) = (Q2R x - Q2R y)%R.
unfold Qminus in |- *; intros; rewrite Q2R_plus; rewrite Q2R_opp; auto.
Qed.
-Lemma Q2R_inv : forall x : Q, ~ x==0#1 -> Q2R (/x) = (/ Q2R x)%R.
+Lemma Q2R_inv : forall x : Q, ~ x==0 -> Q2R (/x) = (/ Q2R x)%R.
Proof.
unfold Qinv, Q2R, Qeq in |- *; intros (x1, x2); unfold Qden, Qnum in |- *.
case x1.
@@ -185,7 +181,7 @@ intros;
Qed.
Lemma Q2R_div :
- forall x y : Q, ~ y==0#1 -> Q2R (x/y) = (Q2R x / Q2R y)%R.
+ forall x y : Q, ~ y==0 -> Q2R (x/y) = (Q2R x / Q2R y)%R.
Proof.
unfold Qdiv, Rdiv in |- *.
intros; rewrite Q2R_mult.
@@ -194,16 +190,24 @@ Qed.
Hint Rewrite Q2R_plus Q2R_mult Q2R_opp Q2R_minus Q2R_inv Q2R_div : q2r_simpl.
+Section LegacyQField.
+
+(** In the past, the field tactic was not able to deal with setoid datatypes,
+ so translating from Q to R and applying field on reals was a workaround.
+ See now Qfield for a direct field tactic on Q. *)
+
Ltac QField := apply eqR_Qeq; autorewrite with q2r_simpl; try field; auto.
(** Examples of use: *)
-Goal forall x y z : Q, (x+y)*z == (x*z)+(y*z).
+Let ex1 : forall x y z : Q, (x+y)*z == (x*z)+(y*z).
intros; QField.
-Abort.
+Qed.
-Goal forall x y : Q, ~ y==0#1 -> (x/y)*y == x.
+Let ex2 : forall x y : Q, ~ y==0 -> (x/y)*y == x.
intros; QField.
intro; apply H; apply eqR_Qeq.
rewrite H0; unfold Q2R in |- *; simpl in |- *; field; auto with real.
-Abort.
+Qed.
+
+End LegacyQField. \ No newline at end of file
diff --git a/theories/QArith/Qreduction.v b/theories/QArith/Qreduction.v
index 340cac83..9c522f09 100644
--- a/theories/QArith/Qreduction.v
+++ b/theories/QArith/Qreduction.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Qreduction.v 9245 2006-10-17 12:53:34Z notin $ i*)
+(*i $Id: Qreduction.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
(** Normalisation functions for rational numbers. *)
@@ -145,6 +145,7 @@ Qed.
Definition Qplus' (p q : Q) := Qred (Qplus p q).
Definition Qmult' (p q : Q) := Qred (Qmult p q).
+Definition Qminus' x y := Qred (Qminus x y).
Lemma Qplus'_correct : forall p q : Q, (Qplus' p q)==(Qplus p q).
Proof.
@@ -156,6 +157,11 @@ Proof.
intros; unfold Qmult' in |- *; apply Qred_correct; auto.
Qed.
+Lemma Qminus'_correct : forall p q : Q, (Qminus' p q)==(Qminus p q).
+Proof.
+ intros; unfold Qminus' in |- *; apply Qred_correct; auto.
+Qed.
+
Add Morphism Qplus' : Qplus'_comp.
Proof.
intros; unfold Qplus' in |- *.
@@ -167,3 +173,21 @@ Add Morphism Qmult' : Qmult'_comp.
rewrite H; rewrite H0; auto with qarith.
Qed.
+Add Morphism Qminus' : Qminus'_comp.
+ intros; unfold Qminus' in |- *.
+ rewrite H; rewrite H0; auto with qarith.
+Qed.
+
+Lemma Qred_opp: forall q, Qred (-q) = - (Qred q).
+Proof.
+ intros (x, y); unfold Qred; simpl.
+ rewrite Zggcd_opp; case Zggcd; intros p1 (p2, p3); simpl.
+ unfold Qopp; auto.
+Qed.
+
+Theorem Qred_compare: forall x y,
+ Qcompare x y = Qcompare (Qred x) (Qred y).
+Proof.
+ intros x y; apply Qcompare_comp; apply Qeq_sym; apply Qred_correct.
+Qed.
+
diff --git a/theories/QArith/Qring.v b/theories/QArith/Qring.v
index f9aa3e50..2d45d537 100644
--- a/theories/QArith/Qring.v
+++ b/theories/QArith/Qring.v
@@ -6,99 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Qring.v 9551 2007-01-29 15:13:35Z bgregoir $ i*)
-
-Require Export Ring.
-Require Export QArith_base.
-
-(** * A ring tactic for rational numbers *)
-
-Definition Qeq_bool (x y : Q) :=
- if Qeq_dec x y then true else false.
-
-Lemma Qeq_bool_correct : forall x y : Q, Qeq_bool x y = true -> x==y.
-Proof.
- intros x y; unfold Qeq_bool in |- *; case (Qeq_dec x y); simpl in |- *; auto.
- intros _ H; inversion H.
-Qed.
-
-Definition Qsrt : ring_theory 0 1 Qplus Qmult Qminus Qopp Qeq.
-Proof.
- constructor.
- exact Qplus_0_l.
- exact Qplus_comm.
- exact Qplus_assoc.
- exact Qmult_1_l.
- exact Qmult_comm.
- exact Qmult_assoc.
- exact Qmult_plus_distr_l.
- reflexivity.
- exact Qplus_opp_r.
-Qed.
-
-Ltac isQcst t :=
- match t with
- | inject_Z ?z => isZcst z
- | Qmake ?n ?d =>
- match isZcst n with
- true => isPcst d
- | _ => false
- end
- | _ => false
- end.
-
-Ltac Qcst t :=
- match isQcst t with
- true => t
- | _ => NotConstant
- end.
-
-Add Ring Qring : Qsrt (decidable Qeq_bool_correct, constants [Qcst]).
-(** Exemple of use: *)
-
-Section Examples.
-
-Let ex1 : forall x y z : Q, (x+y)*z == (x*z)+(y*z).
- intros.
- ring.
-Qed.
-
-Let ex2 : forall x y : Q, x+y == y+x.
- intros.
- ring.
-Qed.
-
-Let ex3 : forall x y z : Q, (x+y)+z == x+(y+z).
- intros.
- ring.
-Qed.
-
-Let ex4 : (inject_Z 1)+(inject_Z 1)==(inject_Z 2).
- ring.
-Qed.
-
-Let ex5 : 1+1 == 2#1.
- ring.
-Qed.
-
-Let ex6 : (1#1)+(1#1) == 2#1.
- ring.
-Qed.
-
-Let ex7 : forall x : Q, x-x== 0#1.
- intro.
- ring.
-Qed.
-
-End Examples.
-
-Lemma Qopp_plus : forall a b, -(a+b) == -a + -b.
-Proof.
- intros; ring.
-Qed.
-
-Lemma Qopp_opp : forall q, - -q==q.
-Proof.
- intros; ring.
-Qed.
+(*i $Id: Qring.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
+Require Export Qfield.
diff --git a/theories/QArith/Qround.v b/theories/QArith/Qround.v
new file mode 100644
index 00000000..3f191c75
--- /dev/null
+++ b/theories/QArith/Qround.v
@@ -0,0 +1,139 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+Require Import QArith.
+
+Lemma Qopp_lt_compat: forall p q : Q, p < q -> - q < - p.
+Proof.
+intros (a1,a2) (b1,b2); unfold Qle, Qlt; simpl.
+do 2 rewrite <- Zopp_mult_distr_l; omega.
+Qed.
+
+Hint Resolve Qopp_lt_compat : qarith.
+
+(************)
+
+Coercion Local inject_Z : Z >-> Q.
+
+Definition Qfloor (x:Q) := let (n,d) := x in Zdiv n (Zpos d).
+Definition Qceiling (x:Q) := (-(Qfloor (-x)))%Z.
+
+Lemma Qfloor_Z : forall z:Z, Qfloor z = z.
+Proof.
+intros z.
+simpl.
+auto with *.
+Qed.
+
+Lemma Qceiling_Z : forall z:Z, Qceiling z = z.
+Proof.
+intros z.
+unfold Qceiling.
+simpl.
+rewrite Zdiv_1_r.
+auto with *.
+Qed.
+
+Lemma Qfloor_le : forall x, Qfloor x <= x.
+Proof.
+intros [n d].
+simpl.
+unfold Qle.
+simpl.
+replace (n*1)%Z with n by ring.
+rewrite Zmult_comm.
+apply Z_mult_div_ge.
+auto with *.
+Qed.
+
+Hint Resolve Qfloor_le : qarith.
+
+Lemma Qle_ceiling : forall x, x <= Qceiling x.
+Proof.
+intros x.
+apply Qle_trans with (- - x).
+ rewrite Qopp_involutive.
+ auto with *.
+change (Qceiling x:Q) with (-(Qfloor(-x))).
+auto with *.
+Qed.
+
+Hint Resolve Qle_ceiling : qarith.
+
+Lemma Qle_floor_ceiling : forall x, Qfloor x <= Qceiling x.
+Proof.
+eauto with qarith.
+Qed.
+
+Lemma Qlt_floor : forall x, x < (Qfloor x+1)%Z.
+Proof.
+intros [n d].
+simpl.
+unfold Qlt.
+simpl.
+replace (n*1)%Z with n by ring.
+ring_simplify.
+replace (n / ' d * ' d + ' d)%Z with
+ (('d * (n / 'd) + n mod 'd) + 'd - n mod 'd)%Z by ring.
+rewrite <- Z_div_mod_eq; auto with*.
+rewrite <- Zlt_plus_swap.
+destruct (Z_mod_lt n ('d)); auto with *.
+Qed.
+
+Hint Resolve Qlt_floor : qarith.
+
+Lemma Qceiling_lt : forall x, (Qceiling x-1)%Z < x.
+Proof.
+intros x.
+unfold Qceiling.
+replace (- Qfloor (- x) - 1)%Z with (-(Qfloor (-x) + 1))%Z by ring.
+change ((- (Qfloor (- x) + 1))%Z:Q) with (-(Qfloor (- x) + 1)%Z).
+apply Qlt_le_trans with (- - x); auto with *.
+rewrite Qopp_involutive.
+auto with *.
+Qed.
+
+Hint Resolve Qceiling_lt : qarith.
+
+Lemma Qfloor_resp_le : forall x y, x <= y -> (Qfloor x <= Qfloor y)%Z.
+Proof.
+intros [xn xd] [yn yd] Hxy.
+unfold Qle in *.
+simpl in *.
+rewrite <- (Zdiv_mult_cancel_r xn ('xd) ('yd)); auto with *.
+rewrite <- (Zdiv_mult_cancel_r yn ('yd) ('xd)); auto with *.
+rewrite (Zmult_comm ('yd) ('xd)).
+apply Z_div_le; auto with *.
+Qed.
+
+Hint Resolve Qfloor_resp_le : qarith.
+
+Lemma Qceiling_resp_le : forall x y, x <= y -> (Qceiling x <= Qceiling y)%Z.
+Proof.
+intros x y Hxy.
+unfold Qceiling.
+cut (Qfloor (-y) <= Qfloor (-x))%Z; auto with *.
+Qed.
+
+Hint Resolve Qceiling_resp_le : qarith.
+
+Add Morphism Qfloor with signature Qeq ==> @eq _ as Qfloor_comp.
+Proof.
+intros x y H.
+apply Zle_antisym.
+ auto with *.
+symmetry in H; auto with *.
+Qed.
+
+Add Morphism Qceiling with signature Qeq ==> @eq _ as Qceiling_comp.
+Proof.
+intros x y H.
+apply Zle_antisym.
+ auto with *.
+symmetry in H; auto with *.
+Qed. \ No newline at end of file