1use super::super::laws_cmp::{obeys_cmp, obeys_cmp_concrete_eq, obeys_cmp_deep_eq};
15use super::super::map::{assert_maps_equal, assert_maps_equal_internal};
16use super::super::prelude::*;
17use super::borrow::BorrowSpec;
18use super::cmp::OrdSpec;
19pub use super::cmp::borrowed_key_ordering_matches;
20use super::iter::IteratorSpec;
21
22use alloc::alloc::Allocator;
23use alloc::boxed::Box;
24use alloc::collections::btree_map;
25use alloc::collections::btree_map::{CursorMut, Keys, UnorderedKeyError, Values};
26use alloc::collections::btree_set;
27use alloc::collections::{BTreeMap, BTreeSet};
28use core::borrow::Borrow;
29use core::cmp::Ordering;
30use core::marker::PhantomData;
31use core::ops::Bound;
32use core::option::Option;
33
34verus! {
35
36pub uninterp spec fn key_obeys_cmp_spec<Key: ?Sized>() -> bool;
45
46pub broadcast axiom fn axiom_key_obeys_cmp_spec_meaning<K: Ord>()
48 ensures
49 #[trigger] key_obeys_cmp_spec::<K>() <==> obeys_cmp::<K>(),
50;
51
52pub uninterp spec fn increasing_seq<K>(s: Seq<K>) -> bool;
57
58pub broadcast axiom fn axiom_increasing_seq_meaning<K: Ord>(s: Seq<K>)
60 requires
61 obeys_cmp::<K>(),
62 ensures
63 #[trigger] increasing_seq(s) <==> forall|i, j|
64 0 <= i < j < s.len() ==> s[i].cmp_spec(&s[j]) is Less,
65;
66
67#[verifier::external_type_specification]
70#[verifier::external_body]
71#[verifier::accept_recursive_types(Key)]
72#[verifier::accept_recursive_types(Value)]
73pub struct ExKeys<'a, Key, Value>(Keys<'a, Key, Value>);
74
75pub uninterp spec fn into_iter_keys<'a, Key, Value>(i: Keys<'a, Key, Value>) -> Seq<Key>;
78
79impl<'a, K, V> super::iter::IteratorSpecImpl for Keys<'a, K, V> {
80 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
81 true
82 }
83
84 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
85
86 #[verifier::prophetic]
87 open spec fn produces(&self) -> Seq<bool> {
88 Seq::new(IteratorSpec::remaining(self).len(), |i: int| true)
89 }
90
91 uninterp spec fn decrease(&self) -> Option<nat>;
92
93 open spec fn peek(&self, index: int) -> Option<Self::Item> {
94 if 0 <= index < into_iter_keys(*self).len() {
95 Some(&into_iter_keys(*self)[index])
96 } else {
97 None
98 }
99 }
100}
101
102#[verifier::external_type_specification]
105#[verifier::external_body]
106#[verifier::accept_recursive_types(Key)]
107#[verifier::accept_recursive_types(Value)]
108pub struct ExValues<'a, Key, Value>(Values<'a, Key, Value>);
109
110pub uninterp spec fn into_iter_values<'a, Key, Value>(i: Values<'a, Key, Value>) -> Seq<Value>;
113
114impl<'a, K, V> super::iter::IteratorSpecImpl for Values<'a, K, V> {
115 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
116 true
117 }
118
119 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
120
121 #[verifier::prophetic]
122 open spec fn produces(&self) -> Seq<bool> {
123 Seq::new(IteratorSpec::remaining(self).len(), |i: int| true)
124 }
125
126 uninterp spec fn decrease(&self) -> Option<nat>;
127
128 open spec fn peek(&self, index: int) -> Option<Self::Item> {
129 if 0 <= index < into_iter_values(*self).len() {
130 Some(&into_iter_values(*self)[index])
131 } else {
132 None
133 }
134 }
135}
136
137#[verifier::external_type_specification]
140#[verifier::external_body]
141#[verifier::accept_recursive_types(K)]
142#[verifier::accept_recursive_types(V)]
143pub struct ExMapIter<'a, K, V>(btree_map::Iter<'a, K, V>);
144
145pub uninterp spec fn into_iter<'a, Key, Value>(i: btree_map::Iter<'a, Key, Value>) -> Seq<
148 (Key, Value),
149>;
150
151impl<'a, K, V> super::iter::IteratorSpecImpl for btree_map::Iter<'a, K, V> {
152 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
153 true
154 }
155
156 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
157
158 #[verifier::prophetic]
159 open spec fn produces(&self) -> Seq<bool> {
160 Seq::new(IteratorSpec::remaining(self).len(), |i: int| true)
161 }
162
163 uninterp spec fn decrease(&self) -> Option<nat>;
164
165 open spec fn peek(&self, index: int) -> Option<Self::Item> {
166 if 0 <= index < into_iter(*self).len() {
167 let (k, v) = into_iter(*self)[index];
168 Some((&k, &v))
169 } else {
170 None
171 }
172 }
173}
174
175pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::iter ](
176 m: &'a BTreeMap<Key, Value, A>,
177) -> (iter: btree_map::Iter<'a, Key, Value>)
178 ensures
179 key_obeys_cmp_spec::<Key>() ==> {
180 &&& IteratorSpec::remaining(&iter).len() == m@.dom().len()
181 &&& forall|i: int|
182 #![trigger m@.contains_key(*IteratorSpec::remaining(&iter)[i].0)]
183 #![trigger m@[*IteratorSpec::remaining(&iter)[i].0]]
184 0 <= i < IteratorSpec::remaining(&iter).len() ==> m@.contains_key(
185 *IteratorSpec::remaining(&iter)[i].0,
186 ) && m@[*IteratorSpec::remaining(&iter)[i].0] == *IteratorSpec::remaining(
187 &iter,
188 )[i].1
189 &&& forall|k: Key| #[trigger]
190 m@.contains_key(k) ==> IteratorSpec::remaining(&iter).contains((&k, &m@[k]))
191 &&& IteratorSpec::remaining(&iter).unref().to_set() == m@.kv_pairs()
192 &&& iter.remaining().no_duplicates()
193 &&& into_iter(iter) == IteratorSpec::remaining(&iter).unref()
194 &&& IteratorSpec::decrease(&iter) is Some
195 &&& increasing_seq(iter.remaining().map_values(|kv: (&Key, &Value)| *kv.0))
196 },
197;
198
199#[verifier::external_type_specification]
208#[verifier::external_body]
209#[verifier::accept_recursive_types(Key)]
210#[verifier::accept_recursive_types(Value)]
211#[verifier::reject_recursive_types(A)]
212pub struct ExBTreeMap<Key, Value, A: Allocator + Clone>(BTreeMap<Key, Value, A>);
213
214#[verifier::external_type_specification]
216#[verifier::external_body]
217#[verifier::accept_recursive_types(Key)]
218#[verifier::accept_recursive_types(Value)]
219#[verifier::reject_recursive_types(A)]
220pub struct ExCursorMut<'a, Key: 'a, Value: 'a, A>(CursorMut<'a, Key, Value, A>);
221
222#[verifier::external_type_specification]
224#[verifier::external_body]
225pub struct ExUnorderedKeyError(UnorderedKeyError);
226
227pub ghost struct CursorMutModel<Key, Value> {
232 pub keys: Seq<Key>,
234 pub position: int,
236 pub map: Map<Key, Value>,
238}
239
240impl<Key, Value> CursorMutModel<Key, Value> {
241 pub open spec fn wf(self) -> bool {
243 &&& 0 <= self.position <= self.keys.len()
244 &&& self.keys.no_duplicates()
245 &&& self.keys.to_set() == self.map.dom()
246 &&& increasing_seq(self.keys)
247 }
248}
249
250pub trait CursorMutSpecFns<Key, Value>: View<V = CursorMutModel<Key, Value>> + Sized {
252 #[verifier::prophetic]
254 spec fn final_map(self) -> Map<Key, Value>;
255}
256
257impl<'a, Key, Value, A> View for CursorMut<'a, Key, Value, A> {
258 type V = CursorMutModel<Key, Value>;
259
260 uninterp spec fn view(&self) -> CursorMutModel<Key, Value>;
261}
262
263impl<'a, Key, Value, A> CursorMutSpecFns<Key, Value> for CursorMut<'a, Key, Value, A> {
264 #[verifier::prophetic]
265 uninterp spec fn final_map(self) -> Map<Key, Value>;
266}
267
268pub open spec fn before_lower_bound<Key: Borrow<Q>, Q: Ord + ?Sized>(
270 key: Key,
271 bound: Bound<&Q>,
272) -> bool {
273 let borrowed_key = <Key as BorrowSpec<Q>>::borrow_spec(&key);
274 match bound {
275 Bound::Included(bound_key) => borrowed_key.cmp_spec(bound_key) is Less,
276 Bound::Excluded(bound_key) => !(borrowed_key.cmp_spec(bound_key) is Greater),
277 Bound::Unbounded => false,
278 }
279}
280
281pub open spec fn before_upper_bound<Key: Borrow<Q>, Q: Ord + ?Sized>(
283 key: Key,
284 bound: Bound<&Q>,
285) -> bool {
286 let borrowed_key = <Key as BorrowSpec<Q>>::borrow_spec(&key);
287 match bound {
288 Bound::Included(bound_key) => !(borrowed_key.cmp_spec(bound_key) is Greater),
289 Bound::Excluded(bound_key) => borrowed_key.cmp_spec(bound_key) is Less,
290 Bound::Unbounded => true,
291 }
292}
293
294pub open spec fn positioned_at_lower_bound<Key: Borrow<Q>, Value, Q: Ord + ?Sized>(
296 model: CursorMutModel<Key, Value>,
297 bound: Bound<&Q>,
298) -> bool {
299 &&& forall|i: int|
300 #![trigger before_lower_bound(model.keys[i], bound)]
301 0 <= i < model.position ==> before_lower_bound(model.keys[i], bound)
302 &&& forall|i: int|
303 #![trigger before_lower_bound(model.keys[i], bound)]
304 model.position <= i < model.keys.len() ==> !before_lower_bound(model.keys[i], bound)
305}
306
307pub open spec fn positioned_at_upper_bound<Key: Borrow<Q>, Value, Q: Ord + ?Sized>(
309 model: CursorMutModel<Key, Value>,
310 bound: Bound<&Q>,
311) -> bool {
312 &&& forall|i: int|
313 #![trigger before_upper_bound(model.keys[i], bound)]
314 0 <= i < model.position ==> before_upper_bound(model.keys[i], bound)
315 &&& forall|i: int|
316 #![trigger before_upper_bound(model.keys[i], bound)]
317 model.position <= i < model.keys.len() ==> !before_upper_bound(model.keys[i], bound)
318}
319
320pub open spec fn key_fits_at_position<Key: Ord, Value>(
322 model: CursorMutModel<Key, Value>,
323 key: Key,
324) -> bool {
325 &&& (model.position == 0 || model.keys[model.position - 1].cmp_spec(&key) is Less)
326 &&& (model.position == model.keys.len() || key.cmp_spec(&model.keys[model.position]) is Less)
327}
328
329pub broadcast axiom fn axiom_has_resolved_cursor<Key, Value, A>(cursor: CursorMut<Key, Value, A>)
331 ensures
332 #[trigger] has_resolved(cursor) ==> cursor.final_map() == cursor@.map,
333;
334
335pub trait BTreeMapAdditionalSpecFns<Key, Value>: View<V = Map<Key, Value>> {
336 spec fn spec_index(&self, k: Key) -> Value
337 recommends
338 self@.contains_key(k),
339 ;
340}
341
342impl<Key, Value, A: Allocator + Clone> BTreeMapAdditionalSpecFns<Key, Value> for BTreeMap<
343 Key,
344 Value,
345 A,
346> {
347 #[verifier::inline]
348 open spec fn spec_index(&self, k: Key) -> Value {
349 self@.index(k)
350 }
351}
352
353impl<Key, Value, A: Allocator + Clone> View for BTreeMap<Key, Value, A> {
354 type V = Map<Key, Value>;
355
356 uninterp spec fn view(&self) -> Map<Key, Value>;
357}
358
359impl<Key: DeepView, Value: DeepView, A: Allocator + Clone> DeepView for BTreeMap<Key, Value, A> {
360 type V = Map<Key::V, Value::V>;
361
362 open spec fn deep_view(&self) -> Map<Key::V, Value::V> {
363 btree_map_deep_view_impl(*self)
364 }
365}
366
367#[verifier::opaque]
373pub open spec fn btree_map_deep_view_impl<Key: DeepView, Value: DeepView, A: Allocator + Clone>(
374 m: BTreeMap<Key, Value, A>,
375) -> Map<Key::V, Value::V> {
376 Map::new(
377 m@.dom().map(|k: Key| k.deep_view()),
378 |dk: Key::V|
379 {
380 let k = choose|k: Key| m@.contains_key(k) && #[trigger] k.deep_view() == dk;
381 m@[k].deep_view()
382 },
383 )
384}
385
386pub broadcast proof fn lemma_btree_map_deepview_dom<K: DeepView, V: DeepView>(m: BTreeMap<K, V>)
387 ensures
388 #[trigger] m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()),
389{
390 reveal(btree_map_deep_view_impl);
391 broadcast use group_btree_axioms;
392 broadcast use crate::vstd::group_vstd_default;
393
394 assert(m.deep_view().dom() =~= m@.dom().map(|k: K| k.deep_view()));
395}
396
397pub broadcast proof fn lemma_btree_map_deepview_properties<K: DeepView, V: DeepView>(
398 m: BTreeMap<K, V>,
399)
400 requires
401 crate::relations::injective(|k: K| k.deep_view()),
402 ensures
403 #![trigger m.deep_view()]
404 forall|k: K| #[trigger]
406 m@.contains_key(k) ==> m.deep_view().contains_key(k.deep_view())
407 && m.deep_view()[k.deep_view()] == m@[k].deep_view(),
408 forall|dk: <K as DeepView>::V| #[trigger]
410 m.deep_view().contains_key(dk) ==> exists|k: K|
411 k.deep_view() == dk && #[trigger] m@.contains_key(k),
412{
413 reveal(btree_map_deep_view_impl);
414 broadcast use group_btree_axioms;
415 broadcast use crate::vstd::group_vstd_default;
416
417 assert(m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()));
418 assert forall|k: K| #[trigger] m@.contains_key(k) implies m.deep_view().contains_key(
419 k.deep_view(),
420 ) && m.deep_view()[k.deep_view()] == m@[k].deep_view() by {
421 assert forall|k1: K, k2: K| #[trigger]
422 k1.deep_view() == #[trigger] k2.deep_view() implies k1 == k2 by {
423 let ghost k_deepview = |k: K| k.deep_view();
424 assert(crate::relations::injective(k_deepview));
425 assert(k_deepview(k1) == k_deepview(k2));
426 }
427 }
428}
429
430pub broadcast proof fn lemma_btree_map_deepview_values<K: DeepView, V: DeepView>(m: BTreeMap<K, V>)
431 requires
432 crate::relations::injective(|k: K| k.deep_view()),
433 ensures
434 #[trigger] m.deep_view().values() =~= m@.values().map(|v: V| v.deep_view()),
435{
436 reveal(btree_map_deep_view_impl);
437 broadcast use group_btree_axioms;
438 broadcast use lemma_btree_map_deepview_properties;
439 broadcast use crate::vstd::group_vstd_default;
440
441 let lhs = m.deep_view().values();
442 let rhs = m@.values().map(|v: V| v.deep_view());
443 assert forall|v: V::V| #[trigger] lhs.contains(v) implies rhs.contains(v) by {
444 let dk = choose|dk: K::V| #[trigger]
445 m.deep_view().contains_key(dk) && m.deep_view()[dk] == v;
446 let k = choose|k: K| #[trigger] m@.contains_key(k) && k.deep_view() == dk;
447 let ov = choose|ov: V| #[trigger] m@.contains_key(k) && m@[k] == ov && ov.deep_view() == v;
448 assert(v == ov.deep_view());
449 assert(m@.values().contains(ov));
450 }
451}
452
453pub open spec fn btree_map_inv<Key: Ord, Value, A: Allocator + Clone>(
454 m: &BTreeMap<Key, Value, A>,
455) -> bool {
456 forall|k1: Key, k2: Key|
457 {
458 &&& #[trigger] m@.contains_key(k1)
459 &&& #[trigger] m@.contains_key(k2)
460 &&& k1 != k2
461 } ==> !(k1.cmp_spec(&k2) is Equal)
462}
463
464pub uninterp spec fn spec_btree_map_len<Key, Value, A: Allocator + Clone>(
465 m: &BTreeMap<Key, Value, A>,
466) -> usize;
467
468pub broadcast axiom fn axiom_spec_btree_map_len<Key, Value, A: Allocator + Clone>(
469 m: &BTreeMap<Key, Value, A>,
470)
471 ensures
472 key_obeys_cmp_spec::<Key>() ==> #[trigger] spec_btree_map_len(m) == m@.len(),
473;
474
475#[verifier::when_used_as_spec(spec_btree_map_len)]
476pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::len ](
477 m: &BTreeMap<Key, Value, A>,
478) -> (len: usize)
479 ensures
480 len == spec_btree_map_len(m),
481;
482
483pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::is_empty ](
484 m: &BTreeMap<Key, Value, A>,
485) -> (res: bool)
486 ensures
487 res == m@.is_empty(),
488;
489
490pub assume_specification<K: Clone, V: Clone, A: Allocator + Clone>[ <BTreeMap::<
491 K,
492 V,
493 A,
494> as Clone>::clone ](this: &BTreeMap<K, V, A>) -> (other: BTreeMap<K, V, A>)
495 ensures
496 other@ == this@,
497;
498
499pub assume_specification<Key, Value>[ BTreeMap::<Key, Value>::new ]() -> (m: BTreeMap<Key, Value>)
500 ensures
501 m@ == Map::<Key, Value>::empty(),
502;
503
504pub assume_specification<K, V>[ <BTreeMap<K, V> as core::default::Default>::default ]() -> (m:
505 BTreeMap<K, V>)
506 ensures
507 m@ == Map::<K, V>::empty(),
508;
509
510pub open spec fn btree_map_insert_ensures<Key: Ord, Value, A: Allocator + Clone>(
511 old_m: &BTreeMap<Key, Value, A>,
512 final_m: &BTreeMap<Key, Value, A>,
513 k: Key,
514 v: Value,
515 result: Option<Value>,
516) -> bool {
517 obeys_cmp::<Key>() && btree_map_inv(old_m) ==> {
518 &&& btree_map_inv(final_m)
519 &&& match result {
520 Some(old_value) => exists|stored_key: Key|
521 {
522 &&& #[trigger] old_m@.contains_key(stored_key)
523 &&& k.cmp_spec(&stored_key) is Equal
524 &&& old_value == old_m@[stored_key]
525 &&& final_m@ == old_m@.insert(stored_key, v)
526 },
527 None => {
528 &&& forall|stored_key: Key| #[trigger]
529 old_m@.contains_key(stored_key) ==> !(k.cmp_spec(&stored_key) is Equal)
530 &&& final_m@ == old_m@.insert(k, v)
531 },
532 }
533 }
534}
535
536pub assume_specification<Key: Ord, Value, A: Allocator + Clone>[ BTreeMap::<
537 Key,
538 Value,
539 A,
540>::insert ](m: &mut BTreeMap<Key, Value, A>, k: Key, v: Value) -> (result: Option<Value>)
541 ensures
542 btree_map_insert_ensures(old(m), final(m), k, v, result),
543;
544
545pub broadcast proof fn lemma_btree_map_insert_ensures_if_obeys_cmp_concrete_eq<
546 Key: Ord,
547 Value,
548 A: Allocator + Clone,
549>(
550 old_m: &BTreeMap<Key, Value, A>,
551 final_m: &BTreeMap<Key, Value, A>,
552 k: Key,
553 v: Value,
554 result: Option<Value>,
555)
556 requires
557 obeys_cmp::<Key>(),
558 obeys_cmp_concrete_eq::<Key>(),
559 #[trigger] btree_map_insert_ensures::<Key, Value, A>(old_m, final_m, k, v, result),
560 ensures
561 final_m@ == old_m@.insert(k, v),
562 match result {
563 Some(old_value) => old_m@.contains_key(k) && old_value == old_m[k],
564 None => !old_m@.contains_key(k),
565 },
566{
567}
568
569pub broadcast proof fn lemma_btree_map_insert_ensures_if_obeys_cmp_deep_eq<
570 Key: Ord + DeepView,
571 Value: DeepView,
572 A: Allocator + Clone,
573>(
574 old_m: &BTreeMap<Key, Value, A>,
575 final_m: &BTreeMap<Key, Value, A>,
576 k: Key,
577 v: Value,
578 result: Option<Value>,
579)
580 requires
581 obeys_cmp::<Key>(),
582 obeys_cmp_deep_eq::<Key>(),
583 btree_map_inv(old_m),
584 #[trigger] btree_map_insert_ensures::<Key, Value, A>(old_m, final_m, k, v, result),
585 ensures
586 final_m.deep_view() == old_m.deep_view().insert(k.deep_view(), v.deep_view()),
587 match result {
588 Some(old_value) => {
589 &&& old_m.deep_view().contains_key(k.deep_view())
590 &&& old_value.deep_view() == old_m.deep_view()[k.deep_view()]
591 },
592 None => !old_m.deep_view().contains_key(k.deep_view()),
593 },
594{
595 broadcast use {
596 crate::map::group_map_lemmas,
597 crate::set::group_set_lemmas,
598 Set::lemma_map_contains,
599 };
600
601 reveal(btree_map_deep_view_impl);
602
603 let stored_key = match result {
604 Some(old_value) => choose|stored_key: Key|
605 {
606 &&& #[trigger] old_m@.contains_key(stored_key)
607 &&& k.cmp_spec(&stored_key) is Equal
608 &&& old_value == old_m@[stored_key]
609 &&& final_m@ == old_m@.insert(stored_key, v)
610 },
611 None => k,
612 };
613
614 assert(final_m@.contains_key(stored_key));
615 assert_maps_equal!(
616 final_m.deep_view(),
617 old_m.deep_view().insert(k.deep_view(), v.deep_view()),
618 kd => {
619 if final_m.deep_view().contains_key(kd) && kd != k.deep_view() {
620 let key = choose|key: Key|
621 final_m@.contains_key(key) && #[trigger] key.deep_view() == kd;
622 assert(old_m@.contains_key(key));
623 }
624 if old_m.deep_view().contains_key(kd) {
625 let key = choose|key: Key|
626 old_m@.contains_key(key) && #[trigger] key.deep_view() == kd;
627 assert(final_m@.contains_key(key));
628 }
629 }
630 );
631}
632
633pub open spec fn btree_map_contains_key_ensures<
634 Key: Borrow<Q> + Ord,
635 Value,
636 A: Allocator + Clone,
637 Q: Ord + ?Sized,
638>(m: &BTreeMap<Key, Value, A>, k: &Q, result: bool) -> bool {
639 ({
640 &&& obeys_cmp::<Key>()
641 &&& obeys_cmp::<&Q>()
642 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
643 &&& btree_map_inv(m)
644 }) ==> {
645 &&& result == exists|key: Key|
646 {
647 &&& #[trigger] m@.contains_key(key)
648 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(&key)) is Equal
649 }
650 }
651}
652
653pub assume_specification<
654 Key: Borrow<Q> + Ord,
655 Value,
656 A: Allocator + Clone,
657 Q: Ord + ?Sized,
658>[ BTreeMap::<Key, Value, A>::contains_key::<Q> ](m: &BTreeMap<Key, Value, A>, k: &Q) -> (result:
659 bool)
660 requires
661 borrowed_key_ordering_matches::<Key, Q>(),
662 ensures
663 btree_map_contains_key_ensures(m, k, result),
664;
665
666pub broadcast proof fn lemma_btree_map_contains_key_ensures_if_obeys_cmp_concrete_eq<
667 Key: Ord,
668 Value,
669 A: Allocator + Clone,
670>(m: &BTreeMap<Key, Value, A>, k: &Key, result: bool)
671 requires
672 obeys_cmp::<Key>(),
673 obeys_cmp_concrete_eq::<Key>(),
674 btree_map_inv(m),
675 #[trigger] btree_map_contains_key_ensures(m, k, result),
676 ensures
677 result == m@.contains_key(*k),
678{
679 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
680
681 reveal(crate::laws_cmp::obeys_cmp_ord);
682}
683
684pub broadcast proof fn lemma_btree_map_contains_key_ensures_if_obeys_cmp_deep_eq<
685 Key: Ord + DeepView,
686 Value: DeepView,
687 A: Allocator + Clone,
688>(m: &BTreeMap<Key, Value, A>, k: &Key, result: bool)
689 requires
690 obeys_cmp::<Key>(),
691 obeys_cmp_deep_eq::<Key>(),
692 btree_map_inv(m),
693 #[trigger] btree_map_contains_key_ensures(m, k, result),
694 ensures
695 Key::obeys_cmp_spec(),
696 result == m.deep_view().contains_key(k.deep_view()),
697{
698 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
699 broadcast use {
700 crate::map::group_map_lemmas,
701 crate::set::group_set_lemmas,
702 Set::lemma_map_contains,
703 };
704
705 reveal(crate::laws_cmp::obeys_cmp_ord);
706 reveal(btree_map_deep_view_impl);
707
708 if result {
709 let key = choose|key: Key|
710 {
711 &&& #[trigger] m@.contains_key(key)
712 &&& k.cmp_spec(&key) is Equal
713 };
714 assert(m.deep_view().contains_key(key.deep_view()));
715 }
716 if m.deep_view().contains_key(k.deep_view()) {
717 let key = choose|key: Key|
718 m@.contains_key(key) && #[trigger] key.deep_view() == k.deep_view();
719 assert(k.cmp_spec(&key) is Equal);
720 }
721}
722
723pub open spec fn btree_map_get_ensures<
724 Key: Borrow<Q> + Ord,
725 Value,
726 A: Allocator + Clone,
727 Q: Ord + ?Sized,
728>(m: &BTreeMap<Key, Value, A>, k: &Q, result: Option<&Value>) -> bool {
729 ({
730 &&& obeys_cmp::<Key>()
731 &&& obeys_cmp::<&Q>()
732 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
733 &&& btree_map_inv(m)
734 }) ==> {
735 match result {
736 Some(v) => exists|key: Key|
737 {
738 &&& #[trigger] m@.contains_key(key)
739 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(&key)) is Equal
740 &&& m@[key] == *v
741 },
742 None => forall|key: Key| #[trigger]
743 m@.contains_key(key) ==> !(k.cmp_spec(
744 <Key as BorrowSpec<Q>>::borrow_spec(&key),
745 ) is Equal),
746 }
747 }
748}
749
750pub assume_specification<
751 'a,
752 Key: Borrow<Q> + Ord,
753 Value,
754 A: Allocator + Clone,
755 Q: Ord + ?Sized,
756>[ BTreeMap::<Key, Value, A>::get::<Q> ](m: &'a BTreeMap<Key, Value, A>, k: &Q) -> (result: Option<
757 &'a Value,
758>)
759 requires
760 borrowed_key_ordering_matches::<Key, Q>(),
761 ensures
762 btree_map_get_ensures(m, k, result),
763;
764
765pub broadcast proof fn lemma_btree_map_get_ensures_if_obeys_cmp_concrete_eq<
766 Key: Ord,
767 Value,
768 A: Allocator + Clone,
769>(m: &BTreeMap<Key, Value, A>, k: &Key, result: Option<&Value>)
770 requires
771 obeys_cmp::<Key>(),
772 obeys_cmp_concrete_eq::<Key>(),
773 btree_map_inv(m),
774 #[trigger] btree_map_get_ensures(m, k, result),
775 ensures
776 match result {
777 Some(v) => m@.contains_key(*k) && *v == m@[*k],
778 None => !m@.contains_key(*k),
779 },
780{
781 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
782
783 reveal(crate::laws_cmp::obeys_cmp_ord);
784}
785
786pub broadcast proof fn lemma_btree_map_get_ensures_if_obeys_cmp_deep_eq<
787 Key: Ord + DeepView,
788 Value: DeepView,
789 A: Allocator + Clone,
790>(m: &BTreeMap<Key, Value, A>, k: &Key, result: Option<&Value>)
791 requires
792 obeys_cmp::<Key>(),
793 obeys_cmp_deep_eq::<Key>(),
794 btree_map_inv(m),
795 #[trigger] btree_map_get_ensures(m, k, result),
796 ensures
797 Key::obeys_cmp_spec(),
798 match result {
799 Some(v) => {
800 &&& m.deep_view().contains_key(k.deep_view())
801 &&& v.deep_view() == m.deep_view()[k.deep_view()]
802 },
803 None => !m.deep_view().contains_key(k.deep_view()),
804 },
805{
806 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
807 broadcast use {
808 crate::map::group_map_lemmas,
809 crate::set::group_set_lemmas,
810 Set::lemma_map_contains,
811 };
812
813 reveal(crate::laws_cmp::obeys_cmp_ord);
814 reveal(btree_map_deep_view_impl);
815
816 match result {
817 Some(v) => {
818 let stored_key = choose|key: Key|
819 {
820 &&& #[trigger] m@.contains_key(key)
821 &&& k.cmp_spec(&key) is Equal
822 &&& m@[key] == *v
823 };
824 assert(m.deep_view().contains_key(k.deep_view()));
825 let key = choose|key: Key|
826 m@.contains_key(key) && #[trigger] key.deep_view() == k.deep_view();
827 assert(key == stored_key);
828 },
829 None => {
830 if m.deep_view().contains_key(k.deep_view()) {
831 let key = choose|key: Key|
832 m@.contains_key(key) && #[trigger] key.deep_view() == k.deep_view();
833 assert(k.cmp_spec(&key) is Equal);
834 }
835 },
836 }
837}
838
839pub open spec fn btree_map_remove_ensures<
840 Key: Borrow<Q> + Ord,
841 Value,
842 A: Allocator + Clone,
843 Q: Ord + ?Sized,
844>(
845 old_m: &BTreeMap<Key, Value, A>,
846 final_m: &BTreeMap<Key, Value, A>,
847 k: &Q,
848 result: Option<Value>,
849) -> bool {
850 ({
851 &&& obeys_cmp::<Key>()
852 &&& obeys_cmp::<&Q>()
853 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
854 &&& btree_map_inv(old_m)
855 }) ==> {
856 &&& btree_map_inv(final_m)
857 &&& match result {
858 Some(v) => exists|key: Key|
859 {
860 &&& #[trigger] old_m@.contains_key(key)
861 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(&key)) is Equal
862 &&& old_m@[key] == v
863 &&& final_m@ == old_m@.remove(key)
864 },
865 None => {
866 &&& forall|key: Key| #[trigger]
867 old_m@.contains_key(key) ==> !(k.cmp_spec(
868 <Key as BorrowSpec<Q>>::borrow_spec(&key),
869 ) is Equal)
870 &&& final_m@ == old_m@
871 },
872 }
873 }
874}
875
876pub assume_specification<
877 Key: Borrow<Q> + Ord,
878 Value,
879 A: Allocator + Clone,
880 Q: Ord + ?Sized,
881>[ BTreeMap::<Key, Value, A>::remove::<Q> ](m: &mut BTreeMap<Key, Value, A>, k: &Q) -> (result:
882 Option<Value>)
883 requires
884 borrowed_key_ordering_matches::<Key, Q>(),
885 ensures
886 btree_map_remove_ensures(old(m), final(m), k, result),
887;
888
889pub broadcast proof fn lemma_btree_map_remove_ensures_if_obeys_cmp_concrete_eq<
890 Key: Ord,
891 Value,
892 A: Allocator + Clone,
893>(
894 old_m: &BTreeMap<Key, Value, A>,
895 final_m: &BTreeMap<Key, Value, A>,
896 k: &Key,
897 result: Option<Value>,
898)
899 requires
900 obeys_cmp::<Key>(),
901 obeys_cmp_concrete_eq::<Key>(),
902 btree_map_inv(old_m),
903 #[trigger] btree_map_remove_ensures(old_m, final_m, k, result),
904 ensures
905 final_m@ == old_m@.remove(*k),
906 match result {
907 Some(v) => old_m@.contains_key(*k) && v == old_m@[*k],
908 None => !old_m@.contains_key(*k),
909 },
910{
911 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
912 broadcast use {crate::map::group_map_lemmas, crate::set::group_set_lemmas};
913
914 reveal(crate::laws_cmp::obeys_cmp_ord);
915
916 if result is None {
917 assert(!old_m@.contains_key(*k));
918 assert(old_m@.remove(*k) =~= old_m@);
919 }
920}
921
922pub broadcast proof fn lemma_btree_map_remove_ensures_if_obeys_cmp_deep_eq<
923 Key: Ord + DeepView,
924 Value: DeepView,
925 A: Allocator + Clone,
926>(
927 old_m: &BTreeMap<Key, Value, A>,
928 final_m: &BTreeMap<Key, Value, A>,
929 k: &Key,
930 result: Option<Value>,
931)
932 requires
933 obeys_cmp::<Key>(),
934 obeys_cmp_deep_eq::<Key>(),
935 btree_map_inv(old_m),
936 #[trigger] btree_map_remove_ensures(old_m, final_m, k, result),
937 ensures
938 Key::obeys_cmp_spec(),
939 final_m.deep_view() == old_m.deep_view().remove(k.deep_view()),
940 match result {
941 Some(v) => {
942 &&& old_m.deep_view().contains_key(k.deep_view())
943 &&& v.deep_view() == old_m.deep_view()[k.deep_view()]
944 },
945 None => !old_m.deep_view().contains_key(k.deep_view()),
946 },
947{
948 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
949 broadcast use {
950 crate::map::group_map_lemmas,
951 crate::set::group_set_lemmas,
952 Set::lemma_map_contains,
953 };
954
955 reveal(crate::laws_cmp::obeys_cmp_ord);
956 reveal(btree_map_deep_view_impl);
957
958 let stored_key = match result {
959 Some(v) => choose|key: Key|
960 {
961 &&& #[trigger] old_m@.contains_key(key)
962 &&& k.cmp_spec(&key) is Equal
963 &&& old_m@[key] == v
964 &&& final_m@ == old_m@.remove(key)
965 },
966 None => *k,
967 };
968
969 match result {
970 Some(v) => {
971 assert(old_m.deep_view().contains_key(k.deep_view()));
972 let key = choose|key: Key|
973 old_m@.contains_key(key) && #[trigger] key.deep_view() == k.deep_view();
974 assert(key == stored_key);
975 },
976 None => {
977 if old_m.deep_view().contains_key(k.deep_view()) {
978 let key = choose|key: Key|
979 old_m@.contains_key(key) && #[trigger] key.deep_view() == k.deep_view();
980 assert(k.cmp_spec(&key) is Equal);
981 }
982 },
983 }
984
985 assert_maps_equal!(
986 final_m.deep_view(),
987 old_m.deep_view().remove(k.deep_view()),
988 kd => {
989 if final_m.deep_view().contains_key(kd) {
990 let key = choose|key: Key|
991 final_m@.contains_key(key) && #[trigger] key.deep_view() == kd;
992 assert(old_m@.contains_key(key));
993 assert(key.deep_view() != k.deep_view());
994 }
995 if old_m.deep_view().contains_key(kd) && kd != k.deep_view() {
996 let key = choose|key: Key|
997 old_m@.contains_key(key) && #[trigger] key.deep_view() == kd;
998 assert(final_m@.contains_key(key));
999 }
1000 }
1001 );
1002}
1003
1004pub open spec fn btree_map_get_mut_ensures<
1005 Key: Borrow<Q> + Ord,
1006 Value,
1007 A: Allocator + Clone,
1008 Q: Ord + ?Sized,
1009>(
1010 old_m: &BTreeMap<Key, Value, A>,
1011 final_m: &BTreeMap<Key, Value, A>,
1012 k: &Q,
1013 result: Option<(Value, Value)>,
1014) -> bool {
1015 ({
1016 &&& obeys_cmp::<Key>()
1017 &&& obeys_cmp::<&Q>()
1018 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
1019 &&& btree_map_inv(old_m)
1020 }) ==> {
1021 &&& btree_map_inv(final_m)
1022 &&& match result {
1023 Some((current_value, final_value)) => exists|stored_key: Key|
1024 {
1025 &&& #[trigger] old_m@.contains_key(stored_key)
1026 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(&stored_key)) is Equal
1027 &&& old_m@[stored_key] == current_value
1028 &&& final_m@ == old_m@.insert(stored_key, final_value)
1029 },
1030 None => {
1031 &&& forall|stored_key: Key| #[trigger]
1032 old_m@.contains_key(stored_key) ==> !(k.cmp_spec(
1033 <Key as BorrowSpec<Q>>::borrow_spec(&stored_key),
1034 ) is Equal)
1035 &&& final_m@ == old_m@
1036 },
1037 }
1038 }
1039}
1040
1041pub assume_specification<
1043 'a,
1044 Key: Borrow<Q> + Ord,
1045 Value,
1046 A: Allocator + Clone,
1047 Q: Ord + ?Sized,
1048>[ BTreeMap::<Key, Value, A>::get_mut::<Q> ](
1049 m: &'a mut BTreeMap<Key, Value, A>,
1050 key: &Q,
1051) -> (result: Option<&'a mut Value>)
1052 requires
1053 borrowed_key_ordering_matches::<Key, Q>(),
1054 ensures
1055 match result {
1056 Some(value) => btree_map_get_mut_ensures(
1057 old(m),
1058 final(m),
1059 key,
1060 Some((*value, *final(value))),
1061 ),
1062 None => btree_map_get_mut_ensures(old(m), final(m), key, None),
1063 },
1064;
1065
1066pub broadcast proof fn lemma_btree_map_get_mut_ensures_if_obeys_cmp_concrete_eq<
1067 Key: Ord,
1068 Value,
1069 A: Allocator + Clone,
1070>(
1071 old_m: &BTreeMap<Key, Value, A>,
1072 final_m: &BTreeMap<Key, Value, A>,
1073 k: &Key,
1074 result: Option<(Value, Value)>,
1075)
1076 requires
1077 obeys_cmp::<Key>(),
1078 obeys_cmp_concrete_eq::<Key>(),
1079 btree_map_inv(old_m),
1080 #[trigger] btree_map_get_mut_ensures(old_m, final_m, k, result),
1081 ensures
1082 match result {
1083 Some((current_value, final_value)) => {
1084 &&& old_m@.contains_key(*k)
1085 &&& current_value == old_m@[*k]
1086 &&& final_m@ == old_m@.insert(*k, final_value)
1087 },
1088 None => {
1089 &&& !old_m@.contains_key(*k)
1090 &&& final_m@ == old_m@
1091 },
1092 },
1093{
1094 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1095
1096 reveal(crate::laws_cmp::obeys_cmp_ord);
1097}
1098
1099pub broadcast proof fn lemma_btree_map_get_mut_ensures_if_obeys_cmp_deep_eq<
1100 Key: Ord + DeepView,
1101 Value: DeepView,
1102 A: Allocator + Clone,
1103>(
1104 old_m: &BTreeMap<Key, Value, A>,
1105 final_m: &BTreeMap<Key, Value, A>,
1106 k: &Key,
1107 result: Option<(Value, Value)>,
1108)
1109 requires
1110 obeys_cmp::<Key>(),
1111 obeys_cmp_deep_eq::<Key>(),
1112 btree_map_inv(old_m),
1113 #[trigger] btree_map_get_mut_ensures(old_m, final_m, k, result),
1114 ensures
1115 Key::obeys_cmp_spec(),
1116 match result {
1117 Some((current_value, final_value)) => {
1118 &&& old_m.deep_view().contains_key(k.deep_view())
1119 &&& current_value.deep_view() == old_m.deep_view()[k.deep_view()]
1120 &&& final_m.deep_view() == old_m.deep_view().insert(
1121 k.deep_view(),
1122 final_value.deep_view(),
1123 )
1124 },
1125 None => {
1126 &&& !old_m.deep_view().contains_key(k.deep_view())
1127 &&& final_m.deep_view() == old_m.deep_view()
1128 },
1129 },
1130{
1131 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1132
1133 reveal(crate::laws_cmp::obeys_cmp_ord);
1134
1135 match result {
1136 Some((current_value, final_value)) => {
1137 lemma_btree_map_insert_ensures_if_obeys_cmp_deep_eq(
1138 old_m,
1139 final_m,
1140 *k,
1141 final_value,
1142 Some(current_value),
1143 );
1144 },
1145 None => {
1146 broadcast use {
1147 crate::map::group_map_lemmas,
1148 crate::set::group_set_lemmas,
1149 Set::lemma_map_contains,
1150 };
1151
1152 reveal(btree_map_deep_view_impl);
1153
1154 if old_m.deep_view().contains_key(k.deep_view()) {
1155 let key = choose|key: Key|
1156 old_m@.contains_key(key) && #[trigger] key.deep_view() == k.deep_view();
1157 assert(k.cmp_spec(&key) is Equal);
1158 }
1159 },
1160 }
1161}
1162
1163pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::clear ](
1164 m: &mut BTreeMap<Key, Value, A>,
1165)
1166 ensures
1167 final(m)@ == Map::<Key, Value>::empty(),
1168;
1169
1170pub assume_specification<
1172 'a,
1173 Key: Borrow<Q> + Ord,
1174 Value,
1175 A: Allocator + Clone,
1176 Q: Ord + ?Sized,
1177>[ BTreeMap::<Key, Value, A>::lower_bound_mut::<Q> ](
1178 map: &'a mut BTreeMap<Key, Value, A>,
1179 bound: Bound<&Q>,
1180) -> (cursor: CursorMut<'a, Key, Value, A>)
1181 requires
1182 borrowed_key_ordering_matches::<Key, Q>(),
1183 ensures
1184 ({
1185 &&& obeys_cmp::<Key>()
1186 &&& obeys_cmp::<&Q>()
1187 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
1188 }) ==> {
1189 &&& cursor@.wf()
1190 &&& cursor@.map == old(map)@
1191 &&& final(map)@ == cursor.final_map()
1192 &&& positioned_at_lower_bound(cursor@, bound)
1193 },
1194;
1195
1196pub assume_specification<
1198 'a,
1199 Key: Borrow<Q> + Ord,
1200 Value,
1201 A: Allocator + Clone,
1202 Q: Ord + ?Sized,
1203>[ BTreeMap::<Key, Value, A>::upper_bound_mut::<Q> ](
1204 map: &'a mut BTreeMap<Key, Value, A>,
1205 bound: Bound<&Q>,
1206) -> (cursor: CursorMut<'a, Key, Value, A>)
1207 requires
1208 borrowed_key_ordering_matches::<Key, Q>(),
1209 ensures
1210 ({
1211 &&& obeys_cmp::<Key>()
1212 &&& obeys_cmp::<&Q>()
1213 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
1214 }) ==> {
1215 &&& cursor@.wf()
1216 &&& cursor@.map == old(map)@
1217 &&& final(map)@ == cursor.final_map()
1218 &&& positioned_at_upper_bound(cursor@, bound)
1219 },
1220;
1221
1222pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::next ](
1224 cursor: &'b mut CursorMut<'a, Key, Value, A>,
1225) -> (result: Option<(&'b Key, &'b mut Value)>)
1226 requires
1227 old(cursor)@.wf(),
1228 ensures
1229 final(cursor).final_map() == old(cursor).final_map(),
1230 final(cursor)@.wf(),
1231 match result {
1232 Some((key, value)) => {
1233 let old_model = old(cursor)@;
1234 let new_model = final(cursor)@;
1235 &&& old_model.position < old_model.keys.len()
1236 &&& *key == old_model.keys[old_model.position]
1237 &&& *value == old_model.map[*key]
1238 &&& new_model.keys == old_model.keys
1239 &&& new_model.position == old_model.position + 1
1240 &&& new_model.map == old_model.map.insert(*key, *final(value))
1241 },
1242 None => {
1243 &&& old(cursor)@.position == old(cursor)@.keys.len()
1244 &&& final(cursor)@ == old(cursor)@
1245 },
1246 },
1247;
1248
1249pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::prev ](
1251 cursor: &'b mut CursorMut<'a, Key, Value, A>,
1252) -> (result: Option<(&'b Key, &'b mut Value)>)
1253 requires
1254 old(cursor)@.wf(),
1255 ensures
1256 final(cursor).final_map() == old(cursor).final_map(),
1257 final(cursor)@.wf(),
1258 match result {
1259 Some((key, value)) => {
1260 let old_model = old(cursor)@;
1261 let new_model = final(cursor)@;
1262 &&& old_model.position > 0
1263 &&& *key == old_model.keys[old_model.position - 1]
1264 &&& *value == old_model.map[*key]
1265 &&& new_model.keys == old_model.keys
1266 &&& new_model.position == old_model.position - 1
1267 &&& new_model.map == old_model.map.insert(*key, *final(value))
1268 },
1269 None => {
1270 &&& old(cursor)@.position == 0
1271 &&& final(cursor)@ == old(cursor)@
1272 },
1273 },
1274;
1275
1276pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::peek_prev ](
1278 cursor: &'b mut CursorMut<'a, Key, Value, A>,
1279) -> (result: Option<(&'b Key, &'b mut Value)>)
1280 requires
1281 old(cursor)@.wf(),
1282 ensures
1283 final(cursor).final_map() == old(cursor).final_map(),
1284 final(cursor)@.wf(),
1285 match result {
1286 Some((key, value)) => {
1287 let old_model = old(cursor)@;
1288 let new_model = final(cursor)@;
1289 &&& old_model.position > 0
1290 &&& *key == old_model.keys[old_model.position - 1]
1291 &&& *value == old_model.map[*key]
1292 &&& new_model.keys == old_model.keys
1293 &&& new_model.position == old_model.position
1294 &&& new_model.map == old_model.map.insert(*key, *final(value))
1295 },
1296 None => {
1297 &&& old(cursor)@.position == 0
1298 &&& final(cursor)@ == old(cursor)@
1299 },
1300 },
1301;
1302
1303pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::peek_next ](
1305 cursor: &'b mut CursorMut<'a, Key, Value, A>,
1306) -> (result: Option<(&'b Key, &'b mut Value)>)
1307 requires
1308 old(cursor)@.wf(),
1309 ensures
1310 final(cursor).final_map() == old(cursor).final_map(),
1311 final(cursor)@.wf(),
1312 match result {
1313 Some((key, value)) => {
1314 let old_model = old(cursor)@;
1315 let new_model = final(cursor)@;
1316 &&& old_model.position < old_model.keys.len()
1317 &&& *key == old_model.keys[old_model.position]
1318 &&& *value == old_model.map[*key]
1319 &&& new_model.keys == old_model.keys
1320 &&& new_model.position == old_model.position
1321 &&& new_model.map == old_model.map.insert(*key, *final(value))
1322 },
1323 None => {
1324 &&& old(cursor)@.position == old(cursor)@.keys.len()
1325 &&& final(cursor)@ == old(cursor)@
1326 },
1327 },
1328;
1329
1330pub assume_specification<'a, Key: Ord, Value, A: Allocator + Clone>[ CursorMut::<
1332 'a,
1333 Key,
1334 Value,
1335 A,
1336>::insert_after ](cursor: &mut CursorMut<'a, Key, Value, A>, key: Key, value: Value) -> (result:
1337 Result<(), UnorderedKeyError>)
1338 requires
1339 old(cursor)@.wf(),
1340 ensures
1341 final(cursor).final_map() == old(cursor).final_map(),
1342 obeys_cmp::<Key>() ==> {
1343 &&& final(cursor)@.wf()
1344 &&& match result {
1345 Ok(()) => {
1346 let old_model = old(cursor)@;
1347 let new_model = final(cursor)@;
1348 &&& key_fits_at_position(old_model, key)
1349 &&& new_model.keys == old_model.keys.insert(old_model.position, key)
1350 &&& new_model.position == old_model.position
1351 &&& new_model.map == old_model.map.insert(key, value)
1352 },
1353 Err(_) => {
1354 &&& !key_fits_at_position(old(cursor)@, key)
1355 &&& final(cursor)@ == old(cursor)@
1356 },
1357 }
1358 },
1359;
1360
1361pub assume_specification<'a, Key: Ord, Value, A: Allocator + Clone>[ CursorMut::<
1363 'a,
1364 Key,
1365 Value,
1366 A,
1367>::remove_next ](cursor: &mut CursorMut<'a, Key, Value, A>) -> (result: Option<(Key, Value)>)
1368 requires
1369 old(cursor)@.wf(),
1370 ensures
1371 final(cursor).final_map() == old(cursor).final_map(),
1372 final(cursor)@.wf(),
1373 match result {
1374 Some((key, value)) => {
1375 let old_model = old(cursor)@;
1376 let new_model = final(cursor)@;
1377 &&& old_model.position < old_model.keys.len()
1378 &&& key == old_model.keys[old_model.position]
1379 &&& value == old_model.map[key]
1380 &&& new_model.keys == old_model.keys.remove(old_model.position)
1381 &&& new_model.position == old_model.position
1382 &&& new_model.map == old_model.map.remove(key)
1383 },
1384 None => {
1385 &&& old(cursor)@.position == old(cursor)@.keys.len()
1386 &&& final(cursor)@ == old(cursor)@
1387 },
1388 },
1389;
1390
1391pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::keys ](
1392 m: &'a BTreeMap<Key, Value, A>,
1393) -> (keys: Keys<'a, Key, Value>)
1394 ensures
1395 key_obeys_cmp_spec::<Key>() ==> {
1396 &&& IteratorSpec::remaining(&keys).unref().to_set() == m@.dom()
1397 &&& IteratorSpec::remaining(&keys).no_duplicates()
1398 &&& IteratorSpec::remaining(&keys).len() == m@.dom().len()
1399 &&& increasing_seq(IteratorSpec::remaining(&keys))
1400 &&& into_iter_keys(keys) == IteratorSpec::remaining(&keys).unref()
1401 &&& IteratorSpec::decrease(&keys) is Some
1402 },
1403;
1404
1405pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::values ](
1406 m: &'a BTreeMap<Key, Value, A>,
1407) -> (values: Values<'a, Key, Value>)
1408 ensures
1409 key_obeys_cmp_spec::<Key>() ==> {
1410 &&& IteratorSpec::remaining(&values).unref().to_set() == m@.values()
1411 &&& IteratorSpec::remaining(&values).len() == m@.dom().len()
1412 &&& into_iter_values(values) == IteratorSpec::remaining(&values).unref()
1413 &&& IteratorSpec::decrease(&values) is Some
1414 &&& exists|key_seq: Seq<Key>|
1415 {
1416 &&& increasing_seq(key_seq)
1417 &&& key_seq.to_set() == m@.dom()
1418 &&& key_seq.no_duplicates()
1419 &&& IteratorSpec::remaining(&values) == key_seq.map(|i: int, k| &m@[k])
1420 }
1421 },
1422;
1423
1424pub broadcast axiom fn axiom_btree_map_decreases<Key, Value, A: Allocator + Clone>(
1425 m: BTreeMap<Key, Value, A>,
1426)
1427 ensures
1428 #[trigger] (decreases_to!(m => m@)),
1429;
1430
1431#[verifier::external_type_specification]
1434#[verifier::external_body]
1435#[verifier::accept_recursive_types(K)]
1436pub struct ExSetIter<'a, K: 'a>(btree_set::Iter<'a, K>);
1437
1438pub uninterp spec fn into_iter_btree_keys<'a, Key>(i: btree_set::Iter::<'a, Key>) -> Seq<Key>;
1441
1442impl<'a, T> super::iter::IteratorSpecImpl for btree_set::Iter::<'a, T> {
1443 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
1444 true
1445 }
1446
1447 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
1448
1449 #[verifier::prophetic]
1450 open spec fn produces(&self) -> Seq<bool> {
1451 Seq::new(IteratorSpec::remaining(self).len(), |i: int| true)
1452 }
1453
1454 uninterp spec fn decrease(&self) -> Option<nat>;
1455
1456 open spec fn peek(&self, index: int) -> Option<Self::Item> {
1457 if 0 <= index < into_iter_btree_keys(*self).len() {
1458 Some(&into_iter_btree_keys(*self)[index])
1459 } else {
1460 None
1461 }
1462 }
1463}
1464
1465#[verifier::external_type_specification]
1474#[verifier::external_body]
1475#[verifier::accept_recursive_types(Key)]
1476#[verifier::reject_recursive_types(A)]
1477pub struct ExBTreeSet<Key, A: Allocator + Clone>(BTreeSet<Key, A>);
1478
1479impl<Key, A: Allocator + Clone> View for BTreeSet<Key, A> {
1480 type V = Set<Key>;
1481
1482 uninterp spec fn view(&self) -> Set<Key>;
1483}
1484
1485impl<Key: DeepView, A: Allocator + Clone> DeepView for BTreeSet<Key, A> {
1486 type V = Set<Key::V>;
1487
1488 open spec fn deep_view(&self) -> Set<Key::V> {
1489 self@.map(|x: Key| x.deep_view())
1490 }
1491}
1492
1493pub open spec fn btree_set_inv<Key: Ord, A: Allocator + Clone>(m: &BTreeSet<Key, A>) -> bool {
1494 forall|k1: Key, k2: Key|
1495 {
1496 &&& #[trigger] m@.contains(k1)
1497 &&& #[trigger] m@.contains(k2)
1498 &&& k1 != k2
1499 } ==> !(k1.cmp_spec(&k2) is Equal)
1500}
1501
1502pub uninterp spec fn spec_btree_set_len<Key, A: Allocator + Clone>(m: &BTreeSet<Key, A>) -> usize;
1503
1504pub broadcast axiom fn axiom_spec_btree_set_len<Key, A: Allocator + Clone>(m: &BTreeSet<Key, A>)
1505 ensures
1506 key_obeys_cmp_spec::<Key>() ==> #[trigger] spec_btree_set_len(m) == m@.len(),
1507;
1508
1509#[verifier::when_used_as_spec(spec_btree_set_len)]
1510pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::len ](
1511 m: &BTreeSet<Key, A>,
1512) -> (len: usize)
1513 ensures
1514 len == spec_btree_set_len(m),
1515;
1516
1517pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::is_empty ](
1518 m: &BTreeSet<Key, A>,
1519) -> (res: bool)
1520 ensures
1521 res == m@.is_empty(),
1522;
1523
1524pub assume_specification<K: Clone, A: Allocator + Clone>[ <BTreeSet::<K, A> as Clone>::clone ](
1525 this: &BTreeSet<K, A>,
1526) -> (other: BTreeSet<K, A>)
1527 ensures
1528 other@ == this@,
1529;
1530
1531pub assume_specification<Key>[ BTreeSet::<Key>::new ]() -> (m: BTreeSet<Key>)
1532 ensures
1533 m@ == Set::<Key>::empty(),
1534;
1535
1536pub assume_specification<T>[ <BTreeSet<T> as core::default::Default>::default ]() -> (m: BTreeSet<
1537 T,
1538>)
1539 ensures
1540 m@ == Set::<T>::empty(),
1541;
1542
1543pub open spec fn btree_set_insert_ensures<Key: Ord, A: Allocator + Clone>(
1544 old_m: &BTreeSet<Key, A>,
1545 final_m: &BTreeSet<Key, A>,
1546 k: Key,
1547 result: bool,
1548) -> bool {
1549 obeys_cmp::<Key>() && btree_set_inv(old_m) ==> {
1550 &&& btree_set_inv(final_m)
1551 &&& if result {
1552 &&& forall|stored_key: Key| #[trigger]
1553 old_m@.contains(stored_key) ==> !(k.cmp_spec(&stored_key) is Equal)
1554 &&& final_m@ == old_m@.insert(k)
1555 } else {
1556 &&& exists|stored_key: Key| #[trigger]
1557 old_m@.contains(stored_key) && k.cmp_spec(&stored_key) is Equal
1558 &&& final_m@ == old_m@
1559 }
1560 }
1561}
1562
1563pub assume_specification<Key: Ord, A: Allocator + Clone>[ BTreeSet::<Key, A>::insert ](
1564 m: &mut BTreeSet<Key, A>,
1565 k: Key,
1566) -> (result: bool)
1567 ensures
1568 btree_set_insert_ensures(old(m), final(m), k, result),
1569;
1570
1571pub broadcast proof fn lemma_btree_set_insert_ensures_if_obeys_cmp_concrete_eq<
1572 Key: Ord,
1573 A: Allocator + Clone,
1574>(old_m: &BTreeSet<Key, A>, final_m: &BTreeSet<Key, A>, k: Key, result: bool)
1575 requires
1576 obeys_cmp::<Key>(),
1577 obeys_cmp_concrete_eq::<Key>(),
1578 btree_set_inv(old_m),
1579 #[trigger] btree_set_insert_ensures::<Key, A>(old_m, final_m, k, result),
1580 ensures
1581 final_m@ == old_m@.insert(k),
1582 result == !old_m@.contains(k),
1583{
1584 broadcast use crate::set::group_set_lemmas;
1585
1586 assert(k.cmp_spec(&k) is Equal);
1587 if !result {
1588 assert(old_m@.contains(k));
1589 assert(old_m@.insert(k) =~= old_m@);
1590 }
1591}
1592
1593pub broadcast proof fn lemma_btree_set_insert_ensures_if_obeys_cmp_deep_eq<
1594 Key: Ord + DeepView,
1595 A: Allocator + Clone,
1596>(old_m: &BTreeSet<Key, A>, final_m: &BTreeSet<Key, A>, k: Key, result: bool)
1597 requires
1598 obeys_cmp::<Key>(),
1599 obeys_cmp_deep_eq::<Key>(),
1600 btree_set_inv(old_m),
1601 #[trigger] btree_set_insert_ensures::<Key, A>(old_m, final_m, k, result),
1602 ensures
1603 final_m.deep_view() == old_m.deep_view().insert(k.deep_view()),
1604 result == !old_m.deep_view().contains(k.deep_view()),
1605{
1606 broadcast use {
1607 crate::set::group_set_lemmas,
1608 Set::lemma_map_contains,
1609 Set::lemma_set_map_insert_commute,
1610 };
1611
1612 if result {
1613 assert(!old_m.deep_view().contains(k.deep_view())) by {
1614 if old_m.deep_view().contains(k.deep_view()) {
1615 let stored_key = choose|stored_key: Key|
1616 old_m@.contains(stored_key) && #[trigger] stored_key.deep_view()
1617 == k.deep_view();
1618 assert(k.cmp_spec(&stored_key) is Equal);
1619 }
1620 }
1621 } else {
1622 let stored_key = choose|stored_key: Key| #[trigger]
1623 old_m@.contains(stored_key) && k.cmp_spec(&stored_key) is Equal;
1624 assert(stored_key.deep_view() == k.deep_view());
1625 assert(old_m.deep_view().contains(k.deep_view()));
1626 }
1627 assert(final_m.deep_view() =~= old_m.deep_view().insert(k.deep_view()));
1628}
1629
1630pub open spec fn btree_set_contains_ensures<
1631 Key: Borrow<Q> + Ord,
1632 A: Allocator + Clone,
1633 Q: Ord + ?Sized,
1634>(m: &BTreeSet<Key, A>, k: &Q, result: bool) -> bool {
1635 ({
1636 &&& obeys_cmp::<Key>()
1637 &&& obeys_cmp::<&Q>()
1638 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
1639 &&& btree_set_inv(m)
1640 }) ==> {
1641 &&& result == exists|key: Key|
1642 {
1643 &&& #[trigger] m@.contains(key)
1644 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(&key)) is Equal
1645 }
1646 }
1647}
1648
1649pub assume_specification<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>[ BTreeSet::<
1650 Key,
1651 A,
1652>::contains ](m: &BTreeSet<Key, A>, k: &Q) -> (result: bool)
1653 requires
1654 borrowed_key_ordering_matches::<Key, Q>(),
1655 ensures
1656 btree_set_contains_ensures(m, k, result),
1657;
1658
1659pub broadcast proof fn lemma_btree_set_contains_ensures_if_obeys_cmp_concrete_eq<
1660 Key: Ord,
1661 A: Allocator + Clone,
1662>(m: &BTreeSet<Key, A>, k: &Key, result: bool)
1663 requires
1664 obeys_cmp::<Key>(),
1665 obeys_cmp_concrete_eq::<Key>(),
1666 btree_set_inv(m),
1667 #[trigger] btree_set_contains_ensures(m, k, result),
1668 ensures
1669 result == m@.contains(*k),
1670{
1671 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1672
1673 reveal(crate::laws_cmp::obeys_cmp_ord);
1674}
1675
1676pub broadcast proof fn lemma_btree_set_contains_ensures_if_obeys_cmp_deep_eq<
1677 Key: Ord + DeepView,
1678 A: Allocator + Clone,
1679>(m: &BTreeSet<Key, A>, k: &Key, result: bool)
1680 requires
1681 obeys_cmp::<Key>(),
1682 obeys_cmp_deep_eq::<Key>(),
1683 btree_set_inv(m),
1684 #[trigger] btree_set_contains_ensures(m, k, result),
1685 ensures
1686 Key::obeys_cmp_spec(),
1687 result == m.deep_view().contains(k.deep_view()),
1688{
1689 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1690 broadcast use {crate::set::group_set_lemmas, Set::lemma_map_contains};
1691
1692 reveal(crate::laws_cmp::obeys_cmp_ord);
1693
1694 if result {
1695 let key = choose|key: Key|
1696 {
1697 &&& #[trigger] m@.contains(key)
1698 &&& k.cmp_spec(&key) is Equal
1699 };
1700 assert(m.deep_view().contains(key.deep_view()));
1701 }
1702 if m.deep_view().contains(k.deep_view()) {
1703 let key = choose|key: Key| m@.contains(key) && #[trigger] key.deep_view() == k.deep_view();
1704 assert(k.cmp_spec(&key) is Equal);
1705 }
1706}
1707
1708pub open spec fn btree_set_get_ensures<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>(
1709 m: &BTreeSet<Key, A>,
1710 k: &Q,
1711 result: Option<&Key>,
1712) -> bool {
1713 ({
1714 &&& obeys_cmp::<Key>()
1715 &&& obeys_cmp::<&Q>()
1716 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
1717 &&& btree_set_inv(m)
1718 }) ==> {
1719 &&& match result {
1720 Some(key) => {
1721 &&& m@.contains(*key)
1722 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(key)) is Equal
1723 },
1724 None => forall|key: Key| #[trigger]
1725 m@.contains(key) ==> !(k.cmp_spec(
1726 <Key as BorrowSpec<Q>>::borrow_spec(&key),
1727 ) is Equal),
1728 }
1729 }
1730}
1731
1732pub assume_specification<
1733 'a,
1734 Key: Borrow<Q> + Ord,
1735 A: Allocator + Clone,
1736 Q: Ord + ?Sized,
1737>[ BTreeSet::<Key, A>::get::<Q> ](m: &'a BTreeSet<Key, A>, k: &Q) -> (result: Option<&'a Key>)
1738 requires
1739 borrowed_key_ordering_matches::<Key, Q>(),
1740 ensures
1741 btree_set_get_ensures(m, k, result),
1742;
1743
1744pub broadcast proof fn lemma_btree_set_get_ensures_if_obeys_cmp_concrete_eq<
1745 Key: Ord,
1746 A: Allocator + Clone,
1747>(m: &BTreeSet<Key, A>, k: &Key, result: Option<&Key>)
1748 requires
1749 obeys_cmp::<Key>(),
1750 obeys_cmp_concrete_eq::<Key>(),
1751 btree_set_inv(m),
1752 #[trigger] btree_set_get_ensures(m, k, result),
1753 ensures
1754 match result {
1755 Some(key) => m@.contains(*key) && *key == *k,
1756 None => !m@.contains(*k),
1757 },
1758{
1759 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1760
1761 reveal(crate::laws_cmp::obeys_cmp_ord);
1762}
1763
1764pub broadcast proof fn lemma_btree_set_get_ensures_if_obeys_cmp_deep_eq<
1765 Key: Ord + DeepView,
1766 A: Allocator + Clone,
1767>(m: &BTreeSet<Key, A>, k: &Key, result: Option<&Key>)
1768 requires
1769 obeys_cmp::<Key>(),
1770 obeys_cmp_deep_eq::<Key>(),
1771 btree_set_inv(m),
1772 #[trigger] btree_set_get_ensures(m, k, result),
1773 ensures
1774 Key::obeys_cmp_spec(),
1775 match result {
1776 Some(key) => {
1777 &&& m@.contains(*key)
1778 &&& m.deep_view().contains(k.deep_view())
1779 &&& key.deep_view() == k.deep_view()
1780 },
1781 None => !m.deep_view().contains(k.deep_view()),
1782 },
1783{
1784 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1785 broadcast use {crate::set::group_set_lemmas, Set::lemma_map_contains};
1786
1787 reveal(crate::laws_cmp::obeys_cmp_ord);
1788
1789 match result {
1790 Some(key) => {
1791 assert(m.deep_view().contains(key.deep_view()));
1792 },
1793 None => {
1794 if m.deep_view().contains(k.deep_view()) {
1795 let key = choose|key: Key|
1796 m@.contains(key) && #[trigger] key.deep_view() == k.deep_view();
1797 assert(k.cmp_spec(&key) is Equal);
1798 }
1799 },
1800 }
1801}
1802
1803pub open spec fn btree_set_remove_ensures<
1804 Key: Borrow<Q> + Ord,
1805 A: Allocator + Clone,
1806 Q: Ord + ?Sized,
1807>(old_m: &BTreeSet<Key, A>, final_m: &BTreeSet<Key, A>, k: &Q, result: bool) -> bool {
1808 ({
1809 &&& obeys_cmp::<Key>()
1810 &&& obeys_cmp::<&Q>()
1811 &&& <Key as BorrowSpec<Q>>::obeys_borrow_spec()
1812 &&& btree_set_inv(old_m)
1813 }) ==> {
1814 &&& btree_set_inv(final_m)
1815 &&& if result {
1816 exists|key: Key|
1817 {
1818 &&& #[trigger] old_m@.contains(key)
1819 &&& k.cmp_spec(<Key as BorrowSpec<Q>>::borrow_spec(&key)) is Equal
1820 &&& final_m@ == old_m@.remove(key)
1821 }
1822 } else {
1823 &&& forall|key: Key| #[trigger]
1824 old_m@.contains(key) ==> !(k.cmp_spec(
1825 <Key as BorrowSpec<Q>>::borrow_spec(&key),
1826 ) is Equal)
1827 &&& final_m@ == old_m@
1828 }
1829 }
1830}
1831
1832pub assume_specification<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>[ BTreeSet::<
1833 Key,
1834 A,
1835>::remove::<Q> ](m: &mut BTreeSet<Key, A>, k: &Q) -> (result: bool)
1836 requires
1837 borrowed_key_ordering_matches::<Key, Q>(),
1838 ensures
1839 btree_set_remove_ensures(old(m), final(m), k, result),
1840;
1841
1842pub broadcast proof fn lemma_btree_set_remove_ensures_if_obeys_cmp_concrete_eq<
1843 Key: Ord,
1844 A: Allocator + Clone,
1845>(old_m: &BTreeSet<Key, A>, final_m: &BTreeSet<Key, A>, k: &Key, result: bool)
1846 requires
1847 obeys_cmp::<Key>(),
1848 obeys_cmp_concrete_eq::<Key>(),
1849 btree_set_inv(old_m),
1850 #[trigger] btree_set_remove_ensures(old_m, final_m, k, result),
1851 ensures
1852 final_m@ == old_m@.remove(*k),
1853 result == old_m@.contains(*k),
1854{
1855 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1856 broadcast use crate::set::group_set_lemmas;
1857
1858 reveal(crate::laws_cmp::obeys_cmp_ord);
1859
1860 if !result {
1861 assert(!old_m@.contains(*k));
1862 assert(old_m@.remove(*k) =~= old_m@);
1863 }
1864}
1865
1866pub broadcast proof fn lemma_btree_set_remove_ensures_if_obeys_cmp_deep_eq<
1867 Key: Ord + DeepView,
1868 A: Allocator + Clone,
1869>(old_m: &BTreeSet<Key, A>, final_m: &BTreeSet<Key, A>, k: &Key, result: bool)
1870 requires
1871 obeys_cmp::<Key>(),
1872 obeys_cmp_deep_eq::<Key>(),
1873 btree_set_inv(old_m),
1874 #[trigger] btree_set_remove_ensures(old_m, final_m, k, result),
1875 ensures
1876 Key::obeys_cmp_spec(),
1877 final_m.deep_view() == old_m.deep_view().remove(k.deep_view()),
1878 result == old_m.deep_view().contains(k.deep_view()),
1879{
1880 broadcast use crate::laws_cmp::lemma_ref_obeys_cmp_spec;
1881 broadcast use {crate::set::group_set_lemmas, Set::lemma_map_contains};
1882
1883 reveal(crate::laws_cmp::obeys_cmp_ord);
1884
1885 let stored_key = if result {
1886 choose|key: Key|
1887 {
1888 &&& #[trigger] old_m@.contains(key)
1889 &&& k.cmp_spec(&key) is Equal
1890 &&& final_m@ == old_m@.remove(key)
1891 }
1892 } else {
1893 *k
1894 };
1895 assert(stored_key.deep_view() == k.deep_view());
1896
1897 if result {
1898 assert(old_m.deep_view().contains(k.deep_view()));
1899 } else if old_m.deep_view().contains(k.deep_view()) {
1900 let key = choose|key: Key|
1901 old_m@.contains(key) && #[trigger] key.deep_view() == k.deep_view();
1902 assert(k.cmp_spec(&key) is Equal);
1903 }
1904 assert forall|kd: Key::V| #[trigger]
1905 final_m.deep_view().contains(kd) <==> old_m.deep_view().remove(k.deep_view()).contains(
1906 kd,
1907 ) by {
1908 if final_m.deep_view().contains(kd) {
1909 let key = choose|key: Key| final_m@.contains(key) && #[trigger] key.deep_view() == kd;
1910 assert(old_m@.contains(key));
1911 assert(key.deep_view() != k.deep_view());
1912 }
1913 if old_m.deep_view().contains(kd) && kd != k.deep_view() {
1914 let key = choose|key: Key| old_m@.contains(key) && #[trigger] key.deep_view() == kd;
1915 assert(final_m@.contains(key));
1916 }
1917 }
1918 assert(final_m.deep_view() =~= old_m.deep_view().remove(k.deep_view()));
1919}
1920
1921pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::clear ](
1922 m: &mut BTreeSet<Key, A>,
1923) where A: Clone
1924 ensures
1925 final(m)@ == Set::<Key>::empty(),
1926;
1927
1928pub assume_specification<'a, Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::iter ](
1929 m: &'a BTreeSet<Key, A>,
1930) -> (r: btree_set::Iter<'a, Key>)
1931 ensures
1932 key_obeys_cmp_spec::<Key>() ==> {
1933 &&& IteratorSpec::remaining(&r).unref().to_set() == m@
1934 &&& IteratorSpec::remaining(&r).no_duplicates()
1935 &&& IteratorSpec::remaining(&r).len() == m@.len()
1936 &&& increasing_seq(IteratorSpec::remaining(&r))
1937 &&& into_iter_btree_keys(r) == IteratorSpec::remaining(&r).unref()
1938 &&& IteratorSpec::decrease(&r) is Some
1939 },
1940;
1941
1942pub broadcast axiom fn axiom_btree_set_decreases<Key, A: Allocator + Clone>(m: BTreeSet<Key, A>)
1943 ensures
1944 #[trigger] (decreases_to!(m => m@)),
1945;
1946
1947pub broadcast group group_btree_axioms {
1948 axiom_key_obeys_cmp_spec_meaning,
1949 axiom_increasing_seq_meaning,
1950 axiom_spec_btree_map_len,
1951 lemma_btree_map_insert_ensures_if_obeys_cmp_concrete_eq,
1952 lemma_btree_map_insert_ensures_if_obeys_cmp_deep_eq,
1953 lemma_btree_map_contains_key_ensures_if_obeys_cmp_concrete_eq,
1954 lemma_btree_map_contains_key_ensures_if_obeys_cmp_deep_eq,
1955 lemma_btree_map_get_ensures_if_obeys_cmp_concrete_eq,
1956 lemma_btree_map_get_ensures_if_obeys_cmp_deep_eq,
1957 lemma_btree_map_remove_ensures_if_obeys_cmp_concrete_eq,
1958 lemma_btree_map_remove_ensures_if_obeys_cmp_deep_eq,
1959 lemma_btree_map_get_mut_ensures_if_obeys_cmp_concrete_eq,
1960 lemma_btree_map_get_mut_ensures_if_obeys_cmp_deep_eq,
1961 axiom_spec_btree_set_len,
1962 lemma_btree_set_insert_ensures_if_obeys_cmp_concrete_eq,
1963 lemma_btree_set_insert_ensures_if_obeys_cmp_deep_eq,
1964 lemma_btree_set_contains_ensures_if_obeys_cmp_concrete_eq,
1965 lemma_btree_set_contains_ensures_if_obeys_cmp_deep_eq,
1966 lemma_btree_set_get_ensures_if_obeys_cmp_concrete_eq,
1967 lemma_btree_set_get_ensures_if_obeys_cmp_deep_eq,
1968 lemma_btree_set_remove_ensures_if_obeys_cmp_concrete_eq,
1969 lemma_btree_set_remove_ensures_if_obeys_cmp_deep_eq,
1970 axiom_btree_map_decreases,
1971 axiom_btree_set_decreases,
1972 axiom_has_resolved_cursor,
1973}
1974
1975}