1#![allow(non_snake_case)]
2use vstd::arithmetic::power::*;
32use vstd::arithmetic::power2::*;
33use vstd::bits::*;
34use vstd::prelude::*;
35
36pub use paste;
37
38#[doc(hidden)]
39#[macro_export]
40macro_rules! __bitflags_cfg_expr {
41 (() $base:expr) => {
42 $base
43 };
44 ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $base:expr) => {
45 (cfg!($($cfg)*) && $crate::__bitflags_cfg_expr!(($($rest)*) $base))
46 };
47 ((#[$_other:meta] $($rest:tt)*) $base:expr) => {
48 $crate::__bitflags_cfg_expr!(($($rest)*) $base)
49 };
50}
51
52#[doc(hidden)]
53#[macro_export]
54macro_rules! __bitflags_cfg_guarded_expr {
55 (() $e:expr) => {
56 $e
57 };
58 ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $e:expr) => {{
59 #[cfg($($cfg)*)]
60 {
61 $crate::__bitflags_cfg_guarded_expr!(($($rest)*) $e)
62 }
63 #[cfg(not($($cfg)*))]
64 {
65 true
66 }
67 }};
68 ((#[$_other:meta] $($rest:tt)*) $e:expr) => {
69 $crate::__bitflags_cfg_guarded_expr!(($($rest)*) $e)
70 };
71}
72
73#[doc(hidden)]
74#[macro_export]
75macro_rules! __bitflags_cfg_guarded_stmt {
76 (() $stmt:stmt) => {
77 $stmt
78 };
79 ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $stmt:stmt) => {
80 #[cfg($($cfg)*)]
81 {
82 $crate::__bitflags_cfg_guarded_stmt!(($($rest)*) $stmt)
83 }
84 };
85 ((#[$_other:meta] $($rest:tt)*) $stmt:stmt) => {
86 $crate::__bitflags_cfg_guarded_stmt!(($($rest)*) $stmt)
87 };
88}
89
90#[verusfmt::skip]
109#[macro_export]
110macro_rules! bitflags {
111 (
112 $(#[$outer:meta])*
113 $vis:vis struct $name:ident: $T:ty {
114 $(
115 $(#[$inner:ident $($args:tt)*])*
116 const $Flag:ident = $value:expr;
117 )*
118 }
119
120 $($t:tt)*
121 ) => {
122 $crate::paste::paste! {
123 verus! {
124 $(#[$outer])*
125 #[repr(transparent)]
126 $vis struct $name {
127 bits: $T,
129 }
130
131 impl ::core::clone::Clone for $name {
132 #[inline]
133 fn clone(&self) -> (r: Self)
134 returns self
135 {
136 Self {
137 bits: self.bits,
138 }
139 }
140 }
141
142 impl ::core::marker::Copy for $name {}
143
144 impl ::vstd::view::View for $name {
145 type V = ::vstd::set::Set<[< __ghost $name >]>;
146
147 open spec fn view(&self) -> Self::V {
148 Self::flags_from_bits(self.bits())
149 }
150 }
151
152 #[allow(non_camel_case_types)]
153 $vis ghost enum [< __ghost $name >] {
154 $(
155 [< __ghost $Flag >],
156 )*
157 }
158
159 impl [< __ghost $name >] {
160 $vis open spec fn enabled(self) -> bool {
161 match self {
162 $(
163 [< __ghost $name >]::[< __ghost $Flag >] => $crate::__bitflags_cfg_expr! {
164 ($(#[$inner $($args)*])*) true
165 },
166 )*
167 }
168 }
169
170 $vis open spec fn bit(self) -> $T {
171 match self {
172 $(
173 [< __ghost $name >]::[< __ghost $Flag >] => (($value) as $T),
174 )*
175 }
176 }
177 }
178
179 impl ::vstd::set_lib::FiniteFull for [< __ghost $name >] {
180 proof fn full_properties() {
181 let s = ::vstd::iset::ISet::empty()
182 $(.insert([< __ghost $name >]::[< __ghost $Flag >]))*;
183 assert(::vstd::iset::ISet::new(|a: [< __ghost $name >]| true) =~= s);
184 }
185 }
186
187 impl $name {
188 $vis open spec fn flags_spec(&self) -> ::vstd::set::Set<[< __ghost $name >]> {
189 Self::flags_from_bits(self.bits())
190 }
191
192 $vis open spec fn flags_from_bits(bits: $T) -> ::vstd::set::Set<[< __ghost $name >]> {
193 ::vstd::set::Set::< [< __ghost $name >] >::from_finite_type(|flag: [< __ghost $name >]| {
194 flag.enabled() && (bits & flag.bit()) == flag.bit()
195 })
196 }
197
198 closed spec fn from_bits_unchecked_spec(bits: $T) -> Self {
199 Self { bits }
200 }
201
202 #[verifier::when_used_as_spec(from_bits_unchecked_spec)]
203 const fn from_bits_unchecked(bits: $T) -> (r: Self)
204 ensures
205 r.bits() == bits,
206 r.flags_spec() == Self::flags_from_bits(bits),
207 returns
208 Self::from_bits_unchecked(bits),
209 {
210 Self { bits }
211 }
212
213 $(
214 $vis closed spec fn [< $Flag _spec >]() -> Self {
215 Self::from_bits_unchecked_spec($value as $T)
216 }
217
218 $(#[$inner $($args)*])*
219 #[verifier::when_used_as_spec([< $Flag _spec >])]
220 $vis const fn $Flag() -> (r: Self)
221 ensures
222 r.bits() == ($value),
223 r.flags_spec() == Self::flags_from_bits(($value) as $T),
224 returns Self::[< $Flag _spec >](),
225 {
226 Self::from_bits_unchecked($value)
227 }
228 )*
229
230 $vis open spec fn all_bits_spec() -> $T {
232 (0 as $T) $(| (
233 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
234 (($value) as $T)
235 } else {
236 0 as $T
237 }
238 ))*
239 }
240
241 #[verifier::when_used_as_spec(all_bits_spec)]
242 $vis const fn all_bits() -> $T
243 returns Self::all_bits(),
244 {
245 (0 as $T) $(| (
246 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
247 (($value) as $T)
248 } else {
249 0 as $T
250 }
251 ))*
252 }
253
254 $(
255 $(#[$inner $($args)*])*
256 proof fn [< lemma_ $Flag _constant >]()
257 ensures
258 Self::$Flag().bits() == (($value) as $T),
259 {
260 let flag = Self::$Flag();
261 assert(flag.bits() == (($value) as $T));
262 }
263 )*
264
265 $vis broadcast proof fn lemma_consts()
266 ensures
267 $(
268 #![trigger $crate::__bitflags_cfg_guarded_expr!(
269 ($(#[$inner $($args)*])*)
270 Self::$Flag().bits()
271 )]
272 $crate::__bitflags_cfg_guarded_expr!(
273 ($(#[$inner $($args)*])*)
274 Self::$Flag().bits() == (($value) as $T)
275 ),
276 )*
277 {
278 $(
279 $crate::__bitflags_cfg_guarded_stmt!(
280 ($(#[$inner $($args)*])*)
281 Self::[< lemma_ $Flag _constant >]()
282 );
283 )*
284 }
285
286 $vis closed spec fn bits_spec(&self) -> $T { self.bits }
288
289 #[verifier::when_used_as_spec(bits_spec)]
290 $vis const fn bits(&self) -> $T
291 returns self.bits(),
292 {
293 self.bits
294 }
295
296 $vis closed spec fn empty_spec() -> Self {
297 Self::from_bits_unchecked_spec(0)
298 }
299
300 #[verifier::when_used_as_spec(empty_spec)]
301 $vis const fn empty() -> (r: Self)
302 ensures
303 r.bits() == 0,
304 r.flags_spec() == Self::flags_from_bits(0),
305 returns Self::empty(),
306 {
307 Self::from_bits_unchecked(0)
308 }
309
310 $vis closed spec fn all_spec() -> Self {
311 Self::from_bits_unchecked_spec(Self::all_bits_spec())
312 }
313
314 #[verifier::when_used_as_spec(all_spec)]
315 $vis const fn all() -> (r: Self)
316 ensures
317 r == Self::all_spec(),
318 {
319 Self::from_bits_unchecked(Self::all_bits())
320 }
321
322 $vis open spec fn contains_spec(&self, other: Self) -> bool {
323 other@.subset_of(self@)
324 }
325
326 $vis open spec fn contains_flags_spec(&self, other: Self) -> bool {
327 self.contains(other)
328 }
329
330 #[verifier::when_used_as_spec(contains_spec)]
331 $vis const fn contains(&self, other: Self) -> bool
332 returns self.contains(other),
333 {
334 let res = $(
335 (
336 !$crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true }
337 || (other.bits & (($value) as $T)) != (($value) as $T)
338 || (self.bits & (($value) as $T)) == (($value) as $T)
339 )
340 )&&*;
341 proof {
342 assert(self@ =~= Self::flags_from_bits(self.bits()));
343 assert(other@ =~= Self::flags_from_bits(other.bits()));
344
345 if res {
346 assert forall|flag: [< __ghost $name >]| #[trigger]
347 other@.contains(flag) implies self@.contains(flag) by {
348 match flag {
349 $(
350 [< __ghost $name >]::[< __ghost $Flag >] => {
351 assert(other@.contains(flag));
352 assert(Self::flags_from_bits(other.bits()).contains(flag));
353 assert(flag.enabled());
354 if flag.enabled() {
355 assert((other.bits() & (($value) as $T)) == (($value) as $T));
356 assert((self.bits() & (($value) as $T)) == (($value) as $T));
357 assert(Self::flags_from_bits(self.bits()).contains(flag));
358 }
359 },
360 )*
361 }
362 }
363 assert(other@.subset_of(self@));
364 }
365
366 if other@.subset_of(self@) {
367 $(
368 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true }
369 && (other.bits() & (($value) as $T)) == (($value) as $T)
370 {
371 assert(Self::flags_from_bits(other.bits()).contains(
372 [< __ghost $name >]::[< __ghost $Flag >],
373 ));
374 assert(other@.contains([< __ghost $name >]::[< __ghost $Flag >]));
375 assert(self@.contains([< __ghost $name >]::[< __ghost $Flag >]));
376 assert(Self::flags_from_bits(self.bits()).contains(
377 [< __ghost $name >]::[< __ghost $Flag >],
378 ));
379 assert((self.bits() & (($value) as $T)) == (($value) as $T));
380 }
381 )*
382 assert(res);
383 }
384 }
385 res
386 }
387
388 $vis open spec fn intersects_spec(&self, other: Self) -> bool {
389 exists|flag: [< __ghost $name >]| #[trigger] self@.contains(flag) && other@.contains(flag)
390 }
391
392 #[verifier::when_used_as_spec(intersects_spec)]
393 $vis const fn intersects(&self, other: Self) -> bool
394 returns self.intersects(other),
395 {
396 let res = $(
397 (
398 $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true }
399 && (self.bits & (($value) as $T)) == (($value) as $T)
400 && (other.bits & (($value) as $T)) == (($value) as $T)
401 )
402 )||*;
403 proof {
404
405 if res {
406 $(
407 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true }
408 && (self.bits() & (($value) as $T)) == (($value) as $T)
409 && (other.bits() & (($value) as $T)) == (($value) as $T)
410 {
411 assert(self@.contains([< __ghost $name >]::[< __ghost $Flag >]));
412 assert(other@.contains([< __ghost $name >]::[< __ghost $Flag >]));
413 assert(exists|flag: [< __ghost $name >]|
414 #[trigger] self@.contains(flag) && other@.contains(flag));
415 }
416 )*
417 assert(exists|flag: [< __ghost $name >]|
418 #[trigger] self@.contains(flag) && other@.contains(flag));
419 }
420
421 if exists|flag: [< __ghost $name >]| #[trigger] self@.contains(flag) && other@.contains(flag) {
422 let flag = choose|flag: [< __ghost $name >]| self@.contains(flag) && other@.contains(flag);
423 assert(self@.contains(flag));
424 assert(other@.contains(flag));
425 match flag {
426 $(
427 [< __ghost $name >]::[< __ghost $Flag >] => {
428 assert(flag.enabled());
429 assert((self.bits() & (($value) as $T)) == (($value) as $T));
430 assert((other.bits() & (($value) as $T)) == (($value) as $T));
431 },
432 )*
433 }
434 assert(res);
435 }
436 }
437 res
438 }
439
440 $vis closed spec fn from_bits_truncate_spec(bits: $T) -> Self {
441 Self::from_bits_unchecked_spec(bits & Self::all_bits())
442 }
443
444 $vis closed spec fn from_bits_retain_spec(bits: $T) -> Self {
445 Self::from_bits_unchecked_spec(bits)
446 }
447
448 #[verifier::when_used_as_spec(from_bits_retain_spec)]
449 $vis const fn from_bits_retain(bits: $T) -> (r: Self)
450 ensures
451 r.bits() == bits,
452 r.flags_spec() == Self::flags_from_bits(bits),
453 returns Self::from_bits_retain(bits),
454 {
455 Self::from_bits_unchecked(bits)
456 }
457
458 #[verifier::when_used_as_spec(from_bits_truncate_spec)]
459 $vis const fn from_bits_truncate(bits: $T) -> (r: Self)
460 returns Self::from_bits_truncate(bits),
461 {
462 Self::from_bits_unchecked(bits & Self::all_bits())
463 }
464
465 $vis closed spec fn from_bits_spec(bits: $T) -> Option<Self> {
466 if (bits & Self::all_bits()) == bits {
467 Some(Self::from_bits_unchecked_spec(bits))
468 } else {
469 None
470 }
471 }
472
473 #[verifier::when_used_as_spec(from_bits_spec)]
474 $vis const fn from_bits(bits: $T) -> (r: Option<Self>)
475 ensures
476 r is Some == ((bits & Self::all_bits()) == bits),
477 r matches Some(flags_value) ==> {
478 &&& flags_value.bits() == bits
479 &&& flags_value.flags_spec() == Self::flags_from_bits(bits)
480 },
481 returns
482 Self::from_bits(bits),
483 {
484 if (bits & Self::all_bits()) == bits {
485 Some(Self::from_bits_unchecked(bits))
486 } else {
487 None
488 }
489 }
490
491 $vis closed spec fn remove_spec(self, other: Self) -> Self {
492 Self::from_bits_unchecked_spec(self.bits() & !other.bits())
493 }
494
495 $vis fn insert(&mut self, other: Self)
496 ensures
497 final(self).bits() == (old(self).bits() | other.bits()),
498 final(self).flags_spec() == Self::flags_from_bits(
499 old(self).bits() | other.bits(),
500 ),
501 {
502 let bits = self.bits | other.bits;
503 *self = Self::from_bits_unchecked(bits);
504 }
505
506 $vis fn remove(&mut self, other: Self)
507 ensures
508 *final(self) == old(self).remove_spec(other),
509 final(self).bits() == (old(self).bits() & !other.bits()),
510 final(self).flags_spec() == Self::flags_from_bits(
511 old(self).bits() & !other.bits(),
512 ),
513 {
514 let bits = self.bits & !other.bits;
515 *self = Self::from_bits_unchecked(bits);
516 }
517
518 $vis fn toggle(&mut self, other: Self)
520 ensures
521 final(self).bits() == (old(self).bits() ^ other.bits()),
522 final(self).flags_spec() == Self::flags_from_bits(
523 old(self).bits() ^ other.bits(),
524 ),
525 {
526 let bits = self.bits ^ other.bits;
527 *self = Self::from_bits_unchecked(bits);
528 }
529
530
531 $vis closed spec fn union_spec(self, other: Self) -> Self {
532 Self::from_bits_unchecked_spec(self.bits() | other.bits())
533 }
534
535 #[verifier::when_used_as_spec(union_spec)]
536 $vis const fn union(self, other: Self) -> (r: Self)
537 ensures
538 r.bits() == (self.bits() | other.bits()),
539 returns self.union(other),
540 {
541 Self::from_bits_unchecked(self.bits | other.bits)
542 }
543
544 $vis closed spec fn intersection_spec(self, other: Self) -> Self {
545 Self::from_bits_unchecked_spec(self.bits() & other.bits())
546 }
547
548 #[verifier::when_used_as_spec(intersection_spec)]
549 $vis const fn intersection(self, other: Self) -> (r: Self)
550 ensures
551 r.bits() == (self.bits() & other.bits()),
552 returns self.intersection(other),
553 {
554 Self::from_bits_unchecked(self.bits & other.bits)
555 }
556
557 $vis closed spec fn difference_spec(self, other: Self) -> Self {
558 Self::from_bits_unchecked_spec(self.bits() & !other.bits())
559 }
560
561 #[verifier::when_used_as_spec(difference_spec)]
562 $vis const fn difference(self, other: Self) -> (r: Self)
563 ensures
564 r.bits() == (self.bits() & !other.bits()),
565 returns self.difference(other),
566 {
567 Self::from_bits_unchecked(self.bits & !other.bits)
568 }
569
570 $vis closed spec fn symmetric_difference_spec(self, other: Self) -> Self {
571 Self::from_bits_unchecked_spec(self.bits() ^ other.bits())
572 }
573
574 #[verifier::when_used_as_spec(symmetric_difference_spec)]
575 $vis const fn symmetric_difference(self, other: Self) -> (r: Self)
576 ensures
577 r.bits() == (self.bits() ^ other.bits()),
578 returns self.symmetric_difference(other),
579 {
580 Self::from_bits_unchecked(self.bits ^ other.bits)
581 }
582 }
583
584 impl core::cmp::PartialEq for $name {
585 fn eq(&self, other: &Self) -> (r: bool)
586 ensures r == (self.bits() == other.bits()),
587 {
588 self.bits == other.bits
589 }
590 }
591
592 impl ::vstd::std_specs::cmp::PartialEqSpecImpl for $name {
593 closed spec fn obeys_eq_spec() -> bool { true }
594
595 closed spec fn eq_spec(&self, other: &Self) -> bool {
596 self.bits() == other.bits()
597 }
598 }
599
600 impl core::cmp::Eq for $name {}
601
602 impl ::vstd::std_specs::ops::BitOrSpecImpl for $name {
603 open spec fn obeys_bitor_spec() -> bool { true }
604
605 open spec fn bitor_req(self, rhs: Self) -> bool { true }
606
607 open spec fn bitor_spec(self, rhs: Self) -> Self::Output {
608 self.union(rhs)
609 }
610 }
611
612 impl core::ops::BitOr for $name {
613 type Output = Self;
614 fn bitor(self, other: Self) -> (r: Self)
615 ensures
616 r.bits() == (self.bits() | other.bits()),
617 {
618 Self::from_bits_unchecked(self.bits | other.bits)
619 }
620 }
621
622 impl vstd::std_specs::ops::BitAndSpecImpl for $name {
623 open spec fn obeys_bitand_spec() -> bool { true }
624
625 open spec fn bitand_req(self, rhs: Self) -> bool { true }
626
627 open spec fn bitand_spec(self, rhs: Self) -> Self::Output {
628 self.intersection(rhs)
629 }
630 }
631
632 impl core::ops::BitAnd for $name {
633 type Output = Self;
634 fn bitand(self, other: Self) -> (r: Self)
635 ensures
636 r.bits() == (self.bits() & other.bits()),
637 {
638 Self::from_bits_unchecked(self.bits & other.bits)
639 }
640 }
641
642 impl vstd::std_specs::ops::BitXorSpecImpl for $name {
643 open spec fn obeys_bitxor_spec() -> bool { true }
644
645 open spec fn bitxor_req(self, rhs: Self) -> bool { true }
646
647 open spec fn bitxor_spec(self, rhs: Self) -> Self::Output {
648 self.symmetric_difference(rhs)
649 }
650 }
651
652 impl core::ops::BitXor for $name {
653 type Output = Self;
654 fn bitxor(self, other: Self) -> (r: Self)
655 ensures
656 r.bits() == (self.bits() ^ other.bits()),
657 {
658 Self::from_bits_unchecked(self.bits ^ other.bits)
659 }
660 }
661
662 impl vstd::std_specs::ops::SubSpecImpl for $name {
663 open spec fn obeys_sub_spec() -> bool { true }
664
665 open spec fn sub_req(self, rhs: Self) -> bool { true }
666
667 open spec fn sub_spec(self, rhs: Self) -> Self::Output {
668 self.difference(rhs)
669 }
670 }
671
672 impl core::ops::Sub for $name {
673 type Output = Self;
674 fn sub(self, other: Self) -> (r: Self)
675 ensures
676 r.bits() == (self.bits() & !other.bits()),
677 {
678 self.difference(other)
679 }
680 }
681
682 impl vstd::std_specs::ops::NotSpecImpl for $name {
683 open spec fn obeys_not_spec() -> bool { true }
684
685 open spec fn not_req(self) -> bool { true }
686
687 closed spec fn not_spec(self) -> Self::Output {
688 Self::from_bits_unchecked_spec(!self.bits() & Self::all_bits())
689 }
690 }
691
692 impl core::ops::Not for $name {
693 type Output = Self;
694
695 fn not(self) -> (r: Self)
696 ensures
697 r.bits() == (!self.bits() & $name::all_bits()),
698 {
699 Self::from_bits_unchecked(!self.bits & $name::all_bits())
700 }
701 }
702
703 } impl ::core::fmt::Debug for $name {
706 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
707 f.debug_tuple(stringify!($name)).field(&self.bits).finish()
708 }
709 }
710
711 } };
713}
714
715#[macro_export]
744#[verusfmt::skip]
745macro_rules! bitflags_quick {
746 ($name:ident, $($bit_name:ident : { $($bits:expr),* $(,)? }),* $(,)?) => {
747 verus! {
748 impl $name {
749 $(
750 pub fn $bit_name() -> (r: Self)
751 ensures r == Self::from_bits_truncate( ($($bits)|*) as _ ),
752 {
753 Self::from_bits_truncate( ($($bits)|*) as _ )
754 }
755 )*
756 }
757 }
758 };
759}
760
761bitflags! {
767 pub struct Flags: u32 {
768 const A = 0b00000001;
769 const B = 0b00000010;
770 const C = 0b00000100;
771 const ABC = 0b00000111;
772 }
773}
774
775verus! {
776
777#[allow(dead_code)]
778fn _bitflags_smoke_test() {
779 let a = Flags::A();
780 let b = Flags::B();
781 let c = Flags::C();
782 let abc = Flags::ABC();
783
784 assert(a.bits() == 0b001u32);
785 assert(a.bits() == Flags::A().bits());
786 assert(b.bits() == 0b010u32);
787 assert(c.bits() == 0b100u32);
788 assert(abc.bits() == 0b111u32);
789 assert(a@ =~= Flags::flags_from_bits(a.bits()));
790 assert(abc@ =~= Flags::flags_from_bits(abc.bits()));
791
792 let abc_b = abc.bits();
793 let a_b = a.bits();
794 let b_b = b.bits();
795 assert((abc_b & a_b) == a_b) by (bit_vector)
796 requires
797 abc_b == 0b111u32 && a_b == 0b001u32,
798 ;
799 assert((abc_b & b_b) == b_b) by (bit_vector)
800 requires
801 abc_b == 0b111u32 && b_b == 0b010u32,
802 ;
803 assert((a_b & b_b) != b_b) by (bit_vector)
804 requires
805 a_b == 0b001u32 && b_b == 0b010u32,
806 ;
807 assert forall|flag: __ghostFlags| #[trigger] abc@.contains(flag) by {
808 assert(abc@ =~= Flags::flags_from_bits(abc.bits()));
809 match flag {
810 __ghostFlags::__ghostA => {
811 assert((abc_b & 0b001u32) == 0b001u32) by (bit_vector)
812 requires abc_b == 0b111u32,
813 ;
814 assert((abc.bits() & 0b001u32) == 0b001u32);
815 },
816 __ghostFlags::__ghostB => {
817 assert((abc_b & 0b010u32) == 0b010u32) by (bit_vector)
818 requires abc_b == 0b111u32,
819 ;
820 assert((abc.bits() & 0b010u32) == 0b010u32);
821 },
822 __ghostFlags::__ghostC => {
823 assert((abc_b & 0b100u32) == 0b100u32) by (bit_vector)
824 requires abc_b == 0b111u32,
825 ;
826 assert((abc.bits() & 0b100u32) == 0b100u32);
827 },
828 __ghostFlags::__ghostABC => {
829 assert((abc_b & 0b111u32) == 0b111u32) by (bit_vector)
830 requires abc_b == 0b111u32,
831 ;
832 assert((abc.bits() & 0b111u32) == 0b111u32);
833 },
834 }
835 }
836 assert(a@.subset_of(abc@));
837 assert(b@.subset_of(abc@));
838 assert(b@.contains(__ghostFlags::__ghostB)) by {
839 assert(b@ =~= Flags::flags_from_bits(b.bits()));
840 assert((b_b & 0b010u32) == 0b010u32) by (bit_vector)
841 requires b_b == 0b010u32,
842 ;
843 assert((b.bits() & 0b010u32) == 0b010u32);
844 }
845 assert(a@.contains(__ghostFlags::__ghostA)) by {
846 assert(a@ =~= Flags::flags_from_bits(a.bits()));
847 assert((a_b & 0b001u32) == 0b001u32) by (bit_vector)
848 requires a_b == 0b001u32,
849 ;
850 assert((a.bits() & 0b001u32) == 0b001u32);
851 }
852 assert(!a@.contains(__ghostFlags::__ghostB)) by {
853 assert(a@ =~= Flags::flags_from_bits(a.bits()));
854 assert((a_b & 0b010u32) != 0b010u32) by (bit_vector)
855 requires a_b == 0b001u32,
856 ;
857 assert((a.bits() & 0b010u32) != 0b010u32);
858 }
859 assert(!b@.subset_of(a@)) by {
860 if b@.subset_of(a@) {
861 assert(a@.contains(__ghostFlags::__ghostB));
862 }
863 }
864 assert(abc.contains(a));
865 assert(abc.contains(b));
866 assert(!a.contains(b));
867
868 let mut removed = abc;
869 removed.remove(a);
870 let removed_b = removed.bits();
871 assert(removed_b == (abc_b & !a_b));
872 assert(removed_b == 0b110u32) by (bit_vector)
873 requires
874 removed_b == (abc_b & !a_b),
875 abc_b == 0b111u32 && a_b == 0b001u32,
876 ;
877 assert(removed@ =~= Flags::flags_from_bits(removed.bits()));
878
879 assert(abc.intersects(a)) by {
880 assert(abc@.contains(__ghostFlags::__ghostA));
881 assert(a@.contains(__ghostFlags::__ghostA));
882 assert(exists|flag: __ghostFlags| #[trigger] abc@.contains(flag) && a@.contains(flag));
883 }
884 assert(!a.intersects(b)) by {
885 assert forall|flag: __ghostFlags| !(#[trigger] a@.contains(flag) && b@.contains(flag)) by {
886 match flag {
887 __ghostFlags::__ghostA => {
888 assert(b@ =~= Flags::flags_from_bits(b.bits()));
889 assert((b_b & 0b001u32) != 0b001u32) by (bit_vector)
890 requires b_b == 0b010u32,
891 ;
892 assert((b.bits() & 0b001u32) != 0b001u32);
893 assert(!b@.contains(flag));
894 },
895 __ghostFlags::__ghostB => {
896 assert(!a@.contains(flag));
897 },
898 __ghostFlags::__ghostC => {
899 assert(a@ =~= Flags::flags_from_bits(a.bits()));
900 assert((a_b & 0b100u32) != 0b100u32) by (bit_vector)
901 requires a_b == 0b001u32,
902 ;
903 assert((a.bits() & 0b100u32) != 0b100u32);
904 assert(!a@.contains(flag));
905 },
906 __ghostFlags::__ghostABC => {
907 assert(a@ =~= Flags::flags_from_bits(a.bits()));
908 assert((a_b & 0b111u32) != 0b111u32) by (bit_vector)
909 requires a_b == 0b001u32,
910 ;
911 assert((a.bits() & 0b111u32) != 0b111u32);
912 assert(!a@.contains(flag));
913 },
914 }
915 }
916 assert(!exists|flag: __ghostFlags| #[trigger] a@.contains(flag) && b@.contains(flag));
917 }
918
919}
920
921}