Skip to content

Commit 65cdb2f

Browse files
committed
Add support for ADD and MUL operation on BooleanFunction, SmallBooleanFunction, BigBooleanFunction and AnfPolynomial
1 parent 2e0aa72 commit 65cdb2f

File tree

4 files changed

+492
-6
lines changed

4 files changed

+492
-6
lines changed

src/anf_polynom.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use itertools::Itertools;
66
use num_bigint::BigUint;
77
use num_traits::{FromPrimitive, One, ToPrimitive, Zero};
88
use std::fmt::Display;
9-
use std::ops::{BitAnd, BitAndAssign, BitXor, BitXorAssign};
9+
use std::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitXor, BitXorAssign, Mul, MulAssign};
1010
use fast_boolean_anf_transform::fast_bool_anf_transform_unsigned;
1111
use crate::{BigBooleanFunction, BooleanFunction, BooleanFunctionError, SmallBooleanFunction};
1212
use crate::utils::fast_anf_transform_biguint;
@@ -307,6 +307,31 @@ impl BitXor for AnfPolynomial {
307307
}
308308
}
309309

310+
/// ADD operator for Boolean functions ANF polynomial.
311+
///
312+
/// It is equivalent to [crate::AnfPolynomial::bitxor] operator.
313+
///
314+
/// # Panics
315+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
316+
impl Add for AnfPolynomial {
317+
type Output = Self;
318+
fn add(self, rhs: Self) -> Self::Output {
319+
self ^ rhs
320+
}
321+
}
322+
323+
/// In-place ADD operator for Boolean functions ANF polynomial.
324+
///
325+
/// It is equivalent to [crate::AnfPolynomial::bitxor_assign] operator.
326+
///
327+
/// # Panics
328+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
329+
impl AddAssign for AnfPolynomial {
330+
fn add_assign(&mut self, rhs: Self) {
331+
*self ^= rhs;
332+
}
333+
}
334+
310335
/// In-place AND operator for Boolean functions ANF polynomial
311336
///
312337
/// # Panics
@@ -391,6 +416,31 @@ impl BitAnd for AnfPolynomial {
391416
}
392417
}
393418

