summaryrefslogtreecommitdiff
path: root/theories/QArith/Qcanon.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/QArith/Qcanon.v')
-rw-r--r--theories/QArith/Qcanon.v344
1 files changed, 184 insertions, 160 deletions
diff --git a/theories/QArith/Qcanon.v b/theories/QArith/Qcanon.v
index 9cbd400d..98c5ff9e 100644
--- a/theories/QArith/Qcanon.v
+++ b/theories/QArith/Qcanon.v
@@ -6,9 +6,11 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Qcanon.v 8989 2006-06-25 22:17:49Z letouzey $ i*)
+(*i $Id: Qcanon.v 9245 2006-10-17 12:53:34Z notin $ i*)
+Require Import Field.
Require Import QArith.
+Require Import Znumtheory.
Require Import Eqdep_dec.
(** [Qc] : A canonical representation of rational numbers.
@@ -22,50 +24,50 @@ Arguments Scope Qcmake [Q_scope].
Open Scope Qc_scope.
Lemma Qred_identity :
- forall q:Q, Zgcd (Qnum q) (QDen q) = 1%Z -> Qred q = q.
+ forall q:Q, Zgcd (Qnum q) (QDen q) = 1%Z -> Qred q = q.
Proof.
-unfold Qred; intros (a,b); simpl.
-generalize (Zggcd_gcd a ('b)) (Zggcd_correct_divisors a ('b)).
-intros.
-rewrite H1 in H; clear H1.
-destruct (Zggcd a ('b)) as (g,(aa,bb)); simpl in *; subst.
-destruct H0.
-rewrite Zmult_1_l in H, H0.
-subst; simpl; auto.
+ unfold Qred; intros (a,b); simpl.
+ generalize (Zggcd_gcd a ('b)) (Zggcd_correct_divisors a ('b)).
+ intros.
+ rewrite H1 in H; clear H1.
+ destruct (Zggcd a ('b)) as (g,(aa,bb)); simpl in *; subst.
+ destruct H0.
+ rewrite Zmult_1_l in H, H0.
+ subst; simpl; auto.
Qed.
Lemma Qred_identity2 :
- forall q:Q, Qred q = q -> Zgcd (Qnum q) (QDen q) = 1%Z.
-Proof.
-unfold Qred; intros (a,b); simpl.
-generalize (Zggcd_gcd a ('b)) (Zggcd_correct_divisors a ('b)) (Zgcd_is_pos a ('b)).
-intros.
-rewrite <- H; rewrite <- H in H1; clear H.
-destruct (Zggcd a ('b)) as (g,(aa,bb)); simpl in *; subst.
-injection H2; intros; clear H2.
-destruct H0.
-clear H0 H3.
-destruct g as [|g|g]; destruct bb as [|bb|bb]; simpl in *; try discriminate.
-f_equal.
-apply Pmult_reg_r with bb.
-injection H2; intros.
-rewrite <- H0.
-rewrite H; simpl; auto.
-elim H1; auto.
+ forall q:Q, Qred q = q -> Zgcd (Qnum q) (QDen q) = 1%Z.
+Proof.
+ unfold Qred; intros (a,b); simpl.
+ generalize (Zggcd_gcd a ('b)) (Zggcd_correct_divisors a ('b)) (Zgcd_is_pos a ('b)).
+ intros.
+ rewrite <- H; rewrite <- H in H1; clear H.
+ destruct (Zggcd a ('b)) as (g,(aa,bb)); simpl in *; subst.
+ injection H2; intros; clear H2.
+ destruct H0.
+ clear H0 H3.
+ destruct g as [|g|g]; destruct bb as [|bb|bb]; simpl in *; try discriminate.
+ f_equal.
+ apply Pmult_reg_r with bb.
+ injection H2; intros.
+ rewrite <- H0.
+ rewrite H; simpl; auto.
+ elim H1; auto.
Qed.
Lemma Qred_iff : forall q:Q, Qred q = q <-> Zgcd (Qnum q) (QDen q) = 1%Z.
Proof.
-split; intros.
-apply Qred_identity2; auto.
-apply Qred_identity; auto.
+ split; intros.
+ apply Qred_identity2; auto.
+ apply Qred_identity; auto.
Qed.
Lemma Qred_involutive : forall q:Q, Qred (Qred q) = Qred q.
Proof.
-intros; apply Qred_complete.
-apply Qred_correct.
+ intros; apply Qred_complete.
+ apply Qred_correct.
Qed.
Definition Q2Qc (q:Q) : Qc := Qcmake (Qred q) (Qred_involutive q).
@@ -74,16 +76,16 @@ Notation " !! " := Q2Qc : Qc_scope.
Lemma Qc_is_canon : forall q q' : Qc, q == q' -> q = q'.
Proof.
-intros (q,proof_q) (q',proof_q').
-simpl.
-intros H.
-assert (H0:=Qred_complete _ _ H).
-assert (q = q') by congruence.
-subst q'.
-assert (proof_q = proof_q').
- apply eq_proofs_unicity; auto; intros.
- repeat decide equality.
-congruence.
+ intros (q,proof_q) (q',proof_q').
+ simpl.
+ intros H.
+ assert (H0:=Qred_complete _ _ H).
+ assert (q = q') by congruence.
+ subst q'.
+ assert (proof_q = proof_q').
+ apply eq_proofs_unicity; auto; intros.
+ repeat decide equality.
+ congruence.
Qed.
Hint Resolve Qc_is_canon.
@@ -105,39 +107,39 @@ Notation "p ?= q" := (Qccompare p q) : Qc_scope.
Lemma Qceq_alt : forall p q, (p = q) <-> (p ?= q) = Eq.
Proof.
-unfold Qccompare.
-intros; rewrite <- Qeq_alt.
-split; auto.
-intro H; rewrite H; auto with qarith.
+ unfold Qccompare.
+ intros; rewrite <- Qeq_alt.
+ split; auto.
+ intro H; rewrite H; auto with qarith.
Qed.
Lemma Qclt_alt : forall p q, (p<q) <-> (p?=q = Lt).
Proof.
-intros; exact (Qlt_alt p q).
+ intros; exact (Qlt_alt p q).
Qed.
Lemma Qcgt_alt : forall p q, (p>q) <-> (p?=q = Gt).
Proof.
-intros; exact (Qgt_alt p q).
+ intros; exact (Qgt_alt p q).
Qed.
Lemma Qle_alt : forall p q, (p<=q) <-> (p?=q <> Gt).
Proof.
-intros; exact (Qle_alt p q).
+ intros; exact (Qle_alt p q).
Qed.
Lemma Qge_alt : forall p q, (p>=q) <-> (p?=q <> Lt).
Proof.
-intros; exact (Qge_alt p q).
+ intros; exact (Qge_alt p q).
Qed.
(** equality on [Qc] is decidable: *)
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.
+ intros.
+ destruct (Qeq_dec x y) as [H|H]; auto.
+ right; swap H; subst; auto with qarith.
Defined.
(** The addition, multiplication and opposite are defined
@@ -160,8 +162,8 @@ Infix "/" := Qcdiv : Qc_scope.
Lemma Q_apart_0_1 : 1 <> 0.
Proof.
- unfold Q2Qc.
- intros H; discriminate H.
+ unfold Q2Qc.
+ intros H; discriminate H.
Qed.
Ltac qc := match goal with
@@ -175,309 +177,309 @@ Opaque Qred.
Theorem Qcplus_assoc : forall x y z, x+(y+z)=(x+y)+z.
Proof.
- intros; qc; apply Qplus_assoc.
+ intros; qc; apply Qplus_assoc.
Qed.
(** [0] is a neutral element for addition: *)
Lemma Qcplus_0_l : forall x, 0+x = x.
Proof.
- intros; qc; apply Qplus_0_l.
+ intros; qc; apply Qplus_0_l.
Qed.
Lemma Qcplus_0_r : forall x, x+0 = x.
Proof.
- intros; qc; apply Qplus_0_r.
+ intros; qc; apply Qplus_0_r.
Qed.
(** Commutativity of addition: *)
Theorem Qcplus_comm : forall x y, x+y = y+x.
Proof.
- intros; qc; apply Qplus_comm.
+ intros; qc; apply Qplus_comm.
Qed.
(** Properties of [Qopp] *)
Lemma Qcopp_involutive : forall q, - -q = q.
Proof.
- intros; qc; apply Qopp_involutive.
+ intros; qc; apply Qopp_involutive.
Qed.
Theorem Qcplus_opp_r : forall q, q+(-q) = 0.
Proof.
- intros; qc; apply Qplus_opp_r.
+ intros; qc; apply Qplus_opp_r.
Qed.
(** Multiplication is associative: *)
Theorem Qcmult_assoc : forall n m p, n*(m*p)=(n*m)*p.
Proof.
- intros; qc; apply Qmult_assoc.
+ intros; qc; apply Qmult_assoc.
Qed.
(** [1] is a neutral element for multiplication: *)
Lemma Qcmult_1_l : forall n, 1*n = n.
Proof.
- intros; qc; apply Qmult_1_l.
+ intros; qc; apply Qmult_1_l.
Qed.
Theorem Qcmult_1_r : forall n, n*1=n.
Proof.
- intros; qc; apply Qmult_1_r.
+ intros; qc; apply Qmult_1_r.
Qed.
(** Commutativity of multiplication *)
Theorem Qcmult_comm : forall x y, x*y=y*x.
Proof.
- intros; qc; apply Qmult_comm.
+ intros; qc; apply Qmult_comm.
Qed.
(** Distributivity *)
Theorem Qcmult_plus_distr_r : forall x y z, x*(y+z)=(x*y)+(x*z).
Proof.
- intros; qc; apply Qmult_plus_distr_r.
+ intros; qc; apply Qmult_plus_distr_r.
Qed.
Theorem Qcmult_plus_distr_l : forall x y z, (x+y)*z=(x*z)+(y*z).
Proof.
- intros; qc; apply Qmult_plus_distr_l.
+ intros; qc; apply Qmult_plus_distr_l.
Qed.
(** Integrality *)
Theorem Qcmult_integral : forall x y, x*y=0 -> x=0 \/ y=0.
Proof.
- intros.
- destruct (Qmult_integral x y); try qc; auto.
- injection H; clear H; intros.
- rewrite <- (Qred_correct (x*y)).
- rewrite <- (Qred_correct 0).
- rewrite H; auto with qarith.
+ intros.
+ destruct (Qmult_integral x y); try qc; auto.
+ injection H; clear H; intros.
+ rewrite <- (Qred_correct (x*y)).
+ rewrite <- (Qred_correct 0).
+ rewrite H; auto with qarith.
Qed.
Theorem Qcmult_integral_l : forall x y, ~ x = 0 -> x*y = 0 -> y = 0.
Proof.
- intros; destruct (Qcmult_integral _ _ H0); tauto.
+ intros; destruct (Qcmult_integral _ _ H0); tauto.
Qed.
(** Inverse and division. *)
Theorem Qcmult_inv_r : forall x, x<>0 -> x*(/x) = 1.
Proof.
- intros; qc; apply Qmult_inv_r; auto.
+ intros; qc; apply Qmult_inv_r; auto.
Qed.
Theorem Qcmult_inv_l : forall x, x<>0 -> (/x)*x = 1.
Proof.
- intros.
- rewrite Qcmult_comm.
- apply Qcmult_inv_r; auto.
+ intros.
+ rewrite Qcmult_comm.
+ apply Qcmult_inv_r; auto.
Qed.
Lemma Qcinv_mult_distr : forall p q, / (p * q) = /p * /q.
Proof.
- intros; qc; apply Qinv_mult_distr.
+ intros; qc; apply Qinv_mult_distr.
Qed.
Theorem Qcdiv_mult_l : forall x y, y<>0 -> (x*y)/y = x.
Proof.
- unfold Qcdiv.
- intros.
- rewrite <- Qcmult_assoc.
- rewrite Qcmult_inv_r; auto.
- apply Qcmult_1_r.
+ unfold Qcdiv.
+ intros.
+ rewrite <- Qcmult_assoc.
+ rewrite Qcmult_inv_r; auto.
+ apply Qcmult_1_r.
Qed.
Theorem Qcmult_div_r : forall x y, ~ y = 0 -> y*(x/y) = x.
Proof.
- unfold Qcdiv.
- intros.
- rewrite Qcmult_assoc.
- rewrite Qcmult_comm.
- rewrite Qcmult_assoc.
- rewrite Qcmult_inv_l; auto.
- apply Qcmult_1_l.
+ unfold Qcdiv.
+ intros.
+ rewrite Qcmult_assoc.
+ rewrite Qcmult_comm.
+ rewrite Qcmult_assoc.
+ rewrite Qcmult_inv_l; auto.
+ apply Qcmult_1_l.
Qed.
(** Properties of order upon Q. *)
Lemma Qcle_refl : forall x, x<=x.
Proof.
-unfold Qcle; intros; simpl; apply Qle_refl.
+ unfold Qcle; intros; simpl; apply Qle_refl.
Qed.
Lemma Qcle_antisym : forall x y, x<=y -> y<=x -> x=y.
Proof.
-unfold Qcle; intros; simpl in *.
-apply Qc_is_canon; apply Qle_antisym; auto.
+ unfold Qcle; intros; simpl in *.
+ apply Qc_is_canon; apply Qle_antisym; auto.
Qed.
Lemma Qcle_trans : forall x y z, x<=y -> y<=z -> x<=z.
Proof.
-unfold Qcle; intros; eapply Qle_trans; eauto.
+ unfold Qcle; intros; eapply Qle_trans; eauto.
Qed.
Lemma Qclt_not_eq : forall x y, x<y -> x<>y.
Proof.
-unfold Qclt; intros; simpl in *.
-intro; destruct (Qlt_not_eq _ _ H).
-subst; auto with qarith.
+ unfold Qclt; intros; simpl in *.
+ intro; destruct (Qlt_not_eq _ _ H).
+ subst; auto with qarith.
Qed.
(** Large = strict or equal *)
Lemma Qclt_le_weak : forall x y, x<y -> x<=y.
Proof.
-unfold Qcle, Qclt; intros; apply Qlt_le_weak; auto.
+ unfold Qcle, Qclt; intros; apply Qlt_le_weak; auto.
Qed.
Lemma Qcle_lt_trans : forall x y z, x<=y -> y<z -> x<z.
Proof.
-unfold Qcle, Qclt; intros; eapply Qle_lt_trans; eauto.
+ unfold Qcle, Qclt; intros; eapply Qle_lt_trans; eauto.
Qed.
Lemma Qclt_le_trans : forall x y z, x<y -> y<=z -> x<z.
Proof.
-unfold Qcle, Qclt; intros; eapply Qlt_le_trans; eauto.
+ unfold Qcle, Qclt; intros; eapply Qlt_le_trans; eauto.
Qed.
Lemma Qlt_trans : forall x y z, x<y -> y<z -> x<z.
Proof.
-unfold Qclt; intros; eapply Qlt_trans; eauto.
+ unfold Qclt; intros; eapply Qlt_trans; eauto.
Qed.
(** [x<y] iff [~(y<=x)] *)
Lemma Qcnot_lt_le : forall x y, ~ x<y -> y<=x.
Proof.
-unfold Qcle, Qclt; intros; apply Qnot_lt_le; auto.
+ unfold Qcle, Qclt; intros; apply Qnot_lt_le; auto.
Qed.
Lemma Qcnot_le_lt : forall x y, ~ x<=y -> y<x.
Proof.
-unfold Qcle, Qclt; intros; apply Qnot_le_lt; auto.
+ unfold Qcle, Qclt; intros; apply Qnot_le_lt; auto.
Qed.
Lemma Qclt_not_le : forall x y, x<y -> ~ y<=x.
Proof.
-unfold Qcle, Qclt; intros; apply Qlt_not_le; auto.
+ unfold Qcle, Qclt; intros; apply Qlt_not_le; auto.
Qed.
Lemma Qcle_not_lt : forall x y, x<=y -> ~ y<x.
Proof.
-unfold Qcle, Qclt; intros; apply Qle_not_lt; auto.
+ unfold Qcle, Qclt; intros; apply Qle_not_lt; auto.
Qed.
Lemma Qcle_lt_or_eq : forall x y, x<=y -> x<y \/ x==y.
Proof.
-unfold Qcle, Qclt; intros; apply Qle_lt_or_eq; auto.
+ unfold Qcle, Qclt; intros; apply Qle_lt_or_eq; auto.
Qed.
(** Some decidability results about orders. *)
Lemma Qc_dec : forall x y, {x<y} + {y<x} + {x=y}.
Proof.
-unfold Qclt, Qcle; intros.
-destruct (Q_dec x y) as [H|H].
-left; auto.
-right; apply Qc_is_canon; auto.
+ unfold Qclt, Qcle; intros.
+ destruct (Q_dec x y) as [H|H].
+ left; auto.
+ right; apply Qc_is_canon; auto.
Defined.
Lemma Qclt_le_dec : forall x y, {x<y} + {y<=x}.
Proof.
-unfold Qclt, Qcle; intros; apply Qlt_le_dec; auto.
+ unfold Qclt, Qcle; intros; apply Qlt_le_dec; auto.
Defined.
(** Compatibility of operations with respect to order. *)
Lemma Qcopp_le_compat : forall p q, p<=q -> -q <= -p.
Proof.
-unfold Qcle, Qcopp; intros; simpl in *.
-repeat rewrite Qred_correct.
-apply Qopp_le_compat; auto.
+ unfold Qcle, Qcopp; intros; simpl in *.
+ repeat rewrite Qred_correct.
+ apply Qopp_le_compat; auto.
Qed.
Lemma Qcle_minus_iff : forall p q, p <= q <-> 0 <= q+-p.
Proof.
-unfold Qcle, Qcminus; intros; simpl in *.
-repeat rewrite Qred_correct.
-apply Qle_minus_iff; auto.
+ unfold Qcle, Qcminus; intros; simpl in *.
+ repeat rewrite Qred_correct.
+ apply Qle_minus_iff; auto.
Qed.
Lemma Qclt_minus_iff : forall p q, p < q <-> 0 < q+-p.
Proof.
-unfold Qclt, Qcplus, Qcopp; intros; simpl in *.
-repeat rewrite Qred_correct.
-apply Qlt_minus_iff; auto.
+ unfold Qclt, Qcplus, Qcopp; intros; simpl in *.
+ repeat rewrite Qred_correct.
+ apply Qlt_minus_iff; auto.
Qed.
Lemma Qcplus_le_compat :
- forall x y z t, x<=y -> z<=t -> x+z <= y+t.
+ forall x y z t, x<=y -> z<=t -> x+z <= y+t.
Proof.
-unfold Qcplus, Qcle; intros; simpl in *.
-repeat rewrite Qred_correct.
-apply Qplus_le_compat; auto.
+ unfold Qcplus, Qcle; intros; simpl in *.
+ repeat rewrite Qred_correct.
+ apply Qplus_le_compat; auto.
Qed.
Lemma Qcmult_le_compat_r : forall x y z, x <= y -> 0 <= z -> x*z <= y*z.
Proof.
-unfold Qcmult, Qcle; intros; simpl in *.
-repeat rewrite Qred_correct.
-apply Qmult_le_compat_r; auto.
+ unfold Qcmult, Qcle; intros; simpl in *.
+ repeat rewrite Qred_correct.
+ apply Qmult_le_compat_r; auto.
Qed.
Lemma Qcmult_lt_0_le_reg_r : forall x y z, 0 < z -> x*z <= y*z -> x <= y.
Proof.
-unfold Qcmult, Qcle, Qclt; intros; simpl in *.
-repeat progress rewrite Qred_correct in * |-.
-eapply Qmult_lt_0_le_reg_r; eauto.
+ unfold Qcmult, Qcle, Qclt; intros; simpl in *.
+ repeat progress rewrite Qred_correct in * |-.
+ eapply Qmult_lt_0_le_reg_r; eauto.
Qed.
Lemma Qcmult_lt_compat_r : forall x y z, 0 < z -> x < y -> x*z < y*z.
Proof.
-unfold Qcmult, Qclt; intros; simpl in *.
-repeat progress rewrite Qred_correct in *.
-eapply Qmult_lt_compat_r; eauto.
+ unfold Qcmult, Qclt; intros; simpl in *.
+ repeat progress rewrite Qred_correct in *.
+ eapply Qmult_lt_compat_r; eauto.
Qed.
(** Rational to the n-th power *)
Fixpoint Qcpower (q:Qc)(n:nat) { struct n } : Qc :=
- match n with
- | O => 1
- | S n => q * (Qcpower q n)
- end.
+ match n with
+ | O => 1
+ | S n => q * (Qcpower q n)
+ end.
Notation " q ^ n " := (Qcpower q n) : Qc_scope.
Lemma Qcpower_1 : forall n, 1^n = 1.
Proof.
-induction n; simpl; auto with qarith.
-rewrite IHn; auto with qarith.
+ induction n; simpl; auto with qarith.
+ rewrite IHn; auto with qarith.
Qed.
Lemma Qcpower_0 : forall n, n<>O -> 0^n = 0.
Proof.
-destruct n; simpl.
-destruct 1; auto.
-intros.
-apply Qc_is_canon.
-simpl.
-compute; auto.
+ destruct n; simpl.
+ destruct 1; auto.
+ intros.
+ apply Qc_is_canon.
+ simpl.
+ compute; auto.
Qed.
Lemma Qpower_pos : forall p n, 0 <= p -> 0 <= p^n.
Proof.
-induction n; simpl; auto with qarith.
-intros; compute; intro; discriminate.
-intros.
-apply Qcle_trans with (0*(p^n)).
-compute; intro; discriminate.
-apply Qcmult_le_compat_r; auto.
+ induction n; simpl; auto with qarith.
+ intros; compute; intro; discriminate.
+ intros.
+ apply Qcle_trans with (0*(p^n)).
+ compute; intro; discriminate.
+ apply Qcmult_le_compat_r; auto.
Qed.
(** And now everything is easier concerning tactics: *)
@@ -488,10 +490,12 @@ Definition Qc_eq_bool (x y : Qc) :=
if Qc_eq_dec x y then true else false.
Lemma Qc_eq_bool_correct : forall x y : Qc, Qc_eq_bool x y = true -> x=y.
-intros x y; unfold Qc_eq_bool in |- *; case (Qc_eq_dec x y); simpl in |- *; auto.
-intros _ H; inversion H.
+Proof.
+ intros x y; unfold Qc_eq_bool in |- *; case (Qc_eq_dec x y); simpl in |- *; auto.
+ intros _ H; inversion H.
Qed.
+(*
Definition Qcrt : Ring_Theory Qcplus Qcmult 1 0 Qcopp Qc_eq_bool.
Proof.
constructor.
@@ -506,17 +510,37 @@ 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.
+ exact Qcplus_0_l.
+ exact Qcplus_comm.
+ exact Qcplus_assoc.
+ exact Qcmult_1_l.
+ exact Qcmult_comm.
+ exact Qcmult_assoc.
+ exact Qcmult_plus_distr_l.
+ reflexivity.
+ exact Qcplus_opp_r.
+Qed.
-(** A field tactic for rational numbers *)
+Definition Qcft :
+ field_theory 0%Qc 1%Qc Qcplus Qcmult Qcminus Qcopp Qcdiv Qcinv (eq(A:=Qc)).
+Proof.
+ constructor.
+ exact Qcrt.
+ exact Q_apart_0_1.
+ reflexivity.
+ exact Qcmult_inv_l.
+Qed.
-Require Import Field.
+Add Field Qcfield : Qcft.
-Add Field Qc Qcplus Qcmult 1 0 Qcopp Qc_eq_bool Qcinv Qcrt Qcmult_inv_l
- with div:=Qcdiv.
+(** A field tactic for rational numbers *)
-Example test_field : forall x y : Qc, y<>0 -> (x/y)*y = x.
+Example test_field : (forall x y : Qc, y<>0 -> (x/y)*y = x)%Qc.
intros.
field.
auto.