Boolean Function

This module defines the BooleanFunction class, which forms the foundation of the BoolForge package.

A BooleanFunction represents a Boolean mapping \(f : \{0,1\}^n \rightarrow \{0,1\}\) and provides methods for evaluating, analyzing, and transforming Boolean functions. Supported operations include algebraic manipulation, sensitivity and canalization analysis, truth table generation, and function composition.

Several computationally intensive methods support optional Numba-based just-in-time (JIT) acceleration to improve performance for large or repeated computations. All functionality remains available without Numba, although performance may be reduced.

This module is part of the core BoolForge library and is intended for both direct programmatic use and integration with higher-level Boolean network classes.

Example

Basic usage:

>>> from boolforge import BooleanFunction
>>> f = BooleanFunction("x1 | (x2 & x3)")
>>> f([1, 0, 1])
1
class boolforge.boolean_function.BooleanFunction(f: list[int] | ndarray | str, variables: list[str] | ndarray | None = None, name: str = '')[source]

Bases: object

A Boolean function.

This class represents a Boolean function \(f : \{0,1\}^n \to \{0,1\}\) and stores its truth table together with variable names and optional metadata.

Parameters

flist[int] | np.ndarray | str

Truth table of length 2**n representing the outputs of a Boolean function with n inputs, or a Boolean expression string that can be evaluated. Expression strings are parsed using utils.f_from_expression.

namestr, optional

Name of the node regulated by the Boolean function. Default is "".

variableslist[str] | np.ndarray | None, optional

Names of the input variables, given in order. Must have length n. If None (default), variables are named x0, ..., x_{n-1}.

Attributes

fnp.ndarray

NumPy array of dtype uint8 and length 2**n containing only the values 0 and 1, representing the truth table of the Boolean function.

nint

Number of input variables.

variablesnp.ndarray

One-dimensional NumPy array of length n containing variable names.

namestr

Name of the node regulated by the Boolean function.

propertiesdict

Dictionary for dynamically computed properties of the Boolean function (e.g., canalizing structure, effective inputs, robustness measures).

classmethod from_cana(cana_BooleanNode: BooleanNode) BooleanFunction[source]

Construct a BoolForge BooleanFunction from a CANA BooleanNode.

This compatibility method converts a cana.boolean_node.BooleanNode instance into a BoolForge BooleanFunction by extracting its truth table representation.

Parameters

cana_BooleanNodecana.boolean_node.BooleanNode

Boolean node object from the CANA library.

Returns

BooleanFunction

A BoolForge BooleanFunction instance with the same truth table as the input CANA BooleanNode.

Notes

This method is intended for interoperability with the CANA package.

__str__()[source]

Return a human-readable string representation of the Boolean function.

This method returns the underlying truth table as a NumPy array.

__repr__()[source]

Return an unambiguous string representation of the BooleanFunction.

For small functions (n < 6), the full truth table is shown. For larger functions, only the number of inputs is displayed to avoid excessive output.

__mul__(value)[source]

Element-wise Boolean multiplication (logical AND).

This method implements logical AND between Boolean functions or between a Boolean function and a scalar value in {0,1}.

Parameters

valueBooleanFunction or int

BooleanFunction of the same size or an integer value (0 or 1).

Returns

BooleanFunction

Result of element-wise Boolean multiplication.

__rmul__(value)[source]

Right-hand element-wise Boolean multiplication (logical AND).

This method enables expressions of the form value * BooleanFunction where value is an integer in {0,1}.

Parameters

valueint

Integer value (0 or 1).

Returns

BooleanFunction

Result of element-wise Boolean multiplication.

__and__(value)[source]

Element-wise logical AND.

This method implements element-wise logical AND between Boolean functions or between a Boolean function and a scalar value in {0,1}.

Parameters

valueBooleanFunction or int

BooleanFunction of the same size or an integer value (0 or 1).

Returns

BooleanFunction

Result of element-wise logical AND.

__or__(value)[source]

Element-wise logical OR.

This method implements element-wise logical OR between Boolean functions or between a Boolean function and a scalar value in {0,1}.

Parameters

valueBooleanFunction or int

BooleanFunction of the same size or an integer value (0 or 1).

Returns

BooleanFunction

Result of element-wise logical OR.

__xor__(value)[source]

Element-wise logical XOR.

This method implements element-wise logical XOR between Boolean functions or between a Boolean function and a scalar value in {0,1}.

Parameters

valueBooleanFunction or int

