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