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>(tracked m: &mut Map<K, V>, key: K) -> (tracked v: &mut V)
290 requires
291 old(m).dom().contains(key),
292 ensures
293 *v === old(m).index(key),
294 final(m).dom() === old(m).dom(),
295 forall|k: K| k != key ==> #[trigger] final(m).index(k) === old(m).index(k),
296 final(m).index(key) === *final(v),
297;
298
299pub axiom fn tracked_borrow_mut_points_to<K, R, T: crate::cast_ptr::Repr<R>>(
303 tracked m: &mut Map<K, crate::cast_ptr::PointsTo<R, T>>,
304 key: K,
305) -> (tracked v: &mut crate::cast_ptr::PointsTo<R, T>)
306 requires
307 old(m).dom().contains(key),
308 ensures
309 *v === old(m).index(key),
310 v.pptr() === old(m).index(key).pptr(),
313 v.addr() === old(m).index(key).addr(),
314 v.is_init() == old(m).index(key).is_init(),
315 v.wf(&v.inner_perms) == old(m).index(key).wf(&old(m).index(key).inner_perms),
316 v.inner_perms === old(m).index(key).inner_perms,
317 final(m).dom() === old(m).dom(),
318 forall|k: K| k != key ==> #[trigger] final(m).index(k) === old(m).index(k),
319 final(m).index(key) === *final(v),
320 final(m).index(key).pptr() === final(v).pptr(),
321 final(m).index(key).is_init() == final(v).is_init(),
322 final(m).index(key).wf(&final(v).inner_perms) == final(v).wf(&final(v).inner_perms),
323;
324
325} verus! {
327
328pub open spec fn forall_map<K, V>(map: Map<K, V>, f: spec_fn(K, V) -> bool) -> bool {
330 forall|k| #[trigger] map.contains_key(k) ==> f(k, map[k])
331}
332
333pub open spec fn forall_map_values<K, V>(map: Map<K, V>, f: spec_fn(V) -> bool) -> bool {
335 forall|k| #[trigger] map.contains_key(k) ==> f(map[k])
336}
337
338pub broadcast group group_forall_map_lemmas {
339 lemma_forall_map_insert,
340 lemma_forall_map_values_insert,
341 lemma_forall_map_remove,
342 lemma_forall_map_values_remove,
343}
344
345pub proof fn lemma_forall_map_entry<K, V>(m: Map<K, V>, f: spec_fn(K, V) -> bool, k: K)
347 requires
348 forall_map(m, f),
349 m.contains_key(k),
350 ensures
351 f(k, m[k]),
352{
353}
354
355pub proof fn lemma_forall_map_values_entry<K, V>(m: Map<K, V>, f: spec_fn(V) -> bool, k: K)
357 requires
358 forall_map_values(m, f),
359 m.contains_key(k),
360 ensures
361 f(m[k]),
362{
363}
364
365pub broadcast proof fn lemma_forall_map_insert<K, V>(
368 m: Map<K, V>,
369 f: spec_fn(K, V) -> bool,
370 k: K,
371 v: V,
372)
373 ensures
374 #[trigger] forall_map(m.insert(k, v), f) ==> f(k, v) && if m.contains_key(k) {
375 forall_map(m.remove(k), f)
376 } else {
377 forall_map(m, f)
378 },
379{
380 assert(m.insert(k, v).contains_key(k));
381 if m.contains_key(k) {
382 assert(m.insert(k, v) == m.remove(k).insert(k, v));
383 } else {
384 assert(m.insert(k, v) == m.insert(k, v));
385 }
386 if forall_map(m.insert(k, v), f) {
387 if m.contains_key(k) {
388 } else {
389 assert(forall|k0| #[trigger] m.contains_key(k0) ==> m.insert(k, v).contains_key(k0));
390 }
391 }
392}
393
394pub broadcast proof fn lemma_forall_map_values_insert<K, V>(
397 m: Map<K, V>,
398 f: spec_fn(V) -> bool,
399 k: K,
400 v: V,
401)
402 ensures
403 #[trigger] forall_map_values(m.insert(k, v), f) ==> f(v) && if m.contains_key(k) {
404 forall_map_values(m.remove(k), f)
405 } else {
406 forall_map_values(m, f)
407 },
408{
409 assert(m.insert(k, v).contains_key(k));
410 if m.contains_key(k) {
411 assert(m.insert(k, v) == m.remove(k).insert(k, v));
412 } else {
413 assert(m.insert(k, v) == m.insert(k, v));
414 }
415 if forall_map_values(m.insert(k, v), f) {
416 if m.contains_key(k) {
417 } else {
418 assert(forall|k0| #[trigger] m.contains_key(k0) ==> m.insert(k, v).contains_key(k0));
419 }
420 }
421}
422
423pub broadcast proof fn lemma_forall_map_remove<K, V>(m: Map<K, V>, f: spec_fn(K, V) -> bool, k: K)
426 ensures
427 forall_map(m, f) <==> #[trigger] forall_map(m.remove(k), f) && (m.contains_key(k) ==> f(
428 k,
429 m[k],
430 )),
431{
432 if m.contains_key(k) {
433 assert(m == m.remove(k).insert(k, m[k]));
434 } else {
435 assert(m == m.remove(k));
436 }
437}
438
439pub broadcast proof fn lemma_forall_map_values_remove<K, V>(
442 m: Map<K, V>,
443 f: spec_fn(V) -> bool,
444 k: K,
445)
446 ensures
447 forall_map_values(m, f) <==> #[trigger] forall_map_values(m.remove(k), f) && (
448 m.contains_key(k) ==> f(m[k])),
449{
450 if m.contains_key(k) {
451 assert(m == m.remove(k).insert(k, m[k]));
452 } else {
453 assert(m == m.remove(k));
454 }
455
456}
457
458pub open spec fn project_first_key<K1, K2, V>(m: Map<(K1, K2), V>, k1: K1) -> Map<K2, V> {
461 Map::new(|k2: K2| m.contains_key((k1, k2)), |k2: K2| m[(k1, k2)])
462}
463
464pub open spec fn project_second_key<K1, K2, V>(m: Map<(K1, K2), V>, k2: K2) -> Map<K1, V> {
467 Map::new(|k1: K1| m.contains_key((k1, k2)), |k1: K1| m[(k1, k2)])
468}
469
470pub proof fn lemma_project_first_key_sound<K1, K2, V>(m: Map<(K1, K2), V>, k1: K1)
473 ensures
474 forall|k2: K2|
475 {
476 &&& #[trigger] project_first_key(m, k1).contains_key(k2) <==> m.contains_key(
477 (k1, k2),
478 )
479 &&& project_first_key(m, k1).contains_key(k2) ==> project_first_key(m, k1)[k2]
480 == m[(k1, k2)]
481 },
482{
483}
484
485pub proof fn lemma_project_first_key_value_filter_non_empty<K1, K2, V>(
488 m: Map<(K1, K2), V>,
489 k1: K1,
490 f: spec_fn(V) -> bool,
491)
492 requires
493 value_filter(project_first_key(m, k1), f).len() != 0,
494 ensures
495 exists|k2: K2| #[trigger]
496 project_first_key(m, k1).contains_key(k2) && f(project_first_key(m, k1)[k2]),
497{
498 lemma_value_filter_choose(project_first_key(m, k1), f);
499 let k2 = value_filter_choose(project_first_key(m, k1), f);
500 assert(project_first_key(m, k1).contains_key(k2) && f(m[(k1, k2)]));
501}
502
503pub proof fn lemma_project_first_key_value_filter_empty<K1, K2, V>(
504 m: Map<(K1, K2), V>,
505 k1: K1,
506 f: spec_fn(V) -> bool,
507)
508 requires
509 m.dom().finite(),
510 value_filter(project_first_key(m, k1), f).len() == 0,
511 ensures
512 forall|k2: K2| #[trigger]
513 project_first_key(m, k1).contains_key(k2) ==> !f(project_first_key(m, k1)[k2]),
514{
515 assert forall|k2: K2| #[trigger] project_first_key(m, k1).contains_key(k2) implies !f(
516 project_first_key(m, k1)[k2],
517 ) by {
518 if f(project_first_key(m, k1)[k2]) {
519 assert(value_filter(project_first_key(m, k1), f).dom().contains(k2));
520 lemma_project_first_key_finite(m, k1);
521 lemma_value_filter_finite(project_first_key(m, k1), f);
522 Set::lemma_len0_is_empty(value_filter(project_first_key(m, k1), f).dom());
523 assert(false);
524 }
525 }
526}
527
528pub proof fn lemma_project_first_key_finite<K1, K2, V>(m: Map<(K1, K2), V>, k1: K1)
530 requires
531 m.dom().finite(),
532 ensures
533 project_first_key(m, k1).dom().finite(),
534 decreases m.dom().len(),
535{
536 if m.dom().len() == 0 {
537 assert(project_first_key(m, k1).dom() == Set::<K2>::empty());
538 } else {
539 let pair = m.dom().choose();
540 lemma_project_first_key_finite(m.remove(pair), k1);
541 if pair.0 != k1 {
542 assert(project_first_key(m, k1) == project_first_key(m.remove(pair), k1));
543 } else {
544 assert(project_first_key(m, k1).dom() == project_first_key(
545 m.remove(pair),
546 k1,
547 ).dom().insert(pair.1));
548 }
549 }
550}
551
552}