upred_big_op.v 16.5 KB
Newer Older
1
From iris.algebra Require Export upred list.
2
From iris.prelude Require Import gmap fin_collections functions.
3
Import uPred.
4

5
6
7
8
9
10
11
12
13
14
15
(** We define the following big operators:

- The operators [ [★] Ps ] and [ [∧] Ps ] fold [★] and [∧] over the list [Ps].
  This operator is not a quantifier, so it binds strongly.
- The operator [ [★ map] k ↦ x ∈ m, P ] asserts that [P] holds separately for
  each [k ↦ x] in the map [m]. This operator is a quantifier, and thus has the
  same precedence as [∀] and [∃].
- The operator [ [★ set] x ∈ X, P ] asserts that [P] holds separately for each
  [x] in the set [X]. This operator is a quantifier, and thus has the same
  precedence as [∀] and [∃]. *)

16
17
(** * Big ops over lists *)
(* These are the basic building blocks for other big ops *)
18
Fixpoint uPred_big_and {M} (Ps : list (uPred M)) : uPred M :=
19
20
  match Ps with [] => True | P :: Ps => P  uPred_big_and Ps end%I.
Instance: Params (@uPred_big_and) 1.
21
Notation "'[∧]' Ps" := (uPred_big_and Ps) (at level 20) : uPred_scope.
22
23
24
Fixpoint uPred_big_sep {M} (Ps : list (uPred M)) : uPred M :=
  match Ps with [] => True | P :: Ps => P  uPred_big_sep Ps end%I.
Instance: Params (@uPred_big_sep) 1.
25
Notation "'[★]' Ps" := (uPred_big_sep Ps) (at level 20) : uPred_scope.
26

27
(** * Other big ops *)
28
Definition uPred_big_sepM {M} `{Countable K} {A}
29
    (m : gmap K A) (Φ : K  A  uPred M) : uPred M :=
30
  [] (curry Φ <$> map_to_list m).
31
Instance: Params (@uPred_big_sepM) 6.
32
33
34
Notation "'[★' 'map' ] k ↦ x ∈ m , P" := (uPred_big_sepM m (λ k x, P))
  (at level 200, m at level 10, k, x at level 1, right associativity,
   format "[★  map ]  k ↦ x  ∈  m ,  P") : uPred_scope.
35

36
Definition uPred_big_sepS {M} `{Countable A}
37
  (X : gset A) (Φ : A  uPred M) : uPred M := [] (Φ <$> elements X).
38
Instance: Params (@uPred_big_sepS) 5.
39
40
41
Notation "'[★' 'set' ] x ∈ X , P" := (uPred_big_sepS X (λ x, P))
  (at level 200, X at level 10, x at level 1, right associativity,
   format "[★  set ]  x  ∈  X ,  P") : uPred_scope.
42

43
(** * Persistence of lists of uPreds *)
44
Class PersistentL {M} (Ps : list (uPred M)) :=
45
  persistentL : Forall PersistentP Ps.
46
Arguments persistentL {_} _ {_}.
47

48
(** * Properties *)
49
Section big_op.
50
Context {M : ucmraT}.
51
52
53
Implicit Types Ps Qs : list (uPred M).
Implicit Types A : Type.

54
(** ** Big ops over lists *)
55
Global Instance big_and_proper : Proper (() ==> ()) (@uPred_big_and M).
56
Proof. by induction 1 as [|P Q Ps Qs HPQ ? IH]; rewrite /= ?HPQ ?IH. Qed.
57
Global Instance big_sep_proper : Proper (() ==> ()) (@uPred_big_sep M).
58
Proof. by induction 1 as [|P Q Ps Qs HPQ ? IH]; rewrite /= ?HPQ ?IH. Qed.
59

60
Global Instance big_and_ne n : Proper (dist n ==> dist n) (@uPred_big_and M).
61
Proof. by induction 1 as [|P Q Ps Qs HPQ ? IH]; rewrite /= ?HPQ ?IH. Qed.
62
Global Instance big_sep_ne n : Proper (dist n ==> dist n) (@uPred_big_sep M).
63
64
Proof. by induction 1 as [|P Q Ps Qs HPQ ? IH]; rewrite /= ?HPQ ?IH. Qed.