419+
/// MUL operator for Boolean functions ANF polynomial.
420+
///
421+
/// It is equivalent to [crate::AnfPolynomial::bitand] operator.
422+
///
423+
/// # Panics
424+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
425+
impl Mul for AnfPolynomial {
426+
type Output = Self;
427+
fn mul(self, rhs: Self) -> Self::Output {
428+
self & rhs
429+
}
430+
}
431+
432+
/// In-place MUL operator for Boolean functions ANF polynomial.
433+
///
434+
/// It is equivalent to [crate::AnfPolynomial::bitand_assign] operator.
435+
///
436+
/// # Panics
437+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
438+
impl MulAssign for AnfPolynomial {
439+
fn mul_assign(&mut self, rhs: Self) {
440+
*self &= rhs;
441+
}
442+
}
443+
394444
#[cfg(test)]
395445
mod tests {
396446
use crate::anf_polynom::AnfPolynomial;
@@ -594,6 +644,23 @@ mod tests {
594644
assert_eq!(anf_2.to_string(), "x0*x1*x2 + x0*x2 + x0 + x2 + 1");
595645
}
596646

647+
#[test]
648+
fn test_add() {
649+
let anf_1 = AnfPolynomial::from_str("x0*x1*x4*x7 + x2*x3 + x1 + 0", 8).unwrap();
650+
let mut anf_2 = AnfPolynomial::from_str("x0*x1*x2*x4*x7 + x2*x3 + x3 + 1", 8).unwrap();
651+
let anf_3 = anf_1.clone() + anf_2.clone();
652+
assert_eq!(anf_3.to_string(), "x0*x1*x2*x4*x7 + x0*x1*x4*x7 + x1 + x3 + 1");
653+
anf_2 += anf_1;
654+
assert_eq!(anf_2.to_string(), "x0*x1*x2*x4*x7 + x0*x1*x4*x7 + x1 + x3 + 1");
655+
656+
let anf_1 = AnfPolynomial::from_str("x0*x1 + x0 + x1 + x2", 3).unwrap();
657+
let mut anf_2 = AnfPolynomial::from_str("x0*x1*x2 + x0*x2 + x1*x0 + x1 + 1", 3).unwrap();
658+
let anf_3 = anf_1.clone() + anf_2.clone();
659+
assert_eq!(anf_3.to_string(), "x0*x1*x2 + x0*x2 + x0 + x2 + 1");
660+
anf_2 += anf_1;
661+
assert_eq!(anf_2.to_string(), "x0*x1*x2 + x0*x2 + x0 + x2 + 1");
662+
}
663+
597664
#[test]
598665
fn test_and() {
599666
let anf_1 = AnfPolynomial::from_str("x0*x1", 3).unwrap();
@@ -687,4 +754,21 @@ mod tests {
687754
anf_2 &= anf_1;
688755
assert_eq!(anf_2.to_string(), "x5*x6*x7 + x4*x5 + x4*x6 + x3*x7 + x3 + x6 + x7 + 1");
689756
}
757+
758+
#[test]
759+
fn test_mul() {
760+
let anf_1 = AnfPolynomial::from_str("x0*x1 + x0 + x1 + x2", 3).unwrap();
761+
let mut anf_2 = AnfPolynomial::from_str("x0*x1 + x0*x1*x2 + x1 + 1", 3).unwrap();
762+
let anf_3 = anf_1.clone() * anf_2.clone();
763+
assert_eq!(anf_3.to_string(), "x0*x1*x2 + x1*x2 + x0 + x2");
764+
anf_2 *= anf_1;
765+
assert_eq!(anf_2.to_string(), "x0*x1*x2 + x1*x2 + x0 + x2");
766+
767+
let anf_1 = AnfPolynomial::from_str("x3*x7 + x3 + x4*x5 + x4*x6 + x5*x6*x7 + x6 + x7 + 1", 8).unwrap();
768+
let mut anf_2 = AnfPolynomial::from_str("x3*x5*x6*x7 + x3*x6*x7 + x3*x6 + x3*x7 + x3 + x4*x5*x6 + x4*x5*x7 + x4*x7 + x4 + x6*x7 + x6 + x7 + 1", 8).unwrap();
769+
let anf_3 = anf_1.clone() * anf_2.clone();
770+
assert_eq!(anf_3.to_string(), "x3*x4*x5*x7 + x3*x4*x5 + x4*x5*x6 + x3*x4*x7 + x4*x5*x7 + x3*x6*x7 + x3*x4 + x3*x6 + x3*x7 + x4*x7 + x6*x7 + x3 + x4 + x6 + x7 + 1");
771+
anf_2 *= anf_1;
772+
assert_eq!(anf_2.to_string(), "x3*x4*x5*x7 + x3*x4*x5 + x4*x5*x6 + x3*x4*x7 + x4*x5*x7 + x3*x6*x7 + x3*x4 + x3*x6 + x3*x7 + x4*x7 + x6*x7 + x3 + x4 + x6 + x7 + 1");
773+
}
690774
}

src/big_boolean_function.rs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use itertools::{enumerate, Itertools};
1010
use num_bigint::BigUint;
1111
use num_integer::binomial;
1212
use num_traits::{FromPrimitive, One, Zero};
13-
use std::ops::{BitAnd, BitAndAssign, BitXor, BitXorAssign, Not};
13+
use std::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitXor, BitXorAssign, Mul, MulAssign, Not};
1414

1515
/// Struct representing a boolean function with a big truth table.
1616
///
@@ -461,6 +461,32 @@ impl BitXor for BigBooleanFunction {
461461
}
462462
}
463463

464+
/// ADD operator for Boolean functions truth tables.
465+
///
466+
/// It is equivalent to [crate::BigBooleanFunction::bitxor] operator.
467+
///
468+
/// # Panics
469+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
470+
impl Add for BigBooleanFunction {
471+
type Output = Self;
472+
473+
fn add(self, rhs: Self) -> Self::Output {
474+
self ^ rhs
475+
}
476+
}
477+
478+
/// In-place ADD operator for Boolean functions truth tables.
479+
///
480+
/// It is equivalent to [crate::BigBooleanFunction::bitxor_assign] operator.
481+
///
482+
/// # Panics
483+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
484+
impl AddAssign for BigBooleanFunction {
485+
fn add_assign(&mut self, rhs: Self) {
486+
*self ^= rhs;
487+
}
488+
}
489+
464490
/// In-place AND operator for Boolean functions truth tables.
465491
///
466492
/// # Panics
@@ -488,6 +514,31 @@ impl BitAnd for BigBooleanFunction {
488514
}
489515
}
490516

