From 980d315f7f6d5e05eabbda84f95e11bfa30a0033 Mon Sep 17 00:00:00 2001 From: letouzey Date: Fri, 16 Oct 2009 13:12:52 +0000 Subject: Structure/OrderTac.v : highlight the "order" tactic by isolating it from FSets, and improve it As soon as you have a eq, a lt and a le (that may be lt\/eq, or (complement (flip (lt))) and a few basic properties over them, you can instantiate functor MakeOrderTac and gain an "order" tactic. See comments in the file for the scope of this tactic. NB: order doesn't call auto anymore. It only searches for a contradiction in the current set of (in)equalities (after the goal was optionally turned into hyp by double negation). Thanks to S. Lescuyer for his suggestions about this tactic. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12397 85f007b7-540e-0410-9357-904b9bb8a0f7 --- Makefile.common | 1 + theories/FSets/FMapAVL.v | 2 +- theories/FSets/FMapList.v | 6 +- theories/MSets/MSetInterface.v | 4 +- theories/MSets/MSetList.v | 2 +- theories/Structures/OrderTac.v | 255 +++++++++++++++++++++++++++++++++++++ theories/Structures/OrderedType.v | 237 +++++++++------------------------- theories/Structures/OrderedType2.v | 230 +++++++-------------------------- theories/theories.itarget | 2 +- 9 files changed, 365 insertions(+), 374 deletions(-) create mode 100644 theories/Structures/OrderTac.v diff --git a/Makefile.common b/Makefile.common index 67abba61b9..532fe9b3d6 100644 --- a/Makefile.common +++ b/Makefile.common @@ -313,6 +313,7 @@ LOGICVO:=$(addprefix theories/Logic/, \ IndefiniteDescription.vo SetIsType.vo FunctionalExtensionality.vo ) STRUCTURESVO:=$(addprefix theories/Structures/, \ + OrderTac.vo \ DecidableType.vo DecidableTypeEx.vo \ OrderedType.vo OrderedTypeEx.vo OrderedTypeAlt.vo \ DecidableType2.vo DecidableType2Ex.vo \ diff --git a/theories/FSets/FMapAVL.v b/theories/FSets/FMapAVL.v index a53a485d37..c457a83c42 100644 --- a/theories/FSets/FMapAVL.v +++ b/theories/FSets/FMapAVL.v @@ -1178,7 +1178,7 @@ Lemma split_in_3 : forall m x, bst m -> Proof. intros m x; functional induction (split x m); subst; simpl; auto; intros; inv bst; try clear e0; - destruct X.compare; try (order;fail); rewrite <-IHt, e1; auto. + destruct X.compare; try order; trivial; rewrite <- IHt, e1; auto. Qed. Lemma split_bst : forall m x, bst m -> diff --git a/theories/FSets/FMapList.v b/theories/FSets/FMapList.v index 4c21e17387..9ad2f65cfb 100644 --- a/theories/FSets/FMapList.v +++ b/theories/FSets/FMapList.v @@ -1276,8 +1276,7 @@ Proof. try destruct p0 as (x'',e''); try contradiction; auto. destruct (X.compare x x'); destruct (X.compare x' x''); - MapS.Raw.MX.elim_comp. - intuition. + MapS.Raw.MX.elim_comp; intuition. apply D.eq_trans with e'; auto. inversion_clear Hm1; inversion_clear Hm2; inversion_clear Hm3. apply (IHm1 H1 (Build_slist H6) (Build_slist H8)); intuition. @@ -1293,8 +1292,7 @@ Proof. try destruct p0 as (x'',e''); try contradiction; auto. destruct (X.compare x x'); destruct (X.compare x' x''); - MapS.Raw.MX.elim_comp; auto. - intuition. + MapS.Raw.MX.elim_comp; intuition. left; apply D.lt_trans with e'; auto. left; apply lt_eq with e'; auto. left; apply eq_lt with e'; auto. diff --git a/theories/MSets/MSetInterface.v b/theories/MSets/MSetInterface.v index d5cbea61c5..119868f4e6 100644 --- a/theories/MSets/MSetInterface.v +++ b/theories/MSets/MSetInterface.v @@ -865,12 +865,12 @@ Module MakeSetOrdering (O:OrderedType)(Import M:IN O). destruct Disj as [(IN,Em)|(IN & y & INy & LTy & Be)]. left; split; auto. rewrite (Ad2 x); auto. - intros z. rewrite (Ad1 z); intros [U|U]; try specialize (Ab1 z U); order. + intros z. rewrite (Ad1 z); intros [U|U]; try specialize (Ab1 z U); auto; order. right; split; auto. rewrite (Ad1 x); auto. exists y; repeat split; auto. rewrite (Ad2 y); auto. - intros z. rewrite (Ad2 z). intros [U|U]; try specialize (Ab2 z U); order. + intros z. rewrite (Ad2 z). intros [U|U]; try specialize (Ab2 z U); auto; order. Qed. End MakeSetOrdering. diff --git a/theories/MSets/MSetList.v b/theories/MSets/MSetList.v index a6fc0affa7..471b43e241 100644 --- a/theories/MSets/MSetList.v +++ b/theories/MSets/MSetList.v @@ -442,7 +442,7 @@ Module MakeRaw (X: OrderedType) <: RawSets X. Proof. induction2; try rewrite ?InA_cons, ?Hrec, ?Hrec'; intuition; inv; auto; try sort_inf_in; try order. - right; intuition; inv; order. + right; intuition; inv; auto. Qed. Lemma equal_spec : diff --git a/theories/Structures/OrderTac.v b/theories/Structures/OrderTac.v new file mode 100644 index 0000000000..11e3bdf9d0 --- /dev/null +++ b/theories/Structures/OrderTac.v @@ -0,0 +1,255 @@ +(***********************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* t -> Prop. +Instance eq_equiv : Equivalence eq. +Instance lt_strorder : StrictOrder lt. +Instance lt_compat : Proper (eq==>eq==>iff) lt. +Parameter lt_total : forall x y, lt x y \/ eq x y \/ lt y x. +Parameter le_lteq : forall x y, le x y <-> lt x y \/ eq x y. + +End OrderTacSig. + +(** NB : we should _not_ use "Inline" for these predicates, + otherwise the ltac matching will not work properly later. *) + +(** An abstract vision of the predicates. This allows a one-line + statement for interesting transitivity properties: for instance + [trans_ord LE LE = LE] will imply later [le x y -> le y z -> le x z]. + *) + +Inductive ord := EQ | LT | LE. +Definition trans_ord o o' := + match o, o' with + | EQ, _ => o' + | _, EQ => o + | LE, LE => LE + | _, _ => LT + end. +Infix "+" := trans_ord : order. + +(** ** [MakeOrderTac] : The functor providing the order tactic. *) + +Module MakeOrderTac(Import O:OrderTacSig). + +Local Open Scope order. + +Infix "==" := eq (at level 70, no associativity) : order. +Infix "<" := lt : order. +Infix "<=" := le : order. + +(** ** Properties that will be used by the tactic *) + +(** Reflexivity rules *) + +Lemma eq_refl : forall x, x==x. +Proof. reflexivity. Qed. + +Lemma le_refl : forall x, x<=x. +Proof. intros; rewrite le_lteq; right; reflexivity. Qed. + +Lemma lt_antirefl : forall x, ~ x y==x. +Proof. auto with *. Qed. + +Lemma le_antisym : forall x y, x<=y -> y<=x -> x==y. +Proof. + intros x y; rewrite 2 le_lteq. intuition. + elim (StrictOrder_Irreflexive x); transitivity y; auto. +Qed. + +Lemma neq_sym : forall x y, ~x==y -> ~y==x. +Proof. auto using eq_sym. Qed. + +(** Transitivity rules : first, a generic formulation, then instances*) + +Ltac subst_eqns := + match goal with + | H : _==_ |- _ => (rewrite H || rewrite <- H); clear H; subst_eqns + | _ => idtac + end. + +Definition interp_ord o := + match o with EQ => eq | LT => lt | LE => le end. +Notation "#" := interp_ord : order. + +Lemma trans : forall o o' x y z, #o x y -> #o' y z -> #(o+o') x z. +Proof. +destruct o, o'; simpl; intros x y z; rewrite ?le_lteq; intuition; + subst_eqns; eauto using (StrictOrder_Transitive x y z) with *. +Qed. + +Definition eq_trans x y z : x==y -> y==z -> x==z := trans EQ EQ x y z. +Definition le_trans x y z : x<=y -> y<=z -> x<=z := trans LE LE x y z. +Definition lt_trans x y z : x y x y x y<=z -> x y x y==z -> x y<=z -> x<=z := trans EQ LE x y z. +Definition le_eq x y z : x<=y -> y==z -> x<=z := trans LE EQ x y z. + +Lemma eq_neq : forall x y z, x==y -> ~y==z -> ~x==z. +Proof. eauto using eq_trans, eq_sym. Qed. + +Lemma neq_eq : forall x y z, ~x==y -> y==z -> ~x==z. +Proof. eauto using eq_trans, eq_sym. Qed. + +(** (double) negation rules *) + +Lemma not_neq_eq : forall x y, ~~x==y -> x==y. +Proof. +intros x y H. destruct (lt_total x y) as [H'|[H'|H']]; auto; + destruct H; intro H; rewrite H in H'; eapply lt_antirefl; eauto. +Qed. + +Lemma not_ge_lt : forall x y, ~y<=x -> x x<=y. +Proof. +intros x y H. rewrite le_lteq. generalize (lt_total x y); intuition. +Qed. + +Lemma le_neq_lt : forall x y, x<=y -> ~x==y -> x