mapset.v 5.17 KB
Newer Older
Robbert Krebbers's avatar
Robbert Krebbers committed
1
(* Copyright (c) 2012-2015, Robbert Krebbers. *)
2
3
4
5
(* This file is distributed under the terms of the BSD license. *)
(** 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. *)
6
From stdpp Require Export fin_map_dom.
7

Robbert Krebbers's avatar
Robbert Krebbers committed
8
9
Record mapset (M : Type  Type) : Type :=
  Mapset { mapset_car: M (unit : Type) }.
10
11
12
13
14
15
Arguments Mapset {_} _.
Arguments mapset_car {_} _.

Section mapset.
Context `{FinMap K M}.

Robbert Krebbers's avatar
Robbert Krebbers committed
16
Instance mapset_elem_of: ElemOf K (mapset M) := λ x X,
17
  mapset_car X !! x = Some ().
Robbert Krebbers's avatar
Robbert Krebbers committed
18
19
Instance mapset_empty: Empty (mapset M) := Mapset .
Instance mapset_singleton: Singleton K (mapset M) := λ x,
20
  Mapset {[ x := () ]}.
Robbert Krebbers's avatar
Robbert Krebbers committed
21
Instance mapset_union: Union (mapset M) := λ X1 X2,
22
  let (m1) := X1 in let (m2) := X2 in Mapset (m1  m2).
Robbert Krebbers's avatar
Robbert Krebbers committed
23
Instance mapset_intersection: Intersection (mapset M) := λ X1 X2,
24
  let (m1) := X1 in let (m2) := X2 in Mapset (m1  m2).
Robbert Krebbers's avatar
Robbert Krebbers committed
25
Instance mapset_difference: Difference (mapset M) := λ X1 X2,
26
  let (m1) := X1 in let (m2) := X2 in Mapset (m1  m2).
Robbert Krebbers's avatar
Robbert Krebbers committed
27
Instance mapset_elems: Elements K (mapset M) := λ X,
28
  let (m) := X in (map_to_list m).*1.
29

Robbert Krebbers's avatar
Robbert Krebbers committed
30
Lemma mapset_eq (X1 X2 : mapset M) : X1 = X2   x, x  X1  x  X2.
31
Proof.
32
  split; [by intros ->|].
33
34
  destruct X1 as [m1], X2 as [m2]. simpl. intros E.
  f_equal. apply map_eq. intros i. apply option_eq. intros []. by apply E.
35
36
Qed.

37
Global Instance mapset_eq_dec `{ m1 m2 : M unit, Decision (m1 = m2)}
Robbert Krebbers's avatar
Robbert Krebbers committed
38
  (X1 X2 : mapset M) : Decision (X1 = X2) | 1.
39
40
Proof.
 refine
41
42
  match X1, X2 with Mapset m1, Mapset m2 => cast_if (decide (m1 = m2)) end;
  abstract congruence.
43
Defined.
Robbert Krebbers's avatar
Robbert Krebbers committed
44
Global Instance mapset_elem_of_dec x (X : mapset M) : Decision (x  X) | 1.
45
46
Proof. solve_decision. Defined.

Robbert Krebbers's avatar
Robbert Krebbers committed
47
Instance: Collection K (mapset M).
48
49
Proof.
  split; [split | | ].
50
  - unfold empty, elem_of, mapset_empty, mapset_elem_of.
51
    simpl. intros. by simpl_map.
52
  - unfold singleton, elem_of, mapset_singleton, mapset_elem_of.
53
    simpl. by split; intros; simplify_map_eq.
54
  - unfold union, elem_of, mapset_union, mapset_elem_of.
55
56
    intros [m1] [m2] ?. simpl. rewrite lookup_union_Some_raw.
    destruct (m1 !! x) as [[]|]; tauto.
57
  - unfold intersection, elem_of, mapset_intersection, mapset_elem_of.
58
    intros [m1] [m2] ?. simpl. rewrite lookup_intersection_Some.
