vstd_extra/resource/storage_protocol/
frac.rs1use vstd::map::*;
3use vstd::pcm::Loc;
4use vstd::prelude::*;
5use vstd::storage_protocol::*;
6
7verus! {
8
9broadcast use group_map_axioms;
10
11#[verifier::ext_equal]
13pub ghost enum FracP<T> {
14 Unit,
15 Frac(real, T),
16 Invalid,
17}
18
19impl<T> Protocol<(), T> for FracP<T> {
20 open spec fn op(self, other: Self) -> Self {
21 match (self, other) {
22 (FracP::Unit, x) => x,
23 (x, FracP::Unit) => x,
24 (FracP::Frac(q1, v1), FracP::Frac(q2, v2)) => {
25 if v1 == v2 && 0.0real < q1 && 0.0real < q2 && q1 + q2 <= 1.0real {
26 FracP::Frac(q1 + q2, v1)
27 } else {
28 FracP::Invalid
29 }
30 },
31 _ => FracP::Invalid,
32 }
33 }
34
35 open spec fn rel(self, s: Map<(), T>) -> bool {
36 match self {
37 FracP::Frac(q, v) => {
38 &&& s.contains_key(())
39 &&& s[()] == v
40 &&& q == 1.0real
41 },
42 _ => false,
43 }
44 }
45
46 open spec fn unit() -> Self {
47 FracP::Unit
48 }
49
50 proof fn commutative(a: Self, b: Self) {
51 }
52
53 proof fn associative(a: Self, b: Self, c: Self) {
54 }
55
56 proof fn op_unit(a: Self) {
57 }
58}
59
60impl<T> FracP<T> {
61 pub open spec fn frac(self) -> real {
62 match self {
63 FracP::Frac(q, _) => q,
64 _ => 0.0real,
65 }
66 }
67
68 pub open spec fn new(v: T) -> Self {
69 FracP::Frac(1.0real, v)
70 }
71
72 pub open spec fn construct_frac(q: real, v: T) -> Self {
73 FracP::Frac(q, v)
74 }
75
76 pub open spec fn value(self) -> T
77 recommends
78 self is Frac,
79 {
80 match self {
81 FracP::Frac(_, v) => v,
82 _ => arbitrary(),
83 }
84 }
85
86 pub proof fn lemma_guards(self)
87 requires
88 self is Frac,
89 ensures
90 guards::<(), T, Self>(self, map![() => self.value()]),
91 {
92 }
93}
94
95}