Skip to content
Snippets Groups Projects
Commit 8084db97 authored by Ralf Jung's avatar Ralf Jung
Browse files

Merge branch 'ralf/gen-heap-names' into 'master'

gen_heap: expose that inG identities are preserved

See merge request iris/iris!585
parents a0e020ca 3a7c26b0
No related branches found
No related tags found
No related merge requests found
...@@ -112,34 +112,31 @@ Proof. apply (heap_adequacy clientΣ)=> ?. apply client_safe. Qed. ...@@ -112,34 +112,31 @@ Proof. apply (heap_adequacy clientΣ)=> ?. apply client_safe. Qed.
Some Iris modules involve a form of "global state". For example, defining the Some Iris modules involve a form of "global state". For example, defining the
`↦` for HeapLang involves a piece of ghost state that matches the current `↦` for HeapLang involves a piece of ghost state that matches the current
physical heap. The `gname` of that ghost state must be picked once when the physical heap. The `gname` of that ghost state must be picked once when the
proof starts, and then globally known everywhere. Hence it is added to proof starts, and then globally known everywhere. Hence `gen_heapG`, the type
`gen_heapG`, the type class for the generalized heap module: class for the generalized heap module, bundles the usual `inG` assumptions
together with the `gname`:
```coq ```coq
Class gen_heapPreG (L V : Type) (Σ : gFunctors) `{Countable L} := {
gen_heap_preG_inG :> inG Σ (authR (gen_heapUR L V))
}.
Class gen_heapG (L V : Type) (Σ : gFunctors) `{Countable L} := { Class gen_heapG (L V : Type) (Σ : gFunctors) `{Countable L} := {
gen_heap_inG :> inG Σ (authR (gen_heapUR L V)); gen_heap_inG :> gen_heapPreG L V Σ;
gen_heap_name : gname gen_heap_name : gname
}. }.
``` ```
Such modules always need some kind of "initialization" to create an instance The `gen_heapPreG` typeclass (without the singleton data) is relevant for
of their type class. For example, the initialization for `heapG` is happening initialization, i.e., to create an instance of `gen_heapG`. This is happening as
as part of [`heap_adequacy`](iris_heap_lang/adequacy.v); this in turn uses part of [`heap_adequacy`](iris_heap_lang/adequacy.v) using the
the initialization lemma for `gen_heapG` from initialization lemma for `gen_heapG` from
[`gen_heap_init`](iris/base_logic/lib/gen_heap.v): [`gen_heap_init`](iris/base_logic/lib/gen_heap.v):
```coq ```coq
Lemma gen_heap_init `{gen_heapPreG L V Σ} σ : Lemma gen_heap_init `{gen_heapPreG L V Σ} σ :
(|==> _ : gen_heapG L V Σ, gen_heap_ctx σ)%I. (|==> _ : gen_heapG L V Σ, gen_heap_ctx σ)%I.
``` ```
These lemmas themselves only make assumptions the way normal modules (those These lemmas themselves only make assumptions the way normal modules (those
without global state) do, which are typically collected in a `somethingPreG` without global state) do. Just like in the normal case, `somethingPreG` type
type class (such as `gen_heapPreG`): classes have an `Instance` showing that a `subG` is enough to instantiate them:
```coq
Class gen_heapPreG (L V : Type) (Σ : gFunctors) `{Countable L} := {
gen_heap_preG_inG :> inG Σ (authR (gen_heapUR L V))
}.
```
Just like in the normal case, `somethingPreG` type classes have an `Instance`
showing that a `subG` is enough to instantiate them:
```coq ```coq
Instance subG_gen_heapPreG {Σ L V} `{Countable L} : Instance subG_gen_heapPreG {Σ L V} `{Countable L} :
subG (gen_heapΣ L V) Σ gen_heapPreG L V Σ. subG (gen_heapΣ L V) Σ gen_heapPreG L V Σ.
......
...@@ -61,26 +61,23 @@ these can be matched up with the invariant namespaces. *) ...@@ -61,26 +61,23 @@ these can be matched up with the invariant namespaces. *)
as a premise). as a premise).
*) *)
(** The CMRAs we need, and the global ghost names we are using. (** The CMRAs we need, and the global ghost names we are using. *)
Class gen_heapPreG (L V : Type) (Σ : gFunctors) `{Countable L} := {
gen_heap_preG_inG :> inG Σ (gmap_viewR L (leibnizO V));
gen_meta_preG_inG :> inG Σ (gmap_viewR L gnameO);
gen_meta_data_preG_inG :> inG Σ (namespace_mapR (agreeR positiveO));
}.
Typically, the adequacy theorem will use [gen_heap_init] to obtain an instance
of this class; everything else should assume it as a premise. *)
Class gen_heapG (L V : Type) (Σ : gFunctors) `{Countable L} := GenHeapG { Class gen_heapG (L V : Type) (Σ : gFunctors) `{Countable L} := GenHeapG {
gen_heap_inG :> inG Σ (gmap_viewR L (leibnizO V)); gen_heap_inG :> gen_heapPreG L V Σ;
gen_meta_inG :> inG Σ (gmap_viewR L gnameO);
gen_meta_data_inG :> inG Σ (namespace_mapR (agreeR positiveO));
gen_heap_name : gname; gen_heap_name : gname;
gen_meta_name : gname gen_meta_name : gname
}. }.
Global Arguments GenHeapG L V Σ {_ _ _} _ _.
Global Arguments gen_heap_name {L V Σ _ _} _ : assert. Global Arguments gen_heap_name {L V Σ _ _} _ : assert.
Global Arguments gen_meta_name {L V Σ _ _} _ : assert. Global Arguments gen_meta_name {L V Σ _ _} _ : assert.
Class gen_heapPreG (L V : Type) (Σ : gFunctors) `{Countable L} := {
gen_heap_preG_inG :> inG Σ (gmap_viewR L (leibnizO V));
gen_meta_preG_inG :> inG Σ (gmap_viewR L gnameO);
gen_meta_data_preG_inG :> inG Σ (namespace_mapR (agreeR positiveO));
}.
Definition gen_heapΣ (L V : Type) `{Countable L} : gFunctors := #[ Definition gen_heapΣ (L V : Type) `{Countable L} : gFunctors := #[
GFunctor (gmap_viewR L (leibnizO V)); GFunctor (gmap_viewR L (leibnizO V));
GFunctor (gmap_viewR L gnameO); GFunctor (gmap_viewR L gnameO);
...@@ -308,19 +305,32 @@ Section gen_heap. ...@@ -308,19 +305,32 @@ Section gen_heap.
Qed. Qed.
End gen_heap. End gen_heap.
Lemma gen_heap_init `{Countable L, !gen_heapPreG L V Σ} σ : (** This variant of [gen_heap_init] should only be used when absolutely needed.
|==> _ : gen_heapG L V Σ, The key difference to [gen_heap_init] is that the [inG] instances in the new
[gen_heapG] instance are related to the original [gen_heapPreG] instance,
whereas [gen_heap_init] forgets about that relation. *)
Lemma gen_heap_init_names `{Countable L, !gen_heapPreG L V Σ} σ :
|==> γh γm : gname,
let hG := GenHeapG L V Σ γh γm in
gen_heap_interp σ ([ map] l v σ, l v) ([ map] l _ σ, meta_token l ). gen_heap_interp σ ([ map] l v σ, l v) ([ map] l _ σ, meta_token l ).
Proof. Proof.
iMod (own_alloc (gmap_view_auth 1 ( : gmap L (leibnizO V)))) as (γh) "Hh". iMod (own_alloc (gmap_view_auth 1 ( : gmap L (leibnizO V)))) as (γh) "Hh".
{ exact: gmap_view_auth_valid. } { exact: gmap_view_auth_valid. }
iMod (own_alloc (gmap_view_auth 1 ( : gmap L gnameO))) as (γm) "Hm". iMod (own_alloc (gmap_view_auth 1 ( : gmap L gnameO))) as (γm) "Hm".
{ exact: gmap_view_auth_valid. } { exact: gmap_view_auth_valid. }
pose (gen_heap := GenHeapG L V Σ _ _ _ _ _ γh γm). iExists γh, γm.
iExists gen_heap. iAssert (gen_heap_interp (hG:=GenHeapG _ _ _ γh γm) ) with "[Hh Hm]" as "Hinterp".
iAssert (gen_heap_interp (hG:=gen_heap) ) with "[Hh Hm]" as "Hinterp".
{ iExists ; simpl. iFrame "Hh Hm". by rewrite dom_empty_L. } { iExists ; simpl. iFrame "Hh Hm". by rewrite dom_empty_L. }
iMod (gen_heap_alloc_big with "Hinterp") as "(Hinterp & $ & $)". iMod (gen_heap_alloc_big with "Hinterp") as "(Hinterp & $ & $)".
{ apply map_disjoint_empty_r. } { apply map_disjoint_empty_r. }
rewrite right_id_L. done. rewrite right_id_L. done.
Qed. Qed.
Lemma gen_heap_init `{Countable L, !gen_heapPreG L V Σ} σ :
|==> _ : gen_heapG L V Σ,
gen_heap_interp σ ([ map] l v σ, l v) ([ map] l _ σ, meta_token l ).
Proof.
iMod (gen_heap_init_names σ) as (γh γm) "Hinit".
iExists (GenHeapG _ _ _ γh γm).
done.
Qed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment