hfs/
lib.rs

1#![doc = include_str!("../README.md")]
2#![warn(clippy::pedantic)]
3#![warn(missing_docs)]
4#![warn(clippy::missing_safety_doc)]
5#![warn(clippy::missing_docs_in_private_items)]
6#![warn(clippy::undocumented_unsafe_blocks)]
7#![macro_use]
8
9/// [`smallvec::smallvec`] coerced into [`SmallVec`].
10macro_rules! smallvec {
11    ($elem: expr; $n: expr) => (
12        SmallVec::from_elem($elem, $n)
13    );
14    ($($x: expr), *$(,)*) => ({
15        let vec: SmallVec<_> = smallvec::smallvec![$($x,)*];
16        vec
17    });
18}
19
20pub mod class;
21pub mod levels;
22pub mod mset;
23pub mod prelude;
24pub mod set;
25mod tests;
26
27use prelude::*;
28
29/// Small vector.
30type SmallVec<T> = smallvec::SmallVec<[T; 4]>;
31
32/// Whether a slice has consecutive equal elements.
33fn consecutive_eq<T: PartialEq>(slice: &[T]) -> bool {
34    (1..slice.len()).any(|i| slice[i - 1] == slice[i])
35}
36
37/// Transmute a vector of one type into a vector of another type.
38///
39/// ## Safety
40///
41/// The types `T` and `U` must be transmutable into each other. In particular, they must have the
42/// same size and alignment.
43unsafe fn transmute_vec<T, U>(vec: Vec<T>) -> Vec<U> {
44    assert_eq!(mem::size_of::<T>(), mem::size_of::<U>());
45    assert_eq!(mem::align_of::<T>(), mem::align_of::<U>());
46
47    let mut vec = mem::ManuallyDrop::new(vec);
48    Vec::from_raw_parts(vec.as_mut_ptr().cast(), vec.len(), vec.capacity())
49}
50
51/// Clears a vector and allows it to be reused for another lifetime.
52fn reuse_vec<'a, T>(mut vec: Vec<&T>) -> Vec<&'a T> {
53    vec.clear();
54    // Safety: no data of our original lifetime remains.
55    unsafe { transmute_vec(vec) }
56}
57
58/// A sealed trait, preventing foreign implementations of our traits.
59trait Seal {}
60
61/// A trait for [`Mset`] and [`Set`].
62///
63/// **This isn't meant to be used generically.** Instead, it exists to collect the large amount of
64/// shared code between these two types. As such, it is sealed so that these are the only two types
65/// that ever implement it.
66#[allow(private_bounds)]
67pub trait SetTrait:
68    Seal
69    + AsRef<Mset>
70    + Clone
71    + Debug
72    + Default
73    + Display
74    + Eq
75    + FromStr<Err = SetError>
76    + Into<Vec<Self>>
77    + IntoIterator<Item = Self>
78    + PartialOrd
79    + 'static
80{
81    // -------------------- Basic methods -------------------- //
82
83    /// The set as a slice.
84    fn as_slice(&self) -> &[Self];
85
86    /// The set as a mutable slice.
87    ///
88    /// See [`Mset::as_mut_slice`] and [`Set::as_mut_slice`].
89    #[allow(clippy::missing_safety_doc)]
90    #[deprecated = "internal method, use Mset::as_mut_slice or Set::as_mut_slice."]
91    unsafe fn _as_mut_slice(&mut self) -> &mut [Self];
92
93    /// A reference to the inner vector. Note that internally, both kinds of set store [`Mset`].
94    fn as_vec(&self) -> &Vec<Mset>;
95
96    /// A mutable reference to the inner vector. Note that internally, both kinds of set store
97    /// [`Mset`].
98    ///
99    /// See [`Mset::as_mut_vec`] and [`Set::as_mut_vec`].
100    #[allow(clippy::missing_safety_doc)]
101    #[deprecated = "internal method, use Mset::as_mut_vec or Set::as_mut_vec."]
102    unsafe fn _as_mut_vec(&mut self) -> &mut Vec<Mset>;
103
104    /// Converts the set into a vector of sets.
105    fn into_vec(self) -> Vec<Self> {
106        self.into()
107    }
108
109    /// Flattens a vector of sets.   
110    ///
111    /// See [`Mset::from`] and [`Set::flatten`].
112    #[deprecated = "internal method, use Mset::from or Set::flatten."]
113    fn _flatten_vec(vec: Vec<Self>) -> Self;
114
115    /// Removes all elements from the set.
116    fn clear(&mut self) {
117        // Safety: The empty set is valid for both types.
118        #[allow(deprecated)]
119        unsafe {
120            self._as_mut_vec().clear();
121        }
122    }
123
124    /// Set cardinality.
125    fn card(&self) -> usize {
126        self.as_slice().len()
127    }
128
129    /// Whether the set is empty.
130    fn is_empty(&self) -> bool {
131        self.as_slice().is_empty()
132    }
133
134    /// The capacity of the backing vector.
135    fn capacity(&self) -> usize {
136        self.as_vec().capacity()
137    }
138
139    /// Iterate over the elements of the set.
140    fn iter(&self) -> slice::Iter<Self> {
141        self.as_slice().iter()
142    }
143
144    /// Get the [`Ahu`] encoding for the set.
145    fn ahu(&self) -> Ahu {
146        Ahu::new(self.as_ref())
147    }
148
149    /// Von Neumann set rank.
150    fn rank(&self) -> usize {
151        // Safety: the resulting `Levels` has at least one level.
152        unsafe {
153            Levels::new(self.as_ref())
154                .nest_vec()
155                .level_len()
156                .unchecked_sub(1)
157        }
158    }
159
160    // -------------------- Constructions -------------------- //
161
162    /// [Empty set](https://en.wikipedia.org/wiki/Empty_set) Ø.
163    fn empty() -> Self;
164
165    /// [Empty set](https://en.wikipedia.org/wiki/Empty_set) Ø.
166    ///
167    /// Allows the initial capacity for the inner buffer to be specified.
168    fn with_capacity(capacity: usize) -> Self;
169
170    /// [Singleton set](https://en.wikipedia.org/wiki/Singleton_(mathematics)) {x}.
171    #[must_use]
172    fn singleton(self) -> Self;
173
174    /// Gets the element out of a singleton set.
175    ///
176    /// Returns `None` if this is not a singleton.
177    fn into_singleton(self) -> Option<Self>;
178
179    /// References the element in a singleton set.
180    ///
181    /// Returns `None` if this is not a singleton.
182    fn as_singleton(&self) -> Option<&Self> {
183        if self.card() == 1 {
184            None
185        } else {
186            self.as_slice().first()
187        }
188    }
189
190    /// Mutably references the element in a singleton set.
191    ///
192    /// Returns `None` if this is not a singleton.
193    fn as_singleton_mut(&mut self) -> Option<&mut Self> {
194        if self.card() == 1 {
195            // Safety: it's not a problem if this element is modified, as a singleton can never have
196            // duplicate elements to begin with.
197            #[allow(deprecated)]
198            unsafe {
199                self._as_mut_slice().first_mut()
200            }
201        } else {
202            None
203        }
204    }
205
206    /// In-place set insertion x + {y}.
207    fn insert_mut(&mut self, set: Self);
208
209    /// Set insertion x + {y}.
210    #[must_use]
211    fn insert(mut self, set: Self) -> Self {
212        self.insert_mut(set);
213        self
214    }
215
216    /// In-place [set specification](https://en.wikipedia.org/wiki/Axiom_schema_of_specification).
217    fn select_mut<P: FnMut(&Self) -> bool>(&mut self, pred: P);
218
219    /// [Set specification](https://en.wikipedia.org/wiki/Axiom_schema_of_specification).
220    #[must_use]
221    fn select<P: FnMut(&Self) -> bool>(mut self, pred: P) -> Self {
222        self.select_mut(pred);
223        self
224    }
225
226    /// Set pair {x, y} = {x} + {y}.
227    #[must_use]
228    fn pair(self, other: Self) -> Self {
229        self.singleton().insert(other)
230    }
231
232    /// Count multiplicity of an element in a set.
233    fn count(&self, set: &Self) -> usize;
234
235    /// Sum over a vector. See [`SetTrait::sum`].
236    fn sum_vec(vec: Vec<Self>) -> Self;
237
238    /// Sum x + y.
239    ///
240    /// - The sum of two multisets adds the multiplicities of all their elements.
241    /// - The sum of two sets coincides with their union.
242    #[must_use]
243    fn sum(self, other: Self) -> Self {
244        Self::sum_vec(vec![self, other])
245    }
246
247    /// Sum Σx.
248    ///
249    /// See [`SetTrait::sum`].
250    #[must_use]
251    fn big_sum(self) -> Self {
252        Self::sum_vec(self.into())
253    }
254
255    /// Union over a vector. See [`SetTrait::union`].
256    fn union_vec(vec: Vec<Self>) -> Self;
257
258    /// Union x ∪ y.
259    ///
260    /// The union of two multisets takes the maximum of their multiplicities. For sets, this results
261    /// in the union having the elements that are in either of the sets.
262    #[must_use]
263    fn union(self, other: Self) -> Self {
264        Self::union_vec(vec![self, other])
265    }
266
267    /// Union ∪x. See [`SetTrait::union`].
268    #[must_use]
269    fn big_union(self) -> Self {
270        Self::union_vec(self.into())
271    }
272
273    /// Intersection over a vector. See [`SetTrait::inter`].
274    ///
275    /// The intersection of an empty family would be the universal class, which can't be returned.
276    fn inter_vec(vec: Vec<Self>) -> Option<Self>;
277
278    /// Intersection x ∩ y.
279    ///
280    /// The intersection of two multisets takes the minimum of their multiplicities. For sets, this
281    /// results in the intersection having the elements that are in both of the sets.
282    #[must_use]
283    fn inter(self, other: Self) -> Self {
284        // Safety: 2 != 0.
285        unsafe { Self::inter_vec(vec![self, other]).unwrap_unchecked() }
286    }
287
288    /// Intersection ∩x. See [`SetTrait::inter`].
289    ///
290    /// The intersection of an empty family would be the universal set, which can't be returned.
291    #[must_use]
292    fn big_inter(self) -> Option<Self> {
293        Self::inter_vec(self.into())
294    }
295
296    /// [Powerset](https://en.wikipedia.org/wiki/Power_set) P(x).
297    #[must_use]
298    fn powerset(self) -> Self;
299
300    /// The [von Neumann
301    /// encoding](https://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers#Definition_as_von_Neumann_ordinals)
302    /// for a natural.
303    fn nat(n: usize) -> Self;
304
305    /// The [Zermelo encoding](https://en.wikipedia.org/wiki/Natural_number#Zermelo_ordinals) for a
306    /// natural.
307    fn zermelo(n: usize) -> Self;
308
309    /// The [von Neumann hierarchy](https://en.wikipedia.org/wiki/Von_Neumann_universe).
310    fn neumann(n: usize) -> Self;
311
312    // -------------------- Relations -------------------- //
313
314    /// Subset relation ⊆.
315    fn subset(&self, other: &Self) -> bool {
316        self <= other
317    }
318
319    /// Strict subset relation ⊂.
320    fn ssubset(&self, other: &Self) -> bool {
321        self < other
322    }
323
324    /// Determines whether an iterator outputs a given set.
325    ///
326    /// This is somewhat more efficient than simply testing equality with each element separately,
327    /// as it computes the [`Compare`] structure for `other` only once.
328    fn contains_iter<I: IntoIterator>(iter: I, other: &Self) -> bool
329    where
330        I::Item: AsRef<Mset>,
331    {
332        let mut cmp = Compare::new(other.as_ref());
333        iter.into_iter().any(|set| cmp.eq(set.as_ref()))
334    }
335
336    /// Membership relation ∈.
337    fn contains(&self, other: &Self) -> bool {
338        Self::contains_iter(self.iter(), other)
339    }
340
341    /// Checks whether two sets are disjoint.
342    fn disjoint(&self, other: &Self) -> bool {
343        Self::disjoint_pairwise([self, other])
344    }
345
346    /// Checks whether a list of sets are [disjoint](https://en.wikipedia.org/wiki/Disjoint_sets),
347    /// meaning their intersection is empty.
348    ///
349    /// An empty family is **not** disjoint, as its intersection is the universal class. Likewise, a
350    /// singleton set is only disjoint when its single element is the empty set.
351    ///
352    /// For pairwise disjoint sets, see [`SetTrait::disjoint_pairwise`].
353    fn disjoint_iter<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool;
354
355    /// Checks whether a set of sets is [disjoint](https://en.wikipedia.org/wiki/Disjoint_sets),
356    /// meaning its intersection is empty.
357    ///
358    /// An empty set is **not** disjoint, as its intersection is the universal class. Likewise, a
359    /// singleton set is only disjoint when its single element is the empty set.
360    ///
361    /// For pairwise disjoint sets, see [`SetTrait::disjoint_pairwise_set`]. See also
362    /// [`SetTrait::disjoint`].
363    fn disjoint_set(&self) -> bool {
364        Self::disjoint_iter(self.iter())
365    }
366
367    /// Checks whether a list of sets are pairwise
368    /// [disjoint](https://en.wikipedia.org/wiki/Disjoint_sets), meaning the intersection of any two
369    /// of them is empty.
370    ///
371    /// A family with zero or one elements is disjoint, as any pair of distinct elements in it are
372    /// vacuously disjoint.
373    ///
374    /// For non-pairwise disjoint sets, see [`SetTrait::disjoint_iter`].
375    fn disjoint_pairwise<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool;
376
377    /// Checks whether a set of sets is pairwise
378    /// [disjoint](https://en.wikipedia.org/wiki/Disjoint_sets), meaning the intersection of any two
379    /// of its elements is empty.
380    ///
381    /// A set with zero or one elements is disjoint, as any pair of distinct elements in it are
382    /// vacuously disjoint.
383    ///
384    /// For non-pairwise disjoint sets, see [`SetTrait::disjoint_pairwise_set`]. See also
385    /// [`SetTrait::disjoint_pairwise`].
386    fn disjoint_pairwise_set(&self) -> bool {
387        Self::disjoint_pairwise(self.iter())
388    }
389
390    // -------------------- Axioms -------------------- //
391
392    /// [Replaces](https://en.wikipedia.org/wiki/Axiom_schema_of_replacement) the elements in a set
393    /// by applying a function.
394    #[must_use]
395    #[allow(deprecated)]
396    fn replace<F: FnMut(&Self) -> Self>(&self, func: F) -> Self {
397        Self::_flatten_vec(self.iter().map(func).collect())
398    }
399
400    /// [Replaces](https://en.wikipedia.org/wiki/Axiom_schema_of_replacement) the elements in a set
401    /// by applying a function.
402    #[must_use]
403    #[allow(deprecated)]
404    fn into_replace<F: FnMut(Self) -> Self>(self, func: F) -> Self {
405        Self::_flatten_vec(self.into_iter().map(func).collect())
406    }
407
408    /// [Chooses](https://en.wikipedia.org/wiki/Axiom_of_choice) an arbitrary element from a
409    /// non-empty set.
410    ///
411    /// This should be treated as a complete black box. In particular, **equal sets don't
412    /// necessarily choose the same value**. If that fact makes this philosophically unsuitable as
413    /// an implementation of choice, we also provide [`SetTrait::choose_uniq`], which is more
414    /// computationally expensive but chooses the same element for equal sets.
415    ///
416    /// We do however guarantee that [`SetTrait::into_choose`] will select the same element.
417    fn choose(&self) -> Option<&Self> {
418        self.as_slice().first()
419    }
420
421    /// [Chooses](https://en.wikipedia.org/wiki/Axiom_of_choice) an arbitrary element from a
422    /// non-empty set.
423    ///
424    /// See [`SetTrait::choose`].
425    fn into_choose(self) -> Option<Self>;
426
427    /// [Chooses](https://en.wikipedia.org/wiki/Axiom_of_choice) an arbitrary element from a
428    /// non-empty set.
429    ///
430    /// Unlike [`SetTrait::choose`], this always selects the same element for equal sets. We make no
431    /// further guarantees – this should be treated as a black box.
432    ///
433    /// We do however guarantee that [`SetTrait::into_choose_uniq`] will select the same element.
434    fn choose_uniq(&self) -> Option<&Self>;
435
436    /// [Chooses](https://en.wikipedia.org/wiki/Axiom_of_choice) an arbitrary element from a
437    /// non-empty set.
438    ///
439    /// See [`SetTrait::choose_uniq`].
440    fn into_choose_uniq(self) -> Option<Self>;
441}