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 broadcast proof fn lemma_set_insert_finite_iff<A>(s: Set<A>, a: A)
963 ensures
964 #[trigger] s.insert(a).finite() <==> s.finite(),
965{
966 if s.insert(a).finite() {
967 if s.contains(a) {
968 assert(s == s.insert(a));
969 } else {
970 assert(s == s.insert(a).remove(a));
971 }
972 }
973 assert(s.insert(a).finite() ==> s.finite());
974}
975
976pub broadcast proof fn lemma_set_remove_finite_iff<A>(s: Set<A>, a: A)
978 ensures
979 #[trigger] s.remove(a).finite() <==> s.finite(),
980{
981 if s.remove(a).finite() {
982 if s.contains(a) {
983 assert(s == s.remove(a).insert(a));
984 } else {
985 assert(s == s.remove(a));
986 }
987 }
988}
989
990pub broadcast proof fn lemma_set_union_finite_iff<A>(s1: Set<A>, s2: Set<A>)
992 ensures
993 #[trigger] s1.union(s2).finite() <==> s1.finite() && s2.finite(),
994{
995 if s1.union(s2).finite() {
996 lemma_set_union_finite_implies_sets_finite(s1, s2);
997 }
998}
999
1000pub proof fn lemma_set_union_finite_implies_sets_finite<A>(s1: Set<A>, s2: Set<A>)
1001 requires
1002 s1.union(s2).finite(),
1003 ensures
1004 s1.finite(),
1005 s2.finite(),
1006 decreases s1.union(s2).len(),
1007{
1008 if s1.union(s2) =~= set![] {
1009 assert(s1 =~= set![]);
1010 assert(s2 =~= set![]);
1011 } else {
1012 let a = s1.union(s2).choose();
1013 assert(s1.remove(a).union(s2.remove(a)) == s1.union(s2).remove(a));
1014 axiom_set_remove_len(s1.union(s2), a);
1015 lemma_set_union_finite_implies_sets_finite(s1.remove(a), s2.remove(a));
1016 assert(forall|s: Set<A>|
1017 #![auto]
1018 s.remove(a).insert(a) == if s.contains(a) {
1019 s
1020 } else {
1021 s.insert(a)
1022 });
1023 lemma_set_insert_finite_iff(s1, a);
1024 lemma_set_insert_finite_iff(s2, a);
1025 }
1026}
1027
1028pub proof fn lemma_len_union<A>(s1: Set<A>, s2: Set<A>)
1031 requires
1032 s1.finite(),
1033 s2.finite(),
1034 ensures
1035 s1.union(s2).len() <= s1.len() + s2.len(),
1036 decreases s1.len(),
1037{
1038 if s1.is_empty() {
1039 assert(s1.union(s2) =~= s2);
1040 } else {
1041 let a = s1.choose();
1042 if s2.contains(a) {
1043 assert(s1.union(s2) =~= s1.remove(a).union(s2));
1044 } else {
1045 assert(s1.union(s2).remove(a) =~= s1.remove(a).union(s2));
1046 }
1047 lemma_len_union::<A>(s1.remove(a), s2);
1048 }
1049}
1050
1051pub proof fn lemma_len_union_ind<A>(s1: Set<A>, s2: Set<A>)
1054 requires
1055 s1.finite(),
1056 s2.finite(),
1057 ensures
1058 s1.union(s2).len() >= s1.len(),
1059 s1.union(s2).len() >= s2.len(),
1060 decreases s2.len(),
1061{
1062 broadcast use group_set_properties;
1063
1064 if s2.len() == 0 {
1065 } else {
1066 let y = choose|y: A| s2.contains(y);
1067 if s1.contains(y) {
1068 assert(s1.remove(y).union(s2.remove(y)) =~= s1.union(s2).remove(y));
1069 lemma_len_union_ind(s1.remove(y), s2.remove(y))
1070 } else {
1071 assert(s1.union(s2.remove(y)) =~= s1.union(s2).remove(y));
1072 lemma_len_union_ind(s1, s2.remove(y))
1073 }
1074 }
1075}
1076
1077pub proof fn lemma_len_intersect<A>(s1: Set<A>, s2: Set<A>)
1079 requires
1080 s1.finite(),
1081 ensures
1082 s1.intersect(s2).len() <= s1.len(),
1083 decreases s1.len(),
1084{
1085 if s1.is_empty() {
1086 assert(s1.intersect(s2) =~= s1);
1087 } else {
1088 let a = s1.choose();
1089 assert(s1.intersect(s2).remove(a) =~= s1.remove(a).intersect(s2));
1090 lemma_len_intersect::<A>(s1.remove(a), s2);
1091 }
1092}
1093
1094pub proof fn lemma_len_subset<A>(s1: Set<A>, s2: Set<A>)
1097 requires
1098 s2.finite(),
1099 s1.subset_of(s2),
1100 ensures
1101 s1.len() <= s2.len(),
1102 s1.finite(),
1103{
1104 lemma_len_intersect::<A>(s2, s1);
1105 assert(s2.intersect(s1) =~= s1);
1106}
1107
1108pub broadcast proof fn lemma_set_subset_finite<A>(s: Set<A>, sub: Set<A>)
1110 requires
1111 s.finite(),
1112 sub.subset_of(s),
1113 ensures
1114 #![trigger sub.subset_of(s)]
1115 sub.finite(),
1116{
1117 let complement = s.difference(sub);
1118 assert(sub =~= s.difference(complement));
1119}
1120
1121pub proof fn lemma_len_difference<A>(s1: Set<A>, s2: Set<A>)
1123 requires
1124 s1.finite(),
1125 ensures
1126 s1.difference(s2).len() <= s1.len(),
1127 decreases s1.len(),
1128{
1129 if s1.is_empty() {
1130 assert(s1.difference(s2) =~= s1);
1131 } else {
1132 let a = s1.choose();
1133 assert(s1.difference(s2).remove(a) =~= s1.remove(a).difference(s2));
1134 lemma_len_difference::<A>(s1.remove(a), s2);
1135 }
1136}
1137
1138pub open spec fn set_int_range(lo: int, hi: int) -> Set<int> {
1140 Set::new(|i: int| lo <= i && i < hi)
1141}
1142
1143pub proof fn lemma_int_range(lo: int, hi: int)
1146 requires
1147 lo <= hi,
1148 ensures
1149 set_int_range(lo, hi).finite(),
1150 set_int_range(lo, hi).len() == hi - lo,
1151 decreases hi - lo,
1152{
1153 if lo == hi {
1154 assert(set_int_range(lo, hi) =~= Set::empty());
1155 } else {
1156 lemma_int_range(lo, hi - 1);
1157 assert(set_int_range(lo, hi - 1).insert(hi - 1) =~= set_int_range(lo, hi));
1158 }
1159}
1160
1161pub proof fn lemma_subset_equality<A>(x: Set<A>, y: Set<A>)
1163 requires
1164 x.subset_of(y),
1165 x.finite(),
1166 y.finite(),
1167 x.len() == y.len(),
1168 ensures
1169 x =~= y,
1170 decreases x.len(),
1171{
1172 broadcast use group_set_properties;
1173
1174 if x =~= Set::<A>::empty() {
1175 } else {
1176 let e = x.choose();
1177 lemma_subset_equality(x.remove(e), y.remove(e));
1178 }
1179}
1180
1181pub proof fn lemma_map_size<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
1184 requires
1185 x.finite(),
1186 injective_on(f, x),
1187 x.map(f) == y,
1188 ensures
1189 y.finite(),
1190 x.len() == y.len(),
1191 decreases x.len(),
1192{
1193 broadcast use group_set_properties;
1194
1195 if x.len() == 0 {
1196 if !y.is_empty() {
1197 let e = y.choose();
1198 }
1199 } else {
1200 let a = x.choose();
1201 assert(x.remove(a).map(f) == y.remove(f(a)));
1202 lemma_map_size(x.remove(a), y.remove(f(a)), f);
1203 assert(y == y.remove(f(a)).insert(f(a)));
1204 }
1205}
1206
1207pub proof fn lemma_map_size_bound<A, B>(x: Set<A>, y: Set<B>, f: spec_fn(A) -> B)
1210 requires
1211 x.finite(),
1212 x.map(f) == y,
1213 ensures
1214 y.finite(),
1215 y.len() <= x.len(),
1216 decreases x.len(),
1217{
1218 broadcast use group_set_properties;
1219
1220 if x.is_empty() {
1221 if !y.is_empty() {
1222 let e = y.choose();
1223 }
1224 } else {
1225 let xx = x.choose();
1226 let img = f(xx);
1227 let pre = x.filter(|a: A| f(a) == f(xx));
1228 x.lemma_len_filter(|a: A| f(a) == f(xx));
1229 let wit = choose|a: A| x.contains(a) && f(a) == f(xx);
1230 assert forall|b: B| (#[trigger] y.remove(f(xx)).contains(b)) implies exists|a: A|
1231 x.difference(pre).contains(a) && f(a) == b by {
1232 let pre_wit = choose|a: A| x.contains(a) && f(a) == b;
1233 assert(x.difference(pre).contains(pre_wit));
1234 }
1235
1236 assert(x == x.difference(pre).union(pre));
1237 assert(y == y.remove(f(xx)).insert(f(xx)));
1238 assert(x.difference(pre).map(f) == y.remove(f(xx)));
1239 lemma_map_size_bound(x.difference(pre), y.remove(f(xx)), f);
1240 }
1241}
1242
1243pub broadcast proof fn lemma_set_union_again1<A>(a: Set<A>, b: Set<A>)
1247 ensures
1248 #[trigger] a.union(b).union(b) =~= a.union(b),
1249{
1250}
1251
1252pub broadcast proof fn lemma_set_union_again2<A>(a: Set<A>, b: Set<A>)
1256 ensures
1257 #[trigger] a.union(b).union(a) =~= a.union(b),
1258{
1259}
1260
1261pub broadcast proof fn lemma_set_intersect_again1<A>(a: Set<A>, b: Set<A>)
1265 ensures
1266 #![trigger (a.intersect(b)).intersect(b)]
1267 (a.intersect(b)).intersect(b) =~= a.intersect(b),
1268{
1269}
1270
1271pub broadcast proof fn lemma_set_intersect_again2<A>(a: Set<A>, b: Set<A>)
1275 ensures
1276 #![trigger (a.intersect(b)).intersect(a)]
1277 (a.intersect(b)).intersect(a) =~= a.intersect(b),
1278{
1279}
1280
1281pub broadcast proof fn lemma_set_difference2<A>(s1: Set<A>, s2: Set<A>, a: A)
1284 ensures
1285 #![trigger s1.difference(s2).contains(a)]
1286 s2.contains(a) ==> !s1.difference(s2).contains(a),
1287{
1288}
1289
1290pub broadcast proof fn lemma_set_disjoint<A>(a: Set<A>, b: Set<A>)
1294 ensures
1295 #![trigger (a + b).difference(a)] a.disjoint(b) ==> ((a + b).difference(a) =~= b && (a + b).difference(b) =~= a),
1297{
1298}
1299
1300pub broadcast proof fn lemma_set_empty_equivalency_len<A>(s: Set<A>)
1308 requires
1309 s.finite(),
1310 ensures
1311 #![trigger s.len()]
1312 (s.len() == 0 <==> s == Set::<A>::empty()) && (s.len() != 0 ==> exists|x: A| s.contains(x)),
1313{
1314 assert(s.len() == 0 ==> s =~= Set::empty()) by {
1315 if s.len() == 0 {
1316 assert(forall|a: A| !(Set::empty().contains(a)));
1317 assert(Set::<A>::empty().len() == 0);
1318 assert(Set::<A>::empty().len() == s.len());
1319 assert((exists|a: A| s.contains(a)) || (forall|a: A| !s.contains(a)));
1320 if exists|a: A| s.contains(a) {
1321 let a = s.choose();
1322 assert(s.remove(a).len() == s.len() - 1) by {
1323 axiom_set_remove_len(s, a);
1324 }
1325 }
1326 }
1327 }
1328 assert(s.len() == 0 <== s =~= Set::empty());
1329}
1330
1331pub broadcast proof fn lemma_set_disjoint_lens<A>(a: Set<A>, b: Set<A>)
1335 requires
1336 a.finite(),
1337 b.finite(),
1338 ensures
1339 a.disjoint(b) ==> #[trigger] (a + b).len() == a.len() + b.len(),
1340 decreases a.len(),
1341{
1342 if a.len() == 0 {
1343 lemma_set_empty_equivalency_len(a);
1344 assert(a + b =~= b);
1345 } else {
1346 if a.disjoint(b) {
1347 let x = a.choose();
1348 assert(a.remove(x) + b =~= (a + b).remove(x));
1349 lemma_set_disjoint_lens(a.remove(x), b);
1350 }
1351 }
1352}
1353
1354pub proof fn lemma_disjoint_iff_empty_intersection<T>(a: Set<T>, b: Set<T>)
1356 ensures
1357 a.disjoint(b) <==> a.intersect(b).is_empty(),
1358{
1359 broadcast use group_set_properties;
1360
1361 if a.disjoint(b) {
1362 assert(b.disjoint(a));
1363 assert(forall|x: T| a.contains(x) ==> !(a.contains(x) && b.contains(x)));
1364 assert(forall|x: T| b.contains(x) ==> !(a.contains(x) && b.contains(x)));
1365 assert(forall|x: T| !a.intersect(b).contains(x));
1366 }
1367 if a.intersect(b).is_empty() {
1368 assert(forall|x: T| !a.intersect(b).contains(x));
1369 if !a.disjoint(b) {
1370 assert(exists|x: T| a.contains(x) && b.contains(x));
1371 let x = choose|x: T| a.contains(x) && b.contains(x);
1372 assert(a.intersect(b).contains(x));
1373 assert(!a.intersect(b).is_empty());
1374 }
1375 }
1376}
1377
1378pub broadcast proof fn lemma_set_intersect_union_lens<A>(a: Set<A>, b: Set<A>)
1382 requires
1383 a.finite(),
1384 b.finite(),
1385 ensures
1386 #[trigger] (a + b).len() + #[trigger] a.intersect(b).len() == a.len() + b.len(),
1387 decreases a.len(),
1388{
1389 if a.len() == 0 {
1390 lemma_set_empty_equivalency_len(a);
1391 assert(a + b =~= b);
1392 assert(a.intersect(b) =~= Set::empty());
1393 assert(a.intersect(b).len() == 0);
1394 } else {
1395 let x = a.choose();
1396 lemma_set_intersect_union_lens(a.remove(x), b);
1397 if (b.contains(x)) {
1398 assert(a.remove(x) + b =~= (a + b));
1399 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1400 } else {
1401 assert(a.remove(x) + b =~= (a + b).remove(x));
1402 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1403 }
1404 }
1405}
1406
1407pub broadcast proof fn lemma_set_difference_len<A>(a: Set<A>, b: Set<A>)
1414 requires
1415 a.finite(),
1416 b.finite(),
1417 ensures
1418 (#[trigger] a.difference(b).len() + b.difference(a).len() + a.intersect(b).len() == (a
1419 + b).len()) && (a.difference(b).len() == a.len() - a.intersect(b).len()),
1420 decreases a.len(),
1421{
1422 if a.len() == 0 {
1423 lemma_set_empty_equivalency_len(a);
1424 assert(a.difference(b) =~= Set::empty());
1425 assert(b.difference(a) =~= b);
1426 assert(a.intersect(b) =~= Set::empty());
1427 assert(a + b =~= b);
1428 } else {
1429 let x = a.choose();
1430 lemma_set_difference_len(a.remove(x), b);
1431 if b.contains(x) {
1432 assert(a.intersect(b).remove(x) =~= a.remove(x).intersect(b));
1433 assert(a.remove(x).difference(b) =~= a.difference(b));
1434 assert(b.difference(a.remove(x)).remove(x) =~= b.difference(a));
1435 assert(a.remove(x) + b =~= a + b);
1436 } else {
1437 assert(a.remove(x) + b =~= (a + b).remove(x));
1438 assert(a.remove(x).difference(b) =~= a.difference(b).remove(x));
1439 assert(b.difference(a.remove(x)) =~= b.difference(a));
1440 assert(a.remove(x).intersect(b) =~= a.intersect(b));
1441 }
1442 }
1443}
1444
1445pub broadcast group group_set_properties {
1446 lemma_set_union_again1,
1447 lemma_set_union_again2,
1448 lemma_set_intersect_again1,
1449 lemma_set_intersect_again2,
1450 lemma_set_difference2,
1451 lemma_set_disjoint,
1452 lemma_set_disjoint_lens,
1453 lemma_set_intersect_union_lens,
1454 lemma_set_difference_len,
1455 lemma_set_empty_equivalency_len,
1458}
1459
1460pub broadcast proof fn axiom_is_empty<A>(s: Set<A>)
1461 requires
1462 !(#[trigger] s.is_empty()),
1463 ensures
1464 exists|a: A| s.contains(a),
1465{
1466 admit(); }
1468
1469pub broadcast proof fn axiom_is_empty_len0<A>(s: Set<A>)
1470 ensures
1471 #[trigger] s.is_empty() <==> (s.finite() && s.len() == 0),
1472{
1473}
1474
1475#[doc(hidden)]
1476#[verifier::inline]
1477pub open spec fn check_argument_is_set<A>(s: Set<A>) -> Set<A> {
1478 s
1479}
1480
1481#[macro_export]
1495macro_rules! assert_sets_equal {
1496 [$($tail:tt)*] => {
1497 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set_lib::assert_sets_equal_internal!($($tail)*))
1498 };
1499}
1500
1501#[macro_export]
1502#[doc(hidden)]
1503macro_rules! assert_sets_equal_internal {
1504 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
1505 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1506 };
1507 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1508 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1509 };
1510 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
1511 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1512 };
1513 (crate::prelude::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1514 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1515 };
1516 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
1517 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2)
1518 };
1519 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $elem:ident $( : $t:ty )? => $bblock:block) => {
1520 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, $elem $( : $t )? => $bblock)
1521 };
1522 ($s1:expr, $s2:expr $(,)?) => {
1523 $crate::vstd::set_lib::assert_sets_equal_internal!($s1, $s2, elem => { })
1524 };
1525 ($s1:expr, $s2:expr, $elem:ident $( : $t:ty )? => $bblock:block) => {
1526 #[verifier::spec] let s1 = $crate::vstd::set_lib::check_argument_is_set($s1);
1527 #[verifier::spec] let s2 = $crate::vstd::set_lib::check_argument_is_set($s2);
1528 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
1529 $crate::vstd::prelude::assert_forall_by(|$elem $( : $t )?| {
1530 $crate::vstd::prelude::ensures(
1531 $crate::vstd::prelude::imply(s1.contains($elem), s2.contains($elem))
1532 &&
1533 $crate::vstd::prelude::imply(s2.contains($elem), s1.contains($elem))
1534 );
1535 { $bblock }
1536 });
1537 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
1538 });
1539 }
1540}
1541
1542pub broadcast group group_set_lib_default {
1543 axiom_is_empty,
1544 axiom_is_empty_len0,
1545 lemma_set_subset_finite,
1546 Set::lemma_map_by_finite,
1547 Set::lemma_map_flatten_by_finite,
1548 range_set_properties,
1549 full_set_properties,
1550}
1551
1552pub use assert_sets_equal_internal;
1553pub use assert_sets_equal;
1554
1555}