aboutsummaryrefslogtreecommitdiffhomepage
path: root/theories/QArith
diff options
context:
space:
mode:
authorGravatar letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7>2009-11-03 08:24:06 +0000
committerGravatar letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7>2009-11-03 08:24:06 +0000
commit4f0ad99adb04e7f2888e75f2a10e8c916dde179b (patch)
tree4b52d7436fe06f4b2babfd5bfed84762440e7de7 /theories/QArith
parent4e68924f48d3f6d5ffdf1cd394b590b5a6e15ea1 (diff)
OrderedType implementation for various numerical datatypes + min/max structures
- A richer OrderedTypeFull interface : OrderedType + predicate "le" - Implementations {Nat,N,P,Z,Q}OrderedType.v, also providing "order" tactics - By the way: as suggested by S. Lescuyer, specification of compare is now inductive - GenericMinMax: axiomatisation + properties of min and max out of OrderedTypeFull structures. - MinMax.v, {Z,P,N,Q}minmax.v are specialization of GenericMinMax, with also some domain-specific results, and compatibility layer with already existing results. - Some ML code of plugins had to be adapted, otherwise wrong "eq", "lt" or simimlar constants were found by functions like coq_constant. - Beware of the aliasing problems: for instance eq:=@eq t instead of eq:=@eq M.t in Make_UDT made (r)omega stopped working (Z_as_OT.t instead of Z in statement of Zmax_spec). - Some Morphism declaration are now ambiguous: switch to new syntax anyway. - Misc adaptations of FSets/MSets - Classes/RelationPairs.v: from two relations over A and B, we inspect relations over A*B and their properties in terms of classes. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12461 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'theories/QArith')
-rw-r--r--theories/QArith/QArith_base.v150
-rw-r--r--theories/QArith/QOrderedType.v68
-rw-r--r--theories/QArith/Qminmax.v130
3 files changed, 260 insertions, 88 deletions
diff --git a/theories/QArith/QArith_base.v b/theories/QArith/QArith_base.v
index c87c9df9e..70830ad80 100644
--- a/theories/QArith/QArith_base.v
+++ b/theories/QArith/QArith_base.v
@@ -10,7 +10,7 @@
Require Export ZArith.
Require Export ZArithRing.
-Require Export Setoid Bool.
+Require Export Morphisms Setoid Bool.
(** * Definition of [Q] and basic properties *)
@@ -101,7 +101,7 @@ Qed.
Theorem Qeq_trans : forall x y z, x == y -> y == z -> x == z.
Proof.
-unfold Qeq in |- *; intros.
+unfold Qeq; intros.
apply Zmult_reg_l with (QDen y).
auto with qarith.
transitivity (Qnum x * QDen y * QDen z)%Z; try ring.
@@ -110,6 +110,15 @@ transitivity (Qnum y * QDen z * QDen x)%Z; try ring.
rewrite H0; ring.
Qed.
+Hint Resolve Qeq_refl : qarith.
+Hint Resolve Qeq_sym : qarith.
+Hint Resolve Qeq_trans : qarith.
+
+(** In a word, [Qeq] is a setoid equality. *)
+
+Instance Q_Setoid : Equivalence Qeq.
+Proof. split; red; eauto with qarith. Qed.
+
(** Furthermore, this equality is decidable: *)
Theorem Qeq_dec : forall x y, {x==y} + {~ x==y}.
@@ -155,18 +164,6 @@ Proof.
intros; rewrite <- Qle_bool_iff; auto.
Qed.
-(** We now consider [Q] seen as a setoid. *)
-
-Add Relation Q Qeq
- reflexivity proved by Qeq_refl
- symmetry proved by Qeq_sym
- transitivity proved by Qeq_trans
-as Q_Setoid.
-
-Hint Resolve Qeq_refl : qarith.
-Hint Resolve Qeq_sym : qarith.
-Hint Resolve Qeq_trans : qarith.
-
Theorem Qnot_eq_sym : forall x y, ~x == y -> ~y == x.
Proof.
auto with qarith.
@@ -218,7 +215,7 @@ Qed.
(** * Setoid compatibility results *)
-Add Morphism Qplus : Qplus_comp.
+Instance Qplus_comp : Proper (Qeq==>Qeq==>Qeq) Qplus.
Proof.
unfold Qeq, Qplus; simpl.
Open Scope Z_scope.
@@ -232,24 +229,23 @@ Proof.
Close Scope Z_scope.
Qed.
-Add Morphism Qopp : Qopp_comp.
+Instance Qopp_comp : Proper (Qeq==>Qeq) Qopp.
Proof.
unfold Qeq, Qopp; simpl.
Open Scope Z_scope.
- intros.
+ intros x y H; simpl.
replace (- Qnum x * ' Qden y) with (- (Qnum x * ' Qden y)) by ring.
- rewrite H in |- *; ring.
+ rewrite H; ring.
Close Scope Z_scope.
Qed.
-Add Morphism Qminus : Qminus_comp.
+Instance Qminus_comp : Proper (Qeq==>Qeq==>Qeq) Qminus.
Proof.
- intros.
- unfold Qminus.
- rewrite H; rewrite H0; auto with qarith.
+ intros x x' Hx y y' Hy.
+ unfold Qminus. rewrite Hx, Hy; auto with qarith.
Qed.
-Add Morphism Qmult : Qmult_comp.
+Instance Qmult_comp : Proper (Qeq==>Qeq==>Qeq) Qmult.
Proof.
unfold Qeq; simpl.
Open Scope Z_scope.
@@ -263,7 +259,7 @@ Proof.
Close Scope Z_scope.
Qed.
-Add Morphism Qinv : Qinv_comp.
+Instance Qinv_comp : Proper (Qeq==>Qeq) Qinv.
Proof.
unfold Qeq, Qinv; simpl.
Open Scope Z_scope.
@@ -281,83 +277,49 @@ Proof.
Close Scope Z_scope.
Qed.
-Add Morphism Qdiv : Qdiv_comp.
+Instance Qdiv_comp : Proper (Qeq==>Qeq==>Qeq) Qdiv.
Proof.
- intros; unfold Qdiv.
- rewrite H; rewrite H0; auto with qarith.
+ intros x x' Hx y y' Hy; unfold Qdiv.
+ rewrite Hx, Hy; auto with qarith.
Qed.
-Add Morphism Qle with signature Qeq ==> Qeq ==> iff as Qle_comp.
+Instance Qcompare_comp : Proper (Qeq==>Qeq==>eq) Qcompare.
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.
+ unfold Qeq, Qcompare.
Open Scope Z_scope.
- intros (p1, p2) (q1, q2) H (r1, r2) (s1, s2) H0 H1; simpl in *.
- apply Zmult_le_reg_r with ('p2).
- unfold Zgt; auto.
- replace (q1 * 's2 * 'p2) with (q1 * 'p2 * 's2) by ring.
- rewrite <- H.
- apply Zmult_le_reg_r with ('r2).
- unfold Zgt; auto.
- 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.
- auto with zarith.
+ intros (p1,p2) (q1,q2) H (r1,r2) (s1,s2) H'; simpl in *.
+ rewrite <- (Zcompare_mult_compat (q2*s2) (p1*'r2)).
+ rewrite <- (Zcompare_mult_compat (p2*r2) (q1*'s2)).
+ change ('(q2*s2)) with ('q2 * 's2).
+ change ('(p2*r2)) with ('p2 * 'r2).
+ replace ('q2 * 's2 * (p1*'r2)) with ((p1*'q2)*'r2*'s2) by ring.
+ rewrite H.
+ replace ('q2 * 's2 * (r1*'p2)) with ((r1*'s2)*'q2*'p2) by ring.
+ rewrite H'.
+ f_equal; ring.
Close Scope Z_scope.
Qed.
-Add Morphism Qlt with signature Qeq ==> Qeq ==> iff as Qlt_comp.
+Instance Qle_comp : Proper (Qeq==>Qeq==>iff) Qle.
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, Qlt; simpl.
- Open Scope Z_scope.
- intros (p1, p2) (q1, q2) H (r1, r2) (s1, s2) H0 H1; simpl in *.
- apply Zgt_lt.
- generalize (Zlt_gt _ _ H1); clear H1; intro H1.
- apply Zmult_gt_reg_r with ('p2); auto with zarith.
- replace (q1 * 's2 * 'p2) with (q1 * 'p2 * 's2) by ring.
- rewrite <- H.
- apply Zmult_gt_reg_r with ('r2); auto with zarith.
- 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.
- apply Zlt_gt.
- apply Zmult_gt_0_lt_compat_l; auto with zarith.
- Close Scope Z_scope.
+ intros p q H r s H'. rewrite 2 Qle_alt, H, H'; auto with *.
Qed.
-Add Morphism Qeq_bool with signature Qeq ==> Qeq ==> (@eq bool) as Qeqb_comp.
+Instance Qlt_compat : Proper (Qeq==>Qeq==>iff) Qlt.
Proof.
- intros; apply eq_true_iff_eq.
- rewrite 2 Qeq_bool_iff, H, H0; split; auto with qarith.
+ intros p q H r s H'. rewrite 2 Qlt_alt, H, H'; auto with *.
Qed.
-Add Morphism Qle_bool with signature Qeq ==> Qeq ==> (@eq bool) as Qleb_comp.
+Instance Qeqb_comp : Proper (Qeq==>Qeq==>eq) Qeq_bool.
Proof.
- intros; apply eq_true_iff_eq.
- rewrite 2 Qle_bool_iff, H, H0.
- split; auto with qarith.
+ intros p q H r s H'; apply eq_true_iff_eq.
+ rewrite 2 Qeq_bool_iff, H, H'; split; auto with qarith.
Qed.
-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)).
+Instance Qleb_comp : Proper (Qeq==>Qeq==>eq) Qle_bool.
Proof.
- intros.
- do 2 rewrite Qeq_alt in H0.
- unfold Qeq, Qlt, Qcompare in *.
- apply Zcompare_egal_dec; auto.
- omega.
-Qed.
-
-Add Morphism Qcompare : Qcompare_comp.
-Proof.
- intros; apply Qcompare_egal_dec; rewrite H; rewrite H0; auto.
+ intros p q H r s H'; apply eq_true_iff_eq.
+ rewrite 2 Qle_bool_iff, H, H'; split; auto with qarith.
Qed.
@@ -554,6 +516,11 @@ Qed.
Hint Resolve Qle_trans : qarith.
+Lemma Qlt_irrefl : forall x, ~x<x.
+Proof.
+ unfold Qlt. auto with zarith.
+Qed.
+
Lemma Qlt_not_eq : forall x y, x<y -> ~ x==y.
Proof.
unfold Qlt, Qeq; auto with zarith.
@@ -561,6 +528,13 @@ Qed.
(** Large = strict or equal *)
+Lemma Qle_lteq : forall x y, x<=y <-> x<y \/ x==y.
+Proof.
+ intros.
+ rewrite Qeq_alt, Qle_alt, Qlt_alt.
+ destruct (x ?= y); intuition; discriminate.
+Qed.
+
Lemma Qlt_le_weak : forall x y, x<y -> x<=y.
Proof.
unfold Qle, Qlt; auto with zarith.
@@ -835,9 +809,9 @@ Qed.
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.
+Instance Qpower_positive_comp : Proper (Qeq==>eq==>Qeq) Qpower_positive.
Proof.
-intros x1 x2 Hx y.
+intros x x' Hx y y' Hy. rewrite <-Hy; clear y' Hy.
unfold Qpower_positive.
induction y; simpl;
try rewrite IHy;
@@ -854,8 +828,8 @@ Definition Qpower (q:Q) (z:Z) :=
Notation " q ^ z " := (Qpower q z) : Q_scope.
-Add Morphism Qpower with signature Qeq ==> eq ==> Qeq as Qpower_comp.
+Instance Qpower_comp : Proper (Qeq==>eq==>Qeq) Qpower.
Proof.
-intros x1 x2 Hx [|y|y]; try reflexivity;
-simpl; rewrite Hx; reflexivity.
+intros x x' Hx y y' Hy. rewrite <- Hy; clear y' Hy.
+destruct y; simpl; rewrite ?Hx; auto with *.
Qed.
diff --git a/theories/QArith/QOrderedType.v b/theories/QArith/QOrderedType.v
new file mode 100644
index 000000000..3d83eac38
--- /dev/null
+++ b/theories/QArith/QOrderedType.v
@@ -0,0 +1,68 @@
+(************************************************************************)
+(* 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_base
+ DecidableType2 OrderedType2 OrderedType2Facts.
+
+Local Open Scope Q_scope.
+
+(** * DecidableType structure for rational numbers *)
+
+Module Q_as_DT <: DecidableType.
+ Definition t := Q.
+ Definition eq := Qeq.
+ Instance eq_equiv : Equivalence Qeq.
+ Definition eq_dec := Qeq_dec.
+
+ (** The next fields are not mandatory, but allow [Q_as_DT] to be
+ also a [DecidableTypeOrig]. *)
+ Definition eq_refl := Qeq_refl.
+ Definition eq_sym := Qeq_sym.
+ Definition eq_trans := eq_trans.
+End Q_as_DT.
+
+
+(** * OrderedType structure for rational numbers *)
+
+Module Q_as_OT <: OrderedTypeFull.
+ Include Q_as_DT.
+ Definition lt := Qlt.
+ Definition le := Qle.
+ Definition compare := Qcompare.
+
+ Instance lt_strorder : StrictOrder Qlt.
+ Proof. split; [ exact Qlt_irrefl | exact Qlt_trans ]. Qed.
+
+ Instance lt_compat : Proper (Qeq==>Qeq==>iff) Qlt.
+ Proof. auto with *. Qed.
+
+ Definition le_lteq := Qle_lteq.
+
+ Lemma Qcompare_antisym : forall x y, CompOpp (x ?= y) = (y ?= x).
+ Proof.
+ unfold "?=". intros. apply Zcompare_antisym.
+ Qed.
+
+ Lemma compare_spec : forall x y, Cmp Qeq Qlt x y (Qcompare x y).
+ Proof.
+ intros.
+ destruct (x ?= y) as [ ]_eqn:H; constructor; auto.
+ rewrite Qeq_alt; auto.
+ rewrite Qlt_alt, <- Qcompare_antisym, H; auto.
+ Qed.
+
+End Q_as_OT.
+
+
+(** * An [order] tactic for [Q] numbers *)
+
+Module QOrder := OTF_to_OrderTac Q_as_OT.
+Ltac q_order := QOrder.order.
+
+(** Note that [q_order] is domain-agnostic: it will not prove
+ [1<=2] or [x<=x+x], but rather things like [x<=y -> y<=x -> x==y]. *)
diff --git a/theories/QArith/Qminmax.v b/theories/QArith/Qminmax.v
new file mode 100644
index 000000000..e9d2f79ab
--- /dev/null
+++ b/theories/QArith/Qminmax.v
@@ -0,0 +1,130 @@
+(************************************************************************)
+(* 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_base OrderedType2 QOrderedType GenericMinMax.
+
+(** * Maximum and Minimum of two rational numbers *)
+
+Local Open Scope Q_scope.
+
+(** [Qmin] and [Qmax] are obtained the usual way from [Qcompare]. *)
+
+Definition Qmax := gmax Qcompare.
+Definition Qmin := gmin Qcompare.
+
+Module QHasMinMax <: HasMinMax Q_as_OT.
+ Module QMM := GenericMinMax Q_as_OT.
+ Definition max := Qmax.
+ Definition min := Qmin.
+ Definition max_spec := QMM.max_spec.
+ Definition min_spec := QMM.min_spec.
+End QHasMinMax.
+
+(** We obtain hence all the generic properties of max and min. *)
+
+Module Import QMinMaxProps := MinMaxProperties Q_as_OT QHasMinMax.
+
+Definition Qmax_case_strong := max_case_strong.
+Definition Qmax_case := max_case.
+Definition Qmax_monotone := max_monotone.
+Definition Qmax_spec := max_spec.
+Definition Qmax_spec_le := max_spec_le.
+Definition Qmax_dec := max_dec.
+Definition Qmax_unicity := max_unicity.
+Definition Qmax_unicity_ext := max_unicity_ext.
+Definition Qmax_id := max_id.
+Notation Qmax_idempotent := Qmax_id (only parsing).
+Definition Qmax_assoc := max_assoc.
+Definition Qmax_comm := max_comm.
+Definition Qmax_l := max_l.
+Definition Qmax_r := max_r.
+Definition Nle_max_l := le_max_l.
+Definition Nle_max_r := le_max_r.
+Definition Qmax_le := max_le.
+Definition Qmax_le_iff := max_le_iff.
+Definition Qmax_lt_iff := max_lt_iff.
+Definition Qmax_lub_l := max_lub_l.
+Definition Qmax_lub_r := max_lub_r.
+Definition Qmax_lub := max_lub.
+Definition Qmax_lub_iff := max_lub_iff.
+Definition Qmax_lub_lt := max_lub_lt.
+Definition Qmax_lub_lt_iff := max_lub_lt_iff.
+Definition Qmax_le_compat_l := max_le_compat_l.
+Definition Qmax_le_compat_r := max_le_compat_r.
+Definition Qmax_le_compat := max_le_compat.
+
+Definition Qmin_case_strong := min_case_strong.
+Definition Qmin_case := min_case.
+Definition Qmin_monotone := min_monotone.
+Definition Qmin_spec := min_spec.
+Definition Qmin_spec_le := min_spec_le.
+Definition Qmin_dec := min_dec.
+Definition Qmin_unicity := min_unicity.
+Definition Qmin_unicity_ext := min_unicity_ext.
+Definition Qmin_id := min_id.
+Notation Qmin_idempotent := Qmin_id (only parsing).
+Definition Qmin_assoc := min_assoc.
+Definition Qmin_comm := min_comm.
+Definition Qmin_l := min_l.
+Definition Qmin_r := min_r.
+Definition Nle_min_l := le_min_l.
+Definition Nle_min_r := le_min_r.
+Definition Qmin_le := min_le.
+Definition Qmin_le_iff := min_le_iff.
+Definition Qmin_lt_iff := min_lt_iff.
+Definition Qmin_glb_l := min_glb_l.
+Definition Qmin_glb_r := min_glb_r.
+Definition Qmin_glb := min_glb.
+Definition Qmin_glb_iff := min_glb_iff.
+Definition Qmin_glb_lt := min_glb_lt.
+Definition Qmin_glb_lt_iff := min_glb_lt_iff.
+Definition Qmin_le_compat_l := min_le_compat_l.
+Definition Qmin_le_compat_r := min_le_compat_r.
+Definition Qmin_le_compat := min_le_compat.
+
+Definition Qmin_max_absorption := min_max_absorption.
+Definition Qmax_min_absorption := max_min_absorption.
+Definition Qmax_min_distr := max_min_distr.
+Definition Qmin_max_distr := min_max_distr.
+Definition Qmax_min_modular := max_min_modular.
+Definition Qmin_max_modular := min_max_modular.
+Definition Qmax_min_disassoc := max_min_disassoc.
+Definition Qmax_min_antimonotone := max_min_antimonotone.
+Definition Qmin_max_antimonotone := min_max_antimonotone.
+
+
+
+(** * Properties specific to the [Q] domain *)
+
+(** Compatibilities (consequences of monotonicity) *)
+
+Lemma Qplus_max_distr_l : forall n m p, Qmax (p + n) (p + m) == p + Qmax n m.
+Proof.
+ intros. apply Qmax_monotone.
+ intros x x' Hx; rewrite Hx; auto with qarith.
+ intros x x' Hx. apply Qplus_le_compat; q_order.
+Qed.
+
+Lemma Qplus_max_distr_r : forall n m p, Qmax (n + p) (m + p) == Qmax n m + p.
+Proof.
+ intros. rewrite (Qplus_comm n p), (Qplus_comm m p), (Qplus_comm _ p).
+ apply Qplus_max_distr_l.
+Qed.
+
+Lemma Qplus_min_distr_l : forall n m p, Qmin (p + n) (p + m) == p + Qmin n m.
+Proof.
+ intros. apply Qmin_monotone.
+ intros x x' Hx; rewrite Hx; auto with qarith.
+ intros x x' Hx. apply Qplus_le_compat; q_order.
+Qed.
+
+Lemma Qplus_min_distr_r : forall n m p, Qmin (n + p) (m + p) == Qmin n m + p.
+Proof.
+ intros. rewrite (Qplus_comm n p), (Qplus_comm m p), (Qplus_comm _ p).
+ apply Qplus_min_distr_l.
+Qed.