Skip to main content

VerusForLoopWrapper

Struct VerusForLoopWrapper 

Source
pub struct VerusForLoopWrapper<'a, I: Iterator> {
    pub index: Ghost<int>,
    pub snapshot: Ghost<I>,
    pub init: Ghost<Option<&'a I>>,
    pub iter: I,
    pub history: Ghost<Seq<I::Item>>,
}

Fields§

§index: Ghost<int>§snapshot: Ghost<I>§init: Ghost<Option<&'a I>>§iter: I§history: Ghost<Seq<I::Item>>

Implementations§

Source§

impl<'a, I: Iterator> VerusForLoopWrapper<'a, I>

Source

pub open spec fn seq(self) -> Seq<I::Item>

{ self.snapshot@.remaining() }
Source

pub open spec fn history(self) -> Seq<I::Item>

{ self.history@ }
Source

pub open spec fn index(self) -> int

{ self.index@ }
Source

pub closed spec fn wf_inner(self) -> bool

These properties help maintain the properties in wf, but they don’t need to be exposed to the client

Source

pub open spec fn wf(self) -> bool

{
    &&& 0 <= self.index() <= self.seq().len()
    &&& self.init@ matches Some(init) ==> self.snapshot@.initial_value_relation(init)
    &&& self.wf_inner()
    &&& self.iter.obeys_prophetic_iter_laws()
        ==> {
            &&& self.history@.len() == self.index()
            &&& forall |i| {
                0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
            }

        }

}

These properties are needed for the client code to verify

Source

pub exec fn new(iter: I, init: Ghost<Option<&'a I>>) -> s : Self

requires
init@ matches Some(i) ==> iter.initial_value_relation(i),
ensures
s.index == 0,
s.snapshot == iter,
s.init == init,
s.iter == iter,
s.history@ == Seq::<I::Item>::empty(),
s.wf(),

Bundle the real iterator with its ghost state and loop invariants

Source

pub exec fn next(&mut self) -> ret : Option<I::Item>

requires
old(self).wf(),
ensures
final(self).seq() == old(self).seq(),
final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
final(self).snapshot == old(self).snapshot,
final(self).init == old(self).init,
final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
final(self).iter.obeys_prophetic_iter_laws() && ret is None
    ==> final(self).snapshot@.will_return_none()
        && final(self).index() == final(self).seq().len(),
final(self).iter.obeys_prophetic_iter_laws()
    ==> (ret matches Some(r) ==> r == old(self).seq()[old(self).index()]),
ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
ret is None ==> final(self).history@ == old(self).history@,
final(self).iter.obeys_prophetic_iter_laws()
    == old(self).iter.obeys_prophetic_iter_laws(),
final(self).iter.obeys_prophetic_iter_laws()
    ==> final(self).iter.will_return_none() == old(self).iter.will_return_none(),
final(self).iter.obeys_prophetic_iter_laws()
    ==> (old(self).iter.decrease() is Some <==> final(self).iter.decrease() is Some),
final(self).iter.obeys_prophetic_iter_laws()
    ==> ({
        if old(self).iter.remaining().len() > 0 {
            &&& final(self).iter.remaining() == old(self).iter.remaining().drop_first()
            &&& ret == Some(old(self).iter.remaining()[0])

        } else {
            final(self).iter.remaining() == old(self).iter.remaining() && ret == None
                && final(self).iter.will_return_none()
        }
    }),
final(self).iter.obeys_prophetic_iter_laws() && old(self).iter.remaining().len() > 0
    && final(self).iter.decrease() is Some
    ==> decreases_to!(old(self).iter.decrease() -> 0 => final(self).iter.decrease() -> 0),

Advance the underlying (real) iterator and prove that the loop invariants are preserved.

Auto Trait Implementations§

§

impl<'a, I> Freeze for VerusForLoopWrapper<'a, I>
where I: Freeze,

§

impl<'a, I> RefUnwindSafe for VerusForLoopWrapper<'a, I>

§

impl<'a, I> Send for VerusForLoopWrapper<'a, I>
where I: Send,

§

impl<'a, I> Sync for VerusForLoopWrapper<'a, I>
where I: Sync,

§

impl<'a, I> Unpin for VerusForLoopWrapper<'a, I>
where I: Unpin, <I as Iterator>::Item: Unpin,

§

impl<'a, I> UnsafeUnpin for VerusForLoopWrapper<'a, I>
where I: UnsafeUnpin,

§

impl<'a, I> UnwindSafe for VerusForLoopWrapper<'a, I>

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, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: From<T>,

Source§

exec fn obeys_from_spec() -> bool

Source§

exec fn from_spec(v: T) -> VERUS_SPEC__A

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, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: Into<T>,

Source§

exec fn obeys_into_spec() -> bool

Source§

exec fn into_spec(self) -> T

Source§

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

Source§

open spec fn obeys_into_spec() -> bool

{ <U as FromSpec<Self>>::obeys_from_spec() }
Source§

open spec fn into_spec(self) -> U

{ U::from_spec(self) }
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, VERUS_SPEC__A> TryFromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryFrom<T>,

Source§

exec fn obeys_try_from_spec() -> bool

Source§

exec fn try_from_spec( v: T, ) -> Result<VERUS_SPEC__A, <VERUS_SPEC__A as TryFrom<T>>::Error>

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.
Source§

impl<T, VERUS_SPEC__A> TryIntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryInto<T>,

Source§

exec fn obeys_try_into_spec() -> bool

Source§

exec fn try_into_spec(self) -> Result<T, <VERUS_SPEC__A as TryInto<T>>::Error>

Source§

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

Source§

open spec fn obeys_try_into_spec() -> bool

{ <U as TryFromSpec<Self>>::obeys_try_from_spec() }
Source§

open spec fn try_into_spec(self) -> Result<U, <U as TryFrom<T>>::Error>

{ <U as TryFromSpec<Self>>::try_from_spec(self) }
§

impl<A> SpecEq<&A> for A
where A: ?Sized,

§

impl<A> SpecEq<&mut A> for A
where A: ?Sized,

§

impl<A> SpecEq<A> for A
where A: ?Sized,

§

impl<A> SpecEq<Ghost<A>> for A

§

impl<A> SpecEq<Tracked<A>> for A