1#[allow(unused_imports)]
2use super::multiset::Multiset;
3#[allow(unused_imports)]
4use super::pervasive::*;
5use super::prelude::Seq;
6#[allow(unused_imports)]
7use super::prelude::*;
8#[allow(unused_imports)]
9use super::relations::*;
10#[allow(unused_imports)]
11use super::set::*;
12
13verus! {
14
15broadcast use super::set::group_set_axioms;
16
17impl<A> Set<A> {
18 pub open spec fn is_full(self) -> bool {
20 self == Set::<A>::full()
21 }
22
23 pub open spec fn is_empty(self) -> (b: bool) {
25 self =~= Set::<A>::empty()
26 }
27
28 pub open spec fn map<B>(self, f: spec_fn(A) -> B) -> Set<B> {
30 Set::new(|a: B| exists|x: A| self.contains(x) && a == f(x))
31 }
32
33 pub open spec fn to_seq(self) -> Seq<A>
35 recommends
36 self.finite(),
37 decreases self.len(),
38 when self.finite()
39 {
40 if self.len() == 0 {
41 Seq::<A>::empty()
42 } else {
43 let x = self.choose();
44 Seq::<A>::empty().push(x) + self.remove(x).to_seq()
45 }
46 }
47
48 pub open spec fn to_sorted_seq(self, leq: spec_fn(A, A) -> bool) -> Seq<A> {
50 self.to_seq().sort_by(leq)
51 }
52
53 pub open spec fn is_singleton(self) -> bool {
55 &&& self.len() > 0
56 &&& (forall|x: A, y: A| self.contains(x) && self.contains(y) ==> x == y)
57 }
58
59 pub closed spec fn find_unique_minimal(self, r: spec_fn(A, A) -> bool) -> A
62 recommends
63 total_ordering(r),
64 self.len() > 0,
65 self.finite(),
66 decreases self.len(),
67 when self.finite()
68 {
69 proof {
70 broadcast use group_set_properties;
71
72 }
73 if self.len() <= 1 {
74 self.choose()
75 } else {
76 let x = choose|x: A| self.contains(x);
77 let min = self.remove(x).find_unique_minimal(r);
78 if r(min, x) {
79 min
80 } else {
81 x
82 }
83 }
84 }
85
86 pub proof fn find_unique_minimal_ensures(self, r: spec_fn(A, A) -> bool)
88 requires
89 self.finite(),
90 self.len() > 0,
91 total_ordering(r),
92 ensures
93 is_minimal(r, self.find_unique_minimal(r), self) && (forall|min: A|
94 is_minimal(r, min, self) ==> self.find_unique_minimal(r) == min),
95 decreases self.len(),
96 {
97 broadcast use group_set_properties;
98
99 if self.len() == 1 {
100 let x = choose|x: A| self.contains(x);
101 assert(self.remove(x).insert(x) =~= self);
102 assert(is_minimal(r, self.find_unique_minimal(r), self));
103 } else {
104 let x = choose|x: A| self.contains(x);
105 self.remove(x).find_unique_minimal_ensures(r);
106 assert(is_minimal(r, self.remove(x).find_unique_minimal(r), self.remove(x)));
107 let y = self.remove(x).find_unique_minimal(r);
108 let min_updated = self.find_unique_minimal(r);
109 assert(!r(y, x) ==> min_updated == x);
110 assert(forall|elt: A|
111 self.remove(x).contains(elt) && #[trigger] r(elt, y) ==> #[trigger] r(y, elt));
112 assert forall|elt: A|
113 self.contains(elt) && #[trigger] r(elt, min_updated) implies #[trigger] r(
114 min_updated,
115 elt,
116 ) by {
117 assert(r(min_updated, x) || r(min_updated, y));
118 if min_updated == y { assert(is_minimal(r, self.find_unique_minimal(r), self));
120 } else { assert(self.remove(x).contains(elt) || elt == x);
122 assert(min_updated == x);
123 assert(r(x, y) || r(y, x));
124 assert(!r(x, y) || !r(y, x));
125 assert(!(min_updated == y) ==> !r(y, x));
126 assert(r(x, y));
127 if (self.remove(x).contains(elt)) {
128 assert(r(elt, y) && r(y, elt) ==> elt == y);
129 } else {
130 }
131 }
132 }
133 assert forall|min_poss: A|
134 is_minimal(r, min_poss, self) implies self.find_unique_minimal(r) == min_poss by {
135 assert(is_minimal(r, min_poss, self.remove(x)) || x == min_poss);
136 assert(r(min_poss, self.find_unique_minimal(r)));
137 }
138 }
139 }
140
141 pub closed spec fn find_unique_maximal(self, r: spec_fn(A, A) -> bool) -> A
144 recommends
145 total_ordering(r),
146 self.len() > 0,
147 decreases self.len(),
148 when self.finite()
149 {
150 proof {
151 broadcast use group_set_properties;
152
153 }
154 if self.len() <= 1 {
155 self.choose()
156 } else {
157 let x = choose|x: A| self.contains(x);
158 let max = self.remove(x).find_unique_maximal(r);
159 if r(x, max) {
160 max
161 } else {
162 x
163 }
164 }
165 }
166
167 pub proof fn find_unique_maximal_ensures(self, r: spec_fn(A, A) -> bool)
169 requires
170 self.finite(),
171 self.len() > 0,
172 total_ordering(r),
173 ensures
174 is_maximal(r, self.find_unique_maximal(r), self) && (forall|max: A|
175 is_maximal(r, max, self) ==> self.find_unique_maximal(r) == max),
176 decreases self.len(),
177 {
178 broadcast use group_set_properties;
179
180 if self.len() == 1 {
181 let x = choose|x: A| self.contains(x);
182 assert(self.remove(x) =~= Set::<A>::empty());
183 assert(self.contains(self.find_unique_maximal(r)));
184 } else {
185 let x = choose|x: A| self.contains(x);
186 self.remove(x).find_unique_maximal_ensures(r);
187 assert(is_maximal(r, self.remove(x).find_unique_maximal(r), self.remove(x)));
188 assert(self.remove(x).insert(x) =~= self);
189 let y = self.remove(x).find_unique_maximal(r);
190 let max_updated = self.find_unique_maximal(r);
191 assert(max_updated == x || max_updated == y);
192 assert(!r(x, y) ==> max_updated == x);
193 assert forall|elt: A|
194 self.contains(elt) && #[trigger] r(max_updated, elt) implies #[trigger] r(
195 elt,
196 max_updated,
197 ) by {
198 assert(r(x, max_updated) || r(y, max_updated));
199 if max_updated == y { assert(r(elt, max_updated));
201 assert(r(x, max_updated));
202 assert(is_maximal(r, self.find_unique_maximal(r), self));
203 } else { assert(self.remove(x).contains(elt) || elt == x);
205 assert(max_updated == x);
206 assert(r(x, y) || r(y, x));
207 assert(!r(x, y) || !r(y, x));
208 assert(!(max_updated == y) ==> !r(x, y));
209 assert(r(y, x));
210 if (self.remove(x).contains(elt)) {
211 assert(r(y, elt) ==> r(elt, y));
212 assert(r(y, elt) && r(elt, y) ==> elt == y);
213 assert(r(elt, x));
214 assert(r(elt, max_updated))
215 } else {
216 }
217 }
218 }
219 assert forall|max_poss: A|
220 is_maximal(r, max_poss, self) implies self.find_unique_maximal(r) == max_poss by {
221 assert(is_maximal(r, max_poss, self.remove(x)) || x == max_poss);
222 assert(r(max_poss, self.find_unique_maximal(r)));
223 assert(r(self.find_unique_maximal(r), max_poss));
224 }
225 }
226 }
227
228 pub open spec fn to_multiset(self) -> Multiset<A>
231 decreases self.len(),
232 when self.finite()
233 {
234 if self.len() == 0 {
235 Multiset::<A>::empty()
236 } else {
237 Multiset::<A>::empty().insert(self.choose()).add(
238 self.remove(self.choose()).to_multiset(),
239 )
240 }
241 }
242
243 pub proof fn lemma_len0_is_empty(self)
245 requires
246 self.finite(),
247 self.len() == 0,
248 ensures
249 self == Set::<A>::empty(),
250 {
251 if exists|a: A| self.contains(a) {
252 assert(self.remove(self.choose()).len() + 1 == 0);
254 }
255 assert(self =~= Set::empty());
256 }
257
258 pub proof fn lemma_singleton_size(self)
260 requires
261 self.is_singleton(),
262 ensures
263 self.len() == 1,
264 {
265 broadcast use group_set_properties;
266
267 assert(self.remove(self.choose()) =~= Set::empty());
268 }
269
270 pub proof fn lemma_is_singleton(s: Set<A>)
272 requires
273 s.finite(),
274 ensures
275 s.is_singleton() == (s.len() == 1),
276 {
277 if s.is_singleton() {
278 s.lemma_singleton_size();
279 }
280 if s.len() == 1 {
281 assert forall|x: A, y: A| s.contains(x) && s.contains(y) implies x == y by {
282 let x = choose|x: A| s.contains(x);
283 broadcast use group_set_properties;
284
285 assert(s.remove(x).len() == 0);
286 assert(s.insert(x) =~= s);
287 }
288 }
289 }
290
291 pub proof fn lemma_len_filter(self, f: spec_fn(A) -> bool)
293 requires
294 self.finite(),
295 ensures
296 self.filter(f).finite(),
297 self.filter(f).len() <= self.len(),
298 decreases self.len(),
299 {
300 lemma_len_intersect::<A>(self, Set::new(f));
301 }
302
303 pub proof fn lemma_greatest_implies_maximal(self, r: spec_fn(A, A) -> bool, max: A)
305 requires
306 pre_ordering(r),
307 ensures
308 is_greatest(r, max, self) ==> is_maximal(r, max, self),
309 {
310 }
311
312 pub proof fn lemma_least_implies_minimal(self, r: spec_fn(A, A) -> bool, min: A)
314 requires
315 pre_ordering(r),
316 ensures
317 is_least(r, min, self) ==> is_minimal(r, min, self),
318 {
319 }
320
321 pub proof fn lemma_maximal_equivalent_greatest(self, r: spec_fn(A, A) -> bool, max: A)
323 requires
324 total_ordering(r),
325 ensures
326 is_greatest(r, max, self) <==> is_maximal(r, max, self),
327 {
328 assert(is_maximal(r, max, self) ==> forall|x: A|
329 !self.contains(x) || !r(max, x) || r(x, max));
330 }
331
332 pub proof fn lemma_minimal_equivalent_least(self, r: spec_fn(A, A) -> bool, min: A)
334 requires
335 total_ordering(r),
336 ensures
337 is_least(r, min, self) <==> is_minimal(r, min, self),
338 {
339 assert(is_minimal(r, min, self) ==> forall|x: A|
340 !self.contains(x) || !r(x, min) || r(min, x));
341 }
342
343 pub proof fn lemma_least_is_unique(self, r: spec_fn(A, A) -> bool)
345 requires
346 partial_ordering(r),
347 ensures
348 forall|min: A, min_prime: A|
349 is_least(r, min, self) && is_least(r, min_prime, self) ==> min == min_prime,
350 {
351 assert forall|min: A, min_prime: A|
352 is_least(r, min, self) && is_least(r, min_prime, self) implies min == min_prime by {
353 assert(r(min, min_prime));
354 assert(r(min_prime, min));
355 }
356 }
357
358 pub proof fn lemma_greatest_is_unique(self, r: spec_fn(A, A) -> bool)
360 requires
361 partial_ordering(r),
362 ensures
363 forall|max: A, max_prime: A|
364 is_greatest(r, max, self) && is_greatest(r, max_prime, self) ==> max == max_prime,
365 {
366 assert forall|max: A, max_prime: A|
367 is_greatest(r, max, self) && is_greatest(r, max_prime, self) implies max
368 == max_prime by {
369 assert(r(max_prime, max));
370 assert(r(max, max_prime));
371 }
372 }
373
374 pub proof fn lemma_minimal_is_unique(self, r: spec_fn(A, A) -> bool)
376 requires
377 total_ordering(r),
378 ensures
379 forall|min: A, min_prime: A|
380 is_minimal(r, min, self) && is_minimal(r, min_prime, self) ==> min == min_prime,
381 {
382 assert forall|min: A, min_prime: A|
383 is_minimal(r, min, self) && is_minimal(r, min_prime, self) implies min == min_prime by {
384 self.lemma_minimal_equivalent_least(r, min);
385 self.lemma_minimal_equivalent_least(r, min_prime);
386 self.lemma_least_is_unique(r);
387 }
388 }
389
390 pub proof fn lemma_maximal_is_unique(self, r: spec_fn(A, A) -> bool)
392 requires
393 self.finite(),
394 total_ordering(r),
395 ensures
396 forall|max: A, max_prime: A|
397 is_maximal(r, max, self) && is_maximal(r, max_prime, self) ==> max == max_prime,
398 {
399 assert forall|max: A, max_prime: A|
400 is_maximal(r, max, self) && is_maximal(r, max_prime, self) implies max == max_prime by {
401 self.lemma_maximal_equivalent_greatest(r, max);
402 self.lemma_maximal_equivalent_greatest(r, max_prime);
403 self.lemma_greatest_is_unique(r);
404 }
405 }
406
407 pub broadcast proof fn lemma_set_insert_diff_decreases(self, s: Set<A>, elt: A)
411 requires
412 self.contains(elt),
413 !s.contains(elt),
414 self.finite(),
415 ensures
416 #[trigger] self.difference(s.insert(elt)).len() < self.difference(s).len(),
417 {
418 self.difference(s.insert(elt)).lemma_subset_not_in_lt(self.difference(s), elt);
419 }
420
421 pub proof fn lemma_subset_not_in_lt(self: Set<A>, s2: Set<A>, elt: A)
423 requires
424 self.subset_of(s2),
425 s2.finite(),
426 !self.contains(elt),
427 s2.contains(elt),
428 ensures
429 self.len() < s2.len(),
430 {
431 let s2_no_elt = s2.remove(elt);
432 assert(self.len() <= s2_no_elt.len()) by {
433 lemma_len_subset(self, s2_no_elt);
434 }
435 }
436
437 pub broadcast proof fn lemma_set_map_insert_commute<B>(self, elt: A, f: spec_fn(A) -> B)
439 ensures
440 #[trigger] self.insert(elt).map(f) =~= self.map(f).insert(f(elt)),
441 {
442 assert forall|x: B| self.map(f).insert(f(elt)).contains(x) implies self.insert(elt).map(
443 f,
444 ).contains(x) by {
445 if x == f(elt) {
446 assert(self.insert(elt).contains(elt));
447 } else {
448 let y = choose|y: A| self.contains(y) && f(y) == x;
449 assert(self.insert(elt).contains(y));
450 }
451 }
452 }
453
454 pub proof fn lemma_map_union_commute<B>(self, t: Set<A>, f: spec_fn(A) -> B)
456 ensures
457 (self.union(t)).map(f) =~= self.map(f).union(t.map(f)),
458 {
459 broadcast use group_set_axioms;
460
461 let lhs = self.union(t).map(f);
462 let rhs = self.map(f).union(t.map(f));
463
464 assert forall|elem: B| rhs.contains(elem) implies lhs.contains(elem) by {
465 if self.map(f).contains(elem) {
466 let preimage = choose|preimage: A| self.contains(preimage) && f(preimage) == elem;
467 assert(self.union(t).contains(preimage));
468 } else {
469 assert(t.map(f).contains(elem));
470 let preimage = choose|preimage: A| t.contains(preimage) && f(preimage) == elem;
471 assert(self.union(t).contains(preimage));
472 }
473 }
474 }
475
476 pub open spec fn all(&self, pred: spec_fn(A) -> bool) -> bool {
478 forall|x: A| self.contains(x) ==> pred(x)
479 }
480
481 pub open spec fn any(&self, pred: spec_fn(A) -> bool) -> bool {
483 exists|x: A| self.contains(x) && pred(x)
484 }
485
486 pub broadcast proof fn lemma_any_map_preserved_pred<B>(
488 self,
489 p: spec_fn(A) -> bool,
490 q: spec_fn(B) -> bool,
491 f: spec_fn(A) -> B,
492 )
493 requires
494 #[trigger] self.any(p),
495 forall|x: A| #[trigger] p(x) ==> q(f(x)),
496 ensures
497 #[trigger] self.map(f).any(q),
498 {
499 let x = choose|x: A| self.contains(x) && p(x);
500 assert(self.map(f).contains(f(x)));
501 }
502
503 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Set<B> {
505 self.map(
506 |elem: A|
507 match f(elem) {
508 Option::Some(r) => set!{r},
509 Option::None => set!{},
510 },
511 ).flatten()
512 }
513
514 pub broadcast proof fn lemma_filter_map_insert<B>(
516 s: Set<A>,
517 f: spec_fn(A) -> Option<B>,
518 elem: A,
519 )
520 ensures
521 #[trigger] s.insert(elem).filter_map(f) == (match f(elem) {
522 Some(res) => s.filter_map(f).insert(res),
523 None => s.filter_map(f),
524 }),
525 {
526 broadcast use group_set_axioms;
527 broadcast use Set::lemma_set_map_insert_commute;
528
529 let lhs = s.insert(elem).filter_map(f);
530 let rhs = match f(elem) {
531 Some(res) => s.filter_map(f).insert(res),
532 None => s.filter_map(f),
533 };
534 let to_set = |elem: A|
535 match f(elem) {
536 Option::Some(r) => set!{r},
537 Option::None => set!{},
538 };
539 assert forall|r: B| #[trigger] lhs.contains(r) implies rhs.contains(r) by {
540 if f(elem) != Some(r) {
541 let orig = choose|orig: A| #[trigger]
542 s.contains(orig) && f(orig) == Option::Some(r);
543 assert(to_set(orig) == set!{r});
544 assert(s.map(to_set).contains(to_set(orig)));
545 }
546 }
547 assert forall|r: B| #[trigger] rhs.contains(r) implies lhs.contains(r) by {
548 if Some(r) == f(elem) {
549 assert(s.insert(elem).map(to_set).contains(to_set(elem)));
550 } else {
551 let orig = choose|orig: A| #[trigger]
552 s.contains(orig) && f(orig) == Option::Some(r);
553 assert(s.insert(elem).map(to_set).contains(to_set(orig)));
554 }
555 }
556 assert(lhs =~= rhs);
557 }
558
559 pub broadcast proof fn lemma_filter_map_union<B>(self, f: spec_fn(A) -> Option<B>, t: Set<A>)
561 ensures
562 #[trigger] self.union(t).filter_map(f) == self.filter_map(f).union(t.filter_map(f)),
563 {
564 broadcast use group_set_axioms;
565
566 let lhs = self.union(t).filter_map(f);
567 let rhs = self.filter_map(f).union(t.filter_map(f));
568 let to_set = |elem: A|
569 match f(elem) {
570 Option::Some(r) => set!{r},
571 Option::None => set!{},
572 };
573
574 assert forall|elem: B| rhs.contains(elem) implies lhs.contains(elem) by {
575 if self.filter_map(f).contains(elem) {
576 let x = choose|x: A| self.contains(x) && f(x) == Option::Some(elem);
577 assert(self.union(t).contains(x));
578 assert(self.union(t).map(to_set).contains(to_set(x)));
579 }
580 if t.filter_map(f).contains(elem) {
581 let x = choose|x: A| t.contains(x) && f(x) == Option::Some(elem);
582 assert(self.union(t).contains(x));
583 assert(self.union(t).map(to_set).contains(to_set(x)));
584 }
585 }
586 assert forall|elem: B| lhs.contains(elem) implies rhs.contains(elem) by {
587 let x = choose|x: A| self.union(t).contains(x) && f(x) == Option::Some(elem);
588 if self.contains(x) {
589 assert(self.map(to_set).contains(to_set(x)));
590 assert(self.filter_map(f).contains(elem));
591 } else {
592 assert(t.contains(x));
593 assert(t.map(to_set).contains(to_set(x)));
594 assert(t.filter_map(f).contains(elem));
595 }
596 }
597 assert(lhs =~= rhs);
598 }
599
600 pub proof fn lemma_map_finite<B>(self, f: spec_fn(A) -> B)
602 requires
603 self.finite(),
604 ensures
605 self.map(f).finite(),
606 decreases self.len(),
607 {
608 broadcast use group_set_axioms;
609 broadcast use lemma_set_empty_equivalency_len;
610
611 if self.len() == 0 {
612 assert(forall|elem: A| !(#[trigger] self.contains(elem)));
613 assert forall|res: B| #[trigger] self.map(f).contains(res) implies false by {
614 let x = choose|x: A| self.contains(x) && f(x) == res;
615 }
616 assert(self.map(f) =~= Set::<B>::empty());
617 } else {
618 let x = choose|x: A| self.contains(x);
619 assert(self.map(f).contains(f(x)));
620 self.remove(x).lemma_map_finite(f);
621 assert(self.remove(x).insert(x) == self);
622 assert(self.map(f) == self.remove(x).map(f).insert(f(x)));
623 }
624 }
625
626 pub broadcast proof fn lemma_set_all_subset(self, s2: Set<A>, p: spec_fn(A) -> bool)
627 requires
628 #[trigger] self.subset_of(s2),
629 s2.all(p),
630 ensures
631 #[trigger] self.all(p),
632 {
633 broadcast use group_set_axioms;
634
635 }
636
637 pub broadcast proof fn lemma_filter_map_finite<B>(self, f: spec_fn(A) -> Option<B>)
639 requires
640 self.finite(),
641 ensures
642 #[trigger] self.filter_map(f).finite(),
643 decreases self.len(),
644 {
645 broadcast use group_set_axioms;
646 broadcast use Set::lemma_filter_map_insert;
647
648 let mapped = self.filter_map(f);
649 if self.len() == 0 {
650 assert(self.filter_map(f) =~= Set::<B>::empty());
651 } else {
652 let elem = self.choose();
653 self.remove(elem).lemma_filter_map_finite(f);
654 assert(self =~= self.remove(elem).insert(elem));
655 }
656 }
657
658 pub broadcast proof fn lemma_to_seq_to_set_id(self)
660 requires
661 self.finite(),
662 ensures
663 #[trigger] self.to_seq().to_set() =~= self,
664 decreases self.len(),
665 {
666 broadcast use group_set_axioms;
667 broadcast use lemma_set_empty_equivalency_len;
668 broadcast use super::seq_lib::group_seq_properties;
669
670 if self.len() == 0 {
671 assert(self.to_seq().to_set() =~= Set::<A>::empty());
672 } else {
673 let elem = self.choose();
674 self.remove(elem).lemma_to_seq_to_set_id();
675 assert(self =~= self.remove(elem).insert(elem));
676 assert(self.to_seq().to_set() =~= self.remove(elem).to_seq().to_set().insert(elem));
677 }
678 }
679}
680
681impl<A> Set<Set<A>> {
682 pub open spec fn flatten(self) -> Set<A> {
683 Set::new(
684 |elem| exists|elem_s: Set<A>| #[trigger] self.contains(elem_s) && elem_s.contains(elem),
685 )
686 }
687
688 pub broadcast proof fn flatten_insert_union_commute(self, other: Set<A>)
689 ensures
690 self.flatten().union(other) =~= #[trigger] self.insert(other).flatten(),
691 {
692 broadcast use group_set_axioms;
693
694 let lhs = self.flatten().union(other);
695 let rhs = self.insert(other).flatten();
696
697 assert forall|elem: A| lhs.contains(elem) implies rhs.contains(elem) by {
698 if exists|s: Set<A>| self.contains(s) && s.contains(elem) {
699 let s = choose|s: Set<A>| self.contains(s) && s.contains(elem);
700 assert(self.insert(other).contains(s));
701 assert(s.contains(elem));
702 } else {
703 assert(self.insert(other).contains(other));
704 }
705 }
706 }
707}
708
709pub proof fn lemma_sets_eq_iff_injective_map_eq<T, S>(s1: Set<T>, s2: Set<T>, f: spec_fn(T) -> S)
711 requires
712 super::relations::injective(f),
713 ensures
714 (s1 == s2) <==> (s1.map(f) == s2.map(f)),
715{
716 broadcast use group_set_axioms;
717
718 if (s1.map(f) == s2.map(f)) {
719 assert(s1.map(f).len() == s2.map(f).len());
720 if !s1.subset_of(s2) {
721 let x = choose|x: T| s1.contains(x) && !s2.contains(x);
722 assert(s1.map(f).contains(f(x)));
723 } else if !s2.subset_of(s1) {
724 let x = choose|x: T| s2.contains(x) && !s1.contains(x);
725 assert(s2.map(f).contains(f(x)));
726 }
727 assert(s1 =~= s2);
728 }
729}
730
731pub broadcast proof fn lemma_set_insert_finite_iff<A>(s: Set<A>, a: A)
733 ensures
734 #[trigger] s.insert(a).finite() <==> s.finite(),
735{
736 if s.insert(a).finite() {
737 if s.contains(a) {
738 assert(s == s.insert(a));
739 } else {
740 assert(s == s.insert(a).remove(a));
741 }
742 }
743 assert(s.insert(a).finite() ==> s.finite());
744}
745
746pub broadcast proof fn lemma_set_remove_finite_iff<A>(s: Set<A>, a: A)
748 ensures
749 #[trigger] s.remove(a).finite() <==> s.finite(),
750{
751 if s.remove(a).finite() {
752 if s.contains(a) {
753 assert(s == s.remove(a).insert(a));
754 } else {
755 assert(s == s.remove(a));
756 }
757 }
758}
759
760pub broadcast proof fn lemma_set_union_finite_iff<A>(s1: Set<A>, s2: Set<A>)
762 ensures
763 #[trigger] s1.union(s2).finite() <==> s1.finite() && s2.finite(),
764{
765 if s1.union(s2).finite() {
766 lemma_set_union_finite_implies_sets_finite(s1, s2);
767 }
768}
769
770pub proof fn lemma_set_union_finite_implies_sets_finite<A>(s1: Set<A>, s2: Set<A>)
771 requires
772 s1.union(s2).finite(),
773 ensures
774 s1.finite(),
775 s2.finite(),
776 decreases s1.union(s2).len(),
777{
778 if s1.union(s2) =~= set![] {
779 assert(s1 =~= set![]);
780 assert(s2 =~= set![]);
781 } else {
782 let a = s1.union(s2).choose();
783 assert(s1.remove(a).union(s2.remove(a)) == s1.union(s2).remove(a));
784 axiom_set_remove_len(s1.union(s2), a);
785 lemma_set_union_finite_implies_sets_finite(s1.remove(a), s2.remove(a));
786 assert(forall|s: Set<A>|
787 #![auto]
788 s.remove(a).insert(a) == if s.contains(a) {
789 s
790 } else {
791 s.insert(a)
792 });
793 lemma_set_insert_finite_iff(s1, a);
794 lemma_set_insert_finite_iff(s2, a);
795 }
796}
797
798pub proof fn lemma_len_union<A>(s1: Set<A>, s2: Set<A>)
801 requires
802 s1.finite(),
803 s2.finite(),
804 ensures
805 s1.union(s2).len() <= s1.len() + s2.len(),
806 decreases s1.len(),
807{
808 if s1.is_empty() {
809 assert(s1.union(s2) =~= s2);
810 } else {
811 let a = s1.choose();
812 if s2.contains(a) {
813 assert(s1.union(s2) =~= s1.remove(a).union(s2));
814 } else {
815 assert(s1.union(s2).remove(a) =~= s1.remove(a).union(s2));
816 }
817 lemma_len_union::<A>(s1.remove(a), s2);
818 }
819}
820
821pub proof fn lemma_len_union_ind<A>(s1: Set<A>, s2: Set<A>)
824 requires
825 s1.finite(),
826 s2.finite(),
827 ensures
828 s1.union(s2).len() >= s1.len(),
829 s1.union(s2).len() >= s2.len(),
830 decreases s2.len(),
831{
832 broadcast use group_set_properties;
833
834 if s2.len() == 0 {
835 } else {
836 let y = choose|y: A| s2.contains(y);
837 if s1.contains(y) {
838 assert(s1.remove(y).union(s2.remove(y)) =~= s1.union(s2).remove(y));
839 lemma_len_union_ind(s1.remove(y), s2.remove(y))
840 } else {
841 assert(s1.union(s2.remove(y)) =~= s1.union(s2).remove(y));
842 lemma_len_union_ind(s1, s2.remove(y))
843 }
844 }
845}
846
847pub proof fn lemma_len_intersect<A>(s1: Set<A>, s2: Set<A>)
849 requires
850 s1.finite(),
851 ensures
852 s1.intersect(s2).len() <= s1.len(),
853 decreases s1.len(),
854{
855 if s1.is_empty() {
856 assert(s1.intersect(s2) =~= s1);
857 } else {
858 let a = s1.choose();
859 assert(s1.intersect(s2).remove(a) =~= s1.remove(a).intersect(s2));
860 lemma_len_intersect::<A>(s1.remove(a), s2);
861 }
862}
863
864pub proof fn lemma_len_subset<A>(s1: Set<A>, s2: Set<A>)
867 requires
868 s2.finite(),
869 s1.subset_of(s2),
870 ensures
871 s1.len() <= s2.len(),
872 s1.finite(),
873{
874 lemma_len_intersect::<A>(s2, s1);
875 assert(s2.intersect(s1) =~= s1);
876}
877
878pub broadcast proof fn lemma_set_subset_finite<A>(s: Set<A>, sub: Set<A>)
880 requires
881 s.finite(),
882 sub.subset_of(s),
883 ensures
884 #![trigger sub.subset_of(s)]
885 sub.finite(),
886{
887 let complement = s.difference(sub);
888 assert(sub =~= s.difference(complement));
889}
890
891pub proof fn lemma_len_difference<A>(s1: Set<A>, s2: Set<A>)
893 requires
894 s1.finite(),
895 ensures
896 s1.difference(s2).len() <= s1.len(),
897 decreases s1.len(),
898{
899 if s1.is_empty() {
900 assert(s1.difference(s2) =~= s1);
901 } else {
902 let a = s1.choose();
903 assert(s1.difference(s2).remove(a) =~= s1.remove(a).difference(s2));
904 lemma_len_difference::<A>(s1.remove(a), s2);
905 }
906}
907
908pub open spec fn set_int_range(lo: int, hi: int) -> Set<int> {
910 Set::new(|i: int| lo <= i && i < hi)
911}
912
913pub proof fn lemma_int_range(lo: int, hi: int)
916 requires
917 lo <= hi,
918 ensures
919 set_int_range(lo, hi).finite(),
920 set_int_range(lo, hi).len() == hi - lo,
921 decreases hi - lo,
922{
923 if lo == hi {
924 assert(set_int_range(lo, hi) =~= Set::empty());
925 } else {
926 lemma_int_range(lo, hi - 1);
927 assert(set_int_range(lo, hi - 1).insert(hi - 1) =~= set_int_range(lo, hi));
928 }
929}
930
931pub proof fn lemma_subset_equality<A>(x: Set<A>, y: Set<A>)
933 requires
934 x.subset_of(y),
935 x.finite(),
936 y.finite(),
937 x.len() == y.len(),
938 ensures
939 x =~= y,
940 decreases x.len(),
941{
942 broadcast use group_set_properties;
943
944 if x =~= Set::<A>::empty() {
945 } else {
946 let e = x.choose();
947 lemma_subset_equality(x.remove(e), y.remove(e));
948 }
949}
950
951pub proof fn lemma_map_size<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
955 requires
956 injective(f),
957 forall|a: A| x.contains(a) ==> y.contains(#[trigger] f(a)),
958 forall|b: B| (#[trigger] y.contains(b)) ==> exists|a: A| x.contains(a) && f(a) == b,
959 x.finite(),
960 y.finite(),
961 ensures
962 x.len() == y.len(),
963 decreases x.len(),
964{
965 broadcast use group_set_properties;
966
967 if x.len() != 0 {
968 let a = x.choose();
969 lemma_map_size(x.remove(a), y.remove(f(a)), f);
970 }
971}
972
973pub broadcast proof fn lemma_set_union_again1<A>(a: Set<A>, b: Set<A>)
977 ensures
978 #[trigger] a.union(b).union(b) =~= a.union(b),
979{
980}
981
982pub broadcast proof fn lemma_set_union_again2<A>(a: Set<A>, b: Set<A>)
986 ensures
987 #[trigger] a.union(b).union(a) =~= a.union(b),
988{
989}
990
991pub broadcast proof fn lemma_set_intersect_again1<A>(a: Set<A>, b: Set<A>)
995 ensures
996 #![trigger (a.intersect(b)).intersect(b)]
997 (a.intersect(b)).intersect(b) =~= a.intersect(b),
998{
999}
1000
1001pub broadcast proof fn lemma_set_intersect_again2<A>(a: Set<A>, b: Set<A>)
1005 ensures
1006 #![trigger (a.intersect(b)).intersect(a)]
1007 (a.intersect(b)).intersect(a) =~= a.intersect(b),
1008{
1009}
1010
1011pub broadcast proof fn lemma_set_difference2<A>(s1: Set<A>, s2: Set<A>, a: A)
1014 ensures
1015 #![trigger s1.difference(s2).contains(a)]
1016 s2.contains(a) ==> !s1.difference(s2).contains(a),
1017{
1018}
1019
1020pub broadcast proof fn lemma_set_disjoint<A>(a: Set<A>, b: Set<A>)
1024 ensures
1025 #![trigger (a + b).difference(a)] a.disjoint(b) ==> ((a + b).difference(a) =~= b && (a + b).difference(b) =~= a),
1027{
1028}
1029
1030pub broadcast proof fn lemma_set_empty_equivalency_len<A>(s: Set<A>)
1038 requires
1039 s.finite(),
1040 ensures
1041 #![trigger s.len()]
1042 (s.len() == 0 <==> s == Set::<A>::empty()) && (s.len() != 0 ==> exists|x: A| s.contains(x)),
1043{
1044 assert(s.len() == 0 ==> s =~= Set::empty()) by {
1045 if s.len() == 0 {
1046 assert(forall|a: A| !(Set::empty().contains(a)));
1047 assert(Set::<A>::empty().len() == 0);
1048 assert(Set::<A>::empty().len() == s.len());
1049 assert((exists|a: A| s.contains(a)) || (forall|a: A| !s.contains(a)));
1050 if exists|a: A| s.contains(a) {
1051 let a = s.choose();
1052 assert(s.remove(a).len() == s.len() - 1) by {
1053 axiom_set_remove_len(s, a);
1054 }
1055 }
1056 }
1057 }
1058 assert(s.len() == 0 <== s =~= Set::empty());
1059}
1060
1061pub broadcast proof fn lemma_set_disjoint_lens<A>(a: Set<A>, b: Set<A>)
1065 requires
1066 a.finite(),
1067 b.finite(),
1068 ensures
1069 a.disjoint(b) ==> #[trigger] (a + b).len() == a.len() + b.len(),
1070 decreases a.len(),
1071{
1072 if a.len() == 0 {
1073 lemma_set_empty_equivalency_len(a);
1074 assert(a + b =~= b);
1075 } else {
1076 if a.disjoint(b) {
1077 let x = a.choose();
1078 assert(a.remove(x) + b =~= (a + b).remove(x));
1079 lemma_set_disjoint_lens(a.remove(x), b);
1080 }
1081 }
1082}
1083
1084pub broadcast proof fn lemma_set_intersect_union_lens<A>(a: Set<A>, b: Set<A>)
1088 requires
1089 a.finite(),
1090 b.finite(),
1091 ensures
1092 #[trigger] (a + b).len() + #[trigger] a.intersect(b).len() == a.len() + b.len(),
1093 decreases a.len(),
1094{
1095 if a.len() == 0 {
1096 lemma_set_empty_equivalency_len(a);
1097 assert(a + b =~= b);
1098 assert(a.intersect(b) =~= Set::empty());
1099 assert(a.intersect(b).len() == 0);
1100 } else {
1101 let x = a.choose();
1102 lemma_set_intersect_union_lens(a.remove(x), b);
1103 if (b.contains(x)) {
1104 assert(a.remove(x) + b =~= (a + b));
1105 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1106 } else {
1107 assert(a.remove(x) + b =~= (a + b).remove(x));
1108 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1109 }
1110 }
1111}
1112
1113pub broadcast proof fn lemma_set_difference_len<A>(a: Set<A>, b: Set<A>)
1120 requires
1121 a.finite(),
1122 b.finite(),
1123 ensures
1124 (#[trigger] a.difference(b).len() + b.difference(a).len() + a.intersect(b).len() == (a
1125 + b).len()) && (a.difference(b).len() == a.len() - a.intersect(b).len()),
1126 decreases a.len(),
1127{
1128 if a.len() == 0 {
1129 lemma_set_empty_equivalency_len(a);
1130 assert(a.difference(b) =~= Set::empty());
1131 assert(b.difference(a) =~= b);
1132 assert(a.intersect(b) =~= Set::empty());
1133 assert(a + b =~= b);
1134 } else {
1135 let x = a.choose();
1136 lemma_set_difference_len(a.remove(x), b);
1137 if b.contains(x) {
1138 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1139 assert(a.remove(x).difference(b) =~= a.difference(b));
1140 assert(b.difference(a.remove(x)).remove(x) =~= b.difference(a));
1141 assert(a.remove(x) + b =~= a + b);
1142 } else {
1143 assert(a.remove(x) + b =~= (a + b).remove(x));
1144 assert(a.remove(x).difference(b) =~= a.difference(b).remove(x));
1145 assert(b.difference(a.remove(x)) =~= b.difference(a));
1146 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1147 }
1148 }
1149}
1150
1151#[deprecated = "Use `broadcast use group_set_properties` instead"]
1153pub proof fn lemma_set_properties<A>()
1154 ensures
1155 forall|a: Set<A>, b: Set<A>| #[trigger] a.union(b).union(b) == a.union(b), forall|a: Set<A>, b: Set<A>| #[trigger] a.union(b).union(a) == a.union(b), forall|a: Set<A>, b: Set<A>| #[trigger] (a.intersect(b)).intersect(b) == a.intersect(b), forall|a: Set<A>, b: Set<A>| #[trigger] (a.intersect(b)).intersect(a) == a.intersect(b), forall|s1: Set<A>, s2: Set<A>, a: A| s2.contains(a) ==> !s1.difference(s2).contains(a), forall|a: Set<A>, b: Set<A>|
1161 #![trigger (a + b).difference(a)]
1162 a.disjoint(b) ==> ((a + b).difference(a) =~= b && (a + b).difference(b) =~= a), forall|s: Set<A>| #[trigger] s.len() != 0 && s.finite() ==> exists|a: A| s.contains(a), forall|a: Set<A>, b: Set<A>|
1165 (a.finite() && b.finite() && a.disjoint(b)) ==> #[trigger] (a + b).len() == a.len()
1166 + b.len(), forall|a: Set<A>, b: Set<A>|
1168 (a.finite() && b.finite()) ==> #[trigger] (a + b).len() + #[trigger] a.intersect(
1169 b,
1170 ).len() == a.len() + b.len(), forall|a: Set<A>, b: Set<A>|
1172 (a.finite() && b.finite()) ==> ((#[trigger] a.difference(b).len() + b.difference(
1173 a,
1174 ).len() + a.intersect(b).len() == (a + b).len()) && (a.difference(b).len() == a.len()
1175 - a.intersect(b).len())), {
1177 broadcast use group_set_properties;
1178
1179 assert forall|s: Set<A>| #[trigger] s.len() != 0 && s.finite() implies exists|a: A|
1180 s.contains(a) by {
1181 assert(s.contains(s.choose()));
1182 }
1183}
1184
1185pub broadcast group group_set_properties {
1186 lemma_set_union_again1,
1187 lemma_set_union_again2,
1188 lemma_set_intersect_again1,
1189 lemma_set_intersect_again2,
1190 lemma_set_difference2,
1191 lemma_set_disjoint,
1192 lemma_set_disjoint_lens,
1193 lemma_set_intersect_union_lens,
1194 lemma_set_difference_len,
1195 lemma_set_empty_equivalency_len,
1198}
1199
1200pub broadcast proof fn axiom_is_empty<A>(s: Set<A>)
1201 requires
1202 !(#[trigger] s.is_empty()),
1203 ensures
1204 exists|a: A| s.contains(a),
1205{
1206 admit(); }
1208
1209pub broadcast proof fn axiom_is_empty_len0<A>(s: Set<A>)
1210 ensures
1211 #[trigger] s.is_empty() <==> (s.finite() && s.len() == 0),
1212{
1213}
1214
1215#[doc(hidden)]
1216#[verifier::inline]
1217pub open spec fn check_argument_is_set<A>(s: Set<A>) -> Set<A> {
1218 s
1219}
1220
1221#[macro_export]
1235macro_rules! assert_sets_equal {
1236 [$($tail:tt)*] => {
1237 ::builtin_macros::verus_proof_macro_exprs!($crate::vstd::set_lib::assert_sets_equal_internal!($($tail)*))
1238 };
1239}
1240
1241#[macro_export]
1242#[doc(hidden)]
1243macro_rules! assert_sets_equal_internal {
1244 (::builtin::spec_eq($s1:expr, $s2:expr)) => {
1245 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1246 };
1247 (::builtin::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1248 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1249 };
1250 (crate::builtin::spec_eq($s1:expr, $s2:expr)) => {
1251 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1252 };
1253 (crate::builtin::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1254 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1255 };
1256 ($s1:expr, $s2:expr $(,)?) => {
1257 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, elem => { })
1258 };
1259 ($s1:expr, $s2:expr, $elem:ident $( : $t:ty )? => $bblock:block) => {
1260 #[verifier::spec] let s1 = $crate::vstd::set_lib::check_argument_is_set($s1);
1261 #[verifier::spec] let s2 = $crate::vstd::set_lib::check_argument_is_set($s2);
1262 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
1263 $crate::vstd::prelude::assert_forall_by(|$elem $( : $t )?| {
1264 $crate::vstd::prelude::ensures(
1265 $crate::vstd::prelude::imply(s1.contains($elem), s2.contains($elem))
1266 &&
1267 $crate::vstd::prelude::imply(s2.contains($elem), s1.contains($elem))
1268 );
1269 { $bblock }
1270 });
1271 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
1272 });
1273 }
1274}
1275
1276pub broadcast group group_set_lib_default {
1277 axiom_is_empty,
1278 axiom_is_empty_len0,
1279 lemma_set_subset_finite,
1280}
1281
1282pub use assert_sets_equal_internal;
1283pub use assert_sets_equal;
1284
1285}