Related
Issue: [[20260122-discount-stage-as-period-terminal-stage|CDC #11: discount stage as period-terminal stage]]
Parent spec: [[spec_0.1h-periods-nests|spec 0.1h — periods and nests]]
Syntax rules: [[05-periods-models|0.4 Periods and models]], [[02-stage-structure-and-timing|0.2 Stage structure and timing]]
Connector spec: [[spec_0.1lA-connector-unification|spec 0.1lA — connector unification]] (discount stage connects via identity connector)
Theory: [[periods-nests-theory|Composition as twister (foundation)]], [[theoretical-propositions|Theoretical propositions (contraction conditions)]]
Examples:
- [[port_stage|port-with-shocks: port_stage.yaml]] — currently β = 1
- [[cons_stage|port-with-shocks: cons_stage.yaml]] — currently β < 1 (will become β = 1)
- [[modular-examples-port-able_port-with-shocks|Unified: port-able stage examples]]
- [[modular-examples-cons_port-with-shocks|Unified: cons stage examples]]
Spec 0.1hA — Discount stage as period-terminal stage¶
1. Problem¶
Time discounting (β) is currently bundled into whichever stage carries the reward function. In the cons-port architecture, the cons stage has β < 1 while the port stage has β = 1. This creates an asymmetry: a period with only a port stage cannot express inter-temporal discounting, because no stage carries β.
This limits composability. With three basic stage types (cons, port, discount), we should be able to form any combination:
| Period type | Stages (proposed) | Currently possible? |
|---|---|---|
| cons only | cons → disc | Yes (β bundled in cons) |
| port → cons | port → cons → disc | Yes (β bundled in cons) |
| cons → port | cons → port → disc | Yes (β bundled in cons) |
| port only | port → disc | No — no stage carries β |
2. Decision¶
Introduce a dedicated discount stage (disc) that appears as the terminal stage in every period. This stage:
- Has no choice variable (control space is empty)
- Has no shocks (exogenous is trivial)
- Has zero stage reward: \(r = 0\)
- Applies the period's time discount factor: \(\beta < 1\)
- Has identity transitions: arrival state = decision state = continuation state
Its Bellman equation is:
The discount stage scales the continuation value by β and passes the state through unchanged. It produces no policy, no optimization, no expectation.
3. Impact on existing stages¶
With discounting extracted, all "economic" stages become β = 1:
| Stage | Before | After |
|---|---|---|
| cons | β < 1, r = u(c) | β = 1, r = u(c) |
| port | β = 1, r = 0 | β = 1, r = 0 (unchanged) |
| disc (new) | — | β < 1, r = 0 |
Economic stages focus purely on their content (optimization, shocks, rewards). The discount stage is the sole bearer of β.
4. Stage YAML¶
name: discount_stage
stage_type: adc-stage
symbols:
# The discount stage inherits the period's state space.
# The specific state variables are determined by the
# preceding stage's continuation interface via the connector.
parameters: [β]
equations:
# Identity transitions (state passes through)
arvl_to_dcsn_transition: |
# identity — arrival state = decision state
dcsn_to_cntn_transition: |
# identity — decision state = continuation state
# Backward mover: pure discounting
cntn_to_dcsn_mover:
Bellman: |
V = β * V[>]
Note
The discount stage's state variables are not declared in the stage YAML itself — they are inherited from the preceding stage's continuation interface via the within-period connector (which is identity, since the discount stage doesn't rename anything). This is consistent with the modularity principle in [[spec_0.1lA-connector-unification|spec 0.1lA]]: the stage declares its equations, and the assembly determines the wiring.
5. Period composition (with :=: connectors)¶
Using the interleaved connector syntax from [[spec_0.1lA-connector-unification|spec 0.1lA]]:
# Port-cons period (the common case)
sequence:
- port_stage
- connector:
- m :=: m # port continuation → cons arrival (identity)
- cons_stage
- connector:
- a :=: a # cons continuation → disc arrival (identity)
- discount_stage
Since all connectors to the discount stage are identity, they can be omitted:
The port-only period that was previously impossible:
6. Impact on value function composition¶
The discount factor moves from inside the cons stage's Bellman equation to a separate multiplicative step:
Before (β inside cons): $$ \mathrm{v}{\mathrm{cons}}(m) = \max_c \bigl{ u(c) + \beta \, \mathrm{v}(m - c) \bigr} $$
After (β in disc stage): $$ \mathrm{v}{\mathrm{cons}}(m) = \max_c \bigl{ u(c) + \mathrm{v}(m - c) \bigr}, \qquad \mathrm{v}}{\mathrm{disc}}(a) = \beta \, \mathrm{v}(a) $$
Composing these two stages recovers the same equation: \(\mathrm{v}_{\mathrm{cons}}(m) = \max_c \{ u(c) + \beta \, \mathrm{v}_{\succ}(m - c) \}\).
7. Contraction conditions¶
The [[theoretical-propositions|theoretical propositions]] document already states that contraction conditions apply at the period level (the product of stage β values must satisfy \(0 < \beta_{\mathrm{period}} < 1\)). With the discount stage, this simplifies: only the disc stage has \(\beta < 1\), so the period-level condition is equivalent to requiring the disc stage's β ∈ (0, 1).
8. Methodization¶
The discount stage requires minimal methodization — no expectation, no grid, no maximization. A bare entry suffices:
stage: discount_stage
methods:
- on: cntn_to_dcsn_mover
schemes:
- scheme: bellman_backward
method: !scale
- on: cntn_to_dcsn_mover.Bellman
schemes: []
- on: arvl_to_dcsn_transition
schemes: []
- on: dcsn_to_cntn_transition
schemes: []
The !scale method signals to the whisperer that this mover is a pure scalar multiplication — no optimization, no interpolation, no grid.
9. Acceptance criteria¶
- [ ]
discount_stage.yamlcreated inpackages/dolo/examples/models/doloplus/port-with-shocks/library/ - [ ]
discount_stage_methods.ymlcreated alongside it - [ ] Existing cons stage YAML updated: β removed from stage (moved to calibration of disc)
- [ ] Period builder scripts updated to append discount stage as terminal
- [ ] Port-only period demonstrated as a test case
- [ ] [[05-periods-models]] updated with discount stage examples
- [ ] [[20260122-discount-stage-as-period-terminal-stage|CDC #11]] marked resolved