1use super::super::prelude::*;
2use super::super::seq::{
3 group_seq_lemmas, lemma_seq_empty, lemma_seq_subrange_index, lemma_seq_subrange_len,
4};
5
6use verus as verus_;
7
8use core::iter::{FromIterator, Iterator, Rev};
9
10verus_! {
11
12#[verifier::external_trait_specification]
13#[verifier::external_trait_extension(IteratorSpec via IteratorSpecImpl)]
14pub trait ExIterator {
15 type ExternalTraitSpecificationFor: Iterator;
16
17 type Item;
18
19 spec fn obeys_prophetic_iter_laws(&self) -> bool;
24
25 #[verifier::prophetic]
27 spec fn remaining(&self) -> Seq<Self::Item>;
28
29 #[verifier::prophetic]
34 spec fn will_return_none(&self) -> bool;
35
36 fn next(&mut self) -> (ret: Option<Self::Item>)
38 ensures
39 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
41 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
42 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
43 final(self).obeys_prophetic_iter_laws() ==>
45 ({
46 if old(self).remaining().len() > 0 {
47 &&& final(self).remaining() == old(self).remaining().drop_first()
48 &&& ret == Some(old(self).remaining()[0])
49 } else {
50 final(self).remaining() == old(self).remaining() && ret == None && final(self).will_return_none()
51 }
52 }),
53 final(self).obeys_prophetic_iter_laws() && old(self).remaining().len() > 0 && final(self).decrease() is Some ==>
55 decreases_to!(old(self).decrease()->0 => final(self).decrease()->0),
56 ;
57
58 spec fn decrease(&self) -> Option<nat>;
65
66 spec fn peek(&self, index: int) -> Option<Self::Item>;
69
70 fn rev(self) -> (r: Rev<Self>)
75 where Self: Sized,
76 ensures
77 self.obeys_prophetic_iter_laws() ==>
78 r == into_rev_spec(self) && rev_post(self, r),
79 ;
80
81 fn collect<B>(self) -> (collection: B)
82 where
83 B: FromIterator<Self::Item>,
84 Self: Sized,
85 ensures
86 self.obeys_prophetic_iter_laws() ==>
87 self.will_return_none() &&
88 FromIteratorSpec::from_iter_ensures(self.remaining(), collection),
89 ;
90
91 fn find<P>(&mut self, predicate: P) -> (r: Option<Self::Item>)
92 where Self: Sized,
93 P: FnMut(&Self::Item) -> bool
94 requires
95 forall |k| #![auto] 0 <= k < self.remaining().len() ==> call_requires(predicate, (&self.remaining()[k], )),
96 ensures
97 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
99 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
100 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
101 final(self).obeys_prophetic_iter_laws() ==> {
102 final(self).remaining().is_suffix_of(old(self).remaining())
103 },
104 final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
108 &&& final(self).remaining().len() == 0
109 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
110 predicate.ensures((#[trigger]&old(self).remaining()[i],), false)
111 },
112 final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
116 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
117 {
118 &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
119 &&& predicate.ensures((&r.unwrap(),), true)
120 &&& old(self).remaining()[idx] == r.unwrap()
121 &&& forall |i| 0 <= i < idx ==>
122 predicate.ensures((#[trigger] &old(self).remaining()[i],), false)
123 }
124 };
125
126 fn all<F>(&mut self, f: F) -> (r: bool)
131 where Self: Sized,
132 F: FnMut(Self::Item) -> bool
133 requires
134 forall |k| #![auto] 0 <= k < self.remaining().len() ==> call_requires(f, (self.remaining()[k], )),
135 ensures
136 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
138 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
139 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
140 final(self).obeys_prophetic_iter_laws() ==> {
141 final(self).remaining().is_suffix_of(old(self).remaining())
142 },
143 final(self).obeys_prophetic_iter_laws() && r ==> {
146 &&& final(self).remaining().len() == 0
147 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
148 f.ensures((#[trigger] old(self).remaining()[i],), true)
149 },
150 final(self).obeys_prophetic_iter_laws() && !r ==> {
153 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
154 {
155 &&& final(self).remaining().len() < old(self).remaining().len()
157 &&& f.ensures((old(self).remaining()[idx],), false)
158 &&& forall |i| 0 <= i < idx ==>
159 f.ensures((#[trigger] old(self).remaining()[i],), true)
160 }
161 };
162
163 fn any<F>(&mut self, f: F) -> (r: bool)
164 where Self: Sized,
165 F: FnMut(Self::Item) -> bool
166 requires
167 forall |k| #![auto] 0 <= k < self.remaining().len() ==> call_requires(f, (self.remaining()[k], )),
168 ensures
169 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
171 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
172 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
173 final(self).obeys_prophetic_iter_laws() ==> {
174 final(self).remaining().is_suffix_of(old(self).remaining())
175 },
176 final(self).obeys_prophetic_iter_laws() && !r ==> {
179 &&& final(self).remaining().len() == 0
180 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
181 f.ensures((#[trigger] old(self).remaining()[i],), false)
182 },
183 final(self).obeys_prophetic_iter_laws() && r ==> {
186 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
187 {
188 &&& final(self).remaining().len() < old(self).remaining().len()
190 &&& f.ensures((old(self).remaining()[idx],), true)
191 &&& forall |i| 0 <= i < idx ==>
192 f.ensures((#[trigger] old(self).remaining()[i],), false)
193 }
194 };
195}
196
197#[verifier::external_trait_specification]
198#[verifier::external_trait_extension(DoubleEndedIteratorSpec via DoubleEndedIteratorSpecImpl)]
199pub trait ExDoubleEndedIterator : Iterator {
200 type ExternalTraitSpecificationFor: DoubleEndedIterator;
201
202 fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
213 ensures
214 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) == <Self as IteratorSpec>::obeys_prophetic_iter_laws(old(self)),
216 <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)),
217 <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),
218 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) ==>
220 ({
221 if <Self as IteratorSpec>::remaining(old(self)).len() > 0 {
222 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)).drop_last()
223 && ret == Some(<Self as IteratorSpec>::remaining(old(self)).last())
224 } else {
225 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)) && ret == None && <Self as IteratorSpec>::will_return_none(final(self))
226 }
227 }),
228 <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 ==>
230 <Self as IteratorSpec>::decrease(old(self))->0 > <Self as IteratorSpec>::decrease(final(self))->0,
231 ;
232
233 spec fn peek_back(&self, index: int) -> Option<Self::Item>;
238}
239
240#[verifier::external_trait_specification]
244pub trait ExIntoIterator {
245 type ExternalTraitSpecificationFor: core::iter::IntoIterator;
246}
247
248pub open spec fn iter_into_iter_spec<I: Iterator>(i: I) -> I {
249 i
250}
251
252#[verifier::when_used_as_spec(iter_into_iter_spec)]
253pub assume_specification<I: Iterator>[ <I as IntoIterator>::into_iter ](i: I) -> (r: I)
254 ensures
255 r == i,
256;
257
258pub uninterp spec fn into_iter_remaining<A, T>(iter: T) -> Seq<A>;
262
263pub broadcast axiom fn axiom_from_iterator_ensures<A, I: Iterator<Item = A> + IteratorSpec>(iter: I)
266 ensures
267 #[trigger] into_iter_remaining::<A, I>(iter) == iter.remaining(),
268;
269
270#[verifier::external_trait_specification]
271#[verifier::external_trait_extension(FromIteratorSpec via FromIteratorSpecImpl)]
272pub trait ExFromIterator<A>: Sized {
273 type ExternalTraitSpecificationFor: FromIterator<A>;
274
275 spec fn from_iter_ensures(remaining: Seq<A>, s: Self) -> bool;
276
277 fn from_iter<T>(iter: T) -> (s: Self)
278 where T: IntoIterator<Item = A>
279 ensures
280 Self::from_iter_ensures(into_iter_remaining(iter), s),
281 ;
282}
283
284#[verifier::external_body]
288#[verifier::external_type_specification]
289#[verifier::reject_recursive_types(I)]
290pub struct ExRev<I>(Rev<I>);
291
292pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
294
295pub uninterp spec fn into_rev_spec<I>(i: I) -> Rev<I>;
299
300pub uninterp spec fn rev_post<I>(i: I, r: Rev<I>) -> bool;
306
307pub broadcast axiom fn rev_postcondition<I: DoubleEndedIteratorSpec>(i: I)
308 requires
309 i.obeys_prophetic_iter_laws(),
310 rev_post(i, into_rev_spec(i)),
311 ensures
312 {
313 let r = #[trigger] into_rev_spec(i);
314 &&& IteratorSpec::remaining(&r) == IteratorSpec::remaining(&i).reverse()
315 &&& IteratorSpec::will_return_none(&r) == i.will_return_none()
316 &&& IteratorSpec::decrease(&r) is Some == i.decrease() is Some
317 },
318;
319
320impl <I> IteratorSpecImpl for Rev<I>
321 where I: DoubleEndedIterator + DoubleEndedIteratorSpec {
322 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
323 rev_iter(*self).obeys_prophetic_iter_laws()
324 }
325
326 #[verifier::prophetic]
327 closed spec fn remaining(&self) -> Seq<Self::Item> {
328 rev_iter(*self).remaining().reverse()
329 }
330
331 #[verifier::prophetic]
332 closed spec fn will_return_none(&self) -> bool {
333 rev_iter(*self).will_return_none()
334 }
335
336 closed spec fn decrease(&self) -> Option<nat> {
337 rev_iter(*self).decrease()
338 }
339
340 open spec fn peek(&self, index: int) -> Option<Self::Item> {
341 rev_iter(*self).peek_back(index)
342 }
343}
344
345impl <I> DoubleEndedIteratorSpecImpl for Rev<I>
346 where I: DoubleEndedIterator + IteratorSpec {
347
348 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
349 rev_iter(*self).peek(index)
350 }
351}
352
353impl <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
382pub struct VerusForLoopWrapper<I: Iterator> {
388 pub index: Ghost<int>,
389 pub snapshot: Ghost<I>,
390 pub iter: I,
391 pub history: Ghost<Seq<I::Item>>,
392}
393
394impl <I: Iterator> VerusForLoopWrapper<I> {
395 #[verifier::prophetic]
396 pub open spec fn seq(self) -> Seq<I::Item> {
397 self.snapshot@.remaining()
398 }
399
400 pub open spec fn history(self) -> Seq<I::Item> {
402 self.history@
403 }
404
405 pub open spec fn index(self) -> int {
406 self.index@
407 }
408
409 #[verifier::prophetic]
412 pub closed spec fn wf_inner(self) -> bool {
413 &&& self.iter.remaining().len() == self.seq().len() - self.index()
414 &&& forall |i| 0 <= i < self.iter.remaining().len() ==> #[trigger] self.iter.remaining()[i] == self.seq()[self.index() + i]
415 &&& self.iter.will_return_none() ==> self.snapshot@.will_return_none()
416 }
417
418 #[verifier::prophetic]
420 pub open spec fn wf(self) -> bool {
421 &&& 0 <= self.index() <= self.seq().len()
422 &&& self.wf_inner()
423 &&& self.iter.obeys_prophetic_iter_laws() ==> {
424 &&& self.history@.len() == self.index()
425 &&& forall |i| 0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
426 }
427 }
428
429 pub fn new(iter: I) -> (s: Self)
431 ensures
432 s.index == 0,
433 s.snapshot == iter,
434 s.iter == iter,
435 s.history@ == Seq::<I::Item>::empty(),
436 s.wf(),
437 {
438 broadcast use lemma_seq_empty;
439 VerusForLoopWrapper {
440 index: Ghost(0),
441 snapshot: Ghost(iter),
442 iter,
443 history: Ghost(Seq::empty()),
444 }
445 }
446
447 pub fn next(&mut self) -> (ret: Option<I::Item>)
450 requires
451 old(self).wf(),
452 ensures
453 final(self).seq() == old(self).seq(),
454 final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
455 final(self).snapshot == old(self).snapshot,
456 final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
457 final(self).iter.obeys_prophetic_iter_laws() && ret is None ==>
458 final(self).snapshot@.will_return_none() && final(self).index() == final(self).seq().len(),
459 final(self).iter.obeys_prophetic_iter_laws() ==> (ret matches Some(r) ==>
460 r == old(self).seq()[old(self).index()]),
461 ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
463 ret is None ==> final(self).history@ == old(self).history@,
464 exists |m: &mut I| #![auto] call_ensures(I::next, (m,), ret) && *m == old(self).iter && *final(m) == final(self).iter,
466 {
467 let ghost old_history = self.history@;
468 let ret = self.iter.next();
469 if ret.is_some() {
470 self.history = Ghost(old_history.push(ret->0));
471 }
472 proof {
473 broadcast use group_seq_lemmas;
474 if ret.is_some() {
475 self.index@ = self.index@ + 1;
476 }
477 }
478 ret
479 }
480}
481
482pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
486
487#[verifier::external_trait_specification]
491#[verifier::external_trait_extension(StepSpec via StepSpecImpl)]
492pub trait ExIterStep: Clone + PartialOrd + Sized {
493 type ExternalTraitSpecificationFor: core::iter::Step;
494
495 spec fn spec_is_lt(self, other: Self) -> bool;
498
499 spec fn spec_steps_between(self, end: Self) -> Option<usize>;
500
501 spec fn spec_steps_between_int(self, end: Self) -> int;
502
503 spec fn spec_forward_checked(self, count: usize) -> Option<Self>;
504
505 spec fn spec_forward_checked_int(self, count: int) -> Option<Self>;
506
507 spec fn spec_backward_checked(self, count: usize) -> Option<Self>;
508
509 spec fn spec_backward_checked_int(self, count: int) -> Option<Self>;
510}
511
512
513pub broadcast group group_iter_axioms {
518 rev_postcondition,
519}
520
521}