diff --git a/theories/examples/producer_consumer.v b/theories/examples/producer_consumer.v new file mode 100644 index 0000000000000000000000000000000000000000..50512af92b291680678e0cc655bb9933749ebf2d --- /dev/null +++ b/theories/examples/producer_consumer.v @@ -0,0 +1,61 @@ +From stdpp Require Import sorting. +From osiris.channel Require Import proto_channel proofmode. +From iris.heap_lang Require Import proofmode notation. +From iris.heap_lang Require Import assert. +From iris.heap_lang.lib Require Import spin_lock. +From osiris.utils Require Import list compare. + + +Definition qenqueue : val := λ: "q" "v", #(). +Definition qdequeue : val := λ: "q", #(). +Definition qis_empty : val := λ: "q", #(). + +Definition enq := true. +Definition deq := false. + +Definition cont := true. +Definition stop := false. + +Definition some := true. +Definition none := false. + +Definition dist_queue : val := + rec: "go" "q" "pc" "cc" "c" := + if: "cc" ≤ #0 then #() else + if: recv "c" (* enq/deq *) + then if: recv "c" (* cont/stop *) + then "go" (qenqueue "q" (recv "c")) "pc" "cc" "c" + else "go" "q" ("pc"-#1) "cc" "c" + else if: (qis_empty "q") + then if: "pc" ≤ #0 + then send "c" #stop;; "go" "q" "pc" ("cc"-#1) "c" + else send "c" #cont;; send "c" #none;; "go" "q" "pc" "cc" "c" + else send "c" #cont;; send "c" #some;; + let: "qv" := qdequeue "q" in + send "c" (Snd "qv");; "go" (Fst "qv") "pc" "cc" "c". + +Definition producer : val := + rec: "go" "c" "l" "produce" := + match: "produce" #() with + SOME "v" => + acquire "l";; + send "c" #enq;; send "c" #cont;; send "c" "v";; + release "l";; + "go" "c" "l" "produce" + | NONE => + acquire "l";; + send "c" #enq;; send "c" #stop + release "l" + end. + +Definition consumer : val := + rec: "go" "c" "l" "consume" := + acquire "l";; + send "c" #deq;; + if: recv "c" (* cont/stop *) + then if: recv "c" (* some/none *) + then let: "v" := recv "c" in + release "l";; "produce" "v";; "go" "c" "l" "consume" + else release "l";; "go" "c" "l" "consume" + else release "l";; #(). +