Commit 361308c7 authored by Robbert Krebbers's avatar Robbert Krebbers

Lots of refactoring. and new results on permutations and list containment.

The refactoring includes:
* Use infix notations for the various list relations
* More consistent naming
* Put lemmas on one line whenever possible
* Change proofs into one-liners when possible
* Make better use of the "Implicit Types" command
* Improve the order of the list module by placing all definitions at the start,
  then the proofs, and finally the tactics.

Besides, there is some new machinery for proofs by reflection on lists. It is
used for a decision procedure for permutations and list containment.
parent 2783aea9
This diff is collapsed.
......@@ -42,8 +42,7 @@ Section simple_collection.
Global Instance elem_of_proper: Proper ((=) ==> () ==> iff) () | 5.
Proof. intros ???. subst. firstorder. Qed.
Lemma elem_of_union_list (Xs : list C) (x : A) :
x Xs X, X Xs x X.
Lemma elem_of_union_list Xs x : x Xs X, X Xs x X.
Proof.
split.
* induction Xs; simpl; intros HXs.
......@@ -249,13 +248,11 @@ Section collection.
Lemma not_elem_of_intersection x X Y : x X Y x X x Y.
Proof.
rewrite elem_of_intersection.
destruct (decide (x X)); tauto.
rewrite elem_of_intersection. destruct (decide (x X)); tauto.
Qed.
Lemma not_elem_of_difference x X Y : x X Y x X x Y.
Proof.
rewrite elem_of_difference.
destruct (decide (x Y)); tauto.
rewrite elem_of_difference. destruct (decide (x Y)); tauto.
Qed.
Lemma union_difference X Y : X Y Y X Y X.
Proof.
......@@ -303,19 +300,18 @@ Section collection_ops.
( x y z, Q x P y f x y = Some z P z)
x, x intersection_with_list f Y Xs P x.
Proof.
intros HY HXs Hf.
induction Xs; simplify_option_equality; [done |].
intros HY HXs Hf. induction Xs; simplify_option_equality; [done |].
intros x Hx. rewrite elem_of_intersection_with in Hx.
decompose_Forall. destruct Hx as (? & ? & ? & ? & ?). eauto.
Qed.
End collection_ops.
(** * Sets without duplicates up to an equivalence *)
Section no_dup.
Section NoDup.
Context `{SimpleCollection A B} (R : relation A) `{!Equivalence R}.
Definition elem_of_upto (x : A) (X : B) := y, y X R x y.
Definition no_dup (X : B) := x y, x X y X R x y x = y.
Definition set_NoDup (X : B) := x y, x X y X R x y x = y.
Global Instance: Proper (() ==> iff) (elem_of_upto x).
Proof. intros ??? E. unfold elem_of_upto. by setoid_rewrite E. Qed.
......@@ -325,7 +321,7 @@ Section no_dup.
* rewrite <-E1, <-E2; intuition.
* rewrite E1, E2; intuition.
Qed.
Global Instance: Proper (() ==> iff) no_dup.
Global Instance: Proper (() ==> iff) set_NoDup.
Proof. firstorder. Qed.
Lemma elem_of_upto_elem_of x X : x X elem_of_upto x X.
......@@ -341,60 +337,63 @@ Section no_dup.
Lemma not_elem_of_upto x X : ¬elem_of_upto x X y, y X ¬R x y.
Proof. unfold elem_of_upto. esolve_elem_of. Qed.
Lemma no_dup_empty: no_dup .
Proof. unfold no_dup. solve_elem_of. Qed.
Lemma no_dup_add x X : ¬elem_of_upto x X no_dup X no_dup ({[ x ]} X).
Proof. unfold no_dup, elem_of_upto. esolve_elem_of. Qed.
Lemma no_dup_inv_add x X : x X no_dup ({[ x ]} X) ¬elem_of_upto x X.
Lemma set_NoDup_empty: set_NoDup .
Proof. unfold set_NoDup. solve_elem_of. Qed.
Lemma set_NoDup_add x X :
¬elem_of_upto x X set_NoDup X set_NoDup ({[ x ]} X).
Proof. unfold set_NoDup, elem_of_upto. esolve_elem_of. Qed.
Lemma set_NoDup_inv_add x X :
x X set_NoDup ({[ x ]} X) ¬elem_of_upto x X.
Proof.
intros Hin Hnodup [y [??]].
rewrite (Hnodup x y) in Hin; solve_elem_of.
Qed.
Lemma no_dup_inv_union_l X Y : no_dup (X Y) no_dup X.
Proof. unfold no_dup. solve_elem_of. Qed.
Lemma no_dup_inv_union_r X Y : no_dup (X Y) no_dup Y.
Proof. unfold no_dup. solve_elem_of. Qed.
End no_dup.
Lemma set_NoDup_inv_union_l X Y : set_NoDup (X Y) set_NoDup X.
Proof. unfold set_NoDup. solve_elem_of. Qed.
Lemma set_NoDup_inv_union_r X Y : set_NoDup (X Y) set_NoDup Y.
Proof. unfold set_NoDup. solve_elem_of. Qed.
End NoDup.
(** * Quantifiers *)
Section quantifiers.
Context `{SimpleCollection A B} (P : A Prop).
Definition cforall X := x, x X P x.
Definition cexists X := x, x X P x.
Lemma cforall_empty : cforall .
Proof. unfold cforall. solve_elem_of. Qed.
Lemma cforall_singleton x : cforall {[ x ]} P x.
Proof. unfold cforall. solve_elem_of. Qed.
Lemma cforall_union X Y : cforall X cforall Y cforall (X Y).
Proof. unfold cforall. solve_elem_of. Qed.
Lemma cforall_union_inv_1 X Y : cforall (X Y) cforall X.
Proof. unfold cforall. solve_elem_of. Qed.
Lemma cforall_union_inv_2 X Y : cforall (X Y) cforall Y.
Proof. unfold cforall. solve_elem_of. Qed.
Lemma cexists_empty : ¬cexists .
Proof. unfold cexists. esolve_elem_of. Qed.
Lemma cexists_singleton x : cexists {[ x ]} P x.
Proof. unfold cexists. esolve_elem_of. Qed.
Lemma cexists_union_1 X Y : cexists X cexists (X Y).
Proof. unfold cexists. esolve_elem_of. Qed.
Lemma cexists_union_2 X Y : cexists Y cexists (X Y).
Proof. unfold cexists. esolve_elem_of. Qed.
Lemma cexists_union_inv X Y : cexists (X Y) cexists X cexists Y.
Proof. unfold cexists. esolve_elem_of. Qed.
Definition set_Forall X := x, x X P x.
Definition set_Exists X := x, x X P x.
Lemma set_Forall_empty : set_Forall .
Proof. unfold set_Forall. solve_elem_of. Qed.
Lemma set_Forall_singleton x : set_Forall {[ x ]} P x.
Proof. unfold set_Forall. solve_elem_of. Qed.
Lemma set_Forall_union X Y : set_Forall X set_Forall Y set_Forall (X Y).
Proof. unfold set_Forall. solve_elem_of. Qed.
Lemma set_Forall_union_inv_1 X Y : set_Forall (X Y) set_Forall X.
Proof. unfold set_Forall. solve_elem_of. Qed.
Lemma set_Forall_union_inv_2 X Y : set_Forall (X Y) set_Forall Y.
Proof. unfold set_Forall. solve_elem_of. Qed.
Lemma set_Exists_empty : ¬set_Exists .
Proof. unfold set_Exists. esolve_elem_of. Qed.
Lemma set_Exists_singleton x : set_Exists {[ x ]} P x.
Proof. unfold set_Exists. esolve_elem_of. Qed.
Lemma set_Exists_union_1 X Y : set_Exists X set_Exists (X Y).
Proof. unfold set_Exists. esolve_elem_of. Qed.
Lemma set_Exists_union_2 X Y : set_Exists Y set_Exists (X Y).
Proof. unfold set_Exists. esolve_elem_of. Qed.
Lemma set_Exists_union_inv X Y :
set_Exists (X Y) set_Exists X set_Exists Y.
Proof. unfold set_Exists. esolve_elem_of. Qed.
End quantifiers.
Section more_quantifiers.
Context `{Collection A B}.
Lemma cforall_weaken (P Q : A Prop) (Hweaken : x, P x Q x) X :
cforall P X cforall Q X.
Proof. unfold cforall. naive_solver. Qed.
Lemma cexists_weaken (P Q : A Prop) (Hweaken : x, P x Q x) X :
cexists P X cexists Q X.
Proof. unfold cexists. naive_solver. Qed.
Lemma set_Forall_weaken (P Q : A Prop) (Hweaken : x, P x Q x) X :
set_Forall P X set_Forall Q X.
Proof. unfold set_Forall. naive_solver. Qed.
Lemma set_Exists_weaken (P Q : A Prop) (Hweaken : x, P x Q x) X :
set_Exists P X set_Exists Q X.
Proof. unfold set_Exists. naive_solver. Qed.
End more_quantifiers.
(** * Fresh elements *)
......@@ -417,8 +416,7 @@ Section fresh.
Global Instance fresh_list_proper: Proper ((=) ==> () ==> (=)) fresh_list.
Proof.
intros ? n ?. subst.
induction n; simpl; intros ?? E; f_equal.
intros ? n ?. subst. induction n; simpl; intros ?? E; f_equal.
* by rewrite E.
* apply IHn. by rewrite E.
Qed.
......@@ -437,10 +435,8 @@ Section fresh.
Lemma fresh_list_nodup n X : NoDup (fresh_list n X).
Proof.
revert X.
induction n; simpl; constructor; auto.
intros Hin. apply fresh_list_is_fresh in Hin.
solve_elem_of.
revert X. induction n; simpl; constructor; auto.
intros Hin. apply fresh_list_is_fresh in Hin. solve_elem_of.
Qed.
End fresh.
......@@ -455,7 +451,10 @@ Section collection_monad.
Context `{CollectionMonad M}.
Global Instance collection_guard: MGuard M := λ P dec A x,
if dec then x else .
match dec with
| left H => x H
| _ =>
end.
Global Instance collection_fmap_proper {A B} (f : A B) :
Proper (() ==> ()) (fmap f).
......@@ -495,8 +494,7 @@ Section collection_monad.
Proof. revert l; induction k; esolve_elem_of. Qed.
Lemma elem_of_mapM_fmap {A B} (f : A B) (g : B M A) l k :
Forall (λ x, y, y g x f y = x) l
k mapM g l fmap f k = l.
Forall (λ x, y, y g x f y = x) l k mapM g l fmap f k = l.
Proof.
intros Hl. revert k.
induction Hl; simpl; intros;
......@@ -504,14 +502,10 @@ Section collection_monad.
Qed.
Lemma elem_of_mapM_Forall {A B} (f : A M B) (P : B Prop) l k :
l mapM f k
Forall (λ x, y, y f x P y) k
Forall P l.
l mapM f k Forall (λ x, y, y f x P y) k Forall P l.
Proof. rewrite elem_of_mapM. apply Forall2_Forall_l. Qed.
Lemma elem_of_mapM_Forall2_l {A B C} (f : A M B)
(P : B C Prop) l1 l2 k :
l1 mapM f k
Forall2 (λ x y, z, z f x P z y) k l2
Lemma elem_of_mapM_Forall2_l {A B C} (f : A M B) (P: B C Prop) l1 l2 k :
l1 mapM f k Forall2 (λ x y, z, z f x P z y) k l2
Forall2 P l1 l2.
Proof.
rewrite elem_of_mapM. intros Hl1. revert l2.
......
......@@ -76,6 +76,7 @@ Notation cast_if_and3 S1 S2 S3 := (if S1 then cast_if_and S2 S3 else right _).
Notation cast_if_and4 S1 S2 S3 S4 :=
(if S1 then cast_if_and3 S2 S3 S4 else right _).
Notation cast_if_or S1 S2 := (if S1 then left _ else cast_if S2).
Notation cast_if_or3 S1 S2 S3 := (if S1 then left _ else cast_if_or S2 S3).
Notation cast_if_not_or S1 S2 := (if S1 then cast_if S2 else left _).
Notation cast_if_not S := (if S then right _ else left _).
......
......@@ -13,7 +13,7 @@ Definition collection_fold `{Elements A C} {B}
Section fin_collection.
Context `{FinCollection A C}.
Global Instance elements_proper: Proper (() ==> Permutation) elements.
Global Instance elements_proper: Proper (() ==> (≡ₚ)) elements.
Proof.
intros ?? E. apply NoDup_Permutation.
* apply elements_nodup.
......@@ -176,10 +176,8 @@ Proof.
apply Hadd. solve_elem_of. apply IH. esolve_elem_of.
Qed.
Lemma collection_fold_proper {B} (R : relation B)
`{!Equivalence R}
(f : A B B) (b : B)
`{!Proper ((=) ==> R ==> R) f}
Lemma collection_fold_proper {B} (R : relation B) `{!Equivalence R}
(f : A B B) (b : B) `{!Proper ((=) ==> R ==> R) f}
(Hf : a1 a2 b, R (f a1 (f a2 b)) (f a2 (f a1 b))) :
Proper (() ==> R) (collection_fold f b).
Proof.
......@@ -188,22 +186,22 @@ Proof.
* by rewrite E.
Qed.
Global Instance cforall_dec `(P : A Prop)
`{ x, Decision (P x)} X : Decision (cforall P X) | 100.
Global Instance set_Forall_dec `(P : A Prop)
`{ x, Decision (P x)} X : Decision (set_Forall P X) | 100.
Proof.
refine (cast_if (decide (Forall P (elements X))));
abstract (unfold cforall; setoid_rewrite elements_spec;
abstract (unfold set_Forall; setoid_rewrite elements_spec;
by rewrite <-Forall_forall).
Defined.
Global Instance cexists_dec `(P : A Prop) `{ x, Decision (P x)} X :
Decision (cexists P X) | 100.
Global Instance set_Exists_dec `(P : A Prop) `{ x, Decision (P x)} X :
Decision (set_Exists P X) | 100.
Proof.
refine (cast_if (decide (Exists P (elements X))));
abstract (unfold cexists; setoid_rewrite elements_spec;
abstract (unfold set_Exists; setoid_rewrite elements_spec;
by rewrite <-Exists_exists).
Defined.
Global Instance rel_elem_of_dec `{ x y, Decision (R x y)} x X :
Decision (elem_of_upto R x X) | 100 := decide (cexists (R x) X).
Decision (elem_of_upto R x X) | 100 := decide (set_Exists (R x) X).
End fin_collection.
......@@ -6,46 +6,34 @@ function in a generic way, to allow more efficient implementations. *)
Require Export collections fin_maps.
Class FinMapDom K M D `{!FMap M}
`{ A, Lookup K A (M A)}
`{ A, Empty (M A)}
`{ A, PartialAlter K A (M A)}
`{!Merge M}
`{ A, FinMapToList K A (M A)}
`{ A, Lookup K A (M A)} `{ A, Empty (M A)} `{ A, PartialAlter K A (M A)}
`{!Merge M} `{ A, FinMapToList K A (M A)}
`{ i j : K, Decision (i = j)}
`{ A, Dom (M A) D}
`{ElemOf K D}
`{Empty D}
`{Singleton K D}
`{Union D}
`{Intersection D}
`{Difference D} := {
`{ A, Dom (M A) D} `{ElemOf K D} `{Empty D} `{Singleton K D}
`{Union D}`{Intersection D} `{Difference D} := {
finmap_dom_map :>> FinMap K M;
finmap_dom_collection :>> Collection K D;
elem_of_dom {A} (m : M A) i : i dom D m is_Some (m !! i)
}.
Section theorems.
Section fin_map_dom.
Context `{FinMapDom K M D}.
Lemma not_elem_of_dom {A} (m : M A) i :
i dom D m m !! i = None.
Lemma not_elem_of_dom {A} (m : M A) i : i dom D m m !! i = None.
Proof. by rewrite elem_of_dom, eq_None_not_Some. Qed.
Lemma subseteq_dom {A} (m1 m2 : M A) :
m1 m2 dom D m1 dom D m2.
Lemma subseteq_dom {A} (m1 m2 : M A) : m1 m2 dom D m1 dom D m2.
Proof.
unfold subseteq, map_subseteq, collection_subseteq.
intros ??. rewrite !elem_of_dom. inversion 1. eauto.
Qed.
Lemma subset_dom {A} (m1 m2 : M A) :
m1 m2 dom D m1 dom D m2.
Lemma subset_dom {A} (m1 m2 : M A) : m1 m2 dom D m1 dom D m2.
Proof.
intros [Hss1 Hss2]. split.
{ by apply subseteq_dom. }
intros Hdom. destruct Hss2. intros i x Hi.
specialize (Hdom i). rewrite !elem_of_dom in Hdom.
feed inversion Hdom. eauto.
by erewrite (Hss1 i) in Hi by eauto.
feed inversion Hdom. eauto. by erewrite (Hss1 i) in Hi by eauto.
Qed.
Lemma dom_empty {A} : dom D (@empty (M A) _) .
......@@ -54,38 +42,32 @@ Proof.
* rewrite elem_of_dom, lookup_empty. by inversion 1.
* solve_elem_of.
Qed.
Lemma dom_empty_inv {A} (m : M A) :
dom D m m = .
Lemma dom_empty_inv {A} (m : M A) : dom D m m = .
Proof.
intros E. apply map_empty. intros. apply not_elem_of_dom.
rewrite E. solve_elem_of.
Qed.
Lemma dom_insert {A} (m : M A) i x :
dom D (<[i:=x]>m) {[ i ]} dom D m.
Lemma dom_insert {A} (m : M A) i x : dom D (<[i:=x]>m) {[ i ]} dom D m.
Proof.
apply elem_of_equiv. intros j.
rewrite elem_of_union, !elem_of_dom, !is_Some_alt.
setoid_rewrite lookup_insert_Some.
destruct (decide (i = j)); esolve_elem_of.
Qed.
Lemma dom_insert_subseteq {A} (m : M A) i x :
dom D m dom D (<[i:=x]>m).
Lemma dom_insert_subseteq {A} (m : M A) i x : dom D m dom D (<[i:=x]>m).
Proof. rewrite (dom_insert _). solve_elem_of. Qed.
Lemma dom_insert_subseteq_compat_l {A} (m : M A) i x X :
X dom D m
X dom D (<[i:=x]>m).
X dom D m X dom D (<[i:=x]>m).
Proof. intros. transitivity (dom D m); eauto using dom_insert_subseteq. Qed.
Lemma dom_singleton {A} (i : K) (x : A) :
dom D {[(i, x)]} {[ i ]}.
Lemma dom_singleton {A} (i : K) (x : A) : dom D {[(i, x)]} {[ i ]}.
Proof.
unfold singleton at 1, map_singleton.
rewrite dom_insert, dom_empty. solve_elem_of.
Qed.
Lemma dom_delete {A} (m : M A) i :
dom D (delete i m) dom D m {[ i ]}.
Lemma dom_delete {A} (m : M A) i : dom D (delete i m) dom D m {[ i ]}.
Proof.
apply elem_of_equiv. intros j.
rewrite elem_of_difference, !elem_of_dom, !is_Some_alt.
......@@ -99,27 +81,22 @@ Lemma delete_insert_dom {A} (m : M A) i x :
i dom D m delete i (<[i:=x]>m) = m.
Proof. rewrite not_elem_of_dom. apply delete_insert. Qed.
Lemma map_disjoint_dom {A} (m1 m2 : M A) :
m1 m2 dom D m1 dom D m2 .
Lemma map_disjoint_dom {A} (m1 m2 : M A) : m1 m2 dom D m1 dom D m2 .
Proof.
unfold disjoint, map_disjoint, map_intersection_forall.
rewrite elem_of_equiv_empty. setoid_rewrite elem_of_intersection.
setoid_rewrite elem_of_dom. setoid_rewrite is_Some_alt. naive_solver.
Qed.
Lemma map_disjoint_dom_1 {A} (m1 m2 : M A) :
m1 m2 dom D m1 dom D m2 .
Lemma map_disjoint_dom_1 {A} (m1 m2 : M A) : m1 m2 dom D m1 dom D m2 .
Proof. apply map_disjoint_dom. Qed.
Lemma map_disjoint_dom_2 {A} (m1 m2 : M A) :
dom D m1 dom D m2 m1 m2.
Lemma map_disjoint_dom_2 {A} (m1 m2 : M A) : dom D m1 dom D m2 m1 m2.
Proof. apply map_disjoint_dom. Qed.
Lemma dom_union {A} (m1 m2 : M A) :
dom D (m1 m2) dom D m1 dom D m2.
Lemma dom_union {A} (m1 m2 : M A) : dom D (m1 m2) dom D m1 dom D m2.
Proof.
apply elem_of_equiv. intros i.
rewrite elem_of_union, !elem_of_dom, !is_Some_alt.
setoid_rewrite lookup_union_Some_raw.
destruct (m1 !! i); naive_solver.
setoid_rewrite lookup_union_Some_raw. destruct (m1 !! i); naive_solver.
Qed.
Lemma dom_intersection {A} (m1 m2 : M A) :
......@@ -131,12 +108,10 @@ Proof.
setoid_rewrite is_Some_alt. naive_solver.
Qed.
Lemma dom_difference {A} (m1 m2 : M A) :
dom D (m1 m2) dom D m1 dom D m2.
Lemma dom_difference {A} (m1 m2 : M A) : dom D (m1 m2) dom D m1 dom D m2.
Proof.
apply elem_of_equiv. intros i.
rewrite elem_of_difference, !elem_of_dom, !is_Some_alt.
setoid_rewrite lookup_difference_Some.
destruct (m2 !! i); naive_solver.
setoid_rewrite lookup_difference_Some. destruct (m2 !! i); naive_solver.
Qed.
End theorems.
End fin_map_dom.
This diff is collapsed.
......@@ -28,9 +28,7 @@ Proof.
split.
* apply _.
* intros. unfold fresh, Nfresh.
setoid_replace X with Y; [done |].
by apply elem_of_equiv.
setoid_replace X with Y; [done |]. by apply elem_of_equiv.
* intros X E. assert (1 0)%N as []; [| done].
apply N.add_le_mono_r with (Nmax X).
by apply Nmax_max.
apply N.add_le_mono_r with (Nmax X). by apply Nmax_max.
Qed.
This diff is collapsed.
......@@ -4,25 +4,18 @@
removed. This implementation forms a monad. *)
Require Export base decidable collections list.
Record listset A := Listset {
listset_car: list A
}.
Record listset A := Listset { listset_car: list A }.
Arguments listset_car {_} _.
Arguments Listset {_} _.
Section listset.
Context {A : Type}.
Instance listset_elem_of: ElemOf A (listset A) := λ x l,
x listset_car l.
Instance listset_empty: Empty (listset A) :=
Listset [].
Instance listset_singleton: Singleton A (listset A) := λ x,
Listset [x].
Instance listset_elem_of: ElemOf A (listset A) := λ x l, x listset_car l.
Instance listset_empty: Empty (listset A) := Listset [].
Instance listset_singleton: Singleton A (listset A) := λ x, Listset [x].
Instance listset_union: Union (listset A) := λ l k,
match l, k with
| Listset l', Listset k' => Listset (l' ++ k')
end.
match l, k with Listset l', Listset k' => Listset (l' ++ k') end.
Global Instance: SimpleCollection A (listset A).
Proof.
......@@ -47,9 +40,7 @@ Instance listset_intersection_with: IntersectionWith A (listset A) := λ f l k,
| Listset l', Listset k' => Listset (list_intersection_with f l' k')
end.
Instance listset_filter: Filter A (listset A) := λ P _ l,
match l with
| Listset l' => Listset (filter P l')
end.
match l with Listset l' => Listset (filter P l') end.
Instance: Collection A (listset A).
Proof.
......@@ -59,8 +50,7 @@ Proof.
* intros [?] [?]. apply elem_of_list_difference.
Qed.
Instance listset_elems: Elements A (listset A) :=
remove_dups listset_car.
Instance listset_elems: Elements A (listset A) := remove_dups listset_car.
Global Instance: FinCollection A (listset A).
Proof.
......@@ -100,16 +90,11 @@ Hint Extern 1 (Elements _ (listset _)) =>
Hint Extern 1 (Filter _ (listset _)) =>
eapply @listset_filter : typeclass_instances.
Instance listset_ret: MRet listset := λ A x,
{[ x ]}.
Instance listset_ret: MRet listset := λ A x, {[ x ]}.
Instance listset_fmap: FMap listset := λ A B f l,
match l with
| Listset l' => Listset (f <$> l')
end.
match l with Listset l' => Listset (f <$> l') end.
Instance listset_bind: MBind listset := λ A B f l,
match l with
| Listset l' => Listset (mbind (listset_car f) l')
end.
match l with Listset l' => Listset (mbind (listset_car f) l') end.
Instance listset_join: MJoin listset := λ A, mbind id.
Instance: CollectionMonad listset.
......@@ -119,7 +104,6 @@ Proof.
* intros ??? [?] ?. apply elem_of_list_bind.
* intros. apply elem_of_list_ret.
* intros ??? [?]. apply elem_of_list_fmap.
* intros ? [?] ?.
unfold mjoin, listset_join, elem_of, listset_elem_of.
* intros ? [?] ?. unfold mjoin, listset_join, elem_of, listset_elem_of.
simpl. by rewrite elem_of_list_bind.
Qed.
......@@ -19,10 +19,8 @@ Context {A : Type} `{∀ x y : A, Decision (x = y)}.
Notation C := (listset_nodup A).
Notation LS := ListsetNoDup.
Instance listset_nodup_elem_of: ElemOf A C := λ x l,
x listset_nodup_car l.
Instance listset_nodup_empty: Empty C :=
LS [] (@NoDup_nil_2 _).
Instance listset_nodup_elem_of: ElemOf A C := λ x l, x listset_nodup_car l.
Instance listset_nodup_empty: Empty C := LS [] (@NoDup_nil_2 _).
Instance listset_nodup_singleton: Singleton A C := λ x,
LS [x] (NoDup_singleton x).
Instance listset_nodup_difference: Difference C := λ l k,
......@@ -85,8 +83,7 @@ Proof.
* apply _.
* intros. unfold intersection_with, listset_nodup_intersection_with,
elem_of, listset_nodup_elem_of. simpl.
rewrite elem_of_remove_dups.
by apply elem_of_list_intersection_with.
rewrite elem_of_remove_dups. by apply elem_of_list_intersection_with.
* intros. apply elem_of_list_filter.
Qed.
End list_collection.
......
......@@ -3,12 +3,9 @@
(** This files gives an implementation of finite sets using finite maps with
elements of the unit type. Since maps enjoy extensional equality, the
constructed finite sets do so as well. *)
Require Export fin_map_dom.
Record mapset (M : Type Type) := Mapset {
mapset_car: M unit
}.
Record mapset (M : Type Type) := Mapset { mapset_car: M unit }.
Arguments Mapset {_} _.
Arguments mapset_car {_} _.
......@@ -17,46 +14,33 @@ Context `{FinMap K M}.
Instance mapset_elem_of: ElemOf K (mapset M) := λ x X,
mapset_car X !! x = Some ().
Instance mapset_empty: Empty (mapset M) :=
Mapset .
Instance mapset_singleton: Singleton K (mapset M) := λ x,
Mapset {[ (x,()) ]}.
Instance mapset_empty: Empty (mapset M) := Mapset .
Instance mapset_singleton: Singleton K (mapset M) := λ x, Mapset {[ (x,()) ]}.
Instance mapset_union: Union (mapset M) := λ X1 X2,
match X1, X2 with
| Mapset m1, Mapset m2 => Mapset (m1 m2)
end.
match X1, X2 with Mapset m1, Mapset m2 => Mapset (m1 m2) end.
Instance mapset_intersection: Intersection (mapset M) := λ X1 X2,
match X1, X2 with
| Mapset m1, Mapset m2 => Mapset (m1 m2)
end.
match X1, X2 with Mapset m1, Mapset m2 => Mapset (m1 m2) end.
Instance mapset_difference: Difference (mapset M) := λ X1 X2,
match X1, X2 with
| Mapset m1, Mapset m2 => Mapset (m1 m2)
end.
match X1, X2 with Mapset m1, Mapset m2 => Mapset (m1 m2) end.
Instance mapset_elems: Elements K (mapset M) := λ X,
match X with
| Mapset m => fst <$> map_to_list m
end.
match X with Mapset m => fst <$> map_to_list m end.
Lemma mapset_eq (X1 X2 : mapset M) : X1 = X2 x, x X1 x X2.
Proof.
split.
* intros. by subst.
* destruct X1 as [m1], X2 as [m2]. simpl. intros E.
f_equal. apply map_eq. intros i.
apply option_eq. intros []. by apply E.
f_equal. apply map_eq. intros i. apply option_eq. intros []. by apply E.
Qed.
Global Instance mapset_eq_dec `{ m1 m2 : M unit, Decision (m1 = m2)}
(X1 X2 : mapset M) : Decision (X1 = X2) | 1.
Proof.
refine
match X1, X2 with
| Mapset m1, Mapset m2 => cast_if (decide (m1 = m2))
end; abstract congruence.
match X1, X2 with Mapset m1, Mapset m2 => cast_if (decide (m1 = m2)) end;
abstract congruence.
Defined.
Global Instance mapset_elem_of_dec x (X : mapset M) :
Decision (x X) | 1.
Global Instance mapset_elem_of_dec x (X : mapset M) : Decision (x X) | 1.
Proof. solve_decision. Defined.
Instance: Collection K (mapset M).
......@@ -78,11 +62,8 @@ Proof.
destruct (m2 !! x) as [[]|]; intuition congruence.
Qed.
Global Instance: PartialOrder (mapset M).
Proof.