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 spec fn obeys_prophetic_iter_laws(&self) -> bool;
22
23 #[verifier::prophetic]
25 spec fn remaining(&self) -> Seq<Self::Item>;
26
27 #[verifier::prophetic]
32 spec fn will_return_none(&self) -> bool;
33
34 fn next(&mut self) -> (ret: Option<Self::Item>)
36 ensures
37 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 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 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 spec fn decrease(&self) -> Option<nat>;
63
64 spec fn peek(&self, index: int) -> Option<Self::Item>;
67
68
69
70 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 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 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 final(self).obeys_prophetic_iter_laws() && !r ==> {
104 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
105 {
106 &&& 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 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 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 final(self).obeys_prophetic_iter_laws() && r ==> {
137 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
138 {
139 &&& 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 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 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 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 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 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 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 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 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 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 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 fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
328 ensures
329 <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 <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 <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 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 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#[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
392pub uninterp spec fn into_iter_remaining<A, T>(iter: T) -> Seq<A>;
396
397pub 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
419impl <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#[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
460pub uninterp spec fn filter_iter<I, F>(r: Filter<I, F>) -> I;
462
463pub uninterp spec fn filter_fun<I, F>(r: Filter<I, F>) -> F;
465
466#[verifier::prophetic]
469pub uninterp spec fn filter_keep<I, F>(r: Filter<I, F>) -> Seq<bool>;
470
471pub 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.len() <= i.remaining().len()
489 &&& forall |j| 0 <= j < keep.len() ==> call_ensures(f, (&i.remaining()[j],), #[trigger] keep[j])
490 &&& IteratorSpec::remaining(&r) == i.remaining()[..keep.len()].filter_index(|j: int| keep[j])
492 &&& 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
506impl <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 open spec fn peek(&self, index: int) -> Option<Self::Item> {
528 None
529 }
530}
531
532#[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
541pub uninterp spec fn map_iter<I, F>(r: core::iter::Map<I, F>) -> I;
543
544pub uninterp spec fn map_fun<I, F>(r: core::iter::Map<I, F>) -> F;
546
547pub 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
566impl <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#[verifier::external_body]
616#[verifier::external_type_specification]
617#[verifier::reject_recursive_types(I)]
618pub struct ExRev<I>(Rev<I>);
619
620pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
622
623pub 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#[verifier::external_body]
672#[verifier::external_type_specification]
673#[verifier::reject_recursive_types(I)]
674pub struct ExSkip<I>(Skip<I>);
675
676pub uninterp spec fn skip_iter<I>(s: Skip<I>) -> I;
678
679pub uninterp spec fn skip_init_n<I>(s: Skip<I>) -> usize;
681
682pub 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 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#[verifier::external_body]
736#[verifier::external_type_specification]
737#[verifier::reject_recursive_types(I)]
738pub struct ExTake<I>(Take<I>);
739
740pub uninterp spec fn take_iter<I>(r: Take<I>) -> I;
742
743pub uninterp spec fn take_count<I>(r: Take<I>) -> usize;
745
746pub 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
761impl <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#[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
804pub uninterp spec fn zip_iter_fst<A, B>(z: Zip<A, B>) -> A;
806
807pub 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
845pub 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, 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
863pub 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 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 #[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 #[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 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 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 ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
944 ret is None ==> final(self).history@ == old(self).history@,
945 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
963pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
967
968#[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 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
994pub 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}