spec_ra.v 8.07 KiB
(* ReLoC -- Relational logic for fine-grained concurrency *)
(** A resource algebra for the specification programs. *)
From iris.algebra Require Import auth excl gmap agree list frac.
From iris.bi Require Export fractional.
From iris.base_logic Require Export invariants.
From iris.proofmode Require Import proofmode.
From iris.heap_lang Require Import lang primitive_laws.
Import uPred.
Definition relocN := nroot .@ "reloc".
Definition specN := relocN .@ "spec".
(** The CMRA for the heap of the specification. *)
Definition heapUR (L V : Type) `{Countable L} : ucmra :=
gmapUR L (prodR fracR (agreeR (leibnizO V))).
Definition tpoolUR : ucmra := gmapUR nat (exclR exprO).
Definition cfgUR := prodUR tpoolUR (heapUR loc (option val)).
(** The CMRA for the thread pool. *)
Class cfgSG Σ := CFGSG { cfg_inG :: inG Σ (authR cfgUR); cfg_name : gname }.
Class relocG Σ := RelocG {
relocG_heapG :: heapGS Σ;
relocG_cfgG :: cfgSG Σ;
}.
Definition to_heap {L V} `{Countable L} : gmap L V → heapUR L V :=
fmap (λ v, (1%Qp, to_agree (v : leibnizO V))).
Definition to_tpool (tp : list expr) : tpoolUR := Excl <$> (map_seq 0 tp).
Section definitionsS.
Context `{cfgSG Σ, invGS Σ}.
Definition heapS_pointsto_def (l : loc) (q : Qp) (v: val) : iProp Σ :=
own cfg_name (◯ (∅, {[ l := (q, to_agree (Some v)) ]})).
Definition heapS_pointsto_aux : seal (@heapS_pointsto_def). by eexists. Qed.
Definition heapS_pointsto := heapS_pointsto_aux.(unseal).
Definition heapS_pointsto_eq :
@heapS_pointsto = @heapS_pointsto_def := heapS_pointsto_aux.(seal_eq).
Definition tpool_pointsto_def (j : nat) (e: expr) : iProp Σ :=
own cfg_name (◯ ({[ j := Excl e ]}, ∅)).
Definition tpool_pointsto_aux : seal (@tpool_pointsto_def). by eexists. Qed.
Definition tpool_pointsto := tpool_pointsto_aux.(unseal).
Definition tpool_pointsto_eq :
@tpool_pointsto = @tpool_pointsto_def := tpool_pointsto_aux.(seal_eq).
Definition mkstate (σ : gmap loc (option val)) (κs : gset proph_id) :=
{| heap := σ; used_proph_id := κs |}.
Definition spec_inv ρ : iProp Σ :=
(∃ tp σ, own cfg_name (● (to_tpool tp, to_heap (heap σ)))
∗ ⌜rtc erased_step ρ (tp,σ)⌝)%I.
Definition spec_ctx : iProp Σ :=
(∃ ρ, inv specN (spec_inv ρ))%I.
Global Instance heapS_pointsto_timeless l q v : Timeless (heapS_pointsto l q v).
Proof. rewrite heapS_pointsto_eq. apply _. Qed.
Global Instance tpool_pointsto_timeless j e: Timeless (tpool_pointsto j e).
Proof. rewrite tpool_pointsto_eq. apply _. Qed.
Global Instance spec_ctx_persistent : Persistent spec_ctx.
Proof. apply _. Qed.
End definitionsS.
Notation "l ↦ₛ{ q } v" := (heapS_pointsto l q v)
(at level 20, q at level 50, format "l ↦ₛ{ q } v") : bi_scope.
Notation "l ↦ₛ v" := (heapS_pointsto l 1 v) (at level 20) : bi_scope.
Notation "j ⤇ e" := (tpool_pointsto j e) (at level 20) : bi_scope.
Section conversions.
Context `{cfgSG Σ}.
Local Open Scope nat_scope.
(** Conversion to tpools and back *)
Lemma to_tpool_valid es : ✓ to_tpool es.
Proof.
rewrite /to_tpool. move: 0.
induction es as [|e es]=> n /= //.
rewrite fmap_insert. by apply insert_valid.
Qed.
Lemma tpool_lookup tp j : to_tpool tp !! j = Excl <$> tp !! j.
Proof.
unfold to_tpool. rewrite lookup_fmap.
by rewrite lookup_map_seq_0.
Qed.
Lemma tpool_lookup_Some tp j e : to_tpool tp !! j = Excl' e → tp !! j = Some e.
Proof. rewrite tpool_lookup fmap_Some. naive_solver. Qed.
Hint Resolve tpool_lookup_Some : core.
Lemma to_tpool_insert tp j e :
j < length tp →
to_tpool (<[j:=e]> tp) = <[j:=Excl e]> (to_tpool tp).
Proof.
intros. apply: map_eq=> i. destruct (decide (i = j)) as [->|].
- by rewrite tpool_lookup lookup_insert list_lookup_insert.
- rewrite tpool_lookup lookup_insert_ne // list_lookup_insert_ne //.
by rewrite tpool_lookup.
Qed.
Lemma to_tpool_insert' tp j e :
is_Some (to_tpool tp !! j) →
to_tpool (<[j:=e]> tp) = <[j:=Excl e]> (to_tpool tp).
Proof.
rewrite tpool_lookup fmap_is_Some lookup_lt_is_Some. apply to_tpool_insert.
Qed.
Lemma to_tpool_snoc tp e :
to_tpool (tp ++ [e]) = <[length tp:=Excl e]>(to_tpool tp).
Proof.
intros. apply: map_eq=> i.
destruct (lt_eq_lt_dec i (length tp)) as [[?| ->]|?].
- rewrite lookup_insert_ne; last lia. by rewrite !tpool_lookup lookup_app_l.
- by rewrite lookup_insert tpool_lookup lookup_app_r // Nat.sub_diag.
- rewrite lookup_insert_ne; last lia.
rewrite !tpool_lookup ?lookup_ge_None_2 ?app_length //=;
change (ofe_car exprO) with expr; lia.
Qed.
Lemma tpool_singleton_included tp j e :
{[j := Excl e]} ≼ to_tpool tp → tp !! j = Some e.
Proof.
move=> /singleton_included_l [ex [/leibniz_equiv_iff]].
rewrite tpool_lookup fmap_Some=> [[e' [-> ->]] /Excl_included ?]. by f_equal.
Qed.
Lemma tpool_singleton_included' tp j e :
{[j := Excl e]} ≼ to_tpool tp → to_tpool tp !! j = Excl' e.
Proof. rewrite tpool_lookup. by move=> /tpool_singleton_included=> ->. Qed.
End conversions.
Section to_heap.
Context (L V : Type) `{Countable L}.
Implicit Types σ : gmap L V.
Implicit Types m : gmap L gname.
Lemma lookup_to_heap_None σ l : σ !! l = None → to_heap σ !! l = None.
Proof. by rewrite /to_heap lookup_fmap=> ->. Qed.
Lemma to_heap_insert l v σ :
to_heap (<[l:=v]> σ) = <[l:=(1%Qp, to_agree (v:leibnizO V))]> (to_heap σ).
Proof. by rewrite /to_heap fmap_insert. Qed.
Lemma heap_singleton_included σ l q v :
{[l := (q, to_agree v)]} ≼ to_heap σ → σ !! l = Some v.
Proof.
rewrite singleton_included_l=> -[[q' av] []].
rewrite /to_heap lookup_fmap fmap_Some_equiv => -[v' [Hl [/= -> ->]]].
move=> /Some_pair_included_total_2 [_] /to_agree_included /leibniz_equiv_iff -> //.
Qed.
Lemma to_heap_valid σ : ✓ to_heap σ.
Proof. intros l. rewrite lookup_fmap. by case: (σ !! l). Qed.
End to_heap.
Section pointsto.
Context `{!cfgSG Σ}.
Global Instance pointstoS_fractional l v : Fractional (λ q, l ↦ₛ{q} v)%I.
Proof.
intros p q. rewrite heapS_pointsto_eq -own_op -auth_frag_op.
by rewrite -pair_op singleton_op -pair_op agree_idemp right_id.
Qed.
Global Instance pointstoS_as_fractional l q v :
AsFractional (l ↦ₛ{q} v) (λ q, l ↦ₛ{q} v)%I q.
Proof. split. done. apply _. Qed.
Global Instance frame_pointstoS p l v q1 q2 q :
FrameFractionalQp q1 q2 q →
Frame p (l ↦ₛ{q1} v) (l ↦ₛ{q2} v) (l ↦ₛ{q} v) | 5.
Proof. apply: frame_fractional. Qed.
Lemma pointstoS_agree l q1 q2 v1 v2 : l ↦ₛ{q1} v1 -∗ l ↦ₛ{q2} v2 -∗ ⌜v1 = v2⌝.
Proof.
apply bi.entails_wand, bi.wand_intro_r.
rewrite heapS_pointsto_eq -own_op -auth_frag_op own_valid uPred.discrete_valid.
f_equiv=> /=.
rewrite -pair_op singleton_op right_id -pair_op.
rewrite auth_frag_valid pair_valid.
intros [_ Hv]. move:Hv => /=.
rewrite singleton_valid.
by move=> [_] /to_agree_op_inv_L [->].
Qed.
Lemma pointstoS_valid l q v : l ↦ₛ{q} v -∗ ✓ q.
Proof.
rewrite heapS_pointsto_eq /heapS_pointsto_def own_valid !uPred.discrete_valid.
apply bi.entails_wand, pure_mono=> /auth_frag_valid /= [_ Hfoo].
revert Hfoo. simpl. rewrite singleton_valid.
by intros [? _].
Qed.
Lemma pointstoS_valid_2 l q1 q2 v1 v2 : l ↦ₛ{q1} v1 -∗ l ↦ₛ{q2} v2 -∗ ✓ (q1 + q2)%Qp.
Proof.
iIntros "H1 H2". iDestruct (pointstoS_agree with "H1 H2") as %->.
iApply (pointstoS_valid l _ v2). by iFrame.
Qed.
Global Instance pointstoS_combine_sep_gives l dq1 dq2 v1 v2 :
CombineSepGives (l ↦ₛ{dq1} v1) (l ↦ₛ{dq2} v2) ⌜✓ (dq1 ⋅ dq2) ∧ v1 = v2⌝.
Proof.
rewrite /CombineSepGives. iIntros "[H1 H2]". iSplit.
- iDestruct (pointstoS_valid_2 with "H1 H2") as %?; auto.
- iDestruct (pointstoS_agree with "H1 H2") as %?; auto.
Qed.
Lemma pointstoS_half_combine l v1 v2 :
l ↦ₛ{1/2} v1 -∗ l ↦ₛ{1/2} v2 -∗ ⌜v1 = v2⌝ ∗ l ↦ₛ v1.
Proof.
iIntros "Hl1 Hl2".
iDestruct (pointstoS_agree with "Hl1 Hl2") as %?. simplify_eq.
iSplit; eauto. iCombine "Hl1 Hl2" as "?". done.
Qed.
End pointsto.