BooleanFunction of the same size or an integer value (0 or 1).

Returns

BooleanFunction

Result of element-wise logical XOR.

__invert__()[source]

Element-wise logical negation.

This method computes the logical NOT of the Boolean function by flipping all truth table entries.

Returns

BooleanFunction

Result of element-wise logical negation.

__call__(values: list[int] | tuple[int, ...] | ndarray)[source]

Evaluate the Boolean function on a given input vector.

This method makes BooleanFunction instances callable and returns the output value for a specified binary input configuration.

Parameters

valueslist[int] | tuple[int, …] | np.ndarray

Sequence of binary values (0 or 1) of length n, where n is the number of input variables of the Boolean function.

Returns

int

Output value of the Boolean function (0 or 1) for the specified input.

Raises

ValueError

If the input length does not match n or if non-binary values are provided.

Examples

>>> f = BooleanFunction("x1 | (x2 & x3)")
>>> f([1, 0, 1])
1
>>> f([0, 1, 0])
0
to_polynomial() str[source]

Convert the Boolean function to a polynomial representation.

This method returns a polynomial representation of the Boolean function in non-reduced disjunctive normal form (DNF).

Returns

str

Polynomial representation of the Boolean function in non-reduced DNF.

to_truth_table(RETURN: bool = True, filename: str | None = None) DataFrame | None[source]

Return or save the full truth table of the Boolean function.

The truth table is represented as a pandas DataFrame in which each row corresponds to an input configuration and the final column contains the output value of the Boolean function.

Parameters

RETURNbool, optional

Whether to return the truth table as a DataFrame. If False, the truth table is only written to file when filename is provided. Default is True.

filenamestr or None, optional

File name (including extension) to which the truth table is saved. Supported formats are 'csv', 'xls', and 'xlsx'. If provided, the truth table is automatically written to disk.

Returns

pandas.DataFrame or None

The full truth table if RETURN=True; otherwise None.

Notes

The column names correspond to the input variable names followed by the function name if provided, or 'f' otherwise. When saving to a file, the output format is determined by the file extension.

Examples

>>> f = BooleanFunction("(x1 & ~x2) | x3")
>>> f.to_truth_table()
   x1  x2  x3  f
0   0   0   0  0
1   0   0   1  1
2   0   1   0  0
3   0   1   1  1
4   1   0   0  1
5   1   0   1  1
6   1   1   0  0
7   1   1   1  1
to_cana() BooleanNode[source]

Convert the BooleanFunction to a CANA BooleanNode.

This compatibility method constructs and returns a cana.boolean_node.BooleanNode instance corresponding to the Boolean function represented by this object.

Returns

cana.boolean_node.BooleanNode

Boolean node object from the CANA library representing the same Boolean function.

Raises

ImportError

If the CANA package is not installed.

Notes

This method requires the CANA package to be installed.

to_logical(AND: str = '&', OR: str = '|', NOT: str = '!', MINIMIZE_EXPRESSION: bool = True) str[source]

Convert the Boolean function to a logical expression.

This method converts the Boolean function from its truth table representation to a logical expression. If the PyEDA package is available, the expression can optionally be minimized using the Espresso algorithm. Otherwise, a non-minimized expression is generated as a fallback.

Parameters

ANDstr, optional

String used to represent the logical AND operator. Default is "&".

ORstr, optional

String used to represent the logical OR operator. Default is "|".

NOTstr, optional

String used to represent the logical NOT operator. Default is "!".

MINIMIZE_EXPRESSIONbool, optional

Whether to minimize the logical expression using the Espresso algorithm (via PyEDA). If False, the expression is returned in non-minimized disjunctive normal form. Default is True.

Returns

str

Logical expression representing the Boolean function.

Notes

If the PyEDA package is not installed, the method falls back to a non-minimized expression derived from the polynomial representation.

summary(*, AS_DICT: bool = False, COMPUTE_ALL: bool = False)[source]

Return a concise summary of the Boolean function.

The summary includes basic structural and statistical properties of the Boolean function and, optionally, additional properties that may require nontrivial computation.

Parameters

AS_DICTbool, optional

If True, return the summary as a dictionary. If False (default), return a formatted string.

COMPUTE_ALLbool, optional

If True, additional properties are computed and included in the summary. These computations may be expensive. If False (default), only already available properties are included.

Returns

str or dict

Summary of the Boolean function, either as a formatted string or as a dictionary depending on the value of AS_DICT.

