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 :: * ;
911use crate :: assert_by_contradiction;
@@ -12,72 +14,65 @@ verus! {
1214
1315broadcast 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> {
127122impl <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