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