heap.v 9.17 KB
Newer Older
1
From iris.heap_lang Require Export lifting.
2
From iris.algebra Require Import upred_big_op gmap frac dec_agree.
3 4
From iris.program_logic Require Export invariants ghost_ownership.
From iris.program_logic Require Import ownership auth.
Ralf Jung's avatar
Ralf Jung committed
5
From iris.proofmode Require Import weakestpre.
6 7 8 9 10
Import uPred.
(* TODO: The entire construction could be generalized to arbitrary languages that have
   a finmap as their state. Or maybe even beyond "as their state", i.e. arbitrary
   predicates over finmaps instead of just ownP. *)

11
Definition heapN : namespace := nroot .@ "heap".
12
Definition heapUR : ucmraT := gmapUR loc (prodR fracR (dec_agreeR val)).
13

14
(** The CMRA we need. *)
15
Class heapG Σ := HeapG {
16 17
  heapG_iris_inG :> irisG heap_lang Σ;
  heap_inG :> authG Σ heapUR;
18 19
  heap_name : gname
}.
20
(** The Functor we need. *)
21 22
Definition to_heap : state  heapUR := fmap (λ v, (1%Qp, DecAgree v)).
Definition of_heap : heapUR  state := omap (maybe DecAgree  snd).
23

24
Section definitions.
25
  Context `{heapG Σ}.
26

27
  Definition heap_mapsto_def (l : loc) (q : Qp) (v: val) : iProp Σ :=
28
    auth_own heap_name {[ l := (q, DecAgree v) ]}.
29 30 31 32 33
  Definition heap_mapsto_aux : { x | x = @heap_mapsto_def }. by eexists. Qed.
  Definition heap_mapsto := proj1_sig heap_mapsto_aux.
  Definition heap_mapsto_eq : @heap_mapsto = @heap_mapsto_def :=
    proj2_sig heap_mapsto_aux.

34
  Definition heap_inv (h : heapUR) : iProp Σ :=
35
    ownP (of_heap h).
36
  Definition heap_ctx : iProp Σ :=
37
    auth_ctx heap_name heapN heap_inv.
38

39
  Global Instance heap_inv_proper : Proper (() ==> ()) heap_inv.
40
  Proof. solve_proper. Qed.
41
  Global Instance heap_ctx_persistent : PersistentP heap_ctx.
42 43
  Proof. apply _. Qed.
End definitions.
44

45
Typeclasses Opaque heap_ctx heap_mapsto.
46
Instance: Params (@heap_inv) 2.
47

Robbert Krebbers's avatar
Robbert Krebbers committed
48 49 50
Notation "l ↦{ q } v" := (heap_mapsto l q v)
  (at level 20, q at level 50, format "l  ↦{ q }  v") : uPred_scope.
Notation "l ↦ v" := (heap_mapsto l 1 v) (at level 20) : uPred_scope.
51

52
Section heap.
53
  Context {Σ : gFunctors}.
54 55
  Implicit Types P Q : iProp Σ.
  Implicit Types Φ : val  iProp Σ.
56
  Implicit Types σ : state.
57
  Implicit Types h g : heapUR.
58

59
  (** Conversion to heaps and back *)
60
  Global Instance of_heap_proper : Proper (() ==> (=)) of_heap.
61
  Proof. solve_proper. Qed.
62
  Lemma from_to_heap σ : of_heap (to_heap σ) = σ.
63
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
64 65 66
    apply map_eq=>l. rewrite lookup_omap lookup_fmap. by case (σ !! l).
  Qed.
  Lemma to_heap_valid σ :  to_heap σ.
67
  Proof. intros l. rewrite lookup_fmap. by case (σ !! l). Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
68
  Lemma of_heap_insert l v h :
69 70
    of_heap (<[l:=(1%Qp, DecAgree v)]> h) = <[l:=v]> (of_heap h).
  Proof. by rewrite /of_heap -(omap_insert _ _ _ (1%Qp, DecAgree v)). Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
71
  Lemma of_heap_singleton_op l q v h :
72 73
     ({[l := (q, DecAgree v)]}  h) 
    of_heap ({[l := (q, DecAgree v)]}  h) = <[l:=v]> (of_heap h).
Robbert Krebbers's avatar
Robbert Krebbers committed
74 75 76 77
  Proof.
    intros Hv. apply map_eq=> l'; destruct (decide (l' = l)) as [->|].
    - move: (Hv l). rewrite /of_heap lookup_insert
        lookup_omap (lookup_op _ h) lookup_singleton.
Robbert Krebbers's avatar
Robbert Krebbers committed
78
      case _:(h !! l)=>[[q' [v'|]]|] //=; last by move=> [??].
Robbert Krebbers's avatar
Robbert Krebbers committed
79 80
      move=> [? /dec_agree_op_inv [->]]. by rewrite dec_agree_idemp.
    - rewrite /of_heap lookup_insert_ne // !lookup_omap.
81
      by rewrite (lookup_op _ h) lookup_singleton_ne // left_id_L.
Robbert Krebbers's avatar
Robbert Krebbers committed
82 83
  Qed.
  Lemma to_heap_insert l v σ :
84
    to_heap (<[l:=v]> σ) = <[l:=(1%Qp, DecAgree v)]> (to_heap σ).
85
  Proof. by rewrite /to_heap -fmap_insert. Qed.
86
  Lemma of_heap_None h l :  h  of_heap h !! l = None  h !! l = None.
87
  Proof.
88
    move=> /(_ l). rewrite /of_heap lookup_omap.
Robbert Krebbers's avatar
Robbert Krebbers committed
89
    by case: (h !! l)=> [[q [v|]]|] //=; destruct 1; auto.
90
  Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
91
  Lemma heap_store_valid l h v1 v2 :
92 93
     ({[l := (1%Qp, DecAgree v1)]}  h) 
     ({[l := (1%Qp, DecAgree v2)]}  h).
94
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
95 96
    intros Hv l'; move: (Hv l'). destruct (decide (l' = l)) as [->|].
    - rewrite !lookup_op !lookup_singleton.
97
      by case: (h !! l)=> [x|] // /Some_valid/exclusive_l.
Robbert Krebbers's avatar
Robbert Krebbers committed
98
    - by rewrite !lookup_op !lookup_singleton_ne.
99
  Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
100
  Hint Resolve heap_store_valid.
Robbert Krebbers's avatar
Robbert Krebbers committed
101

102 103 104
  Context `{heapG Σ}.

  (** General properties of mapsto *)
