Struct vstd::proph::Prophecy

source ·
pub struct Prophecy<T> { /* private fields */ }
Expand description

A “prophecy variable” that predicts some value of type T.

A prophecy can be allocated by calling Prophecy::<T>::new() in exec mode. The result is a prophecy variable whose view is an arbitrary value of type T.

A prophecy can be resolved by calling Prophecy::<T>::resolve() in exec mode. This call ensures that the view of the prophecy variable is equal to the value passed to resolve(). This call (and in particular, its argument v) must be exec-mode to avoid circular dependency on the value of the prophecy variable. The value cannot have any “ghost content” (not even via Ghost); hence the T: Structural trait bound.

We make an informal soundness argument based on the paper The Future is Ours: Prophecy Variables in Separation Logic. The argument goes as follows: For any execution of the program, there is some sequence of calls to resolve(), whose values do not depend on spec- or proof-mode values. Those values can be plugged into the arbitrary ghost values chosen by new(), for the corresponding prophecy variables, to justify the proof accompanying the program. Since both new() and resolve() are exec-mode, there is no ambiguity about which new() call corresponds to a particular resolve() value.

Implementations§

source§

impl<T> Prophecy<T>
where T: Structural,

source

pub closed spec fn view(self) -> T

The prophecized value.

source

pub exec fn new() -> result : Self

Allocate a new prophecy variable.

source

pub exec fn resolve(self, v: &T)

ensures
@ == v,

Resolve the prophecy variable to a concrete value. This consumes self, so it can only be called once.

Auto Trait Implementations§

§

impl<T> Freeze for Prophecy<T>

§

impl<T> RefUnwindSafe for Prophecy<T>
where T: RefUnwindSafe,

§

impl<T> Send for Prophecy<T>
where T: Send,

§

impl<T> Sync for Prophecy<T>
where T: Sync,

§

impl<T> Unpin for Prophecy<T>
where T: Unpin,

§

impl<T> UnwindSafe for Prophecy<T>
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.