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 #[verifier::inline]
20 pub open spec fn is_full(self) -> bool {
21 self.dom().is_full()
22 }
23
24 #[verifier::inline]
26 pub open spec fn is_empty(self) -> (b: bool) {
27 self.dom().is_empty()
28 }
29
30 #[verifier::inline]
32 pub open spec fn contains_key(self, k: K) -> bool {
33 self.dom().contains(k)
34 }
35
36 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 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 pub open spec fn values(self) -> Set<V> {
65 Set::<V>::new(|v: V| self.contains_value(v))
66 }
67
68 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 pub open spec fn contains_pair(self, k: K, v: V) -> bool {
87 self.dom().contains(k) && self[k] == v
88 }
89
90 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 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 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 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 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 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 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 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 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 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 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 pub proof fn lemma_remove_equivalency(self, key: K)
217 ensures
218 self.remove(key).dom() == self.dom().remove(key),
219 {
220 }
221
222 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 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 pub open spec fn filter_keys(self, p: spec_fn(K) -> bool) -> Self {
274 self.restrict(self.dom().filter(p))
275 }
276
277 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 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 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 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 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 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 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 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 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 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 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>(); 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 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 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 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
665pub 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
709pub 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()); 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
735pub 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
749pub 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
758pub 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#[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)), 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 ), {
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}