Robbert Krebbers's avatar
Robbert Krebbers committed
105
  Global Instance heap_mapsto_timeless l q v : TimelessP (l {q} v).
106
  Proof. rewrite heap_mapsto_eq /heap_mapsto_def. apply _. Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
107

108
  Lemma heap_mapsto_op_eq l q1 q2 v : l {q1} v  l {q2} v  l {q1+q2} v.
109 110 111
  Proof.
    by rewrite heap_mapsto_eq -auth_own_op op_singleton pair_op dec_agree_idemp.
  Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
112 113

  Lemma heap_mapsto_op l q1 q2 v1 v2 :
114
    l {q1} v1  l {q2} v2  v1 = v2  l {q1+q2} v1.
115
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
116
    destruct (decide (v1 = v2)) as [->|].
117
    { by rewrite heap_mapsto_op_eq pure_equiv // left_id. }
118
    rewrite heap_mapsto_eq -auth_own_op op_singleton pair_op dec_agree_ne //.
119
    apply (anti_symm ()); last by apply pure_elim_l.
120
    rewrite auth_own_valid gmap_validI (forall_elim l) lookup_singleton.
121
    rewrite option_validI prod_validI !discrete_valid /=.
122
    by apply pure_elim_r.
123 124
  Qed.

125 126 127 128 129 130 131 132 133 134 135
  Lemma heap_mapsto_op_1 l q1 q2 v1 v2 :
    l {q1} v1  l {q2} v2  v1 = v2  l {q1+q2} v1.
  Proof. by rewrite heap_mapsto_op. Qed.

  Lemma heap_mapsto_op_half l q v1 v2 :
    l {q/2} v1  l {q/2} v2  v1 = v2  l {q} v1.
  Proof. by rewrite heap_mapsto_op Qp_div_2. Qed.

  Lemma heap_mapsto_op_half_1 l q v1 v2 :
    l {q/2} v1  l {q/2} v2  v1 = v2  l {q} v1.
  Proof. by rewrite heap_mapsto_op_half. Qed.
136

137
  (** Weakest precondition *)
138 139 140
  Lemma wp_alloc E e v Φ :
    to_val e = Some v  nclose heapN  E 
    heap_ctx   ( l, l  v ={E}= Φ (LitV (LitLoc l)))  WP Alloc e @ E {{ Φ }}.
Ralf Jung's avatar
Ralf Jung committed
141
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
142
    iIntros (<-%of_to_val ?) "[#Hinv HΦ]". rewrite /heap_ctx.
143 144 145 146
    iVs (auth_empty heap_name) as "Hh".
    iVs (auth_open with "[Hh]") as (h) "[Hv [Hh Hclose]]"; eauto.
    rewrite left_id /heap_inv. iDestruct "Hv" as %?.
    iApply wp_alloc_pst. iFrame "Hh". iNext.
147
    iIntros (l) "[% Hh] !==>".
148 149 150 151 152
    iVs ("Hclose" $! {[ l := (1%Qp, DecAgree v) ]} with "[Hh]").
    { rewrite -of_heap_insert -(insert_singleton_op h); last by apply of_heap_None.
      iFrame "Hh". iPureIntro.
      by apply alloc_unit_singleton_local_update; first apply of_heap_None. }
    iApply "HΦ". by rewrite heap_mapsto_eq /heap_mapsto_def.
153 154
  Qed.

155 156 157
  Lemma wp_load E l q v Φ :
    nclose heapN  E 
    heap_ctx   l {q} v   (l {q} v ={E}= Φ v)
158
     WP Load (Lit (LitLoc l)) @ E {{ Φ }}.
Ralf Jung's avatar
Ralf Jung committed
159
  Proof.
160
    iIntros (?) "[#Hinv [Hl HΦ]]".
161
    rewrite /heap_ctx heap_mapsto_eq /heap_mapsto_def.
162 163
    iVs (auth_open with "[Hl]") as (h) "[% [Hl Hclose]]"; eauto.
    rewrite /heap_inv.
Ralf Jung's avatar
Ralf Jung committed
164
    iApply (wp_load_pst _ (<[l:=v]>(of_heap h)));first by rewrite lookup_insert.
165
    rewrite of_heap_singleton_op //. iFrame "Hl".
166
    iIntros "!> Hown !==>". iVs ("Hclose" with "* [Hown]").
167 168
    { iSplit; first done. rewrite of_heap_singleton_op //. by iFrame. }
    by iApply "HΦ".
Ralf Jung's avatar
Ralf Jung committed
169 170
  Qed.

171 172 173
  Lemma wp_store E l v' e v Φ :
    to_val e = Some v  nclose heapN  E 
    heap_ctx   l  v'   (l  v ={E}= Φ (LitV LitUnit))
174
     WP Store (Lit (LitLoc l)) e @ E {{ Φ }}.
Ralf Jung's avatar
Ralf Jung committed
175
  Proof.
176
    iIntros (<-%of_to_val ?) "[#Hinv [Hl HΦ]]".
177
    rewrite /heap_ctx heap_mapsto_eq /heap_mapsto_def.
178 179
    iVs (auth_open with "[Hl]") as (h) "[% [Hl Hclose]]"; eauto.
    rewrite /heap_inv.
180
    iApply (wp_store_pst _ (<[l:=v']>(of_heap h))); rewrite ?lookup_insert //.
181
    rewrite insert_insert !of_heap_singleton_op; eauto. iFrame "Hl".
182
    iIntros "!> Hl !==>".
183 184 185 186 187
    iVs ("Hclose" $! {[l := (1%Qp, DecAgree v)]} with "[Hl]").
    { iSplit.
      - iPureIntro; by apply singleton_local_update, exclusive_local_update.
      - rewrite of_heap_singleton_op //; eauto. }
    by iApply "HΦ".
Ralf Jung's avatar
Ralf Jung committed
188 189
  Qed.

190 191 192
  Lemma wp_cas_fail E l q v' e1 v1 e2 v2 Φ :
    to_val e1 = Some v1  to_val e2 = Some v2  v'  v1  nclose heapN  E 
    heap_ctx   l {q} v'   (l {q} v' ={E}= Φ (LitV (LitBool false)))
193
     WP CAS (Lit (LitLoc l)) e1 e2 @ E {{ Φ }}.
Ralf Jung's avatar
Ralf Jung committed
194
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
195
    iIntros (<-%of_to_val <-%of_to_val ??) "[#Hh [Hl HΦ]]".
196
    rewrite /heap_ctx heap_mapsto_eq /heap_mapsto_def.
197 198
    iVs (auth_open with "[Hl]") as (h) "[% [Hl Hclose]]"; eauto.
    rewrite /heap_inv.
199
    iApply (wp_cas_fail_pst _ (<[l:=v']>(of_heap h))); rewrite ?lookup_insert //.
200
    rewrite of_heap_singleton_op //. iFrame "Hl".
201
    iIntros "!> Hown !==>". iVs ("Hclose" with "* [Hown]").
202 203
    { iSplit; first done. rewrite of_heap_singleton_op //. by iFrame. }
    by iApply "HΦ".
Ralf Jung's avatar
Ralf Jung committed
204
  Qed.
Ralf Jung's avatar
Ralf Jung committed
205

206 207 208
  Lemma wp_cas_suc E l e1 v1 e2 v2 Φ :
    to_val e1 = Some v1  to_val e2 = Some v2  nclose heapN  E 
    heap_ctx   l  v1   (l  v2 ={E}= Φ (LitV (LitBool true)))
209
     WP CAS (Lit (LitLoc l)) e1 e2 @ E {{ Φ }}.
Ralf Jung's avatar
Ralf Jung committed
210
  Proof.
Robbert Krebbers's avatar
Robbert Krebbers committed
211
    iIntros (<-%of_to_val <-%of_to_val ?) "[#Hh [Hl HΦ]]".
212
    rewrite /heap_ctx heap_mapsto_eq /heap_mapsto_def.
213 214
    iVs (auth_open with "[Hl]") as (h) "[% [Hl Hclose]]"; eauto.
    rewrite /heap_inv.
215
    iApply (wp_cas_suc_pst _ (<[l:=v1]>(of_heap h))); rewrite ?lookup_insert //.
216
    rewrite insert_insert !of_heap_singleton_op; eauto. iFrame "Hl".
217
    iIntros "!> Hl !==>".
218 219 220 221 222
    iVs ("Hclose" $! {[l := (1%Qp, DecAgree v2)]} with "[Hl]").
    { iSplit.
      - iPureIntro; by apply singleton_local_update, exclusive_local_update.
      - rewrite of_heap_singleton_op //; eauto. }
    by iApply "HΦ".
Ralf Jung's avatar
Ralf Jung committed
223
  Qed.
224
End heap.