1#[cfg(feature = "nightly")]
2use crate::std::iter::ExactSizeIteratorSpec;
3#[cfg(creusot)]
4use crate::{invariant::inv, resolve::structural_resolve, std::slice::SliceIndexSpec};
5use crate::{logic::ops::IndexLogic, prelude::*};
6#[cfg(feature = "nightly")]
7use std::alloc::Allocator;
8#[cfg(creusot)]
9use std::ops::{Deref, DerefMut, Index, IndexMut};
10use std::vec::*;
11
12#[cfg(feature = "nightly")]
13impl<T, A: Allocator> View for Vec<T, A> {
14 type ViewTy = Seq<T>;
15
16 #[trusted]
17 #[logic(opaque)]
18 #[ensures(result.len() <= usize::MAX@)]
19 fn view(self) -> Seq<T> {
20 dead
21 }
22}
23
24#[cfg(feature = "nightly")]
25impl<T: DeepModel, A: Allocator> DeepModel for Vec<T, A> {
26 type DeepModelTy = Seq<T::DeepModelTy>;
27
28 #[trusted]
29 #[logic(opaque)]
30 #[ensures(self.view().len() == result.len())]
31 #[ensures(forall<i> 0 <= i && i < self.view().len()
32 ==> result[i] == self[i].deep_model())]
33 fn deep_model(self) -> Self::DeepModelTy {
34 dead
35 }
36}
37
38#[cfg(feature = "nightly")]
39impl<T, A: Allocator> IndexLogic<Int> for Vec<T, A> {
40 type Item = T;
41
42 #[logic(open, inline)]
43 fn index_logic(self, ix: Int) -> Self::Item {
44 pearlite! { self@[ix] }
45 }
46}
47
48#[cfg(feature = "nightly")]
49impl<T, A: Allocator> IndexLogic<usize> for Vec<T, A> {
50 type Item = T;
51
52 #[logic(open, inline)]
53 fn index_logic(self, ix: usize) -> Self::Item {
54 pearlite! { self@[ix@] }
55 }
56}
57
58#[cfg(not(feature = "nightly"))]
60impl<T> IndexLogic<Int> for Vec<T> {
61 type Item = T;
62}
63
64#[cfg(not(feature = "nightly"))]
65impl<T> IndexLogic<usize> for Vec<T> {
66 type Item = T;
67}
68
69#[cfg(feature = "nightly")]
70impl<T, A: Allocator> Resolve for Vec<T, A> {
71 #[logic(open, prophetic, inline)]
72 #[creusot::trusted_trivial_if_param_trivial]
73 fn resolve(self) -> bool {
74 pearlite! { forall<i> 0 <= i && i < self@.len() ==> resolve(self[i]) }
75 }
76
77 #[trusted]
78 #[logic(prophetic)]
79 #[requires(structural_resolve(self))]
80 #[ensures(self.resolve())]
81 fn resolve_coherence(self) {}
82}
83
84#[cfg(feature = "nightly")]
85impl<T, A: Allocator> Invariant for Vec<T, A> {
86 #[logic(open, prophetic)]
87 #[creusot::trusted_trivial_if_param_trivial]
88 fn invariant(self) -> bool {
89 pearlite! { inv(self@) }
90 }
91}
92
93extern_spec! {
94 mod std {
95 mod vec {
96 #[ensures(result@.len() == n@)]
97 #[ensures(forall<i> 0 <= i && i < n@ ==> result[i] == elem)]
98 fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T>;
99 }
100 }
101
102 impl<T> Vec<T> {
103 #[check(ghost)]
104 #[ensures(result@.len() == 0)]
105 fn new() -> Vec<T>;
106
107 #[check(terminates)] #[ensures(result@.len() == 0)]
109 fn with_capacity(capacity: usize) -> Vec<T>;
110 }
111
112 impl<T, A: Allocator> Vec<T, A> {
113 #[check(ghost)]
114 #[ensures(result@ == self@.len())]
115 fn len(&self) -> usize;
116
117 #[check(terminates)] #[ensures((^self)@ == self@.snoc(v))]
119 fn push(&mut self, v: T);
120
121 #[check(ghost)]
122 #[ensures(match result {
123 Some(t) =>
124 (^self)@ == self@.subsequence(0, self@.len() - 1) &&
125 self@ == (^self)@.snoc(t),
126 None => *self == ^self && self@.len() == 0
127 })]
128 fn pop(&mut self) -> Option<T>;
129
130 #[check(ghost)]
131 #[requires(ix@ < self@.len())]
132 #[ensures(result == self[ix@])]
133 #[ensures((^self)@ == self@.subsequence(0, ix@).concat(self@.subsequence(ix@ + 1, self@.len())))]
134 #[ensures((^self)@.len() == self@.len() - 1)]
135 fn remove(&mut self, ix: usize) -> T;
136
137 #[check(terminates)] #[ensures((^self)@.len() == self@.len() + 1)]
139 #[ensures(forall<i> 0 <= i && i < index@ ==> (^self)[i] == self[i])]
140 #[ensures((^self)[index@] == element)]
141 #[ensures(forall<i> index@ < i && i < (^self)@.len() ==> (^self)[i] == self[i - 1])]
142 fn insert(&mut self, index: usize, element: T);
143
144 #[check(ghost)]
145 #[ensures(result@ >= self@.len())]
146 fn capacity(&self) -> usize;
147
148 #[check(terminates)] #[ensures((^self)@ == self@)]
150 fn reserve(&mut self, additional: usize);
151
152 #[check(terminates)] #[ensures((^self)@ == self@)]
154 fn reserve_exact(&mut self, additional: usize);
155
156 #[check(ghost)]
157 #[ensures((^self)@ == self@)]
158 fn shrink_to_fit(&mut self);
159
160 #[check(ghost)]
161 #[ensures((^self)@ == self@)]
162 fn shrink_to(&mut self, min_capacity: usize);
163
164 #[check(ghost)]
165 #[ensures((^self)@.len() == 0)]
166 fn clear(&mut self);
167
168 #[check(ghost)]
169 #[ensures(result == (self@.len() == 0))]
170 fn is_empty(&self) -> bool;
171
172 #[check(ghost)]
173 #[ensures(result@ == self@)]
174 fn into_boxed_slice(self) -> Box<[T], A>;
175 }
176
177 impl<T, A: Allocator> Extend<T> for Vec<T, A> {
178 #[requires(I::into_iter.precondition((iter,)))]
179 #[ensures(exists<start_: I::IntoIter, done: &mut I::IntoIter, prod: Seq<T>>
180 inv(start_) && inv(done) && inv(prod) &&
181 I::into_iter.postcondition((iter,), start_) &&
182 done.completed() && start_.produces(prod, *done) && (^self)@ == self@.concat(prod)
183 )]
184 fn extend<I: IntoIterator<Item = T, IntoIter: IteratorSpec>>(&mut self, iter: I);
185 }
186
187 impl<T, I: SliceIndexSpec<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
188 #[check(ghost)]
189 #[requires(ix.in_bounds(self@))]
190 #[ensures(ix.has_value(self@, *result))]
191 #[ensures(ix.has_value((^self)@, ^result))]
192 #[ensures(ix.resolve_elswhere(self@, (^self)@))]
193 #[ensures((^self)@.len() == self@.len())]
194 fn index_mut(&mut self, ix: I) -> &mut <Vec<T, A> as Index<I>>::Output;
195 }
196
197 impl<T, I: SliceIndexSpec<[T]>, A: Allocator> Index<I> for Vec<T, A> {
198 #[check(ghost)]
199 #[requires(ix.in_bounds(self@))]
200 #[ensures(ix.has_value(self@, *result))]
201 fn index(&self, ix: I) -> & <Vec<T, A> as Index<I>>::Output;
202 }
203
204 impl<T, A: Allocator> Deref for Vec<T, A> {
205 #[check(ghost)]
206 #[ensures(result@ == self@)]
207 fn deref(&self) -> &[T];
208 }
209
210 impl<T, A: Allocator> DerefMut for Vec<T, A> {
211 #[check(ghost)]
212 #[ensures(result@ == self@)]
213 #[ensures((^self)@.len() == (*self)@.len())]
214 #[ensures((^result)@ == (^self)@)]
215 fn deref_mut(&mut self) -> &mut [T];
216 }
217
218 impl<T, A: Allocator> IntoIterator for Vec<T, A> {
219 #[check(ghost)]
220 #[ensures(self@ == result@)]
221 fn into_iter(self) -> IntoIter<T, A>;
222 }
223
224 impl<'a, T, A: Allocator> IntoIterator for &'a Vec<T, A> {
225 #[check(ghost)]
226 #[ensures(self@ == result@@)]
227 fn into_iter(self) -> core::slice::Iter<'a, T>;
228 }
229
230 impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec<T, A> {
231 #[check(ghost)]
232 #[ensures(self@ == result@@)]
233 #[ensures((^self)@ == (^result@)@)]
234 fn into_iter(self) -> core::slice::IterMut<'a, T>;
235 }
236
237 impl<T> Default for Vec<T> {
238 #[check(ghost)]
239 #[ensures(result@ == Seq::empty())]
240 fn default() -> Vec<T>;
241 }
242
243 impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
244 #[check(terminates)]
245 #[ensures(self@.len() == result@.len())]
246 #[ensures(forall<i> 0 <= i && i < self@.len() ==>
247 T::clone.postcondition((&self@[i],), result@[i]))]
248 fn clone(&self) -> Vec<T, A>;
249 }
250
251 impl<T> FromIterator<T> for Vec<T> {
252 #[requires(I::into_iter.precondition((iter,)))]
253 #[ensures(exists<into_iter: I::IntoIter, done: &mut I::IntoIter>
254 I::into_iter.postcondition((iter,), into_iter) &&
255 into_iter.produces(result@, *done) && done.completed() && resolve(^done))]
256 fn from_iter<I: IntoIterator<Item = T, IntoIter: IteratorSpec>>(iter: I) -> Self;
257 }
258}
259
260#[cfg(feature = "nightly")]
261impl<T, A: Allocator> View for IntoIter<T, A> {
262 type ViewTy = Seq<T>;
263
264 #[logic(opaque)]
265 fn view(self) -> Self::ViewTy {
266 dead
267 }
268}
269
270#[cfg(feature = "nightly")]
271impl<T, A: Allocator> Resolve for IntoIter<T, A> {
272 #[logic(open, prophetic, inline)]
273 fn resolve(self) -> bool {
274 pearlite! { forall<i> 0 <= i && i < self@.len() ==> resolve(self@[i]) }
275 }
276
277 #[trusted]
278 #[logic(prophetic)]
279 #[requires(structural_resolve(self))]
280 #[ensures(self.resolve())]
281 fn resolve_coherence(self) {}
282}
283
284#[cfg(feature = "nightly")]
285impl<T, A: Allocator> IteratorSpec for IntoIter<T, A> {
286 #[logic(open, prophetic)]
287 fn completed(&mut self) -> bool {
288 pearlite! { resolve(self) && self@ == Seq::empty() }
289 }
290
291 #[logic(open)]
292 fn produces(self, visited: Seq<T>, rhs: Self) -> bool {
293 pearlite! {
294 self@ == visited.concat(rhs@)
295 }
296 }
297
298 #[logic(law)]
299 #[ensures(self.produces(Seq::empty(), self))]
300 fn produces_refl(self) {
301 let _ = Seq::<T>::concat_empty;
302 }
303
304 #[logic(law)]
305 #[requires(a.produces(ab, b))]
306 #[requires(b.produces(bc, c))]
307 #[ensures(a.produces(ab.concat(bc), c))]
308 fn produces_trans(a: Self, ab: Seq<T>, b: Self, bc: Seq<T>, c: Self) {
309 let _ = Seq::<T>::concat_assoc;
310 }
311}
312
313extern_spec! {
314 impl<T, A: Allocator> Iterator for IntoIter<T, A> {
315 #[ensures(result.0@ == self@.len())]
316 #[ensures(result.1 == Some(result.0))]
317 fn size_hint(&self) -> (usize, Option<usize>);
318 }
319}
320
321#[cfg(feature = "nightly")]
322impl<T, A: Allocator> ExactSizeIteratorSpec for IntoIter<T, A> {
323 #[logic(law)]
324 #[requires(Self::size_hint.postcondition((self,), r))]
325 #[ensures(r.1 == Some(r.0))]
326 #[allow(unused_variables)]
327 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
328}
329
330#[cfg(feature = "nightly")]
331impl<T, A: Allocator> DoubleEndedIteratorSpec for IntoIter<T, A> {
332 #[logic(open)]
333 fn produces_back(self, visited: Seq<T>, rhs: Self) -> bool {
334 pearlite! {
335 self@ == rhs@.concat(visited.reverse())
336 }
337 }
338
339 #[logic(open, prophetic)]
340 fn completed_back(&mut self) -> bool {
341 self.completed()
342 }
343
344 #[logic(law)]
345 #[ensures(self.produces_back(Seq::empty(), self))]
346 fn produces_back_refl(self) {
347 let _ = Seq::<T>::reverse_empty();
348 let _ = Seq::<T>::concat_empty;
349 }
350
351 #[logic(law)]
352 #[requires(a.produces_back(ab, b))]
353 #[requires(b.produces_back(bc, c))]
354 #[ensures(a.produces_back(ab.concat(bc), c))]
355 fn produces_back_trans(a: Self, ab: Seq<T>, b: Self, bc: Seq<T>, c: Self) {
356 let _ = ab.reverse_concat(bc);
357 let _ = Seq::<T>::concat_assoc;
358 }
359
360 #[logic(law)]
361 #[requires(Self::size_hint.postcondition((self,), r))]
362 #[ensures(forall<s: Seq<Self::Item>, i: &mut Self>
363 self.produces_back(s, *i) && i.completed_back() ==> r.0@ <= s.len())]
364 #[ensures(match r.1 {
365 Some(r) => {
366 forall<s: Seq<Self::Item>, i: Self> self.produces_back(s, i) ==> s.len() <= r@
367 }
368 None => true
369 })]
370 fn size_hint_back_spec(&self, r: (usize, Option<usize>)) {}
371}
372
373#[cfg(not(feature = "nightly"))]
375mod impls {
376 use crate::{prelude::*, std::iter::ExactSizeIteratorSpec};
377 use std::vec::*;
378
379 impl<T> View for Vec<T> {
380 type ViewTy = Seq<T>;
381 }
382
383 impl<T: DeepModel> DeepModel for Vec<T> {
384 type DeepModelTy = Seq<T::DeepModelTy>;
385 }
386 impl<T> Resolve for Vec<T> {}
387 impl<T> Invariant for Vec<T> {}
388 impl<T> View for IntoIter<T> {
389 type ViewTy = Seq<T>;
390 }
391 impl<T> Resolve for IntoIter<T> {}
392 impl<T> IteratorSpec for IntoIter<T> {}
393 impl<T> ExactSizeIteratorSpec for IntoIter<T> {}
394}
395
396#[macro_export]
402macro_rules! vec {
403 () => (
404 ::std::vec::Vec::new()
405 );
406 ($elem:expr; $n:expr) => (
407 ::std::vec::from_elem($elem, $n)
408 );
409 ($($x:expr),*) => (
410 <[_]>::into_vec(::std::boxed::Box::new([$($x),*]))
411 );
412 ($($x:expr,)*) => (vec![$($x),*])
413}
414pub use vec;