-
Notifications
You must be signed in to change notification settings - Fork 1
/
code_ms_tailcas.v
76 lines (67 loc) · 1.92 KB
/
code_ms_tailcas.v
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
From gpfsl.lang Require Export notation.
From gpfsl.logic Require Import repeat_loop new_delete.
Require Import iris.prelude.options.
Notation link := 0 (only parsing).
Notation data := 1 (only parsing).
Notation head := 0 (only parsing).
Notation tail := 1 (only parsing).
Notation null := 0 (only parsing).
Notation EMPTY := 0 (only parsing).
Notation FAIL_RACE := (-1) (only parsing).
Definition new_queue : val :=
λ: [],
let: "s" := new [ #1] in
"s" +ₗ #link <- #null ;;
let: "q" := new [ #2] in
"q" +ₗ #head <- "s" ;;
"q" +ₗ #tail <- "s" ;;
"q"
.
Definition find_tail : val :=
λ: ["q"],
let: "n" := !ᵃᶜ ("q" +ₗ #tail) in
let: "n'" := !ᵃᶜ ("n" +ₗ #link) in
if: "n'" = #null
then "n"
else
casʳᵉˡ("q" +ₗ #tail, "n", "n'");;
#false
.
Definition try_enq : val :=
λ: ["q"; "x"],
let: "n" := new [ #2] in
"n" +ₗ #data <- "x" ;;
"n" +ₗ #link <- #null ;;
let: "t" := (repeat: (find_tail ["q"])) in
if: casʳᵃ("t" +ₗ #link, #null, "n")
then casʳᵉˡ("q" +ₗ #tail, "t", "n");; #true
else delete [ #2; "n"] ;; #false
.
Definition enqueue : val :=
rec: "try" ["q"; "x"] :=
if: try_enq ["q"; "x"]
then #☠
else "try" ["q"; "x"]
.
Definition try_deq : val :=
λ: ["q"],
let: "s" := !ᵃᶜ ("q" +ₗ #head) in
let: "n" := !ᵃᶜ ("s" +ₗ #link) in
if: "n" = #null
then #EMPTY
else
if: casʳᵃ("q" +ₗ #head, "s", "n")
then ! ("n" +ₗ #data)
else #FAIL_RACE
.
(* Keep retrying if FAIL_RACE *)
Definition dequeue : val :=
rec: "try" ["q"] :=
let: "n" := try_deq ["q"] in
(* FIXME: our language doesn't have comparison for arbitrary literals, so
the next line is limited to integer comparison, which means that
the queue is only intended for use with integers. *)
if: #EMPTY ≤ "n"
then "n"
else "try" ["q"]
.