summaryrefslogtreecommitdiff
path: root/theories/QArith/QArith_base.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/QArith/QArith_base.v')
-rw-r--r--theories/QArith/QArith_base.v145
1 files changed, 103 insertions, 42 deletions
diff --git a/theories/QArith/QArith_base.v b/theories/QArith/QArith_base.v
index 304fbf77..78cf2892 100644
--- a/theories/QArith/QArith_base.v
+++ b/theories/QArith/QArith_base.v
@@ -6,11 +6,11 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: QArith_base.v 10765 2008-04-08 16:15:23Z msozeau $ i*)
+(*i $Id: QArith_base.v 11301 2008-08-04 19:41:18Z herbelin $ i*)
Require Export ZArith.
Require Export ZArithRing.
-Require Export Setoid.
+Require Export Setoid Bool.
(** * Definition of [Q] and basic properties *)
@@ -28,24 +28,24 @@ Ltac simpl_mult := repeat rewrite Zpos_mult_morphism.
Notation "a # b" := (Qmake a b) (at level 55, no associativity) : Q_scope.
-Definition inject_Z (x : Z) := Qmake x 1.
+Definition inject_Z (x : Z) := Qmake x 1.
Arguments Scope inject_Z [Z_scope].
-Notation " 'QDen' p " := (Zpos (Qden p)) (at level 20, no associativity) : Q_scope.
+Notation QDen p := (Zpos (Qden p)).
Notation " 0 " := (0#1) : Q_scope.
Notation " 1 " := (1#1) : Q_scope.
Definition Qeq (p q : Q) := (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z.
Definition Qle (x y : Q) := (Qnum x * QDen y <= Qnum y * QDen x)%Z.
Definition Qlt (x y : Q) := (Qnum x * QDen y < Qnum y * QDen x)%Z.
-Notation Qgt := (fun a b : Q => Qlt b a).
-Notation Qge := (fun a b : Q => Qle b a).
+Notation Qgt a b := (Qlt b a) (only parsing).
+Notation Qge a b := (Qle b a) (only parsing).
-Infix "==" := Qeq (at level 70, no associativity) : Q_scope.
+Infix "==" := Qeq (at level 70, no associativity) : Q_scope.
Infix "<" := Qlt : Q_scope.
-Infix ">" := Qgt : Q_scope.
Infix "<=" := Qle : Q_scope.
-Infix ">=" := Qge : Q_scope.
+Notation "x > y" := (Qlt y x)(only parsing) : Q_scope.
+Notation "x >= y" := (Qle y x)(only parsing) : Q_scope.
Notation "x <= y <= z" := (x<=y/\y<=z) : Q_scope.
(** Another approach : using Qcompare for defining order relations. *)
@@ -84,7 +84,7 @@ rewrite Zcompare_Gt_Lt_antisym; auto.
rewrite Zcompare_Gt_Lt_antisym in H; auto.
Qed.
-Hint Unfold Qeq Qlt Qle: qarith.
+Hint Unfold Qeq Qlt Qle : qarith.
Hint Extern 5 (?X1 <> ?X2) => intro; discriminate: qarith.
(** * Properties of equality. *)
@@ -94,7 +94,7 @@ Proof.
auto with qarith.
Qed.
-Theorem Qeq_sym : forall x y, x == y -> y == x.
+Theorem Qeq_sym : forall x y, x == y -> y == x.
Proof.
auto with qarith.
Qed.
@@ -102,7 +102,7 @@ Qed.
Theorem Qeq_trans : forall x y z, x == y -> y == z -> x == z.
Proof.
unfold Qeq in |- *; intros.
-apply Zmult_reg_l with (QDen y).
+apply Zmult_reg_l with (QDen y).
auto with qarith.
transitivity (Qnum x * QDen y * QDen z)%Z; try ring.
rewrite H.
@@ -117,6 +117,44 @@ Proof.
intros; case (Z_eq_dec (Qnum x * QDen y) (Qnum y * QDen x)); auto.
Defined.
+Definition Qeq_bool x y :=
+ (Zeq_bool (Qnum x * QDen y) (Qnum y * QDen x))%Z.
+
+Definition Qle_bool x y :=
+ (Zle_bool (Qnum x * QDen y) (Qnum y * QDen x))%Z.
+
+Lemma Qeq_bool_iff : forall x y, Qeq_bool x y = true <-> x == y.
+Proof.
+ unfold Qeq_bool, Qeq; intros.
+ symmetry; apply Zeq_is_eq_bool.
+Qed.
+
+Lemma Qeq_bool_eq : forall x y, Qeq_bool x y = true -> x == y.
+Proof.
+ intros; rewrite <- Qeq_bool_iff; auto.
+Qed.
+
+Lemma Qeq_eq_bool : forall x y, x == y -> Qeq_bool x y = true.
+Proof.
+ intros; rewrite Qeq_bool_iff; auto.
+Qed.
+
+Lemma Qeq_bool_neq : forall x y, Qeq_bool x y = false -> ~ x == y.
+Proof.
+ intros x y H; rewrite <- Qeq_bool_iff, H; discriminate.
+Qed.
+
+Lemma Qle_bool_iff : forall x y, Qle_bool x y = true <-> x <= y.
+Proof.
+ unfold Qle_bool, Qle; intros.
+ symmetry; apply Zle_is_le_bool.
+Qed.
+
+Lemma Qle_bool_imp_le : forall x y, Qle_bool x y = true -> x <= y.
+Proof.
+ intros; rewrite <- Qle_bool_iff; auto.
+Qed.
+
(** We now consider [Q] seen as a setoid. *)
Definition Q_Setoid : Setoid_Theory Q Qeq.
@@ -130,7 +168,7 @@ 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.
+Theorem Qnot_eq_sym : forall x y, ~x == y -> ~y == x.
Proof.
auto with qarith.
Qed.
@@ -139,13 +177,13 @@ Hint Resolve Qnot_eq_sym : qarith.
(** * Addition, multiplication and opposite *)
-(** The addition, multiplication and opposite are defined
+(** The addition, multiplication and opposite are defined
in the straightforward way: *)
Definition Qplus (x y : Q) :=
(Qnum x * QDen y + Qnum y * QDen x) # (Qden x * Qden y).
-Definition Qmult (x y : Q) := (Qnum x * Qnum y) # (Qden x * Qden y).
+Definition Qmult (x y : Q) := (Qnum x * Qnum y) # (Qden x * Qden y).
Definition Qopp (x : Q) := (- Qnum x) # (Qden x).
@@ -164,8 +202,8 @@ Infix "+" := Qplus : Q_scope.
Notation "- x" := (Qopp x) : Q_scope.
Infix "-" := Qminus : Q_scope.
Infix "*" := Qmult : Q_scope.
-Notation "/ x" := (Qinv x) : Q_scope.
-Infix "/" := Qdiv : Q_scope.
+Notation "/ x" := (Qinv x) : Q_scope.
+Infix "/" := Qdiv : Q_scope.
(** A light notation for [Zpos] *)
@@ -181,7 +219,7 @@ Qed.
(** * Setoid compatibility results *)
-Add Morphism Qplus : Qplus_comp.
+Add Morphism Qplus : Qplus_comp.
Proof.
unfold Qeq, Qplus; simpl.
Open Scope Z_scope.
@@ -208,7 +246,7 @@ Qed.
Add Morphism Qminus : Qminus_comp.
Proof.
intros.
- unfold Qminus.
+ unfold Qminus.
rewrite H; rewrite H0; auto with qarith.
Qed.
@@ -232,11 +270,11 @@ Proof.
Open Scope Z_scope.
intros (p1, p2) (q1, q2); simpl.
case p1; simpl.
- intros.
+ intros.
assert (q1 = 0).
elim (Zmult_integral q1 ('p2)); auto with zarith.
intros; discriminate.
- subst; auto.
+ subst; auto.
case q1; simpl; intros; try discriminate.
rewrite (Pmult_comm p2 p); rewrite (Pmult_comm q2 p0); auto.
case q1; simpl; intros; try discriminate.
@@ -254,7 +292,7 @@ Add Morphism Qle with signature Qeq ==> Qeq ==> iff as Qle_comp.
Proof.
cut (forall x1 x2, x1==x2 -> forall x3 x4, x3==x4 -> x1<=x3 -> x2<=x4).
split; apply H; assumption || (apply Qeq_sym ; assumption).
-
+
unfold Qeq, Qle; simpl.
Open Scope Z_scope.
intros (p1, p2) (q1, q2) H (r1, r2) (s1, s2) H0 H1; simpl in *.
@@ -289,14 +327,26 @@ Proof.
replace (s1 * 'q2 * 'p2 * 'r2) with (s1 * 'r2 * 'q2 * 'p2) by ring.
rewrite <- H0.
replace (p1 * 'q2 * 's2 * 'r2) with ('q2 * 's2 * (p1 * 'r2)) by ring.
- replace (r1 * 's2 * 'q2 * 'p2) with ('q2 * 's2 * (r1 * 'p2)) by ring.
+ replace (r1 * 's2 * 'q2 * 'p2) with ('q2 * 's2 * (r1 * 'p2)) by ring.
apply Zlt_gt.
apply Zmult_gt_0_lt_compat_l; auto with zarith.
Close Scope Z_scope.
Qed.
+Add Morphism Qeq_bool with signature Qeq ==> Qeq ==> (@eq bool) as Qeqb_comp.
+Proof.
+ intros; apply eq_true_iff_eq.
+ rewrite 2 Qeq_bool_iff, H, H0; split; auto with qarith.
+Qed.
+
+Add Morphism Qle_bool with signature Qeq ==> Qeq ==> (@eq bool) as Qleb_comp.
+Proof.
+ intros; apply eq_true_iff_eq.
+ rewrite 2 Qle_bool_iff, H, H0.
+ split; auto with qarith.
+Qed.
-Lemma Qcompare_egal_dec: forall n m p q : Q,
+Lemma Qcompare_egal_dec: forall n m p q : Q,
(n<m -> p<q) -> (n==m -> p==q) -> (n>m -> p>q) -> ((n?=m) = (p?=q)).
Proof.
intros.
@@ -306,7 +356,6 @@ Proof.
omega.
Qed.
-
Add Morphism Qcompare : Qcompare_comp.
Proof.
intros; apply Qcompare_egal_dec; rewrite H; rewrite H0; auto.
@@ -341,7 +390,7 @@ Lemma Qplus_0_r : forall x, x+0 == x.
Proof.
intros (x1, x2); unfold Qeq, Qplus; simpl.
rewrite Pmult_comm; simpl; ring.
-Qed.
+Qed.
(** Commutativity of addition: *)
@@ -374,6 +423,18 @@ Proof.
intros; red; simpl; rewrite Pmult_assoc; ring.
Qed.
+(** multiplication and zero *)
+
+Lemma Qmult_0_l : forall x , 0*x == 0.
+Proof.
+ intros; compute; reflexivity.
+Qed.
+
+Lemma Qmult_0_r : forall x , x*0 == 0.
+Proof.
+ intros; red; simpl; ring.
+Qed.
+
(** [1] is a neutral element for multiplication: *)
Lemma Qmult_1_l : forall n, 1*n == n.
@@ -385,7 +446,7 @@ Theorem Qmult_1_r : forall n, n*1==n.
Proof.
intro; red; simpl.
rewrite Zmult_1_r with (n := Qnum n).
- rewrite Pmult_comm; simpl; trivial.
+ rewrite Pmult_comm; simpl; trivial.
Qed.
(** Commutativity of multiplication *)
@@ -427,7 +488,7 @@ Proof.
rewrite <- H0; ring.
Qed.
-(** * Inverse and division. *)
+(** * Inverse and division. *)
Lemma Qinv_involutive : forall q, (/ / q) == q.
Proof.
@@ -438,13 +499,13 @@ Theorem Qmult_inv_r : forall x, ~ x == 0 -> x*(/x) == 1.
Proof.
intros (x1, x2); unfold Qeq, Qdiv, Qmult; case x1; simpl;
intros; simpl_mult; try ring.
- elim H; auto.
+ elim H; auto.
Qed.
Lemma Qinv_mult_distr : forall p q, / (p * q) == /p * /q.
Proof.
intros (x1,x2) (y1,y2); unfold Qeq, Qinv, Qmult; simpl.
- destruct x1; simpl; auto;
+ destruct x1; simpl; auto;
destruct y1; simpl; auto.
Qed.
@@ -485,10 +546,10 @@ Proof.
red; trivial.
apply Zle_trans with (y1 * 'x2 * 'z2).
replace (x1 * 'z2 * 'y2) with (x1 * 'y2 * 'z2) by ring.
- apply Zmult_le_compat_r; auto with zarith.
+ apply Zmult_le_compat_r; auto with zarith.
replace (y1 * 'x2 * 'z2) with (y1 * 'z2 * 'x2) by ring.
replace (z1 * 'x2 * 'y2) with (z1 * 'y2 * 'x2) by ring.
- apply Zmult_le_compat_r; auto with zarith.
+ apply Zmult_le_compat_r; auto with zarith.
Close Scope Z_scope.
Qed.
@@ -516,9 +577,9 @@ Proof.
apply Zgt_le_trans with (y1 * 'x2 * 'z2).
replace (y1 * 'x2 * 'z2) with (y1 * 'z2 * 'x2) by ring.
replace (z1 * 'x2 * 'y2) with (z1 * 'y2 * 'x2) by ring.
- apply Zmult_gt_compat_r; auto with zarith.
+ apply Zmult_gt_compat_r; auto with zarith.
replace (x1 * 'z2 * 'y2) with (x1 * 'y2 * 'z2) by ring.
- apply Zmult_le_compat_r; auto with zarith.
+ apply Zmult_le_compat_r; auto with zarith.
Close Scope Z_scope.
Qed.
@@ -532,9 +593,9 @@ Proof.
apply Zle_gt_trans with (y1 * 'x2 * 'z2).
replace (y1 * 'x2 * 'z2) with (y1 * 'z2 * 'x2) by ring.
replace (z1 * 'x2 * 'y2) with (z1 * 'y2 * 'x2) by ring.
- apply Zmult_le_compat_r; auto with zarith.
+ apply Zmult_le_compat_r; auto with zarith.
replace (x1 * 'z2 * 'y2) with (x1 * 'y2 * 'z2) by ring.
- apply Zmult_gt_compat_r; auto with zarith.
+ apply Zmult_gt_compat_r; auto with zarith.
Close Scope Z_scope.
Qed.
@@ -572,7 +633,7 @@ 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
+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. *)
@@ -679,7 +740,7 @@ Proof.
intros [[|n|n] d] Ha; assumption.
Qed.
-Lemma Qle_shift_div_l : forall a b c,
+Lemma Qle_shift_div_l : forall a b c,
0 < c -> a*c <= b -> a <= b/c.
Proof.
intros a b c Hc H.
@@ -690,7 +751,7 @@ rewrite Qmult_div_r; try assumption.
auto with *.
Qed.
-Lemma Qle_shift_inv_l : forall a c,
+Lemma Qle_shift_inv_l : forall a c,
0 < c -> a*c <= 1 -> a <= /c.
Proof.
intros a c Hc H.
@@ -699,7 +760,7 @@ change (a <= 1/c).
apply Qle_shift_div_l; assumption.
Qed.
-Lemma Qle_shift_div_r : forall a b c,
+Lemma Qle_shift_div_r : forall a b c,
0 < b -> a <= c*b -> a/b <= c.
Proof.
intros a b c Hc H.
@@ -710,7 +771,7 @@ rewrite Qmult_div_r; try assumption.
auto with *.
Qed.
-Lemma Qle_shift_inv_r : forall b c,
+Lemma Qle_shift_inv_r : forall b c,
0 < b -> 1 <= c*b -> /b <= c.
Proof.
intros b c Hc H.
@@ -772,7 +833,7 @@ Qed.
(** * Rational to the n-th power *)
-Definition Qpower_positive (q:Q)(p:positive) : Q :=
+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.