Symbol Reference Table¶
Single Source of Truth for Bellman calculus Notation
Core Convention¶
- Spaces: Capital sans-serif (\(\mathsf X_{\prec}\), \(\mathsf X\), \(\mathsf X_{\succ}\))
- Elements: Lowercase italic with perch subscript (\(x_{\prec}\), \(x\), \(x_{\succ}\))
- Functions / maps: Upright roman (\(\mathrm{f}\), \(\mathrm{g}\), \(\mathrm{r}\), \(\mathrm{v}\))
- Operators / movers: Blackboard bold (\(\mathbb{B}\), \(\mathbb{I}\), \(\mathbb{T}\), \(\mathbb{F}\))
- Formal role: Determined by syntactic definition (
@def,@in), not by naming
Perch index alphabet¶
| Perch | Math subscript | YAML tag (preferred) | YAML tag (long form) |
|---|---|---|---|
| Arrival | \(\prec\) | [<] |
arvl |
| Decision | \(\sim\) | [~] |
dcsn |
| Continuation | \(\succ\) | [>] |
cntn |
Decision-perch objects are unmarked in surface syntax (V, x, dV). Arrival and continuation perches use [<] and [>].
Justification of the perch index notation¶
Definition. Let \((\mathcal{F}_\prec,\, \mathcal{F}_\sim,\, \mathcal{F}_\succ)\) be a filtration chain with \(\mathcal{F}_\prec \subseteq \mathcal{F}_\sim \subseteq \mathcal{F}_\succ\), where \(\mathcal{F}_i\) is induced by the state variables observable at perch \(i\):
\[\mathcal{F}_\prec \coloneqq \sigma(x_\prec), \qquad \mathcal{F}_\sim \coloneqq \sigma(x_\prec, x_\sim), \qquad \mathcal{F}_\succ \coloneqq \sigma(x_\prec, x_\sim, x_\succ)\]Designate \(\mathcal{F}_\sim\) as the reference (decision) filtration. The perch subscripts are the predicate induced by fixing one argument of the inclusion order:
- \(x_\prec\): a random variable \(\mathcal{F}_\prec\)-measurable, where \(\mathcal{F}_\prec \prec \mathcal{F}_\sim\) (strictly coarser than the decision)
- \(x\) (unmarked): a random variable \(\mathcal{F}_\sim\)-measurable (the reference)
- \(x_\succ\): a random variable \(\mathcal{F}_\succ\)-measurable, where \(\mathcal{F}_\succ \succ \mathcal{F}_\sim\) (strictly finer than the decision)
The subscripts \(\prec\) and \(\succ\) are not names — they are the order relation of the filtration, with the decision as the fixed argument. This is the same notational pattern as \(\mathbb{R}_{>0} = \{x \in \mathbb{R} : x > 0\}\): the subscript is a predicate (a defining condition relative to a reference point), not a label. The subscript \(\prec\) states the fact that the arrival filtration is strictly coarser than the decision filtration.
The YAML surface forms [<] and [>] are the ASCII rendering of \(\prec\) and \(\succ\).
Remark (novelty and precedents). Using an order relation as a subscript to index position in a filtration appears to be new in the dynamic programming literature. The closest precedents are: (i) the filtration limits \(\mathcal{F}_{t^-}\), \(\mathcal{F}_{t^+}\) in stochastic calculus, which use order-relative logic on a continuous parameter; (ii) the incoming/outgoing boundary notation \(\partial^{\pm}M\) in TQFT; (iii) pre-place/post-place notation \({}^{\bullet}t\), \(t^{\bullet}\) in Petri nets. The motivation for this convention is that perch indices should be compositional (relative to the stage, not to absolute time) and self-describing (the symbol encodes its meaning).
Derivative notation and the _{.} operator convention¶
The _{...} convention: when _{...} appears after an operator name, the content inside the braces specifies with respect to what the operator acts. This is distinct from plain underscore _, which is a name separator (e.g. m_d is "the variable named m-d", not "derivative of m").
| Syntax pattern | Meaning | Mathematical |
|---|---|---|
d_{a}V |
Partial derivative of \(V\) wrt \(a\) | \(\partial_a \mathrm{v}\) |
d_{h}V |
Partial derivative of \(V\) wrt \(h\) | \(\partial_h \mathrm{v}\) |
d_{a}V[<] |
\(\partial_a \mathrm{v}\) at arrival perch | \(\partial_a \mathrm{v}_\prec\) |
d_{a}V[>] |
\(\partial_a \mathrm{v}\) at continuation perch | \(\partial_a \mathrm{v}_\succ\) |
d_{a,a}V |
Second derivative wrt \(a\) | \(\partial_{aa} \mathrm{v}\) |
d_{a}d_{h}V |
Cross partial | \(\partial_a \partial_h \mathrm{v}\) |
E_{θ}(V) |
Expectation wrt \(\theta\) | \(\mathbb{E}_\theta[\mathrm{v}]\) |
max_{c}{...} |
Maximise over \(c\) | \(\sup_c\{\cdots\}\) |
The convention applies uniformly to all operators: d_{.} for derivatives, E_{.} for expectations, max_{.} for maximisation. The variable inside _{...} must be a declared symbol (state, control, or exogenous).
Reserved operator names for differentiation:
| Operator | Mathematical | Meaning |
|---|---|---|
d |
\(\partial\) | Partial derivative — d_{x}V means \(\partial V / \partial x\), holding all other arguments fixed |
D |
\(\mathrm{D}\) | Total derivative (Jacobian / Fréchet) — D_{x}V means \(\mathrm{D}_x V\), the total derivative including indirect dependence through other variables |
In most stage equations, d (partial) is the relevant operator — envelope conditions, Euler equations, and EGM all use partial derivatives. D (total) arises in chain-rule contexts (e.g. computing the total effect of a state change through a transition).
No naming conflict with variables. A bare d (e.g. d: '@in {keep, adjust}') is a valid variable name. The derivative operator is only triggered by the pattern d_{...} — the _{ token is what distinguishes operator-with-subscript from a plain identifier. The parser never confuses d (a variable) with d_{a} (partial derivative wrt \(a\)).
Disambiguation: _{...} (with braces) always means "with respect to." Plain underscore without braces is always a name separator. There is no ambiguity:
| Expression | Meaning |
|---|---|
d_{a}V |
Derivative of \(V\) wrt \(a\) |
m_d |
Variable named "m-d" (decision-perch cash-on-hand) |
V_own |
Value function named "V-own" (branch label) |
d_{a}V_own |
Derivative of \(V_{\text{own}}\) wrt \(a\) |
Declaring marginal values in values_marginal:
When a stage has multiple state variables and the method requires separate marginals (e.g. multi-dimensional EGM), declare one entry per (variable, perch) pair:
values_marginal:
d_{a}V[<]: "@in R" # ∂ₐv at arrival
d_{h}V[<]: "@in R" # ∂ₕv at arrival
d_{a}V: "@in R" # ∂ₐv at decision
d_{h}V: "@in R" # ∂ₕv at decision
d_{a}V[>]: "@in R+" # ∂ₐv at continuation
d_{h}V[>]: "@in R+" # ∂ₕv at continuation
For stages with a single state variable, the _{...} subscript may be omitted since the differentiation variable is unambiguous:
Legacy notation: dV_a (plain underscore) is deprecated. Use d_{a}V instead.
Open design question: declared symbol vs canonical operator
It is currently unresolved whether d_{a}V[<] should be:
-
A declared symbol — the user explicitly lists
d_{a}V[<]: "@in R"invalues_marginal, creating a named object that equations reference. Thed_{a}prefix is a naming convention with no computational meaning at the SYM layer. -
A canonical operator application —
d_{a}is a first-class operator that the system applies toV[<]automatically. No declaration invalues_marginalis needed; the system infers the marginal's existence and type from the operator and its argument.
Under interpretation (1), the system could also accept d_a_V as a plain variable name for the same object (underscore as name separator). Under interpretation (2), d_{a}V[<] is computed, not declared, and d_a_V would be a distinct user-defined symbol with no automatic relationship to the derivative.
Current stance: v0.1 uses interpretation (1) — marginals are declared symbols. The _{...} convention is a naming discipline, not a computational operator. Whether to elevate d_{.} to a true operator (interpretation 2) is deferred to a future spec revision.
ambiguity #values-marginal #operator-vs-symbol #todo¶
Rosetta Stone: Math ↔ YAML¶
| Mathematical | Dolo+ syntax | Description | Declaration | Note |
|---|---|---|---|---|
| \(\mathsf X_{\prec}\) | prestate: space (implied by domain of prestate variable) |
Arrival state space | Optional (implied by domain) | |
| \(\mathsf X\) | states: space |
Decision state space | Optional (implied by domain) | |
| \(\mathsf X_{\succ}\) | poststates: space |
Continuation state space | Optional (implied by domain) | Poststate and continuation state may differ; e.g. in a primal Bellman representation the continuation state is next-period market resources. |
| \(x_{\prec}\) | Variable in prestate, tagged x[<]. Declaring m in prestate implies x[<] = [m]. |
Arrival state variable | Variable name and domain required | In a measure-theoretic framework these are random variables on an underlying probability space. |
| \(x\) | Variable in states, tagged x (unmarked) |
Decision state variable | Variable name and domain required | |
| \(x_{\succ}\) | Variable in poststates, tagged x[>] |
Continuation state variable | Variable name and domain required | |
| \(\mathrm{v}_{\prec}\) | V[<] — sugar for \(\mathrm{v}_{\prec}(x_{\prec})\). Interpreted as V_fn[<](x[<]). Can be a tuple [V_adj[<], V_nadj[<]]. |
Arrival value function | Domain must agree with perch state dimension | |
| \(\mathrm{v}\) | V (unmarked) |
Decision value function | Domain must agree with perch state dimension | |
| \(\mathrm{v}_{\succ}\) | V[>] |
Continuation value function | Domain must agree with perch state dimension | |
| \(\partial_m\mathrm{v}\) | d_{m}V (preferred), dV (single-state shorthand) |
Marginal decision value | Required only if method needs it | For multi-state stages, declare one per state variable: d_{a}V, d_{h}V. |
| \(\partial_a\mathrm{v}_{\succ}\) | d_{a}V[>] (preferred), dV[>] (single-state shorthand) |
Marginal continuation value | Required only if method needs it | |
| \(\mathrm{g}_{\prec\sim}\) | arvl_to_dcsn_transition; optional tag g[<] |
Arrival → decision transition | Required if non-trivial; must satisfy measurability at perches | |
| \(\mathrm{g}_{\sim\succ}\) | dcsn_to_cntn_transition; optional tag g[>] |
Decision → continuation transition | Required if non-trivial | |
| \(\mathbb{B}\) | cntn_to_dcsn_mover; optional tag BB |
Decision mover (backward, cntn → dcsn) | Required if non-trivial; sub-equations depend on chosen method | |
| \(\mathbb{I}\) | dcsn_to_arvl_mover; optional tag II |
Arrival mover (backward, dcsn → arvl) | Required if non-trivial | |
| \(\mathbb{T}_{[S]} = \mathbb{I}\,\mathbb{B}\) | Stage YAML file; sugar: \(\mathbb{S}\) | Stage operator (composite) | Stage name declared at period level | |
| \(\Gamma(x)\) | Feasibility constraint via ⊥ declarations below equation |
Action correspondence | Optional | |
| \(\mathrm{r}\) | rwd_function; sugar r — expands to r_fn(x, a) |
Stage reward | Required if not declared in Bellman operator | |
| \(\beta\) | beta in parameters |
Discount factor | ||
| \(\zeta\) | Shock in exogenous (pre-decision) |
Pre-decision shock | ||
| \(\eta\) | Shock in exogenous (post-decision) |
Post-decision shock | ||
| \(\mathbb{E}_{\succ}\{\cdot\}\) | E_{shock_name}(·) |
Expectation operator | ||
| \(\sup_{a\in\Gamma(x)}\) | max_{c}{} |
Maximisation operator | ||
| \(\arg\sup_{a\in\Gamma}\) | argmax_{c}{} |
Policy operator | ||
| \(\mathrm{a}\colon\mathsf X\to\mathsf A\) | Policy/action/control function; can substitute a declared control variable c |
Optimal policy | Canonically sugared to a_fn(x) since a sits at the decision perch. |
|
| \(a\) | Control variable | |||
| \(N_+\) | Set of branch labels (in branching connector/twister) | Valid successor stage kinds | Required for branching stages (kind: "branching") |
Each \(j \in N_+\) indexes a distinct successor with its own state space. |
| \(p(j \mid x_v, \pi)\) | Appears explicitly in cntn_to_dcsn_mover.Bellman as a coefficient in a weighted sum (exogenous or computed in-equation, e.g. softmax) |
Branching probability for branch \(j\) | Required for probabilistic branching; \(\sum_j p_j = 1\) | Uses standard exogenous/parameter declarations or explicit probability-generation equations — no special YAML metadata is required. |
| \(\mathrm{v}_{\prec,j}\) | Arrival value of branch target \(j\) (e.g. V_own, V_rent; bound by values.V[>] as {own: V_own, rent: V_rent}) |
Branch-specific arrival value function | One per branch; separate named object | Value functions along each branch are named and separable. |
| \(\mathrm{g}_{\sim\succ,j}\) | dcsn_to_cntn_transition.{label} (e.g. dcsn_to_cntn_transition.own; legacy: dcsn_to_cntn_own_transition) |
Branch-specific transition | One per branch; may map to different state spaces | |
| \(\mathsf X_{\succ,j}\) | poststates: {label}: sub-block (e.g. own:, rent:; legacy: cntn_{label}) |
Branch-specific continuation space | One per branch |
Argument delimiters (SYM surface syntax)¶
- Perch tags:
x[<],x[~],x[>]are perch indices (measurability declarations), not function application. - Function evaluation:
f[x],f[x, y](preferred SYM form for “evaluatefat arguments”). - Operator application (higher-order operators acting on expressions/functions):
- Operator bodies use braces
{…}(e.g.max_c{…},argmax_c{…}). - Some named operators use parentheses
(…)(e.g.E_y(V)); treat these as operator arguments, not as general function-call syntax.
Open questions
- Declaration of distributions that depend on the state.
- Function arguments / intermediate evaluation
- Whether to allow
()notation for arbitrary function evaluation at intermediate variables that are not states. Suggestion: only if a function is explicitly declared with a name (e.g.consumed_func: c = y, thenconsumed_func[y]).- Intermediate rule: we use
[]to define function-argument evaluation in SYM.- Use mathematical rules in T core to define/validate function arguments. #function-arguments #functin-arguments #ambiguity #ddsl-core #t-core #function-definition #core-vs-sym
1. The Stage (ADC Structure)¶
Perches (nodes)¶
Each stage has three perches forming a filtration \(\mathcal{F}_{\prec} \subseteq \mathcal{F}_{\sim} \subseteq \mathcal{F}_{\succ}\).
| Perch | Math state | Math value | YAML tag | YAML section |
|---|---|---|---|---|
| Arrival (\(\prec\)) | \(x_{\prec}\in\mathsf X_{\prec}\) | \(\mathrm{v}_{\prec}\) | [<] (preferred), arvl |
prestate |
| Decision (\(\sim\)) | \(x\in\mathsf X\) | \(\mathrm{v}\) | (unmarked), dcsn |
states |
| Continuation (\(\succ\)) | \(x_{\succ}\in\mathsf X_{\succ}\) | \(\mathrm{v}_{\succ}\) | [>] (preferred), cntn |
poststates |
Perch tags are measurability declarations: z[<] asserts that \(z\) is \(\mathcal{F}_{\prec}\)-measurable; z[>] asserts \(\mathcal{F}_{\succ}\)-measurability. Decision-perch variables are unmarked.
Movers (edges)¶
| Edge | Forward (transition) | Backward (value) | YAML forward | YAML backward |
|---|---|---|---|---|
| Arrival → Decision | \(x = \mathrm{g}_{\prec\sim}(x_{\prec},\,\zeta)\) | \(\mathrm{v}_{\prec} = \mathbb{I}\,\mathrm{v}\) | arvl_to_dcsn_transition |
dcsn_to_arvl_mover |
| Decision → Continuation | \(x_{\succ} = \mathrm{g}_{\sim\succ}(x,\,a,\,\eta)\) | \(\mathrm{v} = \mathbb{B}\,\mathrm{v}_{\succ}\) | dcsn_to_cntn_transition |
cntn_to_dcsn_mover |
The composite stage operator is \(\mathbb{T} = \mathbb{I}\circ\mathbb{B}\colon\mathscr{B}(\mathsf X_{\succ})\to\mathscr{B}(\mathsf X_{\prec})\).
Branching stages¶
A branching stage (kind: "branching") has multiple continuation perches, one per branch \(j \in N_+\):
| Perch | Math state | Math value | YAML section |
|---|---|---|---|
| Continuation \(j\) (\(\succ_j\)) | \(x_{\succ,j}\in\mathsf X_{\succ,j}\) | \(\mathrm{v}_{\succ,j}\) | poststates: {label}: |
Each branch has its own state space \(\mathsf X_{\succ,j}\), transition \(\mathrm{g}_{\sim\succ,j}\), and value function \(\mathrm{v}_{\succ,j}\). Branching arises when these state spaces are heterogeneous (different dimensions or domains across branches).
The continuation space is formally a coproduct \(\mathsf X_{\succ} = \coprod_{j \in N_+} \mathsf X_{\succ,j}\), with elements \((j, x_j)\) — a discrete label paired with a branch-specific (typically continuous) state. When all branches share the same continuous space \(\mathsf X_c\), this collapses to a product \(N_+ \times \mathsf X_c\). Value functions on a coproduct decompose as \(\mathrm{v}_{\succ} \in \mathcal{V}(\mathsf X_{\succ}) \iff (\mathrm{v}_{\succ,j})_{j} \in \prod_j \mathcal{V}(\mathsf X_{\succ,j})\) — the named sub-blocks in poststates are the syntactic representation of this decomposition.
The backward mover at a branching stage receives multiple continuation values and aggregates:
| Aggregation | Backward mover \(\mathbb{B}\) | Forward operator |
|---|---|---|
max (discrete choice) |
\(\mathrm{v}(x) = \max_{j \in N_+} \mathrm{v}_{\succ,j}\!\bigl(\mathrm{g}_{\sim\succ,j}(x)\bigr)\) | Route to \(j^* = \arg\max_j\); population partitions |
expectation (stochastic) |
\(\mathrm{v}(x) = \sum_{j \in N_+} p_j(x)\,\mathrm{v}_{\succ,j}\!\bigl(\mathrm{g}_{\sim\succ,j}(x)\bigr)\) | Draw \(j \sim p(\cdot\mid x)\); population splits by weight |
Within-stage discrete choice over a homogeneous finite set (e.g. \(H' \in \mathcal{H}\), same state space for all choices) does not require branching — use
max_{c}{…}instead. Branching is for heterogeneous successors: different state spaces, different value functions, different downstream stages. See Spec 0.1l §9 for the full distinction.
Connectors and twisters are unchanged. Branching is entirely a stage-level concept. Composition between a branching stage's continuation perches and successor stages uses the existing namespace rule: field names match implicitly, or standard rename connectors/twisters provide the mapping. Branching probabilities are declared as standard exogenous: or parameters: in the stage YAML.
Sub-equations within movers¶
Each mover can contain a list of sub-equations; methods supply mover-equation recipes (e.g. EGM).
At minimum the value recursion (V[<] or V) and control recovery (c[>]) must be specified.
| Sub-equation | Purpose | Typical content |
|---|---|---|
Bellman |
Value recursion | V = max_{c}(u(c) + β*V[>]) |
InvEuler |
Inverse Euler (EGM) | c[>] = (β*dV[>])^(-1/ρ) |
MarginalBellman |
Envelope condition | dV = u'(c) |
ShadowBellman |
Marginal expectation | dV[<] = R * E_{θ}(dV) |
To do — interpretation of sub-equations. The sub-equations listed above can be viewed in (at least) two ways:
As implementation schemes: each sub-equation is a recipe that a particular numerical method (VFI, EGM, …) uses to implement the abstract mover \(\mathbb{B}\) or \(\mathbb{I}\). Different methods select different subsets of these equations. Under this view,
BellmanandInvEulerare alternative routes to the same operator — one via direct maximisation, the other via the inverse Euler step.As a decomposition of the mover into named sub-operators: each sub-equation defines a distinct functional object (value recursion, envelope condition, shadow value, etc.) and the mover is the composition or coupling of these objects. Under this view, the sub-equations are part of the mathematical specification, not just solver details.
Clarifying which view is canonical (or whether both coexist at different layers — e.g. view 2 at the SYM/T core level, view 1 at the methodization level) is an open design question.
Forward operators¶
Distribution evolution is described as pushforward under the transition kernels:
- Arrival → Decision: push \(\mu_{\prec}\) forward under \((x_{\prec},\zeta)\mapsto\mathrm{g}_{\prec\sim}(x_{\prec},\zeta)\).
- Decision → Continuation: push \(\mu\) forward under \((x,a,\eta)\mapsto\mathrm{g}_{\sim\succ}(x,a,\eta)\) (with \(a=\pi(x)\)).
The backward mover \(\mathbb{I}\) is the integral operator adjoint to pushforward under \(\mathrm{g}_{\prec\sim}\):
and similarly \(\mathbb{B}\) is adjoint to pushforward under \(\mathrm{g}_{\sim\succ}\). (Categorically, this is an adjunction \(K_{\#}\dashv K^{*}\) in the Kleisli category of the Giry monad.)
2. Shock Configurations¶
| Configuration | \(\mathsf Z_{\prec}\) | \(\mathsf Z_{\succ}\) | Arrival → Decision kernel \(\mathrm{g}_{\prec\sim}\) | Decision → Continuation kernel \(\mathrm{g}_{\sim\succ}\) |
|---|---|---|---|---|
| Pre-decision only | non-trivial | \(\{\varnothing\}\) | \(\mathrm{g}_{\prec\sim}(x_{\prec},\zeta)\) | \(\mathrm{g}_{\sim\succ}(x,a)\) |
| Post-decision only | \(\{\varnothing\}\) | non-trivial | identity: \(\mathrm{g}_{\prec\sim}(x_{\prec})=x\) | \(\mathrm{g}_{\sim\succ}(x,a,\eta)\) |
| Both | non-trivial | non-trivial | general | general |
| Deterministic | \(\{\varnothing\}\) | \(\{\varnothing\}\) | identity: \(\mathrm{g}_{\prec\sim}(x_{\prec})=x\) | \(\mathrm{g}_{\sim\succ}(x,a)\) |
3. Composition¶
| Concept | Mathematical | YAML | Description | Note |
|---|---|---|---|---|
| Stage operator | \(\mathbb{T}_{[S]} = \mathbb{I}_{[S]}\circ\mathbb{B}_{[S]}\) | Stage YAML file | Single stage backward sweep | |
| Intra-period connector | \(\mathrm{g}_{\succ,\prec}\) | connectors: with rename: |
Intra-period field renaming | Same syntax for sequential and branching — connectors just rename. Branching wiring is implied by the stage's multiple continuation perches and the namespace. |
| Period operator | Given by the stage graph | stages: list in period YAML |
Composed backward sweep | For branching periods, the stage graph is a DAG; solve order is topological sort. |
| Inter-period connector | \(\chi_{j,j+1}\) | twisters: with rename: |
Inter-period field renaming | Same syntax for sequential and branching. DAG nests add explicit to: for target period. |
Viewing composition as a graph greatly simplifies the definition of inter- and intra-stage links: no domain, range, or stage-specific measurable functions are needed—only pairs of field names.
Period and stage indexing (in progress)¶
To do. Standardise notation for:
- Stage occurrences within a period (e.g. \(j\), \(s_j\), \(\mathbb{T}_j\)), and
- Period instances within a nest (e.g. \(t\), \(\mathbb{T}^{(t)}\)),
together with SYM surface spelling rules (so these do not get confused with within-stage perch tags
[<], (unmarked),[>]).
4. YAML Syntax¶
Top-level sections¶
symbols:
spaces: # Space/domain definitions (@def)
prestate: # Arrival state variables (@in)
states: # Decision state variables (@in)
poststates: # Continuation state variables (@in)
controls: # Action variables (@in)
exogenous: # Shocks with distributions (@in, @dist)
values: # Value function objects (V[<], V, V[>])
values_marginal: # Marginal value objects (dV[<], dV, dV[>])
parameters: # Problem constants (Υ-level)
settings: # Numerical configuration (ρ-level)
equations:
arvl_to_dcsn_transition: | # g_{≺○} kernel (arrival → decision)
dcsn_to_cntn_transition: | # g_{○≻} kernel (decision → continuation)
cntn_to_dcsn_mover: # 𝔹 backward mover
Bellman: |
InvEuler: |
MarginalBellman: |
dcsn_to_arvl_mover: # 𝕀 backward mover
Bellman: |
ShadowBellman: |
Type operators¶
| Operator | Meaning | Example |
|---|---|---|
@def |
Define space/type ("is defined as") | Xm: "@def R++" |
@in |
Membership declaration ("∈") | m: "@in Xm" |
@dist |
Distribution family | "@dist LogNormal(μ_θ, σ_θ)" |
Equation operators¶
| Operator | YAML form | Mathematical |
|---|---|---|
| Expectation | E_{θ}(V[>]) |
\(\mathbb{E}_{\theta}[\mathrm{v}_{\succ}]\) |
| Maximisation | max_{c}(u + β*V[>]) |
\(\sup_{c}\{u + \beta\,\mathrm{v}_{\succ}\}\) |
| argmax | argmax_{c}(u + β*V[>]) |
\(\arg\sup_{c}\{u + \beta\,\mathrm{v}_{\succ}\}\) |
Worked example: cons_stage¶
symbols:
spaces:
Xm: "@def R++"
Xa: "@def R+"
prestate:
m: "@in Xm"
states:
m_d: "@in Xm"
poststates:
a: "@in Xa"
controls:
c: "@in Xm"
values:
V[<]: "@in R"
V: "@in R"
V[>]: "@in R"
values_marginal:
dV: "@in R+"
dV[>]: "@in R+"
parameters: [β, ρ]
equations:
arvl_to_dcsn_transition: |
m_d = m
dcsn_to_cntn_transition: |
a = m_d - c
cntn_to_dcsn_mover:
Bellman: |
V = max_{c}(u(c) + β*V[>])
InvEuler: |
c[>] = (β*dV[>])^(-1/ρ)
MarginalBellman: |
dV = (c)^(-ρ)
dcsn_to_arvl_mover:
Bellman: |
V[<] = V
Stage operator: \((\mathbb{B}\,\mathrm{v}_{\succ})(m) = \max_{c\in(0,m)}\{u(c) + \beta\,\mathrm{v}_{\succ}(m-c)\}\); \(\mathbb{I}=\mathrm{id}\).
Worked example: noport_stage¶
symbols:
spaces:
Xk: "@def R++"
Xm: "@def R++"
Θ: "@def R++"
prestate:
k: "@in Xk"
states:
k_d: "@in Xk"
poststates:
m: "@in Xm"
exogenous:
θ:
- "@in Θ"
- "@dist LogNormal(μ_θ, σ_θ)"
values:
V[<]: "@in R"
V: "@in R"
V[>]: "@in R"
parameters: [R, μ_θ, σ_θ]
equations:
arvl_to_dcsn_transition: |
k_d = k
dcsn_to_cntn_transition: |
m = k_d*R + θ
cntn_to_dcsn_mover:
Bellman: |
V = E_{θ}(V[>])
dcsn_to_arvl_mover:
Bellman: |
V[<] = V
Stage operator: \((\mathbb{B}\,\mathrm{v}_{\succ})(k) = \mathbb{E}_{\theta}[\mathrm{v}_{\succ}(kR + \theta)]\); \(\mathbb{I}=\mathrm{id}\).
Worked example: tenure_choice (branching stage)¶
symbols:
spaces:
Xa: "@def R+"
XH: "@def linspace(H_min, H_max, n_H)"
XY: "@def {1, ..., n_y}"
prestate:
a: "@in Xa"
H: "@in XH"
y_pre: "@in XY"
states:
a: "@in Xa"
H: "@in XH"
y: "@in XY"
poststates:
own:
a: "@in Xa"
H: "@in XH"
y: "@in XY"
rent:
w: "@in Xa"
y: "@in XY"
controls:
d: "@in {own, rent}"
exogenous:
y:
- "@in XY"
- "@dist MarkovChain(Pi, z_vals)"
values:
V[<]: "@in R"
V: "@in R"
V[>]:
own: V_own
rent: V_rent
V_own: "@in R"
V_rent: "@in R"
parameters: [beta, r]
stage:
kind: "branching"
equations:
arvl_to_dcsn_transition: |
a = a[<]
H = H[<]
y = y_shock
dcsn_to_cntn_transition:
own: |
a[>] = a
H[>] = H
y[>] = y
rent: |
w[>] = (1+r)*a + H
y[>] = y
cntn_to_dcsn_mover:
Bellman: |
V = max_d{V_own[>], V_rent[>]}
dcsn_to_arvl_mover:
Bellman: |
V[<] = E_{y}(V)
Branching stage operator: \((\mathbb{B}\,(\mathrm{v}_{\succ,\text{own}}, \mathrm{v}_{\succ,\text{rent}}))(a,H,y) = \max\bigl\{\mathrm{v}_{\succ,\text{own}}(a,H,y),\;\mathrm{v}_{\succ,\text{rent}}\bigl((1\!+\!r)a+H,\,y\bigr)\bigr\}\); \(\mathbb{I}\,\mathrm{v} = \mathbb{E}_y[\mathrm{v}]\).
The tenure choice stage is branching because own and rent paths have different state spaces (\(\mathsf X_{\succ,\text{own}} = \mathbb{R}_+ \times \mathcal{H} \times \mathcal{Y}\) vs \(\mathsf X_{\succ,\text{rent}} = \mathbb{R}_+ \times \mathcal{Y}\)). Contrast with the downstream
OwnerHousingChoicestage, which has a within-stage discrete choice over \(H' \in \mathcal{H}\) (homogeneous set, same state space for all choices) — that usesmax_{c}{}, not branching.
5. Parameters vs Settings¶
| Category | Level | Defines | Examples |
|---|---|---|---|
| Parameters | Υ (math) | The mathematical problem | \(\beta\), \(\rho\), \(R\), \(\mu_{\theta}\), \(\sigma_{\theta}\), grid bounds for discrete spaces |
| Settings | ρ (code) | Numerical/solver configuration | n_m, n_a (grid sizes), tolerances, max iterations |
Key principle: Changing a parameter changes the mathematical problem. Changing a setting changes only the numerical approximation.
6. ASCII Diagram Conventions¶
┌─────── S₀ ────────┐ ┌─────── S₁ ────────┐
g≺○ g○≻ g≺○ g○≻
≺₀ ───→ ○₀ ───→ ≻₀ ══shared══ ≺₁ ───→ ○₁ ───→ ≻₁
←┄┄┄ ←┄┄┄ ←┄┄┄ ←┄┄┄
𝕀 𝔹 𝕀 𝔹
Solid arrows: forward transitions (\(\mathrm{g}_{\prec\sim}\), \(\mathrm{g}_{\sim\succ}\)).
Dashed arrows: backward movers (\(\mathbb{I}\), \(\mathbb{B}\)).
Double line (══shared══): the continuation space of \(S_0\) coincides with the arrival space of \(S_1\) (shared boundary perch).
Branching stage diagram¶
┌── g○≻_own ──→ ≻_own ══→ S_own ──→ ...
┌───── S_branch ────┐ │
g≺○ ○ ────┤ (max or Σpⱼ)
≺ ───→ ○ ────┐ │
←┄┄┄ ←┄┄┄ └── g○≻_rent ──→ ≻_rent ══→ S_rent ──→ ...
𝕀 𝔹(multi)
Fan-out from the decision perch: each branch \(j\) has its own transition \(\mathrm{g}_{\sim\succ,j}\), continuation perch \(\succ_j\), and downstream stages. The backward mover \(\mathbb{B}\) receives values from all branches and aggregates (max for discrete choice, \(\sum p_j\) for stochastic).
Hardwired Symbols (Pre-defined in DDSL/Dolo+)¶
See Dolo+ Primitives for the full reference of built-in domains, distributions, stochastic processes, mathematical functions, operations, grid discretization methods, and reserved keywords.