Skip to main content

vstd/std_specs/
iter.rs

1use super::super::prelude::*;
2use super::super::seq::{
3    group_seq_lemmas, lemma_seq_empty, lemma_seq_subrange_index, lemma_seq_subrange_len,
4};
5use core::iter::{Filter, FromIterator, Iterator, Rev, Skip, Take, Zip};
6
7// Reduce the boilerplate in the definitions below.  We have to use a macro,
8// since inside of ExIterator, we don't yet know that `self` is an Iterator.
9// We use two macros so that we can convert arguments to Rust-friendly terms
10// (e.g., by translating `final(.)` in to `verus_builtin::final_(.)` in `iter_state_preserved`
11// before doing the real work in `iter_state_preserved_internal`
12#[doc(hidden)]
13#[macro_export]
14macro_rules! iter_state_preserved_internal {
15    ($before:expr, $after:expr $(,)?) => {
16        // Dereference explicitly so method resolution uses the underlying
17        // iterator, and `final` is consumed through a dereference.
18        $crate::vstd::prelude::verus_proof_expr! {{
19            &&& (*($after)).obeys_prophetic_iter_laws() == (*($before)).obeys_prophetic_iter_laws()
20            &&& (*($before)).obeys_prophetic_iter_laws() ==>
21                (*($before)).produces().len() == (*($before)).remaining().len()
22            &&& (*($before)).obeys_prophetic_iter_laws() ==>
23                ((*($after)).decrease() is Some <==> (*($before)).decrease() is Some)
24        }}
25    };
26}
27
28#[macro_export]
29macro_rules! iter_state_preserved {
30    ($($args:tt)*) => {
31        $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::std_specs::iter::iter_state_preserved_internal!($($args)*))
32    };
33}
34
35#[doc(hidden)]
36pub use iter_state_preserved;
37#[doc(hidden)]
38pub use iter_state_preserved_internal;
39
40use verus as verus_skip_verusfmt;
41verus_skip_verusfmt! {
42
43#[verifier::external_trait_specification]
44#[verifier::external_trait_extension(IteratorSpec via IteratorSpecImpl)]
45pub trait ExIterator {
46    type ExternalTraitSpecificationFor: Iterator;
47
48    type Item;
49
50    /// This iterator obeys the specifications below on `next`,
51    /// expressed in terms of prophetic spec functions.
52    /// Only finite iterators (i.e., those that eventually return None
53    /// and then continue to return None) or infinite iterators that
54    /// never return None should use this interface.
55    spec fn obeys_prophetic_iter_laws(&self) -> bool;
56
57    /// Sequence of all potentially returned items
58    #[verifier::prophetic]
59    spec fn remaining(&self) -> Seq<Self::Item>;
60
61    /// For each potential item in `remaining()`, does the item actually
62    /// get returned, or does the iterator get "stuck" trying to produce it,
63    /// e.g., because a client supplied a closure that diverges?
64    #[verifier::prophetic]
65    spec fn produces(&self) -> Seq<bool>;
66
67    /// Advances the iterator and returns the next value.
68    fn next(&mut self) -> (ret: Option<Self::Item>)
69        ensures
70            iter_state_preserved!(old(self), final(self)),
71            // `next` pops the head of the prophesized remaining(), or returns None
72            final(self).obeys_prophetic_iter_laws() ==>
73            ({
74                if old(self).remaining().len() > 0 {
75                    &&& final(self).remaining() == old(self).remaining().drop_first()
76                    &&& final(self).produces() == old(self).produces().drop_first()
77                    &&& ret == Some(old(self).remaining()[0])
78                    &&& old(self).produces()[0]
79                } else {
80                    &&& final(self).remaining() == old(self).remaining()
81                    &&& final(self).produces() == old(self).produces()
82                    &&& ret == None
83                }
84            }),
85            // If the iterator isn't done yet, then it successfully decreases its metric (if any)
86            final(self).obeys_prophetic_iter_laws() && old(self).remaining().len() > 0 && final(self).decrease() is Some ==>
87                decreases_to!(old(self).decrease()->0 => final(self).decrease()->0),
88    ;
89
90    /******* Mechanisms that support ergonomic `for` loops *********/
91
92    /// Value used by default for the decreases clause when no explicit decreases clause is provided
93    /// (the user can override this with an explicit decreases clause).
94    /// If there's no appropriate metric to decrease, this can return None,
95    /// and the user will have to provide an explicit decreases clause.
96    spec fn decrease(&self) -> Option<nat>;
97
98    // If we can make a useful guess as to what the i-th value will be, return it.
99    // Otherwise, return None.
100    spec fn peek(&self, index: int) -> Option<Self::Item>;
101
102
103
104    /******* Provided methods (in alphabetical order) *********/
105    // For provided method that returns a new iterator (e.g., filter, map, or zip),
106    // ideally we would write their postconditions here.  However, this requires
107    // a trait bound of `Self: IteratorSpec`, which introduces a cyclic dependency.
108    // Hence, we introduce a layer of indirection via an uninterp spec function that
109    // describes the postconditions.
110
111    // TODO: The Rust implementations of `all`, `any`, `find`, `find_map` and `position` depend on a correct implementation of `try_fold`
112    //       For now, we assume obeys_prophetic_iter_laws() entails such an implementation, but we should
113    //       eventually constrain implementations of `try_fold` to actually be correct enough to uphold the specs below.
114
115    fn all<F>(&mut self, f: F) -> (r: bool)
116        where Self: Sized,
117            F: FnMut(Self::Item) -> bool
118        requires
119            self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
120            // without the laws, `remaining()` says nothing about the items `f` is called on
121            !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
122        ensures
123            iter_state_preserved!(old(self), final(self)),
124            final(self).obeys_prophetic_iter_laws() ==> {
125                let num_consumed = old(self).remaining().len() - final(self).remaining().len();
126                &&& final(self).remaining().is_suffix_of(old(self).remaining())
127                &&& final(self).produces() == old(self).produces().skip(num_consumed)
128                &&& old(self).produces().take(num_consumed).all(|p: bool| p)
129            },
130            // If all returns true, then the iterator has no remaining elements,
131            // and the predicate was true for all of the original iterator's elements.
132            final(self).obeys_prophetic_iter_laws() && r ==> {
133                &&& final(self).remaining().len() == 0
134                &&& forall |i| 0 <= i < old(self).remaining().len() ==>
135                    f.ensures((#[trigger] old(self).remaining()[i],), true)
136            },
137            // If all returns false, then there is some element for which the
138            // predicate was false, and all previous elements satisfied the predicate.
139            final(self).obeys_prophetic_iter_laws() && !r ==> {
140                let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
141                {
142                    // The failing element was consumed, so the remaining sequence strictly shrank
143                    &&& final(self).remaining().len() < old(self).remaining().len()
144                    &&& f.ensures((old(self).remaining()[idx],), false)
145                    &&& forall |i| 0 <= i < idx ==>
146                        f.ensures((#[trigger] old(self).remaining()[i],), true)
147                }
148            };
149
150    fn any<F>(&mut self, f: F) -> (r: bool)
151        where Self: Sized,
152            F: FnMut(Self::Item) -> bool
153        requires
154            self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
155            // without the laws, `remaining()` says nothing about the items `f` is called on
156            !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
157        ensures
158            iter_state_preserved!(old(self), final(self)),
159            final(self).obeys_prophetic_iter_laws() ==> {
160                let num_consumed = old(self).remaining().len() - final(self).remaining().len();
161                &&& final(self).remaining().is_suffix_of(old(self).remaining())
162                &&& final(self).produces() == old(self).produces().skip(num_consumed)
163                &&& old(self).produces().take(num_consumed).all(|p: bool| p)
164            },
165            // If any returns false, then the iterator has no remaining elements,
166            // and the predicate was false for all of the original iterator's elements.
167            final(self).obeys_prophetic_iter_laws() && !r ==> {
168                &&& final(self).remaining().len() == 0
169                &&& forall |i| 0 <= i < old(self).remaining().len() ==>
170                    f.ensures((#[trigger] old(self).remaining()[i],), false)
171            },
172            // If any returns true, then there is some element that satisfied the predicate,
173            // and all previous elements did not satisfy the predicate.
174            final(self).obeys_prophetic_iter_laws() && r ==> {
175                let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
176                {
177                    // The satisfying element was consumed, so the remaining sequence strictly shrank
178                    &&& final(self).remaining().len() < old(self).remaining().len()
179                    &&& f.ensures((old(self).remaining()[idx],), true)
180                    &&& forall |i| 0 <= i < idx ==>
181                        f.ensures((#[trigger] old(self).remaining()[i],), false)
182                }
183            };
184
185    fn collect<B>(self) -> (collection: B)
186        where
187            B: FromIterator<Self::Item>,
188            Self: Sized,
189        ensures
190            self.obeys_prophetic_iter_laws() ==>
191                FromIteratorSpec::from_iter_ensures(self.remaining(), self.produces(), collection),
192    ;
193
194    fn filter<P>(self, predicate: P) -> (r: core::iter::Filter<Self, P>)
195        where
196            Self: Sized,
197            P: FnMut(&Self::Item) -> bool,
198        requires
199            // `filter`'s implementation loops over the inner iterator until the predicate accepts an element,
200            // so it needs a decreases metric to prove termination.
201            self.decrease() is Some,
202            self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> predicate.requires((#[trigger] &self.remaining()[k], )),
203            // without the laws, `remaining()` says nothing about the items `predicate` is called on
204            !self.obeys_prophetic_iter_laws() ==> forall |x: &Self::Item| #[trigger] predicate.requires((x, )),
205        ensures
206            self.obeys_prophetic_iter_laws() ==> filter_post(self, predicate, r),
207    ;
208
209    fn find<P>(&mut self, predicate: P) -> (r: Option<Self::Item>)
210        where Self: Sized,
211            P: FnMut(&Self::Item) -> bool
212        requires
213            self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> predicate.requires((#[trigger] &self.remaining()[k], )),
214            // without the laws, `remaining()` says nothing about the items `predicate` is called on
215            !self.obeys_prophetic_iter_laws() ==> forall |x: &Self::Item| #[trigger] predicate.requires((x, )),
216        ensures
217            iter_state_preserved!(old(self), final(self)),
218            final(self).obeys_prophetic_iter_laws() ==> final(self).produces() ==
219                old(self).produces().skip(old(self).remaining().len() - final(self).remaining().len()),
220            final(self).obeys_prophetic_iter_laws() ==> {
221                &&& final(self).remaining().is_suffix_of(old(self).remaining())
222                &&& old(self).produces().take(old(self).remaining().len() - final(self).remaining().len()).all(|p: bool| p)
223            },
224            // If find returns None, then the iterator has no remaining
225            // elements, and the predicate was false for all of the original
226            // iterator's elements.
227            final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
228                &&& final(self).remaining().len() == 0
229                &&& forall |i| 0 <= i < old(self).remaining().len() ==>
230                    predicate.ensures((#[trigger]&old(self).remaining()[i],), false)
231            },
232            // If find returns Some, then the returned value satisfies the
233            // predicate, and all previous elements did not satisfy the
234            // predicate.
235            final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
236                let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
237                {
238                    &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
239                    &&& predicate.ensures((&r.unwrap(),), true)
240                    &&& old(self).remaining()[idx] == r.unwrap()
241                    &&& forall |i| 0 <= i < idx ==>
242                        predicate.ensures((#[trigger] &old(self).remaining()[i],), false)
243                }
244            };
245
246    fn find_map<B, F>(&mut self, f: F) -> (r: Option<B>)
247        where Self: Sized,
248            F: FnMut(Self::Item) -> Option<B>
249        requires
250            self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
251            // without the laws, `remaining()` says nothing about the items `f` is called on
252            !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
253        ensures
254            iter_state_preserved!(old(self), final(self)),
255
256            final(self).obeys_prophetic_iter_laws() ==> {
257                let num_consumed = old(self).remaining().len() - final(self).remaining().len();
258                &&& final(self).remaining().is_suffix_of(old(self).remaining())
259                &&& final(self).produces() == old(self).produces().skip(num_consumed)
260                &&& old(self).produces().take(num_consumed).all(|p: bool| p)
261            },
262            // If find_map returns None, then the iterator has no remaining
263            // elements, and f was None for all of the original
264            // iterator's elements.
265            final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
266                &&& final(self).remaining().len() == 0
267                &&& forall |i| 0 <= i < old(self).remaining().len() ==>
268                    f.ensures((#[trigger]old(self).remaining()[i],), None)
269            },
270            // If find_map returns Some, then the returned value satisfies f,
271            // and all previous elements did not satisfy f
272            final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
273                let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
274                {
275                    &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
276                    &&& f.ensures((old(self).remaining()[idx],), r)
277                    &&& forall |i| 0 <= i < idx ==>
278                        f.ensures((#[trigger] old(self).remaining()[i],), None)
279                }
280            };
281
282    fn map<B, F>(self, f: F) -> (r: core::iter::Map<Self, F>)
283        where
284            Self: Sized,
285            F: FnMut(Self::Item) -> B,
286        requires
287            self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
288            // without the laws, `remaining()` says nothing about the items `f` is called on
289            !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
290        ensures
291            self.obeys_prophetic_iter_laws() ==> map_post(self, f, r),
292    ;
293
294    fn position<P>(&mut self, predicate: P) -> (r: Option<usize>)
295        where
296            Self: Sized,
297            P: FnMut(Self::Item) -> bool,
298        requires
299            // without the laws, `remaining()` bounds neither the count std's `position` keeps
300            // (which may overflow) nor the items `predicate` is called on
301            self.obeys_prophetic_iter_laws(),
302            self.remaining().len() <= usize::MAX as int,
303            forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> predicate.requires((#[trigger] self.remaining()[k], )),
304        ensures
305            iter_state_preserved!(old(self), final(self)),
306            final(self).obeys_prophetic_iter_laws() ==> {
307                let num_consumed = old(self).remaining().len() - final(self).remaining().len();
308                &&& final(self).remaining().is_suffix_of(old(self).remaining())
309                &&& final(self).produces() == old(self).produces().skip(num_consumed)
310                &&& old(self).produces().take(num_consumed).all(|p: bool| p)
311            },
312            // If position returns None, then the iterator has no remaining
313            // elements, and the predicate was false for all of the original
314            // iterator's elements.
315            final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
316                &&& final(self).remaining().len() == 0
317                &&& forall |i| 0 <= i < old(self).remaining().len() ==>
318                    predicate.ensures((#[trigger] old(self).remaining()[i],), false)
319            },
320            // If position returns Some, then the returned index whose value satisfies the
321            // predicate, and all previous elements did not satisfy the predicate.
322            final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
323                let index = r.unwrap();
324                {
325                    &&& index as int == (old(self).remaining().len() - final(self).remaining().len() - 1)
326                    &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
327                    &&& predicate.ensures((#[trigger] old(self).remaining()[index as int],), true)
328                    &&& forall |i| 0 <= i < index as int ==>
329                        predicate.ensures((#[trigger] old(self).remaining()[i],), false)
330                }
331            };
332
333    fn rev(self) -> (r: Rev<Self>)
334        where Self: Sized,
335        ensures
336            self.obeys_prophetic_iter_laws() ==> rev_post(self, r),
337    ;
338
339    fn size_hint(&self) -> ((lower, upper): (usize, Option<usize>))
340        ensures
341            self.obeys_prophetic_iter_laws() ==>
342                lower <= self.remaining().len() && (upper matches Some(b) ==> self.remaining().len() <= b),
343        default_ensures
344            (lower, upper) == (0usize, None),
345    ;
346
347    fn skip(self, n: usize) -> (s: Skip<Self>)
348        where Self: Sized,
349        ensures
350            self.obeys_prophetic_iter_laws() ==> skip_post(self, n, s),
351    ;
352
353    fn take(self, n: usize) -> (t: Take<Self>)
354        where Self: Sized,
355        ensures
356            self.obeys_prophetic_iter_laws() ==> take_post(self, n, t),
357    ;
358
359    #[verifier::impls_cannot_extend_spec]
360    fn zip<U>(self, other: U) -> (r: Zip<Self, <U as IntoIterator>::IntoIter>)
361        where
362            Self: Sized,
363            U: IntoIterator,
364        ensures
365            self.obeys_prophetic_iter_laws() ==> zip_post(self, other, r),
366    ;
367}
368
369#[verifier::external_trait_specification]
370#[verifier::external_trait_extension(DoubleEndedIteratorSpec via DoubleEndedIteratorSpecImpl)]
371pub trait ExDoubleEndedIterator : Iterator {
372    type ExternalTraitSpecificationFor: DoubleEndedIterator;
373
374    // In the specs below, we write out the type parameters explicitly, rather than using the more concise form,
375    // e.g., `final(self).obeys_prophetic_iter_laws()`.  If we use the latter, then Rust elaborates it to
376    // `(&final(self)).obeys_prophetic_iter_laws()`, which means the type of the argument is `& &mut Self`,
377    // which means the type argument inferred for `obeys_prophetic_iter_laws` is `&mut Self`.
378    // This happens because of the existing Rust [trait impl](https://doc.rust-lang.org/std/iter/trait.Iterator.html#impl-Iterator-for-%26mut+I):
379    // ```
380    // impl<I> Iterator for &mut I
381    // where
382    //     I: Iterator + ?Sized,[4:21 AM]
383    // ```
384    fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
385        ensures
386            iter_state_preserved!(old(self), final(self)),
387            // `next_back` pops the tail of the prophesized remaining(), or returns None
388            <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) ==>
389            ({
390                if <Self as IteratorSpec>::remaining(old(self)).len() > 0 {
391                    &&& <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)).drop_last()
392                    &&& <Self as IteratorSpec>::produces(final(self)) == <Self as IteratorSpec>::produces(old(self)).drop_last()
393                    &&& ret == Some(<Self as IteratorSpec>::remaining(old(self)).last())
394                    &&& <Self as IteratorSpec>::produces(old(self)).last()
395                } else {
396                    &&& <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self))
397                    &&& <Self as IteratorSpec>::produces(final(self)) == <Self as IteratorSpec>::produces(old(self))
398                    &&& ret == None
399                }
400            }),
401            // If the iterator isn't done yet, then it successfully decreases its metric (if any)
402            <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) && <Self as IteratorSpec>::remaining(old(self)).len() > 0 && <Self as IteratorSpec>::decrease(final(self)) is Some ==>
403                <Self as IteratorSpec>::decrease(old(self))->0 > <Self as IteratorSpec>::decrease(final(self))->0,
404    ;
405
406    /******* Mechanisms that support ergonomic `for` loops *********/
407
408    // If we can make a useful guess as to what the i-th value from the back will be, return it.
409    // Otherwise, return None.
410    spec fn peek_back(&self, index: int) -> Option<Self::Item>;
411}
412
413#[verifier::external_trait_specification]
414#[verifier::external_trait_extension(ExactSizeIteratorSpec via ExactSizeIteratorSpecImpl)]
415pub trait ExExactSizeIterator: Iterator {
416    type ExternalTraitSpecificationFor: ExactSizeIterator;
417
418    // An `ExactSizeIterator` can specify its length non-prophetically,
419    // i.e., without using `self.remaining().len()`.
420    spec fn exact_len(&self) -> usize;
421
422    fn len(&self) -> (len: usize)
423        ensures
424            self.obeys_prophetic_iter_laws() ==> len == self.exact_len() == self.remaining().len() == self.produces().len(),
425    ;
426}
427
428/********************************************************************************
429 * Definitions for `IntoIterator` and `FromIterator``
430 ********************************************************************************/
431#[verifier::external_trait_specification]
432pub trait ExIntoIterator {
433    type ExternalTraitSpecificationFor: core::iter::IntoIterator;
434
435    type Item;
436    type IntoIter: Iterator<Item = Self::Item>;
437
438    fn into_iter(self) -> Self::IntoIter;
439}
440
441pub open spec fn iter_into_iter_spec<I: Iterator>(i: I) -> I {
442    i
443}
444
445#[verifier::when_used_as_spec(iter_into_iter_spec)]
446pub assume_specification<I: Iterator>[ <I as IntoIterator>::into_iter ](i: I) -> (r: I)
447    ensures
448        r == i,
449;
450
451#[verifier::external_trait_specification]
452#[verifier::external_trait_extension(FromIteratorSpec via FromIteratorSpecImpl)]
453pub trait ExFromIterator<A>: Sized {
454    type ExternalTraitSpecificationFor: FromIterator<A>;
455
456    // `produces` indicates whether the items at indices in `remaining` are actually computed
457    spec fn from_iter_ensures(remaining: Seq<A>, produces: Seq<bool>, s: Self) -> bool;
458
459    // from_iter may be nondeterministic, which we represent with an existential
460    #[verifier::impls_cannot_extend_spec]
461    fn from_iter<T>(iter: T) -> (s: Self)
462       where T: IntoIterator<Item = A>
463        ensures
464            exists |initial: T::IntoIter|
465                #[trigger] (T::into_iter).ensures((iter,), initial)
466                && (initial.obeys_prophetic_iter_laws() ==>
467                    Self::from_iter_ensures(initial.remaining(), initial.produces(), s)),
468    ;
469}
470
471/********************************************************************************
472 * Definitions for `&mut I`
473 ********************************************************************************/
474// Forwarding spec impl for the Rust-supplied blanket `impl<I> Iterator for &mut I`.
475// Without this, bare method-call syntax on a `i: &mut I` receiver (e.g. `i.remaining()`)
476// resolves to these (otherwise uninterpreted) functions on `&mut I` rather than on `I`,
477// silently disconnecting clients from `I`'s actual specs.
478impl <I> IteratorSpecImpl for &mut I
479    where I: Iterator {
480    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
481        <I as IteratorSpec>::obeys_prophetic_iter_laws(*self)
482    }
483
484    #[verifier::prophetic]
485    open spec fn remaining(&self) -> Seq<Self::Item> {
486        <I as IteratorSpec>::remaining(*self)
487    }
488
489    #[verifier::prophetic]
490    open spec fn produces(&self) -> Seq<bool> {
491        <I as IteratorSpec>::produces(*self)
492    }
493
494    open spec fn decrease(&self) -> Option<nat> {
495        <I as IteratorSpec>::decrease(*self)
496    }
497
498    open spec fn peek(&self, index: int) -> Option<Self::Item> {
499        <I as IteratorSpec>::peek(*self, index)
500    }
501}
502
503/********************************************************************************
504 * Definitions for `filter()`
505 ********************************************************************************/
506#[verifier::external_body]
507#[verifier::external_type_specification]
508#[verifier::reject_recursive_types(I)]
509#[verifier::reject_recursive_types(F)]
510pub struct ExFilter<I, F>(Filter<I, F>);
511
512// Ghost accessor for the inner iterator
513pub uninterp spec fn filter_iter<I, F>(r: Filter<I, F>) -> I;
514
515// Ghost accessor for the inner predicate
516pub uninterp spec fn filter_fun<I, F>(r: Filter<I, F>) -> F;
517
518// Ghost accessor for the decisions at every inner position.
519#[verifier::prophetic]
520pub uninterp spec fn filter_keep<I, F>(r: Filter<I, F>) -> Seq<bool>;
521
522// Define Iter::filter's postcondition
523pub uninterp spec fn filter_post<I, F>(i: I, f: F, r: Filter<I, F>) -> bool;
524
525// See examples/iterators/map_and_filter.rs for a verified version of this interface.
526// Any changes here should first be verified over there.
527pub broadcast axiom fn filter_postcondition<I, F>(i: I, f: F, r: core::iter::Filter<I, F>)
528    where
529        I: IteratorSpec,
530        F: FnMut(&I::Item) -> bool,
531    requires
532        #[trigger] filter_post(i, f, r),
533    ensures
534        {
535            let keep = filter_keep(r);
536            {
537            // Discarding a position requires producing its value and a false predicate result.
538            // A position that gets stuck is retained, with a false production flag.
539            &&& keep.len() == i.remaining().len()
540            &&& forall |j| 0 <= j < keep.len() && !(#[trigger] keep[j]) ==>
541                i.produces()[j] && f.ensures((&i.remaining()[j],), false)
542            &&& forall |j| 0 <= j < keep.len() && #[trigger] keep[j] ==> {
543                let k = i.remaining()[..j].filter_index(|idx: int| keep[idx]).len() as int;
544                IteratorSpec::produces(&r)[k] ==>
545                    i.produces()[j] && f.ensures((&i.remaining()[j],), true)
546            }
547            // Completeness: Every inner element the predicate keeps is retained and in order.
548            &&& IteratorSpec::remaining(&r) == i.remaining().filter_index(|j: int| keep[j])
549            // Expose the size bound and source positions directly for convenience.
550            &&& IteratorSpec::produces(&r).len() == IteratorSpec::remaining(&r).len()
551            &&& IteratorSpec::remaining(&r).len() <= i.remaining().len()
552            &&& forall |k| #![trigger IteratorSpec::remaining(&r)[k]] 0 <= k < IteratorSpec::remaining(&r).len() ==>
553                    exists |j| 0 <= j < i.remaining().len()
554                        && IteratorSpec::remaining(&r)[k] == #[trigger] i.remaining()[j]
555                        && keep[j]
556                        && k == i.remaining()[..j].filter_index(|idx: int| keep[idx]).len()
557                        && (IteratorSpec::produces(&r)[k] ==>
558                            i.produces()[j] && f.ensures((&i.remaining()[j],), true))
559            &&& IteratorSpec::decrease(&r) is Some == i.decrease() is Some
560            &&& filter_iter(r) == i
561            &&& filter_fun(r) == f
562            }
563        },
564;
565
566impl <I, P> IteratorSpecImpl for core::iter::Filter<I, P>
567    where
568        I: Iterator + IteratorSpec,
569        P: FnMut(&I::Item) -> bool,
570{
571    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
572        filter_iter(*self).obeys_prophetic_iter_laws()
573    }
574
575    #[verifier::prophetic]
576    uninterp spec fn remaining(&self) -> Seq<Self::Item>;
577
578    #[verifier::prophetic]
579    uninterp spec fn produces(&self) -> Seq<bool>;
580
581    uninterp spec fn decrease(&self) -> Option<nat>;
582
583    // `filter` cannot make a useful static guess about which element will be returned at a given index,
584    // since that depends on prophetic evaluations of the predicate.
585    open spec fn peek(&self, index: int) -> Option<Self::Item> {
586        None
587    }
588}
589
590/********************************************************************************
591 * Definitions for `map()`
592 ********************************************************************************/
593#[verifier::external_body]
594#[verifier::external_type_specification]
595#[verifier::reject_recursive_types(I)]
596#[verifier::reject_recursive_types(F)]
597pub struct ExMap<I, F>(core::iter::Map<I, F>);
598
599// Ghost accessor for the inner iterator
600pub uninterp spec fn map_iter<I, F>(r: core::iter::Map<I, F>) -> I;
601
602// Ghost accessor for the inner function
603pub uninterp spec fn map_fun<I, F>(r: core::iter::Map<I, F>) -> F;
604
605// Define Iter::map's postcondition
606pub uninterp spec fn map_post<I, F>(i: I, f: F, r: core::iter::Map<I, F>) -> bool;
607
608// See examples/iterators/map_and_filter.rs for a verified version of this interface.
609// Any changes here should first be verified over there.
610pub broadcast axiom fn map_postcondition<I, F>(i: I, f: F, r: core::iter::Map<I, F>)
611    where
612        I: IteratorSpec,
613        F: FnMut<(I::Item,)>,
614    requires
615        #[trigger] map_post(i, f, r),
616    ensures
617        IteratorSpec::remaining(&r).len() == i.remaining().len(),
618        IteratorSpec::produces(&r).len() == IteratorSpec::remaining(&r).len(),
619        forall |k| #![trigger IteratorSpec::remaining(&r)[k]] #![trigger IteratorSpec::produces(&r)[k]]
620            0 <= k < IteratorSpec::remaining(&r).len() && IteratorSpec::produces(&r)[k] ==>
621            i.produces()[k] && f.ensures((i.remaining()[k],), IteratorSpec::remaining(&r)[k]),
622        IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
623        map_iter(r) == i,
624        map_fun(r) == f,
625;
626
627impl <B, I, F> IteratorSpecImpl for core::iter::Map<I, F>
628    where
629        I: Iterator + IteratorSpec,
630        F: FnMut(I::Item) -> B,
631{
632
633    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
634        map_iter(*self).obeys_prophetic_iter_laws()
635    }
636
637    #[verifier::prophetic]
638    uninterp spec fn remaining(&self) -> Seq<B>;
639
640    #[verifier::prophetic]
641    uninterp spec fn produces(&self) -> Seq<bool>;
642
643    uninterp spec fn decrease(&self) -> Option<nat>;
644
645    open spec fn peek(&self, index: int) -> Option<B> {
646        match map_iter(*self).peek(index) {
647            Some(v) => {
648                let x = choose |x| map_fun(*self).ensures((v,), x);
649                Some(x)
650            }
651            None => None,
652        }
653    }
654}
655
656impl <B, I, F> DoubleEndedIteratorSpecImpl for core::iter::Map<I, F>
657    where I: DoubleEndedIterator + IteratorSpec,
658          F: FnMut(I::Item) -> B,
659{
660    open spec fn peek_back(&self, index: int) -> Option<B> {
661        match map_iter(*self).peek_back(index) {
662            Some(v) => {
663                let x = choose |x| map_fun(*self).ensures((v,), x);
664                Some(x)
665            }
666            None => None,
667        }
668    }
669}
670
671/********************************************************************************
672 * Definitions for `rev()`
673 ********************************************************************************/
674#[verifier::external_body]
675#[verifier::external_type_specification]
676#[verifier::reject_recursive_types(I)]
677pub struct ExRev<I>(Rev<I>);
678
679// Ghost accessor for the inner iterator
680pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
681
682// Define Iter::rev's postcondition
683pub uninterp spec fn rev_post<I>(i: I, r: Rev<I>) -> bool;
684
685pub broadcast axiom fn rev_postcondition<I: DoubleEndedIteratorSpec>(i: I, r: Rev<I>)
686    requires
687        #[trigger] rev_post(i, r),
688    ensures
689        IteratorSpec::remaining(&r) == IteratorSpec::remaining(&i).reverse(),
690        IteratorSpec::produces(&r) == i.produces().reverse(),
691        IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
692;
693
694impl <I> IteratorSpecImpl for Rev<I>
695    where I: DoubleEndedIterator + DoubleEndedIteratorSpec {
696    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
697        rev_iter(*self).obeys_prophetic_iter_laws()
698    }
699
700    #[verifier::prophetic]
701    closed spec fn remaining(&self) -> Seq<Self::Item> {
702        rev_iter(*self).remaining().reverse()
703    }
704
705    #[verifier::prophetic]
706    closed spec fn produces(&self) -> Seq<bool> {
707        rev_iter(*self).produces().reverse()
708    }
709
710    closed spec fn decrease(&self) -> Option<nat> {
711        rev_iter(*self).decrease()
712    }
713
714    open spec fn peek(&self, index: int) -> Option<Self::Item> {
715        rev_iter(*self).peek_back(index)
716    }
717}
718
719impl <I> DoubleEndedIteratorSpecImpl for Rev<I>
720    where I: DoubleEndedIterator + IteratorSpec {
721
722    open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
723        rev_iter(*self).peek(index)
724    }
725}
726
727/********************************************************************************
728 * Definitions for `skip()`
729 ********************************************************************************/
730#[verifier::external_body]
731#[verifier::external_type_specification]
732#[verifier::reject_recursive_types(I)]
733pub struct ExSkip<I>(Skip<I>);
734
735// Ghost accessor for the inner iterator
736pub uninterp spec fn skip_iter<I>(s: Skip<I>) -> I;
737
738// Ghost accessor for the initial count of items to skip
739pub uninterp spec fn skip_init_n<I>(s: Skip<I>) -> usize;
740
741// Define Iter::skip's postcondition
742pub uninterp spec fn skip_post<I>(i: I, n: usize, s: Skip<I>) -> bool;
743
744pub broadcast axiom fn skip_postcondition<I: IteratorSpec>(i: I, n: usize, r: Skip<I>)
745    requires
746        i.obeys_prophetic_iter_laws(),
747        #[trigger] skip_post(i, n, r),
748    ensures
749        IteratorSpec::remaining(&r) == if i.remaining().len() < n { Seq::empty() } else { i.remaining()[n..] },
750        IteratorSpec::produces(&r) == if i.remaining().len() < n { Seq::empty() } else { i.produces()[n..] },
751        skip_iter(r) == i,
752        skip_init_n(r) == n,
753        IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
754;
755
756impl <I> IteratorSpecImpl for Skip<I>
757    where I: Iterator {
758    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
759        skip_iter(*self).obeys_prophetic_iter_laws()
760    }
761
762    #[verifier::prophetic]
763    uninterp spec fn remaining(&self) -> Seq<Self::Item>;
764
765    #[verifier::prophetic]
766    uninterp spec fn produces(&self) -> Seq<bool>;
767
768    uninterp spec fn decrease(&self) -> Option<nat>;
769
770    open spec fn peek(&self, index: int) -> Option<Self::Item> {
771        skip_iter(*self).peek(skip_init_n(*self) + index)
772    }
773}
774
775impl <I> DoubleEndedIteratorSpecImpl for Skip<I>
776    where I: DoubleEndedIteratorSpec + ExactSizeIteratorSpec
777{
778    open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
779        // Skip only drops elements from the front, so the back of the skipped
780        // sequence coincides with the back of the inner iterator, as long as
781        // `index` stays within the (un-skipped) remaining elements.
782        let len = skip_iter(*self).exact_len();
783        if len < skip_init_n(*self) || index >= len - skip_init_n(*self) {
784            None
785        } else {
786            skip_iter(*self).peek_back(index)
787        }
788    }
789}
790
791/********************************************************************************
792 * Definitions for `take()`
793 ********************************************************************************/
794#[verifier::external_body]
795#[verifier::external_type_specification]
796#[verifier::reject_recursive_types(I)]
797pub struct ExTake<I>(Take<I>);
798
799// Ghost accessor for the inner iterator
800pub uninterp spec fn take_iter<I>(r: Take<I>) -> I;
801
802// Ghost accessor for the count
803pub uninterp spec fn take_count<I>(r: Take<I>) -> usize;
804
805// Define Iter::take's postcondition
806pub uninterp spec fn take_post<I>(i: I, n: usize, t: Take<I>) -> bool;
807
808// See examples/iterators/take.rs for a verified version of this interface.
809// Any changes here should first be verified over there.
810pub broadcast axiom fn take_postcondition<I: IteratorSpec>(i: I, n: usize, r: Take<I>)
811    requires
812        i.obeys_prophetic_iter_laws(),
813        #[trigger] take_post(i, n, r),
814    ensures
815        IteratorSpec::remaining(&r) == if i.remaining().len() < n { i.remaining() } else { i.remaining()[..n] },
816        IteratorSpec::produces(&r) == if i.remaining().len() < n { i.produces() } else { i.produces()[..n] },
817        take_iter(r) == i,
818        take_count(r) == n,
819        IteratorSpec::decrease(&r) is Some,
820;
821
822impl <I> IteratorSpecImpl for Take<I>
823    where I: Iterator {
824    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
825        take_iter(*self).obeys_prophetic_iter_laws()
826    }
827
828    #[verifier::prophetic]
829    uninterp spec fn remaining(&self) -> Seq<Self::Item>;
830
831    #[verifier::prophetic]
832    uninterp spec fn produces(&self) -> Seq<bool>;
833
834    uninterp spec fn decrease(&self) -> Option<nat>;
835
836    open spec fn peek(&self, index: int) -> Option<Self::Item> {
837        take_iter(*self).peek(index)
838    }
839}
840
841impl <I> DoubleEndedIteratorSpecImpl for Take<I>
842    where I: DoubleEndedIteratorSpec + ExactSizeIteratorSpec
843{
844    open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
845        let len = take_iter(*self).exact_len();
846        if len < take_count(*self) {
847            None
848        } else {
849            take_iter(*self).peek_back(len - take_count(*self) - index - 1)
850        }
851    }
852}
853
854/********************************************************************************
855 * Definitions for `zip()`
856 ********************************************************************************/
857#[verifier::external_body]
858#[verifier::external_type_specification]
859#[verifier::reject_recursive_types(A)]
860#[verifier::reject_recursive_types(B)]
861pub struct ExZip<A, B>(Zip<A, B>);
862
863// Ghost accessor for the first inner iterator
864pub uninterp spec fn zip_iter_fst<A, B>(z: Zip<A, B>) -> A;
865
866// Ghost accessor for the second inner iterator
867pub uninterp spec fn zip_iter_snd<A, B>(z: Zip<A, B>) -> B;
868
869impl<A, B> IteratorSpecImpl for Zip<A, B>
870    where A: Iterator + IteratorSpec, B: Iterator + IteratorSpec
871{
872    open spec fn obeys_prophetic_iter_laws(&self) -> bool {
873        &&& zip_iter_fst(*self).obeys_prophetic_iter_laws()
874        &&& zip_iter_snd(*self).obeys_prophetic_iter_laws()
875    }
876
877    #[verifier::prophetic]
878    closed spec fn remaining(&self) -> Seq<Self::Item> {
879        zip_iter_fst(*self).remaining().zip_truncate(zip_iter_snd(*self).remaining())
880    }
881
882    #[verifier::prophetic]
883    closed spec fn produces(&self) -> Seq<bool> {
884        zip_iter_fst(*self).produces().zip_truncate(zip_iter_snd(*self).produces()).map_values(|p: (bool, bool)| p.0 && p.1)
885    }
886
887    closed spec fn decrease(&self) -> Option<nat> {
888        match (zip_iter_fst(*self).decrease(), zip_iter_snd(*self).decrease()) {
889            (Some(a), Some(b)) => if a <= b { Some(a) } else { Some(b) },
890            (Some(a), None) => Some(a),
891            (None, Some(b)) => Some(b),
892            (None, None) => None,
893        }
894    }
895
896    open spec fn peek(&self, index: int) -> Option<Self::Item> {
897        match (zip_iter_fst(*self).peek(index), zip_iter_snd(*self).peek(index)) {
898            (Some(a), Some(b)) => Some((a, b)),
899            _ => None,
900        }
901    }
902}
903
904// Define Iter::zip's postcondition
905pub uninterp spec fn zip_post<I, U, Z>(i: I, other: U, r: Z) -> bool;
906
907pub broadcast axiom fn zip_postcondition<I, U>(i: I, other: U, r: Zip<I, <U as IntoIterator>::IntoIter>)
908    where
909            I: Sized + IteratorSpec,
910            U: IntoIterator, //Spec,
911    requires
912        i.obeys_prophetic_iter_laws(),
913        #[trigger] zip_post(i, other, r),
914    ensures
915        (U::into_iter).ensures((other,), zip_iter_snd(r)),
916        zip_iter_fst(r) == i,
917        IteratorSpec::remaining(&r) == i.remaining().zip_truncate(zip_iter_snd(r).remaining()),
918        IteratorSpec::produces(&r) == i.produces().zip_truncate(zip_iter_snd(r).produces()).map_values(|p: (bool, bool)| p.0 && p.1),
919        IteratorSpec::decrease(&r) is Some == (i.decrease() is Some || zip_iter_snd(r).decrease() is Some),
920;
921
922/********************************************************************************
923 * Defines a convenient wrapper type that bundles state and invariants needed
924 * for ergonomic for-loop support.
925 ********************************************************************************/
926
927pub struct VerusForLoopWrapper<I: Iterator> {
928    pub index: Ghost<int>,
929    pub snapshot: Ghost<I>,
930    pub iter: I,
931    pub history: Ghost<Seq<I::Item>>,
932}
933
934impl <I: Iterator> VerusForLoopWrapper<I> {
935    #[verifier::prophetic]
936    pub open spec fn seq(self) -> Seq<I::Item> {
937        self.snapshot@.remaining()
938    }
939
940    // Keep the interface for history and seq the same
941    pub open spec fn history(self) -> Seq<I::Item> {
942        self.history@
943    }
944
945    pub open spec fn index(self) -> int {
946        self.index@
947    }
948
949    /// These properties help maintain the properties in wf,
950    /// but they don't need to be exposed to the client
951    #[verifier::prophetic]
952    pub closed spec fn wf_inner(self) -> bool {
953        &&& self.iter.remaining().len() == self.seq().len() - self.index()
954        &&& forall |i| 0 <= i < self.iter.remaining().len() ==> #[trigger] self.iter.remaining()[i] == self.seq()[self.index() + i]
955        &&& self.index() <= self.snapshot@.produces().len()
956        &&& self.iter.produces() == self.snapshot@.produces().skip(self.index())
957    }
958
959    /// These properties are needed for the client code to verify
960    #[verifier::prophetic]
961    pub open spec fn wf(self) -> bool {
962        &&& 0 <= self.index() <= self.seq().len()
963        &&& self.wf_inner()
964        &&& self.iter.obeys_prophetic_iter_laws() ==> {
965                &&& self.history@.len() == self.index()
966                &&& forall |i| 0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
967                &&& self.snapshot@.produces().take(self.index()).all(|p: bool| p)
968            }
969    }
970
971    /// Bundle the real iterator with its ghost state and loop invariants
972    pub fn new(iter: I) -> (s: Self)
973        ensures
974            s.index == 0,
975            s.snapshot == iter,
976            s.iter == iter,
977            s.history@ == Seq::<I::Item>::empty(),
978            s.wf(),
979    {
980        broadcast use group_seq_lemmas;
981        proof {
982            assert(iter.produces().skip(0) =~= iter.produces());
983        }
984        VerusForLoopWrapper {
985            index: Ghost(0),
986            snapshot: Ghost(iter),
987            iter,
988            history: Ghost(Seq::empty()),
989        }
990    }
991
992    /// Advance the underlying (real) iterator and prove
993    /// that the loop invariants are preserved.
994    pub fn next(&mut self) -> (ret: Option<I::Item>)
995        requires
996            old(self).wf(),
997        ensures
998            final(self).seq() == old(self).seq(),
999            final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
1000            final(self).snapshot == old(self).snapshot,
1001            final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
1002            final(self).iter.obeys_prophetic_iter_laws() && ret is None ==>
1003                final(self).index() == final(self).seq().len()
1004                    && final(self).snapshot@.produces().all(|p: bool| p),
1005            final(self).iter.obeys_prophetic_iter_laws() ==> (ret matches Some(r) ==>
1006                r == old(self).seq()[old(self).index()] && old(self).snapshot@.produces()[old(self).index()]),
1007            // History updates always hold
1008            ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
1009            ret is None ==> final(self).history@ == old(self).history@,
1010            // All of the standard Iterator::next guarantees still hold
1011            exists |m: &mut I| #![auto] (I::next).ensures((m,), ret) && *m == old(self).iter && *final(m) == final(self).iter,
1012    {
1013        let ghost old_history = self.history@;
1014        let ret = self.iter.next();
1015        if ret.is_some() {
1016            self.history = Ghost(old_history.push(ret->0));
1017        }
1018        proof {
1019            broadcast use group_seq_lemmas;
1020            if ret.is_some() {
1021                self.index@ = self.index@ + 1;
1022            }
1023            if self.iter.obeys_prophetic_iter_laws() {
1024                assert(self.snapshot@.produces().len() == self.seq().len());
1025                assert(self.iter.produces() =~= self.snapshot@.produces().skip(self.index()));
1026                if ret.is_none() {
1027                    assert(self.snapshot@.produces().take(self.index()) =~= self.snapshot@.produces());
1028                }
1029            }
1030        }
1031        ret
1032    }
1033}
1034
1035// Artificial function used when we desguar a for loop.
1036// It helps bring the definition of `peek` into scope,
1037// resulting in better automation for some proofs.
1038pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
1039
1040/********************************************************************************
1041 * Definitions for the Step trait
1042 ********************************************************************************/
1043#[verifier::external_trait_specification]
1044#[verifier::external_trait_extension(StepSpec via StepSpecImpl)]
1045pub trait ExIterStep: Clone + PartialOrd + Sized {
1046    type ExternalTraitSpecificationFor: core::iter::Step;
1047
1048    // REVIEW: it would be nice to be able to use SpecOrd::spec_lt (not yet supported)
1049    // TODO: We should now be able to use cmp_spec or partial_cmp_spec here.
1050    spec fn spec_is_lt(self, other: Self) -> bool;
1051
1052    spec fn spec_steps_between(self, end: Self) -> Option<usize>;
1053
1054    spec fn spec_steps_between_int(self, end: Self) -> int;
1055
1056    spec fn spec_forward_checked(self, count: usize) -> Option<Self>;
1057
1058    spec fn spec_forward_checked_int(self, count: int) -> Option<Self>;
1059
1060    spec fn spec_backward_checked(self, count: usize) -> Option<Self>;
1061
1062    spec fn spec_backward_checked_int(self, count: int) -> Option<Self>;
1063}
1064
1065
1066/********************************************************************************
1067 * Collect our broadcast definitions
1068 ********************************************************************************/
1069
1070pub broadcast group group_iter_axioms {
1071    rev_postcondition,
1072    zip_postcondition,
1073    filter_postcondition,
1074    take_postcondition,
1075    skip_postcondition,
1076    map_postcondition,
1077}
1078
1079} // verus!