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)]
33#[cfg_attr(verus_keep_ghost, rustc_diagnostic_item = "verus::vstd::set::Set")]
34pub struct Set<A> {
35 dummy: core::marker::PhantomData<A>,
49}
50
51impl<A> Set<A> {
52 pub uninterp spec fn to_iset(self) -> ISet<A>;
54
55 uninterp spec fn make_set(s: ISet<A>) -> Set<A>;
61
62 broadcast axiom fn axiom_make_set(s: ISet<A>)
67 requires
68 s.finite(),
69 ensures
70 #![trigger Self::make_set(s).to_iset()]
71 Self::make_set(s).to_iset() == s,
72 ;
73
74 broadcast axiom fn axiom_is_finite(self)
77 ensures
78 #![trigger self.to_iset().finite()]
79 self.to_iset().finite(),
80 ;
81
82 #[rustc_diagnostic_item = "verus::vstd::set::Set::empty"]
98 pub closed spec fn empty() -> Set<A> {
99 Self::make_set(ISet::<A>::empty())
100 }
101
102 pub closed spec fn new_from_iset(s: ISet<A>) -> Option<Set<A>> {
114 if s.finite() {
115 Some(Self::make_set(s))
116 } else {
117 None
118 }
119 }
120
121 pub closed spec fn new(f: spec_fn(A) -> bool) -> Option<Set<A>> {
134 Self::new_from_iset(ISet::new(f))
135 }
136
137 #[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.")]
147 pub closed spec fn new_assuming_finite(f: spec_fn(A) -> bool) -> Set<A> {
148 Self::make_set(ISet::new(f))
149 }
150
151 #[rustc_diagnostic_item = "verus::vstd::set::Set::full"]
154 pub open spec fn full() -> Option<Set<A>> {
155 Set::new(|a: A| true)
156 }
157
158 #[rustc_diagnostic_item = "verus::vstd::set::Set::contains"]
160 #[verifier::inline]
161 pub open spec fn contains(self, a: A) -> bool {
162 self.to_iset().contains(a)
163 }
164
165 #[verifier::inline]
167 pub open spec fn spec_has(self, a: A) -> bool {
168 self.contains(a)
169 }
170
171 #[rustc_diagnostic_item = "verus::vstd::set::Set::subset_of"]
173 pub open spec fn subset_of(self, s2: Set<A>) -> bool {
174 forall|a: A| self.contains(a) ==> s2.contains(a)
175 }
176
177 #[verifier::inline]
178 pub open spec fn spec_le(self, s2: Set<A>) -> bool {
179 self.subset_of(s2)
180 }
181
182 #[rustc_diagnostic_item = "verus::vstd::set::Set::insert"]
185 pub closed spec fn insert(self, a: A) -> Set<A> {
186 Self::make_set(self.to_iset().insert(a))
187 }
188
189 #[rustc_diagnostic_item = "verus::vstd::set::Set::remove"]
192 pub closed spec fn remove(self, a: A) -> Set<A> {
193 Self::make_set(self.to_iset().remove(a))
194 }
195
196 pub closed spec fn union(self, s2: Set<A>) -> Set<A> {
198 Self::make_set(self.to_iset().union(s2.to_iset()))
199 }
200
201 #[verifier::inline]
203 pub open spec fn spec_add(self, s2: Set<A>) -> Set<A> {
204 self.union(s2)
205 }
206
207 pub closed spec fn intersect(self, s2: Set<A>) -> Set<A> {
209 Self::make_set(self.to_iset().intersect(s2.to_iset()))
210 }
211
212 #[verifier::inline]
214 pub open spec fn spec_mul(self, s2: Set<A>) -> Set<A> {
215 self.intersect(s2)
216 }
217
218 pub closed spec fn difference(self, s2: Set<A>) -> Set<A> {
220 Self::make_set(self.to_iset().difference(s2.to_iset()))
221 }
222
223 #[verifier::inline]
225 pub open spec fn spec_sub(self, s2: Set<A>) -> Set<A> {
226 self.difference(s2)
227 }
228
229 pub open spec fn complement(self) -> Option<Set<A>> {
232 Set::new(|a| !self.contains(a))
233 }
234
235 pub closed spec fn filter(self, f: spec_fn(A) -> bool) -> Set<A> {
237 Self::make_set(self.to_iset().filter(f))
238 }
239
240 #[deprecated(note = "Every Set is always finite, so this is always true.")]
242 pub open spec fn finite(self) -> bool {
243 true
244 }
245
246 pub open spec fn congruent(self, s2: ISet<A>) -> bool {
249 forall|a: A| #![all_triggers] self.contains(a) <==> s2.contains(a)
250 }
251
252 pub closed spec fn len(self) -> nat {
254 self.to_iset().len()
255 }
256
257 pub open spec fn choose(self) -> A {
264 choose|a: A| self.contains(a)
265 }
266
267 pub open spec fn disjoint(self, s2: Self) -> bool {
270 forall|a: A| self.contains(a) ==> !s2.contains(a)
271 }
272}
273
274pub broadcast proof fn axiom_set_ext_equal<A>(s1: Set<A>, s2: Set<A>)
277 ensures
278 #[trigger] (s1 =~= s2) <==> (forall|a: A| s1.contains(a) == s2.contains(a)),
279{
280 admit();
281}
282
283pub broadcast proof fn axiom_set_ext_equal_deep<A>(s1: Set<A>, s2: Set<A>)
286 ensures
287 #[trigger] (s1 =~~= s2) <==> s1 =~= s2,
288{
289 admit();
290}
291
292broadcast use super::iset::group_iset_lemmas;
293
294pub mod fold {
295 use super::*;
296
297 impl<A> Set<A> {
298 #[verifier::inline]
304 pub open spec fn fold<B>(self, z: B, f: spec_fn(B, A) -> B) -> B
305 recommends
306 super::super::iset::fold::is_fun_commutative(f),
307 {
308 self.to_iset().fold(z, f)
309 }
310 }
311
312}
313
314pub broadcast proof fn lemma_set_empty<A>(a: A)
316 ensures
317 !(#[trigger] Set::empty().contains(a)),
318{
319 broadcast use Set::axiom_make_set;
320
321}
322
323pub broadcast proof fn lemma_set_new<A>(f: spec_fn(A) -> bool, a: A)
326 requires
327 Set::<A>::new(f) is Some,
328 ensures
329 #[trigger] Set::<A>::new(f).unwrap().contains(a) == f(a),
330{
331 broadcast use Set::axiom_make_set;
332
333}
334
335pub broadcast proof fn lemma_set_new_some<A>(f: spec_fn(A) -> bool)
339 requires
340 ISet::<A>::new(f).finite(),
341 ensures
342 #[trigger] Set::<A>::new(f) is Some,
343{
344 broadcast use Set::axiom_make_set;
345
346}
347
348#[allow(deprecated)]
351pub broadcast proof fn lemma_set_new_assuming_finite<A>(f: spec_fn(A) -> bool, a: A)
352 ensures
353 #[trigger] Set::<A>::new_assuming_finite(f).contains(a) == f(a),
354{
355 broadcast use Set::axiom_make_set;
356
357 assume(ISet::new(f).finite()); }
359
360pub broadcast proof fn lemma_set_new_from_iset<A>(s: ISet<A>)
363 requires
364 s.finite(),
365 ensures
366 #![trigger Set::<A>::new_from_iset(s)]
367 Set::<A>::new_from_iset(s) is Some,
368 Set::<A>::new_from_iset(s).unwrap().to_iset() == s,
369{
370 broadcast use Set::axiom_make_set;
371
372 assert(ISet::new(|a: A| s.contains(a)) =~= s);
373}
374
375pub broadcast proof fn lemma_set_insert_same<A>(s: Set<A>, a: A)
377 ensures
378 #[trigger] s.insert(a).contains(a),
379{
380 broadcast use Set::axiom_make_set;
381 broadcast use Set::axiom_is_finite;
382
383}
384
385pub broadcast proof fn lemma_set_insert_different<A>(s: Set<A>, a1: A, a2: A)
388 requires
389 a1 != a2,
390 ensures
391 #[trigger] s.insert(a2).contains(a1) == s.contains(a1),
392{
393 broadcast use Set::axiom_make_set;
394 broadcast use Set::axiom_is_finite;
395
396}
397
398pub broadcast proof fn lemma_set_remove_same<A>(s: Set<A>, a: A)
400 ensures
401 !(#[trigger] s.remove(a).contains(a)),
402{
403 broadcast use Set::axiom_make_set;
404 broadcast use Set::axiom_is_finite;
405
406}
407
408pub broadcast proof fn lemma_set_remove_insert<A>(s: Set<A>, a: A)
411 requires
412 s.contains(a),
413 ensures
414 (#[trigger] s.remove(a)).insert(a) == s,
415{
416 assert forall|aa| #![all_triggers] s.remove(a).insert(a).contains(aa) implies s.contains(
417 aa,
418 ) by {
419 if a == aa {
420 } else {
421 lemma_set_remove_different(s, aa, a);
422 lemma_set_insert_different(s.remove(a), aa, a);
423 }
424 };
425 assert forall|aa| #![all_triggers] s.contains(aa) implies s.remove(a).insert(a).contains(
426 aa,
427 ) by {
428 if a == aa {
429 lemma_set_insert_same(s.remove(a), a);
430 } else {
431 lemma_set_remove_different(s, aa, a);
432 lemma_set_insert_different(s.remove(a), aa, a);
433 }
434 };
435 axiom_set_ext_equal(s.remove(a).insert(a), s);
436}
437
438pub broadcast proof fn lemma_set_remove_different<A>(s: Set<A>, a1: A, a2: A)
441 requires
442 a1 != a2,
443 ensures
444 #[trigger] s.remove(a2).contains(a1) == s.contains(a1),
445{
446 broadcast use axiom_set_ext_equal;
447 broadcast use Set::axiom_make_set;
448 broadcast use Set::axiom_is_finite;
449
450}
451
452pub broadcast proof fn lemma_set_union<A>(s1: Set<A>, s2: Set<A>, a: A)
455 ensures
456 #[trigger] s1.union(s2).contains(a) == (s1.contains(a) || s2.contains(a)),
457{
458 broadcast use axiom_set_ext_equal;
459 broadcast use Set::axiom_make_set;
460 broadcast use Set::axiom_is_finite;
461
462}
463
464pub broadcast proof fn lemma_set_intersect<A>(s1: Set<A>, s2: Set<A>, a: A)
467 ensures
468 #[trigger] s1.intersect(s2).contains(a) == (s1.contains(a) && s2.contains(a)),
469{
470 broadcast use axiom_set_ext_equal;
471 broadcast use Set::axiom_make_set;
472 broadcast use Set::axiom_is_finite;
473
474}
475
476pub broadcast proof fn lemma_set_difference<A>(s1: Set<A>, s2: Set<A>, a: A)
479 ensures
480 #[trigger] s1.difference(s2).contains(a) == (s1.contains(a) && !s2.contains(a)),
481{
482 broadcast use Set::axiom_make_set;
483 broadcast use Set::axiom_is_finite;
484
485}
486
487pub broadcast proof fn lemma_set_complement<A>(s: Set<A>, a: A)
489 requires
490 ISet::new(|a| !s.contains(a)).finite(),
491 ensures
492 #[trigger] s.complement().unwrap().contains(a) == !s.contains(a),
493{
494 broadcast use Set::axiom_make_set;
495
496}
497
498pub broadcast proof fn lemma_set_filter<A>(s: Set<A>, f: spec_fn(A) -> bool, a: A)
501 ensures
502 #[trigger] s.filter(f).contains(a) == (s.contains(a) && f(a)),
503{
504 broadcast use Set::axiom_make_set;
505 broadcast use Set::axiom_is_finite;
506
507}
508
509pub broadcast proof fn lemma_set_empty_len<A>()
513 ensures
514 #[trigger] Set::<A>::empty().len() == 0,
515{
516 broadcast use Set::axiom_make_set;
517
518}
519
520pub broadcast proof fn lemma_set_insert_len<A>(s: Set<A>, a: A)
523 ensures
524 #[trigger] s.insert(a).len() == s.len() + (if s.contains(a) {
525 0int
526 } else {
527 1
528 }),
529{
530 broadcast use Set::axiom_make_set;
531 broadcast use Set::axiom_is_finite;
532
533}
534
535pub broadcast proof fn lemma_set_remove_len<A>(s: Set<A>, a: A)
538 ensures
539 s.len() == #[trigger] s.remove(a).len() + (if s.contains(a) {
540 1int
541 } else {
542 0
543 }),
544{
545 broadcast use Set::axiom_make_set;
546 broadcast use Set::axiom_is_finite;
547
548}
549
550pub broadcast proof fn lemma_set_contains_len<A>(s: Set<A>, a: A)
552 requires
553 #[trigger] s.contains(a),
554 ensures
555 #[trigger] s.len() != 0,
556{
557 broadcast use Set::axiom_make_set;
558 broadcast use Set::axiom_is_finite;
559
560}
561
562pub broadcast proof fn lemma_set_choose_len<A>(s: Set<A>)
564 requires
565 #[trigger] s.len() != 0,
566 ensures
567 #[trigger] s.contains(s.choose()),
568{
569 assert(s.to_iset().contains(s.to_iset().choose()));
570}
571
572pub broadcast proof fn lemma_to_iset_finite<A>(s: Set<A>)
574 ensures
575 #[trigger] s.to_iset().finite(),
576{
577 broadcast use Set::axiom_make_set;
578 broadcast use Set::axiom_is_finite;
579
580}
581
582pub broadcast proof fn lemma_to_iset_len<A>(s: Set<A>)
585 ensures
586 #[trigger] s.to_iset().len() == s.len(),
587{
588 broadcast use Set::axiom_make_set;
589 broadcast use Set::axiom_is_finite;
590
591}
592
593pub broadcast group group_set_lemmas {
594 axiom_set_ext_equal,
595 axiom_set_ext_equal_deep,
596 lemma_set_empty,
597 lemma_set_new,
598 lemma_set_new_assuming_finite,
599 lemma_set_new_from_iset,
600 lemma_set_new_some,
601 lemma_set_insert_same,
602 lemma_set_insert_different,
603 lemma_set_remove_same,
604 lemma_set_remove_insert,
605 lemma_set_remove_different,
606 lemma_set_union,
607 lemma_set_intersect,
608 lemma_set_difference,
609 lemma_set_complement,
610 lemma_set_filter,
611 lemma_set_empty_len,
612 lemma_set_insert_len,
613 lemma_set_remove_len,
614 lemma_set_contains_len,
615 lemma_set_choose_len,
616 lemma_set_new,
617 lemma_to_iset_finite,
618 lemma_to_iset_len,
619}
620
621#[doc(hidden)]
623#[macro_export]
624macro_rules! set_internal {
625 [$($elem:expr),* $(,)?] => {
626 $crate::vstd::set::Set::empty()
627 $(.insert($elem))*
628 };
629}
630
631#[macro_export]
632macro_rules! set {
633 [$($tail:tt)*] => {
634 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set::set_internal!($($tail)*))
635 };
636}
637
638pub use set_internal;
639pub use set;
640
641}