Source code for babylon.engine.formula_registry

"""Formula registry for hot-swappable mathematical functions.

This module provides a FormulaRegistry class that stores named callables,
enabling runtime replacement of formulas for testing and modding.

Sprint 3: Central Committee (Dependency Injection)
"""

from collections.abc import Callable
from typing import Any

from babylon import formulas

# Type alias for formula functions
FormulaFunc = Callable[..., Any]


[docs] class FormulaRegistry: """Registry for named mathematical formulas. Provides a central lookup for all simulation formulas, enabling: - Hot-swapping formulas for testing with mocks - Modding support for custom formula implementations - Centralized formula management Example: >>> registry = FormulaRegistry.default() >>> la = registry.get("labor_aristocracy_ratio") >>> result = la(core_wages=120.0, value_produced=100.0) """
[docs] def __init__(self) -> None: """Initialize an empty formula registry.""" self._formulas: dict[str, FormulaFunc] = {}
[docs] def register(self, name: str, func: FormulaFunc) -> None: """Register or replace a formula by name. Args: name: Unique identifier for the formula func: Callable implementing the formula """ self._formulas[name] = func
[docs] def get(self, name: str) -> FormulaFunc: """Retrieve a formula by name. Args: name: The formula identifier Returns: The registered formula callable Raises: KeyError: If no formula is registered with the given name """ if name not in self._formulas: raise KeyError(f"No formula registered with name: {name}") return self._formulas[name]
[docs] def list_formulas(self) -> list[str]: """List all registered formula names. Returns: List of formula names in arbitrary order """ return list(self._formulas.keys())
[docs] @classmethod def default(cls) -> "FormulaRegistry": """Create a registry pre-populated with all standard formulas. Registers formulas from babylon.formulas: - labor_aristocracy_ratio - is_labor_aristocracy - consciousness_drift - acquiescence_probability - revolution_probability - crossover_threshold - loss_aversion - exchange_ratio - exploitation_rate - value_transfer - prebisch_singer Returns: FormulaRegistry with all standard formulas registered """ registry = cls() # Fundamental Theorem formulas registry.register("labor_aristocracy_ratio", formulas.calculate_labor_aristocracy_ratio) registry.register("is_labor_aristocracy", formulas.is_labor_aristocracy) registry.register("consciousness_drift", formulas.calculate_consciousness_drift) # Survival Calculus formulas registry.register("acquiescence_probability", formulas.calculate_acquiescence_probability) registry.register("revolution_probability", formulas.calculate_revolution_probability) registry.register("crossover_threshold", formulas.calculate_crossover_threshold) registry.register("loss_aversion", formulas.apply_loss_aversion) # Unequal Exchange formulas registry.register("exchange_ratio", formulas.calculate_exchange_ratio) registry.register("exploitation_rate", formulas.calculate_exploitation_rate) registry.register("value_transfer", formulas.calculate_value_transfer) registry.register("prebisch_singer", formulas.prebisch_singer_effect) # Solidarity Transmission formulas (Sprint 3.4.2) registry.register("solidarity_transmission", formulas.calculate_solidarity_transmission) # Dynamic Balance formulas (Sprint 3.4.4) registry.register("bourgeoisie_decision", formulas.calculate_bourgeoisie_decision) # Community Layer formulas (Feature 022) registry.register("solidarity_potential", formulas.calculate_solidarity_potential) registry.register("threat_score", formulas.calculate_threat_score) registry.register("infrastructure_decay", formulas.calculate_infrastructure_decay) registry.register("solidarity_amplification", formulas.calculate_solidarity_amplification) # D-P-D' Lifecycle Circuit formulas (Feature 030) registry.register("population_flow", formulas.compute_population_flow) registry.register("dependency_ratio", formulas.compute_dependency_ratio) registry.register("legitimation_index", formulas.compute_legitimation_index) registry.register("pareto_gini", formulas.compute_pareto_gini) registry.register("ideology_transmission", formulas.compute_ideology_transmission) registry.register("shadow_subsidy", formulas.compute_shadow_subsidy) return registry