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 broadcast use super::seq_lib::group_seq_properties, super::seq_lib::lemma_seq_skip_of_skip;
600 broadcast use Map::lemma_prefixed_entries_contains, Map::lemma_prefixed_entries_get;
601
602 let lhs = self.insert(prefix + k, v).prefixed_entries(prefix);
603 let rhs = self.prefixed_entries(prefix).insert(k, v);
604 assert(lhs =~= rhs) by {
605 assert(forall|key| key != k ==> prefix.is_prefix_of(#[trigger] (prefix + key)));
606 }
607 }
608
609 pub broadcast proof fn lemma_prefixed_entries_union(self, m: Self, prefix: Seq<K>)
627 ensures
628 #[trigger] self.union_prefer_right(m).prefixed_entries(prefix) == self.prefixed_entries(
629 prefix,
630 ).union_prefer_right(m.prefixed_entries(prefix)),
631 {
632 broadcast use group_map_properties;
633 broadcast use
634 Map::lemma_prefixed_entries_contains,
635 Map::lemma_prefixed_entries_get,
636 Map::lemma_prefixed_entries_insert,
637 ;
638
639 let lhs = self.union_prefer_right(m).prefixed_entries(prefix);
640 let rhs = self.prefixed_entries(prefix).union_prefer_right(m.prefixed_entries(prefix));
641 assert(lhs == rhs);
642 }
643}
644
645impl Map<int, int> {
646 pub open spec fn is_monotonic(self) -> bool {
649 forall|x: int, y: int|
650 self.dom().contains(x) && self.dom().contains(y) && x <= y ==> #[trigger] self[x]
651 <= #[trigger] self[y]
652 }
653
654 pub open spec fn is_monotonic_from(self, start: int) -> bool {
657 forall|x: int, y: int|
658 self.dom().contains(x) && self.dom().contains(y) && start <= x <= y
659 ==> #[trigger] self[x] <= #[trigger] self[y]
660 }
661}
662
663pub broadcast proof fn lemma_union_insert_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
665 requires
666 !m2.contains_key(k),
667 ensures
668 #[trigger] m1.insert(k, v).union_prefer_right(m2) == m1.union_prefer_right(m2).insert(k, v),
669{
670 assert(m1.insert(k, v).union_prefer_right(m2) =~= m1.union_prefer_right(m2).insert(k, v));
671}
672
673pub broadcast proof fn lemma_union_insert_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K, v: V)
674 ensures
675 #[trigger] m1.union_prefer_right(m2.insert(k, v)) == m1.union_prefer_right(m2).insert(k, v),
676{
677 assert(m1.union_prefer_right(m2.insert(k, v)) =~= m1.union_prefer_right(m2).insert(k, v));
678}
679
680pub broadcast proof fn lemma_union_remove_left<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
681 requires
682 m1.contains_key(k),
683 !m2.contains_key(k),
684 ensures
685 #[trigger] m1.union_prefer_right(m2).remove(k) == m1.remove(k).union_prefer_right(m2),
686{
687 assert(m1.remove(k).union_prefer_right(m2) =~= m1.union_prefer_right(m2).remove(k));
688}
689
690pub broadcast proof fn lemma_union_remove_right<K, V>(m1: Map<K, V>, m2: Map<K, V>, k: K)
691 requires
692 !m1.contains_key(k),
693 m2.contains_key(k),
694 ensures
695 #[trigger] m1.union_prefer_right(m2).remove(k) == m1.union_prefer_right(m2.remove(k)),
696{
697 assert(m1.union_prefer_right(m2.remove(k)) =~= m1.union_prefer_right(m2).remove(k));
698}
699
700pub broadcast proof fn lemma_union_dom<K, V>(m1: Map<K, V>, m2: Map<K, V>)
701 ensures
702 #[trigger] m1.union_prefer_right(m2).dom() == m1.dom().union(m2.dom()),
703{
704 assert(m1.dom().union(m2.dom()) =~= m1.union_prefer_right(m2).dom());
705}
706
707pub broadcast proof fn lemma_disjoint_union_size<K, V>(m1: Map<K, V>, m2: Map<K, V>)
709 requires
710 m1.dom().disjoint(m2.dom()),
711 m1.dom().finite(),
712 m2.dom().finite(),
713 ensures
714 #[trigger] m1.union_prefer_right(m2).dom().len() == m1.dom().len() + m2.dom().len(),
715{
716 let u = m1.union_prefer_right(m2);
717 assert(u.dom() =~= m1.dom() + m2.dom()); assert(u.remove_keys(m1.dom()).dom() =~= m2.dom());
719 assert(u.remove_keys(m1.dom()).dom().len() == u.dom().len() - m1.dom().len()) by {
720 u.lemma_remove_keys_len(m1.dom());
721 }
722}
723
724pub broadcast group group_map_union {
725 lemma_union_dom,
726 lemma_union_remove_left,
727 lemma_union_remove_right,
728 lemma_union_insert_left,
729 lemma_union_insert_right,
730 lemma_disjoint_union_size,
731}
732
733pub broadcast proof fn lemma_submap_of_trans<K, V>(m1: Map<K, V>, m2: Map<K, V>, m3: Map<K, V>)
735 requires
736 #[trigger] m1.submap_of(m2),
737 #[trigger] m2.submap_of(m3),
738 ensures
739 m1.submap_of(m3),
740{
741 assert forall|k| m1.dom().contains(k) implies #[trigger] m3.dom().contains(k) && m1[k]
742 == m3[k] by {
743 assert(m2.dom().contains(k));
744 }
745}
746
747pub broadcast proof fn lemma_map_new_domain<K, V>(fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V)
750 ensures
751 #[trigger] Map::<K, V>::new(fk, fv).dom() == Set::<K>::new(|k: K| fk(k)),
752{
753 assert(Set::new(fk) =~= Set::<K>::new(|k: K| fk(k)));
754}
755
756pub broadcast proof fn lemma_map_new_values<K, V>(fk: spec_fn(K) -> bool, fv: spec_fn(K) -> V)
761 ensures
762 #[trigger] Map::<K, V>::new(fk, fv).values() == Set::<V>::new(
763 |v: V| (exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v),
764 ),
765{
766 let keys = Set::<K>::new(fk);
767 let values = Map::<K, V>::new(fk, fv).values();
768 let map = Map::<K, V>::new(fk, fv);
769 assert(map.dom() =~= keys);
770 assert(forall|k: K| #[trigger] fk(k) ==> keys.contains(k));
771 assert(values =~= Set::<V>::new(
772 |v: V| (exists|k: K| #[trigger] fk(k) && #[trigger] fv(k) == v),
773 ));
774}
775
776pub broadcast group group_map_properties {
777 lemma_map_new_domain,
778 lemma_map_new_values,
779}
780
781pub broadcast group group_map_extra {
782 Map::lemma_map_remove_keys_insert,
783 Map::lemma_filter_keys_insert,
784 Map::lemma_insert_contains_value,
785 Map::lemma_insert_invariant_contains,
786 Map::lemma_prefixed_entries_get,
787 Map::lemma_prefixed_entries_contains,
788 Map::lemma_prefixed_entries_insert,
789 Map::lemma_prefixed_entries_union,
790}
791
792pub proof fn lemma_values_finite<K, V>(m: Map<K, V>)
793 requires
794 m.dom().finite(),
795 ensures
796 m.values().finite(),
797 decreases m.len(),
798{
799 if m.len() > 0 {
800 let k = m.dom().choose();
801 let v = m[k];
802 let m1 = m.remove(k);
803 assert(m.contains_key(k));
804 assert(m.contains_value(v));
805 let mv = m.values();
806 let m1v = m1.values();
807 assert_sets_equal!(mv == m1v.insert(v), v0 => {
808 if m.contains_value(v0) {
809 if v0 != v {
810 let k0 = choose|k0| #![auto] m.contains_key(k0) && m[k0] == v0;
811 assert(k0 != k);
812 assert(m1.contains_key(k0));
813 assert(mv.contains(v0) ==> m1v.insert(v).contains(v0));
814 assert(mv.contains(v0) <== m1v.insert(v).contains(v0));
815 }
816 }
817 });
818 assert(m1.len() < m.len());
819 lemma_values_finite(m1);
820 axiom_set_insert_finite(m1.values(), v);
821 } else {
822 assert(m.values() =~= Set::<V>::empty());
823 }
824}
825
826}