1use vstd::prelude::*;
3use vstd::{map::*, set::*};
4
5verus! {
6
7broadcast use {group_map_axioms, group_set_axioms};
8
9pub broadcast proof fn lemma_map_remove_keys_finite<K, V>(m: Map<K, V>, keys: Set<K>)
10 requires
11 m.dom().finite(),
12 keys.finite(),
13 ensures
14 (#[trigger] m.remove_keys(keys)).dom().finite(),
15{
16 assert(m.remove_keys(keys).dom() =~= m.dom().difference(keys));
17}
18
19pub broadcast group group_map_remove_keys_lemmas {
20 lemma_map_remove_keys_finite,
21}
22
23pub proof fn lemma_map_insert_len<K, V>(m: Map<K, V>, k: K, v: V)
27 requires
28 m.dom().finite(),
29 ensures
30 #[trigger] m.insert(k, v).len() == m.len() + (if m.contains_key(k) {
31 0int
32 } else {
33 1
34 }),
35{
36 axiom_map_insert_domain(m, k, v)
37}
38
39pub proof fn lemma_map_remove_len<K, V>(m: Map<K, V>, k: K)
43 requires
44 m.dom().finite(),
45 ensures
46 m.len() == #[trigger] m.remove(k).len() + (if m.contains_key(k) {
47 1
48 } else {
49 0int
50 }),
51{
52 axiom_map_remove_domain(m, k)
53}
54
55pub open spec fn value_filter<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool) -> Map<K, V> {
57 m.restrict(m.dom().filter(|s| f(m[s])))
58}
59
60pub open spec fn value_filter_choose<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool) -> K {
61 choose|k: K| value_filter(m, f).contains_key(k)
62}
63
64pub broadcast group group_value_filter_lemmas {
65 lemma_value_filter_finite,
66 lemma_value_filter_choose,
67 lemma_insert_value_filter_same_len,
68 lemma_insert_value_filter_different_len_contains,
69 lemma_insert_value_filter_different_len_not_contains,
70}
71
72pub broadcast proof fn lemma_value_filter_finite<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool)
74 requires
75 m.dom().finite(),
76 ensures
77 #[trigger] value_filter(m, f).dom().finite(),
78{
79 assert(value_filter(m, f).dom() == m.dom().filter(|s| f(m[s])));
80 m.dom().lemma_len_filter(|s| f(m[s]));
81}
82
83pub proof fn lemma_value_filter_contains<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K)
87 requires
88 m.contains_key(k),
89 ensures
90 if f(m[k]) {
91 value_filter(m, f).contains_key(k)
92 } else {
93 !value_filter(m, f).contains_key(k)
94 },
95{
96}
97
98pub proof fn lemma_value_filter_all_true<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool)
101 requires
102 forall|k: K| m.contains_key(k) ==> #[trigger] f(m[k]),
103 ensures
104 value_filter(m, f) =~= m,
105{
106}
107
108pub proof fn lemma_value_filter_all_false<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool)
111 ensures
112 value_filter(m, f).is_empty() <==> forall|k: K| m.contains_key(k) ==> !#[trigger] f(m[k]),
113{
114 if value_filter(m, f).is_empty() {
115 assert forall|k: K| m.contains_key(k) implies !#[trigger] f(m[k]) by {
116 if f(m[k]) {
117 assert(value_filter(m, f).contains_key(k));
118 }
119 }
120 }
121}
122
123pub proof fn lemma_remove_value_filter_true<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K)
127 requires
128 f(m[k]),
129 ensures
130 value_filter(m.remove(k), f) =~= value_filter(m, f).remove(k),
131{
132}
133
134pub proof fn lemma_remove_value_filter_false<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K)
138 requires
139 !f(m[k]),
140 ensures
141 value_filter(m.remove(k), f) =~= value_filter(m, f),
142{
143}
144
145pub proof fn lemma_insert_value_filter_true<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K, v: V)
150 requires
151 f(v),
152 ensures
153 value_filter(m.insert(k, v), f) =~= value_filter(m, f).insert(k, v),
154{
155}
156
157pub proof fn lemma_insert_value_filter_false<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K, v: V)
163 requires
164 !f(v),
165 ensures
166 value_filter(m.insert(k, v), f) =~= if m.contains_key(k) {
167 value_filter(m, f).remove(k)
168 } else {
169 value_filter(m, f)
170 },
171 value_filter(m.insert(k, v), f) =~= if m.contains_key(k) {
172 value_filter(m, f).remove(k)
173 } else {
174 value_filter(m, f)
175 },
176{
177}
178
179pub broadcast proof fn lemma_insert_value_filter_same_len<K, V>(
184 m: Map<K, V>,
185 f: spec_fn(V) -> bool,
186 k: K,
187 v: V,
188)
189 requires
190 m.dom().finite(),
191 m.contains_key(k) && f(m[k]) == f(v) || !m.contains_key(k) && !f(v),
192 ensures
193 #[trigger] value_filter(m.insert(k, v), f).len() == value_filter(m, f).len(),
194{
195 lemma_value_filter_finite(m, f);
196 if f(v) {
197 lemma_insert_value_filter_true(m, f, k, v);
198 lemma_map_insert_len(value_filter(m, f), k, v);
199 } else {
200 lemma_insert_value_filter_false(m, f, k, v);
201 lemma_map_remove_len(value_filter(m, f), k);
202 }
203}
204
205pub broadcast proof fn lemma_insert_value_filter_different_len_contains<K, V>(
210 m: Map<K, V>,
211 f: spec_fn(V) -> bool,
212 k: K,
213 v: V,
214)
215 requires
216 m.dom().finite(),
217 m.contains_key(k),
218 f(m[k]) != f(v),
219 ensures
220 #[trigger] value_filter(m.insert(k, v), f).len() == value_filter(m, f).len() + if f(v) {
221 1
222 } else {
223 -1
224 },
225{
226 lemma_value_filter_finite(m, f);
227 if f(v) {
228 lemma_insert_value_filter_true(m, f, k, v);
229 lemma_map_insert_len(m, k, v);
230 } else {
231 lemma_insert_value_filter_false(m, f, k, v);
232 assert(value_filter(m.insert(k, v), f).len() == value_filter(m, f).remove(k).len());
233 lemma_map_remove_len(value_filter(m, f), k);
234 }
235}
236
237pub broadcast proof fn lemma_insert_value_filter_different_len_not_contains<K, V>(
241 m: Map<K, V>,
242 f: spec_fn(V) -> bool,
243 k: K,
244 v: V,
245)
246 requires
247 m.dom().finite(),
248 !m.contains_key(k),
249 f(v),
250 ensures
251 #[trigger] value_filter(m.insert(k, v), f).len() == value_filter(m, f).len() + 1,
252{
253 lemma_value_filter_finite(m, f);
254 lemma_insert_value_filter_true(m, f, k, v);
255 lemma_map_insert_len(m, k, v);
256}
257
258pub proof fn lemma_value_filter_contains_key<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K)
259 requires
260 value_filter(m, f).contains_key(k),
261 ensures
262 m.contains_key(k),
263{
264}
265
266pub broadcast proof fn lemma_value_filter_choose<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool)
267 requires
268 value_filter(m, f).len() != 0,
269 ensures
270 value_filter(m, f).contains_key(#[trigger] value_filter_choose(m, f)),
271 f(m[value_filter_choose(m, f)]),
272{
273 if value_filter(m, f).dom().finite() {
274 axiom_set_choose_len(value_filter(m, f).dom());
275 } else {
276 axiom_set_choose_infinite(value_filter(m, f).dom());
277 }
278}
279
280pub axiom fn tracked_borrow_mut<K, V>(
290 tracked m: &mut Map<K, V>,
291 key: K,
292) -> (tracked v: &mut V)
293 requires
294 old(m).dom().contains(key),
295 ensures
296 *v === old(m).index(key),
297 final(m).dom() === old(m).dom(),
298 forall|k: K| k != key ==> #[trigger] final(m).index(k) === old(m).index(k),
299 final(m).index(key) === *final(v);
300
301pub axiom fn tracked_borrow_mut_points_to<K, R, T: crate::cast_ptr::Repr<R>>(
305 tracked m: &mut Map<K, crate::cast_ptr::PointsTo<R, T>>,
306 key: K,
307) -> (tracked v: &mut crate::cast_ptr::PointsTo<R, T>)
308 requires
309 old(m).dom().contains(key),
310 ensures
311 *v === old(m).index(key),
312 v.pptr() === old(m).index(key).pptr(),
315 v.addr() === old(m).index(key).addr(),
316 v.is_init() == old(m).index(key).is_init(),
317 v.wf(&v.inner_perms) == old(m).index(key).wf(&old(m).index(key).inner_perms),
318 v.inner_perms === old(m).index(key).inner_perms,
319 final(m).dom() === old(m).dom(),
320 forall|k: K| k != key ==> #[trigger] final(m).index(k) === old(m).index(k),
321 final(m).index(key) === *final(v),
322 final(m).index(key).pptr() === final(v).pptr(),
323 final(m).index(key).is_init() == final(v).is_init(),
324 final(m).index(key).wf(&final(v).inner_perms)
325 == final(v).wf(&final(v).inner_perms);
326
327} verus! {
329
330pub open spec fn forall_map<K, V>(map: Map<K, V>, f: spec_fn(K, V) -> bool) -> bool {
332 forall|k| #[trigger] map.contains_key(k) ==> f(k, map[k])
333}
334
335pub open spec fn forall_map_values<K, V>(map: Map<K, V>, f: spec_fn(V) -> bool) -> bool {
337 forall|k| #[trigger] map.contains_key(k) ==> f(map[k])
338}
339
340pub broadcast group group_forall_map_lemmas {
341 lemma_forall_map_insert,
342 lemma_forall_map_values_insert,
343 lemma_forall_map_remove,
344 lemma_forall_map_values_remove,
345}
346
347pub proof fn lemma_forall_map_entry<K, V>(m: Map<K, V>, f: spec_fn(K, V) -> bool, k: K)
349 requires
350 forall_map(m, f),
351 m.contains_key(k),
352 ensures
353 f(k, m[k]),
354{
355}
356
357pub proof fn lemma_forall_map_values_entry<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K)
359 requires
360 forall_map_values(m, f),
361 m.contains_key(k),
362 ensures
363 f(m[k]),
364{
365}
366
367pub broadcast proof fn lemma_forall_map_insert<K, V>(
370 m: Map<K, V>,
371 f: spec_fn(K, V) -> bool,
372 k: K,
373 v: V,
374)
375 ensures
376 #[trigger] forall_map(m.insert(k, v), f) ==> f(k, v) && if m.contains_key(k) {
377 forall_map(m.remove(k), f)
378 } else {
379 forall_map(m, f)
380 },
381{
382 assert(m.insert(k, v).contains_key(k));
383 if m.contains_key(k) {
384 assert(m.insert(k, v) == m.remove(k).insert(k, v));
385 } else {
386 assert(m.insert(k, v) == m.insert(k, v));
387 }
388 if forall_map(m.insert(k, v), f) {
389 if m.contains_key(k) {
390 } else {
391 assert(forall|k0| #[trigger] m.contains_key(k0) ==> m.insert(k, v).contains_key(k0));
392 }
393 }
394}
395
396pub broadcast proof fn lemma_forall_map_values_insert<K, V>(
399 m: Map<K, V>,
400 f: spec_fn(V) -> bool,
401 k: K,
402 v: V,
403)
404 ensures
405 #[trigger] forall_map_values(m.insert(k, v), f) ==> f(v) && if m.contains_key(k) {
406 forall_map_values(m.remove(k), f)
407 } else {
408 forall_map_values(m, f)
409 },
410{
411 assert(m.insert(k, v).contains_key(k));
412 if m.contains_key(k) {
413 assert(m.insert(k, v) == m.remove(k).insert(k, v));
414 } else {
415 assert(m.insert(k, v) == m.insert(k, v));
416 }
417 if forall_map_values(m.insert(k, v), f) {
418 if m.contains_key(k) {
419 } else {
420 assert(forall|k0| #[trigger] m.contains_key(k0) ==> m.insert(k, v).contains_key(k0));
421 }
422 }
423}
424
425pub broadcast proof fn lemma_forall_map_remove<K, V>(m: Map<K, V>, f: spec_fn(K, V) -> bool, k: K)
428 ensures
429 forall_map(m, f) <==> #[trigger] forall_map(m.remove(k), f) && (m.contains_key(k) ==> f(
430 k,
431 m[k],
432 )),
433{
434 if m.contains_key(k) {
435 assert(m == m.remove(k).insert(k, m[k]));
436 } else {
437 assert(m == m.remove(k));
438 }
439}
440
441pub broadcast proof fn lemma_forall_map_values_remove<K, V>(
444 m: Map<K, V>,
445 f: spec_fn(V) -> bool,
446 k: K,
447)
448 ensures
449 forall_map_values(m, f) <==> #[trigger] forall_map_values(m.remove(k), f) && (
450 m.contains_key(k) ==> f(m[k])),
451{
452 if m.contains_key(k) {
453 assert(m == m.remove(k).insert(k, m[k]));
454 } else {
455 assert(m == m.remove(k));
456 }
457
458}
459
460pub open spec fn project_first_key<K1, K2, V>(m: Map<(K1, K2), V>, k1: K1) -> Map<K2, V> {
463 Map::new(|k2: K2| m.contains_key((k1, k2)), |k2: K2| m[(k1, k2)])
464}
465
466pub open spec fn project_second_key<K1, K2, V>(m: Map<(K1, K2), V>, k2: K2) -> Map<K1, V> {
469 Map::new(|k1: K1| m.contains_key((k1, k2)), |k1: K1| m[(k1, k2)])
470}
471
472pub proof fn lemma_project_first_key_sound<K1, K2, V>(m: Map<(K1, K2), V>, k1: K1)
475 ensures
476 forall|k2: K2|
477 {
478 &&& #[trigger] project_first_key(m, k1).contains_key(k2) <==> m.contains_key(
479 (k1, k2),
480 )
481 &&& project_first_key(m, k1).contains_key(k2) ==> project_first_key(m, k1)[k2]
482 == m[(k1, k2)]
483 },
484{
485}
486
487pub proof fn lemma_project_first_key_value_filter_non_empty<K1, K2, V>(
490 m: Map<(K1, K2), V>,
491 k1: K1,
492 f: spec_fn(V) -> bool,
493)
494 requires
495 value_filter(project_first_key(m, k1), f).len() != 0,
496 ensures
497 exists|k2: K2| #[trigger]
498 project_first_key(m, k1).contains_key(k2) && f(project_first_key(m, k1)[k2]),
499{
500 lemma_value_filter_choose(project_first_key(m, k1), f);
501 let k2 = value_filter_choose(project_first_key(m, k1), f);
502 assert(project_first_key(m, k1).contains_key(k2) && f(m[(k1, k2)]));
503}
504
505pub proof fn lemma_project_first_key_value_filter_empty<K1, K2, V>(
506 m: Map<(K1, K2), V>,
507 k1: K1,
508 f: spec_fn(V) -> bool,
509)
510 requires
511 m.dom().finite(),
512 value_filter(project_first_key(m, k1), f).len() == 0,
513 ensures
514 forall|k2: K2| #[trigger]
515 project_first_key(m, k1).contains_key(k2) ==> !f(project_first_key(m, k1)[k2]),
516{
517 assert forall|k2: K2| #[trigger] project_first_key(m, k1).contains_key(k2) implies !f(
518 project_first_key(m, k1)[k2],
519 ) by {
520 if f(project_first_key(m, k1)[k2]) {
521 assert(value_filter(project_first_key(m, k1), f).dom().contains(k2));
522 lemma_project_first_key_finite(m, k1);
523 lemma_value_filter_finite(project_first_key(m, k1), f);
524 Set::lemma_len0_is_empty(value_filter(project_first_key(m, k1), f).dom());
525 assert(false);
526 }
527 }
528}
529
530pub proof fn lemma_project_first_key_finite<K1, K2, V>(m: Map<(K1, K2), V>, k1: K1)
532 requires
533 m.dom().finite(),
534 ensures
535 project_first_key(m, k1).dom().finite(),
536 decreases m.dom().len(),
537{
538 if m.dom().len() == 0 {
539 assert(project_first_key(m, k1).dom() == Set::<K2>::empty());
540 } else {
541 let pair = m.dom().choose();
542 lemma_project_first_key_finite(m.remove(pair), k1);
543 if pair.0 != k1 {
544 assert(project_first_key(m, k1) == project_first_key(m.remove(pair), k1));
545 } else {
546 assert(project_first_key(m, k1).dom() == project_first_key(
547 m.remove(pair),
548 k1,
549 ).dom().insert(pair.1));
550 }
551 }
552}
553
554}