1#[allow(unused_imports)]
2use super::iset::*;
3#[allow(unused_imports)]
4use super::map::*;
5#[allow(unused_imports)]
6use super::pervasive::*;
7#[allow(unused_imports)]
8use super::prelude::*;
9
10verus! {
11
12#[verifier::ext_equal]
31#[verifier::external_body]
32#[verifier::accept_recursive_types(A)]
33pub struct Set<A> {
34 dummy: core::marker::PhantomData<A>,
48}
49
50impl<A> Set<A> {
51 pub uninterp spec fn to_iset(self) -> ISet<A>;
53
54 uninterp spec fn make_set(s: ISet<A>) -> Set<A>;
60
61 broadcast axiom fn axiom_make_set(s: ISet<A>)
66 requires
67 s.finite(),
68 ensures
69 #![trigger Self::make_set(s).to_iset()]
70 Self::make_set(s).to_iset() == s,
71 ;
72
73 broadcast axiom fn axiom_is_finite(self)
76 ensures
77 #![trigger self.to_iset().finite()]
78 self.to_iset().finite(),
79 ;
80
81 #[rustc_diagnostic_item = "verus::vstd::set::Set::empty"]
97 pub closed spec fn empty() -> Set<A> {
98 Self::make_set(ISet::<A>::empty())
99 }
100
101 pub closed spec fn new_from_iset(s: ISet<A>) -> Option<Set<A>> {
113 if s.finite() {
114 Some(Self::make_set(s))
115 } else {
116 None
117 }
118 }
119
120 pub closed spec fn new(f: spec_fn(A) -> bool) -> Option<Set<A>> {
133 Self::new_from_iset(ISet::new(f))
134 }
135
136 #[deprecated(note = "Set::new_assuming_finite is helpful for incremental porting of existing code to the new version of Verus supporting finite sets. But it's dangerous since it assumes the given function describes a finite set.")]
146 pub closed spec fn new_assuming_finite(f: spec_fn(A) -> bool) -> Set<A> {
147 Self::make_set(ISet::new(f))
148 }
149
150 #[rustc_diagnostic_item = "verus::vstd::set::Set::full"]
153 pub open spec fn full() -> Option<Set<A>> {
154 Set::new(|a: A| true)
155 }
156
157 #[rustc_diagnostic_item = "verus::vstd::set::Set::contains"]
159 #[verifier::inline]
160 pub open spec fn contains(self, a: A) -> bool {
161 self.to_iset().contains(a)
162 }
163
164 #[verifier::inline]
166 pub open spec fn spec_has(self, a: A) -> bool {
167 self.contains(a)
168 }
169
170 #[rustc_diagnostic_item = "verus::vstd::set::Set::subset_of"]
172 pub open spec fn subset_of(self, s2: Set<A>) -> bool {
173 forall|a: A| self.contains(a) ==> s2.contains(a)
174 }
175
176 #[verifier::inline]
177 pub open spec fn spec_le(self, s2: Set<A>) -> bool {
178 self.subset_of(s2)
179 }
180
181 #[rustc_diagnostic_item = "verus::vstd::set::Set::insert"]
184 pub closed spec fn insert(self, a: A) -> Set<A> {
185 Self::make_set(self.to_iset().insert(a))
186 }
187
188 #[rustc_diagnostic_item = "verus::vstd::set::Set::remove"]
191 pub closed spec fn remove(self, a: A) -> Set<A> {
192 Self::make_set(self.to_iset().remove(a))
193 }
194
195 pub closed spec fn union(self, s2: Set<A>) -> Set<A> {
197 Self::make_set(self.to_iset().union(s2.to_iset()))
198 }
199
200 #[verifier::inline]
202 pub open spec fn spec_add(self, s2: Set<A>) -> Set<A> {
203 self.union(s2)
204 }
205
206 pub closed spec fn intersect(self, s2: Set<A>) -> Set<A> {
208 Self::make_set(self.to_iset().intersect(s2.to_iset()))
209 }
210
211 #[verifier::inline]
213 pub open spec fn spec_mul(self, s2: Set<A>) -> Set<A> {
214 self.intersect(s2)
215 }
216
217 pub closed spec fn difference(self, s2: Set<A>) -> Set<A> {
219 Self::make_set(self.to_iset().difference(s2.to_iset()))
220 }
221
222 #[verifier::inline]
224 pub open spec fn spec_sub(self, s2: Set<A>) -> Set<A> {
225 self.difference(s2)
226 }
227
228 pub open spec fn complement(self) -> Option<Set<A>> {
231 Set::new(|a| !self.contains(a))
232 }
233
234 pub closed spec fn filter(self, f: spec_fn(A) -> bool) -> Set<A> {
236 Self::make_set(self.to_iset().filter(f))
237 }
238
239 #[deprecated(note = "Every Set is always finite, so this is always true.")]
241 pub open spec fn finite(self) -> bool {
242 true
243 }
244
245 pub open spec fn congruent(self, s2: ISet<A>) -> bool {
248 forall|a: A| #![all_triggers] self.contains(a) <==> s2.contains(a)
249 }
250
251 pub closed spec fn len(self) -> nat {
253 self.to_iset().len()
254 }
255
256 pub open spec fn choose(self) -> A {
263 choose|a: A| self.contains(a)
264 }
265
266 pub open spec fn disjoint(self, s2: Self) -> bool {
269 forall|a: A| self.contains(a) ==> !s2.contains(a)
270 }
271}
272
273pub broadcast proof fn axiom_set_ext_equal<A>(s1: Set<A>, s2: Set<A>)
276 ensures
277 #[trigger] (s1 =~= s2) <==> (forall|a: A| s1.contains(a) == s2.contains(a)),
278{
279 admit();
280}
281
282pub broadcast proof fn axiom_set_ext_equal_deep<A>(s1: Set<A>, s2: Set<A>)
285 ensures
286 #[trigger] (s1 =~~= s2) <==> s1 =~= s2,
287{
288 admit();
289}
290
291broadcast use super::iset::group_iset_lemmas;
292
293pub mod fold {
294 use super::*;
295
296 impl<A> Set<A> {
297 #[verifier::inline]
303 pub open spec fn fold<B>(self, z: B, f: spec_fn(B, A) -> B) -> B
304 recommends
305 super::super::iset::fold::is_fun_commutative(f),
306 {
307 self.to_iset().fold(z, f)
308 }
309 }
310
311}
312
313pub broadcast proof fn lemma_set_empty<A>(a: A)
315 ensures
316 !(#[trigger] Set::empty().contains(a)),
317{
318 broadcast use Set::axiom_make_set;
319
320}
321
322pub broadcast proof fn lemma_set_new<A>(f: spec_fn(A) -> bool, a: A)
325 requires
326 Set::<A>::new(f) is Some,
327 ensures
328 #[trigger] Set::<A>::new(f).unwrap().contains(a) == f(a),
329{
330 broadcast use Set::axiom_make_set;
331
332}
333
334pub broadcast proof fn lemma_set_new_some<A>(f: spec_fn(A) -> bool)
338 requires
339 ISet::<A>::new(f).finite(),
340 ensures
341 #[trigger] Set::<A>::new(f) is Some,
342{
343 broadcast use Set::axiom_make_set;
344
345}
346
347#[allow(deprecated)]
350pub broadcast proof fn lemma_set_new_assuming_finite<A>(f: spec_fn(A) -> bool, a: A)
351 ensures
352 #[trigger] Set::<A>::new_assuming_finite(f).contains(a) == f(a),
353{
354 broadcast use Set::axiom_make_set;
355
356 assume(ISet::new(f).finite()); }
358
359pub broadcast proof fn lemma_set_new_from_iset<A>(s: ISet<A>)
362 requires
363 s.finite(),
364 ensures
365 #![trigger Set::<A>::new_from_iset(s)]
366 Set::<A>::new_from_iset(s) is Some,
367 Set::<A>::new_from_iset(s).unwrap().to_iset() == s,
368{
369 broadcast use Set::axiom_make_set;
370
371 assert(ISet::new(|a: A| s.contains(a)) =~= s);
372}
373
374pub broadcast proof fn lemma_set_insert_same<A>(s: Set<A>, a: A)
376 ensures
377 #[trigger] s.insert(a).contains(a),
378{
379 broadcast use Set::axiom_make_set;
380 broadcast use Set::axiom_is_finite;
381
382}
383
384pub broadcast proof fn lemma_set_insert_different<A>(s: Set<A>, a1: A, a2: A)
387 requires
388 a1 != a2,
389 ensures
390 #[trigger] s.insert(a2).contains(a1) == s.contains(a1),
391{
392 broadcast use Set::axiom_make_set;
393 broadcast use Set::axiom_is_finite;
394
395}
396
397pub broadcast proof fn lemma_set_remove_same<A>(s: Set<A>, a: A)
399 ensures
400 !(#[trigger] s.remove(a).contains(a)),
401{
402 broadcast use Set::axiom_make_set;
403 broadcast use Set::axiom_is_finite;
404
405}
406
407pub broadcast proof fn lemma_set_remove_insert<A>(s: Set<A>, a: A)
410 requires
411 s.contains(a),
412 ensures
413 (#[trigger] s.remove(a)).insert(a) == s,
414{
415 assert forall|aa| #![all_triggers] s.remove(a).insert(a).contains(aa) implies s.contains(
416 aa,
417 ) by {
418 if a == aa {
419 } else {
420 lemma_set_remove_different(s, aa, a);
421 lemma_set_insert_different(s.remove(a), aa, a);
422 }
423 };
424 assert forall|aa| #![all_triggers] s.contains(aa) implies s.remove(a).insert(a).contains(
425 aa,
426 ) by {
427 if a == aa {
428 lemma_set_insert_same(s.remove(a), a);
429 } else {
430 lemma_set_remove_different(s, aa, a);
431 lemma_set_insert_different(s.remove(a), aa, a);
432 }
433 };
434 axiom_set_ext_equal(s.remove(a).insert(a), s);
435}
436
437pub broadcast proof fn lemma_set_remove_different<A>(s: Set<A>, a1: A, a2: A)
440 requires
441 a1 != a2,
442 ensures
443 #[trigger] s.remove(a2).contains(a1) == s.contains(a1),
444{
445 broadcast use axiom_set_ext_equal;
446 broadcast use Set::axiom_make_set;
447 broadcast use Set::axiom_is_finite;
448
449}
450
451pub broadcast proof fn lemma_set_union<A>(s1: Set<A>, s2: Set<A>, a: A)
454 ensures
455 #[trigger] s1.union(s2).contains(a) == (s1.contains(a) || s2.contains(a)),
456{
457 broadcast use axiom_set_ext_equal;
458 broadcast use Set::axiom_make_set;
459 broadcast use Set::axiom_is_finite;
460
461}
462
463pub broadcast proof fn lemma_set_intersect<A>(s1: Set<A>, s2: Set<A>, a: A)
466 ensures
467 #[trigger] s1.intersect(s2).contains(a) == (s1.contains(a) && s2.contains(a)),
468{
469 broadcast use axiom_set_ext_equal;
470 broadcast use Set::axiom_make_set;
471 broadcast use Set::axiom_is_finite;
472
473}
474
475pub broadcast proof fn lemma_set_difference<A>(s1: Set<A>, s2: Set<A>, a: A)
478 ensures
479 #[trigger] s1.difference(s2).contains(a) == (s1.contains(a) && !s2.contains(a)),
480{
481 broadcast use Set::axiom_make_set;
482 broadcast use Set::axiom_is_finite;
483
484}
485
486pub broadcast proof fn lemma_set_complement<A>(s: Set<A>, a: A)
488 requires
489 ISet::new(|a| !s.contains(a)).finite(),
490 ensures
491 #[trigger] s.complement().unwrap().contains(a) == !s.contains(a),
492{
493 broadcast use Set::axiom_make_set;
494
495}
496
497pub broadcast proof fn lemma_set_filter<A>(s: Set<A>, f: spec_fn(A) -> bool, a: A)
500 ensures
501 #[trigger] s.filter(f).contains(a) == (s.contains(a) && f(a)),
502{
503 broadcast use Set::axiom_make_set;
504 broadcast use Set::axiom_is_finite;
505
506}
507
508pub broadcast proof fn lemma_set_empty_len<A>()
512 ensures
513 #[trigger] Set::<A>::empty().len() == 0,
514{
515 broadcast use Set::axiom_make_set;
516
517}
518
519pub broadcast proof fn lemma_set_insert_len<A>(s: Set<A>, a: A)
522 ensures
523 #[trigger] s.insert(a).len() == s.len() + (if s.contains(a) {
524 0int
525 } else {
526 1
527 }),
528{
529 broadcast use Set::axiom_make_set;
530 broadcast use Set::axiom_is_finite;
531
532}
533
534pub broadcast proof fn lemma_set_remove_len<A>(s: Set<A>, a: A)
537 ensures
538 s.len() == #[trigger] s.remove(a).len() + (if s.contains(a) {
539 1int
540 } else {
541 0
542 }),
543{
544 broadcast use Set::axiom_make_set;
545 broadcast use Set::axiom_is_finite;
546
547}
548
549pub broadcast proof fn lemma_set_contains_len<A>(s: Set<A>, a: A)
551 requires
552 #[trigger] s.contains(a),
553 ensures
554 #[trigger] s.len() != 0,
555{
556 broadcast use Set::axiom_make_set;
557 broadcast use Set::axiom_is_finite;
558
559}
560
561pub broadcast proof fn lemma_set_choose_len<A>(s: Set<A>)
563 requires
564 #[trigger] s.len() != 0,
565 ensures
566 #[trigger] s.contains(s.choose()),
567{
568 assert(s.to_iset().contains(s.to_iset().choose()));
569}
570
571pub broadcast proof fn lemma_to_iset_finite<A>(s: Set<A>)
573 ensures
574 #[trigger] s.to_iset().finite(),
575{
576 broadcast use Set::axiom_make_set;
577 broadcast use Set::axiom_is_finite;
578
579}
580
581pub broadcast proof fn lemma_to_iset_len<A>(s: Set<A>)
584 ensures
585 #[trigger] s.to_iset().len() == s.len(),
586{
587 broadcast use Set::axiom_make_set;
588 broadcast use Set::axiom_is_finite;
589
590}
591
592pub broadcast group group_set_lemmas {
593 axiom_set_ext_equal,
594 axiom_set_ext_equal_deep,
595 lemma_set_empty,
596 lemma_set_new,
597 lemma_set_new_assuming_finite,
598 lemma_set_new_from_iset,
599 lemma_set_new_some,
600 lemma_set_insert_same,
601 lemma_set_insert_different,
602 lemma_set_remove_same,
603 lemma_set_remove_insert,
604 lemma_set_remove_different,
605 lemma_set_union,
606 lemma_set_intersect,
607 lemma_set_difference,
608 lemma_set_complement,
609 lemma_set_filter,
610 lemma_set_empty_len,
611 lemma_set_insert_len,
612 lemma_set_remove_len,
613 lemma_set_contains_len,
614 lemma_set_choose_len,
615 lemma_set_new,
616 lemma_to_iset_finite,
617 lemma_to_iset_len,
618}
619
620#[doc(hidden)]
622#[macro_export]
623macro_rules! set_internal {
624 [$($elem:expr),* $(,)?] => {
625 $crate::vstd::set::Set::empty()
626 $(.insert($elem))*
627 };
628}
629
630#[macro_export]
631macro_rules! set {
632 [$($tail:tt)*] => {
633 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set::set_internal!($($tail)*))
634 };
635}
636
637pub use set_internal;
638pub use set;
639
640}