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>
impl<'a, I: Iterator> VerusForLoopWrapper<'a, I>
Sourcepub closed spec fn wf_inner(self) -> bool
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
Sourcepub open spec fn wf(self) -> bool
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
Sourcepub exec fn new(iter: I, init: Ghost<Option<&'a I>>) -> s : Self
pub exec fn new(iter: I, init: Ghost<Option<&'a I>>) -> s : Self
requires
init@ matches Some(i) ==> iter.initial_value_relation(i),ensuress.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
Sourcepub exec fn next(&mut self) -> ret : Option<I::Item>
pub exec fn next(&mut self) -> ret : Option<I::Item>
requires
old(self).wf(),ensuresfinal(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>
impl<'a, I> UnsafeUnpin for VerusForLoopWrapper<'a, I>where
I: UnsafeUnpin,
impl<'a, I> UnwindSafe for VerusForLoopWrapper<'a, I>
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
Mutably borrows from an owned value. Read more
Source§impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
Source§impl<T, VERUS_SPEC__A> TryFromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: TryFrom<T>,
impl<T, VERUS_SPEC__A> TryFromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: TryFrom<T>,
Source§exec fn obeys_try_from_spec() -> bool
exec fn obeys_try_from_spec() -> bool
Source§impl<T, VERUS_SPEC__A> TryIntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: TryInto<T>,
impl<T, VERUS_SPEC__A> TryIntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: TryInto<T>,
Source§exec fn obeys_try_into_spec() -> bool
exec fn obeys_try_into_spec() -> bool
Source§impl<T, U> TryIntoSpecImpl<U> for Twhere
U: TryFrom<T>,
impl<T, U> TryIntoSpecImpl<U> for Twhere
U: TryFrom<T>,
Source§open spec fn obeys_try_into_spec() -> bool
open spec fn obeys_try_into_spec() -> bool
{ <U as TryFromSpec<Self>>::obeys_try_from_spec() }