vortex_mask/
bitops.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::ops::BitAnd;
5use std::ops::BitOr;
6use std::ops::Not;
7
8use vortex_error::vortex_panic;
9
10use crate::AllOr;
11use crate::Mask;
12
13impl BitAnd for &Mask {
14    type Output = Mask;
15
16    fn bitand(self, rhs: Self) -> Self::Output {
17        if self.len() != rhs.len() {
18            vortex_panic!("Masks must have the same length");
19        }
20
21        match (self.bit_buffer(), rhs.bit_buffer()) {
22            (AllOr::All, _) => rhs.clone(),
23            (_, AllOr::All) => self.clone(),
24            (AllOr::None, _) => Mask::new_false(self.len()),
25            (_, AllOr::None) => Mask::new_false(self.len()),
26            (AllOr::Some(lhs), AllOr::Some(rhs)) => Mask::from_buffer(lhs & rhs),
27        }
28    }
29}
30
31impl BitOr for &Mask {
32    type Output = Mask;
33
34    fn bitor(self, rhs: Self) -> Self::Output {
35        if self.len() != rhs.len() {
36            vortex_panic!("Masks must have the same length");
37        }
38
39        match (self.bit_buffer(), rhs.bit_buffer()) {
40            (AllOr::All, _) => Mask::new_true(self.len()),
41            (_, AllOr::All) => Mask::new_true(self.len()),
42            (AllOr::None, _) => rhs.clone(),
43            (_, AllOr::None) => self.clone(),
44            (AllOr::Some(lhs), AllOr::Some(rhs)) => Mask::from_buffer(lhs | rhs),
45        }
46    }
47}
48
49impl Not for Mask {
50    type Output = Mask;
51
52    fn not(self) -> Self::Output {
53        !(&self)
54    }
55}
56
57impl Not for &Mask {
58    type Output = Mask;
59
60    fn not(self) -> Self::Output {
61        match self.bit_buffer() {
62            AllOr::All => Mask::new_false(self.len()),
63            AllOr::None => Mask::new_true(self.len()),
64            AllOr::Some(buffer) => Mask::from_buffer(!buffer),
65        }
66    }
67}
68
69#[cfg(test)]
70#[allow(clippy::many_single_char_names)]
71mod tests {
72    use vortex_buffer::BitBuffer;
73
74    use super::*;
75
76    #[test]
77    fn test_bitand_all_combinations() {
78        let len = 5;
79
80        // Test AllTrue & AllTrue
81        let all_true = Mask::new_true(len);
82        let result = &all_true & &all_true;
83        assert!(result.all_true());
84        assert_eq!(result.true_count(), len);
85
86        // Test AllTrue & AllFalse
87        let all_false = Mask::new_false(len);
88        let result = &all_true & &all_false;
89        assert!(result.all_false());
90        assert_eq!(result.true_count(), 0);
91
92        // Test AllFalse & AllTrue
93        let result = &all_false & &all_true;
94        assert!(result.all_false());
95        assert_eq!(result.true_count(), 0);
96
97        // Test AllFalse & AllFalse
98        let result = &all_false & &all_false;
99        assert!(result.all_false());
100        assert_eq!(result.true_count(), 0);
101    }
102
103    #[test]
104    fn test_bitand_with_values() {
105        let mask1 = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
106        let mask2 = Mask::from_buffer(BitBuffer::from_iter([true, true, false, false, true]));
107
108        let result = &mask1 & &mask2;
109        assert_eq!(result.len(), 5);
110        assert_eq!(result.true_count(), 2);
111        assert!(result.value(0)); // true & true = true
112        assert!(!result.value(1)); // false & true = false
113        assert!(!result.value(2)); // true & false = false
114        assert!(!result.value(3)); // false & false = false
115        assert!(result.value(4)); // true & true = true
116    }
117
118    #[test]
119    fn test_bitand_all_true_with_values() {
120        let all_true = Mask::new_true(5);
121        let values = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
122
123        // AllTrue & Values should return Values
124        let result = &all_true & &values;
125        assert_eq!(result.true_count(), 3);
126        assert_eq!(result.len(), 5);
127        assert!(result.value(0));
128        assert!(!result.value(1));
129        assert!(result.value(2));
130        assert!(!result.value(3));
131        assert!(result.value(4));
132    }
133
134    #[test]
135    fn test_bitand_all_false_with_values() {
136        let all_false = Mask::new_false(5);
137        let values = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
138
139        // AllFalse & Values should return AllFalse
140        let result = &all_false & &values;
141        assert!(result.all_false());
142        assert_eq!(result.true_count(), 0);
143    }
144
145    #[test]
146    fn test_bitand_values_with_all_true() {
147        let values = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
148        let all_true = Mask::new_true(5);
149
150        // Values & AllTrue should return Values
151        let result = &values & &all_true;
152        assert_eq!(result.true_count(), 3);
153        assert_eq!(result.len(), 5);
154        assert!(result.value(0));
155        assert!(!result.value(1));
156        assert!(result.value(2));
157        assert!(!result.value(3));
158        assert!(result.value(4));
159    }
160
161    #[test]
162    fn test_bitand_values_with_all_false() {
163        let values = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
164        let all_false = Mask::new_false(5);
165
166        // Values & AllFalse should return AllFalse
167        let result = &values & &all_false;
168        assert!(result.all_false());
169        assert_eq!(result.true_count(), 0);
170    }
171
172    #[test]
173    fn test_bitand_empty_masks() {
174        let empty1 = Mask::new_true(0);
175        let empty2 = Mask::new_false(0);
176
177        let result = &empty1 & &empty2;
178        assert_eq!(result.len(), 0);
179        assert!(result.is_empty());
180    }
181
182    #[test]
183    #[should_panic(expected = "Masks must have the same length")]
184    fn test_bitand_different_lengths() {
185        let mask1 = Mask::new_true(5);
186        let mask2 = Mask::new_true(3);
187        let _unused = &mask1 & &mask2;
188    }
189
190    #[test]
191    fn test_not_all_true() {
192        let all_true = Mask::new_true(5);
193        let result = !&all_true;
194        assert!(result.all_false());
195        assert_eq!(result.true_count(), 0);
196        assert_eq!(result.len(), 5);
197    }
198
199    #[test]
200    fn test_not_all_false() {
201        let all_false = Mask::new_false(5);
202        let result = !&all_false;
203        assert!(result.all_true());
204        assert_eq!(result.true_count(), 5);
205        assert_eq!(result.len(), 5);
206    }
207
208    #[test]
209    fn test_not_values() {
210        let values = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
211        let result = !&values;
212
213        assert_eq!(result.len(), 5);
214        assert_eq!(result.true_count(), 2);
215        assert!(!result.value(0)); // !true = false
216        assert!(result.value(1)); // !false = true
217        assert!(!result.value(2)); // !true = false
218        assert!(result.value(3)); // !false = true
219        assert!(!result.value(4)); // !true = false
220    }
221
222    #[test]
223    fn test_not_empty() {
224        let empty_true = Mask::new_true(0);
225        let result = !&empty_true;
226        assert_eq!(result.len(), 0);
227        assert!(result.is_empty());
228
229        let empty_false = Mask::new_false(0);
230        let result = !&empty_false;
231        assert_eq!(result.len(), 0);
232        assert!(result.is_empty());
233    }
234
235    #[test]
236    fn test_double_not() {
237        let original = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
238        let double_not = !&(!&original);
239
240        // Double negation should return the original
241        assert_eq!(double_not.true_count(), original.true_count());
242        for i in 0..5 {
243            assert_eq!(double_not.value(i), original.value(i));
244        }
245    }
246
247    #[test]
248    fn test_demorgan_law() {
249        // Test De Morgan's law: !(A & B) = !A | !B
250        let a = Mask::from_buffer(BitBuffer::from_iter([true, true, false, false]));
251        let b = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false]));
252
253        let and_result = &a & &b;
254        let not_and = !&and_result;
255
256        let not_a = !&a;
257        let not_b = !&b;
258        let or_result = &not_a | &not_b;
259
260        assert_eq!(not_and.len(), 4);
261        assert!(!not_and.value(0)); // !(true & true) = false
262        assert!(not_and.value(1)); // !(true & false) = true
263        assert!(not_and.value(2)); // !(false & true) = true
264        assert!(not_and.value(3)); // !(false & false) = true
265
266        assert_eq!(or_result.len(), 4);
267        assert_eq!(or_result, not_and)
268    }
269
270    #[test]
271    fn test_bitand_associativity() {
272        // Test (A & B) & C = A & (B & C)
273        let a = Mask::from_buffer(BitBuffer::from_iter([true, true, false, true]));
274        let b = Mask::from_buffer(BitBuffer::from_iter([true, false, true, true]));
275        let c = Mask::from_buffer(BitBuffer::from_iter([false, true, true, true]));
276
277        let left_assoc = &(&a & &b) & &c;
278        let right_assoc = &a & &(&b & &c);
279
280        assert_eq!(left_assoc.true_count(), right_assoc.true_count());
281        for i in 0..4 {
282            assert_eq!(left_assoc.value(i), right_assoc.value(i));
283        }
284    }
285
286    #[test]
287    fn test_bitand_commutativity() {
288        // Test A & B = B & A
289        let a = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false]));
290        let b = Mask::from_buffer(BitBuffer::from_iter([false, true, false, true]));
291
292        let a_and_b = &a & &b;
293        let b_and_a = &b & &a;
294
295        assert_eq!(a_and_b.true_count(), b_and_a.true_count());
296        for i in 0..4 {
297            assert_eq!(a_and_b.value(i), b_and_a.value(i));
298        }
299    }
300
301    #[test]
302    fn test_bitand_identity() {
303        // Test A & AllTrue = A
304        let mask = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false]));
305        let all_true = Mask::new_true(4);
306
307        let result = &mask & &all_true;
308        assert_eq!(result.true_count(), mask.true_count());
309        for i in 0..4 {
310            assert_eq!(result.value(i), mask.value(i));
311        }
312    }
313
314    #[test]
315    fn test_bitand_annihilator() {
316        // Test A & AllFalse = AllFalse
317        let mask = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false]));
318        let all_false = Mask::new_false(4);
319
320        let result = &mask & &all_false;
321        assert!(result.all_false());
322        assert_eq!(result.true_count(), 0);
323    }
324
325    #[test]
326    fn test_bitand_idempotence() {
327        // Test A & A = A
328        let mask = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
329        let result = &mask & &mask;
330
331        assert_eq!(result.true_count(), mask.true_count());
332        for i in 0..5 {
333            assert_eq!(result.value(i), mask.value(i));
334        }
335    }
336
337    #[test]
338    fn test_complex_expression() {
339        // Test a more complex expression: (!(!A) | B) & !C
340        let a = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false]));
341        let b = Mask::from_buffer(BitBuffer::from_iter([true, true, false, false]));
342        let c = Mask::from_buffer(BitBuffer::from_iter([false, true, false, true]));
343
344        let not_not_a = !(&(!&a));
345        let not_not_a_or_b = &not_not_a | &b;
346        let not_c = !&c;
347        let result = &not_not_a_or_b & &not_c;
348
349        // Verify the result manually
350        assert!(result.value(0)); // (!(!true) | true) & !false = (true | true) & true = true
351        assert!(!result.value(1)); // (!(!false) | true) & !true = (false | true) & false = false
352        assert!(result.value(2)); // (!(!true) | false) & !false = (true | false) & true = true
353        assert!(!result.value(3)); // (!(!false) | false) & !true = (false | false) & false = false
354    }
355
356    #[test]
357    fn test_bitor() {
358        // Test basic OR operations
359        let mask1 = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false, true]));
360        let mask2 = Mask::from_buffer(BitBuffer::from_iter([true, true, false, false, true]));
361
362        let result = &mask1 | &mask2;
363        assert_eq!(result.len(), 5);
364        assert_eq!(result.true_count(), 4);
365        assert!(result.value(0)); // true | true = true
366        assert!(result.value(1)); // false | true = true
367        assert!(result.value(2)); // true | false = true
368        assert!(!result.value(3)); // false | false = false
369        assert!(result.value(4)); // true | true = true
370
371        // Test with AllTrue
372        let all_true = Mask::new_true(5);
373        let result = &mask1 | &all_true;
374        assert!(result.all_true());
375
376        // Test with AllFalse
377        let all_false = Mask::new_false(5);
378        let result = &mask1 | &all_false;
379        assert_eq!(result.true_count(), mask1.true_count());
380    }
381}