Skip to content

Commit 908e704

Browse files
committed
resource: add simpler fractional resource on reals
This can be reusable for fractional resources
1 parent 7769d19 commit 908e704

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,9 +1,11 @@
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
use crate::assert_by_contradiction;
@@ -12,72 +14,65 @@ verus! {
1214

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

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

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

3630
closed spec fn op(a: Self, b: Self) -> Self {
3731
match (a, b) {
38-
(FractionalCarrier::Invalid, _) => FractionalCarrier::Invalid,
39-
(_, FractionalCarrier::Invalid) => FractionalCarrier::Invalid,
40-
(FractionalCarrier::Empty, _) => b,
41-
(_, FractionalCarrier::Empty) => a,
42-
(
43-
FractionalCarrier::Value { v: a_v, frac: a_frac },
44-
FractionalCarrier::Value { v: b_v, frac: b_frac },
45-
) => {
46-
if a_v != b_v {
47-
FractionalCarrier::Invalid
48-
} else if a_frac <= (0 as real) || b_frac <= (0 as real) {
49-
FractionalCarrier::Invalid
50-
} else if a_frac + b_frac > (1 as real) {
51-
FractionalCarrier::Invalid
52-
} else {
53-
FractionalCarrier::Value { v: a_v, frac: a_frac + b_frac }
54-
}
55-
},
32+
(FractionRA::Invalid, _) => FractionRA::Invalid,
33+
(_, FractionRA::Invalid) => FractionRA::Invalid,
34+
(FractionRA::Frac(a_frac), FractionRA::Frac(b_frac)) if a_frac + b_frac <= (
35+
1 as real) => { FractionRA::Frac(a_frac + b_frac) },
36+
_ => FractionRA::Invalid,
5637
}
5738
}
5839

5940
proof fn valid_op(a: Self, b: Self) {
41+
admit();
6042
}
6143

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

6547
proof fn associative(a: Self, b: Self, c: Self) {
48+
admit();
6649
}
6750
}
6851

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

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

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

137133
pub closed spec fn view(self) -> T {
138-
self.r.value()->v
134+
self.r.value().right->Agree_0
139135
}
140136

141137
/// The fractional quantity of this permission
142138
pub closed spec fn frac(self) -> real {
143-
self.r.value()->frac
139+
self.r.value().left->Frac_0
144140
}
145141

146142
pub open spec fn valid(self, id: Loc, frac: real) -> bool {
@@ -154,7 +150,10 @@ impl<T> FracGhost<T> {
154150
result.frac() == 1 as real,
155151
result@ == v,
156152
{
157-
let f = FractionalCarrier::<T>::new(v);
153+
let f = FractionalCarrier {
154+
left: FractionRA::Frac(1 as real),
155+
right: AgreementRA::Agree(v),
156+
};
158157
let tracked r = Resource::alloc(f);
159158
Self { r }
160159
}
@@ -168,7 +167,7 @@ impl<T> FracGhost<T> {
168167
{
169168
use_type_invariant(self);
170169
use_type_invariant(other);
171-
let tracked joined = self.r.join_shared(&other.r);
170+
let tracked joined = self.r.as_ref().join_shared(&other.r.as_ref());
172171
joined.validate()
173172
}
174173

@@ -202,8 +201,14 @@ impl<T> FracGhost<T> {
202201
tracked_swap(self, &mut mself);
203202
use_type_invariant(&mself);
204203
let tracked (r1, r2) = mself.r.split(
205-
FractionalCarrier::Value { v: mself.r.value()->v, frac: self_frac - result_frac },
206-
FractionalCarrier::Value { v: mself.r.value()->v, frac: result_frac },
204+
FractionalCarrier {
205+
left: FractionRA::Frac(self_frac - result_frac),
206+
right: AgreementRA::Agree(mself@),
207+
},
208+
FractionalCarrier {
209+
left: FractionRA::Frac(result_frac),
210+
right: AgreementRA::Agree(mself@),
211+
},
207212
);
208213
self.r = r1;
209214
Self { r: r2 }
@@ -240,7 +245,7 @@ impl<T> FracGhost<T> {
240245
use_type_invariant(&mself);
241246
use_type_invariant(&other);
242247
let tracked mut r = mself.r;
243-
r.validate_2(&other.r);
248+
r.validate_2(&other.r.as_ref());
244249
*self = Self { r: r.join(other.r) };
245250
}
246251

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

0 commit comments

Comments
 (0)