is_constant() bool[source]

Check whether the Boolean function is constant.

A Boolean function is constant if all entries of its truth table are identical (all 0 or all 1).

Returns

bool

True if the Boolean function is constant, False otherwise.

is_degenerate(USE_NUMBA: bool = True) bool[source]

Determine whether the Boolean function is degenerate.

A Boolean function is degenerate if it contains at least one non-essential variable, i.e., a variable on which the function’s output does not depend.

Parameters

USE_NUMBAbool, optional

Whether to use Numba-accelerated computation when available. Default is True.

Returns

bool

True if the Boolean function contains at least one non-essential variable, False if all variables are essential.

is_monotonic() bool[source]

Determine whether the Boolean function is monotonic.

A Boolean function is monotonic if it is monotonic in each variable, i.e., for every variable the function is either non-decreasing or non-increasing with respect to that variable.

Returns

bool

True if the Boolean function is monotonic, False otherwise.

is_canalizing() bool[source]

Determine whether the Boolean function is canalizing.

A Boolean function is canalizing if there exists at least one variable and a value in {0,1} such that fixing that variable to the given value forces the output of the function to be constant.

Returns

bool

True if the Boolean function is canalizing, False otherwise.

is_k_canalizing(k: int) bool[source]

Determine whether the Boolean function is k-canalizing.

A Boolean function is k-canalizing if it has a sequence of at least k canalizing variables. After fixing a canalizing variable to its canalizing value, the resulting subfunction must itself be (k−1)-canalizing, recursively.

Parameters

kint

Desired canalizing depth, with 0 <= k <= n. Every Boolean function is trivially 0-canalizing.

Returns

bool

True if the Boolean function is k-canalizing, False otherwise.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

He, Q., & Macauley, M. (2016).

Stratification and enumeration of Boolean functions by canalizing depth. Physica D: Nonlinear Phenomena, 314, 1–8.

Dimitrova, E., Stigler, B., Kadelka, C., & Murrugarra, D. (2022).

Revealing the canalizing structure of Boolean functions: Algorithms and applications. Automatica, 146, 110630.

is_kset_canalizing(k: int) bool[source]

Determine whether the Boolean function is k-set canalizing.

A Boolean function is k-set canalizing if there exists a set of k variables such that fixing these variables to specific values forces the output of the function, regardless of the remaining n - k variables.

Parameters

kint

Size of the variable set, with 0 <= k <= n.

Returns

bool

True if the Boolean function is k-set canalizing, False otherwise.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Kadelka, C., Keilty, B., & Laubenbacher, R. (2023).

Collectively canalizing Boolean functions. Advances in Applied Mathematics, 145, 102475.

get_hamming_weight() int[source]

Compute the Hamming weight of the Boolean function.

The Hamming weight is the number of input states for which the function evaluates to 1 (i.e., the number of ones in the truth table).

Returns

int

The Hamming weight of the Boolean function.

get_essential_variables() list[source]

Determine the essential variables of the Boolean function.

A variable x_i is essential if there exists at least one assignment of the remaining variables such that flipping x_i changes the output of the function.

Returns

list[int]

Indices of all essential variables. If the truth table is empty, returns an empty list.

get_number_of_essential_variables() int[source]

Count the number of essential variables of the Boolean function.

Returns

int

The number of essential variables.

get_type_of_inputs() ndarray[source]

Classify each input variable of the Boolean function.

Each variable is classified as one of:

  • 'positive': flipping the variable from 0 to 1 never decreases the output

  • 'negative': flipping the variable from 0 to 1 never increases the output

  • 'conditional': flipping the variable can both increase and decrease the output

  • 'non-essential': flipping the variable never changes the output

The result is cached in self.properties['InputTypes'].

Returns

np.ndarray

Array of shape (n,) with dtype str giving the type of each input variable.

get_symmetry_groups() list[list[int]][source]

Identify symmetry groups of input variables.

Two variables belong to the same symmetry group if swapping their values leaves the Boolean function invariant for all assignments of the remaining variables.

Returns

list[list[int]]

A list of symmetry groups, where each group is given by a list of variable indices.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

get_absolute_bias() float[source]

Compute the absolute bias of the Boolean function.

The absolute bias is defined as

| (H / 2**(n-1)) - 1 |,

where H is the Hamming weight of the function. It measures how far the output distribution deviates from being perfectly balanced.

Returns

float

The absolute bias of the Boolean function.

