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
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> {
126121impl <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