summaryrefslogtreecommitdiffstats
path: root/theories/lmpmc_queue_spec.v
blob: 0ea3a4a316a391fbfbd447e034bb1eeedf763501 (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
From iris.program_logic Require Import atomic.
From iris.heap_lang Require Import notation proofmode.

From lmpmc Require Import util.

Record lmpmc_queue_hl :=
  LmpmcQueueHl
    { new : val;
      enqueue : val;
      try_dequeue : val;
      link : val;
    }.

Record lmpmc_queue_iris {Σ} `{!heapGS Σ} (hl : lmpmc_queue_hl) :=
  LmpmcQueueIris
    { queue_repr : loc → loc → list val → iProp Σ;
      #[global] queue_repr_timeless ℓ_deq ℓ_enq vs :: Timeless (queue_repr ℓ_deq ℓ_enq vs);

      new_spec :
        {{{ True }}}
          hl.(new) #()
        {{{ (ℓ_deq ℓ_enq : loc), RET (#ℓ_deq, #ℓ_enq); queue_repr ℓ_deq ℓ_enq [] }}};

      enqueue_spec (ℓ_enq : loc) (data : val) :<<{ ∀∀ ℓ_deq cvs, queue_repr ℓ_deq ℓ_enq cvs }>>
            hl.(enqueue) #ℓ_enq data @<<{ queue_repr ℓ_deq ℓ_enq (cvs ++ [data]) | RET #() }>>;

      try_dequeue_spec (ℓ_deq : loc) :<<{ ∀∀ ℓ_enq cvs, queue_repr ℓ_deq ℓ_enq cvs }>>
            hl.(try_dequeue) #ℓ_deq @<<{ queue_repr ℓ_deq ℓ_enq (tail cvs) | RET (val_opt_hl (head cvs)) }>>;

      (** Linking two queues:
       *     _______________      _______________
       *    /      Q1       \    /       Q2      \
       *    ℓ_deq1 ... ℓ_enq1 <> ℓ_deq2 ... ℓ_enq2
       *    \          \ link op args /          /
       *     \          \____________/          /
       *      \            Q1 <> Q2            /
       *       \______________________________/
       *)
      link_spec (ℓ_enq1 ℓ_deq2 : loc) :<<{ ∀∀ (b : bool) ℓ_deq1 ℓ_enq2 cvs1 cvs2, queue_repr ℓ_deq1 ℓ_enq1 cvs1 ∗
                            if b then queue_repr ℓ_deq2 ℓ_enq2 cvs2 else ⌜ℓ_deq1 = ℓ_deq2 ∧ ℓ_enq1 = ℓ_enq2⌝ }>>
            hl.(link) #ℓ_enq1 #ℓ_deq2 @<<{ if b then queue_repr ℓ_deq1 ℓ_enq2 (cvs1 ++ cvs2) else True | RET #() }>>;
    }.
#[global] Arguments lmpmc_queue_iris _ {_} _ : assert.