gset.v 8.24 KB
Newer Older
1
From iris.algebra Require Export cmra.
2
From iris.algebra Require Import updates local_updates.
Ralf Jung's avatar
Ralf Jung committed
3
From stdpp Require Export collections gmap mapset.
4
Set Default Proof Using "Type".
Robbert Krebbers's avatar
Robbert Krebbers committed
5

6 7 8 9 10
(* The union CMRA *)
Section gset.
  Context `{Countable K}.
  Implicit Types X Y : gset K.

11
  Canonical Structure gsetC := discreteC (gset K).
12 13 14

  Instance gset_valid : Valid (gset K) := λ _, True.
  Instance gset_op : Op (gset K) := union.
Amin Timany's avatar
Amin Timany committed
15
  Instance gset_pcore : PCore (gset K) := λ X, Some X.
16 17 18

  Lemma gset_op_union X Y : X  Y = X  Y.
  Proof. done. Qed.
Amin Timany's avatar
Amin Timany committed
19
  Lemma gset_core_self X : core X = X.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  Proof. done. Qed.
  Lemma gset_included X Y : X  Y  X  Y.
  Proof.
    split.
    - intros [Z ->]. rewrite gset_op_union. set_solver.
    - intros (Z&->&?)%subseteq_disjoint_union_L. by exists Z.
  Qed.

  Lemma gset_ra_mixin : RAMixin (gset K).
  Proof.
    apply ra_total_mixin; eauto.
    - solve_proper.
    - solve_proper.
    - solve_proper.
    - intros X1 X2 X3. by rewrite !gset_op_union assoc_L.
    - intros X1 X2. by rewrite !gset_op_union comm_L.
36
    - intros X. by rewrite gset_core_self idemp_L.
37 38 39 40 41 42 43 44 45 46 47 48 49 50
  Qed.
  Canonical Structure gsetR := discreteR (gset K) gset_ra_mixin.

  Lemma gset_ucmra_mixin : UCMRAMixin (gset K).
  Proof. split. done. intros X. by rewrite gset_op_union left_id_L. done. Qed.
  Canonical Structure gsetUR :=
    discreteUR (gset K) gset_ra_mixin gset_ucmra_mixin.

  Lemma gset_opM X mY : X ? mY = X  from_option id  mY.
  Proof. destruct mY; by rewrite /= ?right_id_L. Qed.

  Lemma gset_update X Y : X ~~> Y.
  Proof. done. Qed.

51
  Lemma gset_local_update X Y X' : X  X'  (X,Y) ~l~> (X',X').
52 53
  Proof.
    intros (Z&->&?)%subseteq_disjoint_union_L.
54 55
    rewrite local_update_unital_discrete=> Z' _ /leibniz_equiv_iff->.
    split. done. rewrite gset_op_union. set_solver.
56
  Qed.
Amin Timany's avatar
Amin Timany committed
57

58
  Global Instance gset_persistent X : Persistent X.
Amin Timany's avatar
Amin Timany committed
59
  Proof. by apply persistent_total; rewrite gset_core_self. Qed.
60 61
End gset.

62
Arguments gsetC _ {_ _}.
Amin Timany's avatar
Amin Timany committed
63 64 65
Arguments gsetR _ {_ _}.
Arguments gsetUR _ {_ _}.

66
(* The disjoint union CMRA *)
67 68 69 70 71
Inductive gset_disj K `{Countable K} :=
  | GSet : gset K  gset_disj K
  | GSetBot : gset_disj K.
Arguments GSet {_ _ _} _.
Arguments GSetBot {_ _ _}.
Robbert Krebbers's avatar
Robbert Krebbers committed
72

