Library zoo_saturn.queue_mpsc_1
Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.iris.bi.big_op.
Require Import zoo.iris.base_logic.lib.mono_list.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.base.
Require Import zoo_std.option.
Require Import zoo_std.xtchain.
Require Export zoo_saturn.queue_mpsc_1__code.
Require Import zoo_saturn.queue_mpsc_1__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type front node back new_back : location.
Implicit Type hist past nodes : list location.
Implicit Type v : val.
Implicit Type o : option val.
Implicit Type vs : list val.
Class QueueMpsc1G Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] queue_mpsc_1۰G۰history۰G :: MonoListG Σ location
; #[local] queue_mpsc_1۰G۰model۰G :: TwinsG Σ (leibnizO (list val))
}.
Definition queue_mpsc_1۰Σ :=
#[mono_list۰Σ location
; twins۰Σ (leibnizO (list val))
].
#[global] Instance subGーqueue_mpsc_1۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG queue_mpsc_1۰Σ Σ →
QueueMpsc1G Σ.
Module base.
Section queue_mpsc_1۰G.
Context `{queue_mpsc_1۰G : QueueMpsc1G Σ}.
Implicit Type t : location.
Record queue_mpsc_1۰name :=
{ queue_mpsc_1۰name۰inv : namespace
; queue_mpsc_1۰name۰history : gname
; queue_mpsc_1۰name۰model : gname
}.
Implicit Type γ : queue_mpsc_1۰name.
#[global] Instance queue_mpsc_1۰nameーeq_dec : EqDecision queue_mpsc_1۰name :=
ltac:(solve_decision).
#[global] Instance queue_mpsc_1۰nameーcountable :
Countable queue_mpsc_1۰name.
#[local] Definition history۰auth' γ_history hist :=
mono_list۰auth γ_history (DfracOwn 1) hist.
#[local] Definition history۰auth γ hist :=
history۰auth' γ.(queue_mpsc_1۰name۰history) hist.
#[local] Definition history۰at γ i node :=
mono_list۰at γ.(queue_mpsc_1۰name۰history) i node.
#[local] Definition model₁' γ_model vs :=
twins۰twin₁ γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ vs :=
model₁' γ.(queue_mpsc_1۰name۰model) vs.
#[local] Definition model₂' γ_model vs :=
twins۰twin₂ γ_model vs.
#[local] Definition model₂ γ vs :=
model₂' γ.(queue_mpsc_1۰name۰model) vs.
#[local] Definition node۰model γ node i : iProp Σ :=
node ↦ₕ Header §Node 2 ∗
history۰at γ i node.
#[local] Instance : CustomIpat "node۰model" :=
" ( #H{}_header & #Hhistory_at_{} ) ".
#[local] Definition inv۰inner t γ : iProp Σ :=
∃ hist past front nodes back vs,
⌜hist = past ++ front :: nodes⌝ ∗
⌜back ∈ hist⌝ ∗
t.[front] ↦{#1/4} #front ∗
t.[back] ↦ #back ∗
xtchain (Header §Node 2) (DfracOwn 1) hist §Null ∗
([∗ list] node; v ∈ nodes; vs, node.[data] ↦ v) ∗
history۰auth γ hist ∗
model₂ γ vs.
#[local] Instance : CustomIpat "inv۰inner" :=
" ( %hist{} & %past{} & %front{} & %nodes{} & %back{} & %vs{} & >%Hhist{} & >%Hback{} & >Ht_front & >Ht_back & >Hhist & >Hnodes & >Hhistory_auth & >Hmodel₂ ) ".
#[local] Definition inv' t γ :=
inv γ.(queue_mpsc_1۰name۰inv) (inv۰inner t γ).
Definition queue_mpsc_1۰inv t γ ι : iProp Σ :=
⌜ι = γ.(queue_mpsc_1۰name۰inv)⌝ ∗
inv' t γ.
#[local] Instance : CustomIpat "inv" :=
" ( -> & #Hinv ) ".
Definition queue_mpsc_1۰model :=
model₁.
#[local] Instance : CustomIpat "model" :=
" Hmodel₁{_{}} ".
#[local] Definition consumer₁ t front : iProp Σ :=
t.[front] ↦{#3/4} #front.
#[local] Definition consumer₂ t : iProp Σ :=
∃ front,
consumer₁ t front.
#[local] Instance : CustomIpat "consumer₂" :=
" ( %front{} & Hconsumer{_{}} ) ".
Definition queue_mpsc_1۰consumer :=
consumer₂.
#[local] Instance : CustomIpat "consumer" :=
" (:consumer₂) ".
#[global] Instance queue_mpsc_1۰modelーtimeless γ vs :
Timeless (queue_mpsc_1۰model γ vs).
#[global] Instance queue_mpsc_1۰consumerーtimeless t :
Timeless (queue_mpsc_1۰consumer t).
#[global] Instance queue_mpsc_1۰invーpersistent t γ ι :
Persistent (queue_mpsc_1۰inv t γ ι).
#[local] Lemma historyーalloc front :
⊢ |==>
∃ γ_history,
history۰auth' γ_history [front].
#[local] Lemma history۰atーget {γ hist} i node :
hist !! i = Some node →
history۰auth γ hist ⊢
history۰at γ i node.
#[local] Lemma history۰atーlookup γ hist i node :
history۰auth γ hist -∗
history۰at γ i node -∗
⌜hist !! i = Some node⌝.
#[local] Lemma historyーupdate {γ hist} node :
history۰auth γ hist ⊢ |==>
history۰auth γ (hist ++ [node]) ∗
history۰at γ (length hist) node.
#[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.
#[local] Lemma inv۰innerーhistory۰at t γ front :
inv' t γ -∗
consumer₁ t front ={⊤}=∗
∃ i,
consumer₁ t front ∗
node۰model γ front i.
Lemma queue_mpsc_1۰modelーexclusive γ vs1 vs2 :
queue_mpsc_1۰model γ vs1 -∗
queue_mpsc_1۰model γ vs2 -∗
False.
Lemma queue_mpsc_1۰consumerーexclusive t :
queue_mpsc_1۰consumer t -∗
queue_mpsc_1۰consumer t -∗
False.
Lemma queue_mpsc_1٠createーspec ι :
{{{
True
}}}
queue_mpsc_1٠create ()
{{{
t γ
, RET #t;
meta_token t ⊤ ∗
queue_mpsc_1۰inv t γ ι ∗
queue_mpsc_1۰model γ [] ∗
queue_mpsc_1۰consumer t
}}}.
#[local] Lemma queue_mpsc_1٠frontーspec t γ :
{{{
inv' t γ
}}}
(#t).{front}
{{{
front i
, RET #front;
node۰model γ front i
}}}.
#[local] Lemma backーspec t γ :
{{{
inv' t γ
}}}
(#t).{back}
{{{
back i
, RET #back;
node۰model γ back i
}}}.
Variant operation :=
| IsEmpty (Ψ : bool → iProp Σ)
| Pop (Ψ : option val → iProp Σ)
| Other.
Implicit Type op : operation.
Variant operation' :=
| IsEmpty'
| Pop'
| Other'.
#[local] Instance operation'ーeq_dec : EqDecision operation' :=
ltac:(solve_decision).
#[local] Coercion operation۰to_operation' op :=
match op with
| IsEmpty _ ⇒
IsEmpty'
| Pop _ ⇒
Pop'
| Other ⇒
Other'
end.
#[local] Definition is_empty۰au γ (Ψ : bool → iProp Σ) : iProp Σ :=
AU <{
∃∃ vs,
model₁ γ vs
}> @ ⊤ ∖ ↑γ.(queue_mpsc_1۰name۰inv), ∅ <{
model₁ γ vs
, COMM
Ψ (bool_decide (vs = []))
}>.
#[local] Definition pop۰au γ (Ψ : option val → iProp Σ) : iProp Σ :=
AU <{
∃∃ vs,
model₁ γ vs
}> @ ⊤ ∖ ↑γ.(queue_mpsc_1۰name۰inv), ∅ <{
model₁ γ (tail vs)
, COMM
Ψ (head vs)
}>.
#[local] Lemma nextーspecーaux op t γ i node :
{{{
inv' t γ ∗
history۰at γ i node ∗
( if decide (op = Other' :> operation') then True else
consumer₁ t node
) ∗
match op with
| IsEmpty Ψ ⇒
is_empty۰au γ Ψ
| Pop Ψ ⇒
pop۰au γ Ψ
| Other ⇒
True
end
}}}
(#node).{next}
{{{
res
, RET res;
( if decide (op = Other' :> operation') then True else
consumer₁ t node
) ∗
( ⌜res = §Null%V⌝ ∗
match op with
| IsEmpty Ψ ⇒
Ψ true
| Pop Ψ ⇒
Ψ None
| Other ⇒
True
end
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i ∗
match op with
| IsEmpty Ψ ⇒
Ψ false
| Pop Ψ ⇒
pop۰au γ Ψ
| Other ⇒
True
end
)
}}}.
#[local] Lemma nextーspec {t γ i} node :
{{{
inv' t γ ∗
history۰at γ i node
}}}
(#node).{next}
{{{
res
, RET res;
⌜res = §Null%V⌝
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i
}}}.
#[local] Lemma nextーspecーis_empty {t γ i node} Ψ :
{{{
inv' t γ ∗
history۰at γ i node ∗
consumer₁ t node ∗
is_empty۰au γ Ψ
}}}
(#node).{next}
{{{
res
, RET res;
consumer₁ t node ∗
( ⌜res = §Null%V⌝ ∗
Ψ true
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i ∗
Ψ false
)
}}}.
#[local] Lemma nextーspecーpop {t γ i node} Ψ :
{{{
inv' t γ ∗
history۰at γ i node ∗
consumer₁ t node ∗
pop۰au γ Ψ
}}}
(#node).{next}
{{{
res
, RET res;
consumer₁ t node ∗
( ⌜res = §Null%V⌝ ∗
Ψ None
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i ∗
pop۰au γ Ψ
)
}}}.
Lemma queue_mpsc_1٠is_emptyーspec t γ ι :
<<<
queue_mpsc_1۰inv t γ ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠is_empty #t @ ↑ι
<<<
queue_mpsc_1۰model γ vs
| RET #(bool_decide (vs = []%list));
queue_mpsc_1۰consumer t
>>>.
#[local] Lemma queue_mpsc_1٠push₁ーspec t γ i node new_back v :
<<<
inv' t γ ∗
node۰model γ node i ∗
new_back ↦ₕ Header §Node 2 ∗
new_back.[next] ↦ §Null ∗
new_back.[data] ↦ v
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠push₁ #node #new_back @ ↑γ.(queue_mpsc_1۰name۰inv)
<<<
queue_mpsc_1۰model γ (vs ++ [v])
| RET ();
∃ j,
history۰at γ j new_back
>>>.
#[local] Lemma queue_mpsc_1٠fix_backーspec t γ i back j new_back :
{{{
inv' t γ ∗
history۰at γ i back ∗
node۰model γ new_back j
}}}
queue_mpsc_1٠fix_back #t #back #new_back
{{{
RET ();
True
}}}.
Lemma queue_mpsc_1٠pushーspec t γ ι v :
<<<
queue_mpsc_1۰inv t γ ι
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠push #t v @ ↑ι
<<<
queue_mpsc_1۰model γ (vs ++ [v])
| RET ();
True
>>>.
#[local] Lemma queue_mpsc_1٠popーspecーaux t γ :
<<<
inv' t γ ∗
consumer₂ t
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpsc_1٠pop #t @ ↑γ.(queue_mpsc_1۰name۰inv)
<<<
model₁ γ (tail vs)
| RET head vs;
consumer₂ t
>>>.
Lemma queue_mpsc_1٠popーspec t γ ι :
<<<
queue_mpsc_1۰inv t γ ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠pop #t @ ↑ι
<<<
queue_mpsc_1۰model γ (tail vs)
| RET head vs;
queue_mpsc_1۰consumer t
>>>.
End queue_mpsc_1۰G.
#[global] Opaque queue_mpsc_1۰inv.
#[global] Opaque queue_mpsc_1۰model.
#[global] Opaque queue_mpsc_1۰consumer.
End base.
Require zoo_saturn.queue_mpsc_1__opaque.
Section queue_mpsc_1۰G.
Context `{queue_mpsc_1۰G : QueueMpsc1G Σ}.
Implicit Type 𝑡 : location.
Implicit Type t : val.
Definition queue_mpsc_1۰inv t ι : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.queue_mpsc_1۰inv 𝑡 γ ι.
#[local] Instance : CustomIpat "inv" :=
" ( %𝑡{} & %γ{} & {%Heq{};->} & #Hmeta{_{}} & Hinv{_{}} ) ".
Definition queue_mpsc_1۰model t vs : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.queue_mpsc_1۰model γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %𝑡{} & %γ{} & {%Heq{};->} & #Hmeta{_{}} & Hmodel{_{}} ) ".
Definition queue_mpsc_1۰consumer t : iProp Σ :=
∃ 𝑡,
⌜t = #𝑡⌝ ∗
base.queue_mpsc_1۰consumer 𝑡.
#[local] Instance : CustomIpat "consumer" :=
" ( %𝑡{} & {%Heq{};->} & Hconsumer{_{}} ) ".
#[global] Instance queue_mpsc_1۰modelーtimeless t vs :
Timeless (queue_mpsc_1۰model t vs).
#[global] Instance queue_mpsc_1۰consumerーtimeless t :
Timeless (queue_mpsc_1۰consumer t ).
#[global] Instance queue_mpsc_1۰invーpersistent t ι :
Persistent (queue_mpsc_1۰inv t ι).
Lemma queue_mpsc_1۰modelーexclusive t vs1 vs2 :
queue_mpsc_1۰model t vs1 -∗
queue_mpsc_1۰model t vs2 -∗
False.
Lemma queue_mpsc_1۰consumerーexclusive t :
queue_mpsc_1۰consumer t -∗
queue_mpsc_1۰consumer t -∗
False.
Lemma queue_mpsc_1٠createーspec ι :
{{{
True
}}}
queue_mpsc_1٠create ()
{{{
t
, RET t;
queue_mpsc_1۰inv t ι ∗
queue_mpsc_1۰model t [] ∗
queue_mpsc_1۰consumer t
}}}.
Lemma queue_mpsc_1٠is_emptyーspec t ι :
<<<
queue_mpsc_1۰inv t ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model t vs
>>>
queue_mpsc_1٠is_empty t @ ↑ι
<<<
queue_mpsc_1۰model t vs
| RET #(bool_decide (vs = []%list));
queue_mpsc_1۰consumer t
>>>.
Lemma queue_mpsc_1٠pushーspec t ι v :
<<<
queue_mpsc_1۰inv t ι
| ∀∀ vs,
queue_mpsc_1۰model t vs
>>>
queue_mpsc_1٠push t v @ ↑ι
<<<
queue_mpsc_1۰model t (vs ++ [v])
| RET ();
True
>>>.
Lemma queue_mpsc_1٠popーspec t ι :
<<<
queue_mpsc_1۰inv t ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model t vs
>>>
queue_mpsc_1٠pop t @ ↑ι
<<<
queue_mpsc_1۰model t (tail vs)
| RET head vs;
queue_mpsc_1۰consumer t
>>>.
End queue_mpsc_1۰G.
#[global] Opaque queue_mpsc_1۰inv.
#[global] Opaque queue_mpsc_1۰model.
#[global] Opaque queue_mpsc_1۰consumer.
Require Import zoo.common.countable.
Require Import zoo.iris.bi.big_op.
Require Import zoo.iris.base_logic.lib.mono_list.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.base.
Require Import zoo_std.option.
Require Import zoo_std.xtchain.
Require Export zoo_saturn.queue_mpsc_1__code.
Require Import zoo_saturn.queue_mpsc_1__types.
Require Import zoo.options.
Implicit Type b : bool.
Implicit Type front node back new_back : location.
Implicit Type hist past nodes : list location.
Implicit Type v : val.
Implicit Type o : option val.
Implicit Type vs : list val.
Class QueueMpsc1G Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] queue_mpsc_1۰G۰history۰G :: MonoListG Σ location
; #[local] queue_mpsc_1۰G۰model۰G :: TwinsG Σ (leibnizO (list val))
}.
Definition queue_mpsc_1۰Σ :=
#[mono_list۰Σ location
; twins۰Σ (leibnizO (list val))
].
#[global] Instance subGーqueue_mpsc_1۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG queue_mpsc_1۰Σ Σ →
QueueMpsc1G Σ.
Module base.
Section queue_mpsc_1۰G.
Context `{queue_mpsc_1۰G : QueueMpsc1G Σ}.
Implicit Type t : location.
Record queue_mpsc_1۰name :=
{ queue_mpsc_1۰name۰inv : namespace
; queue_mpsc_1۰name۰history : gname
; queue_mpsc_1۰name۰model : gname
}.
Implicit Type γ : queue_mpsc_1۰name.
#[global] Instance queue_mpsc_1۰nameーeq_dec : EqDecision queue_mpsc_1۰name :=
ltac:(solve_decision).
#[global] Instance queue_mpsc_1۰nameーcountable :
Countable queue_mpsc_1۰name.
#[local] Definition history۰auth' γ_history hist :=
mono_list۰auth γ_history (DfracOwn 1) hist.
#[local] Definition history۰auth γ hist :=
history۰auth' γ.(queue_mpsc_1۰name۰history) hist.
#[local] Definition history۰at γ i node :=
mono_list۰at γ.(queue_mpsc_1۰name۰history) i node.
#[local] Definition model₁' γ_model vs :=
twins۰twin₁ γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ vs :=
model₁' γ.(queue_mpsc_1۰name۰model) vs.
#[local] Definition model₂' γ_model vs :=
twins۰twin₂ γ_model vs.
#[local] Definition model₂ γ vs :=
model₂' γ.(queue_mpsc_1۰name۰model) vs.
#[local] Definition node۰model γ node i : iProp Σ :=
node ↦ₕ Header §Node 2 ∗
history۰at γ i node.
#[local] Instance : CustomIpat "node۰model" :=
" ( #H{}_header & #Hhistory_at_{} ) ".
#[local] Definition inv۰inner t γ : iProp Σ :=
∃ hist past front nodes back vs,
⌜hist = past ++ front :: nodes⌝ ∗
⌜back ∈ hist⌝ ∗
t.[front] ↦{#1/4} #front ∗
t.[back] ↦ #back ∗
xtchain (Header §Node 2) (DfracOwn 1) hist §Null ∗
([∗ list] node; v ∈ nodes; vs, node.[data] ↦ v) ∗
history۰auth γ hist ∗
model₂ γ vs.
#[local] Instance : CustomIpat "inv۰inner" :=
" ( %hist{} & %past{} & %front{} & %nodes{} & %back{} & %vs{} & >%Hhist{} & >%Hback{} & >Ht_front & >Ht_back & >Hhist & >Hnodes & >Hhistory_auth & >Hmodel₂ ) ".
#[local] Definition inv' t γ :=
inv γ.(queue_mpsc_1۰name۰inv) (inv۰inner t γ).
Definition queue_mpsc_1۰inv t γ ι : iProp Σ :=
⌜ι = γ.(queue_mpsc_1۰name۰inv)⌝ ∗
inv' t γ.
#[local] Instance : CustomIpat "inv" :=
" ( -> & #Hinv ) ".
Definition queue_mpsc_1۰model :=
model₁.
#[local] Instance : CustomIpat "model" :=
" Hmodel₁{_{}} ".
#[local] Definition consumer₁ t front : iProp Σ :=
t.[front] ↦{#3/4} #front.
#[local] Definition consumer₂ t : iProp Σ :=
∃ front,
consumer₁ t front.
#[local] Instance : CustomIpat "consumer₂" :=
" ( %front{} & Hconsumer{_{}} ) ".
Definition queue_mpsc_1۰consumer :=
consumer₂.
#[local] Instance : CustomIpat "consumer" :=
" (:consumer₂) ".
#[global] Instance queue_mpsc_1۰modelーtimeless γ vs :
Timeless (queue_mpsc_1۰model γ vs).
#[global] Instance queue_mpsc_1۰consumerーtimeless t :
Timeless (queue_mpsc_1۰consumer t).
#[global] Instance queue_mpsc_1۰invーpersistent t γ ι :
Persistent (queue_mpsc_1۰inv t γ ι).
#[local] Lemma historyーalloc front :
⊢ |==>
∃ γ_history,
history۰auth' γ_history [front].
#[local] Lemma history۰atーget {γ hist} i node :
hist !! i = Some node →
history۰auth γ hist ⊢
history۰at γ i node.
#[local] Lemma history۰atーlookup γ hist i node :
history۰auth γ hist -∗
history۰at γ i node -∗
⌜hist !! i = Some node⌝.
#[local] Lemma historyーupdate {γ hist} node :
history۰auth γ hist ⊢ |==>
history۰auth γ (hist ++ [node]) ∗
history۰at γ (length hist) node.
#[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.
#[local] Lemma inv۰innerーhistory۰at t γ front :
inv' t γ -∗
consumer₁ t front ={⊤}=∗
∃ i,
consumer₁ t front ∗
node۰model γ front i.
Lemma queue_mpsc_1۰modelーexclusive γ vs1 vs2 :
queue_mpsc_1۰model γ vs1 -∗
queue_mpsc_1۰model γ vs2 -∗
False.
Lemma queue_mpsc_1۰consumerーexclusive t :
queue_mpsc_1۰consumer t -∗
queue_mpsc_1۰consumer t -∗
False.
Lemma queue_mpsc_1٠createーspec ι :
{{{
True
}}}
queue_mpsc_1٠create ()
{{{
t γ
, RET #t;
meta_token t ⊤ ∗
queue_mpsc_1۰inv t γ ι ∗
queue_mpsc_1۰model γ [] ∗
queue_mpsc_1۰consumer t
}}}.
#[local] Lemma queue_mpsc_1٠frontーspec t γ :
{{{
inv' t γ
}}}
(#t).{front}
{{{
front i
, RET #front;
node۰model γ front i
}}}.
#[local] Lemma backーspec t γ :
{{{
inv' t γ
}}}
(#t).{back}
{{{
back i
, RET #back;
node۰model γ back i
}}}.
Variant operation :=
| IsEmpty (Ψ : bool → iProp Σ)
| Pop (Ψ : option val → iProp Σ)
| Other.
Implicit Type op : operation.
Variant operation' :=
| IsEmpty'
| Pop'
| Other'.
#[local] Instance operation'ーeq_dec : EqDecision operation' :=
ltac:(solve_decision).
#[local] Coercion operation۰to_operation' op :=
match op with
| IsEmpty _ ⇒
IsEmpty'
| Pop _ ⇒
Pop'
| Other ⇒
Other'
end.
#[local] Definition is_empty۰au γ (Ψ : bool → iProp Σ) : iProp Σ :=
AU <{
∃∃ vs,
model₁ γ vs
}> @ ⊤ ∖ ↑γ.(queue_mpsc_1۰name۰inv), ∅ <{
model₁ γ vs
, COMM
Ψ (bool_decide (vs = []))
}>.
#[local] Definition pop۰au γ (Ψ : option val → iProp Σ) : iProp Σ :=
AU <{
∃∃ vs,
model₁ γ vs
}> @ ⊤ ∖ ↑γ.(queue_mpsc_1۰name۰inv), ∅ <{
model₁ γ (tail vs)
, COMM
Ψ (head vs)
}>.
#[local] Lemma nextーspecーaux op t γ i node :
{{{
inv' t γ ∗
history۰at γ i node ∗
( if decide (op = Other' :> operation') then True else
consumer₁ t node
) ∗
match op with
| IsEmpty Ψ ⇒
is_empty۰au γ Ψ
| Pop Ψ ⇒
pop۰au γ Ψ
| Other ⇒
True
end
}}}
(#node).{next}
{{{
res
, RET res;
( if decide (op = Other' :> operation') then True else
consumer₁ t node
) ∗
( ⌜res = §Null%V⌝ ∗
match op with
| IsEmpty Ψ ⇒
Ψ true
| Pop Ψ ⇒
Ψ None
| Other ⇒
True
end
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i ∗
match op with
| IsEmpty Ψ ⇒
Ψ false
| Pop Ψ ⇒
pop۰au γ Ψ
| Other ⇒
True
end
)
}}}.
#[local] Lemma nextーspec {t γ i} node :
{{{
inv' t γ ∗
history۰at γ i node
}}}
(#node).{next}
{{{
res
, RET res;
⌜res = §Null%V⌝
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i
}}}.
#[local] Lemma nextーspecーis_empty {t γ i node} Ψ :
{{{
inv' t γ ∗
history۰at γ i node ∗
consumer₁ t node ∗
is_empty۰au γ Ψ
}}}
(#node).{next}
{{{
res
, RET res;
consumer₁ t node ∗
( ⌜res = §Null%V⌝ ∗
Ψ true
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i ∗
Ψ false
)
}}}.
#[local] Lemma nextーspecーpop {t γ i node} Ψ :
{{{
inv' t γ ∗
history۰at γ i node ∗
consumer₁ t node ∗
pop۰au γ Ψ
}}}
(#node).{next}
{{{
res
, RET res;
consumer₁ t node ∗
( ⌜res = §Null%V⌝ ∗
Ψ None
∨ ∃ node',
⌜res = #node'⌝ ∗
node۰model γ node' ˖i ∗
pop۰au γ Ψ
)
}}}.
Lemma queue_mpsc_1٠is_emptyーspec t γ ι :
<<<
queue_mpsc_1۰inv t γ ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠is_empty #t @ ↑ι
<<<
queue_mpsc_1۰model γ vs
| RET #(bool_decide (vs = []%list));
queue_mpsc_1۰consumer t
>>>.
#[local] Lemma queue_mpsc_1٠push₁ーspec t γ i node new_back v :
<<<
inv' t γ ∗
node۰model γ node i ∗
new_back ↦ₕ Header §Node 2 ∗
new_back.[next] ↦ §Null ∗
new_back.[data] ↦ v
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠push₁ #node #new_back @ ↑γ.(queue_mpsc_1۰name۰inv)
<<<
queue_mpsc_1۰model γ (vs ++ [v])
| RET ();
∃ j,
history۰at γ j new_back
>>>.
#[local] Lemma queue_mpsc_1٠fix_backーspec t γ i back j new_back :
{{{
inv' t γ ∗
history۰at γ i back ∗
node۰model γ new_back j
}}}
queue_mpsc_1٠fix_back #t #back #new_back
{{{
RET ();
True
}}}.
Lemma queue_mpsc_1٠pushーspec t γ ι v :
<<<
queue_mpsc_1۰inv t γ ι
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠push #t v @ ↑ι
<<<
queue_mpsc_1۰model γ (vs ++ [v])
| RET ();
True
>>>.
#[local] Lemma queue_mpsc_1٠popーspecーaux t γ :
<<<
inv' t γ ∗
consumer₂ t
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpsc_1٠pop #t @ ↑γ.(queue_mpsc_1۰name۰inv)
<<<
model₁ γ (tail vs)
| RET head vs;
consumer₂ t
>>>.
Lemma queue_mpsc_1٠popーspec t γ ι :
<<<
queue_mpsc_1۰inv t γ ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model γ vs
>>>
queue_mpsc_1٠pop #t @ ↑ι
<<<
queue_mpsc_1۰model γ (tail vs)
| RET head vs;
queue_mpsc_1۰consumer t
>>>.
End queue_mpsc_1۰G.
#[global] Opaque queue_mpsc_1۰inv.
#[global] Opaque queue_mpsc_1۰model.
#[global] Opaque queue_mpsc_1۰consumer.
End base.
Require zoo_saturn.queue_mpsc_1__opaque.
Section queue_mpsc_1۰G.
Context `{queue_mpsc_1۰G : QueueMpsc1G Σ}.
Implicit Type 𝑡 : location.
Implicit Type t : val.
Definition queue_mpsc_1۰inv t ι : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.queue_mpsc_1۰inv 𝑡 γ ι.
#[local] Instance : CustomIpat "inv" :=
" ( %𝑡{} & %γ{} & {%Heq{};->} & #Hmeta{_{}} & Hinv{_{}} ) ".
Definition queue_mpsc_1۰model t vs : iProp Σ :=
∃ 𝑡 γ,
⌜t = #𝑡⌝ ∗
𝑡 ↪ γ ∗
base.queue_mpsc_1۰model γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %𝑡{} & %γ{} & {%Heq{};->} & #Hmeta{_{}} & Hmodel{_{}} ) ".
Definition queue_mpsc_1۰consumer t : iProp Σ :=
∃ 𝑡,
⌜t = #𝑡⌝ ∗
base.queue_mpsc_1۰consumer 𝑡.
#[local] Instance : CustomIpat "consumer" :=
" ( %𝑡{} & {%Heq{};->} & Hconsumer{_{}} ) ".
#[global] Instance queue_mpsc_1۰modelーtimeless t vs :
Timeless (queue_mpsc_1۰model t vs).
#[global] Instance queue_mpsc_1۰consumerーtimeless t :
Timeless (queue_mpsc_1۰consumer t ).
#[global] Instance queue_mpsc_1۰invーpersistent t ι :
Persistent (queue_mpsc_1۰inv t ι).
Lemma queue_mpsc_1۰modelーexclusive t vs1 vs2 :
queue_mpsc_1۰model t vs1 -∗
queue_mpsc_1۰model t vs2 -∗
False.
Lemma queue_mpsc_1۰consumerーexclusive t :
queue_mpsc_1۰consumer t -∗
queue_mpsc_1۰consumer t -∗
False.
Lemma queue_mpsc_1٠createーspec ι :
{{{
True
}}}
queue_mpsc_1٠create ()
{{{
t
, RET t;
queue_mpsc_1۰inv t ι ∗
queue_mpsc_1۰model t [] ∗
queue_mpsc_1۰consumer t
}}}.
Lemma queue_mpsc_1٠is_emptyーspec t ι :
<<<
queue_mpsc_1۰inv t ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model t vs
>>>
queue_mpsc_1٠is_empty t @ ↑ι
<<<
queue_mpsc_1۰model t vs
| RET #(bool_decide (vs = []%list));
queue_mpsc_1۰consumer t
>>>.
Lemma queue_mpsc_1٠pushーspec t ι v :
<<<
queue_mpsc_1۰inv t ι
| ∀∀ vs,
queue_mpsc_1۰model t vs
>>>
queue_mpsc_1٠push t v @ ↑ι
<<<
queue_mpsc_1۰model t (vs ++ [v])
| RET ();
True
>>>.
Lemma queue_mpsc_1٠popーspec t ι :
<<<
queue_mpsc_1۰inv t ι ∗
queue_mpsc_1۰consumer t
| ∀∀ vs,
queue_mpsc_1۰model t vs
>>>
queue_mpsc_1٠pop t @ ↑ι
<<<
queue_mpsc_1۰model t (tail vs)
| RET head vs;
queue_mpsc_1۰consumer t
>>>.
End queue_mpsc_1۰G.
#[global] Opaque queue_mpsc_1۰inv.
#[global] Opaque queue_mpsc_1۰model.
#[global] Opaque queue_mpsc_1۰consumer.