Struct vstd::pcm::frac::FracGhost

source ·
pub struct FracGhost<T, const TOTAL: u64 = 2> { /* private fields */ }
Expand description

An implementation of a resource for fractional ownership of a ghost variable.

While most presentations of fractional permissions use the fractional total of 1, with fractions being arbitrary rational numbers, this library represents fractional permissions as integers, totalling to some compile-time constant TOTAL. Thus, you can have any fractions from 1 up to TOTAL, and if you have TOTAL, you can update the ghost variable.

If you just want to split the permission in half, you can also use the GhostVar<T> and GhostVarAuth<T> library.

§Example

fn example_use() {
    let tracked mut r = FracGhost::<u64, 3>::new(123);
    assert(r@ == 123);
    assert(r.frac() == 3);
    let tracked r2 = r.split(2);
    assert(r@ == 123);
    assert(r2@ == 123);
    assert(r.frac() == 1);
    assert(r2.frac() == 2);
    proof {
        r.combine(r2);
        r.update(456);
    }
    assert(r@ == 456);
    assert(r.frac() == 3);

    let tracked mut a = FracGhost::<u32>::new(5);
    assert(a@ == 5);
    assert(a.frac() == 2);
    let tracked mut b = a.split(1);
    assert(a.frac() == 1);
    assert(b.frac() == 1);
    proof {
        a.update_with(&mut b, 123);
    }
    assert(a@ == 123);

    proof {
        a.combine(b);
        a.update(6);
    }
    assert(a@ == 6);
}

Implementations§

source§

impl<T, const TOTAL: u64> FracGhost<T, TOTAL>

source

pub closed spec fn id(self) -> Loc

source

pub closed spec fn view(self) -> T

source

pub closed spec fn frac(self) -> int

The fractional quantity of this permission. The “fraction” is represented as an integer, out of TOTAL.

source

pub open spec fn valid(self, id: Loc, frac: int) -> bool

{
    &&& self.id() == id
    &&& self.frac() == frac

}
source

pub proof fn new(v: T) -> tracked result : Self

requires
TOTAL > 0,
ensures
result.frac() == TOTAL as int,
result@ == v,

Allocate a new token with the given value. The returned token represents the TOTAL quantity.

source

pub proof fn agree(tracked &self, tracked other: &Self)

requires
self.id() == other.id(),
ensures
self@ == other@,

Two tokens agree on their values.

source

pub proof fn take(tracked &mut self) -> tracked result : Self

ensures
result == *old(self),

Take a token out of a mutable reference, leaving a meaningless token behind.

source

pub proof fn split(tracked &mut self, n: int) -> tracked result : Self

requires
0 < n < old(self).frac(),
ensures
result.id() == self.id() == old(self).id(),
self@ == old(self)@,
result@ == old(self)@,
self.frac() + result.frac() == old(self).frac(),
result.frac() == n,

Split one token into two tokens whose quantities sum to the original. The returned token has quantity n; the new value of the input token has quantity old(self).frac() - n.

source

pub proof fn combine(tracked &mut self, tracked other: Self)

requires
old(self).id() == other.id(),
ensures
self.id() == old(self).id(),
self@ == old(self)@,
self@ == other@,
self.frac() == old(self).frac() + other.frac(),

Combine two tokens, summing their quantities.

source

pub proof fn update(tracked &mut self, v: T)

requires
old(self).frac() == TOTAL,
ensures
self.id() == old(self).id(),
self@ == v,
self.frac() == old(self).frac(),

Update the value of the token. This requires having ALL the permissions, i.e., a quantity total of TOTAL.

source

pub proof fn update_with(tracked &mut self, tracked other: &mut Self, v: T)

requires
old(self).id() == old(other).id(),
old(self).frac() + old(other).frac() == TOTAL,
ensures
self.id() == old(self).id(),
other.id() == old(other).id(),
self.frac() == old(self).frac(),
other.frac() == old(other).frac(),
old(self)@ == old(other)@,
self@ == v,
other@ == v,

Update the value of the token. This requires having ALL the permissions, i.e., the tokens together must have a quantity total of TOTAL.

source

pub proof fn bounded(tracked &self)

ensures
0 < self.frac() <= TOTAL,

Allowed values for a token’s quantity.

source

pub proof fn dummy() -> tracked result : Self

requires
TOTAL > 0,

Obtain an arbitrary token with no information about it. Useful if you need a well-typed placeholder.

Auto Trait Implementations§

§

impl<T, const TOTAL: u64> Freeze for FracGhost<T, TOTAL>

§

impl<T, const TOTAL: u64> RefUnwindSafe for FracGhost<T, TOTAL>
where T: RefUnwindSafe,

§

impl<T, const TOTAL: u64> Send for FracGhost<T, TOTAL>
where T: Send,

§

impl<T, const TOTAL: u64> Sync for FracGhost<T, TOTAL>
where T: Sync,

§

impl<T, const TOTAL: u64> Unpin for FracGhost<T, TOTAL>
where T: Unpin,

§

impl<T, const TOTAL: u64> UnwindSafe for FracGhost<T, TOTAL>
where T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.