summaryrefslogtreecommitdiffstats
path: root/theories/fin_queue_spec.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/fin_queue_spec.v')
-rw-r--r--theories/fin_queue_spec.v67
1 files changed, 67 insertions, 0 deletions
diff --git a/theories/fin_queue_spec.v b/theories/fin_queue_spec.v
new file mode 100644
index 0000000..f7e0886
--- /dev/null
+++ b/theories/fin_queue_spec.v
@@ -0,0 +1,67 @@
1From iris.program_logic Require Import atomic.
2From iris.heap_lang Require Import notation proofmode.
3
4From lmpmc Require Import util.
5
6(* Doing this split because I don't know how to otherwise get a nice
7 closed proof. *)
8
9Record fin_queue_hl :=
10 FinQueueHl
11 { new : val;
12 enqueue : val;
13 finalize : val;
14 try_dequeue : val;}.
15Record fin_queue_iris {Σ} `{!heapGS Σ} (hl : fin_queue_hl) :=
16 FinQueueIris
17 { (** If [⊢ queue_repr ℓ vs mfin], then there is a queue at [ℓ]
18 which currently holds the values [vs], and possibly a final
19 value [mfin]. The dequeue and enqueue operations work in
20 FIFO fashion, with [head vs] (if any) representing the next
21 value that would be dequeued by a [try_dequeue ℓ] operation.
22
23 Only non-finalized queues can be enqueued in. Non-finalized queues
24 can be finalized using the [finalize ℓ v] operation, which sets
25 [mfin] to [v]. Subsequent [try_dequeue ℓ] operations then first
26 dequeue the remainder of [vs]; when [vs] is empty, they return [mfin]
27 (but, critically, do not unset it). *)
28 queue_repr : loc → list val → option val → iProp Σ;
29 #[global] queue_repr_timeless ℓ vs mfin :: Timeless (queue_repr ℓ vs mfin);
30
31 (** If [⊢ queue_fin ℓ v], then the queue at [ℓ] has been
32 finalized and all elements except for the final element [v]
33 have been dequeued.
34
35 Queues that enter this state never leave this state; this
36 allows [queue_fin ℓ v] to be a persistent proposition. *)
37 queue_fin : loc → val → iProp Σ;
38 #[global] queue_fin_persistent ℓ v :: Persistent (queue_fin ℓ v);
39 #[global] queue_fin_timeless ℓ v :: Timeless (queue_fin ℓ v);
40 queue_fin_obtain ℓ fin : queue_repr ℓ [] (Some fin) -∗ queue_fin ℓ fin;
41 queue_fin_agree ℓ vs fin mfin :
42 queue_fin ℓ fin -∗
43 queue_repr ℓ vs mfin -∗
44 ⌜vs = []⌝ ∗ ⌜mfin = Some fin⌝;
45
46 new_spec :
47 {{{ True }}}
48 hl.(new) #()
49 {{{ (ℓ : loc), RET #ℓ; queue_repr ℓ [] None }}};
50
51 enqueue_spec (ℓ_q : loc) (data : val) :
52 ⊢ <<{ ∀∀ vs, queue_repr ℓ_q vs None }>>
53 hl.(enqueue) #ℓ_q data @ ∅
54 <<{ queue_repr ℓ_q (vs ++ [data]) None | RET #() }>>;
55
56 finalize_spec (ℓ_q : loc) (data : val) :
57 ⊢ <<{ ∀∀ vs, queue_repr ℓ_q vs None }>>
58 hl.(finalize) #ℓ_q data @ ∅
59 <<{ queue_repr ℓ_q vs (Some data) | RET #() }>>;
60
61 try_dequeue_spec (ℓ_q : loc) :
62 ⊢ <<{ ∀∀ vs mfin, queue_repr ℓ_q vs mfin }>>
63 hl.(try_dequeue) #ℓ_q @ ∅
64 <<{ queue_repr ℓ_q (tail vs) mfin
65 | RET (if head vs is Some v then InjLV v else InjRV (val_opt_hl mfin)) }>>;
66 }.
67#[global] Arguments fin_queue_iris _ {_} _ : assert.