1use crate::contrib::exec_spec::*;
3use crate::prelude::*;
4use std::collections::{HashMap, HashSet};
5
6verus! {
7
8broadcast use {
12 crate::group_vstd_default,
13 crate::std_specs::hash::group_hash_axioms,
14 crate::std_specs::hash::lemma_hashmap_deepview_dom,
15};
16
17impl<
19 'a,
20 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
21 V: DeepView + DeepViewClone,
22> ToRef<&'a HashMap<K, V>> for &'a HashMap<K, V> {
23 #[inline(always)]
24 fn get_ref(self) -> &'a HashMap<K, V> {
25 &self
26 }
27}
28
29impl<
30 'a,
31 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
32 V: DeepView + DeepViewClone,
33> ToOwned<HashMap<K, V>> for &'a HashMap<K, V> {
34 #[verifier::external_body]
35 #[inline(always)]
36 fn get_owned(self) -> HashMap<K, V> {
37 let mut new_map = HashMap::new();
38 for (k, v) in self.iter() {
39 new_map.insert(k.deep_clone(), v.deep_clone());
40 }
41 new_map
42 }
43}
44
45impl<
46 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
47 V: DeepView + DeepViewClone,
48> DeepViewClone for HashMap<K, V> {
49 #[verifier::external_body]
50 #[inline(always)]
51 fn deep_clone(&self) -> Self {
52 let mut new_map = HashMap::new();
53 for (k, v) in self.iter() {
54 new_map.insert(k.deep_clone(), v.deep_clone());
55 }
56 new_map
57 }
58}
59
60impl<
61 'a,
62 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
63 V: DeepView + DeepViewClone,
64> ExecSpecEq<'a> for &'a HashMap<K, V> where
65 &'a K: ExecSpecEq<'a, Other = &'a K>,
66 &'a V: ExecSpecEq<'a, Other = &'a V>,
67 {
68 type Other = &'a HashMap<K, V>;
69
70 #[verifier::external_body]
71 #[inline(always)]
72 fn exec_eq(this: Self, other: Self::Other) -> bool {
73 if this.len() != other.len() {
74 return false;
75 }
76 for (k, v) in this.iter() {
77 match other.get(k) {
78 Some(ov) => {
79 if !<&'a V>::exec_eq(v, ov) {
80 return false;
81 }
82 },
83 None => return false,
84 }
85 }
86 true
87 }
88}
89
90impl<
91 'a,
92 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
93 V: DeepView + DeepViewClone,
94> ExecSpecLen for &'a HashMap<K, V> {
95 #[inline(always)]
96 #[verifier::external_body]
97 fn exec_len(self) -> (res: usize)
98 ensures
99 res == self.deep_view().len(),
100 {
101 self.len()
102 }
103}
104
105pub trait ExecSpecMapEmpty: Sized {
108 fn exec_empty() -> Self;
109}
110
111pub trait ExecSpecMapIndex<'a>: Sized + DeepView<
114 V = Map<<Self::Key as DeepView>::V, <Self::Value as DeepView>::V>,
115> {
116 type Key: DeepView;
117
118 type Value: DeepView;
119
120 fn exec_index(self, key: Self::Key) -> Self::Value
121 requires
122 self.deep_view().dom().contains(key.deep_view()),
123 ;
124}
125
126pub trait ExecSpecMapInsert<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
128 type Key: DeepView + DeepViewClone;
129
130 type Value: DeepView + DeepViewClone;
131
132 fn exec_insert(self, key: Self::Key, value: Self::Value) -> Out;
133}
134
135pub trait ExecSpecMapRemove<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
137 type Key: DeepView + DeepViewClone;
138
139 fn exec_remove(self, key: Self::Key) -> Out;
140}
141
142pub trait ExecSpecMapDom<'a>: Sized + DeepView {
144 type Key: DeepView + DeepViewClone;
145
146 fn exec_dom(self) -> HashSet<Self::Key>;
147}
148
149pub trait ExecSpecMapGet<'a>: Sized + DeepView {
151 type Key: DeepView + DeepViewClone;
152
153 type Value: DeepView + DeepViewClone;
154
155 fn exec_get(self, k: Self::Key) -> Option<Self::Value>;
156}
157
158impl<K: DeepView + std::hash::Hash + std::cmp::Eq, V: DeepView> ExecSpecMapEmpty for HashMap<K, V> {
160 #[inline(always)]
161 fn exec_empty() -> (res: Self)
162 ensures
163 res.deep_view() =~= Map::empty(),
164 {
165 HashMap::new()
166 }
167}
168
169impl<'a, K: DeepView + std::hash::Hash + std::cmp::Eq, V: DeepView> ExecSpecMapIndex<
170 'a,
171> for &'a HashMap<K, V> {
172 type Key = K;
173
174 type Value = &'a V;
175
176 #[verifier::external_body]
177 #[inline(always)]
178 fn exec_index(self, index: Self::Key) -> (res: Self::Value)
179 ensures
180 res.deep_view() == self.deep_view()[index.deep_view()],
181 {
182 self.get(&index).unwrap()
183 }
184}
185
186impl<'a, K, V> ExecSpecMapInsert<'a, HashMap<K, V>> for &'a HashMap<K, V> where
187 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
188 V: DeepView + DeepViewClone,
189 {
190 type Key = K;
191
192 type Value = V;
193
194 #[verifier::external_body]
195 #[inline(always)]
196 fn exec_insert(self, key: Self::Key, value: Self::Value) -> (res: HashMap<K, V>)
197 ensures
198 res.deep_view() =~= self.deep_view().insert(key.deep_view(), value.deep_view()),
199 {
200 let mut m = self.deep_clone();
201 let _ = m.insert(key.deep_clone(), value.deep_clone());
202 m
203 }
204}
205
206impl<'a, K, V> ExecSpecMapRemove<'a, HashMap<K, V>> for &'a HashMap<K, V> where
207 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
208 V: DeepView + DeepViewClone,
209 {
210 type Key = K;
211
212 #[verifier::external_body]
213 #[inline(always)]
214 fn exec_remove(self, key: Self::Key) -> (res: HashMap<K, V>)
215 ensures
216 res.deep_view() =~= self.deep_view().remove(key.deep_view()),
217 {
218 let mut m = self.deep_clone();
219 let _ = m.remove(&key);
220 m
221 }
222}
223
224impl<'a, K, V> ExecSpecMapDom<'a> for &'a HashMap<K, V> where
225 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
226 V: DeepView + DeepViewClone,
227 {
228 type Key = K;
229
230 #[verifier::external_body]
231 #[inline(always)]
232 fn exec_dom(self) -> (res: HashSet<K>)
233 ensures
234 res.deep_view() =~= self.deep_view().dom(),
235 {
236 let mut m = HashSet::new();
237 for key in self.keys() {
238 m.insert(key.deep_clone());
239 }
240 m
241 }
242}
243
244impl<'a, K, V> ExecSpecMapGet<'a> for &'a HashMap<K, V> where
245 K: DeepView + DeepViewClone + std::hash::Hash + std::cmp::Eq,
246 V: DeepView + DeepViewClone,
247 {
248 type Key = K;
249
250 type Value = V;
251
252 #[verifier::external_body]
253 #[inline(always)]
254 fn exec_get(self, k: Self::Key) -> (res: Option<Self::Value>)
255 ensures
256 match (res, self.deep_view().get(k.deep_view())) {
257 (Some(v1), Some(v2)) => v1.deep_view() == v2,
258 (None, None) => true,
259 (_, _) => false,
260 },
261 {
262 self.get(&k).map(|v| v.deep_clone())
263 }
264}
265
266}