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::*;
7use super::set::*;
8#[cfg(verus_keep_ghost)]
9use super::set_lib::*;
10
11verus! {
12
13broadcast use {super::map::group_map_axioms, super::set::group_set_axioms};
14
15impl<K, V> Map<K, V> {
16 #[verifier::inline]
18 pub open spec fn is_full(self) -> bool {
19 self.dom().is_full()
20 }
21
22 #[verifier::inline]
24 pub open spec fn is_empty(self) -> (b: bool) {
25 self.dom().is_empty()
26 }
27
28 #[verifier::inline]
30 pub open spec fn contains_key(self, k: K) -> bool {
31 self.dom().contains(k)
32 }
33
34 pub open spec fn contains_value(self, v: V) -> bool {
36 exists|i: K| #[trigger] self.dom().contains(i) && self[i] == v
37 }
38
39 pub open spec fn index_opt(self, k: K) -> Option<V> {
42 if self.contains_key(k) {
43 Some(self[k])
44 } else {
45 None
46 }
47 }
48
49 pub open spec fn values(self) -> Set<V> {
63 Set::<V>::new(|v: V| self.contains_value(v))
64 }
65
66 pub open spec fn kv_pairs(self) -> Set<(K, V)> {
80 Set::<(K, V)>::new(|kv: (K, V)| self.dom().contains(kv.0) && self[kv.0] == kv.1)
81 }
82
83 pub open spec fn contains_pair(self, k: K, v: V) -> bool {
85 self.dom().contains(k) && self[k] == v
86 }
87
88 pub open spec fn submap_of(self, m2: Self) -> bool {
99 forall|k: K| #[trigger]
100 self.dom().contains(k) ==> #[trigger] m2.dom().contains(k) && self[k] == m2[k]
101 }
102
103 #[verifier::inline]
104 pub open spec fn spec_le(self, m2: Self) -> bool {
105 self.submap_of(m2)
106 }
107
108 pub open spec fn union_prefer_right(self, m2: Self) -> Self {
122 Self::new(
123 |k: K| self.dom().contains(k) || m2.dom().contains(k),
124 |k: K|
125 if m2.dom().contains(k) {
126 m2[k]
127 } else {
128 self[k]
129 },
130 )
131 }
132
133 pub open spec fn remove_keys(self, keys: Set<K>) -> Self {
145 Self::new(|k: K| self.dom().contains(k) && !keys.contains(k), |k: K| self[k])
146 }
147
148 pub open spec fn restrict(self, keys: Set<K>) -> Self {
160 Self::new(|k: K| self.dom().contains(k) && keys.contains(k), |k: K| self[k])
161 }
162
163 pub open spec fn is_equal_on_key(self, m2: Self, key: K) -> bool {
165 ||| (!self.dom().contains(key) && !m2.dom().contains(key))
166 ||| (self.dom().contains(key) && m2.dom().contains(key) && self[key] == m2[key])
167 }
168
169 pub open spec fn agrees(self, m2: Self) -> bool {
171 forall|k| #![auto] self.dom().contains(k) && m2.dom().contains(k) ==> self[k] == m2[k]
172 }
173
174 pub open spec fn map_entries<W>(self, f: spec_fn(K, V) -> W) -> Map<K, W> {
176 Map::new(|k: K| self.contains_key(k), |k: K| f(k, self[k]))
177 }
178
179 pub open spec fn map_values<W>(self, f: spec_fn(V) -> W) -> Map<K, W> {
181 Map::new(|k: K| self.contains_key(k), |k: K| f(self[k]))
182 }
183
184 pub open spec fn is_injective(self) -> bool {
186 forall|x: K, y: K|
187 x != y && self.dom().contains(x) && self.dom().contains(y) ==> #[trigger] self[x]
188 != #[trigger] self[y]
189 }
190
191 pub open spec fn invert(self) -> Map<V, K> {
194 Map::<V, K>::new(
195 |v: V| self.contains_value(v),
196 |v: V| choose|k: K| self.contains_pair(k, v),
197 )
198 }
199
200 pub proof fn lemma_remove_key_len(self, key: K)
204 requires
205 self.dom().contains(key),
206 self.dom().finite(),
207 ensures
208 self.dom().len() == 1 + self.remove(key).dom().len(),
209 {
210 }
211
212 pub proof fn lemma_remove_equivalency(self, key: K)
215 ensures
216 self.remove(key).dom() == self.dom().remove(key),
217 {
218 }
219
220 pub proof fn lemma_remove_keys_len(self, keys: Set<K>)
223 requires
224 forall|k: K| #[trigger] keys.contains(k) ==> self.contains_key(k),
225 keys.finite(),
226 self.dom().finite(),
227 ensures
228 self.remove_keys(keys).dom().len() == self.dom().len() - keys.len(),
229 decreases keys.len(),
230 {
231 broadcast use group_set_properties;
232
233 if keys.len() > 0 {
234 let key = keys.choose();
235 let val = self[key];
236 self.remove(key).lemma_remove_keys_len(keys.remove(key));
237 assert(self.remove(key).remove_keys(keys.remove(key)) =~= self.remove_keys(keys));
238 } else {
239 assert(self.remove_keys(keys) =~= self);
240 }
241 }
242
243 pub proof fn lemma_invert_is_injective(self)
245 ensures
246 self.invert().is_injective(),
247 {
248 assert forall|x: V, y: V|
249 x != y && self.invert().dom().contains(x) && self.invert().dom().contains(
250 y,
251 ) implies #[trigger] self.invert()[x] != #[trigger] self.invert()[y] by {
252 let i = choose|i: K| #[trigger] self.dom().contains(i) && self[i] == x;
253 assert(self.contains_pair(i, x));
254 let j = choose|j: K| self.contains_pair(j, x) && self.invert()[x] == j;
255 let k = choose|k: K| #[trigger] self.dom().contains(k) && self[k] == y;
256 assert(self.contains_pair(k, y));
257 let l = choose|l: K| self.contains_pair(l, y) && self.invert()[y] == l && l != j;
258 }
259 }
260
261 pub open spec fn filter_keys(self, p: spec_fn(K) -> bool) -> Self {
272 self.restrict(self.dom().filter(p))
273 }
274
275 pub open spec fn get(self, k: K) -> Option<V> {
291 if self.dom().contains(k) {
292 Some(self[k])
293 } else {
294 None
295 }
296 }
297
298 pub proof fn get_dom_value_any(self, p: spec_fn(V) -> bool)
310 ensures
311 self.dom().any(|k: K| p(self[k])) <==> self.values().any(p),
312 {
313 broadcast use group_map_properties;
314
315 if self.dom().any(|k: K| p(self[k])) {
316 let k = choose|k: K| self.dom().contains(k) && #[trigger] p(self[k]);
317 assert(self.values().contains(self[k]));
318 assert(self.values().any(p));
319 }
320 }
321
322 pub proof fn lemma_submap_eq_iff(self, m: Self)
336 ensures
337 (self == m) <==> (self.submap_of(m) && m.submap_of(self)),
338 {
339 broadcast use group_map_properties;
340
341 if self.submap_of(m) && m.submap_of(self) {
342 assert(self.dom() == m.dom());
343 assert(self == m);
344 }
345 }
346
347 pub broadcast proof fn lemma_map_remove_keys_insert(self, r: Set<K>, k: K, v: V)
366 ensures
367 #[trigger] self.insert(k, v).remove_keys(r) == if r.contains(k) {
368 self.remove_keys(r)
369 } else {
370 self.remove_keys(r).insert(k, v)
371 },
372 {
373 broadcast use group_map_properties;
374
375 let lhs = self.insert(k, v).remove_keys(r);
376 let rhs = if r.contains(k) {
377 self.remove_keys(r)
378 } else {
379 self.remove_keys(r).insert(k, v)
380 };
381 assert(lhs == rhs);
382 }
383
384 pub broadcast proof fn lemma_filter_keys_insert(self, p: spec_fn(K) -> bool, k: K, v: V)
399 ensures
400 #[trigger] self.insert(k, v).filter_keys(p) == (if p(k) {
401 self.filter_keys(p).insert(k, v)
402 } else {
403 self.filter_keys(p)
404 }),
405 {
406 broadcast use group_map_properties;
407
408 let lhs = self.insert(k, v).filter_keys(p);
409 let rhs = if p(k) {
410 self.filter_keys(p).insert(k, v)
411 } else {
412 self.filter_keys(p)
413 };
414 assert(lhs == rhs);
415 }
416
417 pub broadcast proof fn lemma_insert_contains_value(self, k: K, v: V)
427 ensures
428 #[trigger] self.insert(k, v).contains_value(v),
429 {
430 assert(self.insert(k, v).contains_key(k));
431 }
432
433 pub broadcast proof fn lemma_insert_invariant_contains(self, old_v: V, k: K, v: V)
445 requires
446 self.contains_key(k) ==> self[k] != old_v,
447 old_v != v,
448 ensures
449 #[trigger] self.insert(k, v).contains_value(old_v) == self.contains_value(old_v),
450 {
451 if self.contains_value(old_v) {
452 let old_k = choose|key: K| #[trigger] self.dom().contains(key) && self[key] == old_v;
453 assert(self.insert(k, v).contains_key(old_k));
454 }
455 }
456}
457
458impl<K, V> Map<Seq<K>, V> {
459 pub open spec fn prefixed_entries(self, prefix: Seq<K>) -> Self {
478 Map::new(|k: Seq<K>| self.contains_key(prefix + k), |k: Seq<K>| self[prefix + k])
479 }
480
481 pub broadcast proof fn lemma_prefixed_entries_get(self, prefix: Seq<K>, k: Seq<K>)
496 requires
497 self.prefixed_entries(prefix).contains_key(k),
498 ensures
499 self.prefixed_entries(prefix)[k] == #[trigger] self[prefix + k],
500 {
501 broadcast use group_map_properties;
502
503 }
504
505 pub broadcast proof fn lemma_prefixed_entries_contains(self, prefix: Seq<K>, k: Seq<K>)
524 ensures
525 #[trigger] self.prefixed_entries(prefix).contains_key(k) <==> self.contains_key(
526 prefix + k,
527 ),
528 {
529 broadcast use group_map_properties;
530
531 let lhs = self.prefixed_entries(prefix);
532 let rhs = self;
533 }
534
535 pub broadcast proof fn lemma_prefixed_entries_insert(self, prefix: Seq<K>, k: Seq<K>, v: V)
551 ensures
552 #[trigger] self.insert(prefix + k, v).prefixed_entries(prefix) == self.prefixed_entries(
553 prefix,
554 ).insert(k, v),
555 {
556 broadcast use group_map_properties;
557 broadcast use super::seq::group_seq_axioms;
558
559 #[allow(deprecated)]
560 super::seq_lib::lemma_seq_properties::<K>(); broadcast use Map::lemma_prefixed_entries_contains, Map::lemma_prefixed_entries_get;
562
563 let lhs = self.insert(prefix + k, v).prefixed_entries(prefix);
564 let rhs = self.prefixed_entries(prefix).insert(k, v);
565 assert(lhs =~= rhs) by {
566 assert(forall|key| key != k ==> prefix.is_prefix_of(#[trigger] (prefix + key)));
567 }
568 }
569
570 pub broadcast proof fn lemma_prefixed_entries_union(self, m: Self, prefix: Seq<K>)
588 ensures
589 #[trigger] self.union_prefer_right(m).prefixed_entries(prefix) == self.prefixed_entries(
590 prefix,
591 ).union_prefer_right(m.prefixed_entries(prefix)),
592 {
593 broadcast use group_map_properties;
594 broadcast use
595 Map::lemma_prefixed_entries_contains,
596 Map::lemma_prefixed_entries_get,
597 Map::lemma_prefixed_entries_insert,
598 ;
599
600 let lhs = self.union_prefer_right(m).prefixed_entries(prefix);
601 let rhs = self.prefixed_entries(prefix).union_prefer_right(m.prefixed_entries(prefix));
602 assert(lhs == rhs);
603 }
604}
605
606impl Map<int, int> {
607 pub open spec fn is_monotonic(self) -> bool {
610 forall|x: int, y: int|
611 self.dom().contains(x) && self.dom().contains(y) && x <= y ==> #[trigger] self[x]
612 <= #[trigger] self[y]
613 }
614
615 pub open spec fn is_monotonic_from(self, start: int) -> bool {
618 forall|x: int, y: int|
619 self.dom().contains(x) && self.dom().contains(y) && start <= x <= y
620 ==> #[trigger] self[x] <= #[trigger] self[y]
621 }
622}
623
624pub broadcast proof fn lemma_union_insert_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
626 requires
627 !m2.contains_key(k),
628 ensures
629 #[trigger] m1.insert(k, v).union_prefer_right(m2) == m1.union_prefer_right(m2).insert(k, v),
630{
631 assert(m1.insert(k, v).union_prefer_right(m2) =~= m1.union_prefer_right(m2).insert(k, v));
632}
633
634pub broadcast proof fn lemma_union_insert_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
635 ensures
636 #[trigger] m1.union_prefer_right(m2.insert(k, v)) == m1.union_prefer_right(m2).insert(k, v),
637{
638 assert(m1.union_prefer_right(m2.insert(k, v)) =~= m1.union_prefer_right(m2).insert(k, v));
639}
640
641pub broadcast proof fn lemma_union_remove_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
642 requires
643 m1.contains_key(k),
644 !m2.contains_key(k),
645 ensures
646 #[trigger] m1.union_prefer_right(m2).remove(k) == m1.remove(k).union_prefer_right(m2),
647{
648 assert(m1.remove(k).union_prefer_right(m2) =~= m1.union_prefer_right(m2).remove(k));
649}
650
651pub broadcast proof fn lemma_union_remove_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
652 requires
653 !m1.contains_key(k),
654 m2.contains_key(k),
655 ensures
656 #[trigger] m1.union_prefer_right(m2).remove(k) == m1.union_prefer_right(m2.remove(k)),
657{
658 assert(m1.union_prefer_right(m2.remove(k)) =~= m1.union_prefer_right(m2).remove(k));
659}
660
661pub broadcast proof fn lemma_union_dom<K, V>(m1: Map<K, V>, m2: Map<K, V>)
662 ensures
663 #[trigger] m1.union_prefer_right(m2).dom() == m1.dom().union(m2.dom()),
664{
665 assert(m1.dom().union(m2.dom()) =~= m1.union_prefer_right(m2).dom());
666}
667
668pub broadcast proof fn lemma_disjoint_union_size<K, V>(m1: Map<K, V>, m2: Map<K, V>)
670 requires
671 m1.dom().disjoint(m2.dom()),
672 m1.dom().finite(),
673 m2.dom().finite(),
674 ensures
675 #[trigger] m1.union_prefer_right(m2).dom().len() == m1.dom().len() + m2.dom().len(),
676{
677 let u = m1.union_prefer_right(m2);
678 assert(u.dom() =~= m1.dom() + m2.dom()); assert(u.remove_keys(m1.dom()).dom() =~= m2.dom());
680 assert(u.remove_keys(m1.dom()).dom().len() == u.dom().len() - m1.dom().len()) by {
681 u.lemma_remove_keys_len(m1.dom());
682 }
683}
684
685pub broadcast group group_map_union {
686 lemma_union_dom,
687 lemma_union_remove_left,
688 lemma_union_remove_right,
689 lemma_union_insert_left,
690 lemma_union_insert_right,
691 lemma_disjoint_union_size,
692}
693
694pub broadcast proof fn lemma_submap_of_trans<K, V>(m1: Map<K, V>, m2: Map<K, V>, m3: Map<K, V>)
696 requires
697 #[trigger] m1.submap_of(m2),
698 #[trigger] m2.submap_of(m3),
699 ensures
700 m1.submap_of(m3),
701{
702 assert forall|k| m1.dom().contains(k) implies #[trigger] m3.dom().contains(k) && m1[k]
703 == m3[k] by {
704 assert(m2.dom().contains(k));
705 }
706}
707
708pub broadcast proof fn lemma_map_new_domain<K, V>(fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V)
711 ensures
712 #[trigger] Map::<K, V>::new(fk, fv).dom() == Set::<K>::new(|k: K| fk(k)),
713{
714 assert(Set::new(fk) =~= Set::<K>::new(|k: K| fk(k)));
715}
716
717pub broadcast proof fn lemma_map_new_values<K, V>(fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V)
722 ensures
723 #[trigger] Map::<K, V>::new(fk, fv).values() == Set::<V>::new(
724 |v: V| (exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v),
725 ),
726{
727 let keys = Set::<K>::new(fk);
728 let values = Map::<K, V>::new(fk, fv).values();
729 let map = Map::<K, V>::new(fk, fv);
730 assert(map.dom() =~= keys);
731 assert(forall|k: K| #[trigger] fk(k) ==> keys.contains(k));
732 assert(values =~= Set::<V>::new(
733 |v: V| (exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v),
734 ));
735}
736
737#[deprecated = "Use `broadcast use group_map_properties` instead"]
739pub proof fn lemma_map_properties<K, V>()
740 ensures
741 forall|fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V| #[trigger]
742 Map::<K, V>::new(fk, fv).dom() == Set::<K>::new(|k: K| fk(k)), forall|fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V| #[trigger]
744 Map::<K, V>::new(fk, fv).values() == Set::<V>::new(
745 |v: V| exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v,
746 ), {
748 broadcast use group_map_properties;
749
750}
751
752pub broadcast group group_map_properties {
753 lemma_map_new_domain,
754 lemma_map_new_values,
755}
756
757pub broadcast group group_map_extra {
758 Map::lemma_map_remove_keys_insert,
759 Map::lemma_filter_keys_insert,
760 Map::lemma_insert_contains_value,
761 Map::lemma_insert_invariant_contains,
762 Map::lemma_prefixed_entries_get,
763 Map::lemma_prefixed_entries_contains,
764 Map::lemma_prefixed_entries_insert,
765 Map::lemma_prefixed_entries_union,
766}
767
768pub proof fn lemma_values_finite<K, V>(m: Map<K, V>)
769 requires
770 m.dom().finite(),
771 ensures
772 m.values().finite(),
773 decreases m.len(),
774{
775 if m.len() > 0 {
776 let k = m.dom().choose();
777 let v = m[k];
778 let m1 = m.remove(k);
779 assert(m.contains_key(k));
780 assert(m.contains_value(v));
781 let mv = m.values();
782 let m1v = m1.values();
783 assert_sets_equal!(mv == m1v.insert(v), v0 => {
784 if m.contains_value(v0) {
785 if v0 != v {
786 let k0 = choose|k0| #![auto] m.contains_key(k0) && m[k0] == v0;
787 assert(k0 != k);
788 assert(m1.contains_key(k0));
789 assert(mv.contains(v0) ==> m1v.insert(v).contains(v0));
790 assert(mv.contains(v0) <== m1v.insert(v).contains(v0));
791 }
792 }
793 });
794 assert(m1.len() < m.len());
795 lemma_values_finite(m1);
796 axiom_set_insert_finite(m1.values(), v);
797 } else {
798 assert(m.values() =~= Set::<V>::empty());
799 }
800}
801
802}