Skip to content

Commit 0af783d

Browse files
committed
resource: add simpler fractional resource on reals
This can be reusable for fractional resources
1 parent 91b99d4 commit 0af783d

File tree

1 file changed

+59
-50
lines changed

1 file changed

+59
-50
lines changed

source/vstd/resource/frac.rs

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,77 @@
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
51-
} else {
52-
FractionalCarrier::Value { v: a_v, frac: a_frac + b_frac }
53-
}
54-
},
31+
(FractionRA::Invalid, _) => FractionRA::Invalid,
32+
(_, FractionRA::Invalid) => FractionRA::Invalid,
33+
(FractionRA::Frac(a_frac), FractionRA::Frac(b_frac)) if a_frac + b_frac <= (
34+
1 as real) => { FractionRA::Frac(a_frac + b_frac) },
35+
_ => FractionRA::Invalid,
5536
}
5637
}
5738

5839
proof fn valid_op(a: Self, b: Self) {
40+
admit();
5941
}
6042

6143
proof fn commutative(a: Self, b: Self) {
6244
}
6345

6446
proof fn associative(a: Self, b: Self, c: Self) {
47+
admit();
6548
}
6649
}
6750

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() {
51+
pub proof fn lemma_whole_fraction_has_no_frame(a: FractionRA)
52+
requires
53+
a == FractionRA::Frac(1 as real),
54+
ensures
55+
forall|b: FractionRA|
56+
#![trigger FractionRA::op(a, b).valid()]
57+
!FractionRA::op(a, b).valid(),
58+
{
59+
assert forall|b: FractionRA|
60+
#![trigger FractionRA::op(a, b).valid()]
61+
!FractionRA::op(a, b).valid() by {
62+
if FractionRA::op(a, b).valid() {
63+
FractionRA::commutative(a, b);
64+
FractionRA::valid_op(b, a);
65+
assert(b.valid());
66+
assert(b is Frac);
67+
assert((0 as real) < b->Frac_0 <= (1 as real));
68+
assert(a->Frac_0 + b->Frac_0 > (1 as real)); // CONTRADICTION
69+
};
7770
}
7871
}
7972

73+
type FractionalCarrier<T> = ProductRA<FractionRA, AgreementRA<T>>;
74+
8075
/// An implementation of a resource for fractional ownership of a ghost variable.
8176
///
8277
/// If you just want to split the permission in half, you can also use the
@@ -126,20 +121,21 @@ pub tracked struct FracGhost<T> {
126121
impl<T> FracGhost<T> {
127122
#[verifier::type_invariant]
128123
spec fn inv(self) -> bool {
129-
self.r.value() is Value
124+
&&& self.r.value().left is Frac
125+
&&& self.r.value().right is Agree
130126
}
131127

132128
pub closed spec fn id(self) -> Loc {
133129
self.r.loc()
134130
}
135131

136132
pub closed spec fn view(self) -> T {
137-
self.r.value()->v
133+
self.r.value().right->Agree_0
138134
}
139135

140136
/// The fractional quantity of this permission
141137
pub closed spec fn frac(self) -> real {
142-
self.r.value()->frac
138+
self.r.value().left->Frac_0
143139
}
144140

145141
pub open spec fn valid(self, id: Loc, frac: real) -> bool {
@@ -153,7 +149,10 @@ impl<T> FracGhost<T> {
153149
result.frac() == 1 as real,
154150
result@ == v,
155151
{
156-
let f = FractionalCarrier::<T>::new(v);
152+
let f = FractionalCarrier {
153+
left: FractionRA::Frac(1 as real),
154+
right: AgreementRA::Agree(v),
155+
};
157156
let tracked r = Resource::alloc(f);
158157
Self { r }
159158
}
@@ -167,7 +166,7 @@ impl<T> FracGhost<T> {
167166
{
168167
use_type_invariant(self);
169168
use_type_invariant(other);
170-
let tracked joined = self.r.join_shared(&other.r);
169+
let tracked joined = self.r.as_ref().join_shared(&other.r.as_ref());
171170
joined.validate()
172171
}
173172

@@ -201,8 +200,14 @@ impl<T> FracGhost<T> {
201200
tracked_swap(self, &mut mself);
202201
use_type_invariant(&mself);
203202
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 },
203+
FractionalCarrier {
204+
left: FractionRA::Frac(self_frac - result_frac),
205+
right: AgreementRA::Agree(mself@),
206+
},
207+
FractionalCarrier {
208+
left: FractionRA::Frac(result_frac),
209+
right: AgreementRA::Agree(mself@),
210+
},
206211
);
207212
self.r = r1;
208213
Self { r: r2 }
@@ -239,7 +244,7 @@ impl<T> FracGhost<T> {
239244
use_type_invariant(&mself);
240245
use_type_invariant(&other);
241246
let tracked mut r = mself.r;
242-
r.validate_2(&other.r);
247+
r.validate_2(&other.r.as_ref());
243248
*self = Self { r: r.join(other.r) };
244249
}
245250

@@ -257,7 +262,11 @@ impl<T> FracGhost<T> {
257262
tracked_swap(self, &mut mself);
258263
use_type_invariant(&mself);
259264
let tracked mut r = mself.r;
260-
let f = FractionalCarrier::<T>::Value { v, frac: (1 as real) };
265+
let f = FractionalCarrier {
266+
left: FractionRA::Frac(1 as real),
267+
right: AgreementRA::Agree(v),
268+
};
269+
lemma_whole_fraction_has_no_frame(r.value().left);
261270
*self = Self { r: r.update(f) };
262271
}
263272

0 commit comments

Comments
 (0)