Library zoo_saturn.bag_2
From zoo Require Import
prelude.
From zoo.common Require Import
countable
fin_maps.
From zoo.iris.bi Require Import
big_op.
From zoo.iris.base_logic Require Import
lib.mono_gmap
lib.twins.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Import
option
xtchain.
From zoo_saturn Require Export
base
bag_2__code.
From zoo_saturn Require Import
bag_2__types
spmc_queue.
From zoo Require Import
options.
Implicit Types l node ππππ π’πππ : location.
Implicit Types nodes : list location.
Implicit Types v t producer consumer : val.
Implicit Types o : option val.
Implicit Types vs ws : list val.
Implicit Types vss wss : gmap val (list val).
Class Bag2G Ξ£ `{zoo_G : !ZooG Ξ£} :=
{ #[local] bag_2_G_spmc_queue_G :: SpmcQueueG Ξ£
; #[local] bag_2_G_queues_G :: MonoGmapG Ξ£ location val
; #[local] bag_2_G_model_G :: TwinsG Ξ£ (leibnizO (gmap val (list val)))
}.
Definition bag_2_Ξ£ :=
#[spmc_queue_Ξ£
; mono_gmap_Ξ£ location val
; twins_Ξ£ (leibnizO (gmap val (list val)))
].
#[global] Instance subG_bag_2_Ξ£ Ξ£ `{zoo_G : !ZooG Ξ£} :
subG bag_2_Ξ£ Ξ£ β
Bag2G Ξ£.
Record producer :=
{ producer_queue : val
; producer_node : location
}.
Implicit Types πππππ’πππ : producer.
#[local] Coercion producer_to_val πππππ’πππ : val :=
( πππππ’πππ.(producer_queue),
#πππππ’πππ.(producer_node)
).
#[local] Lemma producer_eq_alt πππππ’πππ1 πππππ’πππ2 :
πππππ’πππ1.(producer_queue) = πππππ’πππ2.(producer_queue) β
πππππ’πππ1.(producer_node) = πππππ’πππ2.(producer_node) β
πππππ’πππ1 = πππππ’πππ2.
#[local] Instance producer_to_val_inj :
Inj (=) (=) producer_to_val.
Record descriptor :=
{ descriptor_queue : val
; descriptor_vals : list val
}.
Implicit Types descr : descriptor.
Implicit Types descrs : gmap location descriptor.
#[local] Definition descriptor_update_vals descr f :=
{|descriptor_queue := descr.(descriptor_queue)
; descriptor_vals := f descr.(descriptor_vals)
|}.
#[local] Definition descriptor_to_producer descr node :=
{|producer_queue := descr.(descriptor_queue)
; producer_node := node
|}.
#[local] Lemma descriptor_to_producer_inj descr1 node1 descr2 node2 :
descriptor_to_producer descr1 node1 = descriptor_to_producer descr2 node2 β
node1 = node2.
Section bag_2_G.
Context `{bag_2_G : Bag2G Ξ£}.
Record metadata :=
{ metadata_inv : namespace
; metadata_model : gname
; metadata_queues : gname
}.
Implicit Types Ξ³ : metadata.
#[local] Instance metadata_eq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadata_countable :
Countable metadata.
#[local] Definition queues_auth' Ξ³_queues nodes descrs wss : iProp Ξ£ :=
mono_gmap_auth Ξ³_queues (DfracOwn 1) (descriptor_queue <$> descrs) β
βdom descrs = list_to_set nodesβ β
β map_Forall (Ξ» node descr,
wss !! (descriptor_to_producer descr node : val) = Some descr.(descriptor_vals)
) descrs
β.
#[local] Instance : CustomIpat "queues_auth" :=
" ( Hauth & %Hnodes & %Hdescrs ) ".
#[local] Definition queues_auth Ξ³ :=
queues_auth' Ξ³.(metadata_queues).
#[local] Definition queues_at' :=
mono_gmap_at.
#[local] Definition queues_at Ξ³ :=
queues_at' Ξ³.(metadata_queues).
#[local] Definition queues_elem Ξ³ queue : iProp Ξ£ :=
match queue with
| None β
True
| Some queue β
β node,
queues_at Ξ³ node queue β
spmc_queue_inv queue (Ξ³.(metadata_inv).@"producer")
end.
#[local] Instance : CustomIpat "queues_elem" :=
" ( %node & #Hqueues_at & #Hqueue_inv ) ".
#[local] Definition modelβ' Ξ³_model vss :=
twins_twin1 Ξ³_model (DfracOwn 1) vss.
#[local] Definition modelβ Ξ³ :=
modelβ' Ξ³.(metadata_model).
#[local] Definition modelβ' Ξ³_model vss :=
twins_twin2 Ξ³_model vss.
#[local] Definition modelβ Ξ³ :=
modelβ' Ξ³.(metadata_model).
#[local] Definition descriptor_model Ξ³ node descr : iProp Ξ£ :=
β o,
node.[queue] β¦ o β
βfrom_option (.= descr.(descriptor_queue)) True oβ β
spmc_queue_inv descr.(descriptor_queue) (Ξ³.(metadata_inv).@"producer") β
spmc_queue_model descr.(descriptor_queue) descr.(descriptor_vals).
#[local] Instance : CustomIpat "descriptor_model" :=
" ( %o{} & Hnode{}_queue & {>;}%Ho{} & {{inv}#Hqueue{}_inv;{inv}#Hqueue_inv;_} & {>;}Hqueue{}_model ) ".
#[local] Definition inv_inner l Ξ³ : iProp Ξ£ :=
β nodes descrs wss,
l.[producers] β¦ from_option #@{location} Β§Null (head nodes) β
xtchain (Header Β§Node 2) DfracDiscarded nodes Β§Null β
queues_auth Ξ³ nodes descrs wss β
modelβ Ξ³ wss β
[β map] node β¦ descr β descrs,
descriptor_model Ξ³ node descr.
#[local] Instance : CustomIpat "inv_inner" :=
" ( %nodes{} & %descrs{} & %wss & Hl_producers & Hnodes{} & >Hqueues_auth & >Hmodelβ & Hdescrs ) ".
#[local] Definition inv' l Ξ³ :=
inv (Ξ³.(metadata_inv).@"inv") (inv_inner l Ξ³).
Definition bag_2_inv t ΞΉ : iProp Ξ£ :=
β l Ξ³,
βt = #lβ β
βΞΉ = Ξ³.(metadata_inv)β β
meta l nroot Ξ³ β
inv' l Ξ³.
#[local] Instance : CustomIpat "inv" :=
" ( %l & %Ξ³ & -> & -> & #Hmeta & #Hinv ) ".
Definition bag_2_model t vss : iProp Ξ£ :=
β l Ξ³,
βt = #lβ β
meta l nroot Ξ³ β
modelβ Ξ³ vss.
#[local] Instance : CustomIpat "model" :=
" ( %l{;_} & %Ξ³{;_} & %Heq{} & #Hmeta_{} & Hmodelβ{_{}} ) ".
Definition bag_2_producer t producer ws : iProp Ξ£ :=
β l Ξ³ πππππ’πππ,
βt = #lβ β
βproducer = πππππ’πππβ β
meta l nroot Ξ³ β
πππππ’πππ.(producer_node) β¦β Header Β§Node 2 β
queues_at Ξ³ πππππ’πππ.(producer_node) πππππ’πππ.(producer_queue) β
spmc_queue_inv πππππ’πππ.(producer_queue) (Ξ³.(metadata_inv).@"producer") β
spmc_queue_producer πππππ’πππ.(producer_queue) ws.
#[local] Instance : CustomIpat "producer" :=
" ( %l{;_} & %Ξ³{;_} & %πππππ’πππ{} & %Ht_eq{} & {%Hproducer_eq{};->} & #Hmeta{_{};_} & #Hnode_header{_{}} & #Hqueues_at{_{}} & #Hqueue_inv{_{}} & Hqueue_producer{_{}} ) ".
Definition bag_2_consumer t consumer : iProp Ξ£ :=
β l Ξ³ ππππ π’πππ (queue : option val),
βt = #lβ β
meta l nroot Ξ³ β
βconsumer = #ππππ π’πππβ β
ππππ π’πππ.[consumer_queue] β¦ queue β
queues_elem Ξ³ queue.
#[local] Instance : CustomIpat "consumer" :=
" ( %l{;_} & %Ξ³{;_} & %ππππ π’πππ{} & %queue{} & %Heq{} & Hmeta_{} & {%Hconsumer_eq{};->} & Hconsumer_queue{_{}} & #Hqueues_elem{_{}} ) ".
#[local] Instance queues_auth_timeless Ξ³ nodes descrs wss :
Timeless (queues_auth Ξ³ nodes descrs wss).
#[global] Instance bag_2_model_timeless t vss :
Timeless (bag_2_model t vss).
#[global] Instance bag_2_inv_persistent t ΞΉ :
Persistent (bag_2_inv t ΞΉ).
#[local] Lemma queues_alloc :
β’ |==>
β Ξ³_queues,
queues_auth' Ξ³_queues [] β β .
#[local] Lemma queues_at_get {Ξ³ nodes descrs wss} i node :
nodes !! i = Some node β
queues_auth Ξ³ nodes descrs wss β’
β descr,
βdescrs !! node = Some descrβ β
queues_at Ξ³ node descr.(descriptor_queue).
#[local] Lemma queues_at_valid Ξ³ nodes descrs wss node queue :
queues_auth Ξ³ nodes descrs wss -β
queues_at Ξ³ node queue -β
β descr,
βdescrs !! node = Some descrβ β
βdescr.(descriptor_queue) = queueβ β
βwss !! (descriptor_to_producer descr node : val) = Some descr.(descriptor_vals)β.
#[local] Lemma queues_at_valid_producer Ξ³ nodes descrs wss πππππ’πππ :
queues_auth Ξ³ nodes descrs wss -β
queues_at Ξ³ πππππ’πππ.(producer_node) πππππ’πππ.(producer_queue) -β
β descr,
βdescrs !! πππππ’πππ.(producer_node) = Some descrβ β
βdescr.(descriptor_queue) = πππππ’πππ.(producer_queue)β β
βwss !! (πππππ’πππ : val) = Some descr.(descriptor_vals)β.
#[local] Lemma queues_insert {Ξ³ nodes descrs wss} node descr :
descrs !! node = None β
queues_auth Ξ³ nodes descrs wss β’ |==>
queues_auth Ξ³
(node :: nodes)
(<[node := descr]> descrs)
(<[descriptor_to_producer descr node : val := descr.(descriptor_vals)]> wss) β
queues_at Ξ³ node descr.(descriptor_queue).
#[local] Lemma queues_update {Ξ³ nodes descrs wss} node descr f :
descrs !! node = Some descr β
queues_auth Ξ³ nodes descrs wss β’
queues_auth Ξ³
nodes
(<[node := descriptor_update_vals descr f]> descrs)
(<[descriptor_to_producer descr node : val := f descr.(descriptor_vals)]> wss).
#[local] Lemma queues_update_producer {Ξ³ nodes descrs wss} πππππ’πππ descr f :
descrs !! πππππ’πππ.(producer_node) = Some descr β
descr.(descriptor_queue) = πππππ’πππ.(producer_queue) β
queues_auth Ξ³ nodes descrs wss β’
queues_auth Ξ³
nodes
(<[πππππ’πππ.(producer_node) := descriptor_update_vals descr f]> descrs)
(<[πππππ’πππ : val := f descr.(descriptor_vals)]> wss).
#[local] Lemma model_alloc :
β’ |==>
β Ξ³_model,
modelβ' Ξ³_model β β
modelβ' Ξ³_model β .
#[local] Lemma modelβ_exclusive Ξ³ vss1 vss2 :
modelβ Ξ³ vss1 -β
modelβ Ξ³ vss2 -β
False.
#[local] Lemma model_agree Ξ³ vss1 vss2 :
modelβ Ξ³ vss1 -β
modelβ Ξ³ vss2 -β
βvss1 = vss2β.
#[local] Lemma model_update {Ξ³ vss1 vss2} vss :
modelβ Ξ³ vss1 -β
modelβ Ξ³ vss2 ==β
modelβ Ξ³ vss β
modelβ Ξ³ vss.
Opaque queues_auth'.
Lemma bag_2_model_exclusive t vss1 vss2 :
bag_2_model t vss1 -β
bag_2_model t vss2 -β
False.
Lemma bag_2_producer_valid t ΞΉ vss producer ws E :
βΞΉ β E β
bag_2_inv t ΞΉ -β
bag_2_model t vss -β
bag_2_producer t producer ws ={E}=β
β vs,
βvss !! producer = Some vsβ β
βvs `suffix_of` wsβ.
Lemma bag_2_producer_exclusive t1 t2 producer ws1 ws2 :
bag_2_producer t1 producer ws1 -β
bag_2_producer t2 producer ws2 -β
False.
Lemma bag_2_consumer_exclusive t1 t2 consumer :
bag_2_consumer t1 consumer -β
bag_2_consumer t2 consumer -β
False.
Lemma bag_2Ω createπspec ΞΉ :
{{{
True
}}}
bag_2Ω create ()
{{{
t
, RET t;
bag_2_inv t ΞΉ β
bag_2_model t β
}}}.
#[local] Lemma bag_2Ω add_producerβπspec l Ξ³ (queue : val) :
<<<
meta l nroot Ξ³ β
inv' l Ξ³ β
spmc_queue_inv queue (Ξ³.(metadata_inv).@"producer") β
spmc_queue_model queue []
| ββ vss,
modelβ Ξ³ vss
>>>
bag_2Ω add_producerβ #l (Some queue) @ βΞ³.(metadata_inv)
<<<
ββ node,
let πππππ’πππ :=
{|producer_queue := queue
; producer_node := node
|}
in
modelβ Ξ³ (<[πππππ’πππ : val := []]> vss)
| RET #node;
node β¦β Header Β§Node 2 β
queues_at Ξ³ node queue
>>>.
#[local] Lemma bag_2Ω add_producerπspec l Ξ³ (queue : val) :
<<<
meta l nroot Ξ³ β
inv' l Ξ³ β
spmc_queue_inv queue (Ξ³.(metadata_inv).@"producer") β
spmc_queue_model queue []
| ββ vss,
modelβ Ξ³ vss
>>>
bag_2Ω add_producer #l queue @ βΞ³.(metadata_inv)
<<<
ββ node,
let πππππ’πππ :=
{|producer_queue := queue
; producer_node := node
|}
in
modelβ Ξ³ (<[πππππ’πππ : val := []]> vss)
| RET #node;
node β¦β Header Β§Node 2 β
queues_at Ξ³ node queue
>>>.
Lemma bag_2Ω create_producerπspec t ΞΉ :
<<<
bag_2_inv t ΞΉ
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω create_producer t @ βΞΉ
<<<
ββ producer,
bag_2_model t (<[producer := []]> vss)
| RET producer;
bag_2_producer t producer []
>>>.
Lemma bag_2Ω close_producerπspec t ΞΉ producer ws :
{{{
bag_2_inv t ΞΉ β
bag_2_producer t producer ws
}}}
bag_2Ω close_producer producer
{{{
RET ();
bag_2_producer t producer ws
}}}.
Lemma bag_2Ω create_consumerπspec t ΞΉ :
{{{
bag_2_inv t ΞΉ
}}}
bag_2Ω create_consumer t
{{{
consumer
, RET consumer;
bag_2_consumer t consumer
}}}.
Lemma bag_2Ω pushπspec t ΞΉ producer ws v :
<<<
bag_2_inv t ΞΉ β
bag_2_producer t producer ws
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω push producer v @ βΞΉ
<<<
ββ vs,
βvss !! producer = Some vsβ β
bag_2_model t (<[producer := vs ++ [v]]> vss)
| RET ();
bag_2_producer t producer (vs ++ [v])
>>>.
#[local] Lemma bag_2Ω popβπspec l Ξ³ ππππ π’πππ (queue : option val) nodes :
<<<
meta l nroot Ξ³ β
inv' l Ξ³ β
ππππ π’πππ.[consumer_queue] β¦ queue β
queues_elem Ξ³ queue β
xtchain (Header Β§Node 2) DfracDiscarded nodes Β§Null β
[β list] node β nodes,
β queue,
queues_at Ξ³ node queue
| ββ vss,
modelβ Ξ³ vss
>>>
bag_2Ω popβ #ππππ π’πππ (from_option #@{location} Β§Null%V $ head nodes) @ βΞ³.(metadata_inv)
<<<
ββ o,
match o with
| None β
modelβ Ξ³ vss
| Some v β
β producer vs,
βvss !! producer = Some (v :: vs)β β
modelβ Ξ³ (<[producer := vs]> vss)
end
| queue : option val,
RET o;
ππππ π’πππ.[consumer_queue] β¦ queue β
queues_elem Ξ³ queue
>>>.
#[local] Lemma bag_2Ω popβπspec t ΞΉ consumer :
<<<
bag_2_inv t ΞΉ β
bag_2_consumer t consumer
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω popβ t consumer @ βΞΉ
<<<
ββ o,
match o with
| None β
bag_2_model t vss
| Some v β
β producer vs,
βvss !! producer = Some (v :: vs)β β
bag_2_model t (<[producer := vs]> vss)
end
| RET o;
bag_2_consumer t consumer
>>>.
Lemma bag_2Ω popπspec t ΞΉ consumer :
<<<
bag_2_inv t ΞΉ β
bag_2_consumer t consumer
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω pop t consumer @ βΞΉ
<<<
ββ o,
match o with
| None β
bag_2_model t vss
| Some v β
β producer vs,
βvss !! producer = Some (v :: vs)β β
bag_2_model t (<[producer := vs]> vss)
end
| RET o;
bag_2_consumer t consumer
>>>.
End bag_2_G.
From zoo_saturn Require
bag_2__opaque.
#[global] Opaque bag_2_inv.
#[global] Opaque bag_2_model.
#[global] Opaque bag_2_producer.
#[global] Opaque bag_2_consumer.
prelude.
From zoo.common Require Import
countable
fin_maps.
From zoo.iris.bi Require Import
big_op.
From zoo.iris.base_logic Require Import
lib.mono_gmap
lib.twins.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Import
option
xtchain.
From zoo_saturn Require Export
base
bag_2__code.
From zoo_saturn Require Import
bag_2__types
spmc_queue.
From zoo Require Import
options.
Implicit Types l node ππππ π’πππ : location.
Implicit Types nodes : list location.
Implicit Types v t producer consumer : val.
Implicit Types o : option val.
Implicit Types vs ws : list val.
Implicit Types vss wss : gmap val (list val).
Class Bag2G Ξ£ `{zoo_G : !ZooG Ξ£} :=
{ #[local] bag_2_G_spmc_queue_G :: SpmcQueueG Ξ£
; #[local] bag_2_G_queues_G :: MonoGmapG Ξ£ location val
; #[local] bag_2_G_model_G :: TwinsG Ξ£ (leibnizO (gmap val (list val)))
}.
Definition bag_2_Ξ£ :=
#[spmc_queue_Ξ£
; mono_gmap_Ξ£ location val
; twins_Ξ£ (leibnizO (gmap val (list val)))
].
#[global] Instance subG_bag_2_Ξ£ Ξ£ `{zoo_G : !ZooG Ξ£} :
subG bag_2_Ξ£ Ξ£ β
Bag2G Ξ£.
Record producer :=
{ producer_queue : val
; producer_node : location
}.
Implicit Types πππππ’πππ : producer.
#[local] Coercion producer_to_val πππππ’πππ : val :=
( πππππ’πππ.(producer_queue),
#πππππ’πππ.(producer_node)
).
#[local] Lemma producer_eq_alt πππππ’πππ1 πππππ’πππ2 :
πππππ’πππ1.(producer_queue) = πππππ’πππ2.(producer_queue) β
πππππ’πππ1.(producer_node) = πππππ’πππ2.(producer_node) β
πππππ’πππ1 = πππππ’πππ2.
#[local] Instance producer_to_val_inj :
Inj (=) (=) producer_to_val.
Record descriptor :=
{ descriptor_queue : val
; descriptor_vals : list val
}.
Implicit Types descr : descriptor.
Implicit Types descrs : gmap location descriptor.
#[local] Definition descriptor_update_vals descr f :=
{|descriptor_queue := descr.(descriptor_queue)
; descriptor_vals := f descr.(descriptor_vals)
|}.
#[local] Definition descriptor_to_producer descr node :=
{|producer_queue := descr.(descriptor_queue)
; producer_node := node
|}.
#[local] Lemma descriptor_to_producer_inj descr1 node1 descr2 node2 :
descriptor_to_producer descr1 node1 = descriptor_to_producer descr2 node2 β
node1 = node2.
Section bag_2_G.
Context `{bag_2_G : Bag2G Ξ£}.
Record metadata :=
{ metadata_inv : namespace
; metadata_model : gname
; metadata_queues : gname
}.
Implicit Types Ξ³ : metadata.
#[local] Instance metadata_eq_dec : EqDecision metadata :=
ltac:(solve_decision).
#[local] Instance metadata_countable :
Countable metadata.
#[local] Definition queues_auth' Ξ³_queues nodes descrs wss : iProp Ξ£ :=
mono_gmap_auth Ξ³_queues (DfracOwn 1) (descriptor_queue <$> descrs) β
βdom descrs = list_to_set nodesβ β
β map_Forall (Ξ» node descr,
wss !! (descriptor_to_producer descr node : val) = Some descr.(descriptor_vals)
) descrs
β.
#[local] Instance : CustomIpat "queues_auth" :=
" ( Hauth & %Hnodes & %Hdescrs ) ".
#[local] Definition queues_auth Ξ³ :=
queues_auth' Ξ³.(metadata_queues).
#[local] Definition queues_at' :=
mono_gmap_at.
#[local] Definition queues_at Ξ³ :=
queues_at' Ξ³.(metadata_queues).
#[local] Definition queues_elem Ξ³ queue : iProp Ξ£ :=
match queue with
| None β
True
| Some queue β
β node,
queues_at Ξ³ node queue β
spmc_queue_inv queue (Ξ³.(metadata_inv).@"producer")
end.
#[local] Instance : CustomIpat "queues_elem" :=
" ( %node & #Hqueues_at & #Hqueue_inv ) ".
#[local] Definition modelβ' Ξ³_model vss :=
twins_twin1 Ξ³_model (DfracOwn 1) vss.
#[local] Definition modelβ Ξ³ :=
modelβ' Ξ³.(metadata_model).
#[local] Definition modelβ' Ξ³_model vss :=
twins_twin2 Ξ³_model vss.
#[local] Definition modelβ Ξ³ :=
modelβ' Ξ³.(metadata_model).
#[local] Definition descriptor_model Ξ³ node descr : iProp Ξ£ :=
β o,
node.[queue] β¦ o β
βfrom_option (.= descr.(descriptor_queue)) True oβ β
spmc_queue_inv descr.(descriptor_queue) (Ξ³.(metadata_inv).@"producer") β
spmc_queue_model descr.(descriptor_queue) descr.(descriptor_vals).
#[local] Instance : CustomIpat "descriptor_model" :=
" ( %o{} & Hnode{}_queue & {>;}%Ho{} & {{inv}#Hqueue{}_inv;{inv}#Hqueue_inv;_} & {>;}Hqueue{}_model ) ".
#[local] Definition inv_inner l Ξ³ : iProp Ξ£ :=
β nodes descrs wss,
l.[producers] β¦ from_option #@{location} Β§Null (head nodes) β
xtchain (Header Β§Node 2) DfracDiscarded nodes Β§Null β
queues_auth Ξ³ nodes descrs wss β
modelβ Ξ³ wss β
[β map] node β¦ descr β descrs,
descriptor_model Ξ³ node descr.
#[local] Instance : CustomIpat "inv_inner" :=
" ( %nodes{} & %descrs{} & %wss & Hl_producers & Hnodes{} & >Hqueues_auth & >Hmodelβ & Hdescrs ) ".
#[local] Definition inv' l Ξ³ :=
inv (Ξ³.(metadata_inv).@"inv") (inv_inner l Ξ³).
Definition bag_2_inv t ΞΉ : iProp Ξ£ :=
β l Ξ³,
βt = #lβ β
βΞΉ = Ξ³.(metadata_inv)β β
meta l nroot Ξ³ β
inv' l Ξ³.
#[local] Instance : CustomIpat "inv" :=
" ( %l & %Ξ³ & -> & -> & #Hmeta & #Hinv ) ".
Definition bag_2_model t vss : iProp Ξ£ :=
β l Ξ³,
βt = #lβ β
meta l nroot Ξ³ β
modelβ Ξ³ vss.
#[local] Instance : CustomIpat "model" :=
" ( %l{;_} & %Ξ³{;_} & %Heq{} & #Hmeta_{} & Hmodelβ{_{}} ) ".
Definition bag_2_producer t producer ws : iProp Ξ£ :=
β l Ξ³ πππππ’πππ,
βt = #lβ β
βproducer = πππππ’πππβ β
meta l nroot Ξ³ β
πππππ’πππ.(producer_node) β¦β Header Β§Node 2 β
queues_at Ξ³ πππππ’πππ.(producer_node) πππππ’πππ.(producer_queue) β
spmc_queue_inv πππππ’πππ.(producer_queue) (Ξ³.(metadata_inv).@"producer") β
spmc_queue_producer πππππ’πππ.(producer_queue) ws.
#[local] Instance : CustomIpat "producer" :=
" ( %l{;_} & %Ξ³{;_} & %πππππ’πππ{} & %Ht_eq{} & {%Hproducer_eq{};->} & #Hmeta{_{};_} & #Hnode_header{_{}} & #Hqueues_at{_{}} & #Hqueue_inv{_{}} & Hqueue_producer{_{}} ) ".
Definition bag_2_consumer t consumer : iProp Ξ£ :=
β l Ξ³ ππππ π’πππ (queue : option val),
βt = #lβ β
meta l nroot Ξ³ β
βconsumer = #ππππ π’πππβ β
ππππ π’πππ.[consumer_queue] β¦ queue β
queues_elem Ξ³ queue.
#[local] Instance : CustomIpat "consumer" :=
" ( %l{;_} & %Ξ³{;_} & %ππππ π’πππ{} & %queue{} & %Heq{} & Hmeta_{} & {%Hconsumer_eq{};->} & Hconsumer_queue{_{}} & #Hqueues_elem{_{}} ) ".
#[local] Instance queues_auth_timeless Ξ³ nodes descrs wss :
Timeless (queues_auth Ξ³ nodes descrs wss).
#[global] Instance bag_2_model_timeless t vss :
Timeless (bag_2_model t vss).
#[global] Instance bag_2_inv_persistent t ΞΉ :
Persistent (bag_2_inv t ΞΉ).
#[local] Lemma queues_alloc :
β’ |==>
β Ξ³_queues,
queues_auth' Ξ³_queues [] β β .
#[local] Lemma queues_at_get {Ξ³ nodes descrs wss} i node :
nodes !! i = Some node β
queues_auth Ξ³ nodes descrs wss β’
β descr,
βdescrs !! node = Some descrβ β
queues_at Ξ³ node descr.(descriptor_queue).
#[local] Lemma queues_at_valid Ξ³ nodes descrs wss node queue :
queues_auth Ξ³ nodes descrs wss -β
queues_at Ξ³ node queue -β
β descr,
βdescrs !! node = Some descrβ β
βdescr.(descriptor_queue) = queueβ β
βwss !! (descriptor_to_producer descr node : val) = Some descr.(descriptor_vals)β.
#[local] Lemma queues_at_valid_producer Ξ³ nodes descrs wss πππππ’πππ :
queues_auth Ξ³ nodes descrs wss -β
queues_at Ξ³ πππππ’πππ.(producer_node) πππππ’πππ.(producer_queue) -β
β descr,
βdescrs !! πππππ’πππ.(producer_node) = Some descrβ β
βdescr.(descriptor_queue) = πππππ’πππ.(producer_queue)β β
βwss !! (πππππ’πππ : val) = Some descr.(descriptor_vals)β.
#[local] Lemma queues_insert {Ξ³ nodes descrs wss} node descr :
descrs !! node = None β
queues_auth Ξ³ nodes descrs wss β’ |==>
queues_auth Ξ³
(node :: nodes)
(<[node := descr]> descrs)
(<[descriptor_to_producer descr node : val := descr.(descriptor_vals)]> wss) β
queues_at Ξ³ node descr.(descriptor_queue).
#[local] Lemma queues_update {Ξ³ nodes descrs wss} node descr f :
descrs !! node = Some descr β
queues_auth Ξ³ nodes descrs wss β’
queues_auth Ξ³
nodes
(<[node := descriptor_update_vals descr f]> descrs)
(<[descriptor_to_producer descr node : val := f descr.(descriptor_vals)]> wss).
#[local] Lemma queues_update_producer {Ξ³ nodes descrs wss} πππππ’πππ descr f :
descrs !! πππππ’πππ.(producer_node) = Some descr β
descr.(descriptor_queue) = πππππ’πππ.(producer_queue) β
queues_auth Ξ³ nodes descrs wss β’
queues_auth Ξ³
nodes
(<[πππππ’πππ.(producer_node) := descriptor_update_vals descr f]> descrs)
(<[πππππ’πππ : val := f descr.(descriptor_vals)]> wss).
#[local] Lemma model_alloc :
β’ |==>
β Ξ³_model,
modelβ' Ξ³_model β β
modelβ' Ξ³_model β .
#[local] Lemma modelβ_exclusive Ξ³ vss1 vss2 :
modelβ Ξ³ vss1 -β
modelβ Ξ³ vss2 -β
False.
#[local] Lemma model_agree Ξ³ vss1 vss2 :
modelβ Ξ³ vss1 -β
modelβ Ξ³ vss2 -β
βvss1 = vss2β.
#[local] Lemma model_update {Ξ³ vss1 vss2} vss :
modelβ Ξ³ vss1 -β
modelβ Ξ³ vss2 ==β
modelβ Ξ³ vss β
modelβ Ξ³ vss.
Opaque queues_auth'.
Lemma bag_2_model_exclusive t vss1 vss2 :
bag_2_model t vss1 -β
bag_2_model t vss2 -β
False.
Lemma bag_2_producer_valid t ΞΉ vss producer ws E :
βΞΉ β E β
bag_2_inv t ΞΉ -β
bag_2_model t vss -β
bag_2_producer t producer ws ={E}=β
β vs,
βvss !! producer = Some vsβ β
βvs `suffix_of` wsβ.
Lemma bag_2_producer_exclusive t1 t2 producer ws1 ws2 :
bag_2_producer t1 producer ws1 -β
bag_2_producer t2 producer ws2 -β
False.
Lemma bag_2_consumer_exclusive t1 t2 consumer :
bag_2_consumer t1 consumer -β
bag_2_consumer t2 consumer -β
False.
Lemma bag_2Ω createπspec ΞΉ :
{{{
True
}}}
bag_2Ω create ()
{{{
t
, RET t;
bag_2_inv t ΞΉ β
bag_2_model t β
}}}.
#[local] Lemma bag_2Ω add_producerβπspec l Ξ³ (queue : val) :
<<<
meta l nroot Ξ³ β
inv' l Ξ³ β
spmc_queue_inv queue (Ξ³.(metadata_inv).@"producer") β
spmc_queue_model queue []
| ββ vss,
modelβ Ξ³ vss
>>>
bag_2Ω add_producerβ #l (Some queue) @ βΞ³.(metadata_inv)
<<<
ββ node,
let πππππ’πππ :=
{|producer_queue := queue
; producer_node := node
|}
in
modelβ Ξ³ (<[πππππ’πππ : val := []]> vss)
| RET #node;
node β¦β Header Β§Node 2 β
queues_at Ξ³ node queue
>>>.
#[local] Lemma bag_2Ω add_producerπspec l Ξ³ (queue : val) :
<<<
meta l nroot Ξ³ β
inv' l Ξ³ β
spmc_queue_inv queue (Ξ³.(metadata_inv).@"producer") β
spmc_queue_model queue []
| ββ vss,
modelβ Ξ³ vss
>>>
bag_2Ω add_producer #l queue @ βΞ³.(metadata_inv)
<<<
ββ node,
let πππππ’πππ :=
{|producer_queue := queue
; producer_node := node
|}
in
modelβ Ξ³ (<[πππππ’πππ : val := []]> vss)
| RET #node;
node β¦β Header Β§Node 2 β
queues_at Ξ³ node queue
>>>.
Lemma bag_2Ω create_producerπspec t ΞΉ :
<<<
bag_2_inv t ΞΉ
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω create_producer t @ βΞΉ
<<<
ββ producer,
bag_2_model t (<[producer := []]> vss)
| RET producer;
bag_2_producer t producer []
>>>.
Lemma bag_2Ω close_producerπspec t ΞΉ producer ws :
{{{
bag_2_inv t ΞΉ β
bag_2_producer t producer ws
}}}
bag_2Ω close_producer producer
{{{
RET ();
bag_2_producer t producer ws
}}}.
Lemma bag_2Ω create_consumerπspec t ΞΉ :
{{{
bag_2_inv t ΞΉ
}}}
bag_2Ω create_consumer t
{{{
consumer
, RET consumer;
bag_2_consumer t consumer
}}}.
Lemma bag_2Ω pushπspec t ΞΉ producer ws v :
<<<
bag_2_inv t ΞΉ β
bag_2_producer t producer ws
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω push producer v @ βΞΉ
<<<
ββ vs,
βvss !! producer = Some vsβ β
bag_2_model t (<[producer := vs ++ [v]]> vss)
| RET ();
bag_2_producer t producer (vs ++ [v])
>>>.
#[local] Lemma bag_2Ω popβπspec l Ξ³ ππππ π’πππ (queue : option val) nodes :
<<<
meta l nroot Ξ³ β
inv' l Ξ³ β
ππππ π’πππ.[consumer_queue] β¦ queue β
queues_elem Ξ³ queue β
xtchain (Header Β§Node 2) DfracDiscarded nodes Β§Null β
[β list] node β nodes,
β queue,
queues_at Ξ³ node queue
| ββ vss,
modelβ Ξ³ vss
>>>
bag_2Ω popβ #ππππ π’πππ (from_option #@{location} Β§Null%V $ head nodes) @ βΞ³.(metadata_inv)
<<<
ββ o,
match o with
| None β
modelβ Ξ³ vss
| Some v β
β producer vs,
βvss !! producer = Some (v :: vs)β β
modelβ Ξ³ (<[producer := vs]> vss)
end
| queue : option val,
RET o;
ππππ π’πππ.[consumer_queue] β¦ queue β
queues_elem Ξ³ queue
>>>.
#[local] Lemma bag_2Ω popβπspec t ΞΉ consumer :
<<<
bag_2_inv t ΞΉ β
bag_2_consumer t consumer
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω popβ t consumer @ βΞΉ
<<<
ββ o,
match o with
| None β
bag_2_model t vss
| Some v β
β producer vs,
βvss !! producer = Some (v :: vs)β β
bag_2_model t (<[producer := vs]> vss)
end
| RET o;
bag_2_consumer t consumer
>>>.
Lemma bag_2Ω popπspec t ΞΉ consumer :
<<<
bag_2_inv t ΞΉ β
bag_2_consumer t consumer
| ββ vss,
bag_2_model t vss
>>>
bag_2Ω pop t consumer @ βΞΉ
<<<
ββ o,
match o with
| None β
bag_2_model t vss
| Some v β
β producer vs,
βvss !! producer = Some (v :: vs)β β
bag_2_model t (<[producer := vs]> vss)
end
| RET o;
bag_2_consumer t consumer
>>>.
End bag_2_G.
From zoo_saturn Require
bag_2__opaque.
#[global] Opaque bag_2_inv.
#[global] Opaque bag_2_model.
#[global] Opaque bag_2_producer.
#[global] Opaque bag_2_consumer.