Skip to content

Commit bc667c0

Browse files
author
Ubuntu
committed
vstd: add core Vec contracts
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 37c58501-5f9f-4a00-b559-69d47c22f399
1 parent 11eda20 commit bc667c0

1 file changed

Lines changed: 88 additions & 1 deletion

File tree

source/vstd/std_specs/vec.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ use verus_builtin::*;
44

55
use super::super::slice::SliceIndexSpec;
66
use super::core::IndexSpec;
7+
use alloc::boxed::Box;
78
use alloc::collections::TryReserveError;
89
use alloc::vec::{IntoIter, Vec};
910
use core::alloc::Allocator;
1011
use core::clone::Clone;
1112
use core::marker::PhantomData;
12-
use core::ops::Index;
13+
use core::ops::{FnMut, Index};
1314
use core::option::Option;
1415
use core::option::Option::None;
1516
use core::slice::SliceIndex;
@@ -476,4 +477,90 @@ pub broadcast group group_vec_axioms {
476477
axiom_vec_decreases_to_view,
477478
}
478479

480+
pub trait CapacitySpec {
481+
spec fn spec_capacity(&self) -> nat;
482+
}
483+
484+
impl<T, A: Allocator> CapacitySpec for Vec<T, A> {
485+
#[verifier::external_body]
486+
uninterp spec fn spec_capacity(&self) -> nat;
487+
}
488+
489+
pub uninterp spec fn vec_start_ptr<T>(seq: Seq<T>, capacity: nat, ptr: *const T) -> bool;
490+
491+
pub uninterp spec fn vec_start_mut_ptr<T>(seq: Seq<T>, capacity: nat, ptr: *mut T) -> bool;
492+
493+
pub open spec fn vec_set_len_domain<T>(seq: Seq<T>, capacity: nat, new_len: usize) -> bool {
494+
new_len as nat <= capacity
495+
}
496+
497+
pub uninterp spec fn vec_set_len_result<T>(
498+
old_seq: Seq<T>,
499+
capacity: nat,
500+
new_len: usize,
501+
final_seq: Seq<T>,
502+
) -> bool;
503+
504+
pub uninterp spec fn boxed_slice_view<T, A: Allocator>(boxed: Box<[T], A>) -> Seq<T>;
505+
506+
pub uninterp spec fn boxed_slice_capacity<T, A: Allocator>(boxed: Box<[T], A>) -> nat;
507+
508+
pub uninterp spec fn vec_resize_with_result<T, F: FnMut() -> T>(
509+
source: Seq<T>,
510+
new_len: usize,
511+
f: F,
512+
result: Seq<T>,
513+
) -> bool;
514+
515+
pub assume_specification<T, A: Allocator>[ Vec::<T, A>::as_mut_ptr ](
516+
vec: &mut Vec<T, A>,
517+
) -> (ptr: *mut T)
518+
ensures
519+
vec_start_mut_ptr(old(vec)@, old(vec).spec_capacity(), ptr),
520+
final(vec)@ == old(vec)@,
521+
;
522+
523+
pub assume_specification<T, A: Allocator>[ Vec::<T, A>::as_ptr ](
524+
vec: &Vec<T, A>,
525+
) -> (ptr: *const T)
526+
ensures
527+
vec_start_ptr(vec@, vec.spec_capacity(), ptr),
528+
;
529+
530+
pub assume_specification<T, A: Allocator>[ Vec::<T, A>::into_boxed_slice ](
531+
vec: Vec<T, A>,
532+
) -> (ret: Box<[T], A>)
533+
ensures
534+
boxed_slice_view::<T, A>(ret) == vec@,
535+
boxed_slice_capacity::<T, A>(ret) == vec@.len(),
536+
;
537+
538+
pub assume_specification<T, A: Allocator, F: FnMut() -> T>[
539+
Vec::<T, A>::resize_with::<F>
540+
](
541+
vec: &mut Vec<T, A>,
542+
new_len: usize,
543+
f: F,
544+
)
545+
ensures
546+
new_len <= old(vec)@.len() ==> final(vec)@ == old(vec)@.subrange(0, new_len as int),
547+
new_len > old(vec)@.len() ==> vec_resize_with_result(
548+
old(vec)@,
549+
new_len,
550+
f,
551+
final(vec)@,
552+
),
553+
;
554+
555+
pub assume_specification<T, A: Allocator>[ Vec::<T, A>::set_len ](
556+
vec: &mut Vec<T, A>,
557+
new_len: usize,
558+
)
559+
requires
560+
vec_set_len_domain(old(vec)@, old(vec).spec_capacity(), new_len),
561+
ensures
562+
final(vec)@.len() == new_len,
563+
vec_set_len_result(old(vec)@, old(vec).spec_capacity(), new_len, final(vec)@),
564+
;
565+
479566
} // verus!

0 commit comments

Comments
 (0)