-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcounter_monotonic.rav
63 lines (51 loc) · 1.01 KB
/
counter_monotonic.rav
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
import Library.Auth
import Library.MaxNat
field c: Int
module AuthMaxNat = Auth[MaxNat]
import AuthMaxNat._
ghost field h: AuthMaxNat
inv counterInv(x: Ref) {
exists v: Int :: own(x.h, auth_frag(v,v)) && own(x.c, v, 1.0)
}
proc incr(x: Ref)
requires counterInv(x)
ensures counterInv(x)
{
var v1: Int;
unfold counterInv(x);
v1 := x.c;
fold counterInv(x);
var new_v1 : Int := v1 + 1;
var res: Bool;
ghost var v2: Int;
unfold counterInv(x);
v2 :| own(x.c, v2, 1.0);
assert v1 <= v2;
res := cas(x.c, v1, new_v1);
if (!res) {
fold counterInv(x);
incr(x);
} else {
// Frame preserving update of ghost resource x.h
fpu(x.h, auth_frag(v1,v1), auth_frag(new_v1,new_v1));
fold counterInv(x);
}
}
proc read(x: Ref)
returns (v: Int)
requires counterInv(x)
ensures counterInv(x)
{
unfold counterInv(x);
v := x.c;
fold counterInv(x);
return v;
}
proc make()
returns (x: Ref)
ensures counterInv(x)
{
x := new(c: 0);
// fold counterInv(x);
assume false;
}