1+ use super :: super :: assert_by_contradiction;
12use super :: super :: modes:: * ;
23use super :: super :: prelude:: * ;
34use super :: Loc ;
5+ use super :: agree:: AgreementRA ;
6+ use super :: algebra:: Resource ;
47use super :: algebra:: ResourceAlgebra ;
58use super :: pcm:: PCM ;
6- use super :: pcm :: Resource ;
9+ use super :: product :: ProductRA ;
710use super :: storage_protocol:: * ;
811use super :: * ;
912
1013verus ! {
1114
1215broadcast use { super :: super :: map:: group_map_axioms, super :: super :: set:: group_set_axioms} ;
1316
14- enum FractionalCarrier <T > {
15- Value { v: T , frac: real } ,
16- Empty ,
17+ pub enum FractionRA {
18+ Frac ( real) ,
1719 Invalid ,
1820}
1921
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 > {
22+ impl ResourceAlgebra for FractionRA {
2723 closed spec fn valid( self ) -> bool {
2824 match self {
29- FractionalCarrier :: Invalid => false ,
30- FractionalCarrier :: Empty => true ,
31- 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) ,
3227 }
3328 }
3429
3530 closed spec fn op( a: Self , b: Self ) -> Self {
3631 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- } ,
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 ,
5537 }
5638 }
5739
5840 proof fn valid_op( a: Self , b: Self ) {
41+ admit( ) ;
5942 }
6043
6144 proof fn commutative( a: Self , b: Self ) {
6245 }
6346
6447 proof fn associative( a: Self , b: Self , c: Self ) {
48+ admit( ) ;
6549 }
6650}
6751
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( ) {
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+ } ) ;
7771 }
7872}
7973
74+ type FractionalCarrier <T > = ProductRA <FractionRA , AgreementRA <T >>;
75+
8076/// An implementation of a resource for fractional ownership of a ghost variable.
8177///
8278/// If you just want to split the permission in half, you can also use the
@@ -126,20 +122,21 @@ pub tracked struct FracGhost<T> {
126122impl <T > FracGhost <T > {
127123 #[ verifier:: type_invariant]
128124 spec fn inv( self ) -> bool {
129- self . r. value( ) is Value
125+ &&& self . r. value( ) . left is Frac
126+ &&& self . r. value( ) . right is Agree
130127 }
131128
132129 pub closed spec fn id( self ) -> Loc {
133130 self . r. loc( )
134131 }
135132
136133 pub closed spec fn view( self ) -> T {
137- self . r. value( ) ->v
134+ self . r. value( ) . right-> Agree_0
138135 }
139136
140137 /// The fractional quantity of this permission
141138 pub closed spec fn frac( self ) -> real {
142- self . r. value( ) ->frac
139+ self . r. value( ) . left-> Frac_0
143140 }
144141
145142 pub open spec fn valid( self , id: Loc , frac: real) -> bool {
@@ -153,7 +150,10 @@ impl<T> FracGhost<T> {
153150 result. frac( ) == 1 as real,
154151 result@ == v,
155152 {
156- let f = FractionalCarrier :: <T >:: new( v) ;
153+ let f = FractionalCarrier {
154+ left: FractionRA :: Frac ( 1 as real) ,
155+ right: AgreementRA :: Agree ( v) ,
156+ } ;
157157 let tracked r = Resource :: alloc( f) ;
158158 Self { r }
159159 }
@@ -201,8 +201,14 @@ impl<T> FracGhost<T> {
201201 tracked_swap( self , & mut mself) ;
202202 use_type_invariant( & mself) ;
203203 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 } ,
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+ } ,
206212 ) ;
207213 self . r = r1;
208214 Self { r: r2 }
@@ -257,7 +263,11 @@ impl<T> FracGhost<T> {
257263 tracked_swap( self , & mut mself) ;
258264 use_type_invariant( & mself) ;
259265 let tracked mut r = mself. r;
260- 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) ;
261271 * self = Self { r: r. update( f) } ;
262272 }
263273
0 commit comments