summaryrefslogtreecommitdiff
path: root/theories/FSets/FSetProperties.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/FSets/FSetProperties.v')
-rw-r--r--theories/FSets/FSetProperties.v806
1 files changed, 489 insertions, 317 deletions
diff --git a/theories/FSets/FSetProperties.v b/theories/FSets/FSetProperties.v
index 6e93a546..7413b06b 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 8853 2006-05-23 18:17:38Z herbelin $ *)
+(* $Id: FSetProperties.v 11064 2008-06-06 17:00:52Z letouzey $ *)
(** * Finite sets library *)
@@ -16,414 +16,259 @@
[In x s] instead of [mem x s=true],
[Equal s s'] instead of [equal s s'=true], etc. *)
-Require Export FSetInterface.
-Require Import FSetFacts.
+Require Export FSetInterface.
+Require Import DecidableTypeEx FSetFacts FSetDecide.
Set Implicit Arguments.
Unset Strict Implicit.
-Hint Unfold transpose compat_op compat_nat.
+Hint Unfold transpose compat_op.
Hint Extern 1 (Setoid_Theory _ _) => constructor; congruence.
-Module Properties (M: S).
- Module ME:=OrderedTypeFacts(M.E).
- Import ME. (* for ME.eq_dec *)
- Import M.E.
- Import M.
- Import Logic. (* to unmask [eq] *)
- Import Peano. (* to unmask [lt] *)
-
- (** Results about lists without duplicates *)
+(** 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. *)
- Module FM := Facts M.
- Import FM.
-
- Definition Add (x : elt) (s s' : t) :=
- forall y : elt, In y s' <-> E.eq x y \/ In y s.
+Module WProperties (Import E : DecidableType)(M : WSfun E).
+ Module Import Dec := WDecide E M.
+ Module Import FM := Dec.F (* FSetFacts.WFacts E M *).
+ Import M.
Lemma In_dec : forall x s, {In x s} + {~ In x s}.
Proof.
intros; generalize (mem_iff s x); case (mem x s); intuition.
Qed.
- Section BasicProperties.
-
- (** properties of [Equal] *)
+ Definition Add x s s' := forall y, In y s' <-> E.eq x y \/ In y s.
- Lemma equal_refl : forall s, s[=]s.
+ Lemma Add_Equal : forall x s s', Add x s s' <-> s' [=] add x s.
Proof.
- unfold Equal; intuition.
- Qed.
-
- Lemma equal_sym : forall s s', s[=]s' -> s'[=]s.
- Proof.
- unfold Equal; intros.
- rewrite H; intuition.
+ unfold Add.
+ split; intros.
+ red; intros.
+ rewrite H; clear H.
+ fsetdec.
+ fsetdec.
Qed.
+
+ Ltac expAdd := repeat rewrite Add_Equal.
- Lemma equal_trans : forall s1 s2 s3, s1[=]s2 -> s2[=]s3 -> s1[=]s3.
- Proof.
- unfold Equal; intros.
- rewrite H; exact (H0 a).
- Qed.
+ Section BasicProperties.
Variable s s' s'' s1 s2 s3 : t.
Variable x x' : elt.
- (** properties of [Subset] *)
-
- Lemma subset_refl : s[<=]s.
- Proof.
- unfold Subset; intuition.
- Qed.
+ Lemma equal_refl : s[=]s.
+ Proof. fsetdec. Qed.
- Lemma subset_antisym : s[<=]s' -> s'[<=]s -> s[=]s'.
- Proof.
- unfold Subset, Equal; intuition.
- Qed.
+ Lemma equal_sym : s[=]s' -> s'[=]s.
+ Proof. fsetdec. Qed.
+
+ Lemma equal_trans : s1[=]s2 -> s2[=]s3 -> s1[=]s3.
+ Proof. fsetdec. Qed.
+
+ Lemma subset_refl : s[<=]s.
+ Proof. fsetdec. Qed.
Lemma subset_trans : s1[<=]s2 -> s2[<=]s3 -> s1[<=]s3.
- Proof.
- unfold Subset; intuition.
- Qed.
+ Proof. fsetdec. Qed.
+
+ Lemma subset_antisym : s[<=]s' -> s'[<=]s -> s[=]s'.
+ Proof. fsetdec. Qed.
Lemma subset_equal : s[=]s' -> s[<=]s'.
- Proof.
- unfold Subset, Equal; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma subset_empty : empty[<=]s.
- Proof.
- unfold Subset; intros a; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma subset_remove_3 : s1[<=]s2 -> remove x s1 [<=] s2.
- Proof.
- unfold Subset; intros H a; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma subset_diff : s1[<=]s3 -> diff s1 s2 [<=] s3.
- Proof.
- unfold Subset; intros H a; set_iff; intuition.
- Qed.
-
+ Proof. fsetdec. Qed.
+
Lemma subset_add_3 : In x s2 -> s1[<=]s2 -> add x s1 [<=] s2.
- Proof.
- unfold Subset; intros H H0 a; set_iff; intuition.
- rewrite <- H2; auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma subset_add_2 : s1[<=]s2 -> s1[<=] add x s2.
- Proof.
- unfold Subset; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma in_subset : In x s1 -> s1[<=]s2 -> In x s2.
- Proof.
- unfold Subset; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma double_inclusion : s1[=]s2 <-> s1[<=]s2 /\ s2[<=]s1.
- Proof.
- unfold Subset, Equal; split; intros; intuition; generalize (H a); intuition.
- Qed.
-
- (** properties of [empty] *)
+ Proof. intuition fsetdec. Qed.
Lemma empty_is_empty_1 : Empty s -> s[=]empty.
- Proof.
- unfold Empty, Equal; intros; generalize (H a); set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma empty_is_empty_2 : s[=]empty -> Empty s.
- Proof.
- unfold Empty, Equal; intros; generalize (H a); set_iff; tauto.
- Qed.
-
- (** properties of [add] *)
+ Proof. fsetdec. Qed.
Lemma add_equal : In x s -> add x s [=] s.
- Proof.
- unfold Equal; intros; set_iff; intuition.
- rewrite <- H1; auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma add_add : add x (add x' s) [=] add x' (add x s).
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
-
- (** properties of [remove] *)
+ Proof. fsetdec. Qed.
Lemma remove_equal : ~ In x s -> remove x s [=] s.
- Proof.
- unfold Equal; intros; set_iff; intuition.
- rewrite H1 in H; auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma Equal_remove : s[=]s' -> remove x s [=] remove x s'.
- Proof.
- intros; rewrite H; apply equal_refl.
- Qed.
-
- (** properties of [add] and [remove] *)
+ Proof. fsetdec. Qed.
Lemma add_remove : In x s -> add x (remove x s) [=] s.
- Proof.
- unfold Equal; intros; set_iff; elim (eq_dec x a); intuition.
- rewrite <- H1; auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma remove_add : ~In x s -> remove x (add x s) [=] s.
- Proof.
- unfold Equal; intros; set_iff; elim (eq_dec x a); intuition.
- rewrite H1 in H; auto.
- Qed.
-
- (** properties of [singleton] *)
+ Proof. fsetdec. Qed.
Lemma singleton_equal_add : singleton x [=] add x empty.
- Proof.
- unfold Equal; intros; set_iff; intuition.
- Qed.
-
- (** properties of [union] *)
+ Proof. fsetdec. Qed.
Lemma union_sym : union s s' [=] union s' s.
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_subset_equal : s[<=]s' -> union s s' [=] s'.
- Proof.
- unfold Subset, Equal; intros; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_equal_1 : s[=]s' -> union s s'' [=] union s' s''.
- Proof.
- intros; rewrite H; apply equal_refl.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_equal_2 : s'[=]s'' -> union s s' [=] union s s''.
- Proof.
- intros; rewrite H; apply equal_refl.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_assoc : union (union s s') s'' [=] union s (union s' s'').
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma add_union_singleton : add x s [=] union (singleton x) s.
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_add : union (add x s) s' [=] add x (union s s').
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
+
+ Lemma union_remove_add_1 :
+ union (remove x s) (add x s') [=] union (add x s) (remove x s').
+ Proof. fsetdec. Qed.
+
+ Lemma union_remove_add_2 : In x s ->
+ union (remove x s) (add x s') [=] union s s'.
+ Proof. fsetdec. Qed.
Lemma union_subset_1 : s [<=] union s s'.
- Proof.
- unfold Subset; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_subset_2 : s' [<=] union s s'.
- Proof.
- unfold Subset; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_subset_3 : s[<=]s'' -> s'[<=]s'' -> union s s' [<=] s''.
- Proof.
- unfold Subset; intros H H0 a; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_subset_4 : s[<=]s' -> union s s'' [<=] union s' s''.
- Proof.
- unfold Subset; intros H a; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_subset_5 : s[<=]s' -> union s'' s [<=] union s'' s'.
- Proof.
- unfold Subset; intros H a; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma empty_union_1 : Empty s -> union s s' [=] s'.
- Proof.
- unfold Equal, Empty; intros; set_iff; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma empty_union_2 : Empty s -> union s' s [=] s'.
- Proof.
- unfold Equal, Empty; intros; set_iff; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma not_in_union : ~In x s -> ~In x s' -> ~In x (union s s').
- Proof.
- intros; set_iff; intuition.
- Qed.
-
- (** properties of [inter] *)
+ Proof. fsetdec. Qed.
Lemma inter_sym : inter s s' [=] inter s' s.
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_subset_equal : s[<=]s' -> inter s s' [=] s.
- Proof.
- unfold Equal; intros; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_equal_1 : s[=]s' -> inter s s'' [=] inter s' s''.
- Proof.
- intros; rewrite H; apply equal_refl.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_equal_2 : s'[=]s'' -> inter s s' [=] inter s s''.
- Proof.
- intros; rewrite H; apply equal_refl.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_assoc : inter (inter s s') s'' [=] inter s (inter s' s'').
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_inter_1 : inter (union s s') s'' [=] union (inter s s'') (inter s' s'').
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma union_inter_2 : union (inter s s') s'' [=] inter (union s s'') (union s' s'').
- Proof.
- unfold Equal; intros; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_add_1 : In x s' -> inter (add x s) s' [=] add x (inter s s').
- Proof.
- unfold Equal; intros; set_iff; intuition.
- rewrite <- H1; auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_add_2 : ~ In x s' -> inter (add x s) s' [=] inter s s'.
- Proof.
- unfold Equal; intros; set_iff; intuition.
- destruct H; rewrite H0; auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma empty_inter_1 : Empty s -> Empty (inter s s').
- Proof.
- unfold Empty; intros; set_iff; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma empty_inter_2 : Empty s' -> Empty (inter s s').
- Proof.
- unfold Empty; intros; set_iff; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_subset_1 : inter s s' [<=] s.
- Proof.
- unfold Subset; intro a; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_subset_2 : inter s s' [<=] s'.
- Proof.
- unfold Subset; intro a; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma inter_subset_3 :
s''[<=]s -> s''[<=]s' -> s''[<=] inter s s'.
- Proof.
- unfold Subset; intros H H' a; set_iff; intuition.
- Qed.
-
- (** properties of [diff] *)
+ Proof. fsetdec. Qed.
Lemma empty_diff_1 : Empty s -> Empty (diff s s').
- Proof.
- unfold Empty, Equal; intros; set_iff; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma empty_diff_2 : Empty s -> diff s' s [=] s'.
- Proof.
- unfold Empty, Equal; intros; set_iff; firstorder.
- Qed.
+ Proof. fsetdec. Qed.
Lemma diff_subset : diff s s' [<=] s.
- Proof.
- unfold Subset; intros a; set_iff; tauto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma diff_subset_equal : s[<=]s' -> diff s s' [=] empty.
- Proof.
- unfold Subset, Equal; intros; set_iff; intuition; absurd (In a empty); auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma remove_diff_singleton :
remove x s [=] diff s (singleton x).
- Proof.
- unfold Equal; intros; set_iff; intuition.
- Qed.
+ Proof. fsetdec. Qed.
Lemma diff_inter_empty : inter (diff s s') (inter s s') [=] empty.
- Proof.
- unfold Equal; intros; set_iff; intuition; absurd (In a empty); auto.
- Qed.
+ Proof. fsetdec. Qed.
Lemma diff_inter_all : union (diff s s') (inter s s') [=] s.
- Proof.
- unfold Equal; intros; set_iff; intuition.
- elim (In_dec a s'); auto.
- Qed.
-
- (** properties of [Add] *)
+ Proof. fsetdec. Qed.
Lemma Add_add : Add x s (add x s).
- Proof.
- unfold Add; intros; set_iff; intuition.
- Qed.
+ Proof. expAdd; fsetdec. Qed.
Lemma Add_remove : In x s -> Add x (remove x s) s.
- Proof.
- unfold Add; intros; set_iff; intuition.
- elim (eq_dec x y); auto.
- rewrite <- H1; auto.
- Qed.
+ Proof. expAdd; fsetdec. Qed.
Lemma union_Add : Add x s s' -> Add x (union s s'') (union s' s'').
- Proof.
- unfold Add; intros; set_iff; rewrite H; tauto.
- Qed.
+ Proof. expAdd; fsetdec. Qed.
Lemma inter_Add :
In x s'' -> Add x s s' -> Add x (inter s s'') (inter s' s'').
- Proof.
- unfold Add; intros; set_iff; rewrite H0; intuition.
- rewrite <- H2; auto.
- Qed.
+ Proof. expAdd; fsetdec. Qed.
Lemma union_Equal :
In x s'' -> Add x s s' -> union s s'' [=] union s' s''.
- Proof.
- unfold Add, Equal; intros; set_iff; rewrite H0; intuition.
- rewrite <- H1; auto.
- Qed.
+ Proof. expAdd; fsetdec. Qed.
Lemma inter_Add_2 :
~In x s'' -> Add x s s' -> inter s s'' [=] inter s' s''.
- Proof.
- unfold Add, Equal; intros; set_iff; rewrite H0; intuition.
- destruct H; rewrite H1; auto.
- Qed.
+ Proof. expAdd; fsetdec. Qed.
End BasicProperties.
- Hint Immediate equal_sym: set.
- Hint Resolve equal_refl equal_trans : set.
-
- Hint Immediate add_remove remove_add union_sym inter_sym: set.
- Hint Resolve subset_refl subset_equal subset_antisym
+ Hint Immediate equal_sym add_remove remove_add union_sym inter_sym: set.
+ Hint Resolve equal_refl equal_trans subset_refl subset_equal subset_antisym
subset_trans subset_empty subset_remove_3 subset_diff subset_add_3
subset_add_2 in_subset empty_is_empty_1 empty_is_empty_2 add_equal
remove_equal singleton_equal_add union_subset_equal union_equal_1
@@ -436,6 +281,31 @@ Module Properties (M: S).
remove_diff_singleton diff_inter_empty diff_inter_all Add_add Add_remove
Equal_remove add_add : set.
+ (** * Properties of elements *)
+
+ Lemma elements_Empty : forall s, Empty s <-> elements s = nil.
+ Proof.
+ intros.
+ unfold Empty.
+ split; intros.
+ assert (forall a, ~ List.In a (elements s)).
+ red; intros.
+ apply (H a).
+ rewrite elements_iff.
+ rewrite InA_alt; exists a; auto.
+ destruct (elements s); auto.
+ elim (H0 e); simpl; auto.
+ red; intros.
+ rewrite elements_iff in H0.
+ rewrite InA_alt in H0; destruct H0.
+ rewrite H in H0; destruct H0 as (_,H0); inversion H0.
+ Qed.
+
+ Lemma elements_empty : elements empty = nil.
+ Proof.
+ rewrite <-elements_Empty; auto with set.
+ Qed.
+
(** * Alternative (weaker) specifications for [fold] *)
Section Old_Spec_Now_Properties.
@@ -447,14 +317,14 @@ Module Properties (M: S).
*)
Lemma fold_0 :
- forall s (A : Set) (i : A) (f : elt -> A -> A),
+ 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) /\
fold f s i = fold_right f i l.
Proof.
intros; exists (rev (elements s)); split.
- apply NoDupA_rev; auto.
+ apply NoDupA_rev; auto with set.
exact E.eq_trans.
split; intros.
rewrite elements_iff; do 2 rewrite InA_alt.
@@ -468,7 +338,7 @@ Module Properties (M: S).
[fold_2]. *)
Lemma fold_1 :
- forall s (A : Set) (eqA : A -> A -> Prop)
+ forall s (A : Type) (eqA : A -> A -> Prop)
(st : Setoid_Theory A eqA) (i : A) (f : elt -> A -> A),
Empty s -> eqA (fold f s i) i.
Proof.
@@ -481,7 +351,7 @@ Module Properties (M: S).
Qed.
Lemma fold_2 :
- forall s s' x (A : Set) (eqA : A -> A -> Prop)
+ forall s s' x (A : Type) (eqA : A -> A -> Prop)
(st : Setoid_Theory A eqA) (i : A) (f : elt -> A -> A),
compat_op E.eq eqA f ->
transpose eqA f ->
@@ -492,9 +362,21 @@ Module Properties (M: S).
rewrite Hl2; rewrite Hl'2; clear Hl2 Hl'2.
apply fold_right_add with (eqA:=E.eq)(eqB:=eqA); auto.
eauto.
- exact eq_dec.
rewrite <- Hl1; auto.
- intros; rewrite <- Hl1; rewrite <- Hl'1; auto.
+ intros a; rewrite InA_cons; rewrite <- Hl1; rewrite <- Hl'1;
+ rewrite (H2 a); intuition.
+ Qed.
+
+ (** In fact, [fold] on empty sets is more than equivalent to
+ the initial element, it is Leibniz-equal to it. *)
+
+ Lemma fold_1b :
+ forall s (A : Type)(i : A) (f : elt -> A -> A),
+ Empty s -> (fold f s i) = i.
+ Proof.
+ intros.
+ rewrite M.fold_1.
+ rewrite elements_Empty in H; rewrite H; simpl; auto.
Qed.
(** Similar specifications for [cardinal]. *)
@@ -531,41 +413,46 @@ Module Properties (M: S).
(** * Induction principle over sets *)
+ 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 s; rewrite M.cardinal_1; intros H a; red.
- rewrite elements_iff.
- destruct (elements s); simpl in *; discriminate || inversion 1.
+ 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.
+ intros; rewrite M.cardinal_1 in H.
+ generalize (elements_2 (s:=s)).
+ destruct (elements s); try discriminate.
+ exists e; auto.
Qed.
- Lemma Equal_cardinal_aux :
- forall n s s', cardinal s = n -> s[=]s' -> cardinal s = cardinal s'.
+ Lemma cardinal_inv_2b :
+ forall s, cardinal s <> 0 -> { x : elt | In x s }.
Proof.
- simple induction n; intros.
- rewrite H; symmetry .
- apply cardinal_1.
- rewrite <- H0; auto.
- destruct (cardinal_inv_2 H0) as (x,H2).
- revert H0.
- 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)); auto with set.
- rewrite H1 in H2; auto with set.
+ intro; generalize (@cardinal_inv_2 s); destruct cardinal;
+ [intuition|eauto].
Qed.
Lemma Equal_cardinal : forall s s', s[=]s' -> cardinal s = cardinal s'.
Proof.
- intros; apply Equal_cardinal_aux with (cardinal s); auto.
- Qed.
+ 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.
@@ -574,40 +461,33 @@ Module Properties (M: S).
Hint Resolve Add_add Add_remove Equal_remove cardinal_inv_1 Equal_cardinal.
- Lemma cardinal_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 n s, cardinal s = n -> P s.
- Proof.
- simple induction n; intros; auto.
- destruct (cardinal_inv_2 H) as (x,H0).
- apply X0 with (remove x s) x; auto.
- apply X1; auto.
- rewrite (cardinal_2 (x:=x)(s:=remove x s)(s':=s)) in H; auto.
- Qed.
-
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.
Proof.
- intros; apply cardinal_induction with (cardinal s); auto.
- Qed.
+ 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:Set)(eqA:A->A->Prop)(st:Setoid_Theory _ eqA).
+ 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 : eqA (fold f empty i) i.
+ Lemma fold_empty : (fold f empty i) = i.
Proof.
- apply fold_1; auto.
+ apply fold_1b; auto with set.
Qed.
Lemma fold_equal :
@@ -642,7 +522,7 @@ Module Properties (M: S).
Proof.
intros.
sym_st.
- apply fold_2 with (eqA:=eqA); auto.
+ apply fold_2 with (eqA:=eqA); auto with set.
Qed.
Lemma remove_fold_2: forall s x, ~In x s ->
@@ -742,7 +622,8 @@ Module Properties (M: S).
apply fold_1; auto with set.
Qed.
- Lemma fold_union: forall s s', (forall x, ~In x s\/~In x s') ->
+ Lemma fold_union: forall 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.
@@ -760,8 +641,8 @@ Module Properties (M: S).
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 (@eq _) (fun _ => S)) by (unfold compat_op; auto).
- assert (fp : transpose (@eq _) (fun _:elt => S)) by (unfold transpose; auto).
+ 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.
@@ -774,11 +655,11 @@ Module Properties (M: S).
simpl; auto.
Qed.
- (** properties of [cardinal] *)
+ (** more properties of [cardinal] *)
Lemma empty_cardinal : cardinal empty = 0.
Proof.
- rewrite cardinal_fold; apply fold_1; auto.
+ rewrite cardinal_fold; apply fold_1; auto with set.
Qed.
Hint Immediate empty_cardinal cardinal_1 : set.
@@ -798,11 +679,11 @@ Module Properties (M: S).
Proof.
intros; do 3 rewrite cardinal_fold.
rewrite <- fold_plus.
- apply fold_diff_inter with (eqA:=@eq nat); auto.
+ apply fold_diff_inter with (eqA:=@Logic.eq nat); auto.
Qed.
Lemma union_cardinal:
- forall s s', (forall x, ~In x s\/~In x s') ->
+ forall s s', (forall x, ~(In x s/\In x s')) ->
cardinal (union s s')=cardinal s+cardinal s'.
Proof.
intros; do 3 rewrite cardinal_fold.
@@ -841,7 +722,7 @@ Module Properties (M: S).
intros.
do 4 rewrite cardinal_fold.
do 2 rewrite <- fold_plus.
- apply fold_union_inter with (eqA:=@eq nat); auto.
+ apply fold_union_inter with (eqA:=@Logic.eq nat); auto.
Qed.
Lemma union_cardinal_inter :
@@ -872,7 +753,7 @@ Module Properties (M: S).
intros.
do 2 rewrite cardinal_fold.
change S with ((fun _ => S) x);
- apply fold_add with (eqA:=@eq nat); auto.
+ apply fold_add with (eqA:=@Logic.eq nat); auto.
Qed.
Lemma remove_cardinal_1 :
@@ -881,7 +762,7 @@ Module Properties (M: S).
intros.
do 2 rewrite cardinal_fold.
change S with ((fun _ =>S) x).
- apply remove_fold_1 with (eqA:=@eq nat); auto.
+ apply remove_fold_1 with (eqA:=@Logic.eq nat); auto.
Qed.
Lemma remove_cardinal_2 :
@@ -892,4 +773,295 @@ Module Properties (M: S).
Hint Resolve subset_cardinal union_cardinal add_cardinal_1 add_cardinal_2.
+End WProperties.
+
+
+(** A clone of [WProperties] working on full sets. *)
+
+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,
+ invalid for Weak Sets. *)
+
+Module OrdProperties (M:S).
+ Module ME:=OrderedTypeFacts(M.E).
+ Module Import P := Properties M.
+ Import FM.
+ Import M.E.
+ Import M.
+
+ (** First, a specialized version of SortA_equivlistA_eqlistA: *)
+ Lemma sort_equivlistA_eqlistA : forall l l' : list elt,
+ sort E.lt l -> sort E.lt l' -> equivlistA E.eq l l' -> eqlistA E.eq l l'.
+ Proof.
+ apply SortA_equivlistA_eqlistA; eauto.
+ Qed.
+
+ Definition gtb x y := match E.compare x y with GT _ => true | _ => false end.
+ Definition leb x := fun y => negb (gtb x y).
+
+ Definition elements_lt x s := List.filter (gtb x) (elements s).
+ Definition elements_ge x s := List.filter (leb x) (elements s).
+
+ Lemma gtb_1 : forall x y, gtb x y = true <-> E.lt y x.
+ Proof.
+ intros; unfold gtb; destruct (E.compare x y); intuition; try discriminate; ME.order.
+ Qed.
+
+ Lemma leb_1 : forall x y, leb x y = true <-> ~E.lt y x.
+ Proof.
+ intros; unfold leb, gtb; destruct (E.compare x y); intuition; try discriminate; ME.order.
+ Qed.
+
+ Lemma gtb_compat : forall x, compat_bool E.eq (gtb x).
+ Proof.
+ red; intros x a b H.
+ generalize (gtb_1 x a)(gtb_1 x b); destruct (gtb x a); destruct (gtb x b); auto.
+ intros.
+ symmetry; rewrite H1.
+ apply ME.eq_lt with a; auto.
+ rewrite <- H0; auto.
+ intros.
+ rewrite H0.
+ apply ME.eq_lt with b; auto.
+ rewrite <- H1; auto.
+ Qed.
+
+ Lemma leb_compat : forall x, compat_bool E.eq (leb x).
+ Proof.
+ red; intros x a b H; unfold leb.
+ f_equal; apply gtb_compat; auto.
+ Qed.
+ Hint Resolve gtb_compat leb_compat.
+
+ Lemma elements_split : forall x s,
+ elements s = elements_lt x s ++ elements_ge x s.
+ Proof.
+ unfold elements_lt, elements_ge, leb; intros.
+ eapply (@filter_split _ E.eq); eauto with set. ME.order. ME.order. ME.order.
+ intros.
+ rewrite gtb_1 in H.
+ assert (~E.lt y x).
+ unfold gtb in *; destruct (E.compare x y); intuition; try discriminate; ME.order.
+ ME.order.
+ Qed.
+
+ Lemma elements_Add : forall s s' x, ~In x s -> Add x s s' ->
+ eqlistA E.eq (elements s') (elements_lt x s ++ x :: elements_ge x s).
+ Proof.
+ intros; unfold elements_ge, elements_lt.
+ apply sort_equivlistA_eqlistA; auto with set.
+ apply (@SortA_app _ E.eq); auto.
+ apply (@filter_sort _ E.eq); auto with set; eauto with set.
+ constructor; auto.
+ apply (@filter_sort _ E.eq); auto with set; eauto with set.
+ rewrite ME.Inf_alt by (apply (@filter_sort _ E.eq); eauto with set).
+ intros.
+ rewrite filter_InA in H1; auto; destruct H1.
+ rewrite leb_1 in H2.
+ rewrite <- elements_iff in H1.
+ assert (~E.eq x y).
+ contradict H; rewrite H; auto.
+ ME.order.
+ intros.
+ rewrite filter_InA in H1; auto; destruct H1.
+ rewrite gtb_1 in H3.
+ inversion_clear H2.
+ ME.order.
+ rewrite filter_InA in H4; auto; destruct H4.
+ rewrite leb_1 in H4.
+ ME.order.
+ red; intros a.
+ rewrite InA_app_iff; rewrite InA_cons.
+ do 2 (rewrite filter_InA; auto).
+ do 2 rewrite <- elements_iff.
+ rewrite leb_1; rewrite gtb_1.
+ rewrite (H0 a); intuition.
+ destruct (E.compare a x); intuition.
+ right; right; split; auto.
+ ME.order.
+ Qed.
+
+ Definition Above x s := forall y, In y s -> E.lt y x.
+ Definition Below x s := forall y, In y s -> E.lt x y.
+
+ Lemma elements_Add_Above : forall s s' x,
+ Above x s -> Add x s s' ->
+ eqlistA E.eq (elements s') (elements s ++ x::nil).
+ Proof.
+ intros.
+ apply sort_equivlistA_eqlistA; auto with set.
+ apply (@SortA_app _ E.eq); auto with set.
+ intros.
+ inversion_clear H2.
+ rewrite <- elements_iff in H1.
+ apply ME.lt_eq with x; auto.
+ inversion H3.
+ red; intros a.
+ rewrite InA_app_iff; rewrite InA_cons; rewrite InA_nil.
+ do 2 rewrite <- elements_iff; rewrite (H0 a); intuition.
+ Qed.
+
+ Lemma elements_Add_Below : forall s s' x,
+ Below x s -> Add x s s' ->
+ eqlistA E.eq (elements s') (x::elements s).
+ Proof.
+ intros.
+ apply sort_equivlistA_eqlistA; auto with set.
+ change (sort E.lt ((x::nil) ++ elements s)).
+ apply (@SortA_app _ E.eq); auto with set.
+ intros.
+ inversion_clear H1.
+ rewrite <- elements_iff in H2.
+ apply ME.eq_lt with x; auto.
+ inversion H3.
+ red; intros a.
+ rewrite InA_cons.
+ do 2 rewrite <- elements_iff; rewrite (H0 a); intuition.
+ Qed.
+
+ (** Two other induction principles on sets: we can be more restrictive
+ on the element we add at each step. *)
+
+ Lemma set_induction_max :
+ forall P : t -> Type,
+ (forall s : t, Empty s -> P s) ->
+ (forall s s', P s -> forall x, Above x s -> Add x s s' -> P s') ->
+ forall s : t, P s.
+ Proof.
+ intros; remember (cardinal s) as n; revert s Heqn; induction n; intros; auto.
+ case_eq (max_elt s); intros.
+ apply X0 with (remove e s) e; auto with set.
+ apply IHn.
+ assert (S n = S (cardinal (remove e s))).
+ rewrite Heqn; apply cardinal_2 with e; auto with set.
+ inversion H0; auto.
+ red; intros.
+ rewrite remove_iff in H0; destruct H0.
+ generalize (@max_elt_2 s e y H H0); ME.order.
+
+ assert (H0:=max_elt_3 H).
+ rewrite cardinal_Empty in H0; rewrite H0 in Heqn; inversion Heqn.
+ Qed.
+
+ Lemma set_induction_min :
+ forall P : t -> Type,
+ (forall s : t, Empty s -> P s) ->
+ (forall s s', P s -> forall x, Below x s -> Add x s s' -> P s') ->
+ forall s : t, P s.
+ Proof.
+ intros; remember (cardinal s) as n; revert s Heqn; induction n; intros; auto.
+ case_eq (min_elt s); intros.
+ apply X0 with (remove e s) e; auto with set.
+ apply IHn.
+ assert (S n = S (cardinal (remove e s))).
+ rewrite Heqn; apply cardinal_2 with e; auto with set.
+ inversion H0; auto.
+ red; intros.
+ rewrite remove_iff in H0; destruct H0.
+ generalize (@min_elt_2 s e y H H0); ME.order.
+
+ assert (H0:=min_elt_3 H).
+ rewrite cardinal_Empty in H0; auto; rewrite H0 in Heqn; inversion Heqn.
+ Qed.
+
+ (** More properties of [fold] : behavior with respect to Above/Below *)
+
+ Lemma fold_3 :
+ forall s s' x (A : Type) (eqA : A -> A -> Prop)
+ (st : Setoid_Theory A 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.
+ intros.
+ do 2 rewrite M.fold_1.
+ do 2 rewrite <- fold_left_rev_right.
+ change (f x (fold_right f i (rev (elements s)))) with
+ (fold_right f i (rev (x::nil)++rev (elements s))).
+ apply (@fold_right_eqlistA E.t E.eq A eqA st); auto.
+ rewrite <- distr_rev.
+ apply eqlistA_rev.
+ apply elements_Add_Above; auto.
+ Qed.
+
+ Lemma fold_4 :
+ forall s s' x (A : Type) (eqA : A -> A -> Prop)
+ (st : Setoid_Theory A 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.
+ intros.
+ do 2 rewrite M.fold_1.
+ set (g:=fun (a : A) (e : elt) => f e a).
+ change (eqA (fold_left g (elements s') i) (fold_left g (x::elements s) i)).
+ unfold g.
+ do 2 rewrite <- fold_left_rev_right.
+ apply (@fold_right_eqlistA E.t E.eq A eqA st); auto.
+ apply eqlistA_rev.
+ apply elements_Add_Below; auto.
+ Qed.
+
+ (** The following results have already been proved earlier,
+ but we can now prove them with one hypothesis less:
+ no need for [(transpose eqA f)]. *)
+
+ Section FoldOpt.
+ Variables (A:Type)(eqA:A->A->Prop)(st:Setoid_Theory _ eqA).
+ Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f).
+
+ Lemma fold_equal :
+ forall i s s', s[=]s' -> eqA (fold f s i) (fold f s' i).
+ Proof.
+ intros; do 2 rewrite M.fold_1.
+ do 2 rewrite <- fold_left_rev_right.
+ apply (@fold_right_eqlistA E.t E.eq A eqA st); auto.
+ apply eqlistA_rev.
+ apply sort_equivlistA_eqlistA; auto with set.
+ 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.
+ intros; apply fold_equal; auto with set.
+ Qed.
+
+ 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.
+
+ End FoldOpt.
+
+ (** An alternative version of [choose_3] *)
+
+ Lemma choose_equal : forall s s', Equal s s' ->
+ match choose s, choose s' with
+ | Some x, Some x' => E.eq x x'
+ | None, None => True
+ | _, _ => False
+ end.
+ Proof.
+ intros s s' H;
+ generalize (@choose_1 s)(@choose_2 s)
+ (@choose_1 s')(@choose_2 s')(@choose_3 s s');
+ destruct (choose s); destruct (choose s'); simpl; intuition.
+ apply H5 with e; rewrite <-H; auto.
+ apply H5 with e; rewrite H; auto.
+ Qed.
+
+End OrdProperties.