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}