517+
/// MUL operator for Boolean functions truth tables.
518+
///
519+
/// It is equivalent to [crate::BigBooleanFunction::bitand] operator.
520+
///
521+
/// # Panics
522+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
523+
impl Mul for BigBooleanFunction {
524+
type Output = Self;
525+
fn mul(self, rhs: Self) -> Self::Output {
526+
self & rhs
527+
}
528+
}
529+
530+
/// In-place MUL operator for Boolean functions truth tables.
531+
///
532+
/// It is equivalent to [crate::BigBooleanFunction::bitand_assign] operator.
533+
///
534+
/// # Panics
535+
/// If the Boolean functions have different number of variables, and the `unsafe_disable_safety_checks` feature is not enabled.
536+
impl MulAssign for BigBooleanFunction {
537+
fn mul_assign(&mut self, rhs: Self) {
538+
*self &= rhs;
539+
}
540+
}
541+
491542
/// NOT operator for Boolean functions.
492543
///
493544
/// This is equivalent to the [crate::BooleanFunctionImpl::reverse] operation: it reverses each output of the Boolean function.
@@ -936,6 +987,30 @@ mod tests {
936987
assert_eq!(boolean_function3.variables_count(), 7);
937988
}
938989

990+
#[test]
991+
fn test_add() {
992+
let mut boolean_function = BigBooleanFunction::from_truth_table(
993+
BigUint::from_str_radix("80921c010276c440400810a80e200425", 16).unwrap(),
994+
7,
995+
);
996+
let boolean_function2 = BigBooleanFunction::from_truth_table(
997+
BigUint::from_str_radix("22442244118811882244224411881188", 16).unwrap(),
998+
7,
999+
);
1000+
let boolean_function3 = boolean_function.clone() + boolean_function2.clone();
1001+
boolean_function += boolean_function2;
1002+
assert_eq!(
1003+
boolean_function.printable_hex_truth_table(),
1004+
"a2d63e4513fed5c8624c32ec1fa815ad"
1005+
);
1006+
assert_eq!(boolean_function.variables_count(), 7);
1007+
assert_eq!(
1008+
boolean_function3.printable_hex_truth_table(),
1009+
"a2d63e4513fed5c8624c32ec1fa815ad"
1010+
);
1011+
assert_eq!(boolean_function3.variables_count(), 7);
1012+
}
1013+
9391014
#[test]
9401015
fn test_and() {
9411016
let mut boolean_function = BigBooleanFunction::from_truth_table(
@@ -960,6 +1035,30 @@ mod tests {
9601035
assert_eq!(boolean_function3.variables_count(), 8);
9611036
}
9621037

1038+
#[test]
1039+
fn test_mul() {
1040+
let mut boolean_function = BigBooleanFunction::from_truth_table(
1041+
BigUint::from_str_radix("4f1ead396f247a0410bdb210c006eab568ab4bfa8acb7a13b14ede67096c6eed", 16).unwrap(),
1042+
8,
1043+
);
1044+
let boolean_function2 = BigBooleanFunction::from_truth_table(
1045+
BigUint::from_str_radix("c870974094ead8a96a450b2ef33486b4e61a4c5e97816f7a7bae007d4c53fc7d", 16).unwrap(),
1046+
8,
1047+
);
1048+
let boolean_function3 = boolean_function.clone() * boolean_function2.clone();
1049+
boolean_function *= boolean_function2;
1050+
assert_eq!(
1051+
boolean_function.printable_hex_truth_table(),
1052+
"481085000420580000050200c00482b4600a485a82816a12310e006508406c6d"
1053+
);
1054+
assert_eq!(boolean_function.variables_count(), 8);
1055+
assert_eq!(
1056+
boolean_function3.printable_hex_truth_table(),
1057+
"481085000420580000050200c00482b4600a485a82816a12310e006508406c6d"
1058+
);
1059+
assert_eq!(boolean_function3.variables_count(), 8);
1060+
}
1061+
9631062
#[test]
9641063
fn test_biguint_truth_table() {
9651064
let boolean_function = BigBooleanFunction::from_truth_table(

0 commit comments

Comments
 (0)