1use super::super::prelude::*;
2use super::iter::{FromIteratorSpecImpl, IteratorSpec};
3use verus_builtin::*;
4
5use super::super::slice::SliceIndexSpec;
6use super::core::IndexSpec;
7use alloc::collections::TryReserveError;
8use alloc::vec::{IntoIter, Vec};
9use core::alloc::Allocator;
10use core::clone::Clone;
11use core::marker::PhantomData;
12use core::ops::Index;
13use core::option::Option;
14use core::option::Option::None;
15use core::slice::SliceIndex;
16
17use verus as verus_skip_verusfmt;
18verus_skip_verusfmt! {
19
20#[verifier::external_type_specification]
21#[verifier::external_body]
22#[verifier::accept_recursive_types(T)]
23#[verifier::reject_recursive_types(A)]
24pub struct ExVec<T, A: Allocator>(Vec<T, A>);
25
26pub trait VecAdditionalSpecFns<T>: View<V = Seq<T>> {
27 spec fn spec_index(&self, i: int) -> T
28 recommends
29 0 <= i < self.view().len(),
30 ;
31}
32
33impl<T, A: Allocator> VecAdditionalSpecFns<T> for Vec<T, A> {
34 #[verifier::inline]
35 open spec fn spec_index(&self, i: int) -> T {
36 self.view().index(i)
37 }
38}
39
40#[verifier::external_type_specification]
41#[verifier::external_body]
42pub struct ExTryReserveError(alloc::collections::TryReserveError);
43
44#[verifier::external_body]
52#[cfg_attr(verus_keep_ghost, rustc_diagnostic_item = "verus::vstd::std_specs::vec::vec_index")]
53pub fn vec_index<T, A: Allocator>(vec: &Vec<T, A>, i: usize) -> (element: &T)
54 requires
55 i < vec.view().len(),
56 ensures
57 *element == vec.view().index(i as int),
58 no_unwind
59{
60 &vec[i]
61}
62
63#[doc(hidden)]
65#[verifier::external_body]
66#[cfg_attr(verus_keep_ghost, rustc_diagnostic_item = "verus::vstd::std_specs::vec::vec_index_mut")]
67pub fn vec_index_mut<T, A: Allocator>(vec: &mut Vec<T, A>, i: usize) -> (element: &mut T)
68 requires
69 i < vec.view().len(),
70 ensures
71 *element == old(vec)@.index(i as int),
72 final(vec)@ == old(vec)@.update(i as int, *final(element)),
73
74 *final(element) == final(vec).view().index(i as int),
75 no_unwind
76{
77 &mut vec[i]
78}
79
80pub uninterp spec fn spec_vec_len<T, A: Allocator>(v: &Vec<T, A>) -> usize;
82
83pub broadcast proof fn axiom_spec_len<T, A: Allocator>(v: &Vec<T, A>)
86 ensures
87 #[trigger] spec_vec_len(v) == v@.len(),
88{
89 admit();
90}
91
92#[verifier::when_used_as_spec(spec_vec_len)]
93pub assume_specification<T, A: Allocator>[ Vec::<T, A>::len ](vec: &Vec<T, A>) -> (len: usize)
94 ensures
95 len == spec_vec_len(vec),
96 no_unwind
97;
98
99pub assume_specification<T>[ Vec::<T>::new ]() -> (v: Vec<T>)
101 ensures
102 v@ == Seq::<T>::empty(),
103;
104
105pub assume_specification<T>[ <Vec<T> as core::default::Default>::default ]() -> (v: Vec<T>)
106 ensures
107 v@ == Seq::<T>::empty(),
108;
109
110pub assume_specification<T, A: Allocator>[ Vec::<T, A>::new_in ](alloc: A) -> (v: Vec<T, A>)
111 ensures
112 v@ == Seq::<T>::empty(),
113;
114
115pub assume_specification<T>[ Vec::<T>::with_capacity ](capacity: usize) -> (v: Vec<T>)
116 ensures
117 v@ == Seq::<T>::empty(),
118;
119
120pub assume_specification<T, A: Allocator>[ Vec::<T, A>::with_capacity_in ](capacity: usize, alloc: A) -> (v: Vec<T, A>)
121 ensures
122 v@ == Seq::<T>::empty(),
123;
124
125pub assume_specification<T, A: Allocator>[ Vec::<T, A>::reserve ](
126 vec: &mut Vec<T, A>,
127 additional: usize,
128)
129 ensures
130 final(vec)@ == old(vec)@,
131;
132
133pub assume_specification<T, A: Allocator>[ Vec::<T, A>::try_reserve ](
134 vec: &mut Vec<T, A>,
135 additional: usize,
136) -> (result: Result<(), TryReserveError>)
137 ensures
138 final(vec)@ == old(vec)@,
139;
140
141pub assume_specification<T, A: Allocator>[ Vec::<T, A>::try_reserve_exact ](
142 vec: &mut Vec<T, A>,
143 additional: usize,
144) -> (result: Result<(), TryReserveError>)
145 ensures
146 final(vec)@ == old(vec)@,
147;
148
149pub assume_specification<T, A: Allocator>[ Vec::<T, A>::push ](vec: &mut Vec<T, A>, value: T)
150 ensures
151 final(vec)@ == old(vec)@.push(value),
152;
153
154pub assume_specification<T, A: Allocator>[ Vec::<T, A>::pop ](vec: &mut Vec<T, A>) -> (value:
155 Option<T>)
156 ensures
157 old(vec)@.len() > 0 ==> value == Some(old(vec)@[old(vec)@.len() - 1])
158 && final(vec)@ == old(vec)@[..old(vec)@.len() - 1],
159 old(vec)@.len() == 0 ==> value == None::<T> && final(vec)@ == old(vec)@,
160;
161
162pub assume_specification<T, A: Allocator>[ Vec::<T, A>::append ](
163 vec: &mut Vec<T, A>,
164 other: &mut Vec<T, A>,
165)
166 ensures
167 final(vec)@ == old(vec)@ + old(other)@,
168 final(other)@ == Seq::<T>::empty(),
169;
170
171pub assume_specification<T: core::clone::Clone, A: Allocator>[ Vec::<T, A>::extend_from_slice ](
172 vec: &mut Vec<T, A>,
173 other: &[T],
174)
175 ensures
176 final(vec)@.len() == old(vec)@.len() + other@.len(),
177 forall|i: int|
178 #![trigger final(vec)@[i]]
179 0 <= i < final(vec)@.len() ==> if i < old(vec)@.len() {
180 final(vec)@[i] == old(vec)@[i]
181 } else {
182 cloned::<T>(other@[i - old(vec)@.len()], final(vec)@[i])
183 },
184;
185
186impl<T: Sized, I: SliceIndex<[T]>, A: Allocator> super::core::IndexSpecImpl<I> for Vec<T, A> {
187 open spec fn index_req(&self, index: &I) -> bool {
188 forall|s: &[T]| #[trigger] s@ == self@ ==> index.in_bounds(s)
189 }
190}
191
192pub assume_specification<T, I: SliceIndex<[T]>, A: Allocator>[Vec::<T, A>::index](
193 vec: &Vec<T, A>,
194 i: I,
195) -> (r: &<Vec<T, A> as Index<I>>::Output)
196 ensures
197 exists|s: &[T]| #[trigger] s@ == vec@ && call_ensures(<I as SliceIndex<[T]>>::index, (i, s), r),
198;
199
200pub assume_specification<T, A: Allocator>[ Vec::<T, A>::swap_remove ](
201 vec: &mut Vec<T, A>,
202 i: usize,
203) -> (element: T)
204 requires
205 i < old(vec).len(),
206 ensures
207 element == old(vec)[i as int],
208 final(vec)@ == old(vec)@.update(i as int, old(vec)@.last()).drop_last(),
209;
210
211pub assume_specification<T, A: Allocator>[ Vec::<T, A>::insert ](
212 vec: &mut Vec<T, A>,
213 i: usize,
214 element: T,
215)
216 requires
217 i <= old(vec).len(),
218 ensures
219 final(vec)@ == old(vec)@.insert(i as int, element),
220;
221
222pub assume_specification<T, A: Allocator> [ <Vec<T, A>>::is_empty ](
223 v: &Vec<T, A>,
224) -> (res: bool)
225 ensures res <==> v@.len() == 0,
226 opens_invariants none
227 no_unwind
228;
229
230pub assume_specification<T, A: Allocator>[ Vec::<T, A>::remove ](
231 vec: &mut Vec<T, A>,
232 i: usize,
233) -> (element: T)
234 requires
235 i < old(vec).len(),
236 ensures
237 element == old(vec)[i as int],
238 final(vec)@ == old(vec)@.remove(i as int),
239;
240
241pub assume_specification<T, A: Allocator>[ Vec::<T, A>::clear ](vec: &mut Vec<T, A>)
242 ensures
243 final(vec).view() == Seq::<T>::empty(),
244;
245
246pub assume_specification<T, A: Allocator>[ Vec::<T, A>::as_slice ](vec: &Vec<T, A>) -> (slice: &[T])
247 ensures
248 slice@ == vec@,
249 opens_invariants none
250 no_unwind
251;
252
253#[doc(hidden)]
254pub assume_specification<T, A: Allocator>[ Vec::<T, A>::as_mut_slice ](vec: &mut Vec<T, A>) -> (slice: &mut [T])
255 ensures
256 slice@ == old(vec)@,
257 final(slice)@ == final(vec)@,
258 opens_invariants none
259 no_unwind
260;
261
262pub assume_specification<T, A: Allocator>[ <Vec<T, A> as core::ops::Deref>::deref ](
263 vec: &Vec<T, A>,
264) -> (slice: &[T])
265 ensures
266 slice@ == vec@,
267;
268
269pub assume_specification<T, A: Allocator>[ <Vec<T, A> as core::ops::DerefMut>::deref_mut ](
270 vec: &mut Vec<T, A>,
271) -> (slice: &mut [T])
272 ensures
273 slice@ == old(vec)@,
274 final(slice)@ == final(vec)@,
275;
276
277pub assume_specification<T, A: Allocator + core::clone::Clone>[ Vec::<T, A>::split_off ](
278 vec: &mut Vec<T, A>,
279 at: usize,
280) -> (return_value: Vec<T, A>)
281 requires
282 at <= old(vec)@.len(),
283 ensures
284 final(vec)@ == old(vec)@[..at],
285 return_value@ == old(vec)@[at..],
286;
287
288pub open spec fn vec_clone_trigger<T, A: Allocator>(v1: Vec<T, A>, v2: Vec<T, A>) -> bool {
289 true
290}
291
292pub assume_specification<T: Clone, A: Allocator + Clone>[ <Vec<T, A> as Clone>::clone ](
293 vec: &Vec<T, A>,
294) -> (res: Vec<T, A>)
295 ensures
296 res.len() == vec.len(),
297 forall|i| #![all_triggers] 0 <= i < vec.len() ==> cloned::<T>(vec[i], res[i]),
298 vec_clone_trigger(*vec, res),
299 vec@ =~= res@ ==> vec@ == res@,
300;
301
302pub broadcast proof fn vec_clone_deep_view_proof<T: DeepView, A: Allocator>(
303 v1: Vec<T, A>,
304 v2: Vec<T, A>,
305)
306 requires
307 #[trigger] vec_clone_trigger(v1, v2),
308 v1.deep_view() =~= v2.deep_view(),
309 ensures
310 v1.deep_view() == v2.deep_view(),
311{
312}
313
314pub assume_specification<T, A: Allocator>[ Vec::<T, A>::truncate ](vec: &mut Vec<T, A>, len: usize)
315 ensures
316 len <= old(vec).len() ==> final(vec)@ == old(vec)@[..len],
317 len > old(vec).len() ==> final(vec)@ == old(vec)@,
318;
319
320pub assume_specification<T: Clone, A: Allocator>[ Vec::<T, A>::resize ](
321 vec: &mut Vec<T, A>,
322 len: usize,
323 value: T,
324)
325 ensures
326 len <= old(vec).len() ==> final(vec)@ == old(vec)@[..len],
327 len > old(vec).len() ==> {
328 &&& final(vec)@.len() == len
329 &&& final(vec)@[..old(vec).len()] == old(vec)@
330 &&& forall|i| #![all_triggers] old(vec).len() <= i < len ==> cloned::<T>(value, final(vec)@[i])
331 },
332;
333
334pub broadcast proof fn axiom_vec_index_decreases<A>(v: Vec<A>, i: int)
335 requires
336 0 <= i < v.len(),
337 ensures
338 #[trigger] (decreases_to!(v => v[i])),
339{
340 admit();
341}
342
343pub assume_specification<T: PartialEq<U>, U, A1: Allocator, A2: Allocator>[ <Vec<T, A1> as PartialEq<Vec<U, A2>>>::eq ](
344 x: &Vec<T, A1>,
345 y: &Vec<U, A2>,
346) -> bool
347;
348
349impl<T: super::cmp::PartialEqSpec<U>, U, A1: Allocator, A2: Allocator> super::cmp::PartialEqSpecImpl<Vec<U, A2>> for Vec<T, A1> {
350 open spec fn obeys_eq_spec() -> bool {
351 T::obeys_eq_spec()
352 }
353
354 open spec fn eq_spec(&self, other: &Vec<U, A2>) -> bool {
355 &&& self.len() == other.len()
356 &&& forall|i: int| #![auto] 0 <= i < self.len() ==> self[i].eq_spec(&other[i])
357 }
358}
359
360#[verifier::external_type_specification]
363#[verifier::external_body]
364#[verifier::accept_recursive_types(T)]
365#[verifier::reject_recursive_types(A)]
366pub struct ExIntoIter<T, A: Allocator>(IntoIter<T, A>);
367
368pub uninterp spec fn into_iter_elts<T, A: Allocator>(i: IntoIter<T, A>) -> Seq<T>;
371
372impl <T, A: Allocator> super::iter::IteratorSpecImpl for IntoIter<T, A> {
373 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
374 true
375 }
376
377 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
378 uninterp spec fn will_return_none(&self) -> bool;
379 uninterp spec fn decrease(&self) -> Option<nat>;
380
381 open spec fn peek(&self, index: int) -> Option<Self::Item> {
382 if 0 <= index < into_iter_elts(*self).len() {
383 Some(into_iter_elts(*self)[index])
384 } else {
385 None
386 }
387 }
388}
389
390impl <T, A: Allocator> super::iter::DoubleEndedIteratorSpecImpl for IntoIter<T, A> {
391 open spec fn peek_back(&self, index: int) -> Option<Self::Item> {
392 let len = into_iter_elts(*self).len();
393 if 0 <= index < len {
394 Some(into_iter_elts(*self)[len - index - 1])
395 } else {
396 None
397 }
398 }
399}
400
401pub assume_specification<T: Clone>[ alloc::vec::from_elem ](elem: T, n: usize) -> (v: Vec<T>)
403 ensures
404 v.len() == n,
405 forall |i| 0 <= i < n ==> cloned(elem, #[trigger] v@[i]);
406
407pub assume_specification<T, A: Allocator>[ Vec::<T, A>::into_iter ](vec: Vec<T, A>) -> (iter: <Vec<
408 T,
409 A,
410> as core::iter::IntoIterator>::IntoIter)
411 ensures
412 IteratorSpec::remaining(&iter) == vec@,
413 into_iter_elts(iter) == IteratorSpec::remaining(&iter),
414 IteratorSpec::decrease(&iter) is Some,
415;
416
417pub assume_specification<'a, T, A: Allocator> [<&'a Vec<T, A> as core::iter::IntoIterator>::into_iter] (vec: &'a Vec<T, A>) ->
418 (iter: <&'a Vec<T, A> as core::iter::IntoIterator>::IntoIter)
419 ensures
420 IteratorSpec::remaining(&iter) == vec@.as_ref(),
421 super::slice::into_iter_elts(iter) == IteratorSpec::remaining(&iter).unref(),
422 IteratorSpec::decrease(&iter) is Some,
423;
424
425impl<T> FromIteratorSpecImpl<T> for Vec<T> {
426 open spec fn from_iter_ensures(remaining: Seq<T>, s: Self) -> bool {
427 remaining == s@
428 }
429}
430
431pub broadcast proof fn lemma_vec_obeys_eq_spec<T: PartialEq>()
432 requires
433 super::super::laws_eq::obeys_eq::<T>(),
434 ensures
435 #[trigger] super::super::laws_eq::obeys_eq::<Vec<T>>(),
436{
437 broadcast use {axiom_spec_len, super::super::seq::group_seq_lemmas};
438 reveal(super::super::laws_eq::obeys_eq_spec_properties);
439}
440
441pub broadcast proof fn lemma_vec_obeys_view_eq<T: PartialEq + View>()
442 requires
443 super::super::laws_eq::obeys_concrete_eq::<T>(),
444 ensures
445 #[trigger] super::super::laws_eq::obeys_view_eq::<Vec<T>>(),
446{
447 use super::cmp::PartialEqSpec;
448 broadcast use {axiom_spec_len, super::super::seq::group_seq_lemmas};
449 reveal(super::super::laws_eq::obeys_eq_spec_properties);
450 reveal(super::super::laws_eq::obeys_concrete_eq);
451 reveal(super::super::laws_eq::obeys_view_eq);
452 assert(forall|x: Vec<T>, y: Vec<T>| x.eq_spec(&y) ==> x@ == y@);
453}
454
455pub broadcast proof fn lemma_vec_obeys_deep_eq<T: PartialEq + DeepView>()
456 requires
457 super::super::laws_eq::obeys_deep_eq::<T>(),
458 ensures
459 #[trigger] super::super::laws_eq::obeys_deep_eq::<Vec<T>>(),
460{
461 use super::cmp::PartialEqSpec;
462 broadcast use {axiom_spec_len, super::super::seq::group_seq_lemmas};
463 reveal(super::super::laws_eq::obeys_eq_spec_properties);
464 reveal(super::super::laws_eq::obeys_deep_eq);
465 assert(forall|x: Vec<T>, y: Vec<T>| x.eq_spec(&y) ==> x.deep_view() == y.deep_view());
466 assert forall|x: Vec<T>, y: Vec<T>| x.deep_view() == y.deep_view() implies x.eq_spec(&y) by {
467 assert(x.deep_view().len() == y.deep_view().len());
468 assert forall|i: int| #![auto] 0 <= i < x.len() implies x[i].eq_spec(&y[i]) by {
469 assert(x.deep_view()[i] == y.deep_view()[i]);
470 }
471 }
472}
473
474pub broadcast axiom fn axiom_vec_has_resolved<T>(vec: Vec<T>, i: int)
475 ensures
476 0 <= i < vec.len() ==> #[trigger] has_resolved::<Vec<T>>(vec) ==> has_resolved(
477 #[trigger] vec@[i],
478 ),
479;
480
481pub broadcast axiom fn axiom_vec_decreases_to_view<T>(v: Vec<T>)
482 ensures
483 #[trigger] (decreases_to!(v => v@));
484
485pub broadcast group group_vec_axioms {
486 axiom_spec_len,
487 axiom_vec_index_decreases,
488 vec_clone_deep_view_proof,
489 axiom_vec_has_resolved,
490 axiom_vec_decreases_to_view,
491}
492
493pub axiom fn tracked_borrow_slice<T, A: Allocator>(tracked vec: &Vec<T, A>) -> (tracked t: &[T])
494 ensures t@ == vec@;
495
496pub axiom fn tracked_borrow_mut_slice<T, A: Allocator>(tracked vec: &mut Vec<T, A>) -> (tracked t: &mut [T])
497 ensures
498 (*t)@ == old(vec)@,
499 (*t).len() == final(t).len(),
500 final(vec)@ == final(t)@;
501
502}