11use super :: super :: modes:: * ;
22use super :: super :: prelude:: * ;
33use super :: Loc ;
4+ use super :: agree:: AgreementRA ;
5+ use super :: algebra:: Resource ;
46use super :: algebra:: ResourceAlgebra ;
57use super :: pcm:: PCM ;
6- use super :: pcm :: Resource ;
8+ use super :: product :: ProductRA ;
79use super :: storage_protocol:: * ;
810use super :: * ;
911
1012verus ! {
1113
1214broadcast 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> {
126125impl <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