1use super::super::prelude::*;
26use super::iter::IteratorSpec;
27
28use core::alloc::Allocator;
29use core::borrow::Borrow;
30use core::hash::{BuildHasher, Hash, Hasher};
31use core::marker::PhantomData;
32use core::option::Option;
33use core::option::Option::None;
34use std::collections::hash_map;
35use std::collections::hash_map::{
36 DefaultHasher, Entry, Keys, OccupiedEntry, RandomState, VacantEntry, Values,
37};
38use std::collections::hash_set;
39use std::collections::{HashMap, HashSet};
40
41verus! {
42
43#[verifier::external_type_specification]
52#[verifier::external_body]
53pub struct ExDefaultHasher(DefaultHasher);
54
55impl View for DefaultHasher {
56 type V = Seq<Seq<u8>>;
57
58 #[verifier::external_body]
59 uninterp spec fn view(&self) -> Seq<Seq<u8>>;
60}
61
62pub trait DefaultHasherAdditionalSpecFns {
63 spec fn spec_finish(s: Seq<Seq<u8>>) -> u64;
64}
65
66impl DefaultHasherAdditionalSpecFns for DefaultHasher {
67 #[verifier::external_body]
68 uninterp spec fn spec_finish(s: Seq<Seq<u8>>) -> u64;
69}
70
71pub assume_specification[ DefaultHasher::new ]() -> (result: DefaultHasher)
73 ensures
74 result@ == Seq::<Seq<u8>>::empty(),
75;
76
77pub assume_specification[ DefaultHasher::write ](state: &mut DefaultHasher, bytes: &[u8])
79 ensures
80 final(state)@ == old(state)@.push(bytes@),
81;
82
83pub assume_specification[ DefaultHasher::finish ](state: &DefaultHasher) -> (result: u64)
85 ensures
86 result == DefaultHasher::spec_finish(state@),
87;
88
89#[verifier::external_body]
107pub uninterp spec fn obeys_key_model<Key: ?Sized>() -> bool;
108
109pub broadcast proof fn axiom_bool_obeys_hash_table_key_model()
114 ensures
115 #[trigger] obeys_key_model::<bool>(),
116{
117 admit();
118}
119
120pub broadcast proof fn axiom_u8_obeys_hash_table_key_model()
121 ensures
122 #[trigger] obeys_key_model::<u8>(),
123{
124 admit();
125}
126
127pub broadcast proof fn axiom_u16_obeys_hash_table_key_model()
128 ensures
129 #[trigger] obeys_key_model::<u16>(),
130{
131 admit();
132}
133
134pub broadcast proof fn axiom_u32_obeys_hash_table_key_model()
135 ensures
136 #[trigger] obeys_key_model::<u32>(),
137{
138 admit();
139}
140
141pub broadcast proof fn axiom_u64_obeys_hash_table_key_model()
142 ensures
143 #[trigger] obeys_key_model::<u64>(),
144{
145 admit();
146}
147
148pub broadcast proof fn axiom_u128_obeys_hash_table_key_model()
149 ensures
150 #[trigger] obeys_key_model::<u128>(),
151{
152 admit();
153}
154
155pub broadcast proof fn axiom_usize_obeys_hash_table_key_model()
156 ensures
157 #[trigger] obeys_key_model::<usize>(),
158{
159 admit();
160}
161
162pub broadcast proof fn axiom_i8_obeys_hash_table_key_model()
163 ensures
164 #[trigger] obeys_key_model::<i8>(),
165{
166 admit();
167}
168
169pub broadcast proof fn axiom_i16_obeys_hash_table_key_model()
170 ensures
171 #[trigger] obeys_key_model::<i16>(),
172{
173 admit();
174}
175
176pub broadcast proof fn axiom_i32_obeys_hash_table_key_model()
177 ensures
178 #[trigger] obeys_key_model::<i32>(),
179{
180 admit();
181}
182
183pub broadcast proof fn axiom_i64_obeys_hash_table_key_model()
184 ensures
185 #[trigger] obeys_key_model::<i64>(),
186{
187 admit();
188}
189
190pub broadcast proof fn axiom_i128_obeys_hash_table_key_model()
191 ensures
192 #[trigger] obeys_key_model::<i128>(),
193{
194 admit();
195}
196
197pub broadcast proof fn axiom_isize_obeys_hash_table_key_model()
198 ensures
199 #[trigger] obeys_key_model::<isize>(),
200{
201 admit();
202}
203
204pub broadcast proof fn axiom_box_bool_obeys_hash_table_key_model()
205 ensures
206 #[trigger] obeys_key_model::<Box<bool>>(),
207{
208 admit();
209}
210
211pub broadcast proof fn axiom_box_integer_type_obeys_hash_table_key_model<Key: Integer + ?Sized>()
212 requires
213 obeys_key_model::<Key>(),
214 ensures
215 #[trigger] obeys_key_model::<Box<Key>>(),
216{
217 admit();
218}
219
220#[verifier::external_trait_specification]
221pub trait ExHasher {
222 type ExternalTraitSpecificationFor: Hasher;
223}
224
225#[verifier::external_trait_specification]
234pub trait ExBuildHasher {
235 type ExternalTraitSpecificationFor: BuildHasher;
236
237 type Hasher: Hasher;
238}
239
240#[verifier::external_body]
254pub uninterp spec fn builds_valid_hashers<T: ?Sized>() -> bool;
255
256#[verifier::external_type_specification]
263#[verifier::external_body]
264pub struct ExRandomState(RandomState);
265
266pub broadcast proof fn axiom_random_state_builds_valid_hashers()
267 ensures
268 #[trigger] builds_valid_hashers::<RandomState>(),
269{
270 admit();
271}
272
273#[verifier::external_type_specification]
276#[verifier::external_body]
277#[verifier::accept_recursive_types(Key)]
278#[verifier::accept_recursive_types(Value)]
279pub struct ExKeys<'a, Key: 'a, Value: 'a>(Keys<'a, Key, Value>);
280
281pub uninterp spec fn into_iter_keys<'a, Key, Value>(i: Keys<'a, Key, Value>) -> Seq<Key>;
284
285impl<'a, K, V> super::iter::IteratorSpecImpl for Keys<'a, K, V> {
286 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
287 true
288 }
289
290 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
291
292 uninterp spec fn will_return_none(&self) -> bool;
293
294 #[verifier::prophetic]
295 open spec fn initial_value_relation(&self, init: &Self) -> bool {
296 &&& IteratorSpec::remaining(init) == IteratorSpec::remaining(self)
297 &&& into_iter_keys(*self) == IteratorSpec::remaining(self).unref()
298 }
299
300 uninterp spec fn decrease(&self) -> Option<nat>;
301
302 open spec fn peek(&self, index: int) -> Option<Self::Item> {
303 if 0 <= index < into_iter_keys(*self).len() {
304 Some(&into_iter_keys(*self)[index])
305 } else {
306 None
307 }
308 }
309}
310
311#[verifier::external_type_specification]
314#[verifier::external_body]
315#[verifier::accept_recursive_types(Key)]
316#[verifier::accept_recursive_types(Value)]
317pub struct ExValues<'a, Key: 'a, Value: 'a>(Values<'a, Key, Value>);
318
319pub uninterp spec fn into_iter_values<'a, Key, Value>(i: Values<'a, Key, Value>) -> Seq<Value>;
322
323impl<'a, K, V> super::iter::IteratorSpecImpl for Values<'a, K, V> {
324 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
325 true
326 }
327
328 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
329
330 uninterp spec fn will_return_none(&self) -> bool;
331
332 #[verifier::prophetic]
333 open spec fn initial_value_relation(&self, init: &Self) -> bool {
334 &&& IteratorSpec::remaining(init) == IteratorSpec::remaining(self)
335 &&& into_iter_values(*self) == IteratorSpec::remaining(self).unref()
336 }
337
338 uninterp spec fn decrease(&self) -> Option<nat>;
339
340 open spec fn peek(&self, index: int) -> Option<Self::Item> {
341 if 0 <= index < into_iter_values(*self).len() {
342 Some(&into_iter_values(*self)[index])
343 } else {
344 None
345 }
346 }
347}
348
349#[verifier::external_type_specification]
352#[verifier::external_body]
353#[verifier::accept_recursive_types(Key)]
354#[verifier::accept_recursive_types(Value)]
355pub struct ExMapIter<'a, Key: 'a, Value: 'a>(hash_map::Iter<'a, Key, Value>);
356
357pub uninterp spec fn into_iter<'a, Key, Value>(i: hash_map::Iter<'a, Key, Value>) -> Seq<
360 (Key, Value),
361>;
362
363impl<'a, K, V> super::iter::IteratorSpecImpl for hash_map::Iter<'a, K, V> {
364 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
365 true
366 }
367
368 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
369
370 uninterp spec fn will_return_none(&self) -> bool;
371
372 #[verifier::prophetic]
373 open spec fn initial_value_relation(&self, init: &Self) -> bool {
374 &&& IteratorSpec::remaining(init) == IteratorSpec::remaining(self)
375 &&& into_iter(*self) == IteratorSpec::remaining(self).unref()
376 }
377
378 uninterp spec fn decrease(&self) -> Option<nat>;
379
380 open spec fn peek(&self, index: int) -> Option<Self::Item> {
381 if 0 <= index < into_iter(*self).len() {
382 let (k, v) = into_iter(*self)[index];
383 Some((&k, &v))
384 } else {
385 None
386 }
387 }
388}
389
390pub uninterp spec fn spec_hash_map_iter<'a, Key, Value, S, A: Allocator>(
397 m: &'a HashMap<Key, Value, S, A>,
398) -> (r: hash_map::Iter<'a, Key, Value>);
399
400pub broadcast proof fn axiom_spec_hash_map_iter<'a, Key, Value, S>(m: &'a HashMap<Key, Value, S>)
401 ensures
402 ({
403 let v = #[trigger] spec_hash_map_iter(m).remaining();
404 &&& v.len() == m@.dom().len()
405 &&& forall|i: int|
406 #![trigger m@.contains_key(*v[i].0)]
407 #![trigger m@[*v[i].0]]
408 0 <= i < v.len() ==> m@.contains_key(*v[i].0) && m@[*v[i].0] == *v[i].1
409 &&& forall|k: Key| #[trigger] m@.contains_key(k) ==> v.contains((&k, &m@[k]))
410 &&& v.unref().to_set() == m@.kv_pairs()
411 }),
412{
413 admit();
414}
415
416#[verifier::when_used_as_spec(spec_hash_map_iter)]
417pub assume_specification<'a, Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::iter ](
418 m: &'a HashMap<Key, Value, S, A>,
419) -> (iter: hash_map::Iter<'a, Key, Value>)
420 ensures
421 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
422 &&& iter == spec_hash_map_iter(m)
423 &&& iter.remaining().no_duplicates()
424 &&& IteratorSpec::decrease(&iter) is Some
425 &&& IteratorSpec::initial_value_relation(&iter, &iter)
426 },
427;
428
429#[verifier::external_type_specification]
441#[verifier::external_body]
442#[verifier::accept_recursive_types(Key)]
443#[verifier::accept_recursive_types(Value)]
444#[verifier::reject_recursive_types(S)]
445#[verifier::reject_recursive_types(A)]
446pub struct ExHashMap<Key, Value, S, A: Allocator>(HashMap<Key, Value, S, A>);
447
448pub trait HashMapAdditionalSpecFns<Key, Value>: View<V = Map<Key, Value>> {
449 spec fn spec_index(&self, k: Key) -> Value
450 recommends
451 self@.contains_key(k),
452 ;
453}
454
455impl<Key, Value, S, A: Allocator> HashMapAdditionalSpecFns<Key, Value> for HashMap<
456 Key,
457 Value,
458 S,
459 A,
460> {
461 #[verifier::inline]
462 open spec fn spec_index(&self, k: Key) -> Value {
463 self@.index(k)
464 }
465}
466
467#[verifier::opaque]
473pub open spec fn hash_map_deep_view_impl<
474 Key: DeepView,
475 Value: DeepView,
476 S,
477 A: core::alloc::Allocator,
478>(m: HashMap<Key, Value, S, A>) -> Map<Key::V, Value::V> {
479 Map::new(
480 |k: Key::V|
481 exists|orig_k: Key| #[trigger] m@.contains_key(orig_k) && k == orig_k.deep_view(),
482 |dk: Key::V|
483 {
484 let k = choose|k: Key| m@.contains_key(k) && #[trigger] k.deep_view() == dk;
485 m@[k].deep_view()
486 },
487 )
488}
489
490pub broadcast proof fn lemma_hashmap_deepview_dom<K: DeepView, V: DeepView>(m: HashMap<K, V>)
491 ensures
492 #[trigger] m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()),
493{
494 reveal(hash_map_deep_view_impl);
495 broadcast use group_hash_axioms;
496 broadcast use crate::vstd::group_vstd_default;
497
498 assert(m.deep_view().dom() =~= m@.dom().map(|k: K| k.deep_view()));
499}
500
501pub broadcast proof fn lemma_hashmap_deepview_properties<K: DeepView, V: DeepView>(m: HashMap<K, V>)
502 requires
503 crate::relations::injective(|k: K| k.deep_view()),
504 ensures
505 #![trigger m.deep_view()]
506 forall|k: K| #[trigger]
508 m@.contains_key(k) ==> m.deep_view().contains_key(k.deep_view())
509 && m.deep_view()[k.deep_view()] == m@[k].deep_view(),
510 forall|dk: <K as DeepView>::V| #[trigger]
512 m.deep_view().contains_key(dk) ==> exists|k: K|
513 k.deep_view() == dk && #[trigger] m@.contains_key(k),
514{
515 reveal(hash_map_deep_view_impl);
516 broadcast use group_hash_axioms;
517 broadcast use crate::vstd::group_vstd_default;
518
519 assert(m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()));
520 assert forall|k: K| #[trigger] m@.contains_key(k) implies m.deep_view().contains_key(
521 k.deep_view(),
522 ) && m.deep_view()[k.deep_view()] == m@[k].deep_view() by {
523 assert forall|k1: K, k2: K| #[trigger]
524 k1.deep_view() == #[trigger] k2.deep_view() implies k1 == k2 by {
525 let ghost k_deepview = |k: K| k.deep_view();
526 assert(crate::relations::injective(k_deepview));
527 assert(k_deepview(k1) == k_deepview(k2));
528 }
529 }
530}
531
532pub broadcast proof fn lemma_hashmap_deepview_values<K: DeepView, V: DeepView>(m: HashMap<K, V>)
533 requires
534 crate::relations::injective(|k: K| k.deep_view()),
535 ensures
536 #[trigger] m.deep_view().values() =~= m@.values().map(|v: V| v.deep_view()),
537{
538 reveal(hash_map_deep_view_impl);
539 broadcast use group_hash_axioms;
540 broadcast use lemma_hashmap_deepview_properties;
541 broadcast use crate::vstd::group_vstd_default;
542
543 let lhs = m.deep_view().values();
544 let rhs = m@.values().map(|v: V| v.deep_view());
545 assert forall|v: V::V| #[trigger] lhs.contains(v) implies rhs.contains(v) by {
546 let dk = choose|dk: K::V| #[trigger]
547 m.deep_view().contains_key(dk) && m.deep_view()[dk] == v;
548 let k = choose|k: K| #[trigger] m@.contains_key(k) && k.deep_view() == dk;
549 let ov = choose|ov: V| #[trigger] m@.contains_key(k) && m@[k] == ov && ov.deep_view() == v;
550 assert(v == ov.deep_view());
551 assert(m@.values().contains(ov));
552 }
553}
554
555pub broadcast proof fn axiom_hashmap_deepview_borrow<
558 K: DeepView + Borrow<Q>,
559 V: DeepView,
560 Q: View<V = <K as DeepView>::V> + Hash + Eq + ?Sized,
561>(m: HashMap<K, V>, k: &Q)
562 requires
563 obeys_key_model::<K>(),
564 crate::relations::injective(|k: K| k.deep_view()),
565 ensures
566 #[trigger] contains_borrowed_key(m@, k) <==> m.deep_view().contains_key(k@),
567{
568 admit();
569}
570
571pub broadcast proof fn axiom_hashmap_view_finite_dom<K, V>(m: HashMap<K, V>)
573 ensures
574 #[trigger] m@.dom().finite(),
575{
576 admit();
577}
578
579pub uninterp spec fn spec_hash_map_len<Key, Value, S, A: Allocator>(
580 m: &HashMap<Key, Value, S, A>,
581) -> usize;
582
583pub broadcast proof fn axiom_spec_hash_map_len<Key, Value, S, A: Allocator>(
584 m: &HashMap<Key, Value, S, A>,
585)
586 ensures
587 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> #[trigger] spec_hash_map_len(m)
588 == m@.len(),
589{
590 admit();
591}
592
593#[verifier::when_used_as_spec(spec_hash_map_len)]
594pub assume_specification<Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::len ](
595 m: &HashMap<Key, Value, S, A>,
596) -> (len: usize)
597 ensures
598 len == spec_hash_map_len(m),
599;
600
601pub assume_specification<Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::is_empty ](
602 m: &HashMap<Key, Value, S, A>,
603) -> (res: bool)
604 ensures
605 res == m@.is_empty(),
606;
607
608pub assume_specification<K: Clone, V: Clone, S: Clone, A: Allocator + Clone>[ <HashMap::<
609 K,
610 V,
611 S,
612 A,
613> as Clone>::clone ](this: &HashMap<K, V, S, A>) -> (other: HashMap<K, V, S, A>)
614 ensures
615 other@ == this@,
616;
617
618pub assume_specification<Key, Value>[ HashMap::<Key, Value>::new ]() -> (m: HashMap<
619 Key,
620 Value,
621 RandomState,
622>)
623 ensures
624 m@ == Map::<Key, Value>::empty(),
625;
626
627pub assume_specification<K, V, S: core::default::Default>[ <HashMap<
628 K,
629 V,
630 S,
631> as core::default::Default>::default ]() -> (m: HashMap<K, V, S>)
632 ensures
633 m@ == Map::<K, V>::empty(),
634;
635
636pub assume_specification<Key, Value>[ HashMap::<Key, Value>::with_capacity ](capacity: usize) -> (m:
637 HashMap<Key, Value, RandomState>)
638 ensures
639 m@ == Map::<Key, Value>::empty(),
640;
641
642pub assume_specification<Key: Eq + Hash, Value, S: BuildHasher, A: Allocator>[ HashMap::<
643 Key,
644 Value,
645 S,
646 A,
647>::reserve ](m: &mut HashMap<Key, Value, S, A>, additional: usize)
648 ensures
649 final(m)@ == old(m)@,
650;
651
652pub assume_specification<Key: Eq + Hash, Value, S: BuildHasher, A: Allocator>[ HashMap::<
653 Key,
654 Value,
655 S,
656 A,
657>::insert ](m: &mut HashMap<Key, Value, S, A>, k: Key, v: Value) -> (result: Option<Value>)
658 ensures
659 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
660 &&& final(m)@ == old(m)@.insert(k, v)
661 &&& match result {
662 Some(v) => old(m)@.contains_key(k) && v == old(m)[k],
663 None => !old(m)@.contains_key(k),
664 }
665 },
666;
667
668pub uninterp spec fn contains_borrowed_key<Key, Value, Q: ?Sized>(
683 m: Map<Key, Value>,
684 k: &Q,
685) -> bool;
686
687pub broadcast proof fn axiom_contains_deref_key<Q, Value>(m: Map<Q, Value>, k: &Q)
688 ensures
689 #[trigger] contains_borrowed_key::<Q, Value, Q>(m, k) <==> m.contains_key(*k),
690{
691 admit();
692}
693
694pub broadcast proof fn axiom_contains_box<Q, Value>(m: Map<Box<Q>, Value>, k: &Q)
695 ensures
696 #[trigger] contains_borrowed_key::<Box<Q>, Value, Q>(m, k) <==> m.contains_key(
697 Box::new(*k),
698 ),
699{
700 admit();
701}
702
703pub assume_specification<
704 Key: Borrow<Q> + Hash + Eq,
705 Value,
706 S: BuildHasher,
707 A: Allocator,
708 Q: Hash + Eq + ?Sized,
709>[ HashMap::<Key, Value, S, A>::contains_key::<Q> ](
710 m: &HashMap<Key, Value, S, A>,
711 k: &Q,
712) -> (result: bool)
713 ensures
714 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> result == contains_borrowed_key(
715 m@,
716 k,
717 ),
718;
719
720pub uninterp spec fn maps_borrowed_key_to_value<Key, Value, Q: ?Sized>(
737 m: Map<Key, Value>,
738 k: &Q,
739 v: Value,
740) -> bool;
741
742pub broadcast proof fn axiom_maps_deref_key_to_value<Q, Value>(m: Map<Q, Value>, k: &Q, v: Value)
743 ensures
744 #[trigger] maps_borrowed_key_to_value::<Q, Value, Q>(m, k, v) <==> m.contains_key(*k)
745 && m[*k] == v,
746{
747 admit();
748}
749
750pub broadcast proof fn axiom_maps_box_key_to_value<Q, Value>(m: Map<Box<Q>, Value>, q: &Q, v: Value)
751 ensures
752 #[trigger] maps_borrowed_key_to_value::<Box<Q>, Value, Q>(m, q, v) <==> {
753 let k = Box::new(*q);
754 &&& m.contains_key(k)
755 &&& m[k] == v
756 },
757{
758 admit();
759}
760
761pub assume_specification<
762 'a,
763 Key: Borrow<Q> + Hash + Eq,
764 Value,
765 S: BuildHasher,
766 A: Allocator,
767 Q: Hash + Eq + ?Sized,
768>[ HashMap::<Key, Value, S, A>::get::<Q> ](m: &'a HashMap<Key, Value, S, A>, k: &Q) -> (result:
769 Option<&'a Value>)
770 ensures
771 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> match result {
772 Some(v) => maps_borrowed_key_to_value(m@, k, *v),
773 None => !contains_borrowed_key(m@, k),
774 },
775;
776
777pub uninterp spec fn borrowed_key_removed<Key, Value, Q: ?Sized>(
793 old_m: Map<Key, Value>,
794 new_m: Map<Key, Value>,
795 k: &Q,
796) -> bool;
797
798pub broadcast proof fn axiom_deref_key_removed<Q, Value>(
799 old_m: Map<Q, Value>,
800 new_m: Map<Q, Value>,
801 k: &Q,
802)
803 ensures
804 #[trigger] borrowed_key_removed::<Q, Value, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
805 *k,
806 ),
807{
808 admit();
809}
810
811pub broadcast proof fn axiom_box_key_removed<Q, Value>(
812 old_m: Map<Box<Q>, Value>,
813 new_m: Map<Box<Q>, Value>,
814 q: &Q,
815)
816 ensures
817 #[trigger] borrowed_key_removed::<Box<Q>, Value, Q>(old_m, new_m, q) <==> new_m
818 == old_m.remove(Box::new(*q)),
819{
820 admit();
821}
822
823pub assume_specification<
824 Key: Borrow<Q> + Hash + Eq,
825 Value,
826 S: BuildHasher,
827 A: Allocator,
828 Q: Hash + Eq + ?Sized,
829>[ HashMap::<Key, Value, S, A>::remove::<Q> ](m: &mut HashMap<Key, Value, S, A>, k: &Q) -> (result:
830 Option<Value>)
831 ensures
832 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
833 &&& borrowed_key_removed(old(m)@, final(m)@, k)
834 &&& match result {
835 Some(v) => maps_borrowed_key_to_value(old(m)@, k, v),
836 None => !contains_borrowed_key(old(m)@, k),
837 }
838 },
839;
840
841pub assume_specification<Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::clear ](
842 m: &mut HashMap<Key, Value, S, A>,
843)
844 ensures
845 final(m)@ == Map::<Key, Value>::empty(),
846;
847
848pub uninterp spec fn spec_keys_iter<'a, Key, Value, S, A: Allocator>(
855 m: &'a HashMap<Key, Value, S, A>,
856) -> (keys: Keys<'a, Key, Value>);
857
858pub broadcast proof fn axiom_spec_keys_iter<'a, Key, Value, S, A: Allocator>(
859 m: &'a HashMap<Key, Value, S, A>,
860)
861 ensures
862 (#[trigger] spec_keys_iter(m).remaining()).unref().to_set() == m@.dom(),
863 spec_keys_iter(m).remaining().no_duplicates(),
864 spec_keys_iter(m).remaining().len() == m@.dom().len(),
865{
866 admit();
867}
868
869#[verifier::when_used_as_spec(spec_keys_iter)]
870pub assume_specification<'a, Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::keys ](
871 m: &'a HashMap<Key, Value, S, A>,
872) -> (keys: Keys<'a, Key, Value>)
873 ensures
874 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
875 &&& keys == spec_keys_iter(m)
876 &&& IteratorSpec::decrease(&keys) is Some
877 &&& IteratorSpec::initial_value_relation(&keys, &keys)
878 },
879;
880
881pub uninterp spec fn spec_values_iter<'a, Key, Value, S, A: Allocator>(
888 m: &'a HashMap<Key, Value, S, A>,
889) -> (values: Values<'a, Key, Value>);
890
891pub broadcast proof fn axiom_spec_values_iter<'a, Key, Value, S, A: Allocator>(
892 m: &'a HashMap<Key, Value, S, A>,
893)
894 ensures
895 (#[trigger] spec_values_iter(m).remaining()).unref().to_set() == m@.values(),
896 spec_values_iter(m).remaining().len() == m@.dom().len(),
897{
898 admit();
899}
900
901#[verifier::when_used_as_spec(spec_values_iter)]
902pub assume_specification<'a, Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::values ](
903 m: &'a HashMap<Key, Value, S, A>,
904) -> (values: Values<'a, Key, Value>)
905 ensures
906 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
907 &&& values == spec_values_iter(m)
908 &&& IteratorSpec::decrease(&values) is Some
909 &&& IteratorSpec::initial_value_relation(&values, &values)
910 },
911;
912
913pub broadcast proof fn axiom_hashmap_decreases<Key, Value, S>(m: HashMap<Key, Value, S>)
914 ensures
915 #[trigger] (decreases_to!(m => m@)),
916{
917 admit();
918}
919
920#[verifier::external_type_specification]
923#[verifier::external_body]
924#[verifier::accept_recursive_types(Key)]
925pub struct ExSetIter<'a, Key: 'a>(hash_set::Iter<'a, Key>);
926
927pub uninterp spec fn into_iter_hash_keys<'a, Key>(i: hash_set::Iter::<'a, Key>) -> Seq<Key>;
930
931impl<'a, K> super::iter::IteratorSpecImpl for hash_set::Iter::<'a, K> {
932 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
933 true
934 }
935
936 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
937
938 uninterp spec fn will_return_none(&self) -> bool;
939
940 #[verifier::prophetic]
941 open spec fn initial_value_relation(&self, init: &Self) -> bool {
942 &&& IteratorSpec::remaining(init) == IteratorSpec::remaining(self)
943 &&& into_iter_hash_keys(*self) == IteratorSpec::remaining(self).unref()
944 }
945
946 uninterp spec fn decrease(&self) -> Option<nat>;
947
948 open spec fn peek(&self, index: int) -> Option<Self::Item> {
949 if 0 <= index < into_iter_hash_keys(*self).len() {
950 Some(&into_iter_hash_keys(*self)[index])
951 } else {
952 None
953 }
954 }
955}
956
957#[verifier::external_type_specification]
969#[verifier::external_body]
970#[verifier::accept_recursive_types(Key)]
971#[verifier::reject_recursive_types(S)]
972#[verifier::reject_recursive_types(A)]
973pub struct ExHashSet<Key, S, A: Allocator>(HashSet<Key, S, A>);
974
975pub uninterp spec fn spec_hash_set_len<Key, S, A: Allocator>(m: &HashSet<Key, S, A>) -> usize;
976
977pub broadcast proof fn axiom_spec_hash_set_len<Key, S, A: Allocator>(m: &HashSet<Key, S, A>)
978 ensures
979 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> #[trigger] spec_hash_set_len(m)
980 == m@.len(),
981{
982 admit();
983}
984
985#[verifier::when_used_as_spec(spec_hash_set_len)]
986pub assume_specification<Key, S, A: Allocator>[ HashSet::<Key, S, A>::len ](
987 m: &HashSet<Key, S, A>,
988) -> (len: usize)
989 ensures
990 len == spec_hash_set_len(m),
991;
992
993pub assume_specification<Key, S, A: Allocator>[ HashSet::<Key, S, A>::is_empty ](
994 m: &HashSet<Key, S, A>,
995) -> (res: bool)
996 ensures
997 res == m@.is_empty(),
998;
999
1000pub assume_specification<Key>[ HashSet::<Key>::new ]() -> (m: HashSet<Key, RandomState>)
1001 ensures
1002 m@ == Set::<Key>::empty(),
1003;
1004
1005pub assume_specification<T, S: core::default::Default>[ <HashSet<
1006 T,
1007 S,
1008> as core::default::Default>::default ]() -> (m: HashSet<T, S>)
1009 ensures
1010 m@ == Set::<T>::empty(),
1011;
1012
1013pub assume_specification<Key>[ HashSet::<Key>::with_capacity ](capacity: usize) -> (m: HashSet<
1014 Key,
1015 RandomState,
1016>)
1017 ensures
1018 m@ == Set::<Key>::empty(),
1019;
1020
1021pub assume_specification<Key: Eq + Hash, S: BuildHasher, A: Allocator>[ HashSet::<
1022 Key,
1023 S,
1024 A,
1025>::reserve ](m: &mut HashSet<Key, S, A>, additional: usize)
1026 ensures
1027 final(m)@ == old(m)@,
1028;
1029
1030pub assume_specification<Key: Eq + Hash, S: BuildHasher, A: Allocator>[ HashSet::<
1031 Key,
1032 S,
1033 A,
1034>::insert ](m: &mut HashSet<Key, S, A>, k: Key) -> (result: bool)
1035 ensures
1036 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
1037 &&& final(m)@ == old(m)@.insert(k)
1038 &&& result == !old(m)@.contains(k)
1039 },
1040;
1041
1042pub uninterp spec fn set_contains_borrowed_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q) -> bool;
1057
1058pub broadcast proof fn axiom_set_contains_deref_key<Q>(m: Set<Q>, k: &Q)
1059 ensures
1060 #[trigger] set_contains_borrowed_key::<Q, Q>(m, k) <==> m.contains(*k),
1061{
1062 admit();
1063}
1064
1065pub broadcast proof fn axiom_set_contains_box<Q>(m: Set<Box<Q>>, k: &Q)
1066 ensures
1067 #[trigger] set_contains_borrowed_key::<Box<Q>, Q>(m, k) <==> m.contains(Box::new(*k)),
1068{
1069 admit();
1070}
1071
1072pub assume_specification<
1073 Key: Borrow<Q> + Hash + Eq,
1074 S: BuildHasher,
1075 A: Allocator,
1076 Q: Hash + Eq + ?Sized,
1077>[ HashSet::<Key, S, A>::contains ](m: &HashSet<Key, S, A>, k: &Q) -> (result: bool)
1078 ensures
1079 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> result
1080 == set_contains_borrowed_key(m@, k),
1081;
1082
1083pub uninterp spec fn sets_borrowed_key_to_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q, v: &Key) -> bool;
1100
1101pub broadcast proof fn axiom_set_deref_key_to_value<Q>(m: Set<Q>, k: &Q, v: &Q)
1102 ensures
1103 #[trigger] sets_borrowed_key_to_key::<Q, Q>(m, k, v) <==> m.contains(*k) && k == v,
1104{
1105 admit();
1106}
1107
1108pub broadcast proof fn axiom_set_box_key_to_value<Q>(m: Set<Box<Q>>, q: &Q, v: &Box<Q>)
1109 ensures
1110 #[trigger] sets_borrowed_key_to_key::<Box<Q>, Q>(m, q, v) <==> (m.contains(*v) && Box::new(
1111 *q,
1112 ) == v),
1113{
1114 admit();
1115}
1116
1117pub assume_specification<
1118 'a,
1119 Key: Borrow<Q> + Hash + Eq,
1120 S: BuildHasher,
1121 A: Allocator,
1122 Q: Hash + Eq + ?Sized,
1123>[ HashSet::<Key, S, A>::get::<Q> ](m: &'a HashSet<Key, S, A>, k: &Q) -> (result: Option<&'a Key>)
1124 ensures
1125 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> match result {
1126 Some(v) => sets_borrowed_key_to_key(m@, k, v),
1127 None => !set_contains_borrowed_key(m@, k),
1128 },
1129;
1130
1131pub uninterp spec fn sets_differ_by_borrowed_key<Key, Q: ?Sized>(
1146 old_m: Set<Key>,
1147 new_m: Set<Key>,
1148 k: &Q,
1149) -> bool;
1150
1151pub broadcast proof fn axiom_set_deref_key_removed<Q>(old_m: Set<Q>, new_m: Set<Q>, k: &Q)
1152 ensures
1153 #[trigger] sets_differ_by_borrowed_key::<Q, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
1154 *k,
1155 ),
1156{
1157 admit();
1158}
1159
1160pub broadcast proof fn axiom_set_box_key_removed<Q>(old_m: Set<Box<Q>>, new_m: Set<Box<Q>>, q: &Q)
1161 ensures
1162 #[trigger] sets_differ_by_borrowed_key::<Box<Q>, Q>(old_m, new_m, q) <==> new_m
1163 == old_m.remove(Box::new(*q)),
1164{
1165 admit();
1166}
1167
1168pub assume_specification<
1169 Key: Borrow<Q> + Hash + Eq,
1170 S: BuildHasher,
1171 A: Allocator,
1172 Q: Hash + Eq + ?Sized,
1173>[ HashSet::<Key, S, A>::remove::<Q> ](m: &mut HashSet<Key, S, A>, k: &Q) -> (result: bool)
1174 ensures
1175 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
1176 &&& sets_differ_by_borrowed_key(old(m)@, final(m)@, k)
1177 &&& result == set_contains_borrowed_key(old(m)@, k)
1178 },
1179;
1180
1181pub assume_specification<Key, S, A: Allocator>[ HashSet::<Key, S, A>::clear ](
1182 m: &mut HashSet<Key, S, A>,
1183)
1184 ensures
1185 final(m)@ == Set::<Key>::empty(),
1186;
1187
1188pub uninterp spec fn spec_hash_keys_iter<'a, Key, S, A: Allocator>(m: &'a HashSet<Key, S, A>) -> (r:
1195 hash_set::Iter<'a, Key>);
1196
1197pub broadcast proof fn axiom_spec_hash_keys_iter<'a, Key, S, A: Allocator>(
1198 m: &'a HashSet<Key, S, A>,
1199)
1200 ensures
1201 (#[trigger] spec_hash_keys_iter(m).remaining()).unref().to_set() == m@,
1202 spec_hash_keys_iter(m).remaining().no_duplicates(),
1203 spec_hash_keys_iter(m).remaining().len() == m@.len(),
1204{
1205 admit();
1206}
1207
1208#[verifier::when_used_as_spec(spec_hash_keys_iter)]
1209pub assume_specification<'a, Key, S, A: Allocator>[ HashSet::<Key, S, A>::iter ](
1210 m: &'a HashSet<Key, S, A>,
1211) -> (hash_keys: hash_set::Iter<'a, Key>)
1212 ensures
1213 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
1214 &&& hash_keys == spec_hash_keys_iter(m)
1215 &&& IteratorSpec::decrease(&hash_keys) is Some
1216 &&& IteratorSpec::initial_value_relation(&hash_keys, &hash_keys)
1217 },
1218;
1219
1220pub broadcast proof fn axiom_hashset_decreases<Key, S, A: Allocator>(m: HashSet<Key, S, A>)
1221 ensures
1222 #[trigger] (decreases_to!(m => m@)),
1223{
1224 admit();
1225}
1226
1227#[verifier::reject_recursive_types_in_ground_variants(K)]
1232#[verifier::reject_recursive_types_in_ground_variants(V)]
1233#[verifier::reject_recursive_types(A)]
1234#[verifier::external_body]
1235#[verifier::external_type_specification]
1236pub struct ExOccupiedEntry<'a, K: 'a, V: 'a, A: Allocator>(OccupiedEntry<'a, K, V, A>);
1237
1238#[verifier::reject_recursive_types_in_ground_variants(K)]
1239#[verifier::accept_recursive_types(V)]
1240#[verifier::reject_recursive_types(A)]
1241#[verifier::external_body]
1242#[verifier::external_type_specification]
1243pub struct ExVacantEntry<'a, K: 'a, V: 'a, A: Allocator>(VacantEntry<'a, K, V, A>);
1244
1245#[verifier::external_type_specification]
1246#[verifier::reject_recursive_types(A)]
1247pub struct ExEntry<'a, K: 'a, V: 'a, A: Allocator>(Entry<'a, K, V, A>);
1248
1249pub trait OccupiedEntrySpecFns<K, V, A>: Sized {
1254 spec fn spec_key(self) -> K;
1255
1256 spec fn value(self) -> V;
1257
1258 #[verifier::prophetic]
1259 spec fn final_value(self) -> Option<V>;
1260}
1261
1262impl<'a, K, V, A: Allocator> OccupiedEntrySpecFns<K, V, A> for OccupiedEntry<'a, K, V, A> {
1263 uninterp spec fn spec_key(self) -> K;
1264
1265 uninterp spec fn value(self) -> V;
1266
1267 #[verifier::prophetic]
1268 uninterp spec fn final_value(self) -> Option<V>;
1269}
1270
1271pub trait VacantEntrySpecFns<K, V, A>: Sized {
1276 spec fn spec_key(self) -> K;
1277
1278 #[verifier::prophetic]
1279 spec fn final_value(self) -> Option<V>;
1280}
1281
1282impl<'a, K, V, A: Allocator> VacantEntrySpecFns<K, V, A> for VacantEntry<'a, K, V, A> {
1283 uninterp spec fn spec_key(self) -> K;
1284
1285 #[verifier::prophetic]
1286 uninterp spec fn final_value(self) -> Option<V>;
1287}
1288
1289pub trait EntrySpecFns<K, V, A>: Sized {
1293 spec fn spec_key(self) -> K;
1294
1295 spec fn value(self) -> Option<V>;
1296
1297 #[verifier::prophetic]
1298 spec fn final_value(self) -> Option<V>;
1299}
1300
1301impl<'a, K, V, A: Allocator> EntrySpecFns<K, V, A> for Entry<'a, K, V, A> {
1302 open spec fn spec_key(self) -> K {
1303 match self {
1304 Entry::Occupied(occupied_entry) => occupied_entry.spec_key(),
1305 Entry::Vacant(vacant_entry) => vacant_entry.spec_key(),
1306 }
1307 }
1308
1309 open spec fn value(self) -> Option<V> {
1310 match self {
1311 Entry::Occupied(occupied_entry) => Some(occupied_entry.value()),
1312 Entry::Vacant(vacant_entry) => None,
1313 }
1314 }
1315
1316 #[verifier::prophetic]
1317 open spec fn final_value(self) -> Option<V> {
1318 match self {
1319 Entry::Occupied(occupied_entry) => occupied_entry.final_value(),
1320 Entry::Vacant(vacant_entry) => vacant_entry.final_value(),
1321 }
1322 }
1323}
1324
1325pub broadcast axiom fn axiom_has_resolved_occupied_entry<K, V, A: Allocator>(
1326 entry: OccupiedEntry<K, V, A>,
1327)
1328 ensures
1329 #[trigger] has_resolved(entry) ==> entry.final_value() == Some(entry.value()),
1330;
1331
1332pub broadcast axiom fn axiom_has_resolved_vacant_entry<K, V, A: Allocator>(
1333 entry: VacantEntry<K, V, A>,
1334)
1335 ensures
1336 #[trigger] has_resolved(entry) ==> entry.final_value() == None::<V>,
1337;
1338
1339pub broadcast proof fn axiom_has_resolved_entry<K, V, A: Allocator>(entry: Entry<K, V, A>)
1340 ensures
1341 #[trigger] has_resolved(entry) ==> entry.final_value() == entry.value(),
1342{
1343 broadcast use axiom_has_resolved_occupied_entry;
1344 broadcast use axiom_has_resolved_vacant_entry;
1345
1346}
1347
1348pub assume_specification<'a, Key: Hash + Eq, Value, S: BuildHasher, A: Allocator>[ HashMap::<
1349 Key,
1350 Value,
1351 S,
1352 A,
1353>::entry ](m: &'a mut HashMap<Key, Value, S, A>, key: Key) -> (entry: Entry<'a, Key, Value, A>)
1354 ensures
1355 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> (entry.key() == key
1356 && entry.value() == old(m)@.get(key) && final(m)@ == (match entry.final_value() {
1357 Some(value) => old(m)@.insert(key, value),
1358 None => old(m)@.remove(key),
1359 })),
1360;
1361
1362#[verifier::allow_in_spec]
1364pub assume_specification<'a, 'b, K, V, A: Allocator>[ Entry::key ](
1365 entry: &'b Entry::<'a, K, V, A>,
1366) -> (key: &'b K)
1367 returns
1368 &entry.spec_key(),
1369;
1370
1371pub assume_specification<'a, K, V, A: Allocator>[ Entry::or_insert ](
1372 entry: Entry::<'a, K, V, A>,
1373 default: V,
1374) -> (value: &'a mut V)
1375 ensures
1376 *value == (match entry.value() {
1377 Some(v) => v,
1378 None => default,
1379 }),
1380 entry.final_value() == Some(*final(value)),
1381;
1382
1383pub assume_specification<'a, K, V, A: Allocator>[ Entry::insert_entry ](
1384 entry: Entry::<'a, K, V, A>,
1385 value: V,
1386) -> (occ_entry: OccupiedEntry<'a, K, V, A>)
1387 ensures
1388 occ_entry.key() == entry.key(),
1389 occ_entry.value() == value,
1390 entry.final_value() == occ_entry.final_value(),
1391;
1392
1393mod m_occ {
1396 use super::*;
1397
1398 #[verifier::allow_in_spec]
1399 pub assume_specification<'a, 'b, K, V, A: Allocator>[ OccupiedEntry::key ](
1400 entry: &'b OccupiedEntry::<'a, K, V, A>,
1401 ) -> (key: &'b K)
1402 returns
1403 &entry.spec_key(),
1404 ;
1405
1406}
1407
1408pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::remove_entry ](
1409 entry: OccupiedEntry::<'a, K, V, A>,
1410) -> (kv: (K, V))
1411 ensures
1412 entry.final_value() == None,
1413 returns
1414 (*entry.key(), entry.value()),
1415;
1416
1417pub assume_specification<'a, 'b, K, V, A: Allocator>[ OccupiedEntry::get ](
1418 entry: &'b OccupiedEntry::<'a, K, V, A>,
1419) -> (value: &'b V)
1420 ensures
1421 *value == entry.value(),
1422;
1423
1424pub assume_specification<'a, 'b, K, V, A: Allocator>[ OccupiedEntry::get_mut ](
1425 entry: &'b mut OccupiedEntry::<'a, K, V, A>,
1426) -> (value: &'b mut V)
1427 ensures
1428 *value == old(entry).value(),
1429 final(entry).key() == old(entry).key(),
1430 final(entry).value() == *final(value),
1431 final(entry).final_value() == old(entry).final_value(),
1432;
1433
1434pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::into_mut ](
1435 entry: OccupiedEntry::<'a, K, V, A>,
1436) -> (value: &mut V)
1437 ensures
1438 *value == entry.value(),
1439 entry.final_value() == Some(*final(value)),
1440;
1441
1442pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::insert ](
1443 entry: &mut OccupiedEntry::<'a, K, V, A>,
1444 value: V,
1445) -> (old_value: V)
1446 ensures
1447 old_value == old(entry).value(),
1448 final(entry).key() == old(entry).key(),
1449 final(entry).value() == value,
1450 final(entry).final_value() == old(entry).final_value(),
1451;
1452
1453pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::remove ](
1454 entry: OccupiedEntry::<'a, K, V, A>,
1455) -> (value: V)
1456 ensures
1457 value == entry.value(),
1458 entry.final_value() == None,
1459;
1460
1461mod m_vac {
1464 use super::*;
1465
1466 #[verifier::allow_in_spec]
1467 pub assume_specification<'a, 'b, K: 'a, V: 'a, A: Allocator>[ VacantEntry::key ](
1468 entry: &'b VacantEntry::<'a, K, V, A>,
1469 ) -> (key: &'b K)
1470 returns
1471 &entry.spec_key(),
1472 ;
1473
1474}
1475
1476pub assume_specification<'a, K: 'a, V: 'a, A: Allocator>[ VacantEntry::into_key ](
1477 entry: VacantEntry::<'a, K, V, A>,
1478) -> (key: K)
1479 ensures
1480 key == entry.key(),
1481 entry.final_value() == None,
1482;
1483
1484pub assume_specification<'a, K: 'a, V: 'a, A: Allocator>[ VacantEntry::insert ](
1485 entry: VacantEntry::<'a, K, V, A>,
1486 value: V,
1487) -> (value_ref: &mut V)
1488 ensures
1489 *value_ref == value,
1490 entry.final_value() == Some(*final(value_ref)),
1491;
1492
1493pub assume_specification<'a, K: 'a, V: 'a, A: Allocator>[ VacantEntry::insert_entry ](
1494 entry: VacantEntry::<'a, K, V, A>,
1495 value: V,
1496) -> (occ_entry: OccupiedEntry::<'a, K, V, A>)
1497 ensures
1498 occ_entry.key() == entry.key(),
1499 occ_entry.value() == value,
1500 entry.final_value() == occ_entry.final_value(),
1501;
1502
1503pub broadcast group group_hash_axioms {
1504 axiom_box_key_removed,
1505 axiom_contains_deref_key,
1506 axiom_contains_box,
1507 axiom_deref_key_removed,
1508 axiom_maps_deref_key_to_value,
1509 axiom_maps_box_key_to_value,
1510 axiom_hashmap_deepview_borrow,
1511 axiom_hashmap_view_finite_dom,
1512 axiom_bool_obeys_hash_table_key_model,
1513 axiom_u8_obeys_hash_table_key_model,
1514 axiom_u16_obeys_hash_table_key_model,
1515 axiom_u32_obeys_hash_table_key_model,
1516 axiom_u64_obeys_hash_table_key_model,
1517 axiom_u128_obeys_hash_table_key_model,
1518 axiom_usize_obeys_hash_table_key_model,
1519 axiom_i8_obeys_hash_table_key_model,
1520 axiom_i16_obeys_hash_table_key_model,
1521 axiom_i32_obeys_hash_table_key_model,
1522 axiom_i64_obeys_hash_table_key_model,
1523 axiom_i128_obeys_hash_table_key_model,
1524 axiom_isize_obeys_hash_table_key_model,
1525 axiom_box_bool_obeys_hash_table_key_model,
1526 axiom_box_integer_type_obeys_hash_table_key_model,
1527 axiom_random_state_builds_valid_hashers,
1528 axiom_spec_hash_map_len,
1529 axiom_set_box_key_removed,
1530 axiom_set_contains_deref_key,
1531 axiom_set_contains_box,
1532 axiom_set_deref_key_removed,
1533 axiom_set_deref_key_to_value,
1534 axiom_set_box_key_to_value,
1535 axiom_spec_hash_set_len,
1536 axiom_spec_hash_map_iter,
1537 axiom_spec_hash_keys_iter,
1538 axiom_spec_keys_iter,
1539 axiom_spec_values_iter,
1540 axiom_hashmap_decreases,
1541 axiom_hashset_decreases,
1542 axiom_has_resolved_occupied_entry,
1543 axiom_has_resolved_vacant_entry,
1544 axiom_has_resolved_entry,
1545}
1546
1547}