aeat.domain.calculations.registry._formula_runtime module

Registry-backed formula runtime using typed operation graphs.

Evaluates FormulaExpression trees declared on a ModeloRevision against casilla inputs and binding values drawn from a RegistrySnapshot. The calculation entry point calculate_registry_snapshot() is the primary surface used by ValidatedRegistryAuthority-backed callers to produce CasillaObservation rows with full provenance.

See also

domain.calculations.registry._runtime_graph

Produces formula evaluation order and dependency projections.

domain.calculations.registry._formula_runtime_ops

Arithmetic, rounding, and parameter lookup helpers called by this evaluator.

domain.calculations.registry._formula_initial_values

Builds the initial casilla value map and materialised observation envelope for this runtime.

class RegistryCalculationEntry(**data)[source]

Bases: BaseModel

One trace row emitted by the registry formula runtime.

Carries the per-formula provenance for a single formula-computed CasillaId. Entries cover only casillas computed by a registry formula; input and bound casillas remain in CasillaObservation storage and must be read through RegistryCalculationResult.observations.

Parameters:
  • formula_id (FormulaId)

  • target_casilla_id (CasillaId)

  • op (str)

  • operand_refs (tuple[str, ...])

  • operand_casilla_refs (tuple[CasillaId, ...])

  • operand_values (tuple[Decimal, ...])

  • value (Decimal)

  • legal_refs (tuple[LegalRefId, ...])

  • source_refs (tuple[SourceRefId, ...])

formula_id: FormulaId
target_casilla_id: CasillaId
op: str
operand_refs: tuple[str, ...]
operand_casilla_refs: tuple[CasillaId, ...]
operand_values: tuple[Decimal, ...]
value: Decimal
legal_refs: tuple[LegalRefId, ...]
source_refs: tuple[SourceRefId, ...]
class RegistryCalculationUnresolvedOutcome(**data)[source]

Bases: BaseModel

One formula target that could not produce a Decimal value.

The outcome rides beside RegistryCalculationResult.observations so the engine’s value channels remain Decimal-only. Legal/source refs and formula lineage mirror CasillaObservation for the same target.

Parameters:
casilla_id: CasillaId
reason: RegistryUnresolvedOutcomeReason
formula_id: FormulaId
op: str
operand_refs: tuple[str, ...]
operand_casilla_refs: tuple[CasillaId, ...]
operand_values: tuple[Decimal, ...]
legal_refs: tuple[LegalRefId, ...]
source_refs: tuple[SourceRefId, ...]
context: Mapping[str, str]
class RegistryCalculationResult(**data)[source]

Bases: BaseModel

Calculated outputs for one registry snapshot.

Canonical storage is observations: a typed tuple of CasillaObservation covering every casilla on the RegistrySnapshot revision (inputs, bound, and formula-computed). Each observation carries its final Decimal value plus the legal / source provenance for that casilla pulled from the registry. Formula-computed observations additionally carry formula_id, op, operand_refs, and operand_values so the full evaluation lineage survives the engine boundary.

The values and entries views are derived convenience properties for readers that need the flat {casilla_id: Decimal} map or the formula-only RegistryCalculationEntry tuple. The typed envelope is the contract; the flat views never grow new fields.

Coverage asymmetry preserved by the derivation:

  • values covers every observation (inputs, bound, computed), keyed by casilla_id to value.

  • entries covers ONLY observations where formula_id is set. len(entries) <= len(observations) always; equality holds only when every casilla is formula-computed (rare in practice).

Consumers that need provenance for non-computed casillas must iterate observations directly; the entries view drops them by design.

Parameters:
modelo: str
revision: str
observations: tuple[CasillaObservation, ...]
unresolved_outcomes: tuple[RegistryCalculationUnresolvedOutcome, ...]
property values: Mapping[CasillaId, Decimal]

Read-only view from registry casilla id to final Decimal value.

Deliberately a plain @property, not a pydantic computed_field: the typed observations envelope is canonical storage; exposing this in JSON would round-trip self-incompatibly under extra='forbid' because the loader would refuse the duplicate field on the way back in.

property entries: tuple[RegistryCalculationEntry, ...]

Read-only view of formula-computed RegistryCalculationEntry rows.

Preserves the formula-only entry view with target_casilla_id and op fields for the application-layer indexers that build {target_casilla_id: entry} dictionaries. Insertion order from observations is preserved; the engine emits in formula evaluation order, which matches the original entries shape.

calculate_registry_snapshot(snapshot, *, inputs, date_context, binding_values=None, enum_binding_values=None, relation_values=None, unresolved_relation_ids=(), unresolved_binding_ids=(), date_binding_values=None, text_inputs=None)[source]

Evaluate all computed formulas for a registry snapshot.

enum_binding_values carries string-valued bindings (typically profile-sourced enums like CCAA) that the lookup_bracket_by_ccaa op routes against. They are kept in a separate mapping from binding_values so the Decimal-only contract on numeric bindings stays intact.

date_binding_values carries date-valued profile facts (e.g. birth_date) consumed by the age_at_year_end op. Date facts cannot flow through the Decimal binding_values channel; keeping them in a dedicated channel preserves the Decimal-only invariant.

The returned RegistryCalculationResult stores CasillaObservation rows for all materialised casillas. Input validation is delegated to domain.calculations.registry._formula_runtime_ops and domain.calculations.registry._formula_text_inputs; initial casilla values and absent-by-design markers are delegated to domain.calculations.registry._formula_initial_values.

Parameters:
  • snapshot (RegistrySnapshot) – The RegistrySnapshot that supplies the revision, casilla definitions, and formula graph to evaluate.

  • inputs (Mapping[TypeVar(InputKey), TypeVar(InputValue)]) – Operator-supplied input casilla values; rejected if any value is not a decimal.Decimal.

  • date_context (Mapping[str, date]) – Date-axis context (e.g. filing_period) consumed by date-aware ops; filing_period defaults to the snapshot’s year-end when absent.

  • binding_values (Mapping[TypeAliasType, Decimal] | None) – Optional resolved numeric binding values keyed by DataBindingDefinition id; Decimal-only.

  • enum_binding_values (Mapping[TypeAliasType, str] | None) – Optional string-valued bindings (e.g. profile CCAA) keyed by binding id; consumed by enum-routed ops.

  • relation_values (Mapping[TypeAliasType, Decimal] | None) – Optional resolved relation values keyed by relation.id; Decimal-only.

  • unresolved_relation_ids (tuple[TypeAliasType, ...]) – Relation ids that source resolution proved missing/incomplete but non-blocking. Formula targets depending on these ids are omitted instead of zero-contributed; relation ids not listed here remain hard validation errors when absent.

  • unresolved_binding_ids (tuple[TypeAliasType, ...]) – Binding ids whose enrolled resolver ran for a present source but produced no value (expected-but-missing). Formula targets depending on these ids are omitted instead of raising binding_value_missing; binding ids not listed here remain hard validation errors when absent from binding_values.

  • date_binding_values (Mapping[TypeAliasType, date] | None) – Optional date-valued profile bindings (e.g. birth_date) consumed by date-aware ops.

  • text_inputs (Mapping[TypeVar(TextInputKey), TypeVar(TextInputValue)] | None) – Optional string-valued operator inputs keyed by casilla id; consumed by text-routed ops.

Return type:

RegistryCalculationResult