dolo-plus spec_0.1 — open ambiguities (working notes)¶
This file records open ambiguities that matter for spec_0.1/* and should be resolved (or explicitly deferred) before we lock down the v0.1 version.
2. “Shift across perches” is doing two different jobs (semantic measurability vs representation trick)¶
What the current rule says¶
The shift rule says:
- you may shift a variable across perches only if it is measurable w.r.t. the target perch information set.
What the motivating example is¶
The motivating example is:
- allow
c[+1]for EGM because the policy is represented on the continuation grid.
Why this is ambiguous¶
These are not the same thing:
- “Measurable w.r.t. \( \mathcal{F}_{+1} \)” is a semantic statement about random variables / information sets.
- “Represent policy on continuation grid” is a representation / methodization statement (how you store/parameterize the function numerically), not a semantic measurability claim.
EGM is full of these “representation shifts”: you compute today’s c but index/parameterize it by a (post-decision state). That’s not “c happens at +1”; it’s “c is parameterized on the +1 grid”.
Why this matters¶
If we keep measurability as the only rule for interpreting perch shifts, we’ll hit contradictions as soon as:
- the mapping from \(x[0]\) to \(x[+1]\) is not invertible, or
- the control isn’t recoverable from \(x[+1]\), or
- we want to allow “EGM-style” objects that are fundamentally solver artifacts.
Minimal deconfliction (without rewriting everything)¶
Make an explicit distinction in the spec between:
- Perch evaluation (semantic): “this object is defined / measurable at perch \(i\)”
- Perch representation (numerical): “this object is represented on the grid associated with perch \(i\)”
Then define c[+1] to mean representation shift, not semantic shift, at least in v0.1.
Concretely:
- Keep measurability as the gatekeeper for semantic shifts (if we need them later).
- For EGM-style, define
c[+1]as a request: “store/construct the policy using continuation coordinates.”
This aligns with the two-layer SYM/T core idea: the meaning map \( \Upsilon \) shouldn’t depend on EGM representation choices; that lives in \( \rho \) / methodization.
3. Parameter declaration shape in dolo-plus SYM (label-keyed vs name-keyed)¶
This ambiguity is about whether dolo-plus SYM parameter declarations should follow the Foundations label → declaration-string pattern, or a more Dolo-compatible name → decorators pattern.
Option A — label-keyed “full declaration string” (Foundations-style)¶
Example (key is the label; value includes the symbol name):
Pros:
- closest to Foundations:
"discount factor": β @in (0,1)(label carried in the YAML key). - very readable for humans; labels are first-class.
Cons:
- downstream code must always parse the value string to recover the bare symbol name (
β) safely. - easy to accidentally let the full string leak into the “name” path unless normalization is strict.
- harder to provide a legacy “names-only” view without extra parsing.
Option B — name-keyed decorator payload (dolo-plus-compatibility style)¶
Example (key is the bare symbol name; value is decorator-only payload):
Pros:
- keeps the canonical symbol name (
β) explicit and stable (good for calibration lookup and old Dolo compilation paths). - decorator payload is small; full declaration string can be reconstructed as
β + " " + decorator.
Cons:
- label like “discount_rate” is not carried by default (unless we add an explicit label mechanism).
Open question:
- In dolo-plus v0.1, do we want
symbols.parameterskeyed by labels (Option A) or keyed by bare names (Option B)?
4. Whether symbols should be a new class (SymbolsDict)¶
Status: Unresolved (implementation exists, design needs confirmation)
Current implementation¶
SymbolsDict is a new class that extends dict and provides dual access:
# Legacy access (vanilla Dolo compatibility)
symbols['parameters'] # -> ['β', 'γ', 'r']
# Structured access (dolo-plus mode)
symbols.decls['parameters']['β'] # -> SymbolDecl object
symbols.decls['parameters']['β'].value # -> 0.96 (after calibration)
symbols.decls['parameters']['β'].domain # -> ('interval', 'open', 0.0, 1.0)
Why this is ambiguous¶
The current approach inherits from dict to maintain backwards compatibility, but this creates questions:
-
Is inheritance the right pattern? Dolo code uses
symbolsas a plain dict extensively. Inheriting fromdictworks, but it's unclear if this is the cleanest long-term design. -
Where should
.declslive? Currently.declsis an attribute onSymbolsDict. Alternatives: - Separate object:
model.symbol_declsalongsidemodel.symbols - Method:
model.get_symbol_decl('parameters', 'β') -
Keep as-is:
model.symbols.decls['parameters']['β'] -
Should
SymbolDeclbe mutable? Currently it's a mutable dataclass (.valueis set after calibration). Should it be immutable with a separate calibrated view?
Options¶
- Keep as-is:
SymbolsDictextendsdict, provides.declsattribute - Wrapper pattern: Keep
symbolsas plain dict, attach structured view via separate attribute on Model - Full replacement: Make
symbolsa proper class with explicit methods for both views (breaking change)
Related code¶
dolo/compiler/symbols.py:SymbolsDict,SymbolDecl,DecoratorAppdolo/compiler/model.py:SymbolicModel.symbolsproperty
5. Do labelled sub-equations imply branching fan-out? (dcsn_to_cntn_*)¶
This ambiguity is about how to interpret named sub-equations (YAML mappings) when they appear under forward-transition keys, especially in branching stages.
The intended idea (fan-out via labels)¶
If a stage’s continuation is branch-keyed (e.g. poststates.own, poststates.rent), then it is tempting to allow:
equations.dcsn_to_cntn_transitionas a mapping keyed by those same labels
and interpret the label → equation blocks as fan-out branches (multiple dcsn→cntn kernels), rather than as “just a named set of equations”.
Why this is ambiguous¶
We already use labelled sub-equations for a different purpose:
- In mover blocks like
cntn_to_dcsn_mover, labels (Bellman,InvEuler, …) represent different functional operators / computations on the same continuation value function, not branching.
So “subequations = fan-out” is not a valid global rule: backward induction often computes multiple objects from the same \(V^{>}\) even in non-branching stages.
Minimal resolution rule (proposed)¶
Treat labelled sub-equations under forward transitions as branch fan-out only when:
- the stage is
kind: branching, and - the sub-equation keys match the declared continuation-perch labels (
poststates.{label}), and - each labelled block writes only to fields in its corresponding continuation perch.
Otherwise, treat labelled sub-equations as ordinary named components (not branches).
Pointers:
docs/development/dolo-plus-impl/spec_0.1l-branching.md§3.2 (branch transitions) and §11.2 (parsing rules).