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
278pub broadcast axiom fn axiom_set_decreases_to_member<A>(s: Set<A>, a: A)
280 requires
281 #[trigger] s.contains(a),
282 ensures
283 #[trigger] (decreases_to!(s => a)),
284;
285
286broadcast use super::iset::group_iset_lemmas;
287
288pub mod fold {
289 use super::*;
290
291 impl<A> Set<A> {
292 #[verifier::inline]
298 pub open spec fn fold<B>(self, z: B, f: spec_fn(B, A) -> B) -> B
299 recommends
300 super::super::iset::fold::is_fun_commutative(f),
301 {
302 self.to_iset().fold(z, f)
303 }
304 }
305
306}
307
308pub broadcast proof fn lemma_set_empty<A>(a: A)
310 ensures
311 !(#[trigger] Set::empty().contains(a)),
312{
313 broadcast use Set::axiom_make_set;
314
315}
316
317pub broadcast proof fn lemma_set_new<A>(f: spec_fn(A) -> bool, a: A)
320 requires
321 Set::<A>::new(f) is Some,
322 ensures
323 #[trigger] Set::<A>::new(f).unwrap().contains(a) == f(a),
324{
325 broadcast use Set::axiom_make_set;
326
327}
328
329pub broadcast proof fn lemma_set_new_some<A>(f: spec_fn(A) -> bool)
333 requires
334 ISet::<A>::new(f).finite(),
335 ensures
336 #[trigger] Set::<A>::new(f) is Some,
337{
338 broadcast use Set::axiom_make_set;
339
340}
341
342pub broadcast proof fn lemma_set_new_from_iset<A>(s: ISet<A>)
345 requires
346 s.finite(),
347 ensures
348 #![trigger Set::<A>::new_from_iset(s)]
349 Set::<A>::new_from_iset(s) is Some,
350 Set::<A>::new_from_iset(s).unwrap().to_iset() == s,
351{
352 broadcast use Set::axiom_make_set;
353
354 assert(ISet::new(|a: A| s.contains(a)) =~= s);
355}
356
357pub broadcast proof fn lemma_set_insert_same<A>(s: Set<A>, a: A)
359 ensures
360 #[trigger] s.insert(a).contains(a),
361{
362 broadcast use Set::axiom_make_set;
363 broadcast use Set::axiom_is_finite;
364
365}
366
367pub broadcast proof fn lemma_set_insert_different<A>(s: Set<A>, a1: A, a2: A)
370 requires
371 a1 != a2,
372 ensures
373 #[trigger] s.insert(a2).contains(a1) == s.contains(a1),
374{
375 broadcast use Set::axiom_make_set;
376 broadcast use Set::axiom_is_finite;
377
378}
379
380pub broadcast proof fn lemma_set_remove_same<A>(s: Set<A>, a: A)
382 ensures
383 !(#[trigger] s.remove(a).contains(a)),
384{
385 broadcast use Set::axiom_make_set;
386 broadcast use Set::axiom_is_finite;
387
388}
389
390pub broadcast proof fn lemma_set_remove_insert<A>(s: Set<A>, a: A)
393 requires
394 s.contains(a),
395 ensures
396 (#[trigger] s.remove(a)).insert(a) == s,
397{
398 assert forall|aa| #![all_triggers] s.remove(a).insert(a).contains(aa) implies s.contains(
399 aa,
400 ) by {
401 if a == aa {
402 } else {
403 lemma_set_remove_different(s, aa, a);
404 lemma_set_insert_different(s.remove(a), aa, a);
405 }
406 };
407 assert forall|aa| #![all_triggers] s.contains(aa) implies s.remove(a).insert(a).contains(
408 aa,
409 ) by {
410 if a == aa {
411 lemma_set_insert_same(s.remove(a), a);
412 } else {
413 lemma_set_remove_different(s, aa, a);
414 lemma_set_insert_different(s.remove(a), aa, a);
415 }
416 };
417 axiom_set_ext_equal(s.remove(a).insert(a), s);
418}
419
420pub broadcast proof fn lemma_set_remove_different<A>(s: Set<A>, a1: A, a2: A)
423 requires
424 a1 != a2,
425 ensures
426 #[trigger] s.remove(a2).contains(a1) == s.contains(a1),
427{
428 broadcast use axiom_set_ext_equal;
429 broadcast use Set::axiom_make_set;
430 broadcast use Set::axiom_is_finite;
431
432}
433
434pub broadcast proof fn lemma_set_union<A>(s1: Set<A>, s2: Set<A>, a: A)
437 ensures
438 #[trigger] s1.union(s2).contains(a) == (s1.contains(a) || s2.contains(a)),
439{
440 broadcast use axiom_set_ext_equal;
441 broadcast use Set::axiom_make_set;
442 broadcast use Set::axiom_is_finite;
443
444}
445
446pub broadcast proof fn lemma_set_intersect<A>(s1: Set<A>, s2: Set<A>, a: A)
449 ensures
450 #[trigger] s1.intersect(s2).contains(a) == (s1.contains(a) && s2.contains(a)),
451{
452 broadcast use axiom_set_ext_equal;
453 broadcast use Set::axiom_make_set;
454 broadcast use Set::axiom_is_finite;
455
456}
457
458pub broadcast proof fn lemma_set_difference<A>(s1: Set<A>, s2: Set<A>, a: A)
461 ensures
462 #[trigger] s1.difference(s2).contains(a) == (s1.contains(a) && !s2.contains(a)),
463{
464 broadcast use Set::axiom_make_set;
465 broadcast use Set::axiom_is_finite;
466
467}
468
469pub broadcast proof fn lemma_set_complement<A>(s: Set<A>, a: A)
471 requires
472 ISet::new(|a| !s.contains(a)).finite(),
473 ensures
474 #[trigger] s.complement().unwrap().contains(a) == !s.contains(a),
475{
476 broadcast use Set::axiom_make_set;
477
478}
479
480pub broadcast proof fn lemma_set_filter<A>(s: Set<A>, f: spec_fn(A) -> bool, a: A)
483 ensures
484 #[trigger] s.filter(f).contains(a) == (s.contains(a) && f(a)),
485{
486 broadcast use Set::axiom_make_set;
487 broadcast use Set::axiom_is_finite;
488
489}
490
491pub broadcast proof fn lemma_set_empty_len<A>()
495 ensures
496 #[trigger] Set::<A>::empty().len() == 0,
497{
498 broadcast use Set::axiom_make_set;
499
500}
501
502pub broadcast proof fn lemma_set_insert_len<A>(s: Set<A>, a: A)
505 ensures
506 #[trigger] s.insert(a).len() == s.len() + (if s.contains(a) {
507 0int
508 } else {
509 1
510 }),
511{
512 broadcast use Set::axiom_make_set;
513 broadcast use Set::axiom_is_finite;
514
515}
516
517pub broadcast proof fn lemma_set_remove_len<A>(s: Set<A>, a: A)
520 ensures
521 s.len() == #[trigger] s.remove(a).len() + (if s.contains(a) {
522 1int
523 } else {
524 0
525 }),
526{
527 broadcast use Set::axiom_make_set;
528 broadcast use Set::axiom_is_finite;
529
530}
531
532pub broadcast proof fn lemma_set_contains_len<A>(s: Set<A>, a: A)
534 requires
535 #[trigger] s.contains(a),
536 ensures
537 #[trigger] s.len() != 0,
538{
539 broadcast use Set::axiom_make_set;
540 broadcast use Set::axiom_is_finite;
541
542}
543
544pub broadcast proof fn lemma_set_choose_len<A>(s: Set<A>)
546 requires
547 #[trigger] s.len() != 0,
548 ensures
549 #[trigger] s.contains(s.choose()),
550{
551 assert(s.to_iset().contains(s.to_iset().choose()));
552}
553
554pub broadcast proof fn lemma_to_iset_finite<A>(s: Set<A>)
556 ensures
557 #[trigger] s.to_iset().finite(),
558{
559 broadcast use Set::axiom_make_set;
560 broadcast use Set::axiom_is_finite;
561
562}
563
564pub broadcast proof fn lemma_to_iset_len<A>(s: Set<A>)
567 ensures
568 #[trigger] s.to_iset().len() == s.len(),
569{
570 broadcast use Set::axiom_make_set;
571 broadcast use Set::axiom_is_finite;
572
573}
574
575pub broadcast group group_set_lemmas {
576 axiom_set_ext_equal,
577 axiom_set_ext_equal_deep,
578 axiom_set_decreases_to_member,
579 lemma_set_empty,
580 lemma_set_new,
581 lemma_set_new_from_iset,
582 lemma_set_new_some,
583 lemma_set_insert_same,
584 lemma_set_insert_different,
585 lemma_set_remove_same,
586 lemma_set_remove_insert,
587 lemma_set_remove_different,
588 lemma_set_union,
589 lemma_set_intersect,
590 lemma_set_difference,
591 lemma_set_complement,
592 lemma_set_filter,
593 lemma_set_empty_len,
594 lemma_set_insert_len,
595 lemma_set_remove_len,
596 lemma_set_contains_len,
597 lemma_set_choose_len,
598 lemma_set_new,
599 lemma_to_iset_finite,
600 lemma_to_iset_len,
601}
602
603#[doc(hidden)]
605#[macro_export]
606macro_rules! set_internal {
607 [$($elem:expr),* $(,)?] => {
608 $crate::vstd::set::Set::empty()
609 $(.insert($elem))*
610 };
611}
612
613#[macro_export]
614macro_rules! set {
615 [$($tail:tt)*] => {
616 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::set::set_internal!($($tail)*))
617 };
618}
619
620pub use set_internal;
621pub use set;
622
623}