summaryrefslogtreecommitdiff
path: root/theories
diff options
context:
space:
mode:
authorGravatar Stephane Glondu <steph@glondu.net>2009-02-01 00:54:40 +0100
committerGravatar Stephane Glondu <steph@glondu.net>2009-02-01 00:54:40 +0100
commitcfbfe13f5b515ae2e3c6cdd97e2ccee03bc26e56 (patch)
treeb7832bd5d412a5a5d69cb36ae2ded62c71124c22 /theories
parent113b703a695acbe31ac6dd6a8c4aa94f6fda7545 (diff)
Imported Upstream version 8.2~rc2+dfsgupstream/8.2.rc2+dfsg
Diffstat (limited to 'theories')
-rw-r--r--theories/Arith/Div2.v64
-rw-r--r--theories/Arith/Even.v158
-rw-r--r--theories/Arith/Max.v6
-rw-r--r--theories/Classes/EquivDec.v56
-rw-r--r--theories/Classes/Equivalence.v40
-rw-r--r--theories/Classes/Functions.v19
-rw-r--r--theories/Classes/Init.v14
-rw-r--r--theories/Classes/Morphisms.v140
-rw-r--r--theories/Classes/Morphisms_Prop.v37
-rw-r--r--theories/Classes/Morphisms_Relations.v10
-rw-r--r--theories/Classes/RelationClasses.v116
-rw-r--r--theories/Classes/SetoidAxioms.v9
-rw-r--r--theories/Classes/SetoidClass.v66
-rw-r--r--theories/Classes/SetoidDec.v35
-rw-r--r--theories/Classes/SetoidTactics.v8
-rw-r--r--theories/FSets/FMapFacts.v1276
-rw-r--r--theories/FSets/FMapInterface.v10
-rw-r--r--theories/FSets/FMapList.v4
-rw-r--r--theories/FSets/FMapPositive.v86
-rw-r--r--theories/FSets/FSetAVL.v10
-rw-r--r--theories/FSets/FSetBridge.v13
-rw-r--r--theories/FSets/FSetDecide.v49
-rw-r--r--theories/FSets/FSetEqProperties.v47
-rw-r--r--theories/FSets/FSetFacts.v48
-rw-r--r--theories/FSets/FSetFullAVL.v10
-rw-r--r--theories/FSets/FSetInterface.v35
-rw-r--r--theories/FSets/FSetList.v10
-rw-r--r--theories/FSets/FSetProperties.v566
-rw-r--r--theories/FSets/FSetToFiniteSet.v12
-rw-r--r--theories/FSets/FSetWeakList.v57
-rw-r--r--theories/FSets/OrderedType.v35
-rw-r--r--theories/FSets/OrderedTypeAlt.v11
-rw-r--r--theories/FSets/OrderedTypeEx.v24
-rw-r--r--theories/Init/Datatypes.v30
-rw-r--r--theories/Init/Logic.v18
-rw-r--r--theories/Init/Peano.v38
-rw-r--r--theories/Init/Tactics.v46
-rw-r--r--theories/Lists/SetoidList.v209
-rw-r--r--theories/Logic/ClassicalDescription.v4
-rw-r--r--theories/Logic/ClassicalFacts.v4
-rw-r--r--theories/Logic/Decidable.v9
-rw-r--r--theories/Logic/DecidableTypeEx.v24
-rw-r--r--theories/Logic/Diaconescu.v4
-rw-r--r--theories/Logic/EqdepFacts.v10
-rw-r--r--theories/Logic/FunctionalExtensionality.v60
-rw-r--r--theories/NArith/BinNat.v6
-rw-r--r--theories/NArith/Ndigits.v289
-rw-r--r--theories/Numbers/Integer/Abstract/ZBase.v8
-rw-r--r--theories/Numbers/Integer/Abstract/ZDomain.v4
-rw-r--r--theories/Numbers/Integer/Abstract/ZMulOrder.v6
-rw-r--r--theories/Numbers/Integer/BigZ/BigZ.v4
-rw-r--r--theories/Numbers/Integer/BigZ/ZMake.v3
-rw-r--r--theories/Numbers/Integer/NatPairs/ZNatPairs.v6
-rw-r--r--theories/Numbers/NatInt/NZBase.v4
-rw-r--r--theories/Numbers/NatInt/NZOrder.v4
-rw-r--r--theories/Numbers/Natural/Abstract/NAdd.v4
-rw-r--r--theories/Numbers/Natural/Abstract/NBase.v10
-rw-r--r--theories/Numbers/Natural/Abstract/NDefOps.v4
-rw-r--r--theories/Numbers/Natural/Abstract/NStrongRec.v8
-rw-r--r--theories/Numbers/Natural/BigN/BigN.v4
-rw-r--r--theories/Numbers/Natural/BigN/NMake_gen.ml3
-rw-r--r--theories/Numbers/NumPrelude.v6
-rw-r--r--theories/Program/Basics.v18
-rw-r--r--theories/Program/Combinators.v16
-rw-r--r--theories/Program/Equality.v325
-rw-r--r--theories/Program/FunctionalExtensionality.v109
-rw-r--r--theories/Program/Program.v9
-rw-r--r--theories/Program/Subset.v5
-rw-r--r--theories/Program/Syntax.v24
-rw-r--r--theories/Program/Tactics.v52
-rw-r--r--theories/Program/Utils.v4
-rw-r--r--theories/Program/Wf.v207
-rw-r--r--theories/QArith/Qpower.v2
-rw-r--r--theories/Relations/Operators_Properties.v334
-rw-r--r--theories/Relations/Relation_Operators.v132
-rw-r--r--theories/Setoids/Setoid.v61
-rw-r--r--theories/Setoids/Setoid_Prop.v79
-rw-r--r--theories/Setoids/Setoid_tac.v595
-rw-r--r--theories/ZArith/Zdiv.v89
-rw-r--r--theories/ZArith/auxiliary.v42
80 files changed, 3481 insertions, 2532 deletions
diff --git a/theories/Arith/Div2.v b/theories/Arith/Div2.v
index 1216a545..7cab976f 100644
--- a/theories/Arith/Div2.v
+++ b/theories/Arith/Div2.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Div2.v 10625 2008-03-06 11:21:01Z notin $ i*)
+(*i $Id: Div2.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
Require Import Lt.
Require Import Plus.
@@ -60,45 +60,38 @@ Hint Resolve lt_div2: arith.
(** Properties related to the parity *)
-Lemma even_odd_div2 :
- forall n,
- (even n <-> div2 n = div2 (S n)) /\ (odd n <-> S (div2 n) = div2 (S n)).
+Lemma even_div2 : forall n, even n -> div2 n = div2 (S n)
+with odd_div2 : forall n, odd n -> S (div2 n) = div2 (S n).
Proof.
- intro n. pattern n in |- *. apply ind_0_1_SS.
- (* n = 0 *)
- split. split; auto with arith.
- split. intro H. inversion H.
- intro H. absurd (S (div2 0) = div2 1); auto with arith.
- (* n = 1 *)
- split. split. intro. inversion H. inversion H1.
- intro H. absurd (div2 1 = div2 2).
- simpl in |- *. discriminate. assumption.
- split; auto with arith.
- (* n = (S (S n')) *)
- intros. decompose [and] H. unfold iff in H0, H1.
- decompose [and] H0. decompose [and] H1. clear H H0 H1.
- split; split; auto with arith.
- intro H. inversion H. inversion H1.
- change (S (div2 n0) = S (div2 (S n0))) in |- *. auto with arith.
- intro H. inversion H. inversion H1.
- change (S (S (div2 n0)) = S (div2 (S n0))) in |- *. auto with arith.
+ destruct n; intro H.
+ (* 0 *) trivial.
+ (* S n *) inversion_clear H. apply odd_div2 in H0 as <-. trivial.
+ destruct n; intro.
+ (* 0 *) inversion H.
+ (* S n *) inversion_clear H. apply even_div2 in H0 as <-. trivial.
Qed.
-(** Specializations *)
-
-Lemma even_div2 : forall n, even n -> div2 n = div2 (S n).
-Proof fun n => proj1 (proj1 (even_odd_div2 n)).
+Lemma div2_even : forall n, div2 n = div2 (S n) -> even n
+with div2_odd : forall n, S (div2 n) = div2 (S n) -> odd n.
+Proof.
+ destruct n; intro H.
+ (* 0 *) constructor.
+ (* S n *) constructor. apply div2_odd. rewrite H. trivial.
+ destruct n; intro H.
+ (* 0 *) discriminate.
+ (* S n *) constructor. apply div2_even. injection H as <-. trivial.
+Qed.
-Lemma div2_even : forall n, div2 n = div2 (S n) -> even n.
-Proof fun n => proj2 (proj1 (even_odd_div2 n)).
+Hint Resolve even_div2 div2_even odd_div2 div2_odd: arith.
-Lemma odd_div2 : forall n, odd n -> S (div2 n) = div2 (S n).
-Proof fun n => proj1 (proj2 (even_odd_div2 n)).
+Lemma even_odd_div2 :
+ forall n,
+ (even n <-> div2 n = div2 (S n)) /\ (odd n <-> S (div2 n) = div2 (S n)).
+Proof.
+ auto decomp using div2_odd, div2_even, odd_div2, even_div2.
+Qed.
-Lemma div2_odd : forall n, S (div2 n) = div2 (S n) -> odd n.
-Proof fun n => proj2 (proj2 (even_odd_div2 n)).
-Hint Resolve even_div2 div2_even odd_div2 div2_odd: arith.
(** Properties related to the double ([2n]) *)
@@ -132,8 +125,7 @@ Proof.
split; split; auto with arith.
intro H. inversion H. inversion H1.
(* n = (S (S n')) *)
- intros. decompose [and] H. unfold iff in H0, H1.
- decompose [and] H0. decompose [and] H1. clear H H0 H1.
+ intros. destruct H as ((IH1,IH2),(IH3,IH4)).
split; split.
intro H. inversion H. inversion H1.
simpl in |- *. rewrite (double_S (div2 n0)). auto with arith.
@@ -142,8 +134,6 @@ Proof.
simpl in |- *. rewrite (double_S (div2 n0)). auto with arith.
simpl in |- *. rewrite (double_S (div2 n0)). intro H. injection H. auto with arith.
Qed.
-
-
(** Specializations *)
Lemma even_double : forall n, even n -> n = double (div2 n).
diff --git a/theories/Arith/Even.v b/theories/Arith/Even.v
index 1484666b..59209370 100644
--- a/theories/Arith/Even.v
+++ b/theories/Arith/Even.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Even.v 10410 2007-12-31 13:11:55Z msozeau $ i*)
+(*i $Id: Even.v 11512 2008-10-27 12:28:36Z herbelin $ i*)
(** Here we define the predicates [even] and [odd] by mutual induction
and we prove the decidability and the exclusion of those predicates.
@@ -52,153 +52,91 @@ Qed.
(** * Facts about [even] & [odd] wrt. [plus] *)
-Lemma even_plus_aux :
- forall n m,
- (odd (n + m) <-> odd n /\ even m \/ even n /\ odd m) /\
- (even (n + m) <-> even n /\ even m \/ odd n /\ odd m).
+Lemma even_plus_split : forall n m,
+ (even (n + m) -> even n /\ even m \/ odd n /\ odd m)
+with odd_plus_split : forall n m,
+ odd (n + m) -> odd n /\ even m \/ even n /\ odd m.
Proof.
- intros n; elim n; simpl in |- *; auto with arith.
- intros m; split; auto.
- split.
- intros H; right; split; auto with arith.
- intros H'; case H'; auto with arith.
- intros H'0; elim H'0; intros H'1 H'2; inversion H'1.
- intros H; elim H; auto.
- split; auto with arith.
- intros H'; elim H'; auto with arith.
- intros H; elim H; auto.
- intros H'0; elim H'0; intros H'1 H'2; inversion H'1.
- intros n0 H' m; elim (H' m); intros H'1 H'2; elim H'1; intros E1 E2; elim H'2;
- intros E3 E4; clear H'1 H'2.
- split; split.
- intros H'0; case E3.
- inversion H'0; auto.
- intros H; elim H; intros H0 H1; clear H; auto with arith.
- intros H; elim H; intros H0 H1; clear H; auto with arith.
- intros H'0; case H'0; intros C0; case C0; intros C1 C2.
- apply odd_S.
- apply E4; left; split; auto with arith.
- inversion C1; auto.
- apply odd_S.
- apply E4; right; split; auto with arith.
- inversion C1; auto.
- intros H'0.
- case E1.
- inversion H'0; auto.
- intros H; elim H; intros H0 H1; clear H; auto with arith.
- intros H; elim H; intros H0 H1; clear H; auto with arith.
- intros H'0; case H'0; intros C0; case C0; intros C1 C2.
- apply even_S.
- apply E2; left; split; auto with arith.
- inversion C1; auto.
- apply even_S.
- apply E2; right; split; auto with arith.
- inversion C1; auto.
+intros. clear even_plus_split. destruct n; simpl in *.
+ auto with arith.
+ inversion_clear H;
+ apply odd_plus_split in H0 as [(H0,?)|(H0,?)]; auto with arith.
+intros. clear odd_plus_split. destruct n; simpl in *.
+ auto with arith.
+ inversion_clear H;
+ apply even_plus_split in H0 as [(H0,?)|(H0,?)]; auto with arith.
Qed.
-
-Lemma even_even_plus : forall n m, even n -> even m -> even (n + m).
+
+Lemma even_even_plus : forall n m, even n -> even m -> even (n + m)
+with odd_plus_l : forall n m, odd n -> even m -> odd (n + m).
Proof.
- intros n m; case (even_plus_aux n m).
- intros H H0; case H0; auto.
+intros n m [|] ?. trivial. apply even_S, odd_plus_l; trivial.
+intros n m [] ?. apply odd_S, even_even_plus; trivial.
Qed.
-
-Lemma odd_even_plus : forall n m, odd n -> odd m -> even (n + m).
+
+Lemma odd_plus_r : forall n m, even n -> odd m -> odd (n + m)
+with odd_even_plus : forall n m, odd n -> odd m -> even (n + m).
Proof.
- intros n m; case (even_plus_aux n m).
- intros H H0; case H0; auto.
+intros n m [|] ?. trivial. apply odd_S, odd_even_plus; trivial.
+intros n m [] ?. apply even_S, odd_plus_r; trivial.
+Qed.
+
+Lemma even_plus_aux : forall n m,
+ (odd (n + m) <-> odd n /\ even m \/ even n /\ odd m) /\
+ (even (n + m) <-> even n /\ even m \/ odd n /\ odd m).
+Proof.
+split; split; auto using odd_plus_split, even_plus_split.
+intros [[]|[]]; auto using odd_plus_r, odd_plus_l.
+intros [[]|[]]; auto using even_even_plus, odd_even_plus.
Qed.
Lemma even_plus_even_inv_r : forall n m, even (n + m) -> even n -> even m.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'0.
- intros H'1; case H'1; auto.
- intros H0; elim H0; auto.
- intros H0 H1 H2; case (not_even_and_odd n); auto.
- case H0; auto.
+ intros n m H; destruct (even_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd n); auto.
Qed.
Lemma even_plus_even_inv_l : forall n m, even (n + m) -> even m -> even n.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'0.
- intros H'1; case H'1; auto.
- intros H0; elim H0; auto.
- intros H0 H1 H2; case (not_even_and_odd m); auto.
- case H0; auto.
+ intros n m H; destruct (even_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd m); auto.
Qed.
Lemma even_plus_odd_inv_r : forall n m, even (n + m) -> odd n -> odd m.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'0.
- intros H'1; case H'1; auto.
- intros H0 H1 H2; case (not_even_and_odd n); auto.
- case H0; auto.
- intros H0; case H0; auto.
+ intros n m H; destruct (even_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd n); auto.
Qed.
Lemma even_plus_odd_inv_l : forall n m, even (n + m) -> odd m -> odd n.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'0.
- intros H'1; case H'1; auto.
- intros H0 H1 H2; case (not_even_and_odd m); auto.
- case H0; auto.
- intros H0; case H0; auto.
+ intros n m H; destruct (even_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd m); auto.
Qed.
Hint Resolve even_even_plus odd_even_plus: arith.
-Lemma odd_plus_l : forall n m, odd n -> even m -> odd (n + m).
-Proof.
- intros n m; case (even_plus_aux n m).
- intros H; case H; auto.
-Qed.
-
-Lemma odd_plus_r : forall n m, even n -> odd m -> odd (n + m).
-Proof.
- intros n m; case (even_plus_aux n m).
- intros H; case H; auto.
-Qed.
-
Lemma odd_plus_even_inv_l : forall n m, odd (n + m) -> odd m -> even n.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'.
- intros H'1; case H'1; auto.
- intros H0 H1 H2; case (not_even_and_odd m); auto.
- case H0; auto.
- intros H0; case H0; auto.
+ intros n m H; destruct (odd_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd m); auto.
Qed.
Lemma odd_plus_even_inv_r : forall n m, odd (n + m) -> odd n -> even m.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'.
- intros H'1; case H'1; auto.
- intros H0; case H0; auto.
- intros H0 H1 H2; case (not_even_and_odd n); auto.
- case H0; auto.
+ intros n m H; destruct (odd_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd n); auto.
Qed.
Lemma odd_plus_odd_inv_l : forall n m, odd (n + m) -> even m -> odd n.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'.
- intros H'1; case H'1; auto.
- intros H0; case H0; auto.
- intros H0 H1 H2; case (not_even_and_odd m); auto.
- case H0; auto.
+ intros n m H; destruct (odd_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd m); auto.
Qed.
Lemma odd_plus_odd_inv_r : forall n m, odd (n + m) -> even n -> odd m.
Proof.
- intros n m H; case (even_plus_aux n m).
- intros H' H'0; elim H'.
- intros H'1; case H'1; auto.
- intros H0 H1 H2; case (not_even_and_odd n); auto.
- case H0; auto.
- intros H0; case H0; auto.
+ intros n m H; destruct (odd_plus_split n m) as [[]|[]]; auto.
+ intro; destruct (not_even_and_odd n); auto.
Qed.
Hint Resolve odd_plus_l odd_plus_r: arith.
diff --git a/theories/Arith/Max.v b/theories/Arith/Max.v
index 95af67f8..5de2298d 100644
--- a/theories/Arith/Max.v
+++ b/theories/Arith/Max.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Max.v 9883 2007-06-07 18:44:59Z letouzey $ i*)
+(*i $Id: Max.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
Require Import Le.
@@ -74,13 +74,13 @@ Lemma max_dec : forall n m, {max n m = n} + {max n m = m}.
Proof.
induction n; induction m; simpl in |- *; auto with arith.
elim (IHn m); intro H; elim H; auto.
-Qed.
+Defined.
Lemma max_case : forall n m (P:nat -> Type), P n -> P m -> P (max n m).
Proof.
induction n; simpl in |- *; auto with arith.
induction m; intros; simpl in |- *; auto with arith.
pattern (max n m) in |- *; apply IHn; auto with arith.
-Qed.
+Defined.
Notation max_case2 := max_case (only parsing).
diff --git a/theories/Classes/EquivDec.v b/theories/Classes/EquivDec.v
index 1e58d05d..157217ae 100644
--- a/theories/Classes/EquivDec.v
+++ b/theories/Classes/EquivDec.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -10,13 +9,12 @@
(* Decidable equivalences.
*
* Author: Matthieu Sozeau
- * Institution: LRI, CNRS UMR 8623 - UniversitĂcopyright Paris Sud
+ * Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
* 91405 Orsay, France *)
-(* $Id: EquivDec.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: EquivDec.v 11800 2009-01-18 18:34:15Z msozeau $ *)
-Set Implicit Arguments.
-Unset Strict Implicit.
+Set Manual Implicit Arguments.
(** Export notations. *)
@@ -29,12 +27,12 @@ Require Import Coq.Logic.Decidable.
Open Scope equiv_scope.
-Class [ equiv : Equivalence A ] => DecidableEquivalence :=
+Class DecidableEquivalence `(equiv : Equivalence A) :=
setoid_decidable : forall x y : A, decidable (x === y).
(** The [EqDec] class gives a decision procedure for a particular setoid equality. *)
-Class [ equiv : Equivalence A ] => EqDec :=
+Class EqDec A R {equiv : Equivalence R} :=
equiv_dec : forall x y : A, { x === y } + { x =/= y }.
(** We define the [==] overloaded notation for deciding equality. It does not take precedence
@@ -54,7 +52,7 @@ Open Local Scope program_scope.
(** Invert the branches. *)
-Program Definition nequiv_dec [ EqDec A ] (x y : A) : { x =/= y } + { x === y } := swap_sumbool (x == y).
+Program Definition nequiv_dec `{EqDec A} (x y : A) : { x =/= y } + { x === y } := swap_sumbool (x == y).
(** Overloaded notation for inequality. *)
@@ -62,10 +60,10 @@ Infix "<>" := nequiv_dec (no associativity, at level 70) : equiv_scope.
(** Define boolean versions, losing the logical information. *)
-Definition equiv_decb [ EqDec A ] (x y : A) : bool :=
+Definition equiv_decb `{EqDec A} (x y : A) : bool :=
if x == y then true else false.
-Definition nequiv_decb [ EqDec A ] (x y : A) : bool :=
+Definition nequiv_decb `{EqDec A} (x y : A) : bool :=
negb (equiv_decb x y).
Infix "==b" := equiv_decb (no associativity, at level 70).
@@ -77,16 +75,13 @@ Require Import Coq.Arith.Peano_dec.
(** The equiv is burried inside the setoid, but we can recover it by specifying which setoid we're talking about. *)
-Program Instance nat_eq_eqdec : ! EqDec nat eq :=
- equiv_dec := eq_nat_dec.
+Program Instance nat_eq_eqdec : EqDec nat eq := eq_nat_dec.
Require Import Coq.Bool.Bool.
-Program Instance bool_eqdec : ! EqDec bool eq :=
- equiv_dec := bool_dec.
+Program Instance bool_eqdec : EqDec bool eq := bool_dec.
-Program Instance unit_eqdec : ! EqDec unit eq :=
- equiv_dec x y := in_left.
+Program Instance unit_eqdec : EqDec unit eq := λ x y, in_left.
Next Obligation.
Proof.
@@ -94,39 +89,38 @@ Program Instance unit_eqdec : ! EqDec unit eq :=
reflexivity.
Qed.
-Program Instance prod_eqdec [ EqDec A eq, EqDec B eq ] :
+Program Instance prod_eqdec `(EqDec A eq, EqDec B eq) :
! EqDec (prod A B) eq :=
- equiv_dec x y :=
+ { equiv_dec x y :=
let '(x1, x2) := x in
let '(y1, y2) := y in
if x1 == y1 then
if x2 == y2 then in_left
else in_right
- else in_right.
+ else in_right }.
Solve Obligations using unfold complement, equiv ; program_simpl.
-Program Instance sum_eqdec [ EqDec A eq, EqDec B eq ] :
- ! EqDec (sum A B) eq :=
+Program Instance sum_eqdec `(EqDec A eq, EqDec B eq) :
+ EqDec (sum A B) eq := {
equiv_dec x y :=
match x, y with
| inl a, inl b => if a == b then in_left else in_right
| inr a, inr b => if a == b then in_left else in_right
| inl _, inr _ | inr _, inl _ => in_right
- end.
+ end }.
Solve Obligations using unfold complement, equiv ; program_simpl.
-(** Objects of function spaces with countable domains like bool have decidable equality. *)
-
-Require Import Coq.Program.FunctionalExtensionality.
+(** Objects of function spaces with countable domains like bool have decidable equality.
+ Proving the reflection requires functional extensionality though. *)
-Program Instance bool_function_eqdec [ EqDec A eq ] : ! EqDec (bool -> A) eq :=
- equiv_dec f g :=
+Program Instance bool_function_eqdec `(EqDec A eq) : ! EqDec (bool -> A) eq :=
+ { equiv_dec f g :=
if f true == g true then
if f false == g false then in_left
else in_right
- else in_right.
+ else in_right }.
Solve Obligations using try red ; unfold equiv, complement ; program_simpl.
@@ -138,8 +132,8 @@ Program Instance bool_function_eqdec [ EqDec A eq ] : ! EqDec (bool -> A) eq :=
Require Import List.
-Program Instance list_eqdec [ eqa : EqDec A eq ] : ! EqDec (list A) eq :=
- equiv_dec :=
+Program Instance list_eqdec `(eqa : EqDec A eq) : ! EqDec (list A) eq :=
+ { equiv_dec :=
fix aux (x : list A) y { struct x } :=
match x, y with
| nil, nil => in_left
@@ -148,7 +142,7 @@ Program Instance list_eqdec [ eqa : EqDec A eq ] : ! EqDec (list A) eq :=
if aux tl tl' then in_left else in_right
else in_right
| _, _ => in_right
- end.
+ end }.
Solve Obligations using unfold equiv, complement in * ; program_simpl ; intuition (discriminate || eauto).
diff --git a/theories/Classes/Equivalence.v b/theories/Classes/Equivalence.v
index d52eed47..5e5895ab 100644
--- a/theories/Classes/Equivalence.v
+++ b/theories/Classes/Equivalence.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -13,7 +12,7 @@
Institution: LRI, CNRS UMR 8623 - UniversitĂcopyright Paris Sud
91405 Orsay, France *)
-(* $Id: Equivalence.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: Equivalence.v 11709 2008-12-20 11:42:15Z msozeau $ *)
Require Export Coq.Program.Basics.
Require Import Coq.Program.Tactics.
@@ -28,9 +27,7 @@ Unset Strict Implicit.
Open Local Scope signature_scope.
-Definition equiv [ Equivalence A R ] : relation A := R.
-
-Typeclasses unfold equiv.
+Definition equiv `{Equivalence A R} : relation A := R.
(** Overloaded notations for setoid equivalence and inequivalence. Not to be confused with [eq] and [=]. *)
@@ -42,9 +39,7 @@ Open Local Scope equiv_scope.
(** Overloading for [PER]. *)
-Definition pequiv [ PER A R ] : relation A := R.
-
-Typeclasses unfold pequiv.
+Definition pequiv `{PER A R} : relation A := R.
(** Overloaded notation for partial equivalence. *)
@@ -52,16 +47,11 @@ Infix "=~=" := pequiv (at level 70, no associativity) : equiv_scope.
(** Shortcuts to make proof search easier. *)
-Program Instance equiv_reflexive [ sa : Equivalence A ] : Reflexive equiv.
-
-Program Instance equiv_symmetric [ sa : Equivalence A ] : Symmetric equiv.
+Program Instance equiv_reflexive `(sa : Equivalence A) : Reflexive equiv.
- Next Obligation.
- Proof.
- symmetry ; auto.
- Qed.
+Program Instance equiv_symmetric `(sa : Equivalence A) : Symmetric equiv.
-Program Instance equiv_transitive [ sa : Equivalence A ] : Transitive equiv.
+Program Instance equiv_transitive `(sa : Equivalence A) : Transitive equiv.
Next Obligation.
Proof.
@@ -113,13 +103,12 @@ Section Respecting.
(** Here we build an equivalence instance for functions which relates respectful ones only,
we do not export it. *)
- Definition respecting [ Equivalence A (R : relation A), Equivalence B (R' : relation B) ] : Type :=
+ Definition respecting `(eqa : Equivalence A (R : relation A), eqb : Equivalence B (R' : relation B)) : Type :=
{ morph : A -> B | respectful R R' morph morph }.
- Program Instance respecting_equiv [ eqa : Equivalence A R, eqb : Equivalence B R' ] :
- Equivalence respecting
- (fun (f g : respecting) => forall (x y : A), R x y -> R' (proj1_sig f x) (proj1_sig g y)).
-
+ Program Instance respecting_equiv `(eqa : Equivalence A R, eqb : Equivalence B R') :
+ Equivalence (fun (f g : respecting eqa eqb) => forall (x y : A), R x y -> R' (proj1_sig f x) (proj1_sig g y)).
+
Solve Obligations using unfold respecting in * ; simpl_relation ; program_simpl.
Next Obligation.
@@ -131,13 +120,10 @@ End Respecting.
(** The default equivalence on function spaces, with higher-priority than [eq]. *)
-Program Instance pointwise_equivalence [ eqb : Equivalence B eqB ] :
- Equivalence (A -> B) (pointwise_relation eqB) | 9.
-
- Solve Obligations using simpl_relation ; first [ reflexivity | (symmetry ; auto) ].
+Program Instance pointwise_equivalence {A} `(eqb : Equivalence B eqB) :
+ Equivalence (pointwise_relation A eqB) | 9.
Next Obligation.
Proof.
- transitivity (y x0) ; auto.
+ transitivity (y a) ; auto.
Qed.
-
diff --git a/theories/Classes/Functions.v b/theories/Classes/Functions.v
index 4c844911..998f8cb7 100644
--- a/theories/Classes/Functions.v
+++ b/theories/Classes/Functions.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -13,7 +12,7 @@
Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
91405 Orsay, France *)
-(* $Id: Functions.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: Functions.v 11709 2008-12-20 11:42:15Z msozeau $ *)
Require Import Coq.Classes.RelationClasses.
Require Import Coq.Classes.Morphisms.
@@ -21,22 +20,22 @@ Require Import Coq.Classes.Morphisms.
Set Implicit Arguments.
Unset Strict Implicit.
-Class Injective ((m : Morphism (A -> B) (RA ++> RB) f)) : Prop :=
+Class Injective `(m : Morphism (A -> B) (RA ++> RB) f) : Prop :=
injective : forall x y : A, RB (f x) (f y) -> RA x y.
-Class ((m : Morphism (A -> B) (RA ++> RB) f)) => Surjective : Prop :=
+Class Surjective `(m : Morphism (A -> B) (RA ++> RB) f) : Prop :=
surjective : forall y, exists x : A, RB y (f x).
-Definition Bijective ((m : Morphism (A -> B) (RA ++> RB) (f : A -> B))) :=
+Definition Bijective `(m : Morphism (A -> B) (RA ++> RB) (f : A -> B)) :=
Injective m /\ Surjective m.
-Class MonoMorphism (( m : Morphism (A -> B) (eqA ++> eqB) )) :=
+Class MonoMorphism `(m : Morphism (A -> B) (eqA ++> eqB)) :=
monic :> Injective m.
-Class EpiMorphism ((m : Morphism (A -> B) (eqA ++> eqB))) :=
+Class EpiMorphism `(m : Morphism (A -> B) (eqA ++> eqB)) :=
epic :> Surjective m.
-Class IsoMorphism ((m : Morphism (A -> B) (eqA ++> eqB))) :=
- monomorphism :> MonoMorphism m ; epimorphism :> EpiMorphism m.
+Class IsoMorphism `(m : Morphism (A -> B) (eqA ++> eqB)) :=
+ { monomorphism :> MonoMorphism m ; epimorphism :> EpiMorphism m }.
-Class ((m : Morphism (A -> A) (eqA ++> eqA))) [ ! IsoMorphism m ] => AutoMorphism.
+Class AutoMorphism `(m : Morphism (A -> A) (eqA ++> eqA)) {I : IsoMorphism m}.
diff --git a/theories/Classes/Init.v b/theories/Classes/Init.v
index e5f951d0..5df7a4ed 100644
--- a/theories/Classes/Init.v
+++ b/theories/Classes/Init.v
@@ -13,12 +13,18 @@
Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
91405 Orsay, France *)
-(* $Id: Init.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: Init.v 11709 2008-12-20 11:42:15Z msozeau $ *)
(* Ltac typeclass_instantiation := typeclasses eauto || eauto. *)
Tactic Notation "clapply" ident(c) :=
- eapply @c ; eauto with typeclass_instances.
+ eapply @c ; typeclasses eauto.
+
+(** Hints for the proof search: these combinators should be considered rigid. *)
+
+Require Import Coq.Program.Basics.
+
+Typeclasses Opaque id const flip compose arrow impl iff.
(** The unconvertible typeclass, to test that two objects of the same type are
actually different. *)
@@ -27,8 +33,8 @@ Class Unconvertible (A : Type) (a b : A).
Ltac unconvertible :=
match goal with
- | |- @Unconvertible _ ?x ?y => conv x y ; fail 1 "Convertible"
- | |- _ => apply Build_Unconvertible
+ | |- @Unconvertible _ ?x ?y => unify x y with typeclass_instances ; fail 1 "Convertible"
+ | |- _ => eapply Build_Unconvertible
end.
Hint Extern 0 (@Unconvertible _ _ _) => unconvertible : typeclass_instances. \ No newline at end of file
diff --git a/theories/Classes/Morphisms.v b/theories/Classes/Morphisms.v
index c2ae026d..86097a56 100644
--- a/theories/Classes/Morphisms.v
+++ b/theories/Classes/Morphisms.v
@@ -13,16 +13,15 @@
Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
91405 Orsay, France *)
-(* $Id: Morphisms.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: Morphisms.v 11709 2008-12-20 11:42:15Z msozeau $ *)
+
+Set Manual Implicit Arguments.
Require Import Coq.Program.Basics.
Require Import Coq.Program.Tactics.
Require Import Coq.Relations.Relation_Definitions.
Require Export Coq.Classes.RelationClasses.
-Set Implicit Arguments.
-Unset Strict Implicit.
-
(** * Morphisms.
We now turn to the definition of [Morphism] and declare standard instances.
@@ -32,13 +31,9 @@ Unset Strict Implicit.
The relation [R] will be instantiated by [respectful] and [A] by an arrow type
for usual morphisms. *)
-Class Morphism A (R : relation A) (m : A) : Prop :=
+Class Morphism {A} (R : relation A) (m : A) : Prop :=
respect : R m m.
-(** We make the type implicit, it can be infered from the relations. *)
-
-Implicit Arguments Morphism [A].
-
(** Respectful morphisms. *)
(** The fully dependent version, not used yet. *)
@@ -53,7 +48,7 @@ Definition respectful_hetero
(** The non-dependent version is an instance where we forget dependencies. *)
-Definition respectful (A B : Type)
+Definition respectful {A B : Type}
(R : relation A) (R' : relation B) : relation (A -> B) :=
Eval compute in @respectful_hetero A A (fun _ => B) (fun _ => B) R (fun _ _ => R').
@@ -75,13 +70,20 @@ Arguments Scope respectful [type_scope type_scope signature_scope signature_scop
Open Local Scope signature_scope.
-(** Pointwise lifting is just respect with leibniz equality on the left. *)
+(** Dependent pointwise lifting of a relation on the range. *)
+
+Definition forall_relation {A : Type} {B : A -> Type} (sig : Π a : A, relation (B a)) : relation (Π x : A, B x) :=
+ λ f g, Π a : A, sig a (f a) (g a).
+
+Arguments Scope forall_relation [type_scope type_scope signature_scope].
-Definition pointwise_relation {A B : Type} (R : relation B) : relation (A -> B) :=
- fun f g => forall x : A, R (f x) (g x).
+(** Non-dependent pointwise lifting *)
+
+Definition pointwise_relation (A : Type) {B : Type} (R : relation B) : relation (A -> B) :=
+ Eval compute in forall_relation (B:=λ _, B) (λ _, R).
Lemma pointwise_pointwise A B (R : relation B) :
- relation_equivalence (pointwise_relation R) (@eq A ==> R).
+ relation_equivalence (pointwise_relation A R) (@eq A ==> R).
Proof. intros. split. simpl_relation. firstorder. Qed.
(** We can build a PER on the Coq function space if we have PERs on the domain and
@@ -91,24 +93,26 @@ Hint Unfold Reflexive : core.
Hint Unfold Symmetric : core.
Hint Unfold Transitive : core.
-Program Instance respectful_per [ PER A (R : relation A), PER B (R' : relation B) ] :
- PER (A -> B) (R ==> R').
+Typeclasses Opaque respectful pointwise_relation forall_relation.
+
+Program Instance respectful_per `(PER A (R : relation A), PER B (R' : relation B)) :
+ PER (R ==> R').
Next Obligation.
Proof with auto.
- assert(R x0 x0).
+ assert(R x0 x0).
transitivity y0... symmetry...
transitivity (y x0)...
Qed.
(** Subrelations induce a morphism on the identity. *)
-Instance subrelation_id_morphism [ subrelation A R₁ R₂ ] : Morphism (R₁ ==> R₂) id.
+Instance subrelation_id_morphism `(subrelation A R₁ R₂) : Morphism (R₁ ==> R₂) id.
Proof. firstorder. Qed.
(** The subrelation property goes through products as usual. *)
-Instance morphisms_subrelation_respectful [ subl : subrelation A R₂ R₁, subr : subrelation B S₁ S₂ ] :
+Instance morphisms_subrelation_respectful `(subl : subrelation A R₂ R₁, subr : subrelation B S₁ S₂) :
subrelation (R₁ ==> S₁) (R₂ ==> S₂).
Proof. simpl_relation. apply subr. apply H. apply subl. apply H0. Qed.
@@ -119,8 +123,8 @@ Proof. simpl_relation. Qed.
(** [Morphism] is itself a covariant morphism for [subrelation]. *)
-Lemma subrelation_morphism [ mor : Morphism A R₁ m, unc : Unconvertible (relation A) R₁ R₂,
- sub : subrelation A R₁ R₂ ] : Morphism R₂ m.
+Lemma subrelation_morphism `(mor : Morphism A R₁ m, unc : Unconvertible (relation A) R₁ R₂,
+ sub : subrelation A R₁ R₂) : Morphism R₂ m.
Proof.
intros. apply sub. apply mor.
Qed.
@@ -153,14 +157,14 @@ Proof. firstorder. Qed.
Instance iff_inverse_impl_subrelation : subrelation iff (inverse impl).
Proof. firstorder. Qed.
-Instance pointwise_subrelation [ sub : subrelation A R R' ] :
- subrelation (pointwise_relation (A:=B) R) (pointwise_relation R') | 4.
+Instance pointwise_subrelation {A} `(sub : subrelation B R R') :
+ subrelation (pointwise_relation A R) (pointwise_relation A R') | 4.
Proof. reduce. unfold pointwise_relation in *. apply sub. apply H. Qed.
(** The complement of a relation conserves its morphisms. *)
Program Instance complement_morphism
- [ mR : Morphism (A -> A -> Prop) (RA ==> RA ==> iff) R ] :
+ `(mR : Morphism (A -> A -> Prop) (RA ==> RA ==> iff) R) :
Morphism (RA ==> RA ==> iff) (complement R).
Next Obligation.
@@ -173,7 +177,7 @@ Program Instance complement_morphism
(** The [inverse] too, actually the [flip] instance is a bit more general. *)
Program Instance flip_morphism
- [ mor : Morphism (A -> B -> C) (RA ==> RB ==> RC) f ] :
+ `(mor : Morphism (A -> B -> C) (RA ==> RB ==> RC) f) :
Morphism (RB ==> RA ==> RC) (flip f).
Next Obligation.
@@ -185,7 +189,7 @@ Program Instance flip_morphism
contravariant in the first argument, covariant in the second. *)
Program Instance trans_contra_co_morphism
- [ Transitive A R ] : Morphism (R --> R ++> impl) R.
+ `(Transitive A R) : Morphism (R --> R ++> impl) R.
Next Obligation.
Proof with auto.
@@ -196,7 +200,7 @@ Program Instance trans_contra_co_morphism
(** Morphism declarations for partial applications. *)
Program Instance trans_contra_inv_impl_morphism
- [ Transitive A R ] : Morphism (R --> inverse impl) (R x) | 3.
+ `(Transitive A R) : Morphism (R --> inverse impl) (R x) | 3.
Next Obligation.
Proof with auto.
@@ -204,7 +208,7 @@ Program Instance trans_contra_inv_impl_morphism
Qed.
Program Instance trans_co_impl_morphism
- [ Transitive A R ] : Morphism (R ==> impl) (R x) | 3.
+ `(Transitive A R) : Morphism (R ==> impl) (R x) | 3.
Next Obligation.
Proof with auto.
@@ -212,7 +216,7 @@ Program Instance trans_co_impl_morphism
Qed.
Program Instance trans_sym_co_inv_impl_morphism
- [ PER A R ] : Morphism (R ==> inverse impl) (R x) | 2.
+ `(PER A R) : Morphism (R ==> inverse impl) (R x) | 2.
Next Obligation.
Proof with auto.
@@ -220,7 +224,7 @@ Program Instance trans_sym_co_inv_impl_morphism
Qed.
Program Instance trans_sym_contra_impl_morphism
- [ PER A R ] : Morphism (R --> impl) (R x) | 2.
+ `(PER A R) : Morphism (R --> impl) (R x) | 2.
Next Obligation.
Proof with auto.
@@ -228,7 +232,7 @@ Program Instance trans_sym_contra_impl_morphism
Qed.
Program Instance per_partial_app_morphism
- [ PER A R ] : Morphism (R ==> iff) (R x) | 1.
+ `(PER A R) : Morphism (R ==> iff) (R x) | 1.
Next Obligation.
Proof with auto.
@@ -242,7 +246,7 @@ Program Instance per_partial_app_morphism
to get an [R y z] goal. *)
Program Instance trans_co_eq_inv_impl_morphism
- [ Transitive A R ] : Morphism (R ==> (@eq A) ==> inverse impl) R | 2.
+ `(Transitive A R) : Morphism (R ==> (@eq A) ==> inverse impl) R | 2.
Next Obligation.
Proof with auto.
@@ -251,7 +255,7 @@ Program Instance trans_co_eq_inv_impl_morphism
(** Every Symmetric and Transitive relation gives rise to an equivariant morphism. *)
-Program Instance PER_morphism [ PER A R ] : Morphism (R ==> R ==> iff) R | 1.
+Program Instance PER_morphism `(PER A R) : Morphism (R ==> R ==> iff) R | 1.
Next Obligation.
Proof with auto.
@@ -261,7 +265,7 @@ Program Instance PER_morphism [ PER A R ] : Morphism (R ==> R ==> iff) R | 1.
transitivity y... transitivity y0... symmetry...
Qed.
-Lemma symmetric_equiv_inverse [ Symmetric A R ] : relation_equivalence R (flip R).
+Lemma symmetric_equiv_inverse `(Symmetric A R) : relation_equivalence R (flip R).
Proof. firstorder. Qed.
Program Instance compose_morphism A B C R₀ R₁ R₂ :
@@ -276,7 +280,7 @@ Program Instance compose_morphism A B C R₀ R₁ R₂ :
(** Coq functions are morphisms for leibniz equality,
applied only if really needed. *)
-Instance reflexive_eq_dom_reflexive (A : Type) [ Reflexive B R' ] :
+Instance reflexive_eq_dom_reflexive (A : Type) `(Reflexive B R') :
Reflexive (@Logic.eq A ==> R').
Proof. simpl_relation. Qed.
@@ -307,20 +311,20 @@ Qed.
to set different priorities in different hint bases and select a particular hint database for
resolution of a type class constraint.*)
-Class MorphismProxy A (R : relation A) (m : A) : Prop :=
+Class MorphismProxy {A} (R : relation A) (m : A) : Prop :=
respect_proxy : R m m.
Instance reflexive_morphism_proxy
- [ Reflexive A R ] (x : A) : MorphismProxy R x | 1.
+ `(Reflexive A R) (x : A) : MorphismProxy R x | 1.
Proof. firstorder. Qed.
Instance morphism_morphism_proxy
- [ Morphism A R x ] : MorphismProxy R x | 2.
+ `(Morphism A R x) : MorphismProxy R x | 2.
Proof. firstorder. Qed.
(** [R] is Reflexive, hence we can build the needed proof. *)
-Lemma Reflexive_partial_app_morphism [ Morphism (A -> B) (R ==> R') m, MorphismProxy A R x ] :
+Lemma Reflexive_partial_app_morphism `(Morphism (A -> B) (R ==> R') m, MorphismProxy A R x) :
Morphism R' (m x).
Proof. simpl_relation. Qed.
@@ -399,38 +403,48 @@ Qed.
(** Special-purpose class to do normalization of signatures w.r.t. inverse. *)
-Class (A : Type) => Normalizes (m : relation A) (m' : relation A) : Prop :=
+Class Normalizes (A : Type) (m : relation A) (m' : relation A) : Prop :=
normalizes : relation_equivalence m m'.
-Instance inverse_respectful_norm :
- ! Normalizes (A -> B) (inverse R ==> inverse R') (inverse (R ==> R')) .
-Proof. firstorder. Qed.
+(** Current strategy: add [inverse] everywhere and reduce using [subrelation]
+ afterwards. *)
+
+Lemma inverse_atom A R : Normalizes A R (inverse (inverse R)).
+Proof.
+ firstorder.
+Qed.
-(* If not an inverse on the left, do a double inverse. *)
+Lemma inverse_arrow `(NA : Normalizes A R (inverse R'''), NB : Normalizes B R' (inverse R'')) :
+ Normalizes (A -> B) (R ==> R') (inverse (R''' ==> R'')%signature).
+Proof. unfold Normalizes. intros.
+ rewrite NA, NB. firstorder.
+Qed.
+
+Ltac inverse :=
+ match goal with
+ | [ |- Normalizes _ (respectful _ _) _ ] => eapply @inverse_arrow
+ | _ => eapply @inverse_atom
+ end.
+
+Hint Extern 1 (Normalizes _ _ _) => inverse : typeclass_instances.
+
+(** Treating inverse: can't make them direct instances as we
+ need at least a [flip] present in the goal. *)
-Instance not_inverse_respectful_norm :
- ! Normalizes (A -> B) (R ==> inverse R') (inverse (inverse R ==> R')) | 4.
+Lemma inverse1 `(subrelation A R' R) : subrelation (inverse (inverse R')) R.
Proof. firstorder. Qed.
-Instance inverse_respectful_rec_norm [ Normalizes B R' (inverse R'') ] :
- ! Normalizes (A -> B) (inverse R ==> R') (inverse (R ==> R'')).
-Proof. red ; intros.
- assert(r:=normalizes).
- setoid_rewrite r.
- setoid_rewrite inverse_respectful.
- reflexivity.
-Qed.
+Lemma inverse2 `(subrelation A R R') : subrelation R (inverse (inverse R')).
+Proof. firstorder. Qed.
-(** Once we have normalized, we will apply this instance to simplify the problem. *)
+Hint Extern 1 (subrelation (flip _) _) => eapply @inverse1 : typeclass_instances.
+Hint Extern 1 (subrelation _ (flip _)) => eapply @inverse2 : typeclass_instances.
-Definition morphism_inverse_morphism [ mor : Morphism A R m ] : Morphism (inverse R) m := mor.
+(** Once we have normalized, we will apply this instance to simplify the problem. *)
-Ltac morphism_inverse :=
- match goal with
- [ |- @Morphism _ (flip _) _ ] => eapply @morphism_inverse_morphism
- end.
+Definition morphism_inverse_morphism `(mor : Morphism A R m) : Morphism (inverse R) m := mor.
-Hint Extern 2 (@Morphism _ _ _) => morphism_inverse : typeclass_instances.
+Hint Extern 2 (@Morphism _ (flip _) _) => eapply @morphism_inverse_morphism : typeclass_instances.
(** Bootstrap !!! *)
@@ -445,7 +459,7 @@ Proof.
apply H0.
Qed.
-Lemma morphism_releq_morphism [ Normalizes A R R', Morphism _ R' m ] : Morphism R m.
+Lemma morphism_releq_morphism `(Normalizes A R R', Morphism _ R' m) : Morphism R m.
Proof.
intros.
@@ -467,7 +481,7 @@ Hint Extern 6 (@Morphism _ _ _) => morphism_normalization : typeclass_instances.
(** Every reflexive relation gives rise to a morphism, only for immediately solving goals without variables. *)
-Lemma reflexive_morphism [ Reflexive A R ] (x : A)
+Lemma reflexive_morphism `{Reflexive A R} (x : A)
: Morphism R x.
Proof. firstorder. Qed.
diff --git a/theories/Classes/Morphisms_Prop.v b/theories/Classes/Morphisms_Prop.v
index ec62e12e..3bbd56cf 100644
--- a/theories/Classes/Morphisms_Prop.v
+++ b/theories/Classes/Morphisms_Prop.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-top" "Coq.Classes.Morphisms") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -32,18 +31,6 @@ Program Instance not_iff_morphism :
Program Instance and_impl_morphism :
Morphism (impl ==> impl ==> impl) and.
-(* Program Instance and_impl_iff_morphism : *)
-(* Morphism (impl ==> iff ==> impl) and. *)
-
-(* Program Instance and_iff_impl_morphism : *)
-(* Morphism (iff ==> impl ==> impl) and. *)
-
-(* Program Instance and_inverse_impl_iff_morphism : *)
-(* Morphism (inverse impl ==> iff ==> inverse impl) and. *)
-
-(* Program Instance and_iff_inverse_impl_morphism : *)
-(* Morphism (iff ==> inverse impl ==> inverse impl) and. *)
-
Program Instance and_iff_morphism :
Morphism (iff ==> iff ==> iff) and.
@@ -52,18 +39,6 @@ Program Instance and_iff_morphism :
Program Instance or_impl_morphism :
Morphism (impl ==> impl ==> impl) or.
-(* Program Instance or_impl_iff_morphism : *)
-(* Morphism (impl ==> iff ==> impl) or. *)
-
-(* Program Instance or_iff_impl_morphism : *)
-(* Morphism (iff ==> impl ==> impl) or. *)
-
-(* Program Instance or_inverse_impl_iff_morphism : *)
-(* Morphism (inverse impl ==> iff ==> inverse impl) or. *)
-
-(* Program Instance or_iff_inverse_impl_morphism : *)
-(* Morphism (iff ==> inverse impl ==> inverse impl) or. *)
-
Program Instance or_iff_morphism :
Morphism (iff ==> iff ==> iff) or.
@@ -73,7 +48,7 @@ Program Instance iff_iff_iff_impl_morphism : Morphism (iff ==> iff ==> iff) impl
(** Morphisms for quantifiers *)
-Program Instance ex_iff_morphism {A : Type} : Morphism (pointwise_relation iff ==> iff) (@ex A).
+Program Instance ex_iff_morphism {A : Type} : Morphism (pointwise_relation A iff ==> iff) (@ex A).
Next Obligation.
Proof.
@@ -87,7 +62,7 @@ Program Instance ex_iff_morphism {A : Type} : Morphism (pointwise_relation iff =
Qed.
Program Instance ex_impl_morphism {A : Type} :
- Morphism (pointwise_relation impl ==> impl) (@ex A).
+ Morphism (pointwise_relation A impl ==> impl) (@ex A).
Next Obligation.
Proof.
@@ -96,7 +71,7 @@ Program Instance ex_impl_morphism {A : Type} :
Qed.
Program Instance ex_inverse_impl_morphism {A : Type} :
- Morphism (pointwise_relation (inverse impl) ==> inverse impl) (@ex A).
+ Morphism (pointwise_relation A (inverse impl) ==> inverse impl) (@ex A).
Next Obligation.
Proof.
@@ -105,7 +80,7 @@ Program Instance ex_inverse_impl_morphism {A : Type} :
Qed.
Program Instance all_iff_morphism {A : Type} :
- Morphism (pointwise_relation iff ==> iff) (@all A).
+ Morphism (pointwise_relation A iff ==> iff) (@all A).
Next Obligation.
Proof.
@@ -114,7 +89,7 @@ Program Instance all_iff_morphism {A : Type} :
Qed.
Program Instance all_impl_morphism {A : Type} :
- Morphism (pointwise_relation impl ==> impl) (@all A).
+ Morphism (pointwise_relation A impl ==> impl) (@all A).
Next Obligation.
Proof.
@@ -123,7 +98,7 @@ Program Instance all_impl_morphism {A : Type} :
Qed.
Program Instance all_inverse_impl_morphism {A : Type} :
- Morphism (pointwise_relation (inverse impl) ==> inverse impl) (@all A).
+ Morphism (pointwise_relation A (inverse impl) ==> inverse impl) (@all A).
Next Obligation.
Proof.
diff --git a/theories/Classes/Morphisms_Relations.v b/theories/Classes/Morphisms_Relations.v
index 1b389667..24b8d636 100644
--- a/theories/Classes/Morphisms_Relations.v
+++ b/theories/Classes/Morphisms_Relations.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-top" "Coq.Classes.Morphisms") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -42,17 +41,14 @@ Proof. do 2 red. unfold predicate_implication. auto. Qed.
(* when [R] and [R'] are in [relation_equivalence]. *)
Instance relation_equivalence_pointwise :
- Morphism (relation_equivalence ==> pointwise_relation (A:=A) (pointwise_relation (A:=A) iff)) id.
+ Morphism (relation_equivalence ==> pointwise_relation A (pointwise_relation A iff)) id.
Proof. intro. apply (predicate_equivalence_pointwise (cons A (cons A nil))). Qed.
Instance subrelation_pointwise :
- Morphism (subrelation ==> pointwise_relation (A:=A) (pointwise_relation (A:=A) impl)) id.
+ Morphism (subrelation ==> pointwise_relation A (pointwise_relation A impl)) id.
Proof. intro. apply (predicate_implication_pointwise (cons A (cons A nil))). Qed.
Lemma inverse_pointwise_relation A (R : relation A) :
- relation_equivalence (pointwise_relation (inverse R)) (inverse (pointwise_relation (A:=A) R)).
+ relation_equivalence (pointwise_relation A (inverse R)) (inverse (pointwise_relation A R)).
Proof. intros. split; firstorder. Qed.
-
-
-
diff --git a/theories/Classes/RelationClasses.v b/theories/Classes/RelationClasses.v
index 9a43a1ba..f95894be 100644
--- a/theories/Classes/RelationClasses.v
+++ b/theories/Classes/RelationClasses.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-name: "coqtop.byte"; coq-prog-args: ("-emacs-U" "-top" "Coq.Classes.RelationClasses") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -14,7 +13,7 @@
Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
91405 Orsay, France *)
-(* $Id: RelationClasses.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: RelationClasses.v 11800 2009-01-18 18:34:15Z msozeau $ *)
Require Export Coq.Classes.Init.
Require Import Coq.Program.Basics.
@@ -23,12 +22,13 @@ Require Export Coq.Relations.Relation_Definitions.
(** We allow to unfold the [relation] definition while doing morphism search. *)
-Typeclasses unfold relation.
-
Notation inverse R := (flip (R:relation _) : relation _).
Definition complement {A} (R : relation A) : relation A := fun x y => R x y -> False.
+(** Opaque for proof-search. *)
+Typeclasses Opaque complement.
+
(** These are convertible. *)
Lemma complement_inverse : forall A (R : relation A), complement (inverse R) = inverse (complement R).
@@ -39,64 +39,65 @@ Proof. reflexivity. Qed.
Set Implicit Arguments.
Unset Strict Implicit.
-Class Reflexive A (R : relation A) :=
+Class Reflexive {A} (R : relation A) :=
reflexivity : forall x, R x x.
-Class Irreflexive A (R : relation A) :=
+Class Irreflexive {A} (R : relation A) :=
irreflexivity :> Reflexive (complement R).
-Class Symmetric A (R : relation A) :=
+Class Symmetric {A} (R : relation A) :=
symmetry : forall x y, R x y -> R y x.
-Class Asymmetric A (R : relation A) :=
+Class Asymmetric {A} (R : relation A) :=
asymmetry : forall x y, R x y -> R y x -> False.
-Class Transitive A (R : relation A) :=
+Class Transitive {A} (R : relation A) :=
transitivity : forall x y z, R x y -> R y z -> R x z.
Hint Resolve @irreflexivity : ord.
Unset Implicit Arguments.
+(** A HintDb for relations. *)
+
+Ltac solve_relation :=
+ match goal with
+ | [ |- ?R ?x ?x ] => reflexivity
+ | [ H : ?R ?x ?y |- ?R ?y ?x ] => symmetry ; exact H
+ end.
+
+Hint Extern 4 => solve_relation : relations.
+
(** We can already dualize all these properties. *)
-Program Instance flip_Reflexive [ Reflexive A R ] : Reflexive (flip R) :=
- reflexivity := reflexivity (R:=R).
+Program Instance flip_Reflexive `(Reflexive A R) : Reflexive (flip R) :=
+ reflexivity (R:=R).
-Program Instance flip_Irreflexive [ Irreflexive A R ] : Irreflexive (flip R) :=
- irreflexivity := irreflexivity (R:=R).
+Program Instance flip_Irreflexive `(Irreflexive A R) : Irreflexive (flip R) :=
+ irreflexivity (R:=R).
-Program Instance flip_Symmetric [ Symmetric A R ] : Symmetric (flip R).
+Program Instance flip_Symmetric `(Symmetric A R) : Symmetric (flip R).
- Solve Obligations using unfold flip ; program_simpl ; clapply Symmetric.
+ Solve Obligations using unfold flip ; intros ; tcapp symmetry ; assumption.
-Program Instance flip_Asymmetric [ Asymmetric A R ] : Asymmetric (flip R).
+Program Instance flip_Asymmetric `(Asymmetric A R) : Asymmetric (flip R).
- Solve Obligations using program_simpl ; unfold flip in * ; intros ; clapply asymmetry.
+ Solve Obligations using program_simpl ; unfold flip in * ; intros ; typeclass_app asymmetry ; eauto.
-Program Instance flip_Transitive [ Transitive A R ] : Transitive (flip R).
+Program Instance flip_Transitive `(Transitive A R) : Transitive (flip R).
- Solve Obligations using unfold flip ; program_simpl ; clapply transitivity.
+ Solve Obligations using unfold flip ; program_simpl ; typeclass_app transitivity ; eauto.
-Program Instance Reflexive_complement_Irreflexive [ Reflexive A (R : relation A) ]
+Program Instance Reflexive_complement_Irreflexive `(Reflexive A (R : relation A))
: Irreflexive (complement R).
Next Obligation.
- Proof.
- unfold complement.
- red. intros H.
- intros H' ; apply H'.
- apply reflexivity.
- Qed.
-
+ Proof. firstorder. Qed.
-Program Instance complement_Symmetric [ Symmetric A (R : relation A) ] : Symmetric (complement R).
+Program Instance complement_Symmetric `(Symmetric A (R : relation A)) : Symmetric (complement R).
Next Obligation.
- Proof.
- red ; intros H'.
- apply (H (symmetry H')).
- Qed.
+ Proof. firstorder. Qed.
(** * Standard instances. *)
@@ -147,52 +148,52 @@ Program Instance eq_Transitive : Transitive (@eq A).
(** A [PreOrder] is both Reflexive and Transitive. *)
-Class PreOrder A (R : relation A) : Prop :=
+Class PreOrder {A} (R : relation A) : Prop := {
PreOrder_Reflexive :> Reflexive R ;
- PreOrder_Transitive :> Transitive R.
+ PreOrder_Transitive :> Transitive R }.
(** A partial equivalence relation is Symmetric and Transitive. *)
-Class PER (carrier : Type) (pequiv : relation carrier) : Prop :=
- PER_Symmetric :> Symmetric pequiv ;
- PER_Transitive :> Transitive pequiv.
+Class PER {A} (R : relation A) : Prop := {
+ PER_Symmetric :> Symmetric R ;
+ PER_Transitive :> Transitive R }.
(** Equivalence relations. *)
-Class Equivalence (carrier : Type) (equiv : relation carrier) : Prop :=
- Equivalence_Reflexive :> Reflexive equiv ;
- Equivalence_Symmetric :> Symmetric equiv ;
- Equivalence_Transitive :> Transitive equiv.
+Class Equivalence {A} (R : relation A) : Prop := {
+ Equivalence_Reflexive :> Reflexive R ;
+ Equivalence_Symmetric :> Symmetric R ;
+ Equivalence_Transitive :> Transitive R }.
(** An Equivalence is a PER plus reflexivity. *)
-Instance Equivalence_PER [ Equivalence A R ] : PER A R | 10 :=
- PER_Symmetric := Equivalence_Symmetric ;
- PER_Transitive := Equivalence_Transitive.
+Instance Equivalence_PER `(Equivalence A R) : PER R | 10 :=
+ { PER_Symmetric := Equivalence_Symmetric ;
+ PER_Transitive := Equivalence_Transitive }.
(** We can now define antisymmetry w.r.t. an equivalence relation on the carrier. *)
-Class Antisymmetric ((equ : Equivalence A eqA)) (R : relation A) :=
+Class Antisymmetric A eqA `{equ : Equivalence A eqA} (R : relation A) :=
antisymmetry : forall x y, R x y -> R y x -> eqA x y.
-Program Instance flip_antiSymmetric {{Antisymmetric A eqA R}} :
+Program Instance flip_antiSymmetric `(Antisymmetric A eqA R) :
! Antisymmetric A eqA (flip R).
(** Leibinz equality [eq] is an equivalence relation.
The instance has low priority as it is always applicable
if only the type is constrained. *)
-Program Instance eq_equivalence : Equivalence A (@eq A) | 10.
+Program Instance eq_equivalence : Equivalence (@eq A) | 10.
(** Logical equivalence [iff] is an equivalence relation. *)
-Program Instance iff_equivalence : Equivalence Prop iff.
+Program Instance iff_equivalence : Equivalence iff.
(** We now develop a generalization of results on relations for arbitrary predicates.
The resulting theory can be applied to homogeneous binary relations but also to
arbitrary n-ary predicates. *)
-Require Import List.
+Require Import Coq.Lists.List.
(* Notation " [ ] " := nil : list_scope. *)
(* Notation " [ x ; .. ; y ] " := (cons x .. (cons y nil) ..) (at level 1) : list_scope. *)
@@ -273,7 +274,7 @@ Definition predicate_implication {l : list Type} :=
(** Notations for pointwise equivalence and implication of predicates. *)
Infix "<∙>" := predicate_equivalence (at level 95, no associativity) : predicate_scope.
-Infix "-∙>" := predicate_implication (at level 70) : predicate_scope.
+Infix "-∙>" := predicate_implication (at level 70, right associativity) : predicate_scope.
Open Local Scope predicate_scope.
@@ -306,7 +307,7 @@ Notation "∙⊄∙" := false_predicate : predicate_scope.
(** Predicate equivalence is an equivalence, and predicate implication defines a preorder. *)
Program Instance predicate_equivalence_equivalence :
- Equivalence (predicate l) predicate_equivalence.
+ Equivalence (@predicate_equivalence l).
Next Obligation.
induction l ; firstorder.
@@ -324,7 +325,7 @@ Program Instance predicate_equivalence_equivalence :
Qed.
Program Instance predicate_implication_preorder :
- PreOrder (predicate l) predicate_implication.
+ PreOrder (@predicate_implication l).
Next Obligation.
induction l ; firstorder.
@@ -356,10 +357,10 @@ Definition relation_disjunction {A} (R : relation A) (R' : relation A) : relatio
(** Relation equivalence is an equivalence, and subrelation defines a partial order. *)
Instance relation_equivalence_equivalence (A : Type) :
- Equivalence (relation A) relation_equivalence.
+ Equivalence (@relation_equivalence A).
Proof. intro A. exact (@predicate_equivalence_equivalence (cons A (cons A nil))). Qed.
-Instance relation_implication_preorder : PreOrder (relation A) subrelation.
+Instance relation_implication_preorder : PreOrder (@subrelation A).
Proof. intro A. exact (@predicate_implication_preorder (cons A (cons A nil))). Qed.
(** *** Partial Order.
@@ -367,14 +368,14 @@ Proof. intro A. exact (@predicate_implication_preorder (cons A (cons A nil))). Q
We give an equivalent definition, up-to an equivalence relation
on the carrier. *)
-Class [ equ : Equivalence A eqA, preo : PreOrder A R ] => PartialOrder :=
+Class PartialOrder A eqA `{equ : Equivalence A eqA} R `{preo : PreOrder A R} :=
partial_order_equivalence : relation_equivalence eqA (relation_conjunction R (inverse R)).
(** The equivalence proof is sufficient for proving that [R] must be a morphism
for equivalence (see Morphisms).
It is also sufficient to show that [R] is antisymmetric w.r.t. [eqA] *)
-Instance partial_order_antisym [ PartialOrder A eqA R ] : ! Antisymmetric A eqA R.
+Instance partial_order_antisym `(PartialOrder A eqA R) : ! Antisymmetric A eqA R.
Proof with auto.
reduce_goal. pose proof partial_order_equivalence as poe. do 3 red in poe.
apply <- poe. firstorder.
@@ -389,3 +390,6 @@ Program Instance subrelation_partial_order :
Proof.
unfold relation_equivalence in *. firstorder.
Qed.
+
+Typeclasses Opaque arrows predicate_implication predicate_equivalence
+ relation_equivalence pointwise_lifting.
diff --git a/theories/Classes/SetoidAxioms.v b/theories/Classes/SetoidAxioms.v
index 9264b6d2..305168ec 100644
--- a/theories/Classes/SetoidAxioms.v
+++ b/theories/Classes/SetoidAxioms.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -13,7 +12,7 @@
* Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
* 91405 Orsay, France *)
-(* $Id: SetoidAxioms.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: SetoidAxioms.v 11709 2008-12-20 11:42:15Z msozeau $ *)
Require Import Coq.Program.Program.
@@ -22,10 +21,10 @@ Unset Strict Implicit.
Require Export Coq.Classes.SetoidClass.
-(* Application of the extensionality axiom to turn a goal on leibinz equality to
- a setoid equivalence. *)
+(* Application of the extensionality axiom to turn a goal on
+ Leibinz equality to a setoid equivalence (use with care!). *)
-Axiom setoideq_eq : forall [ sa : Setoid a ] (x y : a), x == y -> x = y.
+Axiom setoideq_eq : forall `{sa : Setoid a} (x y : a), x == y -> x = y.
(** Application of the extensionality principle for setoids. *)
diff --git a/theories/Classes/SetoidClass.v b/theories/Classes/SetoidClass.v
index 178d5333..47f92ada 100644
--- a/theories/Classes/SetoidClass.v
+++ b/theories/Classes/SetoidClass.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -13,7 +12,7 @@
Institution: LRI, CNRS UMR 8623 - UniversitĂcopyright Paris Sud
91405 Orsay, France *)
-(* $Id: SetoidClass.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: SetoidClass.v 11800 2009-01-18 18:34:15Z msozeau $ *)
Set Implicit Arguments.
Unset Strict Implicit.
@@ -27,11 +26,9 @@ Require Import Coq.Classes.Functions.
(** A setoid wraps an equivalence. *)
-Class Setoid A :=
+Class Setoid A := {
equiv : relation A ;
- setoid_equiv :> Equivalence A equiv.
-
-Typeclasses unfold equiv.
+ setoid_equiv :> Equivalence equiv }.
(* Too dangerous instance *)
(* Program Instance [ eqa : Equivalence A eqA ] => *)
@@ -40,13 +37,13 @@ Typeclasses unfold equiv.
(** Shortcuts to make proof search easier. *)
-Definition setoid_refl [ sa : Setoid A ] : Reflexive equiv.
+Definition setoid_refl `(sa : Setoid A) : Reflexive equiv.
Proof. typeclasses eauto. Qed.
-Definition setoid_sym [ sa : Setoid A ] : Symmetric equiv.
+Definition setoid_sym `(sa : Setoid A) : Symmetric equiv.
Proof. typeclasses eauto. Qed.
-Definition setoid_trans [ sa : Setoid A ] : Transitive equiv.
+Definition setoid_trans `(sa : Setoid A) : Transitive equiv.
Proof. typeclasses eauto. Qed.
Existing Instance setoid_refl.
@@ -58,8 +55,8 @@ Existing Instance setoid_trans.
(* Program Instance eq_setoid : Setoid A := *)
(* equiv := eq ; setoid_equiv := eq_equivalence. *)
-Program Instance iff_setoid : Setoid Prop :=
- equiv := iff ; setoid_equiv := iff_equivalence.
+Program Instance iff_setoid : Setoid Prop :=
+ { equiv := iff ; setoid_equiv := iff_equivalence }.
(** Overloaded notations for setoid equivalence and inequivalence. Not to be confused with [eq] and [=]. *)
@@ -87,7 +84,7 @@ Ltac clsubst_nofail :=
Tactic Notation "clsubst" "*" := clsubst_nofail.
-Lemma nequiv_equiv_trans : forall [ Setoid A ] (x y z : A), x =/= y -> y == z -> x =/= z.
+Lemma nequiv_equiv_trans : forall `{Setoid A} (x y z : A), x =/= y -> y == z -> x =/= z.
Proof with auto.
intros; intro.
assert(z == y) by (symmetry ; auto).
@@ -95,7 +92,7 @@ Proof with auto.
contradiction.
Qed.
-Lemma equiv_nequiv_trans : forall [ Setoid A ] (x y z : A), x == y -> y =/= z -> x =/= z.
+Lemma equiv_nequiv_trans : forall `{Setoid A} (x y z : A), x == y -> y =/= z -> x =/= z.
Proof.
intros; intro.
assert(y == x) by (symmetry ; auto).
@@ -122,23 +119,11 @@ Ltac setoidify := repeat setoidify_tac.
(** Every setoid relation gives rise to a morphism, in fact every partial setoid does. *)
-Program Definition setoid_morphism [ sa : Setoid A ] : Morphism (equiv ++> equiv ++> iff) equiv :=
- PER_morphism.
-
-(** Add this very useful instance in the database. *)
-
-Implicit Arguments setoid_morphism [[!sa]].
-Existing Instance setoid_morphism.
-
-Program Definition setoid_partial_app_morphism [ sa : Setoid A ] (x : A) : Morphism (equiv ++> iff) (equiv x) :=
- Reflexive_partial_app_morphism.
-
-Existing Instance setoid_partial_app_morphism.
+Program Instance setoid_morphism `(sa : Setoid A) : Morphism (equiv ++> equiv ++> iff) equiv :=
+ respect.
-Definition type_eq : relation Type :=
- fun x y => x = y.
-
-Program Instance type_equivalence : Equivalence Type type_eq.
+Program Instance setoid_partial_app_morphism `(sa : Setoid A) (x : A) : Morphism (equiv ++> iff) (equiv x) :=
+ respect.
Ltac morphism_tac := try red ; unfold arrow ; intros ; program_simpl ; try tauto.
@@ -148,29 +133,12 @@ Ltac obligation_tactic ::= morphism_tac.
using [iff_impl_id_morphism] if the proof is in [Prop] and
[eq_arrow_id_morphism] if it is in Type. *)
-Program Instance iff_impl_id_morphism : Morphism (iff ++> impl) Basics.id.
-
-(* Program Instance eq_arrow_id_morphism : ? Morphism (eq +++> arrow) id. *)
-
-(* Definition compose_respect (A B C : Type) (R : relation (A -> B)) (R' : relation (B -> C)) *)
-(* (x y : A -> C) : Prop := forall (f : A -> B) (g : B -> C), R f f -> R' g g. *)
-
-(* Program Instance (A B C : Type) (R : relation (A -> B)) (R' : relation (B -> C)) *)
-(* [ mg : ? Morphism R' g ] [ mf : ? Morphism R f ] => *)
-(* compose_morphism : ? Morphism (compose_respect R R') (g o f). *)
-
-(* Next Obligation. *)
-(* Proof. *)
-(* apply (respect (m0:=mg)). *)
-(* apply (respect (m0:=mf)). *)
-(* assumption. *)
-(* Qed. *)
+Program Instance iff_impl_id_morphism : Morphism (iff ++> impl) id.
(** Partial setoids don't require reflexivity so we can build a partial setoid on the function space. *)
-Class PartialSetoid (carrier : Type) :=
- pequiv : relation carrier ;
- pequiv_prf :> PER carrier pequiv.
+Class PartialSetoid (A : Type) :=
+ { pequiv : relation A ; pequiv_prf :> PER pequiv }.
(** Overloaded notation for partial setoid equivalence. *)
diff --git a/theories/Classes/SetoidDec.v b/theories/Classes/SetoidDec.v
index 8a069343..bac64724 100644
--- a/theories/Classes/SetoidDec.v
+++ b/theories/Classes/SetoidDec.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -10,10 +9,10 @@
(* Decidable setoid equality theory.
*
* Author: Matthieu Sozeau
- * Institution: LRI, CNRS UMR 8623 - UniversitĂcopyright Paris Sud
+ * Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
* 91405 Orsay, France *)
-(* $Id: SetoidDec.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: SetoidDec.v 11800 2009-01-18 18:34:15Z msozeau $ *)
Set Implicit Arguments.
Unset Strict Implicit.
@@ -27,12 +26,12 @@ Require Export Coq.Classes.SetoidClass.
Require Import Coq.Logic.Decidable.
-Class DecidableSetoid A [ Setoid A ] :=
+Class DecidableSetoid `(S : Setoid A) :=
setoid_decidable : forall x y : A, decidable (x == y).
(** The [EqDec] class gives a decision procedure for a particular setoid equality. *)
-Class (( s : Setoid A )) => EqDec :=
+Class EqDec `(S : Setoid A) :=
equiv_dec : forall x y : A, { x == y } + { x =/= y }.
(** We define the [==] overloaded notation for deciding equality. It does not take precedence
@@ -52,7 +51,7 @@ Open Local Scope program_scope.
(** Invert the branches. *)
-Program Definition nequiv_dec [ EqDec A ] (x y : A) : { x =/= y } + { x == y } := swap_sumbool (x == y).
+Program Definition nequiv_dec `{EqDec A} (x y : A) : { x =/= y } + { x == y } := swap_sumbool (x == y).
(** Overloaded notation for inequality. *)
@@ -60,10 +59,10 @@ Infix "=/=" := nequiv_dec (no associativity, at level 70).
(** Define boolean versions, losing the logical information. *)
-Definition equiv_decb [ EqDec A ] (x y : A) : bool :=
+Definition equiv_decb `{EqDec A} (x y : A) : bool :=
if x == y then true else false.
-Definition nequiv_decb [ EqDec A ] (x y : A) : bool :=
+Definition nequiv_decb `{EqDec A} (x y : A) : bool :=
negb (equiv_decb x y).
Infix "==b" := equiv_decb (no associativity, at level 70).
@@ -75,19 +74,19 @@ Require Import Coq.Arith.Arith.
(** The equiv is burried inside the setoid, but we can recover it by specifying which setoid we're talking about. *)
-Program Instance eq_setoid A : Setoid A :=
- equiv := eq ; setoid_equiv := eq_equivalence.
+Program Instance eq_setoid A : Setoid A | 10 :=
+ { equiv := eq ; setoid_equiv := eq_equivalence }.
Program Instance nat_eq_eqdec : EqDec (eq_setoid nat) :=
- equiv_dec := eq_nat_dec.
+ eq_nat_dec.
Require Import Coq.Bool.Bool.
Program Instance bool_eqdec : EqDec (eq_setoid bool) :=
- equiv_dec := bool_dec.
+ bool_dec.
Program Instance unit_eqdec : EqDec (eq_setoid unit) :=
- equiv_dec x y := in_left.
+ λ x y, in_left.
Next Obligation.
Proof.
@@ -95,8 +94,8 @@ Program Instance unit_eqdec : EqDec (eq_setoid unit) :=
reflexivity.
Qed.
-Program Instance prod_eqdec [ ! EqDec (eq_setoid A), ! EqDec (eq_setoid B) ] : EqDec (eq_setoid (prod A B)) :=
- equiv_dec x y :=
+Program Instance prod_eqdec `(! EqDec (eq_setoid A), ! EqDec (eq_setoid B)) : EqDec (eq_setoid (prod A B)) :=
+ λ x y,
let '(x1, x2) := x in
let '(y1, y2) := y in
if x1 == y1 then
@@ -108,10 +107,8 @@ Program Instance prod_eqdec [ ! EqDec (eq_setoid A), ! EqDec (eq_setoid B) ] : E
(** Objects of function spaces with countable domains like bool have decidable equality. *)
-Require Import Coq.Program.FunctionalExtensionality.
-
-Program Instance bool_function_eqdec [ ! EqDec (eq_setoid A) ] : EqDec (eq_setoid (bool -> A)) :=
- equiv_dec f g :=
+Program Instance bool_function_eqdec `(! EqDec (eq_setoid A)) : EqDec (eq_setoid (bool -> A)) :=
+ λ f g,
if f true == g true then
if f false == g false then in_left
else in_right
diff --git a/theories/Classes/SetoidTactics.v b/theories/Classes/SetoidTactics.v
index 6398b125..caacc9ec 100644
--- a/theories/Classes/SetoidTactics.v
+++ b/theories/Classes/SetoidTactics.v
@@ -13,7 +13,7 @@
* Institution: LRI, CNRS UMR 8623 - UniversitĂcopyright Paris Sud
* 91405 Orsay, France *)
-(* $Id: SetoidTactics.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: SetoidTactics.v 11709 2008-12-20 11:42:15Z msozeau $ *)
Require Export Coq.Classes.RelationClasses.
Require Export Coq.Classes.Morphisms.
@@ -45,11 +45,11 @@ Class DefaultRelation A (R : relation A).
(** To search for the default relation, just call [default_relation]. *)
-Definition default_relation [ DefaultRelation A R ] := R.
+Definition default_relation `{DefaultRelation A R} := R.
(** Every [Equivalence] gives a default relation, if no other is given (lowest priority). *)
-Instance equivalence_default [ Equivalence A R ] : DefaultRelation R | 4.
+Instance equivalence_default `(Equivalence A R) : DefaultRelation R | 4.
(** The setoid_replace tactics in Ltac, defined in terms of default relations and
the setoid_rewrite tactic. *)
@@ -178,7 +178,7 @@ Ltac reverse_arrows x :=
end.
Ltac default_add_morphism_tactic :=
- intros ;
+ unfold flip ; intros ;
(try destruct_morphism) ;
match goal with
| [ |- (?x ==> ?y) _ _ ] => red_subst_eq_morphism (x ==> y) ; reverse_arrows (x ==> y)
diff --git a/theories/FSets/FMapFacts.v b/theories/FSets/FMapFacts.v
index 05cd1892..df12166e 100644
--- a/theories/FSets/FMapFacts.v
+++ b/theories/FSets/FMapFacts.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FMapFacts.v 11359 2008-09-04 09:43:36Z notin $ *)
+(* $Id: FMapFacts.v 11720 2008-12-28 07:12:15Z letouzey $ *)
(** * Finite maps library *)
@@ -20,9 +20,14 @@ Require Export FMapInterface.
Set Implicit Arguments.
Unset Strict Implicit.
+Hint Extern 1 (Equivalence _) => constructor; congruence.
+
+Notation Leibniz := (@eq _) (only parsing).
+
+
(** * Facts about weak maps *)
-Module WFacts (E:DecidableType)(Import M:WSfun E).
+Module WFacts_fun (E:DecidableType)(Import M:WSfun E).
Notation eq_dec := E.eq_dec.
Definition eqb x y := if eq_dec x y then true else false.
@@ -32,6 +37,15 @@ Proof.
destruct b; destruct b'; intuition.
Qed.
+Lemma eq_option_alt : forall (elt:Type)(o o':option elt),
+ o=o' <-> (forall e, o=Some e <-> o'=Some e).
+Proof.
+split; intros.
+subst; split; auto.
+destruct o; destruct o'; try rewrite H; auto.
+symmetry; rewrite <- H; auto.
+Qed.
+
Lemma MapsTo_fun : forall (elt:Type) m x (e e':elt),
MapsTo x e m -> MapsTo x e' m -> e=e'.
Proof.
@@ -85,14 +99,10 @@ Qed.
Lemma not_find_in_iff : forall m x, ~In x m <-> find x m = None.
Proof.
-intros.
-generalize (find_mapsto_iff m x); destruct (find x m).
-split; intros; try discriminate.
-destruct H0.
-exists e; rewrite H; auto.
-split; auto.
-intros; intros (e,H1).
-rewrite H in H1; discriminate.
+split; intros.
+rewrite eq_option_alt. intro e. rewrite <- find_mapsto_iff.
+split; intro H'; try discriminate. elim H; exists e; auto.
+intros (e,He); rewrite find_mapsto_iff,H in He; discriminate.
Qed.
Lemma in_find_iff : forall m x, In x m <-> find x m <> None.
@@ -334,21 +344,14 @@ Qed.
Lemma find_o : forall m x y, E.eq x y -> find x m = find y m.
Proof.
-intros.
-generalize (find_mapsto_iff m x) (find_mapsto_iff m y) (fun e => MapsTo_iff m e H).
-destruct (find x m); destruct (find y m); intros.
-rewrite <- H0; rewrite H2; rewrite H1; auto.
-symmetry; rewrite <- H1; rewrite <- H2; rewrite H0; auto.
-rewrite <- H0; rewrite H2; rewrite H1; auto.
-auto.
+intros. rewrite eq_option_alt. intro e. rewrite <- 2 find_mapsto_iff.
+apply MapsTo_iff; auto.
Qed.
Lemma empty_o : forall x, find x (empty elt) = None.
Proof.
-intros.
-case_eq (find x (empty elt)); intros; auto.
-generalize (find_2 H).
-rewrite empty_mapsto_iff; intuition.
+intros. rewrite eq_option_alt. intro e.
+rewrite <- find_mapsto_iff, empty_mapsto_iff; now intuition.
Qed.
Lemma empty_a : forall x, mem x (empty elt) = false.
@@ -368,15 +371,12 @@ Qed.
Lemma add_neq_o : forall m x y e,
~ E.eq x y -> find y (add x e m) = find y m.
Proof.
-intros.
-case_eq (find y m); intros; auto with map.
-case_eq (find y (add x e m)); intros; auto with map.
-rewrite <- H0; symmetry.
-apply find_1; apply add_3 with x e; auto with map.
+intros. rewrite eq_option_alt. intro e'. rewrite <- 2 find_mapsto_iff.
+apply add_neq_mapsto_iff; auto.
Qed.
Hint Resolve add_neq_o : map.
-Lemma add_o : forall m x y e,
+Lemma add_o : forall m x y e,
find y (add x e m) = if eq_dec x y then Some e else find y m.
Proof.
intros; destruct (eq_dec x y); auto with map.
@@ -404,45 +404,38 @@ Qed.
Lemma remove_eq_o : forall m x y,
E.eq x y -> find y (remove x m) = None.
Proof.
-intros.
-generalize (remove_1 (m:=m) H).
-generalize (find_mapsto_iff (remove x m) y).
-destruct (find y (remove x m)); auto.
-destruct 2.
-exists e; rewrite H0; auto.
+intros. rewrite eq_option_alt. intro e.
+rewrite <- find_mapsto_iff, remove_mapsto_iff; now intuition.
Qed.
Hint Resolve remove_eq_o : map.
-Lemma remove_neq_o : forall m x y,
- ~ E.eq x y -> find y (remove x m) = find y m.
+Lemma remove_neq_o : forall m x y,
+ ~ E.eq x y -> find y (remove x m) = find y m.
Proof.
-intros.
-case_eq (find y m); intros; auto with map.
-case_eq (find y (remove x m)); intros; auto with map.
-rewrite <- H0; symmetry.
-apply find_1; apply remove_3 with x; auto with map.
+intros. rewrite eq_option_alt. intro e.
+rewrite <- find_mapsto_iff, remove_neq_mapsto_iff; now intuition.
Qed.
Hint Resolve remove_neq_o : map.
-Lemma remove_o : forall m x y,
+Lemma remove_o : forall m x y,
find y (remove x m) = if eq_dec x y then None else find y m.
Proof.
intros; destruct (eq_dec x y); auto with map.
Qed.
-Lemma remove_eq_b : forall m x y,
+Lemma remove_eq_b : forall m x y,
E.eq x y -> mem y (remove x m) = false.
Proof.
intros; rewrite mem_find_b; rewrite remove_eq_o; auto.
Qed.
-Lemma remove_neq_b : forall m x y,
+Lemma remove_neq_b : forall m x y,
~ E.eq x y -> mem y (remove x m) = mem y m.
Proof.
intros; do 2 rewrite mem_find_b; rewrite remove_neq_o; auto.
Qed.
-Lemma remove_b : forall m x y,
+Lemma remove_b : forall m x y,
mem y (remove x m) = negb (eqb x y) && mem y m.
Proof.
intros; do 2 rewrite mem_find_b; rewrite remove_o; unfold eqb.
@@ -506,7 +499,7 @@ Qed.
Lemma map2_1bis : forall (m: t elt)(m': t elt') x
(f:option elt->option elt'->option elt''),
f None None = None ->
- find x (map2 f m m') = f (find x m) (find x m').
+ find x (map2 f m m') = f (find x m) (find x m').
Proof.
intros.
case_eq (find x m); intros.
@@ -525,23 +518,16 @@ rewrite (find_1 H4) in H0; discriminate.
rewrite (find_1 H4) in H1; discriminate.
Qed.
-Lemma elements_o : forall m x,
+Lemma elements_o : forall m x,
find x m = findA (eqb x) (elements m).
Proof.
-intros.
-assert (forall e, find x m = Some e <-> InA (eq_key_elt (elt:=elt)) (x,e) (elements m)).
- intros; rewrite <- find_mapsto_iff; apply elements_mapsto_iff.
-assert (H0:=elements_3w m).
-generalize (fun e => @findA_NoDupA _ _ _ E.eq_sym E.eq_trans eq_dec (elements m) x e H0).
-fold (eqb x).
-destruct (find x m); destruct (findA (eqb x) (elements m));
- simpl; auto; intros.
-symmetry; rewrite <- H1; rewrite <- H; auto.
-symmetry; rewrite <- H1; rewrite <- H; auto.
-rewrite H; rewrite H1; auto.
-Qed.
-
-Lemma elements_b : forall m x,
+intros. rewrite eq_option_alt. intro e.
+rewrite <- find_mapsto_iff, elements_mapsto_iff.
+unfold eqb.
+rewrite <- findA_NoDupA; intuition; try apply elements_3w; eauto.
+Qed.
+
+Lemma elements_b : forall m x,
mem x m = existsb (fun p => eqb x (fst p)) (elements m).
Proof.
intros.
@@ -568,30 +554,41 @@ Qed.
End BoolSpec.
-Section Equalities.
+Section Equalities.
Variable elt:Type.
+ (** Another characterisation of [Equal] *)
+
+Lemma Equal_mapsto_iff : forall m1 m2 : t elt,
+ Equal m1 m2 <-> (forall k e, MapsTo k e m1 <-> MapsTo k e m2).
+Proof.
+intros m1 m2. split; [intros Heq k e|intros Hiff].
+rewrite 2 find_mapsto_iff, Heq. split; auto.
+intro k. rewrite eq_option_alt. intro e.
+rewrite <- 2 find_mapsto_iff; auto.
+Qed.
+
(** * Relations between [Equal], [Equiv] and [Equivb]. *)
(** First, [Equal] is [Equiv] with Leibniz on elements. *)
-Lemma Equal_Equiv : forall (m m' : t elt),
+Lemma Equal_Equiv : forall (m m' : t elt),
Equal m m' <-> Equiv (@Logic.eq elt) m m'.
Proof.
- unfold Equal, Equiv; split; intros.
- split; intros.
- rewrite in_find_iff, in_find_iff, H; intuition.
- rewrite find_mapsto_iff in H0,H1; congruence.
- destruct H.
- specialize (H y).
- specialize (H0 y).
- do 2 rewrite in_find_iff in H.
- generalize (find_mapsto_iff m y)(find_mapsto_iff m' y).
- do 2 destruct find; auto; intros.
- f_equal; apply H0; [rewrite H1|rewrite H2]; auto.
- destruct H as [H _]; now elim H.
- destruct H as [_ H]; now elim H.
+intros. rewrite Equal_mapsto_iff. split; intros.
+split.
+split; intros (e,Hin); exists e; [rewrite <- H|rewrite H]; auto.
+intros; apply MapsTo_fun with m k; auto; rewrite H; auto.
+split; intros H'.
+destruct H.
+assert (Hin : In k m') by (rewrite <- H; exists e; auto).
+destruct Hin as (e',He').
+rewrite (H0 k e e'); auto.
+destruct H.
+assert (Hin : In k m) by (rewrite H; exists e; auto).
+destruct Hin as (e',He').
+rewrite <- (H0 k e' e); auto.
Qed.
(** [Equivb] and [Equiv] and equivalent when [eq_elt] and [cmp]
@@ -649,8 +646,8 @@ Lemma Equal_trans : forall (elt:Type)(m m' m'' : t elt),
Equal m m' -> Equal m' m'' -> Equal m m''.
Proof. unfold Equal; congruence. Qed.
-Definition Equal_ST : forall elt:Type, Setoid_Theory (t elt) (@Equal _).
-Proof.
+Definition Equal_ST : forall elt:Type, Equivalence (@Equal elt).
+Proof.
constructor; red; [apply Equal_refl | apply Equal_sym | apply Equal_trans].
Qed.
@@ -660,8 +657,6 @@ Add Relation key E.eq
transitivity proved by E.eq_trans
as KeySetoid.
-Typeclasses unfold key.
-
Implicit Arguments Equal [[elt]].
Add Parametric Relation (elt : Type) : (t elt) Equal
@@ -670,52 +665,52 @@ Add Parametric Relation (elt : Type) : (t elt) Equal
transitivity proved by (@Equal_trans elt)
as EqualSetoid.
-Add Parametric Morphism elt : (@In elt) with signature E.eq ==> Equal ==> iff as In_m.
+Add Parametric Morphism elt : (@In elt)
+ with signature E.eq ==> Equal ==> iff as In_m.
Proof.
unfold Equal; intros k k' Hk m m' Hm.
rewrite (In_iff m Hk), in_find_iff, in_find_iff, Hm; intuition.
Qed.
Add Parametric Morphism elt : (@MapsTo elt)
- with signature E.eq ==> @Logic.eq _ ==> Equal ==> iff as MapsTo_m.
+ with signature E.eq ==> Leibniz ==> Equal ==> iff as MapsTo_m.
Proof.
unfold Equal; intros k k' Hk e m m' Hm.
-rewrite (MapsTo_iff m e Hk), find_mapsto_iff, find_mapsto_iff, Hm;
+rewrite (MapsTo_iff m e Hk), find_mapsto_iff, find_mapsto_iff, Hm;
intuition.
Qed.
-Add Parametric Morphism elt : (@Empty elt) with signature Equal ==> iff as Empty_m.
+Add Parametric Morphism elt : (@Empty elt)
+ with signature Equal ==> iff as Empty_m.
Proof.
unfold Empty; intros m m' Hm; intuition.
rewrite <-Hm in H0; eauto.
rewrite Hm in H0; eauto.
Qed.
-Add Parametric Morphism elt : (@is_empty elt) with signature Equal ==> @Logic.eq _ as is_empty_m.
+Add Parametric Morphism elt : (@is_empty elt)
+ with signature Equal ==> Leibniz as is_empty_m.
Proof.
intros m m' Hm.
rewrite eq_bool_alt, <-is_empty_iff, <-is_empty_iff, Hm; intuition.
Qed.
-Add Parametric Morphism elt : (@mem elt) with signature E.eq ==> Equal ==> @Logic.eq _ as mem_m.
+Add Parametric Morphism elt : (@mem elt)
+ with signature E.eq ==> Equal ==> Leibniz as mem_m.
Proof.
intros k k' Hk m m' Hm.
rewrite eq_bool_alt, <- mem_in_iff, <-mem_in_iff, Hk, Hm; intuition.
Qed.
-Add Parametric Morphism elt : (@find elt) with signature E.eq ==> Equal ==> @Logic.eq _ as find_m.
+Add Parametric Morphism elt : (@find elt)
+ with signature E.eq ==> Equal ==> Leibniz as find_m.
Proof.
-intros k k' Hk m m' Hm.
-generalize (find_mapsto_iff m k)(find_mapsto_iff m' k')
- (not_find_in_iff m k)(not_find_in_iff m' k');
-do 2 destruct find; auto; intros.
-rewrite <- H, Hk, Hm, H0; auto.
-rewrite <- H1, Hk, Hm, H2; auto.
-symmetry; rewrite <- H2, <-Hk, <-Hm, H1; auto.
+intros k k' Hk m m' Hm. rewrite eq_option_alt. intro e.
+rewrite <- 2 find_mapsto_iff, Hk, Hm. split; auto.
Qed.
-Add Parametric Morphism elt : (@add elt) with signature
- E.eq ==> @Logic.eq _ ==> Equal ==> Equal as add_m.
+Add Parametric Morphism elt : (@add elt)
+ with signature E.eq ==> Leibniz ==> Equal ==> Equal as add_m.
Proof.
intros k k' Hk e m m' Hm y.
rewrite add_o, add_o; do 2 destruct eq_dec; auto.
@@ -723,8 +718,8 @@ elim n; rewrite <-Hk; auto.
elim n; rewrite Hk; auto.
Qed.
-Add Parametric Morphism elt : (@remove elt) with signature
- E.eq ==> Equal ==> Equal as remove_m.
+Add Parametric Morphism elt : (@remove elt)
+ with signature E.eq ==> Equal ==> Equal as remove_m.
Proof.
intros k k' Hk m m' Hm y.
rewrite remove_o, remove_o; do 2 destruct eq_dec; auto.
@@ -732,7 +727,8 @@ elim n; rewrite <-Hk; auto.
elim n; rewrite Hk; auto.
Qed.
-Add Parametric Morphism elt elt' : (@map elt elt') with signature @Logic.eq _ ==> Equal ==> Equal as map_m.
+Add Parametric Morphism elt elt' : (@map elt elt')
+ with signature Leibniz ==> Equal ==> Equal as map_m.
Proof.
intros f m m' Hm y.
rewrite map_o, map_o, Hm; auto.
@@ -743,25 +739,23 @@ Qed.
(* old name: *)
Notation not_find_mapsto_iff := not_find_in_iff.
-End WFacts.
+End WFacts_fun.
-(** * Same facts for full maps *)
+(** * Same facts for self-contained weak sets and for full maps *)
-Module Facts (M:S).
- Module D := OT_as_DT M.E.
- Include WFacts D M.
-End Facts.
+Module WFacts (M:S) := WFacts_fun M.E M.
+Module Facts := WFacts.
+
+(** * Additional Properties for weak maps
-(** * Additional Properties for weak maps
-
Results about [fold], [elements], induction principles...
*)
-Module WProperties (E:DecidableType)(M:WSfun E).
- Module Import F:=WFacts E M.
+Module WProperties_fun (E:DecidableType)(M:WSfun E).
+ Module Import F:=WFacts_fun E M.
Import M.
- Section Elt.
+ Section Elt.
Variable elt:Type.
Definition Add x (e:elt) m m' := forall y, find y m' = find y (add x e m).
@@ -769,6 +763,44 @@ Module WProperties (E:DecidableType)(M:WSfun E).
Notation eqke := (@eq_key_elt elt).
Notation eqk := (@eq_key elt).
+ (** Complements about InA, NoDupA and findA *)
+
+ Lemma InA_eqke_eqk : forall k1 k2 e1 e2 l,
+ E.eq k1 k2 -> InA eqke (k1,e1) l -> InA eqk (k2,e2) l.
+ Proof.
+ intros k1 k2 e1 e2 l Hk. rewrite 2 InA_alt.
+ intros ((k',e') & (Hk',He') & H); simpl in *.
+ exists (k',e'); split; auto.
+ red; simpl; eauto.
+ Qed.
+
+ Lemma NoDupA_eqk_eqke : forall l, NoDupA eqk l -> NoDupA eqke l.
+ Proof.
+ induction 1; auto.
+ constructor; auto.
+ destruct x as (k,e).
+ eauto using InA_eqke_eqk.
+ Qed.
+
+ Lemma findA_rev : forall l k, NoDupA eqk l ->
+ findA (eqb k) l = findA (eqb k) (rev l).
+ Proof.
+ intros.
+ case_eq (findA (eqb k) l).
+ intros. symmetry.
+ unfold eqb.
+ rewrite <- findA_NoDupA, InA_rev, findA_NoDupA
+ by eauto using NoDupA_rev; eauto.
+ case_eq (findA (eqb k) (rev l)); auto.
+ intros e.
+ unfold eqb.
+ rewrite <- findA_NoDupA, InA_rev, findA_NoDupA
+ by eauto using NoDupA_rev.
+ intro Eq; rewrite Eq; auto.
+ Qed.
+
+ (** * Elements *)
+
Lemma elements_Empty : forall m:t elt, Empty m <-> elements m = nil.
Proof.
intros.
@@ -793,29 +825,268 @@ Module WProperties (E:DecidableType)(M:WSfun E).
rewrite <-elements_Empty; apply empty_1.
Qed.
- Lemma fold_Empty : forall m (A:Type)(f:key->elt->A->A)(i:A),
- Empty m -> fold f m i = i.
+ (** * Conversions between maps and association lists. *)
+
+ Definition of_list (l : list (key*elt)) :=
+ List.fold_right (fun p => add (fst p) (snd p)) (empty _) l.
+
+ Definition to_list := elements.
+
+ Lemma of_list_1 : forall l k e,
+ NoDupA eqk l ->
+ (MapsTo k e (of_list l) <-> InA eqke (k,e) l).
+ Proof.
+ induction l as [|(k',e') l IH]; simpl; intros k e Hnodup.
+ rewrite empty_mapsto_iff, InA_nil; intuition.
+ inversion_clear Hnodup as [| ? ? Hnotin Hnodup'].
+ specialize (IH k e Hnodup'); clear Hnodup'.
+ rewrite add_mapsto_iff, InA_cons, <- IH.
+ unfold eq_key_elt at 1; simpl.
+ split; destruct 1 as [H|H]; try (intuition;fail).
+ destruct (eq_dec k k'); [left|right]; split; auto.
+ contradict Hnotin.
+ apply InA_eqke_eqk with k e; intuition.
+ Qed.
+
+ Lemma of_list_1b : forall l k,
+ NoDupA eqk l ->
+ find k (of_list l) = findA (eqb k) l.
+ Proof.
+ induction l as [|(k',e') l IH]; simpl; intros k Hnodup.
+ apply empty_o.
+ inversion_clear Hnodup as [| ? ? Hnotin Hnodup'].
+ specialize (IH k Hnodup'); clear Hnodup'.
+ rewrite add_o, IH.
+ unfold eqb; do 2 destruct eq_dec; auto; elim n; eauto.
+ Qed.
+
+ Lemma of_list_2 : forall l, NoDupA eqk l ->
+ equivlistA eqke l (to_list (of_list l)).
+ Proof.
+ intros l Hnodup (k,e).
+ rewrite <- elements_mapsto_iff, of_list_1; intuition.
+ Qed.
+
+ Lemma of_list_3 : forall s, Equal (of_list (to_list s)) s.
+ Proof.
+ intros s k.
+ rewrite of_list_1b, elements_o; auto.
+ apply elements_3w.
+ Qed.
+
+ (** * Fold *)
+
+ (** ** Induction principles about fold contributed by S. Lescuyer *)
+
+ (** In the following lemma, the step hypothesis is deliberately restricted
+ to the precise map m we are considering. *)
+
+ Lemma fold_rec :
+ forall (A:Type)(P : t elt -> A -> Type)(f : key -> elt -> A -> A),
+ forall (i:A)(m:t elt),
+ (forall m, Empty m -> P m i) ->
+ (forall k e a m' m'', MapsTo k e m -> ~In k m' ->
+ Add k e m' m'' -> P m' a -> P m'' (f k e a)) ->
+ P m (fold f m i).
+ Proof.
+ intros A P f i m Hempty Hstep.
+ rewrite fold_1, <- fold_left_rev_right.
+ set (F:=fun (y : key * elt) (x : A) => f (fst y) (snd y) x).
+ set (l:=rev (elements m)).
+ assert (Hstep' : forall k e a m' m'', InA eqke (k,e) l -> ~In k m' ->
+ Add k e m' m'' -> P m' a -> P m'' (F (k,e) a)).
+ intros k e a m' m'' H ? ? ?; eapply Hstep; eauto.
+ revert H; unfold l; rewrite InA_rev, elements_mapsto_iff; auto.
+ assert (Hdup : NoDupA eqk l).
+ unfold l. apply NoDupA_rev; try red; eauto. apply elements_3w.
+ assert (Hsame : forall k, find k m = findA (eqb k) l).
+ intros k. unfold l. rewrite elements_o, findA_rev; auto.
+ apply elements_3w.
+ clearbody l. clearbody F. clear Hstep f. revert m Hsame. induction l.
+ (* empty *)
+ intros m Hsame; simpl.
+ apply Hempty. intros k e.
+ rewrite find_mapsto_iff, Hsame; simpl; discriminate.
+ (* step *)
+ intros m Hsame; destruct a as (k,e); simpl.
+ apply Hstep' with (of_list l); auto.
+ rewrite InA_cons; left; red; auto.
+ inversion_clear Hdup. contradict H. destruct H as (e',He').
+ apply InA_eqke_eqk with k e'; auto.
+ rewrite <- of_list_1; auto.
+ intro k'. rewrite Hsame, add_o, of_list_1b. simpl.
+ unfold eqb. do 2 destruct eq_dec; auto; elim n; eauto.
+ inversion_clear Hdup; auto.
+ apply IHl.
+ intros; eapply Hstep'; eauto.
+ inversion_clear Hdup; auto.
+ intros; apply of_list_1b. inversion_clear Hdup; auto.
+ Qed.
+
+ (** Same, with [empty] and [add] instead of [Empty] and [Add]. In this
+ case, [P] must be compatible with equality of sets *)
+
+ Theorem fold_rec_bis :
+ forall (A:Type)(P : t elt -> A -> Type)(f : key -> elt -> A -> A),
+ forall (i:A)(m:t elt),
+ (forall m m' a, Equal m m' -> P m a -> P m' a) ->
+ (P (empty _) i) ->
+ (forall k e a m', MapsTo k e m -> ~In k m' ->
+ P m' a -> P (add k e m') (f k e a)) ->
+ P m (fold f m i).
+ Proof.
+ intros A P f i m Pmorphism Pempty Pstep.
+ apply fold_rec; intros.
+ apply Pmorphism with (empty _); auto. intro k. rewrite empty_o.
+ case_eq (find k m0); auto; intros e'; rewrite <- find_mapsto_iff.
+ intro H'; elim (H k e'); auto.
+ apply Pmorphism with (add k e m'); try intro; auto.
+ Qed.
+
+ Lemma fold_rec_nodep :
+ forall (A:Type)(P : A -> Type)(f : key -> elt -> A -> A)(i:A)(m:t elt),
+ P i -> (forall k e a, MapsTo k e m -> P a -> P (f k e a)) ->
+ P (fold f m i).
+ Proof.
+ intros; apply fold_rec_bis with (P:=fun _ => P); auto.
+ Qed.
+
+ (** [fold_rec_weak] is a weaker principle than [fold_rec_bis] :
+ the step hypothesis must here be applicable anywhere.
+ At the same time, it looks more like an induction principle,
+ and hence can be easier to use. *)
+
+ Lemma fold_rec_weak :
+ forall (A:Type)(P : t elt -> A -> Type)(f : key -> elt -> A -> A)(i:A),
+ (forall m m' a, Equal m m' -> P m a -> P m' a) ->
+ P (empty _) i ->
+ (forall k e a m, ~In k m -> P m a -> P (add k e m) (f k e a)) ->
+ forall m, P m (fold f m i).
+ Proof.
+ intros; apply fold_rec_bis; auto.
+ Qed.
+
+ Lemma fold_rel :
+ forall (A B:Type)(R : A -> B -> Type)
+ (f : key -> elt -> A -> A)(g : key -> elt -> B -> B)(i : A)(j : B)
+ (m : t elt),
+ R i j ->
+ (forall k e a b, MapsTo k e m -> R a b -> R (f k e a) (g k e b)) ->
+ R (fold f m i) (fold g m j).
+ Proof.
+ intros A B R f g i j m Rempty Rstep.
+ do 2 rewrite fold_1, <- fold_left_rev_right.
+ set (l:=rev (elements m)).
+ assert (Rstep' : forall k e a b, InA eqke (k,e) l ->
+ R a b -> R (f k e a) (g k e b)) by
+ (intros; apply Rstep; auto; rewrite elements_mapsto_iff, <- InA_rev; auto).
+ clearbody l; clear Rstep m.
+ induction l; simpl; auto.
+ apply Rstep'; auto.
+ destruct a; simpl; rewrite InA_cons; left; red; auto.
+ Qed.
+
+ (** From the induction principle on [fold], we can deduce some general
+ induction principles on maps. *)
+
+ Lemma map_induction :
+ forall P : t elt -> Type,
+ (forall m, Empty m -> P m) ->
+ (forall m m', P m -> forall x e, ~In x m -> Add x e m m' -> P m') ->
+ forall m, P m.
+ Proof.
+ intros. apply (@fold_rec _ (fun s _ => P s) (fun _ _ _ => tt) tt m); eauto.
+ Qed.
+
+ Lemma map_induction_bis :
+ forall P : t elt -> Type,
+ (forall m m', Equal m m' -> P m -> P m') ->
+ P (empty _) ->
+ (forall x e m, ~In x m -> P m -> P (add x e m)) ->
+ forall m, P m.
Proof.
intros.
- rewrite fold_1.
- rewrite elements_Empty in H; rewrite H; simpl; auto.
+ apply (@fold_rec_bis _ (fun s _ => P s) (fun _ _ _ => tt) tt m); eauto.
Qed.
- Lemma NoDupA_eqk_eqke : forall l, NoDupA eqk l -> NoDupA eqke l.
+ (** [fold] can be used to reconstruct the same initial set. *)
+
+ Lemma fold_identity : forall m : t elt, Equal (fold (@add _) m (empty _)) m.
Proof.
- induction 1; auto.
- constructor; auto.
- contradict H.
- destruct x as (x,y).
- rewrite InA_alt in *; destruct H as ((a,b),((H1,H2),H3)); simpl in *.
- exists (a,b); auto.
+ intros.
+ apply fold_rec with (P:=fun m acc => Equal acc m); auto with map.
+ intros m' Heq k'.
+ rewrite empty_o.
+ case_eq (find k' m'); auto; intros e'; rewrite <- find_mapsto_iff.
+ intro; elim (Heq k' e'); auto.
+ intros k e a m' m'' _ _ Hadd Heq k'.
+ rewrite Hadd, 2 add_o, Heq; auto.
+ Qed.
+
+ Section Fold_More.
+
+ (** ** Additional properties of fold *)
+
+ (** When a function [f] is compatible and allows transpositions, we can
+ compute [fold f] in any order. *)
+
+ Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)(f:key->elt->A->A).
+
+ (** This is more convenient than a [compat_op eqke ...].
+ In fact, every [compat_op], [compat_bool], etc, should
+ become a [Morphism] someday. *)
+ Hypothesis Comp : Morphism (E.eq==>Leibniz==>eqA==>eqA) f.
+
+ Lemma fold_init :
+ forall m i i', eqA i i' -> eqA (fold f m i) (fold f m i').
+ Proof.
+ intros. apply fold_rel with (R:=eqA); auto.
+ intros. apply Comp; auto.
+ Qed.
+
+ Lemma fold_Empty :
+ forall m i, Empty m -> eqA (fold f m i) i.
+ Proof.
+ intros. apply fold_rec_nodep with (P:=fun a => eqA a i).
+ reflexivity.
+ intros. elim (H k e); auto.
Qed.
- Lemma fold_Equal : forall m1 m2 (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory A eqA)
- (f:key->elt->A->A)(i:A),
- compat_op eqke eqA (fun y =>f (fst y) (snd y)) ->
- transpose eqA (fun y => f (fst y) (snd y)) ->
- Equal m1 m2 ->
+ (** As noticed by P. Casteran, asking for the general [SetoidList.transpose]
+ here is too restrictive. Think for instance of [f] being [M.add] :
+ in general, [M.add k e (M.add k e' m)] is not equivalent to
+ [M.add k e' (M.add k e m)]. Fortunately, we will never encounter this
+ situation during a real [fold], since the keys received by this [fold]
+ are unique. Hence we can ask the transposition property to hold only
+ for non-equal keys.
+
+ This idea could be push slightly further, by asking the transposition
+ property to hold only for (non-equal) keys living in the map given to
+ [fold]. Please contact us if you need such a version.
+
+ FSets could also benefit from a restricted [transpose], but for this
+ case the gain is unclear. *)
+
+ Definition transpose_neqkey :=
+ forall k k' e e' a, ~E.eq k k' ->
+ eqA (f k e (f k' e' a)) (f k' e' (f k e a)).
+
+ Hypothesis Tra : transpose_neqkey.
+
+ Lemma fold_commutes : forall i m k e, ~In k m ->
+ eqA (fold f m (f k e i)) (f k e (fold f m i)).
+ Proof.
+ intros i m k e Hnotin.
+ apply fold_rel with (R:= fun a b => eqA a (f k e b)); auto.
+ reflexivity.
+ intros.
+ transitivity (f k0 e0 (f k e b)).
+ apply Comp; auto.
+ apply Tra; auto.
+ contradict Hnotin; rewrite <- Hnotin; exists e0; auto.
+ Qed.
+
+ Lemma fold_Equal : forall m1 m2 i, Equal m1 m2 ->
eqA (fold f m1 i) (fold f m2 i).
Proof.
assert (eqke_refl : forall p, eqke p p).
@@ -826,22 +1097,26 @@ Module WProperties (E:DecidableType)(M:WSfun E).
intros (x1,x2) (y1,y2) (z1,z2); unfold eq_key_elt; simpl.
intuition; eauto; congruence.
intros; do 2 rewrite fold_1; do 2 rewrite <- fold_left_rev_right.
- apply fold_right_equivlistA with (eqA:=eqke) (eqB:=eqA); auto.
+ apply fold_right_equivlistA_restr with
+ (R:=fun p p' => ~eqk p p') (eqA:=eqke) (eqB:=eqA); auto.
+ intros (k1,e1) (k2,e2) a1 a2 (Hk,He) Ha; simpl in *; apply Comp; auto.
+ unfold eq_key; auto.
+ intros (k1,e1) (k2,e2) (k3,e3). unfold eq_key_elt, eq_key; simpl.
+ intuition eauto.
+ intros (k,e) (k',e'); unfold eq_key; simpl; auto.
apply NoDupA_rev; auto; apply NoDupA_eqk_eqke; apply elements_3w.
apply NoDupA_rev; auto; apply NoDupA_eqk_eqke; apply elements_3w.
+ apply ForallList2_equiv1 with (eqA:=eqk); try red; eauto.
+ apply NoDupA_rev; try red; eauto. apply elements_3w.
red; intros.
do 2 rewrite InA_rev.
destruct x; do 2 rewrite <- elements_mapsto_iff.
do 2 rewrite find_mapsto_iff.
- rewrite H1; split; auto.
+ rewrite H; split; auto.
Qed.
- Lemma fold_Add : forall m1 m2 x e (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory A eqA)
- (f:key->elt->A->A)(i:A),
- compat_op eqke eqA (fun y =>f (fst y) (snd y)) ->
- transpose eqA (fun y =>f (fst y) (snd y)) ->
- ~In x m1 -> Add x e m1 m2 ->
- eqA (fold f m2 i) (f x e (fold f m1 i)).
+ Lemma fold_Add : forall m1 m2 k e i, ~In k m1 -> Add k e m1 m2 ->
+ eqA (fold f m2 i) (f k e (fold f m1 i)).
Proof.
assert (eqke_refl : forall p, eqke p p).
red; auto.
@@ -852,52 +1127,68 @@ Module WProperties (E:DecidableType)(M:WSfun E).
intuition; eauto; congruence.
intros; do 2 rewrite fold_1; do 2 rewrite <- fold_left_rev_right.
set (f':=fun y x0 => f (fst y) (snd y) x0) in *.
- change (f x e (fold_right f' i (rev (elements m1))))
- with (f' (x,e) (fold_right f' i (rev (elements m1)))).
- apply fold_right_add with (eqA:=eqke)(eqB:=eqA); auto.
+ change (f k e (fold_right f' i (rev (elements m1))))
+ with (f' (k,e) (fold_right f' i (rev (elements m1)))).
+ apply fold_right_add_restr with
+ (R:=fun p p'=>~eqk p p')(eqA:=eqke)(eqB:=eqA); auto.
+ intros (k1,e1) (k2,e2) a1 a2 (Hk,He) Ha; unfold f'; simpl in *. apply Comp; auto.
+
+ unfold eq_key; auto.
+ intros (k1,e1) (k2,e2) (k3,e3). unfold eq_key_elt, eq_key; simpl.
+ intuition eauto.
+ unfold f'; intros (k1,e1) (k2,e2); unfold eq_key; simpl; auto.
apply NoDupA_rev; auto; apply NoDupA_eqk_eqke; apply elements_3w.
apply NoDupA_rev; auto; apply NoDupA_eqk_eqke; apply elements_3w.
+ apply ForallList2_equiv1 with (eqA:=eqk); try red; eauto.
+ apply NoDupA_rev; try red; eauto. apply elements_3w.
rewrite InA_rev.
- contradict H1.
+ contradict H.
exists e.
rewrite elements_mapsto_iff; auto.
intros a.
- rewrite InA_cons; do 2 rewrite InA_rev;
+ rewrite InA_cons; do 2 rewrite InA_rev;
destruct a as (a,b); do 2 rewrite <- elements_mapsto_iff.
do 2 rewrite find_mapsto_iff; unfold eq_key_elt; simpl.
- rewrite H2.
+ rewrite H0.
rewrite add_o.
- destruct (eq_dec x a); intuition.
- inversion H3; auto.
+ destruct (eq_dec k a); intuition.
+ inversion H1; auto.
f_equal; auto.
- elim H1.
+ elim H.
exists b; apply MapsTo_1 with a; auto with map.
elim n; auto.
Qed.
- Lemma cardinal_fold : forall m : t elt,
+ Lemma fold_add : forall m k e i, ~In k m ->
+ eqA (fold f (add k e m) i) (f k e (fold f m i)).
+ Proof.
+ intros. apply fold_Add; try red; auto.
+ Qed.
+
+ End Fold_More.
+
+ (** * Cardinal *)
+
+ Lemma cardinal_fold : forall m : t elt,
cardinal m = fold (fun _ _ => S) m 0.
Proof.
intros; rewrite cardinal_1, fold_1.
symmetry; apply fold_left_length; auto.
Qed.
- Lemma cardinal_Empty : forall m : t elt,
+ Lemma cardinal_Empty : forall m : t elt,
Empty m <-> cardinal m = 0.
Proof.
intros.
rewrite cardinal_1, elements_Empty.
destruct (elements m); intuition; discriminate.
Qed.
-
- Lemma Equal_cardinal : forall m m' : t elt,
+
+ Lemma Equal_cardinal : forall m m' : t elt,
Equal m m' -> cardinal m = cardinal m'.
Proof.
intros; do 2 rewrite cardinal_fold.
- apply fold_Equal with (eqA:=@eq _); auto.
- constructor; auto; congruence.
- red; auto.
- red; auto.
+ apply fold_Equal with (eqA:=Leibniz); compute; auto.
Qed.
Lemma cardinal_1 : forall m : t elt, Empty m -> cardinal m = 0.
@@ -910,10 +1201,7 @@ Module WProperties (E:DecidableType)(M:WSfun E).
Proof.
intros; do 2 rewrite cardinal_fold.
change S with ((fun _ _ => S) x e).
- apply fold_Add; auto.
- constructor; intros; auto; congruence.
- red; simpl; auto.
- red; simpl; auto.
+ apply fold_Add with (eqA:=Leibniz); compute; auto.
Qed.
Lemma cardinal_inv_1 : forall m : t elt,
@@ -943,27 +1231,16 @@ Module WProperties (E:DecidableType)(M:WSfun E).
eauto.
Qed.
- Lemma map_induction :
- forall P : t elt -> Type,
- (forall m, Empty m -> P m) ->
- (forall m m', P m -> forall x e, ~In x m -> Add x e m m' -> P m') ->
- forall m, P m.
- Proof.
- intros; remember (cardinal m) as n; revert m Heqn; induction n; intros.
- apply X; apply cardinal_inv_1; auto.
+ (** * Additional notions over maps *)
- destruct (cardinal_inv_2 (sym_eq Heqn)) as ((x,e),H0); simpl in *.
- assert (Add x e (remove x m) m).
- red; intros.
- rewrite add_o; rewrite remove_o; destruct (eq_dec x y); eauto with map.
- apply X0 with (remove x m) x e; auto with map.
- apply IHn; auto with map.
- assert (S n = S (cardinal (remove x m))).
- rewrite Heqn; eapply cardinal_2; eauto with map.
- inversion H1; auto with map.
- Qed.
+ Definition Disjoint (m m' : t elt) :=
+ forall k, ~(In k m /\ In k m').
+
+ Definition Partition (m m1 m2 : t elt) :=
+ Disjoint m1 m2 /\
+ (forall k e, MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2).
- (** * Let's emulate some functions not present in the interface *)
+ (** * Emulation of some functions lacking in the interface *)
Definition filter (f : key -> elt -> bool)(m : t elt) :=
fold (fun k e m => if f k e then add k e m else m) m (empty _).
@@ -977,122 +1254,411 @@ Module WProperties (E:DecidableType)(M:WSfun E).
Definition partition (f : key -> elt -> bool)(m : t elt) :=
(filter f m, filter (fun k e => negb (f k e)) m).
+ (** [update] adds to [m1] all the bindings of [m2]. It can be seen as
+ an [union] operator which gives priority to its 2nd argument
+ in case of binding conflit. *)
+
+ Definition update (m1 m2 : t elt) := fold (@add _) m2 m1.
+
+ (** [restrict] keeps from [m1] only the bindings whose key is in [m2].
+ It can be seen as an [inter] operator, with priority to its 1st argument
+ in case of binding conflit. *)
+
+ Definition restrict (m1 m2 : t elt) := filter (fun k _ => mem k m2) m1.
+
+ (** [diff] erases from [m1] all bindings whose key is in [m2]. *)
+
+ Definition diff (m1 m2 : t elt) := filter (fun k _ => negb (mem k m2)) m1.
+
Section Specs.
Variable f : key -> elt -> bool.
- Hypothesis Hf : forall e, compat_bool E.eq (fun k => f k e).
+ Hypothesis Hf : Morphism (E.eq==>Leibniz==>Leibniz) f.
- Lemma filter_iff : forall m k e,
+ Lemma filter_iff : forall m k e,
MapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = true.
Proof.
- unfold filter; intros.
- rewrite fold_1.
- rewrite <- fold_left_rev_right.
- rewrite (elements_mapsto_iff m).
- rewrite <- (InA_rev eqke (k,e) (elements m)).
- assert (NoDupA eqk (rev (elements m))).
- apply NoDupA_rev; auto; try apply elements_3w; auto.
- intros (k1,e1); compute; auto.
- intros (k1,e1)(k2,e2); compute; auto.
- intros (k1,e1)(k2,e2)(k3,e3); compute; eauto.
- induction (rev (elements m)); simpl; auto.
-
- rewrite empty_mapsto_iff.
- intuition.
- inversion H1.
-
- destruct a as (k',e'); simpl.
- inversion_clear H.
- case_eq (f k' e'); intros; simpl;
- try rewrite add_mapsto_iff; rewrite IHl; clear IHl; intuition.
- constructor; red; auto.
- rewrite (Hf e' H2),H4 in H; auto.
- inversion_clear H3.
- compute in H2; destruct H2; auto.
- destruct (E.eq_dec k' k); auto.
- elim H0.
- rewrite InA_alt in *; destruct H2 as (w,Hw); exists w; intuition.
- red in H2; red; simpl in *; intuition.
- rewrite e0; auto.
- inversion_clear H3; auto.
- compute in H2; destruct H2.
- rewrite (Hf e H2),H3,H in H4; discriminate.
+ unfold filter.
+ set (f':=fun k e m => if f k e then add k e m else m).
+ intro m. pattern m, (fold f' m (empty _)). apply fold_rec.
+
+ intros m' Hm' k e. rewrite empty_mapsto_iff. intuition.
+ elim (Hm' k e); auto.
+
+ intros k e acc m1 m2 Hke Hn Hadd IH k' e'.
+ change (Equal m2 (add k e m1)) in Hadd; rewrite Hadd.
+ unfold f'; simpl.
+ case_eq (f k e); intros Hfke; simpl;
+ rewrite !add_mapsto_iff, IH; clear IH; intuition.
+ rewrite <- Hfke; apply Hf; auto.
+ destruct (eq_dec k k') as [Hk|Hk]; [left|right]; auto.
+ elim Hn; exists e'; rewrite Hk; auto.
+ assert (f k e = f k' e') by (apply Hf; auto). congruence.
Qed.
-
+
Lemma for_all_iff : forall m,
for_all f m = true <-> (forall k e, MapsTo k e m -> f k e = true).
Proof.
- cut (forall m : t elt,
- for_all f m = true <->
- (forall k e, InA eqke (k,e) (rev (elements m)) -> f k e = true)).
- intros; rewrite H; split; intros.
- apply H0; rewrite InA_rev, <- elements_mapsto_iff; auto.
- apply H0; rewrite InA_rev, <- elements_mapsto_iff in H1; auto.
-
- unfold for_all; intros.
- rewrite fold_1.
- rewrite <- fold_left_rev_right.
- assert (NoDupA eqk (rev (elements m))).
- apply NoDupA_rev; auto; try apply elements_3w; auto.
- intros (k1,e1); compute; auto.
- intros (k1,e1)(k2,e2); compute; auto.
- intros (k1,e1)(k2,e2)(k3,e3); compute; eauto.
- induction (rev (elements m)); simpl; auto.
-
- intuition.
- inversion H1.
-
- destruct a as (k,e); simpl.
- inversion_clear H.
- case_eq (f k e); intros; simpl;
- try rewrite IHl; clear IHl; intuition.
- inversion_clear H3; auto.
- compute in H4; destruct H4.
- rewrite (Hf e0 H3), H4; auto.
- rewrite <-H, <-(H2 k e); auto.
- constructor; red; auto.
+ unfold for_all.
+ set (f':=fun k e b => if f k e then b else false).
+ intro m. pattern m, (fold f' m true). apply fold_rec.
+
+ intros m' Hm'. split; auto. intros _ k e Hke. elim (Hm' k e); auto.
+
+ intros k e b m1 m2 _ Hn Hadd IH. clear m.
+ change (Equal m2 (add k e m1)) in Hadd.
+ unfold f'; simpl. case_eq (f k e); intros Hfke.
+ (* f k e = true *)
+ rewrite IH. clear IH. split; intros Hmapsto k' e' Hke'.
+ rewrite Hadd, add_mapsto_iff in Hke'.
+ destruct Hke' as [(?,?)|(?,?)]; auto.
+ rewrite <- Hfke; apply Hf; auto.
+ apply Hmapsto. rewrite Hadd, add_mapsto_iff; right; split; auto.
+ contradict Hn; exists e'; rewrite Hn; auto.
+ (* f k e = false *)
+ split; intros H; try discriminate.
+ rewrite <- Hfke. apply H.
+ rewrite Hadd, add_mapsto_iff; auto.
Qed.
-
+
Lemma exists_iff : forall m,
- exists_ f m = true <->
+ exists_ f m = true <->
(exists p, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true).
Proof.
- cut (forall m : t elt,
- exists_ f m = true <->
- (exists p, InA eqke p (rev (elements m))
- /\ f (fst p) (snd p) = true)).
- intros; rewrite H; split; intros.
- destruct H0 as ((k,e),Hke); exists (k,e).
- rewrite InA_rev, <-elements_mapsto_iff in Hke; auto.
- destruct H0 as ((k,e),Hke); exists (k,e).
- rewrite InA_rev, <-elements_mapsto_iff; auto.
- unfold exists_; intros.
- rewrite fold_1.
- rewrite <- fold_left_rev_right.
- assert (NoDupA eqk (rev (elements m))).
- apply NoDupA_rev; auto; try apply elements_3w; auto.
- intros (k1,e1); compute; auto.
- intros (k1,e1)(k2,e2); compute; auto.
- intros (k1,e1)(k2,e2)(k3,e3); compute; eauto.
- induction (rev (elements m)); simpl; auto.
-
- intuition; try discriminate.
- destruct H0 as ((k,e),(Hke,_)); inversion Hke.
-
- destruct a as (k,e); simpl.
- inversion_clear H.
- case_eq (f k e); intros; simpl;
- try rewrite IHl; clear IHl; intuition.
+ unfold exists_.
+ set (f':=fun k e b => if f k e then true else b).
+ intro m. pattern m, (fold f' m false). apply fold_rec.
+
+ intros m' Hm'. split; try (intros; discriminate).
+ intros ((k,e),(Hke,_)); simpl in *. elim (Hm' k e); auto.
+
+ intros k e b m1 m2 _ Hn Hadd IH. clear m.
+ change (Equal m2 (add k e m1)) in Hadd.
+ unfold f'; simpl. case_eq (f k e); intros Hfke.
+ (* f k e = true *)
+ split; [intros _|auto].
exists (k,e); simpl; split; auto.
- constructor; red; auto.
- destruct H2 as ((k',e'),(Hke',Hf')); exists (k',e'); simpl; auto.
- destruct H2 as ((k',e'),(Hke',Hf')); simpl in *.
- inversion_clear Hke'.
- compute in H2; destruct H2.
- rewrite (Hf e' H2), H3,H in Hf'; discriminate.
+ rewrite Hadd, add_mapsto_iff; auto.
+ (* f k e = false *)
+ rewrite IH. clear IH. split; intros ((k',e'),(Hke1,Hke2)); simpl in *.
+ exists (k',e'); simpl; split; auto.
+ rewrite Hadd, add_mapsto_iff; right; split; auto.
+ contradict Hn. exists e'; rewrite Hn; auto.
+ rewrite Hadd, add_mapsto_iff in Hke1. destruct Hke1 as [(?,?)|(?,?)].
+ assert (f k' e' = f k e) by (apply Hf; auto). congruence.
exists (k',e'); auto.
Qed.
+
End Specs.
+ Lemma Disjoint_alt : forall m m',
+ Disjoint m m' <->
+ (forall k e e', MapsTo k e m -> MapsTo k e' m' -> False).
+ Proof.
+ unfold Disjoint; split.
+ intros H k v v' H1 H2.
+ apply H with k; split.
+ exists v; trivial.
+ exists v'; trivial.
+ intros H k ((v,Hv),(v',Hv')).
+ eapply H; eauto.
+ Qed.
+
+ Section Partition.
+ Variable f : key -> elt -> bool.
+ Hypothesis Hf : Morphism (E.eq==>Leibniz==>Leibniz) f.
+
+ Lemma partition_iff_1 : forall m m1 k e,
+ m1 = fst (partition f m) ->
+ (MapsTo k e m1 <-> MapsTo k e m /\ f k e = true).
+ Proof.
+ unfold partition; simpl; intros. subst m1.
+ apply filter_iff; auto.
+ Qed.
+
+ Lemma partition_iff_2 : forall m m2 k e,
+ m2 = snd (partition f m) ->
+ (MapsTo k e m2 <-> MapsTo k e m /\ f k e = false).
+ Proof.
+ unfold partition; simpl; intros. subst m2.
+ rewrite filter_iff.
+ split; intros (H,H'); split; auto.
+ destruct (f k e); simpl in *; auto.
+ rewrite H'; auto.
+ repeat red; intros. f_equal. apply Hf; auto.
+ Qed.
+
+ Lemma partition_Partition : forall m m1 m2,
+ partition f m = (m1,m2) -> Partition m m1 m2.
+ Proof.
+ intros. split.
+ rewrite Disjoint_alt. intros k e e'.
+ rewrite (@partition_iff_1 m m1), (@partition_iff_2 m m2)
+ by (rewrite H; auto).
+ intros (U,V) (W,Z). rewrite <- (MapsTo_fun U W) in Z; congruence.
+ intros k e.
+ rewrite (@partition_iff_1 m m1), (@partition_iff_2 m m2)
+ by (rewrite H; auto).
+ destruct (f k e); intuition.
+ Qed.
+
+ End Partition.
+
+ Lemma Partition_In : forall m m1 m2 k,
+ Partition m m1 m2 -> In k m -> {In k m1}+{In k m2}.
+ Proof.
+ intros m m1 m2 k Hm Hk.
+ destruct (In_dec m1 k) as [H|H]; [left|right]; auto.
+ destruct Hm as (Hm,Hm').
+ destruct Hk as (e,He); rewrite Hm' in He; destruct He.
+ elim H; exists e; auto.
+ exists e; auto.
+ Defined.
+
+ Lemma Disjoint_sym : forall m1 m2, Disjoint m1 m2 -> Disjoint m2 m1.
+ Proof.
+ intros m1 m2 H k (H1,H2). elim (H k); auto.
+ Qed.
+
+ Lemma Partition_sym : forall m m1 m2,
+ Partition m m1 m2 -> Partition m m2 m1.
+ Proof.
+ intros m m1 m2 (H,H'); split.
+ apply Disjoint_sym; auto.
+ intros; rewrite H'; intuition.
+ Qed.
+
+ Lemma Partition_Empty : forall m m1 m2, Partition m m1 m2 ->
+ (Empty m <-> (Empty m1 /\ Empty m2)).
+ Proof.
+ intros m m1 m2 (Hdisj,Heq). split.
+ intro He.
+ split; intros k e Hke; elim (He k e); rewrite Heq; auto.
+ intros (He1,He2) k e Hke. rewrite Heq in Hke. destruct Hke.
+ elim (He1 k e); auto.
+ elim (He2 k e); auto.
+ Qed.
+
+ Lemma Partition_Add :
+ forall m m' x e , ~In x m -> Add x e m m' ->
+ forall m1 m2, Partition m' m1 m2 ->
+ exists m3, (Add x e m3 m1 /\ Partition m m3 m2 \/
+ Add x e m3 m2 /\ Partition m m1 m3).
+ Proof.
+ unfold Partition. intros m m' x e Hn Hadd m1 m2 (Hdisj,Hor).
+ assert (Heq : Equal m (remove x m')).
+ change (Equal m' (add x e m)) in Hadd. rewrite Hadd.
+ intro k. rewrite remove_o, add_o.
+ destruct eq_dec as [He|Hne]; auto.
+ rewrite <- He, <- not_find_in_iff; auto.
+ assert (H : MapsTo x e m').
+ change (Equal m' (add x e m)) in Hadd; rewrite Hadd.
+ apply add_1; auto.
+ rewrite Hor in H; destruct H.
+
+ (* first case : x in m1 *)
+ exists (remove x m1); left. split; [|split].
+ (* add *)
+ change (Equal m1 (add x e (remove x m1))).
+ intro k.
+ rewrite add_o, remove_o.
+ destruct eq_dec as [He|Hne]; auto.
+ rewrite <- He; apply find_1; auto.
+ (* disjoint *)
+ intros k (H1,H2). elim (Hdisj k). split; auto.
+ rewrite remove_in_iff in H1; destruct H1; auto.
+ (* mapsto *)
+ intros k' e'.
+ rewrite Heq, 2 remove_mapsto_iff, Hor.
+ intuition.
+ elim (Hdisj x); split; [exists e|exists e']; auto.
+ apply MapsTo_1 with k'; auto.
+
+ (* second case : x in m2 *)
+ exists (remove x m2); right. split; [|split].
+ (* add *)
+ change (Equal m2 (add x e (remove x m2))).
+ intro k.
+ rewrite add_o, remove_o.
+ destruct eq_dec as [He|Hne]; auto.
+ rewrite <- He; apply find_1; auto.
+ (* disjoint *)
+ intros k (H1,H2). elim (Hdisj k). split; auto.
+ rewrite remove_in_iff in H2; destruct H2; auto.
+ (* mapsto *)
+ intros k' e'.
+ rewrite Heq, 2 remove_mapsto_iff, Hor.
+ intuition.
+ elim (Hdisj x); split; [exists e'|exists e]; auto.
+ apply MapsTo_1 with k'; auto.
+ Qed.
+
+ Lemma Partition_fold :
+ forall (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)(f:key->elt->A->A),
+ Morphism (E.eq==>Leibniz==>eqA==>eqA) f ->
+ transpose_neqkey eqA f ->
+ forall m m1 m2 i,
+ Partition m m1 m2 ->
+ eqA (fold f m i) (fold f m1 (fold f m2 i)).
+ Proof.
+ intros A eqA st f Comp Tra.
+ induction m as [m Hm|m m' IH k e Hn Hadd] using map_induction.
+
+ intros m1 m2 i Hp. rewrite (fold_Empty (eqA:=eqA)); auto.
+ rewrite (Partition_Empty Hp) in Hm. destruct Hm.
+ rewrite 2 (fold_Empty (eqA:=eqA)); auto. reflexivity.
+
+ intros m1 m2 i Hp.
+ destruct (Partition_Add Hn Hadd Hp) as (m3,[(Hadd',Hp')|(Hadd',Hp')]).
+ (* fst case: m3 is (k,e)::m1 *)
+ assert (~In k m3).
+ contradict Hn. destruct Hn as (e',He').
+ destruct Hp' as (Hp1,Hp2). exists e'. rewrite Hp2; auto.
+ transitivity (f k e (fold f m i)).
+ apply fold_Add with (eqA:=eqA); auto.
+ symmetry.
+ transitivity (f k e (fold f m3 (fold f m2 i))).
+ apply fold_Add with (eqA:=eqA); auto.
+ apply Comp; auto.
+ symmetry; apply IH; auto.
+ (* snd case: m3 is (k,e)::m2 *)
+ assert (~In k m3).
+ contradict Hn. destruct Hn as (e',He').
+ destruct Hp' as (Hp1,Hp2). exists e'. rewrite Hp2; auto.
+ assert (~In k m1).
+ contradict Hn. destruct Hn as (e',He').
+ destruct Hp' as (Hp1,Hp2). exists e'. rewrite Hp2; auto.
+ transitivity (f k e (fold f m i)).
+ apply fold_Add with (eqA:=eqA); auto.
+ transitivity (f k e (fold f m1 (fold f m3 i))).
+ apply Comp; auto using IH.
+ transitivity (fold f m1 (f k e (fold f m3 i))).
+ symmetry.
+ apply fold_commutes with (eqA:=eqA); auto.
+ apply fold_init with (eqA:=eqA); auto.
+ symmetry.
+ apply fold_Add with (eqA:=eqA); auto.
+ Qed.
+
+ Lemma Partition_cardinal : forall m m1 m2, Partition m m1 m2 ->
+ cardinal m = cardinal m1 + cardinal m2.
+ Proof.
+ intros.
+ rewrite (cardinal_fold m), (cardinal_fold m1).
+ set (f:=fun (_:key)(_:elt)=>S).
+ setoid_replace (fold f m 0) with (fold f m1 (fold f m2 0)).
+ rewrite <- cardinal_fold.
+ intros. apply fold_rel with (R:=fun u v => u = v + cardinal m2); simpl; auto.
+ apply Partition_fold with (eqA:=@Logic.eq _); try red; auto.
+ compute; auto.
+ Qed.
+
+ Lemma Partition_partition : forall m m1 m2, Partition m m1 m2 ->
+ let f := fun k (_:elt) => mem k m1 in
+ Equal m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m)).
+ Proof.
+ intros m m1 m2 Hm f.
+ assert (Hf : Morphism (E.eq==>Leibniz==>Leibniz) f).
+ intros k k' Hk e e' _; unfold f; rewrite Hk; auto.
+ set (m1':= fst (partition f m)).
+ set (m2':= snd (partition f m)).
+ split; rewrite Equal_mapsto_iff; intros k e.
+ rewrite (@partition_iff_1 f Hf m m1') by auto.
+ unfold f.
+ rewrite <- mem_in_iff.
+ destruct Hm as (Hm,Hm').
+ rewrite Hm'.
+ intuition.
+ exists e; auto.
+ elim (Hm k); split; auto; exists e; auto.
+ rewrite (@partition_iff_2 f Hf m m2') by auto.
+ unfold f.
+ rewrite <- not_mem_in_iff.
+ destruct Hm as (Hm,Hm').
+ rewrite Hm'.
+ intuition.
+ elim (Hm k); split; auto; exists e; auto.
+ elim H1; exists e; auto.
+ Qed.
+
+ Lemma update_mapsto_iff : forall m m' k e,
+ MapsTo k e (update m m') <->
+ (MapsTo k e m' \/ (MapsTo k e m /\ ~In k m')).
+ Proof.
+ unfold update.
+ intros m m'.
+ pattern m', (fold (@add _) m' m). apply fold_rec.
+
+ intros m0 Hm0 k e.
+ assert (~In k m0) by (intros (e0,He0); apply (Hm0 k e0); auto).
+ intuition.
+ elim (Hm0 k e); auto.
+
+ intros k e m0 m1 m2 _ Hn Hadd IH k' e'.
+ change (Equal m2 (add k e m1)) in Hadd.
+ rewrite Hadd, 2 add_mapsto_iff, IH, add_in_iff. clear IH. intuition.
+ Qed.
+
+ Lemma update_dec : forall m m' k e, MapsTo k e (update m m') ->
+ { MapsTo k e m' } + { MapsTo k e m /\ ~In k m'}.
+ Proof.
+ intros m m' k e H. rewrite update_mapsto_iff in H.
+ destruct (In_dec m' k) as [H'|H']; [left|right]; intuition.
+ elim H'; exists e; auto.
+ Defined.
+
+ Lemma update_in_iff : forall m m' k,
+ In k (update m m') <-> In k m \/ In k m'.
+ Proof.
+ intros m m' k. split.
+ intros (e,H); rewrite update_mapsto_iff in H.
+ destruct H; [right|left]; exists e; intuition.
+ destruct (In_dec m' k) as [H|H].
+ destruct H as (e,H). intros _; exists e.
+ rewrite update_mapsto_iff; left; auto.
+ destruct 1 as [H'|H']; [|elim H; auto].
+ destruct H' as (e,H'). exists e.
+ rewrite update_mapsto_iff; right; auto.
+ Qed.
+
+ Lemma diff_mapsto_iff : forall m m' k e,
+ MapsTo k e (diff m m') <-> MapsTo k e m /\ ~In k m'.
+ Proof.
+ intros m m' k e.
+ unfold diff.
+ rewrite filter_iff.
+ intuition.
+ rewrite mem_1 in *; auto; discriminate.
+ intros ? ? Hk _ _ _; rewrite Hk; auto.
+ Qed.
+
+ Lemma diff_in_iff : forall m m' k,
+ In k (diff m m') <-> In k m /\ ~In k m'.
+ Proof.
+ intros m m' k. split.
+ intros (e,H); rewrite diff_mapsto_iff in H.
+ destruct H; split; auto. exists e; auto.
+ intros ((e,H),H'); exists e; rewrite diff_mapsto_iff; auto.
+ Qed.
+
+ Lemma restrict_mapsto_iff : forall m m' k e,
+ MapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'.
+ Proof.
+ intros m m' k e.
+ unfold restrict.
+ rewrite filter_iff.
+ intuition.
+ intros ? ? Hk _ _ _; rewrite Hk; auto.
+ Qed.
+
+ Lemma restrict_in_iff : forall m m' k,
+ In k (restrict m m') <-> In k m /\ In k m'.
+ Proof.
+ intros m m' k. split.
+ intros (e,H); rewrite restrict_mapsto_iff in H.
+ destruct H; split; auto. exists e; auto.
+ intros ((e,H),H'); exists e; rewrite restrict_mapsto_iff; auto.
+ Qed.
+
(** specialized versions analyzing only keys (resp. elements) *)
Definition filter_dom (f : key -> bool) := filter (fun k _ => f k).
@@ -1106,17 +1672,85 @@ Module WProperties (E:DecidableType)(M:WSfun E).
End Elt.
- Add Parametric Morphism elt : (@cardinal elt) with signature Equal ==> @Logic.eq _ as cardinal_m.
+ Add Parametric Morphism elt : (@cardinal elt)
+ with signature Equal ==> Leibniz as cardinal_m.
Proof. intros; apply Equal_cardinal; auto. Qed.
-End WProperties.
-
-(** * Same Properties for full maps *)
-
-Module Properties (M:S).
- Module D := OT_as_DT M.E.
- Include WProperties D M.
-End Properties.
+ Add Parametric Morphism elt : (@Disjoint elt)
+ with signature Equal ==> Equal ==> iff as Disjoint_m.
+ Proof.
+ intros m1 m1' Hm1 m2 m2' Hm2. unfold Disjoint. split; intros.
+ rewrite <- Hm1, <- Hm2; auto.
+ rewrite Hm1, Hm2; auto.
+ Qed.
+
+ Add Parametric Morphism elt : (@Partition elt)
+ with signature Equal ==> Equal ==> Equal ==> iff as Partition_m.
+ Proof.
+ intros m1 m1' Hm1 m2 m2' Hm2 m3 m3' Hm3. unfold Partition.
+ rewrite <- Hm2, <- Hm3.
+ split; intros (H,H'); split; auto; intros.
+ rewrite <- Hm1, <- Hm2, <- Hm3; auto.
+ rewrite Hm1, Hm2, Hm3; auto.
+ Qed.
+
+ Add Parametric Morphism elt : (@update elt)
+ with signature Equal ==> Equal ==> Equal as update_m.
+ Proof.
+ intros m1 m1' Hm1 m2 m2' Hm2.
+ setoid_replace (update m1 m2) with (update m1' m2); unfold update.
+ apply fold_Equal with (eqA:=Equal); auto.
+ intros k k' Hk e e' He m m' Hm; rewrite Hk,He,Hm; red; auto.
+ intros k k' e e' i Hneq x.
+ rewrite !add_o; do 2 destruct eq_dec; auto. elim Hneq; eauto.
+ apply fold_init with (eqA:=Equal); auto.
+ intros k k' Hk e e' He m m' Hm; rewrite Hk,He,Hm; red; auto.
+ Qed.
+
+ Add Parametric Morphism elt : (@restrict elt)
+ with signature Equal ==> Equal ==> Equal as restrict_m.
+ Proof.
+ intros m1 m1' Hm1 m2 m2' Hm2.
+ setoid_replace (restrict m1 m2) with (restrict m1' m2);
+ unfold restrict, filter.
+ apply fold_rel with (R:=Equal); try red; auto.
+ intros k e i i' H Hii' x.
+ pattern (mem k m2); rewrite Hm2. (* UGLY, see with Matthieu *)
+ destruct mem; rewrite Hii'; auto.
+ apply fold_Equal with (eqA:=Equal); auto.
+ intros k k' Hk e e' He m m' Hm; simpl in *.
+ pattern (mem k m2); rewrite Hk. (* idem *)
+ destruct mem; rewrite ?Hk,?He,Hm; red; auto.
+ intros k k' e e' i Hneq x.
+ case_eq (mem k m2); case_eq (mem k' m2); intros; auto.
+ rewrite !add_o; do 2 destruct eq_dec; auto. elim Hneq; eauto.
+ Qed.
+
+ Add Parametric Morphism elt : (@diff elt)
+ with signature Equal ==> Equal ==> Equal as diff_m.
+ Proof.
+ intros m1 m1' Hm1 m2 m2' Hm2.
+ setoid_replace (diff m1 m2) with (diff m1' m2);
+ unfold diff, filter.
+ apply fold_rel with (R:=Equal); try red; auto.
+ intros k e i i' H Hii' x.
+ pattern (mem k m2); rewrite Hm2. (* idem *)
+ destruct mem; simpl; rewrite Hii'; auto.
+ apply fold_Equal with (eqA:=Equal); auto.
+ intros k k' Hk e e' He m m' Hm; simpl in *.
+ pattern (mem k m2); rewrite Hk. (* idem *)
+ destruct mem; simpl; rewrite ?Hk,?He,Hm; red; auto.
+ intros k k' e e' i Hneq x.
+ case_eq (mem k m2); case_eq (mem k' m2); intros; simpl; auto.
+ rewrite !add_o; do 2 destruct eq_dec; auto. elim Hneq; eauto.
+ Qed.
+
+End WProperties_fun.
+
+(** * Same Properties for self-contained weak maps and for full maps *)
+
+Module WProperties (M:WS) := WProperties_fun M.E M.
+Module Properties := WProperties.
(** * Properties specific to maps with ordered keys *)
@@ -1151,7 +1785,8 @@ Module OrdProperties (M:S).
Ltac clean_eauto := unfold O.eqke, O.ltk; simpl; intuition; eauto.
- Definition gtb (p p':key*elt) := match E.compare (fst p) (fst p') with GT _ => true | _ => false end.
+ Definition gtb (p p':key*elt) :=
+ match E.compare (fst p) (fst p') with GT _ => true | _ => false end.
Definition leb p := fun p' => negb (gtb p p').
Definition elements_lt p m := List.filter (gtb p) (elements m).
@@ -1275,7 +1910,7 @@ Module OrdProperties (M:S).
rewrite find_mapsto_iff; rewrite (H0 t0); rewrite <- find_mapsto_iff.
rewrite add_mapsto_iff; unfold O.eqke; simpl.
intuition.
- destruct (ME.eq_dec x t0); auto.
+ destruct (E.eq_dec x t0); auto.
elimtype False.
assert (In t0 m).
exists e0; auto.
@@ -1305,7 +1940,7 @@ Module OrdProperties (M:S).
rewrite find_mapsto_iff; rewrite (H0 t0); rewrite <- find_mapsto_iff.
rewrite add_mapsto_iff; unfold O.eqke; simpl.
intuition.
- destruct (ME.eq_dec x t0); auto.
+ destruct (E.eq_dec x t0); auto.
elimtype False.
assert (In t0 m).
exists e0; auto.
@@ -1361,7 +1996,7 @@ Module OrdProperties (M:S).
inversion_clear H1; [ | inversion_clear H2; eauto ].
red in H3; simpl in H3; destruct H3.
destruct p as (p1,p2).
- destruct (ME.eq_dec p1 x).
+ destruct (E.eq_dec p1 x).
apply ME.lt_eq with p1; auto.
inversion_clear H2.
inversion_clear H5.
@@ -1513,74 +2148,53 @@ Module OrdProperties (M:S).
(** The following lemma has already been proved on Weak Maps,
but with one additionnal hypothesis (some [transpose] fact). *)
- Lemma fold_Equal : forall s1 s2 (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory A eqA)
- (f:key->elt->A->A)(i:A),
- compat_op eqke eqA (fun y =>f (fst y) (snd y)) ->
- Equal s1 s2 ->
- eqA (fold f s1 i) (fold f s2 i).
+ Lemma fold_Equal : forall m1 m2 (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)
+ (f:key->elt->A->A)(i:A),
+ Morphism (E.eq==>Leibniz==>eqA==>eqA) f ->
+ Equal m1 m2 ->
+ eqA (fold f m1 i) (fold f m2 i).
Proof.
- intros.
+ intros m1 m2 A eqA st f i Hf Heq.
do 2 rewrite fold_1.
do 2 rewrite <- fold_left_rev_right.
apply fold_right_eqlistA with (eqA:=eqke) (eqB:=eqA); auto.
- apply eqlistA_rev.
- apply elements_Equal_eqlistA; auto.
+ intros (k,e) (k',e') a a' (Hk,He) Ha; simpl in *; apply Hf; auto.
+ apply eqlistA_rev. apply elements_Equal_eqlistA. auto.
Qed.
- Lemma fold_Add : forall s1 s2 x e (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory A eqA)
- (f:key->elt->A->A)(i:A),
- compat_op eqke eqA (fun y =>f (fst y) (snd y)) ->
- transpose eqA (fun y =>f (fst y) (snd y)) ->
- ~In x s1 -> Add x e s1 s2 ->
- eqA (fold f s2 i) (f x e (fold f s1 i)).
- Proof.
- intros; do 2 rewrite fold_1; do 2 rewrite <- fold_left_rev_right.
- set (f':=fun y x0 => f (fst y) (snd y) x0) in *.
- change (f x e (fold_right f' i (rev (elements s1))))
- with (f' (x,e) (fold_right f' i (rev (elements s1)))).
- trans_st (fold_right f' i
- (rev (elements_lt (x, e) s1 ++ (x,e) :: elements_ge (x, e) s1))).
- apply fold_right_eqlistA with (eqA:=eqke) (eqB:=eqA); auto.
- apply eqlistA_rev.
- apply elements_Add; auto.
- rewrite distr_rev; simpl.
- rewrite app_ass; simpl.
- rewrite (elements_split (x,e) s1).
- rewrite distr_rev; simpl.
- apply fold_right_commutes with (eqA:=eqke) (eqB:=eqA); auto.
- Qed.
-
- Lemma fold_Add_Above : forall s1 s2 x e (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory A eqA)
- (f:key->elt->A->A)(i:A),
- compat_op eqke eqA (fun y =>f (fst y) (snd y)) ->
- Above x s1 -> Add x e s1 s2 ->
- eqA (fold f s2 i) (f x e (fold f s1 i)).
+ Lemma fold_Add_Above : forall m1 m2 x e (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)
+ (f:key->elt->A->A)(i:A),
+ Morphism (E.eq==>Leibniz==>eqA==>eqA) f ->
+ Above x m1 -> Add x e m1 m2 ->
+ eqA (fold f m2 i) (f x e (fold f m1 i)).
Proof.
intros; do 2 rewrite fold_1; do 2 rewrite <- fold_left_rev_right.
set (f':=fun y x0 => f (fst y) (snd y) x0) in *.
- trans_st (fold_right f' i (rev (elements s1 ++ (x,e)::nil))).
+ transitivity (fold_right f' i (rev (elements m1 ++ (x,e)::nil))).
apply fold_right_eqlistA with (eqA:=eqke) (eqB:=eqA); auto.
+ intros (k1,e1) (k2,e2) a1 a2 (Hk,He) Ha; unfold f'; simpl in *; apply H; auto.
apply eqlistA_rev.
apply elements_Add_Above; auto.
rewrite distr_rev; simpl.
- refl_st.
+ reflexivity.
Qed.
- Lemma fold_Add_Below : forall s1 s2 x e (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory A eqA)
- (f:key->elt->A->A)(i:A),
- compat_op eqke eqA (fun y =>f (fst y) (snd y)) ->
- Below x s1 -> Add x e s1 s2 ->
- eqA (fold f s2 i) (fold f s1 (f x e i)).
+ Lemma fold_Add_Below : forall m1 m2 x e (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)
+ (f:key->elt->A->A)(i:A),
+ Morphism (E.eq==>Leibniz==>eqA==>eqA) f ->
+ Below x m1 -> Add x e m1 m2 ->
+ eqA (fold f m2 i) (fold f m1 (f x e i)).
Proof.
intros; do 2 rewrite fold_1; do 2 rewrite <- fold_left_rev_right.
set (f':=fun y x0 => f (fst y) (snd y) x0) in *.
- trans_st (fold_right f' i (rev (((x,e)::nil)++elements s1))).
+ transitivity (fold_right f' i (rev (((x,e)::nil)++elements m1))).
apply fold_right_eqlistA with (eqA:=eqke) (eqB:=eqA); auto.
+ intros (k1,e1) (k2,e2) a1 a2 (Hk,He) Ha; unfold f'; simpl in *; apply H; auto.
apply eqlistA_rev.
simpl; apply elements_Add_Below; auto.
rewrite distr_rev; simpl.
rewrite fold_right_app.
- refl_st.
+ reflexivity.
Qed.
End Fold_properties.
@@ -1589,7 +2203,3 @@ Module OrdProperties (M:S).
End OrdProperties.
-
-
-
-
diff --git a/theories/FSets/FMapInterface.v b/theories/FSets/FMapInterface.v
index 1e475887..ebdc9c57 100644
--- a/theories/FSets/FMapInterface.v
+++ b/theories/FSets/FMapInterface.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FMapInterface.v 10616 2008-03-04 17:33:35Z letouzey $ *)
+(* $Id: FMapInterface.v 11699 2008-12-18 11:49:08Z letouzey $ *)
(** * Finite map library *)
@@ -55,11 +55,7 @@ Definition Cmp (elt:Type)(cmp:elt->elt->bool) e1 e2 := cmp e1 e2 = true.
No requirements for an ordering on keys nor elements, only decidability
of equality on keys. First, a functorial signature: *)
-Module Type WSfun (E : EqualityType).
-
- (** The module E of base objects is meant to be a [DecidableType]
- (and used to be so). But requiring only an [EqualityType] here
- allows subtyping between weak and ordered maps. *)
+Module Type WSfun (E : DecidableType).
Definition key := E.t.
@@ -261,7 +257,7 @@ End WSfun.
Similar to [WSfun] but expressed in a self-contained way. *)
Module Type WS.
- Declare Module E : EqualityType.
+ Declare Module E : DecidableType.
Include Type WSfun E.
End WS.
diff --git a/theories/FSets/FMapList.v b/theories/FSets/FMapList.v
index 23bf8196..0ec5ef36 100644
--- a/theories/FSets/FMapList.v
+++ b/theories/FSets/FMapList.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FMapList.v 10616 2008-03-04 17:33:35Z letouzey $ *)
+(* $Id: FMapList.v 11699 2008-12-18 11:49:08Z letouzey $ *)
(** * Finite map library *)
@@ -402,7 +402,7 @@ Proof.
elim (Sort_Inf_NotIn H6 H7).
destruct H as (e'', hyp); exists e''; auto.
apply MapsTo_eq with k; auto; order.
- apply H1 with k; destruct (eq_dec x k); auto.
+ apply H1 with k; destruct (X.eq_dec x k); auto.
destruct (X.compare x x'); try contradiction; clear y.
diff --git a/theories/FSets/FMapPositive.v b/theories/FSets/FMapPositive.v
index 9bc2a599..7fbc3d47 100644
--- a/theories/FSets/FMapPositive.v
+++ b/theories/FSets/FMapPositive.v
@@ -11,7 +11,7 @@
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
* 91405 Orsay, France *)
-(* $Id: FMapPositive.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: FMapPositive.v 11699 2008-12-18 11:49:08Z letouzey $ *)
Require Import Bool.
Require Import ZArith.
@@ -111,17 +111,17 @@ Module PositiveOrderedTypeBits <: UsualOrderedType.
apply EQ; red; auto.
Qed.
-End PositiveOrderedTypeBits.
-
-(** Other positive stuff *)
-
-Lemma peq_dec (x y: positive): {x = y} + {x <> y}.
-Proof.
+ Lemma eq_dec (x y: positive): {x = y} + {x <> y}.
+ Proof.
intros. case_eq ((x ?= y) Eq); intros.
left. apply Pcompare_Eq_eq; auto.
right. red. intro. subst y. rewrite (Pcompare_refl x) in H. discriminate.
right. red. intro. subst y. rewrite (Pcompare_refl x) in H. discriminate.
-Qed.
+ Qed.
+
+End PositiveOrderedTypeBits.
+
+(** Other positive stuff *)
Fixpoint append (i j : positive) {struct i} : positive :=
match i with
@@ -717,7 +717,7 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits.
Lemma remove_3 : MapsTo y e (remove x m) -> MapsTo y e m.
Proof.
unfold MapsTo.
- destruct (peq_dec x y).
+ destruct (E.eq_dec x y).
subst.
rewrite grs; intros; discriminate.
rewrite gro; auto.
@@ -820,16 +820,21 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits.
Variable B : Type.
- Fixpoint xmapi (f : positive -> A -> B) (m : t A) (i : positive)
- {struct m} : t B :=
- match m with
- | Leaf => @Leaf B
- | Node l o r => Node (xmapi f l (append i (xO xH)))
- (option_map (f i) o)
- (xmapi f r (append i (xI xH)))
- end.
+ Section Mapi.
+
+ Variable f : positive -> A -> B.
- Definition mapi (f : positive -> A -> B) m := xmapi f m xH.
+ Fixpoint xmapi (m : t A) (i : positive) {struct m} : t B :=
+ match m with
+ | Leaf => @Leaf B
+ | Node l o r => Node (xmapi l (append i (xO xH)))
+ (option_map (f i) o)
+ (xmapi r (append i (xI xH)))
+ end.
+
+ Definition mapi m := xmapi m xH.
+
+ End Mapi.
Definition map (f : A -> B) m := mapi (fun _ => f) m.
@@ -983,14 +988,47 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits.
Qed.
- Definition fold (A : Type)(B : Type) (f: positive -> A -> B -> B) (tr: t A) (v: B) :=
- List.fold_left (fun a p => f (fst p) (snd p) a) (elements tr) v.
-
+ Section Fold.
+
+ Variables A B : Type.
+ Variable f : positive -> A -> B -> B.
+
+ Fixpoint xfoldi (m : t A) (v : B) (i : positive) :=
+ match m with
+ | Leaf => v
+ | Node l (Some x) r =>
+ xfoldi r (f i x (xfoldi l v (append i 2))) (append i 3)
+ | Node l None r =>
+ xfoldi r (xfoldi l v (append i 2)) (append i 3)
+ end.
+
+ Lemma xfoldi_1 :
+ forall m v i,
+ xfoldi m v i = fold_left (fun a p => f (fst p) (snd p) a) (xelements m i) v.
+ Proof.
+ set (F := fun a p => f (fst p) (snd p) a).
+ induction m; intros; simpl; auto.
+ destruct o.
+ rewrite fold_left_app; simpl.
+ rewrite <- IHm1.
+ rewrite <- IHm2.
+ unfold F; simpl; reflexivity.
+ rewrite fold_left_app; simpl.
+ rewrite <- IHm1.
+ rewrite <- IHm2.
+ reflexivity.
+ Qed.
+
+ Definition fold m i := xfoldi m i 1.
+
+ End Fold.
+
Lemma fold_1 :
forall (A:Type)(m:t A)(B:Type)(i : B) (f : key -> A -> B -> B),
fold f m i = fold_left (fun a p => f (fst p) (snd p) a) (elements m) i.
Proof.
- intros; unfold fold; auto.
+ intros; unfold fold, elements.
+ rewrite xfoldi_1; reflexivity.
Qed.
Fixpoint equal (A:Type)(cmp : A -> A -> bool)(m1 m2 : t A) {struct m1} : bool :=
@@ -1128,10 +1166,10 @@ Module PositiveMapAdditionalFacts.
(* Derivable from the Map interface *)
Theorem gsspec:
forall (A:Type)(i j: positive) (x: A) (m: t A),
- find i (add j x m) = if peq_dec i j then Some x else find i m.
+ find i (add j x m) = if E.eq_dec i j then Some x else find i m.
Proof.
intros.
- destruct (peq_dec i j); [ rewrite e; apply gss | apply gso; auto ].
+ destruct (E.eq_dec i j); [ rewrite e; apply gss | apply gso; auto ].
Qed.
(* Not derivable from the Map interface *)
diff --git a/theories/FSets/FSetAVL.v b/theories/FSets/FSetAVL.v
index faa705f6..cc1c0a76 100644
--- a/theories/FSets/FSetAVL.v
+++ b/theories/FSets/FSetAVL.v
@@ -11,7 +11,7 @@
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
* 91405 Orsay, France *)
-(* $Id: FSetAVL.v 10811 2008-04-17 16:29:49Z letouzey $ *)
+(* $Id: FSetAVL.v 11699 2008-12-18 11:49:08Z letouzey $ *)
(** * FSetAVL *)
@@ -1881,6 +1881,14 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X.
destruct Raw.compare; intros; [apply EQ|apply LT|apply GT]; red; auto.
Defined.
+ Definition eq_dec (s s':t) : { eq s s' } + { ~ eq s s' }.
+ Proof.
+ intros (s,b) (s',b'); unfold eq; simpl.
+ case_eq (Raw.equal s s'); intro H; [left|right].
+ apply equal_2; auto.
+ intro H'; rewrite equal_1 in H; auto; discriminate.
+ Defined.
+
(* specs *)
Section Specs.
Variable s s' s'': t.
diff --git a/theories/FSets/FSetBridge.v b/theories/FSets/FSetBridge.v
index 0622451f..c03fb92e 100644
--- a/theories/FSets/FSetBridge.v
+++ b/theories/FSets/FSetBridge.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetBridge.v 10601 2008-02-28 00:20:33Z letouzey $ *)
+(* $Id: FSetBridge.v 11699 2008-12-18 11:49:08Z letouzey $ *)
(** * Finite sets library *)
@@ -20,11 +20,8 @@ Set Firstorder Depth 2.
(** * From non-dependent signature [S] to dependent signature [Sdep]. *)
-Module DepOfNodep (M: S) <: Sdep with Module E := M.E.
- Import M.
+Module DepOfNodep (Import M: S) <: Sdep with Module E := M.E.
- Module ME := OrderedTypeFacts E.
-
Definition empty : {s : t | Empty s}.
Proof.
exists empty; auto with set.
@@ -50,7 +47,7 @@ Module DepOfNodep (M: S) <: Sdep with Module E := M.E.
Proof.
intros; exists (add x s); auto.
unfold Add in |- *; intuition.
- elim (ME.eq_dec x y); auto.
+ elim (E.eq_dec x y); auto.
intros; right.
eapply add_3; eauto.
Qed.
@@ -68,7 +65,7 @@ Module DepOfNodep (M: S) <: Sdep with Module E := M.E.
intros; exists (remove x s); intuition.
absurd (In x (remove x s)); auto with set.
apply In_1 with y; auto.
- elim (ME.eq_dec x y); intros; auto.
+ elim (E.eq_dec x y); intros; auto.
absurd (In x (remove x s)); auto with set.
apply In_1 with y; auto.
eauto with set.
@@ -396,6 +393,8 @@ Module NodepOfDep (M: Sdep) <: S with Module E := M.E.
intros; discriminate H.
Qed.
+ Definition eq_dec := equal.
+
Definition equal (s s' : t) : bool :=
if equal s s' then true else false.
diff --git a/theories/FSets/FSetDecide.v b/theories/FSets/FSetDecide.v
index 0639c1f1..06b4e028 100644
--- a/theories/FSets/FSetDecide.v
+++ b/theories/FSets/FSetDecide.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetDecide.v 11064 2008-06-06 17:00:52Z letouzey $ *)
+(* $Id: FSetDecide.v 11699 2008-12-18 11:49:08Z letouzey $ *)
(**************************************************************)
(* FSetDecide.v *)
@@ -19,10 +19,10 @@
Require Import Decidable DecidableTypeEx FSetFacts.
-(** First, a version for Weak Sets *)
+(** First, a version for Weak Sets in functorial presentation *)
-Module WDecide (E : DecidableType)(Import M : WSfun E).
- Module F := FSetFacts.WFacts E M.
+Module WDecide_fun (E : DecidableType)(Import M : WSfun E).
+ Module F := FSetFacts.WFacts_fun E M.
(** * Overview
This functor defines the tactic [fsetdec], which will
@@ -509,7 +509,14 @@ the above form:
| J : _ |- _ => progress (change T with E.t in J)
| |- _ => progress (change T with E.t)
end )
- end).
+ | H : forall x : ?T, _ |- _ =>
+ progress (change T with E.t in H);
+ repeat (
+ match goal with
+ | J : _ |- _ => progress (change T with E.t in J)
+ | |- _ => progress (change T with E.t)
+ end )
+ end).
(** These two tactics take us from Coq's built-in equality
to [E.eq] (and vice versa) when possible. *)
@@ -747,6 +754,12 @@ the above form:
In x (singleton x).
Proof. fsetdec. Qed.
+ Lemma test_add_In : forall x y s,
+ In x (add y s) ->
+ ~ E.eq x y ->
+ In x s.
+ Proof. fsetdec. Qed.
+
Lemma test_Subset_add_remove : forall x s,
s [<=] (add x (remove x s)).
Proof. fsetdec. Qed.
@@ -825,17 +838,27 @@ the above form:
intros until 3. intros g_eq. rewrite <- g_eq. fsetdec.
Qed.
+ Lemma test_baydemir :
+ forall (f : t -> t),
+ forall (s : t),
+ forall (x y : elt),
+ In x (add y (f s)) ->
+ ~ E.eq x y ->
+ In x (f s).
+ Proof.
+ fsetdec.
+ Qed.
+
End FSetDecideTestCases.
-End WDecide.
+End WDecide_fun.
Require Import FSetInterface.
-(** Now comes a special version dedicated to full sets. For this
- one, only one argument [(M:S)] is necessary. *)
+(** Now comes variants for self-contained weak sets and for full sets.
+ For these variants, only one argument is necessary. Thanks to
+ the subtyping [WS<=S], the [Decide] functor which is meant to be
+ used on modules [(M:S)] can simply be an alias of [WDecide]. *)
-Module Decide (M : S).
- Module D:=OT_as_DT M.E.
- Module WD := WDecide D M.
- Ltac fsetdec := WD.fsetdec.
-End Decide. \ No newline at end of file
+Module WDecide (M:WS) := WDecide_fun M.E M.
+Module Decide := WDecide.
diff --git a/theories/FSets/FSetEqProperties.v b/theories/FSets/FSetEqProperties.v
index a397cc28..80ab2b2c 100644
--- a/theories/FSets/FSetEqProperties.v
+++ b/theories/FSets/FSetEqProperties.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetEqProperties.v 11064 2008-06-06 17:00:52Z letouzey $ *)
+(* $Id: FSetEqProperties.v 11720 2008-12-28 07:12:15Z letouzey $ *)
(** * Finite sets library *)
@@ -19,8 +19,8 @@
Require Import FSetProperties Zerob Sumbool Omega DecidableTypeEx.
-Module WEqProperties (Import E:DecidableType)(M:WSfun E).
-Module Import MP := WProperties E M.
+Module WEqProperties_fun (Import E:DecidableType)(M:WSfun E).
+Module Import MP := WProperties_fun E M.
Import FM Dec.F.
Import M.
@@ -73,7 +73,7 @@ Qed.
Lemma is_empty_equal_empty: is_empty s = equal s empty.
Proof.
apply bool_1; split; intros.
-rewrite <- (empty_is_empty_1 (s:=empty)); auto with set.
+auto with set.
rewrite <- is_empty_iff; auto with set.
Qed.
@@ -281,7 +281,7 @@ Qed.
Lemma singleton_mem_2: ~E.eq x y -> mem y (singleton x)=false.
Proof.
intros; rewrite singleton_b.
-unfold eqb; destruct (eq_dec x y); intuition.
+unfold eqb; destruct (E.eq_dec x y); intuition.
Qed.
Lemma singleton_mem_3: mem y (singleton x)=true -> E.eq x y.
@@ -494,7 +494,7 @@ destruct (mem x s); destruct (mem x s'); intuition.
Qed.
Section Fold.
-Variables (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory _ eqA).
+Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA).
Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f)(Ass:transpose eqA f).
Variables (i:A).
Variables (s s':t)(x:elt).
@@ -852,7 +852,7 @@ assert (gc : compat_opL (fun x:elt => plus (g x))). auto.
assert (gt : transposeL (fun x:elt =>plus (g x))). red; intros; omega.
assert (fgc : compat_opL (fun x:elt =>plus ((f x)+(g x)))). auto.
assert (fgt : transposeL (fun x:elt=>plus ((f x)+(g x)))). red; intros; omega.
-assert (st := gen_st nat).
+assert (st : Equivalence (@Logic.eq nat)) by (split; congruence).
intros s;pattern s; apply set_rec.
intros.
rewrite <- (fold_equal _ _ st _ fc ft 0 _ _ H).
@@ -867,7 +867,7 @@ Lemma sum_filter : forall f, (compat_bool E.eq f) ->
forall s, (sum (fun x => if f x then 1 else 0) s) = (cardinal (filter f s)).
Proof.
unfold sum; intros f Hf.
-assert (st := gen_st nat).
+assert (st : Equivalence (@Logic.eq nat)) by (split; congruence).
assert (cc : compat_opL (fun x => plus (if f x then 1 else 0))).
red; intros.
rewrite (Hf x x' H); auto.
@@ -892,7 +892,7 @@ rewrite filter_iff; auto; set_iff; tauto.
Qed.
Lemma fold_compat :
- forall (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory _ eqA)
+ forall (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)
(f g:elt->A->A),
(compat_op E.eq eqA f) -> (transpose eqA f) ->
(compat_op E.eq eqA g) -> (transpose eqA g) ->
@@ -901,19 +901,19 @@ Lemma fold_compat :
Proof.
intros A eqA st f g fc ft gc gt i.
intro s; pattern s; apply set_rec; intros.
-trans_st (fold f s0 i).
+transitivity (fold f s0 i).
apply fold_equal with (eqA:=eqA); auto.
rewrite equal_sym; auto.
-trans_st (fold g s0 i).
+transitivity (fold g s0 i).
apply H0; intros; apply H1; auto with set.
elim (equal_2 H x); auto with set; intros.
apply fold_equal with (eqA:=eqA); auto with set.
-trans_st (f x (fold f s0 i)).
+transitivity (f x (fold f s0 i)).
apply fold_add with (eqA:=eqA); auto with set.
-trans_st (g x (fold f s0 i)); auto with set.
-trans_st (g x (fold g s0 i)); auto with set.
-sym_st; apply fold_add with (eqA:=eqA); auto.
-do 2 rewrite fold_empty; refl_st.
+transitivity (g x (fold f s0 i)); auto with set.
+transitivity (g x (fold g s0 i)); auto with set.
+symmetry; apply fold_add with (eqA:=eqA); auto.
+do 2 rewrite fold_empty; reflexivity.
Qed.
Lemma sum_compat :
@@ -927,13 +927,12 @@ Qed.
End Sum.
-End WEqProperties.
-
+End WEqProperties_fun.
-(** Now comes a special version dedicated to full sets. For this
- one, only one argument [(M:S)] is necessary. *)
+(** Now comes variants for self-contained weak sets and for full sets.
+ For these variants, only one argument is necessary. Thanks to
+ the subtyping [WS<=S], the [EqProperties] functor which is meant to be
+ used on modules [(M:S)] can simply be an alias of [WEqProperties]. *)
-Module EqProperties (M:S).
- Module D := OT_as_DT M.E.
- Include WEqProperties D M.
-End EqProperties.
+Module WEqProperties (M:WS) := WEqProperties_fun M.E M.
+Module EqProperties := WEqProperties.
diff --git a/theories/FSets/FSetFacts.v b/theories/FSets/FSetFacts.v
index d77d9c60..1e15d3a1 100644
--- a/theories/FSets/FSetFacts.v
+++ b/theories/FSets/FSetFacts.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetFacts.v 11282 2008-07-28 11:51:53Z msozeau $ *)
+(* $Id: FSetFacts.v 11720 2008-12-28 07:12:15Z letouzey $ *)
(** * Finite sets library *)
@@ -21,11 +21,9 @@ Require Export FSetInterface.
Set Implicit Arguments.
Unset Strict Implicit.
-(** First, a functor for Weak Sets. Since the signature [WS] includes
- an EqualityType and not a stronger DecidableType, this functor
- should take two arguments in order to compensate this. *)
+(** First, a functor for Weak Sets in functorial version. *)
-Module WFacts (Import E : DecidableType)(Import M : WSfun E).
+Module WFacts_fun (Import E : DecidableType)(Import M : WSfun E).
Notation eq_dec := E.eq_dec.
Definition eqb x y := if eq_dec x y then true else false.
@@ -293,12 +291,12 @@ End BoolSpec.
(** * [E.eq] and [Equal] are setoid equalities *)
-Definition E_ST : Setoid_Theory elt E.eq.
+Definition E_ST : Equivalence E.eq.
Proof.
constructor ; red; [apply E.eq_refl|apply E.eq_sym|apply E.eq_trans].
Qed.
-Definition Equal_ST : Setoid_Theory t Equal.
+Definition Equal_ST : Equivalence Equal.
Proof.
constructor ; red; [apply eq_refl | apply eq_sym | apply eq_trans].
Qed.
@@ -309,8 +307,6 @@ Add Relation elt E.eq
transitivity proved by E.eq_trans
as EltSetoid.
-Typeclasses unfold elt.
-
Add Relation t Equal
reflexivity proved by eq_refl
symmetry proved by eq_sym
@@ -418,18 +414,15 @@ Qed.
(* [Subset] is a setoid order *)
Lemma Subset_refl : forall s, s[<=]s.
-Proof. red; auto. Defined.
+Proof. red; auto. Qed.
Lemma Subset_trans : forall s s' s'', s[<=]s'->s'[<=]s''->s[<=]s''.
-Proof. unfold Subset; eauto. Defined.
+Proof. unfold Subset; eauto. Qed.
-Add Relation t Subset
+Add Relation t Subset
reflexivity proved by Subset_refl
transitivity proved by Subset_trans
as SubsetSetoid.
-(* NB: for the moment, it is important to use Defined and not Qed in
- the two previous lemmas, in order to allow conversion of
- SubsetSetoid coming from separate Facts modules. See bug #1738. *)
Instance In_s_m : Morphism (E.eq ==> Subset ++> impl) In | 1.
Proof.
@@ -480,28 +473,35 @@ Proof.
unfold Equal; intros; repeat rewrite filter_iff; auto; rewrite H0; tauto.
Qed.
+Lemma filter_ext : forall f f', compat_bool E.eq f -> (forall x, f x = f' x) ->
+ forall s s', s[=]s' -> filter f s [=] filter f' s'.
+Proof.
+intros f f' Hf Hff' s s' Hss' x. do 2 (rewrite filter_iff; auto).
+rewrite Hff', Hss'; intuition.
+red; intros; rewrite <- 2 Hff'; auto.
+Qed.
+
Lemma filter_subset : forall f, compat_bool E.eq f ->
forall s s', s[<=]s' -> filter f s [<=] filter f s'.
Proof.
unfold Subset; intros; rewrite filter_iff in *; intuition.
Qed.
-(* For [elements], [min_elt], [max_elt] and [choose], we would need setoid
+(* For [elements], [min_elt], [max_elt] and [choose], we would need setoid
structures on [list elt] and [option elt]. *)
(* Later:
Add Morphism cardinal ; cardinal_m.
*)
-End WFacts.
-
+End WFacts_fun.
-(** Now comes a special version dedicated to full sets. For this
- one, only one argument [(M:S)] is necessary. *)
+(** Now comes variants for self-contained weak sets and for full sets.
+ For these variants, only one argument is necessary. Thanks to
+ the subtyping [WS<=S], the [Facts] functor which is meant to be
+ used on modules [(M:S)] can simply be an alias of [WFacts]. *)
-Module Facts (Import M:S).
- Module D:=OT_as_DT M.E.
- Include WFacts D M.
+Module WFacts (M:WS) := WFacts_fun M.E M.
+Module Facts := WFacts.
-End Facts.
diff --git a/theories/FSets/FSetFullAVL.v b/theories/FSets/FSetFullAVL.v
index 1fc109f3..a2d8e681 100644
--- a/theories/FSets/FSetFullAVL.v
+++ b/theories/FSets/FSetFullAVL.v
@@ -11,7 +11,7 @@
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
* 91405 Orsay, France *)
-(* $Id: FSetFullAVL.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: FSetFullAVL.v 11699 2008-12-18 11:49:08Z letouzey $ *)
(** * FSetFullAVL
@@ -913,6 +913,14 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X.
change (Raw.Equal s s'); auto.
Defined.
+ Definition eq_dec (s s':t) : { eq s s' } + { ~ eq s s' }.
+ Proof.
+ intros (s,b,a) (s',b',a'); unfold eq; simpl.
+ case_eq (Raw.equal s s'); intro H; [left|right].
+ apply equal_2; auto.
+ intro H'; rewrite equal_1 in H; auto; discriminate.
+ Defined.
+
(* specs *)
Section Specs.
Variable s s' s'': t.
diff --git a/theories/FSets/FSetInterface.v b/theories/FSets/FSetInterface.v
index 1255fcc8..79eea34e 100644
--- a/theories/FSets/FSetInterface.v
+++ b/theories/FSets/FSetInterface.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetInterface.v 10616 2008-03-04 17:33:35Z letouzey $ *)
+(* $Id: FSetInterface.v 11701 2008-12-18 11:49:12Z letouzey $ *)
(** * Finite set library *)
@@ -44,11 +44,7 @@ Unset Strict Implicit.
Weak sets are sets without ordering on base elements, only
a decidable equality. *)
-Module Type WSfun (E : EqualityType).
-
- (** The module E of base objects is meant to be a [DecidableType]
- (and used to be so). But requiring only an [EqualityType] here
- allows subtyping between weak and ordered sets *)
+Module Type WSfun (E : DecidableType).
Definition elt := E.t.
@@ -62,8 +58,8 @@ Module Type WSfun (E : EqualityType).
Definition For_all (P : elt -> Prop) s := forall x, In x s -> P x.
Definition Exists (P : elt -> Prop) s := exists x, In x s /\ P x.
- Notation "s [=] t" := (Equal s t) (at level 70, no associativity).
- Notation "s [<=] t" := (Subset s t) (at level 70, no associativity).
+ Notation "s [=] t" := (Equal s t) (at level 70, no associativity).
+ Notation "s [<=] t" := (Subset s t) (at level 70, no associativity).
Parameter empty : t.
(** The empty set. *)
@@ -95,12 +91,8 @@ Module Type WSfun (E : EqualityType).
(** Set difference. *)
Definition eq : t -> t -> Prop := Equal.
- (** In order to have the subtyping WS < S between weak and ordered
- sets, we do not require here an [eq_dec]. This interface is hence
- not compatible with [DecidableType], but only with [EqualityType],
- so in general it may not possible to form weak sets of weak sets.
- Some particular implementations may allow this nonetheless, in
- particular [FSetWeakList.Make]. *)
+
+ Parameter eq_dec : forall s s', { eq s s' } + { ~ eq s s' }.
Parameter equal : t -> t -> bool.
(** [equal s1 s2] tests whether the sets [s1] and [s2] are
@@ -282,7 +274,7 @@ End WSfun.
module [E] of base elements is incorporated in the signature. *)
Module Type WS.
- Declare Module E : EqualityType.
+ Declare Module E : DecidableType.
Include Type WSfun E.
End WS.
@@ -367,17 +359,16 @@ WSfun ---> WS
| |
| |
V V
-Sfun ---> S
-
+Sfun ---> S
-Module S_WS (M : S) <: SW := M.
+Module S_WS (M : S) <: WS := M.
Module Sfun_WSfun (E:OrderedType)(M : Sfun E) <: WSfun E := M.
-Module S_Sfun (E:OrderedType)(M : S with Module E:=E) <: Sfun E := M.
-Module WS_WSfun (E:EqualityType)(M : WS with Module E:=E) <: WSfun E := M.
+Module S_Sfun (M : S) <: Sfun M.E := M.
+Module WS_WSfun (M : WS) <: WSfun M.E := M.
>>
*)
-(** * Dependent signature
+(** * Dependent signature
Signature [Sdep] presents ordered sets using dependent types *)
@@ -402,7 +393,7 @@ Module Type Sdep.
Parameter lt : t -> t -> Prop.
Parameter compare : forall s s' : t, Compare lt eq s s'.
- Parameter eq_refl : forall s : t, eq s s.
+ Parameter eq_refl : forall s : t, eq s s.
Parameter eq_sym : forall s s' : t, eq s s' -> eq s' s.
Parameter eq_trans : forall s s' s'' : t, eq s s' -> eq s' s'' -> eq s s''.
Parameter lt_trans : forall s s' s'' : t, lt s s' -> lt s' s'' -> lt s s''.
diff --git a/theories/FSets/FSetList.v b/theories/FSets/FSetList.v
index a205d5b0..b009e109 100644
--- a/theories/FSets/FSetList.v
+++ b/theories/FSets/FSetList.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetList.v 10616 2008-03-04 17:33:35Z letouzey $ *)
+(* $Id: FSetList.v 11866 2009-01-28 19:10:15Z letouzey $ *)
(** * Finite sets library *)
@@ -1263,6 +1263,14 @@ Module Make (X: OrderedType) <: S with Module E := X.
auto.
Defined.
+ Definition eq_dec : { eq s s' } + { ~ eq s s' }.
+ Proof.
+ change eq with Equal.
+ case_eq (equal s s'); intro H; [left | right].
+ apply equal_2; auto.
+ intro H'; rewrite equal_1 in H; auto; discriminate.
+ Defined.
+
End Spec.
End Make.
diff --git a/theories/FSets/FSetProperties.v b/theories/FSets/FSetProperties.v
index 7413b06b..8dc7fbd9 100644
--- a/theories/FSets/FSetProperties.v
+++ b/theories/FSets/FSetProperties.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetProperties.v 11064 2008-06-06 17:00:52Z letouzey $ *)
+(* $Id: FSetProperties.v 11720 2008-12-28 07:12:15Z letouzey $ *)
(** * Finite sets library *)
@@ -22,15 +22,13 @@ Set Implicit Arguments.
Unset Strict Implicit.
Hint Unfold transpose compat_op.
-Hint Extern 1 (Setoid_Theory _ _) => constructor; congruence.
+Hint Extern 1 (Equivalence _) => constructor; congruence.
-(** First, a functor for Weak Sets. Since the signature [WS] includes
- an EqualityType and not a stronger DecidableType, this functor
- should take two arguments in order to compensate this. *)
+(** First, a functor for Weak Sets in functorial version. *)
-Module WProperties (Import E : DecidableType)(M : WSfun E).
- Module Import Dec := WDecide E M.
- Module Import FM := Dec.F (* FSetFacts.WFacts E M *).
+Module WProperties_fun (Import E : DecidableType)(M : WSfun E).
+ Module Import Dec := WDecide_fun E M.
+ Module Import FM := Dec.F (* FSetFacts.WFacts_fun E M *).
Import M.
Lemma In_dec : forall x s, {In x s} + {~ In x s}.
@@ -126,6 +124,10 @@ Module WProperties (Import E : DecidableType)(M : WSfun E).
Lemma singleton_equal_add : singleton x [=] add x empty.
Proof. fsetdec. Qed.
+ Lemma remove_singleton_empty :
+ In x s -> remove x s [=] empty -> singleton x [=] s.
+ Proof. fsetdec. Qed.
+
Lemma union_sym : union s s' [=] union s' s.
Proof. fsetdec. Qed.
@@ -306,21 +308,176 @@ Module WProperties (Import E : DecidableType)(M : WSfun E).
rewrite <-elements_Empty; auto with set.
Qed.
- (** * Alternative (weaker) specifications for [fold] *)
+ (** * Conversions between lists and sets *)
+
+ Definition of_list (l : list elt) := List.fold_right add empty l.
- Section Old_Spec_Now_Properties.
+ Definition to_list := elements.
+
+ Lemma of_list_1 : forall l x, In x (of_list l) <-> InA E.eq x l.
+ Proof.
+ induction l; simpl; intro x.
+ rewrite empty_iff, InA_nil. intuition.
+ rewrite add_iff, InA_cons, IHl. intuition.
+ Qed.
+
+ Lemma of_list_2 : forall l, equivlistA E.eq (to_list (of_list l)) l.
+ Proof.
+ unfold to_list; red; intros.
+ rewrite <- elements_iff; apply of_list_1.
+ Qed.
+
+ Lemma of_list_3 : forall s, of_list (to_list s) [=] s.
+ Proof.
+ unfold to_list; red; intros.
+ rewrite of_list_1; symmetry; apply elements_iff.
+ Qed.
+
+ (** * Fold *)
+
+ Section Fold.
Notation NoDup := (NoDupA E.eq).
+ Notation InA := (InA E.eq).
+
+ (** ** Induction principles for fold (contributed by S. Lescuyer) *)
+
+ (** In the following lemma, the step hypothesis is deliberately restricted
+ to the precise set s we are considering. *)
+
+ Theorem fold_rec :
+ forall (A:Type)(P : t -> A -> Type)(f : elt -> A -> A)(i:A)(s:t),
+ (forall s', Empty s' -> P s' i) ->
+ (forall x a s' s'', In x s -> ~In x s' -> Add x s' s'' ->
+ P s' a -> P s'' (f x a)) ->
+ P s (fold f s i).
+ Proof.
+ intros A P f i s Pempty Pstep.
+ rewrite fold_1, <- fold_left_rev_right.
+ set (l:=rev (elements s)).
+ assert (Pstep' : forall x a s' s'', InA x l -> ~In x s' -> Add x s' s'' ->
+ P s' a -> P s'' (f x a)).
+ intros; eapply Pstep; eauto.
+ rewrite elements_iff, <- InA_rev; auto.
+ assert (Hdup : NoDup l) by
+ (unfold l; eauto using elements_3w, NoDupA_rev).
+ assert (Hsame : forall x, In x s <-> InA x l) by
+ (unfold l; intros; rewrite elements_iff, InA_rev; intuition).
+ clear Pstep; clearbody l; revert s Hsame; induction l.
+ (* empty *)
+ intros s Hsame; simpl.
+ apply Pempty. intro x. rewrite Hsame, InA_nil; intuition.
+ (* step *)
+ intros s Hsame; simpl.
+ apply Pstep' with (of_list l); auto.
+ inversion_clear Hdup; rewrite of_list_1; auto.
+ red. intros. rewrite Hsame, of_list_1, InA_cons; intuition.
+ apply IHl.
+ intros; eapply Pstep'; eauto.
+ inversion_clear Hdup; auto.
+ exact (of_list_1 l).
+ Qed.
+
+ (** Same, with [empty] and [add] instead of [Empty] and [Add]. In this
+ case, [P] must be compatible with equality of sets *)
+
+ Theorem fold_rec_bis :
+ forall (A:Type)(P : t -> A -> Type)(f : elt -> A -> A)(i:A)(s:t),
+ (forall s s' a, s[=]s' -> P s a -> P s' a) ->
+ (P empty i) ->
+ (forall x a s', In x s -> ~In x s' -> P s' a -> P (add x s') (f x a)) ->
+ P s (fold f s i).
+ Proof.
+ intros A P f i s Pmorphism Pempty Pstep.
+ apply fold_rec; intros.
+ apply Pmorphism with empty; auto with set.
+ rewrite Add_Equal in H1; auto with set.
+ apply Pmorphism with (add x s'); auto with set.
+ Qed.
+
+ Lemma fold_rec_nodep :
+ forall (A:Type)(P : A -> Type)(f : elt -> A -> A)(i:A)(s:t),
+ P i -> (forall x a, In x s -> P a -> P (f x a)) ->
+ P (fold f s i).
+ Proof.
+ intros; apply fold_rec_bis with (P:=fun _ => P); auto.
+ Qed.
+
+ (** [fold_rec_weak] is a weaker principle than [fold_rec_bis] :
+ the step hypothesis must here be applicable to any [x].
+ At the same time, it looks more like an induction principle,
+ and hence can be easier to use. *)
+
+ Lemma fold_rec_weak :
+ forall (A:Type)(P : t -> A -> Type)(f : elt -> A -> A)(i:A),
+ (forall s s' a, s[=]s' -> P s a -> P s' a) ->
+ P empty i ->
+ (forall x a s, ~In x s -> P s a -> P (add x s) (f x a)) ->
+ forall s, P s (fold f s i).
+ Proof.
+ intros; apply fold_rec_bis; auto.
+ Qed.
+
+ Lemma fold_rel :
+ forall (A B:Type)(R : A -> B -> Type)
+ (f : elt -> A -> A)(g : elt -> B -> B)(i : A)(j : B)(s : t),
+ R i j ->
+ (forall x a b, In x s -> R a b -> R (f x a) (g x b)) ->
+ R (fold f s i) (fold g s j).
+ Proof.
+ intros A B R f g i j s Rempty Rstep.
+ do 2 rewrite fold_1, <- fold_left_rev_right.
+ set (l:=rev (elements s)).
+ assert (Rstep' : forall x a b, InA x l -> R a b -> R (f x a) (g x b)) by
+ (intros; apply Rstep; auto; rewrite elements_iff, <- InA_rev; auto).
+ clearbody l; clear Rstep s.
+ induction l; simpl; auto.
+ Qed.
+
+ (** From the induction principle on [fold], we can deduce some general
+ induction principles on sets. *)
+
+ Lemma set_induction :
+ forall P : t -> Type,
+ (forall s, Empty s -> P s) ->
+ (forall s s', P s -> forall x, ~In x s -> Add x s s' -> P s') ->
+ forall s, P s.
+ Proof.
+ intros. apply (@fold_rec _ (fun s _ => P s) (fun _ _ => tt) tt s); eauto.
+ Qed.
+
+ Lemma set_induction_bis :
+ forall P : t -> Type,
+ (forall s s', s [=] s' -> P s -> P s') ->
+ P empty ->
+ (forall x s, ~In x s -> P s -> P (add x s)) ->
+ forall s, P s.
+ Proof.
+ intros.
+ apply (@fold_rec_bis _ (fun s _ => P s) (fun _ _ => tt) tt s); eauto.
+ Qed.
+
+ (** [fold] can be used to reconstruct the same initial set. *)
+
+ Lemma fold_identity : forall s, fold add s empty [=] s.
+ Proof.
+ intros.
+ apply fold_rec with (P:=fun s acc => acc[=]s); auto with set.
+ intros. rewrite H2; rewrite Add_Equal in H1; auto with set.
+ Qed.
+
+ (** ** Alternative (weaker) specifications for [fold] *)
(** When [FSets] was first designed, the order in which Ocaml's [Set.fold]
- takes the set elements was unspecified. This specification reflects this fact:
+ takes the set elements was unspecified. This specification reflects
+ this fact:
*)
- Lemma fold_0 :
+ Lemma fold_0 :
forall s (A : Type) (i : A) (f : elt -> A -> A),
exists l : list elt,
NoDup l /\
- (forall x : elt, In x s <-> InA E.eq x l) /\
+ (forall x : elt, In x s <-> InA x l) /\
fold f s i = fold_right f i l.
Proof.
intros; exists (rev (elements s)); split.
@@ -333,26 +490,26 @@ Module WProperties (Import E : DecidableType)(M : WSfun E).
apply fold_1.
Qed.
- (** An alternate (and previous) specification for [fold] was based on
- the recursive structure of a set. It is now lemmas [fold_1] and
+ (** An alternate (and previous) specification for [fold] was based on
+ the recursive structure of a set. It is now lemmas [fold_1] and
[fold_2]. *)
Lemma fold_1 :
- forall s (A : Type) (eqA : A -> A -> Prop)
- (st : Setoid_Theory A eqA) (i : A) (f : elt -> A -> A),
+ forall s (A : Type) (eqA : A -> A -> Prop)
+ (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
Empty s -> eqA (fold f s i) i.
Proof.
unfold Empty; intros; destruct (fold_0 s i f) as (l,(H1, (H2, H3))).
rewrite H3; clear H3.
generalize H H2; clear H H2; case l; simpl; intros.
- refl_st.
+ reflexivity.
elim (H e).
elim (H2 e); intuition.
Qed.
Lemma fold_2 :
forall s s' x (A : Type) (eqA : A -> A -> Prop)
- (st : Setoid_Theory A eqA) (i : A) (f : elt -> A -> A),
+ (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
compat_op E.eq eqA f ->
transpose eqA f ->
~ In x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i)).
@@ -379,283 +536,238 @@ Module WProperties (Import E : DecidableType)(M : WSfun E).
rewrite elements_Empty in H; rewrite H; simpl; auto.
Qed.
- (** Similar specifications for [cardinal]. *)
+ Section Fold_More.
- Lemma cardinal_fold : forall s, cardinal s = fold (fun _ => S) s 0.
- Proof.
- intros; rewrite cardinal_1; rewrite M.fold_1.
- symmetry; apply fold_left_length; auto.
- Qed.
-
- Lemma cardinal_0 :
- forall s, exists l : list elt,
- NoDupA E.eq l /\
- (forall x : elt, In x s <-> InA E.eq x l) /\
- cardinal s = length l.
- Proof.
- intros; exists (elements s); intuition; apply cardinal_1.
- Qed.
-
- Lemma cardinal_1 : forall s, Empty s -> cardinal s = 0.
- Proof.
- intros; rewrite cardinal_fold; apply fold_1; auto.
- Qed.
-
- Lemma cardinal_2 :
- forall s s' x, ~ In x s -> Add x s s' -> cardinal s' = S (cardinal s).
- Proof.
- intros; do 2 rewrite cardinal_fold.
- change S with ((fun _ => S) x).
- apply fold_2; auto.
- Qed.
-
- End Old_Spec_Now_Properties.
-
- (** * Induction principle over sets *)
+ Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA).
+ Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f)(Ass:transpose eqA f).
- Lemma cardinal_Empty : forall s, Empty s <-> cardinal s = 0.
+ Lemma fold_commutes : forall i s x,
+ eqA (fold f s (f x i)) (f x (fold f s i)).
Proof.
intros.
- rewrite elements_Empty, M.cardinal_1.
- destruct (elements s); intuition; discriminate.
- Qed.
-
- Lemma cardinal_inv_1 : forall s, cardinal s = 0 -> Empty s.
- Proof.
- intros; rewrite cardinal_Empty; auto.
- Qed.
- Hint Resolve cardinal_inv_1.
-
- Lemma cardinal_inv_2 :
- forall s n, cardinal s = S n -> { x : elt | In x s }.
- Proof.
- intros; rewrite M.cardinal_1 in H.
- generalize (elements_2 (s:=s)).
- destruct (elements s); try discriminate.
- exists e; auto.
- Qed.
-
- Lemma cardinal_inv_2b :
- forall s, cardinal s <> 0 -> { x : elt | In x s }.
- Proof.
- intro; generalize (@cardinal_inv_2 s); destruct cardinal;
- [intuition|eauto].
- Qed.
-
- Lemma Equal_cardinal : forall s s', s[=]s' -> cardinal s = cardinal s'.
- Proof.
- symmetry.
- remember (cardinal s) as n; symmetry in Heqn; revert s s' Heqn H.
- induction n; intros.
- apply cardinal_1; rewrite <- H; auto.
- destruct (cardinal_inv_2 Heqn) as (x,H2).
- revert Heqn.
- rewrite (cardinal_2 (s:=remove x s) (s':=s) (x:=x)); auto with set.
- rewrite (cardinal_2 (s:=remove x s') (s':=s') (x:=x)); eauto with set.
- Qed.
-
- Add Morphism cardinal : cardinal_m.
- Proof.
- exact Equal_cardinal.
+ apply fold_rel with (R:=fun u v => eqA u (f x v)); intros.
+ reflexivity.
+ transitivity (f x0 (f x b)); auto.
Qed.
- Hint Resolve Add_add Add_remove Equal_remove cardinal_inv_1 Equal_cardinal.
+ (** ** Fold is a morphism *)
- Lemma set_induction :
- forall P : t -> Type,
- (forall s : t, Empty s -> P s) ->
- (forall s s' : t, P s -> forall x : elt, ~In x s -> Add x s s' -> P s') ->
- forall s : t, P s.
+ Lemma fold_init : forall i i' s, eqA i i' ->
+ eqA (fold f s i) (fold f s i').
Proof.
- intros; remember (cardinal s) as n; revert s Heqn; induction n; intros; auto.
- destruct (cardinal_inv_2 (sym_eq Heqn)) as (x,H0).
- apply X0 with (remove x s) x; auto with set.
- apply IHn; auto.
- assert (S n = S (cardinal (remove x s))).
- rewrite Heqn; apply cardinal_2 with x; auto with set.
- inversion H; auto.
- Qed.
-
- (** Other properties of [fold]. *)
-
- Section Fold.
- Variables (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory _ eqA).
- Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f)(Ass:transpose eqA f).
-
- Section Fold_1.
- Variable i i':A.
-
- Lemma fold_empty : (fold f empty i) = i.
- Proof.
- apply fold_1b; auto with set.
+ intros. apply fold_rel with (R:=eqA); auto.
Qed.
Lemma fold_equal :
- forall s s', s[=]s' -> eqA (fold f s i) (fold f s' i).
+ forall i s s', s[=]s' -> eqA (fold f s i) (fold f s' i).
Proof.
- intros s; pattern s; apply set_induction; clear s; intros.
- trans_st i.
+ intros i s; pattern s; apply set_induction; clear s; intros.
+ transitivity i.
apply fold_1; auto.
- sym_st; apply fold_1; auto.
+ symmetry; apply fold_1; auto.
rewrite <- H0; auto.
- trans_st (f x (fold f s i)).
+ transitivity (f x (fold f s i)).
apply fold_2 with (eqA := eqA); auto.
- sym_st; apply fold_2 with (eqA := eqA); auto.
+ symmetry; apply fold_2 with (eqA := eqA); auto.
unfold Add in *; intros.
rewrite <- H2; auto.
Qed.
-
- Lemma fold_add : forall s x, ~In x s ->
+
+ (** ** Fold and other set operators *)
+
+ Lemma fold_empty : forall i, fold f empty i = i.
+ Proof.
+ intros i; apply fold_1b; auto with set.
+ Qed.
+
+ Lemma fold_add : forall i s x, ~In x s ->
eqA (fold f (add x s) i) (f x (fold f s i)).
Proof.
- intros; apply fold_2 with (eqA := eqA); auto.
+ intros; apply fold_2 with (eqA := eqA); auto with set.
Qed.
- Lemma add_fold : forall s x, In x s ->
+ Lemma add_fold : forall i s x, In x s ->
eqA (fold f (add x s) i) (fold f s i).
Proof.
intros; apply fold_equal; auto with set.
Qed.
- Lemma remove_fold_1: forall s x, In x s ->
+ Lemma remove_fold_1: forall i s x, In x s ->
eqA (f x (fold f (remove x s) i)) (fold f s i).
Proof.
intros.
- sym_st.
+ symmetry.
apply fold_2 with (eqA:=eqA); auto with set.
Qed.
- Lemma remove_fold_2: forall s x, ~In x s ->
+ Lemma remove_fold_2: forall i s x, ~In x s ->
eqA (fold f (remove x s) i) (fold f s i).
Proof.
intros.
apply fold_equal; auto with set.
Qed.
- Lemma fold_commutes : forall s x,
- eqA (fold f s (f x i)) (f x (fold f s i)).
- Proof.
- intros; pattern s; apply set_induction; clear s; intros.
- trans_st (f x i).
- apply fold_1; auto.
- sym_st.
- apply Comp; auto.
- apply fold_1; auto.
- trans_st (f x0 (fold f s (f x i))).
- apply fold_2 with (eqA:=eqA); auto.
- trans_st (f x0 (f x (fold f s i))).
- trans_st (f x (f x0 (fold f s i))).
- apply Comp; auto.
- sym_st.
- apply fold_2 with (eqA:=eqA); auto.
- Qed.
-
- Lemma fold_init : forall s, eqA i i' ->
- eqA (fold f s i) (fold f s i').
- Proof.
- intros; pattern s; apply set_induction; clear s; intros.
- trans_st i.
- apply fold_1; auto.
- trans_st i'.
- sym_st; apply fold_1; auto.
- trans_st (f x (fold f s i)).
- apply fold_2 with (eqA:=eqA); auto.
- trans_st (f x (fold f s i')).
- sym_st; apply fold_2 with (eqA:=eqA); auto.
- Qed.
-
- End Fold_1.
- Section Fold_2.
- Variable i:A.
-
- Lemma fold_union_inter : forall s s',
+ Lemma fold_union_inter : forall i s s',
eqA (fold f (union s s') (fold f (inter s s') i))
(fold f s (fold f s' i)).
Proof.
intros; pattern s; apply set_induction; clear s; intros.
- trans_st (fold f s' (fold f (inter s s') i)).
+ transitivity (fold f s' (fold f (inter s s') i)).
apply fold_equal; auto with set.
- trans_st (fold f s' i).
+ transitivity (fold f s' i).
apply fold_init; auto.
apply fold_1; auto with set.
- sym_st; apply fold_1; auto.
+ symmetry; apply fold_1; auto.
rename s'0 into s''.
destruct (In_dec x s').
(* In x s' *)
- trans_st (fold f (union s'' s') (f x (fold f (inter s s') i))); auto with set.
+ transitivity (fold f (union s'' s') (f x (fold f (inter s s') i))); auto with set.
apply fold_init; auto.
apply fold_2 with (eqA:=eqA); auto with set.
rewrite inter_iff; intuition.
- trans_st (f x (fold f s (fold f s' i))).
- trans_st (fold f (union s s') (f x (fold f (inter s s') i))).
+ transitivity (f x (fold f s (fold f s' i))).
+ transitivity (fold f (union s s') (f x (fold f (inter s s') i))).
apply fold_equal; auto.
apply equal_sym; apply union_Equal with x; auto with set.
- trans_st (f x (fold f (union s s') (fold f (inter s s') i))).
+ transitivity (f x (fold f (union s s') (fold f (inter s s') i))).
apply fold_commutes; auto.
- sym_st; apply fold_2 with (eqA:=eqA); auto.
+ apply Comp; auto.
+ symmetry; apply fold_2 with (eqA:=eqA); auto.
(* ~(In x s') *)
- trans_st (f x (fold f (union s s') (fold f (inter s'' s') i))).
+ transitivity (f x (fold f (union s s') (fold f (inter s'' s') i))).
apply fold_2 with (eqA:=eqA); auto with set.
- trans_st (f x (fold f (union s s') (fold f (inter s s') i))).
+ transitivity (f x (fold f (union s s') (fold f (inter s s') i))).
apply Comp;auto.
apply fold_init;auto.
apply fold_equal;auto.
apply equal_sym; apply inter_Add_2 with x; auto with set.
- trans_st (f x (fold f s (fold f s' i))).
- sym_st; apply fold_2 with (eqA:=eqA); auto.
+ transitivity (f x (fold f s (fold f s' i))).
+ apply Comp; auto.
+ symmetry; apply fold_2 with (eqA:=eqA); auto.
Qed.
- End Fold_2.
- Section Fold_3.
- Variable i:A.
-
- Lemma fold_diff_inter : forall s s',
+ Lemma fold_diff_inter : forall i s s',
eqA (fold f (diff s s') (fold f (inter s s') i)) (fold f s i).
Proof.
intros.
- trans_st (fold f (union (diff s s') (inter s s'))
- (fold f (inter (diff s s') (inter s s')) i)).
- sym_st; apply fold_union_inter; auto.
- trans_st (fold f s (fold f (inter (diff s s') (inter s s')) i)).
+ transitivity (fold f (union (diff s s') (inter s s'))
+ (fold f (inter (diff s s') (inter s s')) i)).
+ symmetry; apply fold_union_inter; auto.
+ transitivity (fold f s (fold f (inter (diff s s') (inter s s')) i)).
apply fold_equal; auto with set.
apply fold_init; auto.
apply fold_1; auto with set.
Qed.
- Lemma fold_union: forall s s',
+ Lemma fold_union: forall i s s',
(forall x, ~(In x s/\In x s')) ->
eqA (fold f (union s s') i) (fold f s (fold f s' i)).
Proof.
intros.
- trans_st (fold f (union s s') (fold f (inter s s') i)).
+ transitivity (fold f (union s s') (fold f (inter s s') i)).
apply fold_init; auto.
- sym_st; apply fold_1; auto with set.
+ symmetry; apply fold_1; auto with set.
unfold Empty; intro a; generalize (H a); set_iff; tauto.
apply fold_union_inter; auto.
Qed.
- End Fold_3.
- End Fold.
+ End Fold_More.
Lemma fold_plus :
forall s p, fold (fun _ => S) s p = fold (fun _ => S) s 0 + p.
Proof.
- assert (st := gen_st nat).
- assert (fe : compat_op E.eq (@Logic.eq _) (fun _ => S)) by (unfold compat_op; auto).
- assert (fp : transpose (@Logic.eq _) (fun _:elt => S)) by (unfold transpose; auto).
- intros s p; pattern s; apply set_induction; clear s; intros.
- rewrite (fold_1 st p (fun _ => S) H).
- rewrite (fold_1 st 0 (fun _ => S) H); trivial.
- assert (forall p s', Add x s s' -> fold (fun _ => S) s' p = S (fold (fun _ => S) s p)).
- change S with ((fun _ => S) x).
- intros; apply fold_2; auto.
- rewrite H2; auto.
- rewrite (H2 0); auto.
- rewrite H.
- simpl; auto.
- Qed.
-
- (** more properties of [cardinal] *)
+ intros. apply fold_rel with (R:=fun u v => u = v + p); simpl; auto.
+ Qed.
+
+ End Fold.
+
+ (** * Cardinal *)
+
+ (** ** Characterization of cardinal in terms of fold *)
+
+ Lemma cardinal_fold : forall s, cardinal s = fold (fun _ => S) s 0.
+ Proof.
+ intros; rewrite cardinal_1; rewrite M.fold_1.
+ symmetry; apply fold_left_length; auto.
+ Qed.
+
+ (** ** Old specifications for [cardinal]. *)
+
+ Lemma cardinal_0 :
+ forall s, exists l : list elt,
+ NoDupA E.eq l /\
+ (forall x : elt, In x s <-> InA E.eq x l) /\
+ cardinal s = length l.
+ Proof.
+ intros; exists (elements s); intuition; apply cardinal_1.
+ Qed.
+
+ Lemma cardinal_1 : forall s, Empty s -> cardinal s = 0.
+ Proof.
+ intros; rewrite cardinal_fold; apply fold_1; auto.
+ Qed.
+
+ Lemma cardinal_2 :
+ forall s s' x, ~ In x s -> Add x s s' -> cardinal s' = S (cardinal s).
+ Proof.
+ intros; do 2 rewrite cardinal_fold.
+ change S with ((fun _ => S) x).
+ apply fold_2; auto.
+ Qed.
+
+ (** ** Cardinal and (non-)emptiness *)
+
+ Lemma cardinal_Empty : forall s, Empty s <-> cardinal s = 0.
+ Proof.
+ intros.
+ rewrite elements_Empty, M.cardinal_1.
+ destruct (elements s); intuition; discriminate.
+ Qed.
+
+ Lemma cardinal_inv_1 : forall s, cardinal s = 0 -> Empty s.
+ Proof.
+ intros; rewrite cardinal_Empty; auto.
+ Qed.
+ Hint Resolve cardinal_inv_1.
+
+ Lemma cardinal_inv_2 :
+ forall s n, cardinal s = S n -> { x : elt | In x s }.
+ Proof.
+ intros; rewrite M.cardinal_1 in H.
+ generalize (elements_2 (s:=s)).
+ destruct (elements s); try discriminate.
+ exists e; auto.
+ Qed.
+
+ Lemma cardinal_inv_2b :
+ forall s, cardinal s <> 0 -> { x : elt | In x s }.
+ Proof.
+ intro; generalize (@cardinal_inv_2 s); destruct cardinal;
+ [intuition|eauto].
+ Qed.
+
+ (** ** Cardinal is a morphism *)
+
+ Lemma Equal_cardinal : forall s s', s[=]s' -> cardinal s = cardinal s'.
+ Proof.
+ symmetry.
+ remember (cardinal s) as n; symmetry in Heqn; revert s s' Heqn H.
+ induction n; intros.
+ apply cardinal_1; rewrite <- H; auto.
+ destruct (cardinal_inv_2 Heqn) as (x,H2).
+ revert Heqn.
+ rewrite (cardinal_2 (s:=remove x s) (s':=s) (x:=x)); auto with set.
+ rewrite (cardinal_2 (s:=remove x s') (s':=s') (x:=x)); eauto with set.
+ Qed.
+
+ Add Morphism cardinal : cardinal_m.
+ Proof.
+ exact Equal_cardinal.
+ Qed.
+
+ Hint Resolve Add_add Add_remove Equal_remove cardinal_inv_1 Equal_cardinal.
+
+ (** ** Cardinal and set operators *)
Lemma empty_cardinal : cardinal empty = 0.
Proof.
@@ -773,18 +885,18 @@ Module WProperties (Import E : DecidableType)(M : WSfun E).
Hint Resolve subset_cardinal union_cardinal add_cardinal_1 add_cardinal_2.
-End WProperties.
+End WProperties_fun.
+(** Now comes variants for self-contained weak sets and for full sets.
+ For these variants, only one argument is necessary. Thanks to
+ the subtyping [WS<=S], the [Properties] functor which is meant to be
+ used on modules [(M:S)] can simply be an alias of [WProperties]. *)
-(** A clone of [WProperties] working on full sets. *)
+Module WProperties (M:WS) := WProperties_fun M.E M.
+Module Properties := WProperties.
-Module Properties (M:S).
- Module D := OT_as_DT M.E.
- Include WProperties D M.
-End Properties.
-
-(** Now comes some properties specific to the element ordering,
+(** Now comes some properties specific to the element ordering,
invalid for Weak Sets. *)
Module OrdProperties (M:S).
@@ -973,7 +1085,7 @@ Module OrdProperties (M:S).
Lemma fold_3 :
forall s s' x (A : Type) (eqA : A -> A -> Prop)
- (st : Setoid_Theory A eqA) (i : A) (f : elt -> A -> A),
+ (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
compat_op E.eq eqA f ->
Above x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i)).
Proof.
@@ -990,7 +1102,7 @@ Module OrdProperties (M:S).
Lemma fold_4 :
forall s s' x (A : Type) (eqA : A -> A -> Prop)
- (st : Setoid_Theory A eqA) (i : A) (f : elt -> A -> A),
+ (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
compat_op E.eq eqA f ->
Below x s -> Add x s s' -> eqA (fold f s' i) (fold f s (f x i)).
Proof.
@@ -1010,7 +1122,7 @@ Module OrdProperties (M:S).
no need for [(transpose eqA f)]. *)
Section FoldOpt.
- Variables (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory _ eqA).
+ Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA).
Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f).
Lemma fold_equal :
@@ -1024,14 +1136,6 @@ Module OrdProperties (M:S).
red; intro a; do 2 rewrite <- elements_iff; auto.
Qed.
- Lemma fold_init : forall i i' s, eqA i i' ->
- eqA (fold f s i) (fold f s i').
- Proof.
- intros; do 2 rewrite M.fold_1.
- do 2 rewrite <- fold_left_rev_right.
- induction (rev (elements s)); simpl; auto.
- Qed.
-
Lemma add_fold : forall i s x, In x s ->
eqA (fold f (add x s) i) (fold f s i).
Proof.
diff --git a/theories/FSets/FSetToFiniteSet.v b/theories/FSets/FSetToFiniteSet.v
index ae51d905..56a66261 100644
--- a/theories/FSets/FSetToFiniteSet.v
+++ b/theories/FSets/FSetToFiniteSet.v
@@ -11,7 +11,7 @@
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
* 91405 Orsay, France *)
-(* $Id: FSetToFiniteSet.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: FSetToFiniteSet.v 11735 2009-01-02 17:22:31Z herbelin $ *)
Require Import Ensembles Finite_sets.
Require Import FSetInterface FSetProperties OrderedTypeEx DecidableTypeEx.
@@ -20,7 +20,7 @@ Require Import FSetInterface FSetProperties OrderedTypeEx DecidableTypeEx.
to the good old [Ensembles] and [Finite_sets] theory. *)
Module WS_to_Finite_set (U:UsualDecidableType)(M: WSfun U).
- Module MP:= WProperties U M.
+ Module MP:= WProperties_fun U M.
Import M MP FM Ensembles Finite_sets.
Definition mkEns : M.t -> Ensemble M.elt :=
@@ -30,7 +30,7 @@ Module WS_to_Finite_set (U:UsualDecidableType)(M: WSfun U).
Lemma In_In : forall s x, M.In x s <-> In _ (!!s) x.
Proof.
- unfold In; compute; auto.
+ unfold In; compute; auto with extcore.
Qed.
Lemma Subset_Included : forall s s', s[<=]s' <-> Included _ (!!s) (!!s').
@@ -155,9 +155,7 @@ Module WS_to_Finite_set (U:UsualDecidableType)(M: WSfun U).
End WS_to_Finite_set.
-Module S_to_Finite_set (U:UsualOrderedType)(M: Sfun U).
- Module D := OT_as_DT U.
- Include WS_to_Finite_set D M.
-End S_to_Finite_set.
+Module S_to_Finite_set (U:UsualOrderedType)(M: Sfun U) :=
+ WS_to_Finite_set U M.
diff --git a/theories/FSets/FSetWeakList.v b/theories/FSets/FSetWeakList.v
index 71a0d584..309016ce 100644
--- a/theories/FSets/FSetWeakList.v
+++ b/theories/FSets/FSetWeakList.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: FSetWeakList.v 10631 2008-03-06 18:17:24Z msozeau $ *)
+(* $Id: FSetWeakList.v 11866 2009-01-28 19:10:15Z letouzey $ *)
(** * Finite sets library *)
@@ -746,53 +746,12 @@ Module Raw (X: DecidableType).
Definition eq_dec : forall (s s':t)(Hs:NoDup s)(Hs':NoDup s'),
{ eq s s' }+{ ~eq s s' }.
Proof.
- unfold eq.
- induction s; intros s'.
- (* nil *)
- destruct s'; [left|right].
- firstorder.
- unfold not, Equal.
- intros H; generalize (H e); clear H.
- rewrite InA_nil, InA_cons; intuition.
- (* cons *)
- intros.
- case_eq (mem a s'); intros H;
- [ destruct (IHs (remove a s')) as [H'|H'];
- [ | | left|right]|right];
- clear IHs.
- inversion_clear Hs; auto.
- apply remove_unique; auto.
- (* In a s' /\ s [=] remove a s' *)
- generalize (mem_2 H); clear H; intro H.
- unfold Equal in *; intros b.
- rewrite InA_cons; split.
- destruct 1.
- apply In_eq with a; auto.
- rewrite H' in H0.
- apply remove_3 with a; auto.
- destruct (X.eq_dec b a); [left|right]; auto.
- rewrite H'.
- apply remove_2; auto.
- (* In a s' /\ ~ s [=] remove a s' *)
- generalize (mem_2 H); clear H; intro H.
- contradict H'.
- unfold Equal in *; intros b.
- split; intros.
- apply remove_2; auto.
- inversion_clear Hs.
- contradict H1; apply In_eq with b; auto.
- rewrite <- H'; rewrite InA_cons; auto.
- assert (In b s') by (apply remove_3 with a; auto).
- rewrite <- H', InA_cons in H1; destruct H1; auto.
- elim (remove_1 Hs' (X.eq_sym H1) H0).
- (* ~ In a s' *)
- assert (~In a s').
- red; intro H'; rewrite (mem_1 H') in H; discriminate.
- contradict H0.
- unfold Equal in *.
- rewrite <- H0.
- rewrite InA_cons; auto.
- Qed.
+ intros.
+ change eq with Equal.
+ case_eq (equal s s'); intro H; [left | right].
+ apply equal_2; auto.
+ intro H'; rewrite equal_1 in H; auto; discriminate.
+ Defined.
End ForNotations.
End Raw.
@@ -993,6 +952,6 @@ Module Make (X: DecidableType) <: WS with Module E := X.
{ eq s s' }+{ ~eq s s' }.
Proof.
intros s s'; exact (Raw.eq_dec s.(unique) s'.(unique)).
- Qed.
+ Defined.
End Make.
diff --git a/theories/FSets/OrderedType.v b/theories/FSets/OrderedType.v
index c56a24cf..fadd27dd 100644
--- a/theories/FSets/OrderedType.v
+++ b/theories/FSets/OrderedType.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: OrderedType.v 10616 2008-03-04 17:33:35Z letouzey $ *)
+(* $Id: OrderedType.v 11700 2008-12-18 11:49:10Z letouzey $ *)
Require Export SetoidList.
Set Implicit Arguments.
@@ -19,7 +19,7 @@ Inductive Compare (X : Type) (lt eq : X -> X -> Prop) (x y : X) : Type :=
| EQ : eq x y -> Compare lt eq x y
| GT : lt y x -> Compare lt eq x y.
-Module Type OrderedType.
+Module Type MiniOrderedType.
Parameter Inline t : Type.
@@ -29,7 +29,7 @@ Module Type OrderedType.
Axiom eq_refl : forall x : t, eq x x.
Axiom eq_sym : forall x y : t, eq x y -> eq y x.
Axiom eq_trans : forall x y z : t, eq x y -> eq y z -> eq x z.
-
+
Axiom lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z.
Axiom lt_not_eq : forall x y : t, lt x y -> ~ eq x y.
@@ -38,15 +38,34 @@ Module Type OrderedType.
Hint Immediate eq_sym.
Hint Resolve eq_refl eq_trans lt_not_eq lt_trans.
+End MiniOrderedType.
+
+Module Type OrderedType.
+ Include Type MiniOrderedType.
+
+ (** A [eq_dec] can be deduced from [compare] below. But adding this
+ redundant field allows to see an OrderedType as a DecidableType. *)
+ Parameter eq_dec : forall x y, { eq x y } + { ~ eq x y }.
+
End OrderedType.
+Module MOT_to_OT (Import O : MiniOrderedType) <: OrderedType.
+ Include O.
+
+ Definition eq_dec : forall x y : t, {eq x y} + {~ eq x y}.
+ Proof.
+ intros; elim (compare x y); intro H; [ right | left | right ]; auto.
+ assert (~ eq y x); auto.
+ Defined.
+
+End MOT_to_OT.
+
(** * Ordered types properties *)
(** Additional properties that can be derived from signature
[OrderedType]. *)
-Module OrderedTypeFacts (O: OrderedType).
- Import O.
+Module OrderedTypeFacts (Import O: OrderedType).
Lemma lt_antirefl : forall x, ~ lt x x.
Proof.
@@ -293,10 +312,8 @@ Ltac false_order := elimtype False; order.
elim (elim_compare_gt (x:=x) (y:=y));
[ intros _1 _2; rewrite _2; clear _1 _2 | auto ].
- Lemma eq_dec : forall x y : t, {eq x y} + {~ eq x y}.
- Proof.
- intros; elim (compare x y); [ right | left | right ]; auto.
- Defined.
+ (** For compatibility reasons *)
+ Definition eq_dec := eq_dec.
Lemma lt_dec : forall x y : t, {lt x y} + {~ lt x y}.
Proof.
diff --git a/theories/FSets/OrderedTypeAlt.v b/theories/FSets/OrderedTypeAlt.v
index 516df0f0..9d179995 100644
--- a/theories/FSets/OrderedTypeAlt.v
+++ b/theories/FSets/OrderedTypeAlt.v
@@ -11,11 +11,12 @@
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
* 91405 Orsay, France *)
-(* $Id: OrderedTypeAlt.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: OrderedTypeAlt.v 11699 2008-12-18 11:49:08Z letouzey $ *)
Require Import OrderedType.
-(** * An alternative (but equivalent) presentation for an Ordered Type inferface. *)
+(** * An alternative (but equivalent) presentation for an Ordered Type
+ inferface. *)
(** NB: [comparison], defined in [Datatypes.v] is [Eq|Lt|Gt]
whereas [compare], defined in [OrderedType.v] is [EQ _ | LT _ | GT _ ]
@@ -81,6 +82,12 @@ Module OrderedType_from_Alt (O:OrderedTypeAlt) <: OrderedType.
rewrite compare_sym; rewrite H; auto.
Defined.
+ Definition eq_dec : forall x y, { eq x y } + { ~ eq x y }.
+ Proof.
+ intros; unfold eq.
+ case (x ?= y); [ left | right | right ]; auto; discriminate.
+ Defined.
+
End OrderedType_from_Alt.
(** From the original presentation to this alternative one. *)
diff --git a/theories/FSets/OrderedTypeEx.v b/theories/FSets/OrderedTypeEx.v
index 03171396..03e3ab83 100644
--- a/theories/FSets/OrderedTypeEx.v
+++ b/theories/FSets/OrderedTypeEx.v
@@ -11,7 +11,7 @@
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
* 91405 Orsay, France *)
-(* $Id: OrderedTypeEx.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: OrderedTypeEx.v 11699 2008-12-18 11:49:08Z letouzey $ *)
Require Import OrderedType.
Require Import ZArith.
@@ -34,6 +34,7 @@ Module Type UsualOrderedType.
Axiom lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z.
Axiom lt_not_eq : forall x y : t, lt x y -> ~ eq x y.
Parameter compare : forall x y : t, Compare lt eq x y.
+ Parameter eq_dec : forall x y : t, { eq x y } + { ~ eq x y }.
End UsualOrderedType.
(** a [UsualOrderedType] is in particular an [OrderedType]. *)
@@ -68,6 +69,8 @@ Module Nat_as_OT <: UsualOrderedType.
intro; constructor 3; auto.
Defined.
+ Definition eq_dec := eq_nat_dec.
+
End Nat_as_OT.
@@ -99,6 +102,8 @@ Module Z_as_OT <: UsualOrderedType.
apply GT; unfold lt, Zlt; rewrite <- Zcompare_Gt_Lt_antisym; auto.
Defined.
+ Definition eq_dec := Z_eq_dec.
+
End Z_as_OT.
(** [positive] is an ordered type with respect to the usual order on natural numbers. *)
@@ -140,6 +145,11 @@ Module Positive_as_OT <: UsualOrderedType.
rewrite <- Pcompare_antisym; rewrite H; auto.
Defined.
+ Definition eq_dec : forall x y, { eq x y } + { ~ eq x y }.
+ Proof.
+ intros; unfold eq; decide equality.
+ Defined.
+
End Positive_as_OT.
@@ -183,6 +193,11 @@ Module N_as_OT <: UsualOrderedType.
destruct (Nleb x y); intuition.
Defined.
+ Definition eq_dec : forall x y, { eq x y } + { ~ eq x y }.
+ Proof.
+ intros. unfold eq. decide equality. apply Positive_as_OT.eq_dec.
+ Defined.
+
End N_as_OT.
@@ -243,5 +258,12 @@ Module PairOrderedType(O1 O2:OrderedType) <: OrderedType.
apply GT; unfold lt; auto.
Defined.
+ Definition eq_dec : forall x y : t, {eq x y} + {~ eq x y}.
+ Proof.
+ intros; elim (compare x y); intro H; [ right | left | right ]; auto.
+ auto using lt_not_eq.
+ assert (~ eq y x); auto using lt_not_eq, eq_sym.
+ Defined.
+
End PairOrderedType.
diff --git a/theories/Init/Datatypes.v b/theories/Init/Datatypes.v
index e5e6fd23..0163c01c 100644
--- a/theories/Init/Datatypes.v
+++ b/theories/Init/Datatypes.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Datatypes.v 11073 2008-06-08 20:24:51Z herbelin $ i*)
+(*i $Id: Datatypes.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
Set Implicit Arguments.
@@ -59,19 +59,39 @@ Lemma andb_prop : forall a b:bool, andb a b = true -> a = true /\ b = true.
Proof.
destruct a; destruct b; intros; split; try (reflexivity || discriminate).
Qed.
-Hint Resolve andb_prop: bool v62.
+Hint Resolve andb_prop: bool.
Lemma andb_true_intro :
forall b1 b2:bool, b1 = true /\ b2 = true -> andb b1 b2 = true.
Proof.
destruct b1; destruct b2; simpl in |- *; tauto || auto with bool.
Qed.
-Hint Resolve andb_true_intro: bool v62.
+Hint Resolve andb_true_intro: bool.
(** Interpretation of booleans as propositions *)
Inductive eq_true : bool -> Prop := is_eq_true : eq_true true.
+(** Additional rewriting lemmas about [eq_true] *)
+
+Lemma eq_true_ind_r :
+ forall (P : bool -> Prop) (b : bool), P b -> eq_true b -> P true.
+Proof.
+ intros P b H H0; destruct H0 in H; assumption.
+Defined.
+
+Lemma eq_true_rec_r :
+ forall (P : bool -> Set) (b : bool), P b -> eq_true b -> P true.
+Proof.
+ intros P b H H0; destruct H0 in H; assumption.
+Defined.
+
+Lemma eq_true_rect_r :
+ forall (P : bool -> Type) (b : bool), P b -> eq_true b -> P true.
+Proof.
+ intros P b H H0; destruct H0 in H; assumption.
+Defined.
+
(** [nat] is the datatype of natural numbers built from [O] and successor [S];
note that the constructor name is the letter O.
Numbers in [nat] can be denoted using a decimal notation;
@@ -95,7 +115,7 @@ Inductive Empty_set : Set :=.
Inductive identity (A:Type) (a:A) : A -> Type :=
refl_identity : identity (A:=A) a a.
-Hint Resolve refl_identity: core v62.
+Hint Resolve refl_identity: core.
Implicit Arguments identity_ind [A].
Implicit Arguments identity_rec [A].
@@ -144,7 +164,7 @@ Section projections.
end.
End projections.
-Hint Resolve pair inl inr: core v62.
+Hint Resolve pair inl inr: core.
Lemma surjective_pairing :
forall (A B:Type) (p:A * B), p = pair (fst p) (snd p).
diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v
index 6a636ccc..ae79744f 100644
--- a/theories/Init/Logic.v
+++ b/theories/Init/Logic.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Logic.v 10304 2007-11-08 17:06:32Z emakarov $ i*)
+(*i $Id: Logic.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
Set Implicit Arguments.
@@ -150,6 +150,16 @@ Proof.
intros; tauto.
Qed.
+Lemma iff_and : forall A B : Prop, (A <-> B) -> (A -> B) /\ (B -> A).
+Proof.
+intros A B []; split; trivial.
+Qed.
+
+Lemma iff_to_and : forall A B : Prop, (A <-> B) <-> (A -> B) /\ (B -> A).
+Proof.
+intros; tauto.
+Qed.
+
(** [(IF_then_else P Q R)], written [IF P then Q else R] denotes
either [P] and [Q], or [~P] and [Q] *)
@@ -245,8 +255,8 @@ Implicit Arguments eq_ind [A].
Implicit Arguments eq_rec [A].
Implicit Arguments eq_rect [A].
-Hint Resolve I conj or_introl or_intror refl_equal: core v62.
-Hint Resolve ex_intro ex_intro2: core v62.
+Hint Resolve I conj or_introl or_intror refl_equal: core.
+Hint Resolve ex_intro ex_intro2: core.
Section Logic_lemmas.
@@ -339,7 +349,7 @@ Proof.
destruct 1; destruct 1; destruct 1; destruct 1; destruct 1; reflexivity.
Qed.
-Hint Immediate sym_eq sym_not_eq: core v62.
+Hint Immediate sym_eq sym_not_eq: core.
(** Basic definitions about relations and properties *)
diff --git a/theories/Init/Peano.v b/theories/Init/Peano.v
index 9ef63cc8..43b1f634 100644
--- a/theories/Init/Peano.v
+++ b/theories/Init/Peano.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Peano.v 11115 2008-06-12 16:03:32Z werner $ i*)
+(*i $Id: Peano.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
(** The type [nat] of Peano natural numbers (built from [O] and [S])
is defined in [Datatypes.v] *)
@@ -47,7 +47,7 @@ Hint Resolve (f_equal pred): v62.
Theorem pred_Sn : forall n:nat, n = pred (S n).
Proof.
- simpl; reflexivity.
+ simpl; reflexivity.
Qed.
(** Injectivity of successor *)
@@ -59,13 +59,13 @@ Proof.
rewrite Sn_eq_Sm; trivial.
Qed.
-Hint Immediate eq_add_S: core v62.
+Hint Immediate eq_add_S: core.
Theorem not_eq_S : forall n m:nat, n <> m -> S n <> S m.
Proof.
red in |- *; auto.
Qed.
-Hint Resolve not_eq_S: core v62.
+Hint Resolve not_eq_S: core.
Definition IsSucc (n:nat) : Prop :=
match n with
@@ -80,13 +80,13 @@ Proof.
unfold not; intros n H.
inversion H.
Qed.
-Hint Resolve O_S: core v62.
+Hint Resolve O_S: core.
Theorem n_Sn : forall n:nat, n <> S n.
Proof.
induction n; auto.
Qed.
-Hint Resolve n_Sn: core v62.
+Hint Resolve n_Sn: core.
(** Addition *)
@@ -105,7 +105,7 @@ Lemma plus_n_O : forall n:nat, n = n + 0.
Proof.
induction n; simpl in |- *; auto.
Qed.
-Hint Resolve plus_n_O: core v62.
+Hint Resolve plus_n_O: core.
Lemma plus_O_n : forall n:nat, 0 + n = n.
Proof.
@@ -116,7 +116,7 @@ Lemma plus_n_Sm : forall n m:nat, S (n + m) = n + S m.
Proof.
intros n m; induction n; simpl in |- *; auto.
Qed.
-Hint Resolve plus_n_Sm: core v62.
+Hint Resolve plus_n_Sm: core.
Lemma plus_Sn_m : forall n m:nat, S n + m = S (n + m).
Proof.
@@ -138,13 +138,13 @@ Fixpoint mult (n m:nat) {struct n} : nat :=
where "n * m" := (mult n m) : nat_scope.
-Hint Resolve (f_equal2 mult): core v62.
+Hint Resolve (f_equal2 mult): core.
Lemma mult_n_O : forall n:nat, 0 = n * 0.
Proof.
induction n; simpl in |- *; auto.
Qed.
-Hint Resolve mult_n_O: core v62.
+Hint Resolve mult_n_O: core.
Lemma mult_n_Sm : forall n m:nat, n * m + n = n * S m.
Proof.
@@ -152,7 +152,7 @@ Proof.
destruct H; rewrite <- plus_n_Sm; apply (f_equal S).
pattern m at 1 3 in |- *; elim m; simpl in |- *; auto.
Qed.
-Hint Resolve mult_n_Sm: core v62.
+Hint Resolve mult_n_Sm: core.
(** Standard associated names *)
@@ -165,16 +165,12 @@ Fixpoint minus (n m:nat) {struct n} : nat :=
match n, m with
| O, _ => n
| S k, O => n
-(*=======
-
- | O, _ => n
- | S k, O => S k *)
| S k, S l => k - l
end
where "n - m" := (minus n m) : nat_scope.
-(** Definition of the usual orders, the basic properties of [le] and [lt]
+(** Definition of the usual orders, the basic properties of [le] and [lt]
can be found in files Le and Lt *)
Inductive le (n:nat) : nat -> Prop :=
@@ -183,21 +179,21 @@ Inductive le (n:nat) : nat -> Prop :=
where "n <= m" := (le n m) : nat_scope.
-Hint Constructors le: core v62.
-(*i equivalent to : "Hints Resolve le_n le_S : core v62." i*)
+Hint Constructors le: core.
+(*i equivalent to : "Hints Resolve le_n le_S : core." i*)
Definition lt (n m:nat) := S n <= m.
-Hint Unfold lt: core v62.
+Hint Unfold lt: core.
Infix "<" := lt : nat_scope.
Definition ge (n m:nat) := m <= n.
-Hint Unfold ge: core v62.
+Hint Unfold ge: core.
Infix ">=" := ge : nat_scope.
Definition gt (n m:nat) := m < n.
-Hint Unfold gt: core v62.
+Hint Unfold gt: core.
Infix ">" := gt : nat_scope.
diff --git a/theories/Init/Tactics.v b/theories/Init/Tactics.v
index 10555fc0..2d7e2159 100644
--- a/theories/Init/Tactics.v
+++ b/theories/Init/Tactics.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Tactics.v 11309 2008-08-06 10:30:35Z herbelin $ i*)
+(*i $Id: Tactics.v 11741 2009-01-03 14:34:39Z herbelin $ i*)
Require Import Notations.
Require Import Logic.
@@ -72,6 +72,17 @@ Ltac false_hyp H G :=
Ltac case_eq x := generalize (refl_equal x); pattern x at -1; case x.
+(* Similar variants of destruct *)
+
+Tactic Notation "destruct_with_eqn" constr(x) :=
+ destruct x as []_eqn.
+Tactic Notation "destruct_with_eqn" ident(n) :=
+ try intros until n; destruct n as []_eqn.
+Tactic Notation "destruct_with_eqn" ":" ident(H) constr(x) :=
+ destruct x as []_eqn:H.
+Tactic Notation "destruct_with_eqn" ":" ident(H) ident(n) :=
+ try intros until n; destruct n as []_eqn:H.
+
(* Rewriting in all hypothesis several times everywhere *)
Tactic Notation "rewrite_all" constr(eq) := repeat rewrite eq in *.
@@ -135,14 +146,31 @@ bapply lemma ltac:(fun H => destruct H as [H _]; apply H in J).
Tactic Notation "apply" "<-" constr(lemma) "in" ident(J) :=
bapply lemma ltac:(fun H => destruct H as [_ H]; apply H in J).
-(** A tactic simpler than auto that is useful for ending proofs "in one step" *)
-Tactic Notation "now" tactic(t) :=
-t;
-match goal with
-| H : _ |- _ => solve [inversion H]
-| _ => solve [trivial | reflexivity | symmetry; trivial | discriminate | split]
-| _ => fail 1 "Cannot solve this goal."
-end.
+(** An experimental tactic simpler than auto that is useful for ending
+ proofs "in one step" *)
+
+Ltac easy :=
+ let rec use_hyp H :=
+ match type of H with
+ | _ /\ _ => exact H || destruct_hyp H
+ | _ => try solve [inversion H]
+ end
+ with do_intro := let H := fresh in intro H; use_hyp H
+ with destruct_hyp H := case H; clear H; do_intro; do_intro in
+ let rec use_hyps :=
+ match goal with
+ | H : _ /\ _ |- _ => exact H || (destruct_hyp H; use_hyps)
+ | H : _ |- _ => solve [inversion H]
+ | _ => idtac
+ end in
+ let rec do_atom :=
+ solve [reflexivity | symmetry; trivial] ||
+ contradiction ||
+ (split; do_atom)
+ with do_ccl := trivial; repeat do_intro; do_atom in
+ (use_hyps; do_ccl) || fail "Cannot solve this goal".
+
+Tactic Notation "now" tactic(t) := t; easy.
(** A tactic to document or check what is proved at some point of a script *)
Ltac now_show c := change c.
diff --git a/theories/Lists/SetoidList.v b/theories/Lists/SetoidList.v
index 4edc1581..2592abb5 100644
--- a/theories/Lists/SetoidList.v
+++ b/theories/Lists/SetoidList.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: SetoidList.v 10616 2008-03-04 17:33:35Z letouzey $ *)
+(* $Id: SetoidList.v 11800 2009-01-18 18:34:15Z msozeau $ *)
Require Export List.
Require Export Sorting.
@@ -69,10 +69,10 @@ Definition equivlistA l l' := forall x, InA x l <-> InA x l'.
(** lists with same elements modulo [eqA] at the same place *)
-Inductive eqlistA : list A -> list A -> Prop :=
- | eqlistA_nil : eqlistA nil nil
- | eqlistA_cons : forall x x' l l',
- eqA x x' -> eqlistA l l' -> eqlistA (x::l) (x'::l').
+Inductive eqlistA : list A -> list A -> Prop :=
+ | eqlistA_nil : eqlistA nil nil
+ | eqlistA_cons : forall x x' l l',
+ eqA x x' -> eqlistA l l' -> eqlistA (x::l) (x'::l').
Hint Constructors eqlistA.
@@ -445,7 +445,11 @@ Definition compat_op (f : A -> B -> B) :=
Definition transpose (f : A -> B -> B) :=
forall (x y : A) (z : B), eqB (f x (f y z)) (f y (f x z)).
-Variable st:Setoid_Theory _ eqB.
+(** A version of transpose with restriction on where it should hold *)
+Definition transpose_restr (R : A -> A -> Prop)(f : A -> B -> B) :=
+ forall (x y : A) (z : B), R x y -> eqB (f x (f y z)) (f y (f x z)).
+
+Variable st:Equivalence eqB.
Variable f:A->B->B.
Variable i:B.
Variable Comp:compat_op f.
@@ -455,17 +459,7 @@ Lemma fold_right_eqlistA :
eqB (fold_right f i s) (fold_right f i s').
Proof.
induction 1; simpl; auto.
-refl_st.
-Qed.
-
-Variable Ass:transpose f.
-
-Lemma fold_right_commutes : forall s1 s2 x,
- eqB (fold_right f i (s1++x::s2)) (f x (fold_right f i (s1++s2))).
-Proof.
-induction s1; simpl; auto; intros.
-refl_st.
-trans_st (f a (f x (fold_right f i (s1++s2)))).
+reflexivity.
Qed.
Lemma equivlistA_NoDupA_split : forall l l1 l2 x y, eqA x y ->
@@ -490,38 +484,193 @@ Proof.
destruct H8; auto.
elim H0.
destruct H7; [left|right]; eapply InA_eqA; eauto.
-Qed.
+Qed.
-Lemma fold_right_equivlistA :
- forall s s', NoDupA s -> NoDupA s' ->
+(** [ForallList2] : specifies that a certain binary predicate should
+ always hold when inspecting two different elements of the list. *)
+
+Inductive ForallList2 (R : A -> A -> Prop) : list A -> Prop :=
+ | ForallNil : ForallList2 R nil
+ | ForallCons : forall a l,
+ (forall b, In b l -> R a b) ->
+ ForallList2 R l -> ForallList2 R (a::l).
+Hint Constructors ForallList2.
+
+(** [NoDupA] can be written in terms of [ForallList2] *)
+
+Lemma ForallList2_NoDupA : forall l,
+ ForallList2 (fun a b => ~eqA a b) l <-> NoDupA l.
+Proof.
+ induction l; split; intros; auto.
+ inversion_clear H. constructor; [ | rewrite <- IHl; auto ].
+ rewrite InA_alt; intros (a',(Haa',Ha')).
+ exact (H0 a' Ha' Haa').
+ inversion_clear H. constructor; [ | rewrite IHl; auto ].
+ intros b Hb.
+ contradict H0.
+ rewrite InA_alt; exists b; auto.
+Qed.
+
+Lemma ForallList2_impl : forall (R R':A->A->Prop),
+ (forall a b, R a b -> R' a b) ->
+ forall l, ForallList2 R l -> ForallList2 R' l.
+Proof.
+ induction 2; auto.
+Qed.
+
+(** The following definition is easier to use than [ForallList2]. *)
+
+Definition ForallList2_alt (R:A->A->Prop) l :=
+ forall a b, InA a l -> InA b l -> ~eqA a b -> R a b.
+
+Section Restriction.
+Variable R : A -> A -> Prop.
+
+(** [ForallList2] and [ForallList2_alt] are related, but no completely
+ equivalent. For proving one implication, we need to know that the
+ list has no duplicated elements... *)
+
+Lemma ForallList2_equiv1 : forall l, NoDupA l ->
+ ForallList2_alt R l -> ForallList2 R l.
+Proof.
+ induction l; auto.
+ constructor. intros b Hb.
+ inversion_clear H.
+ apply H0; auto.
+ contradict H1.
+ apply InA_eqA with b; auto.
+ apply IHl.
+ inversion_clear H; auto.
+ intros b c Hb Hc Hneq.
+ apply H0; auto.
+Qed.
+
+(** ... and for proving the other implication, we need to be able
+ to reverse and adapt relation [R] modulo [eqA]. *)
+
+Hypothesis R_sym : forall a b, R a b -> R b a.
+Hypothesis R_compat : forall a, compat_P (R a).
+
+Lemma ForallList2_equiv2 : forall l,
+ ForallList2 R l -> ForallList2_alt R l.
+Proof.
+ induction l.
+ intros _. red. intros a b Ha. inversion Ha.
+ inversion_clear 1 as [|? ? H_R Hl].
+ intros b c Hb Hc Hneq.
+ inversion_clear Hb; inversion_clear Hc.
+ (* b,c = a : impossible *)
+ elim Hneq; eauto.
+ (* b = a, c in l *)
+ rewrite InA_alt in H0; destruct H0 as (d,(Hcd,Hd)).
+ apply R_compat with d; auto.
+ apply R_sym; apply R_compat with a; auto.
+ (* b in l, c = a *)
+ rewrite InA_alt in H; destruct H as (d,(Hcd,Hd)).
+ apply R_compat with a; auto.
+ apply R_sym; apply R_compat with d; auto.
+ (* b,c in l *)
+ apply (IHl Hl); auto.
+Qed.
+
+Lemma ForallList2_equiv : forall l, NoDupA l ->
+ (ForallList2 R l <-> ForallList2_alt R l).
+Proof.
+split; [apply ForallList2_equiv2|apply ForallList2_equiv1]; auto.
+Qed.
+
+Lemma ForallList2_equivlistA : forall l l', NoDupA l' ->
+ equivlistA l l' -> ForallList2 R l -> ForallList2 R l'.
+Proof.
+intros.
+apply ForallList2_equiv1; auto.
+intros a b Ha Hb Hneq.
+red in H0; rewrite <- H0 in Ha,Hb.
+revert a b Ha Hb Hneq.
+change (ForallList2_alt R l).
+apply ForallList2_equiv2; auto.
+Qed.
+
+Variable TraR :transpose_restr R f.
+
+Lemma fold_right_commutes_restr :
+ forall s1 s2 x, ForallList2 R (s1++x::s2) ->
+ eqB (fold_right f i (s1++x::s2)) (f x (fold_right f i (s1++s2))).
+Proof.
+induction s1; simpl; auto; intros.
+reflexivity.
+transitivity (f a (f x (fold_right f i (s1++s2)))).
+apply Comp; auto.
+apply IHs1.
+inversion_clear H; auto.
+apply TraR.
+inversion_clear H.
+apply H0.
+apply in_or_app; simpl; auto.
+Qed.
+
+Lemma fold_right_equivlistA_restr :
+ forall s s', NoDupA s -> NoDupA s' -> ForallList2 R s ->
equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s').
Proof.
simple induction s.
destruct s'; simpl.
- intros; refl_st; auto.
+ intros; reflexivity.
unfold equivlistA; intros.
- destruct (H1 a).
+ destruct (H2 a).
assert (X : InA a nil); auto; inversion X.
- intros x l Hrec s' N N' E; simpl in *.
+ intros x l Hrec s' N N' F E; simpl in *.
assert (InA x s').
rewrite <- (E x); auto.
destruct (InA_split H) as (s1,(y,(s2,(H1,H2)))).
subst s'.
- trans_st (f x (fold_right f i (s1++s2))).
+ transitivity (f x (fold_right f i (s1++s2))).
apply Comp; auto.
apply Hrec; auto.
inversion_clear N; auto.
eapply NoDupA_split; eauto.
+ inversion_clear F; auto.
eapply equivlistA_NoDupA_split; eauto.
- trans_st (f y (fold_right f i (s1++s2))).
- apply Comp; auto; refl_st.
- sym_st; apply fold_right_commutes.
+ transitivity (f y (fold_right f i (s1++s2))).
+ apply Comp; auto. reflexivity.
+ symmetry; apply fold_right_commutes_restr.
+ apply ForallList2_equivlistA with (x::l); auto.
+Qed.
+
+Lemma fold_right_add_restr :
+ forall s' s x, NoDupA s -> NoDupA s' -> ForallList2 R s' -> ~ InA x s ->
+ equivlistA s' (x::s) -> eqB (fold_right f i s') (f x (fold_right f i s)).
+Proof.
+ intros; apply (@fold_right_equivlistA_restr s' (x::s)); auto.
+Qed.
+
+End Restriction.
+
+(** we know state similar results, but without restriction on transpose. *)
+
+Variable Tra :transpose f.
+
+Lemma fold_right_commutes : forall s1 s2 x,
+ eqB (fold_right f i (s1++x::s2)) (f x (fold_right f i (s1++s2))).
+Proof.
+induction s1; simpl; auto; intros.
+reflexivity.
+transitivity (f a (f x (fold_right f i (s1++s2)))); auto.
+Qed.
+
+Lemma fold_right_equivlistA :
+ forall s s', NoDupA s -> NoDupA s' ->
+ equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s').
+Proof.
+intros; apply fold_right_equivlistA_restr with (R:=fun _ _ => True);
+ try red; auto.
+apply ForallList2_equiv1; try red; auto.
Qed.
Lemma fold_right_add :
forall s' s x, NoDupA s -> NoDupA s' -> ~ InA x s ->
equivlistA s' (x::s) -> eqB (fold_right f i s') (f x (fold_right f i s)).
-Proof.
+Proof.
intros; apply (@fold_right_equivlistA s' (x::s)); auto.
Qed.
@@ -538,7 +687,7 @@ destruct (eqA_dec x a).
left; auto.
destruct IHl.
left; auto.
-right; red; inversion_clear 1; tauto.
+right; red; inversion_clear 1; contradiction.
Qed.
Fixpoint removeA (x : A) (l : list A){struct l} : list A :=
@@ -547,7 +696,7 @@ Fixpoint removeA (x : A) (l : list A){struct l} : list A :=
| y::tl => if (eqA_dec x y) then removeA x tl else y::(removeA x tl)
end.
-Lemma removeA_filter : forall x l,
+Lemma removeA_filter : forall x l,
removeA x l = filter (fun y => if eqA_dec x y then false else true) l.
Proof.
induction l; simpl; auto.
diff --git a/theories/Logic/ClassicalDescription.v b/theories/Logic/ClassicalDescription.v
index d15e2c96..31c41120 100644
--- a/theories/Logic/ClassicalDescription.v
+++ b/theories/Logic/ClassicalDescription.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: ClassicalDescription.v 11238 2008-07-19 09:34:03Z herbelin $ i*)
+(*i $Id: ClassicalDescription.v 11481 2008-10-20 19:23:51Z herbelin $ i*)
(** This file provides classical logic and definite description, which is
equivalent to providing classical logic and Church's iota operator *)
@@ -21,7 +21,7 @@ Set Implicit Arguments.
Require Export Classical.
Require Import ChoiceFacts.
-Notation Local inhabited A := A.
+Notation Local inhabited A := A (only parsing).
Axiom constructive_definite_description :
forall (A : Type) (P : A->Prop), (exists! x : A, P x) -> { x : A | P x }.
diff --git a/theories/Logic/ClassicalFacts.v b/theories/Logic/ClassicalFacts.v
index 8a045ec8..db92696b 100644
--- a/theories/Logic/ClassicalFacts.v
+++ b/theories/Logic/ClassicalFacts.v
@@ -7,7 +7,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: ClassicalFacts.v 11238 2008-07-19 09:34:03Z herbelin $ i*)
+(*i $Id: ClassicalFacts.v 11481 2008-10-20 19:23:51Z herbelin $ i*)
(** Some facts and definitions about classical logic
@@ -119,7 +119,7 @@ Qed.
*)
-Notation Local inhabited A := A.
+Notation Local inhabited A := A (only parsing).
Lemma prop_ext_A_eq_A_imp_A :
prop_extensionality -> forall A:Prop, inhabited A -> (A -> A) = A.
diff --git a/theories/Logic/Decidable.v b/theories/Logic/Decidable.v
index a7c098e8..00d63252 100644
--- a/theories/Logic/Decidable.v
+++ b/theories/Logic/Decidable.v
@@ -5,7 +5,7 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Decidable.v 10500 2008-02-02 15:51:00Z letouzey $ i*)
+(*i $Id: Decidable.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
(** Properties of decidable propositions *)
@@ -80,6 +80,13 @@ Proof.
unfold decidable; tauto.
Qed.
+Theorem not_iff :
+ forall A B:Prop, decidable A -> decidable B ->
+ ~ (A <-> B) -> (A /\ ~ B) \/ (~ A /\ B).
+Proof.
+unfold decidable; tauto.
+Qed.
+
(** Results formulated with iff, used in FSetDecide.
Negation are expanded since it is unclear whether setoid rewrite
will always perform conversion. *)
diff --git a/theories/Logic/DecidableTypeEx.v b/theories/Logic/DecidableTypeEx.v
index 9c928598..9c59c519 100644
--- a/theories/Logic/DecidableTypeEx.v
+++ b/theories/Logic/DecidableTypeEx.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
-(* $Id: DecidableTypeEx.v 10739 2008-04-01 14:45:20Z herbelin $ *)
+(* $Id: DecidableTypeEx.v 11699 2008-12-18 11:49:08Z letouzey $ *)
Require Import DecidableType OrderedType OrderedTypeEx.
Set Implicit Arguments.
@@ -46,24 +46,16 @@ Module Make_UDT (M:MiniDecidableType) <: UsualDecidableType.
Definition eq_dec := M.eq_dec.
End Make_UDT.
-(** An OrderedType can be seen as a DecidableType *)
+(** An OrderedType can now directly be seen as a DecidableType *)
-Module OT_as_DT (O:OrderedType) <: DecidableType.
- Module OF := OrderedTypeFacts O.
- Definition t := O.t.
- Definition eq := O.eq.
- Definition eq_refl := O.eq_refl.
- Definition eq_sym := O.eq_sym.
- Definition eq_trans := O.eq_trans.
- Definition eq_dec := OF.eq_dec.
-End OT_as_DT.
+Module OT_as_DT (O:OrderedType) <: DecidableType := O.
(** (Usual) Decidable Type for [nat], [positive], [N], [Z] *)
-Module Nat_as_DT <: UsualDecidableType := OT_as_DT (Nat_as_OT).
-Module Positive_as_DT <: UsualDecidableType := OT_as_DT (Positive_as_OT).
-Module N_as_DT <: UsualDecidableType := OT_as_DT (N_as_OT).
-Module Z_as_DT <: UsualDecidableType := OT_as_DT (Z_as_OT).
+Module Nat_as_DT <: UsualDecidableType := Nat_as_OT.
+Module Positive_as_DT <: UsualDecidableType := Positive_as_OT.
+Module N_as_DT <: UsualDecidableType := N_as_OT.
+Module Z_as_DT <: UsualDecidableType := Z_as_OT.
(** From two decidable types, we can build a new DecidableType
over their cartesian product. *)
@@ -99,7 +91,7 @@ End PairDecidableType.
(** Similarly for pairs of UsualDecidableType *)
-Module PairUsualDecidableType(D1 D2:UsualDecidableType) <: DecidableType.
+Module PairUsualDecidableType(D1 D2:UsualDecidableType) <: UsualDecidableType.
Definition t := prod D1.t D2.t.
Definition eq := @eq t.
Definition eq_refl := @refl_equal t.
diff --git a/theories/Logic/Diaconescu.v b/theories/Logic/Diaconescu.v
index 880ef7e2..b935a676 100644
--- a/theories/Logic/Diaconescu.v
+++ b/theories/Logic/Diaconescu.v
@@ -7,7 +7,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Diaconescu.v 11238 2008-07-19 09:34:03Z herbelin $ i*)
+(*i $Id: Diaconescu.v 11481 2008-10-20 19:23:51Z herbelin $ i*)
(** Diaconescu showed that the Axiom of Choice entails Excluded-Middle
in topoi [Diaconescu75]. Lacas and Werner adapted the proof to show
@@ -267,7 +267,7 @@ End ProofIrrel_RelChoice_imp_EqEM.
(** Proof sketch from Bell [Bell93] (with thanks to P. Castéran) *)
-Notation Local inhabited A := A.
+Notation Local inhabited A := A (only parsing).
Section ExtensionalEpsilon_imp_EM.
diff --git a/theories/Logic/EqdepFacts.v b/theories/Logic/EqdepFacts.v
index 844bff88..d5738c82 100644
--- a/theories/Logic/EqdepFacts.v
+++ b/theories/Logic/EqdepFacts.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: EqdepFacts.v 11095 2008-06-10 19:36:10Z herbelin $ i*)
+(*i $Id: EqdepFacts.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
(** This file defines dependent equality and shows its equivalence with
equality on dependent pairs (inhabiting sigma-types). It derives
@@ -53,7 +53,7 @@ Section Dependent_Equality.
Inductive eq_dep (p:U) (x:P p) : forall q:U, P q -> Prop :=
eq_dep_intro : eq_dep p x p x.
- Hint Constructors eq_dep: core v62.
+ Hint Constructors eq_dep: core.
Lemma eq_dep_refl : forall (p:U) (x:P p), eq_dep p x p x.
Proof eq_dep_intro.
@@ -63,7 +63,7 @@ Section Dependent_Equality.
Proof.
destruct 1; auto.
Qed.
- Hint Immediate eq_dep_sym: core v62.
+ Hint Immediate eq_dep_sym: core.
Lemma eq_dep_trans :
forall (p q r:U) (x:P p) (y:P q) (z:P r),
@@ -135,8 +135,8 @@ Qed.
(** Exported hints *)
-Hint Resolve eq_dep_intro: core v62.
-Hint Immediate eq_dep_sym: core v62.
+Hint Resolve eq_dep_intro: core.
+Hint Immediate eq_dep_sym: core.
(************************************************************************)
(** * Eq_rect_eq <-> Eq_dep_eq <-> UIP <-> UIP_refl <-> K *)
diff --git a/theories/Logic/FunctionalExtensionality.v b/theories/Logic/FunctionalExtensionality.v
new file mode 100644
index 00000000..4445b0e1
--- /dev/null
+++ b/theories/Logic/FunctionalExtensionality.v
@@ -0,0 +1,60 @@
+(************************************************************************)
+(* 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: FunctionalExtensionality.v 11686 2008-12-16 12:57:26Z msozeau $ i*)
+
+(** This module states the axiom of (dependent) functional extensionality and (dependent) eta-expansion.
+ It introduces a tactic [extensionality] to apply the axiom of extensionality to an equality goal. *)
+
+Set Manual Implicit Arguments.
+
+(** The converse of functional extensionality. *)
+
+Lemma equal_f : forall {A B : Type} {f g : A -> B},
+ f = g -> forall x, f x = g x.
+Proof.
+ intros.
+ rewrite H.
+ auto.
+Qed.
+
+(** Statements of functional extensionality for simple and dependent functions. *)
+
+Axiom functional_extensionality_dep : forall {A} {B : A -> Type},
+ forall (f g : forall x : A, B x),
+ (forall x, f x = g x) -> f = g.
+
+Lemma functional_extensionality {A B} (f g : A -> B) :
+ (forall x, f x = g x) -> f = g.
+Proof.
+ intros ; eauto using @functional_extensionality_dep.
+Qed.
+
+(** Apply [functional_extensionality], introducing variable x. *)
+
+Tactic Notation "extensionality" ident(x) :=
+ match goal with
+ [ |- ?X = ?Y ] =>
+ (apply (@functional_extensionality _ _ X Y) ||
+ apply (@functional_extensionality_dep _ _ X Y)) ; intro x
+ end.
+
+(** Eta expansion follows from extensionality. *)
+
+Lemma eta_expansion_dep {A} {B : A -> Type} (f : forall x : A, B x) :
+ f = fun x => f x.
+Proof.
+ intros.
+ extensionality x.
+ reflexivity.
+Qed.
+
+Lemma eta_expansion {A B} (f : A -> B) : f = fun x => f x.
+Proof.
+ intros A B f. apply (eta_expansion_dep f).
+Qed.
diff --git a/theories/NArith/BinNat.v b/theories/NArith/BinNat.v
index 20dabed2..3752abcc 100644
--- a/theories/NArith/BinNat.v
+++ b/theories/NArith/BinNat.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: BinNat.v 10806 2008-04-16 23:51:06Z letouzey $ i*)
+(*i $Id: BinNat.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
Require Import BinPos.
Unset Boxed Definitions.
@@ -393,10 +393,10 @@ Theorem Ncompare_n_Sm :
Proof.
intros n m; split; destruct n as [| p]; destruct m as [| q]; simpl; auto.
destruct p; simpl; intros; discriminate.
-pose proof (proj1 (Pcompare_p_Sq p q));
+pose proof (Pcompare_p_Sq p q) as (?,_).
assert (p = q <-> Npos p = Npos q); [split; congruence | tauto].
intros H; destruct H; discriminate.
-pose proof (proj2 (Pcompare_p_Sq p q));
+pose proof (Pcompare_p_Sq p q) as (_,?);
assert (p = q <-> Npos p = Npos q); [split; congruence | tauto].
Qed.
diff --git a/theories/NArith/Ndigits.v b/theories/NArith/Ndigits.v
index dcdb5f92..fb32274e 100644
--- a/theories/NArith/Ndigits.v
+++ b/theories/NArith/Ndigits.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Ndigits.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
+(*i $Id: Ndigits.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
Require Import Bool.
Require Import Bvector.
@@ -52,8 +52,8 @@ Proof.
destruct n; destruct n'; simpl; auto.
generalize p0; clear p0; induction p as [p Hrecp| p Hrecp| ]; simpl;
auto.
- destruct p0; simpl; trivial; intros; rewrite Hrecp; trivial.
- destruct p0; simpl; trivial; intros; rewrite Hrecp; trivial.
+ destruct p0; trivial; rewrite Hrecp; trivial.
+ destruct p0; trivial; rewrite Hrecp; trivial.
destruct p0 as [p| p| ]; simpl; auto.
Qed.
@@ -115,7 +115,7 @@ Definition xorf (f g:nat -> bool) (n:nat) := xorb (f n) (g n).
Lemma xorf_eq :
forall f f', eqf (xorf f f') (fun n => false) -> eqf f f'.
Proof.
- unfold eqf, xorf. intros. apply xorb_eq. apply H.
+ unfold eqf, xorf. intros. apply xorb_eq, H.
Qed.
Lemma xorf_assoc :
@@ -166,14 +166,12 @@ Lemma Nbit_faithful_3 :
(forall p':positive, eqf (Nbit (Npos p)) (Nbit (Npos p')) -> p = p') ->
eqf (Nbit (Npos (xO p))) (Nbit a) -> Npos (xO p) = a.
Proof.
- destruct a. intros. cut (eqf (Nbit N0) (Nbit (Npos (xO p)))).
+ destruct a; intros. cut (eqf (Nbit N0) (Nbit (Npos (xO p)))).
intro. rewrite (Nbit_faithful_1 (Npos (xO p)) H1). reflexivity.
unfold eqf. intro. unfold eqf in H0. rewrite H0. reflexivity.
- case p. intros. absurd (false = true). discriminate.
- exact (H0 0).
- intros. rewrite (H p0 (fun n => H0 (S n))). reflexivity.
- intros. absurd (false = true). discriminate.
- exact (H0 0).
+ destruct p. discriminate (H0 O).
+ rewrite (H p (fun n => H0 (S n))). reflexivity.
+ discriminate (H0 0).
Qed.
Lemma Nbit_faithful_4 :
@@ -181,27 +179,26 @@ Lemma Nbit_faithful_4 :
(forall p':positive, eqf (Nbit (Npos p)) (Nbit (Npos p')) -> p = p') ->
eqf (Nbit (Npos (xI p))) (Nbit a) -> Npos (xI p) = a.
Proof.
- destruct a. intros. cut (eqf (Nbit N0) (Nbit (Npos (xI p)))).
+ destruct a; intros. cut (eqf (Nbit N0) (Nbit (Npos (xI p)))).
intro. rewrite (Nbit_faithful_1 (Npos (xI p)) H1). reflexivity.
- unfold eqf. intro. unfold eqf in H0. rewrite H0. reflexivity.
- case p. intros. rewrite (H p0 (fun n:nat => H0 (S n))). reflexivity.
- intros. absurd (true = false). discriminate.
- exact (H0 0).
- intros. absurd (N0 = Npos p0). discriminate.
+ intro. rewrite H0. reflexivity.
+ destruct p. rewrite (H p (fun n:nat => H0 (S n))). reflexivity.
+ discriminate (H0 0).
cut (eqf (Nbit (Npos 1)) (Nbit (Npos (xI p0)))).
- intro. exact (Nbit_faithful_1 (Npos p0) (fun n:nat => H1 (S n))).
- unfold eqf in *. intro. rewrite H0. reflexivity.
+ intro. discriminate (Nbit_faithful_1 (Npos p0) (fun n:nat => H1 (S n))).
+ intro. rewrite H0. reflexivity.
Qed.
Lemma Nbit_faithful : forall a a':N, eqf (Nbit a) (Nbit a') -> a = a'.
Proof.
destruct a. exact Nbit_faithful_1.
- induction p. intros a' H. apply Nbit_faithful_4. intros. cut (Npos p = Npos p').
- intro. inversion H1. reflexivity.
- exact (IHp (Npos p') H0).
+ induction p. intros a' H. apply Nbit_faithful_4. intros.
+ assert (Npos p = Npos p') by exact (IHp (Npos p') H0).
+ inversion H1. reflexivity.
assumption.
- intros. apply Nbit_faithful_3. intros. cut (Npos p = Npos p'). intro. inversion H1. reflexivity.
- exact (IHp (Npos p') H0).
+ intros. apply Nbit_faithful_3. intros.
+ assert (Npos p = Npos p') by exact (IHp (Npos p') H0).
+ inversion H1. reflexivity.
assumption.
exact Nbit_faithful_2.
Qed.
@@ -216,40 +213,37 @@ Qed.
Lemma Nxor_sem_2 :
forall a':N, Nbit (Nxor (Npos 1) a') 0 = negb (Nbit a' 0).
Proof.
- intro. case a'. trivial.
- simpl. intro.
- case p; trivial.
+ intro. destruct a'. trivial.
+ destruct p; trivial.
Qed.
Lemma Nxor_sem_3 :
forall (p:positive) (a':N),
Nbit (Nxor (Npos (xO p)) a') 0 = Nbit a' 0.
Proof.
- intros. case a'. trivial.
- simpl. intro.
- case p0; trivial. intro.
- case (Pxor p p1); trivial.
- intro. case (Pxor p p1); trivial.
+ intros. destruct a'. trivial.
+ simpl. destruct p0; trivial.
+ destruct (Pxor p p0); trivial.
+ destruct (Pxor p p0); trivial.
Qed.
Lemma Nxor_sem_4 :
forall (p:positive) (a':N),
Nbit (Nxor (Npos (xI p)) a') 0 = negb (Nbit a' 0).
Proof.
- intros. case a'. trivial.
- simpl. intro. case p0; trivial. intro.
- case (Pxor p p1); trivial.
- intro.
- case (Pxor p p1); trivial.
+ intros. destruct a'. trivial.
+ simpl. destruct p0; trivial.
+ destruct (Pxor p p0); trivial.
+ destruct (Pxor p p0); trivial.
Qed.
Lemma Nxor_sem_5 :
forall a a':N, Nbit (Nxor a a') 0 = xorf (Nbit a) (Nbit a') 0.
Proof.
- destruct a. intro. change (Nbit a' 0 = xorb false (Nbit a' 0)). rewrite false_xorb. trivial.
- case p. exact Nxor_sem_4.
- intros. change (Nbit (Nxor (Npos (xO p0)) a') 0 = xorb false (Nbit a' 0)).
- rewrite false_xorb. apply Nxor_sem_3. exact Nxor_sem_2.
+ destruct a; intro. change (Nbit a' 0 = xorb false (Nbit a' 0)). rewrite false_xorb. trivial.
+ destruct p. apply Nxor_sem_4.
+ change (Nbit (Nxor (Npos (xO p)) a') 0 = xorb false (Nbit a' 0)).
+ rewrite false_xorb. apply Nxor_sem_3. apply Nxor_sem_2.
Qed.
Lemma Nxor_sem_6 :
@@ -258,28 +252,29 @@ Lemma Nxor_sem_6 :
forall a a':N,
Nbit (Nxor a a') (S n) = xorf (Nbit a) (Nbit a') (S n).
Proof.
- intros.
+ intros.
+(* pose proof (fun p1 p2 => H (Npos p1) (Npos p2)) as H'. clear H. rename H' into H.*)
generalize (fun p1 p2 => H (Npos p1) (Npos p2)); clear H; intro H.
unfold xorf in *.
- case a. simpl Nbit; rewrite false_xorb. reflexivity.
- case a'; intros.
+ destruct a as [|p]. simpl Nbit; rewrite false_xorb. reflexivity.
+ destruct a' as [|p0].
simpl Nbit; rewrite xorb_false. reflexivity.
- case p0. case p; intros; simpl Nbit in *.
- rewrite <- H; simpl; case (Pxor p2 p1); trivial.
- rewrite <- H; simpl; case (Pxor p2 p1); trivial.
+ destruct p. destruct p0; simpl Nbit in *.
+ rewrite <- H; simpl; case (Pxor p p0); trivial.
+ rewrite <- H; simpl; case (Pxor p p0); trivial.
rewrite xorb_false. reflexivity.
- case p; intros; simpl Nbit in *.
- rewrite <- H; simpl; case (Pxor p2 p1); trivial.
- rewrite <- H; simpl; case (Pxor p2 p1); trivial.
+ destruct p0; simpl Nbit in *.
+ rewrite <- H; simpl; case (Pxor p p0); trivial.
+ rewrite <- H; simpl; case (Pxor p p0); trivial.
rewrite xorb_false. reflexivity.
- simpl Nbit. rewrite false_xorb. simpl. case p; trivial.
+ simpl Nbit. rewrite false_xorb. destruct p0; trivial.
Qed.
Lemma Nxor_semantics :
forall a a':N, eqf (Nbit (Nxor a a')) (xorf (Nbit a) (Nbit a')).
Proof.
- unfold eqf. intros. generalize a a'. elim n. exact Nxor_sem_5.
- exact Nxor_sem_6.
+ unfold eqf. intros; generalize a, a'. induction n.
+ apply Nxor_sem_5. apply Nxor_sem_6; assumption.
Qed.
(** Consequences:
@@ -289,8 +284,8 @@ Qed.
Lemma Nxor_eq : forall a a':N, Nxor a a' = N0 -> a = a'.
Proof.
- intros. apply Nbit_faithful. apply xorf_eq. apply eqf_trans with (f' := Nbit (Nxor a a')).
- apply eqf_sym. apply Nxor_semantics.
+ intros. apply Nbit_faithful, xorf_eq. apply eqf_trans with (f' := Nbit (Nxor a a')).
+ apply eqf_sym, Nxor_semantics.
rewrite H. unfold eqf. trivial.
Qed.
@@ -298,19 +293,17 @@ Lemma Nxor_assoc :
forall a a' a'':N, Nxor (Nxor a a') a'' = Nxor a (Nxor a' a'').
Proof.
intros. apply Nbit_faithful.
- apply eqf_trans with
- (f' := xorf (xorf (Nbit a) (Nbit a')) (Nbit a'')).
- apply eqf_trans with (f' := xorf (Nbit (Nxor a a')) (Nbit a'')).
+ apply eqf_trans with (xorf (xorf (Nbit a) (Nbit a')) (Nbit a'')).
+ apply eqf_trans with (xorf (Nbit (Nxor a a')) (Nbit a'')).
apply Nxor_semantics.
apply eqf_xorf. apply Nxor_semantics.
apply eqf_refl.
- apply eqf_trans with
- (f' := xorf (Nbit a) (xorf (Nbit a') (Nbit a''))).
+ apply eqf_trans with (xorf (Nbit a) (xorf (Nbit a') (Nbit a''))).
apply xorf_assoc.
- apply eqf_trans with (f' := xorf (Nbit a) (Nbit (Nxor a' a''))).
+ apply eqf_trans with (xorf (Nbit a) (Nbit (Nxor a' a''))).
apply eqf_xorf. apply eqf_refl.
- apply eqf_sym. apply Nxor_semantics.
- apply eqf_sym. apply Nxor_semantics.
+ apply eqf_sym, Nxor_semantics.
+ apply eqf_sym, Nxor_semantics.
Qed.
(** Checking whether a number is odd, i.e.
@@ -370,18 +363,16 @@ Qed.
Lemma Nxor_bit0 :
forall a a':N, Nbit0 (Nxor a a') = xorb (Nbit0 a) (Nbit0 a').
Proof.
- intros. rewrite <- Nbit0_correct. rewrite (Nxor_semantics a a' 0).
- unfold xorf. rewrite Nbit0_correct. rewrite Nbit0_correct. reflexivity.
+ intros. rewrite <- Nbit0_correct, (Nxor_semantics a a' 0).
+ unfold xorf. rewrite Nbit0_correct, Nbit0_correct. reflexivity.
Qed.
Lemma Nxor_div2 :
forall a a':N, Ndiv2 (Nxor a a') = Nxor (Ndiv2 a) (Ndiv2 a').
Proof.
intros. apply Nbit_faithful. unfold eqf. intro.
- rewrite (Nxor_semantics (Ndiv2 a) (Ndiv2 a') n).
- rewrite Ndiv2_correct.
- rewrite (Nxor_semantics a a' (S n)).
- unfold xorf. rewrite Ndiv2_correct. rewrite Ndiv2_correct.
+ rewrite (Nxor_semantics (Ndiv2 a) (Ndiv2 a') n), Ndiv2_correct, (Nxor_semantics a a' (S n)).
+ unfold xorf. rewrite 2! Ndiv2_correct.
reflexivity.
Qed.
@@ -389,8 +380,9 @@ Lemma Nneg_bit0 :
forall a a':N,
Nbit0 (Nxor a a') = true -> Nbit0 a = negb (Nbit0 a').
Proof.
- intros. rewrite <- true_xorb. rewrite <- H. rewrite Nxor_bit0.
- rewrite xorb_assoc. rewrite xorb_nilpotent. rewrite xorb_false. reflexivity.
+ intros.
+ rewrite <- true_xorb, <- H, Nxor_bit0, xorb_assoc, xorb_nilpotent, xorb_false.
+ reflexivity.
Qed.
Lemma Nneg_bit0_1 :
@@ -410,10 +402,9 @@ Lemma Nsame_bit0 :
forall (a a':N) (p:positive),
Nxor a a' = Npos (xO p) -> Nbit0 a = Nbit0 a'.
Proof.
- intros. rewrite <- (xorb_false (Nbit0 a)). cut (Nbit0 (Npos (xO p)) = false).
- intro. rewrite <- H0. rewrite <- H. rewrite Nxor_bit0. rewrite <- xorb_assoc.
- rewrite xorb_nilpotent. rewrite false_xorb. reflexivity.
- reflexivity.
+ intros. rewrite <- (xorb_false (Nbit0 a)).
+ assert (H0: Nbit0 (Npos (xO p)) = false) by reflexivity.
+ rewrite <- H0, <- H, Nxor_bit0, <- xorb_assoc, xorb_nilpotent, false_xorb. reflexivity.
Qed.
(** a lexicographic order on bits, starting from the lowest bit *)
@@ -434,42 +425,40 @@ Lemma Nbit0_less :
forall a a',
Nbit0 a = false -> Nbit0 a' = true -> Nless a a' = true.
Proof.
- intros. elim (Ndiscr (Nxor a a')). intro H1. elim H1. intros p H2. unfold Nless in |- *.
- rewrite H2. generalize H2. elim p. intros. simpl in |- *. rewrite H. rewrite H0. reflexivity.
- intros. cut (Nbit0 (Nxor a a') = false). intro. rewrite (Nxor_bit0 a a') in H5.
- rewrite H in H5. rewrite H0 in H5. discriminate H5.
- rewrite H4. reflexivity.
- intro. simpl in |- *. rewrite H. rewrite H0. reflexivity.
- intro H1. cut (Nbit0 (Nxor a a') = false). intro. rewrite (Nxor_bit0 a a') in H2.
- rewrite H in H2. rewrite H0 in H2. discriminate H2.
- rewrite H1. reflexivity.
+ intros. destruct (Ndiscr (Nxor a a')) as [(p,H2)|H1]. unfold Nless.
+ rewrite H2. destruct p. simpl. rewrite H, H0. reflexivity.
+ assert (H1: Nbit0 (Nxor a a') = false) by (rewrite H2; reflexivity).
+ rewrite (Nxor_bit0 a a'), H, H0 in H1. discriminate H1.
+ simpl. rewrite H, H0. reflexivity.
+ assert (H2: Nbit0 (Nxor a a') = false) by (rewrite H1; reflexivity).
+ rewrite (Nxor_bit0 a a'), H, H0 in H2. discriminate H2.
Qed.
Lemma Nbit0_gt :
forall a a',
Nbit0 a = true -> Nbit0 a' = false -> Nless a a' = false.
Proof.
- intros. elim (Ndiscr (Nxor a a')). intro H1. elim H1. intros p H2. unfold Nless in |- *.
- rewrite H2. generalize H2. elim p. intros. simpl in |- *. rewrite H. rewrite H0. reflexivity.
- intros. cut (Nbit0 (Nxor a a') = false). intro. rewrite (Nxor_bit0 a a') in H5.
- rewrite H in H5. rewrite H0 in H5. discriminate H5.
- rewrite H4. reflexivity.
- intro. simpl in |- *. rewrite H. rewrite H0. reflexivity.
- intro H1. unfold Nless in |- *. rewrite H1. reflexivity.
+ intros. destruct (Ndiscr (Nxor a a')) as [(p,H2)|H1]. unfold Nless.
+ rewrite H2. destruct p. simpl. rewrite H, H0. reflexivity.
+ assert (H1: Nbit0 (Nxor a a') = false) by (rewrite H2; reflexivity).
+ rewrite (Nxor_bit0 a a'), H, H0 in H1. discriminate H1.
+ simpl. rewrite H, H0. reflexivity.
+ assert (H2: Nbit0 (Nxor a a') = false) by (rewrite H1; reflexivity).
+ rewrite (Nxor_bit0 a a'), H, H0 in H2. discriminate H2.
Qed.
Lemma Nless_not_refl : forall a, Nless a a = false.
Proof.
- intro. unfold Nless in |- *. rewrite (Nxor_nilpotent a). reflexivity.
+ intro. unfold Nless. rewrite (Nxor_nilpotent a). reflexivity.
Qed.
Lemma Nless_def_1 :
forall a a', Nless (Ndouble a) (Ndouble a') = Nless a a'.
Proof.
- simple induction a. simple induction a'. reflexivity.
+ destruct a; destruct a'. reflexivity.
trivial.
- simple induction a'. unfold Nless in |- *. simpl in |- *. elim p; trivial.
- unfold Nless in |- *. simpl in |- *. intro. case (Pxor p p0). reflexivity.
+ unfold Nless. simpl. destruct p; trivial.
+ unfold Nless. simpl. destruct (Pxor p p0). reflexivity.
trivial.
Qed.
@@ -477,10 +466,10 @@ Lemma Nless_def_2 :
forall a a',
Nless (Ndouble_plus_one a) (Ndouble_plus_one a') = Nless a a'.
Proof.
- simple induction a. simple induction a'. reflexivity.
+ destruct a; destruct a'. reflexivity.
trivial.
- simple induction a'. unfold Nless in |- *. simpl in |- *. elim p; trivial.
- unfold Nless in |- *. simpl in |- *. intro. case (Pxor p p0). reflexivity.
+ unfold Nless. simpl. destruct p; trivial.
+ unfold Nless. simpl. destruct (Pxor p p0). reflexivity.
trivial.
Qed.
@@ -500,79 +489,71 @@ Qed.
Lemma Nless_z : forall a, Nless a N0 = false.
Proof.
- simple induction a. reflexivity.
- unfold Nless in |- *. intro. rewrite (Nxor_neutral_right (Npos p)). elim p; trivial.
+ induction a. reflexivity.
+ unfold Nless. rewrite (Nxor_neutral_right (Npos p)). induction p; trivial.
Qed.
Lemma N0_less_1 :
forall a, Nless N0 a = true -> {p : positive | a = Npos p}.
Proof.
- simple induction a. intro. discriminate H.
- intros. split with p. reflexivity.
+ destruct a. intros. discriminate.
+ intros. exists p. reflexivity.
Qed.
Lemma N0_less_2 : forall a, Nless N0 a = false -> a = N0.
Proof.
- simple induction a. trivial.
- unfold Nless in |- *. simpl in |- *.
- cut (forall p:positive, Nless_aux N0 (Npos p) p = false -> False).
- intros. elim (H p H0).
- simple induction p. intros. discriminate H0.
- intros. exact (H H0).
- intro. discriminate H.
+ induction a as [|p]; intro H. trivial.
+ elimtype False. induction p as [|p IHp|]; discriminate || simpl; auto using IHp.
Qed.
Lemma Nless_trans :
forall a a' a'',
Nless a a' = true -> Nless a' a'' = true -> Nless a a'' = true.
Proof.
- intro a. pattern a; apply N_ind_double.
- intros. case_eq (Nless N0 a''). trivial.
- intro H1. rewrite (N0_less_2 a'' H1) in H0. rewrite (Nless_z a') in H0. discriminate H0.
- intros a0 H a'. pattern a'; apply N_ind_double.
- intros. rewrite (Nless_z (Ndouble a0)) in H0. discriminate H0.
- intros a1 H0 a'' H1. rewrite (Nless_def_1 a0 a1) in H1.
- pattern a''; apply N_ind_double; clear a''.
- intro. rewrite (Nless_z (Ndouble a1)) in H2. discriminate H2.
- intros. rewrite (Nless_def_1 a1 a2) in H3. rewrite (Nless_def_1 a0 a2).
- exact (H a1 a2 H1 H3).
- intros. apply Nless_def_3.
- intros a1 H0 a'' H1. pattern a''; apply N_ind_double.
- intro. rewrite (Nless_z (Ndouble_plus_one a1)) in H2. discriminate H2.
- intros. rewrite (Nless_def_4 a1 a2) in H3. discriminate H3.
- intros. apply Nless_def_3.
- intros a0 H a'. pattern a'; apply N_ind_double.
- intros. rewrite (Nless_z (Ndouble_plus_one a0)) in H0. discriminate H0.
- intros. rewrite (Nless_def_4 a0 a1) in H1. discriminate H1.
- intros a1 H0 a'' H1. pattern a''; apply N_ind_double.
- intro. rewrite (Nless_z (Ndouble_plus_one a1)) in H2. discriminate H2.
- intros. rewrite (Nless_def_4 a1 a2) in H3. discriminate H3.
- rewrite (Nless_def_2 a0 a1) in H1. intros. rewrite (Nless_def_2 a1 a2) in H3.
- rewrite (Nless_def_2 a0 a2). exact (H a1 a2 H1 H3).
+ induction a as [|a IHa|a IHa] using N_ind_double; intros a' a'' H H0.
+ destruct (Nless N0 a'') as []_eqn:Heqb. trivial.
+ rewrite (N0_less_2 a'' Heqb), (Nless_z a') in H0. discriminate H0.
+ induction a' as [|a' _|a' _] using N_ind_double.
+ rewrite (Nless_z (Ndouble a)) in H. discriminate H.
+ rewrite (Nless_def_1 a a') in H.
+ induction a'' using N_ind_double.
+ rewrite (Nless_z (Ndouble a')) in H0. discriminate H0.
+ rewrite (Nless_def_1 a' a'') in H0. rewrite (Nless_def_1 a a'').
+ exact (IHa _ _ H H0).
+ apply Nless_def_3.
+ induction a'' as [|a'' _|a'' _] using N_ind_double.
+ rewrite (Nless_z (Ndouble_plus_one a')) in H0. discriminate H0.
+ rewrite (Nless_def_4 a' a'') in H0. discriminate H0.
+ apply Nless_def_3.
+ induction a' as [|a' _|a' _] using N_ind_double.
+ rewrite (Nless_z (Ndouble_plus_one a)) in H. discriminate H.
+ rewrite (Nless_def_4 a a') in H. discriminate H.
+ induction a'' using N_ind_double.
+ rewrite (Nless_z (Ndouble_plus_one a')) in H0. discriminate H0.
+ rewrite (Nless_def_4 a' a'') in H0. discriminate H0.
+ rewrite (Nless_def_2 a' a'') in H0. rewrite (Nless_def_2 a a') in H.
+ rewrite (Nless_def_2 a a''). exact (IHa _ _ H H0).
Qed.
Lemma Nless_total :
forall a a', {Nless a a' = true} + {Nless a' a = true} + {a = a'}.
Proof.
- intro a.
- pattern a; apply N_rec_double; clear a.
- intro. case_eq (Nless N0 a'). intro H. left. left. auto.
- intro H. right. rewrite (N0_less_2 a' H). reflexivity.
- intros a0 H a'.
- pattern a'; apply N_rec_double; clear a'.
- case_eq (Nless N0 (Ndouble a0)). intro H0. left. right. auto.
- intro H0. right. exact (N0_less_2 _ H0).
- intros a1 H0. rewrite Nless_def_1. rewrite Nless_def_1. elim (H a1). intro H1.
- left. assumption.
- intro H1. right. rewrite H1. reflexivity.
- intros a1 H0. left. left. apply Nless_def_3.
- intros a0 H a'.
- pattern a'; apply N_rec_double; clear a'.
- left. right. case a0; reflexivity.
- intros a1 H0. left. right. apply Nless_def_3.
- intros a1 H0. rewrite Nless_def_2. rewrite Nless_def_2. elim (H a1). intro H1.
- left. assumption.
- intro H1. right. rewrite H1. reflexivity.
+ induction a using N_rec_double; intro a'.
+ destruct (Nless N0 a') as []_eqn:Heqb. left. left. auto.
+ right. rewrite (N0_less_2 a' Heqb). reflexivity.
+ induction a' as [|a' _|a' _] using N_rec_double.
+ destruct (Nless N0 (Ndouble a)) as []_eqn:Heqb. left. right. auto.
+ right. exact (N0_less_2 _ Heqb).
+ rewrite 2!Nless_def_1. destruct (IHa a') as [ | ->].
+ left. assumption.
+ right. reflexivity.
+ left. left. apply Nless_def_3.
+ induction a' as [|a' _|a' _] using N_rec_double.
+ left. right. destruct a; reflexivity.
+ left. right. apply Nless_def_3.
+ rewrite 2!Nless_def_2. destruct (IHa a') as [ | ->].
+ left. assumption.
+ right. reflexivity.
Qed.
(** Number of digits in a number *)
@@ -621,7 +602,7 @@ Proof.
induction n; intros.
rewrite (V0_eq _ bv); simpl; auto.
rewrite (VSn_eq _ _ bv); simpl.
-generalize (IHn (Vtail _ _ bv)); clear IHn.
+specialize IHn with (Vtail _ _ bv).
destruct (Vhead _ _ bv);
destruct (Bv2N n (Vtail bool n bv));
simpl; auto with arith.
@@ -701,7 +682,7 @@ Lemma Nbit0_Blow : forall n, forall (bv:Bvector (S n)),
Proof.
intros.
unfold Blow.
-pattern bv at 1; rewrite (VSn_eq _ _ bv).
+rewrite (VSn_eq _ _ bv) at 1.
simpl.
destruct (Bv2N n (Vtail bool n bv)); simpl;
destruct (Vhead bool n bv); auto.
@@ -750,9 +731,9 @@ Lemma Nxor_BVxor : forall n (bv bv' : Bvector n),
Proof.
induction n.
intros.
-rewrite (V0_eq _ bv); rewrite (V0_eq _ bv'); simpl; auto.
+rewrite (V0_eq _ bv), (V0_eq _ bv'); simpl; auto.
intros.
-rewrite (VSn_eq _ _ bv); rewrite (VSn_eq _ _ bv'); simpl; auto.
+rewrite (VSn_eq _ _ bv), (VSn_eq _ _ bv'); simpl; auto.
rewrite IHn.
destruct (Vhead bool n bv); destruct (Vhead bool n bv');
destruct (Bv2N n (Vtail bool n bv)); destruct (Bv2N n (Vtail bool n bv')); simpl; auto.
diff --git a/theories/Numbers/Integer/Abstract/ZBase.v b/theories/Numbers/Integer/Abstract/ZBase.v
index 29e18548..0f71f2cc 100644
--- a/theories/Numbers/Integer/Abstract/ZBase.v
+++ b/theories/Numbers/Integer/Abstract/ZBase.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: ZBase.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: ZBase.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Export Decidable.
Require Export ZAxioms.
@@ -36,14 +36,14 @@ Proof NZpred_succ.
Theorem Zeq_refl : forall n : Z, n == n.
Proof (proj1 NZeq_equiv).
-Theorem Zeq_symm : forall n m : Z, n == m -> m == n.
+Theorem Zeq_sym : forall n m : Z, n == m -> m == n.
Proof (proj2 (proj2 NZeq_equiv)).
Theorem Zeq_trans : forall n m p : Z, n == m -> m == p -> n == p.
Proof (proj1 (proj2 NZeq_equiv)).
-Theorem Zneq_symm : forall n m : Z, n ~= m -> m ~= n.
-Proof NZneq_symm.
+Theorem Zneq_sym : forall n m : Z, n ~= m -> m ~= n.
+Proof NZneq_sym.
Theorem Zsucc_inj : forall n1 n2 : Z, S n1 == S n2 -> n1 == n2.
Proof NZsucc_inj.
diff --git a/theories/Numbers/Integer/Abstract/ZDomain.v b/theories/Numbers/Integer/Abstract/ZDomain.v
index 15beb2b9..9a17e151 100644
--- a/theories/Numbers/Integer/Abstract/ZDomain.v
+++ b/theories/Numbers/Integer/Abstract/ZDomain.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: ZDomain.v 10934 2008-05-15 21:58:20Z letouzey $ i*)
+(*i $Id: ZDomain.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Export NumPrelude.
@@ -49,7 +49,7 @@ assert (x == y); [rewrite Exx'; now rewrite Eyy' |
rewrite <- H2; assert (H3 : e x y); [now apply -> eq_equiv_e | now inversion H3]]].
Qed.
-Theorem neq_symm : forall n m, n # m -> m # n.
+Theorem neq_sym : forall n m, n # m -> m # n.
Proof.
intros n m H1 H2; symmetry in H2; false_hyp H2 H1.
Qed.
diff --git a/theories/Numbers/Integer/Abstract/ZMulOrder.v b/theories/Numbers/Integer/Abstract/ZMulOrder.v
index e3f1d9aa..c7996ffd 100644
--- a/theories/Numbers/Integer/Abstract/ZMulOrder.v
+++ b/theories/Numbers/Integer/Abstract/ZMulOrder.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: ZMulOrder.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: ZMulOrder.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Export ZAddOrder.
@@ -173,7 +173,7 @@ Notation Zmul_neg := Zlt_mul_0 (only parsing).
Theorem Zle_0_mul :
forall n m : Z, 0 <= n * m -> 0 <= n /\ 0 <= m \/ n <= 0 /\ m <= 0.
Proof.
-assert (R : forall n : Z, 0 == n <-> n == 0) by (intros; split; apply Zeq_symm).
+assert (R : forall n : Z, 0 == n <-> n == 0) by (intros; split; apply Zeq_sym).
intros n m. repeat rewrite Zlt_eq_cases. repeat rewrite R.
rewrite Zlt_0_mul, Zeq_mul_0.
pose proof (Zlt_trichotomy n 0); pose proof (Zlt_trichotomy m 0). tauto.
@@ -184,7 +184,7 @@ Notation Zmul_nonneg := Zle_0_mul (only parsing).
Theorem Zle_mul_0 :
forall n m : Z, n * m <= 0 -> 0 <= n /\ m <= 0 \/ n <= 0 /\ 0 <= m.
Proof.
-assert (R : forall n : Z, 0 == n <-> n == 0) by (intros; split; apply Zeq_symm).
+assert (R : forall n : Z, 0 == n <-> n == 0) by (intros; split; apply Zeq_sym).
intros n m. repeat rewrite Zlt_eq_cases. repeat rewrite R.
rewrite Zlt_mul_0, Zeq_mul_0.
pose proof (Zlt_trichotomy n 0); pose proof (Zlt_trichotomy m 0). tauto.
diff --git a/theories/Numbers/Integer/BigZ/BigZ.v b/theories/Numbers/Integer/BigZ/BigZ.v
index cb920124..e5e950ac 100644
--- a/theories/Numbers/Integer/BigZ/BigZ.v
+++ b/theories/Numbers/Integer/BigZ/BigZ.v
@@ -8,7 +8,7 @@
(* Benjamin Gregoire, Laurent Thery, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: BigZ.v 11282 2008-07-28 11:51:53Z msozeau $ i*)
+(*i $Id: BigZ.v 11576 2008-11-10 19:13:15Z msozeau $ i*)
Require Export BigN.
Require Import ZMulOrder.
@@ -104,8 +104,6 @@ exact sub_opp.
exact add_opp.
Qed.
-Typeclasses unfold NZadd NZmul NZsub NZeq.
-
Add Ring BigZr : BigZring.
(** Todo: tactic translating from [BigZ] to [Z] + omega *)
diff --git a/theories/Numbers/Integer/BigZ/ZMake.v b/theories/Numbers/Integer/BigZ/ZMake.v
index 6305156b..98ad4c64 100644
--- a/theories/Numbers/Integer/BigZ/ZMake.v
+++ b/theories/Numbers/Integer/BigZ/ZMake.v
@@ -8,7 +8,7 @@
(* Benjamin Gregoire, Laurent Thery, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: ZMake.v 11282 2008-07-28 11:51:53Z msozeau $ i*)
+(*i $Id: ZMake.v 11576 2008-11-10 19:13:15Z msozeau $ i*)
Require Import ZArith.
Require Import BigNumPrelude.
@@ -30,7 +30,6 @@ Module Make (N:NType) <: ZType.
| Neg : N.t -> t_.
Definition t := t_.
- Typeclasses unfold t.
Definition zero := Pos N.zero.
Definition one := Pos N.one.
diff --git a/theories/Numbers/Integer/NatPairs/ZNatPairs.v b/theories/Numbers/Integer/NatPairs/ZNatPairs.v
index 8b3d815d..9427b37b 100644
--- a/theories/Numbers/Integer/NatPairs/ZNatPairs.v
+++ b/theories/Numbers/Integer/NatPairs/ZNatPairs.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: ZNatPairs.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: ZNatPairs.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Import NSub. (* The most complete file for natural numbers *)
Require Export ZMulOrder. (* The most complete file for integers *)
@@ -110,7 +110,7 @@ Proof.
unfold reflexive, Zeq. reflexivity.
Qed.
-Theorem ZE_symm : symmetric Z Zeq.
+Theorem ZE_sym : symmetric Z Zeq.
Proof.
unfold symmetric, Zeq; now symmetry.
Qed.
@@ -127,7 +127,7 @@ Qed.
Theorem NZeq_equiv : equiv Z Zeq.
Proof.
-unfold equiv; repeat split; [apply ZE_refl | apply ZE_trans | apply ZE_symm].
+unfold equiv; repeat split; [apply ZE_refl | apply ZE_trans | apply ZE_sym].
Qed.
Add Relation Z Zeq
diff --git a/theories/Numbers/NatInt/NZBase.v b/theories/Numbers/NatInt/NZBase.v
index 8b01e353..bd4d6232 100644
--- a/theories/Numbers/NatInt/NZBase.v
+++ b/theories/Numbers/NatInt/NZBase.v
@@ -8,14 +8,14 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NZBase.v 10934 2008-05-15 21:58:20Z letouzey $ i*)
+(*i $Id: NZBase.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Import NZAxioms.
Module NZBasePropFunct (Import NZAxiomsMod : NZAxiomsSig).
Open Local Scope NatIntScope.
-Theorem NZneq_symm : forall n m : NZ, n ~= m -> m ~= n.
+Theorem NZneq_sym : forall n m : NZ, n ~= m -> m ~= n.
Proof.
intros n m H1 H2; symmetry in H2; false_hyp H2 H1.
Qed.
diff --git a/theories/Numbers/NatInt/NZOrder.v b/theories/Numbers/NatInt/NZOrder.v
index 15004824..d0e2faf8 100644
--- a/theories/Numbers/NatInt/NZOrder.v
+++ b/theories/Numbers/NatInt/NZOrder.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NZOrder.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: NZOrder.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Import NZAxioms.
Require Import NZMul.
@@ -118,7 +118,7 @@ Qed.
Theorem NZneq_succ_diag_r : forall n : NZ, n ~= S n.
Proof.
-intro n; apply NZneq_symm; apply NZneq_succ_diag_l.
+intro n; apply NZneq_sym; apply NZneq_succ_diag_l.
Qed.
Theorem NZnlt_succ_diag_l : forall n : NZ, ~ S n < n.
diff --git a/theories/Numbers/Natural/Abstract/NAdd.v b/theories/Numbers/Natural/Abstract/NAdd.v
index f58b87d8..91ae5b70 100644
--- a/theories/Numbers/Natural/Abstract/NAdd.v
+++ b/theories/Numbers/Natural/Abstract/NAdd.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NAdd.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: NAdd.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Export NBase.
@@ -103,7 +103,7 @@ Qed.
Theorem succ_add_discr : forall n m : N, m ~= S (n + m).
Proof.
intro n; induct m.
-apply neq_symm. apply neq_succ_0.
+apply neq_sym. apply neq_succ_0.
intros m IH H. apply succ_inj in H. rewrite add_succ_r in H.
unfold not in IH; now apply IH.
Qed.
diff --git a/theories/Numbers/Natural/Abstract/NBase.v b/theories/Numbers/Natural/Abstract/NBase.v
index 3e4032b5..85e2c2ab 100644
--- a/theories/Numbers/Natural/Abstract/NBase.v
+++ b/theories/Numbers/Natural/Abstract/NBase.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NBase.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: NBase.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Export Decidable.
Require Export NAxioms.
@@ -48,14 +48,14 @@ Proof pred_0.
Theorem Neq_refl : forall n : N, n == n.
Proof (proj1 NZeq_equiv).
-Theorem Neq_symm : forall n m : N, n == m -> m == n.
+Theorem Neq_sym : forall n m : N, n == m -> m == n.
Proof (proj2 (proj2 NZeq_equiv)).
Theorem Neq_trans : forall n m p : N, n == m -> m == p -> n == p.
Proof (proj1 (proj2 NZeq_equiv)).
-Theorem neq_symm : forall n m : N, n ~= m -> m ~= n.
-Proof NZneq_symm.
+Theorem neq_sym : forall n m : N, n ~= m -> m ~= n.
+Proof NZneq_sym.
Theorem succ_inj : forall n1 n2 : N, S n1 == S n2 -> n1 == n2.
Proof NZsucc_inj.
@@ -111,7 +111,7 @@ Qed.
Theorem neq_0_succ : forall n : N, 0 ~= S n.
Proof.
-intro n; apply neq_symm; apply neq_succ_0.
+intro n; apply neq_sym; apply neq_succ_0.
Qed.
(* Next, we show that all numbers are nonnegative and recover regular induction
diff --git a/theories/Numbers/Natural/Abstract/NDefOps.v b/theories/Numbers/Natural/Abstract/NDefOps.v
index e15e4672..0a8f5f1e 100644
--- a/theories/Numbers/Natural/Abstract/NDefOps.v
+++ b/theories/Numbers/Natural/Abstract/NDefOps.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NDefOps.v 11039 2008-06-02 23:26:13Z letouzey $ i*)
+(*i $Id: NDefOps.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Import Bool. (* To get the orb and negb function *)
Require Export NStrongRec.
@@ -243,7 +243,7 @@ Definition E2 := prod_rel Neq Neq.
Add Relation (prod N N) E2
reflexivity proved by (prod_rel_refl N N Neq Neq E_equiv E_equiv)
-symmetry proved by (prod_rel_symm N N Neq Neq E_equiv E_equiv)
+symmetry proved by (prod_rel_sym N N Neq Neq E_equiv E_equiv)
transitivity proved by (prod_rel_trans N N Neq Neq E_equiv E_equiv)
as E2_rel.
diff --git a/theories/Numbers/Natural/Abstract/NStrongRec.v b/theories/Numbers/Natural/Abstract/NStrongRec.v
index 031dbdea..c6a6da48 100644
--- a/theories/Numbers/Natural/Abstract/NStrongRec.v
+++ b/theories/Numbers/Natural/Abstract/NStrongRec.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NStrongRec.v 11040 2008-06-03 00:04:16Z letouzey $ i*)
+(*i $Id: NStrongRec.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
(** This file defined the strong (course-of-value, well-founded) recursion
and proves its properties *)
@@ -81,9 +81,9 @@ Proof.
intros n1 n2 H. unfold g. now apply strong_rec_wd.
Qed.
-Theorem NtoA_eq_symm : symmetric (N -> A) (fun_eq Neq Aeq).
+Theorem NtoA_eq_sym : symmetric (N -> A) (fun_eq Neq Aeq).
Proof.
-apply fun_eq_symm.
+apply fun_eq_sym.
exact (proj2 (proj2 NZeq_equiv)).
exact (proj2 (proj2 Aeq_equiv)).
Qed.
@@ -97,7 +97,7 @@ exact (proj1 (proj2 Aeq_equiv)).
Qed.
Add Relation (N -> A) (fun_eq Neq Aeq)
- symmetry proved by NtoA_eq_symm
+ symmetry proved by NtoA_eq_sym
transitivity proved by NtoA_eq_trans
as NtoA_eq_rel.
diff --git a/theories/Numbers/Natural/BigN/BigN.v b/theories/Numbers/Natural/BigN/BigN.v
index 41c255b1..16007656 100644
--- a/theories/Numbers/Natural/BigN/BigN.v
+++ b/theories/Numbers/Natural/BigN/BigN.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: BigN.v 11282 2008-07-28 11:51:53Z msozeau $ i*)
+(*i $Id: BigN.v 11576 2008-11-10 19:13:15Z msozeau $ i*)
(** * Natural numbers in base 2^31 *)
@@ -78,8 +78,6 @@ exact mul_assoc.
exact mul_add_distr_r.
Qed.
-Typeclasses unfold NZadd NZsub NZmul.
-
Add Ring BigNr : BigNring.
(** Todo: tactic translating from [BigN] to [Z] + omega *)
diff --git a/theories/Numbers/Natural/BigN/NMake_gen.ml b/theories/Numbers/Natural/BigN/NMake_gen.ml
index 4d6b45c5..04c7b96d 100644
--- a/theories/Numbers/Natural/BigN/NMake_gen.ml
+++ b/theories/Numbers/Natural/BigN/NMake_gen.ml
@@ -8,7 +8,7 @@
(* Benjamin Gregoire, Laurent Thery, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NMake_gen.ml 11282 2008-07-28 11:51:53Z msozeau $ i*)
+(*i $Id: NMake_gen.ml 11576 2008-11-10 19:13:15Z msozeau $ i*)
(*S NMake_gen.ml : this file generates NMake.v *)
@@ -139,7 +139,6 @@ let _ =
pr "";
pr " Definition %s := %s_." t t;
pr "";
- pr " Typeclasses unfold %s." t;
pr " Definition w_0 := w0_op.(znz_0).";
pr "";
diff --git a/theories/Numbers/NumPrelude.v b/theories/Numbers/NumPrelude.v
index fdccf214..95d8b366 100644
--- a/theories/Numbers/NumPrelude.v
+++ b/theories/Numbers/NumPrelude.v
@@ -8,7 +8,7 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-(*i $Id: NumPrelude.v 10943 2008-05-19 08:45:13Z letouzey $ i*)
+(*i $Id: NumPrelude.v 11674 2008-12-12 19:48:40Z letouzey $ i*)
Require Export Setoid.
@@ -212,7 +212,7 @@ unfold reflexive, prod_rel.
destruct x; split; [apply (proj1 EA_equiv) | apply (proj1 EB_equiv)]; simpl.
Qed.
-Lemma prod_rel_symm : symmetric (A * B) prod_rel.
+Lemma prod_rel_sym : symmetric (A * B) prod_rel.
Proof.
unfold symmetric, prod_rel.
destruct x; destruct y;
@@ -229,7 +229,7 @@ Qed.
Theorem prod_rel_equiv : equiv (A * B) prod_rel.
Proof.
-unfold equiv; split; [exact prod_rel_refl | split; [exact prod_rel_trans | exact prod_rel_symm]].
+unfold equiv; split; [exact prod_rel_refl | split; [exact prod_rel_trans | exact prod_rel_sym]].
Qed.
End RelationOnProduct.
diff --git a/theories/Program/Basics.v b/theories/Program/Basics.v
index a1a78acc..29494069 100644
--- a/theories/Program/Basics.v
+++ b/theories/Program/Basics.v
@@ -5,19 +5,19 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* $Id: Basics.v 11709 2008-12-20 11:42:15Z msozeau $ *)
-(* Standard functions and combinators.
- * Proofs about them require functional extensionality and can be found in [Combinators].
- *
- * Author: Matthieu Sozeau
- * Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
- * 91405 Orsay, France *)
+(** Standard functions and combinators.
+
+ Proofs about them require functional extensionality and can be found in [Combinators].
-(* $Id: Basics.v 11046 2008-06-03 22:48:06Z msozeau $ *)
+ Author: Matthieu Sozeau
+ Institution: LRI, CNRS UMR 8623 - Université Paris Sud
+ 91405 Orsay, France *)
-(** The polymorphic identity function. *)
+(** The polymorphic identity function is defined in [Datatypes]. *)
-Definition id {A} := fun x : A => x.
+Implicit Arguments id [[A]].
(** Function composition. *)
diff --git a/theories/Program/Combinators.v b/theories/Program/Combinators.v
index e267fbbe..ae9749de 100644
--- a/theories/Program/Combinators.v
+++ b/theories/Program/Combinators.v
@@ -5,15 +5,16 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* $Id: Combinators.v 11709 2008-12-20 11:42:15Z msozeau $ *)
-(* Proofs about standard combinators, exports functional extensionality.
- *
- * Author: Matthieu Sozeau
- * Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
- * 91405 Orsay, France *)
+(** Proofs about standard combinators, exports functional extensionality.
+
+ Author: Matthieu Sozeau
+ Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
+ 91405 Orsay, France *)
Require Import Coq.Program.Basics.
-Require Export Coq.Program.FunctionalExtensionality.
+Require Export FunctionalExtensionality.
Open Scope program_scope.
@@ -40,7 +41,8 @@ Proof.
reflexivity.
Qed.
-Hint Rewrite @compose_id_left @compose_id_right @compose_assoc : core.
+Hint Rewrite @compose_id_left @compose_id_right : core.
+Hint Rewrite <- @compose_assoc : core.
(** [flip] is involutive. *)
diff --git a/theories/Program/Equality.v b/theories/Program/Equality.v
index c776070a..99d54755 100644
--- a/theories/Program/Equality.v
+++ b/theories/Program/Equality.v
@@ -1,4 +1,4 @@
-(* -*- coq-prog-args: ("-emacs-U") -*- *)
+(* -*- coq-prog-name: "~/research/coq/trunk/bin/coqtop.byte"; coq-prog-args: ("-emacs-U"); compile-command: "make -C ../.. TIME='time'" -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -7,7 +7,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Equality.v 11282 2008-07-28 11:51:53Z msozeau $ i*)
+(*i $Id: Equality.v 11709 2008-12-20 11:42:15Z msozeau $ i*)
(** Tactics related to (dependent) equality and proof irrelevance. *)
@@ -20,6 +20,10 @@ Require Import Coq.Program.Tactics.
Notation " [ x : X ] = [ y : Y ] " := (@JMeq X x Y y) (at level 0, X at next level, Y at next level).
+(** Notation for the single element of [x = x] *)
+
+Notation "'refl'" := (@refl_equal _ _).
+
(** Do something on an heterogeneous equality appearing in the context. *)
Ltac on_JMeq tac :=
@@ -30,7 +34,7 @@ Ltac on_JMeq tac :=
(** Try to apply [JMeq_eq] to get back a regular equality when the two types are equal. *)
Ltac simpl_one_JMeq :=
- on_JMeq ltac:(fun H => replace_hyp H (JMeq_eq H)).
+ on_JMeq ltac:(fun H => apply JMeq_eq in H).
(** Repeat it for every possible hypothesis. *)
@@ -185,7 +189,6 @@ Ltac simplify_eqs :=
(** A tactic that tries to remove trivial equality guards in induction hypotheses coming
from [dependent induction]/[generalize_eqs] invocations. *)
-
Ltac simpl_IH_eq H :=
match type of H with
| @JMeq _ ?x _ _ -> _ =>
@@ -224,9 +227,291 @@ Ltac do_simpl_IHs_eqs :=
Ltac simpl_IHs_eqs := repeat do_simpl_IHs_eqs.
-Ltac simpl_depind := subst* ; autoinjections ; try discriminates ;
+(** We split substitution tactics in the two directions depending on which
+ names we want to keep corresponding to the generalization performed by the
+ [generalize_eqs] tactic. *)
+
+Ltac subst_left_no_fail :=
+ repeat (match goal with
+ [ H : ?X = ?Y |- _ ] => subst X
+ end).
+
+Ltac subst_right_no_fail :=
+ repeat (match goal with
+ [ H : ?X = ?Y |- _ ] => subst Y
+ end).
+
+Ltac inject_left H :=
+ progress (inversion H ; subst_left_no_fail ; clear_dups) ; clear H.
+
+Ltac inject_right H :=
+ progress (inversion H ; subst_right_no_fail ; clear_dups) ; clear H.
+
+Ltac autoinjections_left := repeat autoinjection ltac:inject_left.
+Ltac autoinjections_right := repeat autoinjection ltac:inject_right.
+
+Ltac simpl_depind := subst_no_fail ; autoinjections ; try discriminates ;
+ simpl_JMeq ; simpl_existTs ; simpl_IHs_eqs.
+
+Ltac simpl_depind_l := subst_left_no_fail ; autoinjections_left ; try discriminates ;
simpl_JMeq ; simpl_existTs ; simpl_IHs_eqs.
+Ltac simpl_depind_r := subst_right_no_fail ; autoinjections_right ; try discriminates ;
+ simpl_JMeq ; simpl_existTs ; simpl_IHs_eqs.
+
+(** Support for the [Equations] command.
+ These tactics implement the necessary machinery to solve goals produced by the
+ [Equations] command relative to dependent pattern-matching.
+ It is completely inspired from the "Eliminating Dependent Pattern-Matching" paper by
+ Goguen, McBride and McKinna. *)
+
+
+(** The NoConfusionPackage class provides a method for making progress on proving a property
+ [P] implied by an equality on an inductive type [I]. The type of [noConfusion] for a given
+ [P] should be of the form [ Π Δ, (x y : I Δ) (x = y) -> NoConfusion P x y ], where
+ [NoConfusion P x y] for constructor-headed [x] and [y] will give a formula ending in [P].
+ This gives a general method for simplifying by discrimination or injectivity of constructors.
+
+ Some actual instances are defined later in the file using the more primitive [discriminate] and
+ [injection] tactics on which we can always fall back.
+ *)
+
+Class NoConfusionPackage (I : Type) := { NoConfusion : Π P : Prop, Type ; noConfusion : Π P, NoConfusion P }.
+
+(** The [DependentEliminationPackage] provides the default dependent elimination principle to
+ be used by the [equations] resolver. It is especially useful to register the dependent elimination
+ principles for things in [Prop] which are not automatically generated. *)
+
+Class DependentEliminationPackage (A : Type) :=
+ { elim_type : Type ; elim : elim_type }.
+
+(** A higher-order tactic to apply a registered eliminator. *)
+
+Ltac elim_tac tac p :=
+ let ty := type of p in
+ let eliminator := eval simpl in (elim (A:=ty)) in
+ tac p eliminator.
+
+(** Specialization to do case analysis or induction.
+ Note: the [equations] tactic tries [case] before [elim_case]: there is no need to register
+ generated induction principles. *)
+
+Ltac elim_case p := elim_tac ltac:(fun p el => destruct p using el) p.
+Ltac elim_ind p := elim_tac ltac:(fun p el => induction p using el) p.
+
+(** The [BelowPackage] class provides the definition of a [Below] predicate for some datatype,
+ allowing to talk about course-of-value recursion on it. *)
+
+Class BelowPackage (A : Type) := {
+ Below : A -> Type ;
+ below : Π (a : A), Below a }.
+
+(** The [Recursor] class defines a recursor on a type, based on some definition of [Below]. *)
+
+Class Recursor (A : Type) (BP : BelowPackage A) :=
+ { rec_type : A -> Type ; rec : Π (a : A), rec_type a }.
+
+(** Lemmas used by the simplifier, mainly rephrasings of [eq_rect], [eq_ind]. *)
+
+Lemma solution_left : Π A (B : A -> Type) (t : A), B t -> (Π x, x = t -> B x).
+Proof. intros; subst. apply X. Defined.
+
+Lemma solution_right : Π A (B : A -> Type) (t : A), B t -> (Π x, t = x -> B x).
+Proof. intros; subst; apply X. Defined.
+
+Lemma deletion : Π A B (t : A), B -> (t = t -> B).
+Proof. intros; assumption. Defined.
+
+Lemma simplification_heq : Π A B (x y : A), (x = y -> B) -> (JMeq x y -> B).
+Proof. intros; apply X; apply (JMeq_eq H). Defined.
+
+Lemma simplification_existT2 : Π A (P : A -> Type) B (p : A) (x y : P p),
+ (x = y -> B) -> (existT P p x = existT P p y -> B).
+Proof. intros. apply X. apply inj_pair2. exact H. Defined.
+
+Lemma simplification_existT1 : Π A (P : A -> Type) B (p q : A) (x : P p) (y : P q),
+ (p = q -> existT P p x = existT P q y -> B) -> (existT P p x = existT P q y -> B).
+Proof. intros. injection H. intros ; auto. Defined.
+
+Lemma simplification_K : Π A (x : A) (B : x = x -> Type), B (refl_equal x) -> (Π p : x = x, B p).
+Proof. intros. rewrite (UIP_refl A). assumption. Defined.
+
+(** This hint database and the following tactic can be used with [autosimpl] to
+ unfold everything to [eq_rect]s. *)
+
+Hint Unfold solution_left solution_right deletion simplification_heq
+ simplification_existT1 simplification_existT2
+ eq_rect_r eq_rec eq_ind : equations.
+
+(** Simply unfold as much as possible. *)
+
+Ltac unfold_equations := repeat progress autosimpl with equations.
+
+(** The tactic [simplify_equations] is to be used when a program generated using [Equations]
+ is in the goal. It simplifies it as much as possible, possibly using [K] if needed. *)
+
+Ltac simplify_equations := repeat (unfold_equations ; simplify_eqs).
+
+(** We will use the [block_induction] definition to separate the goal from the
+ equalities generated by the tactic. *)
+
+Definition block_dep_elim {A : Type} (a : A) := a.
+
+(** Using these we can make a simplifier that will perform the unification
+ steps needed to put the goal in normalised form (provided there are only
+ constructor forms). Compare with the lemma 16 of the paper.
+ We don't have a [noCycle] procedure yet. *)
+
+Ltac simplify_one_dep_elim_term c :=
+ match c with
+ | @JMeq _ _ _ _ -> _ => refine (simplification_heq _ _ _ _ _)
+ | ?t = ?t -> _ => intros _ || refine (simplification_K _ t _ _)
+ | eq (existT _ _ _) (existT _ _ _) -> _ =>
+ refine (simplification_existT2 _ _ _ _ _ _ _) ||
+ refine (simplification_existT1 _ _ _ _ _ _ _ _)
+ | ?x = ?y -> _ => (* variables case *)
+ (let hyp := fresh in intros hyp ;
+ move hyp before x ;
+ generalize dependent x ; refine (solution_left _ _ _ _) ; intros until 0) ||
+ (let hyp := fresh in intros hyp ;
+ move hyp before y ;
+ generalize dependent y ; refine (solution_right _ _ _ _) ; intros until 0)
+ | @eq ?A ?t ?u -> ?P => apply (noConfusion (I:=A) P)
+ | ?f ?x = ?g ?y -> _ => let H := fresh in progress (intros H ; injection H ; clear H)
+ | ?t = ?u -> _ => let hyp := fresh in
+ intros hyp ; elimtype False ; discriminate
+ | ?x = ?y -> _ => let hyp := fresh in
+ intros hyp ; (try (clear hyp ; (* If non dependent, don't clear it! *) fail 1)) ;
+ case hyp ; clear hyp
+ | block_dep_elim ?T => fail 1 (* Do not put any part of the rhs in the hyps *)
+ | _ => intro
+ end.
+
+Ltac simplify_one_dep_elim :=
+ match goal with
+ | [ |- ?gl ] => simplify_one_dep_elim_term gl
+ end.
+
+(** Repeat until no progress is possible. By construction, it should leave the goal with
+ no remaining equalities generated by the [generalize_eqs] tactic. *)
+
+Ltac simplify_dep_elim := repeat simplify_one_dep_elim.
+
+(** To dependent elimination on some hyp. *)
+
+Ltac depelim id :=
+ generalize_eqs id ; destruct id ; simplify_dep_elim.
+
+(** Do dependent elimination of the last hypothesis, but not simplifying yet
+ (used internally). *)
+
+Ltac destruct_last :=
+ on_last_hyp ltac:(fun id => simpl in id ; generalize_eqs id ; destruct id).
+
+(** The rest is support tactics for the [Equations] command. *)
+
+(** Notation for inaccessible patterns. *)
+
+Definition inaccessible_pattern {A : Type} (t : A) := t.
+
+Notation "?( t )" := (inaccessible_pattern t).
+
+(** To handle sections, we need to separate the context in two parts:
+ variables introduced by the section and the rest. We introduce a dummy variable
+ between them to indicate that. *)
+
+CoInductive end_of_section := the_end_of_the_section.
+
+Ltac set_eos := let eos := fresh "eos" in
+ assert (eos:=the_end_of_the_section).
+
+(** We have a specialized [reverse_local] tactic to reverse the goal until the begining of the
+ section variables *)
+
+Ltac reverse_local :=
+ match goal with
+ | [ H : ?T |- _ ] =>
+ match T with
+ | end_of_section => idtac | _ => revert H ; reverse_local end
+ | _ => idtac
+ end.
+
+(** Do as much as possible to apply a method, trying to get the arguments right.
+ !!Unsafe!! We use [auto] for the [_nocomp] variant of [Equations], in which case some
+ non-dependent arguments of the method can remain after [apply]. *)
+
+Ltac simpl_intros m := ((apply m || refine m) ; auto) || (intro ; simpl_intros m).
+
+(** Hopefully the first branch suffices. *)
+
+Ltac try_intros m :=
+ solve [ intros ; unfold block_dep_elim ; refine m || apply m ] ||
+ solve [ unfold block_dep_elim ; simpl_intros m ].
+
+(** To solve a goal by inversion on a particular target. *)
+
+Ltac solve_empty target :=
+ do_nat target intro ; elimtype False ; destruct_last ; simplify_dep_elim.
+
+Ltac simplify_method tac := repeat (tac || simplify_one_dep_elim) ; reverse_local.
+
+(** Solving a method call: we can solve it by splitting on an empty family member
+ or we must refine the goal until the body can be applied. *)
+
+Ltac solve_method rec :=
+ match goal with
+ | [ H := ?body : nat |- _ ] => subst H ; clear ; abstract (simplify_method idtac ; solve_empty body)
+ | [ H := [ ?body ] : ?T |- _ ] => clear H ; simplify_method ltac:(exact body) ; rec ; try_intros (body:T)
+ end.
+
+(** Impossible cases, by splitting on a given target. *)
+
+Ltac solve_split :=
+ match goal with
+ | [ |- let split := ?x : nat in _ ] => clear ; abstract (intros _ ; solve_empty x)
+ end.
+
+(** If defining recursive functions, the prototypes come first. *)
+
+Ltac intro_prototypes :=
+ match goal with
+ | [ |- Π x : _, _ ] => intro ; intro_prototypes
+ | _ => idtac
+ end.
+
+Ltac do_case p := destruct p || elim_case p || (case p ; clear p).
+Ltac do_ind p := induction p || elim_ind p.
+
+Ltac dep_elimify := match goal with [ |- ?T ] => change (block_dep_elim T) end.
+
+Ltac un_dep_elimify := unfold block_dep_elim in *.
+
+Ltac case_last := dep_elimify ;
+ on_last_hyp ltac:(fun p =>
+ let ty := type of p in
+ match ty with
+ | ?x = ?x => revert p ; refine (simplification_K _ x _ _)
+ | ?x = ?y => revert p
+ | _ => simpl in p ; generalize_eqs p ; do_case p
+ end).
+
+Ltac nonrec_equations :=
+ solve [solve_equations (case_last) (solve_method idtac)] || solve [ solve_split ]
+ || fail "Unnexpected equations goal".
+
+Ltac recursive_equations :=
+ solve [solve_equations (case_last) (solve_method ltac:intro)] || solve [ solve_split ]
+ || fail "Unnexpected recursive equations goal".
+
+(** The [equations] tactic is the toplevel tactic for solving goals generated
+ by [Equations]. *)
+
+Ltac equations := set_eos ;
+ match goal with
+ | [ |- Π x : _, _ ] => intro ; recursive_equations
+ | _ => nonrec_equations
+ end.
+
(** The following tactics allow to do induction on an already instantiated inductive predicate
by first generalizing it and adding the proper equalities to the context, in a maner similar to
the BasicElim tactic of "Elimination with a motive" by Conor McBride. *)
@@ -235,43 +520,49 @@ Ltac simpl_depind := subst* ; autoinjections ; try discriminates ;
and starts a dependent induction using this tactic. *)
Ltac do_depind tac H :=
- generalize_eqs_vars H ; tac H ; repeat progress simpl_depind.
+ (try intros until H) ; dep_elimify ; generalize_eqs_vars H ; tac H ; simplify_dep_elim ; un_dep_elimify.
(** A variant where generalized variables should be given by the user. *)
Ltac do_depind' tac H :=
- generalize_eqs H ; tac H ; repeat progress simpl_depind.
+ (try intros until H) ; dep_elimify ; generalize_eqs H ; tac H ; simplify_dep_elim ; un_dep_elimify.
-(** Calls [destruct] on the generalized hypothesis, results should be similar to inversion. *)
+(** Calls [destruct] on the generalized hypothesis, results should be similar to inversion.
+ By default, we don't try to generalize the hyp by its variable indices. *)
Tactic Notation "dependent" "destruction" ident(H) :=
- do_depind ltac:(fun hyp => destruct hyp ; intros) H ; subst*.
+ do_depind' ltac:(fun hyp => do_case hyp) H.
Tactic Notation "dependent" "destruction" ident(H) "using" constr(c) :=
- do_depind ltac:(fun hyp => destruct hyp using c ; intros) H.
+ do_depind' ltac:(fun hyp => destruct hyp using c) H.
(** This tactic also generalizes the goal by the given variables before the induction. *)
Tactic Notation "dependent" "destruction" ident(H) "generalizing" ne_hyp_list(l) :=
- do_depind' ltac:(fun hyp => revert l ; destruct hyp ; intros) H.
+ do_depind' ltac:(fun hyp => revert l ; do_case hyp) H.
Tactic Notation "dependent" "destruction" ident(H) "generalizing" ne_hyp_list(l) "using" constr(c) :=
- do_depind' ltac:(fun hyp => revert l ; destruct hyp using c ; intros) H.
+ do_depind' ltac:(fun hyp => revert l ; destruct hyp using c) H.
(** Then we have wrappers for usual calls to induction. One can customize the induction tactic by
- writting another wrapper calling do_depind. *)
+ writting another wrapper calling do_depind. We suppose the hyp has to be generalized before
+ calling [induction]. *)
Tactic Notation "dependent" "induction" ident(H) :=
- do_depind ltac:(fun hyp => induction hyp ; intros) H.
+ do_depind ltac:(fun hyp => do_ind hyp) H.
Tactic Notation "dependent" "induction" ident(H) "using" constr(c) :=
- do_depind ltac:(fun hyp => induction hyp using c ; intros) H.
+ do_depind ltac:(fun hyp => induction hyp using c) H.
(** This tactic also generalizes the goal by the given variables before the induction. *)
Tactic Notation "dependent" "induction" ident(H) "generalizing" ne_hyp_list(l) :=
- do_depind' ltac:(fun hyp => generalize l ; clear l ; induction hyp ; intros) H.
+ do_depind' ltac:(fun hyp => generalize l ; clear l ; do_ind hyp) H.
Tactic Notation "dependent" "induction" ident(H) "generalizing" ne_hyp_list(l) "using" constr(c) :=
- do_depind' ltac:(fun hyp => generalize l ; clear l ; induction hyp using c ; intros) H.
+ do_depind' ltac:(fun hyp => generalize l ; clear l ; induction hyp using c) H.
+Ltac simplify_IH_hyps := repeat
+ match goal with
+ | [ hyp : _ |- _ ] => specialize_hypothesis hyp
+ end. \ No newline at end of file
diff --git a/theories/Program/FunctionalExtensionality.v b/theories/Program/FunctionalExtensionality.v
deleted file mode 100644
index b5ad5b4d..00000000
--- a/theories/Program/FunctionalExtensionality.v
+++ /dev/null
@@ -1,109 +0,0 @@
-(* -*- coq-prog-args: ("-emacs-U" "-nois") -*- *)
-(************************************************************************)
-(* 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: FunctionalExtensionality.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
-
-(** This module states the axiom of (dependent) functional extensionality and (dependent) eta-expansion.
- It introduces a tactic [extensionality] to apply the axiom of extensionality to an equality goal.
-
- It also defines two lemmas for expansion of fixpoint defs using extensionnality and proof-irrelevance
- to avoid a side condition on the functionals. *)
-
-Require Import Coq.Program.Utils.
-Require Import Coq.Program.Wf.
-Require Import Coq.Program.Equality.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-
-(** The converse of functional equality. *)
-
-Lemma equal_f : forall A B : Type, forall (f g : A -> B),
- f = g -> forall x, f x = g x.
-Proof.
- intros.
- rewrite H.
- auto.
-Qed.
-
-(** Statements of functional equality for simple and dependent functions. *)
-
-Axiom fun_extensionality_dep : forall A, forall B : (A -> Type),
- forall (f g : forall x : A, B x),
- (forall x, f x = g x) -> f = g.
-
-Lemma fun_extensionality : forall A B (f g : A -> B),
- (forall x, f x = g x) -> f = g.
-Proof.
- intros ; apply fun_extensionality_dep.
- assumption.
-Qed.
-
-Hint Resolve fun_extensionality fun_extensionality_dep : program.
-
-(** Apply [fun_extensionality], introducing variable x. *)
-
-Tactic Notation "extensionality" ident(x) :=
- match goal with
- [ |- ?X = ?Y ] => apply (@fun_extensionality _ _ X Y) || apply (@fun_extensionality_dep _ _ X Y) ; intro x
- end.
-
-(** Eta expansion follows from extensionality. *)
-
-Lemma eta_expansion_dep : forall A (B : A -> Type) (f : forall x : A, B x),
- f = fun x => f x.
-Proof.
- intros.
- extensionality x.
- reflexivity.
-Qed.
-
-Lemma eta_expansion : forall A B (f : A -> B),
- f = fun x => f x.
-Proof.
- intros ; apply eta_expansion_dep.
-Qed.
-
-(** The two following lemmas allow to unfold a well-founded fixpoint definition without
- restriction using the functional extensionality axiom. *)
-
-(** For a function defined with Program using a well-founded order. *)
-
-Program Lemma fix_sub_eq_ext :
- forall (A : Set) (R : A -> A -> Prop) (Rwf : well_founded R)
- (P : A -> Set)
- (F_sub : forall x : A, (forall (y : A | R y x), P y) -> P x),
- forall x : A,
- Fix_sub A R Rwf P F_sub x =
- F_sub x (fun (y : A | R y x) => Fix A R Rwf P F_sub y).
-Proof.
- intros ; apply Fix_eq ; auto.
- intros.
- assert(f = g).
- extensionality y ; apply H.
- rewrite H0 ; auto.
-Qed.
-
-(** For a function defined with Program using a measure. *)
-
-Program Lemma fix_sub_measure_eq_ext :
- forall (A : Type) (f : A -> nat) (P : A -> Type)
- (F_sub : forall x : A, (forall (y : A | f y < f x), P y) -> P x),
- forall x : A,
- Fix_measure_sub A f P F_sub x =
- F_sub x (fun (y : A | f y < f x) => Fix_measure_sub A f P F_sub y).
-Proof.
- intros ; apply Fix_measure_eq ; auto.
- intros.
- assert(f0 = g).
- extensionality y ; apply H.
- rewrite H0 ; auto.
-Qed.
-
-
diff --git a/theories/Program/Program.v b/theories/Program/Program.v
index b6c3031e..7d0c3948 100644
--- a/theories/Program/Program.v
+++ b/theories/Program/Program.v
@@ -1,3 +1,12 @@
+(************************************************************************)
+(* 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 *)
+(************************************************************************)
+(* $Id: Program.v 11709 2008-12-20 11:42:15Z msozeau $ *)
+
Require Export Coq.Program.Utils.
Require Export Coq.Program.Wf.
Require Export Coq.Program.Equality.
diff --git a/theories/Program/Subset.v b/theories/Program/Subset.v
index d021326a..3d551281 100644
--- a/theories/Program/Subset.v
+++ b/theories/Program/Subset.v
@@ -5,14 +5,15 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* $Id: Subset.v 11709 2008-12-20 11:42:15Z msozeau $ *)
+
+(** Tactics related to subsets and proof irrelevance. *)
Require Import Coq.Program.Utils.
Require Import Coq.Program.Equality.
Open Local Scope program_scope.
-(** Tactics related to subsets and proof irrelevance. *)
-
(** The following tactics implement a poor-man's solution for proof-irrelevance: it tries to
factorize every proof of the same proposition in a goal so that equality of such proofs becomes trivial. *)
diff --git a/theories/Program/Syntax.v b/theories/Program/Syntax.v
index 6cd75257..222b5c8d 100644
--- a/theories/Program/Syntax.v
+++ b/theories/Program/Syntax.v
@@ -1,4 +1,3 @@
-(* -*- coq-prog-args: ("-emacs-U") -*- *)
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
@@ -6,14 +5,15 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* $Id: Syntax.v 11823 2009-01-21 15:32:37Z msozeau $ *)
-(* Custom notations and implicits for Coq prelude definitions.
- *
- * Author: Matthieu Sozeau
- * Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
- * 91405 Orsay, France *)
+(** Custom notations and implicits for Coq prelude definitions.
-(** Notations for the unit type and value. *)
+ Author: Matthieu Sozeau
+ Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
+ 91405 Orsay, France *)
+
+(** Notations for the unit type and value Ă  la Haskell. *)
Notation " () " := Datatypes.unit : type_scope.
Notation " () " := tt.
@@ -42,7 +42,7 @@ Notation " [ ] " := nil : list_scope.
Notation " [ x ] " := (cons x nil) : list_scope.
Notation " [ x ; .. ; y ] " := (cons x .. (cons y nil) ..) : list_scope.
-(** n-ary exists *)
+(** Treating n-ary exists *)
Notation " 'exists' x y , p" := (ex (fun x => (ex (fun y => p))))
(at level 200, x ident, y ident, right associativity) : type_scope.
@@ -53,7 +53,7 @@ Notation " 'exists' x y z , p" := (ex (fun x => (ex (fun y => (ex (fun z => p)))
Notation " 'exists' x y z w , p" := (ex (fun x => (ex (fun y => (ex (fun z => (ex (fun w => p))))))))
(at level 200, x ident, y ident, z ident, w ident, right associativity) : type_scope.
-Tactic Notation "exist" constr(x) := exists x.
-Tactic Notation "exist" constr(x) constr(y) := exists x ; exists y.
-Tactic Notation "exist" constr(x) constr(y) constr(z) := exists x ; exists y ; exists z.
-Tactic Notation "exist" constr(x) constr(y) constr(z) constr(w) := exists x ; exists y ; exists z ; exists w.
+Tactic Notation "exists" constr(x) := exists x.
+Tactic Notation "exists" constr(x) constr(y) := exists x ; exists y.
+Tactic Notation "exists" constr(x) constr(y) constr(z) := exists x ; exists y ; exists z.
+Tactic Notation "exists" constr(x) constr(y) constr(z) constr(w) := exists x ; exists y ; exists z ; exists w.
diff --git a/theories/Program/Tactics.v b/theories/Program/Tactics.v
index bb5054b4..499629a6 100644
--- a/theories/Program/Tactics.v
+++ b/theories/Program/Tactics.v
@@ -6,11 +6,24 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Tactics.v 11282 2008-07-28 11:51:53Z msozeau $ i*)
+(*i $Id: Tactics.v 11709 2008-12-20 11:42:15Z msozeau $ i*)
(** This module implements various tactics used to simplify the goals produced by Program,
which are also generally useful. *)
+(** The [do] tactic but using a Coq-side nat. *)
+
+Ltac do_nat n tac :=
+ match n with
+ | 0 => idtac
+ | S ?n' => tac ; do_nat n' tac
+ end.
+
+(** Do something on the last hypothesis, or fail *)
+
+Ltac on_last_hyp tac :=
+ match goal with [ H : _ |- _ ] => tac H || fail 1 end.
+
(** Destructs one pair, without care regarding naming. *)
Ltac destruct_one_pair :=
@@ -80,7 +93,7 @@ Ltac clear_dup :=
| [ H' : ?Y |- _ ] =>
match H with
| H' => fail 2
- | _ => conv X Y ; (clear H' || clear H)
+ | _ => unify X Y ; (clear H' || clear H)
end
end
end.
@@ -91,7 +104,7 @@ Ltac clear_dups := repeat clear_dup.
Ltac subst_no_fail :=
repeat (match goal with
- [ H : ?X = ?Y |- _ ] => subst X || subst Y
+ [ H : ?X = ?Y |- _ ] => subst X || subst Y
end).
Tactic Notation "subst" "*" := subst_no_fail.
@@ -108,6 +121,26 @@ Ltac on_application f tac T :=
| context [f ?x ?y] => tac (f x y)
| context [f ?x] => tac (f x)
end.
+
+(** A variant of [apply] using [refine], doing as much conversion as necessary. *)
+
+Ltac rapply p :=
+ refine (p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _ _) ||
+ refine (p _ _ _ _ _) ||
+ refine (p _ _ _ _) ||
+ refine (p _ _ _) ||
+ refine (p _ _) ||
+ refine (p _) ||
+ refine p.
(** Tactical [on_call f tac] applies [tac] on any application of [f] in the hypothesis or goal. *)
@@ -154,13 +187,14 @@ Tactic Notation "destruct_call" constr(f) "as" simple_intropattern(l) "in" hyp(i
(** Try to inject any potential constructor equality hypothesis. *)
-Ltac autoinjection :=
- let tac H := progress (inversion H ; subst ; clear_dups) ; clear H in
- match goal with
- | [ H : ?f ?a = ?f' ?a' |- _ ] => tac H
- end.
+Ltac autoinjection tac :=
+ match goal with
+ | [ H : ?f ?a = ?f' ?a' |- _ ] => tac H
+ end.
+
+Ltac inject H := progress (inversion H ; subst*; clear_dups) ; clear H.
-Ltac autoinjections := repeat autoinjection.
+Ltac autoinjections := repeat (clear_dups ; autoinjection ltac:inject).
(** Destruct an hypothesis by first copying it to avoid dependencies. *)
diff --git a/theories/Program/Utils.v b/theories/Program/Utils.v
index fcd85f41..b08093bf 100644
--- a/theories/Program/Utils.v
+++ b/theories/Program/Utils.v
@@ -6,7 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Utils.v 11309 2008-08-06 10:30:35Z herbelin $ i*)
+(*i $Id: Utils.v 11709 2008-12-20 11:42:15Z msozeau $ i*)
+
+(** Various syntaxic shortands that are useful with [Program]. *)
Require Export Coq.Program.Tactics.
diff --git a/theories/Program/Wf.v b/theories/Program/Wf.v
index b6ba5d44..12bdf3a7 100644
--- a/theories/Program/Wf.v
+++ b/theories/Program/Wf.v
@@ -1,3 +1,15 @@
+(************************************************************************)
+(* 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 *)
+(************************************************************************)
+(* $Id: Wf.v 11709 2008-12-20 11:42:15Z msozeau $ *)
+
+(** Reformulation of the Wf module using subsets where possible, providing
+ the support for [Program]'s treatment of well-founded definitions. *)
+
Require Import Coq.Init.Wf.
Require Import Coq.Program.Utils.
Require Import ProofIrrelevance.
@@ -6,8 +18,6 @@ Open Local Scope program_scope.
Implicit Arguments Acc_inv [A R x y].
-(** Reformulation of the Wellfounded module using subsets where possible. *)
-
Section Well_founded.
Variable A : Type.
Variable R : A -> A -> Prop.
@@ -146,3 +156,196 @@ Section Well_founded_measure.
End Well_founded_measure.
Extraction Inline Fix_measure_F_sub Fix_measure_sub.
+
+Set Implicit Arguments.
+
+(** Reasoning about well-founded fixpoints on measures. *)
+
+Section Measure_well_founded.
+
+ (* Measure relations are well-founded if the underlying relation is well-founded. *)
+
+ Variables T M: Set.
+ Variable R: M -> M -> Prop.
+ Hypothesis wf: well_founded R.
+ Variable m: T -> M.
+
+ Definition MR (x y: T): Prop := R (m x) (m y).
+
+ Lemma measure_wf: well_founded MR.
+ Proof with auto.
+ unfold well_founded.
+ cut (forall a: M, (fun mm: M => forall a0: T, m a0 = mm -> Acc MR a0) a).
+ intros.
+ apply (H (m a))...
+ apply (@well_founded_ind M R wf (fun mm => forall a, m a = mm -> Acc MR a)).
+ intros.
+ apply Acc_intro.
+ intros.
+ unfold MR in H1.
+ rewrite H0 in H1.
+ apply (H (m y))...
+ Defined.
+
+End Measure_well_founded.
+
+Section Fix_measure_rects.
+
+ Variable A: Set.
+ Variable m: A -> nat.
+ Variable P: A -> Type.
+ Variable f: forall (x : A), (forall y: { y: A | m y < m x }, P (proj1_sig y)) -> P x.
+
+ Lemma F_unfold x r:
+ Fix_measure_F_sub A m P f x r =
+ f (fun y => Fix_measure_F_sub A m P f (proj1_sig y) (Acc_inv r (proj2_sig y))).
+ Proof. intros. case r; auto. Qed.
+
+ (* Fix_measure_F_sub_rect lets one prove a property of
+ functions defined using Fix_measure_F_sub by showing
+ that property to be invariant over single application of the
+ function body (f in our case). *)
+
+ Lemma Fix_measure_F_sub_rect
+ (Q: forall x, P x -> Type)
+ (inv: forall x: A,
+ (forall (y: A) (H: MR lt m y x) (a: Acc lt (m y)),
+ Q y (Fix_measure_F_sub A m P f y a)) ->
+ forall (a: Acc lt (m x)),
+ Q x (f (fun y: {y: A | m y < m x} =>
+ Fix_measure_F_sub A m P f (proj1_sig y) (Acc_inv a (proj2_sig y)))))
+ : forall x a, Q _ (Fix_measure_F_sub A m P f x a).
+ Proof with auto.
+ intros Q inv.
+ set (R := fun (x: A) => forall a, Q _ (Fix_measure_F_sub A m P f x a)).
+ cut (forall x, R x)...
+ apply (well_founded_induction_type (measure_wf lt_wf m)).
+ subst R.
+ simpl.
+ intros.
+ rewrite F_unfold...
+ Qed.
+
+ (* Let's call f's second parameter its "lowers" function, since it
+ provides it access to results for inputs with a lower measure.
+
+ In preparation of lemma similar to Fix_measure_F_sub_rect, but
+ for Fix_measure_sub, we first
+ need an extra hypothesis stating that the function body has the
+ same result for different "lowers" functions (g and h below) as long
+ as those produce the same results for lower inputs, regardless
+ of the lt proofs. *)
+
+ Hypothesis equiv_lowers:
+ forall x0 (g h: forall x: {y: A | m y < m x0}, P (proj1_sig x)),
+ (forall x p p', g (exist (fun y: A => m y < m x0) x p) = h (exist _ x p')) ->
+ f g = f h.
+
+ (* From equiv_lowers, it follows that
+ [Fix_measure_F_sub A m P f x] applications do not not
+ depend on the Acc proofs. *)
+
+ Lemma eq_Fix_measure_F_sub x (a a': Acc lt (m x)):
+ Fix_measure_F_sub A m P f x a =
+ Fix_measure_F_sub A m P f x a'.
+ Proof.
+ intros x a.
+ pattern x, (Fix_measure_F_sub A m P f x a).
+ apply Fix_measure_F_sub_rect.
+ intros.
+ rewrite F_unfold.
+ apply equiv_lowers.
+ intros.
+ apply H.
+ assumption.
+ Qed.
+
+ (* Finally, Fix_measure_F_rect lets one prove a property of
+ functions defined using Fix_measure_F by showing that
+ property to be invariant over single application of the function
+ body (f). *)
+
+ Lemma Fix_measure_sub_rect
+ (Q: forall x, P x -> Type)
+ (inv: forall
+ (x: A)
+ (H: forall (y: A), MR lt m y x -> Q y (Fix_measure_sub A m P f y))
+ (a: Acc lt (m x)),
+ Q x (f (fun y: {y: A | m y < m x} => Fix_measure_sub A m P f (proj1_sig y))))
+ : forall x, Q _ (Fix_measure_sub A m P f x).
+ Proof with auto.
+ unfold Fix_measure_sub.
+ intros.
+ apply Fix_measure_F_sub_rect.
+ intros.
+ assert (forall y: A, MR lt m y x0 -> Q y (Fix_measure_F_sub A m P f y (lt_wf (m y))))...
+ set (inv x0 X0 a). clearbody q.
+ rewrite <- (equiv_lowers (fun y: {y: A | m y < m x0} => Fix_measure_F_sub A m P f (proj1_sig y) (lt_wf (m (proj1_sig y)))) (fun y: {y: A | m y < m x0} => Fix_measure_F_sub A m P f (proj1_sig y) (Acc_inv a (proj2_sig y))))...
+ intros.
+ apply eq_Fix_measure_F_sub.
+ Qed.
+
+End Fix_measure_rects.
+
+(** Tactic to fold a definitions based on [Fix_measure_sub]. *)
+
+Ltac fold_sub f :=
+ match goal with
+ | [ |- ?T ] =>
+ match T with
+ appcontext C [ @Fix_measure_sub _ _ _ _ ?arg ] =>
+ let app := context C [ f arg ] in
+ change app
+ end
+ end.
+
+(** This module provides the fixpoint equation provided one assumes
+ functional extensionality. *)
+
+Module WfExtensionality.
+
+ Require Import FunctionalExtensionality.
+
+ (** The two following lemmas allow to unfold a well-founded fixpoint definition without
+ restriction using the functional extensionality axiom. *)
+
+ (** For a function defined with Program using a well-founded order. *)
+
+ Program Lemma fix_sub_eq_ext :
+ forall (A : Set) (R : A -> A -> Prop) (Rwf : well_founded R)
+ (P : A -> Set)
+ (F_sub : forall x : A, (forall (y : A | R y x), P y) -> P x),
+ forall x : A,
+ Fix_sub A R Rwf P F_sub x =
+ F_sub x (fun (y : A | R y x) => Fix A R Rwf P F_sub y).
+ Proof.
+ intros ; apply Fix_eq ; auto.
+ intros.
+ assert(f = g).
+ extensionality y ; apply H.
+ rewrite H0 ; auto.
+ Qed.
+
+ (** For a function defined with Program using a measure. *)
+
+ Program Lemma fix_sub_measure_eq_ext :
+ forall (A : Type) (f : A -> nat) (P : A -> Type)
+ (F_sub : forall x : A, (forall (y : A | f y < f x), P y) -> P x),
+ forall x : A,
+ Fix_measure_sub A f P F_sub x =
+ F_sub x (fun (y : A | f y < f x) => Fix_measure_sub A f P F_sub y).
+ Proof.
+ intros ; apply Fix_measure_eq ; auto.
+ intros.
+ assert(f0 = g).
+ extensionality y ; apply H.
+ rewrite H0 ; auto.
+ Qed.
+
+ (** Tactic to unfold once a definition based on [Fix_measure_sub]. *)
+
+ Ltac unfold_sub f fargs :=
+ set (call:=fargs) ; unfold f in call ; unfold call ; clear call ;
+ rewrite fix_sub_measure_eq_ext ; repeat fold_sub fargs ; simpl proj1_sig.
+
+End WfExtensionality.
diff --git a/theories/QArith/Qpower.v b/theories/QArith/Qpower.v
index 8672592d..efaefbb7 100644
--- a/theories/QArith/Qpower.v
+++ b/theories/QArith/Qpower.v
@@ -221,7 +221,7 @@ 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;
+repeat apply Zmult_lt_0_compat; red; auto;
apply Zpower_pos_pos; red; auto.
(* xO *)
rewrite IHp, <-Pplus_diag.
diff --git a/theories/Relations/Operators_Properties.v b/theories/Relations/Operators_Properties.v
index 0638ca8f..d0916b09 100644
--- a/theories/Relations/Operators_Properties.v
+++ b/theories/Relations/Operators_Properties.v
@@ -6,15 +6,17 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Operators_Properties.v 9598 2007-02-06 19:45:52Z herbelin $ i*)
+(*i $Id: Operators_Properties.v 11481 2008-10-20 19:23:51Z herbelin $ i*)
-(****************************************************************************)
-(* Bruno Barras *)
-(****************************************************************************)
+(************************************************************************)
+(** * Some properties of the operators on relations *)
+(************************************************************************)
+(** * Initial version by Bruno Barras *)
+(************************************************************************)
Require Import Relation_Definitions.
Require Import Relation_Operators.
-
+Require Import Setoid.
Section Properties.
@@ -25,6 +27,8 @@ Section Properties.
Section Clos_Refl_Trans.
+ (** Correctness of the reflexive-transitive closure operator *)
+
Lemma clos_rt_is_preorder : preorder A (clos_refl_trans A R).
Proof.
apply Build_preorder.
@@ -33,6 +37,8 @@ Section Properties.
exact (rt_trans A R).
Qed.
+ (** Idempotency of the reflexive-transitive closure operator *)
+
Lemma clos_rt_idempotent :
incl (clos_refl_trans A (clos_refl_trans A R)) (clos_refl_trans A R).
Proof.
@@ -42,32 +48,13 @@ Section Properties.
apply rt_trans with y; auto with sets.
Qed.
- Lemma clos_refl_trans_ind_left :
- forall (A:Type) (R:A -> A -> Prop) (M:A) (P:A -> Prop),
- P M ->
- (forall P0 N:A, clos_refl_trans A R M P0 -> P P0 -> R P0 N -> P N) ->
- forall a:A, clos_refl_trans A R M a -> P a.
- Proof.
- intros.
- generalize H H0.
- clear H H0.
- elim H1; intros; auto with sets.
- apply H2 with x; auto with sets.
-
- apply H3.
- apply H0; auto with sets.
-
- intros.
- apply H5 with P0; auto with sets.
- apply rt_trans with y; auto with sets.
- Qed.
-
-
End Clos_Refl_Trans.
-
Section Clos_Refl_Sym_Trans.
+ (** Reflexive-transitive closure is included in the
+ reflexive-symmetric-transitive closure *)
+
Lemma clos_rt_clos_rst :
inclusion A (clos_refl_trans A R) (clos_refl_sym_trans A R).
Proof.
@@ -76,6 +63,8 @@ Section Properties.
apply rst_trans with y; auto with sets.
Qed.
+ (** Correctness of the reflexive-symmetric-transitive closure *)
+
Lemma clos_rst_is_equiv : equivalence A (clos_refl_sym_trans A R).
Proof.
apply Build_equivalence.
@@ -84,6 +73,8 @@ Section Properties.
exact (rst_sym A R).
Qed.
+ (** Idempotency of the reflexive-symmetric-transitive closure operator *)
+
Lemma clos_rst_idempotent :
incl (clos_refl_sym_trans A (clos_refl_sym_trans A R))
(clos_refl_sym_trans A R).
@@ -92,7 +83,294 @@ Section Properties.
induction 1; auto with sets.
apply rst_trans with y; auto with sets.
Qed.
-
+
End Clos_Refl_Sym_Trans.
+ Section Equivalences.
+
+ (** *** Equivalences between the different definition of the reflexive,
+ symmetric, transitive closures *)
+
+ (** *** Contributed by P. Casteran *)
+
+ (** Direct transitive closure vs left-step extension *)
+
+ Lemma t1n_trans : forall x y, clos_trans_1n A R x y -> clos_trans A R x y.
+ Proof.
+ induction 1.
+ left; assumption.
+ right with y; auto.
+ left; auto.
+ Qed.
+
+ Lemma trans_t1n : forall x y, clos_trans A R x y -> clos_trans_1n A R x y.
+ Proof.
+ induction 1.
+ left; assumption.
+ generalize IHclos_trans2; clear IHclos_trans2; induction IHclos_trans1.
+ right with y; auto.
+ right with y; auto.
+ eapply IHIHclos_trans1; auto.
+ apply t1n_trans; auto.
+ Qed.
+
+ Lemma t1n_trans_equiv : forall x y,
+ clos_trans A R x y <-> clos_trans_1n A R x y.
+ Proof.
+ split.
+ apply trans_t1n.
+ apply t1n_trans.
+ Qed.
+
+ (** Direct transitive closure vs right-step extension *)
+
+ Lemma tn1_trans : forall x y, clos_trans_n1 A R x y -> clos_trans A R x y.
+ Proof.
+ induction 1.
+ left; assumption.
+ right with y; auto.
+ left; assumption.
+ Qed.
+
+ Lemma trans_tn1 : forall x y, clos_trans A R x y -> clos_trans_n1 A R x y.
+ Proof.
+ induction 1.
+ left; assumption.
+ elim IHclos_trans2.
+ intro y0; right with y.
+ auto.
+ auto.
+ intros.
+ right with y0; auto.
+ Qed.
+
+ Lemma tn1_trans_equiv : forall x y,
+ clos_trans A R x y <-> clos_trans_n1 A R x y.
+ Proof.
+ split.
+ apply trans_tn1.
+ apply tn1_trans.
+ Qed.
+
+ (** Direct reflexive-transitive closure is equivalent to
+ transitivity by left-step extension *)
+
+ Lemma R_rt1n : forall x y, R x y -> clos_refl_trans_1n A R x y.
+ Proof.
+ intros x y H.
+ right with y;[assumption|left].
+ Qed.
+
+ Lemma R_rtn1 : forall x y, R x y -> clos_refl_trans_n1 A R x y.
+ Proof.
+ intros x y H.
+ right with x;[assumption|left].
+ Qed.
+
+ Lemma rt1n_trans : forall x y,
+ clos_refl_trans_1n A R x y -> clos_refl_trans A R x y.
+ Proof.
+ induction 1.
+ constructor 2.
+ constructor 3 with y; auto.
+ constructor 1; auto.
+ Qed.
+
+ Lemma trans_rt1n : forall x y,
+ clos_refl_trans A R x y -> clos_refl_trans_1n A R x y.
+ Proof.
+ induction 1.
+ apply R_rt1n; assumption.
+ left.
+ generalize IHclos_refl_trans2; clear IHclos_refl_trans2;
+ induction IHclos_refl_trans1; auto.
+
+ right with y; auto.
+ eapply IHIHclos_refl_trans1; auto.
+ apply rt1n_trans; auto.
+ Qed.
+
+ Lemma rt1n_trans_equiv : forall x y,
+ clos_refl_trans A R x y <-> clos_refl_trans_1n A R x y.
+ Proof.
+ split.
+ apply trans_rt1n.
+ apply rt1n_trans.
+ Qed.
+
+ (** Direct reflexive-transitive closure is equivalent to
+ transitivity by right-step extension *)
+
+ Lemma rtn1_trans : forall x y,
+ clos_refl_trans_n1 A R x y -> clos_refl_trans A R x y.
+ Proof.
+ induction 1.
+ constructor 2.
+ constructor 3 with y; auto.
+ constructor 1; assumption.
+ Qed.
+
+ Lemma trans_rtn1 : forall x y,
+ clos_refl_trans A R x y -> clos_refl_trans_n1 A R x y.
+ Proof.
+ induction 1.
+ apply R_rtn1; auto.
+ left.
+ elim IHclos_refl_trans2; auto.
+ intros.
+ right with y0; auto.
+ Qed.
+
+ Lemma rtn1_trans_equiv : forall x y,
+ clos_refl_trans A R x y <-> clos_refl_trans_n1 A R x y.
+ Proof.
+ split.
+ apply trans_rtn1.
+ apply rtn1_trans.
+ Qed.
+
+ (** Induction on the left transitive step *)
+
+ Lemma clos_refl_trans_ind_left :
+ forall (x:A) (P:A -> Prop), P x ->
+ (forall y z:A, clos_refl_trans A R x y -> P y -> R y z -> P z) ->
+ forall z:A, clos_refl_trans A R x z -> P z.
+ Proof.
+ intros.
+ revert H H0.
+ induction H1; intros; auto with sets.
+ apply H1 with x; auto with sets.
+
+ apply IHclos_refl_trans2.
+ apply IHclos_refl_trans1; auto with sets.
+
+ intros.
+ apply H0 with y0; auto with sets.
+ apply rt_trans with y; auto with sets.
+ Qed.
+
+ (** Induction on the right transitive step *)
+
+ Lemma rt1n_ind_right : forall (P : A -> Prop) (z:A),
+ P z ->
+ (forall x y, R x y -> clos_refl_trans_1n A R y z -> P y -> P x) ->
+ forall x, clos_refl_trans_1n A R x z -> P x.
+ induction 3; auto.
+ apply H0 with y; auto.
+ Qed.
+
+ Lemma clos_refl_trans_ind_right : forall (P : A -> Prop) (z:A),
+ P z ->
+ (forall x y, R x y -> P y -> clos_refl_trans A R y z -> P x) ->
+ forall x, clos_refl_trans A R x z -> P x.
+ intros.
+ rewrite rt1n_trans_equiv in H1.
+ elim H1 using rt1n_ind_right; auto.
+ intros; rewrite <- rt1n_trans_equiv in *.
+ eauto.
+ Qed.
+
+ (** Direct reflexive-symmetric-transitive closure is equivalent to
+ transitivity by symmetric left-step extension *)
+
+ Lemma rts1n_rts : forall x y,
+ clos_refl_sym_trans_1n A R x y -> clos_refl_sym_trans A R x y.
+ Proof.
+ induction 1.
+ constructor 2.
+ constructor 4 with y; auto.
+ case H;[constructor 1|constructor 3; constructor 1]; auto.
+ Qed.
+
+ Lemma rts_1n_trans : forall x y, clos_refl_sym_trans_1n A R x y ->
+ forall z, clos_refl_sym_trans_1n A R y z ->
+ clos_refl_sym_trans_1n A R x z.
+ induction 1.
+ auto.
+ intros; right with y; eauto.
+ Qed.
+
+ Lemma rts1n_sym : forall x y, clos_refl_sym_trans_1n A R x y ->
+ clos_refl_sym_trans_1n A R y x.
+ Proof.
+ intros x y H; elim H.
+ constructor 1.
+ intros x0 y0 z D H0 H1; apply rts_1n_trans with y0; auto.
+ right with x0.
+ tauto.
+ left.
+ Qed.
+
+ Lemma rts_rts1n : forall x y,
+ clos_refl_sym_trans A R x y -> clos_refl_sym_trans_1n A R x y.
+ induction 1.
+ constructor 2 with y; auto.
+ constructor 1.
+ constructor 1.
+ apply rts1n_sym; auto.
+ eapply rts_1n_trans; eauto.
+ Qed.
+
+ Lemma rts_rts1n_equiv : forall x y,
+ clos_refl_sym_trans A R x y <-> clos_refl_sym_trans_1n A R x y.
+ Proof.
+ split.
+ apply rts_rts1n.
+ apply rts1n_rts.
+ Qed.
+
+ (** Direct reflexive-symmetric-transitive closure is equivalent to
+ transitivity by symmetric right-step extension *)
+
+ Lemma rtsn1_rts : forall x y,
+ clos_refl_sym_trans_n1 A R x y -> clos_refl_sym_trans A R x y.
+ Proof.
+ induction 1.
+ constructor 2.
+ constructor 4 with y; auto.
+ case H;[constructor 1|constructor 3; constructor 1]; auto.
+ Qed.
+
+ Lemma rtsn1_trans : forall y z, clos_refl_sym_trans_n1 A R y z->
+ forall x, clos_refl_sym_trans_n1 A R x y ->
+ clos_refl_sym_trans_n1 A R x z.
+ Proof.
+ induction 1.
+ auto.
+ intros.
+ right with y0; eauto.
+ Qed.
+
+ Lemma rtsn1_sym : forall x y, clos_refl_sym_trans_n1 A R x y ->
+ clos_refl_sym_trans_n1 A R y x.
+ Proof.
+ intros x y H; elim H.
+ constructor 1.
+ intros y0 z D H0 H1. apply rtsn1_trans with y0; auto.
+ right with z.
+ tauto.
+ left.
+ Qed.
+
+ Lemma rts_rtsn1 : forall x y,
+ clos_refl_sym_trans A R x y -> clos_refl_sym_trans_n1 A R x y.
+ Proof.
+ induction 1.
+ constructor 2 with x; auto.
+ constructor 1.
+ constructor 1.
+ apply rtsn1_sym; auto.
+ eapply rtsn1_trans; eauto.
+ Qed.
+
+ Lemma rts_rtsn1_equiv : forall x y,
+ clos_refl_sym_trans A R x y <-> clos_refl_sym_trans_n1 A R x y.
+ Proof.
+ split.
+ apply rts_rtsn1.
+ apply rtsn1_rts.
+ Qed.
+
+ End Equivalences.
+
End Properties.
diff --git a/theories/Relations/Relation_Operators.v b/theories/Relations/Relation_Operators.v
index 87cd1e6f..027a9e6c 100644
--- a/theories/Relations/Relation_Operators.v
+++ b/theories/Relations/Relation_Operators.v
@@ -6,68 +6,119 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Relation_Operators.v 10681 2008-03-16 13:40:45Z msozeau $ i*)
+(*i $Id: Relation_Operators.v 11481 2008-10-20 19:23:51Z herbelin $ i*)
-(****************************************************************************)
-(* Bruno Barras, Cristina Cornes *)
-(* *)
-(* Some of these definitons were taken from : *)
-(* Constructing Recursion Operators in Type Theory *)
-(* L. Paulson JSC (1986) 2, 325-355 *)
-(****************************************************************************)
+(************************************************************************)
+(** * Bruno Barras, Cristina Cornes *)
+(** * *)
+(** * Some of these definitions were taken from : *)
+(** * Constructing Recursion Operators in Type Theory *)
+(** * L. Paulson JSC (1986) 2, 325-355 *)
+(************************************************************************)
Require Import Relation_Definitions.
Require Import List.
-(** Some operators to build relations *)
+(** * Some operators to build relations *)
+
+(** ** Transitive closure *)
Section Transitive_Closure.
Variable A : Type.
Variable R : relation A.
-
+
+ (** Definition by direct transitive closure *)
+
Inductive clos_trans (x: A) : A -> Prop :=
- | t_step : forall y:A, R x y -> clos_trans x y
- | t_trans :
- forall y z:A, clos_trans x y -> clos_trans y z -> clos_trans x z.
+ | t_step (y:A) : R x y -> clos_trans x y
+ | t_trans (y z:A) : clos_trans x y -> clos_trans y z -> clos_trans x z.
+
+ (** Alternative definition by transitive extension on the left *)
+
+ Inductive clos_trans_1n (x: A) : A -> Prop :=
+ | t1n_step (y:A) : R x y -> clos_trans_1n x y
+ | t1n_trans (y z:A) : R x y -> clos_trans_1n y z -> clos_trans_1n x z.
+
+ (** Alternative definition by transitive extension on the right *)
+
+ Inductive clos_trans_n1 (x: A) : A -> Prop :=
+ | tn1_step (y:A) : R x y -> clos_trans_n1 x y
+ | tn1_trans (y z:A) : R y z -> clos_trans_n1 x y -> clos_trans_n1 x z.
+
End Transitive_Closure.
+(** ** Reflexive-transitive closure *)
Section Reflexive_Transitive_Closure.
Variable A : Type.
Variable R : relation A.
- Inductive clos_refl_trans (x:A) : A -> Prop:=
- | rt_step : forall y:A, R x y -> clos_refl_trans x y
+ (** Definition by direct reflexive-transitive closure *)
+
+ Inductive clos_refl_trans (x:A) : A -> Prop :=
+ | rt_step (y:A) : R x y -> clos_refl_trans x y
| rt_refl : clos_refl_trans x x
- | rt_trans :
- forall y z:A,
+ | rt_trans (y z:A) :
clos_refl_trans x y -> clos_refl_trans y z -> clos_refl_trans x z.
+
+ (** Alternative definition by transitive extension on the left *)
+
+ Inductive clos_refl_trans_1n (x: A) : A -> Prop :=
+ | rt1n_refl : clos_refl_trans_1n x x
+ | rt1n_trans (y z:A) :
+ R x y -> clos_refl_trans_1n y z -> clos_refl_trans_1n x z.
+
+ (** Alternative definition by transitive extension on the right *)
+
+ Inductive clos_refl_trans_n1 (x: A) : A -> Prop :=
+ | rtn1_refl : clos_refl_trans_n1 x x
+ | rtn1_trans (y z:A) :
+ R y z -> clos_refl_trans_n1 x y -> clos_refl_trans_n1 x z.
+
End Reflexive_Transitive_Closure.
+(** ** Reflexive-symmetric-transitive closure *)
Section Reflexive_Symetric_Transitive_Closure.
Variable A : Type.
Variable R : relation A.
+ (** Definition by direct reflexive-symmetric-transitive closure *)
+
Inductive clos_refl_sym_trans : relation A :=
- | rst_step : forall x y:A, R x y -> clos_refl_sym_trans x y
- | rst_refl : forall x:A, clos_refl_sym_trans x x
- | rst_sym :
- forall x y:A, clos_refl_sym_trans x y -> clos_refl_sym_trans y x
- | rst_trans :
- forall x y z:A,
+ | rst_step (x y:A) : R x y -> clos_refl_sym_trans x y
+ | rst_refl (x:A) : clos_refl_sym_trans x x
+ | rst_sym (x y:A) : clos_refl_sym_trans x y -> clos_refl_sym_trans y x
+ | rst_trans (x y z:A) :
clos_refl_sym_trans x y ->
clos_refl_sym_trans y z -> clos_refl_sym_trans x z.
+
+ (** Alternative definition by symmetric-transitive extension on the left *)
+
+ Inductive clos_refl_sym_trans_1n (x: A) : A -> Prop :=
+ | rts1n_refl : clos_refl_sym_trans_1n x x
+ | rts1n_trans (y z:A) : R x y \/ R y x ->
+ clos_refl_sym_trans_1n y z -> clos_refl_sym_trans_1n x z.
+
+ (** Alternative definition by symmetric-transitive extension on the right *)
+
+ Inductive clos_refl_sym_trans_n1 (x: A) : A -> Prop :=
+ | rtsn1_refl : clos_refl_sym_trans_n1 x x
+ | rtsn1_trans (y z:A) : R y z \/ R z y ->
+ clos_refl_sym_trans_n1 x y -> clos_refl_sym_trans_n1 x z.
+
End Reflexive_Symetric_Transitive_Closure.
+(** ** Converse of a relation *)
-Section Transposee.
+Section Converse.
Variable A : Type.
Variable R : relation A.
Definition transp (x y:A) := R y x.
-End Transposee.
+End Converse.
+(** ** Union of relations *)
Section Union.
Variable A : Type.
@@ -76,6 +127,7 @@ Section Union.
Definition union (x y:A) := R1 x y \/ R2 x y.
End Union.
+(** ** Disjoint union of relations *)
Section Disjoint_Union.
Variables A B : Type.
@@ -83,16 +135,15 @@ Variable leA : A -> A -> Prop.
Variable leB : B -> B -> Prop.
Inductive le_AsB : A + B -> A + B -> Prop :=
- | le_aa : forall x y:A, leA x y -> le_AsB (inl _ x) (inl _ y)
- | le_ab : forall (x:A) (y:B), le_AsB (inl _ x) (inr _ y)
- | le_bb : forall x y:B, leB x y -> le_AsB (inr _ x) (inr _ y).
+ | le_aa (x y:A) : leA x y -> le_AsB (inl _ x) (inl _ y)
+ | le_ab (x:A) (y:B) : le_AsB (inl _ x) (inr _ y)
+ | le_bb (x y:B) : leB x y -> le_AsB (inr _ x) (inr _ y).
End Disjoint_Union.
-
+(** ** Lexicographic order on dependent pairs *)
Section Lexicographic_Product.
- (* Lexicographic order on dependent pairs *)
Variable A : Type.
Variable B : A -> Type.
@@ -106,8 +157,10 @@ Section Lexicographic_Product.
| right_lex :
forall (x:A) (y y':B x),
leB x y y' -> lexprod (existS B x y) (existS B x y').
+
End Lexicographic_Product.
+(** ** Product of relations *)
Section Symmetric_Product.
Variable A : Type.
@@ -123,16 +176,15 @@ Section Symmetric_Product.
End Symmetric_Product.
+(** ** Multiset of two relations *)
Section Swap.
Variable A : Type.
Variable R : A -> A -> Prop.
Inductive swapprod : A * A -> A * A -> Prop :=
- | sp_noswap : forall x x':A * A, symprod A A R R x x' -> swapprod x x'
- | sp_swap :
- forall (x y:A) (p:A * A),
- symprod A A R R (x, y) p -> swapprod (y, x) p.
+ | sp_noswap x y (p:A * A) : symprod A A R R (x, y) p -> swapprod (x, y) p
+ | sp_swap x y (p:A * A) : symprod A A R R (x, y) p -> swapprod (y, x) p.
End Swap.
@@ -144,16 +196,14 @@ Section Lexicographic_Exponentiation.
Let List := list A.
Inductive Ltl : List -> List -> Prop :=
- | Lt_nil : forall (a:A) (x:List), Ltl Nil (a :: x)
- | Lt_hd : forall a b:A, leA a b -> forall x y:list A, Ltl (a :: x) (b :: y)
- | Lt_tl : forall (a:A) (x y:List), Ltl x y -> Ltl (a :: x) (a :: y).
-
+ | Lt_nil (a:A) (x:List) : Ltl Nil (a :: x)
+ | Lt_hd (a b:A) : leA a b -> forall x y:list A, Ltl (a :: x) (b :: y)
+ | Lt_tl (a:A) (x y:List) : Ltl x y -> Ltl (a :: x) (a :: y).
Inductive Desc : List -> Prop :=
| d_nil : Desc Nil
- | d_one : forall x:A, Desc (x :: Nil)
- | d_conc :
- forall (x y:A) (l:List),
+ | d_one (x:A) : Desc (x :: Nil)
+ | d_conc (x y:A) (l:List) :
leA x y -> Desc (l ++ y :: Nil) -> Desc ((l ++ y :: Nil) ++ x :: Nil).
Definition Pow : Set := sig Desc.
diff --git a/theories/Setoids/Setoid.v b/theories/Setoids/Setoid.v
index d6975e91..e7fe82b2 100644
--- a/theories/Setoids/Setoid.v
+++ b/theories/Setoids/Setoid.v
@@ -6,38 +6,53 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Setoid.v 10765 2008-04-08 16:15:23Z msozeau $: i*)
+(*i $Id: Setoid.v 11720 2008-12-28 07:12:15Z letouzey $: i*)
Require Export Coq.Classes.SetoidTactics.
(** For backward compatibility *)
-Definition Setoid_Theory := @Equivalence.
-Definition Build_Setoid_Theory := @Build_Equivalence.
-Definition Seq_refl A Aeq (s : Setoid_Theory A Aeq) : forall x:A, Aeq x x :=
- Eval compute in reflexivity.
-Definition Seq_sym A Aeq (s : Setoid_Theory A Aeq) : forall x y:A, Aeq x y -> Aeq y x :=
- Eval compute in symmetry.
-Definition Seq_trans A Aeq (s : Setoid_Theory A Aeq) : forall x y z:A, Aeq x y -> Aeq y z -> Aeq x z :=
- Eval compute in transitivity.
+Definition Setoid_Theory := @Equivalence.
+Definition Build_Setoid_Theory := @Build_Equivalence.
-(** Some tactics for manipulating Setoid Theory not officially
- declared as Setoid. *)
+Definition Seq_refl A Aeq (s : Setoid_Theory A Aeq) : forall x:A, Aeq x x.
+ unfold Setoid_Theory. intros ; reflexivity.
+Defined.
+
+Definition Seq_sym A Aeq (s : Setoid_Theory A Aeq) : forall x y:A, Aeq x y -> Aeq y x.
+ unfold Setoid_Theory. intros ; symmetry ; assumption.
+Defined.
-Ltac trans_st x := match goal with
- | H : Setoid_Theory _ ?eqA |- ?eqA _ _ =>
- apply (Seq_trans _ _ H) with x; auto
- end.
+Definition Seq_trans A Aeq (s : Setoid_Theory A Aeq) : forall x y z:A, Aeq x y -> Aeq y z -> Aeq x z.
+ unfold Setoid_Theory. intros ; transitivity y ; assumption.
+Defined.
-Ltac sym_st := match goal with
- | H : Setoid_Theory _ ?eqA |- ?eqA _ _ =>
- apply (Seq_sym _ _ H); auto
- end.
+(** Some tactics for manipulating Setoid Theory not officially
+ declared as Setoid. *)
-Ltac refl_st := match goal with
- | H : Setoid_Theory _ ?eqA |- ?eqA _ _ =>
- apply (Seq_refl _ _ H); auto
- end.
+Ltac trans_st x :=
+ idtac "trans_st on Setoid_Theory is OBSOLETE";
+ idtac "use transitivity on Equivalence instead";
+ match goal with
+ | H : Setoid_Theory _ ?eqA |- ?eqA _ _ =>
+ apply (Seq_trans _ _ H) with x; auto
+ end.
+
+Ltac sym_st :=
+ idtac "sym_st on Setoid_Theory is OBSOLETE";
+ idtac "use symmetry on Equivalence instead";
+ match goal with
+ | H : Setoid_Theory _ ?eqA |- ?eqA _ _ =>
+ apply (Seq_sym _ _ H); auto
+ end.
+
+Ltac refl_st :=
+ idtac "refl_st on Setoid_Theory is OBSOLETE";
+ idtac "use reflexivity on Equivalence instead";
+ match goal with
+ | H : Setoid_Theory _ ?eqA |- ?eqA _ _ =>
+ apply (Seq_refl _ _ H); auto
+ end.
Definition gen_st : forall A : Set, Setoid_Theory _ (@eq A).
Proof.
diff --git a/theories/Setoids/Setoid_Prop.v b/theories/Setoids/Setoid_Prop.v
deleted file mode 100644
index 7300937e..00000000
--- a/theories/Setoids/Setoid_Prop.v
+++ /dev/null
@@ -1,79 +0,0 @@
-
-(************************************************************************)
-(* 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: Setoid_Prop.v 10739 2008-04-01 14:45:20Z herbelin $: i*)
-
-Require Import Setoid_tac.
-
-(** * A few examples on [iff] *)
-
-(** [iff] as a relation *)
-
-Add Relation Prop iff
- reflexivity proved by iff_refl
- symmetry proved by iff_sym
- transitivity proved by iff_trans
-as iff_relation.
-
-(** [impl] as a relation *)
-
-Theorem impl_trans: transitive _ impl.
-Proof.
- hnf; unfold impl; tauto.
-Qed.
-
-Add Relation Prop impl
- reflexivity proved by impl_refl
- transitivity proved by impl_trans
-as impl_relation.
-
-(** [impl] is a morphism *)
-
-Add Morphism impl with signature iff ==> iff ==> iff as Impl_Morphism.
-Proof.
- unfold impl; tauto.
-Qed.
-
-(** [and] is a morphism *)
-
-Add Morphism and with signature iff ==> iff ==> iff as And_Morphism.
- tauto.
-Qed.
-
-(** [or] is a morphism *)
-
-Add Morphism or with signature iff ==> iff ==> iff as Or_Morphism.
-Proof.
- tauto.
-Qed.
-
-(** [not] is a morphism *)
-
-Add Morphism not with signature iff ==> iff as Not_Morphism.
-Proof.
- tauto.
-Qed.
-
-(** The same examples on [impl] *)
-
-Add Morphism and with signature impl ++> impl ++> impl as And_Morphism2.
-Proof.
- unfold impl; tauto.
-Qed.
-
-Add Morphism or with signature impl ++> impl ++> impl as Or_Morphism2.
-Proof.
- unfold impl; tauto.
-Qed.
-
-Add Morphism not with signature impl --> impl as Not_Morphism2.
-Proof.
- unfold impl; tauto.
-Qed.
-
diff --git a/theories/Setoids/Setoid_tac.v b/theories/Setoids/Setoid_tac.v
deleted file mode 100644
index cdc4eafe..00000000
--- a/theories/Setoids/Setoid_tac.v
+++ /dev/null
@@ -1,595 +0,0 @@
-(************************************************************************)
-(* 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: Setoid_tac.v 10739 2008-04-01 14:45:20Z herbelin $ i*)
-
-Require Export Relation_Definitions.
-
-Set Implicit Arguments.
-
-(** * Definitions of [Relation_Class] and n-ary [Morphism_Theory] *)
-
-(* X will be used to distinguish covariant arguments whose type is an *)
-(* Asymmetric* relation from contravariant arguments of the same type *)
-Inductive X_Relation_Class (X: Type) : Type :=
- SymmetricReflexive :
- forall A Aeq, symmetric A Aeq -> reflexive _ Aeq -> X_Relation_Class X
- | AsymmetricReflexive : X -> forall A Aeq, reflexive A Aeq -> X_Relation_Class X
- | SymmetricAreflexive : forall A Aeq, symmetric A Aeq -> X_Relation_Class X
- | AsymmetricAreflexive : X -> forall A (Aeq : relation A), X_Relation_Class X
- | Leibniz : Type -> X_Relation_Class X.
-
-Inductive variance : Set :=
- Covariant
- | Contravariant.
-
-Definition Argument_Class := X_Relation_Class variance.
-Definition Relation_Class := X_Relation_Class unit.
-
-Inductive Reflexive_Relation_Class : Type :=
- RSymmetric :
- forall A Aeq, symmetric A Aeq -> reflexive _ Aeq -> Reflexive_Relation_Class
- | RAsymmetric :
- forall A Aeq, reflexive A Aeq -> Reflexive_Relation_Class
- | RLeibniz : Type -> Reflexive_Relation_Class.
-
-Inductive Areflexive_Relation_Class : Type :=
- | ASymmetric : forall A Aeq, symmetric A Aeq -> Areflexive_Relation_Class
- | AAsymmetric : forall A (Aeq : relation A), Areflexive_Relation_Class.
-
-Implicit Type Hole Out: Relation_Class.
-
-Definition relation_class_of_argument_class : Argument_Class -> Relation_Class.
- destruct 1.
- exact (SymmetricReflexive _ s r).
- exact (AsymmetricReflexive tt r).
- exact (SymmetricAreflexive _ s).
- exact (AsymmetricAreflexive tt Aeq).
- exact (Leibniz _ T).
-Defined.
-
-Definition carrier_of_relation_class : forall X, X_Relation_Class X -> Type.
- destruct 1.
- exact A.
- exact A.
- exact A.
- exact A.
- exact T.
-Defined.
-
-Definition relation_of_relation_class :
- forall X R, @carrier_of_relation_class X R -> carrier_of_relation_class R -> Prop.
- destruct R.
- exact Aeq.
- exact Aeq.
- exact Aeq.
- exact Aeq.
- exact (@eq T).
-Defined.
-
-Lemma about_carrier_of_relation_class_and_relation_class_of_argument_class :
- forall R,
- carrier_of_relation_class (relation_class_of_argument_class R) =
- carrier_of_relation_class R.
- destruct R; reflexivity.
-Defined.
-
-Inductive nelistT (A : Type) : Type :=
- singl : A -> nelistT A
- | necons : A -> nelistT A -> nelistT A.
-
-Definition Arguments := nelistT Argument_Class.
-
-Implicit Type In: Arguments.
-
-Definition function_type_of_morphism_signature :
- Arguments -> Relation_Class -> Type.
- intros In Out.
- induction In.
- exact (carrier_of_relation_class a -> carrier_of_relation_class Out).
- exact (carrier_of_relation_class a -> IHIn).
-Defined.
-
-Definition make_compatibility_goal_aux:
- forall In Out
- (f g: function_type_of_morphism_signature In Out), Prop.
- intros; induction In; simpl in f, g.
- induction a; simpl in f, g.
- exact (forall x1 x2, Aeq x1 x2 -> relation_of_relation_class Out (f x1) (g x2)).
- destruct x.
- exact (forall x1 x2, Aeq x1 x2 -> relation_of_relation_class Out (f x1) (g x2)).
- exact (forall x1 x2, Aeq x2 x1 -> relation_of_relation_class Out (f x1) (g x2)).
- exact (forall x1 x2, Aeq x1 x2 -> relation_of_relation_class Out (f x1) (g x2)).
- destruct x.
- exact (forall x1 x2, Aeq x1 x2 -> relation_of_relation_class Out (f x1) (g x2)).
- exact (forall x1 x2, Aeq x2 x1 -> relation_of_relation_class Out (f x1) (g x2)).
- exact (forall x, relation_of_relation_class Out (f x) (g x)).
- induction a; simpl in f, g.
- exact (forall x1 x2, Aeq x1 x2 -> IHIn (f x1) (g x2)).
- destruct x.
- exact (forall x1 x2, Aeq x1 x2 -> IHIn (f x1) (g x2)).
- exact (forall x1 x2, Aeq x2 x1 -> IHIn (f x1) (g x2)).
- exact (forall x1 x2, Aeq x1 x2 -> IHIn (f x1) (g x2)).
- destruct x.
- exact (forall x1 x2, Aeq x1 x2 -> IHIn (f x1) (g x2)).
- exact (forall x1 x2, Aeq x2 x1 -> IHIn (f x1) (g x2)).
- exact (forall x, IHIn (f x) (g x)).
-Defined.
-
-Definition make_compatibility_goal :=
- (fun In Out f => make_compatibility_goal_aux In Out f f).
-
-Record Morphism_Theory In Out : Type :=
- { Function : function_type_of_morphism_signature In Out;
- Compat : make_compatibility_goal In Out Function }.
-
-
-(** The [iff] relation class *)
-
-Definition Iff_Relation_Class : Relation_Class.
- eapply (@SymmetricReflexive unit _ iff).
- exact iff_sym.
- exact iff_refl.
-Defined.
-
-(** The [impl] relation class *)
-
-Definition impl (A B: Prop) := A -> B.
-
-Theorem impl_refl: reflexive _ impl.
-Proof.
- hnf; unfold impl; tauto.
-Qed.
-
-Definition Impl_Relation_Class : Relation_Class.
- eapply (@AsymmetricReflexive unit tt _ impl).
- exact impl_refl.
-Defined.
-
-(** Every function is a morphism from Leibniz+ to Leibniz *)
-
-Definition list_of_Leibniz_of_list_of_types: nelistT Type -> Arguments.
- induction 1.
- exact (singl (Leibniz _ a)).
- exact (necons (Leibniz _ a) IHX).
-Defined.
-
-Definition morphism_theory_of_function :
- forall (In: nelistT Type) (Out: Type),
- let In' := list_of_Leibniz_of_list_of_types In in
- let Out' := Leibniz _ Out in
- function_type_of_morphism_signature In' Out' ->
- Morphism_Theory In' Out'.
- intros.
- exists X.
- induction In; unfold make_compatibility_goal; simpl.
- reflexivity.
- intro; apply (IHIn (X x)).
-Defined.
-
-(** Every predicate is a morphism from Leibniz+ to Iff_Relation_Class *)
-
-Definition morphism_theory_of_predicate :
- forall (In: nelistT Type),
- let In' := list_of_Leibniz_of_list_of_types In in
- function_type_of_morphism_signature In' Iff_Relation_Class ->
- Morphism_Theory In' Iff_Relation_Class.
- intros.
- exists X.
- induction In; unfold make_compatibility_goal; simpl.
- intro; apply iff_refl.
- intro; apply (IHIn (X x)).
-Defined.
-
-(** * Utility functions to prove that every transitive relation is a morphism *)
-
-Definition equality_morphism_of_symmetric_areflexive_transitive_relation:
- forall (A: Type)(Aeq: relation A)(sym: symmetric _ Aeq)(trans: transitive _ Aeq),
- let ASetoidClass := SymmetricAreflexive _ sym in
- (Morphism_Theory (necons ASetoidClass (singl ASetoidClass)) Iff_Relation_Class).
- intros.
- exists Aeq.
- unfold make_compatibility_goal; simpl; split; eauto.
-Defined.
-
-Definition equality_morphism_of_symmetric_reflexive_transitive_relation:
- forall (A: Type)(Aeq: relation A)(refl: reflexive _ Aeq)(sym: symmetric _ Aeq)
- (trans: transitive _ Aeq), let ASetoidClass := SymmetricReflexive _ sym refl in
- (Morphism_Theory (necons ASetoidClass (singl ASetoidClass)) Iff_Relation_Class).
- intros.
- exists Aeq.
- unfold make_compatibility_goal; simpl; split; eauto.
-Defined.
-
-Definition equality_morphism_of_asymmetric_areflexive_transitive_relation:
- forall (A: Type)(Aeq: relation A)(trans: transitive _ Aeq),
- let ASetoidClass1 := AsymmetricAreflexive Contravariant Aeq in
- let ASetoidClass2 := AsymmetricAreflexive Covariant Aeq in
- (Morphism_Theory (necons ASetoidClass1 (singl ASetoidClass2)) Impl_Relation_Class).
- intros.
- exists Aeq.
- unfold make_compatibility_goal; simpl; unfold impl; eauto.
-Defined.
-
-Definition equality_morphism_of_asymmetric_reflexive_transitive_relation:
- forall (A: Type)(Aeq: relation A)(refl: reflexive _ Aeq)(trans: transitive _ Aeq),
- let ASetoidClass1 := AsymmetricReflexive Contravariant refl in
- let ASetoidClass2 := AsymmetricReflexive Covariant refl in
- (Morphism_Theory (necons ASetoidClass1 (singl ASetoidClass2)) Impl_Relation_Class).
- intros.
- exists Aeq.
- unfold make_compatibility_goal; simpl; unfold impl; eauto.
-Defined.
-
-(** * The CIC part of the reflexive tactic ([setoid_rewrite]) *)
-
-Inductive rewrite_direction : Type :=
- | Left2Right
- | Right2Left.
-
-Implicit Type dir: rewrite_direction.
-
-Definition variance_of_argument_class : Argument_Class -> option variance.
- destruct 1.
- exact None.
- exact (Some v).
- exact None.
- exact (Some v).
- exact None.
-Defined.
-
-Definition opposite_direction :=
- fun dir =>
- match dir with
- | Left2Right => Right2Left
- | Right2Left => Left2Right
- end.
-
-Lemma opposite_direction_idempotent:
- forall dir, (opposite_direction (opposite_direction dir)) = dir.
-Proof.
- destruct dir; reflexivity.
-Qed.
-
-Inductive check_if_variance_is_respected :
- option variance -> rewrite_direction -> rewrite_direction -> Prop :=
- | MSNone : forall dir dir', check_if_variance_is_respected None dir dir'
- | MSCovariant : forall dir, check_if_variance_is_respected (Some Covariant) dir dir
- | MSContravariant :
- forall dir,
- check_if_variance_is_respected (Some Contravariant) dir (opposite_direction dir).
-
-Definition relation_class_of_reflexive_relation_class:
- Reflexive_Relation_Class -> Relation_Class.
- induction 1.
- exact (SymmetricReflexive _ s r).
- exact (AsymmetricReflexive tt r).
- exact (Leibniz _ T).
-Defined.
-
-Definition relation_class_of_areflexive_relation_class:
- Areflexive_Relation_Class -> Relation_Class.
- induction 1.
- exact (SymmetricAreflexive _ s).
- exact (AsymmetricAreflexive tt Aeq).
-Defined.
-
-Definition carrier_of_reflexive_relation_class :=
- fun R => carrier_of_relation_class (relation_class_of_reflexive_relation_class R).
-
-Definition carrier_of_areflexive_relation_class :=
- fun R => carrier_of_relation_class (relation_class_of_areflexive_relation_class R).
-
-Definition relation_of_areflexive_relation_class :=
- fun R => relation_of_relation_class (relation_class_of_areflexive_relation_class R).
-
-Inductive Morphism_Context Hole dir : Relation_Class -> rewrite_direction -> Type :=
- | App :
- forall In Out dir',
- Morphism_Theory In Out -> Morphism_Context_List Hole dir dir' In ->
- Morphism_Context Hole dir Out dir'
- | ToReplace : Morphism_Context Hole dir Hole dir
- | ToKeep :
- forall S dir',
- carrier_of_reflexive_relation_class S ->
- Morphism_Context Hole dir (relation_class_of_reflexive_relation_class S) dir'
- | ProperElementToKeep :
- forall S dir' (x: carrier_of_areflexive_relation_class S),
- relation_of_areflexive_relation_class S x x ->
- Morphism_Context Hole dir (relation_class_of_areflexive_relation_class S) dir'
-with Morphism_Context_List Hole dir :
- rewrite_direction -> Arguments -> Type
-:=
- fcl_singl :
- forall S dir' dir'',
- check_if_variance_is_respected (variance_of_argument_class S) dir' dir'' ->
- Morphism_Context Hole dir (relation_class_of_argument_class S) dir' ->
- Morphism_Context_List Hole dir dir'' (singl S)
- | fcl_cons :
- forall S L dir' dir'',
- check_if_variance_is_respected (variance_of_argument_class S) dir' dir'' ->
- Morphism_Context Hole dir (relation_class_of_argument_class S) dir' ->
- Morphism_Context_List Hole dir dir'' L ->
- Morphism_Context_List Hole dir dir'' (necons S L).
-
-Scheme Morphism_Context_rect2 := Induction for Morphism_Context Sort Type
-with Morphism_Context_List_rect2 := Induction for Morphism_Context_List Sort Type.
-
-Definition product_of_arguments : Arguments -> Type.
- induction 1.
- exact (carrier_of_relation_class a).
- exact (prod (carrier_of_relation_class a) IHX).
-Defined.
-
-Definition get_rewrite_direction: rewrite_direction -> Argument_Class -> rewrite_direction.
- intros dir R.
- destruct (variance_of_argument_class R).
- destruct v.
- exact dir. (* covariant *)
- exact (opposite_direction dir). (* contravariant *)
- exact dir. (* symmetric relation *)
-Defined.
-
-Definition directed_relation_of_relation_class:
- forall dir (R: Relation_Class),
- carrier_of_relation_class R -> carrier_of_relation_class R -> Prop.
- destruct 1.
- exact (@relation_of_relation_class unit).
- intros; exact (relation_of_relation_class _ X0 X).
-Defined.
-
-Definition directed_relation_of_argument_class:
- forall dir (R: Argument_Class),
- carrier_of_relation_class R -> carrier_of_relation_class R -> Prop.
- intros dir R.
- rewrite <-
- (about_carrier_of_relation_class_and_relation_class_of_argument_class R).
- exact (directed_relation_of_relation_class dir (relation_class_of_argument_class R)).
-Defined.
-
-
-Definition relation_of_product_of_arguments:
- forall dir In,
- product_of_arguments In -> product_of_arguments In -> Prop.
- induction In.
- simpl.
- exact (directed_relation_of_argument_class (get_rewrite_direction dir a) a).
-
- simpl; intros.
- destruct X; destruct X0.
- apply and.
- exact
- (directed_relation_of_argument_class (get_rewrite_direction dir a) a c c0).
- exact (IHIn p p0).
-Defined.
-
-Definition apply_morphism:
- forall In Out (m: function_type_of_morphism_signature In Out)
- (args: product_of_arguments In), carrier_of_relation_class Out.
- intros.
- induction In.
- exact (m args).
- simpl in m, args.
- destruct args.
- exact (IHIn (m c) p).
-Defined.
-
-Theorem apply_morphism_compatibility_Right2Left:
- forall In Out (m1 m2: function_type_of_morphism_signature In Out)
- (args1 args2: product_of_arguments In),
- make_compatibility_goal_aux _ _ m1 m2 ->
- relation_of_product_of_arguments Right2Left _ args1 args2 ->
- directed_relation_of_relation_class Right2Left _
- (apply_morphism _ _ m2 args1)
- (apply_morphism _ _ m1 args2).
- induction In; intros.
- simpl in m1, m2, args1, args2, H0 |- *.
- destruct a; simpl in H; hnf in H0.
- apply H; exact H0.
- destruct v; simpl in H0; apply H; exact H0.
- apply H; exact H0.
- destruct v; simpl in H0; apply H; exact H0.
- rewrite H0; apply H; exact H0.
-
- simpl in m1, m2, args1, args2, H0 |- *.
- destruct args1; destruct args2; simpl.
- destruct H0.
- simpl in H.
- destruct a; simpl in H.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- destruct v.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- destruct v.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- rewrite H0; apply IHIn.
- apply H.
- exact H1.
-Qed.
-
-Theorem apply_morphism_compatibility_Left2Right:
- forall In Out (m1 m2: function_type_of_morphism_signature In Out)
- (args1 args2: product_of_arguments In),
- make_compatibility_goal_aux _ _ m1 m2 ->
- relation_of_product_of_arguments Left2Right _ args1 args2 ->
- directed_relation_of_relation_class Left2Right _
- (apply_morphism _ _ m1 args1)
- (apply_morphism _ _ m2 args2).
-Proof.
- induction In; intros.
- simpl in m1, m2, args1, args2, H0 |- *.
- destruct a; simpl in H; hnf in H0.
- apply H; exact H0.
- destruct v; simpl in H0; apply H; exact H0.
- apply H; exact H0.
- destruct v; simpl in H0; apply H; exact H0.
- rewrite H0; apply H; exact H0.
-
- simpl in m1, m2, args1, args2, H0 |- *.
- destruct args1; destruct args2; simpl.
- destruct H0.
- simpl in H.
- destruct a; simpl in H.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- destruct v.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- apply IHIn.
- apply H; exact H0.
- exact H1.
- apply IHIn.
- destruct v; simpl in H, H0; apply H; exact H0.
- exact H1.
- rewrite H0; apply IHIn.
- apply H.
- exact H1.
-Qed.
-
-Definition interp :
- forall Hole dir Out dir', carrier_of_relation_class Hole ->
- Morphism_Context Hole dir Out dir' -> carrier_of_relation_class Out.
- intros Hole dir Out dir' H t.
- elim t using
- (@Morphism_Context_rect2 Hole dir (fun S _ _ => carrier_of_relation_class S)
- (fun _ L fcl => product_of_arguments L));
- intros.
- exact (apply_morphism _ _ (Function m) X).
- exact H.
- exact c.
- exact x.
- simpl;
- rewrite <-
- (about_carrier_of_relation_class_and_relation_class_of_argument_class S);
- exact X.
- split.
- rewrite <-
- (about_carrier_of_relation_class_and_relation_class_of_argument_class S);
- exact X.
- exact X0.
-Defined.
-
-(* CSC: interp and interp_relation_class_list should be mutually defined, since
- the proof term of each one contains the proof term of the other one. However
- I cannot do that interactively (I should write the Fix by hand) *)
-Definition interp_relation_class_list :
- forall Hole dir dir' (L: Arguments), carrier_of_relation_class Hole ->
- Morphism_Context_List Hole dir dir' L -> product_of_arguments L.
- intros Hole dir dir' L H t.
- elim t using
- (@Morphism_Context_List_rect2 Hole dir (fun S _ _ => carrier_of_relation_class S)
- (fun _ L fcl => product_of_arguments L));
- intros.
- exact (apply_morphism _ _ (Function m) X).
- exact H.
- exact c.
- exact x.
- simpl;
- rewrite <-
- (about_carrier_of_relation_class_and_relation_class_of_argument_class S);
- exact X.
- split.
- rewrite <-
- (about_carrier_of_relation_class_and_relation_class_of_argument_class S);
- exact X.
- exact X0.
-Defined.
-
-Theorem setoid_rewrite:
- forall Hole dir Out dir' (E1 E2: carrier_of_relation_class Hole)
- (E: Morphism_Context Hole dir Out dir'),
- (directed_relation_of_relation_class dir Hole E1 E2) ->
- (directed_relation_of_relation_class dir' Out (interp E1 E) (interp E2 E)).
-Proof.
- intros.
- elim E using
- (@Morphism_Context_rect2 Hole dir
- (fun S dir'' E => directed_relation_of_relation_class dir'' S (interp E1 E) (interp E2 E))
- (fun dir'' L fcl =>
- relation_of_product_of_arguments dir'' _
- (interp_relation_class_list E1 fcl)
- (interp_relation_class_list E2 fcl))); intros.
- change (directed_relation_of_relation_class dir'0 Out0
- (apply_morphism _ _ (Function m) (interp_relation_class_list E1 m0))
- (apply_morphism _ _ (Function m) (interp_relation_class_list E2 m0))).
- destruct dir'0.
- apply apply_morphism_compatibility_Left2Right.
- exact (Compat m).
- exact H0.
- apply apply_morphism_compatibility_Right2Left.
- exact (Compat m).
- exact H0.
-
- exact H.
-
- unfold interp, Morphism_Context_rect2.
- (* CSC: reflexivity used here *)
- destruct S; destruct dir'0; simpl; (apply r || reflexivity).
-
- destruct dir'0; exact r.
-
- destruct S; unfold directed_relation_of_argument_class; simpl in H0 |- *;
- unfold get_rewrite_direction; simpl.
- destruct dir'0; destruct dir'';
- (exact H0 ||
- unfold directed_relation_of_argument_class; simpl; apply s; exact H0).
- (* the following mess with generalize/clear/intros is to help Coq resolving *)
- (* second order unification problems. *)
- generalize m c H0; clear H0 m c; inversion c;
- generalize m c; clear m c; rewrite <- H1; rewrite <- H2; intros;
- (exact H3 || rewrite (opposite_direction_idempotent dir'0); apply H3).
- destruct dir'0; destruct dir'';
- (exact H0 ||
- unfold directed_relation_of_argument_class; simpl; apply s; exact H0).
- (* the following mess with generalize/clear/intros is to help Coq resolving *)
- (* second order unification problems. *)
- generalize m c H0; clear H0 m c; inversion c;
- generalize m c; clear m c; rewrite <- H1; rewrite <- H2; intros;
- (exact H3 || rewrite (opposite_direction_idempotent dir'0); apply H3).
- destruct dir'0; destruct dir''; (exact H0 || hnf; symmetry; exact H0).
-
- change
- (directed_relation_of_argument_class (get_rewrite_direction dir'' S) S
- (eq_rect _ (fun T : Type => T) (interp E1 m) _
- (about_carrier_of_relation_class_and_relation_class_of_argument_class S))
- (eq_rect _ (fun T : Type => T) (interp E2 m) _
- (about_carrier_of_relation_class_and_relation_class_of_argument_class S)) /\
- relation_of_product_of_arguments dir'' _
- (interp_relation_class_list E1 m0) (interp_relation_class_list E2 m0)).
- split.
- clear m0 H1; destruct S; simpl in H0 |- *; unfold get_rewrite_direction; simpl.
- destruct dir''; destruct dir'0; (exact H0 || hnf; apply s; exact H0).
- inversion c.
- rewrite <- H3; exact H0.
- rewrite (opposite_direction_idempotent dir'0); exact H0.
- destruct dir''; destruct dir'0; (exact H0 || hnf; apply s; exact H0).
- inversion c.
- rewrite <- H3; exact H0.
- rewrite (opposite_direction_idempotent dir'0); exact H0.
- destruct dir''; destruct dir'0; (exact H0 || hnf; symmetry; exact H0).
- exact H1.
- Qed.
diff --git a/theories/ZArith/Zdiv.v b/theories/ZArith/Zdiv.v
index 4c560c6b..228a882a 100644
--- a/theories/ZArith/Zdiv.v
+++ b/theories/ZArith/Zdiv.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: Zdiv.v 10999 2008-05-27 15:55:22Z letouzey $ i*)
+(*i $Id: Zdiv.v 11477 2008-10-20 15:16:14Z letouzey $ i*)
(* Contribution by Claude Marché and Xavier Urbain *)
@@ -901,66 +901,63 @@ Proof.
intros; rewrite Zmult_mod, Zmod_mod, <- Zmult_mod; auto.
Qed.
-(** For a specific number n, equality modulo n is hence a nice setoid
- equivalence, compatible with the usual operations. Due to restrictions
- with Coq setoids, we cannot state this in a section, but it works
- at least with a module. *)
+(** For a specific number N, equality modulo N is hence a nice setoid
+ equivalence, compatible with [+], [-] and [*]. *)
-Module Type SomeNumber.
- Parameter n:Z.
-End SomeNumber.
+Definition eqm N a b := (a mod N = b mod N).
-Module EqualityModulo (M:SomeNumber).
+Lemma eqm_refl N : forall a, (eqm N) a a.
+Proof. unfold eqm; auto. Qed.
- Definition eqm a b := (a mod M.n = b mod M.n).
- Infix "==" := eqm (at level 70).
+Lemma eqm_sym N : forall a b, (eqm N) a b -> (eqm N) b a.
+Proof. unfold eqm; auto. Qed.
- Lemma eqm_refl : forall a, a == a.
- Proof. unfold eqm; auto. Qed.
+Lemma eqm_trans N : forall a b c,
+ (eqm N) a b -> (eqm N) b c -> (eqm N) a c.
+Proof. unfold eqm; eauto with *. Qed.
- Lemma eqm_sym : forall a b, a == b -> b == a.
- Proof. unfold eqm; auto. Qed.
+Add Parametric Relation N : Z (eqm N)
+ reflexivity proved by (eqm_refl N)
+ symmetry proved by (eqm_sym N)
+ transitivity proved by (eqm_trans N) as eqm_setoid.
- Lemma eqm_trans : forall a b c, a == b -> b == c -> a == c.
- Proof. unfold eqm; eauto with *. Qed.
-
- Add Relation Z eqm
- reflexivity proved by eqm_refl
- symmetry proved by eqm_sym
- transitivity proved by eqm_trans as eqm_setoid.
-
- Add Morphism Zplus : Zplus_eqm.
- Proof.
+Add Parametric Morphism N : Zplus
+ with signature (eqm N) ==> (eqm N) ==> (eqm N) as Zplus_eqm.
+Proof.
unfold eqm; intros; rewrite Zplus_mod, H, H0, <- Zplus_mod; auto.
- Qed.
+Qed.
- Add Morphism Zminus : Zminus_eqm.
- Proof.
+Add Parametric Morphism N : Zminus
+ with signature (eqm N) ==> (eqm N) ==> (eqm N) as Zminus_eqm.
+Proof.
unfold eqm; intros; rewrite Zminus_mod, H, H0, <- Zminus_mod; auto.
- Qed.
+Qed.
- Add Morphism Zmult : Zmult_eqm.
- Proof.
+Add Parametric Morphism N : Zmult
+ with signature (eqm N) ==> (eqm N) ==> (eqm N) as Zmult_eqm.
+Proof.
unfold eqm; intros; rewrite Zmult_mod, H, H0, <- Zmult_mod; auto.
- Qed.
+Qed.
- Add Morphism Zopp : Zopp_eqm.
- Proof.
- intros; change (-x == -y) with (0-x == 0-y).
+Add Parametric Morphism N : Zopp
+ with signature (eqm N) ==> (eqm N) as Zopp_eqm.
+Proof.
+ intros; change ((eqm N) (-x) (-y)) with ((eqm N) (0-x) (0-y)).
rewrite H; red; auto.
- Qed.
-
- Lemma Zmod_eqm : forall a, a mod M.n == a.
- Proof.
- unfold eqm; intros; apply Zmod_mod.
- Qed.
+Qed.
- (* Zmod and Zdiv are not full morphisms with respect to eqm.
- For instance, take n=2. Then 3 == 1 but we don't have
- 1 mod 3 == 1 mod 1 nor 1/3 == 1/1.
- *)
+Lemma Zmod_eqm N : forall a, (eqm N) (a mod N) a.
+Proof.
+ intros; exact (Zmod_mod a N).
+Qed.
-End EqualityModulo.
+(* NB: Zmod and Zdiv are not morphisms with respect to eqm.
+ For instance, let (==) be (eqm 2). Then we have (3 == 1) but:
+ ~ (3 mod 3 == 1 mod 3)
+ ~ (1 mod 3 == 1 mod 1)
+ ~ (3/3 == 1/3)
+ ~ (1/3 == 1/1)
+*)
Lemma Zdiv_Zdiv : forall a b c, 0<=b -> 0<=c -> (a/b)/c = a/(b*c).
Proof.
diff --git a/theories/ZArith/auxiliary.v b/theories/ZArith/auxiliary.v
index 726fb45a..ffc3e70f 100644
--- a/theories/ZArith/auxiliary.v
+++ b/theories/ZArith/auxiliary.v
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id: auxiliary.v 9302 2006-10-27 21:21:17Z barras $ i*)
+(*i $Id: auxiliary.v 11739 2009-01-02 19:33:19Z herbelin $ i*)
(** Binary Integers (Pierre Crégut, CNET, Lannion, France) *)
@@ -91,46 +91,6 @@ Proof.
rewrite Zplus_opp_r; trivial.
Qed.
-(**********************************************************************)
-(** * Factorization lemmas *)
-
-Theorem Zred_factor0 : forall n:Z, n = n * 1.
- intro x; rewrite (Zmult_1_r x); reflexivity.
-Qed.
-
-Theorem Zred_factor1 : forall n:Z, n + n = n * 2.
-Proof.
- exact Zplus_diag_eq_mult_2.
-Qed.
-
-Theorem Zred_factor2 : forall n m:Z, n + n * m = n * (1 + m).
-Proof.
- intros x y; pattern x at 1 in |- *; rewrite <- (Zmult_1_r x);
- rewrite <- Zmult_plus_distr_r; trivial with arith.
-Qed.
-
-Theorem Zred_factor3 : forall n m:Z, n * m + n = n * (1 + m).
-Proof.
- intros x y; pattern x at 2 in |- *; rewrite <- (Zmult_1_r x);
- rewrite <- Zmult_plus_distr_r; rewrite Zplus_comm;
- trivial with arith.
-Qed.
-
-Theorem Zred_factor4 : forall n m p:Z, n * m + n * p = n * (m + p).
-Proof.
- intros x y z; symmetry in |- *; apply Zmult_plus_distr_r.
-Qed.
-
-Theorem Zred_factor5 : forall n m:Z, n * 0 + m = m.
-Proof.
- intros x y; rewrite <- Zmult_0_r_reverse; auto with arith.
-Qed.
-
-Theorem Zred_factor6 : forall n:Z, n = n + 0.
-Proof.
- intro; rewrite Zplus_0_r; trivial with arith.
-Qed.
-
Theorem Zle_mult_approx :
forall n m p:Z, n > 0 -> p > 0 -> 0 <= m -> 0 <= m * n + p.
Proof.