73
Section gset_disj.
74 75
  Context `{Countable K}.
  Arguments op _ _ !_ !_ /.
76 77
  Arguments cmra_op _ !_ !_ /.
  Arguments ucmra_op _ !_ !_ /.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

  Canonical Structure gset_disjC := leibnizC (gset_disj K).

  Instance gset_disj_valid : Valid (gset_disj K) := λ X,
    match X with GSet _ => True | GSetBot => False end.
  Instance gset_disj_empty : Empty (gset_disj K) := GSet .
  Instance gset_disj_op : Op (gset_disj K) := λ X Y,
    match X, Y with
    | GSet X, GSet Y => if decide (X  Y) then GSet (X  Y) else GSetBot
    | _, _ => GSetBot
    end.
  Instance gset_disj_pcore : PCore (gset_disj K) := λ _, Some .

  Ltac gset_disj_solve :=
    repeat (simpl || case_decide);
    first [apply (f_equal GSet)|done|exfalso]; set_solver by eauto.

95
  Lemma gset_disj_included X Y : GSet X  GSet Y  X  Y.
96 97 98 99 100 101
  Proof.
    split.
    - move=> [[Z|]]; simpl; try case_decide; set_solver.
    - intros (Z&->&?)%subseteq_disjoint_union_L.
      exists (GSet Z). gset_disj_solve.
  Qed.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
  Lemma gset_disj_valid_inv_l X Y :  (GSet X  Y)   Y', Y = GSet Y'  X  Y'.
  Proof. destruct Y; repeat (simpl || case_decide); by eauto. Qed.
  Lemma gset_disj_union X Y : X  Y  GSet X  GSet Y = GSet (X  Y).
  Proof. intros. by rewrite /= decide_True. Qed.
  Lemma gset_disj_valid_op X Y :  (GSet X  GSet Y)  X  Y.
  Proof. simpl. case_decide; by split. Qed.

  Lemma gset_disj_ra_mixin : RAMixin (gset_disj K).
  Proof.
    apply ra_total_mixin; eauto.
    - intros [?|]; destruct 1; gset_disj_solve.
    - by constructor.
    - by destruct 1.
    - intros [X1|] [X2|] [X3|]; gset_disj_solve.
    - intros [X1|] [X2|]; gset_disj_solve.
    - intros [X|]; gset_disj_solve.
    - exists (GSet ); gset_disj_solve.
    - intros [X1|] [X2|]; gset_disj_solve.
  Qed.
  Canonical Structure gset_disjR := discreteR (gset_disj K) gset_disj_ra_mixin.

  Lemma gset_disj_ucmra_mixin : UCMRAMixin (gset_disj K).
  Proof. split; try apply _ || done. intros [X|]; gset_disj_solve. Qed.
  Canonical Structure gset_disjUR :=
    discreteUR (gset_disj K) gset_disj_ra_mixin gset_disj_ucmra_mixin.

  Arguments op _ _ _ _ : simpl never.

130
  Lemma gset_disj_alloc_updateP_strong P (Q : gset_disj K  Prop) X :
131 132
    ( Y, X  Y   j, j  Y  P j) 
    ( i, i  X  P i  Q (GSet ({[i]}  X)))  GSet X ~~>: Q.
133
  Proof.
134 135 136
    intros Hfresh HQ.
    apply cmra_discrete_updateP=> ? /gset_disj_valid_inv_l [Y [->?]].
    destruct (Hfresh (X  Y)) as (i&?&?); first set_solver.
137 138 139 140
    exists (GSet ({[ i ]}  X)); split.
    - apply HQ; set_solver by eauto.
    - apply gset_disj_valid_op. set_solver by eauto.
  Qed.
141
  Lemma gset_disj_alloc_updateP_strong' P X :
142 143
    ( Y, X  Y   j, j  Y  P j) 
    GSet X ~~>: λ Y,  i, Y = GSet ({[ i ]}  X)  i  X  P i.
144
  Proof. eauto using gset_disj_alloc_updateP_strong. Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
145

146
  Lemma gset_disj_alloc_empty_updateP_strong P (Q : gset_disj K  Prop) :
147 148
    ( Y : gset K,  j, j  Y  P j) 
    ( i, P i  Q (GSet {[i]}))  GSet  ~~>: Q.
149
  Proof.
150
    intros. apply (gset_disj_alloc_updateP_strong P); eauto.
151
    intros i; rewrite right_id_L; auto.
152
  Qed.
153
  Lemma gset_disj_alloc_empty_updateP_strong' P :
154 155
    ( Y : gset K,  j, j  Y  P j) 
    GSet  ~~>: λ Y,  i, Y = GSet {[ i ]}  P i.
156
  Proof. eauto using gset_disj_alloc_empty_updateP_strong. Qed.
157

158
  Section fresh_updates.
159
    Local Set Default Proof Using "Type*".
160 161
    Context `{Fresh K (gset K), !FreshSpec K (gset K)}.

