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 default_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 default_ensures
86 self.will_return_none(),
87 self.obeys_prophetic_iter_laws() ==>
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 default_ensures
95 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
97 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
98 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
99 final(self).obeys_prophetic_iter_laws() ==> {
100 final(self).remaining().is_suffix_of(old(self).remaining())
101 },
102 final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
106 &&& final(self).remaining().len() == 0
107 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
108 predicate.ensures((#[trigger]&old(self).remaining()[i],), false)
109 },
110 final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
114 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
115 {
116 &&& 0 <= final(self).remaining().len() < old(self).remaining().len()
117 &&& predicate.ensures((&r.unwrap(),), true)
118 &&& old(self).remaining()[idx] == r.unwrap()
119 &&& forall |i| 0 <= i < idx ==>
120 predicate.ensures((#[trigger] &old(self).remaining()[i],), false)
121 }
122 };
123
124 fn all<F>(&mut self, f: F) -> (r: bool)
129 where Self: Sized,
130 F: FnMut(Self::Item) -> bool
131 default_ensures
132 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
134 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
135 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
136 final(self).obeys_prophetic_iter_laws() ==> {
137 final(self).remaining().is_suffix_of(old(self).remaining())
138 },
139 final(self).obeys_prophetic_iter_laws() && r ==> {
142 &&& final(self).remaining().len() == 0
143 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
144 f.ensures((#[trigger] old(self).remaining()[i],), true)
145 },
146 final(self).obeys_prophetic_iter_laws() && !r ==> {
149 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
150 {
151 &&& final(self).remaining().len() < old(self).remaining().len()
153 &&& f.ensures((old(self).remaining()[idx],), false)
154 &&& forall |i| 0 <= i < idx ==>
155 f.ensures((#[trigger] old(self).remaining()[i],), true)
156 }
157 };
158
159 fn any<F>(&mut self, f: F) -> (r: bool)
160 where Self: Sized,
161 F: FnMut(Self::Item) -> bool
162 default_ensures
163 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
165 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
166 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
167 final(self).obeys_prophetic_iter_laws() ==> {
168 final(self).remaining().is_suffix_of(old(self).remaining())
169 },
170 final(self).obeys_prophetic_iter_laws() && !r ==> {
173 &&& final(self).remaining().len() == 0
174 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
175 f.ensures((#[trigger] old(self).remaining()[i],), false)
176 },
177 final(self).obeys_prophetic_iter_laws() && r ==> {
180 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
181 {
182 &&& final(self).remaining().len() < old(self).remaining().len()
184 &&& f.ensures((old(self).remaining()[idx],), true)
185 &&& forall |i| 0 <= i < idx ==>
186 f.ensures((#[trigger] old(self).remaining()[i],), false)
187 }
188 };
189}
190
191#[verifier::external_trait_specification]
192#[verifier::external_trait_extension(DoubleEndedIteratorSpec via DoubleEndedIteratorSpecImpl)]
193pub trait ExDoubleEndedIterator : Iterator {
194 type ExternalTraitSpecificationFor: DoubleEndedIterator;
195
196 fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
207 ensures
208 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) == <Self as IteratorSpec>::obeys_prophetic_iter_laws(old(self)),
210 <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)),
211 <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),
212 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) ==>
214 ({
215 if <Self as IteratorSpec>::remaining(old(self)).len() > 0 {
216 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)).drop_last()
217 && ret == Some(<Self as IteratorSpec>::remaining(old(self)).last())
218 } else {
219 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)) && ret == None && <Self as IteratorSpec>::will_return_none(final(self))
220 }
221 }),
222 <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 ==>
224 <Self as IteratorSpec>::decrease(old(self))->0 > <Self as IteratorSpec>::decrease(final(self))->0,
225 ;
226
227 spec fn peek_back(&self, index: int) -> Option<Self::Item>;
232}
233
234#[verifier::external_trait_specification]
238pub trait ExIntoIterator {
239 type ExternalTraitSpecificationFor: core::iter::IntoIterator;
240}
241
242pub open spec fn iter_into_iter_spec<I: Iterator>(i: I) -> I {
243 i
244}
245
246#[verifier::when_used_as_spec(iter_into_iter_spec)]
247pub assume_specification<I: Iterator>[ <I as IntoIterator>::into_iter ](i: I) -> (r: I)
248 ensures
249 r == i,
250;
251
252pub uninterp spec fn into_iter_remaining<A, T>(iter: T) -> Seq<A>;
256
257pub broadcast axiom fn axiom_from_iterator_ensures<A, I: Iterator<Item = A> + IteratorSpec>(iter: I)
260 ensures
261 #[trigger] into_iter_remaining::<A, I>(iter) == iter.remaining(),
262;
263
264#[verifier::external_trait_specification]
265#[verifier::external_trait_extension(FromIteratorSpec via FromIteratorSpecImpl)]
266pub trait ExFromIterator<A>: Sized {
267 type ExternalTraitSpecificationFor: FromIterator<A>;
268
269 spec fn from_iter_ensures(remaining: Seq<A>, s: Self) -> bool;
270
271 fn from_iter<T>(iter: T) -> (s: Self)
272 where T: IntoIterator<Item = A>
273 ensures
274 Self::from_iter_ensures(into_iter_remaining(iter), s),
275 ;
276}
277
278#[verifier::external_body]
282#[verifier::external_type_specification]
283#[verifier::reject_recursive_types(I)]
284pub struct ExRev<I>(Rev<I>);
285
286pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
288
289pub uninterp spec fn into_rev_spec<I>(i: I) -> Rev<I>;
293
294pub uninterp spec fn rev_post<I>(i: I, r: Rev<I>) -> bool;
300
301pub broadcast axiom fn rev_postcondition<I: DoubleEndedIteratorSpec>(i: I)
302 requires
303 i.obeys_prophetic_iter_laws(),
304 rev_post(i, into_rev_spec(i)),
305 ensures
306 {
307 let r = #[trigger] into_rev_spec(i);
308 &&& IteratorSpec::remaining(&r) == IteratorSpec::remaining(&i).reverse()
309 &&& IteratorSpec::will_return_none(&r) == i.will_return_none()
310 &&& IteratorSpec::decrease(&r) is Some == i.decrease() is Some
311 },
312;
313
314impl <I> IteratorSpecImpl for Rev<I>
315 where I: DoubleEndedIterator + DoubleEndedIteratorSpec {
316 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
317 rev_iter(*self).obeys_prophetic_iter_laws()
318 }
319
320 #[verifier::prophetic]
321 closed spec fn remaining(&self) -> Seq<Self::Item> {
322 rev_iter(*self).remaining().reverse()
323 }
324
325 #[verifier::prophetic]
326 closed spec fn will_return_none(&self) -> bool {
327 rev_iter(*self).will_return_none()
328 }
329
330 closed spec fn decrease(&self) -> Option<nat> {
331 rev_iter(*self).decrease()
332 }
333
334 open spec fn peek(&self, index: int) -> Option<Self::Item> {
335 rev_iter(*self).peek_back(index)
336 }
337}
338
339impl <I> DoubleEndedIteratorSpecImpl for Rev<I>
340 where I: DoubleEndedIterator + IteratorSpec {
341
342 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
343 rev_iter(*self).peek(index)
344 }
345}
346
347impl <I> IteratorSpecImpl for &mut I
352 where I: Iterator {
353 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
354 <I as IteratorSpec>::obeys_prophetic_iter_laws(*self)
355 }
356
357 #[verifier::prophetic]
358 open spec fn remaining(&self) -> Seq<Self::Item> {
359 <I as IteratorSpec>::remaining(*self)
360 }
361
362 #[verifier::prophetic]
363 open spec fn will_return_none(&self) -> bool {
364 <I as IteratorSpec>::will_return_none(*self)
365 }
366
367 open spec fn decrease(&self) -> Option<nat> {
368 <I as IteratorSpec>::decrease(*self)
369 }
370
371 open spec fn peek(&self, index: int) -> Option<Self::Item> {
372 <I as IteratorSpec>::peek(*self, index)
373 }
374}
375
376pub struct VerusForLoopWrapper<I: Iterator> {
382 pub index: Ghost<int>,
383 pub snapshot: Ghost<I>,
384 pub iter: I,
385 pub history: Ghost<Seq<I::Item>>,
386}
387
388impl <I: Iterator> VerusForLoopWrapper<I> {
389 #[verifier::prophetic]
390 pub open spec fn seq(self) -> Seq<I::Item> {
391 self.snapshot@.remaining()
392 }
393
394 pub open spec fn history(self) -> Seq<I::Item> {
396 self.history@
397 }
398
399 pub open spec fn index(self) -> int {
400 self.index@
401 }
402
403 #[verifier::prophetic]
406 pub closed spec fn wf_inner(self) -> bool {
407 &&& self.iter.remaining().len() == self.seq().len() - self.index()
408 &&& forall |i| 0 <= i < self.iter.remaining().len() ==> #[trigger] self.iter.remaining()[i] == self.seq()[self.index() + i]
409 &&& self.iter.will_return_none() ==> self.snapshot@.will_return_none()
410 }
411
412 #[verifier::prophetic]
414 pub open spec fn wf(self) -> bool {
415 &&& 0 <= self.index() <= self.seq().len()
416 &&& self.wf_inner()
417 &&& self.iter.obeys_prophetic_iter_laws() ==> {
418 &&& self.history@.len() == self.index()
419 &&& forall |i| 0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
420 }
421 }
422
423 pub fn new(iter: I) -> (s: Self)
425 ensures
426 s.index == 0,
427 s.snapshot == iter,
428 s.iter == iter,
429 s.history@ == Seq::<I::Item>::empty(),
430 s.wf(),
431 {
432 broadcast use lemma_seq_empty;
433 VerusForLoopWrapper {
434 index: Ghost(0),
435 snapshot: Ghost(iter),
436 iter,
437 history: Ghost(Seq::empty()),
438 }
439 }
440
441 pub fn next(&mut self) -> (ret: Option<I::Item>)
444 requires
445 old(self).wf(),
446 ensures
447 final(self).seq() == old(self).seq(),
448 final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
449 final(self).snapshot == old(self).snapshot,
450 final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
451 final(self).iter.obeys_prophetic_iter_laws() && ret is None ==>
452 final(self).snapshot@.will_return_none() && final(self).index() == final(self).seq().len(),
453 final(self).iter.obeys_prophetic_iter_laws() ==> (ret matches Some(r) ==>
454 r == old(self).seq()[old(self).index()]),
455 ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
457 ret is None ==> final(self).history@ == old(self).history@,
458 exists |m: &mut I| #![auto] call_ensures(I::next, (m,), ret) && *m == old(self).iter && *final(m) == final(self).iter,
460 {
461 let ghost old_history = self.history@;
462 let ret = self.iter.next();
463 if ret.is_some() {
464 self.history = Ghost(old_history.push(ret->0));
465 }
466 proof {
467 broadcast use group_seq_lemmas;
468 if ret.is_some() {
469 self.index@ = self.index@ + 1;
470 }
471 }
472 ret
473 }
474}
475
476pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
480
481#[verifier::external_trait_specification]
485#[verifier::external_trait_extension(StepSpec via StepSpecImpl)]
486pub trait ExIterStep: Clone + PartialOrd + Sized {
487 type ExternalTraitSpecificationFor: core::iter::Step;
488
489 spec fn spec_is_lt(self, other: Self) -> bool;
492
493 spec fn spec_steps_between(self, end: Self) -> Option<usize>;
494
495 spec fn spec_steps_between_int(self, end: Self) -> int;
496
497 spec fn spec_forward_checked(self, count: usize) -> Option<Self>;
498
499 spec fn spec_forward_checked_int(self, count: int) -> Option<Self>;
500
501 spec fn spec_backward_checked(self, count: usize) -> Option<Self>;
502
503 spec fn spec_backward_checked_int(self, count: int) -> Option<Self>;
504}
505
506
507pub broadcast group group_iter_axioms {
512 rev_postcondition,
513}
514
515}