"""
BooFun: A comprehensive Boolean function analysis library.
This library provides tools for creating, analyzing, and visualizing Boolean functions
using multiple representations and advanced mathematical techniques.
Key Features:
- Multiple Boolean function representations (truth tables, circuits, BDDs, etc.)
- Spectral analysis and Fourier transforms
- Property testing algorithms
- Visualization tools
- Built-in Boolean function generators
Basic Usage:
>>> import boofun as bf
>>>
>>> # Create functions from any input
>>> xor = bf.create([0, 1, 1, 0]) # From truth table
>>> maj = bf.majority(5) # Built-in majority
>>> parity = bf.parity(4) # Built-in parity (XOR)
>>>
>>> # Natural operations
>>> g = xor & maj # AND
>>> h = ~xor # NOT
>>>
>>> # Spectral analysis
>>> xor.fourier() # Fourier coefficients
>>> xor.influences() # Variable influences
>>> xor.degree() # Fourier degree
"""
from typing import Optional
from .api import create
from .core import BooleanFunction, ExactErrorModel, NoiseErrorModel, PACErrorModel, Property, Space
from .core.adapters import (
CallableAdapter,
NumPyAdapter,
SymPyAdapter,
adapt_callable,
adapt_numpy_function,
adapt_sympy_expr,
)
from .core.builtins import BooleanFunctionBuiltins
from .core.io import load, save
# Exception hierarchy for structured error handling
from .utils.exceptions import (
BooleanFunctionError,
ConfigurationError,
ConversionError,
ErrorCode,
EvaluationError,
InvalidInputError,
InvalidRepresentationError,
InvalidTruthTableError,
InvariantViolationError,
ResourceUnavailableError,
ValidationError,
)
# Legacy adapter for migrating from old BooleanFunc class (kept for backwards compatibility)
# Import on demand: from boofun.core.legacy_adapter import from_legacy, to_legacy
try:
from .core.legacy_adapter import LegacyWrapper, from_legacy, to_legacy # noqa: F401
_HAS_LEGACY = True
except ImportError:
_HAS_LEGACY = False
from .analysis import PropertyTester, SpectralAnalyzer
from .analysis import block_sensitivity as analysis_block_sensitivity
from .analysis import certificates as analysis_certificates
from .analysis import sensitivity as analysis_sensitivity
from .analysis import symmetry as analysis_symmetry
# Fourier analysis utilities (Chapter 1 O'Donnell)
from .analysis.fourier import (
convolution,
dominant_coefficients,
even_part,
fourier_degree,
fourier_sparsity,
negate_inputs,
odd_part,
parseval_verify,
plancherel_inner_product,
restriction,
spectral_norm,
tensor_product,
)
# GF(2) analysis (Algebraic Normal Form)
from .analysis.gf2 import (
correlation_with_parity,
gf2_degree,
gf2_fourier_transform,
gf2_monomials,
gf2_to_string,
is_linear_over_gf2,
)
from .testing import BooleanFunctionValidator, quick_validate, validate_representation
from .utils.finite_fields import GFField
from .utils.finite_fields import get_field as get_gf_field
# =============================================================================
# Top-level shortcuts for common functions (mathematician-friendly API)
# =============================================================================
[docs]
def majority(n: int) -> BooleanFunction:
"""
Create majority function on n variables: Maj_n(x) = 1 iff |{i: x_i=1}| > n/2.
Example:
>>> maj5 = bf.majority(5)
>>> maj5([1, 1, 1, 0, 0]) # True (3 > 2.5)
"""
return BooleanFunctionBuiltins.majority(n)
[docs]
def parity(n: int) -> BooleanFunction:
"""
Create parity (XOR) function on n variables: ⊕_n(x) = x_1 ⊕ x_2 ⊕ ... ⊕ x_n.
Example:
>>> xor3 = bf.parity(3)
>>> xor3([1, 1, 0]) # False (even number of 1s)
"""
return BooleanFunctionBuiltins.parity(n)
[docs]
def tribes(k: int, n: int) -> BooleanFunction:
"""
Create tribes function: AND of ORs on groups of k variables.
Tribes_{k,n}(x) = ⋀_{j=1}^{n/k} ⋁_{i∈T_j} x_i
Example:
>>> t = bf.tribes(2, 4) # (x₁ ∨ x₂) ∧ (x₃ ∨ x₄)
"""
return BooleanFunctionBuiltins.tribes(k, n)
[docs]
def dictator(n: int, i: int = 0) -> BooleanFunction:
"""
Create dictator function on variable i: f(x) = x_i.
Args:
n: Number of variables
i: Index of dictating variable (default 0)
Examples:
>>> d = bf.dictator(5) # 5-var dictator on x₀
>>> d = bf.dictator(5, 2) # 5-var dictator on x₂
"""
return BooleanFunctionBuiltins.dictator(n, i)
[docs]
def constant(value: bool, n: int) -> BooleanFunction:
"""
Create constant function: f(x) = value for all x.
Example:
>>> zero = bf.constant(False, 3)
>>> one = bf.constant(True, 3)
"""
return BooleanFunctionBuiltins.constant(value, n)
[docs]
def AND(n: int) -> BooleanFunction:
"""
Create AND function on n variables: f(x) = x_1 ∧ x_2 ∧ ... ∧ x_n.
Example:
>>> and3 = bf.AND(3)
"""
truth_table = [0] * (2**n)
truth_table[-1] = 1 # Only all-1s input gives 1
return create(truth_table)
[docs]
def OR(n: int) -> BooleanFunction:
"""
Create OR function on n variables: f(x) = x_1 ∨ x_2 ∨ ... ∨ x_n.
Example:
>>> or3 = bf.OR(3)
"""
truth_table = [1] * (2**n)
truth_table[0] = 0 # Only all-0s input gives 0
return create(truth_table)
[docs]
def random(n: int, balanced: bool = False, seed: Optional[int] = None) -> BooleanFunction:
"""
Create a random Boolean function on n variables.
Args:
n: Number of variables
balanced: If True, output has equal 0s and 1s (default False)
seed: Random seed for reproducibility
Returns:
Random Boolean function
Example:
>>> f = bf.random(4) # Random 4-variable function
>>> g = bf.random(4, balanced=True) # Random balanced function
>>> h = bf.random(4, seed=42) # Reproducible random function
"""
import numpy as np
if seed is not None:
np.random.seed(seed)
size = 2**n
if balanced:
# Balanced: exactly half 0s and half 1s
truth_table = np.zeros(size, dtype=int)
ones_positions = np.random.choice(size, size // 2, replace=False)
truth_table[ones_positions] = 1
else:
truth_table = np.random.randint(0, 2, size)
return create(truth_table.tolist())
[docs]
def from_weights(weights, threshold_value=None) -> BooleanFunction:
"""
Create LTF (Linear Threshold Function) from weight vector.
Alias for weighted_majority() with more intuitive name for LTF creation.
f(x) = 1 iff w₁x₁ + w₂x₂ + ... + wₙxₙ ≥ θ
Args:
weights: List of integer/float weights for each variable
threshold_value: Threshold (default: sum(weights)/2)
Returns:
LTF (Linear Threshold Function)
Example:
>>> # Electoral college with 3 states: CA(55), TX(38), NY(29)
>>> electoral = bf.from_weights([55, 38, 29], threshold=61)
"""
return weighted_majority(weights, threshold_value)
[docs]
def threshold(n: int, k: int) -> BooleanFunction:
"""
Create k-threshold function on n variables.
f(x) = 1 if Σxᵢ ≥ k, else 0
Special cases:
- threshold(n, n) = AND
- threshold(n, 1) = OR
- threshold(n, (n+1)/2) = MAJORITY (for odd n)
Example:
>>> at_least_2 = bf.threshold(4, 2) # True if ≥2 inputs are 1
"""
from .analysis.ltf_analysis import create_threshold_function
return create_threshold_function(n, k)
[docs]
def weighted_majority(weights, threshold_value=None) -> BooleanFunction:
"""
Create a weighted majority (LTF) function.
f(x) = sign(w₁x₁ + ... + wₙxₙ - θ)
LTFs are also called "halfspaces" - they represent hyperplanes
cutting through the Boolean hypercube.
Example:
# Nassau County voting system
>>> nassau = bf.weighted_majority([31, 31, 28, 21, 2, 2])
# Standard majority (all equal weights)
>>> maj = bf.weighted_majority([1, 1, 1, 1, 1])
"""
from .analysis.ltf_analysis import create_weighted_majority
return create_weighted_majority(weights, threshold_value)
# Function families for growth analysis
try:
from .families import ( # noqa: F401
ANDFamily,
DictatorFamily,
FunctionFamily,
GrowthTracker,
InductiveFamily,
LTFFamily,
MajorityFamily,
ORFamily,
ParityFamily,
ThresholdFamily,
TribesFamily,
)
HAS_FAMILIES = True
except ImportError:
HAS_FAMILIES = False
# Optional imports with graceful fallback
try:
from .visualization import BooleanFunctionVisualizer # noqa: F401
HAS_VISUALIZATION = True
except ImportError:
HAS_VISUALIZATION = False
try:
from .quantum import QuantumBooleanFunction, create_quantum_boolean_function # noqa: F401
HAS_QUANTUM = True
except ImportError:
HAS_QUANTUM = False
# Version information
__version__ = "0.2.0"
__author__ = "Gabriel Taboada"
# Core exports for typical usage
__all__ = [
# =====================================================
# PRIMARY API (mathematician-friendly)
# =====================================================
# Creation
"create",
"BooleanFunction",
# File I/O
"load",
"save",
# Built-in functions (short names)
"majority",
"parity",
"tribes",
"dictator",
"constant",
"AND",
"OR",
"threshold",
"weighted_majority",
"random", # Random function generator
"from_weights", # Alias for weighted_majority
# Analysis (use directly or via function methods)
"SpectralAnalyzer",
"PropertyTester",
# =====================================================
# EXCEPTIONS (structured error handling)
# =====================================================
"ErrorCode", # Machine-readable error codes
"BooleanFunctionError", # Base exception
"ValidationError", # User input validation failures
"InvalidInputError", # Invalid function arguments
"InvalidRepresentationError", # Unsupported representation
"InvalidTruthTableError", # Malformed truth table
"EvaluationError", # Function evaluation failures
"ConversionError", # Representation conversion failures
"ConfigurationError", # Setup/configuration errors
"ResourceUnavailableError", # Optional deps unavailable
"InvariantViolationError", # Internal library bugs
# =====================================================
# SECONDARY API (advanced users)
# =====================================================
# Full builtins class
"BooleanFunctionBuiltins",
# Analysis submodules
"analysis_sensitivity",
"analysis_block_sensitivity",
"analysis_certificates",
"analysis_symmetry",
# Fourier analysis (Chapter 1 O'Donnell)
"parseval_verify",
"plancherel_inner_product",
"convolution",
"negate_inputs",
"odd_part",
"even_part",
"tensor_product",
"restriction",
"fourier_degree",
"spectral_norm",
"fourier_sparsity",
"dominant_coefficients",
# GF(2) analysis
"gf2_fourier_transform",
"gf2_degree",
"gf2_monomials",
"gf2_to_string",
"is_linear_over_gf2",
"correlation_with_parity",
# Testing and validation
"BooleanFunctionValidator",
"quick_validate",
"validate_representation",
# Adapters for external integration
"CallableAdapter",
"SymPyAdapter",
"NumPyAdapter",
"adapt_callable",
"adapt_sympy_expr",
"adapt_numpy_function",
# Core utilities
"Space",
"Property",
"ExactErrorModel",
"PACErrorModel",
"NoiseErrorModel",
"get_gf_field",
"GFField",
# Version info
"__version__",
]
# Add optional exports if available
if HAS_FAMILIES:
__all__.extend(
[
"MajorityFamily",
"ParityFamily",
"TribesFamily",
"ThresholdFamily",
"ANDFamily",
"ORFamily",
"DictatorFamily",
"LTFFamily",
"GrowthTracker",
"FunctionFamily",
"InductiveFamily",
]
)
if HAS_VISUALIZATION:
__all__.append("BooleanFunctionVisualizer")
if HAS_QUANTUM:
__all__.extend(["QuantumBooleanFunction", "create_quantum_boolean_function"])