162
    Lemma gset_disj_alloc_updateP (Q : gset_disj K  Prop) X :
163 164
      ( i, i  X  Q (GSet ({[i]}  X)))  GSet X ~~>: Q.
    Proof.
165
      intro; eapply gset_disj_alloc_updateP_strong with (λ _, True); eauto.
166 167
      intros Y ?; exists (fresh Y); eauto using is_fresh.
    Qed.
168 169 170
    Lemma gset_disj_alloc_updateP' X :
      GSet X ~~>: λ Y,  i, Y = GSet ({[ i ]}  X)  i  X.
    Proof. eauto using gset_disj_alloc_updateP. Qed.
171

172
    Lemma gset_disj_alloc_empty_updateP (Q : gset_disj K  Prop) :
173
      ( i, Q (GSet {[i]}))  GSet  ~~>: Q.
174 175 176 177 178
    Proof.
      intro. apply gset_disj_alloc_updateP. intros i; rewrite right_id_L; auto.
    Qed.
    Lemma gset_disj_alloc_empty_updateP' : GSet  ~~>: λ Y,  i, Y = GSet {[ i ]}.
    Proof. eauto using gset_disj_alloc_empty_updateP. Qed.
179
  End fresh_updates.
Zhen Zhang's avatar
Zhen Zhang committed
180

181 182 183 184 185 186 187 188 189 190 191
  Lemma gset_disj_dealloc_local_update X Y :
    (GSet X, GSet Y) ~l~> (GSet (X  Y), ).
  Proof.
    apply local_update_total_valid=> _ _ /gset_disj_included HYX.
    rewrite local_update_unital_discrete=> -[Xf|] _ /leibniz_equiv_iff //=.
    rewrite {1}/op /=. destruct (decide _) as [HXf|]; [intros[= ->]|done].
    by rewrite difference_union_distr_l_L
      difference_diag_L !left_id_L difference_disjoint_L.
  Qed.
  Lemma gset_disj_dealloc_empty_local_update X Z :
    (GSet Z  GSet X, GSet Z) ~l~> (GSet X,).
192
  Proof.
193 194 195
    apply local_update_total_valid=> /gset_disj_valid_op HZX _ _.
    assert (X = (Z  X)  Z) as HX by set_solver.
    rewrite gset_disj_union // {2}HX. apply gset_disj_dealloc_local_update.
196
  Qed.
197 198
  Lemma gset_disj_dealloc_op_local_update X Y Z :
    (GSet Z  GSet X, GSet Z  GSet Y) ~l~> (GSet X,GSet Y).
199
  Proof.
200 201
    rewrite -{2}(left_id  _ (GSet Y)).
    apply op_local_update_frame, gset_disj_dealloc_empty_local_update.
202 203
  Qed.

204 205 206 207 208 209 210
  Lemma gset_disj_alloc_op_local_update X Y Z :
    Z  X  (GSet X,GSet Y) ~l~> (GSet Z  GSet X, GSet Z  GSet Y).
  Proof.
    intros. apply op_local_update_discrete. by rewrite gset_disj_valid_op.
  Qed.
  Lemma gset_disj_alloc_local_update X Y Z :
    Z  X  (GSet X,GSet Y) ~l~> (GSet (Z  X), GSet (Z  Y)).
Robbert Krebbers's avatar
Robbert Krebbers committed
211
  Proof.
212 213 214
    intros. apply local_update_total_valid=> _ _ /gset_disj_included ?.
    rewrite -!gset_disj_union //; last set_solver.
    auto using gset_disj_alloc_op_local_update.
Robbert Krebbers's avatar
Robbert Krebbers committed
215
  Qed.
216 217
  Lemma gset_disj_alloc_empty_local_update X Z :
    Z  X  (GSet X, GSet ) ~l~> (GSet (Z  X), GSet Z).
218
  Proof.
219
    intros. rewrite -{2}(right_id_L _ union Z).
220
    apply gset_disj_alloc_local_update; set_solver.
221
  Qed.
222
End gset_disj.
223

224
Arguments gset_disjC _ {_ _}.
225 226
Arguments gset_disjR _ {_ _}.
Arguments gset_disjUR _ {_ _}.