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 {
16 super::map::group_map_lemmas,
17 super::set::group_set_lemmas,
18 super::set_lib::group_set_lib_default,
19 super::iset::group_iset_lemmas,
20};
21
22impl<K, V> Map<K, V> {
23 #[verifier::inline]
25 pub open spec fn is_full(self) -> bool {
26 forall|k: K| self.dom().contains(k)
27 }
28
29 #[verifier::inline]
31 pub open spec fn is_empty(self) -> (b: bool) {
32 self.dom().is_empty()
33 }
34
35 #[verifier::inline]
37 pub open spec fn contains_key(self, k: K) -> bool {
38 self.dom().contains(k)
39 }
40
41 pub open spec fn contains_value(self, v: V) -> bool {
43 exists|i: K| #[trigger] self.dom().contains(i) && self[i] == v
44 }
45
46 pub open spec fn index_opt(self, k: K) -> Option<V> {
49 if self.contains_key(k) {
50 Some(self[k])
51 } else {
52 None
53 }
54 }
55
56 pub open spec fn values(self) -> Set<V> {
70 self.dom().map(|k: K| self[k])
71 }
72
73 pub open spec fn kv_pairs(self) -> Set<(K, V)> {
87 self.dom().map(|k: K| (k, self[k]))
88 }
89
90 pub open spec fn contains_pair(self, k: K, v: V) -> bool {
92 &&& self.dom().contains(k)
96 &&& self.dom().contains(k) ==> self[k] == v
97 }
98
99 pub open spec fn submap_of(self, m2: Self) -> bool {
110 forall|k: K| #[trigger]
111 self.dom().contains(k) ==> #[trigger] m2.dom().contains(k) && self[k] == m2[k]
112 }
113
114 #[verifier::inline]
115 pub open spec fn spec_le(self, m2: Self) -> bool {
116 self.submap_of(m2)
117 }
118
119 pub open spec fn union_prefer_right(self, m2: Self) -> Self {
133 Self::new(
134 self.dom().union(m2.dom()),
135 |k: K|
136 if m2.dom().contains(k) {
137 m2[k]
138 } else {
139 self[k]
140 },
141 )
142 }
143
144 pub open spec fn remove_keys(self, keys: Set<K>) -> Self {
156 Self::new(self.dom().difference(keys), |k: K| self[k])
157 }
158
159 pub open spec fn restrict(self, keys: Set<K>) -> Self {
171 Self::new(self.dom().intersect(keys), |k: K| self[k])
172 }
173
174 pub open spec fn is_equal_on_key(self, m2: Self, key: K) -> bool {
176 ||| (!self.dom().contains(key) && !m2.dom().contains(key))
177 ||| (self.dom().contains(key) && m2.dom().contains(key) && self[key] == m2[key])
178 }
179
180 pub open spec fn agrees(self, m2: Self) -> bool {
182 forall|k| #![auto] self.dom().contains(k) && m2.dom().contains(k) ==> self[k] == m2[k]
183 }
184
185 pub open spec fn map_entries<W>(self, f: spec_fn(K, V) -> W) -> Map<K, W> {
187 Map::<K, W>::new(self.dom(), |k: K| f(k, self[k]))
188 }
189
190 pub open spec fn map_values<W>(self, f: spec_fn(V) -> W) -> Map<K, W> {
192 Map::<K, W>::new(self.dom(), |k: K| f(self[k]))
193 }
194
195 pub open spec fn is_injective(self) -> bool {
197 forall|x: K, y: K|
198 x != y && self.dom().contains(x) && self.dom().contains(y) ==> #[trigger] self[x]
199 != #[trigger] self[y]
200 }
201
202 pub open spec fn invert(self) -> Map<V, K> {
205 Map::<V, K>::new(self.values(), |v: V| choose|k: K| self.contains_pair(k, v))
206 }
207
208 pub proof fn lemma_remove_key_len(self, key: K)
212 requires
213 self.dom().contains(key),
214 ensures
215 self.dom().len() == 1 + self.remove(key).dom().len(),
216 {
217 }
218
219 pub proof fn lemma_remove_equivalency(self, key: K)
222 ensures
223 self.remove(key).dom() == self.dom().remove(key),
224 {
225 }
226
227 pub proof fn lemma_remove_keys_len(self, keys: Set<K>)
230 requires
231 forall|k: K| #[trigger] keys.contains(k) ==> self.contains_key(k),
232 ensures
233 self.remove_keys(keys).dom().len() == self.dom().len() - keys.len(),
234 decreases keys.len(),
235 {
236 broadcast use group_set_properties;
237
238 if keys.len() > 0 {
239 let key = keys.choose();
240 let val = self[key];
241 self.remove(key).lemma_remove_keys_len(keys.remove(key));
242 assert(self.remove(key).remove_keys(keys.remove(key)) =~= self.remove_keys(keys));
243 } else {
244 assert(self.remove_keys(keys) =~= self);
245 }
246 }
247
248 pub proof fn lemma_invert_is_injective(self)
250 ensures
251 self.invert().is_injective(),
252 {
253 assert forall|x: V, y: V|
254 x != y && self.invert().dom().contains(x) && self.invert().dom().contains(
255 y,
256 ) implies #[trigger] self.invert()[x] != #[trigger] self.invert()[y] by {
257 assert(exists|i: K| #[trigger] self.dom().contains(i) && self[i] == x);
258 let i = choose|i: K| #[trigger] self.dom().contains(i) && self[i] == x;
259 assert(self.contains_pair(i, x));
260 let j = choose|j: K| self.contains_pair(j, x) && self.invert()[x] == j;
261 assert(exists|k: K| #[trigger] self.dom().contains(k) && self[k] == y);
262 let k = choose|k: K| #[trigger] self.dom().contains(k) && self[k] == y;
263 assert(self.contains_pair(k, y));
264 let l = choose|l: K| self.contains_pair(l, y) && self.invert()[y] == l && l != j;
265 }
266 }
267
268 pub open spec fn filter_keys(self, p: spec_fn(K) -> bool) -> Self {
279 self.restrict(self.dom().filter(p))
280 }
281
282 pub open spec fn get(self, k: K) -> Option<V> {
298 if self.dom().contains(k) {
299 Some(self[k])
300 } else {
301 None
302 }
303 }
304
305 pub proof fn get_dom_value_any(self, p: spec_fn(V) -> bool)
317 ensures
318 self.dom().any(|k: K| p(self[k])) <==> self.values().any(p),
319 {
320 broadcast use group_map_properties;
321
322 if self.dom().any(|k: K| p(self[k])) {
323 let k = choose|k: K| self.dom().contains(k) && #[trigger] p(self[k]);
324 assert(self.values().contains(self[k]));
325 assert(self.values().any(p));
326 }
327 }
328
329 pub proof fn lemma_submap_eq_iff(self, m: Self)
343 ensures
344 (self == m) <==> (self.submap_of(m) && m.submap_of(self)),
345 {
346 broadcast use group_map_properties;
347
348 if self.submap_of(m) && m.submap_of(self) {
349 assert(self.dom() == m.dom());
350 assert(self == m);
351 }
352 }
353
354 pub broadcast proof fn lemma_map_remove_keys_insert(self, r: Set<K>, k: K, v: V)
373 ensures
374 #[trigger] self.insert(k, v).remove_keys(r) == if r.contains(k) {
375 self.remove_keys(r)
376 } else {
377 self.remove_keys(r).insert(k, v)
378 },
379 {
380 broadcast use group_map_properties;
381
382 let lhs = self.insert(k, v).remove_keys(r);
383 let rhs = if r.contains(k) {
384 self.remove_keys(r)
385 } else {
386 self.remove_keys(r).insert(k, v)
387 };
388 assert(lhs == rhs);
389 }
390
391 pub broadcast proof fn lemma_filter_keys_insert(self, p: spec_fn(K) -> bool, k: K, v: V)
406 ensures
407 #[trigger] self.insert(k, v).filter_keys(p) == (if p(k) {
408 self.filter_keys(p).insert(k, v)
409 } else {
410 self.filter_keys(p)
411 }),
412 {
413 broadcast use group_map_properties;
414
415 let lhs = self.insert(k, v).filter_keys(p);
416 let rhs = if p(k) {
417 self.filter_keys(p).insert(k, v)
418 } else {
419 self.filter_keys(p)
420 };
421 assert(lhs == rhs);
422 }
423
424 pub broadcast proof fn lemma_insert_contains_value(self, k: K, v: V)
434 ensures
435 #[trigger] self.insert(k, v).contains_value(v),
436 {
437 assert(self.insert(k, v).contains_key(k));
438 }
439
440 pub broadcast proof fn lemma_insert_invariant_contains(self, old_v: V, k: K, v: V)
452 requires
453 self.contains_key(k) ==> self[k] != old_v,
454 old_v != v,
455 ensures
456 #[trigger] self.insert(k, v).contains_value(old_v) == self.contains_value(old_v),
457 {
458 if self.contains_value(old_v) {
459 let old_k = choose|key: K| #[trigger] self.dom().contains(key) && self[key] == old_v;
460 assert(self.insert(k, v).contains_key(old_k));
461 }
462 }
463
464 pub proof fn lemma_injective_values_len(self)
465 requires
466 self.is_injective(),
467 ensures
468 self.values().len() == self.dom().len(),
469 {
470 let f = |k: K|
471 if self.contains_key(k) {
472 self[k]
473 } else {
474 arbitrary()
475 };
476 assert(forall|a1: K, a2: K|
477 self.dom().contains(a1) && self.dom().contains(a2) && #[trigger] f(a1) == #[trigger] f(
478 a2,
479 ) ==> a1 == a2);
480 assert(self.dom().map(f) == self.values());
481 lemma_map_size(self.dom(), self.values(), f);
482 }
483
484 pub proof fn lemma_values_len(self)
485 ensures
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().unwrap().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(
520 Set::new(|k: Seq<K>| self.contains_key(prefix + k)).unwrap(),
521 |k: Seq<K>| self[prefix + k],
522 )
523 }
524
525 proof fn lemma_ne_implies_prefixed_ne(prefix: Seq<K>, s1: Seq<K>, s2: Seq<K>)
529 requires
530 s1 != s2,
531 ensures
532 prefix + s1 != prefix + s2,
533 decreases prefix.len(),
534 {
535 broadcast use super::seq::group_seq_axioms;
536
537 if s1.len() == s2.len() {
538 if forall|i: int| 0 <= i < s1.len() ==> s1[i] == s2[i] {
539 assert(s1 =~= s2);
540 } else {
541 let i: int = choose|i: int| 0 <= i < s1.len() && s1[i] != s2[i];
542 assert((prefix + s1)[prefix.len() + i] == s1[i]);
543 assert((prefix + s2)[prefix.len() + i] == s2[i]);
544 }
545 } else {
546 assert((prefix + s1).len() == prefix.len() + s1.len());
547 assert((prefix + s2).len() == prefix.len() + s2.len());
548 }
549 }
550
551 proof fn lemma_prefixed_entries_dom_finite(self, prefix: Seq<K>)
554 ensures
555 ISet::new(|k: Seq<K>| self.contains_key(prefix + k)).finite(),
556 decreases self.dom().len(),
557 {
558 let f = |k: Seq<K>| self.contains_key(prefix + k);
559 if forall|k: Seq<K>| !(#[trigger] self.contains_key(prefix + k)) {
560 assert(ISet::new(f) =~= ISet::empty());
561 } else {
562 let s: Seq<K> = choose|s: Seq<K>| #[trigger] self.contains_key(prefix + s);
563 self.remove(prefix + s).lemma_prefixed_entries_dom_finite(prefix);
564 let set_remove_f = |k: Seq<K>| self.remove(prefix + s).contains_key(prefix + k);
565 let is1 = ISet::new(f);
566 let is2 = ISet::new(set_remove_f).insert(s);
567 assert forall|x| is1.contains(x) implies is2.contains(x) by {
568 if x != s {
569 Self::lemma_ne_implies_prefixed_ne(prefix, s, x);
570 assert(self.remove(prefix + s).contains_key(prefix + x));
571 }
572 }
573 assert(ISet::new(f) =~= ISet::new(set_remove_f).insert(s));
574 }
575 }
576
577 pub broadcast proof fn lemma_prefixed_entries_get(self, prefix: Seq<K>, k: Seq<K>)
592 requires
593 self.prefixed_entries(prefix).contains_key(k),
594 ensures
595 self.prefixed_entries(prefix)[k] == #[trigger] self[prefix + k],
596 {
597 broadcast use group_map_properties;
598
599 self.lemma_prefixed_entries_dom_finite(prefix);
600 }
601
602 pub broadcast proof fn lemma_prefixed_entries_contains(self, prefix: Seq<K>, k: Seq<K>)
621 ensures
622 #[trigger] self.prefixed_entries(prefix).contains_key(k) <==> self.contains_key(
623 prefix + k,
624 ),
625 {
626 broadcast use group_map_properties;
627
628 let lhs = self.prefixed_entries(prefix);
629 let rhs = self;
630
631 self.lemma_prefixed_entries_dom_finite(prefix);
632 }
633
634 pub broadcast proof fn lemma_prefixed_entries_insert(self, prefix: Seq<K>, k: Seq<K>, v: V)
650 ensures
651 #[trigger] self.insert(prefix + k, v).prefixed_entries(prefix) == self.prefixed_entries(
652 prefix,
653 ).insert(k, v),
654 {
655 broadcast use group_map_properties;
656 broadcast use super::seq::group_seq_axioms;
657 broadcast use super::seq_lib::group_seq_properties, super::seq_lib::lemma_seq_skip_of_skip;
658 broadcast use Map::lemma_prefixed_entries_contains, Map::lemma_prefixed_entries_get;
659
660 let lhs = self.insert(prefix + k, v).prefixed_entries(prefix);
661 let rhs = self.prefixed_entries(prefix).insert(k, v);
662 assert(lhs =~= rhs) by {
663 assert(forall|key| key != k ==> prefix.is_prefix_of(#[trigger] (prefix + key)));
664 }
665 }
666
667 pub broadcast proof fn lemma_prefixed_entries_union(self, m: Self, prefix: Seq<K>)
685 ensures
686 #[trigger] self.union_prefer_right(m).prefixed_entries(prefix) == self.prefixed_entries(
687 prefix,
688 ).union_prefer_right(m.prefixed_entries(prefix)),
689 {
690 broadcast use group_map_properties;
691 broadcast use
692 Map::lemma_prefixed_entries_contains,
693 Map::lemma_prefixed_entries_get,
694 Map::lemma_prefixed_entries_insert,
695 ;
696
697 let lhs = self.union_prefer_right(m).prefixed_entries(prefix);
698 let rhs = self.prefixed_entries(prefix).union_prefer_right(m.prefixed_entries(prefix));
699 assert(lhs == rhs);
700 }
701}
702
703impl Map<int, int> {
704 pub open spec fn is_monotonic(self) -> bool {
707 forall|x: int, y: int|
708 self.dom().contains(x) && self.dom().contains(y) && x <= y ==> #[trigger] self[x]
709 <= #[trigger] self[y]
710 }
711
712 pub open spec fn is_monotonic_from(self, start: int) -> bool {
715 forall|x: int, y: int|
716 self.dom().contains(x) && self.dom().contains(y) && start <= x <= y
717 ==> #[trigger] self[x] <= #[trigger] self[y]
718 }
719}
720
721pub broadcast proof fn lemma_union_insert_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
723 requires
724 !m2.contains_key(k),
725 ensures
726 #[trigger] m1.insert(k, v).union_prefer_right(m2) == m1.union_prefer_right(m2).insert(k, v),
727{
728 assert(m1.insert(k, v).union_prefer_right(m2) =~= m1.union_prefer_right(m2).insert(k, v));
729}
730
731pub broadcast proof fn lemma_union_insert_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
732 ensures
733 #[trigger] m1.union_prefer_right(m2.insert(k, v)) == m1.union_prefer_right(m2).insert(k, v),
734{
735 assert(m1.union_prefer_right(m2.insert(k, v)) =~= m1.union_prefer_right(m2).insert(k, v));
736}
737
738pub broadcast proof fn lemma_union_remove_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
739 requires
740 m1.contains_key(k),
741 !m2.contains_key(k),
742 ensures
743 #[trigger] m1.union_prefer_right(m2).remove(k) == m1.remove(k).union_prefer_right(m2),
744{
745 assert(m1.remove(k).union_prefer_right(m2) =~= m1.union_prefer_right(m2).remove(k));
746}
747
748pub broadcast proof fn lemma_union_remove_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
749 requires
750 !m1.contains_key(k),
751 m2.contains_key(k),
752 ensures
753 #[trigger] m1.union_prefer_right(m2).remove(k) == m1.union_prefer_right(m2.remove(k)),
754{
755 assert(m1.union_prefer_right(m2.remove(k)) =~= m1.union_prefer_right(m2).remove(k));
756}
757
758pub broadcast proof fn lemma_union_dom<K, V>(m1: Map<K, V>, m2: Map<K, V>)
759 ensures
760 #[trigger] m1.union_prefer_right(m2).dom() == m1.dom().union(m2.dom()),
761{
762 assert(m1.dom().union(m2.dom()) =~= m1.union_prefer_right(m2).dom());
763}
764
765pub broadcast proof fn lemma_disjoint_union_size<K, V>(m1: Map<K, V>, m2: Map<K, V>)
767 requires
768 m1.dom().disjoint(m2.dom()),
769 ensures
770 #[trigger] m1.union_prefer_right(m2).dom().len() == m1.dom().len() + m2.dom().len(),
771{
772 let u = m1.union_prefer_right(m2);
773 assert(u.dom() =~= m1.dom() + m2.dom());
774 assert(u.remove_keys(m1.dom()).dom() =~= m2.dom());
775 assert(u.remove_keys(m1.dom()).dom().len() == u.dom().len() - m1.dom().len()) by {
776 u.lemma_remove_keys_len(m1.dom());
777 }
778}
779
780pub broadcast group group_map_union {
781 lemma_union_dom,
782 lemma_union_remove_left,
783 lemma_union_remove_right,
784 lemma_union_insert_left,
785 lemma_union_insert_right,
786 lemma_disjoint_union_size,
787}
788
789pub broadcast proof fn lemma_submap_of_trans<K, V>(m1: Map<K, V>, m2: Map<K, V>, m3: Map<K, V>)
791 requires
792 #[trigger] m1.submap_of(m2),
793 #[trigger] m2.submap_of(m3),
794 ensures
795 m1.submap_of(m3),
796{
797 assert forall|k| m1.dom().contains(k) implies #[trigger] m3.dom().contains(k) && m1[k]
798 == m3[k] by {
799 assert(m2.dom().contains(k));
800 }
801}
802
803pub broadcast proof fn lemma_map_new_domain<K, V>(s: Set<K>, fv: spec_fn(K) -> V)
806 ensures
807 #[trigger] Map::<K, V>::new(s, fv).dom() == s,
808{
809}
810
811pub broadcast proof fn lemma_map_new_values<K, V>(s: Set<K>, fv: spec_fn(K) -> V)
816 ensures
817 #[trigger] Map::<K, V>::new(s, fv).values() == s.map(fv),
818{
819}
820
821pub broadcast group group_map_properties {
822 lemma_map_new_domain,
823 lemma_map_new_values,
824}
825
826pub broadcast group group_map_extra {
827 Map::lemma_map_remove_keys_insert,
828 Map::lemma_filter_keys_insert,
829 Map::lemma_insert_contains_value,
830 Map::lemma_insert_invariant_contains,
831 Map::lemma_prefixed_entries_get,
832 Map::lemma_prefixed_entries_contains,
833 Map::lemma_prefixed_entries_insert,
834 Map::lemma_prefixed_entries_union,
835}
836
837}