1use super::super::prelude::*;
2use super::super::seq::{
3 axiom_seq_empty, axiom_seq_subrange_index, axiom_seq_subrange_len, group_seq_axioms,
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 #[verifier::prophetic]
71 spec fn initial_value_relation(&self, init: &Self) -> bool;
72
73 spec fn peek(&self, index: int) -> Option<Self::Item>;
76
77 fn rev(self) -> (r: Rev<Self>)
82 where Self: Sized,
83 default_ensures
84 self.obeys_prophetic_iter_laws() && self.initial_value_relation(&self) ==>
85 r == into_rev_spec(self) && rev_post(self, r),
86 ;
87
88 fn collect<B>(self) -> (collection: B)
89 where
90 B: FromIterator<Self::Item>,
91 Self: Sized,
92 default_ensures
93 self.will_return_none(),
94 self.obeys_prophetic_iter_laws() && self.initial_value_relation(&self) ==>
95 FromIteratorSpec::from_iter_ensures(self.remaining(), collection),
96 ;
97
98 fn find<P>(&mut self, predicate: P) -> (r: Option<Self::Item>)
99 where Self: Sized,
100 P: FnMut(&Self::Item) -> bool
101 default_ensures
102 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
104 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
105 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
106 final(self).obeys_prophetic_iter_laws() ==> {
107 final(self).remaining().is_suffix_of(old(self).remaining())
108 },
109 final(self).obeys_prophetic_iter_laws() && r.is_none() ==> {
113 &&& final(self).remaining().len() == 0
114 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
115 predicate.ensures((#[trigger]&old(self).remaining()[i],), false)
116 },
117 final(self).obeys_prophetic_iter_laws() && r.is_some() ==> {
121 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
122 {
123 &&& old(self).remaining().len() > 0
124 &&& predicate.ensures((&r.unwrap(),), true)
125 &&& old(self).remaining()[idx] == r.unwrap()
126 &&& forall |i| 0 <= i < idx ==>
127 predicate.ensures((#[trigger] &old(self).remaining()[i],), false)
128 }
129 };
130
131 fn all<F>(&mut self, f: F) -> (r: bool)
136 where Self: Sized,
137 F: FnMut(Self::Item) -> bool
138 default_ensures
139 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
141 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
142 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
143 final(self).obeys_prophetic_iter_laws() ==> {
144 final(self).remaining().is_suffix_of(old(self).remaining())
145 },
146 final(self).obeys_prophetic_iter_laws() && r ==> {
149 &&& final(self).remaining().len() == 0
150 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
151 f.ensures((#[trigger] old(self).remaining()[i],), true)
152 },
153 final(self).obeys_prophetic_iter_laws() && !r ==> {
156 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
157 {
158 &&& final(self).remaining().len() < old(self).remaining().len()
160 &&& f.ensures((old(self).remaining()[idx],), false)
161 &&& forall |i| 0 <= i < idx ==>
162 f.ensures((#[trigger] old(self).remaining()[i],), true)
163 }
164 };
165
166 fn any<F>(&mut self, f: F) -> (r: bool)
167 where Self: Sized,
168 F: FnMut(Self::Item) -> bool
169 default_ensures
170 final(self).obeys_prophetic_iter_laws() == old(self).obeys_prophetic_iter_laws(),
172 final(self).obeys_prophetic_iter_laws() ==> final(self).will_return_none() == old(self).will_return_none(),
173 final(self).obeys_prophetic_iter_laws() ==> (old(self).decrease() is Some <==> final(self).decrease() is Some),
174 final(self).obeys_prophetic_iter_laws() ==> {
175 final(self).remaining().is_suffix_of(old(self).remaining())
176 },
177 final(self).obeys_prophetic_iter_laws() && !r ==> {
180 &&& final(self).remaining().len() == 0
181 &&& forall |i| 0 <= i < old(self).remaining().len() ==>
182 f.ensures((#[trigger] old(self).remaining()[i],), false)
183 },
184 final(self).obeys_prophetic_iter_laws() && r ==> {
187 let idx = old(self).remaining().len() - final(self).remaining().len() - 1;
188 {
189 &&& final(self).remaining().len() < old(self).remaining().len()
191 &&& f.ensures((old(self).remaining()[idx],), true)
192 &&& forall |i| 0 <= i < idx ==>
193 f.ensures((#[trigger] old(self).remaining()[i],), false)
194 }
195 };
196}
197
198#[verifier::external_trait_specification]
199#[verifier::external_trait_extension(DoubleEndedIteratorSpec via DoubleEndedIteratorSpecImpl)]
200pub trait ExDoubleEndedIterator : Iterator {
201 type ExternalTraitSpecificationFor: DoubleEndedIterator;
202
203 fn next_back(&mut self) -> (ret: Option<<Self as core::iter::Iterator>::Item>)
214 ensures
215 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) == <Self as IteratorSpec>::obeys_prophetic_iter_laws(old(self)),
217 <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)),
218 <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),
219 <Self as IteratorSpec>::obeys_prophetic_iter_laws(final(self)) ==>
221 ({
222 if <Self as IteratorSpec>::remaining(old(self)).len() > 0 {
223 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)).drop_last()
224 && ret == Some(<Self as IteratorSpec>::remaining(old(self)).last())
225 } else {
226 <Self as IteratorSpec>::remaining(final(self)) == <Self as IteratorSpec>::remaining(old(self)) && ret == None && <Self as IteratorSpec>::will_return_none(final(self))
227 }
228 }),
229 <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 ==>
231 <Self as IteratorSpec>::decrease(old(self))->0 > <Self as IteratorSpec>::decrease(final(self))->0,
232 ;
233
234 spec fn peek_back(&self, index: int) -> Option<Self::Item>;
239}
240
241#[verifier::external_trait_specification]
245pub trait ExIntoIterator {
246 type ExternalTraitSpecificationFor: core::iter::IntoIterator;
247}
248
249pub open spec fn iter_into_iter_spec<I: Iterator>(i: I) -> I {
250 i
251}
252
253#[verifier::when_used_as_spec(iter_into_iter_spec)]
254pub assume_specification<I: Iterator>[ <I as IntoIterator>::into_iter ](i: I) -> (r: I)
255 ensures
256 r == i,
257;
258
259pub uninterp spec fn into_iter_remaining<A, T>(iter: T) -> Seq<A>;
263
264pub broadcast axiom fn axiom_from_iterator_ensures<A, I: Iterator<Item = A> + IteratorSpec>(iter: I)
267 ensures
268 #[trigger] into_iter_remaining::<A, I>(iter) == iter.remaining(),
269;
270
271#[verifier::external_trait_specification]
272#[verifier::external_trait_extension(FromIteratorSpec via FromIteratorSpecImpl)]
273pub trait ExFromIterator<A>: Sized {
274 type ExternalTraitSpecificationFor: FromIterator<A>;
275
276 spec fn from_iter_ensures(remaining: Seq<A>, s: Self) -> bool;
277
278 fn from_iter<T>(iter: T) -> (s: Self)
279 where T: IntoIterator<Item = A>
280 ensures
281 Self::from_iter_ensures(into_iter_remaining(iter), s),
282 ;
283}
284
285#[verifier::external_body]
289#[verifier::external_type_specification]
290#[verifier::reject_recursive_types(I)]
291pub struct ExRev<I>(Rev<I>);
292
293pub uninterp spec fn rev_iter<I>(r: Rev<I>) -> I;
295
296pub uninterp spec fn into_rev_spec<I>(i: I) -> Rev<I>;
298
299pub uninterp spec fn rev_post<I>(i: I, r: Rev<I>) -> bool;
305
306pub broadcast axiom fn rev_postcondition<I: DoubleEndedIteratorSpec>(i: I)
307 requires
308 i.obeys_prophetic_iter_laws(),
309 i.initial_value_relation(&i),
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 &&& IteratorSpec::initial_value_relation(&r, &r)
318 },
319;
320
321impl <I> IteratorSpecImpl for Rev<I>
322 where I: DoubleEndedIterator + DoubleEndedIteratorSpec {
323 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
324 rev_iter(*self).obeys_prophetic_iter_laws()
325 }
326
327 #[verifier::prophetic]
328 closed spec fn remaining(&self) -> Seq<Self::Item> {
329 rev_iter(*self).remaining().reverse()
330 }
331
332 #[verifier::prophetic]
333 closed spec fn will_return_none(&self) -> bool {
334 rev_iter(*self).will_return_none()
335 }
336
337 #[verifier::prophetic]
338 open spec fn initial_value_relation(&self, init: &Self) -> bool {
339 &&& IteratorSpec::remaining(init) == IteratorSpec::remaining(self)
340 &&& rev_iter(*self).initial_value_relation(&rev_iter(*init))
341 }
342
343 closed spec fn decrease(&self) -> Option<nat> {
344 rev_iter(*self).decrease()
345 }
346
347 open spec fn peek(&self, index: int) -> Option<Self::Item> {
348 rev_iter(*self).peek_back(index)
349 }
350}
351
352impl <I> DoubleEndedIteratorSpecImpl for Rev<I>
353 where I: DoubleEndedIterator + IteratorSpec {
354
355 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
356 rev_iter(*self).peek(index)
357 }
358}
359
360impl <I> IteratorSpecImpl for &mut I
365 where I: Iterator {
366 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
367 <I as IteratorSpec>::obeys_prophetic_iter_laws(*self)
368 }
369
370 #[verifier::prophetic]
371 open spec fn remaining(&self) -> Seq<Self::Item> {
372 <I as IteratorSpec>::remaining(*self)
373 }
374
375 #[verifier::prophetic]
376 open spec fn will_return_none(&self) -> bool {
377 <I as IteratorSpec>::will_return_none(*self)
378 }
379
380 #[verifier::prophetic]
381 open spec fn initial_value_relation(&self, init: &Self) -> bool {
382 <I as IteratorSpec>::initial_value_relation(*self, &**init)
383 }
384
385 open spec fn decrease(&self) -> Option<nat> {
386 <I as IteratorSpec>::decrease(*self)
387 }
388
389 open spec fn peek(&self, index: int) -> Option<Self::Item> {
390 <I as IteratorSpec>::peek(*self, index)
391 }
392}
393
394pub struct VerusForLoopWrapper<'a, I: Iterator> {
400 pub index: Ghost<int>,
401 pub snapshot: Ghost<I>,
402 pub init: Ghost<Option<&'a I>>,
403 pub iter: I,
404 pub history: Ghost<Seq<I::Item>>,
405}
406
407impl <'a, I: Iterator> VerusForLoopWrapper<'a, I> {
408 #[verifier::prophetic]
409 pub open spec fn seq(self) -> Seq<I::Item> {
410 self.snapshot@.remaining()
411 }
412
413 pub open spec fn history(self) -> Seq<I::Item> {
415 self.history@
416 }
417
418 pub open spec fn index(self) -> int {
419 self.index@
420 }
421
422 #[verifier::prophetic]
425 pub closed spec fn wf_inner(self) -> bool {
426 &&& self.iter.remaining().len() == self.seq().len() - self.index()
427 &&& forall |i| 0 <= i < self.iter.remaining().len() ==> #[trigger] self.iter.remaining()[i] == self.seq()[self.index() + i]
428 &&& self.iter.will_return_none() ==> self.snapshot@.will_return_none()
429 }
430
431 #[verifier::prophetic]
433 pub open spec fn wf(self) -> bool {
434 &&& 0 <= self.index() <= self.seq().len()
435 &&& self.init@ matches Some(init) ==> self.snapshot@.initial_value_relation(init)
436 &&& self.wf_inner()
437 &&& self.iter.obeys_prophetic_iter_laws() ==> {
438 &&& self.history@.len() == self.index()
439 &&& forall |i| 0 <= i < self.index() ==> #[trigger] self.history@[i] == self.seq()[i]
440 }
441 }
442
443 pub fn new(iter: I, init: Ghost<Option<&'a I>>) -> (s: Self)
445 requires
446 init@ matches Some(i) ==> iter.initial_value_relation(i),
447 ensures
448 s.index == 0,
449 s.snapshot == iter,
450 s.init == init,
451 s.iter == iter,
452 s.history@ == Seq::<I::Item>::empty(),
453 s.wf(),
454 {
455 broadcast use axiom_seq_empty;
456 VerusForLoopWrapper {
457 index: Ghost(0),
458 snapshot: Ghost(iter),
459 init: init,
460 iter,
461 history: Ghost(Seq::empty()),
462 }
463 }
464
465 pub fn next(&mut self) -> (ret: Option<I::Item>)
468 requires
469 old(self).wf(),
470 ensures
471 final(self).seq() == old(self).seq(),
472 final(self).index() == old(self).index() + if ret is Some { 1int } else { 0 },
473 final(self).snapshot == old(self).snapshot,
474 final(self).init == old(self).init,
475 final(self).iter.obeys_prophetic_iter_laws() ==> final(self).wf(),
476 final(self).iter.obeys_prophetic_iter_laws() && ret is None ==>
477 final(self).snapshot@.will_return_none() && final(self).index() == final(self).seq().len(),
478 final(self).iter.obeys_prophetic_iter_laws() ==> (ret matches Some(r) ==>
479 r == old(self).seq()[old(self).index()]),
480 ret matches Some(i) ==> final(self).history@ == old(self).history@.push(i),
482 ret is None ==> final(self).history@ == old(self).history@,
483 final(self).iter.obeys_prophetic_iter_laws() == old(self).iter.obeys_prophetic_iter_laws(),
486 final(self).iter.obeys_prophetic_iter_laws() ==> final(self).iter.will_return_none() == old(self).iter.will_return_none(),
487 final(self).iter.obeys_prophetic_iter_laws() ==> (old(self).iter.decrease() is Some <==> final(self).iter.decrease() is Some),
488 final(self).iter.obeys_prophetic_iter_laws() ==>
489 ({
490 if old(self).iter.remaining().len() > 0 {
491 &&& final(self).iter.remaining() == old(self).iter.remaining().drop_first()
492 &&& ret == Some(old(self).iter.remaining()[0])
493 } else {
494 final(self).iter.remaining() == old(self).iter.remaining() && ret == None && final(self).iter.will_return_none()
495 }
496 }),
497 final(self).iter.obeys_prophetic_iter_laws() && old(self).iter.remaining().len() > 0 && final(self).iter.decrease() is Some ==>
498 decreases_to!(old(self).iter.decrease()->0 => final(self).iter.decrease()->0),
499 {
500 let ghost old_history = self.history@;
501 let ret = self.iter.next();
502 if ret.is_some() {
503 self.history = Ghost(old_history.push(ret->0));
504 }
505 proof {
506 broadcast use group_seq_axioms;
507 if ret.is_some() {
508 self.index@ = self.index@ + 1;
509 }
510 }
511 ret
512 }
513}
514
515pub open spec fn trigger_peek_implications<T>(x: T) -> bool { true }
519
520#[verifier::external_trait_specification]
524#[verifier::external_trait_extension(StepSpec via StepSpecImpl)]
525pub trait ExIterStep: Clone + PartialOrd + Sized {
526 type ExternalTraitSpecificationFor: core::iter::Step;
527
528 spec fn spec_is_lt(self, other: Self) -> bool;
531
532 spec fn spec_steps_between(self, end: Self) -> Option<usize>;
533
534 spec fn spec_steps_between_int(self, end: Self) -> int;
535
536 spec fn spec_forward_checked(self, count: usize) -> Option<Self>;
537
538 spec fn spec_forward_checked_int(self, count: int) -> Option<Self>;
539
540 spec fn spec_backward_checked(self, count: usize) -> Option<Self>;
541
542 spec fn spec_backward_checked_int(self, count: int) -> Option<Self>;
543}
544
545
546pub broadcast group group_iter_axioms {
551 rev_postcondition,
552}
553
554}