1pub struct AlgaeSet<E> {
33 pos_conditions: Vec<Box<dyn Fn(E) -> bool>>,
34 neg_conditions: Vec<Box<dyn Fn(E) -> bool>>,
35}
36
37impl<E> AlgaeSet<E> {
38 pub fn new(pos_conditions: Vec<Box<dyn Fn(E) -> bool>>) -> Self {
40 Self {
41 pos_conditions,
42 neg_conditions: vec![],
43 }
44 }
45
46 pub fn mono(condition: Box<dyn Fn(E) -> bool>) -> Self {
48 Self::new(vec![condition])
49 }
50
51 pub fn all() -> Self {
53 Self {
54 pos_conditions: vec![Box::new(|_x: E| true)],
55 neg_conditions: vec![],
56 }
57 }
58}
59
60impl<E: Copy + Clone> AlgaeSet<E> {
61 pub fn has(&self, element: E) -> bool {
63 if self.neg_conditions.iter().any(|c| (c)(element)) {
64 return false;
65 }
66 return self.pos_conditions.iter().any(|c| (c)(element));
67 }
68}
69
70impl<E: PartialEq + Copy + Clone + 'static> AlgaeSet<E> {
71 pub fn add(&mut self, element: E) {
73 self.neg_conditions.retain(|c| !(c)(element));
74 self.pos_conditions.push(Box::new(move |x: E| x == element))
75 }
76
77 pub fn remove(&mut self, element: E) {
79 self.pos_conditions.retain(|c| (c)(element));
80 self.neg_conditions.push(Box::new(move |x: E| x == element))
81 }
82
83 pub fn or(&mut self, other: Self) {
85 self.pos_conditions.push(Box::new(move |x: E| other.has(x)));
86 }
87
88 pub fn and(&mut self, other: Self) {
90 self.neg_conditions
91 .push(Box::new(move |x: E| !other.has(x)));
92 }
93}
94
95#[cfg(test)]
96#[allow(non_snake_case)]
97mod tests {
98
99 use super::*;
100
101 mod infinite_set {
102
103 use super::*;
104
105 #[derive(PartialEq, Clone, Copy)]
106 enum Real {
107 UInt(u32),
108 SInt(i32),
109 Float(f32),
110 }
111
112 #[test]
113 fn has_element() {
114 let REALS = AlgaeSet::<Real>::all();
115 assert!(REALS.has(Real::UInt(12)));
116 assert!(REALS.has(Real::SInt(-42)));
117 assert!(REALS.has(Real::Float(-34.2)));
118 }
119
120 #[test]
121 fn remove_element() {
122 let mut REALS = AlgaeSet::<Real>::all();
123 REALS.remove(Real::Float(23.1));
124 assert!(REALS.has(Real::Float(23.2)));
125 assert!(!REALS.has(Real::Float(23.1)));
126 }
127
128 #[test]
129 fn add_after_remove() {
130 let mut REALS = AlgaeSet::<Real>::all();
131 REALS.remove(Real::Float(32.1));
132 assert!(!REALS.has(Real::Float(32.1)));
133 REALS.add(Real::Float(32.1));
134 assert!(REALS.has(Real::Float(32.1)));
135 }
136
137 #[test]
138 fn remove_after_add_after_remove() {
139 let mut REALS = AlgaeSet::<Real>::all();
140 assert!(REALS.has(Real::Float(32.1)));
141 REALS.remove(Real::Float(32.1));
142 assert!(!REALS.has(Real::Float(32.1)));
143 REALS.add(Real::Float(32.1));
144 assert!(REALS.has(Real::Float(32.1)));
145 REALS.remove(Real::Float(32.1));
146 assert!(!REALS.has(Real::Float(32.1)));
147 }
148
149 #[test]
150 fn overlapping_union() {
151 let REALS = AlgaeSet::<Real>::all();
152 let mut FLOATS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
153 Real::UInt(_) => false,
154 Real::SInt(_) => false,
155 Real::Float(_) => true,
156 }));
157 assert!(!FLOATS.has(Real::UInt(12)));
158 FLOATS.or(REALS);
159 assert!(FLOATS.has(Real::UInt(12)));
160 }
161
162 #[test]
163 fn encompassing_union() {
164 let mut REALS = AlgaeSet::<Real>::all();
165 let FLOATS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
166 Real::UInt(_) => false,
167 Real::SInt(_) => false,
168 Real::Float(_) => true,
169 }));
170 REALS.or(FLOATS);
171 assert!(REALS.has(Real::Float(12.0)));
172 assert!(REALS.has(Real::UInt(12)));
173 assert!(REALS.has(Real::SInt(-12)));
174 }
175
176 #[test]
177 fn disjoint_union() {
178 let UINTS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
179 Real::UInt(_) => true,
180 Real::SInt(_) => false,
181 Real::Float(_) => false,
182 }));
183 let mut FLOATS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
184 Real::UInt(_) => false,
185 Real::SInt(_) => false,
186 Real::Float(_) => true,
187 }));
188 assert!(FLOATS.has(Real::Float(12.0)));
189 assert!(!FLOATS.has(Real::UInt(12)));
190 FLOATS.or(UINTS);
191 assert!(FLOATS.has(Real::Float(12.0)));
192 assert!(FLOATS.has(Real::UInt(12)));
193 }
194
195 #[test]
196 fn overlapping_intersection() {
197 let REALS = AlgaeSet::<Real>::all();
198 let mut FLOATS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
199 Real::UInt(_) => false,
200 Real::SInt(_) => false,
201 Real::Float(_) => true,
202 }));
203 assert!(!FLOATS.has(Real::UInt(12)));
204 FLOATS.and(REALS);
205 assert!(!FLOATS.has(Real::UInt(12)));
206 }
207
208 #[test]
209 fn encompassing_intersection() {
210 let mut REALS = AlgaeSet::<Real>::all();
211 let FLOATS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
212 Real::UInt(_) => false,
213 Real::SInt(_) => false,
214 Real::Float(_) => true,
215 }));
216 assert!(REALS.has(Real::UInt(12)));
217 assert!(REALS.has(Real::SInt(-12)));
218 assert!(REALS.has(Real::Float(12.0)));
219 REALS.and(FLOATS);
220 assert!(REALS.has(Real::Float(12.0)));
221 assert!(!REALS.has(Real::UInt(12)));
222 assert!(!REALS.has(Real::SInt(-12)));
223 }
224
225 #[test]
226 fn disjoint_intersection() {
227 let UINTS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
228 Real::UInt(_) => true,
229 Real::SInt(_) => false,
230 Real::Float(_) => false,
231 }));
232 let mut FLOATS = AlgaeSet::<Real>::mono(Box::new(|x: Real| match x {
233 Real::UInt(_) => false,
234 Real::SInt(_) => false,
235 Real::Float(_) => true,
236 }));
237 assert!(FLOATS.has(Real::Float(12.0)));
238 assert!(!FLOATS.has(Real::UInt(12)));
239 FLOATS.and(UINTS);
240 assert!(!FLOATS.has(Real::Float(12.0)));
241 assert!(!FLOATS.has(Real::UInt(12)));
242 }
243 }
244
245 mod finite_set {
246
247 use super::*;
248
249 #[test]
250 fn has_element() {
251 let Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
252 assert!(Z2.has(1));
253 assert!(Z2.has(0));
254 assert!(!Z2.has(2));
255 assert!(!Z2.has(-2));
256 }
257
258 #[test]
259 fn add_element() {
260 let mut Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
261 assert!(!Z2.has(2));
262 Z2.add(2);
263 assert!(Z2.has(2));
264 }
265
266 #[test]
267 fn remove_element() {
268 let mut Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
269 assert!(Z2.has(1));
270 Z2.remove(1);
271 assert!(!Z2.has(1));
272 }
273
274 #[test]
275 fn overlapping_union() {
276 let mut Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
277 let Z3 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 3 == x));
278 Z2.or(Z3);
279 assert!(Z2.has(0));
280 assert!(Z2.has(1));
281 assert!(Z2.has(2));
282 }
283
284 #[test]
285 fn encompassing_union() {
286 let Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
287 let mut Z3 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 3 == x));
288 Z3.or(Z2);
289 assert!(Z3.has(0));
290 assert!(Z3.has(1));
291 assert!(Z3.has(2));
292 }
293
294 #[test]
295 fn disjoint_union() {
296 let mut one = AlgaeSet::<i32>::mono(Box::new(|x: i32| x == 1));
297 let two = AlgaeSet::<i32>::mono(Box::new(|x: i32| x == 2));
298 one.or(two);
299 assert!(one.has(1));
300 assert!(one.has(2));
301 }
302
303 #[test]
304 fn overlapping_intersection() {
305 let mut Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
306 let one = AlgaeSet::<i32>::mono(Box::new(|x: i32| x == 1));
307 Z2.and(one);
308 assert!(Z2.has(1));
309 assert!(!Z2.has(0));
310 }
311
312 #[test]
313 fn encompassing_intersection() {
314 let Z2 = AlgaeSet::<i32>::mono(Box::new(|x: i32| x % 2 == x));
315 let mut one = AlgaeSet::<i32>::mono(Box::new(|x: i32| x == 1));
316 one.and(Z2);
317 assert!(one.has(1));
318 assert!(!one.has(0));
319 }
320
321 #[test]
322 fn disjoint_intersection() {
323 let mut one = AlgaeSet::<i32>::mono(Box::new(|x: i32| x == 1));
324 let two = AlgaeSet::<i32>::mono(Box::new(|x: i32| x == 2));
325 one.and(two);
326 assert!(!one.has(1));
327 assert!(!one.has(2));
328 }
329 }
330}