1use super::super::prelude::*;
2use super::super::seq::{
3 group_seq_lemmas, lemma_seq_empty, lemma_seq_subrange_index, lemma_seq_subrange_len,
4};
5use core::iter::{Filter, FromIterator, Iterator, Rev, Skip, Take, Zip};
6
7#[doc(hidden)]
13#[macro_export]
14macro_rules! iter_state_preserved_internal {
15 ($before:expr, $after:expr $(,)?) => {
16 $crate::vstd::prelude::verus_proof_expr! {{
19 &&& (*($after)).obeys_prophetic_iter_laws() == (*($before)).obeys_prophetic_iter_laws()
20 &&& (*($before)).obeys_prophetic_iter_laws() ==>
21 (*($before)).produces().len() == (*($before)).remaining().len()
22 &&& (*($before)).obeys_prophetic_iter_laws() ==>
23 ((*($after)).decrease() is Some <==> (*($before)).decrease() is Some)
24 }}
25 };
26}
27
28#[macro_export]
29macro_rules! iter_state_preserved {
30 ($($args:tt)*) => {
31 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::std_specs::iter::iter_state_preserved_internal!($($args)*))
32 };
33}
34
35#[doc(hidden)]
36pub use iter_state_preserved;
37#[doc(hidden)]
38pub use iter_state_preserved_internal;
39
40use verus as verus_skip_verusfmt;
41verus_skip_verusfmt! {
42
43#[verifier::external_trait_specification]
44#[verifier::external_trait_extension(IteratorSpec via IteratorSpecImpl)]
45pub trait ExIterator {
46 type ExternalTraitSpecificationFor: Iterator;
47
48 type Item;
49
50 spec fn obeys_prophetic_iter_laws(&self) -> bool;
56
57 #[verifier::prophetic]
59 spec fn remaining(&self) -> Seq<Self::Item>;
60
61 #[verifier::prophetic]
65 spec fn produces(&self) -> Seq<bool>;
66
67 fn next(&mut self) -> (ret: Option<Self::Item>)
69 ensures
70 iter_state_preserved!(old(self), final(self)),
71 final(self).obeys_prophetic_iter_laws() ==>
73 ({
74 if old(self).remaining().len() > 0 {
75 &&& final(self).remaining() == old(self).remaining().drop_first()
76 &&& final(self).produces() == old(self).produces().drop_first()
77 &&& ret == Some(old(self).remaining()[0])
78 &&& old(self).produces()[0]
79 } else {
80 &&& final(self).remaining() == old(self).remaining()
81 &&& final(self).produces() == old(self).produces()
82 &&& ret == None
83 }
84 }),
85 final(self).obeys_prophetic_iter_laws() && old(self).remaining().len() > 0 && final(self).decrease() is Some ==>
87 decreases_to!(old(self).decrease()->0 => final(self).decrease()->0),
88 ;
89
90 spec fn decrease(&self) -> Option<nat>;
97
98 spec fn peek(&self, index: int) -> Option<Self::Item>;
101
102
103
104 fn all<F>(&mut self, f: F) -> (r: bool)
116 where Self: Sized,
117 F: FnMut(Self::Item) -> bool
118 requires
119 self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
120 !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
122 ensures
123 iter_state_preserved!(old(self), final(self)),
124 final(self).obeys_prophetic_iter_laws() ==> {
125 let num_consumed = old(self).remaining().len() - final(self).remaining().len();
126 &&& final(self).remaining().is_suffix_of(old(self).remaining())
127 &&& final(self).produces() == old(self).produces().skip(num_consumed)
128 &&& old(self).produces().take(num_consumed).all(|p: bool| p)
129 },
130 final(self).obeys_prophetic_iter_laws() && r ==> {
133 &&& final(self).remaining().len() == 0
134 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
135 f.ensures((#[trigger] old(self).remaining()[i],), true)
136 },
137 final(self).obeys_prophetic_iter_laws() && !r ==> {
140 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
141 {
142 &&& final(self).remaining().len() < old(self).remaining().len()
144 &&& f.ensures((old(self).remaining()[idx],), false)
145 &&& forall |i| 0 <= i < idx ==>
146 f.ensures((#[trigger] old(self).remaining()[i],), true)
147 }
148 };
149
150 fn any<F>(&mut self, f: F) -> (r: bool)
151 where Self: Sized,
152 F: FnMut(Self::Item) -> bool
153 requires
154 self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
155 !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
157 ensures
158 iter_state_preserved!(old(self), final(self)),
159 final(self).obeys_prophetic_iter_laws() ==> {
160 let num_consumed = old(self).remaining().len() - final(self).remaining().len();
161 &&& final(self).remaining().is_suffix_of(old(self).remaining())
162 &&& final(self).produces() == old(self).produces().skip(num_consumed)
163 &&& old(self).produces().take(num_consumed).all(|p: bool| p)
164 },
165 final(self).obeys_prophetic_iter_laws() && !r ==> {
168 &&& final(self).remaining().len() == 0
169 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
170 f.ensures((#[trigger] old(self).remaining()[i],), false)
171 },
172 final(self).obeys_prophetic_iter_laws() && r ==> {
175 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
176 {
177 &&& final(self).remaining().len() < old(self).remaining().len()
179 &&& f.ensures((old(self).remaining()[idx],), true)
180 &&& forall |i| 0 <= i < idx ==>
181 f.ensures((#[trigger] old(self).remaining()[i],), false)
182 }
183 };
184
185 fn collect<B>(self) -> (collection: B)
186 where
187 B: FromIterator<Self::Item>,
188 Self: Sized,
189 ensures
190 self.obeys_prophetic_iter_laws() ==>
191 FromIteratorSpec::from_iter_ensures(self.remaining(), self.produces(), collection),
192 ;
193
194 fn filter<P>(self, predicate: P) -> (r: core::iter::Filter<Self, P>)
195 where
196 Self: Sized,
197 P: FnMut(&Self::Item) -> bool,
198 requires
199 self.decrease() is Some,
202 self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> predicate.requires((#[trigger] &self.remaining()[k], )),
203 !self.obeys_prophetic_iter_laws() ==> forall |x: &Self::Item| #[trigger] predicate.requires((x, )),
205 ensures
206 self.obeys_prophetic_iter_laws() ==> filter_post(self, predicate, r),
207 ;
208
209 fn find<P>(&mut self, predicate: P) -> (r: Option<Self::Item>)
210 where Self: Sized,
211 P: FnMut(&Self::Item) -> bool
212 requires
213 self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> predicate.requires((#[trigger] &self.remaining()[k], )),
214 !self.obeys_prophetic_iter_laws() ==> forall |x: &Self::Item| #[trigger] predicate.requires((x, )),
216 ensures
217 iter_state_preserved!(old(self), final(self)),
218 final(self).obeys_prophetic_iter_laws() ==> final(self).produces() ==
219 old(self).produces().skip(old(self).remaining().len() - final(self).remaining().len()),
220 final(self).obeys_prophetic_iter_laws() ==> {
221 &&& final(self).remaining().is_suffix_of(old(self).remaining())
222 &&& old(self).produces().take(old(self).remaining().len() - final(self).remaining().len()).all(|p: bool| p)
223 },
224 final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
228 &&& final(self).remaining().len() == 0
229 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
230 predicate.ensures((#[trigger]&old(self).remaining()[i],), false)
231 },
232 final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
236 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
237 {
238 &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
239 &&& predicate.ensures((&r.unwrap(),), true)
240 &&& old(self).remaining()[idx] == r.unwrap()
241 &&& forall |i| 0 <= i < idx ==>
242 predicate.ensures((#[trigger] &old(self).remaining()[i],), false)
243 }
244 };
245
246 fn find_map<B, F>(&mut self, f: F) -> (r: Option<B>)
247 where Self: Sized,
248 F: FnMut(Self::Item) -> Option<B>
249 requires
250 self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
251 !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
253 ensures
254 iter_state_preserved!(old(self), final(self)),
255
256 final(self).obeys_prophetic_iter_laws() ==> {
257 let num_consumed = old(self).remaining().len() - final(self).remaining().len();
258 &&& final(self).remaining().is_suffix_of(old(self).remaining())
259 &&& final(self).produces() == old(self).produces().skip(num_consumed)
260 &&& old(self).produces().take(num_consumed).all(|p: bool| p)
261 },
262 final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
266 &&& final(self).remaining().len() == 0
267 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
268 f.ensures((#[trigger]old(self).remaining()[i],), None)
269 },
270 final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
273 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
274 {
275 &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
276 &&& f.ensures((old(self).remaining()[idx],), r)
277 &&& forall |i| 0 <= i < idx ==>
278 f.ensures((#[trigger] old(self).remaining()[i],), None)
279 }
280 };
281
282 fn map<B, F>(self, f: F) -> (r: core::iter::Map<Self, F>)
283 where
284 Self: Sized,
285 F: FnMut(Self::Item) -> B,
286 requires
287 self.obeys_prophetic_iter_laws() ==> forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> f.requires((#[trigger] self.remaining()[k], )),
288 !self.obeys_prophetic_iter_laws() ==> forall |x: Self::Item| #[trigger] f.requires((x, )),
290 ensures
291 self.obeys_prophetic_iter_laws() ==> map_post(self, f, r),
292 ;
293
294 fn position<P>(&mut self, predicate: P) -> (r: Option<usize>)
295 where
296 Self: Sized,
297 P: FnMut(Self::Item) -> bool,
298 requires
299 self.obeys_prophetic_iter_laws(),
302 self.remaining().len() <= usize::MAX as int,
303 forall |k| 0 <= k < self.remaining().len() && self.produces()[k] ==> predicate.requires((#[trigger] self.remaining()[k], )),
304 ensures
305 iter_state_preserved!(old(self), final(self)),
306 final(self).obeys_prophetic_iter_laws() ==> {
307 let num_consumed = old(self).remaining().len() - final(self).remaining().len();
308 &&& final(self).remaining().is_suffix_of(old(self).remaining())
309 &&& final(self).produces() == old(self).produces().skip(num_consumed)
310 &&& old(self).produces().take(num_consumed).all(|p: bool| p)
311 },
312 final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
316 &&& final(self).remaining().len() == 0
317 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
318 predicate.ensures((#[trigger] old(self).remaining()[i],), false)
319 },
320 final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
323 let index = r.unwrap();
324 {
325 &&& index as int == (old(self).remaining().len() - final(self).remaining().len() - 1)
326 &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
327 &&& predicate.ensures((#[trigger] old(self).remaining()[index as int],), true)
328 &&& forall |i| 0 <= i < index as int ==>
329 predicate.ensures((#[trigger] old(self).remaining()[i],), false)
330 }
331 };
332
333 fn rev(self) -> (r: Rev<Self>)
334 where Self: Sized,
335 ensures
336 self.obeys_prophetic_iter_laws() ==> rev_post(self, r),
337 ;
338
339 fn size_hint(&self) -> ((lower, upper): (usize, Option<usize>))
340 ensures
341 self.obeys_prophetic_iter_laws() ==>
342 lower <= self.remaining().len() && (upper matches Some(b) ==> self.remaining().len() <= b),
343 default_ensures
344 (lower, upper) == (0usize, None),
345 ;
346
347 fn skip(self, n: usize) -> (s: Skip<Self>)
348 where Self: Sized,
349 ensures
350 self.obeys_prophetic_iter_laws() ==> skip_post(self, n, s),
351 ;
352
353 fn take(self, n: usize) -> (t: Take<Self>)
354 where Self: Sized,
355 ensures
356 self.obeys_prophetic_iter_laws() ==> take_post(self, n, t),
357 ;
358
359 #[verifier::impls_cannot_extend_spec]
360 fn zip<U>(self, other: U) -> (r: Zip<Self, <U as IntoIterator>::IntoIter>)
361 where
362 Self: Sized,
363 U: IntoIterator,
364 ensures
365 self.obeys_prophetic_iter_laws() ==> zip_post(self, other, r),
366 ;
367}
368
369#[verifier::external_trait_specification]
370#[verifier::external_trait_extension(DoubleEndedIteratorSpec via DoubleEndedIteratorSpecImpl)]
371pub trait ExDoubleEndedIterator : Iterator {
372 type ExternalTraitSpecificationFor: DoubleEndedIterator;
373
374 fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
385 ensures
386 iter_state_preserved!(old(self), final(self)),
387 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) ==>
389 ({
390 if <Self as IteratorSpec>::remaining(old(self)).len() > 0 {
391 &&& <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)).drop_last()
392 &&& <Self as IteratorSpec>::produces(final(self)) == <Self as IteratorSpec>::produces(old(self)).drop_last()
393 &&& ret == Some(<Self as IteratorSpec>::remaining(old(self)).last())
394 &&& <Self as IteratorSpec>::produces(old(self)).last()
395 } else {
396 &&& <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self))
397 &&& <Self as IteratorSpec>::produces(final(self)) == <Self as IteratorSpec>::produces(old(self))
398 &&& ret == None
399 }
400 }),
401 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) && <Self as IteratorSpec>::remaining(old(self)).len() > 0 && <Self as IteratorSpec>::decrease(final(self)) is Some ==>
403 <Self as IteratorSpec>::decrease(old(self))->0 > <Self as IteratorSpec>::decrease(final(self))->0,
404 ;
405
406 spec fn peek_back(&self, index: int) -> Option<Self::Item>;
411}
412
413#[verifier::external_trait_specification]
414#[verifier::external_trait_extension(ExactSizeIteratorSpec via ExactSizeIteratorSpecImpl)]
415pub trait ExExactSizeIterator: Iterator {
416 type ExternalTraitSpecificationFor: ExactSizeIterator;
417
418 spec fn exact_len(&self) -> usize;
421
422 fn len(&self) -> (len: usize)
423 ensures
424 self.obeys_prophetic_iter_laws() ==> len == self.exact_len() == self.remaining().len() == self.produces().len(),
425 ;
426}
427
428#[verifier::external_trait_specification]
432pub trait ExIntoIterator {
433 type ExternalTraitSpecificationFor: core::iter::IntoIterator;
434
435 type Item;
436 type IntoIter: Iterator<Item = Self::Item>;
437
438 fn into_iter(self) -> Self::IntoIter;
439}
440
441pub open spec fn iter_into_iter_spec<I: Iterator>(i: I) -> I {
442 i
443}
444
445#[verifier::when_used_as_spec(iter_into_iter_spec)]
446pub assume_specification<I: Iterator>[ <I as IntoIterator>::into_iter ](i: I) -> (r: I)
447 ensures
448 r == i,
449;
450
451#[verifier::external_trait_specification]
452#[verifier::external_trait_extension(FromIteratorSpec via FromIteratorSpecImpl)]
453pub trait ExFromIterator<A>: Sized {
454 type ExternalTraitSpecificationFor: FromIterator<A>;
455
456 spec fn from_iter_ensures(remaining: Seq<A>, produces: Seq<bool>, s: Self) -> bool;
458
459 #[verifier::impls_cannot_extend_spec]
461 fn from_iter<T>(iter: T) -> (s: Self)
462 where T: IntoIterator<Item = A>
463 ensures
464 exists |initial: T::IntoIter|
465 #[trigger] (T::into_iter).ensures((iter,), initial)
466 && (initial.obeys_prophetic_iter_laws() ==>
467 Self::from_iter_ensures(initial.remaining(), initial.produces(), s)),
468 ;
469}
470
471impl <I> IteratorSpecImpl for &mut I
479 where I: Iterator {
480 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
481 <I as IteratorSpec>::obeys_prophetic_iter_laws(*self)
482 }
483
484 #[verifier::prophetic]
485 open spec fn remaining(&self) -> Seq<Self::Item> {
486 <I as IteratorSpec>::remaining(*self)
487 }
488
489 #[verifier::prophetic]
490 open spec fn produces(&self) -> Seq<bool> {
491 <I as IteratorSpec>::produces(*self)
492 }
493
494 open spec fn decrease(&self) -> Option<nat> {
495 <I as IteratorSpec>::decrease(*self)
496 }
497
498 open spec fn peek(&self, index: int) -> Option<Self::Item> {
499 <I as IteratorSpec>::peek(*self, index)
500 }
501}
502
503#[verifier::external_body]
507#[verifier::external_type_specification]
508#[verifier::reject_recursive_types(I)]
509#[verifier::reject_recursive_types(F)]
510pub struct ExFilter<I, F>(Filter<I, F>);
511
512pub uninterp spec fn filter_iter<I, F>(r: Filter<I, F>) -> I;
514
515pub uninterp spec fn filter_fun<I, F>(r: Filter<I, F>) -> F;
517
518#[verifier::prophetic]
520pub uninterp spec fn filter_keep<I, F>(r: Filter<I, F>) -> Seq<bool>;
521
522pub uninterp spec fn filter_post<I, F>(i: I, f: F, r: Filter<I, F>) -> bool;
524
525pub broadcast axiom fn filter_postcondition<I, F>(i: I, f: F, r: core::iter::Filter<I, F>)
528 where
529 I: IteratorSpec,
530 F: FnMut(&I::Item) -> bool,
531 requires
532 #[trigger] filter_post(i, f, r),
533 ensures
534 {
535 let keep = filter_keep(r);
536 {
537 &&& keep.len() == i.remaining().len()
540 &&& forall |j| 0 <= j < keep.len() && !(#[trigger] keep[j]) ==>
541 i.produces()[j] && f.ensures((&i.remaining()[j],), false)
542 &&& forall |j| 0 <= j < keep.len() && #[trigger] keep[j] ==> {
543 let k = i.remaining()[..j].filter_index(|idx: int| keep[idx]).len() as int;
544 IteratorSpec::produces(&r)[k] ==>
545 i.produces()[j] && f.ensures((&i.remaining()[j],), true)
546 }
547 &&& IteratorSpec::remaining(&r) == i.remaining().filter_index(|j: int| keep[j])
549 &&& IteratorSpec::produces(&r).len() == IteratorSpec::remaining(&r).len()
551 &&& IteratorSpec::remaining(&r).len() <= i.remaining().len()
552 &&& forall |k| #![trigger IteratorSpec::remaining(&r)[k]] 0 <= k < IteratorSpec::remaining(&r).len() ==>
553 exists |j| 0 <= j < i.remaining().len()
554 && IteratorSpec::remaining(&r)[k] == #[trigger] i.remaining()[j]
555 && keep[j]
556 && k == i.remaining()[..j].filter_index(|idx: int| keep[idx]).len()
557 && (IteratorSpec::produces(&r)[k] ==>
558 i.produces()[j] && f.ensures((&i.remaining()[j],), true))
559 &&& IteratorSpec::decrease(&r) is Some == i.decrease() is Some
560 &&& filter_iter(r) == i
561 &&& filter_fun(r) == f
562 }
563 },
564;
565
566impl <I, P> IteratorSpecImpl for core::iter::Filter<I, P>
567 where
568 I: Iterator + IteratorSpec,
569 P: FnMut(&I::Item) -> bool,
570{
571 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
572 filter_iter(*self).obeys_prophetic_iter_laws()
573 }
574
575 #[verifier::prophetic]
576 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
577
578 #[verifier::prophetic]
579 uninterp spec fn produces(&self) -> Seq<bool>;
580
581 uninterp spec fn decrease(&self) -> Option<nat>;
582
583 open spec fn peek(&self, index: int) -> Option<Self::Item> {
586 None
587 }
588}
589
590#[verifier::external_body]
594#[verifier::external_type_specification]
595#[verifier::reject_recursive_types(I)]
596#[verifier::reject_recursive_types(F)]
597pub struct ExMap<I, F>(core::iter::Map<I, F>);
598
599pub uninterp spec fn map_iter<I, F>(r: core::iter::Map<I, F>) -> I;
601
602pub uninterp spec fn map_fun<I, F>(r: core::iter::Map<I, F>) -> F;
604
605pub uninterp spec fn map_post<I, F>(i: I, f: F, r: core::iter::Map<I, F>) -> bool;
607
608pub broadcast axiom fn map_postcondition<I, F>(i: I, f: F, r: core::iter::Map<I, F>)
611 where
612 I: IteratorSpec,
613 F: FnMut<(I::Item,)>,
614 requires
615 #[trigger] map_post(i, f, r),
616 ensures
617 IteratorSpec::remaining(&r).len() == i.remaining().len(),
618 IteratorSpec::produces(&r).len() == IteratorSpec::remaining(&r).len(),
619 forall |k| #![trigger IteratorSpec::remaining(&r)[k]] #![trigger IteratorSpec::produces(&r)[k]]
620 0 <= k < IteratorSpec::remaining(&r).len() && IteratorSpec::produces(&r)[k] ==>
621 i.produces()[k] && f.ensures((i.remaining()[k],), IteratorSpec::remaining(&r)[k]),
622 IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
623 map_iter(r) == i,
624 map_fun(r) == f,
625;
626
627impl <B, I, F> IteratorSpecImpl for core::iter::Map<I, F>
628 where
629 I: Iterator + IteratorSpec,
630 F: FnMut(I::Item) -> B,
631{
632
633 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
634 map_iter(*self).obeys_prophetic_iter_laws()
635 }
636
637 #[verifier::prophetic]
638 uninterp spec fn remaining(&self) -> Seq<B>;
639
640 #[verifier::prophetic]
641 uninterp spec fn produces(&self) -> Seq<bool>;
642
643 uninterp spec fn decrease(&self) -> Option<nat>;
644
645 open spec fn peek(&self, index: int) -> Option<B> {
646 match map_iter(*self).peek(index) {
647 Some(v) => {
648 let x = choose |x| map_fun(*self).ensures((v,), x);
649 Some(x)
650 }
651 None => None,
652 }
653 }
654}
655
656impl <B, I, F> DoubleEndedIteratorSpecImpl for core::iter::Map<I, F>
657 where I: DoubleEndedIterator + IteratorSpec,
658 F: FnMut(I::Item) -> B,
659{
660 open spec fn peek_back(&self, index: int) -> Option<B> {
661 match map_iter(*self).peek_back(index) {
662 Some(v) => {
663 let x = choose |x| map_fun(*self).ensures((v,), x);
664 Some(x)
665 }
666 None => None,
667 }
668 }
669}
670
671#[verifier::external_body]
675#[verifier::external_type_specification]
676#[verifier::reject_recursive_types(I)]
677pub struct ExRev<I>(Rev<I>);
678
679pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
681
682pub uninterp spec fn rev_post<I>(i: I, r: Rev<I>) -> bool;
684
685pub broadcast axiom fn rev_postcondition<I: DoubleEndedIteratorSpec>(i: I, r: Rev<I>)
686 requires
687 #[trigger] rev_post(i, r),
688 ensures
689 IteratorSpec::remaining(&r) == IteratorSpec::remaining(&i).reverse(),
690 IteratorSpec::produces(&r) == i.produces().reverse(),
691 IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
692;
693
694impl <I> IteratorSpecImpl for Rev<I>
695 where I: DoubleEndedIterator + DoubleEndedIteratorSpec {
696 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
697 rev_iter(*self).obeys_prophetic_iter_laws()
698 }
699
700 #[verifier::prophetic]
701 closed spec fn remaining(&self) -> Seq<Self::Item> {
702 rev_iter(*self).remaining().reverse()
703 }
704
705 #[verifier::prophetic]
706 closed spec fn produces(&self) -> Seq<bool> {
707 rev_iter(*self).produces().reverse()
708 }
709
710 closed spec fn decrease(&self) -> Option<nat> {
711 rev_iter(*self).decrease()
712 }
713
714 open spec fn peek(&self, index: int) -> Option<Self::Item> {
715 rev_iter(*self).peek_back(index)
716 }
717}
718
719impl <I> DoubleEndedIteratorSpecImpl for Rev<I>
720 where I: DoubleEndedIterator + IteratorSpec {
721
722 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
723 rev_iter(*self).peek(index)
724 }
725}
726
727#[verifier::external_body]
731#[verifier::external_type_specification]
732#[verifier::reject_recursive_types(I)]
733pub struct ExSkip<I>(Skip<I>);
734
735pub uninterp spec fn skip_iter<I>(s: Skip<I>) -> I;
737
738pub uninterp spec fn skip_init_n<I>(s: Skip<I>) -> usize;
740
741pub uninterp spec fn skip_post<I>(i: I, n: usize, s: Skip<I>) -> bool;
743
744pub broadcast axiom fn skip_postcondition<I: IteratorSpec>(i: I, n: usize, r: Skip<I>)
745 requires
746 i.obeys_prophetic_iter_laws(),
747 #[trigger] skip_post(i, n, r),
748 ensures
749 IteratorSpec::remaining(&r) == if i.remaining().len() < n { Seq::empty() } else { i.remaining()[n..] },
750 IteratorSpec::produces(&r) == if i.remaining().len() < n { Seq::empty() } else { i.produces()[n..] },
751 skip_iter(r) == i,
752 skip_init_n(r) == n,
753 IteratorSpec::decrease(&r) is Some == i.decrease() is Some,
754;
755
756impl <I> IteratorSpecImpl for Skip<I>
757 where I: Iterator {
758 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
759 skip_iter(*self).obeys_prophetic_iter_laws()
760 }
761
762 #[verifier::prophetic]
763 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
764
765 #[verifier::prophetic]
766 uninterp spec fn produces(&self) -> Seq<bool>;
767
768 uninterp spec fn decrease(&self) -> Option<nat>;
769
770 open spec fn peek(&self, index: int) -> Option<Self::Item> {
771 skip_iter(*self).peek(skip_init_n(*self) + index)
772 }
773}
774
775impl <I> DoubleEndedIteratorSpecImpl for Skip<I>
776 where I: DoubleEndedIteratorSpec + ExactSizeIteratorSpec
777{
778 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
779 let len = skip_iter(*self).exact_len();
783 if len < skip_init_n(*self) || index >= len - skip_init_n(*self) {
784 None
785 } else {
786 skip_iter(*self).peek_back(index)
787 }
788 }
789}
790
791#[verifier::external_body]
795#[verifier::external_type_specification]
796#[verifier::reject_recursive_types(I)]
797pub struct ExTake<I>(Take<I>);
798
799pub uninterp spec fn take_iter<I>(r: Take<I>) -> I;
801
802pub uninterp spec fn take_count<I>(r: Take<I>) -> usize;
804
805pub uninterp spec fn take_post<I>(i: I, n: usize, t: Take<I>) -> bool;
807
808pub broadcast axiom fn take_postcondition<I: IteratorSpec>(i: I, n: usize, r: Take<I>)
811 requires
812 i.obeys_prophetic_iter_laws(),
813 #[trigger] take_post(i, n, r),
814 ensures
815 IteratorSpec::remaining(&r) == if i.remaining().len() < n { i.remaining() } else { i.remaining()[..n] },
816 IteratorSpec::produces(&r) == if i.remaining().len() < n { i.produces() } else { i.produces()[..n] },
817 take_iter(r) == i,
818 take_count(r) == n,
819 IteratorSpec::decrease(&r) is Some,
820;
821
822impl <I> IteratorSpecImpl for Take<I>
823 where I: Iterator {
824 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
825 take_iter(*self).obeys_prophetic_iter_laws()
826 }
827
828 #[verifier::prophetic]
829 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
830
831 #[verifier::prophetic]
832 uninterp spec fn produces(&self) -> Seq<bool>;
833
834 uninterp spec fn decrease(&self) -> Option<nat>;
835
836 open spec fn peek(&self, index: int) -> Option<Self::Item> {
837 take_iter(*self).peek(index)
838 }
839}
840
841impl <I> DoubleEndedIteratorSpecImpl for Take<I>
842 where I: DoubleEndedIteratorSpec + ExactSizeIteratorSpec
843{
844 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
845 let len = take_iter(*self).exact_len();
846 if len < take_count(*self) {
847 None
848 } else {
849 take_iter(*self).peek_back(len - take_count(*self) - index - 1)
850 }
851 }
852}
853
854#[verifier::external_body]
858#[verifier::external_type_specification]
859#[verifier::reject_recursive_types(A)]
860#[verifier::reject_recursive_types(B)]
861pub struct ExZip<A, B>(Zip<A, B>);
862
863pub uninterp spec fn zip_iter_fst<A, B>(z: Zip<A, B>) -> A;
865
866pub uninterp spec fn zip_iter_snd<A, B>(z: Zip<A, B>) -> B;
868
869impl<A, B> IteratorSpecImpl for Zip<A, B>
870 where A: Iterator + IteratorSpec, B: Iterator + IteratorSpec
871{
872 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
873 &&& zip_iter_fst(*self).obeys_prophetic_iter_laws()
874 &&& zip_iter_snd(*self).obeys_prophetic_iter_laws()
875 }
876
877 #[verifier::prophetic]
878 closed spec fn remaining(&self) -> Seq<Self::Item> {
879 zip_iter_fst(*self).remaining().zip_truncate(zip_iter_snd(*self).remaining())
880 }
881
882 #[verifier::prophetic]
883 closed spec fn produces(&self) -> Seq<bool> {
884 zip_iter_fst(*self).produces().zip_truncate(zip_iter_snd(*self).produces()).map_values(|p: (bool, bool)| p.0 && p.1)
885 }
886
887 closed spec fn decrease(&self) -> Option<nat> {
888 match (zip_iter_fst(*self).decrease(), zip_iter_snd(*self).decrease()) {
889 (Some(a), Some(b)) => if a <= b { Some(a) } else { Some(b) },
890 (Some(a), None) => Some(a),
891 (None, Some(b)) => Some(b),
892 (None, None) => None,
893 }
894 }
895
896 open spec fn peek(&self, index: int) -> Option<Self::Item> {
897 match (zip_iter_fst(*self).peek(index), zip_iter_snd(*self).peek(index)) {
898 (Some(a), Some(b)) => Some((a, b)),
899 _ => None,
900 }
901 }
902}
903
904pub uninterp spec fn zip_post<I, U, Z>(i: I, other: U, r: Z) -> bool;
906
907pub broadcast axiom fn zip_postcondition<I, U>(i: I, other: U, r: Zip<I, <U as IntoIterator>::IntoIter>)
908 where
909 I: Sized + IteratorSpec,
910 U: IntoIterator, requires
912 i.obeys_prophetic_iter_laws(),
913 #[trigger] zip_post(i, other, r),
914 ensures
915 (U::into_iter).ensures((other,), zip_iter_snd(r)),
916 zip_iter_fst(r) == i,
917 IteratorSpec::remaining(&r) == i.remaining().zip_truncate(zip_iter_snd(r).remaining()),
918 IteratorSpec::produces(&r) == i.produces().zip_truncate(zip_iter_snd(r).produces()).map_values(|p: (bool, bool)| p.0 && p.1),
919 IteratorSpec::decrease(&r) is Some == (i.decrease() is Some || zip_iter_snd(r).decrease() is Some),
920;
921
922pub struct VerusForLoopWrapper<I: Iterator> {
928 pub index: Ghost<int>,
929 pub snapshot: Ghost<I>,
930 pub iter: I,
931 pub history: Ghost<Seq<I::Item>>,
932}
933
934impl <I: Iterator> VerusForLoopWrapper<I> {
935 #[verifier::prophetic]
936 pub open spec fn seq(self) -> Seq<I::Item> {
937 self.snapshot@.remaining()
938 }
939
940 pub open spec fn history(self) -> Seq<I::Item> {
942 self.history@
943 }
944
945 pub open spec fn index(self) -> int {
946 self.index@
947 }
948
949 #[verifier::prophetic]
952 pub closed spec fn wf_inner(self) -> bool {
953 &&& self.iter.remaining().len() == self.seq().len() - self.index()
954 &&& forall |i| 0 <= i < self.iter.remaining().len() ==> #[trigger] self.iter.remaining()[i] == self.seq()[self.index() + i]
955 &&& self.index() <= self.snapshot@.produces().len()
956 &&& self.iter.produces() == self.snapshot@.produces().skip(self.index())
957 }
958
959 #[verifier::prophetic]
961 pub open spec fn wf(self) -> bool {
962 &&& 0 <= self.index() <= self.seq().len()
963 &&& self.wf_inner()
964 &&& self.iter.obeys_prophetic_iter_laws() ==> {
965 &&& self.history@.len() == self.index()
966 &&& forall |i| 0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
967 &&& self.snapshot@.produces().take(self.index()).all(|p: bool| p)
968 }
969 }
970
971 pub fn new(iter: I) -> (s: Self)
973 ensures
974 s.index == 0,
975 s.snapshot == iter,
976 s.iter == iter,
977 s.history@ == Seq::<I::Item>::empty(),
978 s.wf(),
979 {
980 broadcast use group_seq_lemmas;
981 proof {
982 assert(iter.produces().skip(0) =~= iter.produces());
983 }
984 VerusForLoopWrapper {
985 index: Ghost(0),
986 snapshot: Ghost(iter),
987 iter,
988 history: Ghost(Seq::empty()),
989 }
990 }
991
992 pub fn next(&mut self) -> (ret: Option<I::Item>)
995 requires
996 old(self).wf(),
997 ensures
998 final(self).seq() == old(self).seq(),
999 final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
1000 final(self).snapshot == old(self).snapshot,
1001 final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
1002 final(self).iter.obeys_prophetic_iter_laws() && ret is None ==>
1003 final(self).index() == final(self).seq().len()
1004 && final(self).snapshot@.produces().all(|p: bool| p),
1005 final(self).iter.obeys_prophetic_iter_laws() ==> (ret matches Some(r) ==>
1006 r == old(self).seq()[old(self).index()] && old(self).snapshot@.produces()[old(self).index()]),
1007 ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
1009 ret is None ==> final(self).history@ == old(self).history@,
1010 exists |m: &mut I| #![auto] (I::next).ensures((m,), ret) && *m == old(self).iter && *final(m) == final(self).iter,
1012 {
1013 let ghost old_history = self.history@;
1014 let ret = self.iter.next();
1015 if ret.is_some() {
1016 self.history = Ghost(old_history.push(ret->0));
1017 }
1018 proof {
1019 broadcast use group_seq_lemmas;
1020 if ret.is_some() {
1021 self.index@ = self.index@ + 1;
1022 }
1023 if self.iter.obeys_prophetic_iter_laws() {
1024 assert(self.snapshot@.produces().len() == self.seq().len());
1025 assert(self.iter.produces() =~= self.snapshot@.produces().skip(self.index()));
1026 if ret.is_none() {
1027 assert(self.snapshot@.produces().take(self.index()) =~= self.snapshot@.produces());
1028 }
1029 }
1030 }
1031 ret
1032 }
1033}
1034
1035pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
1039
1040#[verifier::external_trait_specification]
1044#[verifier::external_trait_extension(StepSpec via StepSpecImpl)]
1045pub trait ExIterStep: Clone + PartialOrd + Sized {
1046 type ExternalTraitSpecificationFor: core::iter::Step;
1047
1048 spec fn spec_is_lt(self, other: Self) -> bool;
1051
1052 spec fn spec_steps_between(self, end: Self) -> Option<usize>;
1053
1054 spec fn spec_steps_between_int(self, end: Self) -> int;
1055
1056 spec fn spec_forward_checked(self, count: usize) -> Option<Self>;
1057
1058 spec fn spec_forward_checked_int(self, count: int) -> Option<Self>;
1059
1060 spec fn spec_backward_checked(self, count: usize) -> Option<Self>;
1061
1062 spec fn spec_backward_checked_int(self, count: int) -> Option<Self>;
1063}
1064
1065
1066pub broadcast group group_iter_axioms {
1071 rev_postcondition,
1072 zip_postcondition,
1073 filter_postcondition,
1074 take_postcondition,
1075 skip_postcondition,
1076 map_postcondition,
1077}
1078
1079}