Skip to main content

oxilean_std/hashset/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use std::hash::Hash;
6
7use super::oxihashset_type::OxiHashSet;
8
9use super::functions::*;
10use std::collections::HashMap;
11
12/// A bijective map between two sets (one-to-one and onto).
13///
14/// Useful for tracking variable renaming during alpha-equivalence checks.
15#[derive(Clone, Debug, Default)]
16pub struct Bijection<A: Eq + Hash + Clone, B: Eq + Hash + Clone> {
17    forward: std::collections::HashMap<A, B>,
18    backward: std::collections::HashMap<B, A>,
19}
20impl<A: Eq + Hash + Clone, B: Eq + Hash + Clone> Bijection<A, B> {
21    /// Create an empty bijection.
22    pub fn new() -> Self {
23        Self {
24            forward: std::collections::HashMap::new(),
25            backward: std::collections::HashMap::new(),
26        }
27    }
28    /// Insert a pair (a, b). Returns `false` if either side is already bound.
29    pub fn insert(&mut self, a: A, b: B) -> bool {
30        if self.forward.contains_key(&a) || self.backward.contains_key(&b) {
31            return false;
32        }
33        self.forward.insert(a.clone(), b.clone());
34        self.backward.insert(b, a);
35        true
36    }
37    /// Look up the image of `a`.
38    pub fn forward(&self, a: &A) -> Option<&B> {
39        self.forward.get(a)
40    }
41    /// Look up the preimage of `b`.
42    pub fn backward(&self, b: &B) -> Option<&A> {
43        self.backward.get(b)
44    }
45    /// Number of pairs.
46    pub fn len(&self) -> usize {
47        self.forward.len()
48    }
49    /// Check whether the bijection is empty.
50    pub fn is_empty(&self) -> bool {
51        self.forward.is_empty()
52    }
53    /// Remove a pair by its left element. Returns the removed right element if present.
54    pub fn remove(&mut self, a: &A) -> Option<B> {
55        if let Some(b) = self.forward.remove(a) {
56            self.backward.remove(&b);
57            Some(b)
58        } else {
59            None
60        }
61    }
62}
63/// Bloom filter axioms: approximate membership with false-positive bounds.
64#[allow(dead_code)]
65pub struct BloomFilterExt {
66    bit_array: Vec<bool>,
67    hash_count: usize,
68    expected_insertions: usize,
69    false_positive_rate: f64,
70}
71/// Power set axioms: the set of all subsets.
72#[allow(dead_code)]
73pub struct PowerSetExt<T: Eq + std::hash::Hash + Clone> {
74    base: OxiHashSet<T>,
75    /// Cantor's theorem: |P(S)| = 2^|S|
76    cardinality_bound: usize,
77}
78/// A multiset: like a set but tracks element multiplicities.
79#[derive(Clone, Debug, PartialEq, Eq, Default)]
80pub struct MultiSet<T: Eq + Hash + Clone> {
81    counts: std::collections::HashMap<T, usize>,
82}
83impl<T: Eq + Hash + Clone> MultiSet<T> {
84    /// Create an empty multiset.
85    pub fn new() -> Self {
86        Self {
87            counts: std::collections::HashMap::new(),
88        }
89    }
90    /// Insert one occurrence of `elem`.
91    pub fn insert(&mut self, elem: T) {
92        *self.counts.entry(elem).or_insert(0) += 1;
93    }
94    /// Remove one occurrence of `elem`. Returns the new count (0 if absent).
95    pub fn remove_one(&mut self, elem: &T) -> usize {
96        if let Some(c) = self.counts.get_mut(elem) {
97            if *c > 1 {
98                *c -= 1;
99                *c
100            } else {
101                self.counts.remove(elem);
102                0
103            }
104        } else {
105            0
106        }
107    }
108    /// Count occurrences of `elem`.
109    pub fn count(&self, elem: &T) -> usize {
110        self.counts.get(elem).copied().unwrap_or(0)
111    }
112    /// Total number of elements (with multiplicity).
113    pub fn total(&self) -> usize {
114        self.counts.values().sum()
115    }
116    /// Number of distinct elements.
117    pub fn distinct_count(&self) -> usize {
118        self.counts.len()
119    }
120    /// Convert to a plain set (discarding multiplicities).
121    pub fn to_set(&self) -> OxiHashSet<T> {
122        OxiHashSet::from_iter(self.counts.keys().cloned())
123    }
124    /// Check if the multiset is empty.
125    pub fn is_empty(&self) -> bool {
126        self.counts.is_empty()
127    }
128    /// Clear the multiset.
129    pub fn clear(&mut self) {
130        self.counts.clear();
131    }
132    /// Return `true` if `elem` is present at least once.
133    pub fn contains(&self, elem: &T) -> bool {
134        self.counts.contains_key(elem)
135    }
136}
137/// Extended lattice structure for sets (join = union, meet = intersection).
138#[allow(dead_code)]
139pub struct SetLatticeExt<T: Eq + std::hash::Hash + Clone> {
140    universe: OxiHashSet<T>,
141    bottom: OxiHashSet<T>,
142    top: OxiHashSet<T>,
143}
144/// A simple disjoint-set (union-find) data structure over integer IDs.
145#[derive(Clone, Debug)]
146pub struct UnionFind {
147    parent: Vec<usize>,
148    rank: Vec<usize>,
149}
150impl UnionFind {
151    /// Create a new union-find with `n` singletons (0..n).
152    pub fn new(n: usize) -> Self {
153        Self {
154            parent: (0..n).collect(),
155            rank: vec![0; n],
156        }
157    }
158    /// Find the representative of the component containing `x` (path compression).
159    pub fn find(&mut self, x: usize) -> usize {
160        if self.parent[x] != x {
161            self.parent[x] = self.find(self.parent[x]);
162        }
163        self.parent[x]
164    }
165    /// Union the components containing `x` and `y`. Returns `true` if they were separate.
166    pub fn union(&mut self, x: usize, y: usize) -> bool {
167        let rx = self.find(x);
168        let ry = self.find(y);
169        if rx == ry {
170            return false;
171        }
172        if self.rank[rx] < self.rank[ry] {
173            self.parent[rx] = ry;
174        } else if self.rank[rx] > self.rank[ry] {
175            self.parent[ry] = rx;
176        } else {
177            self.parent[ry] = rx;
178            self.rank[rx] += 1;
179        }
180        true
181    }
182    /// Check whether `x` and `y` are in the same component.
183    pub fn same(&mut self, x: usize, y: usize) -> bool {
184        self.find(x) == self.find(y)
185    }
186    /// Count the number of distinct components.
187    pub fn component_count(&mut self) -> usize {
188        let n = self.parent.len();
189        (0..n).filter(|&i| self.find(i) == i).count()
190    }
191    /// Collect all elements in the same component as `x`.
192    pub fn component_of(&mut self, x: usize) -> Vec<usize> {
193        let root = self.find(x);
194        let n = self.parent.len();
195        (0..n).filter(|&i| self.find(i) == root).collect()
196    }
197}
198/// Set partition axioms: disjoint covering of a base set.
199#[allow(dead_code)]
200pub struct SetPartitionExt<T: Eq + std::hash::Hash + Clone> {
201    base: OxiHashSet<T>,
202    parts: Vec<OxiHashSet<T>>,
203}
204/// Disjoint union (coproduct) of sets.
205#[allow(dead_code)]
206pub struct DisjointUnionExt<T: Eq + std::hash::Hash + Clone> {
207    left: OxiHashSet<T>,
208    right: OxiHashSet<T>,
209    /// Cardinality of the disjoint union = |left| + |right| (when disjoint)
210    total_cardinality: usize,
211}