Related¶
- Perch semantics (timing / measurability): Spec 1.2 — Stage Structure and Timing
- Composition across stages (periods/nests, connectors/twisters): Spec 0.4 — Periods and models
- Branching stages:
docs/development/dolo-plus-impl/spec_0.1l-branching.md
1.3 Equations and operators¶
This section covers the equations: blocks in a Dolo+ stage: how to write transitions and movers, what they mean at a high level, and a few concrete YAML patterns.
Main goal: keep stage YAML close to the economic model (fields + timing + equations). Translation to T core builds the corresponding typed operators; methodization decides how to compute them.
1.3.1 Main ideas¶
In v0.1, equation blocks come in two families:
- Transitions (forward equations): define how perch-local state fields are produced as information arrives and decisions are applied.
- Movers (backward equations): define how value objects (and optionally shadow/marginal objects and policies) move backward across perches.
Most stages have the following four blocks:
arvl_to_dcsn_transition(arrival → decision)dcsn_to_cntn_transition(decision → continuation)cntn_to_dcsn_mover(continuation → decision)dcsn_to_arvl_mover(decision → arrival)
Equation payloads are Dolang+ expressions. Perch tags ([<], unmarked, [>]) are measurability/evaluation assertions (see Spec 1.2); they are not global time subscripts.
Expectation location (keep it readable)
Put E_shock(·) in the mover that crosses the shock edge you are integrating out.
In the common case “a shock is realized between arrival and decision”, expectation belongs in dcsn_to_arvl_mover:
V[<] = E_y(V).
1.3.2 Equation-block shapes (syntax rules) #syntax-rules¶
Under equations:, each entry is either:
- a string payload (block scalar) — typical for transitions, or
- a single-level mapping — typical for movers (to hold multiple named sub-equations like
Bellman,InvEuler, ...).
1.3.2.1 Sub-equations (within movers)¶
A mover may include multiple named sub-equations as keys mapping to string payloads, e.g.:
Bellman: | ...ShadowBellman: | ...InvEuler: | ...(method-specific, e.g. EGM)
These labels are primarily for readability and for attaching methodization/implementation choices later.
1.3.2.2 Movers are “equations-only” (v0.1l direction)¶
We avoid structured mover metadata keys (e.g. sources, aggregation, weights) and instead express branching logic directly in equation payloads.
Structural invariant (v0.1): under a mover, entries are only named sub-equations mapping to string payloads (Bellman, ShadowBellman, InvEuler, …). Branching is expressed by:
- referencing a branch-indexed continuation-value family (e.g.
V_cntn[own],V_cntn[rent]), and - combining those terms using
max_d{…}or an explicit weighted sum.
Labels vs canonical symbols
The YAML key names are human-facing. Translation to T core consumes canonical operator symbols (derived by the compiler/translator). As an author, you should normally stick to the standard keys above.
1.3.3 Transitions (forward equations)¶
1.3.3.1 Arrival → decision: arvl_to_dcsn_transition¶
Use arvl_to_dcsn_transition to define decision-perch fields from arrival-perch fields plus any shocks that become observed at the decision perch. Typical patterns:
- copy/rename fields:
w = w[<] - incorporate a realized shock:
y = y_shock
1.3.3.2 Decision → continuation: dcsn_to_cntn_transition¶
Use dcsn_to_cntn_transition to define continuation/poststate fields (tagged [>]) from decision-perch fields and controls.
Branching stages generalize this to “one transition per continuation branch”. Canonical v0.1l spelling keeps the key dcsn_to_cntn_transition, but allows it to become a branch-keyed mapping:
equations:
dcsn_to_cntn_transition:
own: |
# ... produce `own`-branch poststates (tagged `[>]`)
rent: |
# ... produce `rent`-branch poststates (tagged `[>]`)
For a smooth transition, legacy spellings like dcsn_to_cntn_{label}_transition remain acceptable as a desugaring target.
1.3.3.3 Optional inverse transition: cntn_to_dcsn_transition (method/representation)¶
Some solution methods (notably EGM-style representations) use a continuation-grid representation for certain objects. In those cases it can be useful to provide a “reverse state” mapping cntn_to_dcsn_transition. This is a representation convenience; it does not introduce a new perch.
1.3.4 Movers (backward equations)¶
1.3.4.1 cntn_to_dcsn_mover (optimization / envelope / method-specific steps)¶
cntn_to_dcsn_mover is where you typically write:
- the optimization step (
max_c{...},max_d{...}, …), - any method-specific constructions (e.g.
InvEulerfor EGM), - shadow/marginal relationships (
ShadowBellman).
1.3.4.2 dcsn_to_arvl_mover (expectation location)¶
dcsn_to_arvl_mover is where you typically locate explicit expectations over shocks observed between arrival and decision:
V[<] = E_y(V)dV[<] = r * E_y(dV)
1.3.4.3 Branching movers (equation-only surface syntax)¶
In a branching stage, the cntn_to_dcsn_mover is still “just equations”. You write the branch combination directly:
For endogenous probabilities (e.g. logit/softmax taste shocks), keep the syntax thin:
- declare a probability vector field
p(recommended: undervalues:; it is derived, not chosen), - compute it inside the mover equations (e.g.
p = softmax(...)), - then use
pas coefficients in a weighted sum.
The domain syntax for probability vectors (e.g. @in simplex(K)) is still being pinned down. #todo
1.3.5 Concrete YAML excerpts¶
1.3.5.1 Expectation location (shock between arrival and decision)¶
equations:
arvl_to_dcsn_transition: |
y = y_shock
w = exp(y) + b[<] * r
dcsn_to_cntn_transition: |
a[>] = w - c
cntn_to_dcsn_mover:
Bellman: |
V = max_c{u(c) + β*V[>]}
dcsn_to_arvl_mover:
Bellman: |
V[<] = E_y(V)
Interpretation:
V(unmarked) is a decision-perch object: “post-shock / conditional on what is known at decision time”.V[<]is an arrival-perch object: “pre-shock / integrated overy”.
1.3.5.2 Multi sub-equation mover (EGM-style pattern)¶
equations:
cntn_to_dcsn_mover:
Bellman: |
V = max_c{u(c) + β*V[>]}
InvEuler: |
c[>] = (β*dV[>])^(-1/γ)
ShadowBellman: |
dV = (c)^(-γ)