1#[cfg(feature = "nightly")]
2use crate::logic::ops::IndexLogic;
3#[cfg(creusot)]
4use crate::{invariant::inv, resolve::structural_resolve};
5use crate::{prelude::*, std::iter::ExactSizeIteratorSpec};
6
7#[cfg(feature = "nightly")]
8use std::alloc::Allocator;
9#[cfg(feature = "nightly")]
10use std::collections::VecDeque;
11use std::collections::vec_deque::Iter;
12#[cfg(creusot)]
13use std::ops::{Index, IndexMut};
14
15#[cfg(feature = "nightly")]
16impl<T, A: Allocator> View for VecDeque<T, A> {
17 type ViewTy = Seq<T>;
18
19 #[trusted]
20 #[logic(opaque)]
21 #[ensures(result.len() <= usize::MAX@)]
22 fn view(self) -> Seq<T> {
23 dead
24 }
25}
26
27#[cfg(feature = "nightly")]
28impl<T: DeepModel, A: Allocator> DeepModel for VecDeque<T, A> {
29 type DeepModelTy = Seq<T::DeepModelTy>;
30
31 #[trusted]
32 #[logic(opaque)]
33 #[ensures(self.view().len() == result.len())]
34 #[ensures(forall<i> 0 <= i && i < self.view().len()
35 ==> result[i] == self[i].deep_model())]
36 fn deep_model(self) -> Self::DeepModelTy {
37 dead
38 }
39}
40
41#[cfg(feature = "nightly")]
42impl<T, A: Allocator> IndexLogic<Int> for VecDeque<T, A> {
43 type Item = T;
44
45 #[logic(open, inline)]
46 fn index_logic(self, ix: Int) -> Self::Item {
47 pearlite! { self@[ix] }
48 }
49}
50
51#[cfg(feature = "nightly")]
52impl<T, A: Allocator> IndexLogic<usize> for VecDeque<T, A> {
53 type Item = T;
54
55 #[logic(open, inline)]
56 fn index_logic(self, ix: usize) -> Self::Item {
57 pearlite! { self@[ix@] }
58 }
59}
60
61#[cfg(feature = "nightly")]
62impl<T, A: Allocator> Resolve for VecDeque<T, A> {
63 #[logic(open, prophetic, inline)]
64 #[creusot::trusted_trivial_if_param_trivial]
65 fn resolve(self) -> bool {
66 pearlite! { forall<i> 0 <= i && i < self@.len() ==> resolve(self[i]) }
67 }
68
69 #[trusted]
70 #[logic(prophetic)]
71 #[requires(structural_resolve(self))]
72 #[ensures(self.resolve())]
73 fn resolve_coherence(self) {}
74}
75
76#[cfg(feature = "nightly")]
77impl<T, A: Allocator> Invariant for VecDeque<T, A> {
78 #[logic(open, prophetic)]
79 #[creusot::trusted_trivial_if_param_trivial]
80 fn invariant(self) -> bool {
81 pearlite! { inv(self@) }
82 }
83}
84
85extern_spec! {
86 impl<T> VecDeque<T> {
87 #[check(ghost)]
88 #[ensures(result@.len() == 0)]
89 fn new() -> Self;
90
91 #[check(terminates)] #[ensures(result@.len() == 0)]
93 fn with_capacity(capacity: usize) -> Self;
94 }
95
96 impl<T, A: Allocator> VecDeque<T, A> {
97 #[check(ghost)]
98 #[ensures(result@ == self@.len())]
99 fn len(&self) -> usize;
100
101 #[check(ghost)]
102 #[ensures(result == (self@.len() == 0))]
103 fn is_empty(&self) -> bool;
104
105 #[check(ghost)]
106 #[ensures((^self)@.len() == 0)]
107 fn clear(&mut self);
108
109 #[check(ghost)]
110 #[ensures(match result {
111 Some(t) =>
112 (^self)@ == self@.subsequence(1, self@.len()) &&
113 self@ == (^self)@.push_front(t),
114 None => *self == ^self && self@.len() == 0
115 })]
116 fn pop_front(&mut self) -> Option<T>;
117
118 #[check(ghost)]
119 #[ensures(match result {
120 Some(t) =>
121 (^self)@ == self@.subsequence(0, self@.len() - 1) &&
122 self@ == (^self)@.push_back(t),
123 None => *self == ^self && self@.len() == 0
124 })]
125 fn pop_back(&mut self) -> Option<T>;
126
127 #[check(terminates)] #[ensures((^self)@.len() == self@.len() + 1)]
129 #[ensures((^self)@ == self@.push_front(value))]
130 fn push_front(&mut self, value: T);
131
132 #[check(terminates)] #[ensures((^self)@ == self@.push_back(value))]
134 fn push_back(&mut self, value: T);
135 }
136
137 impl<T, A: Allocator> Index<usize> for VecDeque<T, A> {
138 #[check(ghost)]
139 #[ensures(*result == self@[i@])]
140 fn index(&self, i: usize) -> &T;
141 }
142
143 impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {
144 #[check(ghost)]
145 #[ensures(*result == (*self)@[i@])]
146 #[ensures(^result == (^self)@[i@])]
147 fn index_mut(&mut self, i: usize) -> &mut T;
148 }
149
150 impl<'a, T, A: Allocator> IntoIterator for &'a VecDeque<T, A> {
151 #[check(ghost)]
152 #[ensures(self@ == result@.to_owned_seq())]
153 fn into_iter(self) -> Iter<'a, T>;
154 }
155}
156
157impl<'a, T> View for Iter<'a, T> {
158 type ViewTy = Seq<&'a T>;
159
160 #[logic(opaque)]
161 fn view(self) -> Self::ViewTy {
162 dead
163 }
164}
165
166impl<'a, T> IteratorSpec for Iter<'a, T> {
167 #[logic(open, prophetic)]
168 fn completed(&mut self) -> bool {
169 pearlite! { resolve(self) && self@ == Seq::empty() }
170 }
171
172 #[logic(open)]
173 fn produces(self, visited: Seq<Self::Item>, tl: Self) -> bool {
174 pearlite! {
175 self@ == visited.concat(tl@)
176 }
177 }
178
179 #[logic(law)]
180 #[ensures(self.produces(Seq::empty(), self))]
181 fn produces_refl(self) {
182 let _ = Seq::<Self::Item>::concat_empty;
183 }
184
185 #[logic(law)]
186 #[requires(a.produces(ab, b))]
187 #[requires(b.produces(bc, c))]
188 #[ensures(a.produces(ab.concat(bc), c))]
189 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
190 let _ = Seq::<Self::Item>::concat_assoc;
191 }
192}
193
194extern_spec! {
195 impl<'a, T> Iterator for Iter<'a, T> {
196 #[ensures(result.0@ == self@.len())]
197 #[ensures(result.1 == Some(result.0))]
198 fn size_hint(&self) -> (usize, Option<usize>);
199 }
200}
201
202impl<'a, T> ExactSizeIteratorSpec for Iter<'a, T> {
203 #[logic(law)]
204 #[requires(Self::size_hint.postcondition((self,), r))]
205 #[ensures(r.1 == Some(r.0))]
206 #[allow(unused_variables)]
207 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
208}
209
210impl<'a, T> DoubleEndedIteratorSpec for Iter<'a, T> {
211 #[logic(open)]
212 fn produces_back(self, visited: Seq<Self::Item>, tl: Self) -> bool {
213 pearlite! {
214 self@ == tl@.concat(visited.reverse())
215 }
216 }
217
218 #[logic(open, prophetic)]
219 fn completed_back(&mut self) -> bool {
220 self.completed()
221 }
222
223 #[logic(law)]
224 #[ensures(self.produces_back(Seq::empty(), self))]
225 fn produces_back_refl(self) {
226 let _ = Seq::<Self::Item>::reverse_empty();
227 let _ = Seq::<Self::Item>::concat_empty;
228 }
229
230 #[logic(law)]
231 #[requires(a.produces_back(ab, b))]
232 #[requires(b.produces_back(bc, c))]
233 #[ensures(a.produces_back(ab.concat(bc), c))]
234 fn produces_back_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
235 let _ = ab.reverse_concat(bc);
236 let _ = Seq::<Self::Item>::concat_assoc;
237 }
238
239 #[logic(law)]
240 #[requires(Self::size_hint.postcondition((self,), r))]
241 #[ensures(forall<s: Seq<Self::Item>, i: &mut Self>
242 self.produces_back(s, *i) && i.completed_back() ==> r.0@ <= s.len())]
243 #[ensures(match r.1 {
244 Some(r) => {
245 forall<s: Seq<Self::Item>, i: Self> self.produces_back(s, i) ==> s.len() <= r@
246 }
247 None => true
248 })]
249 fn size_hint_back_spec(&self, r: (usize, Option<usize>)) {}
250}
251
252#[cfg(not(feature = "nightly"))]
254mod impls {
255 use crate::{logic::ops::IndexLogic, prelude::*};
256 use std::collections::VecDeque;
257
258 impl<T> Resolve for VecDeque<T> {}
259 impl<T> Invariant for VecDeque<T> {}
260 impl<T> View for VecDeque<T> {
261 type ViewTy = Seq<T>;
262 }
263 impl<T: DeepModel> DeepModel for VecDeque<T> {
264 type DeepModelTy = Seq<T::DeepModelTy>;
265 }
266 impl<T> IndexLogic<Int> for VecDeque<T> {
267 type Item = T;
268 }
269 impl<T> IndexLogic<usize> for VecDeque<T> {
270 type Item = T;
271 }
272}