1use super::super::prelude::*;
2use verus_builtin::*;
3
4use alloc::collections::TryReserveError;
5use alloc::vec::{IntoIter, Vec};
6use core::alloc::Allocator;
7use core::clone::Clone;
8use core::marker::PhantomData;
9use core::option::Option;
10use core::option::Option::None;
11
12use verus as verus_;
13verus_! {
14
15#[verifier::external_type_specification]
16#[verifier::external_body]
17#[verifier::accept_recursive_types(T)]
18#[verifier::reject_recursive_types(A)]
19pub struct ExVec<T, A: Allocator>(Vec<T, A>);
20
21pub trait VecAdditionalSpecFns<T>: View<V = Seq<T>> {
22 spec fn spec_index(&self, i: int) -> T
23 recommends
24 0 <= i < self.view().len(),
25 ;
26}
27
28impl<T, A: Allocator> VecAdditionalSpecFns<T> for Vec<T, A> {
29 #[verifier::inline]
30 open spec fn spec_index(&self, i: int) -> T {
31 self.view().index(i)
32 }
33}
34
35#[verifier::external_type_specification]
36#[verifier::external_body]
37pub struct ExTryReserveError(alloc::collections::TryReserveError);
38
39#[verifier::external_body]
50#[cfg_attr(verus_keep_ghost, rustc_diagnostic_item = "verus::vstd::std_specs::vec::vec_index")]
51pub fn vec_index<T, A: Allocator>(vec: &Vec<T, A>, i: usize) -> (element: &T)
52 requires
53 i < vec.view().len(),
54 ensures
55 *element == vec.view().index(i as int),
56 no_unwind
57{
58 &vec[i]
59}
60
61#[doc(hidden)]
63#[verifier::ignore_outside_new_mut_ref_experiment]
64#[verifier::external_body]
65#[cfg_attr(verus_keep_ghost, rustc_diagnostic_item = "verus::vstd::std_specs::vec::vec_index_mut")]
66pub fn vec_index_mut<T, A: Allocator>(vec: &mut Vec<T, A>, i: usize) -> (element: &mut T)
67 requires
68 i < vec.view().len(),
69 ensures
70 *element == (*vec).view().index(i as int),
71 fin(vec)@ == vec@.update(i as int, *fin(element)),
72
73 *fin(element) == fin(vec).view().index(i as int),
74 no_unwind
75{
76 &mut vec[i]
77}
78
79pub uninterp spec fn spec_vec_len<T, A: Allocator>(v: &Vec<T, A>) -> usize;
81
82pub broadcast proof fn axiom_spec_len<T, A: Allocator>(v: &Vec<T, A>)
85 ensures
86 #[trigger] spec_vec_len(v) == v@.len(),
87{
88 admit();
89}
90
91#[verifier::when_used_as_spec(spec_vec_len)]
92pub assume_specification<T, A: Allocator>[ Vec::<T, A>::len ](vec: &Vec<T, A>) -> (len: usize)
93 ensures
94 len == spec_vec_len(vec),
95 no_unwind
96;
97
98pub assume_specification<T>[ Vec::<T>::new ]() -> (v: Vec<T>)
100 ensures
101 v@ == Seq::<T>::empty(),
102;
103
104pub assume_specification<T, A: Allocator>[ Vec::<T, A>::new_in ](alloc: A) -> (v: Vec<T, A>)
105 ensures
106 v@ == Seq::<T>::empty(),
107;
108
109pub assume_specification<T>[ Vec::<T>::with_capacity ](capacity: usize) -> (v: Vec<T>)
110 ensures
111 v@ == Seq::<T>::empty(),
112;
113
114pub assume_specification<T, A: Allocator>[ Vec::<T, A>::with_capacity_in ](capacity: usize, alloc: A) -> (v: Vec<T, A>)
115 ensures
116 v@ == Seq::<T>::empty(),
117;
118
119pub assume_specification<T, A: Allocator>[ Vec::<T, A>::reserve ](
120 vec: &mut Vec<T, A>,
121 additional: usize,
122)
123 ensures
124 vec@ == old(vec)@,
125;
126
127pub assume_specification<T, A: Allocator>[ Vec::<T, A>::try_reserve ](
128 vec: &mut Vec<T, A>,
129 additional: usize,
130) -> (result: Result<(), TryReserveError>)
131 ensures
132 vec@ == old(vec)@,
133;
134
135pub assume_specification<T, A: Allocator>[ Vec::<T, A>::push ](vec: &mut Vec<T, A>, value: T)
136 ensures
137 vec@ == old(vec)@.push(value),
138;
139
140pub assume_specification<T, A: Allocator>[ Vec::<T, A>::pop ](vec: &mut Vec<T, A>) -> (value:
141 Option<T>)
142 ensures
143 old(vec)@.len() > 0 ==> value == Some(old(vec)@[old(vec)@.len() - 1]) && vec@ == old(
144 vec,
145 )@.subrange(0, old(vec)@.len() - 1),
146 old(vec)@.len() == 0 ==> value == None::<T> && vec@ == old(vec)@,
147;
148
149pub assume_specification<T, A: Allocator>[ Vec::<T, A>::append ](
150 vec: &mut Vec<T, A>,
151 other: &mut Vec<T, A>,
152)
153 ensures
154 vec@ == old(vec)@ + old(other)@,
155 other@ == Seq::<T>::empty(),
156;
157
158pub assume_specification<T: core::clone::Clone, A: Allocator>[ Vec::<T, A>::extend_from_slice ](
159 vec: &mut Vec<T, A>,
160 other: &[T],
161)
162 ensures
163 vec@.len() == old(vec)@.len() + other@.len(),
164 forall|i: int|
165 #![trigger vec@[i]]
166 0 <= i < vec@.len() ==> if i < old(vec)@.len() {
167 vec@[i] == old(vec)@[i]
168 } else {
169 cloned::<T>(other@[i - old(vec)@.len()], vec@[i])
170 },
171;
172
173pub assume_specification<T, A: Allocator>[ Vec::<T, A>::swap_remove ](
186 vec: &mut Vec<T, A>,
187 i: usize,
188) -> (element: T)
189 requires
190 i < old(vec).len(),
191 ensures
192 element == old(vec)[i as int],
193 vec@ == old(vec)@.update(i as int, old(vec)@.last()).drop_last(),
194;
195
196pub assume_specification<T, A: Allocator>[ Vec::<T, A>::insert ](
197 vec: &mut Vec<T, A>,
198 i: usize,
199 element: T,
200)
201 requires
202 i <= old(vec).len(),
203 ensures
204 vec@ == old(vec)@.insert(i as int, element),
205;
206
207pub assume_specification<T, A: Allocator> [ <Vec<T, A>>::is_empty ](
208 v: &Vec<T, A>,
209) -> (res: bool)
210 ensures res <==> v@.len() == 0,
211;
212
213pub assume_specification<T, A: Allocator>[ Vec::<T, A>::remove ](
214 vec: &mut Vec<T, A>,
215 i: usize,
216) -> (element: T)
217 requires
218 i < old(vec).len(),
219 ensures
220 element == old(vec)[i as int],
221 vec@ == old(vec)@.remove(i as int),
222;
223
224pub assume_specification<T, A: Allocator>[ Vec::<T, A>::clear ](vec: &mut Vec<T, A>)
225 ensures
226 vec.view() == Seq::<T>::empty(),
227;
228
229pub assume_specification<T, A: Allocator>[ Vec::<T, A>::as_slice ](vec: &Vec<T, A>) -> (slice: &[T])
230 ensures
231 slice@ == vec@,
232;
233
234#[doc(hidden)]
235#[verifier::ignore_outside_new_mut_ref_experiment]
236pub assume_specification<T, A: Allocator>[ Vec::<T, A>::as_mut_slice ](vec: &mut Vec<T, A>) -> (slice: &mut [T])
237 ensures
238 slice@ == vec@,
239 fin(slice)@ == fin(vec)@,
240;
241
242pub assume_specification<T, A: Allocator>[ <Vec<T, A> as core::ops::Deref>::deref ](
243 vec: &Vec<T, A>,
244) -> (slice: &[T])
245 ensures
246 slice@ == vec@,
247;
248
249pub assume_specification<T, A: Allocator + core::clone::Clone>[ Vec::<T, A>::split_off ](
250 vec: &mut Vec<T, A>,
251 at: usize,
252) -> (return_value: Vec<T, A>)
253 requires
254 at <= old(vec)@.len(),
255 ensures
256 vec@ == old(vec)@.subrange(0, at as int),
257 return_value@ == old(vec)@.subrange(at as int, old(vec)@.len() as int),
258;
259
260pub open spec fn vec_clone_trigger<T, A: Allocator>(v1: Vec<T, A>, v2: Vec<T, A>) -> bool {
261 true
262}
263
264pub assume_specification<T: Clone, A: Allocator + Clone>[ <Vec<T, A> as Clone>::clone ](
265 vec: &Vec<T, A>,
266) -> (res: Vec<T, A>)
267 ensures
268 res.len() == vec.len(),
269 forall|i| #![all_triggers] 0 <= i < vec.len() ==> cloned::<T>(vec[i], res[i]),
270 vec_clone_trigger(*vec, res),
271 vec@ =~= res@ ==> vec@ == res@,
272;
273
274pub broadcast proof fn vec_clone_deep_view_proof<T: DeepView, A: Allocator>(
275 v1: Vec<T, A>,
276 v2: Vec<T, A>,
277)
278 requires
279 #[trigger] vec_clone_trigger(v1, v2),
280 v1.deep_view() =~= v2.deep_view(),
281 ensures
282 v1.deep_view() == v2.deep_view(),
283{
284}
285
286pub assume_specification<T, A: Allocator>[ Vec::<T, A>::truncate ](vec: &mut Vec<T, A>, len: usize)
287 ensures
288 len <= old(vec).len() ==> vec@ == old(vec)@.subrange(0, len as int),
289 len > old(vec).len() ==> vec@ == old(vec)@,
290;
291
292pub assume_specification<T: Clone, A: Allocator>[ Vec::<T, A>::resize ](
293 vec: &mut Vec<T, A>,
294 len: usize,
295 value: T,
296)
297 ensures
298 len <= old(vec).len() ==> vec@ == old(vec)@.subrange(0, len as int),
299 len > old(vec).len() ==> {
300 &&& vec@.len() == len
301 &&& vec@.subrange(0, old(vec).len() as int) == old(vec)@
302 &&& forall|i| #![all_triggers] old(vec).len() <= i < len ==> cloned::<T>(value, vec@[i])
303 },
304;
305
306pub broadcast proof fn axiom_vec_index_decreases<A>(v: Vec<A>, i: int)
307 requires
308 0 <= i < v.len(),
309 ensures
310 #[trigger] (decreases_to!(v => v[i])),
311{
312 admit();
313}
314
315impl<T, A: Allocator> super::core::TrustedSpecSealed for Vec<T, A> {
316
317}
318
319impl<T, A: Allocator> super::core::IndexSetTrustedSpec<usize> for Vec<T, A> {
320 open spec fn spec_index_set_requires(&self, index: usize) -> bool {
321 0 <= index < self.len()
322 }
323
324 open spec fn spec_index_set_ensures(&self, new_container: &Self, index: usize, val: T) -> bool {
325 new_container@ === self@.update(index as int, val)
326 }
327}
328
329pub assume_specification<T: PartialEq<U>, U, A1: Allocator, A2: Allocator>[ <Vec<T, A1> as PartialEq<Vec<U, A2>>>::eq ](
330 x: &Vec<T, A1>,
331 y: &Vec<U, A2>,
332) -> bool
333;
334
335impl<T: super::cmp::PartialEqSpec<U>, U, A1: Allocator, A2: Allocator> super::cmp::PartialEqSpecImpl<Vec<U, A2>> for Vec<T, A1> {
336 open spec fn obeys_eq_spec() -> bool {
337 T::obeys_eq_spec()
338 }
339
340 open spec fn eq_spec(&self, other: &Vec<U, A2>) -> bool {
341 &&& self.len() == other.len()
342 &&& forall|i: int| #![auto] 0 <= i < self.len() ==> self[i].eq_spec(&other[i])
343 }
344}
345
346#[verifier::external_type_specification]
349#[verifier::external_body]
350#[verifier::accept_recursive_types(T)]
351#[verifier::reject_recursive_types(A)]
352pub struct ExIntoIter<T, A: Allocator>(IntoIter<T, A>);
353
354impl<T, A: Allocator> View for IntoIter<T, A> {
355 type V = (int, Seq<T>);
356
357 uninterp spec fn view(self: &IntoIter<T, A>) -> (int, Seq<T>);
358}
359
360pub assume_specification<T, A: Allocator>[ IntoIter::<T, A>::next ](
361 elements: &mut IntoIter<T, A>,
362) -> (r: Option<T>)
363 ensures
364 ({
365 let (old_index, old_seq) = old(elements)@;
366 match r {
367 None => {
368 &&& elements@ == old(elements)@
369 &&& old_index >= old_seq.len()
370 },
371 Some(element) => {
372 let (new_index, new_seq) = elements@;
373 &&& 0 <= old_index < old_seq.len()
374 &&& new_seq == old_seq
375 &&& new_index == old_index + 1
376 &&& element == old_seq[old_index]
377 },
378 }
379 }),
380;
381
382pub struct IntoIterGhostIterator<T, A: Allocator> {
383 pub pos: int,
384 pub elements: Seq<T>,
385 pub _marker: PhantomData<A>,
386}
387
388impl<T, A: Allocator> super::super::pervasive::ForLoopGhostIteratorNew for IntoIter<T, A> {
389 type GhostIter = IntoIterGhostIterator<T, A>;
390
391 open spec fn ghost_iter(&self) -> IntoIterGhostIterator<T, A> {
392 IntoIterGhostIterator { pos: self@.0, elements: self@.1, _marker: PhantomData }
393 }
394}
395
396pub assume_specification<T: Clone>[ alloc::vec::from_elem ](elem: T, n: usize) -> (v: Vec<T>)
398 ensures
399 v.len() == n,
400 forall |i| 0 <= i < n ==> cloned(elem, #[trigger] v@[i]);
401
402impl<T, A: Allocator> super::super::pervasive::ForLoopGhostIterator for IntoIterGhostIterator<
403 T,
404 A,
405> {
406 type ExecIter = IntoIter<T, A>;
407
408 type Item = T;
409
410 type Decrease = int;
411
412 open spec fn exec_invariant(&self, exec_iter: &IntoIter<T, A>) -> bool {
413 &&& self.pos == exec_iter@.0
414 &&& self.elements == exec_iter@.1
415 }
416
417 open spec fn ghost_invariant(&self, init: Option<&Self>) -> bool {
418 init matches Some(init) ==> {
419 &&& init.pos == 0
420 &&& init.elements == self.elements
421 &&& 0 <= self.pos <= self.elements.len()
422 }
423 }
424
425 open spec fn ghost_ensures(&self) -> bool {
426 self.pos == self.elements.len()
427 }
428
429 open spec fn ghost_decrease(&self) -> Option<int> {
430 Some(self.elements.len() - self.pos)
431 }
432
433 open spec fn ghost_peek_next(&self) -> Option<T> {
434 if 0 <= self.pos < self.elements.len() {
435 Some(self.elements[self.pos])
436 } else {
437 None
438 }
439 }
440
441 open spec fn ghost_advance(&self, _exec_iter: &IntoIter<T, A>) -> IntoIterGhostIterator<T, A> {
442 Self { pos: self.pos + 1, ..*self }
443 }
444}
445
446impl<T, A: Allocator> View for IntoIterGhostIterator<T, A> {
447 type V = Seq<T>;
448
449 open spec fn view(&self) -> Seq<T> {
450 self.elements.take(self.pos)
451 }
452}
453
454pub uninterp spec fn spec_into_iter<T, A: Allocator>(v: Vec<T, A>) -> (iter: <Vec<
461 T,
462 A,
463> as core::iter::IntoIterator>::IntoIter);
464
465pub broadcast proof fn axiom_spec_into_iter<T, A: Allocator>(v: Vec<T, A>)
466 ensures
467 (#[trigger] spec_into_iter(v))@ == (0int, v@),
468{
469 admit();
470}
471
472#[verifier::when_used_as_spec(spec_into_iter)]
473pub assume_specification<T, A: Allocator>[ Vec::<T, A>::into_iter ](vec: Vec<T, A>) -> (iter: <Vec<
474 T,
475 A,
476> as core::iter::IntoIterator>::IntoIter)
477 ensures
478 iter@ == (0int, vec@),
479;
480
481pub broadcast proof fn lemma_vec_obeys_eq_spec<T: PartialEq>()
482 requires
483 super::super::laws_eq::obeys_eq_spec::<T>(),
484 ensures
485 #[trigger] super::super::laws_eq::obeys_eq_spec::<Vec<T>>(),
486{
487 broadcast use {axiom_spec_len, super::super::seq::group_seq_axioms};
488 reveal(super::super::laws_eq::obeys_eq_spec_properties);
489}
490
491pub broadcast proof fn lemma_vec_obeys_view_eq<T: PartialEq + View>()
492 requires
493 super::super::laws_eq::obeys_concrete_eq::<T>(),
494 ensures
495 #[trigger] super::super::laws_eq::obeys_view_eq::<Vec<T>>(),
496{
497 use super::cmp::PartialEqSpec;
498 broadcast use {axiom_spec_len, super::super::seq::group_seq_axioms};
499 reveal(super::super::laws_eq::obeys_eq_spec_properties);
500 reveal(super::super::laws_eq::obeys_concrete_eq);
501 reveal(super::super::laws_eq::obeys_view_eq);
502 assert(forall|x: Vec<T>, y: Vec<T>| x.eq_spec(&y) ==> x@ == y@);
503}
504
505pub broadcast proof fn lemma_vec_obeys_deep_eq<T: PartialEq + DeepView>()
506 requires
507 super::super::laws_eq::obeys_deep_eq::<T>(),
508 ensures
509 #[trigger] super::super::laws_eq::obeys_deep_eq::<Vec<T>>(),
510{
511 use super::cmp::PartialEqSpec;
512 broadcast use {axiom_spec_len, super::super::seq::group_seq_axioms};
513 reveal(super::super::laws_eq::obeys_eq_spec_properties);
514 reveal(super::super::laws_eq::obeys_deep_eq);
515 assert(forall|x: Vec<T>, y: Vec<T>| x.eq_spec(&y) ==> x.deep_view() == y.deep_view());
516 assert forall|x: Vec<T>, y: Vec<T>| x.deep_view() == y.deep_view() implies x.eq_spec(&y) by {
517 assert(x.deep_view().len() == y.deep_view().len());
518 assert forall|i: int| #![auto] 0 <= i < x.len() implies x[i].eq_spec(&y[i]) by {
519 assert(x.deep_view()[i] == y.deep_view()[i]);
520 }
521 }
522}
523
524pub broadcast axiom fn axiom_vec_has_resolved<T>(vec: Vec<T>, i: int)
525 ensures
526 0 <= i < vec.len() ==> #[trigger] has_resolved::<Vec<T>>(vec) ==> has_resolved(
527 #[trigger] vec@[i],
528 ),
529;
530
531pub broadcast group group_vec_axioms {
532 axiom_spec_len,
533 axiom_vec_index_decreases,
534 vec_clone_deep_view_proof,
535 axiom_spec_into_iter,
536 axiom_vec_has_resolved,
537}
538
539}