vstd/contrib/exec_spec/
set.rs1use crate::contrib::exec_spec::*;
3use crate::prelude::*;
4use std::collections::HashSet;
5
6verus! {
7
8broadcast use {crate::group_vstd_default, crate::std_specs::hash::group_hash_axioms};
12
13impl<'a, K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq> ToRef<
15 &'a HashSet<K>,
16> for &'a HashSet<K> {
17 #[inline(always)]
18 fn get_ref(self) -> &'a HashSet<K> {
19 &self
20 }
21}
22
23impl<'a, K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq> ToOwned<
24 HashSet<K>,
25> for &'a HashSet<K> {
26 #[verifier::external_body]
27 #[inline(always)]
28 fn get_owned(self) -> HashSet<K> {
29 let mut new_set = HashSet::new();
30 for k in self.iter() {
31 new_set.insert(k.deep_clone());
32 }
33 new_set
34 }
35}
36
37impl<K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq> DeepViewClone for HashSet<K> {
38 #[verifier::external_body]
39 #[inline(always)]
40 fn deep_clone(&self) -> Self {
41 let mut new_set = HashSet::new();
42 for k in self.iter() {
43 new_set.insert(k.deep_clone());
44 }
45 new_set
46 }
47}
48
49#[cfg(verus_keep_ghost)]
52impl<
53 T: ObeysDeepEq + std::hash::Hash + std::cmp::Eq,
54 S: std::hash::BuildHasher,
55 A: core::alloc::Allocator,
56> crate::std_specs::cmp::PartialEqSpecImpl for HashSet<T, S, A> {
57 open spec fn obeys_eq_spec() -> bool {
58 crate::std_specs::hash::builds_valid_hashers::<S>()
59 }
60
61 open spec fn eq_spec(&self, other: &Self) -> bool {
62 self.deep_view() == other.deep_view()
63 }
64}
65
66impl<K: ObeysDeepEq + std::hash::Hash + std::cmp::Eq> ObeysDeepEq for HashSet<K> {
67 proof fn lemma_obeys_deep_eq() {
68 reveal(crate::laws_eq::obeys_deep_eq);
69 }
70}
71
72impl<
73 'a,
74 K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq,
75> ExecSpecLen for &'a HashSet<K> {
76 #[inline(always)]
77 #[verifier::external_body]
78 fn exec_len(self) -> (res: usize)
79 ensures
80 res == self.deep_view().len(),
81 {
82 self.len()
83 }
84}
85
86pub trait ExecSpecSetEmpty: Sized {
89 fn exec_empty() -> Self;
90}
91
92pub trait ExecSpecSetContains<'a>: Sized + DeepView {
94 type Elem: DeepView;
95
96 fn exec_contains(self, a: Self::Elem) -> bool;
97}
98
99pub trait ExecSpecSetInsert<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
101 type Elem: DeepView + DeepViewClone;
102
103 fn exec_insert(self, a: Self::Elem) -> Out;
104}
105
106pub trait ExecSpecSetRemove<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
108 type Elem: DeepView + DeepViewClone;
109
110 fn exec_remove(self, a: Self::Elem) -> Out;
111}
112
113pub trait ExecSpecSetIntersect<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
115 fn exec_intersect(self, s2: Self) -> Out;
116}
117
118pub trait ExecSpecSetUnion<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
120 fn exec_union(self, s2: Self) -> Out;
121}
122
123pub trait ExecSpecSetDifference<'a, Out: Sized + DeepView>: Sized + DeepView + ToOwned<Out> {
125 fn exec_difference(self, s2: Self) -> Out;
126}
127
128impl<K: ObeysDeepEq + std::hash::Hash + std::cmp::Eq> ExecSpecSetEmpty for HashSet<K> {
130 #[inline(always)]
131 fn exec_empty() -> (res: Self)
132 ensures
133 res.deep_view() =~= Set::empty(),
134 {
135 HashSet::new()
136 }
137}
138
139impl<'a, K: ObeysDeepEq + std::hash::Hash + std::cmp::Eq> ExecSpecSetContains<'a> for &'a HashSet<
140 K,
141> {
142 type Elem = K;
143
144 #[verifier::external_body]
145 #[inline(always)]
146 fn exec_contains(self, a: Self::Elem) -> (res: bool)
147 ensures
148 res == self.deep_view().contains(a.deep_view()),
149 {
150 self.contains(&a)
151 }
152}
153
154impl<'a, K> ExecSpecSetInsert<'a, HashSet<K>> for &'a HashSet<K> where
155 K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq,
156 {
157 type Elem = K;
158
159 #[verifier::external_body]
160 #[inline(always)]
161 fn exec_insert(self, a: Self::Elem) -> (res: HashSet<K>)
162 ensures
163 res.deep_view() =~= self.deep_view().insert(a.deep_view()),
164 {
165 let mut m = self.deep_clone();
166 let _ = m.insert(a.deep_clone());
167 m
168 }
169}
170
171impl<'a, K> ExecSpecSetRemove<'a, HashSet<K>> for &'a HashSet<K> where
172 K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq,
173 {
174 type Elem = K;
175
176 #[verifier::external_body]
177 #[inline(always)]
178 fn exec_remove(self, a: Self::Elem) -> (res: HashSet<K>)
179 ensures
180 res.deep_view() =~= self.deep_view().remove(a.deep_view()),
181 {
182 let mut m = self.deep_clone();
183 let _ = m.remove(&a);
184 m
185 }
186}
187
188impl<'a, K> ExecSpecSetIntersect<'a, HashSet<K>> for &'a HashSet<K> where
189 K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq,
190 {
191 #[verifier::external_body]
192 #[inline(always)]
193 fn exec_intersect(self, s2: Self) -> (res: HashSet<K>)
194 ensures
195 res.deep_view() =~= self.deep_view().intersect(s2.deep_view()),
196 {
197 let mut intersect = HashSet::new();
198 for k in self.iter() {
199 if s2.contains(k) {
200 intersect.insert(k.deep_clone());
201 }
202 }
203 intersect
204 }
205}
206
207impl<'a, K> ExecSpecSetUnion<'a, HashSet<K>> for &'a HashSet<K> where
208 K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq,
209 {
210 #[verifier::external_body]
211 #[inline(always)]
212 fn exec_union(self, s2: Self) -> (res: HashSet<K>)
213 ensures
214 res.deep_view() =~= self.deep_view().union(s2.deep_view()),
215 {
216 let mut un = self.deep_clone();
217 for k in s2.iter() {
218 un.insert(k.deep_clone());
219 }
220 un
221 }
222}
223
224impl<'a, K> ExecSpecSetDifference<'a, HashSet<K>> for &'a HashSet<K> where
225 K: ObeysDeepEq + DeepViewClone + std::hash::Hash + std::cmp::Eq,
226 {
227 #[verifier::external_body]
228 #[inline(always)]
229 fn exec_difference(self, s2: Self) -> (res: HashSet<K>)
230 ensures
231 res.deep_view() =~= self.deep_view().difference(s2.deep_view()),
232 {
233 let mut diff = HashSet::new();
234 for k in self.iter() {
235 if !s2.contains(k) {
236 diff.insert(k.deep_clone());
237 }
238 }
239 diff
240 }
241}
242
243}