zfc

Library for sets according to ZFC.
git clone https://git.philomathiclife.com/repos/zfc
Log | Files | Refs | README

lib.rs (25772B)


      1 //! [![git]](https://git.philomathiclife.com/zfc/log.html) [![crates-io]](https://crates.io/crates/zfc) [![docs-rs]](crate)
      2 //!
      3 //! [git]: https://git.philomathiclife.com/git_badge.svg
      4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
      5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
      6 //!
      7 //! `zfc` is a library for sets according to
      8 //! [Zermelo–Fraenkel set theory with the axiom of choice (ZFC)](https://en.wikipedia.org/wiki/Zermelo%E2%80%93Fraenkel_set_theory).
      9 #![expect(
     10     clippy::doc_paragraphs_missing_punctuation,
     11     reason = "false positive for crate documentation having image links"
     12 )]
     13 #![cfg_attr(docsrs, feature(doc_cfg))]
     14 #![no_std]
     15 extern crate alloc;
     16 /// Unit tests.
     17 #[cfg(test)]
     18 mod tests;
     19 use alloc::{collections::BTreeSet, vec::Vec};
     20 use core::{
     21     borrow::Borrow,
     22     cmp::Ordering,
     23     error::Error,
     24     fmt::{self, Display, Formatter},
     25     ops::{Range, RangeInclusive, Sub},
     26 };
     27 pub use num_bigint;
     28 use num_bigint::BigUint;
     29 /// Represents the quantity of elements in a [`Set`].
     30 #[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
     31 pub enum Cardinality {
     32     /// The contained `BigUint` represents the quantity of elements in a finite `Set`.
     33     Finite(BigUint),
     34     /// The contained `BigUint` represents the [aleph number](https://en.wikipedia.org/wiki/Aleph_number) of a transfinite `Set`.
     35     Transfinite(BigUint),
     36 }
     37 impl Cardinality {
     38     /// Returns a reference to the contained `BigUint`.
     39     #[inline]
     40     #[must_use]
     41     pub const fn as_biguint(&self) -> &BigUint {
     42         match *self {
     43             Self::Finite(ref val) | Self::Transfinite(ref val) => val,
     44         }
     45     }
     46     /// Creates a `Cardinality::Finite` containing `value`.
     47     #[inline]
     48     #[must_use]
     49     pub const fn from_biguint(value: BigUint) -> Self {
     50         Self::Finite(value)
     51     }
     52     /// `Cardinality::Transfinite` is always greater.
     53     /// For `Cardinality::Finite` the contained `BigUint`
     54     /// is compared to `value`.
     55     #[inline]
     56     #[must_use]
     57     pub fn cmp_u8(&self, value: &u8) -> Ordering {
     58         match *self {
     59             Self::Finite(ref card) => card.cmp(&(*value).into()),
     60             Self::Transfinite(_) => Ordering::Greater,
     61         }
     62     }
     63     /// `Cardinality::Transfinite` is always greater.
     64     /// For `Cardinality::Finite` the contained `BigUint`
     65     /// is compared to `value`.
     66     #[inline]
     67     #[must_use]
     68     pub fn cmp_u16(&self, value: &u16) -> Ordering {
     69         match *self {
     70             Self::Finite(ref card) => card.cmp(&(*value).into()),
     71             Self::Transfinite(_) => Ordering::Greater,
     72         }
     73     }
     74     /// `Cardinality::Transfinite` is always greater.
     75     /// For `Cardinality::Finite` the contained `BigUint`
     76     /// is compared to `value`.
     77     #[inline]
     78     #[must_use]
     79     pub fn cmp_u32(&self, value: &u32) -> Ordering {
     80         match *self {
     81             Self::Finite(ref card) => card.cmp(&(*value).into()),
     82             Self::Transfinite(_) => Ordering::Greater,
     83         }
     84     }
     85     /// `Cardinality::Transfinite` is always greater.
     86     /// For `Cardinality::Finite` the contained `BigUint`
     87     /// is compared to `value`.
     88     #[inline]
     89     #[must_use]
     90     pub fn cmp_u64(&self, value: &u64) -> Ordering {
     91         match *self {
     92             Self::Finite(ref card) => card.cmp(&(*value).into()),
     93             Self::Transfinite(_) => Ordering::Greater,
     94         }
     95     }
     96     /// `Cardinality::Transfinite` is always greater.
     97     /// For `Cardinality::Finite` the contained `BigUint`
     98     /// is compared to `value`.
     99     #[inline]
    100     #[must_use]
    101     pub fn cmp_u128(&self, value: &u128) -> Ordering {
    102         match *self {
    103             Self::Finite(ref card) => card.cmp(&(*value).into()),
    104             Self::Transfinite(_) => Ordering::Greater,
    105         }
    106     }
    107     /// `Cardinality::Transfinite` is always greater.
    108     /// For `Cardinality::Finite` the contained `BigUint`
    109     /// is compared to `value`.
    110     #[inline]
    111     #[must_use]
    112     pub fn cmp_usize(&self, value: &usize) -> Ordering {
    113         match *self {
    114             Self::Finite(ref card) => card.cmp(&(*value).into()),
    115             Self::Transfinite(_) => Ordering::Greater,
    116         }
    117     }
    118     /// `Cardinality::Transfinite` is always greater.
    119     /// For `Cardinality::Finite` the contained `BigUint`
    120     /// is compared to `value`.
    121     #[inline]
    122     #[must_use]
    123     pub fn cmp_biguint(&self, value: &BigUint) -> Ordering {
    124         match *self {
    125             Self::Finite(ref card) => card.cmp(value),
    126             Self::Transfinite(_) => Ordering::Greater,
    127         }
    128     }
    129 }
    130 impl Display for Cardinality {
    131     #[inline]
    132     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    133         match *self {
    134             Self::Finite(ref val) => val.fmt(f),
    135             Self::Transfinite(ref val) => write!(f, "\u{2135}_{val}"),
    136         }
    137     }
    138 }
    139 impl fmt::Debug for Cardinality {
    140     #[inline]
    141     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    142         <Self as Display>::fmt(self, f)
    143     }
    144 }
    145 impl From<BigUint> for Cardinality {
    146     #[inline]
    147     fn from(value: BigUint) -> Self {
    148         Self::from_biguint(value)
    149     }
    150 }
    151 impl TryFrom<BoundedCardinality> for Cardinality {
    152     type Error = CardinalityErr;
    153     #[inline]
    154     fn try_from(value: BoundedCardinality) -> Result<Self, Self::Error> {
    155         if value.lower == value.upper {
    156             Ok(value.lower)
    157         } else {
    158             Err(CardinalityErr)
    159         }
    160     }
    161 }
    162 impl From<Cardinality> for BigUint {
    163     #[inline]
    164     fn from(value: Cardinality) -> Self {
    165         match value {
    166             Cardinality::Finite(val) | Cardinality::Transfinite(val) => val,
    167         }
    168     }
    169 }
    170 impl PartialEq<u8> for Cardinality {
    171     #[inline]
    172     fn eq(&self, other: &u8) -> bool {
    173         match *self {
    174             Self::Finite(ref card) => *card == BigUint::from(*other),
    175             Self::Transfinite(_) => false,
    176         }
    177     }
    178 }
    179 impl PartialEq<u16> for Cardinality {
    180     #[inline]
    181     fn eq(&self, other: &u16) -> bool {
    182         match *self {
    183             Self::Finite(ref card) => *card == BigUint::from(*other),
    184             Self::Transfinite(_) => false,
    185         }
    186     }
    187 }
    188 impl PartialEq<u32> for Cardinality {
    189     #[inline]
    190     fn eq(&self, other: &u32) -> bool {
    191         match *self {
    192             Self::Finite(ref card) => *card == BigUint::from(*other),
    193             Self::Transfinite(_) => false,
    194         }
    195     }
    196 }
    197 impl PartialEq<u64> for Cardinality {
    198     #[inline]
    199     fn eq(&self, other: &u64) -> bool {
    200         match *self {
    201             Self::Finite(ref card) => *card == BigUint::from(*other),
    202             Self::Transfinite(_) => false,
    203         }
    204     }
    205 }
    206 impl PartialEq<u128> for Cardinality {
    207     #[inline]
    208     fn eq(&self, other: &u128) -> bool {
    209         match *self {
    210             Self::Finite(ref card) => *card == BigUint::from(*other),
    211             Self::Transfinite(_) => false,
    212         }
    213     }
    214 }
    215 impl PartialEq<usize> for Cardinality {
    216     #[inline]
    217     fn eq(&self, other: &usize) -> bool {
    218         match *self {
    219             Self::Finite(ref card) => *card == BigUint::from(*other),
    220             Self::Transfinite(_) => false,
    221         }
    222     }
    223 }
    224 impl PartialEq<BigUint> for Cardinality {
    225     #[inline]
    226     fn eq(&self, other: &BigUint) -> bool {
    227         match *self {
    228             Self::Finite(ref card) => card == other,
    229             Self::Transfinite(_) => false,
    230         }
    231     }
    232 }
    233 impl PartialOrd<u8> for Cardinality {
    234     #[inline]
    235     fn partial_cmp(&self, other: &u8) -> Option<Ordering> {
    236         Some(self.cmp_u8(other))
    237     }
    238 }
    239 impl PartialOrd<u16> for Cardinality {
    240     #[inline]
    241     fn partial_cmp(&self, other: &u16) -> Option<Ordering> {
    242         Some(self.cmp_u16(other))
    243     }
    244 }
    245 impl PartialOrd<u32> for Cardinality {
    246     #[inline]
    247     fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
    248         Some(self.cmp_u32(other))
    249     }
    250 }
    251 impl PartialOrd<u64> for Cardinality {
    252     #[inline]
    253     fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
    254         Some(self.cmp_u64(other))
    255     }
    256 }
    257 impl PartialOrd<u128> for Cardinality {
    258     #[inline]
    259     fn partial_cmp(&self, other: &u128) -> Option<Ordering> {
    260         Some(self.cmp_u128(other))
    261     }
    262 }
    263 impl PartialOrd<usize> for Cardinality {
    264     #[inline]
    265     fn partial_cmp(&self, other: &usize) -> Option<Ordering> {
    266         Some(self.cmp_usize(other))
    267     }
    268 }
    269 impl PartialOrd<BigUint> for Cardinality {
    270     #[inline]
    271     fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> {
    272         Some(self.cmp_biguint(other))
    273     }
    274 }
    275 /// Error returned when attempting to create a [`BoundedCardinality`] from a pair of [`BigUint`]s
    276 /// or [`Cardinality`]s such that the upper bound is strictly less than the lower bound.
    277 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
    278 pub struct BoundedErr;
    279 impl Display for BoundedErr {
    280     #[inline]
    281     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    282         f.write_str("upper bound is greater than lower bound")
    283     }
    284 }
    285 impl Error for BoundedErr {}
    286 /// Error returned when attempting to create a [`Cardinality`] from a [`BoundedCardinality`] such that
    287 /// the lower bound is less than the upper bound.
    288 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
    289 pub struct CardinalityErr;
    290 impl Display for CardinalityErr {
    291     #[inline]
    292     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    293         f.write_str("lower bound of the BoundedCardinality is less than the upper bound")
    294     }
    295 }
    296 impl Error for CardinalityErr {}
    297 /// Contains a lower and upper bound [`Cardinality`] used to bound the cardinality of a [`Set`].
    298 #[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
    299 pub struct BoundedCardinality {
    300     /// Lower bound.
    301     lower: Cardinality,
    302     /// Upper bound.
    303     upper: Cardinality,
    304 }
    305 impl BoundedCardinality {
    306     /// Creates an instance of `BoundedCardinality`.
    307     ///
    308     /// Returns `None` iff `lower > upper`.
    309     #[inline]
    310     #[must_use]
    311     pub fn new(lower: Cardinality, upper: Cardinality) -> Option<Self> {
    312         if lower > upper {
    313             None
    314         } else {
    315             Some(Self { lower, upper })
    316         }
    317     }
    318     /// Creates an instance of `BoundedCardinality` with the lower and upper bounds both set to `exact`.
    319     #[inline]
    320     #[must_use]
    321     pub fn new_exact(exact: Cardinality) -> Self {
    322         Self {
    323             lower: exact.clone(),
    324             upper: exact,
    325         }
    326     }
    327     /// Creates an instance of `BoundedCardinality` with the lower and upper bounds as `Cardinality::Finite`
    328     /// of their respective values.
    329     ///
    330     /// Returns `None` iff `lower > upper`.
    331     #[inline]
    332     #[must_use]
    333     pub fn from_biguint(lower: BigUint, upper: BigUint) -> Option<Self> {
    334         if lower > upper {
    335             None
    336         } else {
    337             Some(Self {
    338                 lower: Cardinality::Finite(lower),
    339                 upper: Cardinality::Finite(upper),
    340             })
    341         }
    342     }
    343     /// Creates an instance of `BoundedCardinality` with the lower and upper bounds as `Cardinality::Finite(exact)`.
    344     #[inline]
    345     #[must_use]
    346     pub fn from_biguint_exact(exact: BigUint) -> Self {
    347         Self {
    348             lower: Cardinality::Finite(exact.clone()),
    349             upper: Cardinality::Finite(exact),
    350         }
    351     }
    352     /// Creates an instance of `BoundedCardinality` without verifying `lower <= upper`.
    353     ///
    354     /// # Safety
    355     ///
    356     /// `lower <= upper`.
    357     #[expect(
    358         unsafe_code,
    359         reason = "when literal values are used, code can reasonably bypass checks"
    360     )]
    361     #[inline]
    362     #[must_use]
    363     pub const unsafe fn new_unsafe(lower: Cardinality, upper: Cardinality) -> Self {
    364         Self { lower, upper }
    365     }
    366     /// Creates an instance of `BoundedCardinality` with the lower and upper bounds as `Cardinality::Finite`
    367     /// of their respective values without verifying `lower <= upper`.
    368     ///
    369     /// # Safety
    370     ///
    371     /// `lower <= upper`.
    372     #[expect(
    373         unsafe_code,
    374         reason = "when literal values are used, code can reasonably bypass checks"
    375     )]
    376     #[inline]
    377     #[must_use]
    378     pub const unsafe fn from_biguint_unsafe(lower: BigUint, upper: BigUint) -> Self {
    379         Self {
    380             lower: Cardinality::Finite(lower),
    381             upper: Cardinality::Finite(upper),
    382         }
    383     }
    384     /// Returns a reference to the lower bound.
    385     #[inline]
    386     #[must_use]
    387     pub const fn lower(&self) -> &Cardinality {
    388         &self.lower
    389     }
    390     /// Returns the lower bound.
    391     #[inline]
    392     #[must_use]
    393     pub fn to_lower(self) -> Cardinality {
    394         self.lower
    395     }
    396     /// Returns a reference to the upper bound.
    397     #[inline]
    398     #[must_use]
    399     pub const fn upper(&self) -> &Cardinality {
    400         &self.upper
    401     }
    402     /// Returns the upper bound.
    403     #[inline]
    404     #[must_use]
    405     pub fn to_upper(self) -> Cardinality {
    406         self.upper
    407     }
    408     /// Returns a tuple containing the references to the lower and upper bounds respectively.
    409     #[inline]
    410     #[must_use]
    411     pub const fn lower_upper(&self) -> (&Cardinality, &Cardinality) {
    412         (&self.lower, &self.upper)
    413     }
    414     /// Returns a reference to the contained `BigUint` of `self.lower()`.
    415     #[inline]
    416     #[must_use]
    417     pub const fn lower_biguint(&self) -> &BigUint {
    418         self.lower.as_biguint()
    419     }
    420     /// Returns the lower bound as a `BigUint`.
    421     #[inline]
    422     #[must_use]
    423     pub fn to_lower_biguint(self) -> BigUint {
    424         self.lower.into()
    425     }
    426     /// Returns a reference to the contained `BigUint` of `self.upper()`.
    427     #[inline]
    428     #[must_use]
    429     pub const fn upper_biguint(&self) -> &BigUint {
    430         self.upper.as_biguint()
    431     }
    432     /// Returns the upper bound as a `BigUint`.
    433     #[inline]
    434     #[must_use]
    435     pub fn to_upper_biguint(self) -> BigUint {
    436         self.upper.into()
    437     }
    438     /// Returns a tuple of references to the contained `BigUint`s of `self.lower()` and `self.upper()` respectively.
    439     #[inline]
    440     #[must_use]
    441     pub const fn lower_upper_biguint(&self) -> (&BigUint, &BigUint) {
    442         (self.lower_biguint(), self.upper_biguint())
    443     }
    444 }
    445 impl Display for BoundedCardinality {
    446     #[inline]
    447     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    448         write!(f, "({}, {})", self.lower, self.upper)
    449     }
    450 }
    451 impl fmt::Debug for BoundedCardinality {
    452     #[inline]
    453     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    454         <Self as Display>::fmt(self, f)
    455     }
    456 }
    457 impl From<BigUint> for BoundedCardinality {
    458     #[inline]
    459     fn from(value: BigUint) -> Self {
    460         Self::from_biguint_exact(value)
    461     }
    462 }
    463 impl From<Cardinality> for BoundedCardinality {
    464     #[inline]
    465     fn from(value: Cardinality) -> Self {
    466         Self {
    467             lower: value.clone(),
    468             upper: value,
    469         }
    470     }
    471 }
    472 impl TryFrom<(Cardinality, Cardinality)> for BoundedCardinality {
    473     type Error = BoundedErr;
    474     #[inline]
    475     fn try_from(value: (Cardinality, Cardinality)) -> Result<Self, Self::Error> {
    476         Self::new(value.0, value.1).ok_or(BoundedErr)
    477     }
    478 }
    479 impl TryFrom<(BigUint, BigUint)> for BoundedCardinality {
    480     type Error = BoundedErr;
    481     #[inline]
    482     fn try_from(value: (BigUint, BigUint)) -> Result<Self, Self::Error> {
    483         Self::from_biguint(value.0, value.1).ok_or(BoundedErr)
    484     }
    485 }
    486 impl From<BoundedCardinality> for (Cardinality, Cardinality) {
    487     #[inline]
    488     fn from(value: BoundedCardinality) -> Self {
    489         (value.lower, value.upper)
    490     }
    491 }
    492 impl From<BoundedCardinality> for (BigUint, BigUint) {
    493     #[inline]
    494     fn from(value: BoundedCardinality) -> Self {
    495         (value.lower.into(), value.upper.into())
    496     }
    497 }
    498 /// Represents a set according to
    499 /// [Zermelo–Fraenkel set theory with the axiom of choice (ZFC)](https://en.wikipedia.org/wiki/Zermelo%E2%80%93Fraenkel_set_theory).
    500 ///
    501 /// Note that elements in a `Set` must not be distinguishable by order or frequency, so care must be taken in its
    502 /// implementation if the implementing type exposes an API that distinguishes between the order or frequency of
    503 /// `Elem` (e.g., [`Vec<T>`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html) where `Elem` = `T`).
    504 pub trait Set {
    505     /// The elements that make up the set.
    506     ///
    507     /// Per ZFC, this must not be the same type as `Self` nor a recursive type based on `Self`.
    508     type Elem: Eq + ?Sized;
    509     /// Returns the cardinality of `self` if it is known exactly.
    510     ///
    511     /// The following property must be true:
    512     /// * `self.cardinality().unwrap() == self.bounded_cardinality().lower()` ⇔ `self.bounded_cardinality().lower() == self.bounded_cardinality().upper()`.
    513     #[inline]
    514     fn cardinality(&self) -> Option<Cardinality> {
    515         let bound = self.bounded_cardinality();
    516         if bound.lower < bound.upper {
    517             None
    518         } else {
    519             Some(bound.lower)
    520         }
    521     }
    522     /// Returns the bounded cardinality of `self`.
    523     fn bounded_cardinality(&self) -> BoundedCardinality;
    524     /// Returns `true` iff `Self` contains `elem`.
    525     fn contains<Q>(&self, elem: &Q) -> bool
    526     where
    527         Q: Borrow<Self::Elem> + Eq + ?Sized;
    528     /// Must conform to the following properties:
    529     /// * Irreflexivity.
    530     /// * Antisymmetry.
    531     /// * Transitivity.
    532     /// * ∀`a`, `b`: `Self`, `a.is_proper_subset(b)`⇒  ∀`e`: `Elem` | `a.contains(e)`, `b.contains(e)` ∧ ∃`f`: `Elem`, `b.contains(f) && !a.contains(f)`.
    533     /// * ∀`a`, `b`: `Self`, `a.is_proper_subset(b)` ⇒ `a.is_subset(b)`.
    534     /// * ∀`a`, `b`: `Self`, `a.is_proper_subset(b)` ⇔ `b.is_proper_superset(a)`.
    535     fn is_proper_subset(&self, val: &Self) -> bool;
    536     /// Must conform to the following properties:
    537     /// * Reflexivity.
    538     /// * Antisymmetry.
    539     /// * Transitivity.
    540     /// * ∀`a`, `b`: `Self`, `a.is_subset(b)`⇒  ∀`e`: `Elem` | `a.contains(e)`, `b.contains(e)`.
    541     /// * ∀`a`, `b`: `Self`, `a.is_subset(b)` ⇔ `b.is_superset(a)`.
    542     fn is_subset(&self, val: &Self) -> bool;
    543     /// Must conform to the following properties:
    544     /// * Irreflexivity.
    545     /// * Antisymmetry.
    546     /// * Transitivity.
    547     /// * ∀`a`, `b`: `Self`, `a.is_proper_superset(b)` ⇒ `a.is_superset(b)`.
    548     #[inline]
    549     fn is_proper_superset(&self, val: &Self) -> bool {
    550         val.is_proper_subset(self)
    551     }
    552     /// Must conform to the following properties:
    553     /// * Reflexivity.
    554     /// * Antisymmetry.
    555     /// * Transitivity.
    556     #[inline]
    557     fn is_superset(&self, val: &Self) -> bool {
    558         val.is_subset(self)
    559     }
    560     /// Read [`Set::is_proper_subset`].
    561     #[inline]
    562     fn is_proper_subset_iter<T>(&self, val: &T) -> bool
    563     where
    564         Self::Elem: Borrow<T::Elem> + PartialEq<T::Elem>,
    565         for<'a> &'a Self: IntoIterator<Item = &'a Self::Elem>,
    566         T: Set + ?Sized,
    567         T::Elem: PartialEq<Self::Elem>,
    568     {
    569         self.cardinality() < val.cardinality()
    570             && self
    571                 .into_iter()
    572                 .try_fold(
    573                     (),
    574                     |(), elem| {
    575                         if val.contains(elem) { Ok(()) } else { Err(()) }
    576                     },
    577                 )
    578                 .is_ok_and(|()| true)
    579     }
    580     /// Read [`Set::is_subset`].
    581     #[inline]
    582     fn is_subset_iter<T>(&self, val: &T) -> bool
    583     where
    584         Self::Elem: Borrow<T::Elem> + PartialEq<T::Elem>,
    585         for<'a> &'a Self: IntoIterator<Item = &'a Self::Elem>,
    586         T: Set + ?Sized,
    587         T::Elem: PartialEq<Self::Elem>,
    588     {
    589         self.cardinality() <= val.cardinality()
    590             && self
    591                 .into_iter()
    592                 .try_fold(
    593                     (),
    594                     |(), elem| {
    595                         if val.contains(elem) { Ok(()) } else { Err(()) }
    596                     },
    597                 )
    598                 .is_ok_and(|()| true)
    599     }
    600     /// Read [`Set::is_proper_superset`].
    601     #[inline]
    602     fn is_proper_superset_iter<T>(&self, val: &T) -> bool
    603     where
    604         Self::Elem: PartialEq<T::Elem>,
    605         T: Set + ?Sized,
    606         for<'a> &'a T: IntoIterator<Item = &'a T::Elem>,
    607         T::Elem: Borrow<Self::Elem> + PartialEq<Self::Elem>,
    608     {
    609         val.is_proper_subset_iter(self)
    610     }
    611     /// Read [`Set::is_superset`].
    612     #[inline]
    613     fn is_superset_iter<T>(&self, val: &T) -> bool
    614     where
    615         Self::Elem: PartialEq<T::Elem>,
    616         T: Set + ?Sized,
    617         for<'a> &'a T: IntoIterator<Item = &'a T::Elem>,
    618         T::Elem: Borrow<Self::Elem> + PartialEq<Self::Elem>,
    619     {
    620         val.is_subset_iter(self)
    621     }
    622 }
    623 impl<T> Set for BTreeSet<T>
    624 where
    625     T: Ord,
    626 {
    627     type Elem = T;
    628     #[inline]
    629     fn cardinality(&self) -> Option<Cardinality> {
    630         Some(Cardinality::Finite(self.len().into()))
    631     }
    632     #[inline]
    633     fn bounded_cardinality(&self) -> BoundedCardinality {
    634         let card = Cardinality::from_biguint(self.len().into());
    635         BoundedCardinality {
    636             lower: card.clone(),
    637             upper: card,
    638         }
    639     }
    640     #[inline]
    641     fn contains<Q>(&self, elem: &Q) -> bool
    642     where
    643         Q: Borrow<Self::Elem> + Eq + ?Sized,
    644     {
    645         self.contains(elem.borrow())
    646     }
    647     #[inline]
    648     fn is_proper_subset(&self, val: &Self) -> bool {
    649         self.len() < val.len() && self.intersection(val).count() == val.len()
    650     }
    651     #[inline]
    652     fn is_subset(&self, val: &Self) -> bool {
    653         self.len() <= val.len() && self.intersection(val).count() == val.len()
    654     }
    655 }
    656 impl<T> Set for Range<T>
    657 where
    658     T: Ord,
    659     for<'a, 'b> &'a T: Sub<&'b T>,
    660     for<'a, 'b> <&'a T as Sub<&'b T>>::Output: Into<BigUint>,
    661 {
    662     type Elem = T;
    663     #[expect(
    664         clippy::arithmetic_side_effects,
    665         reason = "we need to calculate the cardinality, and we avoid underflow"
    666     )]
    667     #[inline]
    668     fn cardinality(&self) -> Option<Cardinality> {
    669         Some(Cardinality::Finite(if self.end >= self.start {
    670             (&self.end - &self.start).into()
    671         } else {
    672             BigUint::new(Vec::new())
    673         }))
    674     }
    675     #[expect(
    676         clippy::arithmetic_side_effects,
    677         reason = "we need to calculate the cardinality, and we avoid underflow"
    678     )]
    679     #[inline]
    680     fn bounded_cardinality(&self) -> BoundedCardinality {
    681         let card = Cardinality::Finite(if self.end >= self.start {
    682             (&self.end - &self.start).into()
    683         } else {
    684             BigUint::new(Vec::new())
    685         });
    686         BoundedCardinality {
    687             lower: card.clone(),
    688             upper: card,
    689         }
    690     }
    691     #[inline]
    692     fn contains<Q>(&self, elem: &Q) -> bool
    693     where
    694         Q: Borrow<Self::Elem> + Eq + ?Sized,
    695     {
    696         self.contains(elem.borrow())
    697     }
    698     #[inline]
    699     fn is_proper_subset(&self, val: &Self) -> bool {
    700         match self.start.cmp(&val.start) {
    701             Ordering::Less => false,
    702             Ordering::Equal => self.end < val.end,
    703             Ordering::Greater => self.end <= val.end,
    704         }
    705     }
    706     #[inline]
    707     fn is_subset(&self, val: &Self) -> bool {
    708         self.start >= val.start && self.end <= val.end
    709     }
    710 }
    711 impl<T> Set for RangeInclusive<T>
    712 where
    713     T: Ord,
    714     for<'a, 'b> &'a T: Sub<&'b T>,
    715     for<'a, 'b> <&'a T as Sub<&'b T>>::Output: Into<BigUint>,
    716 {
    717     type Elem = T;
    718     #[expect(
    719         clippy::arithmetic_side_effects,
    720         reason = "we need to calculate the cardinality, and we avoid underflow. Overflow is no worry since we use BigUint."
    721     )]
    722     #[inline]
    723     fn cardinality(&self) -> Option<Cardinality> {
    724         Some(Cardinality::Finite(if self.end() >= self.start() {
    725             (self.end() - self.start()).into() + BigUint::new(alloc::vec![1])
    726         } else {
    727             BigUint::new(Vec::new())
    728         }))
    729     }
    730     #[expect(
    731         clippy::arithmetic_side_effects,
    732         reason = "we need to calculate the cardinality, and we avoid underflow. Overflow is no worry since we use BigUint."
    733     )]
    734     #[inline]
    735     fn bounded_cardinality(&self) -> BoundedCardinality {
    736         let card = Cardinality::Finite(if self.end() >= self.start() {
    737             (self.end() - self.start()).into() + BigUint::new(alloc::vec![1])
    738         } else {
    739             BigUint::new(Vec::new())
    740         });
    741         BoundedCardinality {
    742             lower: card.clone(),
    743             upper: card,
    744         }
    745     }
    746     #[inline]
    747     fn contains<Q>(&self, elem: &Q) -> bool
    748     where
    749         Q: Borrow<Self::Elem> + Eq + ?Sized,
    750     {
    751         self.contains(elem.borrow())
    752     }
    753     #[inline]
    754     fn is_proper_subset(&self, val: &Self) -> bool {
    755         match self.start().cmp(val.start()) {
    756             Ordering::Less => false,
    757             Ordering::Equal => self.end() < val.end(),
    758             Ordering::Greater => self.end() <= val.end(),
    759         }
    760     }
    761     #[inline]
    762     fn is_subset(&self, val: &Self) -> bool {
    763         self.start() >= val.start() && self.end() <= val.end()
    764     }
    765 }
    766 #[cfg(feature = "std")]
    767 extern crate std;
    768 #[cfg(feature = "std")]
    769 use core::hash::{BuildHasher, Hash};
    770 #[cfg(feature = "std")]
    771 use std::collections::HashSet;
    772 #[cfg(feature = "std")]
    773 impl<T, S> Set for HashSet<T, S>
    774 where
    775     T: Eq + Hash,
    776     S: BuildHasher,
    777 {
    778     type Elem = T;
    779     #[inline]
    780     fn cardinality(&self) -> Option<Cardinality> {
    781         Some(Cardinality::Finite(self.len().into()))
    782     }
    783     #[inline]
    784     fn bounded_cardinality(&self) -> BoundedCardinality {
    785         let card = Cardinality::Finite(self.len().into());
    786         BoundedCardinality {
    787             lower: card.clone(),
    788             upper: card,
    789         }
    790     }
    791     #[inline]
    792     fn contains<Q>(&self, elem: &Q) -> bool
    793     where
    794         Q: Borrow<Self::Elem> + Eq + ?Sized,
    795     {
    796         self.contains(elem.borrow())
    797     }
    798     #[inline]
    799     fn is_proper_subset(&self, val: &Self) -> bool {
    800         self.len() < val.len() && self.intersection(val).count() == val.len()
    801     }
    802     #[inline]
    803     fn is_subset(&self, val: &Self) -> bool {
    804         self.len() <= val.len() && self.intersection(val).count() == val.len()
    805     }
    806 }