Skip to content

Commit 9bae3df

Browse files
committed
resource: add simpler fractional resource on reals
This can be reusable for fractional resources
1 parent 338f73e commit 9bae3df

File tree

1 file changed

+60
-47
lines changed

1 file changed

+60
-47
lines changed

source/vstd/resource/frac.rs

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,42 @@
11
use super::super::modes::*;
22
use super::super::prelude::*;
33
use super::Loc;
4+
use super::agree::AgreementRA;
5+
use super::algebra::Resource;
46
use super::algebra::ResourceAlgebra;
57
use super::pcm::PCM;
6-
use super::pcm::Resource;
8+
use super::product::ProductRA;
79
use super::storage_protocol::*;
810
use super::*;
911

1012
verus! {
1113

1214
broadcast use {super::super::map::group_map_axioms, super::super::set::group_set_axioms};
1315

14-
enum FractionalCarrier<T> {
15-
Value { v: T, frac: real },
16-
Empty,
16+
pub enum FractionRA {
17+
Frac(real),
1718
Invalid,
1819
}
1920

20-
impl<T> FractionalCarrier<T> {
21-
spec fn new(v: T) -> Self {
22-
FractionalCarrier::Value { v: v, frac: (1 as real) }
23-
}
24-
}
25-
26-
impl<T> ResourceAlgebra for FractionalCarrier<T> {
21+
impl ResourceAlgebra for FractionRA {
2722
closed spec fn valid(self) -> bool {
2823
match self {
29-
FractionalCarrier::Invalid => false,
30-
FractionalCarrier::Empty => true,
31-
FractionalCarrier::Value { frac, .. } => (0 as real) < frac <= (1 as real),
24+
FractionRA::Invalid => false,
25+
FractionRA::Frac(frac) => (0 as real) < frac <= (1 as real),
3226
}
3327
}
3428

3529
closed spec fn op(a: Self, b: Self) -> Self {
3630
match (a, b) {
37-
(FractionalCarrier::Invalid, _) => FractionalCarrier::Invalid,
38-
(_, FractionalCarrier::Invalid) => FractionalCarrier::Invalid,
39-
(FractionalCarrier::Empty, _) => b,
40-
(_, FractionalCarrier::Empty) => a,
41-
(
42-
FractionalCarrier::Value { v: a_v, frac: a_frac },
43-
FractionalCarrier::Value { v: b_v, frac: b_frac },
44-
) => {
45-
if a_v != b_v {
46-
FractionalCarrier::Invalid
47-
} else if a_frac <= (0 as real) || b_frac <= (0 as real) {
48-
FractionalCarrier::Invalid
49-
} else if a_frac + b_frac > (1 as real) {
50-
FractionalCarrier::Invalid
31+
(FractionRA::Invalid, _) => FractionRA::Invalid,
32+
(_, FractionRA::Invalid) => FractionRA::Invalid,
33+
(FractionRA::Frac(a_frac), FractionRA::Frac(b_frac)) => {
34+
if !a.valid() || !b.valid() {
35+
FractionRA::Invalid
36+
} else if a_frac + b_frac <= (1 as real) {
37+
FractionRA::Frac(a_frac + b_frac)
5138
} else {
52-
FractionalCarrier::Value { v: a_v, frac: a_frac + b_frac }
39+
FractionRA::Invalid
5340
}
5441
},
5542
}
@@ -65,18 +52,30 @@ impl<T> ResourceAlgebra for FractionalCarrier<T> {
6552
}
6653
}
6754

68-
impl<T> PCM for FractionalCarrier<T> {
69-
closed spec fn unit() -> Self {
70-
FractionalCarrier::Empty
71-
}
72-
73-
proof fn op_unit(self) {
74-
}
75-
76-
proof fn unit_valid() {
55+
pub proof fn lemma_whole_fraction_has_no_frame(a: FractionRA)
56+
requires
57+
a == FractionRA::Frac(1 as real),
58+
ensures
59+
forall|b: FractionRA|
60+
#![trigger FractionRA::op(a, b).valid()]
61+
!FractionRA::op(a, b).valid(),
62+
{
63+
assert forall|b: FractionRA|
64+
#![trigger FractionRA::op(a, b).valid()]
65+
!FractionRA::op(a, b).valid() by {
66+
if FractionRA::op(a, b).valid() {
67+
FractionRA::commutative(a, b);
68+
FractionRA::valid_op(b, a);
69+
assert(b.valid());
70+
assert(b is Frac);
71+
assert((0 as real) < b->Frac_0 <= (1 as real));
72+
assert(a->Frac_0 + b->Frac_0 > (1 as real)); // CONTRADICTION
73+
};
7774
}
7875
}
7976

77+
type FractionalCarrier<T> = ProductRA<FractionRA, AgreementRA<T>>;
78+
8079
/// An implementation of a resource for fractional ownership of a ghost variable.
8180
///
8281
/// If you just want to split the permission in half, you can also use the
@@ -126,20 +125,21 @@ pub tracked struct FracGhost<T> {
126125
impl<T> FracGhost<T> {
127126
#[verifier::type_invariant]
128127
spec fn inv(self) -> bool {
129-
self.r.value() is Value
128+
&&& self.r.value().left is Frac
129+
&&& self.r.value().right is Agree
130130
}
131131

132132
pub closed spec fn id(self) -> Loc {
133133
self.r.loc()
134134
}
135135

136136
pub closed spec fn view(self) -> T {
137-
self.r.value()->v
137+
self.r.value().right->Agree_0
138138
}
139139

140140
/// The fractional quantity of this permission
141141
pub closed spec fn frac(self) -> real {
142-
self.r.value()->frac
142+
self.r.value().left->Frac_0
143143
}
144144

145145
pub open spec fn valid(self, id: Loc, frac: real) -> bool {
@@ -153,7 +153,10 @@ impl<T> FracGhost<T> {
153153
result.frac() == 1 as real,
154154
result@ == v,
155155
{
156-
let f = FractionalCarrier::<T>::new(v);
156+
let f = FractionalCarrier {
157+
left: FractionRA::Frac(1 as real),
158+
right: AgreementRA::Agree(v),
159+
};
157160
let tracked r = Resource::alloc(f);
158161
Self { r }
159162
}
@@ -167,7 +170,7 @@ impl<T> FracGhost<T> {
167170
{
168171
use_type_invariant(self);
169172
use_type_invariant(other);
170-
let tracked joined = self.r.join_shared(&other.r);
173+
let tracked joined = self.r.as_ref().join_shared(&other.r.as_ref());
171174
joined.validate()
172175
}
173176

@@ -201,8 +204,14 @@ impl<T> FracGhost<T> {
201204
tracked_swap(self, &mut mself);
202205
use_type_invariant(&mself);
203206
let tracked (r1, r2) = mself.r.split(
204-
FractionalCarrier::Value { v: mself.r.value()->v, frac: self_frac - result_frac },
205-
FractionalCarrier::Value { v: mself.r.value()->v, frac: result_frac },
207+
FractionalCarrier {
208+
left: FractionRA::Frac(self_frac - result_frac),
209+
right: AgreementRA::Agree(mself@),
210+
},
211+
FractionalCarrier {
212+
left: FractionRA::Frac(result_frac),
213+
right: AgreementRA::Agree(mself@),
214+
},
206215
);
207216
self.r = r1;
208217
Self { r: r2 }
@@ -239,7 +248,7 @@ impl<T> FracGhost<T> {
239248
use_type_invariant(&mself);
240249
use_type_invariant(&other);
241250
let tracked mut r = mself.r;
242-
r.validate_2(&other.r);
251+
r.validate_2(&other.r.as_ref());
243252
*self = Self { r: r.join(other.r) };
244253
}
245254

@@ -257,7 +266,11 @@ impl<T> FracGhost<T> {
257266
tracked_swap(self, &mut mself);
258267
use_type_invariant(&mself);
259268
let tracked mut r = mself.r;
260-
let f = FractionalCarrier::<T>::Value { v, frac: (1 as real) };
269+
let f = FractionalCarrier {
270+
left: FractionRA::Frac(1 as real),
271+
right: AgreementRA::Agree(v),
272+
};
273+
lemma_whole_fraction_has_no_frame(r.value().left);
261274
*self = Self { r: r.update(f) };
262275
}
263276

0 commit comments

Comments
 (0)