65
Global Instance big_and_mono' : Proper (Forall2 () ==> ()) (@uPred_big_and M).
66
Proof. by induction 1 as [|P Q Ps Qs HPQ ? IH]; rewrite /= ?HPQ ?IH. Qed.
67
Global Instance big_sep_mono' : Proper (Forall2 () ==> ()) (@uPred_big_sep M).
68
69
Proof. by induction 1 as [|P Q Ps Qs HPQ ? IH]; rewrite /= ?HPQ ?IH. Qed.

70
Global Instance big_and_perm : Proper (() ==> ()) (@uPred_big_and M).
71
72
Proof.
  induction 1 as [|P Ps Qs ? IH|P Q Ps|]; simpl; auto.
73
74
  - by rewrite IH.
  - by rewrite !assoc (comm _ P).
75
  - etrans; eauto.
76
Qed.
77
Global Instance big_sep_perm : Proper (() ==> ()) (@uPred_big_sep M).
78
79
Proof.
  induction 1 as [|P Ps Qs ? IH|P Q Ps|]; simpl; auto.
80
81
  - by rewrite IH.
  - by rewrite !assoc (comm _ P).
82
  - etrans; eauto.
83
Qed.
84

85
Lemma big_and_app Ps Qs : [] (Ps ++ Qs)  [] Ps  [] Qs.
86
Proof. induction Ps as [|?? IH]; by rewrite /= ?left_id -?assoc ?IH. Qed.
87
Lemma big_sep_app Ps Qs : [] (Ps ++ Qs)  [] Ps  [] Qs.
88
Proof. by induction Ps as [|?? IH]; rewrite /= ?left_id -?assoc ?IH. Qed.
89

