creusot_std/std/iter/
enumerate.rs1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{
4 invariant::*,
5 prelude::*,
6 std::iter::{Enumerate, ExactSizeIteratorSpec},
7};
8
9pub trait EnumerateExt<I> {
10 #[logic]
11 fn iter(self) -> I;
12
13 #[logic]
14 fn n(self) -> usize;
15}
16
17impl<I> EnumerateExt<I> for Enumerate<I> {
18 #[logic(opaque)]
19 fn iter(self) -> I {
20 dead
21 }
22
23 #[logic(opaque)]
24 fn n(self) -> usize {
25 dead
26 }
27}
28
29impl<I> Resolve for Enumerate<I> {
30 #[logic(open, prophetic, inline)]
31 fn resolve(self) -> bool {
32 resolve(self.iter())
33 }
34
35 #[trusted]
36 #[logic(prophetic)]
37 #[requires(structural_resolve(self))]
38 #[ensures(self.resolve())]
39 fn resolve_coherence(self) {}
40}
41
42impl<I: IteratorSpec> Invariant for Enumerate<I> {
43 #[logic(prophetic)]
44 #[ensures(result ==> inv(self.iter()))]
45 fn invariant(self) -> bool {
46 pearlite! {
47 inv(self.iter())
48 && (forall<s: Seq<I::Item>, i: I>
49 #[trigger(self.iter().produces(s, i))]
50 self.iter().produces(s, i) ==>
51 self.n()@ + s.len() < core::usize::MAX@)
52 && (forall<i: &mut I> i.completed() ==> (*i).produces(Seq::empty(), ^i))
53 }
54 }
55}
56
57impl<I: IteratorSpec> IteratorSpec for Enumerate<I> {
58 #[logic(open, prophetic)]
59 fn completed(&mut self) -> bool {
60 pearlite! {
61 exists<inner: &mut _> *inner == self.iter() && ^inner == (^self).iter()
62 && inner.completed()
63 && self.n()@ == (^self).n()@
64 }
65 }
66
67 #[logic(open, prophetic)]
68 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
69 pearlite! {
70 visited.len() == o.n()@ - self.n()@
71 && exists<s: Seq<I::Item>>
72 self.iter().produces(s, o.iter())
73 && visited.len() == s.len()
74 && forall<i> 0 <= i && i < s.len() ==> visited[i].0@ == self.n()@ + i && visited[i].1 == s[i]
75 }
76 }
77
78 #[logic(law)]
79 #[ensures(self.produces(Seq::empty(), self))]
80 fn produces_refl(self) {}
81
82 #[logic(law)]
83 #[requires(a.produces(ab, b))]
84 #[requires(b.produces(bc, c))]
85 #[ensures(a.produces(ab.concat(bc), c))]
86 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
87}
88
89extern_spec! {
90 impl<I: Iterator> Iterator for Enumerate<I> {
91 #[ensures(I::size_hint.postcondition((&self.iter(),), result))]
92 fn size_hint(&self) -> (usize, Option<usize>);
93 }
94}
95
96impl<'a, I: ExactSizeIteratorSpec> ExactSizeIteratorSpec for Enumerate<I> {
97 #[logic(law)]
98 #[requires(Self::size_hint.postcondition((self,), r))]
99 #[ensures(r.1 == Some(r.0))]
100 fn size_hint_exact(&self, r: (usize, Option<usize>)) {
101 self.iter().size_hint_exact(r)
102 }
103}