59
60
61
    assert (is_Some (m2 !! x)  m2 !! x = Some ()).
    { split; eauto. by intros [[] ?]. }
    naive_solver.
62
  - unfold difference, elem_of, mapset_difference, mapset_elem_of.
63
64
65
    intros [m1] [m2] ?. simpl. rewrite lookup_difference_Some.
    destruct (m2 !! x) as [[]|]; intuition congruence.
Qed.
66
67
Global Instance: LeibnizEquiv (mapset M).
Proof. intros ??. apply mapset_eq. Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
68
Global Instance: FinCollection K (mapset M).
69
70
Proof.
  split.
71
72
  - apply _.
  - unfold elements, elem_of at 2, mapset_elems, mapset_elem_of.
73
74
    intros [m] x. simpl. rewrite elem_of_list_fmap. split.
    + intros ([y []] &?& Hy). subst. by rewrite <-elem_of_map_to_list.
75
    + intros. exists (x, ()). by rewrite elem_of_map_to_list.
76
  - unfold elements, mapset_elems. intros [m]. simpl.
77
    apply NoDup_fst_map_to_list.
78
79
Qed.

80
Definition mapset_map_with {A B} (f : bool  A  option B)
Robbert Krebbers's avatar
Robbert Krebbers committed
81
    (X : mapset M) : M A  M B :=
82
  let (mX) := X in merge (λ x y,
83
    match x, y with
84
85
    | Some _, Some a => f true a | None, Some a => f false a | _, None => None
    end) mX.
Robbert Krebbers's avatar
Robbert Krebbers committed
86
Definition mapset_dom_with {A} (f : A  bool) (m : M A) : mapset M :=
87
88
  Mapset $ merge (λ x _,
    match x with
89
    | Some a => if f a then Some () else None | None => None
90
91
    end) m (@empty (M A) _).

92
93
Lemma lookup_mapset_map_with {A B} (f : bool  A  option B) X m i :
  mapset_map_with f X m !! i = m !! i = f (bool_decide (i  X)).
94
95
96
97
98
Proof.
  destruct X as [mX]. unfold mapset_map_with, elem_of, mapset_elem_of.
  rewrite lookup_merge by done. simpl.
  by case_bool_decide; destruct (mX !! i) as [[]|], (m !! i).
Qed.
99
Lemma elem_of_mapset_dom_with {A} (f : A  bool) m i :
100
101
102
  i  mapset_dom_with f m   x, m !! i = Some x  f x.
Proof.
  unfold mapset_dom_with, elem_of, mapset_elem_of.
103
  simpl. rewrite lookup_merge by done. destruct (m !! i) as [a|].
104
105
  - destruct (Is_true_reflect (f a)); naive_solver.
  - naive_solver.
106
Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
107
108
Instance mapset_dom {A} : Dom (M A) (mapset M) := mapset_dom_with (λ _, true).
Instance mapset_dom_spec: FinMapDom K M (mapset M).
109
Proof.
110
111
  split; try apply _. intros. unfold dom, mapset_dom, is_Some.
  rewrite elem_of_mapset_dom_with; naive_solver.
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Qed.
End mapset.

(** These instances are declared using [Hint Extern] to avoid too
eager type class search. *)
Hint Extern 1 (ElemOf _ (mapset _)) =>
  eapply @mapset_elem_of : typeclass_instances.
Hint Extern 1 (Empty (mapset _)) =>
  eapply @mapset_empty : typeclass_instances.
Hint Extern 1 (Singleton _ (mapset _)) =>
  eapply @mapset_singleton : typeclass_instances.
Hint Extern 1 (Union (mapset _)) =>
  eapply @mapset_union : typeclass_instances.
Hint Extern 1 (Intersection (mapset _)) =>
  eapply @mapset_intersection : typeclass_instances.
Hint Extern 1 (Difference (mapset _)) =>
  eapply @mapset_difference : typeclass_instances.
Hint Extern 1 (Elements _ (mapset _)) =>
  eapply @mapset_elems : typeclass_instances.
131
Arguments mapset_eq_dec _ _ _ _ : simpl never.