zfc

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

lib.rs (25659B)


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