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 m@.dom().map(|k: Key| k.deep_view()),
481 |dk: Key::V|
482 {
483 let k = choose|k: Key| m@.contains_key(k) && #[trigger] k.deep_view() == dk;
484 m@[k].deep_view()
485 },
486 )
487}
488
489pub broadcast proof fn lemma_hashmap_deepview_dom<K: DeepView, V: DeepView>(m: HashMap<K, V>)
490 ensures
491 #[trigger] m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()),
492{
493 reveal(hash_map_deep_view_impl);
494 broadcast use group_hash_axioms;
495 broadcast use crate::vstd::group_vstd_default;
496
497 assert(m.deep_view().dom() =~= m@.dom().map(|k: K| k.deep_view()));
498}
499
500pub broadcast proof fn lemma_hashmap_deepview_properties<K: DeepView, V: DeepView>(m: HashMap<K, V>)
501 requires
502 crate::relations::injective(|k: K| k.deep_view()),
503 ensures
504 #![trigger m.deep_view()]
505 forall|k: K| #[trigger]
507 m@.contains_key(k) ==> m.deep_view().contains_key(k.deep_view())
508 && m.deep_view()[k.deep_view()] == m@[k].deep_view(),
509 forall|dk: <K as DeepView>::V| #[trigger]
511 m.deep_view().contains_key(dk) ==> exists|k: K|
512 k.deep_view() == dk && #[trigger] m@.contains_key(k),
513{
514 reveal(hash_map_deep_view_impl);
515 broadcast use group_hash_axioms;
516 broadcast use crate::vstd::group_vstd_default;
517
518 lemma_hashmap_deepview_dom(m);
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(m@.dom().contains(k));
524 assert(m@.dom().map(|k: K| k.deep_view()).contains(k.deep_view()));
525 assert(m.deep_view().dom().contains(k.deep_view()));
526 let k2 = choose|k2: K| m@.contains_key(k2) && #[trigger] k2.deep_view() == k.deep_view();
527 assert forall|k1: K, k2: K| #[trigger]
528 k1.deep_view() == #[trigger] k2.deep_view() implies k1 == k2 by {
529 let ghost k_deepview = |k: K| k.deep_view();
530 assert(crate::relations::injective(k_deepview));
531 assert(k_deepview(k1) == k_deepview(k2));
532 }
533 assert(k2 == k);
534 }
535 assert forall|dk: K::V| #[trigger] m.deep_view().contains_key(dk) implies exists|k: K|
536 k.deep_view() == dk && #[trigger] m@.contains_key(k) by {
537 assert(m.deep_view().dom().contains(dk));
538 assert(m@.dom().map(|k: K| k.deep_view()).contains(dk));
539 let k = choose|k: K| #[trigger] m@.dom().contains(k) && k.deep_view() == dk;
540 assert(m@.contains_key(k));
541 }
542}
543
544pub broadcast proof fn lemma_hashmap_deepview_values<K: DeepView, V: DeepView>(m: HashMap<K, V>)
545 requires
546 crate::relations::injective(|k: K| k.deep_view()),
547 ensures
548 #[trigger] m.deep_view().values() =~= m@.values().map(|v: V| v.deep_view()),
549{
550 reveal(hash_map_deep_view_impl);
551 broadcast use group_hash_axioms;
552 broadcast use lemma_hashmap_deepview_properties;
553 broadcast use crate::vstd::group_vstd_default;
554
555 let lhs = m.deep_view().values();
556 let rhs = m@.values().map(|v: V| v.deep_view());
557 assert forall|v: V::V| #[trigger] lhs.contains(v) implies rhs.contains(v) by {
558 let dk = choose|dk: K::V| #[trigger]
559 m.deep_view().contains_key(dk) && m.deep_view()[dk] == v;
560 let k = choose|k: K| #[trigger] m@.contains_key(k) && k.deep_view() == dk;
561 let ov = choose|ov: V| #[trigger] m@.contains_key(k) && m@[k] == ov && ov.deep_view() == v;
562 assert(v == ov.deep_view());
563 assert(m@.values().contains(ov));
564 }
565}
566
567pub broadcast proof fn axiom_hashmap_deepview_borrow<
570 K: DeepView + Borrow<Q>,
571 V: DeepView,
572 Q: View<V = <K as DeepView>::V> + Hash + Eq + ?Sized,
573>(m: HashMap<K, V>, k: &Q)
574 requires
575 obeys_key_model::<K>(),
576 crate::relations::injective(|k: K| k.deep_view()),
577 ensures
578 #[trigger] contains_borrowed_key(m@, k) <==> m.deep_view().contains_key(k@),
579{
580 admit();
581}
582
583pub uninterp spec fn spec_hash_map_len<Key, Value, S, A: Allocator>(
584 m: &HashMap<Key, Value, S, A>,
585) -> usize;
586
587pub broadcast proof fn axiom_spec_hash_map_len<Key, Value, S, A: Allocator>(
588 m: &HashMap<Key, Value, S, A>,
589)
590 ensures
591 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> #[trigger] spec_hash_map_len(m)
592 == m@.len(),
593{
594 admit();
595}
596
597#[verifier::when_used_as_spec(spec_hash_map_len)]
598pub assume_specification<Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::len ](
599 m: &HashMap<Key, Value, S, A>,
600) -> (len: usize)
601 ensures
602 len == spec_hash_map_len(m),
603;
604
605pub assume_specification<Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::is_empty ](
606 m: &HashMap<Key, Value, S, A>,
607) -> (res: bool)
608 ensures
609 res == m@.is_empty(),
610;
611
612pub assume_specification<K: Clone, V: Clone, S: Clone, A: Allocator + Clone>[ <HashMap::<
613 K,
614 V,
615 S,
616 A,
617> as Clone>::clone ](this: &HashMap<K, V, S, A>) -> (other: HashMap<K, V, S, A>)
618 ensures
619 other@.dom() == this@.dom(),
620 forall|key|
621 #![trigger other@.dom().contains(key)]
622 other@.dom().contains(key) ==> cloned(this@[key], #[trigger] other@[key]),
623;
624
625pub assume_specification<Key, Value>[ HashMap::<Key, Value>::new ]() -> (m: HashMap<
626 Key,
627 Value,
628 RandomState,
629>)
630 ensures
631 m@ == Map::<Key, Value>::empty(),
632;
633
634pub assume_specification<K, V, S: core::default::Default>[ <HashMap<
635 K,
636 V,
637 S,
638> as core::default::Default>::default ]() -> (m: HashMap<K, V, S>)
639 ensures
640 m@ == Map::<K, V>::empty(),
641;
642
643pub assume_specification<Key, Value>[ HashMap::<Key, Value>::with_capacity ](capacity: usize) -> (m:
644 HashMap<Key, Value, RandomState>)
645 ensures
646 m@ == Map::<Key, Value>::empty(),
647;
648
649pub assume_specification<Key: Eq + Hash, Value, S: BuildHasher, A: Allocator>[ HashMap::<
650 Key,
651 Value,
652 S,
653 A,
654>::reserve ](m: &mut HashMap<Key, Value, S, A>, additional: usize)
655 ensures
656 final(m)@ == old(m)@,
657;
658
659pub assume_specification<Key: Eq + Hash, Value, S: BuildHasher, A: Allocator>[ HashMap::<
660 Key,
661 Value,
662 S,
663 A,
664>::insert ](m: &mut HashMap<Key, Value, S, A>, k: Key, v: Value) -> (result: Option<Value>)
665 ensures
666 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
667 &&& final(m)@ == old(m)@.insert(k, v)
668 &&& match result {
669 Some(v) => old(m)@.contains_key(k) && v == old(m)[k],
670 None => !old(m)@.contains_key(k),
671 }
672 },
673;
674
675pub uninterp spec fn contains_borrowed_key<Key, Value, Q: ?Sized>(
690 m: Map<Key, Value>,
691 k: &Q,
692) -> bool;
693
694pub broadcast proof fn axiom_contains_deref_key<Q, Value>(m: Map<Q, Value>, k: &Q)
695 ensures
696 #[trigger] contains_borrowed_key::<Q, Value, Q>(m, k) <==> m.contains_key(*k),
697{
698 admit();
699}
700
701pub broadcast proof fn axiom_contains_box<Q, Value>(m: Map<Box<Q>, Value>, k: &Q)
702 ensures
703 #[trigger] contains_borrowed_key::<Box<Q>, Value, Q>(m, k) <==> m.contains_key(
704 Box::new(*k),
705 ),
706{
707 admit();
708}
709
710pub assume_specification<
711 Key: Borrow<Q> + Hash + Eq,
712 Value,
713 S: BuildHasher,
714 A: Allocator,
715 Q: Hash + Eq + ?Sized,
716>[ HashMap::<Key, Value, S, A>::contains_key::<Q> ](
717 m: &HashMap<Key, Value, S, A>,
718 k: &Q,
719) -> (result: bool)
720 ensures
721 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> result == contains_borrowed_key(
722 m@,
723 k,
724 ),
725;
726
727pub uninterp spec fn maps_borrowed_key_to_value<Key, Value, Q: ?Sized>(
744 m: Map<Key, Value>,
745 k: &Q,
746 v: Value,
747) -> bool;
748
749pub broadcast proof fn axiom_maps_deref_key_to_value<Q, Value>(m: Map<Q, Value>, k: &Q, v: Value)
750 ensures
751 #[trigger] maps_borrowed_key_to_value::<Q, Value, Q>(m, k, v) <==> m.contains_key(*k)
752 && m[*k] == v,
753{
754 admit();
755}
756
757pub broadcast proof fn axiom_maps_box_key_to_value<Q, Value>(m: Map<Box<Q>, Value>, q: &Q, v: Value)
758 ensures
759 #[trigger] maps_borrowed_key_to_value::<Box<Q>, Value, Q>(m, q, v) <==> {
760 let k = Box::new(*q);
761 &&& m.contains_key(k)
762 &&& m[k] == v
763 },
764{
765 admit();
766}
767
768pub assume_specification<
769 'a,
770 Key: Borrow<Q> + Hash + Eq,
771 Value,
772 S: BuildHasher,
773 A: Allocator,
774 Q: Hash + Eq + ?Sized,
775>[ HashMap::<Key, Value, S, A>::get::<Q> ](m: &'a HashMap<Key, Value, S, A>, k: &Q) -> (result:
776 Option<&'a Value>)
777 ensures
778 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> match result {
779 Some(v) => maps_borrowed_key_to_value(m@, k, *v),
780 None => !contains_borrowed_key(m@, k),
781 },
782;
783
784pub uninterp spec fn borrowed_key_removed<Key, Value, Q: ?Sized>(
800 old_m: Map<Key, Value>,
801 new_m: Map<Key, Value>,
802 k: &Q,
803) -> bool;
804
805pub broadcast proof fn axiom_deref_key_removed<Q, Value>(
806 old_m: Map<Q, Value>,
807 new_m: Map<Q, Value>,
808 k: &Q,
809)
810 ensures
811 #[trigger] borrowed_key_removed::<Q, Value, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
812 *k,
813 ),
814{
815 admit();
816}
817
818pub broadcast proof fn axiom_box_key_removed<Q, Value>(
819 old_m: Map<Box<Q>, Value>,
820 new_m: Map<Box<Q>, Value>,
821 q: &Q,
822)
823 ensures
824 #[trigger] borrowed_key_removed::<Box<Q>, Value, Q>(old_m, new_m, q) <==> new_m
825 == old_m.remove(Box::new(*q)),
826{
827 admit();
828}
829
830pub assume_specification<
831 Key: Borrow<Q> + Hash + Eq,
832 Value,
833 S: BuildHasher,
834 A: Allocator,
835 Q: Hash + Eq + ?Sized,
836>[ HashMap::<Key, Value, S, A>::remove::<Q> ](m: &mut HashMap<Key, Value, S, A>, k: &Q) -> (result:
837 Option<Value>)
838 ensures
839 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
840 &&& borrowed_key_removed(old(m)@, final(m)@, k)
841 &&& match result {
842 Some(v) => maps_borrowed_key_to_value(old(m)@, k, v),
843 None => !contains_borrowed_key(old(m)@, k),
844 }
845 },
846;
847
848pub assume_specification<Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::clear ](
849 m: &mut HashMap<Key, Value, S, A>,
850)
851 ensures
852 final(m)@ == Map::<Key, Value>::empty(),
853;
854
855pub uninterp spec fn spec_keys_iter<'a, Key, Value, S, A: Allocator>(
862 m: &'a HashMap<Key, Value, S, A>,
863) -> (keys: Keys<'a, Key, Value>);
864
865pub broadcast proof fn axiom_spec_keys_iter<'a, Key, Value, S, A: Allocator>(
866 m: &'a HashMap<Key, Value, S, A>,
867)
868 ensures
869 (#[trigger] spec_keys_iter(m).remaining()).unref().to_set() == m@.dom(),
870 spec_keys_iter(m).remaining().no_duplicates(),
871 spec_keys_iter(m).remaining().len() == m@.dom().len(),
872{
873 admit();
874}
875
876#[verifier::when_used_as_spec(spec_keys_iter)]
877pub assume_specification<'a, Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::keys ](
878 m: &'a HashMap<Key, Value, S, A>,
879) -> (keys: Keys<'a, Key, Value>)
880 ensures
881 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
882 &&& keys == spec_keys_iter(m)
883 &&& IteratorSpec::decrease(&keys) is Some
884 &&& IteratorSpec::initial_value_relation(&keys, &keys)
885 },
886;
887
888pub uninterp spec fn spec_values_iter<'a, Key, Value, S, A: Allocator>(
895 m: &'a HashMap<Key, Value, S, A>,
896) -> (values: Values<'a, Key, Value>);
897
898pub broadcast proof fn axiom_spec_values_iter<'a, Key, Value, S, A: Allocator>(
899 m: &'a HashMap<Key, Value, S, A>,
900)
901 ensures
902 (#[trigger] spec_values_iter(m).remaining()).unref().to_set() == m@.values(),
903 spec_values_iter(m).remaining().len() == m@.dom().len(),
904{
905 admit();
906}
907
908#[verifier::when_used_as_spec(spec_values_iter)]
909pub assume_specification<'a, Key, Value, S, A: Allocator>[ HashMap::<Key, Value, S, A>::values ](
910 m: &'a HashMap<Key, Value, S, A>,
911) -> (values: Values<'a, Key, Value>)
912 ensures
913 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
914 &&& values == spec_values_iter(m)
915 &&& IteratorSpec::decrease(&values) is Some
916 &&& IteratorSpec::initial_value_relation(&values, &values)
917 },
918;
919
920pub broadcast proof fn axiom_hashmap_decreases<Key, Value, S>(m: HashMap<Key, Value, S>)
921 ensures
922 #[trigger] (decreases_to!(m => m@)),
923{
924 admit();
925}
926
927#[verifier::external_type_specification]
930#[verifier::external_body]
931#[verifier::accept_recursive_types(Key)]
932pub struct ExSetIter<'a, Key: 'a>(hash_set::Iter<'a, Key>);
933
934pub uninterp spec fn into_iter_hash_keys<'a, Key>(i: hash_set::Iter::<'a, Key>) -> Seq<Key>;
937
938impl<'a, K> super::iter::IteratorSpecImpl for hash_set::Iter::<'a, K> {
939 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
940 true
941 }
942
943 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
944
945 uninterp spec fn will_return_none(&self) -> bool;
946
947 #[verifier::prophetic]
948 open spec fn initial_value_relation(&self, init: &Self) -> bool {
949 &&& IteratorSpec::remaining(init) == IteratorSpec::remaining(self)
950 &&& into_iter_hash_keys(*self) == IteratorSpec::remaining(self).unref()
951 }
952
953 uninterp spec fn decrease(&self) -> Option<nat>;
954
955 open spec fn peek(&self, index: int) -> Option<Self::Item> {
956 if 0 <= index < into_iter_hash_keys(*self).len() {
957 Some(&into_iter_hash_keys(*self)[index])
958 } else {
959 None
960 }
961 }
962}
963
964#[verifier::external_type_specification]
976#[verifier::external_body]
977#[verifier::accept_recursive_types(Key)]
978#[verifier::reject_recursive_types(S)]
979#[verifier::reject_recursive_types(A)]
980pub struct ExHashSet<Key, S, A: Allocator>(HashSet<Key, S, A>);
981
982pub uninterp spec fn spec_hash_set_len<Key, S, A: Allocator>(m: &HashSet<Key, S, A>) -> usize;
983
984pub broadcast proof fn axiom_spec_hash_set_len<Key, S, A: Allocator>(m: &HashSet<Key, S, A>)
985 ensures
986 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> #[trigger] spec_hash_set_len(m)
987 == m@.len(),
988{
989 admit();
990}
991
992#[verifier::when_used_as_spec(spec_hash_set_len)]
993pub assume_specification<Key, S, A: Allocator>[ HashSet::<Key, S, A>::len ](
994 m: &HashSet<Key, S, A>,
995) -> (len: usize)
996 ensures
997 len == spec_hash_set_len(m),
998;
999
1000pub assume_specification<Key, S, A: Allocator>[ HashSet::<Key, S, A>::is_empty ](
1001 m: &HashSet<Key, S, A>,
1002) -> (res: bool)
1003 ensures
1004 res == m@.is_empty(),
1005;
1006
1007pub assume_specification<Key>[ HashSet::<Key>::new ]() -> (m: HashSet<Key, RandomState>)
1008 ensures
1009 m@ == Set::<Key>::empty(),
1010;
1011
1012pub assume_specification<T, S: core::default::Default>[ <HashSet<
1013 T,
1014 S,
1015> as core::default::Default>::default ]() -> (m: HashSet<T, S>)
1016 ensures
1017 m@ == Set::<T>::empty(),
1018;
1019
1020pub assume_specification<Key>[ HashSet::<Key>::with_capacity ](capacity: usize) -> (m: HashSet<
1021 Key,
1022 RandomState,
1023>)
1024 ensures
1025 m@ == Set::<Key>::empty(),
1026;
1027
1028pub assume_specification<Key: Eq + Hash, S: BuildHasher, A: Allocator>[ HashSet::<
1029 Key,
1030 S,
1031 A,
1032>::reserve ](m: &mut HashSet<Key, S, A>, additional: usize)
1033 ensures
1034 final(m)@ == old(m)@,
1035;
1036
1037pub assume_specification<Key: Eq + Hash, S: BuildHasher, A: Allocator>[ HashSet::<
1038 Key,
1039 S,
1040 A,
1041>::insert ](m: &mut HashSet<Key, S, A>, k: Key) -> (result: bool)
1042 ensures
1043 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
1044 &&& final(m)@ == old(m)@.insert(k)
1045 &&& result == !old(m)@.contains(k)
1046 },
1047;
1048
1049pub uninterp spec fn set_contains_borrowed_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q) -> bool;
1064
1065pub broadcast proof fn axiom_set_contains_deref_key<Q>(m: Set<Q>, k: &Q)
1066 ensures
1067 #[trigger] set_contains_borrowed_key::<Q, Q>(m, k) <==> m.contains(*k),
1068{
1069 admit();
1070}
1071
1072pub broadcast proof fn axiom_set_contains_box<Q>(m: Set<Box<Q>>, k: &Q)
1073 ensures
1074 #[trigger] set_contains_borrowed_key::<Box<Q>, Q>(m, k) <==> m.contains(Box::new(*k)),
1075{
1076 admit();
1077}
1078
1079pub assume_specification<
1080 Key: Borrow<Q> + Hash + Eq,
1081 S: BuildHasher,
1082 A: Allocator,
1083 Q: Hash + Eq + ?Sized,
1084>[ HashSet::<Key, S, A>::contains ](m: &HashSet<Key, S, A>, k: &Q) -> (result: bool)
1085 ensures
1086 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> result
1087 == set_contains_borrowed_key(m@, k),
1088;
1089
1090pub uninterp spec fn sets_borrowed_key_to_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q, v: &Key) -> bool;
1107
1108pub broadcast proof fn axiom_set_deref_key_to_value<Q>(m: Set<Q>, k: &Q, v: &Q)
1109 ensures
1110 #[trigger] sets_borrowed_key_to_key::<Q, Q>(m, k, v) <==> m.contains(*k) && k == v,
1111{
1112 admit();
1113}
1114
1115pub broadcast proof fn axiom_set_box_key_to_value<Q>(m: Set<Box<Q>>, q: &Q, v: &Box<Q>)
1116 ensures
1117 #[trigger] sets_borrowed_key_to_key::<Box<Q>, Q>(m, q, v) <==> (m.contains(*v) && Box::new(
1118 *q,
1119 ) == v),
1120{
1121 admit();
1122}
1123
1124pub assume_specification<
1125 'a,
1126 Key: Borrow<Q> + Hash + Eq,
1127 S: BuildHasher,
1128 A: Allocator,
1129 Q: Hash + Eq + ?Sized,
1130>[ HashSet::<Key, S, A>::get::<Q> ](m: &'a HashSet<Key, S, A>, k: &Q) -> (result: Option<&'a Key>)
1131 ensures
1132 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> match result {
1133 Some(v) => sets_borrowed_key_to_key(m@, k, v),
1134 None => !set_contains_borrowed_key(m@, k),
1135 },
1136;
1137
1138pub uninterp spec fn sets_differ_by_borrowed_key<Key, Q: ?Sized>(
1153 old_m: Set<Key>,
1154 new_m: Set<Key>,
1155 k: &Q,
1156) -> bool;
1157
1158pub broadcast proof fn axiom_set_deref_key_removed<Q>(old_m: Set<Q>, new_m: Set<Q>, k: &Q)
1159 ensures
1160 #[trigger] sets_differ_by_borrowed_key::<Q, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
1161 *k,
1162 ),
1163{
1164 admit();
1165}
1166
1167pub broadcast proof fn axiom_set_box_key_removed<Q>(old_m: Set<Box<Q>>, new_m: Set<Box<Q>>, q: &Q)
1168 ensures
1169 #[trigger] sets_differ_by_borrowed_key::<Box<Q>, Q>(old_m, new_m, q) <==> new_m
1170 == old_m.remove(Box::new(*q)),
1171{
1172 admit();
1173}
1174
1175pub assume_specification<
1176 Key: Borrow<Q> + Hash + Eq,
1177 S: BuildHasher,
1178 A: Allocator,
1179 Q: Hash + Eq + ?Sized,
1180>[ HashSet::<Key, S, A>::remove::<Q> ](m: &mut HashSet<Key, S, A>, k: &Q) -> (result: bool)
1181 ensures
1182 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
1183 &&& sets_differ_by_borrowed_key(old(m)@, final(m)@, k)
1184 &&& result == set_contains_borrowed_key(old(m)@, k)
1185 },
1186;
1187
1188pub assume_specification<Key, S, A: Allocator>[ HashSet::<Key, S, A>::clear ](
1189 m: &mut HashSet<Key, S, A>,
1190)
1191 ensures
1192 final(m)@ == Set::<Key>::empty(),
1193;
1194
1195pub uninterp spec fn spec_hash_keys_iter<'a, Key, S, A: Allocator>(m: &'a HashSet<Key, S, A>) -> (r:
1202 hash_set::Iter<'a, Key>);
1203
1204pub broadcast proof fn axiom_spec_hash_keys_iter<'a, Key, S, A: Allocator>(
1205 m: &'a HashSet<Key, S, A>,
1206)
1207 ensures
1208 (#[trigger] spec_hash_keys_iter(m).remaining()).unref().to_set() == m@,
1209 spec_hash_keys_iter(m).remaining().no_duplicates(),
1210 spec_hash_keys_iter(m).remaining().len() == m@.len(),
1211{
1212 admit();
1213}
1214
1215#[verifier::when_used_as_spec(spec_hash_keys_iter)]
1216pub assume_specification<'a, Key, S, A: Allocator>[ HashSet::<Key, S, A>::iter ](
1217 m: &'a HashSet<Key, S, A>,
1218) -> (hash_keys: hash_set::Iter<'a, Key>)
1219 ensures
1220 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> {
1221 &&& hash_keys == spec_hash_keys_iter(m)
1222 &&& IteratorSpec::decrease(&hash_keys) is Some
1223 &&& IteratorSpec::initial_value_relation(&hash_keys, &hash_keys)
1224 },
1225;
1226
1227pub broadcast proof fn axiom_hashset_decreases<Key, S, A: Allocator>(m: HashSet<Key, S, A>)
1228 ensures
1229 #[trigger] (decreases_to!(m => m@)),
1230{
1231 admit();
1232}
1233
1234#[verifier::reject_recursive_types_in_ground_variants(K)]
1239#[verifier::reject_recursive_types_in_ground_variants(V)]
1240#[verifier::reject_recursive_types(A)]
1241#[verifier::external_body]
1242#[verifier::external_type_specification]
1243pub struct ExOccupiedEntry<'a, K: 'a, V: 'a, A: Allocator>(OccupiedEntry<'a, K, V, A>);
1244
1245#[verifier::reject_recursive_types_in_ground_variants(K)]
1246#[verifier::accept_recursive_types(V)]
1247#[verifier::reject_recursive_types(A)]
1248#[verifier::external_body]
1249#[verifier::external_type_specification]
1250pub struct ExVacantEntry<'a, K: 'a, V: 'a, A: Allocator>(VacantEntry<'a, K, V, A>);
1251
1252#[verifier::external_type_specification]
1253#[verifier::reject_recursive_types(A)]
1254pub struct ExEntry<'a, K: 'a, V: 'a, A: Allocator>(Entry<'a, K, V, A>);
1255
1256pub trait OccupiedEntrySpecFns<K, V, A>: Sized {
1261 spec fn spec_key(self) -> K;
1262
1263 spec fn value(self) -> V;
1264
1265 #[verifier::prophetic]
1266 spec fn final_value(self) -> Option<V>;
1267}
1268
1269impl<'a, K, V, A: Allocator> OccupiedEntrySpecFns<K, V, A> for OccupiedEntry<'a, K, V, A> {
1270 uninterp spec fn spec_key(self) -> K;
1271
1272 uninterp spec fn value(self) -> V;
1273
1274 #[verifier::prophetic]
1275 uninterp spec fn final_value(self) -> Option<V>;
1276}
1277
1278pub trait VacantEntrySpecFns<K, V, A>: Sized {
1283 spec fn spec_key(self) -> K;
1284
1285 #[verifier::prophetic]
1286 spec fn final_value(self) -> Option<V>;
1287}
1288
1289impl<'a, K, V, A: Allocator> VacantEntrySpecFns<K, V, A> for VacantEntry<'a, K, V, A> {
1290 uninterp spec fn spec_key(self) -> K;
1291
1292 #[verifier::prophetic]
1293 uninterp spec fn final_value(self) -> Option<V>;
1294}
1295
1296pub trait EntrySpecFns<K, V, A>: Sized {
1300 spec fn spec_key(self) -> K;
1301
1302 spec fn value(self) -> Option<V>;
1303
1304 #[verifier::prophetic]
1305 spec fn final_value(self) -> Option<V>;
1306}
1307
1308impl<'a, K, V, A: Allocator> EntrySpecFns<K, V, A> for Entry<'a, K, V, A> {
1309 open spec fn spec_key(self) -> K {
1310 match self {
1311 Entry::Occupied(occupied_entry) => occupied_entry.spec_key(),
1312 Entry::Vacant(vacant_entry) => vacant_entry.spec_key(),
1313 }
1314 }
1315
1316 open spec fn value(self) -> Option<V> {
1317 match self {
1318 Entry::Occupied(occupied_entry) => Some(occupied_entry.value()),
1319 Entry::Vacant(vacant_entry) => None,
1320 }
1321 }
1322
1323 #[verifier::prophetic]
1324 open spec fn final_value(self) -> Option<V> {
1325 match self {
1326 Entry::Occupied(occupied_entry) => occupied_entry.final_value(),
1327 Entry::Vacant(vacant_entry) => vacant_entry.final_value(),
1328 }
1329 }
1330}
1331
1332pub broadcast axiom fn axiom_has_resolved_occupied_entry<K, V, A: Allocator>(
1333 entry: OccupiedEntry<K, V, A>,
1334)
1335 ensures
1336 #[trigger] has_resolved(entry) ==> entry.final_value() == Some(entry.value()),
1337;
1338
1339pub broadcast axiom fn axiom_has_resolved_vacant_entry<K, V, A: Allocator>(
1340 entry: VacantEntry<K, V, A>,
1341)
1342 ensures
1343 #[trigger] has_resolved(entry) ==> entry.final_value() == None::<V>,
1344;
1345
1346pub broadcast proof fn axiom_has_resolved_entry<K, V, A: Allocator>(entry: Entry<K, V, A>)
1347 ensures
1348 #[trigger] has_resolved(entry) ==> entry.final_value() == entry.value(),
1349{
1350 broadcast use axiom_has_resolved_occupied_entry;
1351 broadcast use axiom_has_resolved_vacant_entry;
1352
1353}
1354
1355pub assume_specification<'a, Key: Hash + Eq, Value, S: BuildHasher, A: Allocator>[ HashMap::<
1356 Key,
1357 Value,
1358 S,
1359 A,
1360>::entry ](m: &'a mut HashMap<Key, Value, S, A>, key: Key) -> (entry: Entry<'a, Key, Value, A>)
1361 ensures
1362 obeys_key_model::<Key>() && builds_valid_hashers::<S>() ==> (entry.key() == key
1363 && entry.value() == old(m)@.get(key) && final(m)@ == (match entry.final_value() {
1364 Some(value) => old(m)@.insert(key, value),
1365 None => old(m)@.remove(key),
1366 })),
1367;
1368
1369#[verifier::allow_in_spec]
1371pub assume_specification<'a, 'b, K, V, A: Allocator>[ Entry::key ](
1372 entry: &'b Entry::<'a, K, V, A>,
1373) -> (key: &'b K)
1374 returns
1375 &entry.spec_key(),
1376;
1377
1378pub assume_specification<'a, K, V, A: Allocator>[ Entry::or_insert ](
1379 entry: Entry::<'a, K, V, A>,
1380 default: V,
1381) -> (value: &'a mut V)
1382 ensures
1383 *value == (match entry.value() {
1384 Some(v) => v,
1385 None => default,
1386 }),
1387 entry.final_value() == Some(*final(value)),
1388;
1389
1390pub assume_specification<'a, K, V, A: Allocator>[ Entry::insert_entry ](
1391 entry: Entry::<'a, K, V, A>,
1392 value: V,
1393) -> (occ_entry: OccupiedEntry<'a, K, V, A>)
1394 ensures
1395 occ_entry.key() == entry.key(),
1396 occ_entry.value() == value,
1397 entry.final_value() == occ_entry.final_value(),
1398;
1399
1400mod m_occ {
1403 use super::*;
1404
1405 #[verifier::allow_in_spec]
1406 pub assume_specification<'a, 'b, K, V, A: Allocator>[ OccupiedEntry::key ](
1407 entry: &'b OccupiedEntry::<'a, K, V, A>,
1408 ) -> (key: &'b K)
1409 returns
1410 &entry.spec_key(),
1411 ;
1412
1413}
1414
1415pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::remove_entry ](
1416 entry: OccupiedEntry::<'a, K, V, A>,
1417) -> (kv: (K, V))
1418 ensures
1419 entry.final_value() == None,
1420 returns
1421 (*entry.key(), entry.value()),
1422;
1423
1424pub assume_specification<'a, 'b, K, V, A: Allocator>[ OccupiedEntry::get ](
1425 entry: &'b OccupiedEntry::<'a, K, V, A>,
1426) -> (value: &'b V)
1427 ensures
1428 *value == entry.value(),
1429;
1430
1431pub assume_specification<'a, 'b, K, V, A: Allocator>[ OccupiedEntry::get_mut ](
1432 entry: &'b mut OccupiedEntry::<'a, K, V, A>,
1433) -> (value: &'b mut V)
1434 ensures
1435 *value == old(entry).value(),
1436 final(entry).key() == old(entry).key(),
1437 final(entry).value() == *final(value),
1438 final(entry).final_value() == old(entry).final_value(),
1439;
1440
1441pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::into_mut ](
1442 entry: OccupiedEntry::<'a, K, V, A>,
1443) -> (value: &mut V)
1444 ensures
1445 *value == entry.value(),
1446 entry.final_value() == Some(*final(value)),
1447;
1448
1449pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::insert ](
1450 entry: &mut OccupiedEntry::<'a, K, V, A>,
1451 value: V,
1452) -> (old_value: V)
1453 ensures
1454 old_value == old(entry).value(),
1455 final(entry).key() == old(entry).key(),
1456 final(entry).value() == value,
1457 final(entry).final_value() == old(entry).final_value(),
1458;
1459
1460pub assume_specification<'a, K, V, A: Allocator>[ OccupiedEntry::remove ](
1461 entry: OccupiedEntry::<'a, K, V, A>,
1462) -> (value: V)
1463 ensures
1464 value == entry.value(),
1465 entry.final_value() == None,
1466;
1467
1468mod m_vac {
1471 use super::*;
1472
1473 #[verifier::allow_in_spec]
1474 pub assume_specification<'a, 'b, K: 'a, V: 'a, A: Allocator>[ VacantEntry::key ](
1475 entry: &'b VacantEntry::<'a, K, V, A>,
1476 ) -> (key: &'b K)
1477 returns
1478 &entry.spec_key(),
1479 ;
1480
1481}
1482
1483pub assume_specification<'a, K: 'a, V: 'a, A: Allocator>[ VacantEntry::into_key ](
1484 entry: VacantEntry::<'a, K, V, A>,
1485) -> (key: K)
1486 ensures
1487 key == entry.key(),
1488 entry.final_value() == None,
1489;
1490
1491pub assume_specification<'a, K: 'a, V: 'a, A: Allocator>[ VacantEntry::insert ](
1492 entry: VacantEntry::<'a, K, V, A>,
1493 value: V,
1494) -> (value_ref: &mut V)
1495 ensures
1496 *value_ref == value,
1497 entry.final_value() == Some(*final(value_ref)),
1498;
1499
1500pub assume_specification<'a, K: 'a, V: 'a, A: Allocator>[ VacantEntry::insert_entry ](
1501 entry: VacantEntry::<'a, K, V, A>,
1502 value: V,
1503) -> (occ_entry: OccupiedEntry::<'a, K, V, A>)
1504 ensures
1505 occ_entry.key() == entry.key(),
1506 occ_entry.value() == value,
1507 entry.final_value() == occ_entry.final_value(),
1508;
1509
1510pub broadcast group group_hash_axioms {
1511 axiom_box_key_removed,
1512 axiom_contains_deref_key,
1513 axiom_contains_box,
1514 axiom_deref_key_removed,
1515 axiom_maps_deref_key_to_value,
1516 axiom_maps_box_key_to_value,
1517 axiom_hashmap_deepview_borrow,
1518 axiom_bool_obeys_hash_table_key_model,
1519 axiom_u8_obeys_hash_table_key_model,
1520 axiom_u16_obeys_hash_table_key_model,
1521 axiom_u32_obeys_hash_table_key_model,
1522 axiom_u64_obeys_hash_table_key_model,
1523 axiom_u128_obeys_hash_table_key_model,
1524 axiom_usize_obeys_hash_table_key_model,
1525 axiom_i8_obeys_hash_table_key_model,
1526 axiom_i16_obeys_hash_table_key_model,
1527 axiom_i32_obeys_hash_table_key_model,
1528 axiom_i64_obeys_hash_table_key_model,
1529 axiom_i128_obeys_hash_table_key_model,
1530 axiom_isize_obeys_hash_table_key_model,
1531 axiom_box_bool_obeys_hash_table_key_model,
1532 axiom_box_integer_type_obeys_hash_table_key_model,
1533 axiom_random_state_builds_valid_hashers,
1534 axiom_spec_hash_map_len,
1535 axiom_set_box_key_removed,
1536 axiom_set_contains_deref_key,
1537 axiom_set_contains_box,
1538 axiom_set_deref_key_removed,
1539 axiom_set_deref_key_to_value,
1540 axiom_set_box_key_to_value,
1541 axiom_spec_hash_set_len,
1542 axiom_spec_hash_map_iter,
1543 axiom_spec_hash_keys_iter,
1544 axiom_spec_keys_iter,
1545 axiom_spec_values_iter,
1546 axiom_hashmap_decreases,
1547 axiom_hashset_decreases,
1548 axiom_has_resolved_occupied_entry,
1549 axiom_has_resolved_vacant_entry,
1550 axiom_has_resolved_entry,
1551}
1552
1553}