1use super::super::laws_cmp::obeys_cmp;
12use super::super::prelude::*;
13use super::cmp::OrdSpec;
14use super::iter::IteratorSpec;
15
16#[cfg(verus_keep_ghost)]
17use super::super::map::assert_maps_equal;
18
19use alloc::alloc::Allocator;
20use alloc::boxed::Box;
21use alloc::collections::btree_map;
22use alloc::collections::btree_map::{CursorMut, Keys, UnorderedKeyError, Values};
23use alloc::collections::btree_set;
24use alloc::collections::{BTreeMap, BTreeSet};
25use core::borrow::Borrow;
26use core::cmp::Ordering;
27use core::marker::PhantomData;
28use core::ops::Bound;
29use core::option::Option;
30
31verus! {
32
33pub uninterp spec fn key_obeys_cmp_spec<Key: ?Sized>() -> bool;
42
43pub broadcast axiom fn axiom_key_obeys_cmp_spec_meaning<K: Ord>()
45 ensures
46 #[trigger] key_obeys_cmp_spec::<K>() <==> obeys_cmp::<K>(),
47;
48
49pub uninterp spec fn increasing_seq<K>(s: Seq<K>) -> bool;
54
55pub broadcast axiom fn axiom_increasing_seq_meaning<K: Ord>(s: Seq<K>)
57 requires
58 obeys_cmp::<K>(),
59 ensures
60 #[trigger] increasing_seq(s) <==> forall|i, j|
61 0 <= i < j < s.len() ==> s[i].cmp_spec(&s[j]) is Less,
62;
63
64#[verifier::external_type_specification]
67#[verifier::external_body]
68#[verifier::accept_recursive_types(Key)]
69#[verifier::accept_recursive_types(Value)]
70pub struct ExKeys<'a, Key, Value>(Keys<'a, Key, Value>);
71
72pub uninterp spec fn into_iter_keys<'a, Key, Value>(i: Keys<'a, Key, Value>) -> Seq<Key>;
75
76impl<'a, K, V> super::iter::IteratorSpecImpl for Keys<'a, K, V> {
77 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
78 true
79 }
80
81 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
82
83 uninterp spec fn will_return_none(&self) -> bool;
84
85 uninterp spec fn decrease(&self) -> Option<nat>;
86
87 open spec fn peek(&self, index: int) -> Option<Self::Item> {
88 if 0 <= index < into_iter_keys(*self).len() {
89 Some(&into_iter_keys(*self)[index])
90 } else {
91 None
92 }
93 }
94}
95
96#[verifier::external_type_specification]
99#[verifier::external_body]
100#[verifier::accept_recursive_types(Key)]
101#[verifier::accept_recursive_types(Value)]
102pub struct ExValues<'a, Key, Value>(Values<'a, Key, Value>);
103
104pub uninterp spec fn into_iter_values<'a, Key, Value>(i: Values<'a, Key, Value>) -> Seq<Value>;
107
108impl<'a, K, V> super::iter::IteratorSpecImpl for Values<'a, K, V> {
109 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
110 true
111 }
112
113 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
114
115 uninterp spec fn will_return_none(&self) -> bool;
116
117 uninterp spec fn decrease(&self) -> Option<nat>;
118
119 open spec fn peek(&self, index: int) -> Option<Self::Item> {
120 if 0 <= index < into_iter_values(*self).len() {
121 Some(&into_iter_values(*self)[index])
122 } else {
123 None
124 }
125 }
126}
127
128#[verifier::external_type_specification]
131#[verifier::external_body]
132#[verifier::accept_recursive_types(K)]
133#[verifier::accept_recursive_types(V)]
134pub struct ExMapIter<'a, K, V>(btree_map::Iter<'a, K, V>);
135
136pub uninterp spec fn into_iter<'a, Key, Value>(i: btree_map::Iter<'a, Key, Value>) -> Seq<
139 (Key, Value),
140>;
141
142impl<'a, K, V> super::iter::IteratorSpecImpl for btree_map::Iter<'a, K, V> {
143 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
144 true
145 }
146
147 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
148
149 uninterp spec fn will_return_none(&self) -> bool;
150
151 uninterp spec fn decrease(&self) -> Option<nat>;
152
153 open spec fn peek(&self, index: int) -> Option<Self::Item> {
154 if 0 <= index < into_iter(*self).len() {
155 let (k, v) = into_iter(*self)[index];
156 Some((&k, &v))
157 } else {
158 None
159 }
160 }
161}
162
163pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::iter ](
164 m: &'a BTreeMap<Key, Value, A>,
165) -> (iter: btree_map::Iter<'a, Key, Value>)
166 ensures
167 key_obeys_cmp_spec::<Key>() ==> {
168 &&& IteratorSpec::remaining(&iter).len() == m@.dom().len()
169 &&& forall|i: int|
170 #![trigger m@.contains_key(*IteratorSpec::remaining(&iter)[i].0)]
171 #![trigger m@[*IteratorSpec::remaining(&iter)[i].0]]
172 0 <= i < IteratorSpec::remaining(&iter).len() ==> m@.contains_key(
173 *IteratorSpec::remaining(&iter)[i].0,
174 ) && m@[*IteratorSpec::remaining(&iter)[i].0] == *IteratorSpec::remaining(
175 &iter,
176 )[i].1
177 &&& forall|k: Key| #[trigger]
178 m@.contains_key(k) ==> IteratorSpec::remaining(&iter).contains((&k, &m@[k]))
179 &&& IteratorSpec::remaining(&iter).unref().to_set() == m@.kv_pairs()
180 &&& iter.remaining().no_duplicates()
181 &&& into_iter(iter) == IteratorSpec::remaining(&iter).unref()
182 &&& IteratorSpec::decrease(&iter) is Some
183 &&& increasing_seq(iter.remaining().map_values(|kv: (&Key, &Value)| *kv.0))
184 },
185;
186
187#[verifier::external_type_specification]
196#[verifier::external_body]
197#[verifier::accept_recursive_types(Key)]
198#[verifier::accept_recursive_types(Value)]
199#[verifier::reject_recursive_types(A)]
200pub struct ExBTreeMap<Key, Value, A: Allocator + Clone>(BTreeMap<Key, Value, A>);
201
202#[verifier::external_type_specification]
204#[verifier::external_body]
205#[verifier::accept_recursive_types(Key)]
206#[verifier::accept_recursive_types(Value)]
207#[verifier::reject_recursive_types(A)]
208pub struct ExCursorMut<'a, Key: 'a, Value: 'a, A>(CursorMut<'a, Key, Value, A>);
209
210#[verifier::external_type_specification]
212#[verifier::external_body]
213pub struct ExUnorderedKeyError(UnorderedKeyError);
214
215pub ghost struct CursorMutModel<Key, Value> {
220 pub keys: Seq<Key>,
222 pub position: int,
224 pub map: Map<Key, Value>,
226}
227
228impl<Key, Value> CursorMutModel<Key, Value> {
229 pub open spec fn wf(self) -> bool {
231 &&& 0 <= self.position <= self.keys.len()
232 &&& self.keys.no_duplicates()
233 &&& self.keys.to_set() == self.map.dom()
234 &&& increasing_seq(self.keys)
235 }
236}
237
238pub trait CursorMutSpecFns<Key, Value>: View<V = CursorMutModel<Key, Value>> + Sized {
240 #[verifier::prophetic]
242 spec fn final_map(self) -> Map<Key, Value>;
243}
244
245impl<'a, Key, Value, A> View for CursorMut<'a, Key, Value, A> {
246 type V = CursorMutModel<Key, Value>;
247
248 uninterp spec fn view(&self) -> CursorMutModel<Key, Value>;
249}
250
251impl<'a, Key, Value, A> CursorMutSpecFns<Key, Value> for CursorMut<'a, Key, Value, A> {
252 #[verifier::prophetic]
253 uninterp spec fn final_map(self) -> Map<Key, Value>;
254}
255
256pub uninterp spec fn borrowed_key_ordering_matches<Key: Borrow<Q> + Ord, Q: Ord + ?Sized>() -> bool;
261
262pub broadcast axiom fn axiom_deref_key_ordering_matches<Key: Ord>()
264 ensures
265 #[trigger] borrowed_key_ordering_matches::<Key, Key>(),
266;
267
268pub uninterp spec fn borrowed_key_cmp<Key, Q: ?Sized>(stored_key: Key, key: &Q) -> Ordering;
270
271pub broadcast axiom fn axiom_deref_key_cmp<Key: Ord>(stored_key: Key, key: &Key)
273 ensures
274 #[trigger] borrowed_key_cmp::<Key, Key>(stored_key, key) == stored_key.cmp_spec(key),
275;
276
277pub open spec fn before_lower_bound<Key, Q: ?Sized>(key: Key, bound: Bound<&Q>) -> bool {
279 match bound {
280 Bound::Included(bound_key) => borrowed_key_cmp(key, bound_key) is Less,
281 Bound::Excluded(bound_key) => !(borrowed_key_cmp(key, bound_key) is Greater),
282 Bound::Unbounded => false,
283 }
284}
285
286pub open spec fn before_upper_bound<Key, Q: ?Sized>(key: Key, bound: Bound<&Q>) -> bool {
288 match bound {
289 Bound::Included(bound_key) => !(borrowed_key_cmp(key, bound_key) is Greater),
290 Bound::Excluded(bound_key) => borrowed_key_cmp(key, bound_key) is Less,
291 Bound::Unbounded => true,
292 }
293}
294
295pub open spec fn positioned_at_lower_bound<Key, Value, Q: ?Sized>(
297 model: CursorMutModel<Key, Value>,
298 bound: Bound<&Q>,
299) -> bool {
300 &&& forall|i: int|
301 #![trigger before_lower_bound(model.keys[i], bound)]
302 0 <= i < model.position ==> before_lower_bound(model.keys[i], bound)
303 &&& forall|i: int|
304 #![trigger before_lower_bound(model.keys[i], bound)]
305 model.position <= i < model.keys.len() ==> !before_lower_bound(model.keys[i], bound)
306}
307
308pub open spec fn positioned_at_upper_bound<Key, Value, Q: ?Sized>(
310 model: CursorMutModel<Key, Value>,
311 bound: Bound<&Q>,
312) -> bool {
313 &&& forall|i: int|
314 #![trigger before_upper_bound(model.keys[i], bound)]
315 0 <= i < model.position ==> before_upper_bound(model.keys[i], bound)
316 &&& forall|i: int|
317 #![trigger before_upper_bound(model.keys[i], bound)]
318 model.position <= i < model.keys.len() ==> !before_upper_bound(model.keys[i], bound)
319}
320
321pub open spec fn key_fits_at_position<Key: Ord, Value>(
323 model: CursorMutModel<Key, Value>,
324 key: Key,
325) -> bool {
326 &&& (model.position == 0 || model.keys[model.position - 1].cmp_spec(&key) is Less)
327 &&& (model.position == model.keys.len() || key.cmp_spec(&model.keys[model.position]) is Less)
328}
329
330pub broadcast axiom fn axiom_has_resolved_cursor<Key, Value, A>(cursor: CursorMut<Key, Value, A>)
332 ensures
333 #[trigger] has_resolved(cursor) ==> cursor.final_map() == cursor@.map,
334;
335
336pub trait BTreeMapAdditionalSpecFns<Key, Value>: View<V = Map<Key, Value>> {
337 spec fn spec_index(&self, k: Key) -> Value
338 recommends
339 self@.contains_key(k),
340 ;
341}
342
343impl<Key, Value, A: Allocator + Clone> BTreeMapAdditionalSpecFns<Key, Value> for BTreeMap<
344 Key,
345 Value,
346 A,
347> {
348 #[verifier::inline]
349 open spec fn spec_index(&self, k: Key) -> Value {
350 self@.index(k)
351 }
352}
353
354impl<Key, Value, A: Allocator + Clone> View for BTreeMap<Key, Value, A> {
355 type V = Map<Key, Value>;
356
357 uninterp spec fn view(&self) -> Map<Key, Value>;
358}
359
360impl<Key: DeepView, Value: DeepView, A: Allocator + Clone> DeepView for BTreeMap<Key, Value, A> {
361 type V = Map<Key::V, Value::V>;
362
363 open spec fn deep_view(&self) -> Map<Key::V, Value::V> {
364 btree_map_deep_view_impl(*self)
365 }
366}
367
368#[verifier::opaque]
374pub open spec fn btree_map_deep_view_impl<Key: DeepView, Value: DeepView, A: Allocator + Clone>(
375 m: BTreeMap<Key, Value, A>,
376) -> Map<Key::V, Value::V> {
377 Map::new(
378 m@.dom().map(|k: Key| k.deep_view()),
379 |dk: Key::V|
380 {
381 let k = choose|k: Key| m@.contains_key(k) && #[trigger] k.deep_view() == dk;
382 m@[k].deep_view()
383 },
384 )
385}
386
387pub broadcast proof fn lemma_btree_map_deepview_dom<K: DeepView, V: DeepView>(m: BTreeMap<K, V>)
388 ensures
389 #[trigger] m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()),
390{
391 reveal(btree_map_deep_view_impl);
392 broadcast use group_btree_axioms;
393 broadcast use crate::vstd::group_vstd_default;
394
395 assert(m.deep_view().dom() =~= m@.dom().map(|k: K| k.deep_view()));
396}
397
398pub broadcast proof fn lemma_btree_map_deepview_properties<K: DeepView, V: DeepView>(
399 m: BTreeMap<K, V>,
400)
401 requires
402 crate::relations::injective(|k: K| k.deep_view()),
403 ensures
404 #![trigger m.deep_view()]
405 forall|k: K| #[trigger]
407 m@.contains_key(k) ==> m.deep_view().contains_key(k.deep_view())
408 && m.deep_view()[k.deep_view()] == m@[k].deep_view(),
409 forall|dk: <K as DeepView>::V| #[trigger]
411 m.deep_view().contains_key(dk) ==> exists|k: K|
412 k.deep_view() == dk && #[trigger] m@.contains_key(k),
413{
414 reveal(btree_map_deep_view_impl);
415 broadcast use group_btree_axioms;
416 broadcast use crate::vstd::group_vstd_default;
417
418 assert(m.deep_view().dom() == m@.dom().map(|k: K| k.deep_view()));
419 assert forall|k: K| #[trigger] m@.contains_key(k) implies m.deep_view().contains_key(
420 k.deep_view(),
421 ) && m.deep_view()[k.deep_view()] == m@[k].deep_view() by {
422 assert forall|k1: K, k2: K| #[trigger]
423 k1.deep_view() == #[trigger] k2.deep_view() implies k1 == k2 by {
424 let ghost k_deepview = |k: K| k.deep_view();
425 assert(crate::relations::injective(k_deepview));
426 assert(k_deepview(k1) == k_deepview(k2));
427 }
428 }
429}
430
431pub broadcast proof fn lemma_btree_map_deepview_values<K: DeepView, V: DeepView>(m: BTreeMap<K, V>)
432 requires
433 crate::relations::injective(|k: K| k.deep_view()),
434 ensures
435 #[trigger] m.deep_view().values() =~= m@.values().map(|v: V| v.deep_view()),
436{
437 reveal(btree_map_deep_view_impl);
438 broadcast use group_btree_axioms;
439 broadcast use lemma_btree_map_deepview_properties;
440 broadcast use crate::vstd::group_vstd_default;
441
442 let lhs = m.deep_view().values();
443 let rhs = m@.values().map(|v: V| v.deep_view());
444 assert forall|v: V::V| #[trigger] lhs.contains(v) implies rhs.contains(v) by {
445 let dk = choose|dk: K::V| #[trigger]
446 m.deep_view().contains_key(dk) && m.deep_view()[dk] == v;
447 let k = choose|k: K| #[trigger] m@.contains_key(k) && k.deep_view() == dk;
448 let ov = choose|ov: V| #[trigger] m@.contains_key(k) && m@[k] == ov && ov.deep_view() == v;
449 assert(v == ov.deep_view());
450 assert(m@.values().contains(ov));
451 }
452}
453
454pub broadcast axiom fn axiom_btree_map_deepview_borrow<
457 K: DeepView + Borrow<Q>,
458 V: DeepView,
459 Q: View<V = <K as DeepView>::V> + Eq + ?Sized,
460>(m: BTreeMap<K, V>, k: &Q)
461 requires
462 key_obeys_cmp_spec::<K>(),
463 crate::relations::injective(|k: K| k.deep_view()),
464 ensures
465 #[trigger] contains_borrowed_key(m@, k) <==> m.deep_view().contains_key(k@),
466;
467
468pub uninterp spec fn spec_btree_map_len<Key, Value, A: Allocator + Clone>(
469 m: &BTreeMap<Key, Value, A>,
470) -> usize;
471
472pub broadcast axiom fn axiom_spec_btree_map_len<Key, Value, A: Allocator + Clone>(
473 m: &BTreeMap<Key, Value, A>,
474)
475 ensures
476 key_obeys_cmp_spec::<Key>() ==> #[trigger] spec_btree_map_len(m) == m@.len(),
477;
478
479#[verifier::when_used_as_spec(spec_btree_map_len)]
480pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::len ](
481 m: &BTreeMap<Key, Value, A>,
482) -> (len: usize)
483 ensures
484 len == spec_btree_map_len(m),
485;
486
487pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::is_empty ](
488 m: &BTreeMap<Key, Value, A>,
489) -> (res: bool)
490 ensures
491 res == m@.is_empty(),
492;
493
494pub assume_specification<K: Clone, V: Clone, A: Allocator + Clone>[ <BTreeMap::<
495 K,
496 V,
497 A,
498> as Clone>::clone ](this: &BTreeMap<K, V, A>) -> (other: BTreeMap<K, V, A>)
499 ensures
500 other@ == this@,
501;
502
503pub assume_specification<Key, Value>[ BTreeMap::<Key, Value>::new ]() -> (m: BTreeMap<Key, Value>)
504 ensures
505 m@ == Map::<Key, Value>::empty(),
506;
507
508pub assume_specification<K, V>[ <BTreeMap<K, V> as core::default::Default>::default ]() -> (m:
509 BTreeMap<K, V>)
510 ensures
511 m@ == Map::<K, V>::empty(),
512;
513
514pub assume_specification<Key: Ord, Value, A: Allocator + Clone>[ BTreeMap::<
515 Key,
516 Value,
517 A,
518>::insert ](m: &mut BTreeMap<Key, Value, A>, k: Key, v: Value) -> (result: Option<Value>)
519 ensures
520 obeys_cmp::<Key>() ==> {
521 &&& final(m)@ == old(m)@.insert(k, v)
522 &&& match result {
523 Some(v) => old(m)@.contains_key(k) && v == old(m)[k],
524 None => !old(m)@.contains_key(k),
525 }
526 },
527;
528
529pub uninterp spec fn contains_borrowed_key<Key, Value, Q: ?Sized>(
544 m: Map<Key, Value>,
545 k: &Q,
546) -> bool;
547
548pub broadcast axiom fn axiom_contains_deref_key<Q, Value>(m: Map<Q, Value>, k: &Q)
549 ensures
550 #[trigger] contains_borrowed_key::<Q, Value, Q>(m, k) <==> m.contains_key(*k),
551;
552
553pub broadcast axiom fn axiom_contains_box<Q, Value>(m: Map<Box<Q>, Value>, k: &Q)
554 ensures
555 #[trigger] contains_borrowed_key::<Box<Q>, Value, Q>(m, k) <==> m.contains_key(
556 Box::new(*k),
557 ),
558;
559
560pub assume_specification<
561 Key: Borrow<Q> + Ord,
562 Value,
563 A: Allocator + Clone,
564 Q: Ord + ?Sized,
565>[ BTreeMap::<Key, Value, A>::contains_key::<Q> ](m: &BTreeMap<Key, Value, A>, k: &Q) -> (result:
566 bool)
567 ensures
568 obeys_cmp::<Key>() ==> result == contains_borrowed_key(m@, k),
569;
570
571pub uninterp spec fn maps_borrowed_key_to_value<Key, Value, Q: ?Sized>(
588 m: Map<Key, Value>,
589 k: &Q,
590 v: Value,
591) -> bool;
592
593pub broadcast axiom fn axiom_maps_deref_key_to_value<Q, Value>(m: Map<Q, Value>, k: &Q, v: Value)
594 ensures
595 #[trigger] maps_borrowed_key_to_value::<Q, Value, Q>(m, k, v) <==> m.contains_key(*k)
596 && m[*k] == v,
597;
598
599pub broadcast axiom fn axiom_maps_box_key_to_value<Q, Value>(m: Map<Box<Q>, Value>, q: &Q, v: Value)
600 ensures
601 #[trigger] maps_borrowed_key_to_value::<Box<Q>, Value, Q>(m, q, v) <==> {
602 let k = Box::new(*q);
603 &&& m.contains_key(k)
604 &&& m[k] == v
605 },
606;
607
608pub assume_specification<
609 'a,
610 Key: Borrow<Q> + Ord,
611 Value,
612 A: Allocator + Clone,
613 Q: Ord + ?Sized,
614>[ BTreeMap::<Key, Value, A>::get::<Q> ](m: &'a BTreeMap<Key, Value, A>, k: &Q) -> (result: Option<
615 &'a Value,
616>)
617 requires
618 borrowed_key_ordering_matches::<Key, Q>(),
619 ensures
620 obeys_cmp::<Key>() ==> match result {
621 Some(v) => maps_borrowed_key_to_value(m@, k, *v),
622 None => !contains_borrowed_key(m@, k),
623 },
624;
625
626pub uninterp spec fn borrowed_key_removed<Key, Value, Q: ?Sized>(
642 old_m: Map<Key, Value>,
643 new_m: Map<Key, Value>,
644 k: &Q,
645) -> bool;
646
647pub broadcast axiom fn axiom_deref_key_removed<Q, Value>(
648 old_m: Map<Q, Value>,
649 new_m: Map<Q, Value>,
650 k: &Q,
651)
652 ensures
653 #[trigger] borrowed_key_removed::<Q, Value, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
654 *k,
655 ),
656;
657
658pub broadcast axiom fn axiom_box_key_removed<Q, Value>(
659 old_m: Map<Box<Q>, Value>,
660 new_m: Map<Box<Q>, Value>,
661 q: &Q,
662)
663 ensures
664 #[trigger] borrowed_key_removed::<Box<Q>, Value, Q>(old_m, new_m, q) <==> new_m
665 == old_m.remove(Box::new(*q)),
666;
667
668pub assume_specification<
669 Key: Borrow<Q> + Ord,
670 Value,
671 A: Allocator + Clone,
672 Q: Ord + ?Sized,
673>[ BTreeMap::<Key, Value, A>::remove::<Q> ](m: &mut BTreeMap<Key, Value, A>, k: &Q) -> (result:
674 Option<Value>)
675 ensures
676 obeys_cmp::<Key>() ==> {
677 &&& borrowed_key_removed(old(m)@, final(m)@, k)
678 &&& match result {
679 Some(v) => maps_borrowed_key_to_value(old(m)@, k, v),
680 None => !contains_borrowed_key(old(m)@, k),
681 }
682 },
683;
684
685pub open spec fn borrowed_key_mutated<Key, Value, Q: ?Sized>(
687 old_map: Map<Key, Value>,
688 new_map: Map<Key, Value>,
689 key: &Q,
690 old_value: Value,
691 new_value: Value,
692) -> bool {
693 &&& maps_borrowed_key_to_value(old_map, key, old_value)
694 &&& maps_borrowed_key_to_value(new_map, key, new_value)
695 &&& exists|remainder: Map<Key, Value>|
696 {
697 &&& borrowed_key_removed(old_map, remainder, key)
698 &&& borrowed_key_removed(new_map, remainder, key)
699 }
700}
701
702pub broadcast proof fn lemma_borrowed_key_mutated_deref<Key, Value>(
704 old_map: Map<Key, Value>,
705 new_map: Map<Key, Value>,
706 key: &Key,
707 old_value: Value,
708 new_value: Value,
709)
710 ensures
711 #[trigger] borrowed_key_mutated(old_map, new_map, key, old_value, new_value) <==> {
712 &&& old_map.contains_key(*key)
713 &&& old_map[*key] == old_value
714 &&& new_map == old_map.insert(*key, new_value)
715 },
716{
717 broadcast use {
718 axiom_deref_key_removed,
719 axiom_maps_deref_key_to_value,
720 super::super::map::group_map_lemmas,
721 super::super::set::group_set_lemmas,
722 };
723
724 if borrowed_key_mutated(old_map, new_map, key, old_value, new_value) {
725 let remainder = choose|remainder: Map<Key, Value>|
726 {
727 &&& borrowed_key_removed(old_map, remainder, key)
728 &&& borrowed_key_removed(new_map, remainder, key)
729 };
730 assert(remainder == new_map.remove(*key));
731 assert_maps_equal!(new_map, old_map.insert(*key, new_value), candidate => {
732 if candidate != *key {
733 assert(old_map.remove(*key)[candidate] == old_map[candidate]);
734 }
735 });
736 } else if old_map.contains_key(*key) && old_map[*key] == old_value && new_map == old_map.insert(
737 *key,
738 new_value,
739 ) {
740 let remainder = old_map.remove(*key);
741 assert_maps_equal!(new_map.remove(*key), remainder, candidate => {});
742 assert(borrowed_key_removed(new_map, remainder, key));
743 }
744}
745
746pub assume_specification<
748 'a,
749 Key: Borrow<Q> + Ord,
750 Value,
751 A: Allocator + Clone,
752 Q: Ord + ?Sized,
753>[ BTreeMap::<Key, Value, A>::get_mut::<Q> ](
754 map: &'a mut BTreeMap<Key, Value, A>,
755 key: &Q,
756) -> (result: Option<&'a mut Value>)
757 requires
758 borrowed_key_ordering_matches::<Key, Q>(),
759 ensures
760 obeys_cmp::<Key>() ==> match result {
761 Some(value) => borrowed_key_mutated(old(map)@, final(map)@, key, *value, *final(value)),
762 None => !contains_borrowed_key(old(map)@, key) && final(map)@ == old(map)@,
763 },
764;
765
766pub assume_specification<Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::clear ](
767 m: &mut BTreeMap<Key, Value, A>,
768)
769 ensures
770 final(m)@ == Map::<Key, Value>::empty(),
771;
772
773pub assume_specification<
775 'a,
776 Key: Borrow<Q> + Ord,
777 Value,
778 A: Allocator + Clone,
779 Q: Ord + ?Sized,
780>[ BTreeMap::<Key, Value, A>::lower_bound_mut::<Q> ](
781 map: &'a mut BTreeMap<Key, Value, A>,
782 bound: Bound<&Q>,
783) -> (cursor: CursorMut<'a, Key, Value, A>)
784 requires
785 borrowed_key_ordering_matches::<Key, Q>(),
786 ensures
787 obeys_cmp::<Key>() ==> {
788 &&& cursor@.wf()
789 &&& cursor@.map == old(map)@
790 &&& final(map)@ == cursor.final_map()
791 &&& positioned_at_lower_bound(cursor@, bound)
792 },
793;
794
795pub assume_specification<
797 'a,
798 Key: Borrow<Q> + Ord,
799 Value,
800 A: Allocator + Clone,
801 Q: Ord + ?Sized,
802>[ BTreeMap::<Key, Value, A>::upper_bound_mut::<Q> ](
803 map: &'a mut BTreeMap<Key, Value, A>,
804 bound: Bound<&Q>,
805) -> (cursor: CursorMut<'a, Key, Value, A>)
806 requires
807 borrowed_key_ordering_matches::<Key, Q>(),
808 ensures
809 obeys_cmp::<Key>() ==> {
810 &&& cursor@.wf()
811 &&& cursor@.map == old(map)@
812 &&& final(map)@ == cursor.final_map()
813 &&& positioned_at_upper_bound(cursor@, bound)
814 },
815;
816
817pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::next ](
819 cursor: &'b mut CursorMut<'a, Key, Value, A>,
820) -> (result: Option<(&'b Key, &'b mut Value)>)
821 requires
822 old(cursor)@.wf(),
823 ensures
824 final(cursor).final_map() == old(cursor).final_map(),
825 final(cursor)@.wf(),
826 match result {
827 Some((key, value)) => {
828 let old_model = old(cursor)@;
829 let new_model = final(cursor)@;
830 &&& old_model.position < old_model.keys.len()
831 &&& *key == old_model.keys[old_model.position]
832 &&& *value == old_model.map[*key]
833 &&& new_model.keys == old_model.keys
834 &&& new_model.position == old_model.position + 1
835 &&& new_model.map == old_model.map.insert(*key, *final(value))
836 },
837 None => {
838 &&& old(cursor)@.position == old(cursor)@.keys.len()
839 &&& final(cursor)@ == old(cursor)@
840 },
841 },
842;
843
844pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::prev ](
846 cursor: &'b mut CursorMut<'a, Key, Value, A>,
847) -> (result: Option<(&'b Key, &'b mut Value)>)
848 requires
849 old(cursor)@.wf(),
850 ensures
851 final(cursor).final_map() == old(cursor).final_map(),
852 final(cursor)@.wf(),
853 match result {
854 Some((key, value)) => {
855 let old_model = old(cursor)@;
856 let new_model = final(cursor)@;
857 &&& old_model.position > 0
858 &&& *key == old_model.keys[old_model.position - 1]
859 &&& *value == old_model.map[*key]
860 &&& new_model.keys == old_model.keys
861 &&& new_model.position == old_model.position - 1
862 &&& new_model.map == old_model.map.insert(*key, *final(value))
863 },
864 None => {
865 &&& old(cursor)@.position == 0
866 &&& final(cursor)@ == old(cursor)@
867 },
868 },
869;
870
871pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::peek_prev ](
873 cursor: &'b mut CursorMut<'a, Key, Value, A>,
874) -> (result: Option<(&'b Key, &'b mut Value)>)
875 requires
876 old(cursor)@.wf(),
877 ensures
878 final(cursor).final_map() == old(cursor).final_map(),
879 final(cursor)@.wf(),
880 match result {
881 Some((key, value)) => {
882 let old_model = old(cursor)@;
883 let new_model = final(cursor)@;
884 &&& old_model.position > 0
885 &&& *key == old_model.keys[old_model.position - 1]
886 &&& *value == old_model.map[*key]
887 &&& new_model.keys == old_model.keys
888 &&& new_model.position == old_model.position
889 &&& new_model.map == old_model.map.insert(*key, *final(value))
890 },
891 None => {
892 &&& old(cursor)@.position == 0
893 &&& final(cursor)@ == old(cursor)@
894 },
895 },
896;
897
898pub assume_specification<'a, 'b, Key, Value, A>[ CursorMut::<'a, Key, Value, A>::peek_next ](
900 cursor: &'b mut CursorMut<'a, Key, Value, A>,
901) -> (result: Option<(&'b Key, &'b mut Value)>)
902 requires
903 old(cursor)@.wf(),
904 ensures
905 final(cursor).final_map() == old(cursor).final_map(),
906 final(cursor)@.wf(),
907 match result {
908 Some((key, value)) => {
909 let old_model = old(cursor)@;
910 let new_model = final(cursor)@;
911 &&& old_model.position < old_model.keys.len()
912 &&& *key == old_model.keys[old_model.position]
913 &&& *value == old_model.map[*key]
914 &&& new_model.keys == old_model.keys
915 &&& new_model.position == old_model.position
916 &&& new_model.map == old_model.map.insert(*key, *final(value))
917 },
918 None => {
919 &&& old(cursor)@.position == old(cursor)@.keys.len()
920 &&& final(cursor)@ == old(cursor)@
921 },
922 },
923;
924
925pub assume_specification<'a, Key: Ord, Value, A: Allocator + Clone>[ CursorMut::<
927 'a,
928 Key,
929 Value,
930 A,
931>::insert_after ](cursor: &mut CursorMut<'a, Key, Value, A>, key: Key, value: Value) -> (result:
932 Result<(), UnorderedKeyError>)
933 requires
934 old(cursor)@.wf(),
935 ensures
936 final(cursor).final_map() == old(cursor).final_map(),
937 obeys_cmp::<Key>() ==> {
938 &&& final(cursor)@.wf()
939 &&& match result {
940 Ok(()) => {
941 let old_model = old(cursor)@;
942 let new_model = final(cursor)@;
943 &&& key_fits_at_position(old_model, key)
944 &&& new_model.keys == old_model.keys.insert(old_model.position, key)
945 &&& new_model.position == old_model.position
946 &&& new_model.map == old_model.map.insert(key, value)
947 },
948 Err(_) => {
949 &&& !key_fits_at_position(old(cursor)@, key)
950 &&& final(cursor)@ == old(cursor)@
951 },
952 }
953 },
954;
955
956pub assume_specification<'a, Key: Ord, Value, A: Allocator + Clone>[ CursorMut::<
958 'a,
959 Key,
960 Value,
961 A,
962>::remove_next ](cursor: &mut CursorMut<'a, Key, Value, A>) -> (result: Option<(Key, Value)>)
963 requires
964 old(cursor)@.wf(),
965 ensures
966 final(cursor).final_map() == old(cursor).final_map(),
967 final(cursor)@.wf(),
968 match result {
969 Some((key, value)) => {
970 let old_model = old(cursor)@;
971 let new_model = final(cursor)@;
972 &&& old_model.position < old_model.keys.len()
973 &&& key == old_model.keys[old_model.position]
974 &&& value == old_model.map[key]
975 &&& new_model.keys == old_model.keys.remove(old_model.position)
976 &&& new_model.position == old_model.position
977 &&& new_model.map == old_model.map.remove(key)
978 },
979 None => {
980 &&& old(cursor)@.position == old(cursor)@.keys.len()
981 &&& final(cursor)@ == old(cursor)@
982 },
983 },
984;
985
986pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::keys ](
987 m: &'a BTreeMap<Key, Value, A>,
988) -> (keys: Keys<'a, Key, Value>)
989 ensures
990 key_obeys_cmp_spec::<Key>() ==> {
991 &&& IteratorSpec::remaining(&keys).unref().to_set() == m@.dom()
992 &&& IteratorSpec::remaining(&keys).no_duplicates()
993 &&& IteratorSpec::remaining(&keys).len() == m@.dom().len()
994 &&& increasing_seq(IteratorSpec::remaining(&keys))
995 &&& into_iter_keys(keys) == IteratorSpec::remaining(&keys).unref()
996 &&& IteratorSpec::decrease(&keys) is Some
997 },
998;
999
1000pub assume_specification<'a, Key, Value, A: Allocator + Clone>[ BTreeMap::<Key, Value, A>::values ](
1001 m: &'a BTreeMap<Key, Value, A>,
1002) -> (values: Values<'a, Key, Value>)
1003 ensures
1004 key_obeys_cmp_spec::<Key>() ==> {
1005 &&& IteratorSpec::remaining(&values).unref().to_set() == m@.values()
1006 &&& IteratorSpec::remaining(&values).len() == m@.dom().len()
1007 &&& into_iter_values(values) == IteratorSpec::remaining(&values).unref()
1008 &&& IteratorSpec::decrease(&values) is Some
1009 &&& exists|key_seq: Seq<Key>|
1010 {
1011 &&& increasing_seq(key_seq)
1012 &&& key_seq.to_set() == m@.dom()
1013 &&& key_seq.no_duplicates()
1014 &&& IteratorSpec::remaining(&values) == key_seq.map(|i: int, k| &m@[k])
1015 }
1016 },
1017;
1018
1019pub broadcast axiom fn axiom_btree_map_decreases<Key, Value, A: Allocator + Clone>(
1020 m: BTreeMap<Key, Value, A>,
1021)
1022 ensures
1023 #[trigger] (decreases_to!(m => m@)),
1024;
1025
1026#[verifier::external_type_specification]
1029#[verifier::external_body]
1030#[verifier::accept_recursive_types(K)]
1031pub struct ExSetIter<'a, K: 'a>(btree_set::Iter<'a, K>);
1032
1033pub uninterp spec fn into_iter_btree_keys<'a, Key>(i: btree_set::Iter::<'a, Key>) -> Seq<Key>;
1036
1037impl<'a, T> super::iter::IteratorSpecImpl for btree_set::Iter::<'a, T> {
1038 open spec fn obeys_prophetic_iter_laws(&self) -> bool {
1039 true
1040 }
1041
1042 uninterp spec fn remaining(&self) -> Seq<Self::Item>;
1043
1044 uninterp spec fn will_return_none(&self) -> bool;
1045
1046 uninterp spec fn decrease(&self) -> Option<nat>;
1047
1048 open spec fn peek(&self, index: int) -> Option<Self::Item> {
1049 if 0 <= index < into_iter_btree_keys(*self).len() {
1050 Some(&into_iter_btree_keys(*self)[index])
1051 } else {
1052 None
1053 }
1054 }
1055}
1056
1057#[verifier::external_type_specification]
1066#[verifier::external_body]
1067#[verifier::accept_recursive_types(Key)]
1068#[verifier::reject_recursive_types(A)]
1069pub struct ExBTreeSet<Key, A: Allocator + Clone>(BTreeSet<Key, A>);
1070
1071impl<Key, A: Allocator + Clone> View for BTreeSet<Key, A> {
1072 type V = Set<Key>;
1073
1074 uninterp spec fn view(&self) -> Set<Key>;
1075}
1076
1077impl<Key: DeepView, A: Allocator + Clone> DeepView for BTreeSet<Key, A> {
1078 type V = Set<Key::V>;
1079
1080 open spec fn deep_view(&self) -> Set<Key::V> {
1081 self@.map(|x: Key| x.deep_view())
1082 }
1083}
1084
1085pub uninterp spec fn spec_btree_set_len<Key, A: Allocator + Clone>(m: &BTreeSet<Key, A>) -> usize;
1086
1087pub broadcast axiom fn axiom_spec_btree_set_len<Key, A: Allocator + Clone>(m: &BTreeSet<Key, A>)
1088 ensures
1089 key_obeys_cmp_spec::<Key>() ==> #[trigger] spec_btree_set_len(m) == m@.len(),
1090;
1091
1092#[verifier::when_used_as_spec(spec_btree_set_len)]
1093pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::len ](
1094 m: &BTreeSet<Key, A>,
1095) -> (len: usize)
1096 ensures
1097 len == spec_btree_set_len(m),
1098;
1099
1100pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::is_empty ](
1101 m: &BTreeSet<Key, A>,
1102) -> (res: bool)
1103 ensures
1104 res == m@.is_empty(),
1105;
1106
1107pub assume_specification<K: Clone, A: Allocator + Clone>[ <BTreeSet::<K, A> as Clone>::clone ](
1108 this: &BTreeSet<K, A>,
1109) -> (other: BTreeSet<K, A>)
1110 ensures
1111 other@ == this@,
1112;
1113
1114pub assume_specification<Key>[ BTreeSet::<Key>::new ]() -> (m: BTreeSet<Key>)
1115 ensures
1116 m@ == Set::<Key>::empty(),
1117;
1118
1119pub assume_specification<T>[ <BTreeSet<T> as core::default::Default>::default ]() -> (m: BTreeSet<
1120 T,
1121>)
1122 ensures
1123 m@ == Set::<T>::empty(),
1124;
1125
1126pub assume_specification<Key: Ord, A: Allocator + Clone>[ BTreeSet::<Key, A>::insert ](
1127 m: &mut BTreeSet<Key, A>,
1128 k: Key,
1129) -> (result: bool)
1130 ensures
1131 obeys_cmp::<Key>() ==> {
1132 &&& final(m)@ == old(m)@.insert(k)
1133 &&& result == !old(m)@.contains(k)
1134 },
1135;
1136
1137pub uninterp spec fn set_contains_borrowed_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q) -> bool;
1152
1153pub broadcast axiom fn axiom_set_contains_deref_key<Q>(m: Set<Q>, k: &Q)
1154 ensures
1155 #[trigger] set_contains_borrowed_key::<Q, Q>(m, k) <==> m.contains(*k),
1156;
1157
1158pub broadcast axiom fn axiom_set_contains_box<Q>(m: Set<Box<Q>>, k: &Q)
1159 ensures
1160 #[trigger] set_contains_borrowed_key::<Box<Q>, Q>(m, k) <==> m.contains(Box::new(*k)),
1161;
1162
1163pub assume_specification<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>[ BTreeSet::<
1164 Key,
1165 A,
1166>::contains ](m: &BTreeSet<Key, A>, k: &Q) -> (result: bool)
1167 ensures
1168 obeys_cmp::<Key>() ==> result == set_contains_borrowed_key(m@, k),
1169 no_unwind
1170;
1171
1172pub uninterp spec fn sets_borrowed_key_to_key<Key, Q: ?Sized>(m: Set<Key>, k: &Q, v: &Key) -> bool;
1189
1190pub broadcast axiom fn axiom_set_deref_key_to_value<Q>(m: Set<Q>, k: &Q, v: &Q)
1191 ensures
1192 #[trigger] sets_borrowed_key_to_key::<Q, Q>(m, k, v) <==> m.contains(*k) && k == v,
1193;
1194
1195pub broadcast axiom fn axiom_set_box_key_to_value<Q>(m: Set<Box<Q>>, q: &Q, v: &Box<Q>)
1196 ensures
1197 #[trigger] sets_borrowed_key_to_key::<Box<Q>, Q>(m, q, v) <==> (m.contains(*v) && Box::new(
1198 *q,
1199 ) == v),
1200;
1201
1202pub assume_specification<
1203 'a,
1204 Key: Borrow<Q> + Ord,
1205 A: Allocator + Clone,
1206 Q: Ord + ?Sized,
1207>[ BTreeSet::<Key, A>::get::<Q> ](m: &'a BTreeSet<Key, A>, k: &Q) -> (result: Option<&'a Key>)
1208 ensures
1209 obeys_cmp::<Key>() ==> match result {
1210 Some(v) => sets_borrowed_key_to_key(m@, k, v),
1211 None => !set_contains_borrowed_key(m@, k),
1212 },
1213;
1214
1215pub uninterp spec fn sets_differ_by_borrowed_key<Key, Q: ?Sized>(
1230 old_m: Set<Key>,
1231 new_m: Set<Key>,
1232 k: &Q,
1233) -> bool;
1234
1235pub broadcast axiom fn axiom_set_deref_key_removed<Q>(old_m: Set<Q>, new_m: Set<Q>, k: &Q)
1236 ensures
1237 #[trigger] sets_differ_by_borrowed_key::<Q, Q>(old_m, new_m, k) <==> new_m == old_m.remove(
1238 *k,
1239 ),
1240;
1241
1242pub broadcast axiom fn axiom_set_box_key_removed<Q>(old_m: Set<Box<Q>>, new_m: Set<Box<Q>>, q: &Q)
1243 ensures
1244 #[trigger] sets_differ_by_borrowed_key::<Box<Q>, Q>(old_m, new_m, q) <==> new_m
1245 == old_m.remove(Box::new(*q)),
1246;
1247
1248pub assume_specification<Key: Borrow<Q> + Ord, A: Allocator + Clone, Q: Ord + ?Sized>[ BTreeSet::<
1249 Key,
1250 A,
1251>::remove::<Q> ](m: &mut BTreeSet<Key, A>, k: &Q) -> (result: bool)
1252 ensures
1253 obeys_cmp::<Key>() ==> {
1254 &&& sets_differ_by_borrowed_key(old(m)@, final(m)@, k)
1255 &&& result == set_contains_borrowed_key(old(m)@, k)
1256 },
1257;
1258
1259pub assume_specification<Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::clear ](
1260 m: &mut BTreeSet<Key, A>,
1261) where A: Clone
1262 ensures
1263 final(m)@ == Set::<Key>::empty(),
1264;
1265
1266pub assume_specification<'a, Key, A: Allocator + Clone>[ BTreeSet::<Key, A>::iter ](
1267 m: &'a BTreeSet<Key, A>,
1268) -> (r: btree_set::Iter<'a, Key>)
1269 ensures
1270 key_obeys_cmp_spec::<Key>() ==> {
1271 &&& IteratorSpec::remaining(&r).unref().to_set() == m@
1272 &&& IteratorSpec::remaining(&r).no_duplicates()
1273 &&& IteratorSpec::remaining(&r).len() == m@.len()
1274 &&& increasing_seq(IteratorSpec::remaining(&r))
1275 &&& into_iter_btree_keys(r) == IteratorSpec::remaining(&r).unref()
1276 &&& IteratorSpec::decrease(&r) is Some
1277 },
1278;
1279
1280pub broadcast axiom fn axiom_btree_set_decreases<Key, A: Allocator + Clone>(m: BTreeSet<Key, A>)
1281 ensures
1282 #[trigger] (decreases_to!(m => m@)),
1283;
1284
1285pub broadcast group group_btree_axioms {
1286 axiom_key_obeys_cmp_spec_meaning,
1287 axiom_increasing_seq_meaning,
1288 axiom_box_key_removed,
1289 axiom_contains_deref_key,
1290 axiom_contains_box,
1291 axiom_deref_key_removed,
1292 axiom_maps_deref_key_to_value,
1293 axiom_maps_box_key_to_value,
1294 axiom_btree_map_deepview_borrow,
1295 axiom_spec_btree_map_len,
1296 axiom_set_box_key_removed,
1297 axiom_set_contains_deref_key,
1298 axiom_set_contains_box,
1299 axiom_set_deref_key_removed,
1300 axiom_set_deref_key_to_value,
1301 axiom_set_box_key_to_value,
1302 axiom_spec_btree_set_len,
1303 axiom_btree_map_decreases,
1304 axiom_btree_set_decreases,
1305 axiom_deref_key_ordering_matches,
1306 axiom_deref_key_cmp,
1307 axiom_has_resolved_cursor,
1308 lemma_borrowed_key_mutated_deref,
1309}
1310
1311}