Skip to content

Commit

Permalink
Compute BooleanFunction from ANF string representation
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Prévost committed Nov 8, 2024
1 parent ddbee82 commit f4dc2ee
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
46 changes: 43 additions & 3 deletions src/anf_polynom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use itertools::Itertools;
use num_bigint::BigUint;
use num_traits::{One, Zero};
use std::fmt::Display;
use crate::BooleanFunctionError;
use fast_boolean_anf_transform::fast_bool_anf_transform_unsigned;
use crate::{BigBooleanFunction, BooleanFunction, BooleanFunctionError, SmallBooleanFunction};
use crate::utils::fast_anf_transform_biguint;

#[derive(Debug, Clone, Eq, PartialEq)]
enum PolynomialFormat {
Expand Down Expand Up @@ -127,7 +129,7 @@ impl AnfPolynomial {
///
/// Representation must be in the form "`x0*x2*x3 + x2*x3 + x1 + 1`".
///
/// X's index start at 0, meaning the maximum index is variable count - 1.
/// X's index starts at 0, meaning the maximum index is variable count - 1.
///
/// # Parameters:
/// - `anf_polynomial`: The string representation of the ANF form
Expand Down Expand Up @@ -209,6 +211,31 @@ impl AnfPolynomial {
PolynomialFormat::Big(_) => crate::BooleanFunctionType::Big
}
}

/// Convert ANF polynomial to the corresponding Boolean Function, using fast ANF transform algorithm
///
/// # Returns
/// A Boolean function corresponding to the polynomial
pub fn to_boolean_function(&self) -> BooleanFunction {
match &self.polynomial {
PolynomialFormat::Small(polynomial) => {
BooleanFunction::Small(
SmallBooleanFunction::from_truth_table(
fast_bool_anf_transform_unsigned(*polynomial, self.num_variables),
self.num_variables
).unwrap()
)
}
PolynomialFormat::Big(polynomial) => {
BooleanFunction::Big(
BigBooleanFunction::from_truth_table(
fast_anf_transform_biguint(polynomial, self.num_variables),
self.num_variables
)
)
}
}
}
}

/// Display implementation for `AnfPolynomial`.
Expand All @@ -225,7 +252,7 @@ mod tests {
use crate::anf_polynom::AnfPolynomial;
use num_bigint::BigUint;
use num_traits::{Num, One, Zero};
use crate::BooleanFunctionError;
use crate::{BooleanFunctionError, BooleanFunctionImpl};

#[test]
fn test_get_polynomial_small() {
Expand Down Expand Up @@ -357,4 +384,17 @@ mod tests {
assert!(anf_polynomial.is_err());
assert_eq!(anf_polynomial.unwrap_err(), BooleanFunctionError::ErrorParsingAnfString);
}

#[test]
fn test_to_boolean_function() {
let rule_30_anf_str = "x0*x1 + x0 + x1 + x2";
let rule_30_polynomial = AnfPolynomial::from_str(rule_30_anf_str, 3).unwrap();
let rule_30_function = rule_30_polynomial.to_boolean_function();
assert_eq!(rule_30_function.printable_hex_truth_table(), "1e");

let anf_str = "x0*x1*x2*x3*x4*x5*x6 + x7";
let anf_polynomial = AnfPolynomial::from_str(anf_str, 8).unwrap();
let boolean_function = anf_polynomial.to_boolean_function();
assert_eq!(boolean_function.printable_hex_truth_table(), "7fffffffffffffffffffffffffffffff80000000000000000000000000000000");
}
}
29 changes: 28 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,9 +916,25 @@ impl BooleanFunction {
}
Ok(BigBooleanFunction::from_truth_table(truth_table.clone(), num_variables).into())
}

/// Computes Boolean Function from string ANF representation
///
/// The ANF string representation must be in exact form "`x0*x2*x3 + x2*x3 + x1 + 1`".
///
/// X's index starts at 0, meaning the maximum index is variable count - 1.
///
/// # Parameters:
/// - `anf_polynomial`: The string representation of the ANF form
/// - `num_variables`: Variable count of the polynomial
///
/// # Returns
/// The BooleanFunction corresponding to the ANF string representation, or an error if the input string doesn't respect the format and `unsafe_disable_safety_checks` feature is not activated.
pub fn from_anf_polynomial_str(anf_polynomial: &str, num_variables: usize) -> Result<BooleanFunction, BooleanFunctionError> {
Ok(AnfPolynomial::from_str(anf_polynomial, num_variables)?.to_boolean_function())
}
}

// TODO from polynomial etc.
// TODO from AnfPolynomial

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -2152,4 +2168,15 @@ mod tests {
assert!(close_balanced_iterator.next().unwrap().is_balanced());
}
}

#[test]
fn test_from_anf_polynomial_str() {
let rule_30_anf_str = "x0*x1 + x0 + x1 + x2";
let rule_30_function = BooleanFunction::from_anf_polynomial_str(rule_30_anf_str, 3).unwrap();
assert_eq!(rule_30_function.printable_hex_truth_table(), "1e");

let anf_str = "x0*x1*x2*x3*x4*x5*x6 + x7";
let boolean_function = BooleanFunction::from_anf_polynomial_str(anf_str, 8).unwrap();
assert_eq!(boolean_function.printable_hex_truth_table(), "7fffffffffffffffffffffffffffffff80000000000000000000000000000000");
}
}

0 comments on commit f4dc2ee

Please sign in to comment.