@@ -3,9 +3,7 @@ use crate::anf_polynom::AnfPolynomial;
33use crate :: boolean_function_error:: XOR_DIFFERENT_VAR_COUNT_PANIC_MSG ;
44use crate :: iterator:: { BooleanFunctionIterator , CloseBalancedFunctionIterator , SmallCloseBalancedFunctionIterator } ;
55use crate :: utils:: left_kernel_boolean;
6- #[ cfg( not( feature = "unsafe_disable_safety_checks" ) ) ]
7- use crate :: BooleanFunctionError :: TooBigTruthTableForVarCount ;
8- use crate :: BooleanFunctionError :: TooBigVariableCount ;
6+ use crate :: BooleanFunctionError :: { TooBigTruthTableForVarCount , TooBigVariableCount } ;
97use crate :: { BooleanFunction , BooleanFunctionError , BooleanFunctionImpl , BooleanFunctionType } ;
108use fast_boolean_anf_transform:: fast_bool_anf_transform_unsigned;
119use itertools:: { enumerate, Itertools } ;
@@ -327,6 +325,44 @@ impl SmallBooleanFunction {
327325
328326 Ok ( SmallCloseBalancedFunctionIterator :: create ( self , flippable_positions, bits_to_flip_count) )
329327 }
328+
329+ /// Computes SmallBooleanFunction from string ANF representation
330+ ///
331+ /// The ANF string representation must be in exact form "`x0*x2*x3 + x2*x3 + x1 + 1`".
332+ ///
333+ /// X's index starts at 0, meaning the maximum index is variable count - 1.
334+ ///
335+ /// # Parameters:
336+ /// - `anf_polynomial`: The string representation of the ANF form
337+ /// - `num_variables`: Variable count of the polynomial
338+ ///
339+ /// # Returns
340+ /// The SmallBooleanFunction corresponding to the ANF string representation, or an error if:
341+ /// - the input string doesn't respect the format and `unsafe_disable_safety_checks` feature is not activated.
342+ /// - the polynomial variable count is greater than 6
343+ pub fn from_anf_polynomial_str_inner ( anf_polynomial : & str , num_variables : usize ) -> Result < Self , BooleanFunctionError > {
344+ #[ cfg( not( feature = "unsafe_disable_safety_checks" ) ) ]
345+ if num_variables > 6 {
346+ return Err ( TooBigTruthTableForVarCount ) ;
347+ }
348+ Ok ( Self :: from_anf_polynomial_inner (
349+ & AnfPolynomial :: from_str ( anf_polynomial, num_variables) ?
350+ ) ?)
351+ }
352+
353+ /// Computes SmallBooleanFunction from ANF polynomial
354+ ///
355+ /// # Parameters:
356+ /// - `anf_polynomial`: The polynomial in Algebraic Normal Form
357+ ///
358+ /// # Returns
359+ /// The SmallBooleanFunction corresponding to the ANF polynomial, or an error if polynomial variable count > 6
360+ pub fn from_anf_polynomial_inner ( anf_polynomial : & AnfPolynomial ) -> Result < Self , BooleanFunctionError > {
361+ match anf_polynomial. to_boolean_function ( ) {
362+ BooleanFunction :: Small ( small_bf) => Ok ( small_bf) ,
363+ BooleanFunction :: Big ( _) => Err ( TooBigTruthTableForVarCount )
364+ }
365+ }
330366}
331367
332368impl BooleanFunctionImpl for SmallBooleanFunction {
@@ -461,7 +497,7 @@ impl Not for SmallBooleanFunction {
461497
462498#[ cfg( test) ]
463499mod tests {
464- use crate :: { BooleanFunctionImpl , SmallBooleanFunction } ;
500+ use crate :: { AnfPolynomial , BooleanFunctionError , BooleanFunctionImpl , SmallBooleanFunction } ;
465501
466502 #[ test]
467503 fn test_from_truth_table ( ) {
@@ -862,4 +898,39 @@ mod tests {
862898 let mut close_balanced_iterator = bent_function. close_balanced_functions_iterator_inner ( ) . unwrap ( ) ;
863899 assert ! ( close_balanced_iterator. all( |f| f. is_balanced( ) ) ) ;
864900 }
901+
902+ #[ test]
903+ fn test_from_anf_polynomial_str_inner ( ) {
904+ let rule_30_anf_str = "x0*x1 + x0 + x1 + x2" ;
905+ let rule_30_function = SmallBooleanFunction :: from_anf_polynomial_str_inner ( rule_30_anf_str, 3 ) . unwrap ( ) ;
906+ assert_eq ! ( rule_30_function. printable_hex_truth_table( ) , "1e" ) ;
907+ assert_eq ! ( rule_30_function. get_truth_table_u64( ) , 30 ) ;
908+
909+ let rule_30_anf_str = "x0*x1 + x0 + x1 + x2" ;
910+ let boolean_function = SmallBooleanFunction :: from_anf_polynomial_str_inner ( rule_30_anf_str, 8 ) ;
911+ assert ! ( boolean_function. is_err( ) ) ;
912+ assert_eq ! ( boolean_function. unwrap_err( ) , BooleanFunctionError :: TooBigTruthTableForVarCount ) ;
913+
914+ let anf_str = "x0*x1*x3 + x0 + x1 + x2" ;
915+ let boolean_function = SmallBooleanFunction :: from_anf_polynomial_str_inner ( anf_str, 3 ) ;
916+ assert ! ( boolean_function. is_err( ) ) ;
917+ assert_eq ! ( boolean_function. unwrap_err( ) , BooleanFunctionError :: AnfFormNVariableTooBigFactor ( 3 , 3 ) ) ;
918+
919+ let anf_str = "x0*y1 + x0 + x1 + x2" ;
920+ let boolean_function = SmallBooleanFunction :: from_anf_polynomial_str_inner ( anf_str, 3 ) ;
921+ assert ! ( boolean_function. is_err( ) ) ;
922+ assert_eq ! ( boolean_function. unwrap_err( ) , BooleanFunctionError :: ErrorParsingAnfString ) ;
923+ }
924+
925+ #[ test]
926+ fn test_from_anf_polynomial_inner ( ) {
927+ let rule_30_anf = AnfPolynomial :: from_str ( "x0*x1 + x0 + x1 + x2" , 3 ) . unwrap ( ) ;
928+ let rule_30_function = SmallBooleanFunction :: from_anf_polynomial_inner ( & rule_30_anf) . unwrap ( ) ;
929+ assert_eq ! ( rule_30_function. get_truth_table_u64( ) , 30 ) ;
930+
931+ let rule_30_anf = AnfPolynomial :: from_str ( "x0*x1 + x0 + x1 + x2" , 7 ) . unwrap ( ) ;
932+ let boolean_function = SmallBooleanFunction :: from_anf_polynomial_inner ( & rule_30_anf) ;
933+ assert ! ( boolean_function. is_err( ) ) ;
934+ assert_eq ! ( boolean_function. unwrap_err( ) , BooleanFunctionError :: TooBigTruthTableForVarCount ) ;
935+ }
865936}
0 commit comments