1use std::ops::BitAnd;
13use std::ops::BitOr;
14use std::ops::Not;
15
16use vortex_buffer::BitBuffer;
17use vortex_mask::Mask;
18use vortex_vector::BoolDatum;
19use vortex_vector::ScalarOps;
20use vortex_vector::VectorMutOps;
21use vortex_vector::VectorOps;
22use vortex_vector::bool::BoolScalar;
23use vortex_vector::bool::BoolVector;
24
25use super::LogicalAndKleene;
26use super::LogicalOp;
27use super::LogicalOrKleene;
28
29pub struct KleeneAnd;
31
32pub struct KleeneOr;
34
35pub trait KleeneBinaryOp {
41 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer;
43
44 fn absorb_bits(bits: &BitBuffer) -> BitBuffer;
49
50 fn scalar_op(lhs: Option<bool>, rhs: Option<bool>) -> Option<bool>;
52}
53
54impl KleeneBinaryOp for KleeneAnd {
55 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer {
56 lhs.bitand(rhs)
57 }
58
59 fn absorb_bits(bits: &BitBuffer) -> BitBuffer {
60 bits.not() }
62
63 fn scalar_op(lhs: Option<bool>, rhs: Option<bool>) -> Option<bool> {
64 match (lhs, rhs) {
65 (Some(false), _) | (_, Some(false)) => Some(false),
66 (Some(true), Some(true)) => Some(true),
67 _ => None,
68 }
69 }
70}
71
72impl KleeneBinaryOp for KleeneOr {
73 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer {
74 lhs.bitor(rhs)
75 }
76
77 fn absorb_bits(bits: &BitBuffer) -> BitBuffer {
78 bits.clone() }
80
81 fn scalar_op(lhs: Option<bool>, rhs: Option<bool>) -> Option<bool> {
82 match (lhs, rhs) {
83 (Some(true), _) | (_, Some(true)) => Some(true),
84 (Some(false), Some(false)) => Some(false),
85 _ => None,
86 }
87 }
88}
89
90impl LogicalOp<KleeneAnd> for &BoolScalar {
95 type Output = BoolScalar;
96
97 fn op(self, rhs: &BoolScalar) -> BoolScalar {
98 kleene_scalar_op::<KleeneAnd>(self, rhs)
99 }
100}
101
102impl LogicalOp<KleeneOr> for &BoolScalar {
103 type Output = BoolScalar;
104
105 fn op(self, rhs: &BoolScalar) -> BoolScalar {
106 kleene_scalar_op::<KleeneOr>(self, rhs)
107 }
108}
109
110impl LogicalOp<KleeneAnd> for &BoolVector {
111 type Output = BoolVector;
112
113 fn op(self, rhs: &BoolVector) -> BoolVector {
114 kleene_vector_op::<KleeneAnd>(self, rhs)
115 }
116}
117
118impl LogicalOp<KleeneOr> for &BoolVector {
119 type Output = BoolVector;
120
121 fn op(self, rhs: &BoolVector) -> BoolVector {
122 kleene_vector_op::<KleeneOr>(self, rhs)
123 }
124}
125
126impl LogicalOp<KleeneAnd, &BoolDatum> for &BoolDatum {
127 type Output = BoolDatum;
128
129 fn op(self, rhs: &BoolDatum) -> BoolDatum {
130 kleene_datum_op::<KleeneAnd>(self, rhs)
131 }
132}
133
134impl LogicalOp<KleeneOr, &BoolDatum> for &BoolDatum {
135 type Output = BoolDatum;
136
137 fn op(self, rhs: &BoolDatum) -> BoolDatum {
138 kleene_datum_op::<KleeneOr>(self, rhs)
139 }
140}
141
142fn kleene_scalar_op<Op: KleeneBinaryOp>(lhs: &BoolScalar, rhs: &BoolScalar) -> BoolScalar {
147 BoolScalar::new(Op::scalar_op(lhs.value(), rhs.value()))
148}
149
150fn kleene_vector_op<Op: KleeneBinaryOp>(lhs: &BoolVector, rhs: &BoolVector) -> BoolVector {
151 assert_eq!(lhs.len(), rhs.len());
152 let len = lhs.len();
153
154 match (lhs.validity(), rhs.validity()) {
155 (Mask::AllTrue(_), Mask::AllTrue(_)) => {
157 let result_bits = Op::bit_op(lhs.bits(), rhs.bits());
158 BoolVector::new(result_bits, Mask::new_true(len))
159 }
160
161 (Mask::AllFalse(_), Mask::AllFalse(_)) => {
163 let result_bits = lhs.bits().clone();
165 BoolVector::new(result_bits, Mask::new_false(len))
166 }
167
168 (Mask::AllTrue(_), Mask::AllFalse(_)) => {
170 let result_bits = lhs.bits().clone();
174 let validity = Op::absorb_bits(lhs.bits());
175 BoolVector::new(result_bits, Mask::from(validity))
176 }
177
178 (Mask::AllFalse(_), Mask::AllTrue(_)) => {
180 let result_bits = rhs.bits().clone();
184 let validity = Op::absorb_bits(rhs.bits());
185 BoolVector::new(result_bits, Mask::from(validity))
186 }
187
188 (Mask::AllTrue(_), Mask::Values(rhs_values)) => {
190 let result_bits = Op::bit_op(lhs.bits(), rhs.bits());
192 let validity = rhs_values.bit_buffer().bitor(&Op::absorb_bits(lhs.bits()));
193 BoolVector::new(result_bits, Mask::from(validity))
194 }
195
196 (Mask::Values(lhs_values), Mask::AllTrue(_)) => {
198 let result_bits = Op::bit_op(lhs.bits(), rhs.bits());
200 let validity = lhs_values.bit_buffer().bitor(&Op::absorb_bits(rhs.bits()));
201 BoolVector::new(result_bits, Mask::from(validity))
202 }
203
204 (Mask::AllFalse(_), Mask::Values(rhs_values)) => {
206 let result_bits = rhs.bits().clone();
209 let validity = rhs_values.bit_buffer().bitand(&Op::absorb_bits(rhs.bits()));
210 BoolVector::new(result_bits, Mask::from(validity))
211 }
212
213 (Mask::Values(lhs_values), Mask::AllFalse(_)) => {
215 let result_bits = lhs.bits().clone();
218 let validity = lhs_values.bit_buffer().bitand(&Op::absorb_bits(lhs.bits()));
219 BoolVector::new(result_bits, Mask::from(validity))
220 }
221
222 (Mask::Values(lhs_values), Mask::Values(rhs_values)) => {
224 let result_bits = Op::bit_op(lhs.bits(), rhs.bits());
240
241 let lhs_valid_or_rhs_absorbs =
242 lhs_values.bit_buffer().bitor(&Op::absorb_bits(rhs.bits()));
243 let rhs_valid_or_lhs_absorbs =
244 rhs_values.bit_buffer().bitor(&Op::absorb_bits(lhs.bits()));
245 let validity = lhs_valid_or_rhs_absorbs.bitand(&rhs_valid_or_lhs_absorbs);
246
247 BoolVector::new(result_bits, Mask::from(validity))
248 }
249 }
250}
251
252fn kleene_datum_op<Op: KleeneBinaryOp>(lhs: &BoolDatum, rhs: &BoolDatum) -> BoolDatum
253where
254 for<'a> &'a BoolScalar: LogicalOp<Op, Output = BoolScalar>,
255 for<'a> &'a BoolVector: LogicalOp<Op, Output = BoolVector>,
256{
257 match (lhs, rhs) {
258 (BoolDatum::Vector(lhs), BoolDatum::Vector(rhs)) => {
259 BoolDatum::Vector(<&BoolVector as LogicalOp<Op>>::op(lhs, rhs))
260 }
261 (BoolDatum::Scalar(lhs), BoolDatum::Scalar(rhs)) => {
262 BoolDatum::Scalar(<&BoolScalar as LogicalOp<Op>>::op(lhs, rhs))
263 }
264 (BoolDatum::Scalar(sc), BoolDatum::Vector(vec)) => {
266 let expanded = sc.repeat(vec.len()).freeze().into_bool();
267 BoolDatum::Vector(<&BoolVector as LogicalOp<Op>>::op(&expanded, vec))
268 }
269 (BoolDatum::Vector(vec), BoolDatum::Scalar(sc)) => {
271 let expanded = sc.repeat(vec.len()).freeze().into_bool();
272 BoolDatum::Vector(<&BoolVector as LogicalOp<Op>>::op(vec, &expanded))
273 }
274 }
275}
276
277impl LogicalAndKleene for &BoolScalar {
282 type Output = BoolScalar;
283
284 fn and_kleene(self, rhs: &BoolScalar) -> BoolScalar {
285 kleene_scalar_op::<KleeneAnd>(self, rhs)
286 }
287}
288
289impl LogicalAndKleene for &BoolVector {
290 type Output = BoolVector;
291
292 fn and_kleene(self, rhs: &BoolVector) -> BoolVector {
293 kleene_vector_op::<KleeneAnd>(self, rhs)
294 }
295}
296
297impl LogicalAndKleene<&BoolDatum> for &BoolDatum {
298 type Output = BoolDatum;
299
300 fn and_kleene(self, rhs: &BoolDatum) -> BoolDatum {
301 <&BoolDatum as LogicalOp<KleeneAnd, &BoolDatum>>::op(self, rhs)
302 }
303}
304
305impl LogicalOrKleene for &BoolScalar {
306 type Output = BoolScalar;
307
308 fn or_kleene(self, rhs: &BoolScalar) -> BoolScalar {
309 kleene_scalar_op::<KleeneOr>(self, rhs)
310 }
311}
312
313impl LogicalOrKleene for &BoolVector {
314 type Output = BoolVector;
315
316 fn or_kleene(self, rhs: &BoolVector) -> BoolVector {
317 kleene_vector_op::<KleeneOr>(self, rhs)
318 }
319}
320
321impl LogicalOrKleene<&BoolDatum> for &BoolDatum {
322 type Output = BoolDatum;
323
324 fn or_kleene(self, rhs: &BoolDatum) -> BoolDatum {
325 <&BoolDatum as LogicalOp<KleeneOr, &BoolDatum>>::op(self, rhs)
326 }
327}
328
329#[cfg(test)]
330mod tests {
331 use vortex_buffer::bitbuffer;
332 use vortex_mask::Mask;
333 use vortex_vector::bool::BoolScalar;
334 use vortex_vector::bool::BoolVector;
335
336 use super::*;
337
338 #[test]
341 fn test_and_kleene_all_valid() {
342 let left = BoolVector::new(bitbuffer![1 0 1], Mask::new_true(3));
344 let right = BoolVector::new(bitbuffer![1 1 0], Mask::new_true(3));
345
346 let result = left.and_kleene(&right);
347 assert_eq!(result.bits(), &bitbuffer![1 0 0]);
348 assert_eq!(result.validity(), &Mask::new_true(3));
349 }
350
351 #[test]
352 fn test_and_kleene_all_null() {
353 let left = BoolVector::new(bitbuffer![1 1], Mask::new_false(2));
355 let right = BoolVector::new(bitbuffer![1 1], Mask::new_false(2));
356
357 let result = left.and_kleene(&right);
358 assert_eq!(result.validity(), &Mask::new_false(2));
359 }
360
361 #[test]
362 fn test_and_kleene_false_and_null() {
363 let left = BoolVector::new(bitbuffer![0], Mask::new_true(1));
365 let right = BoolVector::new(bitbuffer![1], Mask::new_false(1));
366
367 let result = left.and_kleene(&right);
368 assert_eq!(result.bits(), &bitbuffer![0]);
369 assert_eq!(result.validity(), &Mask::new_true(1));
371 }
372
373 #[test]
376 fn test_scalar_and_kleene_true_true() {
377 let left = BoolScalar::new(Some(true));
378 let right = BoolScalar::new(Some(true));
379 assert_eq!(left.and_kleene(&right).value(), Some(true));
380 }
381
382 #[test]
383 fn test_scalar_and_kleene_true_false() {
384 let left = BoolScalar::new(Some(true));
385 let right = BoolScalar::new(Some(false));
386 assert_eq!(left.and_kleene(&right).value(), Some(false));
387 }
388
389 #[test]
390 fn test_scalar_and_kleene_false_null() {
391 let left = BoolScalar::new(Some(false));
393 let right = BoolScalar::new(None);
394 assert_eq!(left.and_kleene(&right).value(), Some(false));
395 }
396
397 #[test]
398 fn test_scalar_and_kleene_null_false() {
399 let left = BoolScalar::new(None);
401 let right = BoolScalar::new(Some(false));
402 assert_eq!(left.and_kleene(&right).value(), Some(false));
403 }
404
405 #[test]
406 fn test_scalar_and_kleene_true_null() {
407 let left = BoolScalar::new(Some(true));
409 let right = BoolScalar::new(None);
410 assert_eq!(left.and_kleene(&right).value(), None);
411 }
412
413 #[test]
414 fn test_scalar_and_kleene_null_null() {
415 let left = BoolScalar::new(None);
416 let right = BoolScalar::new(None);
417 assert_eq!(left.and_kleene(&right).value(), None);
418 }
419
420 #[test]
423 fn test_or_kleene_all_valid() {
424 let left = BoolVector::new(bitbuffer![1 0 0], Mask::new_true(3));
426 let right = BoolVector::new(bitbuffer![0 1 0], Mask::new_true(3));
427
428 let result = left.or_kleene(&right);
429 assert_eq!(result.bits(), &bitbuffer![1 1 0]);
430 assert_eq!(result.validity(), &Mask::new_true(3));
431 }
432
433 #[test]
434 fn test_or_kleene_all_null() {
435 let left = BoolVector::new(bitbuffer![0 0], Mask::new_false(2));
437 let right = BoolVector::new(bitbuffer![0 0], Mask::new_false(2));
438
439 let result = left.or_kleene(&right);
440 assert_eq!(result.validity(), &Mask::new_false(2));
441 }
442
443 #[test]
444 fn test_or_kleene_true_and_null() {
445 let left = BoolVector::new(bitbuffer![1], Mask::new_true(1));
447 let right = BoolVector::new(bitbuffer![0], Mask::new_false(1));
448
449 let result = left.or_kleene(&right);
450 assert_eq!(result.bits(), &bitbuffer![1]);
451 assert_eq!(result.validity(), &Mask::new_true(1));
453 }
454
455 #[test]
458 fn test_scalar_or_kleene_true_true() {
459 let left = BoolScalar::new(Some(true));
460 let right = BoolScalar::new(Some(true));
461 assert_eq!(left.or_kleene(&right).value(), Some(true));
462 }
463
464 #[test]
465 fn test_scalar_or_kleene_true_false() {
466 let left = BoolScalar::new(Some(true));
467 let right = BoolScalar::new(Some(false));
468 assert_eq!(left.or_kleene(&right).value(), Some(true));
469 }
470
471 #[test]
472 fn test_scalar_or_kleene_false_false() {
473 let left = BoolScalar::new(Some(false));
474 let right = BoolScalar::new(Some(false));
475 assert_eq!(left.or_kleene(&right).value(), Some(false));
476 }
477
478 #[test]
479 fn test_scalar_or_kleene_true_null() {
480 let left = BoolScalar::new(Some(true));
482 let right = BoolScalar::new(None);
483 assert_eq!(left.or_kleene(&right).value(), Some(true));
484 }
485
486 #[test]
487 fn test_scalar_or_kleene_null_true() {
488 let left = BoolScalar::new(None);
490 let right = BoolScalar::new(Some(true));
491 assert_eq!(left.or_kleene(&right).value(), Some(true));
492 }
493
494 #[test]
495 fn test_scalar_or_kleene_false_null() {
496 let left = BoolScalar::new(Some(false));
498 let right = BoolScalar::new(None);
499 assert_eq!(left.or_kleene(&right).value(), None);
500 }
501
502 #[test]
503 fn test_scalar_or_kleene_null_null() {
504 let left = BoolScalar::new(None);
505 let right = BoolScalar::new(None);
506 assert_eq!(left.or_kleene(&right).value(), None);
507 }
508
509 #[test]
512 fn test_datum_and_kleene_vector_vector() {
513 let left = BoolDatum::Vector(BoolVector::new(bitbuffer![0], Mask::new_true(1)));
514 let right = BoolDatum::Vector(BoolVector::new(bitbuffer![1], Mask::new_false(1)));
515
516 let result = left.and_kleene(&right);
517 let BoolDatum::Vector(vec) = result else {
518 panic!("Expected Vector");
519 };
520 assert_eq!(vec.bits(), &bitbuffer![0]);
522 assert_eq!(vec.validity(), &Mask::new_true(1));
523 }
524
525 #[test]
526 fn test_datum_and_kleene_scalar_scalar() {
527 let left = BoolDatum::Scalar(BoolScalar::new(Some(false)));
528 let right = BoolDatum::Scalar(BoolScalar::new(None));
529
530 let result = left.and_kleene(&right);
531 let BoolDatum::Scalar(sc) = result else {
532 panic!("Expected Scalar");
533 };
534 assert_eq!(sc.value(), Some(false));
536 }
537
538 #[test]
539 fn test_datum_or_kleene_scalar_vector() {
540 let left = BoolDatum::Scalar(BoolScalar::new(Some(true)));
541 let right = BoolDatum::Vector(BoolVector::new(bitbuffer![0 0], Mask::new_false(2)));
542
543 let result = left.or_kleene(&right);
544 let BoolDatum::Vector(vec) = result else {
545 panic!("Expected Vector");
546 };
547 assert_eq!(vec.bits(), &bitbuffer![1 1]);
549 assert_eq!(vec.validity(), &Mask::new_true(2));
550 }
551}