@@ -4,12 +4,13 @@ use verus_builtin::*;
44
55use super :: super :: slice:: SliceIndexSpec ;
66use super :: core:: IndexSpec ;
7+ use alloc:: boxed:: Box ;
78use alloc:: collections:: TryReserveError ;
89use alloc:: vec:: { IntoIter , Vec } ;
910use core:: alloc:: Allocator ;
1011use core:: clone:: Clone ;
1112use core:: marker:: PhantomData ;
12- use core:: ops:: Index ;
13+ use core:: ops:: { FnMut , Index } ;
1314use core:: option:: Option ;
1415use core:: option:: Option :: None ;
1516use 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