Skip to main content

vstd/std_specs/
btree.rs

1//! This code adds specifications for the standard-library types
2//! `alloc::collections::BTreeMap` and `alloc::collections::BTreeSet`.
3//!
4//! The specification is only meaningful when the `Key` obeys our [`Ord`] model,
5//! as specified by [`super::super::laws_cmp::obeys_cmp_spec`].
6//! Borrowed-query comparison guarantees additionally require
7//! `obeys_cmp::<&Q>()` and
8//! `<Key as BorrowSpec<Q>>::obeys_borrow_spec()`.
9//!
10//! By default, the Verus standard library brings useful axioms
11//! about the behavior of `BTreeMap` and `BTreeSet` into the ambient
12//! reasoning context by broadcasting the group
13//! `vstd::std_specs::btree::group_btree_axioms`.
14use 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
36/// Whether the `Key` type obeys the cmp spec, required for [`BTreeMap`]
37///
38/// This is a workaround to the fact that [`BTreeMap`] "late binds" the trait bounds when needed.
39/// For instance, [`BTreeMap::iter`] does not require `Key: Ord`, even though it yields ordered
40/// items. Rather, it relies on the fact that [`BTreeMap::insert`] does require `Key: Ord`, meaning
41/// no instance of a [`BTreeMap`] will ever have keys that cannot be comparable.
42///
43/// See also [`axiom_key_obeys_cmp_spec_meaning`].
44pub uninterp spec fn key_obeys_cmp_spec<Key: ?Sized>() -> bool;
45
46/// For types that are ordered, [`key_obeys_cmp_spec`] is equivalent to [`obeys_cmp`].
47pub 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
52/// Whether a sequence is ordered in increasing order.
53/// This only has meaning if `K: Ord` and [`obeys_cmp::<K>`].
54///
55/// See [`axiom_increasing_seq_meaning`] for an interpretation of this predicate.
56pub uninterp spec fn increasing_seq<K>(s: Seq<K>) -> bool;
57
58/// An interpretation for the [`increasing_seq`] predicate.
59pub 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/// Specifications for the behavior of
68/// [`alloc::collections::btree_map::Keys`](https://doc.rust-lang.org/alloc/collections/btree_map/struct.Keys.html).
69#[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
75// To allow reasoning about the "contents" of the Keys iterator, without using
76// a prophecy, we need a function that gives us the underlying sequence of the original keys.
77pub 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/// Specifications for the behavior of
103/// [`alloc::collections::btree_map::Values`](https://doc.rust-lang.org/alloc/collections/btree_map/struct.Values.html).
104#[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
110// To allow reasoning about the "contents" of the Values iterator, without using
111// a prophecy, we need a function that gives us the underlying sequence of the original values.
112pub 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// The `iter` method of a `BTreeMap` returns an iterator of type `btree_map::Iter`,
138// so we specify that type here.
139#[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
145// To allow reasoning about the "contents" of the Iter iterator, without using
146// a prophecy, we need a function that gives us the underlying sequence of the original map.
147pub 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/// Specifications for the behavior of [`alloc::collections::BTreeMap`](https://doc.rust-lang.org/alloc/collections/struct.BTreeMap.html).
200///
201/// We model a `BTreeMap` as having a view of type `Map<Key, Value>`, which reflects the current state of the map.
202///
203/// These specifications are only meaningful if `key_obeys_cmp_spec::<Key>()` holds.
204/// See [`key_obeys_cmp_spec`] for information on use with primitive types and other types.
205///
206/// Axioms about the behavior of BTreeMap are present in the broadcast group `vstd::std_specs::btree::group_btree_axioms`.
207#[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/// Verus declaration for Rust's mutable B-tree cursor type.
215#[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/// Verus declaration for the error returned when a cursor insertion would break key ordering.
223#[verifier::external_type_specification]
224#[verifier::external_body]
225pub struct ExUnorderedKeyError(UnorderedKeyError);
226
227/// The abstract state of a mutable B-tree cursor.
228///
229/// A cursor points at the gap immediately before `keys[position]`. Therefore, `peek_next`
230/// accesses `keys[position]`, while `peek_prev` accesses `keys[position - 1]`.
231pub ghost struct CursorMutModel<Key, Value> {
232    /// All keys in the underlying map, in strictly increasing order.
233    pub keys: Seq<Key>,
234    /// The index of the element immediately after the cursor.
235    pub position: int,
236    /// The current contents of the complete map borrowed by the cursor.
237    pub map: Map<Key, Value>,
238}
239
240impl<Key, Value> CursorMutModel<Key, Value> {
241    /// Whether this model consistently represents an ordered map and a gap in that map.
242    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
250/// Abstract and prophetic state for mutable B-tree cursors.
251pub trait CursorMutSpecFns<Key, Value>: View<V = CursorMutModel<Key, Value>> + Sized {
252    /// The contents of the borrowed map when this cursor's borrow is resolved.
253    #[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
268/// Whether a key occurs before the gap returned by [`BTreeMap::lower_bound_mut`].
269pub 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
281/// Whether a key occurs before the gap returned by [`BTreeMap::upper_bound_mut`].
282pub 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
294/// Whether a cursor is at the gap selected by [`BTreeMap::lower_bound_mut`].
295pub 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
307/// Whether a cursor is at the gap selected by [`BTreeMap::upper_bound_mut`].
308pub 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
320/// Whether a key can be inserted at the cursor's current gap without breaking key order.
321pub 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
329/// Once the cursor has been dropped, its prophesied map is its current map.
330pub 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/// The actual definition of `BTreeMap::deep_view`.
368///
369/// This is a separate function since it introduces a lot of quantifiers and revealing an opaque trait
370/// method is not supported. In most cases, it's easier to use one of the lemmas below instead
371/// of revealing this function directly.
372#[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        // all elements in m.view() are present in m.deep_view()
405        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        // all elements in m.deep_view() are present in m.view()
409        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
1041/// Specification for [`BTreeMap::get_mut`].
1042pub 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
1170/// Specification for [`BTreeMap::lower_bound_mut`].
1171pub 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
1196/// Specification for [`BTreeMap::upper_bound_mut`].
1197pub 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
1222/// Specification for [`CursorMut::next`].
1223pub 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
1249/// Specification for [`CursorMut::prev`].
1250pub 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
1276/// Specification for [`CursorMut::peek_prev`].
1277pub 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
1303/// Specification for [`CursorMut::peek_next`].
1304pub 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
1330/// Specification for [`CursorMut::insert_after`].
1331pub 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
1361/// Specification for [`CursorMut::remove_next`].
1362pub 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// The `iter` method of a `BTreeSet` returns an iterator of type `btree_set::Iter`,
1432// so we specify that type here.
1433#[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
1438// To allow reasoning about the "contents" of the BtreeSet iterator, without using
1439// a prophecy, we need a function that gives us the underlying sequence of the original keys.
1440pub 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/// Specifications for the behavior of [`alloc::collections::BTreeSet`](https://doc.rust-lang.org/alloc/collections/struct.BTreeSet.html).
1466///
1467/// We model a `BTreeSet` as having a view of type `Set<Key>`, which reflects the current state of the set.
1468///
1469/// These specifications are only meaningful if `obeys_cmp::<Key>()` hold.
1470/// See [`obeys_cmp`] for information on use with primitive types and custom types.
1471///
1472/// Axioms about the behavior of BTreeSet are present in the broadcast group `vstd::std_specs::btree::group_btree_axioms`.
1473#[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} // verus!