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 map_by<B>(self, fwd: spec_fn(A) -> B, rev: spec_fn(B) -> A) -> Set<B>
46 recommends
47 forall|a: A| self.contains(a) ==> rev(fwd(a)) == a,
48 {
49 Set::new(|b: B| self.contains(rev(b)) && b == fwd(rev(b)))
50 }
51
52 pub open spec fn map_flatten_by<B>(
58 self,
59 fwd: spec_fn(A) -> Set<B>,
60 rev: spec_fn(B) -> A,
61 ) -> Set<B>
62 recommends
63 forall|a: A, b: B| #[trigger]
64 self.contains(a) && fwd(a).contains(b) ==> #[trigger] rev(b) == a,
65 {
66 Set::new(|b: B| self.contains(rev(b)) && fwd(rev(b)).contains(b))
67 }
68
69 pub proof fn map_flatten_by_is_map_flatten<B>(
70 self,
71 fwd: spec_fn(A) -> Set<B>,
72 rev: spec_fn(B) -> A,
73 )
74 requires
75 forall|a: A, b: B| #[trigger]
76 self.contains(a) && fwd(a).contains(b) ==> #[trigger] rev(b) == a,
77 ensures
78 self.map_flatten_by(fwd, rev) == self.map(fwd).flatten(),
79 {
80 assert forall|b: B| self.map_flatten_by(fwd, rev).contains(b) implies #[trigger] self.map(
81 fwd,
82 ).flatten().contains(b) by {
83 let bs = choose|bs: Set<B>|
84 (exists|a: A| self.contains(a) && bs == fwd(a)) && bs.contains(b);
85 assert(self.map(fwd).contains(bs) <==> (exists|a: A| self.contains(a) && bs == fwd(a)));
86 }
87 }
88
89 pub open spec fn to_seq(self) -> Seq<A>
91 recommends
92 self.finite(),
93 decreases self.len(),
94 when self.finite()
95 {
96 if self.len() == 0 {
97 Seq::<A>::empty()
98 } else {
99 let x = self.choose();
100 Seq::<A>::empty().push(x) + self.remove(x).to_seq()
101 }
102 }
103
104 pub open spec fn to_sorted_seq(self, leq: spec_fn(A, A) -> bool) -> Seq<A> {
106 self.to_seq().sort_by(leq)
107 }
108
109 pub open spec fn is_singleton(self) -> bool {
111 &&& self.len() > 0
112 &&& (forall|x: A, y: A| self.contains(x) && self.contains(y) ==> x == y)
113 }
114
115 pub closed spec fn find_unique_minimal(self, r: spec_fn(A, A) -> bool) -> A
118 recommends
119 total_ordering(r),
120 self.len() > 0,
121 self.finite(),
122 decreases self.len(),
123 when self.finite()
124 {
125 proof {
126 broadcast use group_set_properties;
127
128 }
129 if self.len() <= 1 {
130 self.choose()
131 } else {
132 let x = choose|x: A| self.contains(x);
133 let min = self.remove(x).find_unique_minimal(r);
134 if r(min, x) {
135 min
136 } else {
137 x
138 }
139 }
140 }
141
142 pub proof fn find_unique_minimal_ensures(self, r: spec_fn(A, A) -> bool)
144 requires
145 self.finite(),
146 self.len() > 0,
147 total_ordering(r),
148 ensures
149 is_minimal(r, self.find_unique_minimal(r), self) && (forall|min: A|
150 is_minimal(r, min, self) ==> self.find_unique_minimal(r) == min),
151 decreases self.len(),
152 {
153 broadcast use group_set_properties;
154
155 if self.len() == 1 {
156 let x = choose|x: A| self.contains(x);
157 assert(self.remove(x).insert(x) =~= self);
158 assert(is_minimal(r, self.find_unique_minimal(r), self));
159 } else {
160 let x = choose|x: A| self.contains(x);
161 self.remove(x).find_unique_minimal_ensures(r);
162 assert(is_minimal(r, self.remove(x).find_unique_minimal(r), self.remove(x)));
163 let y = self.remove(x).find_unique_minimal(r);
164 let min_updated = self.find_unique_minimal(r);
165 assert(!r(y, x) ==> min_updated == x);
166 assert(forall|elt: A|
167 self.remove(x).contains(elt) && #[trigger] r(elt, y) ==> #[trigger] r(y, elt));
168 assert forall|elt: A|
169 self.contains(elt) && #[trigger] r(elt, min_updated) implies #[trigger] r(
170 min_updated,
171 elt,
172 ) by {
173 assert(r(min_updated, x) || r(min_updated, y));
174 if min_updated == y { assert(is_minimal(r, self.find_unique_minimal(r), self));
176 } else { assert(self.remove(x).contains(elt) || elt == x);
178 assert(min_updated == x);
179 assert(r(x, y) || r(y, x));
180 assert(!r(x, y) || !r(y, x));
181 assert(!(min_updated == y) ==> !r(y, x));
182 assert(r(x, y));
183 if (self.remove(x).contains(elt)) {
184 assert(r(elt, y) && r(y, elt) ==> elt == y);
185 } else {
186 }
187 }
188 }
189 assert forall|min_poss: A|
190 is_minimal(r, min_poss, self) implies self.find_unique_minimal(r) == min_poss by {
191 assert(is_minimal(r, min_poss, self.remove(x)) || x == min_poss);
192 assert(r(min_poss, self.find_unique_minimal(r)));
193 }
194 }
195 }
196
197 pub closed spec fn find_unique_maximal(self, r: spec_fn(A, A) -> bool) -> A
200 recommends
201 total_ordering(r),
202 self.len() > 0,
203 decreases self.len(),
204 when self.finite()
205 {
206 proof {
207 broadcast use group_set_properties;
208
209 }
210 if self.len() <= 1 {
211 self.choose()
212 } else {
213 let x = choose|x: A| self.contains(x);
214 let max = self.remove(x).find_unique_maximal(r);
215 if r(x, max) {
216 max
217 } else {
218 x
219 }
220 }
221 }
222
223 pub proof fn find_unique_maximal_ensures(self, r: spec_fn(A, A) -> bool)
225 requires
226 self.finite(),
227 self.len() > 0,
228 total_ordering(r),
229 ensures
230 is_maximal(r, self.find_unique_maximal(r), self) && (forall|max: A|
231 is_maximal(r, max, self) ==> self.find_unique_maximal(r) == max),
232 decreases self.len(),
233 {
234 broadcast use group_set_properties;
235
236 if self.len() == 1 {
237 let x = choose|x: A| self.contains(x);
238 assert(self.remove(x) =~= Set::<A>::empty());
239 assert(self.contains(self.find_unique_maximal(r)));
240 } else {
241 let x = choose|x: A| self.contains(x);
242 self.remove(x).find_unique_maximal_ensures(r);
243 assert(is_maximal(r, self.remove(x).find_unique_maximal(r), self.remove(x)));
244 assert(self.remove(x).insert(x) =~= self);
245 let y = self.remove(x).find_unique_maximal(r);
246 let max_updated = self.find_unique_maximal(r);
247 assert(max_updated == x || max_updated == y);
248 assert(!r(x, y) ==> max_updated == x);
249 assert forall|elt: A|
250 self.contains(elt) && #[trigger] r(max_updated, elt) implies #[trigger] r(
251 elt,
252 max_updated,
253 ) by {
254 assert(r(x, max_updated) || r(y, max_updated));
255 if max_updated == y { assert(r(elt, max_updated));
257 assert(r(x, max_updated));
258 assert(is_maximal(r, self.find_unique_maximal(r), self));
259 } else { assert(self.remove(x).contains(elt) || elt == x);
261 assert(max_updated == x);
262 assert(r(x, y) || r(y, x));
263 assert(!r(x, y) || !r(y, x));
264 assert(!(max_updated == y) ==> !r(x, y));
265 assert(r(y, x));
266 if (self.remove(x).contains(elt)) {
267 assert(r(y, elt) ==> r(elt, y));
268 assert(r(y, elt) && r(elt, y) ==> elt == y);
269 assert(r(elt, x));
270 assert(r(elt, max_updated))
271 } else {
272 }
273 }
274 }
275 assert forall|max_poss: A|
276 is_maximal(r, max_poss, self) implies self.find_unique_maximal(r) == max_poss by {
277 assert(is_maximal(r, max_poss, self.remove(x)) || x == max_poss);
278 assert(r(max_poss, self.find_unique_maximal(r)));
279 assert(r(self.find_unique_maximal(r), max_poss));
280 }
281 }
282 }
283
284 pub open spec fn to_multiset(self) -> Multiset<A>
287 decreases self.len(),
288 when self.finite()
289 {
290 if self.len() == 0 {
291 Multiset::<A>::empty()
292 } else {
293 Multiset::<A>::empty().insert(self.choose()).add(
294 self.remove(self.choose()).to_multiset(),
295 )
296 }
297 }
298
299 pub proof fn lemma_len0_is_empty(self)
301 requires
302 self.finite(),
303 self.len() == 0,
304 ensures
305 self == Set::<A>::empty(),
306 {
307 if exists|a: A| self.contains(a) {
308 assert(self.remove(self.choose()).len() + 1 == 0);
310 }
311 assert(self =~= Set::empty());
312 }
313
314 pub proof fn lemma_singleton_size(self)
316 requires
317 self.is_singleton(),
318 ensures
319 self.len() == 1,
320 {
321 broadcast use group_set_properties;
322
323 assert(self.remove(self.choose()) =~= Set::empty());
324 }
325
326 pub proof fn lemma_is_singleton(s: Set<A>)
328 requires
329 s.finite(),
330 ensures
331 s.is_singleton() == (s.len() == 1),
332 {
333 if s.is_singleton() {
334 s.lemma_singleton_size();
335 }
336 if s.len() == 1 {
337 assert forall|x: A, y: A| s.contains(x) && s.contains(y) implies x == y by {
338 let x = choose|x: A| s.contains(x);
339 broadcast use group_set_properties;
340
341 assert(s.remove(x).len() == 0);
342 assert(s.insert(x) =~= s);
343 }
344 }
345 }
346
347 pub proof fn lemma_len_filter(self, f: spec_fn(A) -> bool)
349 requires
350 self.finite(),
351 ensures
352 self.filter(f).finite(),
353 self.filter(f).len() <= self.len(),
354 decreases self.len(),
355 {
356 lemma_len_intersect::<A>(self, Set::new(f));
357 }
358
359 pub proof fn lemma_greatest_implies_maximal(self, r: spec_fn(A, A) -> bool, max: A)
361 requires
362 pre_ordering(r),
363 ensures
364 is_greatest(r, max, self) ==> is_maximal(r, max, self),
365 {
366 }
367
368 pub proof fn lemma_least_implies_minimal(self, r: spec_fn(A, A) -> bool, min: A)
370 requires
371 pre_ordering(r),
372 ensures
373 is_least(r, min, self) ==> is_minimal(r, min, self),
374 {
375 }
376
377 pub proof fn lemma_maximal_equivalent_greatest(self, r: spec_fn(A, A) -> bool, max: A)
379 requires
380 total_ordering(r),
381 ensures
382 is_greatest(r, max, self) <==> is_maximal(r, max, self),
383 {
384 assert(is_maximal(r, max, self) ==> forall|x: A|
385 !self.contains(x) || !r(max, x) || r(x, max));
386 }
387
388 pub proof fn lemma_minimal_equivalent_least(self, r: spec_fn(A, A) -> bool, min: A)
390 requires
391 total_ordering(r),
392 ensures
393 is_least(r, min, self) <==> is_minimal(r, min, self),
394 {
395 assert(is_minimal(r, min, self) ==> forall|x: A|
396 !self.contains(x) || !r(x, min) || r(min, x));
397 }
398
399 pub proof fn lemma_least_is_unique(self, r: spec_fn(A, A) -> bool)
401 requires
402 partial_ordering(r),
403 ensures
404 forall|min: A, min_prime: A|
405 is_least(r, min, self) && is_least(r, min_prime, self) ==> min == min_prime,
406 {
407 assert forall|min: A, min_prime: A|
408 is_least(r, min, self) && is_least(r, min_prime, self) implies min == min_prime by {
409 assert(r(min, min_prime));
410 assert(r(min_prime, min));
411 }
412 }
413
414 pub proof fn lemma_greatest_is_unique(self, r: spec_fn(A, A) -> bool)
416 requires
417 partial_ordering(r),
418 ensures
419 forall|max: A, max_prime: A|
420 is_greatest(r, max, self) && is_greatest(r, max_prime, self) ==> max == max_prime,
421 {
422 assert forall|max: A, max_prime: A|
423 is_greatest(r, max, self) && is_greatest(r, max_prime, self) implies max
424 == max_prime by {
425 assert(r(max_prime, max));
426 assert(r(max, max_prime));
427 }
428 }
429
430 pub proof fn lemma_minimal_is_unique(self, r: spec_fn(A, A) -> bool)
432 requires
433 total_ordering(r),
434 ensures
435 forall|min: A, min_prime: A|
436 is_minimal(r, min, self) && is_minimal(r, min_prime, self) ==> min == min_prime,
437 {
438 assert forall|min: A, min_prime: A|
439 is_minimal(r, min, self) && is_minimal(r, min_prime, self) implies min == min_prime by {
440 self.lemma_minimal_equivalent_least(r, min);
441 self.lemma_minimal_equivalent_least(r, min_prime);
442 self.lemma_least_is_unique(r);
443 }
444 }
445
446 pub proof fn lemma_maximal_is_unique(self, r: spec_fn(A, A) -> bool)
448 requires
449 self.finite(),
450 total_ordering(r),
451 ensures
452 forall|max: A, max_prime: A|
453 is_maximal(r, max, self) && is_maximal(r, max_prime, self) ==> max == max_prime,
454 {
455 assert forall|max: A, max_prime: A|
456 is_maximal(r, max, self) && is_maximal(r, max_prime, self) implies max == max_prime by {
457 self.lemma_maximal_equivalent_greatest(r, max);
458 self.lemma_maximal_equivalent_greatest(r, max_prime);
459 self.lemma_greatest_is_unique(r);
460 }
461 }
462
463 pub broadcast proof fn lemma_set_insert_diff_decreases(self, s: Set<A>, elt: A)
467 requires
468 self.contains(elt),
469 !s.contains(elt),
470 self.finite(),
471 ensures
472 #[trigger] self.difference(s.insert(elt)).len() < self.difference(s).len(),
473 {
474 self.difference(s.insert(elt)).lemma_subset_not_in_lt(self.difference(s), elt);
475 }
476
477 pub proof fn lemma_subset_not_in_lt(self: Set<A>, s2: Set<A>, elt: A)
479 requires
480 self.subset_of(s2),
481 s2.finite(),
482 !self.contains(elt),
483 s2.contains(elt),
484 ensures
485 self.len() < s2.len(),
486 {
487 let s2_no_elt = s2.remove(elt);
488 assert(self.len() <= s2_no_elt.len()) by {
489 lemma_len_subset(self, s2_no_elt);
490 }
491 }
492
493 pub broadcast proof fn lemma_set_map_insert_commute<B>(self, elt: A, f: spec_fn(A) -> B)
495 ensures
496 #[trigger] self.insert(elt).map(f) =~= self.map(f).insert(f(elt)),
497 {
498 assert forall|x: B| self.map(f).insert(f(elt)).contains(x) implies self.insert(elt).map(
499 f,
500 ).contains(x) by {
501 if x == f(elt) {
502 assert(self.insert(elt).contains(elt));
503 } else {
504 let y = choose|y: A| self.contains(y) && f(y) == x;
505 assert(self.insert(elt).contains(y));
506 }
507 }
508 }
509
510 pub proof fn lemma_map_union_commute<B>(self, t: Set<A>, f: spec_fn(A) -> B)
512 ensures
513 (self.union(t)).map(f) =~= self.map(f).union(t.map(f)),
514 {
515 broadcast use group_set_axioms;
516
517 let lhs = self.union(t).map(f);
518 let rhs = self.map(f).union(t.map(f));
519
520 assert forall|elem: B| rhs.contains(elem) implies lhs.contains(elem) by {
521 if self.map(f).contains(elem) {
522 let preimage = choose|preimage: A| self.contains(preimage) && f(preimage) == elem;
523 assert(self.union(t).contains(preimage));
524 } else {
525 assert(t.map(f).contains(elem));
526 let preimage = choose|preimage: A| t.contains(preimage) && f(preimage) == elem;
527 assert(self.union(t).contains(preimage));
528 }
529 }
530 }
531
532 pub open spec fn all(&self, pred: spec_fn(A) -> bool) -> bool {
534 forall|x: A| self.contains(x) ==> pred(x)
535 }
536
537 pub open spec fn any(&self, pred: spec_fn(A) -> bool) -> bool {
539 exists|x: A| self.contains(x) && pred(x)
540 }
541
542 pub broadcast proof fn lemma_any_map_preserved_pred<B>(
544 self,
545 p: spec_fn(A) -> bool,
546 q: spec_fn(B) -> bool,
547 f: spec_fn(A) -> B,
548 )
549 requires
550 #[trigger] self.any(p),
551 forall|x: A| #[trigger] p(x) ==> q(f(x)),
552 ensures
553 #[trigger] self.map(f).any(q),
554 {
555 let x = choose|x: A| self.contains(x) && p(x);
556 assert(self.map(f).contains(f(x)));
557 }
558
559 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Set<B> {
561 self.map(
562 |elem: A|
563 match f(elem) {
564 Option::Some(r) => set!{r},
565 Option::None => set!{},
566 },
567 ).flatten()
568 }
569
570 pub broadcast proof fn lemma_filter_map_insert<B>(
572 s: Set<A>,
573 f: spec_fn(A) -> Option<B>,
574 elem: A,
575 )
576 ensures
577 #[trigger] s.insert(elem).filter_map(f) == (match f(elem) {
578 Some(res) => s.filter_map(f).insert(res),
579 None => s.filter_map(f),
580 }),
581 {
582 broadcast use group_set_axioms;
583 broadcast use Set::lemma_set_map_insert_commute;
584
585 let lhs = s.insert(elem).filter_map(f);
586 let rhs = match f(elem) {
587 Some(res) => s.filter_map(f).insert(res),
588 None => s.filter_map(f),
589 };
590 let to_set = |elem: A|
591 match f(elem) {
592 Option::Some(r) => set!{r},
593 Option::None => set!{},
594 };
595 assert forall|r: B| #[trigger] lhs.contains(r) implies rhs.contains(r) by {
596 if f(elem) != Some(r) {
597 let orig = choose|orig: A| #[trigger]
598 s.contains(orig) && f(orig) == Option::Some(r);
599 assert(to_set(orig) == set!{r});
600 assert(s.map(to_set).contains(to_set(orig)));
601 }
602 }
603 assert forall|r: B| #[trigger] rhs.contains(r) implies lhs.contains(r) by {
604 if Some(r) == f(elem) {
605 assert(s.insert(elem).map(to_set).contains(to_set(elem)));
606 } else {
607 let orig = choose|orig: A| #[trigger]
608 s.contains(orig) && f(orig) == Option::Some(r);
609 assert(s.insert(elem).map(to_set).contains(to_set(orig)));
610 }
611 }
612 assert(lhs =~= rhs);
613 }
614
615 pub broadcast proof fn lemma_filter_map_union<B>(self, f: spec_fn(A) -> Option<B>, t: Set<A>)
617 ensures
618 #[trigger] self.union(t).filter_map(f) == self.filter_map(f).union(t.filter_map(f)),
619 {
620 broadcast use group_set_axioms;
621
622 let lhs = self.union(t).filter_map(f);
623 let rhs = self.filter_map(f).union(t.filter_map(f));
624 let to_set = |elem: A|
625 match f(elem) {
626 Option::Some(r) => set!{r},
627 Option::None => set!{},
628 };
629
630 assert forall|elem: B| rhs.contains(elem) implies lhs.contains(elem) by {
631 if self.filter_map(f).contains(elem) {
632 let x = choose|x: A| self.contains(x) && f(x) == Option::Some(elem);
633 assert(self.union(t).contains(x));
634 assert(self.union(t).map(to_set).contains(to_set(x)));
635 }
636 if t.filter_map(f).contains(elem) {
637 let x = choose|x: A| t.contains(x) && f(x) == Option::Some(elem);
638 assert(self.union(t).contains(x));
639 assert(self.union(t).map(to_set).contains(to_set(x)));
640 }
641 }
642 assert forall|elem: B| lhs.contains(elem) implies rhs.contains(elem) by {
643 let x = choose|x: A| self.union(t).contains(x) && f(x) == Option::Some(elem);
644 if self.contains(x) {
645 assert(self.map(to_set).contains(to_set(x)));
646 assert(self.filter_map(f).contains(elem));
647 } else {
648 assert(t.contains(x));
649 assert(t.map(to_set).contains(to_set(x)));
650 assert(t.filter_map(f).contains(elem));
651 }
652 }
653 assert(lhs =~= rhs);
654 }
655
656 pub proof fn lemma_map_finite<B>(self, f: spec_fn(A) -> B)
658 requires
659 self.finite(),
660 ensures
661 self.map(f).finite(),
662 decreases self.len(),
663 {
664 broadcast use group_set_axioms;
665 broadcast use lemma_set_empty_equivalency_len;
666
667 if self.len() == 0 {
668 assert(forall|elem: A| !(#[trigger] self.contains(elem)));
669 assert forall|res: B| #[trigger] self.map(f).contains(res) implies false by {
670 let x = choose|x: A| self.contains(x) && f(x) == res;
671 }
672 assert(self.map(f) =~= Set::<B>::empty());
673 } else {
674 let x = choose|x: A| self.contains(x);
675 assert(self.map(f).contains(f(x)));
676 self.remove(x).lemma_map_finite(f);
677 assert(self.remove(x).insert(x) == self);
678 assert(self.map(f) == self.remove(x).map(f).insert(f(x)));
679 }
680 }
681
682 pub broadcast proof fn lemma_map_by_finite<B>(self, fwd: spec_fn(A) -> B, rev: spec_fn(B) -> A)
683 requires
684 self.finite(),
685 ensures
686 #[trigger] self.map_by(fwd, rev).finite(),
687 {
688 broadcast use lemma_set_subset_finite;
689
690 assert(self.map_by(fwd, rev).subset_of(self.map(fwd)));
691 self.lemma_map_finite(fwd);
692 }
693
694 pub broadcast proof fn lemma_map_flatten_by_finite<B>(
695 self,
696 fwd: spec_fn(A) -> Set<B>,
697 rev: spec_fn(B) -> A,
698 )
699 requires
700 self.finite(),
701 forall|a: A| self.contains(a) ==> fwd(a).finite(),
702 ensures
703 #[trigger] self.map_flatten_by(fwd, rev).finite(),
704 {
705 broadcast use lemma_set_subset_finite;
706
707 let s1 = self.map_flatten_by(fwd, rev);
708 let s2 = self.map(fwd).flatten();
709 assert forall|b: B| s1.contains(b) implies s2.contains(b) by {
710 assert(self.map(fwd).contains(fwd(rev(b))));
711 }
712 assert(s1.subset_of(s2));
713 self.lemma_map_finite(fwd);
714 self.map(fwd).lemma_flatten_finite();
715 }
716
717 pub broadcast proof fn lemma_set_all_subset(self, s2: Set<A>, p: spec_fn(A) -> bool)
718 requires
719 #[trigger] self.subset_of(s2),
720 s2.all(p),
721 ensures
722 #[trigger] self.all(p),
723 {
724 broadcast use group_set_axioms;
725
726 }
727
728 pub broadcast proof fn lemma_filter_map_finite<B>(self, f: spec_fn(A) -> Option<B>)
730 requires
731 self.finite(),
732 ensures
733 #[trigger] self.filter_map(f).finite(),
734 decreases self.len(),
735 {
736 broadcast use group_set_axioms;
737 broadcast use Set::lemma_filter_map_insert;
738
739 let mapped = self.filter_map(f);
740 if self.len() == 0 {
741 assert(self.filter_map(f) =~= Set::<B>::empty());
742 } else {
743 let elem = self.choose();
744 self.remove(elem).lemma_filter_map_finite(f);
745 assert(self =~= self.remove(elem).insert(elem));
746 }
747 }
748
749 pub broadcast proof fn lemma_to_seq_to_set_id(self)
751 requires
752 self.finite(),
753 ensures
754 #[trigger] self.to_seq().to_set() =~= self,
755 decreases self.len(),
756 {
757 broadcast use group_set_axioms;
758 broadcast use lemma_set_empty_equivalency_len;
759 broadcast use super::seq_lib::group_seq_properties;
760
761 if self.len() == 0 {
762 assert(self.to_seq().to_set() =~= Set::<A>::empty());
763 } else {
764 let elem = self.choose();
765 self.remove(elem).lemma_to_seq_to_set_id();
766 assert(self =~= self.remove(elem).insert(elem));
767 assert(self.to_seq().to_set() =~= self.remove(elem).to_seq().to_set().insert(elem));
768 }
769 }
770}
771
772impl<A> Set<Set<A>> {
773 pub open spec fn flatten(self) -> Set<A> {
774 Set::new(
775 |elem| exists|elem_s: Set<A>| #[trigger] self.contains(elem_s) && elem_s.contains(elem),
776 )
777 }
778
779 pub broadcast proof fn flatten_insert_union_commute(self, other: Set<A>)
780 ensures
781 self.flatten().union(other) =~= #[trigger] self.insert(other).flatten(),
782 {
783 broadcast use group_set_axioms;
784
785 let lhs = self.flatten().union(other);
786 let rhs = self.insert(other).flatten();
787
788 assert forall|elem: A| lhs.contains(elem) implies rhs.contains(elem) by {
789 if exists|s: Set<A>| self.contains(s) && s.contains(elem) {
790 let s = choose|s: Set<A>| self.contains(s) && s.contains(elem);
791 assert(self.insert(other).contains(s));
792 assert(s.contains(elem));
793 } else {
794 assert(self.insert(other).contains(other));
795 }
796 }
797 }
798
799 pub proof fn lemma_flatten_finite(self)
800 requires
801 self.finite(),
802 forall|s: Set<A>| self.contains(s) ==> #[trigger] s.finite(),
803 ensures
804 self.flatten().finite(),
805 decreases self.len(),
806 {
807 broadcast use group_set_axioms;
808
809 if self.len() == 0 {
810 assert(self.flatten() =~= Set::<A>::empty());
811 } else {
812 let s = self.choose();
813 let self2 = self.remove(s);
814 self2.lemma_flatten_finite();
815 self2.flatten_insert_union_commute(s);
816 }
817 }
818}
819
820pub trait FiniteRange: Sized {
821 spec fn range_set(lo: Self, hi: Self) -> Set<Self>;
822
823 spec fn range_len(lo: Self, hi: Self) -> nat;
824
825 proof fn range_properties(lo: Self, hi: Self)
826 ensures
827 Self::range_set(lo, hi).finite(),
828 Self::range_set(lo, hi).len() == Self::range_len(lo, hi),
829 ;
830}
831
832pub broadcast proof fn range_set_properties<A: FiniteRange>(lo: A, hi: A)
833 ensures
834 (#[trigger] A::range_set(lo, hi)).finite(),
835 A::range_set(lo, hi).len() == A::range_len(lo, hi),
836{
837 A::range_properties(lo, hi);
838}
839
840pub trait FiniteFull: Sized {
841 proof fn full_properties()
842 ensures
843 Set::<Self>::full().finite(),
844 ;
845}
846
847pub broadcast proof fn full_set_properties<A: FiniteFull>()
848 ensures
849 #![trigger Set::<A>::full()]
850 (Set::<A>::full()).finite(),
851{
852 A::full_properties();
853}
854
855impl<A: FiniteRange> Set<A> {
856 #[verifier::inline]
857 pub open spec fn range(lo: A, hi: A) -> Set<A> {
858 A::range_set(lo, hi)
859 }
860
861 #[verifier::inline]
862 pub open spec fn range_inclusive(lo: A, hi: A) -> Set<A> {
863 A::range_set(lo, hi).insert(hi)
864 }
865}
866
867impl<A: FiniteFull> Set<A> {
868 #[verifier::inline]
869 pub open spec fn from_finite_type(f: spec_fn(A) -> bool) -> Set<A> {
870 Set::<A>::full().filter(f)
871 }
872}
873
874macro_rules! range_impls {
877 ([$($t:ty)*]) => {
878 $(
879 verus! {
880 impl FiniteRange for $t {
881 open spec fn range_set(lo: Self, hi: Self) -> Set<Self> {
882 Set::new(|i: Self| lo <= i < hi)
883 }
884 open spec fn range_len(lo: Self, hi: Self) -> nat {
885 if lo <= hi { (hi - lo) as nat } else { 0 }
886 }
887 proof fn range_properties(lo: Self, hi: Self)
888 decreases hi - lo
889 {
890 broadcast use axiom_set_empty_finite;
891 broadcast use axiom_set_empty_len;
892 broadcast use axiom_set_insert_finite;
893
894 if hi <= lo {
895 assert(Self::range_set(lo, hi).is_empty());
896 } else {
897 let hi1 = (hi - 1) as $t;
898 Self::range_properties(lo, hi1);
899 assert(Self::range_set(lo, hi) == Self::range_set(lo, hi1).insert(hi1));
900 axiom_set_insert_finite(Self::range_set(lo, hi1), hi1);
901 }
902 }
903 }
904 } )*
906 }
907}
908
909macro_rules! full_impls {
910 ([$($t:ty)*]) => {
911 $(
912 verus! {
913 impl FiniteFull for $t {
914 proof fn full_properties() {
915 broadcast use axiom_set_insert_finite;
916
917 assert(Set::<$t>::full() == Set::range_inclusive($t::MIN, $t::MAX));
918 <$t as FiniteRange>::range_properties($t::MIN, $t::MAX);
919 }
920 }
921 } )*
923 }
924}
925
926range_impls!([
928 int nat
929 usize u8 u16 u32 u64 u128
930 isize i8 i16 i32 i64 i128
931]);
932
933full_impls!([
935 usize u8 u16 u32 u64 u128
936 isize i8 i16 i32 i64 i128
937]);
938
939pub proof fn lemma_sets_eq_iff_injective_map_eq<T, S>(s1: Set<T>, s2: Set<T>, f: spec_fn(T) -> S)
941 requires
942 super::relations::injective(f),
943 ensures
944 (s1 == s2) <==> (s1.map(f) == s2.map(f)),
945{
946 broadcast use group_set_axioms;
947
948 if (s1.map(f) == s2.map(f)) {
949 assert(s1.map(f).len() == s2.map(f).len());
950 if !s1.subset_of(s2) {
951 let x = choose|x: T| s1.contains(x) && !s2.contains(x);
952 assert(s1.map(f).contains(f(x)));
953 } else if !s2.subset_of(s1) {
954 let x = choose|x: T| s2.contains(x) && !s1.contains(x);
955 assert(s2.map(f).contains(f(x)));
956 }
957 assert(s1 =~= s2);
958 }
959}
960
961pub proof fn lemma_sets_eq_iff_injective_map_on_eq<T, S>(s1: Set<T>, s2: Set<T>, f: spec_fn(T) -> S)
963 requires
964 super::relations::injective_on(f, s1 + s2),
965 ensures
966 (s1 == s2) <==> (s1.map(f) == s2.map(f)),
967{
968 broadcast use group_set_axioms;
969
970 if (s1.map(f) == s2.map(f)) {
971 assert(s1.map(f).len() == s2.map(f).len());
972 if !s1.subset_of(s2) {
973 let x = choose|x: T| s1.contains(x) && !s2.contains(x);
974 assert(s1.map(f).contains(f(x)));
975 } else if !s2.subset_of(s1) {
976 let x = choose|x: T| s2.contains(x) && !s1.contains(x);
977 assert(s2.map(f).contains(f(x)));
978 }
979 assert(s1 =~= s2);
980 }
981}
982
983pub broadcast proof fn lemma_set_insert_finite_iff<A>(s: Set<A>, a: A)
985 ensures
986 #[trigger] s.insert(a).finite() <==> s.finite(),
987{
988 if s.insert(a).finite() {
989 if s.contains(a) {
990 assert(s == s.insert(a));
991 } else {
992 assert(s == s.insert(a).remove(a));
993 }
994 }
995 assert(s.insert(a).finite() ==> s.finite());
996}
997
998pub broadcast proof fn lemma_set_remove_finite_iff<A>(s: Set<A>, a: A)
1000 ensures
1001 #[trigger] s.remove(a).finite() <==> s.finite(),
1002{
1003 if s.remove(a).finite() {
1004 if s.contains(a) {
1005 assert(s == s.remove(a).insert(a));
1006 } else {
1007 assert(s == s.remove(a));
1008 }
1009 }
1010}
1011
1012pub broadcast proof fn lemma_set_union_finite_iff<A>(s1: Set<A>, s2: Set<A>)
1014 ensures
1015 #[trigger] s1.union(s2).finite() <==> s1.finite() && s2.finite(),
1016{
1017 if s1.union(s2).finite() {
1018 lemma_set_union_finite_implies_sets_finite(s1, s2);
1019 }
1020}
1021
1022pub proof fn lemma_set_union_finite_implies_sets_finite<A>(s1: Set<A>, s2: Set<A>)
1023 requires
1024 s1.union(s2).finite(),
1025 ensures
1026 s1.finite(),
1027 s2.finite(),
1028 decreases s1.union(s2).len(),
1029{
1030 if s1.union(s2) =~= set![] {
1031 assert(s1 =~= set![]);
1032 assert(s2 =~= set![]);
1033 } else {
1034 let a = s1.union(s2).choose();
1035 assert(s1.remove(a).union(s2.remove(a)) == s1.union(s2).remove(a));
1036 axiom_set_remove_len(s1.union(s2), a);
1037 lemma_set_union_finite_implies_sets_finite(s1.remove(a), s2.remove(a));
1038 assert(forall|s: Set<A>|
1039 #![auto]
1040 s.remove(a).insert(a) == if s.contains(a) {
1041 s
1042 } else {
1043 s.insert(a)
1044 });
1045 lemma_set_insert_finite_iff(s1, a);
1046 lemma_set_insert_finite_iff(s2, a);
1047 }
1048}
1049
1050pub proof fn lemma_len_union<A>(s1: Set<A>, s2: Set<A>)
1053 requires
1054 s1.finite(),
1055 s2.finite(),
1056 ensures
1057 s1.union(s2).len() <= s1.len() + s2.len(),
1058 decreases s1.len(),
1059{
1060 if s1.is_empty() {
1061 assert(s1.union(s2) =~= s2);
1062 } else {
1063 let a = s1.choose();
1064 if s2.contains(a) {
1065 assert(s1.union(s2) =~= s1.remove(a).union(s2));
1066 } else {
1067 assert(s1.union(s2).remove(a) =~= s1.remove(a).union(s2));
1068 }
1069 lemma_len_union::<A>(s1.remove(a), s2);
1070 }
1071}
1072
1073pub proof fn lemma_len_union_ind<A>(s1: Set<A>, s2: Set<A>)
1076 requires
1077 s1.finite(),
1078 s2.finite(),
1079 ensures
1080 s1.union(s2).len() >= s1.len(),
1081 s1.union(s2).len() >= s2.len(),
1082 decreases s2.len(),
1083{
1084 broadcast use group_set_properties;
1085
1086 if s2.len() == 0 {
1087 } else {
1088 let y = choose|y: A| s2.contains(y);
1089 if s1.contains(y) {
1090 assert(s1.remove(y).union(s2.remove(y)) =~= s1.union(s2).remove(y));
1091 lemma_len_union_ind(s1.remove(y), s2.remove(y))
1092 } else {
1093 assert(s1.union(s2.remove(y)) =~= s1.union(s2).remove(y));
1094 lemma_len_union_ind(s1, s2.remove(y))
1095 }
1096 }
1097}
1098
1099pub proof fn lemma_len_intersect<A>(s1: Set<A>, s2: Set<A>)
1101 requires
1102 s1.finite(),
1103 ensures
1104 s1.intersect(s2).len() <= s1.len(),
1105 decreases s1.len(),
1106{
1107 if s1.is_empty() {
1108 assert(s1.intersect(s2) =~= s1);
1109 } else {
1110 let a = s1.choose();
1111 assert(s1.intersect(s2).remove(a) =~= s1.remove(a).intersect(s2));
1112 lemma_len_intersect::<A>(s1.remove(a), s2);
1113 }
1114}
1115
1116pub proof fn lemma_len_subset<A>(s1: Set<A>, s2: Set<A>)
1119 requires
1120 s2.finite(),
1121 s1.subset_of(s2),
1122 ensures
1123 s1.len() <= s2.len(),
1124 s1.finite(),
1125{
1126 lemma_len_intersect::<A>(s2, s1);
1127 assert(s2.intersect(s1) =~= s1);
1128}
1129
1130pub broadcast proof fn lemma_set_subset_finite<A>(s: Set<A>, sub: Set<A>)
1132 requires
1133 s.finite(),
1134 sub.subset_of(s),
1135 ensures
1136 #![trigger sub.subset_of(s)]
1137 sub.finite(),
1138{
1139 let complement = s.difference(sub);
1140 assert(sub =~= s.difference(complement));
1141}
1142
1143pub proof fn lemma_len_difference<A>(s1: Set<A>, s2: Set<A>)
1145 requires
1146 s1.finite(),
1147 ensures
1148 s1.difference(s2).len() <= s1.len(),
1149 decreases s1.len(),
1150{
1151 if s1.is_empty() {
1152 assert(s1.difference(s2) =~= s1);
1153 } else {
1154 let a = s1.choose();
1155 assert(s1.difference(s2).remove(a) =~= s1.remove(a).difference(s2));
1156 lemma_len_difference::<A>(s1.remove(a), s2);
1157 }
1158}
1159
1160pub open spec fn set_int_range(lo: int, hi: int) -> Set<int> {
1162 Set::new(|i: int| lo <= i && i < hi)
1163}
1164
1165pub proof fn lemma_int_range(lo: int, hi: int)
1168 requires
1169 lo <= hi,
1170 ensures
1171 set_int_range(lo, hi).finite(),
1172 set_int_range(lo, hi).len() == hi - lo,
1173 decreases hi - lo,
1174{
1175 if lo == hi {
1176 assert(set_int_range(lo, hi) =~= Set::empty());
1177 } else {
1178 lemma_int_range(lo, hi - 1);
1179 assert(set_int_range(lo, hi - 1).insert(hi - 1) =~= set_int_range(lo, hi));
1180 }
1181}
1182
1183pub proof fn lemma_subset_equality<A>(x: Set<A>, y: Set<A>)
1185 requires
1186 x.subset_of(y),
1187 x.finite(),
1188 y.finite(),
1189 x.len() == y.len(),
1190 ensures
1191 x =~= y,
1192 decreases x.len(),
1193{
1194 broadcast use group_set_properties;
1195
1196 if x =~= Set::<A>::empty() {
1197 } else {
1198 let e = x.choose();
1199 lemma_subset_equality(x.remove(e), y.remove(e));
1200 }
1201}
1202
1203pub proof fn lemma_map_size<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
1206 requires
1207 x.finite(),
1208 injective_on(f, x),
1209 x.map(f) == y,
1210 ensures
1211 y.finite(),
1212 x.len() == y.len(),
1213 decreases x.len(),
1214{
1215 broadcast use group_set_properties;
1216
1217 if x.len() == 0 {
1218 if !y.is_empty() {
1219 let e = y.choose();
1220 }
1221 } else {
1222 let a = x.choose();
1223 assert(x.remove(a).map(f) == y.remove(f(a)));
1224 lemma_map_size(x.remove(a), y.remove(f(a)), f);
1225 assert(y == y.remove(f(a)).insert(f(a)));
1226 }
1227}
1228
1229pub proof fn lemma_map_size_bound<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
1232 requires
1233 x.finite(),
1234 x.map(f) == y,
1235 ensures
1236 y.finite(),
1237 y.len() <= x.len(),
1238 decreases x.len(),
1239{
1240 broadcast use group_set_properties;
1241
1242 if x.is_empty() {
1243 if !y.is_empty() {
1244 let e = y.choose();
1245 }
1246 } else {
1247 let xx = x.choose();
1248 let img = f(xx);
1249 let pre = x.filter(|a: A| f(a) == f(xx));
1250 x.lemma_len_filter(|a: A| f(a) == f(xx));
1251 let wit = choose|a: A| x.contains(a) && f(a) == f(xx);
1252 assert forall|b: B| (#[trigger] y.remove(f(xx)).contains(b)) implies exists|a: A|
1253 x.difference(pre).contains(a) && f(a) == b by {
1254 let pre_wit = choose|a: A| x.contains(a) && f(a) == b;
1255 assert(x.difference(pre).contains(pre_wit));
1256 }
1257
1258 assert(x == x.difference(pre).union(pre));
1259 assert(y == y.remove(f(xx)).insert(f(xx)));
1260 assert(x.difference(pre).map(f) == y.remove(f(xx)));
1261 lemma_map_size_bound(x.difference(pre), y.remove(f(xx)), f);
1262 }
1263}
1264
1265pub broadcast proof fn lemma_set_union_again1<A>(a: Set<A>, b: Set<A>)
1269 ensures
1270 #[trigger] a.union(b).union(b) =~= a.union(b),
1271{
1272}
1273
1274pub broadcast proof fn lemma_set_union_again2<A>(a: Set<A>, b: Set<A>)
1278 ensures
1279 #[trigger] a.union(b).union(a) =~= a.union(b),
1280{
1281}
1282
1283pub broadcast proof fn lemma_set_intersect_again1<A>(a: Set<A>, b: Set<A>)
1287 ensures
1288 #![trigger (a.intersect(b)).intersect(b)]
1289 (a.intersect(b)).intersect(b) =~= a.intersect(b),
1290{
1291}
1292
1293pub broadcast proof fn lemma_set_intersect_again2<A>(a: Set<A>, b: Set<A>)
1297 ensures
1298 #![trigger (a.intersect(b)).intersect(a)]
1299 (a.intersect(b)).intersect(a) =~= a.intersect(b),
1300{
1301}
1302
1303pub broadcast proof fn lemma_set_difference2<A>(s1: Set<A>, s2: Set<A>, a: A)
1306 ensures
1307 #![trigger s1.difference(s2).contains(a)]
1308 s2.contains(a) ==> !s1.difference(s2).contains(a),
1309{
1310}
1311
1312pub broadcast proof fn lemma_set_disjoint<A>(a: Set<A>, b: Set<A>)
1316 ensures
1317 #![trigger (a + b).difference(a)] a.disjoint(b) ==> ((a + b).difference(a) =~= b && (a + b).difference(b) =~= a),
1319{
1320}
1321
1322pub broadcast proof fn lemma_set_empty_equivalency_len<A>(s: Set<A>)
1330 requires
1331 s.finite(),
1332 ensures
1333 #![trigger s.len()]
1334 (s.len() == 0 <==> s == Set::<A>::empty()) && (s.len() != 0 ==> exists|x: A| s.contains(x)),
1335{
1336 assert(s.len() == 0 ==> s =~= Set::empty()) by {
1337 if s.len() == 0 {
1338 assert(forall|a: A| !(Set::empty().contains(a)));
1339 assert(Set::<A>::empty().len() == 0);
1340 assert(Set::<A>::empty().len() == s.len());
1341 assert((exists|a: A| s.contains(a)) || (forall|a: A| !s.contains(a)));
1342 if exists|a: A| s.contains(a) {
1343 let a = s.choose();
1344 assert(s.remove(a).len() == s.len() - 1) by {
1345 axiom_set_remove_len(s, a);
1346 }
1347 }
1348 }
1349 }
1350 assert(s.len() == 0 <== s =~= Set::empty());
1351}
1352
1353pub broadcast proof fn lemma_set_disjoint_lens<A>(a: Set<A>, b: Set<A>)
1357 requires
1358 a.finite(),
1359 b.finite(),
1360 ensures
1361 a.disjoint(b) ==> #[trigger] (a + b).len() == a.len() + b.len(),
1362 decreases a.len(),
1363{
1364 if a.len() == 0 {
1365 lemma_set_empty_equivalency_len(a);
1366 assert(a + b =~= b);
1367 } else {
1368 if a.disjoint(b) {
1369 let x = a.choose();
1370 assert(a.remove(x) + b =~= (a + b).remove(x));
1371 lemma_set_disjoint_lens(a.remove(x), b);
1372 }
1373 }
1374}
1375
1376pub proof fn lemma_disjoint_iff_empty_intersection<T>(a: Set<T>, b: Set<T>)
1378 ensures
1379 a.disjoint(b) <==> a.intersect(b).is_empty(),
1380{
1381 broadcast use group_set_properties;
1382
1383 if a.disjoint(b) {
1384 assert(b.disjoint(a));
1385 assert(forall|x: T| a.contains(x) ==> !(a.contains(x) && b.contains(x)));
1386 assert(forall|x: T| b.contains(x) ==> !(a.contains(x) && b.contains(x)));
1387 assert(forall|x: T| !a.intersect(b).contains(x));
1388 }
1389 if a.intersect(b).is_empty() {
1390 assert(forall|x: T| !a.intersect(b).contains(x));
1391 if !a.disjoint(b) {
1392 assert(exists|x: T| a.contains(x) && b.contains(x));
1393 let x = choose|x: T| a.contains(x) && b.contains(x);
1394 assert(a.intersect(b).contains(x));
1395 assert(!a.intersect(b).is_empty());
1396 }
1397 }
1398}
1399
1400pub broadcast proof fn lemma_set_intersect_union_lens<A>(a: Set<A>, b: Set<A>)
1404 requires
1405 a.finite(),
1406 b.finite(),
1407 ensures
1408 #[trigger] (a + b).len() + #[trigger] a.intersect(b).len() == a.len() + b.len(),
1409 decreases a.len(),
1410{
1411 if a.len() == 0 {
1412 lemma_set_empty_equivalency_len(a);
1413 assert(a + b =~= b);
1414 assert(a.intersect(b) =~= Set::empty());
1415 assert(a.intersect(b).len() == 0);
1416 } else {
1417 let x = a.choose();
1418 lemma_set_intersect_union_lens(a.remove(x), b);
1419 if (b.contains(x)) {
1420 assert(a.remove(x) + b =~= (a + b));
1421 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1422 } else {
1423 assert(a.remove(x) + b =~= (a + b).remove(x));
1424 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1425 }
1426 }
1427}
1428
1429pub broadcast proof fn lemma_set_difference_len<A>(a: Set<A>, b: Set<A>)
1436 requires
1437 a.finite(),
1438 b.finite(),
1439 ensures
1440 (#[trigger] a.difference(b).len() + b.difference(a).len() + a.intersect(b).len() == (a
1441 + b).len()) && (a.difference(b).len() == a.len() - a.intersect(b).len()),
1442 decreases a.len(),
1443{
1444 if a.len() == 0 {
1445 lemma_set_empty_equivalency_len(a);
1446 assert(a.difference(b) =~= Set::empty());
1447 assert(b.difference(a) =~= b);
1448 assert(a.intersect(b) =~= Set::empty());
1449 assert(a + b =~= b);
1450 } else {
1451 let x = a.choose();
1452 lemma_set_difference_len(a.remove(x), b);
1453 if b.contains(x) {
1454 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1455 assert(a.remove(x).difference(b) =~= a.difference(b));
1456 assert(b.difference(a.remove(x)).remove(x) =~= b.difference(a));
1457 assert(a.remove(x) + b =~= a + b);
1458 } else {
1459 assert(a.remove(x) + b =~= (a + b).remove(x));
1460 assert(a.remove(x).difference(b) =~= a.difference(b).remove(x));
1461 assert(b.difference(a.remove(x)) =~= b.difference(a));
1462 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1463 }
1464 }
1465}
1466
1467pub broadcast group group_set_properties {
1468 lemma_set_union_again1,
1469 lemma_set_union_again2,
1470 lemma_set_intersect_again1,
1471 lemma_set_intersect_again2,
1472 lemma_set_difference2,
1473 lemma_set_disjoint,
1474 lemma_set_disjoint_lens,
1475 lemma_set_intersect_union_lens,
1476 lemma_set_difference_len,
1477 lemma_set_empty_equivalency_len,
1480}
1481
1482pub broadcast proof fn axiom_is_empty<A>(s: Set<A>)
1483 requires
1484 !(#[trigger] s.is_empty()),
1485 ensures
1486 exists|a: A| s.contains(a),
1487{
1488 admit(); }
1490
1491pub broadcast proof fn axiom_is_empty_len0<A>(s: Set<A>)
1492 ensures
1493 #[trigger] s.is_empty() <==> (s.finite() && s.len() == 0),
1494{
1495}
1496
1497#[doc(hidden)]
1498#[verifier::inline]
1499pub open spec fn check_argument_is_set<A>(s: Set<A>) -> Set<A> {
1500 s
1501}
1502
1503#[macro_export]
1517macro_rules! assert_sets_equal {
1518 [$($tail:tt)*] => {
1519 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set_lib::assert_sets_equal_internal!($($tail)*))
1520 };
1521}
1522
1523#[macro_export]
1524#[doc(hidden)]
1525macro_rules! assert_sets_equal_internal {
1526 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
1527 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1528 };
1529 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1530 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1531 };
1532 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
1533 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1534 };
1535 (crate::prelude::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1536 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1537 };
1538 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
1539 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1540 };
1541 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1542 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1543 };
1544 ($s1:expr, $s2:expr $(,)?) => {
1545 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, elem => { })
1546 };
1547 ($s1:expr, $s2:expr, $elem:ident $( : $t:ty )? => $bblock:block) => {
1548 #[verifier::spec] let s1 = $crate::vstd::set_lib::check_argument_is_set($s1);
1549 #[verifier::spec] let s2 = $crate::vstd::set_lib::check_argument_is_set($s2);
1550 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
1551 $crate::vstd::prelude::assert_forall_by(|$elem $( : $t )?| {
1552 $crate::vstd::prelude::ensures(
1553 $crate::vstd::prelude::imply(s1.contains($elem), s2.contains($elem))
1554 &&
1555 $crate::vstd::prelude::imply(s2.contains($elem), s1.contains($elem))
1556 );
1557 { $bblock }
1558 });
1559 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
1560 });
1561 }
1562}
1563
1564pub broadcast group group_set_lib_default {
1565 axiom_is_empty,
1566 axiom_is_empty_len0,
1567 lemma_set_subset_finite,
1568 Set::lemma_map_by_finite,
1569 Set::lemma_map_flatten_by_finite,
1570 range_set_properties,
1571 full_set_properties,
1572}
1573
1574pub use assert_sets_equal_internal;
1575pub use assert_sets_equal;
1576
1577}