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 map<B, F>(self, f: F) -> (r: core::iter::Map<Self, F>)
206 where
207 Self: Sized,
208 F: FnMut(Self::Item) -> B,
209 requires
210 forall |k| #![auto] 0 <= k < self.remaining().len() ==> call_requires(f, (self.remaining()[k], )),
211 ensures
212 self.obeys_prophetic_iter_laws() ==> map_post(self, f, r),
213 ;
214
215 fn rev(self) -> (r: Rev<Self>)
216 where Self: Sized,
217 ensures
218 self.obeys_prophetic_iter_laws() ==> rev_post(self, r),
219 ;
220
221 fn skip(self, n: usize) -> (s: Skip<Self>)
222 where Self: Sized,
223 ensures
224 self.obeys_prophetic_iter_laws() ==> skip_post(self, n, s),
225 ;
226
227 fn take(self, n: usize) -> (t: Take<Self>)
228 where Self: Sized,
229 ensures
230 self.obeys_prophetic_iter_laws() ==> take_post(self, n, t),
231 ;
232
233 #[verifier::impls_cannot_extend_spec]
234 fn zip<U>(self, other: U) -> (r: Zip<Self, <U as IntoIterator>::IntoIter>)
235 where
236 Self: Sized,
237 U: IntoIterator,
238 ensures
239 self.obeys_prophetic_iter_laws() ==> zip_post(self, other, r),
240 ;
241}
242
243#[verifier::external_trait_specification]
244#[verifier::external_trait_extension(DoubleEndedIteratorSpec via DoubleEndedIteratorSpecImpl)]
245pub trait ExDoubleEndedIterator : Iterator {
246 type ExternalTraitSpecificationFor: DoubleEndedIterator;
247
248 fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
259 ensures
260 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) == <Self as IteratorSpec>::obeys_prophetic_iter_laws(old(self)),
262 <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)),
263 <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),
264 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) ==>
266 ({
267 if <Self as IteratorSpec>::remaining(old(self)).len() > 0 {
268 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)).drop_last()
269 && ret == Some(<Self as IteratorSpec>::remaining(old(self)).last())
270 } else {
271 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)) && ret == None && <Self as IteratorSpec>::will_return_none(final(self))
272 }
273 }),
274 <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 ==>
276 <Self as IteratorSpec>::decrease(old(self))->0 > <Self as IteratorSpec>::decrease(final(self))->0,
277 ;
278
279 spec fn peek_back(&self, index: int) -> Option<Self::Item>;
284}
285
286#[verifier::external_trait_specification]
287#[verifier::external_trait_extension(ExactSizeIteratorSpec via ExactSizeIteratorSpecImpl)]
288pub trait ExExactSizeIterator: Iterator {
289 type ExternalTraitSpecificationFor: ExactSizeIterator;
290
291 spec fn exact_len(&self) -> usize;
294
295 fn len(&self) -> (len: usize)
296 ensures
297 self.obeys_prophetic_iter_laws() ==> len == self.exact_len() == self.remaining().len();
298}
299
300#[verifier::external_trait_specification]
304pub trait ExIntoIterator {
305 type ExternalTraitSpecificationFor: core::iter::IntoIterator;
306
307 type Item;
308 type IntoIter: Iterator<Item = Self::Item>;
309
310 fn into_iter(self) -> Self::IntoIter;
311}
312
313pub open spec fn iter_into_iter_spec<I: Iterator>(i: I) -> I {
314 i
315}
316
317#[verifier::when_used_as_spec(iter_into_iter_spec)]
318pub assume_specification<I: Iterator>[ <I as IntoIterator>::into_iter ](i: I) -> (r: I)
319 ensures
320 r == i,
321;
322
323pub uninterp spec fn into_iter_remaining<A, T>(iter: T) -> Seq<A>;
327
328pub broadcast axiom fn axiom_from_iterator_ensures<A, I: Iterator<Item = A> + IteratorSpec>(iter: I)
331 ensures
332 #[trigger] into_iter_remaining::<A, I>(iter) == iter.remaining(),
333;
334
335#[verifier::external_trait_specification]
336#[verifier::external_trait_extension(FromIteratorSpec via FromIteratorSpecImpl)]
337pub trait ExFromIterator<A>: Sized {
338 type ExternalTraitSpecificationFor: FromIterator<A>;
339
340 spec fn from_iter_ensures(remaining: Seq<A>, s: Self) -> bool;
341
342 #[verifier::impls_cannot_extend_spec]
343 fn from_iter<T>(iter: T) -> (s: Self)
344 where T: IntoIterator<Item = A>
345 ensures
346 Self::from_iter_ensures(into_iter_remaining(iter), s),
347 ;
348}
349
350impl <I> IteratorSpecImpl for &mut I
358 where I: Iterator {
359 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
360 <I as IteratorSpec>::obeys_prophetic_iter_laws(*self)
361 }
362
363 #[verifier::prophetic]
364 open spec fn remaining(&self) -> Seq<Self::Item> {
365 <I as IteratorSpec>::remaining(*self)
366 }
367
368 #[verifier::prophetic]
369 open spec fn will_return_none(&self) -> bool {
370 <I as IteratorSpec>::will_return_none(*self)
371 }
372
373 open spec fn decrease(&self) -> Option<nat> {
374 <I as IteratorSpec>::decrease(*self)
375 }
376
377 open spec fn peek(&self, index: int) -> Option<Self::Item> {
378 <I as IteratorSpec>::peek(*self, index)
379 }
380}
381
382#[verifier::external_body]
386#[verifier::external_type_specification]
387#[verifier::reject_recursive_types(I)]
388#[verifier::reject_recursive_types(F)]
389pub struct ExFilter<I, F>(Filter<I, F>);
390
391pub uninterp spec fn filter_iter<I, F>(r: Filter<I, F>) -> I;
393
394pub uninterp spec fn filter_fun<I, F>(r: Filter<I, F>) -> F;
396
397#[verifier::prophetic]
400pub uninterp spec fn filter_keep<I, F>(r: Filter<I, F>) -> Seq<bool>;
401
402pub uninterp spec fn filter_post<I, F>(i: I, f: F, r: Filter<I, F>) -> bool;
404
405pub broadcast axiom fn filter_postcondition<I, F>(i: I, f: F, r: core::iter::Filter<I, F>)
406 where
407 I: IteratorSpec,
408 F: FnMut(&I::Item) -> bool,
409 requires
410 i.obeys_prophetic_iter_laws(),
411 i.decrease() is Some,
412 forall |k| #![auto] 0 <= k < i.remaining().len() ==> call_requires(f, (&i.remaining()[k], )),
413 #[trigger] filter_post(i, f, r),
414 ensures
415 {
416 let keep = filter_keep(r);
417 {
418 &&& keep.len() <= i.remaining().len()
420 &&& forall |j| 0 <= j < keep.len() ==> call_ensures(f, (&i.remaining()[j],), #[trigger] keep[j])
421 &&& IteratorSpec::remaining(&r) == i.remaining()[..keep.len()].filter_index(|j: int| keep[j])
423 &&& IteratorSpec::remaining(&r).len() <= i.remaining().len()
425 &&& forall |k| #![trigger IteratorSpec::remaining(&r)[k]] 0 <= k < IteratorSpec::remaining(&r).len() ==>
426 exists |j| 0 <= j < i.remaining().len()
427 && IteratorSpec::remaining(&r)[k] == #[trigger] i.remaining()[j]
428 && call_ensures(f, (&i.remaining()[j],), true)
429 &&& IteratorSpec::will_return_none(&r) ==> i.will_return_none() && keep.len() == i.remaining().len()
430 &&& IteratorSpec::decrease(&r) is Some == i.decrease() is Some
431 &&& filter_iter(r) == i
432 &&& filter_fun(r) == f
433 }
434 },
435;
436
437impl <I, P> IteratorSpecImpl for core::iter::Filter<I, P>
440 where
441 I: Iterator + IteratorSpec,
442 P: FnMut(&I::Item) -> bool,
443{
444 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
445 filter_iter(*self).obeys_prophetic_iter_laws()
446 }
447
448 #[verifier::prophetic]
449 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
450
451 #[verifier::prophetic]
452 uninterp spec fn will_return_none(&self) -> bool;
453
454 uninterp spec fn decrease(&self) -> Option<nat>;
455
456 open spec fn peek(&self, index: int) -> Option<Self::Item> {
459 None
460 }
461}
462
463#[verifier::external_body]
467#[verifier::external_type_specification]
468#[verifier::reject_recursive_types(I)]
469#[verifier::reject_recursive_types(F)]
470pub struct ExMap<I, F>(core::iter::Map<I, F>);
471
472pub uninterp spec fn map_iter<I, F>(r: core::iter::Map<I, F>) -> I;
474
475pub uninterp spec fn map_fun<I, F>(r: core::iter::Map<I, F>) -> F;
477
478pub uninterp spec fn map_post<I, F>(i: I, f: F, r: core::iter::Map<I, F>) -> bool;
480
481pub broadcast axiom fn map_postcondition<I, F>(i: I, f: F, r: core::iter::Map<I, F>)
482 where
483 I: IteratorSpec,
484 F: FnMut<(I::Item,)>,
485 requires
486 i.obeys_prophetic_iter_laws(),
487 #[trigger] map_post(i, f, r),
488 ensures
489 IteratorSpec::remaining(&r).len() <= i.remaining().len(),
490 forall |k| #![auto] 0 <= k < IteratorSpec::remaining(&r).len() ==> call_ensures(f, (i.remaining()[k],), IteratorSpec::remaining(&r)[k]),
491 IteratorSpec::will_return_none(&r) ==> i.will_return_none() && IteratorSpec::remaining(&r).len() == i.remaining().len(),
492 IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
493 map_iter(r) == i,
494 map_fun(r) == f,
495;
496
497impl <B, I, F> IteratorSpecImpl for core::iter::Map<I, F>
500 where
501 I: Iterator + IteratorSpec,
502 F: FnMut(I::Item) -> B,
503{
504
505 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
506 map_iter(*self).obeys_prophetic_iter_laws()
507 }
508
509 #[verifier::prophetic]
510 uninterp spec fn remaining(&self) -> Seq<B>;
511
512 #[verifier::prophetic]
513 uninterp spec fn will_return_none(&self) -> bool;
514
515 uninterp spec fn decrease(&self) -> Option<nat>;
516
517 open spec fn peek(&self, index: int) -> Option<B> {
518 match map_iter(*self).peek(index) {
519 Some(v) => {
520 let x = choose |x| map_fun(*self).ensures((v,), x);
521 Some(x)
522 }
523 None => None,
524 }
525 }
526}
527
528impl <B, I, F> DoubleEndedIteratorSpecImpl for core::iter::Map<I, F>
529 where I: DoubleEndedIterator + IteratorSpec,
530 F: FnMut(I::Item) -> B,
531{
532 open spec fn peek_back(&self, index: int) -> Option<B> {
533 match map_iter(*self).peek_back(index) {
534 Some(v) => {
535 let x = choose |x| map_fun(*self).ensures((v,), x);
536 Some(x)
537 }
538 None => None,
539 }
540 }
541}
542
543#[verifier::external_body]
547#[verifier::external_type_specification]
548#[verifier::reject_recursive_types(I)]
549pub struct ExRev<I>(Rev<I>);
550
551pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
553
554pub uninterp spec fn rev_post<I>(i: I, r: Rev<I>) -> bool;
556
557pub broadcast axiom fn rev_postcondition<I: DoubleEndedIteratorSpec>(i: I, r: Rev<I>)
558 requires
559 #[trigger] rev_post(i, r),
560 ensures
561 IteratorSpec::remaining(&r) == IteratorSpec::remaining(&i).reverse(),
562 IteratorSpec::will_return_none(&r) == i.will_return_none(),
563 IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
564;
565
566impl <I> IteratorSpecImpl for Rev<I>
567 where I: DoubleEndedIterator + DoubleEndedIteratorSpec {
568 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
569 rev_iter(*self).obeys_prophetic_iter_laws()
570 }
571
572 #[verifier::prophetic]
573 closed spec fn remaining(&self) -> Seq<Self::Item> {
574 rev_iter(*self).remaining().reverse()
575 }
576
577 #[verifier::prophetic]
578 closed spec fn will_return_none(&self) -> bool {
579 rev_iter(*self).will_return_none()
580 }
581
582 closed spec fn decrease(&self) -> Option<nat> {
583 rev_iter(*self).decrease()
584 }
585
586 open spec fn peek(&self, index: int) -> Option<Self::Item> {
587 rev_iter(*self).peek_back(index)
588 }
589}
590
591impl <I> DoubleEndedIteratorSpecImpl for Rev<I>
592 where I: DoubleEndedIterator + IteratorSpec {
593
594 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
595 rev_iter(*self).peek(index)
596 }
597}
598
599#[verifier::external_body]
603#[verifier::external_type_specification]
604#[verifier::reject_recursive_types(I)]
605pub struct ExSkip<I>(Skip<I>);
606
607pub uninterp spec fn skip_iter<I>(s: Skip<I>) -> I;
609
610pub uninterp spec fn skip_init_n<I>(s: Skip<I>) -> usize;
612
613pub uninterp spec fn skip_post<I>(i: I, n: usize, s: Skip<I>) -> bool;
615
616pub broadcast axiom fn skip_postcondition<I: IteratorSpec>(i: I, n: usize, r: Skip<I>)
617 requires
618 i.obeys_prophetic_iter_laws(),
619 #[trigger] skip_post(i, n, r),
620 ensures
621 IteratorSpec::remaining(&r) == if i.remaining().len() < n { Seq::empty() } else { i.remaining()[n..] },
622 skip_iter(r) == i,
623 skip_init_n(r) == n,
624 IteratorSpec::will_return_none(&r) <==> i.will_return_none(),
625 IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
626;
627
628impl <I> IteratorSpecImpl for Skip<I>
629 where I: Iterator {
630 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
631 skip_iter(*self).obeys_prophetic_iter_laws()
632 }
633
634 #[verifier::prophetic]
635 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
636
637 #[verifier::prophetic]
638 uninterp spec fn will_return_none(&self) -> bool;
639
640 uninterp spec fn decrease(&self) -> Option<nat>;
641
642 open spec fn peek(&self, index: int) -> Option<Self::Item> {
643 skip_iter(*self).peek(skip_init_n(*self) + index)
644 }
645}
646
647impl <I> DoubleEndedIteratorSpecImpl for Skip<I>
648 where I: DoubleEndedIteratorSpec + ExactSizeIteratorSpec
649{
650 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
651 let len = skip_iter(*self).exact_len();
655 if len < skip_init_n(*self) || index >= len - skip_init_n(*self) {
656 None
657 } else {
658 skip_iter(*self).peek_back(index)
659 }
660 }
661}
662
663#[verifier::external_body]
667#[verifier::external_type_specification]
668#[verifier::reject_recursive_types(I)]
669pub struct ExTake<I>(Take<I>);
670
671pub uninterp spec fn take_iter<I>(r: Take<I>) -> I;
673
674pub uninterp spec fn take_count<I>(r: Take<I>) -> usize;
676
677pub uninterp spec fn take_post<I>(i: I, n: usize, t: Take<I>) -> bool;
679
680pub broadcast axiom fn take_postcondition<I: IteratorSpec>(i: I, n: usize, r: Take<I>)
681 requires
682 i.obeys_prophetic_iter_laws(),
683 #[trigger] take_post(i, n, r),
684 ensures
685 IteratorSpec::remaining(&r) == if i.remaining().len() < n { i.remaining() } else { i.remaining()[..n] },
686 take_iter(r) == i,
687 take_count(r) == n,
688 IteratorSpec::will_return_none(&r) <==> i.will_return_none() || i.remaining().len() >= n,
689 IteratorSpec::decrease(&r) is Some,
690;
691
692impl <I> IteratorSpecImpl for Take<I>
695 where I: Iterator {
696 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
697 take_iter(*self).obeys_prophetic_iter_laws()
698 }
699
700 #[verifier::prophetic]
701 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
702
703 #[verifier::prophetic]
704 uninterp spec fn will_return_none(&self) -> bool;
705
706 uninterp spec fn decrease(&self) -> Option<nat>;
707
708 open spec fn peek(&self, index: int) -> Option<Self::Item> {
709 take_iter(*self).peek(index)
710 }
711}
712
713impl <I> DoubleEndedIteratorSpecImpl for Take<I>
714 where I: DoubleEndedIteratorSpec + ExactSizeIteratorSpec
715{
716 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
717 let len = take_iter(*self).exact_len();
718 if len < take_count(*self) {
719 None
720 } else {
721 take_iter(*self).peek_back(len - take_count(*self) - index - 1)
722 }
723 }
724}
725
726#[verifier::external_body]
730#[verifier::external_type_specification]
731#[verifier::reject_recursive_types(A)]
732#[verifier::reject_recursive_types(B)]
733pub struct ExZip<A, B>(Zip<A, B>);
734
735pub uninterp spec fn zip_iter_fst<A, B>(z: Zip<A, B>) -> A;
737
738pub uninterp spec fn zip_iter_snd<A, B>(z: Zip<A, B>) -> B;
740
741impl<A, B> IteratorSpecImpl for Zip<A, B>
742 where A: Iterator + IteratorSpec, B: Iterator + IteratorSpec
743{
744 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
745 &&& zip_iter_fst(*self).obeys_prophetic_iter_laws()
746 &&& zip_iter_snd(*self).obeys_prophetic_iter_laws()
747 }
748
749 #[verifier::prophetic]
750 closed spec fn remaining(&self) -> Seq<Self::Item> {
751 zip_iter_fst(*self).remaining().zip_truncate(zip_iter_snd(*self).remaining())
752 }
753
754 #[verifier::prophetic]
755 closed spec fn will_return_none(&self) -> bool {
756 zip_iter_fst(*self).will_return_none() || zip_iter_snd(*self).will_return_none()
757 }
758
759 closed spec fn decrease(&self) -> Option<nat> {
760 match (zip_iter_fst(*self).decrease(), zip_iter_snd(*self).decrease()) {
761 (Some(a), Some(b)) => if a <= b { Some(a) } else { Some(b) },
762 (Some(a), None) => Some(a),
763 (None, Some(b)) => Some(b),
764 (None, None) => None,
765 }
766 }
767
768 open spec fn peek(&self, index: int) -> Option<Self::Item> {
769 match (zip_iter_fst(*self).peek(index), zip_iter_snd(*self).peek(index)) {
770 (Some(a), Some(b)) => Some((a, b)),
771 _ => None,
772 }
773 }
774}
775
776pub uninterp spec fn zip_post<I, U, Z>(i: I, other: U, r: Z) -> bool;
778
779pub broadcast axiom fn zip_postcondition<I, U>(i: I, other: U, r: Zip<I, <U as IntoIterator>::IntoIter>)
780 where
781 I: Sized + IteratorSpec,
782 U: IntoIterator, requires
784 i.obeys_prophetic_iter_laws(),
785 #[trigger] zip_post(i, other, r),
786 ensures
787 call_ensures(U::into_iter, (other,), zip_iter_snd(r)),
788 zip_iter_fst(r) == i,
789 IteratorSpec::remaining(&r) == i.remaining().zip_truncate(zip_iter_snd(r).remaining()),
790 IteratorSpec::will_return_none(&r) ==> i.will_return_none() || zip_iter_snd(r).will_return_none(),
791 IteratorSpec::decrease(&r) is Some == (i.decrease() is Some || zip_iter_snd(r).decrease() is Some),
792;
793
794pub struct VerusForLoopWrapper<I: Iterator> {
800 pub index: Ghost<int>,
801 pub snapshot: Ghost<I>,
802 pub iter: I,
803 pub history: Ghost<Seq<I::Item>>,
804}
805
806impl <I: Iterator> VerusForLoopWrapper<I> {
807 #[verifier::prophetic]
808 pub open spec fn seq(self) -> Seq<I::Item> {
809 self.snapshot@.remaining()
810 }
811
812 pub open spec fn history(self) -> Seq<I::Item> {
814 self.history@
815 }
816
817 pub open spec fn index(self) -> int {
818 self.index@
819 }
820
821 #[verifier::prophetic]
824 pub closed spec fn wf_inner(self) -> bool {
825 &&& self.iter.remaining().len() == self.seq().len() - self.index()
826 &&& forall |i| 0 <= i < self.iter.remaining().len() ==> #[trigger] self.iter.remaining()[i] == self.seq()[self.index() + i]
827 &&& self.iter.will_return_none() ==> self.snapshot@.will_return_none()
828 }
829
830 #[verifier::prophetic]
832 pub open spec fn wf(self) -> bool {
833 &&& 0 <= self.index() <= self.seq().len()
834 &&& self.wf_inner()
835 &&& self.iter.obeys_prophetic_iter_laws() ==> {
836 &&& self.history@.len() == self.index()
837 &&& forall |i| 0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
838 }
839 }
840
841 pub fn new(iter: I) -> (s: Self)
843 ensures
844 s.index == 0,
845 s.snapshot == iter,
846 s.iter == iter,
847 s.history@ == Seq::<I::Item>::empty(),
848 s.wf(),
849 {
850 broadcast use lemma_seq_empty;
851 VerusForLoopWrapper {
852 index: Ghost(0),
853 snapshot: Ghost(iter),
854 iter,
855 history: Ghost(Seq::empty()),
856 }
857 }
858
859 pub fn next(&mut self) -> (ret: Option<I::Item>)
862 requires
863 old(self).wf(),
864 ensures
865 final(self).seq() == old(self).seq(),
866 final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
867 final(self).snapshot == old(self).snapshot,
868 final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
869 final(self).iter.obeys_prophetic_iter_laws() && ret is None ==>
870 final(self).snapshot@.will_return_none() && final(self).index() == final(self).seq().len(),
871 final(self).iter.obeys_prophetic_iter_laws() ==> (ret matches Some(r) ==>
872 r == old(self).seq()[old(self).index()]),
873 ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
875 ret is None ==> final(self).history@ == old(self).history@,
876 exists |m: &mut I| #![auto] call_ensures(I::next, (m,), ret) && *m == old(self).iter && *final(m) == final(self).iter,
878 {
879 let ghost old_history = self.history@;
880 let ret = self.iter.next();
881 if ret.is_some() {
882 self.history = Ghost(old_history.push(ret->0));
883 }
884 proof {
885 broadcast use group_seq_lemmas;
886 if ret.is_some() {
887 self.index@ = self.index@ + 1;
888 }
889 }
890 ret
891 }
892}
893
894pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
898
899#[verifier::external_trait_specification]
903#[verifier::external_trait_extension(StepSpec via StepSpecImpl)]
904pub trait ExIterStep: Clone + PartialOrd + Sized {
905 type ExternalTraitSpecificationFor: core::iter::Step;
906
907 spec fn spec_is_lt(self, other: Self) -> bool;
910
911 spec fn spec_steps_between(self, end: Self) -> Option<usize>;
912
913 spec fn spec_steps_between_int(self, end: Self) -> int;
914
915 spec fn spec_forward_checked(self, count: usize) -> Option<Self>;
916
917 spec fn spec_forward_checked_int(self, count: int) -> Option<Self>;
918
919 spec fn spec_backward_checked(self, count: usize) -> Option<Self>;
920
921 spec fn spec_backward_checked_int(self, count: int) -> Option<Self>;
922}
923
924
925pub broadcast group group_iter_axioms {
930 rev_postcondition,
931 zip_postcondition,
932 filter_postcondition,
933 take_postcondition,
934 skip_postcondition,
935 map_postcondition,
936}
937
938}