1#[allow(unused_imports)]
2use super::iset::*;
3#[allow(unused_imports)]
4use super::multiset::Multiset;
5#[allow(unused_imports)]
6use super::pervasive::*;
7use super::prelude::Seq;
8#[allow(unused_imports)]
9use super::prelude::*;
10#[allow(unused_imports)]
11use super::relations::*;
12#[allow(unused_imports)]
13use super::set::*;
14
15verus! {
16
17broadcast use {super::iset::group_iset_lemmas, super::set::group_set_lemmas};
18
19impl<A> Set<A> {
20 pub open spec fn is_empty(self) -> (b: bool) {
22 self =~= Set::<A>::empty()
23 }
24
25 pub closed spec fn map<B>(self, f: spec_fn(A) -> B) -> Set<B> {
27 Set::new_from_iset(self.to_iset().map(f)).unwrap()
28 }
29
30 pub broadcast proof fn lemma_map_contains<B>(self, f: spec_fn(A) -> B, b: B)
33 ensures
34 #[trigger] self.map(f).contains(b) <==> exists|a: A| self.contains(a) && b == f(a),
35 {
36 self.to_iset().lemma_map_finite(f);
37 }
38
39 pub closed spec fn map_by<B>(self, fwd: spec_fn(A) -> B, rev: spec_fn(B) -> A) -> Set<B>
52 recommends
53 forall|a: A| self.contains(a) ==> rev(fwd(a)) == a,
54 {
55 Set::new_from_iset(self.to_iset().map_by(fwd, rev)).unwrap()
56 }
57
58 pub broadcast proof fn lemma_map_by_contains<B>(
61 self,
62 fwd: spec_fn(A) -> B,
63 rev: spec_fn(B) -> A,
64 b: B,
65 )
66 ensures
67 #[trigger] self.map_by(fwd, rev).contains(b) <==> self.contains(rev(b)) && b == fwd(
68 rev(b),
69 ),
70 decreases self.len(),
71 {
72 self.to_iset().lemma_map_by_finite(fwd, rev);
73 }
74
75 pub closed spec fn map_flatten_by<B>(
81 self,
82 fwd: spec_fn(A) -> Set<B>,
83 rev: spec_fn(B) -> A,
84 ) -> Set<B>
85 recommends
86 forall|a: A, b: B| #[trigger]
87 self.contains(a) && fwd(a).contains(b) ==> #[trigger] rev(b) == a,
88 {
89 Set::new(|b: B| self.contains(rev(b)) && fwd(rev(b)).contains(b)).unwrap()
90 }
91
92 proof fn lemma_map_flatten_by_finite<B>(self, fwd: spec_fn(A) -> Set<B>, rev: spec_fn(B) -> A)
95 requires
96 forall|a: A, b: B| #[trigger]
97 self.contains(a) && fwd(a).contains(b) ==> #[trigger] rev(b) == a,
98 ensures
99 ISet::new(|b: B| self.contains(rev(b)) && fwd(rev(b)).contains(b)).finite(),
100 decreases self.len(),
101 {
102 let map_f = |b: B| self.contains(rev(b)) && fwd(rev(b)).contains(b);
103 if self == Self::empty() {
104 assert(ISet::<B>::new(map_f) =~= ISet::<B>::empty());
105 } else {
106 lemma_set_is_empty(self);
107 let a: A = choose|a: A| self.contains(a);
108 self.remove(a).lemma_map_flatten_by_finite(fwd, rev);
109 let map_remove_f = |b: B| self.remove(a).contains(rev(b)) && fwd(rev(b)).contains(b);
110 assert(ISet::<B>::new(map_f) =~= ISet::<B>::new(map_remove_f).union(fwd(a).to_iset()));
111 lemma_to_iset_finite(fwd(a));
112 }
113 }
114
115 pub broadcast proof fn lemma_map_flatten_by_contains<B>(
118 self,
119 fwd: spec_fn(A) -> Set<B>,
120 rev: spec_fn(B) -> A,
121 b: B,
122 )
123 requires
124 forall|a: A, b: B| #[trigger]
125 self.contains(a) && fwd(a).contains(b) ==> #[trigger] rev(b) == a,
126 ensures
127 #[trigger] self.map_flatten_by(fwd, rev).contains(b) <==> self.contains(rev(b)) && fwd(
128 rev(b),
129 ).contains(b),
130 decreases self.len(),
131 {
132 self.lemma_map_flatten_by_finite(fwd, rev);
133 }
134
135 pub proof fn map_flatten_by_is_map_flatten<B>(
138 self,
139 fwd: spec_fn(A) -> Set<B>,
140 rev: spec_fn(B) -> A,
141 )
142 requires
143 forall|a: A, b: B| #[trigger]
144 self.contains(a) && fwd(a).contains(b) ==> #[trigger] rev(b) == a,
145 ensures
146 self.map_flatten_by(fwd, rev) == self.map(fwd).flatten(),
147 {
148 broadcast use Set::lemma_flatten_contains;
149 broadcast use Set::lemma_map_flatten_by_contains;
150 broadcast use Set::lemma_map_contains;
151
152 self.lemma_map_flatten_by_finite(fwd, rev);
153 assert forall|b: B| self.map_flatten_by(fwd, rev).contains(b) implies #[trigger] self.map(
154 fwd,
155 ).flatten().contains(b) by {
156 let bs = choose|bs: Set<B>|
157 (exists|a: A| self.contains(a) && bs == fwd(a)) && #[trigger] bs.contains(b);
158 assert(self.map(fwd).contains(bs) <==> (exists|a: A| self.contains(a) && bs == fwd(a)));
159 }
160 }
161
162 pub open spec fn to_seq(self) -> Seq<A>
164 decreases self.len(),
165 {
166 if self.len() == 0 {
167 Seq::<A>::empty()
168 } else {
169 let x = self.choose();
170 Seq::<A>::empty().push(x) + self.remove(x).to_seq()
171 }
172 }
173
174 pub open spec fn to_sorted_seq(self, leq: spec_fn(A, A) -> bool) -> Seq<A> {
176 self.to_seq().sort_by(leq)
177 }
178
179 pub open spec fn is_singleton(self) -> bool {
181 &&& self.len() > 0
182 &&& (forall|x: A, y: A| self.contains(x) && self.contains(y) ==> x == y)
183 }
184
185 pub open spec fn injective_on<B>(self, r: spec_fn(A) -> B) -> bool {
189 self.to_iset().injective_on(r)
190 }
191
192 pub open spec fn has_least(self, leq: spec_fn(A, A) -> bool, min: A) -> bool {
195 self.to_iset().has_least(leq, min)
196 }
197
198 pub open spec fn has_minimum(self, leq: spec_fn(A, A) -> bool, min: A) -> bool {
200 self.to_iset().has_minimum(leq, min)
201 }
202
203 pub open spec fn has_greatest(self, leq: spec_fn(A, A) -> bool, max: A) -> bool {
206 self.to_iset().has_greatest(leq, max)
207 }
208
209 pub open spec fn has_maximum(self, leq: spec_fn(A, A) -> bool, max: A) -> bool {
211 self.to_iset().has_maximum(leq, max)
212 }
213
214 pub proof fn lemma_injective_on_subset<B>(self, r: spec_fn(A) -> B, other: Self)
216 requires
217 other <= self,
218 self.injective_on(r),
219 ensures
220 other.injective_on(r),
221 {
222 self.to_iset().lemma_injective_on_subset(r, other.to_iset());
223 }
224
225 pub closed spec fn find_unique_minimal(self, r: spec_fn(A, A) -> bool) -> A
228 recommends
229 total_ordering(r),
230 self.len() > 0,
231 decreases self.len(),
232 {
233 self.to_iset().find_unique_minimal(r)
234 }
235
236 pub proof fn find_unique_minimal_ensures(self, r: spec_fn(A, A) -> bool)
238 requires
239 self.len() > 0,
240 total_ordering(r),
241 ensures
242 self.has_minimum(r, self.find_unique_minimal(r)) && (forall|min: A|
243 self.has_minimum(r, min) ==> self.find_unique_minimal(r) == min),
244 {
245 self.to_iset().find_unique_minimal_ensures(r);
246 }
247
248 pub closed spec fn find_unique_maximal(self, r: spec_fn(A, A) -> bool) -> A
251 recommends
252 total_ordering(r),
253 self.len() > 0,
254 {
255 self.to_iset().find_unique_maximal(r)
256 }
257
258 pub proof fn find_unique_maximal_ensures(self, r: spec_fn(A, A) -> bool)
260 requires
261 self.len() > 0,
262 total_ordering(r),
263 ensures
264 self.has_maximum(r, self.find_unique_maximal(r)) && (forall|max: A|
265 self.has_maximum(r, max) ==> self.find_unique_maximal(r) == max),
266 {
267 self.to_iset().find_unique_maximal_ensures(r);
268 }
269
270 pub open spec fn to_multiset(self) -> Multiset<A>
273 decreases self.len(),
274 {
275 if self.len() == 0 {
276 Multiset::<A>::empty()
277 } else {
278 Multiset::<A>::empty().insert(self.choose()).add(
279 self.remove(self.choose()).to_multiset(),
280 )
281 }
282 }
283
284 pub proof fn lemma_len0_is_empty(self)
286 requires
287 self.len() == 0,
288 ensures
289 self == Set::<A>::empty(),
290 {
291 if exists|a: A| self.contains(a) {
292 assert(self.remove(self.choose()).len() + 1 == 0);
294 }
295 assert(self =~= Set::empty());
296 }
297
298 pub proof fn lemma_singleton_size(self)
300 requires
301 self.is_singleton(),
302 ensures
303 self.len() == 1,
304 {
305 broadcast use group_set_properties;
306
307 assert(self.remove(self.choose()) =~= Set::empty());
308 }
309
310 pub proof fn lemma_is_singleton(s: Set<A>)
312 ensures
313 s.is_singleton() == (s.len() == 1),
314 {
315 if s.is_singleton() {
316 s.lemma_singleton_size();
317 }
318 if s.len() == 1 {
319 assert forall|x: A, y: A| s.contains(x) && s.contains(y) implies x == y by {
320 let x = choose|x: A| s.contains(x);
321 broadcast use group_set_properties;
322
323 assert(s.remove(x).len() == 0);
324 assert(s.insert(x) =~= s);
325 }
326 }
327 }
328
329 pub proof fn lemma_len_filter(self, f: spec_fn(A) -> bool)
331 ensures
332 self.filter(f).len() <= self.len(),
333 decreases self.len(),
334 {
335 if self.is_empty() {
336 assert(self.filter(f) =~= self);
337 } else {
338 let a = self.choose();
339 assert(self.filter(f).remove(a) =~= self.remove(a).filter(f));
340 self.remove(a).lemma_len_filter(f);
341 }
342 }
343
344 pub proof fn lemma_greatest_implies_maximal(self, r: spec_fn(A, A) -> bool, max: A)
346 requires
347 pre_ordering(r),
348 ensures
349 self.has_greatest(r, max) ==> self.has_maximum(r, max),
350 {
351 }
352
353 pub proof fn lemma_least_implies_minimal(self, r: spec_fn(A, A) -> bool, min: A)
355 requires
356 pre_ordering(r),
357 ensures
358 self.has_least(r, min) ==> self.has_minimum(r, min),
359 {
360 }
361
362 pub proof fn lemma_maximal_equivalent_greatest(self, r: spec_fn(A, A) -> bool, max: A)
364 requires
365 total_ordering(r),
366 ensures
367 self.has_greatest(r, max) <==> self.has_maximum(r, max),
368 {
369 self.to_iset().lemma_maximal_equivalent_greatest(r, max);
370 }
371
372 pub proof fn lemma_minimal_equivalent_least(self, r: spec_fn(A, A) -> bool, min: A)
374 requires
375 total_ordering(r),
376 ensures
377 self.has_least(r, min) <==> self.has_minimum(r, min),
378 {
379 self.to_iset().lemma_minimal_equivalent_least(r, min);
380 }
381
382 pub proof fn lemma_least_is_unique(self, r: spec_fn(A, A) -> bool)
384 requires
385 partial_ordering(r),
386 ensures
387 forall|min: A, min_prime: A|
388 self.has_least(r, min) && self.has_least(r, min_prime) ==> min == min_prime,
389 {
390 self.to_iset().lemma_least_is_unique(r);
391 }
392
393 pub proof fn lemma_greatest_is_unique(self, r: spec_fn(A, A) -> bool)
395 requires
396 partial_ordering(r),
397 ensures
398 forall|max: A, max_prime: A|
399 self.has_greatest(r, max) && self.has_greatest(r, max_prime) ==> max == max_prime,
400 {
401 self.to_iset().lemma_greatest_is_unique(r);
402 }
403
404 pub proof fn lemma_minimal_is_unique(self, r: spec_fn(A, A) -> bool)
406 requires
407 total_ordering(r),
408 ensures
409 forall|min: A, min_prime: A|
410 self.has_minimum(r, min) && self.has_minimum(r, min_prime) ==> min == min_prime,
411 {
412 self.to_iset().lemma_minimal_is_unique(r);
413 }
414
415 pub proof fn lemma_maximal_is_unique(self, r: spec_fn(A, A) -> bool)
417 requires
418 total_ordering(r),
419 ensures
420 forall|max: A, max_prime: A|
421 self.has_maximum(r, max) && self.has_maximum(r, max_prime) ==> max == max_prime,
422 {
423 self.to_iset().lemma_maximal_is_unique(r);
424 }
425
426 pub broadcast proof fn lemma_set_insert_diff_decreases(self, s: Set<A>, elt: A)
430 requires
431 self.contains(elt),
432 !s.contains(elt),
433 ensures
434 #[trigger] self.difference(s.insert(elt)).len() < self.difference(s).len(),
435 {
436 self.difference(s.insert(elt)).lemma_subset_not_in_lt(self.difference(s), elt);
437 }
438
439 pub proof fn lemma_subset_not_in_lt(self: Set<A>, s2: Set<A>, elt: A)
441 requires
442 self.subset_of(s2),
443 !self.contains(elt),
444 s2.contains(elt),
445 ensures
446 self.len() < s2.len(),
447 {
448 let s2_no_elt = s2.remove(elt);
449 assert(self.len() <= s2_no_elt.len()) by {
450 lemma_len_subset(self, s2_no_elt);
451 }
452 }
453
454 pub broadcast proof fn lemma_set_map_insert_commute<B>(self, elt: A, f: spec_fn(A) -> B)
456 ensures
457 #[trigger] self.insert(elt).map(f) =~= self.map(f).insert(f(elt)),
458 {
459 broadcast use Set::lemma_map_contains;
460
461 assert forall|x: B| self.map(f).insert(f(elt)).contains(x) implies self.insert(elt).map(
462 f,
463 ).contains(x) by {
464 if x == f(elt) {
465 assert(self.insert(elt).contains(elt));
466 } else {
467 let y = choose|y: A| self.contains(y) && f(y) == x;
468 assert(self.insert(elt).contains(y));
469 }
470 }
471 }
472
473 pub proof fn lemma_map_union_commute<B>(self, t: Set<A>, f: spec_fn(A) -> B)
475 ensures
476 (self.union(t)).map(f) =~= self.map(f).union(t.map(f)),
477 {
478 broadcast use Set::lemma_map_contains;
479
480 let lhs = self.union(t).map(f);
481 let rhs = self.map(f).union(t.map(f));
482
483 assert forall|elem: B| rhs.contains(elem) implies lhs.contains(elem) by {
484 if self.map(f).contains(elem) {
485 let preimage = choose|preimage: A| self.contains(preimage) && f(preimage) == elem;
486 assert(self.union(t).contains(preimage));
487 } else {
488 assert(t.map(f).contains(elem));
489 let preimage = choose|preimage: A| t.contains(preimage) && f(preimage) == elem;
490 assert(self.union(t).contains(preimage));
491 }
492 }
493 }
494
495 pub open spec fn all(&self, pred: spec_fn(A) -> bool) -> bool {
497 forall|x: A| self.contains(x) ==> pred(x)
498 }
499
500 pub open spec fn any(&self, pred: spec_fn(A) -> bool) -> bool {
502 exists|x: A| self.contains(x) && pred(x)
503 }
504
505 pub broadcast proof fn lemma_any_map_preserved_pred<B>(
507 self,
508 p: spec_fn(A) -> bool,
509 q: spec_fn(B) -> bool,
510 f: spec_fn(A) -> B,
511 )
512 requires
513 #[trigger] self.any(p),
514 forall|x: A| #[trigger] p(x) ==> q(f(x)),
515 ensures
516 #[trigger] self.map(f).any(q),
517 {
518 broadcast use Set::lemma_map_contains;
519
520 let x = choose|x: A| self.contains(x) && p(x);
521 assert(self.map(f).contains(f(x)));
522 }
523
524 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Set<B> {
526 self.map(
527 |elem: A|
528 match f(elem) {
529 Option::Some(r) => set!{r},
530 Option::None => set!{},
531 },
532 ).flatten()
533 }
534
535 pub broadcast proof fn lemma_filter_map_insert<B>(
537 s: Set<A>,
538 f: spec_fn(A) -> Option<B>,
539 elem: A,
540 )
541 ensures
542 #[trigger] s.insert(elem).filter_map(f) == (match f(elem) {
543 Some(res) => s.filter_map(f).insert(res),
544 None => s.filter_map(f),
545 }),
546 {
547 broadcast use group_set_lemmas;
548 broadcast use Set::lemma_flatten_contains;
549 broadcast use Set::lemma_map_contains;
550 broadcast use Set::lemma_set_map_insert_commute;
551
552 let lhs = s.insert(elem).filter_map(f);
553 let rhs = match f(elem) {
554 Some(res) => s.filter_map(f).insert(res),
555 None => s.filter_map(f),
556 };
557 let to_set = |elem: A|
558 match f(elem) {
559 Option::Some(r) => set!{r},
560 Option::None => set!{},
561 };
562 assert forall|r: B| #[trigger] lhs.contains(r) implies rhs.contains(r) by {
563 if f(elem) != Some(r) {
564 let orig = choose|orig: A| #[trigger]
565 s.contains(orig) && f(orig) == Option::Some(r);
566 assert(to_set(orig) == set!{r});
567 assert(s.map(to_set).contains(to_set(orig)));
568 }
569 }
570 assert forall|r: B| #[trigger] rhs.contains(r) implies lhs.contains(r) by {
571 if Some(r) == f(elem) {
572 assert(s.insert(elem).map(to_set).contains(to_set(elem)));
573 } else {
574 let orig = choose|orig: A| #[trigger]
575 s.contains(orig) && f(orig) == Option::Some(r);
576 assert(s.insert(elem).map(to_set).contains(to_set(orig)));
577 }
578 }
579 assert(lhs =~= rhs);
580 }
581
582 pub broadcast proof fn lemma_filter_map_union<B>(self, f: spec_fn(A) -> Option<B>, t: Set<A>)
584 ensures
585 #[trigger] self.union(t).filter_map(f) == self.filter_map(f).union(t.filter_map(f)),
586 {
587 broadcast use group_set_lemmas;
588 broadcast use Set::lemma_flatten_contains;
589 broadcast use Set::lemma_map_contains;
590
591 let lhs = self.union(t).filter_map(f);
592 let rhs = self.filter_map(f).union(t.filter_map(f));
593 let to_set = |elem: A|
594 match f(elem) {
595 Option::Some(r) => set!{r},
596 Option::None => set!{},
597 };
598
599 assert forall|elem: B| rhs.contains(elem) implies lhs.contains(elem) by {
600 if self.filter_map(f).contains(elem) {
601 let x = choose|x: A| self.contains(x) && f(x) == Option::Some(elem);
602 assert(self.union(t).contains(x));
603 assert(self.union(t).map(to_set).contains(to_set(x)));
604 }
605 if t.filter_map(f).contains(elem) {
606 let x = choose|x: A| t.contains(x) && f(x) == Option::Some(elem);
607 assert(self.union(t).contains(x));
608 assert(self.union(t).map(to_set).contains(to_set(x)));
609 }
610 }
611 assert forall|elem: B| lhs.contains(elem) implies rhs.contains(elem) by {
612 let x = choose|x: A| self.union(t).contains(x) && f(x) == Option::Some(elem);
613 if self.contains(x) {
614 assert(self.map(to_set).contains(to_set(x)));
615 assert(self.filter_map(f).contains(elem));
616 } else {
617 assert(t.contains(x));
618 assert(t.map(to_set).contains(to_set(x)));
619 assert(t.filter_map(f).contains(elem));
620 }
621 }
622 assert(lhs =~= rhs);
623 }
624
625 pub broadcast proof fn lemma_set_all_subset(self, s2: Set<A>, p: spec_fn(A) -> bool)
629 requires
630 #[trigger] self.subset_of(s2),
631 s2.all(p),
632 ensures
633 #[trigger] self.all(p),
634 {
635 broadcast use group_set_lemmas;
636
637 }
638
639 pub broadcast proof fn lemma_to_seq_to_set_id(self)
641 ensures
642 #[trigger] self.to_seq().to_set() =~= self,
643 decreases self.len(),
644 {
645 broadcast use lemma_set_empty_equivalency_len;
646 broadcast use Seq::to_set_ensures;
647 broadcast use super::seq_lib::group_seq_properties;
648
649 if self.len() == 0 {
650 assert(self.to_seq().to_set() =~= Set::<A>::empty());
651 } else {
652 let elem = self.choose();
653 self.remove(elem).lemma_to_seq_to_set_id();
654 assert(self =~= self.remove(elem).insert(elem));
655 assert(self.to_seq().to_set() =~= self.remove(elem).to_seq().to_set().insert(elem));
656 }
657 }
658}
659
660impl<A> Set<Set<A>> {
661 pub closed spec fn flatten(self) -> Set<A> {
664 Set::new(
665 |elem| exists|elem_s: Set<A>| #[trigger] self.contains(elem_s) && elem_s.contains(elem),
666 ).unwrap()
667 }
668
669 proof fn lemma_flatten_finite(self)
672 ensures
673 ISet::new(
674 |elem|
675 exists|elem_s: Set<A>| #[trigger]
676 self.contains(elem_s) && elem_s.contains(elem),
677 ).finite(),
678 decreases self.len(),
679 {
680 let flatten_f = |elem|
681 exists|elem_s: Set<A>| #[trigger] self.contains(elem_s) && elem_s.contains(elem);
682 if forall|s: Set<A>| !self.contains(s) {
683 assert(self =~= Set::<Set<A>>::empty());
684 assert(ISet::new(flatten_f) =~= ISet::<A>::empty());
685 } else {
686 let s = choose|s: Set<A>| self.contains(s);
687 self.remove(s).lemma_flatten_finite();
688 let flatten_remove_f = |elem|
689 exists|elem_s: Set<A>| #[trigger]
690 self.remove(s).contains(elem_s) && elem_s.contains(elem);
691 assert(s.to_iset().finite());
692 assert(ISet::new(flatten_f) =~= ISet::new(flatten_remove_f).union(s.to_iset()));
693 }
694 }
695
696 pub broadcast proof fn lemma_flatten_contains(self, elem: A)
699 ensures
700 #[trigger] self.flatten().contains(elem) <==> (exists|elem_s: Set<A>| #[trigger]
701 self.contains(elem_s) && elem_s.contains(elem)),
702 {
703 self.lemma_flatten_finite();
704 }
705
706 pub broadcast proof fn flatten_insert_union_commute(self, other: Set<A>)
709 ensures
710 self.flatten().union(other) =~= #[trigger] self.insert(other).flatten(),
711 {
712 broadcast use Set::lemma_flatten_contains;
713 broadcast use Set::lemma_map_contains;
714
715 let lhs = self.flatten().union(other);
716 let rhs = self.insert(other).flatten();
717
718 assert forall|elem: A| lhs.contains(elem) implies rhs.contains(elem) by {
719 if self.flatten().contains(elem) {
720 self.lemma_flatten_contains(elem);
721 let s = choose|s: Set<A>| #[trigger] self.contains(s) && s.contains(elem);
722 assert(self.insert(other).contains(s));
723 assert(s.contains(elem));
724 } else {
725 assert(other.contains(elem));
726 assert(self.insert(other).contains(other));
727 }
728 self.insert(other).lemma_flatten_contains(elem);
729 }
730 }
731}
732
733pub trait FiniteRange: Sized {
734 spec fn in_range(i: Self, lo: Self, hi: Self) -> bool;
735
736 spec fn range_set(lo: Self, hi: Self) -> Set<Self>;
737
738 spec fn range_len(lo: Self, hi: Self) -> nat;
739
740 proof fn range_properties(lo: Self, hi: Self)
741 ensures
742 forall|i: Self| #[trigger]
743 Self::range_set(lo, hi).contains(i) <==> Self::in_range(i, lo, hi),
744 Self::range_set(lo, hi).len() == Self::range_len(lo, hi),
745 ;
746}
747
748pub broadcast proof fn range_set_properties<A: FiniteRange>(lo: A, hi: A)
753 ensures
754 forall|i: A| #[trigger] A::range_set(lo, hi).contains(i) <==> A::in_range(i, lo, hi),
755 (#[trigger] A::range_set(lo, hi)).len() == A::range_len(lo, hi),
756{
757 A::range_properties(lo, hi);
758}
759
760pub trait FiniteFull: Sized {
761 proof fn full_properties()
762 ensures
763 Set::<Self>::full() is Some,
764 ;
765}
766
767pub broadcast proof fn full_set_properties<A: FiniteFull>()
771 ensures
772 #![trigger Set::<A>::full()]
773 Set::<A>::full() is Some,
774{
775 A::full_properties();
776}
777
778impl<A: FiniteRange> Set<A> {
779 #[verifier::inline]
780 pub open spec fn range(lo: A, hi: A) -> Set<A> {
781 A::range_set(lo, hi)
782 }
783
784 #[verifier::inline]
785 pub open spec fn range_inclusive(lo: A, hi: A) -> Set<A> {
786 A::range_set(lo, hi).insert(hi)
787 }
788}
789
790impl<A: FiniteFull> Set<A> {
791 #[verifier::inline]
792 pub open spec fn from_finite_type(f: spec_fn(A) -> bool) -> Set<A> {
793 Set::<A>::full().unwrap().filter(f)
794 }
795}
796
797macro_rules! range_impls {
800 ([$($t:ty)*]) => {
801 $(
802 verus! {
803 impl FiniteRange for $t {
804 open spec fn in_range(i: Self, lo: Self, hi: Self) -> bool {
805 lo <= i < hi
806 }
807 open spec fn range_set(lo: Self, hi: Self) -> Set<Self> {
808 Set::new(|i: Self| Self::in_range(i, lo, hi)).unwrap()
809 }
810 open spec fn range_len(lo: Self, hi: Self) -> nat {
811 if lo <= hi { (hi - lo) as nat } else { 0 }
812 }
813 proof fn range_properties(lo: Self, hi: Self)
814 decreases hi - lo
815 {
816 proof fn range_properties_helper(lo: $t, hi: $t)
817 ensures
818 ISet::<$t>::new(|i: $t| $t::in_range(i, lo, hi)).finite(),
819 decreases
820 hi - lo,
821 {
822 if lo >= hi {
823 assert(ISet::<$t>::new(|i: $t| $t::in_range(i, lo, hi)) =~= ISet::<$t>::empty());
824 }
825 else {
826 let hi_minus_1: $t = (hi - 1) as $t;
827 assert(hi_minus_1 == hi - 1);
828 range_properties_helper(lo, hi_minus_1);
829 assert(ISet::<$t>::new(|i: $t| $t::in_range(i, lo, hi)) =~=
830 ISet::<$t>::new(|i: $t| $t::in_range(i, lo, hi_minus_1)).insert(hi_minus_1));
831 }
832 }
833
834 range_properties_helper(lo, hi);
835 if hi <= lo {
836 assert(Self::range_set(lo, hi) =~= Set::<Self>::empty());
837 } else {
838 let hi1 = (hi - 1) as $t;
839 Self::range_properties(lo, hi1);
840 assert(ISet::new(|i: Self| Self::in_range(i, lo, hi)) =~=
841 ISet::new(|i: Self| Self::in_range(i, lo, hi1)).insert(hi1));
842 assert(Self::range_set(lo, hi) == Self::range_set(lo, hi1).insert(hi1));
843 }
844 }
845 }
846 } )*
848 }
849}
850
851macro_rules! full_impls {
852 ([$($t:ty)*]) => {
853 $(
854 verus! {
855 impl FiniteFull for $t {
856 proof fn full_properties() {
857 proof fn full_properties_helper(lo: $t, hi: $t)
858 requires
859 lo <= hi,
860 ensures
861 ISet::<$t>::new(|a: $t| lo <= a && a <= hi).finite(),
862 decreases
863 hi - lo,
864 {
865 if lo == hi {
866 assert(ISet::<$t>::new(|a: $t| lo <= a && a <= hi) =~= iset![lo]);
867 }
868 else {
869 let hi_minus_1: $t = (hi - 1) as $t;
870 assert(hi_minus_1 == hi - 1);
871 full_properties_helper(lo, hi_minus_1);
872 assert(ISet::<$t>::new(|a: $t| lo <= a && a <= hi) =~=
873 ISet::<$t>::new(|a: $t| lo <= a && a <= hi_minus_1).insert(hi));
874 }
875 }
876
877 full_properties_helper($t::MIN, $t::MAX);
878 assert(ISet::<$t>::new(|a: $t| true) =~=
879 ISet::<$t>::new(|a: $t| $t::MIN <= a && a <= $t::MAX));
880 assert(Set::<$t>::full() is Some);
881 Self::range_properties($t::MIN, $t::MAX);
882 assert(Set::<$t>::full().unwrap() == Set::range_inclusive($t::MIN, $t::MAX));
883 }
884 }
885 } )*
887 }
888}
889
890range_impls!([
892 int nat
893 usize u8 u16 u32 u64 u128
894 isize i8 i16 i32 i64 i128
895]);
896
897full_impls!([
899 usize u8 u16 u32 u64 u128
900 isize i8 i16 i32 i64 i128
901]);
902
903pub proof fn lemma_sets_eq_iff_injective_map_eq<T, S>(s1: Set<T>, s2: Set<T>, f: spec_fn(T) -> S)
905 requires
906 super::relations::injective(f),
907 ensures
908 (s1 == s2) <==> (s1.map(f) == s2.map(f)),
909{
910 broadcast use group_set_lemmas;
911 broadcast use Set::lemma_map_contains;
912
913 if (s1.map(f) == s2.map(f)) {
914 assert(s1.map(f).len() == s2.map(f).len());
915 if !s1.subset_of(s2) {
916 let x = choose|x: T| s1.contains(x) && !s2.contains(x);
917 assert(s1.map(f).contains(f(x)));
918 } else if !s2.subset_of(s1) {
919 let x = choose|x: T| s2.contains(x) && !s1.contains(x);
920 assert(s2.map(f).contains(f(x)));
921 }
922 assert(s1 =~= s2);
923 }
924}
925
926pub proof fn lemma_sets_eq_iff_injective_map_on_eq<T, S>(s1: Set<T>, s2: Set<T>, f: spec_fn(T) -> S)
928 requires
929 (s1 + s2).injective_on(f),
930 ensures
931 (s1 == s2) <==> (s1.map(f) == s2.map(f)),
932{
933 broadcast use group_set_lemmas;
934 broadcast use Set::lemma_map_contains;
935
936 if (s1.map(f) == s2.map(f)) {
937 assert(s1.map(f).len() == s2.map(f).len());
938 if !s1.subset_of(s2) {
939 let x = choose|x: T| s1.contains(x) && !s2.contains(x);
940 assert(s1.map(f).contains(f(x)));
941 } else if !s2.subset_of(s1) {
942 let x = choose|x: T| s2.contains(x) && !s1.contains(x);
943 assert(s2.map(f).contains(f(x)));
944 }
945 assert(s1 =~= s2);
946 }
947}
948
949pub proof fn lemma_len_union<A>(s1: Set<A>, s2: Set<A>)
952 ensures
953 s1.union(s2).len() <= s1.len() + s2.len(),
954 decreases s1.len(),
955{
956 if s1.is_empty() {
957 assert(s1.union(s2) =~= s2);
958 } else {
959 let a = s1.choose();
960 if s2.contains(a) {
961 assert(s1.union(s2) =~= s1.remove(a).union(s2));
962 } else {
963 assert(s1.union(s2).remove(a) =~= s1.remove(a).union(s2));
964 }
965 lemma_len_union::<A>(s1.remove(a), s2);
966 }
967}
968
969pub proof fn lemma_len_union_ind<A>(s1: Set<A>, s2: Set<A>)
972 ensures
973 s1.union(s2).len() >= s1.len(),
974 s1.union(s2).len() >= s2.len(),
975 decreases s2.len(),
976{
977 broadcast use group_set_properties;
978
979 if s2.len() == 0 {
980 } else {
981 let y = choose|y: A| s2.contains(y);
982 if s1.contains(y) {
983 assert(s1.remove(y).union(s2.remove(y)) =~= s1.union(s2).remove(y));
984 lemma_len_union_ind(s1.remove(y), s2.remove(y))
985 } else {
986 assert(s1.union(s2.remove(y)) =~= s1.union(s2).remove(y));
987 lemma_len_union_ind(s1, s2.remove(y))
988 }
989 }
990}
991
992pub proof fn lemma_len_intersect<A>(s1: Set<A>, s2: Set<A>)
994 ensures
995 s1.intersect(s2).len() <= s1.len(),
996 decreases s1.len(),
997{
998 if s1.is_empty() {
999 assert(s1.intersect(s2) =~= s1);
1000 } else {
1001 let a = s1.choose();
1002 assert(s1.intersect(s2).remove(a) =~= s1.remove(a).intersect(s2));
1003 lemma_len_intersect::<A>(s1.remove(a), s2);
1004 }
1005}
1006
1007pub proof fn lemma_len_subset<A>(s1: Set<A>, s2: Set<A>)
1010 requires
1011 s1.subset_of(s2),
1012 ensures
1013 s1.len() <= s2.len(),
1014{
1015 lemma_len_intersect::<A>(s2, s1);
1016 assert(s2.intersect(s1) =~= s1);
1017}
1018
1019pub proof fn lemma_len_difference<A>(s1: Set<A>, s2: Set<A>)
1021 ensures
1022 s1.difference(s2).len() <= s1.len(),
1023 decreases s1.len(),
1024{
1025 if s1.is_empty() {
1026 assert(s1.difference(s2) =~= s1);
1027 } else {
1028 let a = s1.choose();
1029 assert(s1.difference(s2).remove(a) =~= s1.remove(a).difference(s2));
1030 lemma_len_difference::<A>(s1.remove(a), s2);
1031 }
1032}
1033
1034pub open spec fn set_int_range(lo: int, hi: int) -> Set<int> {
1036 Set::<int>::range(lo, hi)
1037}
1038
1039pub proof fn lemma_int_range(lo: int, hi: int)
1042 requires
1043 lo <= hi,
1044 ensures
1045 forall|j: int| set_int_range(lo, hi).contains(j) <==> lo <= j < hi,
1046 set_int_range(lo, hi).len() == hi - lo,
1047 decreases hi - lo,
1048{
1049 broadcast use range_set_properties;
1050
1051}
1052
1053pub proof fn lemma_subset_equality<A>(x: Set<A>, y: Set<A>)
1055 requires
1056 x.subset_of(y),
1057 x.len() == y.len(),
1058 ensures
1059 x =~= y,
1060 decreases x.len(),
1061{
1062 broadcast use group_set_properties;
1063
1064 if x =~= Set::<A>::empty() {
1065 } else {
1066 let e = x.choose();
1067 lemma_subset_equality(x.remove(e), y.remove(e));
1068 }
1069}
1070
1071pub proof fn lemma_map_size<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
1074 requires
1075 x.injective_on(f),
1076 x.map(f) == y,
1077 ensures
1078 x.len() == y.len(),
1079 decreases x.len(),
1080{
1081 broadcast use group_set_properties;
1082 broadcast use Set::lemma_map_contains;
1083
1084 if x.len() == 0 {
1085 if !y.is_empty() {
1086 let e = y.choose();
1087 }
1088 } else {
1089 let a = x.choose();
1090 assert(x.remove(a).map(f) == y.remove(f(a)));
1091 lemma_map_size(x.remove(a), y.remove(f(a)), f);
1092 assert(y == y.remove(f(a)).insert(f(a)));
1093 }
1094}
1095
1096pub proof fn lemma_map_size_bound<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
1099 requires
1100 x.map(f) == y,
1101 ensures
1102 y.len() <= x.len(),
1103 decreases x.len(),
1104{
1105 broadcast use group_set_properties;
1106 broadcast use Set::lemma_map_contains;
1107
1108 if x.is_empty() {
1109 if !y.is_empty() {
1110 let e = y.choose();
1111 }
1112 } else {
1113 let xx = x.choose();
1114 let img = f(xx);
1115 let pre = x.filter(|a: A| f(a) == f(xx));
1116 x.lemma_len_filter(|a: A| f(a) == f(xx));
1117 let wit = choose|a: A| x.contains(a) && f(a) == f(xx);
1118 assert forall|b: B| (#[trigger] y.remove(f(xx)).contains(b)) implies exists|a: A|
1119 x.difference(pre).contains(a) && f(a) == b by {
1120 let pre_wit = choose|a: A| x.contains(a) && f(a) == b;
1121 assert(x.difference(pre).contains(pre_wit));
1122 }
1123
1124 assert(x == x.difference(pre).union(pre));
1125 assert(y == y.remove(f(xx)).insert(f(xx)));
1126 assert(x.difference(pre).map(f) == y.remove(f(xx)));
1127 lemma_map_size_bound(x.difference(pre), y.remove(f(xx)), f);
1128 }
1129}
1130
1131pub broadcast proof fn lemma_set_union_again1<A>(a: Set<A>, b: Set<A>)
1135 ensures
1136 #[trigger] a.union(b).union(b) =~= a.union(b),
1137{
1138}
1139
1140pub broadcast proof fn lemma_set_union_again2<A>(a: Set<A>, b: Set<A>)
1144 ensures
1145 #[trigger] a.union(b).union(a) =~= a.union(b),
1146{
1147}
1148
1149pub broadcast proof fn lemma_set_intersect_again1<A>(a: Set<A>, b: Set<A>)
1153 ensures
1154 #![trigger (a.intersect(b)).intersect(b)]
1155 (a.intersect(b)).intersect(b) =~= a.intersect(b),
1156{
1157}
1158
1159pub broadcast proof fn lemma_set_intersect_again2<A>(a: Set<A>, b: Set<A>)
1163 ensures
1164 #![trigger (a.intersect(b)).intersect(a)]
1165 (a.intersect(b)).intersect(a) =~= a.intersect(b),
1166{
1167}
1168
1169pub broadcast proof fn lemma_set_difference2<A>(s1: Set<A>, s2: Set<A>, a: A)
1172 ensures
1173 #![trigger s1.difference(s2).contains(a)]
1174 s2.contains(a) ==> !s1.difference(s2).contains(a),
1175{
1176}
1177
1178pub broadcast proof fn lemma_set_disjoint<A>(a: Set<A>, b: Set<A>)
1182 ensures
1183 #![trigger (a + b).difference(a)] a.disjoint(b) ==> ((a + b).difference(a) =~= b && (a + b).difference(b) =~= a),
1185{
1186}
1187
1188pub broadcast proof fn lemma_set_empty_equivalency_len<A>(s: Set<A>)
1196 ensures
1197 #![trigger s.len()]
1198 (s.len() == 0 <==> s == Set::<A>::empty()) && (s.len() != 0 ==> exists|x: A| s.contains(x)),
1199{
1200 assert(s.len() == 0 ==> s =~= Set::empty()) by {
1201 if s.len() == 0 {
1202 assert(forall|a: A| !(Set::empty().contains(a)));
1203 assert(Set::<A>::empty().len() == 0);
1204 assert(Set::<A>::empty().len() == s.len());
1205 assert((exists|a: A| s.contains(a)) || (forall|a: A| !s.contains(a)));
1206 if exists|a: A| s.contains(a) {
1207 let a = s.choose();
1208 assert(s.remove(a).len() == s.len() - 1) by {
1209 lemma_set_remove_len(s, a);
1210 }
1211 }
1212 }
1213 }
1214 assert(s.len() == 0 <== s =~= Set::empty());
1215}
1216
1217pub broadcast proof fn lemma_set_disjoint_lens<A>(a: Set<A>, b: Set<A>)
1221 ensures
1222 a.disjoint(b) ==> #[trigger] (a + b).len() == a.len() + b.len(),
1223 decreases a.len(),
1224{
1225 if a.len() == 0 {
1226 lemma_set_empty_equivalency_len(a);
1227 assert(a + b =~= b);
1228 } else {
1229 if a.disjoint(b) {
1230 let x = a.choose();
1231 assert(a.remove(x) + b =~= (a + b).remove(x));
1232 lemma_set_disjoint_lens(a.remove(x), b);
1233 }
1234 }
1235}
1236
1237pub proof fn lemma_set_disjoint_iff_empty_intersection<T>(a: Set<T>, b: Set<T>)
1239 ensures
1240 a.disjoint(b) <==> a.intersect(b).is_empty(),
1241{
1242 broadcast use group_set_properties;
1243
1244 if a.disjoint(b) {
1245 assert(b.disjoint(a));
1246 assert(forall|x: T| a.contains(x) ==> !(a.contains(x) && b.contains(x)));
1247 assert(forall|x: T| b.contains(x) ==> !(a.contains(x) && b.contains(x)));
1248 assert(forall|x: T| !a.intersect(b).contains(x));
1249 }
1250 if a.intersect(b).is_empty() {
1251 assert(forall|x: T| !a.intersect(b).contains(x));
1252 if !a.disjoint(b) {
1253 assert(exists|x: T| a.contains(x) && b.contains(x));
1254 let x = choose|x: T| a.contains(x) && b.contains(x);
1255 assert(a.intersect(b).contains(x));
1256 assert(!a.intersect(b).is_empty());
1257 }
1258 }
1259}
1260
1261pub broadcast proof fn lemma_set_intersect_union_lens<A>(a: Set<A>, b: Set<A>)
1265 ensures
1266 #[trigger] (a + b).len() + #[trigger] a.intersect(b).len() == a.len() + b.len(),
1267 decreases a.len(),
1268{
1269 if a.len() == 0 {
1270 lemma_set_empty_equivalency_len(a);
1271 assert(a + b =~= b);
1272 assert(a.intersect(b) =~= Set::empty());
1273 assert(a.intersect(b).len() == 0);
1274 } else {
1275 let x = a.choose();
1276 lemma_set_intersect_union_lens(a.remove(x), b);
1277 if (b.contains(x)) {
1278 assert(a.remove(x) + b =~= (a + b));
1279 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1280 } else {
1281 assert(a.remove(x) + b =~= (a + b).remove(x));
1282 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1283 }
1284 }
1285}
1286
1287pub broadcast proof fn lemma_set_difference_len<A>(a: Set<A>, b: Set<A>)
1294 ensures
1295 (#[trigger] a.difference(b).len() + b.difference(a).len() + a.intersect(b).len() == (a
1296 + b).len()) && (a.difference(b).len() == a.len() - a.intersect(b).len()),
1297 decreases a.len(),
1298{
1299 if a.len() == 0 {
1300 lemma_set_empty_equivalency_len(a);
1301 assert(a.difference(b) =~= Set::empty());
1302 assert(b.difference(a) =~= b);
1303 assert(a.intersect(b) =~= Set::empty());
1304 assert(a + b =~= b);
1305 } else {
1306 let x = a.choose();
1307 lemma_set_difference_len(a.remove(x), b);
1308 if b.contains(x) {
1309 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1310 assert(a.remove(x).difference(b) =~= a.difference(b));
1311 assert(b.difference(a.remove(x)).remove(x) =~= b.difference(a));
1312 assert(a.remove(x) + b =~= a + b);
1313 } else {
1314 assert(a.remove(x) + b =~= (a + b).remove(x));
1315 assert(a.remove(x).difference(b) =~= a.difference(b).remove(x));
1316 assert(b.difference(a.remove(x)) =~= b.difference(a));
1317 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1318 }
1319 }
1320}
1321
1322pub broadcast group group_set_properties {
1323 lemma_set_union_again1,
1324 lemma_set_union_again2,
1325 lemma_set_intersect_again1,
1326 lemma_set_intersect_again2,
1327 lemma_set_difference2,
1328 lemma_set_disjoint,
1329 lemma_set_disjoint_lens,
1330 lemma_set_intersect_union_lens,
1331 lemma_set_difference_len,
1332 lemma_set_empty_equivalency_len,
1335}
1336
1337pub broadcast proof fn lemma_set_is_empty<A>(s: Set<A>)
1338 requires
1339 !(#[trigger] s.is_empty()),
1340 ensures
1341 exists|a: A| s.contains(a),
1342{
1343 super::iset_lib::axiom_iset_is_empty(s.to_iset());
1344}
1345
1346pub broadcast proof fn lemma_set_is_empty_len0<A>(s: Set<A>)
1347 ensures
1348 #[trigger] s.is_empty() <==> s.len() == 0,
1349{
1350}
1351
1352#[doc(hidden)]
1353#[verifier::inline]
1354pub open spec fn check_argument_is_set<A>(s: Set<A>) -> Set<A> {
1355 s
1356}
1357
1358#[macro_export]
1372macro_rules! assert_sets_equal {
1373 [$($tail:tt)*] => {
1374 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set_lib::assert_sets_equal_internal!($($tail)*))
1375 };
1376}
1377
1378#[macro_export]
1379#[doc(hidden)]
1380macro_rules! assert_sets_equal_internal {
1381 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
1382 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1383 };
1384 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1385 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1386 };
1387 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
1388 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1389 };
1390 (crate::prelude::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1391 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1392 };
1393 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
1394 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1395 };
1396 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1397 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1398 };
1399 ($s1:expr, $s2:expr $(,)?) => {
1400 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, elem => { })
1401 };
1402 ($s1:expr, $s2:expr, $elem:ident $( : $t:ty )? => $bblock:block) => {
1403 #[verifier::spec] let s1 = $crate::vstd::set_lib::check_argument_is_set($s1);
1404 #[verifier::spec] let s2 = $crate::vstd::set_lib::check_argument_is_set($s2);
1405 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
1406 $crate::vstd::prelude::assert_forall_by(|$elem $( : $t )?| {
1407 $crate::vstd::prelude::ensures(
1408 $crate::vstd::prelude::imply(s1.contains($elem), s2.contains($elem))
1409 &&
1410 $crate::vstd::prelude::imply(s2.contains($elem), s1.contains($elem))
1411 );
1412 { $bblock }
1413 });
1414 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
1415 });
1416 }
1417}
1418
1419pub broadcast group group_set_lib_default {
1420 lemma_set_is_empty,
1421 lemma_set_is_empty_len0,
1422 Set::lemma_flatten_contains,
1423 Set::lemma_map_contains,
1424 Set::lemma_map_by_contains,
1425 Set::lemma_map_flatten_by_contains,
1426 range_set_properties,
1427 full_set_properties,
1428}
1429
1430pub use assert_sets_equal_internal;
1431pub use assert_sets_equal;
1432
1433}