90
Lemma big_and_contains Ps Qs : Qs `contains` Ps  [] Ps  [] Qs.
91
Proof.
92
  intros [Ps' ->]%contains_Permutation. by rewrite big_and_app and_elim_l.
93
Qed.
94
Lemma big_sep_contains Ps Qs : Qs `contains` Ps  [] Ps  [] Qs.
95
Proof.
96
  intros [Ps' ->]%contains_Permutation. by rewrite big_sep_app sep_elim_l.
97
98
Qed.

99
Lemma big_sep_and Ps : [] Ps  [] Ps.
100
Proof. by induction Ps as [|P Ps IH]; simpl; auto with I. Qed.
101

102
Lemma big_and_elem_of Ps P : P  Ps  [] Ps  P.
103
Proof. induction 1; simpl; auto with I. Qed.
104
Lemma big_sep_elem_of Ps P : P  Ps  [] Ps  P.
105
106
Proof. induction 1; simpl; auto with I. Qed.

107
(** ** Big ops over finite maps *)
108
109
110
Section gmap.
  Context `{Countable K} {A : Type}.
  Implicit Types m : gmap K A.
111
  Implicit Types Φ Ψ : K  A  uPred M.
112

113
  Lemma big_sepM_mono Φ Ψ m1 m2 :
114
    m2  m1  ( k x, m2 !! k = Some x  Φ k x  Ψ k x) 
115
    ([ map] k  x  m1, Φ k x)  [ map] k  x  m2, Ψ k x.
116
  Proof.
117
    intros HX HΦ. trans ([ map] kx  m2, Φ k x)%I.
118
    - by apply big_sep_contains, fmap_contains, map_to_list_contains.
119
    - apply big_sep_mono', Forall2_fmap, Forall_Forall2.
120
      apply Forall_forall=> -[i x] ? /=. by apply HΦ, elem_of_map_to_list.
121
  Qed.
122
123
124
  Lemma big_sepM_proper Φ Ψ m :
    ( k x, m !! k = Some x  Φ k x  Ψ k x) 
    ([ map] k  x  m, Φ k x)  ([ map] k  x  m, Ψ k x).
125
126
127
128
  Proof.
    intros ?; apply (anti_symm ()); apply big_sepM_mono;
      eauto using equiv_entails, equiv_entails_sym, lookup_weaken.
  Qed.
129
130
131
132
133

  Global Instance big_sepM_ne m n :
    Proper (pointwise_relation _ (pointwise_relation _ (dist n)) ==> (dist n))
           (uPred_big_sepM (M:=M) m).
  Proof.
134
    intros Φ1 Φ2 HΦ. apply big_sep_ne, Forall2_fmap.
135
    apply Forall_Forall2, Forall_true=> -[i x]; apply HΦ.
136
  Qed.
137
  Global Instance big_sepM_proper' m :
138
    Proper (pointwise_relation _ (pointwise_relation _ ()) ==> ())
139
           (uPred_big_sepM (M:=M) m).
140
  Proof. intros Φ1 Φ2 HΦ. by apply big_sepM_proper; intros; last apply HΦ. Qed.
141
  Global Instance big_sepM_mono' m :
142
    Proper (pointwise_relation _ (pointwise_relation _ ()) ==> ())
143
           (uPred_big_sepM (M:=M) m).
144
  Proof. intros Φ1 Φ2 HΦ. by apply big_sepM_mono; intros; last apply HΦ. Qed.
145

146
  Lemma big_sepM_empty Φ : ([ map] kx  , Φ k x)  True.
147
  Proof. by rewrite /uPred_big_sepM map_to_list_empty. Qed.
148

149
  Lemma big_sepM_insert Φ m i x :
150
    m !! i = None 
151
    ([ map] ky  <[i:=x]> m, Φ k y)  Φ i x  [ map] ky  m, Φ k y.
152
  Proof. intros ?; by rewrite /uPred_big_sepM map_to_list_insert. Qed.
153

154
  Lemma big_sepM_delete Φ m i x :
155
    m !! i = Some x 
156
    ([ map] ky  m, Φ k y)  Φ i x  [ map] ky  delete i m, Φ k y.
157
158
159
160
  Proof.
    intros. rewrite -big_sepM_insert ?lookup_delete //.
    by rewrite insert_delete insert_id.
  Qed.
161

162
163
164
165
  Lemma big_sepM_lookup Φ m i x :
    m !! i = Some x  ([ map] ky  m, Φ k y)  Φ i x.
  Proof. intros. by rewrite big_sepM_delete // sep_elim_l. Qed.

166
  Lemma big_sepM_singleton Φ i x : ([ map] ky  {[i:=x]}, Φ k y)  Φ i x.
167
168
169
170
  Proof.
    rewrite -insert_empty big_sepM_insert/=; last auto using lookup_empty.
    by rewrite big_sepM_empty right_id.
  Qed.
171

172
173
174
175
176
177
178
  Lemma big_sepM_fmap {B} (f : A  B) (Φ : K  B  uPred M) m :
    ([ map] ky  f <$> m, Φ k y)  ([ map] ky  m, Φ k (f y)).
  Proof.
    rewrite /uPred_big_sepM map_to_list_fmap -list_fmap_compose.
    f_equiv; apply reflexive_eq, list_fmap_ext. by intros []. done.
  Qed.

179
  Lemma big_sepM_insert_override (Φ : K  uPred M) m i x y :
180
    m !! i = Some x 
181
    ([ map] k_  <[i:=y]> m, Φ k)  ([ map] k_  m, Φ k).
182
183
184
185
186
  Proof.
    intros. rewrite -insert_delete big_sepM_insert ?lookup_delete //.
    by rewrite -big_sepM_delete.
  Qed.

187
  Lemma big_sepM_fn_insert {B} (Ψ : K  A  B  uPred M) (f : K  B) m i x b :
188
    m !! i = None 
189
190
       ([ map] ky  <[i:=x]> m, Ψ k y (<[i:=b]> f k))
     (Ψ i x b  [ map] ky  m, Ψ k y (f k)).
191
192
  Proof.
    intros. rewrite big_sepM_insert // fn_lookup_insert.
193
    apply sep_proper, big_sepM_proper; auto=> k y ?.
194
195
196
197
198
199
200
    by rewrite fn_lookup_insert_ne; last set_solver.
  Qed.
  Lemma big_sepM_fn_insert' (Φ : K  uPred M) m i x P :
    m !! i = None 
    ([ map] ky  <[i:=x]> m, <[i:=P]> Φ k)  (P  [ map] ky  m, Φ k).
  Proof. apply (big_sepM_fn_insert (λ _ _, id)). Qed.

201
  Lemma big_sepM_sepM Φ Ψ m :
202
       ([ map] kx  m, Φ k x  Ψ k x)
203
     ([ map] kx  m, Φ k x)  ([ map] kx  m, Ψ k x).
204
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
205
206
    rewrite /uPred_big_sepM.
    induction (map_to_list m) as [|[i x] l IH]; csimpl; rewrite ?right_id //.
207
    by rewrite IH -!assoc (assoc _ (Ψ _ _)) [(Ψ _ _  _)%I]comm -!assoc.
208
  Qed.
209

210
  Lemma big_sepM_later Φ m :
211
     ([ map] kx  m, Φ k x)  ([ map] kx  m,  Φ k x).
212
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
213
214
215
    rewrite /uPred_big_sepM.
    induction (map_to_list m) as [|[i x] l IH]; csimpl; rewrite ?later_True //.
    by rewrite later_sep IH.
216
  Qed.
217
218
219
220
221

  Lemma big_sepM_always Φ m :
    ( [ map] kx  m, Φ k x)  ([ map] kx  m,  Φ k x).
  Proof.
    rewrite /uPred_big_sepM.
222
    induction (map_to_list m) as [|[i x] l IH]; csimpl; rewrite ?always_pure //.
223
224
225
226
    by rewrite always_sep IH.
  Qed.

  Lemma big_sepM_always_if p Φ m :
227
    ?p ([ map] kx  m, Φ k x)  ([ map] kx  m, ?p Φ k x).
228
  Proof. destruct p; simpl; auto using big_sepM_always. Qed.
229
230
231
232
233
234
235

  Lemma big_sepM_forall Φ m :
    ( k x, PersistentP (Φ k x)) 
    ([ map] kx  m, Φ k x)  ( k x, m !! k = Some x  Φ k x).
  Proof.
    intros. apply (anti_symm _).
    { apply forall_intro=> k; apply forall_intro=> x.
236
      apply impl_intro_l, pure_elim_l=> ?; by apply big_sepM_lookup. }
237
238
239
    rewrite /uPred_big_sepM. setoid_rewrite <-elem_of_map_to_list.
    induction (map_to_list m) as [|[i x] l IH]; csimpl; auto.
    rewrite -always_and_sep_l; apply and_intro.
240
    - rewrite (forall_elim i) (forall_elim x) pure_equiv; last by left.
241
242
      by rewrite True_impl.
    - rewrite -IH. apply forall_mono=> k; apply forall_mono=> y.
243
      apply impl_intro_l, pure_elim_l=> ?. rewrite pure_equiv; last by right.
244
245
246
247
      by rewrite True_impl.
  Qed.

  Lemma big_sepM_impl Φ Ψ m :
248
     ( k x, m !! k = Some x  Φ k x  Ψ k x)  ([ map] kx  m, Φ k x)
249
250
251
     [ map] kx  m, Ψ k x.
  Proof.
    rewrite always_and_sep_l. do 2 setoid_rewrite always_forall.
252
    setoid_rewrite always_impl; setoid_rewrite always_pure.
253
254
255
    rewrite -big_sepM_forall -big_sepM_sepM. apply big_sepM_mono; auto=> k x ?.
    by rewrite -always_wand_impl always_elim wand_elim_l.
  Qed.
256
257
End gmap.

258
(** ** Big ops over finite sets *)
259
260
261
Section gset.
  Context `{Countable A}.
  Implicit Types X : gset A.
262
  Implicit Types Φ : A  uPred M.
263

264
  Lemma big_sepS_mono Φ Ψ X Y :
265
    Y  X  ( x, x  Y  Φ x  Ψ x) 
266
    ([ set] x  X, Φ x)  [ set] x  Y, Ψ x.
267
  Proof.
268
    intros HX HΦ. trans ([ set] x  Y, Φ x)%I.
269
    - by apply big_sep_contains, fmap_contains, elements_contains.
270
    - apply big_sep_mono', Forall2_fmap, Forall_Forall2.
271
      apply Forall_forall=> x ? /=. by apply HΦ, elem_of_elements.
272
  Qed.
273
  Lemma big_sepS_proper Φ Ψ X Y :
274
275
    X  Y  ( x, x  X  x  Y  Φ x  Ψ x) 
    ([ set] x  X, Φ x)  ([ set] x  Y, Ψ x).
276
  Proof.
277
278
    move=> /collection_equiv_spec [??] ?; apply (anti_symm ());
      apply big_sepS_mono; eauto using equiv_entails, equiv_entails_sym.
279
  Qed.
280
281
282
283

  Lemma big_sepS_ne X n :
    Proper (pointwise_relation _ (dist n) ==> dist n) (uPred_big_sepS (M:=M) X).
  Proof.
284
    intros Φ1 Φ2 HΦ. apply big_sep_ne, Forall2_fmap.
285
    apply Forall_Forall2, Forall_true=> x; apply HΦ.
286
  Qed.
287
  Lemma big_sepS_proper' X :
288
    Proper (pointwise_relation _ () ==> ()) (uPred_big_sepS (M:=M) X).
289
  Proof. intros Φ1 Φ2 HΦ. apply big_sepS_proper; naive_solver. Qed.
290
  Lemma big_sepS_mono' X :
291
    Proper (pointwise_relation _ () ==> ()) (uPred_big_sepS (M:=M) X).
292
  Proof. intros Φ1 Φ2 HΦ. apply big_sepS_mono; naive_solver. Qed.
293

294
  Lemma big_sepS_empty Φ : ([ set] x  , Φ x)  True.
295
  Proof. by rewrite /uPred_big_sepS elements_empty. Qed.
296

297
  Lemma big_sepS_insert Φ X x :
298
    x  X  ([ set] y  {[ x ]}  X, Φ y)  (Φ x  [ set] y  X, Φ y).
299
  Proof. intros. by rewrite /uPred_big_sepS elements_union_singleton. Qed.
300
  Lemma big_sepS_fn_insert {B} (Ψ : A  B  uPred M) f X x b :
301
    x  X 
302
303
       ([ set] y  {[ x ]}  X, Ψ y (<[x:=b]> f y))
     (Ψ x b  [ set] y  X, Ψ y (f y)).
304
305
306
307
308
  Proof.
    intros. rewrite big_sepS_insert // fn_lookup_insert.
    apply sep_proper, big_sepS_proper; auto=> y ??.
    by rewrite fn_lookup_insert_ne; last set_solver.
  Qed.
309
  Lemma big_sepS_fn_insert' Φ X x P :
310
    x  X  ([ set] y  {[ x ]}  X, <[x:=P]> Φ y)  (P  [ set] y  X, Φ y).
311
  Proof. apply (big_sepS_fn_insert (λ y, id)). Qed.
312

313
  Lemma big_sepS_delete Φ X x :
314
    x  X  ([ set] y  X, Φ y)  Φ x  [ set] y  X  {[ x ]}, Φ y.
315
  Proof.
316
317
    intros. rewrite -big_sepS_insert; last set_solver.
    by rewrite -union_difference_L; last set_solver.
318
  Qed.
319

320
321
322
  Lemma big_sepS_elem_of Φ X x : x  X  ([ set] y  X, Φ y)  Φ x.
  Proof. intros. by rewrite big_sepS_delete // sep_elim_l. Qed.

323
  Lemma big_sepS_singleton Φ x : ([ set] y  {[ x ]}, Φ y)  Φ x.
324
  Proof. intros. by rewrite /uPred_big_sepS elements_singleton /= right_id. Qed.
325

326
  Lemma big_sepS_sepS Φ Ψ X :
327
    ([ set] y  X, Φ y  Ψ y)  ([ set] y  X, Φ y)  ([ set] y  X, Ψ y).
328
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
329
330
    rewrite /uPred_big_sepS.
    induction (elements X) as [|x l IH]; csimpl; first by rewrite ?right_id.
331
    by rewrite IH -!assoc (assoc _ (Ψ _)) [(Ψ _  _)%I]comm -!assoc.
332
333
  Qed.

334
  Lemma big_sepS_later Φ X :  ([ set] y  X, Φ y)  ([ set] y  X,  Φ y).
335
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
336
337
338
    rewrite /uPred_big_sepS.
    induction (elements X) as [|x l IH]; csimpl; first by rewrite ?later_True.
    by rewrite later_sep IH.
339
  Qed.
340

341
  Lemma big_sepS_always Φ X :  ([ set] y  X, Φ y)  ([ set] y  X,  Φ y).
342
343
  Proof.
    rewrite /uPred_big_sepS.
344
    induction (elements X) as [|x l IH]; csimpl; first by rewrite ?always_pure.
345
346
347
348
    by rewrite always_sep IH.
  Qed.

  Lemma big_sepS_always_if q Φ X :
349
    ?q ([ set] y  X, Φ y)  ([ set] y  X, ?q Φ y).
350
  Proof. destruct q; simpl; auto using big_sepS_always. Qed.
351
352
353
354
355
356

  Lemma big_sepS_forall Φ X :
    ( x, PersistentP (Φ x))  ([ set] x  X, Φ x)  ( x,  (x  X)  Φ x).
  Proof.
    intros. apply (anti_symm _).
    { apply forall_intro=> x.
357
      apply impl_intro_l, pure_elim_l=> ?; by apply big_sepS_elem_of. }
358
359
360
    rewrite /uPred_big_sepS. setoid_rewrite <-elem_of_elements.
    induction (elements X) as [|x l IH]; csimpl; auto.
    rewrite -always_and_sep_l; apply and_intro.
361
    - rewrite (forall_elim x) pure_equiv; last by left. by rewrite True_impl.
362
    - rewrite -IH. apply forall_mono=> y.
363
      apply impl_intro_l, pure_elim_l=> ?. rewrite pure_equiv; last by right.
364
365
366
367
      by rewrite True_impl.
  Qed.

  Lemma big_sepS_impl Φ Ψ X :
368
       ( x,  (x  X)  Φ x  Ψ x)  ([ set] x  X, Φ x)  [ set] x  X, Ψ x.
369
370
  Proof.
    rewrite always_and_sep_l always_forall.
371
    setoid_rewrite always_impl; setoid_rewrite always_pure.
372
373
374
    rewrite -big_sepS_forall -big_sepS_sepS. apply big_sepS_mono; auto=> x ?.
    by rewrite -always_wand_impl always_elim wand_elim_l.
  Qed.
375
End gset.
376

377
(** ** Persistence *)
378
Global Instance big_and_persistent Ps : PersistentL Ps  PersistentP ([] Ps).
379
Proof. induction 1; apply _. Qed.
380
Global Instance big_sep_persistent Ps : PersistentL Ps  PersistentP ([] Ps).
381
382
Proof. induction 1; apply _. Qed.

383
Global Instance nil_persistent : PersistentL (@nil (uPred M)).
384
Proof. constructor. Qed.
385
Global Instance cons_persistent P Ps :
386
  PersistentP P  PersistentL Ps  PersistentL (P :: Ps).
387
Proof. by constructor. Qed.
388
389
Global Instance app_persistent Ps Ps' :
  PersistentL Ps  PersistentL Ps'  PersistentL (Ps ++ Ps').
390
Proof. apply Forall_app_2. Qed.
391
Global Instance zip_with_persistent {A B} (f : A  B  uPred M) xs ys :
392
  ( x y, PersistentP (f x y))  PersistentL (zip_with f xs ys).
393
394
395
Proof.
  unfold PersistentL=> ?; revert ys; induction xs=> -[|??]; constructor; auto.
Qed.
396
End big_op.