vstd/contrib/exec_spec/
mod.rs1#![cfg(all(feature = "alloc", feature = "std"))]
5
6use crate::multiset::*;
7use crate::prelude::*;
8use std::collections::HashMap;
9use std::collections::HashSet;
10pub use verus_builtin_macros::exec_spec_type;
11pub use verus_builtin_macros::exec_spec_unverified;
12pub use verus_builtin_macros::exec_spec_verified;
13
14mod arith;
15pub use arith::*;
16mod map;
17pub use map::*;
18mod mem_contents;
19pub use mem_contents::*;
20mod multiset;
21pub use multiset::*;
22mod option;
23pub use option::*;
24mod result;
25pub use result::*;
26mod seq;
27pub use seq::*;
28mod set;
29pub use set::*;
30mod string;
31pub use string::*;
32
33verus! {
34
35pub trait ToRef<T: Sized + DeepView>: Sized + DeepView<V = T::V> {
38 fn get_ref(self) -> (res: T)
39 ensures
40 res.deep_view() == self.deep_view(),
41 ;
42}
43
44pub trait ToOwned<T: Sized + DeepView>: Sized + DeepView<V = T::V> {
45 fn get_owned(self) -> (res: T)
46 ensures
47 res.deep_view() == self.deep_view(),
48 ;
49}
50
51pub trait DeepViewClone: Sized + DeepView {
53 fn deep_clone(&self) -> (res: Self)
54 ensures
55 res.deep_view() == self.deep_view(),
56 ;
57}
58
59pub trait ExecSpecType where
63 for <'a>&'a Self::ExecOwnedType: ToRef<Self::ExecRefType<'a>>,
64 for <'a>Self::ExecRefType<'a>: ToOwned<Self::ExecOwnedType>,
65 {
66 type ExecOwnedType: DeepView<V = Self>;
68
69 type ExecRefType<'a>: DeepView<V = Self>;
71}
72
73pub trait ObeysDeepEq: Sized + PartialEq + DeepView {
75 proof fn lemma_obeys_deep_eq()
76 ensures
77 crate::laws_eq::obeys_deep_eq::<Self>(),
78 ;
79}
80
81#[inline(always)]
83pub fn deep_eq<T: ObeysDeepEq>(x: T, y: T) -> (res: bool)
84 ensures
85 res == (x.deep_view() =~~= y.deep_view()),
86{
87 proof {
88 T::lemma_obeys_deep_eq();
89 reveal(crate::laws_eq::obeys_deep_eq);
90 }
91 x.eq(&y)
92}
93
94impl<'a, T: ObeysDeepEq> ObeysDeepEq for &'a T {
95 proof fn lemma_obeys_deep_eq() {
96 broadcast use crate::laws_eq::lemma_ref_obeys_deep_eq;
97
98 T::lemma_obeys_deep_eq();
99 }
100}
101
102pub trait ExecSpecIndex<'a>: Sized + DeepView<V = Seq<<Self::Elem as DeepView>::V>> {
104 type Elem: DeepView;
105
106 fn exec_index(self, index: usize) -> Self::Elem
107 requires
108 0 <= index < self.deep_view().len(),
109 ;
110}
111
112pub trait ExecSpecLen {
114 fn exec_len(self) -> usize;
115}
116
117macro_rules! impl_primitives {
119 ($(,)?) => {};
120 ($t:ty $(,$rest:ty)* $(,)?) => {
121 verus! {
122 impl ExecSpecType for $t {
123 type ExecOwnedType = $t;
124 type ExecRefType<'a> = $t;
125 }
126
127 impl<'a> ToRef<$t> for &'a $t {
128 #[inline(always)]
129 fn get_ref(self) -> $t {
130 *self
131 }
132 }
133
134 impl ToOwned<$t> for $t {
135 #[inline(always)]
136 fn get_owned(self) -> $t {
137 self
138 }
139 }
140
141 impl DeepViewClone for $t {
142 #[inline(always)]
143 fn deep_clone(&self) -> Self {
144 *self
145 }
146 }
147
148 impl ObeysDeepEq for $t {
149 proof fn lemma_obeys_deep_eq() {
150 reveal(crate::laws_eq::obeys_deep_eq);
151 }
152 }
153 }
154
155 impl_primitives!($($rest),*);
156 };
157}
158
159impl_primitives! {
160 u8, u16, u32, u64, u128, usize,
161 i8, i16, i32, i64, i128, isize,
162 bool, char,
163}
164macro_rules! impl_exec_spec_tuple {
168 ([$(
169 ($T:ident, $n:tt)
170 ),*])=> {
171 verus! {
172
173 impl<'a, $($T: Sized + DeepView),*> ToRef<&'a ($($T,)*)> for &'a ($($T,)*) {
174 #[inline(always)]
175 fn get_ref(self) -> &'a ($($T,)*) {
176 self
177 }
178 }
179
180 impl<'a, $($T: DeepView + DeepViewClone),*> ToOwned<($($T,)*)> for &'a ($($T,)*) {
181 #[inline(always)]
182 fn get_owned(self) -> ($($T,)*) {
183 self.deep_clone()
184 }
185 }
186
187 impl<$($T: DeepViewClone),*> DeepViewClone for ($($T,)*) {
188 #[inline(always)]
189 #[allow(non_snake_case)]
190 fn deep_clone(&self) -> Self {
191 ($(self.$n.deep_clone(),)*)
192 }
193 }
194
195 impl<$($T: ObeysDeepEq),*> ObeysDeepEq for ($($T,)*) {
196 proof fn lemma_obeys_deep_eq() {
197 broadcast use crate::laws_eq::group_laws_eq;
198 $( $T::lemma_obeys_deep_eq(); )*
199 }
200 }
201
202 }
203 };
204}
205
206impl_exec_spec_tuple!([(T0, 0)]);
207
208impl_exec_spec_tuple!([(T0, 0), (T1, 1)]);
209
210impl_exec_spec_tuple!([(T0, 0), (T1, 1), (T2, 2)]);
211
212impl_exec_spec_tuple!([(T0, 0), (T1, 1), (T2, 2), (T3, 3)]);
213
214}