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 #[rustc_diagnostic_item = "verus::vstd::set::Set::full"]
140 pub open spec fn full() -> Option<Set<A>> {
141 Set::new(|a: A| true)
142 }
143
144 #[rustc_diagnostic_item = "verus::vstd::set::Set::contains"]
146 #[verifier::inline]
147 pub open spec fn contains(self, a: A) -> bool {
148 self.to_iset().contains(a)
149 }
150
151 #[verifier::inline]
153 pub open spec fn spec_has(self, a: A) -> bool {
154 self.contains(a)
155 }
156
157 #[rustc_diagnostic_item = "verus::vstd::set::Set::subset_of"]
159 pub open spec fn subset_of(self, s2: Set<A>) -> bool {
160 forall|a: A| self.contains(a) ==> s2.contains(a)
161 }
162
163 #[verifier::inline]
164 pub open spec fn spec_le(self, s2: Set<A>) -> bool {
165 self.subset_of(s2)
166 }
167
168 #[rustc_diagnostic_item = "verus::vstd::set::Set::insert"]
171 pub closed spec fn insert(self, a: A) -> Set<A> {
172 Self::make_set(self.to_iset().insert(a))
173 }
174
175 #[rustc_diagnostic_item = "verus::vstd::set::Set::remove"]
178 pub closed spec fn remove(self, a: A) -> Set<A> {
179 Self::make_set(self.to_iset().remove(a))
180 }
181
182 pub closed spec fn union(self, s2: Set<A>) -> Set<A> {
184 Self::make_set(self.to_iset().union(s2.to_iset()))
185 }
186
187 #[verifier::inline]
189 pub open spec fn spec_add(self, s2: Set<A>) -> Set<A> {
190 self.union(s2)
191 }
192
193 pub closed spec fn intersect(self, s2: Set<A>) -> Set<A> {
195 Self::make_set(self.to_iset().intersect(s2.to_iset()))
196 }
197
198 #[verifier::inline]
200 pub open spec fn spec_mul(self, s2: Set<A>) -> Set<A> {
201 self.intersect(s2)
202 }
203
204 pub closed spec fn difference(self, s2: Set<A>) -> Set<A> {
206 Self::make_set(self.to_iset().difference(s2.to_iset()))
207 }
208
209 #[verifier::inline]
211 pub open spec fn spec_sub(self, s2: Set<A>) -> Set<A> {
212 self.difference(s2)
213 }
214
215 pub open spec fn complement(self) -> Option<Set<A>> {
218 Set::new(|a| !self.contains(a))
219 }
220
221 pub closed spec fn filter(self, f: spec_fn(A) -> bool) -> Set<A> {
223 Self::make_set(self.to_iset().filter(f))
224 }
225
226 #[deprecated(note = "Every Set is always finite, so this is always true.")]
228 pub open spec fn finite(self) -> bool {
229 true
230 }
231
232 pub open spec fn congruent(self, s2: ISet<A>) -> bool {
235 forall|a: A| #![all_triggers] self.contains(a) <==> s2.contains(a)
236 }
237
238 pub closed spec fn len(self) -> nat {
240 self.to_iset().len()
241 }
242
243 pub open spec fn choose(self) -> A {
250 choose|a: A| self.contains(a)
251 }
252
253 pub open spec fn disjoint(self, s2: Self) -> bool {
256 forall|a: A| self.contains(a) ==> !s2.contains(a)
257 }
258}
259
260pub broadcast proof fn axiom_set_ext_equal<A>(s1: Set<A>, s2: Set<A>)
263 ensures
264 #[trigger] (s1 =~= s2) <==> (forall|a: A| s1.contains(a) == s2.contains(a)),
265{
266 admit();
267}
268
269pub broadcast proof fn axiom_set_ext_equal_deep<A>(s1: Set<A>, s2: Set<A>)
272 ensures
273 #[trigger] (s1 =~~= s2) <==> s1 =~= s2,
274{
275 admit();
276}
277
278broadcast use super::iset::group_iset_lemmas;
279
280pub mod fold {
281 use super::*;
282
283 impl<A> Set<A> {
284 #[verifier::inline]
290 pub open spec fn fold<B>(self, z: B, f: spec_fn(B, A) -> B) -> B
291 recommends
292 super::super::iset::fold::is_fun_commutative(f),
293 {
294 self.to_iset().fold(z, f)
295 }
296 }
297
298}
299
300pub broadcast proof fn lemma_set_empty<A>(a: A)
302 ensures
303 !(#[trigger] Set::empty().contains(a)),
304{
305 broadcast use Set::axiom_make_set;
306
307}
308
309pub broadcast proof fn lemma_set_new<A>(f: spec_fn(A) -> bool, a: A)
312 requires
313 Set::<A>::new(f) is Some,
314 ensures
315 #[trigger] Set::<A>::new(f).unwrap().contains(a) == f(a),
316{
317 broadcast use Set::axiom_make_set;
318
319}
320
321pub broadcast proof fn lemma_set_new_some<A>(f: spec_fn(A) -> bool)
325 requires
326 ISet::<A>::new(f).finite(),
327 ensures
328 #[trigger] Set::<A>::new(f) is Some,
329{
330 broadcast use Set::axiom_make_set;
331
332}
333
334pub broadcast proof fn lemma_set_new_from_iset<A>(s: ISet<A>)
337 requires
338 s.finite(),
339 ensures
340 #![trigger Set::<A>::new_from_iset(s)]
341 Set::<A>::new_from_iset(s) is Some,
342 Set::<A>::new_from_iset(s).unwrap().to_iset() == s,
343{
344 broadcast use Set::axiom_make_set;
345
346 assert(ISet::new(|a: A| s.contains(a)) =~= s);
347}
348
349pub broadcast proof fn lemma_set_insert_same<A>(s: Set<A>, a: A)
351 ensures
352 #[trigger] s.insert(a).contains(a),
353{
354 broadcast use Set::axiom_make_set;
355 broadcast use Set::axiom_is_finite;
356
357}
358
359pub broadcast proof fn lemma_set_insert_different<A>(s: Set<A>, a1: A, a2: A)
362 requires
363 a1 != a2,
364 ensures
365 #[trigger] s.insert(a2).contains(a1) == s.contains(a1),
366{
367 broadcast use Set::axiom_make_set;
368 broadcast use Set::axiom_is_finite;
369
370}
371
372pub broadcast proof fn lemma_set_remove_same<A>(s: Set<A>, a: A)
374 ensures
375 !(#[trigger] s.remove(a).contains(a)),
376{
377 broadcast use Set::axiom_make_set;
378 broadcast use Set::axiom_is_finite;
379
380}
381
382pub broadcast proof fn lemma_set_remove_insert<A>(s: Set<A>, a: A)
385 requires
386 s.contains(a),
387 ensures
388 (#[trigger] s.remove(a)).insert(a) == s,
389{
390 assert forall|aa| #![all_triggers] s.remove(a).insert(a).contains(aa) implies s.contains(
391 aa,
392 ) by {
393 if a == aa {
394 } else {
395 lemma_set_remove_different(s, aa, a);
396 lemma_set_insert_different(s.remove(a), aa, a);
397 }
398 };
399 assert forall|aa| #![all_triggers] s.contains(aa) implies s.remove(a).insert(a).contains(
400 aa,
401 ) by {
402 if a == aa {
403 lemma_set_insert_same(s.remove(a), a);
404 } else {
405 lemma_set_remove_different(s, aa, a);
406 lemma_set_insert_different(s.remove(a), aa, a);
407 }
408 };
409 axiom_set_ext_equal(s.remove(a).insert(a), s);
410}
411
412pub broadcast proof fn lemma_set_remove_different<A>(s: Set<A>, a1: A, a2: A)
415 requires
416 a1 != a2,
417 ensures
418 #[trigger] s.remove(a2).contains(a1) == s.contains(a1),
419{
420 broadcast use axiom_set_ext_equal;
421 broadcast use Set::axiom_make_set;
422 broadcast use Set::axiom_is_finite;
423
424}
425
426pub broadcast proof fn lemma_set_union<A>(s1: Set<A>, s2: Set<A>, a: A)
429 ensures
430 #[trigger] s1.union(s2).contains(a) == (s1.contains(a) || s2.contains(a)),
431{
432 broadcast use axiom_set_ext_equal;
433 broadcast use Set::axiom_make_set;
434 broadcast use Set::axiom_is_finite;
435
436}
437
438pub broadcast proof fn lemma_set_intersect<A>(s1: Set<A>, s2: Set<A>, a: A)
441 ensures
442 #[trigger] s1.intersect(s2).contains(a) == (s1.contains(a) && s2.contains(a)),
443{
444 broadcast use axiom_set_ext_equal;
445 broadcast use Set::axiom_make_set;
446 broadcast use Set::axiom_is_finite;
447
448}
449
450pub broadcast proof fn lemma_set_difference<A>(s1: Set<A>, s2: Set<A>, a: A)
453 ensures
454 #[trigger] s1.difference(s2).contains(a) == (s1.contains(a) && !s2.contains(a)),
455{
456 broadcast use Set::axiom_make_set;
457 broadcast use Set::axiom_is_finite;
458
459}
460
461pub broadcast proof fn lemma_set_complement<A>(s: Set<A>, a: A)
463 requires
464 ISet::new(|a| !s.contains(a)).finite(),
465 ensures
466 #[trigger] s.complement().unwrap().contains(a) == !s.contains(a),
467{
468 broadcast use Set::axiom_make_set;
469
470}
471
472pub broadcast proof fn lemma_set_filter<A>(s: Set<A>, f: spec_fn(A) -> bool, a: A)
475 ensures
476 #[trigger] s.filter(f).contains(a) == (s.contains(a) && f(a)),
477{
478 broadcast use Set::axiom_make_set;
479 broadcast use Set::axiom_is_finite;
480
481}
482
483pub broadcast proof fn lemma_set_empty_len<A>()
487 ensures
488 #[trigger] Set::<A>::empty().len() == 0,
489{
490 broadcast use Set::axiom_make_set;
491
492}
493
494pub broadcast proof fn lemma_set_insert_len<A>(s: Set<A>, a: A)
497 ensures
498 #[trigger] s.insert(a).len() == s.len() + (if s.contains(a) {
499 0int
500 } else {
501 1
502 }),
503{
504 broadcast use Set::axiom_make_set;
505 broadcast use Set::axiom_is_finite;
506
507}
508
509pub broadcast proof fn lemma_set_remove_len<A>(s: Set<A>, a: A)
512 ensures
513 s.len() == #[trigger] s.remove(a).len() + (if s.contains(a) {
514 1int
515 } else {
516 0
517 }),
518{
519 broadcast use Set::axiom_make_set;
520 broadcast use Set::axiom_is_finite;
521
522}
523
524pub broadcast proof fn lemma_set_contains_len<A>(s: Set<A>, a: A)
526 requires
527 #[trigger] s.contains(a),
528 ensures
529 #[trigger] s.len() != 0,
530{
531 broadcast use Set::axiom_make_set;
532 broadcast use Set::axiom_is_finite;
533
534}
535
536pub broadcast proof fn lemma_set_choose_len<A>(s: Set<A>)
538 requires
539 #[trigger] s.len() != 0,
540 ensures
541 #[trigger] s.contains(s.choose()),
542{
543 assert(s.to_iset().contains(s.to_iset().choose()));
544}
545
546pub broadcast proof fn lemma_to_iset_finite<A>(s: Set<A>)
548 ensures
549 #[trigger] s.to_iset().finite(),
550{
551 broadcast use Set::axiom_make_set;
552 broadcast use Set::axiom_is_finite;
553
554}
555
556pub broadcast proof fn lemma_to_iset_len<A>(s: Set<A>)
559 ensures
560 #[trigger] s.to_iset().len() == s.len(),
561{
562 broadcast use Set::axiom_make_set;
563 broadcast use Set::axiom_is_finite;
564
565}
566
567pub broadcast group group_set_lemmas {
568 axiom_set_ext_equal,
569 axiom_set_ext_equal_deep,
570 lemma_set_empty,
571 lemma_set_new,
572 lemma_set_new_from_iset,
573 lemma_set_new_some,
574 lemma_set_insert_same,
575 lemma_set_insert_different,
576 lemma_set_remove_same,
577 lemma_set_remove_insert,
578 lemma_set_remove_different,
579 lemma_set_union,
580 lemma_set_intersect,
581 lemma_set_difference,
582 lemma_set_complement,
583 lemma_set_filter,
584 lemma_set_empty_len,
585 lemma_set_insert_len,
586 lemma_set_remove_len,
587 lemma_set_contains_len,
588 lemma_set_choose_len,
589 lemma_set_new,
590 lemma_to_iset_finite,
591 lemma_to_iset_len,
592}
593
594#[doc(hidden)]
596#[macro_export]
597macro_rules! set_internal {
598 [$($elem:expr),* $(,)?] => {
599 $crate::vstd::set::Set::empty()
600 $(.insert($elem))*
601 };
602}
603
604#[macro_export]
605macro_rules! set {
606 [$($tail:tt)*] => {
607 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set::set_internal!($($tail)*))
608 };
609}
610
611pub use set_internal;
612pub use set;
613
614}