creusot_std/std/iter/
filter_map.rs1use crate::prelude::*;
2#[cfg(creusot)]
3use crate::{logic::Mapping, std::ops::*};
4use core::iter::FilterMap;
5
6pub trait FilterMapExt<I, F> {
7 #[logic]
8 fn iter(self) -> I;
9
10 #[logic]
11 fn func(self) -> F;
12}
13
14impl<I, F> FilterMapExt<I, F> for FilterMap<I, F> {
15 #[logic(opaque)]
16 fn iter(self) -> I {
17 dead
18 }
19
20 #[logic(opaque)]
21 fn func(self) -> F {
22 dead
23 }
24}
25
26impl<B, I: Iterator, F: FnMut(I::Item) -> Option<B>> Invariant for FilterMap<I, F> {
27 #[logic(prophetic, open, inline)]
28 fn invariant(self) -> bool {
29 inv(self.iter()) && inv(self.func()) && private_invariant(self)
30 }
31}
32
33#[logic(prophetic)]
34pub fn private_invariant<B, I: Iterator, F: FnMut(I::Item) -> Option<B>>(
35 f: FilterMap<I, F>,
36) -> bool {
37 no_precondition(f.func()) &&
39 immutable(f.func()) &&
41 precise(f.func())
43}
44
45#[logic(open, prophetic)]
48pub fn no_precondition<A, B, F: FnMut(A) -> Option<B>>(f: F) -> bool {
49 pearlite! { forall<i: A> inv(i) ==> f.precondition((i,)) }
50}
51
52#[logic(open, prophetic)]
55pub fn immutable<A, B, F: FnMut(A) -> Option<B>>(f: F) -> bool {
56 pearlite! { forall<g: F> f.hist_inv(g) ==> f == g }
57}
58
59#[logic(open, prophetic)]
61pub fn precise<A, B, F: FnMut(A) -> Option<B>>(f1: F) -> bool {
62 pearlite! { forall<f2: F, i> !((exists<b: B> f1.postcondition_mut((i,), f2, Some(b))) && f1.postcondition_mut((i,), f2, None)) }
63}
64
65impl<I: IteratorSpec, B, F: FnMut(I::Item) -> Option<B>> IteratorSpec for FilterMap<I, F> {
66 #[logic(open, prophetic)]
67 fn completed(&mut self) -> bool {
68 pearlite! {
69 (exists<s: Seq<_>, e: &mut I > self.iter().produces(s, *e) && e.completed() &&
70 forall<i> 0 <= i && i < s.len() ==> (*self).func().postcondition_mut((s[i],), (^self).func(), None))
71 && (*self).func() == (^self).func()
72 }
73 }
74
75 #[logic(open, prophetic)]
76 fn produces(self, visited: Seq<Self::Item>, succ: Self) -> bool {
77 pearlite! {
78 private_invariant(self) ==>
79 self.func().hist_inv(succ.func()) &&
80 exists<s: Seq<I::Item>, f: Mapping<Int, Int>> self.iter().produces(s, succ.iter()) &&
84 (forall<i> 0 <= i && i < visited.len() ==> 0 <= f.get(i) && f.get(i) < s.len()) &&
85 (forall<i, j> 0 <= i && i < j && j < visited.len() ==> f.get(i) < f.get(j)) &&
87 (forall<i> 0 <= i && i < visited.len() ==> self.func().postcondition_mut((s[f.get(i)],), self.func(), Some(visited[i]))) &&
89 (forall<j> 0 <= j && j < s.len()
91 ==> (!exists<i> 0 <= i && i < visited.len() && f.get(i) == j) == self.func().postcondition_mut((s[j],), self.func(), None))
92 }
93 }
94
95 #[logic(law)]
96 #[ensures(self.produces(Seq::empty(), self))]
97 fn produces_refl(self) {}
98
99 #[logic(law)]
100 #[requires(a.produces(ab, b))]
101 #[requires(b.produces(bc, c))]
102 #[ensures(a.produces(ab.concat(bc), c))]
103 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
104}