clutch.base_logic.spec_auth_markov
From Stdlib Require Export Reals Psatz.
From iris.base_logic.lib Require Export fancy_updates own.
From iris.proofmode Require Import base proofmode classes.
From iris.algebra Require Import excl auth.
From iris.prelude Require Import options.
From clutch.prob Require Import couplings distribution markov.
From clutch.base_logic Require Export spec_update.
From iris.base_logic.lib Require Export fancy_updates own.
From iris.proofmode Require Import base proofmode classes.
From iris.algebra Require Import excl auth.
From iris.prelude Require Import options.
From clutch.prob Require Import couplings distribution markov.
From clutch.base_logic Require Export spec_update.
The authoritative spec tracking algebra
Definition specUR (δ : markov) : ucmra := optionUR (exclR (leibnizO (mstate δ))).
Definition authUR_spec (δ : markov) : ucmra := authUR (specUR δ).
Class specPreG (δ : markov) (Σ : gFunctors) := SpecPreG {
specG_pre_authUR :: inG Σ (authUR_spec δ);
}.
Definition specΣ (δ : markov) : gFunctors := GFunctor (authUR_spec δ).
Global Instance subG_caliperGPreS {δ Σ} : subG (specΣ δ) Σ → specPreG δ Σ.
Proof. solve_inG. Qed.
Class specG (δ : markov) (Σ : gFunctors) := SpecG {
specG_authUR :: inG Σ (authUR_spec δ);
specG_gname : gname;
}.
Section spec_auth.
Context `{specG δ Σ}.
Implicit Types a : mstate δ.
Definition specA a : iProp Σ :=
own specG_gname (● (Excl' a : specUR _)).
Definition specF a : iProp Σ :=
own specG_gname (◯ (Excl' a : specUR _)).
Lemma spec_auth_agree a a' :
specA a -∗ specF a' -∗ ⌜a = a'⌝.
Proof.
iIntros "Ha Hf".
iDestruct (own_valid_2 with "Ha Hf") as
%[Hexcl ?]%auth_both_valid_discrete.
rewrite Excl_included in Hexcl.
by apply leibniz_equiv in Hexcl.
Qed.
Lemma spec_auth_update a'' a a' :
specA a -∗ specF a' ==∗ specA a'' ∗ specF a''.
Proof.
iIntros "Ha Hf".
iDestruct (spec_auth_agree with "Ha Hf") as %->.
iMod (own_update_2 with "Ha Hf") as "[Ha Hf]".
{ eapply auth_update .
eapply (option_local_update _ _ (Excl a'' : exclR (leibnizO (mstate δ)))).
by eapply exclusive_local_update. }
by iFrame.
Qed.
End spec_auth.
Lemma spec_auth_alloc {δ Σ} a `{!specPreG δ Σ} :
⊢ |==> ∃ (_ : specG δ Σ), specA a ∗ specF a.
Proof.
iMod (own_alloc ((● (Excl' a : specUR _)) ⋅ (◯ (Excl' a : specUR _))))
as "(%γspec & Hauth & Hfrag)".
{ by apply auth_both_valid_discrete. }
set (HspecG := SpecG δ Σ _ γspec).
iModIntro. iExists HspecG. iFrame.
Qed.
#[global] Instance spec_auth_spec_update {δ Σ} `{specG δ Σ} : spec_updateGS δ Σ := Spec_updateGS specA.
Definition authUR_spec (δ : markov) : ucmra := authUR (specUR δ).
Class specPreG (δ : markov) (Σ : gFunctors) := SpecPreG {
specG_pre_authUR :: inG Σ (authUR_spec δ);
}.
Definition specΣ (δ : markov) : gFunctors := GFunctor (authUR_spec δ).
Global Instance subG_caliperGPreS {δ Σ} : subG (specΣ δ) Σ → specPreG δ Σ.
Proof. solve_inG. Qed.
Class specG (δ : markov) (Σ : gFunctors) := SpecG {
specG_authUR :: inG Σ (authUR_spec δ);
specG_gname : gname;
}.
Section spec_auth.
Context `{specG δ Σ}.
Implicit Types a : mstate δ.
Definition specA a : iProp Σ :=
own specG_gname (● (Excl' a : specUR _)).
Definition specF a : iProp Σ :=
own specG_gname (◯ (Excl' a : specUR _)).
Lemma spec_auth_agree a a' :
specA a -∗ specF a' -∗ ⌜a = a'⌝.
Proof.
iIntros "Ha Hf".
iDestruct (own_valid_2 with "Ha Hf") as
%[Hexcl ?]%auth_both_valid_discrete.
rewrite Excl_included in Hexcl.
by apply leibniz_equiv in Hexcl.
Qed.
Lemma spec_auth_update a'' a a' :
specA a -∗ specF a' ==∗ specA a'' ∗ specF a''.
Proof.
iIntros "Ha Hf".
iDestruct (spec_auth_agree with "Ha Hf") as %->.
iMod (own_update_2 with "Ha Hf") as "[Ha Hf]".
{ eapply auth_update .
eapply (option_local_update _ _ (Excl a'' : exclR (leibnizO (mstate δ)))).
by eapply exclusive_local_update. }
by iFrame.
Qed.
End spec_auth.
Lemma spec_auth_alloc {δ Σ} a `{!specPreG δ Σ} :
⊢ |==> ∃ (_ : specG δ Σ), specA a ∗ specF a.
Proof.
iMod (own_alloc ((● (Excl' a : specUR _)) ⋅ (◯ (Excl' a : specUR _))))
as "(%γspec & Hauth & Hfrag)".
{ by apply auth_both_valid_discrete. }
set (HspecG := SpecG δ Σ _ γspec).
iModIntro. iExists HspecG. iFrame.
Qed.
#[global] Instance spec_auth_spec_update {δ Σ} `{specG δ Σ} : spec_updateGS δ Σ := Spec_updateGS specA.