1use super::super::laws_cmp::obeys_cmp;
12use super::super::prelude::*;
13use super::cmp::OrdSpec;
14use super::iter::IteratorSpec;
15
16use alloc::alloc::Allocator;
17use alloc::boxed::Box;
18use alloc::collections::btree_map;
19use alloc::collections::btree_map::{Keys, Values};
20use alloc::collections::btree_set;
21use alloc::collections::{BTreeMap, BTreeSet};
22use core::borrow::Borrow;
23use core::marker::PhantomData;
24use core::option::Option;
25
26verus! {
27
28pub uninterp spec fn key_obeys_cmp_spec<Key: ?Sized>() -> bool;
37
38pub broadcast axiom fn axiom_key_obeys_cmp_spec_meaning<K: Ord>()
40 ensures
41 #[trigger] key_obeys_cmp_spec::<K>() <==> obeys_cmp::<K>(),
42;
43
44pub uninterp spec fn increasing_seq<K>(s: Seq<K>) -> bool;
49
50pub broadcast axiom fn axiom_increasing_seq_meaning<K: Ord>(s: Seq<K>)
52 requires
53 obeys_cmp::<K>(),
54 ensures
55 #[trigger] increasing_seq(s) <==> forall|i, j|
56 0 <= i < j < s.len() ==> s[i].cmp_spec(&s[j]) is Less,
57;
58
59#[verifier::external_type_specification]
62#[verifier::external_body]
63#[verifier::accept_recursive_types(Key)]
64#[verifier::accept_recursive_types(Value)]
65pub struct ExKeys<'a, Key, Value>(Keys<'a, Key, Value>);
66
67pub uninterp spec fn into_iter_keys<'a, Key, Value>(i: Keys<'a, Key, Value>) -> Seq<Key>;
70
71impl<'a, K, V> super::iter::IteratorSpecImpl for Keys<'a, K, V> {
72 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
73 true
74 }
75
76 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
77
78 uninterp spec fn will_return_none(&self) -> bool;
79
80 uninterp spec fn decrease(&self) -> Option<nat>;
81
82 open spec fn peek(&self, index: int) -> Option<Self::Item> {
83 if 0 <= index < into_iter_keys(*self).len() {
84 Some(&into_iter_keys(*self)[index])
85 } else {
86 None
87 }
88 }
89}
90
91#[verifier::external_type_specification]
94#[verifier::external_body]
95#[verifier::accept_recursive_types(Key)]
96#[verifier::accept_recursive_types(Value)]
97pub struct ExValues<'a, Key, Value>(Values<'a, Key, Value>);
98
99pub uninterp spec fn into_iter_values<'a, Key, Value>(i: Values<'a, Key, Value>) -> Seq<Value>;
102
103impl<'a, K, V> super::iter::IteratorSpecImpl for Values<'a, K, V> {
104 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
105 true
106 }
107
108 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
109
110 uninterp spec fn will_return_none(&self) -> bool;
111
112 uninterp spec fn decrease(&self) -> Option<nat>;
113
114 open spec fn peek(&self, index: int) -> Option<Self::Item> {
115 if 0 <= index < into_iter_values(*self).len() {
116 Some(&into_iter_values(*self)[index])
117 } else {
118 None
119 }
120 }
121}
122
123#[verifier::external_type_specification]
126#[verifier::external_body]
127#[verifier::accept_recursive_types(K)]
128#[verifier::accept_recursive_types(V)]
129pub struct ExMapIter<'a, K, V>(btree_map::Iter<'a, K, V>);
130
131pub uninterp spec fn into_iter<'a, Key, Value>(i: btree_map::Iter<'a, Key, Value>) -> Seq<
134 (Key, Value),
135>;
136
137impl<'a, K, V> super::iter::IteratorSpecImpl for btree_map::Iter<'a, K, V> {
138 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
139 true
140 }
141
142 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
143
144 uninterp spec fn will_return_none(&self) -> bool;
145
146 uninterp spec fn decrease(&self) -> Option<nat>;
147
148 open spec fn peek(&self, index: int) -> Option<Self::Item> {
149 if 0 <= index < into_iter(*self).len() {
150 let (k, v) = into_iter(*self)[index];
151 Some((&k, &v))
152 } else {
153 None
154 }
155 }
156}
157
158pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::iter ](
159 m: &'a BTreeMap<Key, Value, A>,
160) -> (iter: btree_map::Iter<'a, Key, Value>)
161 ensures
162 key_obeys_cmp_spec::<Key>() ==> {
163 &&& IteratorSpec::remaining(&iter).len() == m@.dom().len()
164 &&& forall|i: int|
165 #![trigger m@.contains_key(*IteratorSpec::remaining(&iter)[i].0)]
166 #![trigger m@[*IteratorSpec::remaining(&iter)[i].0]]
167 0 <= i < IteratorSpec::remaining(&iter).len() ==> m@.contains_key(
168 *IteratorSpec::remaining(&iter)[i].0,
169 ) && m@[*IteratorSpec::remaining(&iter)[i].0] == *IteratorSpec::remaining(
170 &iter,
171 )[i].1
172 &&& forall|k: Key| #[trigger]
173 m@.contains_key(k) ==> IteratorSpec::remaining(&iter).contains((&k, &m@[k]))
174 &&& IteratorSpec::remaining(&iter).unref().to_set() == m@.kv_pairs()
175 &&& iter.remaining().no_duplicates()
176 &&& into_iter(iter) == IteratorSpec::remaining(&iter).unref()
177 &&& IteratorSpec::decrease(&iter) is Some
178 &&& increasing_seq(iter.remaining().map_values(|kv: (&Key, &Value)| *kv.0))
179 },
180;
181
182#[verifier::external_type_specification]
191#[verifier::external_body]
192#[verifier::accept_recursive_types(Key)]
193#[verifier::accept_recursive_types(Value)]
194#[verifier::reject_recursive_types(A)]
195pub struct ExBTreeMap<Key, Value, A: Allocator + Clone>(BTreeMap<Key, Value, A>);
196
197pub trait BTreeMapAdditionalSpecFns<Key, Value>: View<V = Map<Key, Value>> {
198 spec fn spec_index(&self, k: Key) -> Value
199 recommends
200 self@.contains_key(k),
201 ;
202}
203
204impl<Key, Value, A: Allocator + Clone> BTreeMapAdditionalSpecFns<Key, Value> for BTreeMap<
205 Key,
206 Value,
207 A,
208> {
209 #[verifier::inline]
210 open spec fn spec_index(&self, k: Key) -> Value {
211 self@.index(k)
212 }
213}
214
215impl<Key, Value, A: Allocator + Clone> View for BTreeMap<Key, Value, A> {
216 type V = Map<Key, Value>;
217
218 uninterp spec fn view(&self) -> Map<Key, Value>;
219}
220
221impl<Key: DeepView, Value: DeepView, A: Allocator + Clone> DeepView for BTreeMap<Key, Value, A> {
222 type V = Map<Key::V, Value::V>;
223
224 open spec fn deep_view(&self) -> Map<Key::V, Value::V> {
225 btree_map_deep_view_impl(*self)
226 }
227}
228
229#[verifier::opaque]
235pub open spec fn btree_map_deep_view_impl<Key: DeepView, Value: DeepView, A: Allocator + Clone>(
236 m: BTreeMap<Key, Value, A>,
237) -> Map<Key::V, Value::V> {
238 Map::new(
239 m@.dom().map(|k: Key| k.deep_view()),
240 |dk: Key::V|
241 {
242 let k = choose|k: Key| m@.contains_key(k) && #[trigger] k.deep_view() == dk;
243 m@[k].deep_view()
244 },
245 )
246}
247
248pub broadcast proof fn lemma_btree_map_deepview_dom<K: DeepView, V: DeepView>(m: BTreeMap<K, V>)
249 ensures
250 #[trigger] m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()),
251{
252 reveal(btree_map_deep_view_impl);
253 broadcast use group_btree_axioms;
254 broadcast use crate::vstd::group_vstd_default;
255
256 assert(m.deep_view().dom() =~= m@.dom().map(|k: K| k.deep_view()));
257}
258
259pub broadcast proof fn lemma_btree_map_deepview_properties<K: DeepView, V: DeepView>(
260 m: BTreeMap<K, V>,
261)
262 requires
263 crate::relations::injective(|k: K| k.deep_view()),
264 ensures
265 #![trigger m.deep_view()]
266 forall|k: K| #[trigger]
268 m@.contains_key(k) ==> m.deep_view().contains_key(k.deep_view())
269 && m.deep_view()[k.deep_view()] == m@[k].deep_view(),
270 forall|dk: <K as DeepView>::V| #[trigger]
272 m.deep_view().contains_key(dk) ==> exists|k: K|
273 k.deep_view() == dk && #[trigger] m@.contains_key(k),
274{
275 reveal(btree_map_deep_view_impl);
276 broadcast use group_btree_axioms;
277 broadcast use crate::vstd::group_vstd_default;
278
279 assert(m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()));
280 assert forall|k: K| #[trigger] m@.contains_key(k) implies m.deep_view().contains_key(
281 k.deep_view(),
282 ) && m.deep_view()[k.deep_view()] == m@[k].deep_view() by {
283 assert forall|k1: K, k2: K| #[trigger]
284 k1.deep_view() == #[trigger] k2.deep_view() implies k1 == k2 by {
285 let ghost k_deepview = |k: K| k.deep_view();
286 assert(crate::relations::injective(k_deepview));
287 assert(k_deepview(k1) == k_deepview(k2));
288 }
289 }
290}
291
292pub broadcast proof fn lemma_btree_map_deepview_values<K: DeepView, V: DeepView>(m: BTreeMap<K, V>)
293 requires
294 crate::relations::injective(|k: K| k.deep_view()),
295 ensures
296 #[trigger] m.deep_view().values() =~= m@.values().map(|v: V| v.deep_view()),
297{
298 reveal(btree_map_deep_view_impl);
299 broadcast use group_btree_axioms;
300 broadcast use lemma_btree_map_deepview_properties;
301 broadcast use crate::vstd::group_vstd_default;
302
303 let lhs = m.deep_view().values();
304 let rhs = m@.values().map(|v: V| v.deep_view());
305 assert forall|v: V::V| #[trigger] lhs.contains(v) implies rhs.contains(v) by {
306 let dk = choose|dk: K::V| #[trigger]
307 m.deep_view().contains_key(dk) && m.deep_view()[dk] == v;
308 let k = choose|k: K| #[trigger] m@.contains_key(k) && k.deep_view() == dk;
309 let ov = choose|ov: V| #[trigger] m@.contains_key(k) && m@[k] == ov && ov.deep_view() == v;
310 assert(v == ov.deep_view());
311 assert(m@.values().contains(ov));
312 }
313}
314
315pub broadcast axiom fn axiom_btree_map_deepview_borrow<
318 K: DeepView + Borrow<Q>,
319 V: DeepView,
320 Q: View<V = <K as DeepView>::V> + Eq + ?Sized,
321>(m: BTreeMap<K, V>, k: &Q)
322 requires
323 key_obeys_cmp_spec::<K>(),
324 crate::relations::injective(|k: K| k.deep_view()),
325 ensures
326 #[trigger] contains_borrowed_key(m@, k) <==> m.deep_view().contains_key(k@),
327;
328
329pub uninterp spec fn spec_btree_map_len<Key, Value, A: Allocator + Clone>(
330 m: &BTreeMap<Key, Value, A>,
331) -> usize;
332
333pub broadcast axiom fn axiom_spec_btree_map_len<Key, Value, A: Allocator + Clone>(
334 m: &BTreeMap<Key, Value, A>,
335)
336 ensures
337 key_obeys_cmp_spec::<Key>() ==> #[trigger] spec_btree_map_len(m) == m@.len(),
338;
339
340#[verifier::when_used_as_spec(spec_btree_map_len)]
341pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::len ](
342 m: &BTreeMap<Key, Value, A>,
343) -> (len: usize)
344 ensures
345 len == spec_btree_map_len(m),
346;
347
348pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::is_empty ](
349 m: &BTreeMap<Key, Value, A>,
350) -> (res: bool)
351 ensures
352 res == m@.is_empty(),
353;
354
355pub assume_specification<K: Clone, V: Clone, A: Allocator + Clone>[ <BTreeMap::<
356 K,
357 V,
358 A,
359> as Clone>::clone ](this: &BTreeMap<K, V, A>) -> (other: BTreeMap<K, V, A>)
360 ensures
361 other@ == this@,
362;
363
364pub assume_specification<Key, Value>[ BTreeMap::<Key, Value>::new ]() -> (m: BTreeMap<Key, Value>)
365 ensures
366 m@ == Map::<Key, Value>::empty(),
367;
368
369pub assume_specification<K, V>[ <BTreeMap<K, V> as core::default::Default>::default ]() -> (m:
370 BTreeMap<K, V>)
371 ensures
372 m@ == Map::<K, V>::empty(),
373;
374
375pub assume_specification<Key: Ord, Value, A: Allocator + Clone>[ BTreeMap::<
376 Key,
377 Value,
378 A,
379>::insert ](m: &mut BTreeMap<Key, Value, A>, k: Key, v: Value) -> (result: Option<Value>)
380 ensures
381 obeys_cmp::<Key>() ==> {
382 &&& final(m)@ == old(m)@.insert(k, v)
383 &&& match result {
384 Some(v) => old(m)@.contains_key(k) && v == old(m)[k],
385 None => !old(m)@.contains_key(k),
386 }
387 },
388;
389
390pub uninterp spec fn contains_borrowed_key<Key, Value, Q: ?Sized>(
405 m: Map<Key, Value>,
406 k: &Q,
407) -> bool;
408
409pub broadcast axiom fn axiom_contains_deref_key<Q, Value>(m: Map<Q, Value>, k: &Q)
410 ensures
411 #[trigger] contains_borrowed_key::<Q, Value, Q>(m, k) <==> m.contains_key(*k),
412;
413
414pub broadcast axiom fn axiom_contains_box<Q, Value>(m: Map<Box<Q>, Value>, k: &Q)
415 ensures
416 #[trigger] contains_borrowed_key::<Box<Q>, Value, Q>(m, k) <==> m.contains_key(
417 Box::new(*k),
418 ),
419;
420
421pub assume_specification<
422 Key: Borrow<Q> + Ord,
423 Value,
424 A: Allocator + Clone,
425 Q: Ord + ?Sized,
426>[ BTreeMap::<Key, Value, A>::contains_key::<Q> ](m: &BTreeMap<Key, Value, A>, k: &Q) -> (result:
427 bool)
428 ensures
429 obeys_cmp::<Key>() ==> result == contains_borrowed_key(m@, k),
430;
431
432pub uninterp spec fn maps_borrowed_key_to_value<Key, Value, Q: ?Sized>(
449 m: Map<Key, Value>,
450 k: &Q,
451 v: Value,
452) -> bool;
453
454pub broadcast axiom fn axiom_maps_deref_key_to_value<Q, Value>(m: Map<Q, Value>, k: &Q, v: Value)
455 ensures
456 #[trigger] maps_borrowed_key_to_value::<Q, Value, Q>(m, k, v) <==> m.contains_key(*k)
457 && m[*k] == v,
458;
459
460pub broadcast axiom fn axiom_maps_box_key_to_value<Q, Value>(m: Map<Box<Q>, Value>, q: &Q, v: Value)
461 ensures
462 #[trigger] maps_borrowed_key_to_value::<Box<Q>, Value, Q>(m, q, v) <==> {
463 let k = Box::new(*q);
464 &&& m.contains_key(k)
465 &&& m[k] == v
466 },
467;
468
469pub assume_specification<
470 'a,
471 Key: Borrow<Q> + Ord,
472 Value,
473 A: Allocator + Clone,
474 Q: Ord + ?Sized,
475>[ BTreeMap::<Key, Value, A>::get::<Q> ](m: &'a BTreeMap<Key, Value, A>, k: &Q) -> (result: Option<
476 &'a Value,
477>)
478 ensures
479 obeys_cmp::<Key>() ==> match result {
480 Some(v) => maps_borrowed_key_to_value(m@, k, *v),
481 None => !contains_borrowed_key(m@, k),
482 },
483;
484
485pub uninterp spec fn borrowed_key_removed<Key, Value, Q: ?Sized>(
501 old_m: Map<Key, Value>,
502 new_m: Map<Key, Value>,
503 k: &Q,
504) -> bool;
505
506pub broadcast axiom fn axiom_deref_key_removed<Q, Value>(
507 old_m: Map<Q, Value>,
508 new_m: Map<Q, Value>,
509 k: &Q,
510)
511 ensures
512 #[trigger] borrowed_key_removed::<Q, Value, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
513 *k,
514 ),
515;
516
517pub broadcast axiom fn axiom_box_key_removed<Q, Value>(
518 old_m: Map<Box<Q>, Value>,
519 new_m: Map<Box<Q>, Value>,
520 q: &Q,
521)
522 ensures
523 #[trigger] borrowed_key_removed::<Box<Q>, Value, Q>(old_m, new_m, q) <==> new_m
524 == old_m.remove(Box::new(*q)),
525;
526
527pub assume_specification<
528 Key: Borrow<Q> + Ord,
529 Value,
530 A: Allocator + Clone,
531 Q: Ord + ?Sized,
532>[ BTreeMap::<Key, Value, A>::remove::<Q> ](m: &mut BTreeMap<Key, Value, A>, k: &Q) -> (result:
533 Option<Value>)
534 ensures
535 obeys_cmp::<Key>() ==> {
536 &&& borrowed_key_removed(old(m)@, final(m)@, k)
537 &&& match result {
538 Some(v) => maps_borrowed_key_to_value(old(m)@, k, v),
539 None => !contains_borrowed_key(old(m)@, k),
540 }
541 },
542;
543
544pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::clear ](
545 m: &mut BTreeMap<Key, Value, A>,
546)
547 ensures
548 final(m)@ == Map::<Key, Value>::empty(),
549;
550
551pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::keys ](
552 m: &'a BTreeMap<Key, Value, A>,
553) -> (keys: Keys<'a, Key, Value>)
554 ensures
555 key_obeys_cmp_spec::<Key>() ==> {
556 &&& IteratorSpec::remaining(&keys).unref().to_set() == m@.dom()
557 &&& IteratorSpec::remaining(&keys).no_duplicates()
558 &&& IteratorSpec::remaining(&keys).len() == m@.dom().len()
559 &&& increasing_seq(IteratorSpec::remaining(&keys))
560 &&& into_iter_keys(keys) == IteratorSpec::remaining(&keys).unref()
561 &&& IteratorSpec::decrease(&keys) is Some
562 },
563;
564
565pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::values ](
566 m: &'a BTreeMap<Key, Value, A>,
567) -> (values: Values<'a, Key, Value>)
568 ensures
569 key_obeys_cmp_spec::<Key>() ==> {
570 &&& IteratorSpec::remaining(&values).unref().to_set() == m@.values()
571 &&& IteratorSpec::remaining(&values).len() == m@.dom().len()
572 &&& into_iter_values(values) == IteratorSpec::remaining(&values).unref()
573 &&& IteratorSpec::decrease(&values) is Some
574 &&& exists|key_seq: Seq<Key>|
575 {
576 &&& increasing_seq(key_seq)
577 &&& key_seq.to_set() == m@.dom()
578 &&& key_seq.no_duplicates()
579 &&& IteratorSpec::remaining(&values) == key_seq.map(|i: int, k| &m@[k])
580 }
581 },
582;
583
584pub broadcast axiom fn axiom_btree_map_decreases<Key, Value, A: Allocator + Clone>(
585 m: BTreeMap<Key, Value, A>,
586)
587 ensures
588 #[trigger] (decreases_to!(m => m@)),
589;
590
591#[verifier::external_type_specification]
594#[verifier::external_body]
595#[verifier::accept_recursive_types(K)]
596pub struct ExSetIter<'a, K: 'a>(btree_set::Iter<'a, K>);
597
598pub uninterp spec fn into_iter_btree_keys<'a, Key>(i: btree_set::Iter::<'a, Key>) -> Seq<Key>;
601
602impl<'a, T> super::iter::IteratorSpecImpl for btree_set::Iter::<'a, T> {
603 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
604 true
605 }
606
607 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
608
609 uninterp spec fn will_return_none(&self) -> bool;
610
611 uninterp spec fn decrease(&self) -> Option<nat>;
612
613 open spec fn peek(&self, index: int) -> Option<Self::Item> {
614 if 0 <= index < into_iter_btree_keys(*self).len() {
615 Some(&into_iter_btree_keys(*self)[index])
616 } else {
617 None
618 }
619 }
620}
621
622#[verifier::external_type_specification]
631#[verifier::external_body]
632#[verifier::accept_recursive_types(Key)]
633#[verifier::reject_recursive_types(A)]
634pub struct ExBTreeSet<Key, A: Allocator + Clone>(BTreeSet<Key, A>);
635
636impl<Key, A: Allocator + Clone> View for BTreeSet<Key, A> {
637 type V = Set<Key>;
638
639 uninterp spec fn view(&self) -> Set<Key>;
640}
641
642impl<Key: DeepView, A: Allocator + Clone> DeepView for BTreeSet<Key, A> {
643 type V = Set<Key::V>;
644
645 open spec fn deep_view(&self) -> Set<Key::V> {
646 self@.map(|x: Key| x.deep_view())
647 }
648}
649
650pub uninterp spec fn spec_btree_set_len<Key, A: Allocator + Clone>(m: &BTreeSet<Key, A>) -> usize;
651
652pub broadcast axiom fn axiom_spec_btree_set_len<Key, A: Allocator + Clone>(m: &BTreeSet<Key, A>)
653 ensures
654 key_obeys_cmp_spec::<Key>() ==> #[trigger] spec_btree_set_len(m) == m@.len(),
655;
656
657#[verifier::when_used_as_spec(spec_btree_set_len)]
658pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::len ](
659 m: &BTreeSet<Key, A>,
660) -> (len: usize)
661 ensures
662 len == spec_btree_set_len(m),
663;
664
665pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::is_empty ](
666 m: &BTreeSet<Key, A>,
667) -> (res: bool)
668 ensures
669 res == m@.is_empty(),
670;
671
672pub assume_specification<K: Clone, A: Allocator + Clone>[ <BTreeSet::<K, A> as Clone>::clone ](
673 this: &BTreeSet<K, A>,
674) -> (other: BTreeSet<K, A>)
675 ensures
676 other@ == this@,
677;
678
679pub assume_specification<Key>[ BTreeSet::<Key>::new ]() -> (m: BTreeSet<Key>)
680 ensures
681 m@ == Set::<Key>::empty(),
682;
683
684pub assume_specification<T>[ <BTreeSet<T> as core::default::Default>::default ]() -> (m: BTreeSet<
685 T,
686>)
687 ensures
688 m@ == Set::<T>::empty(),
689;
690
691pub assume_specification<Key: Ord, A: Allocator + Clone>[ BTreeSet::<Key, A>::insert ](
692 m: &mut BTreeSet<Key, A>,
693 k: Key,
694) -> (result: bool)
695 ensures
696 obeys_cmp::<Key>() ==> {
697 &&& final(m)@ == old(m)@.insert(k)
698 &&& result == !old(m)@.contains(k)
699 },
700;
701
702pub uninterp spec fn set_contains_borrowed_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q) -> bool;
717
718pub broadcast axiom fn axiom_set_contains_deref_key<Q>(m: Set<Q>, k: &Q)
719 ensures
720 #[trigger] set_contains_borrowed_key::<Q, Q>(m, k) <==> m.contains(*k),
721;
722
723pub broadcast axiom fn axiom_set_contains_box<Q>(m: Set<Box<Q>>, k: &Q)
724 ensures
725 #[trigger] set_contains_borrowed_key::<Box<Q>, Q>(m, k) <==> m.contains(Box::new(*k)),
726;
727
728pub assume_specification<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>[ BTreeSet::<
729 Key,
730 A,
731>::contains ](m: &BTreeSet<Key, A>, k: &Q) -> (result: bool)
732 ensures
733 obeys_cmp::<Key>() ==> result == set_contains_borrowed_key(m@, k),
734 no_unwind
735;
736
737pub uninterp spec fn sets_borrowed_key_to_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q, v: &Key) -> bool;
754
755pub broadcast axiom fn axiom_set_deref_key_to_value<Q>(m: Set<Q>, k: &Q, v: &Q)
756 ensures
757 #[trigger] sets_borrowed_key_to_key::<Q, Q>(m, k, v) <==> m.contains(*k) && k == v,
758;
759
760pub broadcast axiom fn axiom_set_box_key_to_value<Q>(m: Set<Box<Q>>, q: &Q, v: &Box<Q>)
761 ensures
762 #[trigger] sets_borrowed_key_to_key::<Box<Q>, Q>(m, q, v) <==> (m.contains(*v) && Box::new(
763 *q,
764 ) == v),
765;
766
767pub assume_specification<
768 'a,
769 Key: Borrow<Q> + Ord,
770 A: Allocator + Clone,
771 Q: Ord + ?Sized,
772>[ BTreeSet::<Key, A>::get::<Q> ](m: &'a BTreeSet<Key, A>, k: &Q) -> (result: Option<&'a Key>)
773 ensures
774 obeys_cmp::<Key>() ==> match result {
775 Some(v) => sets_borrowed_key_to_key(m@, k, v),
776 None => !set_contains_borrowed_key(m@, k),
777 },
778;
779
780pub uninterp spec fn sets_differ_by_borrowed_key<Key, Q: ?Sized>(
795 old_m: Set<Key>,
796 new_m: Set<Key>,
797 k: &Q,
798) -> bool;
799
800pub broadcast axiom fn axiom_set_deref_key_removed<Q>(old_m: Set<Q>, new_m: Set<Q>, k: &Q)
801 ensures
802 #[trigger] sets_differ_by_borrowed_key::<Q, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
803 *k,
804 ),
805;
806
807pub broadcast axiom fn axiom_set_box_key_removed<Q>(old_m: Set<Box<Q>>, new_m: Set<Box<Q>>, q: &Q)
808 ensures
809 #[trigger] sets_differ_by_borrowed_key::<Box<Q>, Q>(old_m, new_m, q) <==> new_m
810 == old_m.remove(Box::new(*q)),
811;
812
813pub assume_specification<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>[ BTreeSet::<
814 Key,
815 A,
816>::remove::<Q> ](m: &mut BTreeSet<Key, A>, k: &Q) -> (result: bool)
817 ensures
818 obeys_cmp::<Key>() ==> {
819 &&& sets_differ_by_borrowed_key(old(m)@, final(m)@, k)
820 &&& result == set_contains_borrowed_key(old(m)@, k)
821 },
822;
823
824pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::clear ](
825 m: &mut BTreeSet<Key, A>,
826) where A: Clone
827 ensures
828 final(m)@ == Set::<Key>::empty(),
829;
830
831pub assume_specification<'a, Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::iter ](
832 m: &'a BTreeSet<Key, A>,
833) -> (r: btree_set::Iter<'a, Key>)
834 ensures
835 key_obeys_cmp_spec::<Key>() ==> {
836 &&& IteratorSpec::remaining(&r).unref().to_set() == m@
837 &&& IteratorSpec::remaining(&r).no_duplicates()
838 &&& IteratorSpec::remaining(&r).len() == m@.len()
839 &&& increasing_seq(IteratorSpec::remaining(&r))
840 &&& into_iter_btree_keys(r) == IteratorSpec::remaining(&r).unref()
841 &&& IteratorSpec::decrease(&r) is Some
842 },
843;
844
845pub broadcast axiom fn axiom_btree_set_decreases<Key, A: Allocator + Clone>(m: BTreeSet<Key, A>)
846 ensures
847 #[trigger] (decreases_to!(m => m@)),
848;
849
850pub broadcast group group_btree_axioms {
851 axiom_key_obeys_cmp_spec_meaning,
852 axiom_increasing_seq_meaning,
853 axiom_box_key_removed,
854 axiom_contains_deref_key,
855 axiom_contains_box,
856 axiom_deref_key_removed,
857 axiom_maps_deref_key_to_value,
858 axiom_maps_box_key_to_value,
859 axiom_btree_map_deepview_borrow,
860 axiom_spec_btree_map_len,
861 axiom_set_box_key_removed,
862 axiom_set_contains_deref_key,
863 axiom_set_contains_box,
864 axiom_set_deref_key_removed,
865 axiom_set_deref_key_to_value,
866 axiom_set_box_key_to_value,
867 axiom_spec_btree_set_len,
868 axiom_btree_map_decreases,
869 axiom_btree_set_decreases,
870}
871
872}