pub struct SumResource<A, B, const TOTAL: u64 = 2> { /* private fields */ }Expand description
SumResource is a token that maintains access to a resource of either type A or type B.
It can be split into up to TOTAL fractions, one of which have the exclusive right to access the resource,
and others shares the knowledge of the resource’s existence and type, but not the ability to access it.
Implementations§
Source§impl<A, B, const TOTAL: u64> SumResource<A, B, TOTAL>
impl<A, B, const TOTAL: u64> SumResource<A, B, TOTAL>
Sourcepub closed spec fn protocol_monoid(self) -> CsumP<A, B, TOTAL>
pub closed spec fn protocol_monoid(self) -> CsumP<A, B, TOTAL>
The underlying protocol monoid value for this resource.
Sourcepub open spec fn is_resource_owner(self) -> bool
pub open spec fn is_resource_owner(self) -> bool
{ self.protocol_monoid().is_resource_owner() }Whether this token has the right to access the underlying resource.
Sourcepub open spec fn resource(self) -> Sum<A, B>
pub open spec fn resource(self) -> Sum<A, B>
{ self.protocol_monoid().resource() }The resource value, only meaningful if is_resource_owner is true.
Sourcepub open spec fn resource_left(self) -> A
pub open spec fn resource_left(self) -> A
{ self.resource()->Left_0 }The resource value if this token is in the left variant, only meaningful if is_resource_owner is true.
Sourcepub open spec fn resource_right(self) -> B
pub open spec fn resource_right(self) -> B
{ self.resource()->Right_0 }The resource value if this token is in the right variant, only meaningful if is_resource_owner is true.
Sourcepub open spec fn is_left(self) -> bool
pub open spec fn is_left(self) -> bool
{ self.protocol_monoid().is_left() }Whether this token is a Left variant.
Sourcepub open spec fn is_right(self) -> bool
pub open spec fn is_right(self) -> bool
{ self.protocol_monoid().is_right() }Whether this token is a Right variant.
Sourcepub open spec fn has_resource(self) -> bool
pub open spec fn has_resource(self) -> bool
{
let p = self.protocol_monoid();
p.is_resource_owner() && p.has_resource()
}Whether the resource is currently stored, returns false if this token is not the resource owner.
Sourcepub open spec fn has_no_resource(self) -> bool
pub open spec fn has_no_resource(self) -> bool
{
let p = self.protocol_monoid();
p.is_resource_owner() && p.has_no_resource()
}Whether the resource has been taken, returns false if this token is not the resource owner.
Sourcepub open spec fn frac(self) -> int
pub open spec fn frac(self) -> int
{ self.protocol_monoid().frac() }The fraction this token represents.
Sourcepub open spec fn wf(self) -> bool
pub open spec fn wf(self) -> bool
{
&&& 1 <= self.frac() <= TOTAL
&&& self.protocol_monoid().is_valid()
&&& self.is_resource_owner() ==> (self.has_resource() <==> !self.has_no_resource())
&&& (self.is_left() <==> !self.is_right())
}Type invariant.
Sourcepub proof fn alloc_left(tracked a: A) -> tracked res : Self
pub proof fn alloc_left(tracked a: A) -> tracked res : Self
TOTAL > 0,ensuresres.is_left(),res.is_resource_owner(),res.has_resource(),res.resource() == Sum::<A, B>::Left(a),res.frac() == TOTAL,res.wf(),Allocates a new SumResource with the resource of type A.
Sourcepub proof fn alloc_right(tracked b: B) -> tracked res : Self
pub proof fn alloc_right(tracked b: B) -> tracked res : Self
TOTAL > 0,ensuresres.is_right(),res.is_resource_owner(),res.has_resource(),res.resource() == Sum::<A, B>::Right(b),res.frac() == TOTAL,res.wf(),Allocates a new SumResource with the resource of type B.
Sourcepub proof fn validate(tracked &self)
pub proof fn validate(tracked &self)
self.wf(),SumResource satisfies its type invariant.
Sourcepub proof fn validate_with_other(tracked &mut self, tracked other: &Self)
pub proof fn validate_with_other(tracked &mut self, tracked other: &Self)
old(self).is_left() && old(self).is_right() || other.is_left() && other.is_right()
|| old(self).is_left() && other.is_left() && old(self).is_resource_owner()
&& other.is_resource_owner()
|| old(self).is_right() && other.is_right() && old(self).is_resource_owner()
&& other.is_resource_owner(),ensures*old(self) == *self,self.id() != other.id(),self.wf(),Two SumResource tokens can not both be the resource owner unless they have different ids.
Sourcepub proof fn validate_with_left(tracked &mut self, tracked other: &Left<A, B, TOTAL>)
pub proof fn validate_with_left(tracked &mut self, tracked other: &Left<A, B, TOTAL>)
old(self).id() == other.id(),ensures*old(self) == *self,self.is_left(),!(self.is_resource_owner() && other.is_resource_owner()),self.frac() + other.frac() <= TOTAL,self.wf(),The existence of a Left token with the same id ensures this token is also a Left token.
Sourcepub proof fn validate_with_right(tracked &mut self, tracked other: &Right<A, B, TOTAL>)
pub proof fn validate_with_right(tracked &mut self, tracked other: &Right<A, B, TOTAL>)
old(self).id() == other.id(),ensures*old(self) == *self,self.is_right(),!(self.is_resource_owner() && other.is_resource_owner()),self.frac() + other.frac() <= TOTAL,self.wf(),The existence of a Right token with the same id ensures this token is also a Right token.
Sourcepub proof fn validate_with_one_left_owner(tracked
&mut self,
tracked other: &OneLeftOwner<A, B, TOTAL>,
)
pub proof fn validate_with_one_left_owner(tracked &mut self, tracked other: &OneLeftOwner<A, B, TOTAL>, )
old(self).id() == other.id(),ensures*old(self) == *self,self.is_left(),!self.is_resource_owner(),self.frac() + 1 <= TOTAL,self.wf(),The existence of a OneLeftOwner token with the same id ensures this token is a Left token that is not the resource owner.
Sourcepub proof fn validate_with_one_right_owner(tracked
&mut self,
tracked other: &OneRightOwner<A, B, TOTAL>,
)
pub proof fn validate_with_one_right_owner(tracked &mut self, tracked other: &OneRightOwner<A, B, TOTAL>, )
old(self).id() == other.id(),ensures*old(self) == *self,self.is_right(),!self.is_resource_owner(),self.frac() + 1 <= TOTAL,self.wf(),The existence of a OneRightOwner token with the same id ensures this token is a Right token that is not the resource owner.
Sourcepub proof fn validate_with_one_left_knowledge(tracked
&mut self,
tracked other: &OneLeftKnowledge<A, B, TOTAL>,
)
pub proof fn validate_with_one_left_knowledge(tracked &mut self, tracked other: &OneLeftKnowledge<A, B, TOTAL>, )
old(self).id() == other.id(),ensures*old(self) == *self,self.is_left(),self.frac() + 1 <= TOTAL,self.wf(),The existence of a OneLeftKnowledge token with the same id ensures this token is a Left token.
Sourcepub proof fn validate_with_one_right_knowledge(tracked
&mut self,
tracked other: &OneRightKnowledge<A, B, TOTAL>,
)
pub proof fn validate_with_one_right_knowledge(tracked &mut self, tracked other: &OneRightKnowledge<A, B, TOTAL>, )
old(self).id() == other.id(),ensures*old(self) == *self,self.is_right(),self.frac() + 1 <= TOTAL,self.wf(),The existence of a OneRightKnowledge token with the same id ensures this token is a Right token.
Sourcepub proof fn tracked_borrow_left(tracked &self) -> tracked res : &A
pub proof fn tracked_borrow_left(tracked &self) -> tracked res : &A
self.is_left(),self.is_resource_owner(),self.has_resource(),ensures*res == self.resource_left(),Borrows the resource of type A.
Sourcepub proof fn tracked_borrow_right(tracked &self) -> tracked res : &B
pub proof fn tracked_borrow_right(tracked &self) -> tracked res : &B
self.is_right(),self.is_resource_owner(),self.has_resource(),ensures*res == self.resource()->Right_0,Borrows the resource of type B.
Sourcepub proof fn split_left_with_resource(tracked &mut self, n: int) -> tracked res : Left<A, B, TOTAL>
pub proof fn split_left_with_resource(tracked &mut self, n: int) -> tracked res : Left<A, B, TOTAL>
old(self).is_left(),0 < n < old(self).frac(),ensuresself.id() == old(self).id(),self.frac() == old(self).frac() - n,res.id() == old(self).id(),res.frac() == n,!self.is_resource_owner(),res.is_resource_owner() <==> old(self).is_resource_owner(),res.is_resource_owner() ==> (res.has_resource() <==> old(self).has_resource()),res.has_resource() ==> res.resource() == old(self).resource_left(),self.wf(),res.wf(),Splits a Left token with the given fraction n, and gives the resource to that Left token if available.
Sourcepub proof fn split_left_without_resource(tracked &mut self, n: int) -> tracked res : Left<A, B, TOTAL>
pub proof fn split_left_without_resource(tracked &mut self, n: int) -> tracked res : Left<A, B, TOTAL>
old(self).is_left(),0 < n < old(self).frac(),ensuresself.id() == old(self).id(),self.frac() == old(self).frac() - n,res.id() == old(self).id(),res.frac() == n,!res.is_resource_owner(),self.is_resource_owner() <==> old(self).is_resource_owner(),self.is_resource_owner() ==> (self.has_resource() <==> old(self).has_resource()),self.has_resource() ==> self.resource() == old(self).resource(),self.wf(),res.wf(),Splits a Left token with the given fraction n, without giving the resource to the Left token.
Sourcepub proof fn split_right_with_resource(tracked &mut self, n: int) -> tracked res : Right<A, B, TOTAL>
pub proof fn split_right_with_resource(tracked &mut self, n: int) -> tracked res : Right<A, B, TOTAL>
old(self).is_right(),0 < n < old(self).frac(),ensuresself.id() == old(self).id(),self.frac() == old(self).frac() - n,res.id() == old(self).id(),res.frac() == n,!self.is_resource_owner(),res.is_resource_owner() <==> old(self).is_resource_owner(),res.is_resource_owner() ==> (res.has_resource() <==> old(self).has_resource()),res.has_resource() ==> res.resource() == old(self).resource_right(),self.wf(),res.wf(),Splits a Right token with the given fraction n, and gives the resource to that Right token if available.
Sourcepub proof fn split_right_without_resource(tracked &mut self, n: int) -> tracked res : Right<A, B, TOTAL>
pub proof fn split_right_without_resource(tracked &mut self, n: int) -> tracked res : Right<A, B, TOTAL>
old(self).is_right(),0 < n < old(self).frac(),ensuresself.id() == old(self).id(),self.frac() == old(self).frac() - n,res.id() == old(self).id(),res.frac() == n,!res.is_resource_owner(),self.is_resource_owner() <==> old(self).is_resource_owner(),self.is_resource_owner() ==> (self.has_resource() <==> old(self).has_resource()),self.has_resource() ==> self.resource() == old(self).resource(),self.wf(),res.wf(),Splits a Right token with the given fraction n, without giving the resource to the Right token.
Sourcepub proof fn split_one_left_owner(tracked &mut self) -> tracked res : OneLeftOwner<A, B, TOTAL>
pub proof fn split_one_left_owner(tracked &mut self) -> tracked res : OneLeftOwner<A, B, TOTAL>
old(self).is_left(),old(self).is_resource_owner(),old(self).frac() > 1,ensuresself.wf(),self.id() == old(self).id(),self.is_left(),self.frac() + 1 == old(self).frac(),!self.is_resource_owner(),res.id() == old(self).id(),res.wf(),res.has_resource() == old(self).has_resource(),res.has_resource() ==> res.resource() == old(self).resource_left(),Splits a OneLeftOwner, giving it the resource.
Sourcepub proof fn split_one_right_owner(tracked &mut self) -> tracked res : OneRightOwner<A, B, TOTAL>
pub proof fn split_one_right_owner(tracked &mut self) -> tracked res : OneRightOwner<A, B, TOTAL>
old(self).is_right(),old(self).is_resource_owner(),old(self).frac() > 1,ensuresself.wf(),self.id() == old(self).id(),self.is_right(),self.frac() + 1 == old(self).frac(),!self.is_resource_owner(),res.id() == old(self).id(),res.wf(),res.has_resource() == old(self).has_resource(),res.has_resource() ==> res.resource() == old(self).resource_right(),Splits a OneRightOwner, giving it the resource.
Sourcepub proof fn split_one_left_knowledge(tracked &mut self) -> tracked res : OneLeftKnowledge<A, B, TOTAL>
pub proof fn split_one_left_knowledge(tracked &mut self) -> tracked res : OneLeftKnowledge<A, B, TOTAL>
old(self).is_left(),old(self).frac() > 1,ensuresself.wf(),self.id() == old(self).id(),self.is_left(),self.frac() + 1 == old(self).frac(),self.is_resource_owner() == old(self).is_resource_owner(),self.has_resource() == old(self).has_resource(),self.has_resource() ==> self.resource() == old(self).resource(),res.id() == old(self).id(),res.wf(),Splits a OneLeftKnowledge, without giving it the resource.
Sourcepub proof fn split_one_right_knowledge(tracked &mut self) -> tracked res : OneRightKnowledge<A, B, TOTAL>
pub proof fn split_one_right_knowledge(tracked &mut self) -> tracked res : OneRightKnowledge<A, B, TOTAL>
old(self).is_right(),old(self).frac() > 1,ensuresself.wf(),self.id() == old(self).id(),self.is_right(),self.frac() + 1 == old(self).frac(),self.is_resource_owner() == old(self).is_resource_owner(),self.has_resource() == old(self).has_resource(),self.has_resource() ==> self.resource() == old(self).resource(),res.id() == old(self).id(),res.wf(),Splits a OneRightKnowledge, without giving it the resource.
Sourcepub proof fn take_resource_left(tracked &mut self) -> tracked res : A
pub proof fn take_resource_left(tracked &mut self) -> tracked res : A
old(self).is_left(),old(self).is_resource_owner(),old(self).has_resource(),ensuresself.is_left(),res == old(self).resource_left(),self.id() == old(self).id(),self.is_resource_owner(),self.has_no_resource(),self.frac() == old(self).frac(),self.wf(),Takes the resource out of the token if it is in the left variant.
Sourcepub proof fn take_resource_right(tracked &mut self) -> tracked res : B
pub proof fn take_resource_right(tracked &mut self) -> tracked res : B
old(self).is_right(),old(self).is_resource_owner(),old(self).has_resource(),ensuresself.is_right(),res == old(self).resource_right(),self.id() == old(self).id(),self.is_resource_owner(),self.has_no_resource(),self.frac() == old(self).frac(),self.wf(),Takes the resource out of the token if it is in the right variant.
Sourcepub proof fn put_resource_left(tracked &mut self, tracked a: A)
pub proof fn put_resource_left(tracked &mut self, tracked a: A)
old(self).is_left(),old(self).is_resource_owner(),old(self).has_no_resource(),ensuresself.is_left(),self.has_resource(),self.is_resource_owner(),self.resource_left() == a,self.id() == old(self).id(),self.frac() == old(self).frac(),self.wf(),Puts a resource of type A back to the token.
Sourcepub proof fn put_resource_right(tracked &mut self, tracked b: B)
pub proof fn put_resource_right(tracked &mut self, tracked b: B)
old(self).is_right(),old(self).is_resource_owner(),old(self).has_no_resource(),ensuresself.is_right(),self.is_resource_owner(),self.has_resource(),self.resource_right() == b,self.id() == old(self).id(),self.frac() == old(self).frac(),self.wf(),Puts a resource of type B back to the token.
Sourcepub proof fn update_left(tracked &mut self, tracked a: A) -> tracked res : Option<A>
pub proof fn update_left(tracked &mut self, tracked a: A) -> tracked res : Option<A>
old(self).is_left(),old(self).is_resource_owner(),old(self).has_resource(),ensuresself.is_left(),self.is_resource_owner(),self.has_resource(),self.resource_left() == a,self.id() == old(self).id(),self.frac() == old(self).frac(),res == Some(old(self).resource_left()),self.wf(),Updates the resource of type A in the token, when the token is in the left variant and is a resource owner.
Returns the old resource if available.
Sourcepub proof fn update_right(tracked &mut self, tracked b: B) -> tracked res : Option<B>
pub proof fn update_right(tracked &mut self, tracked b: B) -> tracked res : Option<B>
old(self).is_right(),old(self).is_resource_owner(),old(self).has_resource(),ensuresself.is_right(),self.is_resource_owner(),self.has_resource(),self.resource_right() == b,self.id() == old(self).id(),self.frac() == old(self).frac(),res == Some(old(self).resource_right()),self.wf(),Updates the resource of type B in the token, when the token is in the right variant and is a resource owner.
Returns the old resource if available.
Sourcepub proof fn change_to_left(tracked &mut self, tracked a: A) -> tracked res : Option<Sum<A, B>>
pub proof fn change_to_left(tracked &mut self, tracked a: A) -> tracked res : Option<Sum<A, B>>
old(self).is_resource_owner(),old(self).frac() == TOTAL,ensuresself.id() == old(self).id(),self.protocol_monoid() == CsumP::<A, B, TOTAL>::Cinl(Some(a), old(self).frac(), true),self.frac() == old(self).frac(),self.is_left(),self.is_resource_owner(),self.has_resource(),self.resource_left() == a,old(self).has_resource() ==> res == Some(old(self).resource()),old(self).has_no_resource() ==> res == None::<Sum<A, B>>,self.wf(),Changes the token to the left invariant with a new resource of type A, and returns the old resource if available.
NOTE: Unlike Self::update_left, this operation can only be done with the full fraction, because there should be no Right tokens to witness
the existence of the old resource after the update.
Sourcepub proof fn change_to_right(tracked &mut self, tracked b: B) -> tracked res : Option<Sum<A, B>>
pub proof fn change_to_right(tracked &mut self, tracked b: B) -> tracked res : Option<Sum<A, B>>
old(self).is_resource_owner(),old(self).frac() == TOTAL,ensuresself.id() == old(self).id(),self.protocol_monoid() == CsumP::<A, B, TOTAL>::Cinr(Some(b), old(self).frac(), true),self.frac() == old(self).frac(),self.is_right(),self.is_resource_owner(),self.has_resource(),self.resource_right() == b,old(self).has_resource() ==> res == Some(old(self).resource()),old(self).has_no_resource() ==> res == None::<Sum<A, B>>,self.wf(),Changes the token to the right invariant with a new resource of type B, and returns the old resource if available.
NOTE: Unlike Self::update_right, this operation can only be done with the full fraction, because there should be no Left tokens to witness
the existence of the old resource after the update.
Sourcepub proof fn join_left(tracked &mut self, tracked other: Left<A, B, TOTAL>)
pub proof fn join_left(tracked &mut self, tracked other: Left<A, B, TOTAL>)
old(self).id() == other.id(),ensuresself.id() == old(self).id(),self.is_left(),self.is_resource_owner() == (old(self).is_resource_owner() || other.is_resource_owner()),self.has_resource() == (old(self).has_resource() || other.has_resource()),self.has_resource()
==> self.resource()
== if old(self).is_resource_owner() {
old(self).resource()
} else {
Sum::Left(other.resource())
},self.frac() == old(self).frac() + other.frac(),self.wf(),Joins this token with another Left token with the same id.
Sourcepub proof fn join_right(tracked &mut self, tracked other: Right<A, B, TOTAL>)
pub proof fn join_right(tracked &mut self, tracked other: Right<A, B, TOTAL>)
old(self).id() == other.id(),ensuresself.id() == old(self).id(),self.is_right(),self.is_resource_owner() == (old(self).is_resource_owner() || other.is_resource_owner()),self.has_resource() == (old(self).has_resource() || other.has_resource()),self.has_resource()
==> self.resource()
== if old(self).is_resource_owner() {
old(self).resource()
} else {
Sum::Right(other.resource())
},self.frac() == old(self).frac() + other.frac(),self.wf(),Joins this token with another Right token with the same id.
Sourcepub proof fn join_one_left_owner(tracked &mut self, tracked other: OneLeftOwner<A, B, TOTAL>)
pub proof fn join_one_left_owner(tracked &mut self, tracked other: OneLeftOwner<A, B, TOTAL>)
old(self).id() == other.id(),ensuresself.id() == old(self).id(),self.is_left(),self.is_resource_owner(),self.has_resource() == other.has_resource(),self.has_resource() ==> self.resource_left() == other.resource(),self.frac() == old(self).frac() + 1,self.wf(),Joins a OneLeftOwner token.
Sourcepub proof fn join_one_right_owner(tracked &mut self, tracked other: OneRightOwner<A, B, TOTAL>)
pub proof fn join_one_right_owner(tracked &mut self, tracked other: OneRightOwner<A, B, TOTAL>)
old(self).id() == other.id(),ensuresself.id() == old(self).id(),self.is_right(),self.is_resource_owner(),self.has_resource() == other.has_resource(),self.has_resource() ==> self.resource_right() == other.resource(),self.frac() == old(self).frac() + 1,self.wf(),Joins a OneRightOwner token.
Sourcepub proof fn join_one_left_knowledge(tracked &mut self, tracked other: OneLeftKnowledge<A, B, TOTAL>)
pub proof fn join_one_left_knowledge(tracked &mut self, tracked other: OneLeftKnowledge<A, B, TOTAL>)
old(self).id() == other.id(),ensuresself.id() == old(self).id(),self.is_left(),self.is_resource_owner() == old(self).is_resource_owner(),self.has_resource() == old(self).has_resource(),self.has_resource() ==> self.resource() == old(self).resource(),self.frac() == old(self).frac() + 1,self.wf(),Joins a OneLeftKnowledge token.
Sourcepub proof fn join_one_right_knowledge(tracked
&mut self,
tracked other: OneRightKnowledge<A, B, TOTAL>,
)
pub proof fn join_one_right_knowledge(tracked &mut self, tracked other: OneRightKnowledge<A, B, TOTAL>, )
old(self).id() == other.id(),ensuresself.id() == old(self).id(),self.is_right(),self.is_resource_owner() == old(self).is_resource_owner(),self.has_resource() == old(self).has_resource(),self.has_resource() ==> self.resource() == old(self).resource(),self.frac() == old(self).frac() + 1,self.wf(),Joins a OneRightKnowledge token.