Library zoo_saturn.mpmc_bstack
From zoo Require Import
prelude.
From zoo.common Require Import
countable.
From zoo.iris.base_logic Require Import
lib.twins.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Import
option.
From zoo_saturn Require Export
base
mpmc_bstack__code.
From zoo_saturn Require Import
mpmc_bstack__types.
From zoo Require Import
options.
Implicit Types b : bool.
Implicit Types cap sz : nat.
Implicit Types l : location.
Implicit Types v t front : val.
Implicit Types vs : list val.
Class MpmcBstackG Σ `{zoo_G : !ZooG Σ} :=
{ #[local] mpmc_bstack_G_model_G :: TwinsG Σ (leibnizO (list val))
}.
Definition mpmc_bstack_Σ :=
#[twins_Σ (leibnizO (list val))
].
#[global] Instance subG_mpmc_bstack_Σ Σ `{zoo_G : !ZooG Σ} :
subG mpmc_bstack_Σ Σ →
MpmcBstackG Σ.
Section mpmc_bstack_G.
Context `{mpmc_bstack_G : MpmcBstackG Σ}.
Record metadata :=
{ metadata_capacity : nat
; metadata_model : gname
}.
Implicit Types γ : metadata.
#[local] Instance metadata_eq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadata_countable :
Countable metadata.
#[local] Fixpoint list_to_val sz vs :=
match vs with
| [] ⇒
§Nil%V
| v :: vs ⇒
‘Cons[ #sz, v, list_to_val (sz - 1) vs ]%V
end.
#[local] Instance list_to_val_inj_similar sz :
Inj (=) (≈@{val}) (list_to_val sz).
#[local] Instance list_to_val_inj sz :
Inj (=) (=) (list_to_val sz).
Lemma list_to_val_inj' vs1 vs2 :
list_to_val (length vs1) vs1 ≈ list_to_val (length vs2) vs2 →
vs1 = vs2.
#[local] Definition model₁' γ_model vs :=
twins_twin1 γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ vs :=
model₁' γ.(metadata_model) vs.
#[local] Definition model₂' γ_model vs :=
twins_twin2 γ_model vs.
#[local] Definition model₂ γ vs :=
model₂' γ.(metadata_model) vs.
#[local] Definition inv_inner l γ : iProp Σ :=
∃ vs,
l.[front] ↦ list_to_val (length vs) vs ∗
model₂ γ vs.
#[local] Instance : CustomIpat "inv_inner" :=
" ( %vs{} & Hl_front & Hmodel₂ ) ".
Definition mpmc_bstack_inv t ι cap : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
⌜cap = γ.(metadata_capacity)⌝ ∗
⌜0 < γ.(metadata_capacity)⌝ ∗
l.[capacity] ↦□ #γ.(metadata_capacity) ∗
inv ι (inv_inner l γ).
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & -> & #Hmeta & -> & %Hcapacity & #Hl_capacity & #Hinv ) ".
Definition mpmc_bstack_model t vs : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
⌜length vs ≤ γ.(metadata_capacity)⌝ ∗
model₁ γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %l{;_} & %γ{;_} & %Heq{} & Hmeta_{} & %Hvs{} & Hmodel₁{_{}} ) ".
#[global] Instance mpmc_bstack_model_timeless t vs :
Timeless (mpmc_bstack_model t vs).
#[global] Instance mpmc_bstack_inv_persistent t ι cap :
Persistent (mpmc_bstack_inv t ι cap).
#[local] Lemma model_alloc :
⊢ |==>
∃ γ_model,
model₁' γ_model [] ∗
model₂' γ_model [].
#[local] Lemma model₁_exclusive γ vs1 vs2 :
model₁ γ vs1 -∗
model₁ γ vs2 -∗
False.
#[local] Lemma model_agree γ vs1 vs2 :
model₁ γ vs1 -∗
model₂ γ vs2 -∗
⌜vs1 = vs2⌝.
#[local] Lemma model_update {γ vs1 vs2} vs :
model₁ γ vs1 -∗
model₂ γ vs2 ==∗
model₁ γ vs ∗
model₂ γ vs.
Lemma mpmc_bstack_model_valid t ι cap vs :
mpmc_bstack_inv t ι cap -∗
mpmc_bstack_model t vs -∗
⌜length vs ≤ cap⌝.
Lemma mpmc_bstack_model_exclusive t vs1 vs2 :
mpmc_bstack_model t vs1 -∗
mpmc_bstack_model t vs2 -∗
False.
Lemma mpmc_bstack٠create𑁒spec ι (cap : Z) :
(0 < cap)%Z →
{{{
True
}}}
mpmc_bstack٠create #cap
{{{
t
, RET t;
mpmc_bstack_inv t ι ₊cap ∗
mpmc_bstack_model t []
}}}.
Lemma mpmc_bstack٠size𑁒spec t ι cap :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠size t @ ↑ι
<<<
mpmc_bstack_model t vs
| RET #(length vs);
True
>>>.
Lemma mpmc_bstack٠is_empty𑁒spec t ι cap :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠is_empty t @ ↑ι
<<<
mpmc_bstack_model t vs
| RET #(bool_decide (vs = []%list));
True
>>>.
#[local] Lemma mpmc_bstack٠push_aux_push𑁒spec t ι cap v :
⊢ (
∀ (sz : Z) front ws,
<<<
⌜sz = length ws⌝ ∗
⌜front = list_to_val (length ws) ws⌝ ∗
⌜length ws < cap⌝ ∗
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠push_aux t #sz v front @ ↑ι
<<<
∃∃ b,
⌜b = bool_decide (length vs < cap)⌝ ∗
mpmc_bstack_model t (if b then v :: vs else vs)
| RET #b;
True
>>>
) ∧ (
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠push t v @ ↑ι
<<<
∃∃ b,
⌜b = bool_decide (length vs < cap)⌝ ∗
mpmc_bstack_model t (if b then v :: vs else vs)
| RET #b;
True
>>>
).
Lemma mpmc_bstack٠push𑁒spec t ι cap v :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠push t v @ ↑ι
<<<
∃∃ b,
⌜b = bool_decide (length vs < cap)⌝ ∗
mpmc_bstack_model t (if b then v :: vs else vs)
| RET #b;
True
>>>.
Lemma mpmc_bstack٠pop𑁒spec t ι cap :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠pop t @ ↑ι
<<<
mpmc_bstack_model t (tail vs)
| RET head vs;
True
>>>.
End mpmc_bstack_G.
From zoo_saturn Require
mpmc_bstack__opaque.
#[global] Opaque mpmc_bstack_inv.
#[global] Opaque mpmc_bstack_model.
prelude.
From zoo.common Require Import
countable.
From zoo.iris.base_logic Require Import
lib.twins.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Import
option.
From zoo_saturn Require Export
base
mpmc_bstack__code.
From zoo_saturn Require Import
mpmc_bstack__types.
From zoo Require Import
options.
Implicit Types b : bool.
Implicit Types cap sz : nat.
Implicit Types l : location.
Implicit Types v t front : val.
Implicit Types vs : list val.
Class MpmcBstackG Σ `{zoo_G : !ZooG Σ} :=
{ #[local] mpmc_bstack_G_model_G :: TwinsG Σ (leibnizO (list val))
}.
Definition mpmc_bstack_Σ :=
#[twins_Σ (leibnizO (list val))
].
#[global] Instance subG_mpmc_bstack_Σ Σ `{zoo_G : !ZooG Σ} :
subG mpmc_bstack_Σ Σ →
MpmcBstackG Σ.
Section mpmc_bstack_G.
Context `{mpmc_bstack_G : MpmcBstackG Σ}.
Record metadata :=
{ metadata_capacity : nat
; metadata_model : gname
}.
Implicit Types γ : metadata.
#[local] Instance metadata_eq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadata_countable :
Countable metadata.
#[local] Fixpoint list_to_val sz vs :=
match vs with
| [] ⇒
§Nil%V
| v :: vs ⇒
‘Cons[ #sz, v, list_to_val (sz - 1) vs ]%V
end.
#[local] Instance list_to_val_inj_similar sz :
Inj (=) (≈@{val}) (list_to_val sz).
#[local] Instance list_to_val_inj sz :
Inj (=) (=) (list_to_val sz).
Lemma list_to_val_inj' vs1 vs2 :
list_to_val (length vs1) vs1 ≈ list_to_val (length vs2) vs2 →
vs1 = vs2.
#[local] Definition model₁' γ_model vs :=
twins_twin1 γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ vs :=
model₁' γ.(metadata_model) vs.
#[local] Definition model₂' γ_model vs :=
twins_twin2 γ_model vs.
#[local] Definition model₂ γ vs :=
model₂' γ.(metadata_model) vs.
#[local] Definition inv_inner l γ : iProp Σ :=
∃ vs,
l.[front] ↦ list_to_val (length vs) vs ∗
model₂ γ vs.
#[local] Instance : CustomIpat "inv_inner" :=
" ( %vs{} & Hl_front & Hmodel₂ ) ".
Definition mpmc_bstack_inv t ι cap : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
⌜cap = γ.(metadata_capacity)⌝ ∗
⌜0 < γ.(metadata_capacity)⌝ ∗
l.[capacity] ↦□ #γ.(metadata_capacity) ∗
inv ι (inv_inner l γ).
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & -> & #Hmeta & -> & %Hcapacity & #Hl_capacity & #Hinv ) ".
Definition mpmc_bstack_model t vs : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
meta l nroot γ ∗
⌜length vs ≤ γ.(metadata_capacity)⌝ ∗
model₁ γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %l{;_} & %γ{;_} & %Heq{} & Hmeta_{} & %Hvs{} & Hmodel₁{_{}} ) ".
#[global] Instance mpmc_bstack_model_timeless t vs :
Timeless (mpmc_bstack_model t vs).
#[global] Instance mpmc_bstack_inv_persistent t ι cap :
Persistent (mpmc_bstack_inv t ι cap).
#[local] Lemma model_alloc :
⊢ |==>
∃ γ_model,
model₁' γ_model [] ∗
model₂' γ_model [].
#[local] Lemma model₁_exclusive γ vs1 vs2 :
model₁ γ vs1 -∗
model₁ γ vs2 -∗
False.
#[local] Lemma model_agree γ vs1 vs2 :
model₁ γ vs1 -∗
model₂ γ vs2 -∗
⌜vs1 = vs2⌝.
#[local] Lemma model_update {γ vs1 vs2} vs :
model₁ γ vs1 -∗
model₂ γ vs2 ==∗
model₁ γ vs ∗
model₂ γ vs.
Lemma mpmc_bstack_model_valid t ι cap vs :
mpmc_bstack_inv t ι cap -∗
mpmc_bstack_model t vs -∗
⌜length vs ≤ cap⌝.
Lemma mpmc_bstack_model_exclusive t vs1 vs2 :
mpmc_bstack_model t vs1 -∗
mpmc_bstack_model t vs2 -∗
False.
Lemma mpmc_bstack٠create𑁒spec ι (cap : Z) :
(0 < cap)%Z →
{{{
True
}}}
mpmc_bstack٠create #cap
{{{
t
, RET t;
mpmc_bstack_inv t ι ₊cap ∗
mpmc_bstack_model t []
}}}.
Lemma mpmc_bstack٠size𑁒spec t ι cap :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠size t @ ↑ι
<<<
mpmc_bstack_model t vs
| RET #(length vs);
True
>>>.
Lemma mpmc_bstack٠is_empty𑁒spec t ι cap :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠is_empty t @ ↑ι
<<<
mpmc_bstack_model t vs
| RET #(bool_decide (vs = []%list));
True
>>>.
#[local] Lemma mpmc_bstack٠push_aux_push𑁒spec t ι cap v :
⊢ (
∀ (sz : Z) front ws,
<<<
⌜sz = length ws⌝ ∗
⌜front = list_to_val (length ws) ws⌝ ∗
⌜length ws < cap⌝ ∗
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠push_aux t #sz v front @ ↑ι
<<<
∃∃ b,
⌜b = bool_decide (length vs < cap)⌝ ∗
mpmc_bstack_model t (if b then v :: vs else vs)
| RET #b;
True
>>>
) ∧ (
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠push t v @ ↑ι
<<<
∃∃ b,
⌜b = bool_decide (length vs < cap)⌝ ∗
mpmc_bstack_model t (if b then v :: vs else vs)
| RET #b;
True
>>>
).
Lemma mpmc_bstack٠push𑁒spec t ι cap v :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠push t v @ ↑ι
<<<
∃∃ b,
⌜b = bool_decide (length vs < cap)⌝ ∗
mpmc_bstack_model t (if b then v :: vs else vs)
| RET #b;
True
>>>.
Lemma mpmc_bstack٠pop𑁒spec t ι cap :
<<<
mpmc_bstack_inv t ι cap
| ∀∀ vs,
mpmc_bstack_model t vs
>>>
mpmc_bstack٠pop t @ ↑ι
<<<
mpmc_bstack_model t (tail vs)
| RET head vs;
True
>>>.
End mpmc_bstack_G.
From zoo_saturn Require
mpmc_bstack__opaque.
#[global] Opaque mpmc_bstack_inv.
#[global] Opaque mpmc_bstack_model.