get_activities(nsim: int = 10000, EXACT: bool = False, *, rng=None) ndarray[source]

Compute the activities of all input variables.

The activity of a variable is the probability that flipping this variable (while keeping all others fixed) changes the output of the Boolean function.

Activities can be computed exactly by enumerating all 2**n input states or estimated via Monte Carlo sampling.

Parameters

nsimint, optional

Number of random samples used when EXACT=False (default: 10000).

EXACTbool, optional

If True, compute activities exactly by enumerating all input states. If False, estimate activities via sampling (default: False).

rngNone or numpy.random.Generator, optional

Random number generator passed to utils._coerce_rng.

Returns

np.ndarray

Array of shape (n,) containing the activities of all variables.

get_average_sensitivity(nsim: int = 10000, EXACT: bool = False, NORMALIZED: bool = True, *, rng=None) float[source]

Compute the average sensitivity of the Boolean function.

The (unnormalized) average sensitivity equals the sum of the activities of all variables. If NORMALIZED=True, the result is divided by n.

The sensitivity can be computed exactly by enumerating all input states or estimated via Monte Carlo sampling.

Parameters

nsimint, optional

Number of random samples used when EXACT=False (default: 10000).

EXACTbool, optional

If True, compute the exact activities by enumerating all input states. If False, estimate them via sampling (default: False).

NORMALIZEDbool, optional

If True, return the average sensitivity divided by n (default: True). If False, return the sum of activities.

rngNone or numpy.random.Generator, optional

Random number generator passed to utils._coerce_rng.

Returns

float

The (optionally normalized) average sensitivity of the Boolean function.

get_layer_structure() dict[source]

Determine the canalizing layer structure of a Boolean function.

This method decomposes a Boolean function into its canalizing layers (standard monomial form) by recursively identifying and removing canalizing variables. All variables that canalize the function at the same recursion step form one canalizing layer and are removed simultaneously.

The decomposition yields the canalizing depth, the number of canalizing layers, the canalizing inputs and outputs, the order of canalizing variables, and the remaining non-canalizing core function.

Returns

dict

Dictionary containing the canalizing layer structure with the following entries:

  • CanalizingDepth : int Total number of canalizing variables.

  • NumberOfLayers : int Number of distinct canalizing layers.

  • CanalizingInputs : np.ndarray Canalizing input value for each canalizing variable.

  • CanalizedOutputs : np.ndarray Output value forced by each canalizing variable.

  • CoreFunction : BooleanFunction Core Boolean function obtained after removing all canalizing variables.

  • OrderOfCanalizingVariables : np.ndarray Order in which canalizing variables are identified.

  • LayerStructure : np.ndarray Number of canalizing variables in each layer.

Notes

The result is cached in self.properties and recomputed only if the canalizing structure has not been computed previously.

Notes

This method has exponential time complexity in n and is intended for smaller Boolean functions.

References

He, Q., & Macauley, M. (2016).

Stratification and enumeration of Boolean functions by canalizing depth. Physica D: Nonlinear Phenomena, 314, 1–8.

Dimitrova, E., Stigler, B., Kadelka, C., & Murrugarra, D. (2022).

Revealing the canalizing structure of Boolean functions: Algorithms and applications. Automatica, 146, 110630.

get_canalizing_depth() int[source]

Return the canalizing depth of the Boolean function.

The canalizing depth is the total number of canalizing variables identified in the canalizing layer decomposition.

Returns

int

Canalizing depth of the Boolean function.

get_kset_canalizing_proportion(k: int) float[source]

Compute the proportion of k-set canalizing input sets.

For a given k, this method computes the probability that a randomly chosen set of k variables canalizes the function, i.e., fixing those variables to some values forces the output regardless of the remaining variables.

Parameters

kint

Size of the variable set, with 0 <= k <= n.

Returns

float

Proportion of k-set canalizing input sets.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Kadelka, C., Keilty, B., & Laubenbacher, R. (2023).

Collectively canalizing Boolean functions. Advances in Applied Mathematics, 145, 102475.

get_kset_canalizing_proportion_of_variables(k: int) float[source]

Compute the proportion of k-set canalizing input sets per variable.

For a given k, this method computes, for each variable, the proportion of k-variable input sets containing that variable which canalize the Boolean function.

Parameters

kint

Size of the variable set, with 0 <= k <= n.

Returns

np.ndarray

Array of length n giving the proportion of k-set canalizing input sets containing each variable.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Kadelka, C., Keilty, B., & Laubenbacher, R. (2023).

