Skip to content

Rollforward API

The rollforward runs state-machine projections across every policy in parallel. The public surface is four pieces: a builder for declaring the period-by-period steps, a compile step, a collector for extracting per-state and per-increment expressions, and the compiled model itself with its inspection helpers.

For concept-level material, see Rollforward. For runnable patterns, see gaspatchio_core/tutorials/rollforward-patterns/ in the source tree.

RollforwardBuilder

gaspatchio_core.RollforwardBuilder

Mutable builder that produces an immutable IR on ._build().

compile_rollforward

gaspatchio_core.compile_rollforward(target)

Run the 5-pass chain over a Builder or an IR.

Each pass logs a one-line TRACE record for observability:

[validate]              ok — N transitions
[resolve_state_refs]    ok
[fold_constants]        ok
[assign_capture_slots]  ok — N slots
[lower_polars]          ok — N kwargs

CompiledRollforward

gaspatchio_core.CompiledRollforward dataclass

Frozen artefact carrying the compiled IR and inspection surface.

Returned by :func:compile_rollforward. Carries everything the kernel needs to execute (plugin_kwargs, plugin_args, capture_slots), the expression surface (expr_for, increment_for), and three inspection helpers for governance and audit.

canonical_form()

Return a stable, deterministic dict describing the model structure.

Two compiled rollforwards with the same Op chain (in the same order), same states, same Schedule canonical-form, and same configuration produce equal canonical-form dicts. Column-name aliases inside Op expressions are reduced to str(expr), so renaming a column does not change the canonical form.

explain()

Return a multi-line human-readable summary of the model.

Lists states, points, schedule, transitions in order, and the cross-cutting configuration (lapse, contract boundary, increment tracking). Plain text — fits in audit reports and TRACE logs.

expr_for(state, *, point='eop')

Return a Polars Expr selecting the per-period values for (state, point).

All extractions from one compiled rollforward share a single kernel call when assigned to an ActuarialFrame::

af.fund = compiled.expr_for("fund")
af.gmdb = compiled.expr_for("gmdb")  # no second kernel run

fingerprint()

Return a SHA-256 fingerprint of the canonical form.

Stable across runs and across machines for an unchanged model. Suitable for governance metadata and run logs.

increment_for(label)

Return a Polars Expr selecting the per-period delta for a labelled Op.

Not yet functional: the kernel does not emit increment fields, and the builder refuses track_increments=True until it does (gh#69).

plugin_expr()

Return the raw kernel call as a self-contained Polars expression.

The escape hatch for use outside ActuarialFrame: alias the struct onto a plain LazyFrame yourself, then extract fields from that column::

df = df.with_columns(compiled.plugin_expr().alias("rf"))
df = df.with_columns(av=pl.col("rf").struct.field("av@eop"))

Inside ActuarialFrame prefer :meth:expr_for, which shares one kernel call across every extraction automatically.

RollforwardCollector

gaspatchio_core.RollforwardCollector

Deprecated: use :meth:CompiledRollforward.expr_for instead.

Emits self-contained per-state / per-increment plugin exprs (one kernel call EACH — no sharing). Retained for backwards compatibility and for raw Polars frames, where a self-contained expr is the only thing that works.

expr_for(state, *, point='eop')

Return a self-contained Expr for (state, point) — one kernel call each.

increment_for(label)

Return a self-contained Expr for a labelled Op's per-period delta.

Not yet functional: the kernel does not emit increment fields, and the builder refuses track_increments=True until it does (gh#69).