@@ -3,9 +3,7 @@ use crate::anf_polynom::AnfPolynomial;
3
3
use crate :: boolean_function_error:: XOR_DIFFERENT_VAR_COUNT_PANIC_MSG ;
4
4
use crate :: iterator:: { BooleanFunctionIterator , CloseBalancedFunctionIterator , SmallCloseBalancedFunctionIterator } ;
5
5
use 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 } ;
9
7
use crate :: { BooleanFunction , BooleanFunctionError , BooleanFunctionImpl , BooleanFunctionType } ;
10
8
use fast_boolean_anf_transform:: fast_bool_anf_transform_unsigned;
11
9
use itertools:: { enumerate, Itertools } ;
@@ -327,6 +325,44 @@ impl SmallBooleanFunction {
327
325
328
326
Ok ( SmallCloseBalancedFunctionIterator :: create ( self , flippable_positions, bits_to_flip_count) )
329
327
}
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
+ }
330
366
}
331
367
332
368
impl BooleanFunctionImpl for SmallBooleanFunction {
@@ -461,7 +497,7 @@ impl Not for SmallBooleanFunction {
461
497
462
498
#[ cfg( test) ]
463
499
mod tests {
464
- use crate :: { BooleanFunctionImpl , SmallBooleanFunction } ;
500
+ use crate :: { AnfPolynomial , BooleanFunctionError , BooleanFunctionImpl , SmallBooleanFunction } ;
465
501
466
502
#[ test]
467
503
fn test_from_truth_table ( ) {
@@ -862,4 +898,39 @@ mod tests {
862
898
let mut close_balanced_iterator = bent_function. close_balanced_functions_iterator_inner ( ) . unwrap ( ) ;
863
899
assert ! ( close_balanced_iterator. all( |f| f. is_balanced( ) ) ) ;
864
900
}
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
+ }
865
936
}
0 commit comments