Library zoo_saturn.queue_mpmc_2
Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.common.relations.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.iris.base_logic.lib.auth_mono.
Require Import zoo.iris.base_logic.lib.auth_nat_max.
Require Import zoo.base.
Require Import zoo.program_logic.prophet_bool.
Require Import zoo_std.option.
Require Export zoo_saturn.queue_mpmc_2__code.
Require Import zoo_saturn.queue_mpmc_2__types.
Require Import zoo.options.
Implicit Type strong : bool.
Implicit Type l back back_prev : location.
Implicit Type backs : gmap location nat.
Implicit Type v w t pref suff 𝑚𝑜𝑣𝑒 : val.
Implicit Type o : option val.
Implicit Type vs vs_front vs_back move : list val.
Variant emptiness :=
| Empty
| Nonempty.
Implicit Type empty : emptiness.
#[local] Instance emptinessーinhabited : Inhabited emptiness :=
populate Empty.
#[local] Instance emptinessーeq_dec : EqDecision emptiness :=
ltac:(solve_decision).
Variant status :=
| Stable empty
| Unstable back move.
Implicit Type status : status.
#[local] Instance statusーinhabited : Inhabited status :=
populate (Stable inhabitant).
#[local] Instance statusーeq_dec : EqDecision status :=
ltac:(solve_decision).
Record state :=
{ state۰backs : gmap location nat
; state۰index : nat
; state۰status : status
}.
Implicit Type state : state.
#[local] Definition state۰with_status state status :=
{|state۰backs := state.(state۰backs)
; state۰index := state.(state۰index)
; state۰status := status
|}.
Definition state۰wf backs i :=
map_Forall (λ _ i_back, i_back ≤ i) backs.
#[local] Definition state۰le state1 state2 :=
state1.(state۰backs) ⊆ state2.(state۰backs) ∧
state1.(state۰index) ≤ state2.(state۰index).
#[local] Instance stateーinhabited : Inhabited state :=
populate
{|state۰backs := inhabitant
; state۰index := inhabitant
; state۰status := inhabitant
|}.
#[local] Instance state۰leーreflexive :
Reflexive state۰le.
#[local] Instance state۰leーtransitive :
Transitive state۰le.
Variant step : relation state :=
| stepーempty state1 state2 :
state1.(state۰status) = Stable Nonempty →
state2 = state۰with_status state1 (Stable Empty) →
step state1 state2
| stepーdestabilize state1 state2 back move :
state1.(state۰status) = Stable Empty →
state2 = state۰with_status state1 (Unstable back move) →
step state1 state2
| stepーstabilize state1 state2 back move :
state1.(state۰status) = Unstable back move →
state1.(state۰backs) !! back = None →
state2 =
{|state۰backs := <[back := state1.(state۰index) + length move]> state1.(state۰backs)
; state۰index := state1.(state۰index) + length move
; state۰status := Stable Nonempty
|} →
step state1 state2.
#[local] Hint Constructors step : core.
#[local] Definition steps :=
rtc step.
#[local] Lemma stepーmono state1 state2 :
step state1 state2 →
state۰le state1 state2.
#[local] Lemma stepsーmono state1 state2 :
steps state1 state2 →
state۰le state1 state2.
Class QueueMpmc2G Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] queue_mpmc_2۰G۰model۰G :: TwinsG Σ (leibnizO (list val))
; #[local] queue_mpmc_2۰G۰state۰G :: AuthMonoG (A := leibnizO state) Σ step
; #[local] queue_mpmc_2۰G۰front۰G :: AuthNatMaxG Σ
}.
Definition queue_mpmc_2۰Σ :=
#[twins۰Σ (leibnizO (list val))
; auth_mono۰Σ (A := leibnizO state) step
; auth_nat_max۰Σ
].
#[global] Instance subGーqueue_mpmc_2۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG queue_mpmc_2۰Σ Σ →
QueueMpmc2G Σ.
#[local] Fixpoint suffix۰to_val (i : nat) vs : val :=
match vs with
| [] ⇒
‘Front[ #i ]
| v :: vs ⇒
‘Cons[ #i, v, suffix۰to_val ˖i vs ]
end.
#[local] Lemma suffix۰to_valーgenerative i1 vs1 i2 vs2 :
suffix۰to_val i1 vs1 ≈ suffix۰to_val i2 vs2 →
suffix۰to_val i1 vs1 = suffix۰to_val i2 vs2.
#[local] Instance suffix۰to_valーinj2 :
Inj2 (=) (=) (=) suffix۰to_val.
#[local] Instance suffix۰to_valーinj2' :
Inj2 (=) (=) (≈) suffix۰to_val.
#[local] Fixpoint prefix۰to_val (i : nat) back vs : val :=
match vs with
| [] ⇒
#back
| v :: vs ⇒
‘Snoc[ #⁺(i + ˖(length vs)), v, prefix۰to_val i back vs ]
end.
#[local] Lemma prefix۰to_valーgenerative i1 back1 vs1 i2 back2 vs2 :
prefix۰to_val i1 back1 vs1 ≈ prefix۰to_val i2 back2 vs2 →
prefix۰to_val i1 back1 vs1 = prefix۰to_val i2 back2 vs2.
#[local] Lemma prefix۰to_valーinj i1 back1 vs1 i2 back2 vs2 :
prefix۰to_val i1 back1 vs1 = prefix۰to_val i2 back2 vs2 →
(vs1 ≠ [] → i1 = i2) ∧
back1 = back2 ∧
vs1 = vs2.
#[local] Lemma prefix۰to_valーinj' i1 back1 vs1 i2 back2 vs2 :
prefix۰to_val i1 back1 vs1 ≈ prefix۰to_val i2 back2 vs2 →
(vs1 ≠ [] → i1 = i2) ∧
back1 = back2 ∧
vs1 = vs2.
Section queue_mpmc_2۰G.
Context `{queue_mpmc_2۰G : QueueMpmc2G Σ}.
Record metadata :=
{ metadata۰inv : namespace
; metadata۰model : gname
; metadata۰state : gname
; metadata۰front : gname
}.
Implicit Type γ : metadata.
#[local] Instance metadataーeq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadataーcountable :
Countable metadata.
#[local] Definition model₁' γ_model vs :=
twins۰twin₁ γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ :=
model₁' γ.(metadata۰model).
#[local] Definition model₂' γ_model vs :=
twins۰twin₂ γ_model vs.
#[local] Definition model₂ γ :=
model₂' γ.(metadata۰model).
#[local] Definition state۰auth' γ_state backs i status : iProp Σ :=
auth_mono۰auth _ γ_state (DfracOwn 1)
{|state۰backs := backs
; state۰index := i
; state۰status := status
|} ∗
⌜state۰wf backs i⌝.
#[local] Instance : CustomIpat "state۰auth" :=
" ( Hauth & %Hwf ) ".
#[local] Definition state۰auth γ backs i status :=
state۰auth' γ.(metadata۰state) backs i status.
#[local] Definition state۰lb γ backs i status :=
auth_mono۰lb _ γ.(metadata۰state)
{|state۰backs := backs
; state۰index := i
; state۰status := status
|}.
#[local] Definition state۰seen γ back i_prev back_prev move : iProp Σ :=
∃ backs,
state۰lb γ backs i_prev (Unstable back move) ∗
⌜backs !! back_prev = Some i_prev⌝.
#[local] Instance : CustomIpat "state۰seen" :=
" ( %backs{} & #Hstate_lb & %Hbacks{}_lookup ) ".
#[local] Definition state۰at γ back i_back : iProp Σ :=
∃ backs i status,
state۰lb γ backs i status ∗
⌜backs !! back = Some i_back⌝ ∗
⌜i_back ≤ i⌝.
#[local] Instance : CustomIpat "state۰at" :=
" ( %backs{} & %i{} & %status{} & #Hstate_lb{_{}} & %Hbacks{}_lookup & %Hi{} ) ".
#[local] Definition front۰auth' γ_front i :=
auth_nat_max۰auth γ_front (DfracOwn 1) i.
#[local] Definition front۰auth γ i :=
front۰auth' γ.(metadata۰front) i.
#[local] Definition front۰lb γ i :=
auth_nat_max۰lb γ.(metadata۰front) i.
#[local] Definition move۰model₁ 𝑚𝑜𝑣𝑒 i_prev back_prev move : iProp Σ :=
⌜𝑚𝑜𝑣𝑒 = §Used%V⌝
∨ ⌜𝑚𝑜𝑣𝑒 = prefix۰to_val i_prev back_prev move⌝ ∗
⌜0 < length move⌝ ∗
back_prev ↦ₕ Header §Back 2.
#[local] Instance : CustomIpat "move۰model₁" :=
" [ -> | ( -> & % & #Hback{}_prev_header ) ] ".
#[local] Definition move۰model₂ γ back 𝑚𝑜𝑣𝑒 : iProp Σ :=
∃ backs_prev i_prev back_prev move,
state۰lb γ backs_prev i_prev (Unstable back move) ∗
move۰model₁ 𝑚𝑜𝑣𝑒 i_prev back_prev move.
#[local] Instance : CustomIpat "move۰model₂" :=
" ( %backs{}_prev & %i{}_prev{_{!}} & %back{}_prev{_{!}} & %move{}{_{!}} & #Hstate_lb_unstable{_{}} & H𝑚𝑜𝑣𝑒{} ) ".
#[local] Definition back۰model₁ back (i : nat) : iProp Σ :=
back ↦ₕ Header §Back 2 ∗
back.[index] ↦□ #i.
#[local] Instance : CustomIpat "back۰model₁" :=
" ( { {!} _ ; #Hback{}_header ; #Hback_header } & #Hback{}_index{_{!}} ) ".
#[local] Definition back۰model₂ back (i : nat) 𝑚𝑜𝑣𝑒 : iProp Σ :=
back۰model₁ back i ∗
back.[move] ↦ 𝑚𝑜𝑣𝑒.
#[local] Instance : CustomIpat "back۰model₂" :=
" ( { {only_move} _ ; (:back۰model₁ // /!/) } & Hback{}_move{_{suff}} ) ".
#[local] Definition back۰model₃ γ back i : iProp Σ :=
∃ 𝑚𝑜𝑣𝑒,
back۰model₂ back i 𝑚𝑜𝑣𝑒 ∗
move۰model₂ γ back 𝑚𝑜𝑣𝑒.
#[local] Instance : CustomIpat "back۰model₃" :=
" ( %𝑚𝑜𝑣𝑒{} & (:back۰model₂) & H𝑚𝑜𝑣𝑒{} ) ".
#[local] Definition inv۰status۰stable γ i vs_front i_back back vs_back vs empty : iProp Σ :=
⌜i_back = i⌝ ∗
⌜vs = vs_front ++ reverse vs_back⌝ ∗
⌜if empty then vs_front = [] else 0 < length vs_front⌝ ∗
state۰at γ back i_back.
#[local] Instance : CustomIpat "inv۰status۰stable" :=
" ( {>;}-> & {>;}%Hvs{} & {>;}{{empty}->;%Hempty{};%Hempty} & {>;}#Hstate_at{_{}} ) ".
#[local] Definition inv۰status۰unstable strong γ backs i vs_front i_back back vs_back vs back_ move : iProp Σ :=
∃ back_prev,
⌜back_ = back⌝ ∗
⌜i_back = (i + length move)%nat⌝ ∗
⌜vs_front = []⌝ ∗
⌜vs_back = []⌝ ∗
⌜vs = reverse move⌝ ∗
⌜0 < length move⌝ ∗
state۰at γ back_prev i ∗
back۰model₂ back i_back (prefix۰to_val i back_prev move) ∗
if strong then
⌜backs !! back = None⌝ ∗
back_prev ↦ₕ Header §Back 2
else
True.
#[local] Instance : CustomIpat "inv۰status۰unstable" :=
" ( %back{}_prev & {>;}-> & {>;}-> & {>;}{{lazy}%Hvs_front{};->} & {>;}{{lazy}%Hvs_back{};->} & {>;}-> & {>;}% & {>;}#Hstate_at_back{}_prev & Hback{} & { {strong} %Hbacks{}_lookup & #Hback{}_prev_header ; _ } ) ".
#[local] Definition inv۰status strong γ backs i status vs_front i_back back vs_back vs : iProp Σ :=
match status with
| Stable empty ⇒
inv۰status۰stable γ i vs_front i_back back vs_back vs empty
| Unstable back_ move ⇒
inv۰status۰unstable strong γ backs i vs_front i_back back vs_back vs back_ move
end.
#[local] Definition inv۰inner strong l γ : iProp Σ :=
∃ backs i status i_front vs_front i_back back vs_back vs,
l.[front] ↦ suffix۰to_val i_front vs_front ∗
front۰auth γ i_front ∗
l.[back] ↦ prefix۰to_val i_back back vs_back ∗
([∗ map] back ↦ i ∈ backs, back۰model₃ γ back i) ∗
model₂ γ vs ∗
state۰auth γ backs i status ∗
⌜(i_front + length vs_front)%nat = ˖i⌝ ∗
inv۰status strong γ backs i status vs_front i_back back vs_back vs.
#[local] Instance : CustomIpat "inv۰inner" :=
" ( %backs{} & %i{} & %status{} & %i_front{} & %vs_front{} & %i_back{} & %back{} & %vs_back{} & %vs{} & Hl_front & {>;}Hfront_auth & Hl_back & Hbacks & Hmodel₂ & {>;}Hstate_auth & {>;}%Hfront{} & Hstatus ) ".
#[local] Definition inv' l γ : iProp Σ :=
inv γ.(metadata۰inv) (inv۰inner false l γ).
Definition queue_mpmc_2۰inv t ι : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
⌜ι = γ.(metadata۰inv)⌝ ∗
l ↪ γ ∗
inv' l γ.
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & -> & -> & #Hmeta & #Hinv ) ".
Definition queue_mpmc_2۰model t vs : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
l ↪ γ ∗
model₁ γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %l{;_} & %γ{;_} & %Heq{} & #Hmeta_{} & Hmodel₁{_{}} ) ".
#[local] Instance state۰authーtimeless γ backs i status :
Timeless (state۰auth γ backs i status).
#[local] Instance state۰atーtimeless γ back i_back :
Timeless (state۰at γ back i_back).
#[global] Instance queue_mpmc_2۰modelーtimeless t vs :
Timeless (queue_mpmc_2۰model t vs).
#[local] Instance state۰atーpersistent γ back i_back :
Persistent (state۰at γ back i_back).
#[global] Instance queue_mpmc_2۰invーpersistent t ι :
Persistent (queue_mpmc_2۰inv t ι).
#[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 stateーalloc back :
⊢ |==>
∃ γ_state,
state۰auth' γ_state ∅ 0 (Unstable back []).
#[local] Lemma state۰authーwf γ backs i status :
state۰auth γ backs i status ⊢
⌜state۰wf backs i⌝.
#[local] Lemma state۰lbーget γ backs i status :
state۰auth γ backs i status ⊢
state۰lb γ backs i status.
#[local] Lemma state۰atーget {γ backs i status} back i_back :
backs !! back = Some i_back →
state۰auth γ backs i status ⊢
state۰at γ back i_back.
#[local] Lemma state۰lbーvalid γ backs1 i1 status1 backs2 i2 status2 :
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 status2 -∗
⌜backs2 ⊆ backs1⌝ ∗
⌜i2 ≤ i1⌝.
#[local] Lemma state۰lbーvalidーUnstable γ backs1 i1 status1 backs2 i2 back2 move2 :
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 (Unstable back2 move2) -∗
⌜backs1 = backs2⌝ ∗
⌜i1 = i2⌝ ∗
⌜status1 = Unstable back2 move2⌝
∨ ⌜backs1 !! back2 = Some (i2 + length move2)%nat⌝ ∗
⌜i2 + length move2 ≤ i1⌝ ∗
state۰at γ back2 (i2 + length move2).
#[local] Lemma state۰lbーlookup {γ backs1 i1 status1 backs2 i2 status2} back i_back :
backs2 !! back = Some i_back →
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 status2 -∗
⌜backs1 !! back = Some i_back⌝.
#[local] Lemma state۰seenーvalid γ backs i status back i_prev back_prev move :
state۰auth γ backs i status -∗
state۰seen γ back i_prev back_prev move -∗
⌜backs !! back_prev = Some i_prev⌝ ∗
( ⌜i = i_prev⌝ ∗
⌜status = Unstable back move⌝
∨ ⌜backs !! back = Some (i_prev + length move)%nat⌝ ∗
⌜i_prev + length move ≤ i⌝ ∗
state۰at γ back (i_prev + length move)
).
#[local] Lemma state۰atーvalid γ backs i status back i_back :
state۰auth γ backs i status -∗
state۰at γ back i_back -∗
⌜backs !! back = Some i_back⌝ ∗
⌜i_back ≤ i⌝.
#[local] Lemma state۰lbーstabilized γ backs1 i1 status1 backs2 i2 back2 move2 :
( status1 ≠ Unstable back2 move2
∨ i2 + length move2 ≤ i1 ∧
0 < length move2
) →
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 (Unstable back2 move2) -∗
⌜backs1 !! back2 = Some (i2 + length move2)%nat⌝ ∗
state۰at γ back2 (i2 + length move2).
#[local] Lemma state۰lbーunstabilized γ backs1 i1 status1 backs2 i2 back2 move2 :
i1 < i2 + length move2 →
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 (Unstable back2 move2) -∗
⌜backs1 = backs2⌝ ∗
⌜i1 = i2⌝ ∗
⌜status1 = Unstable back2 move2⌝.
#[local] Lemma stateーstabilize γ backs i back move :
backs !! back = None →
state۰auth γ backs i (Unstable back move) ⊢ |==>
state۰auth γ (<[back := i + length move]> backs) (i + length move) (Stable Nonempty) ∗
state۰lb γ (<[back := i + length move]> backs) (i + length move) (Stable Nonempty) ∗
state۰at γ back (i + length move).
#[local] Lemma stateーempty γ backs i :
state۰auth γ backs i (Stable Nonempty) ⊢ |==>
state۰auth γ backs i (Stable Empty).
#[local] Lemma stateーdestabilize {γ backs i} back move :
state۰auth γ backs i (Stable Empty) ⊢ |==>
state۰auth γ backs i (Unstable back move).
#[local] Lemma frontーalloc :
⊢ |==>
∃ γ_front,
front۰auth' γ_front 1.
#[local] Lemma front۰lbーget γ i :
front۰auth γ i ⊢
front۰lb γ i.
#[local] Lemma front۰lbーvalid γ i1 i2 :
front۰auth γ i1 -∗
front۰lb γ i2 -∗
⌜i2 ≤ i1⌝.
#[local] Lemma frontーupdate γ i :
front۰auth γ i ⊢ |==>
front۰auth γ ˖i.
Opaque state۰auth.
Opaque state۰at.
#[local] Lemma inv۰statusーweaken γ backs i status vs_front i_back back vs_back vs :
inv۰status true γ backs i status vs_front i_back back vs_back vs ⊢
inv۰status false γ backs i status vs_front i_back back vs_back vs.
#[local] Lemma inv۰statusーStable strong γ backs i status vs_front i_back back vs_back vs :
( strong = true ∧ is_Some (backs !! back)
∨ 0 < length vs_front
∨ 0 < length vs_back
) →
inv۰status strong γ backs i status vs_front i_back back vs_back vs ⊢
∃ empty,
⌜status = Stable empty⌝ ∗
inv۰status۰stable γ i vs_front i_back back vs_back vs empty.
#[local] Lemma inv۰innerーstrengthen l γ :
inv۰inner false l γ ⊢
inv۰inner true l γ.
#[local] Lemma inv'ーstate۰at {l γ} back i_back :
inv' l γ -∗
state۰at γ back i_back ={⊤}=∗
back۰model₁ back i_back.
Lemma queue_mpmc_2۰modelーexclusive t vs1 vs2 :
queue_mpmc_2۰model t vs1 -∗
queue_mpmc_2۰model t vs2 -∗
False.
#[local] Lemma queue_mpmc_2٠suffix_indexーspec (i : nat) vs :
{{{
True
}}}
queue_mpmc_2٠suffix_index (suffix۰to_val i vs)
{{{
RET #i;
True
}}}.
#[local] Lemma queue_mpmc_2٠prefix_indexーspec (i : nat) back vs :
{{{
back ↦ₕ Header §Back 2 ∗
back.[index] ↦□ #i
}}}
queue_mpmc_2٠prefix_index (prefix۰to_val i back vs)
{{{
RET #⁺(i + length vs);
True
}}}.
#[local] Lemma queue_mpmc_2٠rev₁ーspec i vs1 vs2 back :
0 < length vs1 →
{{{
back ↦ₕ Header §Back 2
}}}
queue_mpmc_2٠rev₁ (suffix۰to_val (i + ˖(length vs2)) vs1) (prefix۰to_val i back vs2)
{{{
RET suffix۰to_val ˖i (reverse vs2 ++ vs1);
True
}}}.
#[local] Lemma queue_mpmc_2٠revーspec i back vs :
0 < length vs →
{{{
back ↦ₕ Header §Back 2
}}}
queue_mpmc_2٠rev (prefix۰to_val i back vs)
{{{
RET suffix۰to_val ˖i (reverse vs);
True
}}}.
Lemma queue_mpmc_2٠createーspec ι :
{{{
True
}}}
queue_mpmc_2٠create ()
{{{
t
, RET t;
queue_mpmc_2۰inv t ι ∗
queue_mpmc_2۰model t []
}}}.
#[local] Lemma frontーspec_strong {l γ} i_front i_back :
{{{
inv' l γ ∗
match i_front with
| None ⇒
True
| Some i_front ⇒
front۰lb γ i_front
end ∗
match i_back with
| None ⇒
True
| Some i_back ⇒
∃ back,
state۰at γ back i_back
end
}}}
(#l).{front}
{{{
i_front' vs_front'
, RET suffix۰to_val i_front' vs_front';
front۰lb γ i_front' ∗
match i_front with
| None ⇒
True
| Some i_front ⇒
⌜i_front ≤ i_front'⌝
end ∗
match i_back with
| None ⇒
True
| Some i_back ⇒
∃ i',
⌜i_back ≤ i'⌝ ∗
⌜(i_front' + length vs_front')%nat = ˖i'⌝
end
}}}.
#[local] Lemma frontーspec l γ :
{{{
inv' l γ
}}}
(#l).{front}
{{{
i_front' vs_front'
, RET suffix۰to_val i_front' vs_front';
front۰lb γ i_front'
}}}.
#[local] Lemma moveーspec l γ backs back i move :
{{{
inv' l γ ∗
state۰lb γ backs i (Unstable back move)
}}}
(#back).{move}
{{{
𝑚𝑜𝑣𝑒
, RET 𝑚𝑜𝑣𝑒;
⌜𝑚𝑜𝑣𝑒 = §Used%V⌝
∨ ∃ backs i back_prev move,
⌜𝑚𝑜𝑣𝑒 = prefix۰to_val i back_prev move⌝ ∗
⌜0 < length move⌝ ∗
state۰lb γ backs i (Unstable back move)
}}}.
Lemma queue_mpmc_2٠sizeーspec t ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠size t @ ↑ι
<<<
queue_mpmc_2۰model t vs
| RET #(length vs);
True
>>>.
Lemma queue_mpmc_2٠is_emptyーspec t ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠is_empty t @ ↑ι
<<<
queue_mpmc_2۰model t vs
| RET #(bool_decide (vs = []%list));
True
>>>.
#[local] Lemma queue_mpmc_2٠finishーspec {l γ} i_back back :
{{{
inv' l γ ∗
state۰at γ back i_back
}}}
queue_mpmc_2٠finish #back
{{{
RET ();
True
}}}.
#[local] Lemma queue_mpmc_2٠helpーspec {l γ backs i back_prev back} move :
0 < length move →
{{{
inv' l γ ∗
state۰lb γ backs i (Unstable back move) ∗
back_prev ↦ₕ Header §Back 2
}}}
queue_mpmc_2٠help #l #back #⁺(i + length move) (prefix۰to_val i back_prev move)
{{{
RET ();
True
}}}.
#[local] Lemma queue_mpmc_2٠pushーspecーaux l γ v :
⊢ (
∀ back i ws (j : Z),
<<<
⌜j = ⁺(i + length ws)⌝ ∗
inv' l γ ∗
state۰at γ back i
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠push_aux #l v #j (prefix۰to_val i back ws) @ ↑γ.(metadata۰inv)
<<<
model₁ γ (vs ++ [v])
| RET ();
True
>>>
) ∧ (
<<<
inv' l γ
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠push #l v @ ↑γ.(metadata۰inv)
<<<
model₁ γ (vs ++ [v])
| RET ();
True
>>>
).
Lemma queue_mpmc_2٠pushーspec t v ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠push t v @ ↑ι
<<<
queue_mpmc_2۰model t (vs ++ [v])
| RET ();
True
>>>.
#[local] Lemma queue_mpmc_2٠popーspecーaux l γ :
⊢ (
∀ i_front vs_front,
<<<
inv' l γ ∗
front۰lb γ i_front
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop_1 #l (suffix۰to_val i_front vs_front) @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
) ∧ (
∀ (i_front : nat) backs back i back_prev move,
<<<
⌜i_front ≤ ˖i⌝ ∗
⌜1 < length move⌝ ∗
inv' l γ ∗
state۰lb γ backs i (Unstable back move) ∗
back_prev ↦ₕ Header §Back 2
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop_2 #l ’Front[ #i_front ] #back (prefix۰to_val i back_prev move) @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
) ∧ (
∀ i_front,
<<<
inv' l γ
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop_3 #l ’Front[ #i_front ] @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
) ∧ (
<<<
inv' l γ
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop #l @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
).
Lemma queue_mpmc_2٠popーspec t ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠pop t @ ↑ι
<<<
∃∃ o,
match o with
| None ⇒
queue_mpmc_2۰model t vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
queue_mpmc_2۰model t vs'
end
| RET o;
True
>>>.
End queue_mpmc_2۰G.
Require zoo_saturn.queue_mpmc_2__opaque.
#[global] Opaque queue_mpmc_2۰inv.
#[global] Opaque queue_mpmc_2۰model.
Require Import zoo.common.countable.
Require Import zoo.common.relations.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.iris.base_logic.lib.auth_mono.
Require Import zoo.iris.base_logic.lib.auth_nat_max.
Require Import zoo.base.
Require Import zoo.program_logic.prophet_bool.
Require Import zoo_std.option.
Require Export zoo_saturn.queue_mpmc_2__code.
Require Import zoo_saturn.queue_mpmc_2__types.
Require Import zoo.options.
Implicit Type strong : bool.
Implicit Type l back back_prev : location.
Implicit Type backs : gmap location nat.
Implicit Type v w t pref suff 𝑚𝑜𝑣𝑒 : val.
Implicit Type o : option val.
Implicit Type vs vs_front vs_back move : list val.
Variant emptiness :=
| Empty
| Nonempty.
Implicit Type empty : emptiness.
#[local] Instance emptinessーinhabited : Inhabited emptiness :=
populate Empty.
#[local] Instance emptinessーeq_dec : EqDecision emptiness :=
ltac:(solve_decision).
Variant status :=
| Stable empty
| Unstable back move.
Implicit Type status : status.
#[local] Instance statusーinhabited : Inhabited status :=
populate (Stable inhabitant).
#[local] Instance statusーeq_dec : EqDecision status :=
ltac:(solve_decision).
Record state :=
{ state۰backs : gmap location nat
; state۰index : nat
; state۰status : status
}.
Implicit Type state : state.
#[local] Definition state۰with_status state status :=
{|state۰backs := state.(state۰backs)
; state۰index := state.(state۰index)
; state۰status := status
|}.
Definition state۰wf backs i :=
map_Forall (λ _ i_back, i_back ≤ i) backs.
#[local] Definition state۰le state1 state2 :=
state1.(state۰backs) ⊆ state2.(state۰backs) ∧
state1.(state۰index) ≤ state2.(state۰index).
#[local] Instance stateーinhabited : Inhabited state :=
populate
{|state۰backs := inhabitant
; state۰index := inhabitant
; state۰status := inhabitant
|}.
#[local] Instance state۰leーreflexive :
Reflexive state۰le.
#[local] Instance state۰leーtransitive :
Transitive state۰le.
Variant step : relation state :=
| stepーempty state1 state2 :
state1.(state۰status) = Stable Nonempty →
state2 = state۰with_status state1 (Stable Empty) →
step state1 state2
| stepーdestabilize state1 state2 back move :
state1.(state۰status) = Stable Empty →
state2 = state۰with_status state1 (Unstable back move) →
step state1 state2
| stepーstabilize state1 state2 back move :
state1.(state۰status) = Unstable back move →
state1.(state۰backs) !! back = None →
state2 =
{|state۰backs := <[back := state1.(state۰index) + length move]> state1.(state۰backs)
; state۰index := state1.(state۰index) + length move
; state۰status := Stable Nonempty
|} →
step state1 state2.
#[local] Hint Constructors step : core.
#[local] Definition steps :=
rtc step.
#[local] Lemma stepーmono state1 state2 :
step state1 state2 →
state۰le state1 state2.
#[local] Lemma stepsーmono state1 state2 :
steps state1 state2 →
state۰le state1 state2.
Class QueueMpmc2G Σ `{zoo۰G : !ZooG Σ} :=
{ #[local] queue_mpmc_2۰G۰model۰G :: TwinsG Σ (leibnizO (list val))
; #[local] queue_mpmc_2۰G۰state۰G :: AuthMonoG (A := leibnizO state) Σ step
; #[local] queue_mpmc_2۰G۰front۰G :: AuthNatMaxG Σ
}.
Definition queue_mpmc_2۰Σ :=
#[twins۰Σ (leibnizO (list val))
; auth_mono۰Σ (A := leibnizO state) step
; auth_nat_max۰Σ
].
#[global] Instance subGーqueue_mpmc_2۰Σ Σ `{zoo۰G : !ZooG Σ} :
subG queue_mpmc_2۰Σ Σ →
QueueMpmc2G Σ.
#[local] Fixpoint suffix۰to_val (i : nat) vs : val :=
match vs with
| [] ⇒
‘Front[ #i ]
| v :: vs ⇒
‘Cons[ #i, v, suffix۰to_val ˖i vs ]
end.
#[local] Lemma suffix۰to_valーgenerative i1 vs1 i2 vs2 :
suffix۰to_val i1 vs1 ≈ suffix۰to_val i2 vs2 →
suffix۰to_val i1 vs1 = suffix۰to_val i2 vs2.
#[local] Instance suffix۰to_valーinj2 :
Inj2 (=) (=) (=) suffix۰to_val.
#[local] Instance suffix۰to_valーinj2' :
Inj2 (=) (=) (≈) suffix۰to_val.
#[local] Fixpoint prefix۰to_val (i : nat) back vs : val :=
match vs with
| [] ⇒
#back
| v :: vs ⇒
‘Snoc[ #⁺(i + ˖(length vs)), v, prefix۰to_val i back vs ]
end.
#[local] Lemma prefix۰to_valーgenerative i1 back1 vs1 i2 back2 vs2 :
prefix۰to_val i1 back1 vs1 ≈ prefix۰to_val i2 back2 vs2 →
prefix۰to_val i1 back1 vs1 = prefix۰to_val i2 back2 vs2.
#[local] Lemma prefix۰to_valーinj i1 back1 vs1 i2 back2 vs2 :
prefix۰to_val i1 back1 vs1 = prefix۰to_val i2 back2 vs2 →
(vs1 ≠ [] → i1 = i2) ∧
back1 = back2 ∧
vs1 = vs2.
#[local] Lemma prefix۰to_valーinj' i1 back1 vs1 i2 back2 vs2 :
prefix۰to_val i1 back1 vs1 ≈ prefix۰to_val i2 back2 vs2 →
(vs1 ≠ [] → i1 = i2) ∧
back1 = back2 ∧
vs1 = vs2.
Section queue_mpmc_2۰G.
Context `{queue_mpmc_2۰G : QueueMpmc2G Σ}.
Record metadata :=
{ metadata۰inv : namespace
; metadata۰model : gname
; metadata۰state : gname
; metadata۰front : gname
}.
Implicit Type γ : metadata.
#[local] Instance metadataーeq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadataーcountable :
Countable metadata.
#[local] Definition model₁' γ_model vs :=
twins۰twin₁ γ_model (DfracOwn 1) vs.
#[local] Definition model₁ γ :=
model₁' γ.(metadata۰model).
#[local] Definition model₂' γ_model vs :=
twins۰twin₂ γ_model vs.
#[local] Definition model₂ γ :=
model₂' γ.(metadata۰model).
#[local] Definition state۰auth' γ_state backs i status : iProp Σ :=
auth_mono۰auth _ γ_state (DfracOwn 1)
{|state۰backs := backs
; state۰index := i
; state۰status := status
|} ∗
⌜state۰wf backs i⌝.
#[local] Instance : CustomIpat "state۰auth" :=
" ( Hauth & %Hwf ) ".
#[local] Definition state۰auth γ backs i status :=
state۰auth' γ.(metadata۰state) backs i status.
#[local] Definition state۰lb γ backs i status :=
auth_mono۰lb _ γ.(metadata۰state)
{|state۰backs := backs
; state۰index := i
; state۰status := status
|}.
#[local] Definition state۰seen γ back i_prev back_prev move : iProp Σ :=
∃ backs,
state۰lb γ backs i_prev (Unstable back move) ∗
⌜backs !! back_prev = Some i_prev⌝.
#[local] Instance : CustomIpat "state۰seen" :=
" ( %backs{} & #Hstate_lb & %Hbacks{}_lookup ) ".
#[local] Definition state۰at γ back i_back : iProp Σ :=
∃ backs i status,
state۰lb γ backs i status ∗
⌜backs !! back = Some i_back⌝ ∗
⌜i_back ≤ i⌝.
#[local] Instance : CustomIpat "state۰at" :=
" ( %backs{} & %i{} & %status{} & #Hstate_lb{_{}} & %Hbacks{}_lookup & %Hi{} ) ".
#[local] Definition front۰auth' γ_front i :=
auth_nat_max۰auth γ_front (DfracOwn 1) i.
#[local] Definition front۰auth γ i :=
front۰auth' γ.(metadata۰front) i.
#[local] Definition front۰lb γ i :=
auth_nat_max۰lb γ.(metadata۰front) i.
#[local] Definition move۰model₁ 𝑚𝑜𝑣𝑒 i_prev back_prev move : iProp Σ :=
⌜𝑚𝑜𝑣𝑒 = §Used%V⌝
∨ ⌜𝑚𝑜𝑣𝑒 = prefix۰to_val i_prev back_prev move⌝ ∗
⌜0 < length move⌝ ∗
back_prev ↦ₕ Header §Back 2.
#[local] Instance : CustomIpat "move۰model₁" :=
" [ -> | ( -> & % & #Hback{}_prev_header ) ] ".
#[local] Definition move۰model₂ γ back 𝑚𝑜𝑣𝑒 : iProp Σ :=
∃ backs_prev i_prev back_prev move,
state۰lb γ backs_prev i_prev (Unstable back move) ∗
move۰model₁ 𝑚𝑜𝑣𝑒 i_prev back_prev move.
#[local] Instance : CustomIpat "move۰model₂" :=
" ( %backs{}_prev & %i{}_prev{_{!}} & %back{}_prev{_{!}} & %move{}{_{!}} & #Hstate_lb_unstable{_{}} & H𝑚𝑜𝑣𝑒{} ) ".
#[local] Definition back۰model₁ back (i : nat) : iProp Σ :=
back ↦ₕ Header §Back 2 ∗
back.[index] ↦□ #i.
#[local] Instance : CustomIpat "back۰model₁" :=
" ( { {!} _ ; #Hback{}_header ; #Hback_header } & #Hback{}_index{_{!}} ) ".
#[local] Definition back۰model₂ back (i : nat) 𝑚𝑜𝑣𝑒 : iProp Σ :=
back۰model₁ back i ∗
back.[move] ↦ 𝑚𝑜𝑣𝑒.
#[local] Instance : CustomIpat "back۰model₂" :=
" ( { {only_move} _ ; (:back۰model₁ // /!/) } & Hback{}_move{_{suff}} ) ".
#[local] Definition back۰model₃ γ back i : iProp Σ :=
∃ 𝑚𝑜𝑣𝑒,
back۰model₂ back i 𝑚𝑜𝑣𝑒 ∗
move۰model₂ γ back 𝑚𝑜𝑣𝑒.
#[local] Instance : CustomIpat "back۰model₃" :=
" ( %𝑚𝑜𝑣𝑒{} & (:back۰model₂) & H𝑚𝑜𝑣𝑒{} ) ".
#[local] Definition inv۰status۰stable γ i vs_front i_back back vs_back vs empty : iProp Σ :=
⌜i_back = i⌝ ∗
⌜vs = vs_front ++ reverse vs_back⌝ ∗
⌜if empty then vs_front = [] else 0 < length vs_front⌝ ∗
state۰at γ back i_back.
#[local] Instance : CustomIpat "inv۰status۰stable" :=
" ( {>;}-> & {>;}%Hvs{} & {>;}{{empty}->;%Hempty{};%Hempty} & {>;}#Hstate_at{_{}} ) ".
#[local] Definition inv۰status۰unstable strong γ backs i vs_front i_back back vs_back vs back_ move : iProp Σ :=
∃ back_prev,
⌜back_ = back⌝ ∗
⌜i_back = (i + length move)%nat⌝ ∗
⌜vs_front = []⌝ ∗
⌜vs_back = []⌝ ∗
⌜vs = reverse move⌝ ∗
⌜0 < length move⌝ ∗
state۰at γ back_prev i ∗
back۰model₂ back i_back (prefix۰to_val i back_prev move) ∗
if strong then
⌜backs !! back = None⌝ ∗
back_prev ↦ₕ Header §Back 2
else
True.
#[local] Instance : CustomIpat "inv۰status۰unstable" :=
" ( %back{}_prev & {>;}-> & {>;}-> & {>;}{{lazy}%Hvs_front{};->} & {>;}{{lazy}%Hvs_back{};->} & {>;}-> & {>;}% & {>;}#Hstate_at_back{}_prev & Hback{} & { {strong} %Hbacks{}_lookup & #Hback{}_prev_header ; _ } ) ".
#[local] Definition inv۰status strong γ backs i status vs_front i_back back vs_back vs : iProp Σ :=
match status with
| Stable empty ⇒
inv۰status۰stable γ i vs_front i_back back vs_back vs empty
| Unstable back_ move ⇒
inv۰status۰unstable strong γ backs i vs_front i_back back vs_back vs back_ move
end.
#[local] Definition inv۰inner strong l γ : iProp Σ :=
∃ backs i status i_front vs_front i_back back vs_back vs,
l.[front] ↦ suffix۰to_val i_front vs_front ∗
front۰auth γ i_front ∗
l.[back] ↦ prefix۰to_val i_back back vs_back ∗
([∗ map] back ↦ i ∈ backs, back۰model₃ γ back i) ∗
model₂ γ vs ∗
state۰auth γ backs i status ∗
⌜(i_front + length vs_front)%nat = ˖i⌝ ∗
inv۰status strong γ backs i status vs_front i_back back vs_back vs.
#[local] Instance : CustomIpat "inv۰inner" :=
" ( %backs{} & %i{} & %status{} & %i_front{} & %vs_front{} & %i_back{} & %back{} & %vs_back{} & %vs{} & Hl_front & {>;}Hfront_auth & Hl_back & Hbacks & Hmodel₂ & {>;}Hstate_auth & {>;}%Hfront{} & Hstatus ) ".
#[local] Definition inv' l γ : iProp Σ :=
inv γ.(metadata۰inv) (inv۰inner false l γ).
Definition queue_mpmc_2۰inv t ι : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
⌜ι = γ.(metadata۰inv)⌝ ∗
l ↪ γ ∗
inv' l γ.
#[local] Instance : CustomIpat "inv" :=
" ( %l & %γ & -> & -> & #Hmeta & #Hinv ) ".
Definition queue_mpmc_2۰model t vs : iProp Σ :=
∃ l γ,
⌜t = #l⌝ ∗
l ↪ γ ∗
model₁ γ vs.
#[local] Instance : CustomIpat "model" :=
" ( %l{;_} & %γ{;_} & %Heq{} & #Hmeta_{} & Hmodel₁{_{}} ) ".
#[local] Instance state۰authーtimeless γ backs i status :
Timeless (state۰auth γ backs i status).
#[local] Instance state۰atーtimeless γ back i_back :
Timeless (state۰at γ back i_back).
#[global] Instance queue_mpmc_2۰modelーtimeless t vs :
Timeless (queue_mpmc_2۰model t vs).
#[local] Instance state۰atーpersistent γ back i_back :
Persistent (state۰at γ back i_back).
#[global] Instance queue_mpmc_2۰invーpersistent t ι :
Persistent (queue_mpmc_2۰inv t ι).
#[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 stateーalloc back :
⊢ |==>
∃ γ_state,
state۰auth' γ_state ∅ 0 (Unstable back []).
#[local] Lemma state۰authーwf γ backs i status :
state۰auth γ backs i status ⊢
⌜state۰wf backs i⌝.
#[local] Lemma state۰lbーget γ backs i status :
state۰auth γ backs i status ⊢
state۰lb γ backs i status.
#[local] Lemma state۰atーget {γ backs i status} back i_back :
backs !! back = Some i_back →
state۰auth γ backs i status ⊢
state۰at γ back i_back.
#[local] Lemma state۰lbーvalid γ backs1 i1 status1 backs2 i2 status2 :
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 status2 -∗
⌜backs2 ⊆ backs1⌝ ∗
⌜i2 ≤ i1⌝.
#[local] Lemma state۰lbーvalidーUnstable γ backs1 i1 status1 backs2 i2 back2 move2 :
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 (Unstable back2 move2) -∗
⌜backs1 = backs2⌝ ∗
⌜i1 = i2⌝ ∗
⌜status1 = Unstable back2 move2⌝
∨ ⌜backs1 !! back2 = Some (i2 + length move2)%nat⌝ ∗
⌜i2 + length move2 ≤ i1⌝ ∗
state۰at γ back2 (i2 + length move2).
#[local] Lemma state۰lbーlookup {γ backs1 i1 status1 backs2 i2 status2} back i_back :
backs2 !! back = Some i_back →
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 status2 -∗
⌜backs1 !! back = Some i_back⌝.
#[local] Lemma state۰seenーvalid γ backs i status back i_prev back_prev move :
state۰auth γ backs i status -∗
state۰seen γ back i_prev back_prev move -∗
⌜backs !! back_prev = Some i_prev⌝ ∗
( ⌜i = i_prev⌝ ∗
⌜status = Unstable back move⌝
∨ ⌜backs !! back = Some (i_prev + length move)%nat⌝ ∗
⌜i_prev + length move ≤ i⌝ ∗
state۰at γ back (i_prev + length move)
).
#[local] Lemma state۰atーvalid γ backs i status back i_back :
state۰auth γ backs i status -∗
state۰at γ back i_back -∗
⌜backs !! back = Some i_back⌝ ∗
⌜i_back ≤ i⌝.
#[local] Lemma state۰lbーstabilized γ backs1 i1 status1 backs2 i2 back2 move2 :
( status1 ≠ Unstable back2 move2
∨ i2 + length move2 ≤ i1 ∧
0 < length move2
) →
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 (Unstable back2 move2) -∗
⌜backs1 !! back2 = Some (i2 + length move2)%nat⌝ ∗
state۰at γ back2 (i2 + length move2).
#[local] Lemma state۰lbーunstabilized γ backs1 i1 status1 backs2 i2 back2 move2 :
i1 < i2 + length move2 →
state۰auth γ backs1 i1 status1 -∗
state۰lb γ backs2 i2 (Unstable back2 move2) -∗
⌜backs1 = backs2⌝ ∗
⌜i1 = i2⌝ ∗
⌜status1 = Unstable back2 move2⌝.
#[local] Lemma stateーstabilize γ backs i back move :
backs !! back = None →
state۰auth γ backs i (Unstable back move) ⊢ |==>
state۰auth γ (<[back := i + length move]> backs) (i + length move) (Stable Nonempty) ∗
state۰lb γ (<[back := i + length move]> backs) (i + length move) (Stable Nonempty) ∗
state۰at γ back (i + length move).
#[local] Lemma stateーempty γ backs i :
state۰auth γ backs i (Stable Nonempty) ⊢ |==>
state۰auth γ backs i (Stable Empty).
#[local] Lemma stateーdestabilize {γ backs i} back move :
state۰auth γ backs i (Stable Empty) ⊢ |==>
state۰auth γ backs i (Unstable back move).
#[local] Lemma frontーalloc :
⊢ |==>
∃ γ_front,
front۰auth' γ_front 1.
#[local] Lemma front۰lbーget γ i :
front۰auth γ i ⊢
front۰lb γ i.
#[local] Lemma front۰lbーvalid γ i1 i2 :
front۰auth γ i1 -∗
front۰lb γ i2 -∗
⌜i2 ≤ i1⌝.
#[local] Lemma frontーupdate γ i :
front۰auth γ i ⊢ |==>
front۰auth γ ˖i.
Opaque state۰auth.
Opaque state۰at.
#[local] Lemma inv۰statusーweaken γ backs i status vs_front i_back back vs_back vs :
inv۰status true γ backs i status vs_front i_back back vs_back vs ⊢
inv۰status false γ backs i status vs_front i_back back vs_back vs.
#[local] Lemma inv۰statusーStable strong γ backs i status vs_front i_back back vs_back vs :
( strong = true ∧ is_Some (backs !! back)
∨ 0 < length vs_front
∨ 0 < length vs_back
) →
inv۰status strong γ backs i status vs_front i_back back vs_back vs ⊢
∃ empty,
⌜status = Stable empty⌝ ∗
inv۰status۰stable γ i vs_front i_back back vs_back vs empty.
#[local] Lemma inv۰innerーstrengthen l γ :
inv۰inner false l γ ⊢
inv۰inner true l γ.
#[local] Lemma inv'ーstate۰at {l γ} back i_back :
inv' l γ -∗
state۰at γ back i_back ={⊤}=∗
back۰model₁ back i_back.
Lemma queue_mpmc_2۰modelーexclusive t vs1 vs2 :
queue_mpmc_2۰model t vs1 -∗
queue_mpmc_2۰model t vs2 -∗
False.
#[local] Lemma queue_mpmc_2٠suffix_indexーspec (i : nat) vs :
{{{
True
}}}
queue_mpmc_2٠suffix_index (suffix۰to_val i vs)
{{{
RET #i;
True
}}}.
#[local] Lemma queue_mpmc_2٠prefix_indexーspec (i : nat) back vs :
{{{
back ↦ₕ Header §Back 2 ∗
back.[index] ↦□ #i
}}}
queue_mpmc_2٠prefix_index (prefix۰to_val i back vs)
{{{
RET #⁺(i + length vs);
True
}}}.
#[local] Lemma queue_mpmc_2٠rev₁ーspec i vs1 vs2 back :
0 < length vs1 →
{{{
back ↦ₕ Header §Back 2
}}}
queue_mpmc_2٠rev₁ (suffix۰to_val (i + ˖(length vs2)) vs1) (prefix۰to_val i back vs2)
{{{
RET suffix۰to_val ˖i (reverse vs2 ++ vs1);
True
}}}.
#[local] Lemma queue_mpmc_2٠revーspec i back vs :
0 < length vs →
{{{
back ↦ₕ Header §Back 2
}}}
queue_mpmc_2٠rev (prefix۰to_val i back vs)
{{{
RET suffix۰to_val ˖i (reverse vs);
True
}}}.
Lemma queue_mpmc_2٠createーspec ι :
{{{
True
}}}
queue_mpmc_2٠create ()
{{{
t
, RET t;
queue_mpmc_2۰inv t ι ∗
queue_mpmc_2۰model t []
}}}.
#[local] Lemma frontーspec_strong {l γ} i_front i_back :
{{{
inv' l γ ∗
match i_front with
| None ⇒
True
| Some i_front ⇒
front۰lb γ i_front
end ∗
match i_back with
| None ⇒
True
| Some i_back ⇒
∃ back,
state۰at γ back i_back
end
}}}
(#l).{front}
{{{
i_front' vs_front'
, RET suffix۰to_val i_front' vs_front';
front۰lb γ i_front' ∗
match i_front with
| None ⇒
True
| Some i_front ⇒
⌜i_front ≤ i_front'⌝
end ∗
match i_back with
| None ⇒
True
| Some i_back ⇒
∃ i',
⌜i_back ≤ i'⌝ ∗
⌜(i_front' + length vs_front')%nat = ˖i'⌝
end
}}}.
#[local] Lemma frontーspec l γ :
{{{
inv' l γ
}}}
(#l).{front}
{{{
i_front' vs_front'
, RET suffix۰to_val i_front' vs_front';
front۰lb γ i_front'
}}}.
#[local] Lemma moveーspec l γ backs back i move :
{{{
inv' l γ ∗
state۰lb γ backs i (Unstable back move)
}}}
(#back).{move}
{{{
𝑚𝑜𝑣𝑒
, RET 𝑚𝑜𝑣𝑒;
⌜𝑚𝑜𝑣𝑒 = §Used%V⌝
∨ ∃ backs i back_prev move,
⌜𝑚𝑜𝑣𝑒 = prefix۰to_val i back_prev move⌝ ∗
⌜0 < length move⌝ ∗
state۰lb γ backs i (Unstable back move)
}}}.
Lemma queue_mpmc_2٠sizeーspec t ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠size t @ ↑ι
<<<
queue_mpmc_2۰model t vs
| RET #(length vs);
True
>>>.
Lemma queue_mpmc_2٠is_emptyーspec t ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠is_empty t @ ↑ι
<<<
queue_mpmc_2۰model t vs
| RET #(bool_decide (vs = []%list));
True
>>>.
#[local] Lemma queue_mpmc_2٠finishーspec {l γ} i_back back :
{{{
inv' l γ ∗
state۰at γ back i_back
}}}
queue_mpmc_2٠finish #back
{{{
RET ();
True
}}}.
#[local] Lemma queue_mpmc_2٠helpーspec {l γ backs i back_prev back} move :
0 < length move →
{{{
inv' l γ ∗
state۰lb γ backs i (Unstable back move) ∗
back_prev ↦ₕ Header §Back 2
}}}
queue_mpmc_2٠help #l #back #⁺(i + length move) (prefix۰to_val i back_prev move)
{{{
RET ();
True
}}}.
#[local] Lemma queue_mpmc_2٠pushーspecーaux l γ v :
⊢ (
∀ back i ws (j : Z),
<<<
⌜j = ⁺(i + length ws)⌝ ∗
inv' l γ ∗
state۰at γ back i
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠push_aux #l v #j (prefix۰to_val i back ws) @ ↑γ.(metadata۰inv)
<<<
model₁ γ (vs ++ [v])
| RET ();
True
>>>
) ∧ (
<<<
inv' l γ
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠push #l v @ ↑γ.(metadata۰inv)
<<<
model₁ γ (vs ++ [v])
| RET ();
True
>>>
).
Lemma queue_mpmc_2٠pushーspec t v ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠push t v @ ↑ι
<<<
queue_mpmc_2۰model t (vs ++ [v])
| RET ();
True
>>>.
#[local] Lemma queue_mpmc_2٠popーspecーaux l γ :
⊢ (
∀ i_front vs_front,
<<<
inv' l γ ∗
front۰lb γ i_front
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop_1 #l (suffix۰to_val i_front vs_front) @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
) ∧ (
∀ (i_front : nat) backs back i back_prev move,
<<<
⌜i_front ≤ ˖i⌝ ∗
⌜1 < length move⌝ ∗
inv' l γ ∗
state۰lb γ backs i (Unstable back move) ∗
back_prev ↦ₕ Header §Back 2
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop_2 #l ’Front[ #i_front ] #back (prefix۰to_val i back_prev move) @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
) ∧ (
∀ i_front,
<<<
inv' l γ
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop_3 #l ’Front[ #i_front ] @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
) ∧ (
<<<
inv' l γ
| ∀∀ vs,
model₁ γ vs
>>>
queue_mpmc_2٠pop #l @ ↑γ.(metadata۰inv)
<<<
∃∃ o,
match o with
| None ⇒
model₁ γ vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
model₁ γ vs'
end
| RET o;
True
>>>
).
Lemma queue_mpmc_2٠popーspec t ι :
<<<
queue_mpmc_2۰inv t ι
| ∀∀ vs,
queue_mpmc_2۰model t vs
>>>
queue_mpmc_2٠pop t @ ↑ι
<<<
∃∃ o,
match o with
| None ⇒
queue_mpmc_2۰model t vs
| Some v ⇒
∃ vs',
⌜vs = v :: vs'⌝ ∗
queue_mpmc_2۰model t vs'
end
| RET o;
True
>>>.
End queue_mpmc_2۰G.
Require zoo_saturn.queue_mpmc_2__opaque.
#[global] Opaque queue_mpmc_2۰inv.
#[global] Opaque queue_mpmc_2۰model.