vstd/
map_lib.rs

1#[macro_use]
2use super::map::{Map, assert_maps_equal, assert_maps_equal_internal};
3#[allow(unused_imports)]
4use super::pervasive::*;
5#[allow(unused_imports)]
6use super::prelude::*;
7#[allow(unused_imports)]
8use super::relations::*;
9use super::set::*;
10#[cfg(verus_keep_ghost)]
11use super::set_lib::*;
12
13verus! {
14
15broadcast use {super::map::group_map_axioms, super::set::group_set_axioms};
16
17impl<K, V> Map<K, V> {
18    /// Is `true` if called by a "full" map, i.e., a map containing every element of type `A`.
19    #[verifier::inline]
20    pub open spec fn is_full(self) -> bool {
21        self.dom().is_full()
22    }
23
24    /// Is `true` if called by an "empty" map, i.e., a map containing no elements and has length 0
25    #[verifier::inline]
26    pub open spec fn is_empty(self) -> (b: bool) {
27        self.dom().is_empty()
28    }
29
30    /// Returns true if the key `k` is in the domain of `self`.
31    #[verifier::inline]
32    pub open spec fn contains_key(self, k: K) -> bool {
33        self.dom().contains(k)
34    }
35
36    /// Returns true if the value `v` is in the range of `self`.
37    pub open spec fn contains_value(self, v: V) -> bool {
38        exists|i: K| #[trigger] self.dom().contains(i) && self[i] == v
39    }
40
41    /// Returns `Some(v)` if the key `k` is in the domain of `self` and maps to `v`,
42    /// and `None` if the key `k` is not in the domain of `self`.
43    pub open spec fn index_opt(self, k: K) -> Option<V> {
44        if self.contains_key(k) {
45            Some(self[k])
46        } else {
47            None
48        }
49    }
50
51    ///
52    /// Returns the set of values in the map.
53    ///
54    /// ## Example
55    ///
56    /// ```rust
57    /// let m: Map<int, int> = map![1 => 10, 2 => 11];
58    /// assert(m.values() == set![10int, 11int]) by {
59    ///     assert(m.contains_key(1));
60    ///     assert(m.contains_key(2));
61    ///     assert(m.values() =~= set![10int, 11int]);
62    /// }
63    /// ```
64    pub open spec fn values(self) -> Set<V> {
65        Set::<V>::new(|v: V| self.contains_value(v))
66    }
67
68    ///
69    /// Returns the set of key-value pairs representing the map
70    ///
71    /// ## Example
72    ///
73    /// ```rust
74    /// let m: Map<int, int> = map![1 => 10, 2 => 11];
75    /// assert(m.kv_pairs() == set![(1int, 10int), (2int, 11int)] by {
76    ///     assert(m.contains_pair(1int, 10int));
77    ///     assert(m.contains_pair(2int, 11int));
78    ///     assert(m.kv_pairs() =~= set![(1int, 10int), (2int, 11int)]);
79    /// }
80    /// ```
81    pub open spec fn kv_pairs(self) -> Set<(K, V)> {
82        Set::<(K, V)>::new(|kv: (K, V)| self.dom().contains(kv.0) && self[kv.0] == kv.1)
83    }
84
85    /// Returns true if the key `k` is in the domain of `self`, and it maps to the value `v`.
86    pub open spec fn contains_pair(self, k: K, v: V) -> bool {
87        self.dom().contains(k) && self[k] == v
88    }
89
90    /// Returns true if `m1` is _contained in_ `m2`, i.e., the domain of `m1` is a subset
91    /// of the domain of `m2`, and they agree on all values in `m1`.
92    ///
93    /// ## Example
94    ///
95    /// ```rust
96    /// assert(
97    ///    map![1 => 10, 2 => 11].le(map![1 => 10, 2 => 11, 3 => 12])
98    /// );
99    /// ```
100    pub open spec fn submap_of(self, m2: Self) -> bool {
101        forall|k: K| #[trigger]
102            self.dom().contains(k) ==> #[trigger] m2.dom().contains(k) && self[k] == m2[k]
103    }
104
105    #[verifier::inline]
106    pub open spec fn spec_le(self, m2: Self) -> bool {
107        self.submap_of(m2)
108    }
109
110    /// Gives the union of two maps, defined as:
111    ///  * The domain is the union of the two input maps.
112    ///  * For a given key in _both_ input maps, it maps to the same value that it maps to in the _right_ map (`m2`).
113    ///  * For any other key in either input map (but not both), it maps to the same value
114    ///    as it does in that map.
115    ///
116    /// ## Example
117    ///
118    /// ```rust
119    /// assert(
120    ///    map![1 => 10, 2 => 11].union_prefer_right(map![1 => 20, 3 => 13])
121    ///    =~= map![1 => 20, 2 => 11, 3 => 13]);
122    /// ```
123    pub open spec fn union_prefer_right(self, m2: Self) -> Self {
124        Self::new(
125            |k: K| self.dom().contains(k) || m2.dom().contains(k),
126            |k: K|
127                if m2.dom().contains(k) {
128                    m2[k]
129                } else {
130                    self[k]
131                },
132        )
133    }
134
135    /// Removes the given keys and their associated values from the map.
136    ///
137    /// Ignores any key in `keys` which is not in the domain of `self`.
138    ///
139    /// ## Example
140    ///
141    /// ```rust
142    /// assert(
143    ///    map![1 => 10, 2 => 11, 3 => 12].remove_keys(set!{2, 3, 4})
144    ///    =~= map![1 => 10]);
145    /// ```
146    pub open spec fn remove_keys(self, keys: Set<K>) -> Self {
147        Self::new(|k: K| self.dom().contains(k) && !keys.contains(k), |k: K| self[k])
148    }
149
150    /// Complement to `remove_keys`. Restricts the map to (key, value) pairs
151    /// for keys that are _in_ the given set; that is, it removes any keys
152    /// _not_ in the set.
153    ///
154    /// ## Example
155    ///
156    /// ```rust
157    /// assert(
158    ///    map![1 => 10, 2 => 11, 3 => 12].remove_keys(set!{2, 3, 4})
159    ///    =~= map![2 => 11, 3 => 12]);
160    /// ```
161    pub open spec fn restrict(self, keys: Set<K>) -> Self {
162        Self::new(|k: K| self.dom().contains(k) && keys.contains(k), |k: K| self[k])
163    }
164
165    /// Returns `true` if and only if the given key maps to the same value or does not exist in self and m2.
166    pub open spec fn is_equal_on_key(self, m2: Self, key: K) -> bool {
167        ||| (!self.dom().contains(key) && !m2.dom().contains(key))
168        ||| (self.dom().contains(key) && m2.dom().contains(key) && self[key] == m2[key])
169    }
170
171    /// Returns `true` if the two given maps agree on all keys that their domains share
172    pub open spec fn agrees(self, m2: Self) -> bool {
173        forall|k| #![auto] self.dom().contains(k) && m2.dom().contains(k) ==> self[k] == m2[k]
174    }
175
176    /// Map a function `f` over all (k, v) pairs in `self`.
177    pub open spec fn map_entries<W>(self, f: spec_fn(K, V) -> W) -> Map<K, W> {
178        Map::new(|k: K| self.contains_key(k), |k: K| f(k, self[k]))
179    }
180
181    /// Map a function `f` over the values in `self`.
182    pub open spec fn map_values<W>(self, f: spec_fn(V) -> W) -> Map<K, W> {
183        Map::new(|k: K| self.contains_key(k), |k: K| f(self[k]))
184    }
185
186    /// Returns `true` if and only if a map is injective
187    pub open spec fn is_injective(self) -> bool {
188        forall|x: K, y: K|
189            x != y && self.dom().contains(x) && self.dom().contains(y) ==> #[trigger] self[x]
190                != #[trigger] self[y]
191    }
192
193    /// Swaps map keys and values. Values are not required to be unique; no
194    /// promises on which key is chosen on the intersection.
195    pub open spec fn invert(self) -> Map<V, K> {
196        Map::<V, K>::new(
197            |v: V| self.contains_value(v),
198            |v: V| choose|k: K| self.contains_pair(k, v),
199        )
200    }
201
202    // Proven lemmas
203    /// Removing a key from a map that previously contained that key decreases
204    /// the map's length by one
205    pub proof fn lemma_remove_key_len(self, key: K)
206        requires
207            self.dom().contains(key),
208            self.dom().finite(),
209        ensures
210            self.dom().len() == 1 + self.remove(key).dom().len(),
211    {
212    }
213
214    /// The domain of a map after removing a key is equivalent to removing the key from
215    /// the domain of the original map.
216    pub proof fn lemma_remove_equivalency(self, key: K)
217        ensures
218            self.remove(key).dom() == self.dom().remove(key),
219    {
220    }
221
222    /// Removing a set of n keys from a map that previously contained all n keys
223    /// results in a domain of size n less than the original domain.
224    pub proof fn lemma_remove_keys_len(self, keys: Set<K>)
225        requires
226            forall|k: K| #[trigger] keys.contains(k) ==> self.contains_key(k),
227            keys.finite(),
228            self.dom().finite(),
229        ensures
230            self.remove_keys(keys).dom().len() == self.dom().len() - keys.len(),
231        decreases keys.len(),
232    {
233        broadcast use group_set_properties;
234
235        if keys.len() > 0 {
236            let key = keys.choose();
237            let val = self[key];
238            self.remove(key).lemma_remove_keys_len(keys.remove(key));
239            assert(self.remove(key).remove_keys(keys.remove(key)) =~= self.remove_keys(keys));
240        } else {
241            assert(self.remove_keys(keys) =~= self);
242        }
243    }
244
245    /// The function `invert` results in an injective map
246    pub proof fn lemma_invert_is_injective(self)
247        ensures
248            self.invert().is_injective(),
249    {
250        assert forall|x: V, y: V|
251            x != y && self.invert().dom().contains(x) && self.invert().dom().contains(
252                y,
253            ) implies #[trigger] self.invert()[x] != #[trigger] self.invert()[y] by {
254            let i = choose|i: K| #[trigger] self.dom().contains(i) && self[i] == x;
255            assert(self.contains_pair(i, x));
256            let j = choose|j: K| self.contains_pair(j, x) && self.invert()[x] == j;
257            let k = choose|k: K| #[trigger] self.dom().contains(k) && self[k] == y;
258            assert(self.contains_pair(k, y));
259            let l = choose|l: K| self.contains_pair(l, y) && self.invert()[y] == l && l != j;
260        }
261    }
262
263    /// Keeps only those key-value pairs whose key satisfies `p`.
264    ///
265    /// ## Example
266    /// ```rust
267    /// proof fn example() {
268    ///     let m = map![1 => 10, 2 => 20];
269    ///     let even = |k: int| k % 2 == 0;
270    ///     assert(m.filter_keys(even) =~= map![2 => 20]);
271    /// }
272    /// ```
273    pub open spec fn filter_keys(self, p: spec_fn(K) -> bool) -> Self {
274        self.restrict(self.dom().filter(p))
275    }
276
277    /// Returns the value associated with key `k` in the map if it exists,
278    /// otherwise returns None.
279    ///
280    /// ## Example
281    /// ```rust
282    /// proof fn get_test() {
283    ///     let m: Map<int, bool> = map![
284    ///         1 => true,
285    ///         2 => false
286    ///     ];
287    ///
288    ///     assert(m.get(1) == Some(true));
289    ///     assert(m.get(3) == None);
290    /// }
291    /// ```
292    pub open spec fn get(self, k: K) -> Option<V> {
293        if self.dom().contains(k) {
294            Some(self[k])
295        } else {
296            None
297        }
298    }
299
300    /// A map contains a value satisfying predicate `p` iff some key maps to a value satisfying `p`.
301    ///
302    /// ## Example
303    /// ```rust
304    /// proof fn get_dom_value_any_test() {
305    ///     let m = map![1 => 10, 2 => 20, 3 => 30];
306    ///     let p = |v: int| v > 25;
307    ///     assert(m[3] == 30);
308    ///     assert(m.dom().any(|k| p(m[k])));
309    /// }
310    /// ```
311    pub proof fn get_dom_value_any(self, p: spec_fn(V) -> bool)
312        ensures
313            self.dom().any(|k: K| p(self[k])) <==> self.values().any(p),
314    {
315        broadcast use group_map_properties;
316
317        if self.dom().any(|k: K| p(self[k])) {
318            let k = choose|k: K| self.dom().contains(k) && #[trigger] p(self[k]);
319            assert(self.values().contains(self[k]));
320            assert(self.values().any(p));
321        }
322    }
323
324    /// Two maps are equal if and only if they are submaps of each other.
325    ///
326    /// ## Example
327    /// ```rust
328    /// proof fn submap_eq_test() {
329    ///     let m1 = map![1 => 10, 2 => 20];
330    ///     let m2 = map![1 => 10, 2 => 20];
331    ///     let m3 = map![1 => 10, 2 => 30];
332    ///
333    ///     assert(m1.submap_of(m2) && m2.submap_of(m1));
334    ///     assert(m1 == m2);
335    /// }
336    /// ```
337    pub proof fn lemma_submap_eq_iff(self, m: Self)
338        ensures
339            (self == m) <==> (self.submap_of(m) && m.submap_of(self)),
340    {
341        broadcast use group_map_properties;
342
343        if self.submap_of(m) && m.submap_of(self) {
344            assert(self.dom() == m.dom());
345            assert(self == m);
346        }
347    }
348
349    /// When removing a set of keys from a map after inserting (k,v),
350    /// the result depends on whether k is in the set:
351    /// if k is in the set, the insertion is discarded;
352    /// if not, the insertion happens after removal.
353    ///
354    /// ## Example
355    /// ```rust
356    /// proof fn map_remove_keys_insert_test() {
357    ///     let m = map![1 => 10, 2 => 20, 3 => 30];
358    ///     let to_remove = set![2, 4];
359    ///
360    ///     // 5 not in m: insert happens after remove
361    ///     assert(m.insert(5, 15).remove_keys(to_remove) == m.remove_keys(to_remove).insert(5, 15));
362    ///
363    ///     // 2 in m: insert is eliminated by remove
364    ///     assert(m.insert(2, 25).remove_keys(to_remove) == m.remove_keys(to_remove));
365    /// }
366    /// ```
367    pub broadcast proof fn lemma_map_remove_keys_insert(self, r: Set<K>, k: K, v: V)
368        ensures
369            #[trigger] self.insert(k, v).remove_keys(r) == if r.contains(k) {
370                self.remove_keys(r)
371            } else {
372                self.remove_keys(r).insert(k, v)
373            },
374    {
375        broadcast use group_map_properties;
376
377        let lhs = self.insert(k, v).remove_keys(r);
378        let rhs = if r.contains(k) {
379            self.remove_keys(r)
380        } else {
381            self.remove_keys(r).insert(k, v)
382        };
383        assert(lhs == rhs);
384    }
385
386    /// Filtering keys after inserting `(k, v)` leaves the result unchanged when `p(k)` is false,
387    /// and otherwise adds `(k, v)` to the already-filtered map.
388    ///
389    /// ## Example
390    /// ```rust
391    /// proof fn example() {
392    ///     let m = map![1 => 10];
393    ///     let even = |k: int| k % 2 == 0;
394    ///
395    ///     assert(m.insert(3, 30).filter_keys(even) =~= m.filter_keys(even));
396    ///     assert(m.insert(2, 20).filter_keys(even)
397    ///            =~= m.filter_keys(even).insert(2, 20));
398    /// }
399    /// ```
400    pub broadcast proof fn lemma_filter_keys_insert(self, p: spec_fn(K) -> bool, k: K, v: V)
401        ensures
402            #[trigger] self.insert(k, v).filter_keys(p) == (if p(k) {
403                self.filter_keys(p).insert(k, v)
404            } else {
405                self.filter_keys(p)
406            }),
407    {
408        broadcast use group_map_properties;
409
410        let lhs = self.insert(k, v).filter_keys(p);
411        let rhs = if p(k) {
412            self.filter_keys(p).insert(k, v)
413        } else {
414            self.filter_keys(p)
415        };
416        assert(lhs == rhs);
417    }
418
419    /// Inserting a value in a map means it contains the value that was inserted.
420    ///
421    /// ## Example
422    /// ```rust
423    /// proof fn example() {
424    ///     let a = map![1int => 2int];
425    ///     assert(a.contains_value(2));
426    /// }
427    /// ```
428    pub broadcast proof fn lemma_insert_contains_value(self, k: K, v: V)
429        ensures
430            #[trigger] self.insert(k, v).contains_value(v),
431    {
432        assert(self.insert(k, v).contains_key(k));
433    }
434
435    /// Inserting a value in a map where that key is already present ensures
436    /// The contains value sees (only) the updated value;
437    ///
438    /// ## Example
439    /// ```rust
440    /// proof fn example() {
441    ///     let a = map![1int => 2int].insert(1int, 3int);
442    ///     assert(!a.contains_value(2));
443    ///     assert(a.contains_value(3));
444    /// }
445    /// ```
446    pub broadcast proof fn lemma_insert_invariant_contains(self, old_v: V, k: K, v: V)
447        requires
448            self.contains_key(k) ==> self[k] != old_v,
449            old_v != v,
450        ensures
451            #[trigger] self.insert(k, v).contains_value(old_v) == self.contains_value(old_v),
452    {
453        if self.contains_value(old_v) {
454            let old_k = choose|key: K| #[trigger] self.dom().contains(key) && self[key] == old_v;
455            assert(self.insert(k, v).contains_key(old_k));
456        }
457    }
458
459    pub proof fn lemma_injective_values_len(self)
460        requires
461            self.dom().finite(),
462            self.is_injective(),
463        ensures
464            self.values().finite(),
465            self.values().len() == self.dom().len(),
466    {
467        let f = |k: K|
468            if self.contains_key(k) {
469                self[k]
470            } else {
471                Set::<V>::full().difference(self.values()).choose()
472            };
473        assert(forall|a1: K, a2: K|
474            self.dom().contains(a1) && self.dom().contains(a2) && #[trigger] f(a1) == #[trigger] f(
475                a2,
476            ) ==> a1 == a2);
477        assert(self.dom().map(f) == self.values());
478        lemma_map_size(self.dom(), self.values(), f);
479    }
480
481    pub proof fn lemma_values_len(self)
482        requires
483            self.dom().finite(),
484        ensures
485            self.values().finite(),
486            self.values().len() <= self.dom().len(),
487    {
488        let f = |k: K|
489            if self.contains_key(k) {
490                self[k]
491            } else {
492                Set::<V>::full().difference(self.values()).choose()
493            };
494        assert(self.dom().map(f) == self.values());
495        lemma_map_size_bound(self.dom(), self.values(), f);
496    }
497}
498
499impl<K, V> Map<Seq<K>, V> {
500    /// Returns a sub-map of all entries whose key begins with `prefix`,
501    /// re-indexed so that the stored keys have that prefix removed.
502    ///
503    /// ## Example
504    /// ```rust
505    /// proof fn example() {
506    ///     let m = map![seq![1, 2] => 10, seq![1, 2, 3] => 20, seq![2] => 30];
507    ///     let sub = m.prefixed_entries(seq![1, 2]);
508    ///
509    ///     assert(sub.contains_key(seq![]));          // original key [1,2]
510    ///     assert(sub[seq![]] == 10);
511    ///
512    ///     assert(sub.contains_key(seq![3]));         // original key [1,2,3]
513    ///     assert(sub[seq![3]] == 20);
514    ///
515    ///     assert(!sub.contains_key(seq![2]));        // original key [2] was not prefixed
516    /// }
517    /// ```
518    pub open spec fn prefixed_entries(self, prefix: Seq<K>) -> Self {
519        Map::new(|k: Seq<K>| self.contains_key(prefix + k), |k: Seq<K>| self[prefix + k])
520    }
521
522    /// For every key `k` kept by `prefixed_entries(prefix)`,
523    /// the associated value is the one stored at `prefix + k` in the original map.
524    ///
525    /// ## Example
526    /// ```rust
527    /// proof fn example() {
528    ///     let m = map![seq![1, 2] => 10, seq![1, 2, 3] => 20];
529    ///     let p = seq![1, 2];
530    ///
531    ///     // key inside the sub-map
532    ///     assert(m.prefixed_entries(p)[seq![]] == m[p + seq![]]);      // 10
533    ///     assert(m.prefixed_entries(p)[seq![3]] == m[p + seq![3]]);    // 20
534    /// }
535    /// ```
536    pub broadcast proof fn lemma_prefixed_entries_get(self, prefix: Seq<K>, k: Seq<K>)
537        requires
538            self.prefixed_entries(prefix).contains_key(k),
539        ensures
540            self.prefixed_entries(prefix)[k] == #[trigger] self[prefix + k],
541    {
542        broadcast use group_map_properties;
543
544    }
545
546    /// A key `k` is in `prefixed_entries(prefix)` exactly when the original map
547    /// contains the key `prefix + k`.
548    ///
549    /// ## Example
550    /// ```rust
551    /// proof fn example() {
552    ///     let m = map![seq![1, 2] => 10, seq![1, 2, 3] => 20];
553    ///     let p = seq![1, 2];
554    ///
555    ///     assert(m.prefixed_entries(p).contains_key(seq![])
556    ///            <==> m.contains_key(p + seq![]));
557    ///
558    ///     assert(m.prefixed_entries(p).contains_key(seq![3])
559    ///            <==> m.contains_key(p + seq![3]));
560    ///
561    ///     assert(!m.prefixed_entries(p).contains_key(seq![2]));
562    /// }
563    /// ```
564    pub broadcast proof fn lemma_prefixed_entries_contains(self, prefix: Seq<K>, k: Seq<K>)
565        ensures
566            #[trigger] self.prefixed_entries(prefix).contains_key(k) <==> self.contains_key(
567                prefix + k,
568            ),
569    {
570        broadcast use group_map_properties;
571
572        let lhs = self.prefixed_entries(prefix);
573        let rhs = self;
574    }
575
576    /// Inserting `(prefix + k, v)` before taking `prefixed_entries(prefix)`
577    /// has the same effect as inserting `(k, v)` into the prefixed map.
578    ///
579    /// ## Example
580    /// ```rust
581    /// proof fn example() {
582    ///     let m = map![seq![1, 2] => 10];
583    ///     let p = seq![1, 2];
584    ///
585    ///     let left  = m.insert(p + seq![3], 20).prefixed_entries(p);
586    ///     let right = m.prefixed_entries(p).insert(seq![3], 20);
587    ///
588    ///     assert(left == right);
589    /// }
590    /// ```
591    pub broadcast proof fn lemma_prefixed_entries_insert(self, prefix: Seq<K>, k: Seq<K>, v: V)
592        ensures
593            #[trigger] self.insert(prefix + k, v).prefixed_entries(prefix) == self.prefixed_entries(
594                prefix,
595            ).insert(k, v),
596    {
597        broadcast use group_map_properties;
598        broadcast use super::seq::group_seq_axioms;
599
600        #[allow(deprecated)]
601        super::seq_lib::lemma_seq_properties::<K>();  // new broadcast group not working here
602        broadcast use Map::lemma_prefixed_entries_contains, Map::lemma_prefixed_entries_get;
603
604        let lhs = self.insert(prefix + k, v).prefixed_entries(prefix);
605        let rhs = self.prefixed_entries(prefix).insert(k, v);
606        assert(lhs =~= rhs) by {
607            assert(forall|key| key != k ==> prefix.is_prefix_of(#[trigger] (prefix + key)));
608        }
609    }
610
611    /// Taking the entries that share `prefix` commutes with `union_prefer_right`:
612    /// union the two maps first and then strip the prefix, or strip the prefix from
613    /// each map and then union them—the resulting maps are identical.
614    ///
615    /// ## Example
616    /// ```rust
617    /// proof fn example() {
618    ///     let a = map![seq![1, 2] => 10, seq![2, 3] => 20];
619    ///     let b = map![seq![1, 2] => 99, seq![2, 4] => 40];
620    ///     let p = seq![2];
621    ///
622    ///     assert(
623    ///         a.union_prefer_right(b).prefixed_entries(p)
624    ///         == a.prefixed_entries(p).union_prefer_right(b.prefixed_entries(p))
625    ///     );
626    /// }
627    /// ```
628    pub broadcast proof fn lemma_prefixed_entries_union(self, m: Self, prefix: Seq<K>)
629        ensures
630            #[trigger] self.union_prefer_right(m).prefixed_entries(prefix) == self.prefixed_entries(
631                prefix,
632            ).union_prefer_right(m.prefixed_entries(prefix)),
633    {
634        broadcast use group_map_properties;
635        broadcast use
636            Map::lemma_prefixed_entries_contains,
637            Map::lemma_prefixed_entries_get,
638            Map::lemma_prefixed_entries_insert,
639        ;
640
641        let lhs = self.union_prefer_right(m).prefixed_entries(prefix);
642        let rhs = self.prefixed_entries(prefix).union_prefer_right(m.prefixed_entries(prefix));
643        assert(lhs == rhs);
644    }
645}
646
647impl Map<int, int> {
648    /// Returns `true` if a map is monotonic -- that is, if the mapping between ordered sets
649    /// preserves the regular `<=` ordering on integers.
650    pub open spec fn is_monotonic(self) -> bool {
651        forall|x: int, y: int|
652            self.dom().contains(x) && self.dom().contains(y) && x <= y ==> #[trigger] self[x]
653                <= #[trigger] self[y]
654    }
655
656    /// Returns `true` if and only if a map is monotonic, only considering keys greater than
657    /// or equal to start
658    pub open spec fn is_monotonic_from(self, start: int) -> bool {
659        forall|x: int, y: int|
660            self.dom().contains(x) && self.dom().contains(y) && start <= x <= y
661                ==> #[trigger] self[x] <= #[trigger] self[y]
662    }
663}
664
665// Proven lemmas
666pub broadcast proof fn lemma_union_insert_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
667    requires
668        !m2.contains_key(k),
669    ensures
670        #[trigger] m1.insert(k, v).union_prefer_right(m2) == m1.union_prefer_right(m2).insert(k, v),
671{
672    assert(m1.insert(k, v).union_prefer_right(m2) =~= m1.union_prefer_right(m2).insert(k, v));
673}
674
675pub broadcast proof fn lemma_union_insert_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
676    ensures
677        #[trigger] m1.union_prefer_right(m2.insert(k, v)) == m1.union_prefer_right(m2).insert(k, v),
678{
679    assert(m1.union_prefer_right(m2.insert(k, v)) =~= m1.union_prefer_right(m2).insert(k, v));
680}
681
682pub broadcast proof fn lemma_union_remove_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
683    requires
684        m1.contains_key(k),
685        !m2.contains_key(k),
686    ensures
687        #[trigger] m1.union_prefer_right(m2).remove(k) == m1.remove(k).union_prefer_right(m2),
688{
689    assert(m1.remove(k).union_prefer_right(m2) =~= m1.union_prefer_right(m2).remove(k));
690}
691
692pub broadcast proof fn lemma_union_remove_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
693    requires
694        !m1.contains_key(k),
695        m2.contains_key(k),
696    ensures
697        #[trigger] m1.union_prefer_right(m2).remove(k) == m1.union_prefer_right(m2.remove(k)),
698{
699    assert(m1.union_prefer_right(m2.remove(k)) =~= m1.union_prefer_right(m2).remove(k));
700}
701
702pub broadcast proof fn lemma_union_dom<K, V>(m1: Map<K, V>, m2: Map<K, V>)
703    ensures
704        #[trigger] m1.union_prefer_right(m2).dom() == m1.dom().union(m2.dom()),
705{
706    assert(m1.dom().union(m2.dom()) =~= m1.union_prefer_right(m2).dom());
707}
708
709/// The size of the union of two disjoint maps is equal to the sum of the sizes of the individual maps
710pub broadcast proof fn lemma_disjoint_union_size<K, V>(m1: Map<K, V>, m2: Map<K, V>)
711    requires
712        m1.dom().disjoint(m2.dom()),
713        m1.dom().finite(),
714        m2.dom().finite(),
715    ensures
716        #[trigger] m1.union_prefer_right(m2).dom().len() == m1.dom().len() + m2.dom().len(),
717{
718    let u = m1.union_prefer_right(m2);
719    assert(u.dom() =~= m1.dom() + m2.dom());  //proves u.dom() is finite
720    assert(u.remove_keys(m1.dom()).dom() =~= m2.dom());
721    assert(u.remove_keys(m1.dom()).dom().len() == u.dom().len() - m1.dom().len()) by {
722        u.lemma_remove_keys_len(m1.dom());
723    }
724}
725
726pub broadcast group group_map_union {
727    lemma_union_dom,
728    lemma_union_remove_left,
729    lemma_union_remove_right,
730    lemma_union_insert_left,
731    lemma_union_insert_right,
732    lemma_disjoint_union_size,
733}
734
735/// submap_of (<=) is transitive.
736pub broadcast proof fn lemma_submap_of_trans<K, V>(m1: Map<K, V>, m2: Map<K, V>, m3: Map<K, V>)
737    requires
738        #[trigger] m1.submap_of(m2),
739        #[trigger] m2.submap_of(m3),
740    ensures
741        m1.submap_of(m3),
742{
743    assert forall|k| m1.dom().contains(k) implies #[trigger] m3.dom().contains(k) && m1[k]
744        == m3[k] by {
745        assert(m2.dom().contains(k));
746    }
747}
748
749// This verified lemma used to be an axiom in the Dafny prelude
750/// The domain of a map constructed with `Map::new(fk, fv)` is equivalent to the set constructed with `Set::new(fk)`.
751pub broadcast proof fn lemma_map_new_domain<K, V>(fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V)
752    ensures
753        #[trigger] Map::<K, V>::new(fk, fv).dom() == Set::<K>::new(|k: K| fk(k)),
754{
755    assert(Set::new(fk) =~= Set::<K>::new(|k: K| fk(k)));
756}
757
758// This verified lemma used to be an axiom in the Dafny prelude
759/// The set of values of a map constructed with `Map::new(fk, fv)` is equivalent to
760/// the set constructed with `Set::new(|v: V| (exists |k: K| fk(k) && fv(k) == v)`. In other words,
761/// the set of all values fv(k) where fk(k) is true.
762pub broadcast proof fn lemma_map_new_values<K, V>(fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V)
763    ensures
764        #[trigger] Map::<K, V>::new(fk, fv).values() == Set::<V>::new(
765            |v: V| (exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v),
766        ),
767{
768    let keys = Set::<K>::new(fk);
769    let values = Map::<K, V>::new(fk, fv).values();
770    let map = Map::<K, V>::new(fk, fv);
771    assert(map.dom() =~= keys);
772    assert(forall|k: K| #[trigger] fk(k) ==> keys.contains(k));
773    assert(values =~= Set::<V>::new(
774        |v: V| (exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v),
775    ));
776}
777
778/// Properties of maps from the Dafny prelude (which were axioms in Dafny, but proven here in Verus)
779#[deprecated = "Use `broadcast use group_map_properties` instead"]
780pub proof fn lemma_map_properties<K, V>()
781    ensures
782        forall|fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V| #[trigger]
783            Map::<K, V>::new(fk, fv).dom() == Set::<K>::new(|k: K| fk(k)),  //from lemma_map_new_domain
784        forall|fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V| #[trigger]
785            Map::<K, V>::new(fk, fv).values() == Set::<V>::new(
786                |v: V| exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v,
787            ),  //from lemma_map_new_values
788{
789    broadcast use group_map_properties;
790
791}
792
793pub broadcast group group_map_properties {
794    lemma_map_new_domain,
795    lemma_map_new_values,
796}
797
798pub broadcast group group_map_extra {
799    Map::lemma_map_remove_keys_insert,
800    Map::lemma_filter_keys_insert,
801    Map::lemma_insert_contains_value,
802    Map::lemma_insert_invariant_contains,
803    Map::lemma_prefixed_entries_get,
804    Map::lemma_prefixed_entries_contains,
805    Map::lemma_prefixed_entries_insert,
806    Map::lemma_prefixed_entries_union,
807}
808
809pub proof fn lemma_values_finite<K, V>(m: Map<K, V>)
810    requires
811        m.dom().finite(),
812    ensures
813        m.values().finite(),
814    decreases m.len(),
815{
816    if m.len() > 0 {
817        let k = m.dom().choose();
818        let v = m[k];
819        let m1 = m.remove(k);
820        assert(m.contains_key(k));
821        assert(m.contains_value(v));
822        let mv = m.values();
823        let m1v = m1.values();
824        assert_sets_equal!(mv == m1v.insert(v), v0 => {
825            if m.contains_value(v0) {
826                if v0 != v {
827                    let k0 = choose|k0| #![auto] m.contains_key(k0) && m[k0] == v0;
828                    assert(k0 != k);
829                    assert(m1.contains_key(k0));
830                    assert(mv.contains(v0) ==> m1v.insert(v).contains(v0));
831                    assert(mv.contains(v0) <== m1v.insert(v).contains(v0));
832                }
833            }
834        });
835        assert(m1.len() < m.len());
836        lemma_values_finite(m1);
837        axiom_set_insert_finite(m1.values(), v);
838    } else {
839        assert(m.values() =~= Set::<V>::empty());
840    }
841}
842
843} // verus!