Dolo → dolo-plus Syntax Changes (v0.1)
Date: 28 December 2025
Scope: Minimal syntax differences between vanilla Dolo and dolo-plus (ADC dialect, v0.1 “stage mode”)
Reference files:
- docs/specs/dolo-plus-v0.1/syntax-semantic-rules/doloplus-foundations.md
- claude/prompts/dev-specs/dolo+/spec_0.1/example-dolo-plus-consind-egm.yml
0. Compatibility contract (minimal-change strategy)
- Plain Dolo YAML remains valid dolo-plus YAML and must parse into a dolo-plus representation without loss.
- dolo-plus features are opt-in: stage mode is activated only when
dolo_plus: / dolo_plus_metadata: is present and/or when equations: contains non-scalar blocks.
- In plain Dolo mode, time indices like
[t], [t+1] retain their usual meaning.
- dolo-plus canonicalizes time-style indices into slot indices only when explicitly in stage mode.
1. Top-Level Structure
Dolo
symbols:
equations:
calibration:
domain:
exogenous:
options:
dolo-plus
dolo_plus: # NEW (opt-in): stage-mode metadata (sometimes named `dolo_plus_metadata`)
dialect: adc-stage
version: 0.1
slot_map: {...}
information_timing: {...}
validation: {...}
operators: {...}
equation_symbols: {...} # optional (label → canonical symbol)
inter_stage_links: {...} # optional (wiring across stages; x and V/dV)
symbols:
equations:
calibration:
domain:
exogenous:
options:
2. Index Semantics
| Aspect |
Dolo |
dolo-plus |
| Index meaning |
Time: [t-1], [t], [t+1] |
Slot/perch: [-1], [0], [+1] (stage mode) |
| Interpretation |
Previous/current/next period |
Arrival/decision/continuation within stage |
| Inter-stage link |
Implicit via recursion in time |
Recorded explicitly (state link \(x_{\text{next}}[-1] := x[+1]\); in stationary models value wiring identifies \(V[+1] \equiv V[-1]\) and \(dV[+1] \equiv dV[-1]\)) |
Parser defensiveness (v0.1):
- accept [1] and [+1] as the same slot (normalize internally)
- accept [-1] (optionally [m1]) as the same slot (normalize internally)
- do not mix t-style indices with numeric slot indices in the same file unless explicitly in plain Dolo mode
3. Symbol Groups
| Dolo |
dolo-plus |
Change |
states: [w] |
states: [w] |
Same (canonical slot 0) |
poststates: [a] |
poststates: [a] |
Same (canonical slot +1) |
| (none) |
prestate: [b] |
NEW: arrival perch state (slot -1) |
expectations: [mr] |
(deprecated) |
REMOVED: replaced by explicit E_y(·) operator |
values: [V] |
values: [V] |
Same, but now slot-indexed: V[<], V (unmarked), V[>] (slots -1, 0, +1) |
| (none) |
shadow_value: [dV] |
NEW: shadow-value objects, slot-indexed |
controls: [c] |
controls: [c] |
Same (canonical slot 0), but shiftable under measurability |
4. Equation Block Naming
| Dolo Block |
dolo-plus Label |
Canonical Symbol |
Notes |
transition |
(deprecated) |
— |
Split into \(\mathrm{g}_{\prec\sim}\) + \(\mathrm{g}_{\sim\succ}\) |
half_transition |
arvl_to_dcsn_transition |
\(\mathrm{g}_{\prec\sim}\) |
Arrival → decision |
auxiliary_direct_egm |
dcsn_to_cntn_transition |
\(\mathrm{g}_{\sim\succ}\) |
Decision → continuation |
reverse_state |
cntn_to_dcsn_transition |
\(\mathrm{g}_{\sim\succ}^{-1}\) |
Continuation → decision (inverse) |
expectation |
dcsn_to_arvl_mover |
\(\mathbb{I}\) |
Expectation lives here |
direct_response_egm |
cntn_to_dcsn_mover |
\(\mathbb{B}\) |
Optimization/inversion step |
arbitrage |
(TBD) |
— |
May become sub-equation of mover |
v0.1 note:
- the YAML keys under equations: are descriptive labels
- canonical symbols (\(\mathrm{g}_{\prec\sim}\), \(\mathbb{I}\), …) are carried in metadata (e.g. dolo_plus.equation_symbols) or known by the directive system
5. Equation Block Structure
Dolo (flat)
equations:
half_transition: |
w[t] = exp(y[t]) + a[t-1]*r
expectation: |
mr[t] = β*(c[t+1])^(-γ)*r
equations:
arvl_to_dcsn_transition: |
w[0] = exp(y[0]) + b[-1]*r
cntn_to_dcsn_mover: # Nested sub-equations
Bellman: |
V[0] = max_c{(c[0]^(1-γ))/(1-γ) + β*V[+1]}
InvEuler: |
c[+1] = (β*dV[+1])^(-1/γ)
ShadowBellman: |
dV[0] = (c[0])^(-γ)
6. Expectation Handling
| Aspect |
Dolo |
dolo-plus |
| Symbol group |
expectations: [mr] |
(deprecated) |
| Equation block |
expectation: \| mr[t] = ... |
(deprecated as standalone block) |
| Operator |
Implicit (solver performs integration) |
Explicit: E_y(·) in mover equations |
| Location |
Algorithmic (in solver loop) |
Recorded: dolo_plus.operators.E_y.default_location |
Dolo
expectation: |
mr[t] = β*(c[t+1])^(-γ)*r
dolo-plus
dcsn_to_arvl_mover:
ShadowBellman: |
dV[-1] = r * E_y(dV[0])
7. Variable Indexing Rules
Dolo
- Any symbol can appear with
[t-1], [t], [t+1]
controls[-1] is legal ("previous period's control")
dolo-plus
- In stage mode, numeric indices denote slots (not time).
- We recommend writing indices explicitly (e.g.
w[0], b[-1], a[+1], y[0], c[0]) to make parsing/translation unambiguous.
- Slot-indexed value objects:
V[-1], V[0], V[+1], dV[·], x[·]
- Shift operator:
c[+1] = shift control to continuation perch (if measurable)
- Forbidden:
c[-1] when shock arrives between -1 and 0
validation:
allow_indexed_tokens: [V, dV, x, c]
index_aliases: {"+1": 1, "1": 1, "-1": -1, "m1": -1}
shift_rules:
canonical_slot: {c: 0}
allow: {c: [+1]}
disallow: {c: [-1]}
Dolo
- Not explicitly recorded
- Shocks appear in
exogenous: and in equations via y[t]
dolo-plus
- Explicit:
information_timing.shocks records when shocks are realized/observed
- Used to enforce measurability constraints on shifts
- v0.1 convention (Option B):
x[i] is the information state at perch i; shocks realized on an edge become measurable at the next perch (and thus part of x[·] there)
information_timing:
shocks:
- name: y
realized_between_slots: [-1, 0]
observed_at_slot: 0
Dolo
- No concept of "underlying state slots"
states is just a symbol group
dolo-plus
- Canonical information-state slot object:
x[·] with slots {-1, 0, +1}
- Modeller symbols are bound to slots via
slot_map
slot_map:
ustate_name: x
x[-1]: {group: prestate, tokens: [b]}
x[0]: {group: states, tokens: [w]}
x[+1]: {group: poststates, tokens: [a]}
10. Deprecated Patterns
| Pattern |
Dolo Status |
dolo-plus Status |
expectations: [mr] |
Legal |
Deprecated |
expectation: \| ... |
Legal |
Deprecated (use mover with E_y) |
controls[t-1] |
Legal |
Deprecated in stage mode (use predetermined state) |
transition: \| ... |
Legal |
Split into \(\mathrm{g}_{\prec\sim}\) + \(\mathrm{g}_{\sim\succ}\) |
mixing [t] with [-1/0/+1] |
Legal |
Disallowed in stage mode (unless plain Dolo mode) |
11. Summary: What Changes
- Opt-in stage mode via
dolo_plus: / dolo_plus_metadata: (plain Dolo remains valid dolo-plus)
- Add
prestate: for the arrival perch
- Add slot-indexed value objects (
V[·]) and shadow values (dV[·], group shadow_value)
- Deprecate
expectations: as modeller-facing primitive; use E_y(·) inside the mover (expectation location)
- Use slot indices
[-1,0,+1] in stage mode (with defensive aliasing [1]≡[+1])
- Allow one extra mapping level in movers:
mover: {subeq_label: | ...} (no deeper nesting in v0.1)
- Record shock timing (
information_timing) to justify measurability/shift validation
Christopher Carroll and Akshay Shanker — repository in development, please do not cite.