pub enum SumSP<A, B, const TOTAL: u64> {
Unit,
Left(Option<A>, int, bool),
Right(Option<B>, int, bool),
CsumInvalid,
}Expand description
A sum-type protocol monoid that stores a tracked object of either type A or type B.
The knowledge of the existence of a specific type of resource can be shared up to TOTAL pieces, but only one piece has the exclusive ownership of the resource, allowing arbitrary withdrawing, depositing, or updating.
Variants§
Unit
The unit element, only for technical reasons, not intended to be used directly.
Left(Option<A>, int, bool)
The left side of the sum, with an optional resource, a fraction, and a boolean indicating whether it is the exclusive owner of the resource.
Right(Option<B>, int, bool)
The right side of the sum, with an optional resource, a fraction, and a boolean indicating whether it is the exclusive owner of the resource.
CsumInvalid
An invalid state, used to represent an invalid combination of resources.
Implementations§
Source§impl<A, B, const TOTAL: u64> SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> SumSP<A, B, TOTAL>
pub fn arrow_2(self) -> bool
pub fn arrow_1(self) -> int
pub fn arrow_Left_0(self) -> Option<A>
pub fn arrow_Left_1(self) -> int
pub fn arrow_Left_2(self) -> bool
pub fn arrow_Right_0(self) -> Option<B>
pub fn arrow_Right_1(self) -> int
pub fn arrow_Right_2(self) -> bool
Source§impl<A, B, const TOTAL: u64> SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> SumSP<A, B, TOTAL>
Sourcepub open spec fn is_left(self) -> bool
pub open spec fn is_left(self) -> bool
{ self is Left }Whether the protocol monoid is currently in the left state.
Sourcepub open spec fn is_right(self) -> bool
pub open spec fn is_right(self) -> bool
{ self is Right }Whether the protocol monoid is currently in the right state.
Sourcepub open spec fn is_resource_owner(self) -> bool
pub open spec fn is_resource_owner(self) -> bool
{
match self {
SumSP::Left(_, _, b) | SumSP::Right(_, _, b) => b,
_ => false,
}
}Whether the protocol monoid is an exclusive owner of a resource.
Sourcepub open spec fn has_resource(self) -> bool
pub open spec fn has_resource(self) -> bool
{
match self {
SumSP::Left(ov, n, true) => ov is Some,
SumSP::Right(ov, n, true) => ov is Some,
_ => false,
}
}Whether the protocol monoid currently owns a resource, only meaningful when it is the exclusive owner.
Sourcepub open spec fn has_no_resource(self) -> bool
pub open spec fn has_no_resource(self) -> bool
{
match self {
SumSP::Left(ov, n, true) => ov is None,
SumSP::Right(ov, n, true) => ov is None,
_ => false,
}
}Whether the protocol monoid has had its resource taken, only meaningful when it is the exclusive owner.
Sourcepub open spec fn resource(self) -> Sum<A, B>
pub open spec fn resource(self) -> Sum<A, B>
{
match self {
SumSP::Left(Some(a), n, true) => Sum::Left(a),
SumSP::Right(Some(b), n, true) => Sum::Right(b),
_ => arbitrary(),
}
}The resource stored in the protocol monoid.
Sourcepub open spec fn frac(self) -> int
pub open spec fn frac(self) -> int
{
match self {
SumSP::Left(_, n, _) | SumSP::Right(_, n, _) => n,
_ => 1,
}
}The fraction of the resource knowledge.
Sourcepub open spec fn is_valid(self) -> bool
pub open spec fn is_valid(self) -> bool
{
match self {
SumSP::Unit => true,
SumSP::Left(ov, n, b) => 0 < n <= TOTAL && (ov is Some ==> b),
SumSP::Right(ov, n, b) => 0 < n <= TOTAL && (ov is Some ==> b),
_ => false,
}
}The invariant of the protocol monoid.
Sourcepub proof fn lemma_withdraws_left(self)
pub proof fn lemma_withdraws_left(self)
self.is_left(),self.is_resource_owner(),self.has_resource(),self.is_valid(),ensureswithdraws(self, SumSP::Left(None, self.frac(), true), imap![() => self.resource()]),Sourcepub proof fn lemma_withdraws_right(self)
pub proof fn lemma_withdraws_right(self)
self.is_resource_owner(),self.is_right(),self.has_resource(),self.is_valid(),ensureswithdraws(self, SumSP::Right(None, self.frac(), true), imap![() => self.resource()]),Sourcepub proof fn lemma_deposit_left(self, a: A)
pub proof fn lemma_deposit_left(self, a: A)
self.is_resource_owner(),self.is_left(),self.has_no_resource(),self.is_valid(),ensuresdeposits(self, imap![() => Sum::Left(a)], SumSP::Left(Some(a), self.frac(), true)),Sourcepub proof fn lemma_deposit_right(self, b: B)
pub proof fn lemma_deposit_right(self, b: B)
self.is_resource_owner(),self.is_right(),self.has_no_resource(),self.is_valid(),ensuresdeposits(self, imap![() => Sum::Right(b)], SumSP::Right(Some(b), self.frac(), true)),Sourcepub proof fn lemma_updates_none(self)
pub proof fn lemma_updates_none(self)
self.is_left() || self.is_right(),self.frac() == TOTAL,self.is_resource_owner(),self.has_no_resource(),ensuresupdates(self, SumSP::Left(None, self.frac(), true)),updates(self, SumSP::Right(None, self.frac(), true)),Trait Implementations§
Source§impl<A, B, const TOTAL: u64> Protocol<(), Sum<A, B>> for SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> Protocol<(), Sum<A, B>> for SumSP<A, B, TOTAL>
Source§open spec fn op(self, other: Self) -> Self
open spec fn op(self, other: Self) -> Self
{
match (self, other) {
(SumSP::Unit, x) => x,
(x, SumSP::Unit) => x,
(SumSP::Left(ov1, n1, b1), SumSP::Left(ov2, n2, b2)) => {
if !self.is_valid() || !other.is_valid() || n1 + n2 > TOTAL || b1 && b2
|| ov1 is Some && ov2 is Some
{
SumSP::CsumInvalid
} else {
SumSP::Left(if ov1 is Some { ov1 } else { ov2 }, n1 + n2, b1 || b2)
}
}
(SumSP::Right(ov1, n1, b1), SumSP::Right(ov2, n2, b2)) => {
if !self.is_valid() || !other.is_valid() || n1 + n2 > TOTAL || b1 && b2
|| ov1 is Some && ov2 is Some
{
SumSP::CsumInvalid
} else {
SumSP::Right(if ov1 is Some { ov1 } else { ov2 }, n1 + n2, b1 || b2)
}
}
_ => SumSP::CsumInvalid,
}
}Source§open spec fn rel(self, s: IMap<(), Sum<A, B>>) -> bool
open spec fn rel(self, s: IMap<(), Sum<A, B>>) -> bool
{
match self {
SumSP::Unit => s.is_empty(),
SumSP::Left(None, n, true) => 0 <= n <= TOTAL && s.is_empty(),
SumSP::Left(Some(a), n, true) => {
0 <= n <= TOTAL && s.contains_key(()) && s[()] == Sum::<A, B>::Left(a)
}
SumSP::Right(None, n, true) => 0 <= n <= TOTAL && s.is_empty(),
SumSP::Right(Some(b), n, true) => {
0 <= n <= TOTAL && s.contains_key(()) && s[()] == Sum::<A, B>::Right(b)
}
_ => false,
}
}Source§proof fn commutative(a: Self, b: Self)
proof fn commutative(a: Self, b: Self)
Source§proof fn associative(a: Self, b: Self, c: Self)
proof fn associative(a: Self, b: Self, c: Self)
Auto Trait Implementations§
impl<A, B, const TOTAL: u64> Freeze for SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> RefUnwindSafe for SumSP<A, B, TOTAL>where
A: RefUnwindSafe,
B: RefUnwindSafe,
impl<A, B, const TOTAL: u64> Send for SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> Sync for SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> Unpin for SumSP<A, B, TOTAL>
impl<A, B, const TOTAL: u64> UnsafeUnpin for SumSP<A, B, TOTAL>where
A: UnsafeUnpin,
B: UnsafeUnpin,
impl<A, B, const TOTAL: u64> UnwindSafe for SumSP<A, B, TOTAL>where
A: UnwindSafe,
B: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: From<T>,
impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: From<T>,
fn obeys_from_spec() -> bool
fn from_spec(v: T) -> VERUS_SPEC__A
§impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: Into<T>,
impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: Into<T>,
fn obeys_into_spec() -> bool
fn into_spec(self) -> T
§impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
fn obeys_into_spec() -> bool
fn into_spec(self) -> U
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<A> SpecEq<&A> for Awhere
A: ?Sized,
impl<A> SpecEq<&mut A> for Awhere
A: ?Sized,
impl<A> SpecEq<A> for Awhere
A: ?Sized,
impl<A> SpecEq<Ghost<A>> for A
impl<A> SpecEq<Tracked<A>> for A
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.