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