Collectively canalizing Boolean functions. Advances in Applied Mathematics, 145, 102475.

get_canalizing_strength() tuple[source]

Compute the canalizing strength of the Boolean function.

The canalizing strength is defined as a weighted average of the proportions of k-set canalizing inputs for k = 1, ..., n-1. It equals 0 for minimally canalizing functions (e.g., parity functions) and 1 for maximally canalizing functions (e.g., nested canalizing functions with a single layer).

Returns

float

Canalizing strength of the Boolean function.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Kadelka, C., Keilty, B., & Laubenbacher, R. (2023).

Collectively canalizing Boolean functions. Advances in Applied Mathematics, 145, 102475.

get_canalizing_strength_of_variables() ndarray[source]

Compute the canalizing strength of each variable.

The canalizing strength of a variable is defined as a weighted average of the proportions of k-set canalizing inputs containing that variable for k = 1, ..., n-1.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

Returns

np.ndarray

Array of length n containing the canalizing strength of each variable.

get_input_redundancy() float[source]

Compute the input redundancy of the Boolean function.

Input redundancy quantifies the fraction of inputs that are not required to determine the output. Constant functions have redundancy 1, whereas parity functions have redundancy 0.

Returns

float

Normalized input redundancy in the interval [0, 1].

Raises

ImportError

If the CANA package is not installed.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Marques-Pita, M., & Rocha, L. M. (2013).

Canalization and control in automata networks: body segmentation in Drosophila melanogaster. PLoS One, 8(3), e55946.

Correia, R. B., Gates, A. J., Wang, X., & Rocha, L. M. (2018).

CANA: a python package for quantifying control and canalization in Boolean networks. Frontiers in Physiology, 9, 1046.

get_edge_effectiveness() list[float][source]

Compute the edge effectiveness of each input variable.

Edge effectiveness measures how strongly flipping an input variable influences the output. Non-essential inputs have effectiveness 0, whereas inputs that always flip the output have effectiveness 1.

Returns

list[float]

List of length n containing edge effectiveness values in [0, 1].

Raises

ImportError

If the CANA package is not installed.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Marques-Pita, M., & Rocha, L. M. (2013).

Canalization and control in automata networks: body segmentation in Drosophila melanogaster. PLoS One, 8(3), e55946.

Correia, R. B., Gates, A. J., Wang, X., & Rocha, L. M. (2018).

CANA: a python package for quantifying control and canalization in Boolean networks. Frontiers in Physiology, 9, 1046.

get_effective_degree() float[source]

Compute the effective degree of the Boolean function.

The effective degree is defined as the sum of the edge effectiveness values of all input variables.

Returns

float

Effective degree of the Boolean function.

Raises

ImportError

If the CANA package is not installed.

Notes

This method has exponential time complexity in n and is intended for small Boolean functions.

References

Marques-Pita, M., & Rocha, L. M. (2013).

Canalization and control in automata networks: body segmentation in Drosophila melanogaster. PLoS One, 8(3), e55946.

Correia, R. B., Gates, A. J., Wang, X., & Rocha, L. M. (2018).

CANA: a python package for quantifying control and canalization in Boolean networks. Frontiers in Physiology, 9, 1046.

boolforge.boolean_function.display_truth_table(*functions: BooleanFunction, labels: Sequence[str] | None = None) None[source]

Display the full truth table of one or more Boolean functions.

Each row displays an input configuration (x1, ..., xn) together with the corresponding output values of the provided Boolean functions.

Parameters

*functionsBooleanFunction

One or more BooleanFunction objects with the same number of input variables.

labelsSequence[str] or None, optional

Column labels for the Boolean functions. If None (default), labels are generated automatically as f0, f1, ....

Raises

ValueError

If no Boolean functions are provided, if the functions do not all have the same number of variables, or if the number of labels does not match the number of functions.

Examples

>>> f = BooleanFunction("(x1 & ~x2) | x3")
>>> display_truth_table(f)
boolforge.boolean_function.get_layer_structure_from_canalized_outputs(can_outputs: Sequence[int]) list[source]

Compute the canalizing layer structure from canalized outputs.

Consecutive identical canalized output values are grouped into the same canalizing layer. The size of each layer corresponds to the number of variables in that layer.

Parameters

can_outputsSequence[int]

Sequence of canalized output values in the order in which canalizing variables are identified.

Returns

list[int]

List specifying the number of variables in each canalizing layer.