PO.ID.Exact.DTR

Identification for dynamic treatment regimes: sequential exchangeability and the g-formula.

Setup 20 core · 7 supporting This file provides the general finite-horizon potential-outcome setup for dynamic treatment regimes. ★ PODTRSystem★ regimeTarget_mem_iff

Dynamic Treatment Regime Setup

This file provides the general finite-horizon potential-outcome setup for dynamic treatment regimes. It defines stagewise states, treatments, regimes, sequential assumptions, and observable adjusted functionals used by dynamic backdoor identification theorems.

The setup allows heterogeneous state types across stages and a common treatment value space across stages. Sequential exchangeability and overlap are stated for each treatment sequence and stage.

The main public objects are PODTRSystem, treatment-sequence regimes regimeUpTo and regime, counterfactuals Y_of and S_of, history bundles, the assumption bundle Assumptions, the backward-recursive regression innerReg, and the estimands dtrEffect and adjustedDtr.

structure PODTRSystem reviewed
Causalean.PO

A finite-horizon dynamic treatment-regime system packages the variables for sequential potential-outcome identification: a stage-indexed state history observed before each treatment, the treatment chosen at each stage whose value space is identified with a common treatment alphabet across stages, and a terminal outcome whose value space is identified with the real line, subject to the state nodes being pairwise distinct across stages, the treatment nodes being pairwise distinct across stages, and no state, treatment, or outcome node coinciding with another.

Definition (Lean source)
P :
n :
δ :
Type
γ :
Fin n → Type
∀ k, MeasurableSpace (γ k)
Stage-`k` state variable `Sₖ` (history-dependent covariates observed before the stage-`k` treatment is assigned), valued in the stage's type `γ k`.
S :
∀ k : Fin n, POVar P (γ k)
Stage-`k` treatment node `Dₖ`, given as an index into the ambient system's variable set `P.V`.
D :
Fin n → P.V
The terminal outcome node `Y` (a variable of the ambient system).
Y :
P.V
Each treatment node `Dₖ` has value space measurably equivalent to the common treatment type `δ` (treatment alphabet is the same across stages).
hDmeas :
∀ k : Fin n, P.X (D k) ≃ᵐ δ
The outcome node `Y` has value space measurably equivalent to `ℝ`.
hYreal :
P.X Y ≃ᵐ ℝ
The state nodes are distinct across stages (the map `k ↦ (S k).v` is injective).
distinctSS :
∀ k l : Fin n
if
(S k).v = (S l).v
then
k = l
The treatment nodes are distinct across stages.
distinctDD :
No state node coincides with any treatment node.
distinctSD :
∀ k l : Fin n, (S k).v ≠ D l
No state node coincides with the outcome node.
distinctSY :
∀ k : Fin n, (S k).v ≠ Y
No treatment node coincides with the outcome node.
distinctDY :
∀ k : Fin n, D k ≠ Y
Causalean.PO.PODTRSystem · Causalean/PO/ID/Exact/DTR/Setup.lean:53 · uses POSystem
def dVar reviewed
Causalean.PO.PODTRSystem

The treatment at a stage is packaged as a potential-outcome variable with the common treatment value space.

Definition (Lean source)
def dVar (S : PODTRSystem P n δ γ) (k : Fin n) : POVar P δ := ⟨S.D k, S.hDmeas k⟩
def yVar reviewed
Causalean.PO.PODTRSystem

The terminal outcome is packaged as a real-valued potential-outcome variable.

Definition (Lean source)
def yVar (S : PODTRSystem P n δ γ) : POVar P ℝ := ⟨S.Y, S.hYreal⟩
def regimeTarget reviewed
Causalean.PO.PODTRSystem

The regime target set contains the treatment nodes before the stage cutoff.

Definition (Lean source)
def regimeTarget (S : PODTRSystem P n δ γ) : ℕ → Finset P.V | 0 => ∅ | k + 1 => if h : k < n then insert (S.D ⟨k, h⟩) (S.regimeTarget k) else S.regimeTarget k
Causalean.PO.PODTRSystem.regimeTarget · Causalean/PO/ID/Exact/DTR/Setup.lean:119 · uses PODTRSystem , POSystem
lemma regimeTarget_mem_iff reviewed
Causalean.PO.PODTRSystem

For a dynamic-treatment-regime system S, a variable belongs to the regime target built up to stage k if and only if it is the treatment node of some earlier stage i < k.

Formal statement
S :
PODTRSystem P n δ γ
∀ (k : ℕ) (_ : k ≤ n) (v : P.V),
v ∈ S.regimeTarget k
↔ ∃ i : Fin n, i.val < k ∧ v = S.D i | 0, _, v => by simp [regimeTarget] | k
+ 1, h, v => by have hk : k < n
Proof (Lean source)
lemma regimeTarget_mem_iff (S : PODTRSystem P n δ γ) : ∀ (k : ℕ) (_ : k ≤ n) (v : P.V), v ∈ S.regimeTarget k ↔ ∃ i : Fin n, i.val < k ∧ v = S.D i | 0, _, v => by simp [regimeTarget] | k + 1, h, v => by have hk : k < n := h simp only [regimeTarget, hk, ↓reduceDIte, Finset.mem_insert] constructor · rintro (rfl | hmem) · exact ⟨⟨k, hk⟩, Nat.lt_succ_self _, rfl⟩ · rcases (S.regimeTarget_mem_iff k (le_of_lt hk) v).mp hmem with ⟨i, hi, rfl⟩ exact ⟨i, Nat.lt_succ_of_lt hi, rfl⟩ · rintro ⟨i, hi, rfl⟩ rcases Nat.lt_succ_iff_lt_or_eq.mp hi with hi' | hi' · exact inr ((S.regimeTarget_mem_iff k (le_of_lt hk) _).mpr ⟨i, hi', rfl⟩) · left have : (⟨k, hk⟩ : Fin n) = i := by apply Fin.ext; simp [hi'] rw [this]
Causalean.PO.PODTRSystem.regimeTarget_mem_iff · Causalean/PO/ID/Exact/DTR/Setup.lean:129 · uses PODTRSystem , regimeTarget , POSystem
def regimeUpToAux reviewed
Causalean.PO.PODTRSystem

Mutual-recursive definition of the regime together with a proof that its target equals regimeTarget.

Definition (Lean source)
noncomputable def regimeUpToAux (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : (k : ℕ) → k ≤ n → { r : Regime P.V P.X // r.target = S.regimeTarget k } | 0, _ => ⟨Regime.empty, by simp [regimeTarget, Regime.empty]⟩ | k + 1, h => have hk : k < n := h let rec_pair := S.regimeUpToAux dbar k (le_of_lt hk) let r_rec : Regime P.V P.X := rec_pair.1 have hrec : r_rec.target = S.regimeTarget k := rec_pair.2 let v := S.D ⟨k, hk⟩ have hv_not : v ∉ r_rec.target := by rw [hrec] intro hmem rcases (S.regimeTarget_mem_iff k (le_of_lt hk) _).mp hmem with ⟨i, hi, heq⟩ have hFin : (⟨k, hk⟩ : Fin n) = i := S.distinctDD heq have hval : (k : ℕ) = i.val := by have := congrArg val hFin simpa using this omega let r_new := Regime.sqcup (Regime.single v ((S.hDmeas ⟨k, hk⟩).symm (dbar ⟨k, hk⟩))) r_rec (Regime.single_disjoint_of_not_mem _ _ hv_not) ⟨r_new, by show r_new.target = S.regimeTarget (k + 1) simp only [r_new, Regime.sqcup_target, Regime.single_target, regimeTarget, hk, ↓reduceDIte] rw [hrec] ext w simp [Finset.mem_insert, v]⟩
def regimeUpTo reviewed
Causalean.PO.PODTRSystem

The partial regime fixes treatments before the stage cutoff to a chosen treatment sequence.

Definition (Lean source)
noncomputable def regimeUpTo (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) (k : ℕ) (h : k ≤ n) : Regime P.V P.X := (S.regimeUpToAux dbar k h).1
def regime reviewed
Causalean.PO.PODTRSystem

The full treatment regime fixes every stage's treatment to the chosen treatment sequence.

Definition (Lean source)
noncomputable def regime (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : Regime P.V P.X := S.regimeUpTo dbar n (le_refl n)
def Y_of reviewed
Causalean.PO.PODTRSystem

The terminal counterfactual outcome evaluates the outcome under the full treatment regime.

Definition (Lean source)
noncomputable def Y_of (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : P.Ω → ℝ := S.yVar.cf (S.regime dbar)
def S_of reviewed
Causalean.PO.PODTRSystem

The stage counterfactual state evaluates the state under the earlier treatment interventions.

Definition (Lean source)
noncomputable def S_of (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) (k : Fin n) : P.Ω → γ k := (S.S k).cf (S.regimeUpTo dbar k.val (le_of_lt k.isLt))
def factualD reviewed
Causalean.PO.PODTRSystem

The factual treatment at a stage is the observed treatment value at that stage.

Definition (Lean source)
noncomputable def factualD (S : PODTRSystem P n δ γ) (k : Fin n) : P.Ω → δ := (S.dVar k).factual
Causalean.PO.PODTRSystem.factualD · Causalean/PO/ID/Exact/DTR/Setup.lean:219 · uses PODTRSystem , POSystem
def factualY reviewed
Causalean.PO.PODTRSystem

The factual outcome is the observed terminal outcome.

Definition (Lean source)
noncomputable def factualY (S : PODTRSystem P n δ γ) : P.Ω → ℝ := S.yVar.factual
Causalean.PO.PODTRSystem.factualY · Causalean/PO/ID/Exact/DTR/Setup.lean:223 · uses PODTRSystem , POSystem
def factualS reviewed
Causalean.PO.PODTRSystem

The factual state at a stage is the observed state value at that stage.

Definition (Lean source)
noncomputable def factualS (S : PODTRSystem P n δ γ) (k : Fin n) : P.Ω → γ k := (S.S k).factual
Causalean.PO.PODTRSystem.factualS · Causalean/PO/ID/Exact/DTR/Setup.lean:227 · uses PODTRSystem , POSystem
def indD reviewed
Causalean.PO.PODTRSystem

Joint indicator 1_{D 0 = dbar 0 ∧ … ∧ D (k-1) = dbar (k-1)}.

Definition (Lean source)
noncomputable def indD (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ℕ → P.Ω → ℝ | 0 => fun _ => 1 | k + 1 => fun ω => if h : k < n then S.indD dbar k ω * (S.dVar ⟨k, h⟩).indicator (dbar ⟨k, h⟩) ω else S.indD dbar k ω
def historyBundle reviewed
Causalean.PO.PODTRSystem

A history bundle collects the observed state and treatment history available just before a selected stage, ending with the current state.

Definition (Lean source)
noncomputable def historyBundle (S : PODTRSystem P n δ γ) : (k : ℕ) → k < n → POCFBundle P | 0, h => POCFBundle.cons (RegimedVar.ofFactual (S.S ⟨0, h⟩)) (POCFBundle.nil P) | k + 1, h => POCFBundle.cons (RegimedVar.ofFactual (S.S ⟨k + 1, h⟩)) <| POCFBundle.cons (RegimedVar.ofFactual (S.dVar ⟨k, lt_of_succ_lt h⟩)) <| S.historyBundle k (lt_of_succ_lt h)
def cfYBundle reviewed
Causalean.PO.PODTRSystem

Singleton CF bundle containing just Y(dbar) — used for the per-sequence exchangeability statement.

Definition (Lean source)
noncomputable def cfYBundle (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : POCFBundle P := POCFBundle.cons (⟨S.yVar, S.regime dbar⟩ : RegimedVar P ℝ) (POCFBundle.nil P)
structure Assumptions reviewed
Causalean.PO.PODTRSystem

Sequential backdoor assumptions for dynamic-treatment-regime identification at a general horizon n: potential-outcome consistency for the ambient system; per-sequence sequential exchangeability, i.e. at each stage the treatment is conditionally independent of the counterfactual terminal outcome under the treatment sequence given the history observed up to that stage; pointwise positivity of the stagewise propensity given the same history, almost surely; and integrability of the counterfactual terminal outcome under every treatment sequence together with integrability of the factual terminal outcome.

Definition (Lean source)
consistency :
P.Consistency
Per-sequence sequential exchangeability.
exch :
∀ (dbar : Fin n → δ) (k : Fin n),
P.CondIndepCFBundle (RegimedVar.ofFactual (S.dVar k)) (S.cfYBundle dbar) (S.historyBundle k.val k.isLt) P.μ
Pointwise (a.s.) positivity of stagewise propensities.
overlap :
∀ (dbar : Fin n → δ) (k : Fin n),
∀ᵐ ω ∂P.μ,
0 < (S.historyBundle k.val k.isLt).condExpGiven ((S.dVar k).indicator (dbar k)) P.μ ω
integrable_Y :
∀ dbar : Fin n → δ, Integrable (S.Y_of dbar) P.μ
integrable_factualY :
Integrable S.factualY P.μ
Causalean.PO.PODTRSystem.Assumptions · Causalean/PO/ID/Exact/DTR/Setup.lean:309 · uses PODTRSystem , POSystem
def innerReg reviewed
Causalean.PO.PODTRSystem

The adjusted dynamic-treatment-regime regression is computed by backward recursion through the observed treatment and state history, with the zero-horizon case defined to be zero.

Definition (Lean source)
noncomputable def innerReg (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ℕ → P.Ω → ℝ | 0 => fun ω => if h : 0 < n then (S.historyBundle (n - 1) (sub_lt h one_pos)).condExpGiven (fun ω' => S.factualY ω' * S.indD dbar n ω') P.μ ω / (S.historyBundle (n - 1) (sub_lt h one_pos)).condExpGiven (S.indD dbar n) P.μ ω else 0 | j + 1 => fun ω => if h : j + 1 < n then let histIdx : ℕ := n - j - 2 have hhist : histIdx < n := by change n - j - 2 < n; omega let stage : Fin n := ⟨histIdx, hhist⟩ (S.historyBundle histIdx hhist).condExpGiven (fun ω' => S.innerReg dbar j ω' * (S.dVar stage).indicator (dbar stage) ω') P.μ ω / (S.historyBundle histIdx hhist).condExpGiven ((S.dVar stage).indicator (dbar stage)) P.μ ω else S.innerReg dbar j ω
Causalean.PO.PODTRSystem.innerReg · Causalean/PO/ID/Exact/DTR/Setup.lean:344 · uses PODTRSystem , POSystem
def dtrEffect reviewed
Causalean.PO.PODTRSystem

Mean potential outcome E[Y(dbar)]. Single counterfactual mean.

Definition (Lean source)
noncomputable def dtrEffect (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ℝ := ∫ ω, S.Y_of dbar ω ∂P.μ
Causalean.PO.PODTRSystem.dtrEffect · Causalean/PO/ID/Exact/DTR/Setup.lean:389 · uses PODTRSystem , POSystem
def adjustedDtr reviewed
Causalean.PO.PODTRSystem

Adjusted DTR functional (observable side). Integrates the outermost ratio innerReg dbar (n - 1) — which conditions on historyBundle 0 = (S 0,) — against P.μ. For n = 0 this is 0.

Definition (Lean source)
noncomputable def adjustedDtr (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ℝ := if 0 < n then ∫ ω, S.innerReg dbar (n - 1) ω ∂P.μ else 0
Causalean.PO.PODTRSystem.adjustedDtr · Causalean/PO/ID/Exact/DTR/Setup.lean:393 · uses PODTRSystem , POSystem
7 supporting declarations (lemmas, instances)
Helpers 2 core · 16 supporting This file provides auxiliary measurability, integrability, and sigma-algebra comparison lemmas for the general finite-horizon dynamic treatment regime proofs. ★ indD_factor_split

Dynamic Treatment Regime Helpers

This file provides auxiliary measurability, integrability, and sigma-algebra comparison lemmas for the general finite-horizon dynamic treatment regime proofs. These helpers support the backward-induction and final identification arguments but are split out because they are shared across DTR files.

Important public lemmas include historyBundle_sigma_mono, indD_eq_indicator_event, stronglyMeasurable_indD_sigma_history, factualAgrees_regime, indD_mul_Y_integrable, measurable_innerReg, and yVar_notMem_regime.

def hb_step_proj reviewed
Causalean.PO.PODTRSystem

Projection from the stage-(k+1) joint value down to the stage-k joint value. Drops the fresh (S (k+1), D k) pair and keeps the history prefix.

Definition (Lean source)
noncomputable def hb_step_proj (S : PODTRSystem P n δ γ) (k : ℕ) (h : k + 1 < n) : (∀ i, (S.historyBundle (k+1) h).type i) → (∀ j, (S.historyBundle k (lt_of_succ_lt h)).type j) := fun f j => f j.succ.succ
lemma indD_factor_split reviewed
Causalean.PO.PODTRSystem

For any stage k within the horizon n, the indicator that a unit's observed treatment path matches the regime dbar through stage k+1 factors as the indicator through stage k times the indicator that the observed treatment at stage k equals dbar's value at stage k: indD dbar (k+1) = indD dbar k · 1_{D k = dbar k}.

Formal statement
S :
PODTRSystem P n δ γ
dbar :
Fin n → δ
k :
hk :
k < n
S.indD dbar (k+1) = fun ω => S.indD dbar k ω * (S.dVar ⟨k, hk⟩).indicator (dbar ⟨k, hk⟩) ω
Proof (Lean source)
lemma indD_factor_split (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) (k : ℕ) (hk : k < n) : S.indD dbar (k+1) = fun ω => S.indD dbar k ω * (S.dVar ⟨k, hk⟩).indicator (dbar ⟨k, hk⟩) ω := by funext ω change (if h' : k < n then S.indD dbar k ω * (S.dVar ⟨k, h'⟩).indicator (dbar ⟨k, h'⟩) ω else S.indD dbar k ω) = _ simp [hk]
16 supporting declarations (lemmas, instances)
  • measurable_hb_step_proj lemma — The projection from a stage's extended history to the previous history is measurable.
    S :
    PODTRSystem P n δ γ
    k :
    h :
    k + 1 < n
    Measurable (S.hb_step_proj k h)
    Proof (Lean source)
    lemma measurable_hb_step_proj (S : PODTRSystem P n δ γ) (k : ℕ) (h : k + 1 < n) : Measurable (S.hb_step_proj k h) := by apply measurable_pi_lambda intro j -- Instance search no longer unfolds `historyBundle (k+1)` to see that its -- index type is `Fin (… + 1 + 1)`, so supply the coordinate measurable-space -- family explicitly. let _ : ∀ i : Fin ((S.historyBundle k (lt_of_succ_lt h)).n + 1 + 1), MeasurableSpace ((S.historyBundle (k + 1) h).type i) := fun i => (S.historyBundle (k + 1) h).inst i exact measurable_pi_apply j.succ.succ
    Causalean.PO.PODTRSystem.measurable_hb_step_proj · Causalean/PO/ID/Exact/DTR/Helpers.lean:51
  • hb_jointValue_step_eq lemma — Key algebraic identity: the stage-k joint value factors through the stage-(k+1) joint value via hb_step_proj.
    S :
    PODTRSystem P n δ γ
    k :
    h :
    k + 1 < n
    (S.historyBundle k (lt_of_succ_lt h)).jointValue
    = S.hb_step_proj k h ∘ (S.historyBundle (k+1) h).jointValue
    Proof (Lean source)
    lemma hb_jointValue_step_eq (S : PODTRSystem P n δ γ) (k : ℕ) (h : k + 1 < n) : (S.historyBundle k (lt_of_succ_lt h)).jointValue = S.hb_step_proj k h ∘ (S.historyBundle (k+1) h).jointValue := by funext ω j rfl
    Causalean.PO.PODTRSystem.hb_jointValue_step_eq · Causalean/PO/ID/Exact/DTR/Helpers.lean:64
  • historyBundle_sigma_mono_step lemma — One-step σ-algebra inclusion: σ(history k) ≤ σ(history (k+1)).
    S :
    PODTRSystem P n δ γ
    k :
    h :
    k + 1 < n
    (S.historyBundle k (lt_of_succ_lt h)).sigma ≤ (S.historyBundle (k+1) h).sigma
    Proof (Lean source)
    lemma historyBundle_sigma_mono_step (S : PODTRSystem P n δ γ) (k : ℕ) (h : k + 1 < n) : (S.historyBundle k (lt_of_succ_lt h)).sigma ≤ (S.historyBundle (k+1) h).sigma := by change comap (S.historyBundle k (lt_of_succ_lt h)).jointValue inferInstancecomap (S.historyBundle (k+1) h).jointValue inferInstance rw [S.hb_jointValue_step_eq k h, ← MeasurableSpace.comap_comp] exact MeasurableSpace.comap_mono (S.measurable_hb_step_proj k h).comap_le
    Causalean.PO.PODTRSystem.historyBundle_sigma_mono_step · Causalean/PO/ID/Exact/DTR/Helpers.lean:72
  • historyBundle_sigma_mono lemma — Iterated σ-algebra monotonicity: σ(history j) ≤ σ(history k) for j ≤ k.
    S :
    PODTRSystem P n δ γ
    j k :
    hjk :
    j ≤ k
    hk :
    k < n
    (S.historyBundle j (lt_of_le_of_lt hjk hk)).sigma ≤ (S.historyBundle k hk).sigma
    Proof (Lean source)
    lemma historyBundle_sigma_mono (S : PODTRSystem P n δ γ) (j k : ℕ) (hjk : j ≤ k) (hk : k < n) : (S.historyBundle j (lt_of_le_of_lt hjk hk)).sigma ≤ (S.historyBundle k hk).sigma := by induction k with | zero => interval_cases j exact le_refl _ | succ k ih => rcases Nat.lt_or_ge j (k + 1) with hlt | hge · have hjk' : j ≤ k := Nat.lt_succ_iff.mp hlt have hkn : k < n := lt_of_succ_lt hk exact (ih hjk' hkn).trans (S.historyBundle_sigma_mono_step k hk) · have hjeq : j = k + 1 := le_antisymm hjk hge subst hjeq exact le_refl _
    Causalean.PO.PODTRSystem.historyBundle_sigma_mono · Causalean/PO/ID/Exact/DTR/Helpers.lean:83
  • indD_eq_zero_or_one lemma — indD dbar k ω ∈ {0, 1} for every ω and every k.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    ∀ (k : ℕ) (ω : P.Ω),
    S.indD dbar k ω
    = 0 ∨ S.indD dbar k ω = 1 | 0, _ => inr rfl | k
    + 1, ω
    => by unfold indD by_cases hk : k < n · simp only [hk, ↓reduceDIte] rcases indD_eq_zero_or_one S dbar k ω with h | h · left; simp [h] · rcases (S.dVar ⟨k, hk⟩).indicator_eq_one_or_zero (dbar ⟨k, hk⟩) ω with h' | h' · right; simp [h, h'] · left; simp [h, h'] · simp only [hk, ↓reduceDIte] exact indD_eq_zero_or_one S dbar k ω
    Proof (Lean source)
    lemma indD_eq_zero_or_one (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ∀ (k : ℕ) (ω : P.Ω), S.indD dbar k ω = 0 ∨ S.indD dbar k ω = 1 | 0, _ => inr rfl | k + 1, ω => by unfold indD by_cases hk : k < n · simp only [hk, ↓reduceDIte] rcases indD_eq_zero_or_one S dbar k ω with h | h · left; simp [h] · rcases (S.dVar ⟨k, hk⟩).indicator_eq_one_or_zero (dbar ⟨k, hk⟩) ω with h' | h' · right; simp [h, h'] · left; simp [h, h'] · simp only [hk, ↓reduceDIte] exact indD_eq_zero_or_one S dbar k ω
    Causalean.PO.PODTRSystem.indD_eq_zero_or_one · Causalean/PO/ID/Exact/DTR/Helpers.lean:103
  • indD_integrable lemma — indD dbar k is bounded by 1, hence integrable for finite μ.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    k :
    Integrable (S.indD dbar k) P.μ
    Proof (Lean source)
    lemma indD_integrable (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) (k : ℕ) [IsFiniteMeasure P.μ] : Integrable (S.indD dbar k) P.μ := by refine Integrable.of_bound (S.measurable_indD dbar k).aestronglyMeasurable 1 (Filter.Eventually.of_forall ?_) intro ω rcases S.indD_eq_zero_or_one dbar k ω with h | h <;> simp [h]
    Causalean.PO.PODTRSystem.indD_integrable · Causalean/PO/ID/Exact/DTR/Helpers.lean:119
  • indD_eq_indicator_event lemma — Event expression for indD: as a set-indicator of the agreement event.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    ∀ (k : ℕ) (_ : k ≤ n),
    S.indD dbar k
    = ({ω | ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i}).indicator (fun _ => (1 : ℝ)) | 0, _ => by funext ω simp [indD] | k
    + 1, h => by have hk : k < n
    Proof (Lean source)
    lemma indD_eq_indicator_event (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ∀ (k : ℕ) (_ : k ≤ n), S.indD dbar k = ({ω | ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i}).indicator (fun _ => (1 : ℝ)) | 0, _ => by funext ω simp [indD] | k + 1, h => by have hk : k < n := h funext ω have hrec := indD_eq_indicator_event S dbar k (le_of_lt hk) -- Rewrite indD dbar (k+1) ω in terms of indD dbar k ω * indicator. have hstep : S.indD dbar (k+1) ω = S.indD dbar k ω * (S.dVar ⟨k, hk⟩).indicator (dbar ⟨k, hk⟩) ω := by change (if h' : k < n then S.indD dbar k ω * (S.dVar ⟨k, h'⟩).indicator (dbar ⟨k, h'⟩) ω else S.indD dbar k ω) = _ simp [hk] rw [hstep] rw [show S.indD dbar k = _ from hrec] by_cases hall : ∀ i : Fin n, i.val < k + 1 → S.factualD i ω = dbar i · have hprefix : ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i := fun i hi => hall i (Nat.lt_succ_of_lt hi) have hnew : S.factualD ⟨k, hk⟩ ω = dbar ⟨k, hk⟩ := hall ⟨k, hk⟩ (Nat.lt_succ_self _) have hmem : ω ∈ {ω | ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i} := hprefix have hmem' : ω ∈ {ω | ∀ i : Fin n, i.val < k + 1 → S.factualD i ω = dbar i} := hall rw [Set.indicator_of_mem hmem, Set.indicator_of_mem hmem'] rw [(S.dVar ⟨k, hk⟩).indicator_apply_eq_one hnew] ring · have hnmem' : ω ∉ {ω | ∀ i : Fin n, i.val < k + 1 → S.factualD i ω = dbar i} := hall rw [Set.indicator_of_notMem hnmem'] by_cases hprefix : ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i · have hnew : S.factualD ⟨k, hk⟩ ω ≠ dbar ⟨k, hk⟩ := by intro hn apply hall intro i hi rcases Nat.lt_succ_iff_lt_or_eq.mp hi with hi' | hi' · exact hprefix i hi' · have : i = ⟨k, hk⟩ := Fin.ext (by simpa using hi') rw [this]; exact hn have hmem : ω ∈ {ω | ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i} := hprefix rw [Set.indicator_of_mem hmem] rw [(S.dVar ⟨k, hk⟩).indicator_apply_eq_zero hnew] ring · have hnmem : ω ∉ {ω | ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i} := hprefix rw [Set.indicator_of_notMem hnmem] ring
    Causalean.PO.PODTRSystem.indD_eq_indicator_event · Causalean/PO/ID/Exact/DTR/Helpers.lean:128
  • measurable_factualS_sigma_history lemma — factualS k' is (historyBundle m).sigma-measurable for k'.val ≤ m.
    S :
    PODTRSystem P n δ γ
    m :
    hm :
    m < n
    k' :
    Fin n
    hk' :
    k'.val ≤ m
    Measurable[(S.historyBundle m hm).sigma] (S.factualS k')
    Proof (Lean source)
    lemma measurable_factualS_sigma_history (S : PODTRSystem P n δ γ) (m : ℕ) (hm : m < n) (k' : Fin n) (hk' : k'.val ≤ m) : Measurable[(S.historyBundle m hm).sigma] (S.factualS k') := by induction m with | zero => have hkv : k'.val = 0 := Nat.le_zero.mp hk' have hkeq : k' = ⟨0, hm⟩ := Fin.ext (by simp [hkv]) subst hkeq intro s hs refine ⟨(fun f : ∀ i, (S.historyBundle 0 hm).type i => f ⟨0, Nat.zero_lt_succ 0⟩) ⁻¹' s, ?_, ?_⟩ · exact measurable_pi_apply _ hs · rfl | succ m ih => rcases Nat.lt_or_ge k'.val (m + 1) with hlt | hge · have hkm : k'.val ≤ m := Nat.lt_succ_iff.mp hlt have hmn : m < n := lt_of_succ_lt hm have hrec := ih hmn hkm -- Upgrade via σ-algebra monotonicity. intro s hs exact S.historyBundle_sigma_mono_step m hm _ (hrec hs) · have hkeq : k'.val = m + 1 := le_antisymm hk' hge have hkfin : k' = ⟨m + 1, hm⟩ := Fin.ext hkeq subst hkfin intro s hs refine ⟨(fun f : ∀ i, (S.historyBundle (m+1) hm).type i => f ⟨0, Nat.zero_lt_succ _⟩) ⁻¹' s, ?_, ?_⟩ · exact measurable_pi_apply _ hs · rfl
    Causalean.PO.PODTRSystem.measurable_factualS_sigma_history · Causalean/PO/ID/Exact/DTR/Helpers.lean:212
  • measurable_factualD_sigma_history lemma — factualD k' is (historyBundle m).sigma-measurable for k'.val < m.
    S :
    PODTRSystem P n δ γ
    m :
    hm :
    m < n
    k' :
    Fin n
    hk' :
    k'.val < m
    Measurable[(S.historyBundle m hm).sigma] (S.factualD k')
    Proof (Lean source)
    lemma measurable_factualD_sigma_history (S : PODTRSystem P n δ γ) (m : ℕ) (hm : m < n) (k' : Fin n) (hk' : k'.val < m) : Measurable[(S.historyBundle m hm).sigma] (S.factualD k') := by induction m with | zero => exact absurd hk' (Nat.not_lt_zero _) | succ m ih => rcases Nat.lt_or_ge k'.val m with hlt | hge · have hmn : m < n := Nat.lt_of_succ_lt hm intro s hs exact S.historyBundle_sigma_mono_step m hm _ ((ih hmn hlt) hs) · have hkeq : k'.val = m := by omega have hmlt : m < n := Nat.lt_of_succ_lt hm have hkfin : k' = ⟨m, hmlt⟩ := Fin.ext hkeq intro s hs -- index 1 in historyBundle (m+1) — use a Fin literal. let i1 : Fin ((S.historyBundle (m+1) hm).n) := ⟨1, by -- The length of historyBundle (m+1) is (historyBundle m).n + 1 + 1 ≥ 2. change 1 < (S.historyBundle m hmlt).n + 1 + 1 omega⟩ refine ⟨(fun f : ∀ i, (S.historyBundle (m+1) hm).type i => f i1) ⁻¹' s, ?_, ?_⟩ · exact measurable_pi_apply _ hs · rw [hkfin]; rfl
    Causalean.PO.PODTRSystem.measurable_factualD_sigma_history · Causalean/PO/ID/Exact/DTR/Helpers.lean:243
  • stronglyMeasurable_indicator_dVar_sigma_history lemma — The real-valued indicator dVar ⟨k', hk⟩.indicator (dbar ⟨k', hk⟩) is (historyBundle m).sigma-strongly-measurable for k' < m.
    S :
    PODTRSystem P n δ γ
    m :
    hm :
    m < n
    k' :
    Fin n
    hk' :
    k'.val < m
    x :
    δ
    StronglyMeasurable[(S.historyBundle m hm).sigma] ((S.dVar k').indicator x)
    Proof (Lean source)
    lemma stronglyMeasurable_indicator_dVar_sigma_history (S : PODTRSystem P n δ γ) (m : ℕ) (hm : m < n) (k' : Fin n) (hk' : k'.val < m) (x : δ) : StronglyMeasurable[(S.historyBundle m hm).sigma] ((S.dVar k').indicator x) := by have hfmeas := S.measurable_factualD_sigma_history m hm k' hk' have hev : MeasurableSet[(S.historyBundle m hm).sigma] ((S.dVar k').event x) := hfmeas (MeasurableSet.singleton x) have hmeas : Measurable[(S.historyBundle m hm).sigma] ((S.dVar k').indicator x) := by unfold POVar.indicator exact measurable_const.indicator hev exact hmeas.stronglyMeasurable
    Causalean.PO.PODTRSystem.stronglyMeasurable_indicator_dVar_sigma_history · Causalean/PO/ID/Exact/DTR/Helpers.lean:268
  • stronglyMeasurable_indD_sigma_history lemma — The joint-agreement indicator indD dbar m' is (historyBundle m).sigma-strongly-measurable for m' ≤ m.
    S :
    PODTRSystem P n δ γ
    m :
    hm :
    m < n
    dbar :
    Fin n → δ
    ∀ (m' : ℕ) (_ : m' ≤ m),
    StronglyMeasurable[(S.historyBundle m hm).sigma] (S.indD dbar m') | 0, _
    => by unfold indD exact stronglyMeasurable_const | m' + 1, h => by have hm' : m' < n
    Proof (Lean source)
    lemma stronglyMeasurable_indD_sigma_history (S : PODTRSystem P n δ γ) (m : ℕ) (hm : m < n) (dbar : Fin n → δ) : ∀ (m' : ℕ) (_ : m' ≤ m), StronglyMeasurable[(S.historyBundle m hm).sigma] (S.indD dbar m') | 0, _ => by unfold indD exact stronglyMeasurable_const | m' + 1, h => by have hm' : m' < n := lt_of_lt_of_le h (le_of_lt hm) have hrec := stronglyMeasurable_indD_sigma_history S m hm dbar m' (le_of_succ_le h) have hmlt : m' < m := h have hind := S.stronglyMeasurable_indicator_dVar_sigma_history m hm ⟨m', hm'⟩ hmlt (dbar ⟨m', hm'⟩) -- `indD (m'+1) = indD m' * indicator`. have heq : S.indD dbar (m' + 1) = fun ω => S.indD dbar m' ω * (S.dVar ⟨m', hm'⟩).indicator (dbar ⟨m', hm'⟩) ω := S.indD_factor_split dbar m' hm' rw [heq] -- `StronglyMeasurable` closed under mul. exact hrec.mul hind
    Causalean.PO.PODTRSystem.stronglyMeasurable_indD_sigma_history · Causalean/PO/ID/Exact/DTR/Helpers.lean:284
  • factualAgrees_regimeUpTo lemma — Helper: for each k ≤ n, FactualAgrees for regimeUpTo dbar k holds on the event "factualD i = dbar i for all i.val < k".
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    ∀ (k : ℕ) (h : k ≤ n) (ω : P.Ω)
    if
    (∀ i : Fin n, i.val < k → S.factualD i ω = dbar i)
    then
    P.FactualAgrees (S.regimeUpTo dbar k h) ω | 0, _, ω, _
    => by change P.FactualAgrees (S.regimeUpToAux dbar 0 (by exact zero_le n)).1 ω unfold regimeUpToAux exact POSystem.factualAgrees_empty ω | k
    + 1, h, ω, hall => by have hk : k < n
    Proof (Lean source)
    lemma factualAgrees_regimeUpTo (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ∀ (k : ℕ) (h : k ≤ n) (ω : P.Ω), (∀ i : Fin n, i.val < k → S.factualD i ω = dbar i) → P.FactualAgrees (S.regimeUpTo dbar k h) ω | 0, _, ω, _ => by change P.FactualAgrees (S.regimeUpToAux dbar 0 (by exact zero_le n)).1 ω unfold regimeUpToAux exact POSystem.factualAgrees_empty ω | k + 1, h, ω, hall => by have hk : k < n := h have hprefix : ∀ i : Fin n, i.val < k → S.factualD i ω = dbar i := fun i hi => hall i (Nat.lt_succ_of_lt hi) have hnew : S.factualD ⟨k, hk⟩ ω = dbar ⟨k, hk⟩ := hall ⟨k, hk⟩ (Nat.lt_succ_self _) have hrec := factualAgrees_regimeUpTo S dbar k (le_of_lt hk) ω hprefix -- Unfold regimeUpTo at k+1 to a sqcup. change P.FactualAgrees (S.regimeUpToAux dbar (k+1) h).1 ω unfold regimeUpToAux simp only apply POSystem.factualAgrees_sqcup · exact (S.dVar ⟨k, hk⟩).factualAgrees_single (dbar ⟨k, hk⟩) hnew · -- hrec is about S.regimeUpTo dbar k _ = (S.regimeUpToAux dbar k _).1. exact hrec
    Causalean.PO.PODTRSystem.factualAgrees_regimeUpTo · Causalean/PO/ID/Exact/DTR/Helpers.lean:310
  • factualAgrees_regime lemma — General multi-target consistency: every ω in the full agreement event factually agrees with S.regime dbar.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    ∀ ω ∈ {ω | ∀ i : Fin n, S.factualD i ω = dbar i}, P.FactualAgrees (S.regime dbar) ω
    Proof (Lean source)
    lemma factualAgrees_regime (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ∀ ω ∈ {ω | ∀ i : Fin n, S.factualD i ω = dbar i}, P.FactualAgrees (S.regime dbar) ω := by intro ω hω exact S.factualAgrees_regimeUpTo dbar n (le_refl n) ω (fun i _ => hω i)
    Causalean.PO.PODTRSystem.factualAgrees_regime · Causalean/PO/ID/Exact/DTR/Helpers.lean:336
  • indD_mul_Y_integrable lemma — indD dbar k · Y(dbar) is integrable, bounded by |Y(dbar)|.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    k :
    hY :
    Integrable (S.Y_of dbar) P.μ
    Integrable (fun ω => S.indD dbar k ω * S.Y_of dbar ω) P.μ
    Proof (Lean source)
    lemma indD_mul_Y_integrable (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) (k : ℕ) (hY : Integrable (S.Y_of dbar) P.μ) : Integrable (fun ω => S.indD dbar k ω * S.Y_of dbar ω) P.μ := by refine hY.mono ((S.measurable_indD dbar k).mul (S.measurable_Y_of dbar)).aestronglyMeasurable ?_ refine Filter.Eventually.of_forall (fun ω => ?_) rcases S.indD_eq_zero_or_one dbar k ω with h | h <;> simp [h]
    Causalean.PO.PODTRSystem.indD_mul_Y_integrable · Causalean/PO/ID/Exact/DTR/Helpers.lean:346
  • measurable_innerReg lemma — innerReg dbar j is measurable for every j.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    ∀ j : ℕ,
    Measurable (S.innerReg dbar j) | 0
    => by unfold innerReg by_cases hn : 0 < n · simp only [hn, ↓reduceDIte] set B
    Proof (Lean source)
    lemma measurable_innerReg (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : ∀ j : ℕ, Measurable (S.innerReg dbar j) | 0 => by unfold innerReg by_cases hn : 0 < n · simp only [hn, ↓reduceDIte] set B := S.historyBundle (n-1) (sub_lt hn one_pos) have hN := (B.stronglyMeasurable_condExpGiven (μ := P.μ) (fun ω' => S.factualY ω' * S.indD dbar n ω')).measurable have hD := (B.stronglyMeasurable_condExpGiven (μ := P.μ) (S.indD dbar n)).measurable exact hN.div hD · simp only [hn, ↓reduceDIte] exact measurable_const | j + 1 => by unfold innerReg by_cases hj : j + 1 < n · simp only [hj, ↓reduceDIte] have hkk : n - j - 2 < n := by omega set kFin : Fin n := ⟨n - j - 2, hkk⟩ set ind_k : P.Ω → ℝ := (S.dVar kFin).indicator (dbar kFin) set B := S.historyBundle (n - j - 2) hkk have hN := (B.stronglyMeasurable_condExpGiven (μ := P.μ) (fun ω' => S.innerReg dbar j ω' * ind_k ω')).measurable have hD := (B.stronglyMeasurable_condExpGiven (μ := P.μ) ind_k).measurable exact hN.div hD · simp only [hj, ↓reduceDIte] exact S.measurable_innerReg dbar j
    Causalean.PO.PODTRSystem.measurable_innerReg · Causalean/PO/ID/Exact/DTR/Helpers.lean:357
  • yVar_notMem_regime lemma — The outcome node Y is not a target of S.regime dbar.
    S :
    PODTRSystem P n δ γ
    dbar :
    Fin n → δ
    S.yVar.v ∉ (S.regime dbar).target
    Proof (Lean source)
    lemma yVar_notMem_regime (S : PODTRSystem P n δ γ) (dbar : Fin n → δ) : S.yVar.v ∉ (S.regime dbar).target := by intro hmem have hmem' : S.yVar.v ∈ S.regimeTarget n := by rw [← S.regimeUpTo_target_eq dbar n (le_refl n)] exact hmem rcases (S.regimeTarget_mem_iff n (le_refl n) S.yVar.v).mp hmem' with ⟨i, _, heq⟩ exact (S.distinctDY i) heq.symm
    Causalean.PO.PODTRSystem.yVar_notMem_regime · Causalean/PO/ID/Exact/DTR/Helpers.lean:399
Induction 1 core · 1 supporting This file proves the base case and inductive step for the backward-induction identity behind general finite-horizon dynamic backdoor identification. ★ cdtr_base

Dynamic Treatment Regime Induction

This file proves the base case and inductive step for the backward-induction identity behind general finite-horizon dynamic backdoor identification. The identity connects the observable iterated conditional-expectation ratios to the conditional mean of the regime counterfactual outcome.

The public theorems cdtr_base and cdtr_step are the cancellation identities consumed by cdtr_iter, cdtr_backdoor, and dtr_backdoor in DTR/Main.lean.

theorem cdtr_base reviewed
Causalean.PO.PODTRSystem

Base case of the backward induction for a dynamic treatment regime. Under the dynamic-treatment-regime identification assumptions — consistency and stage-wise sequential exchangeability/overlap, provided the horizon n is positive, the depth-zero adjusted-regression functional, multiplied by the indicator that the observed treatment matches the target regime dbar through stage n-1, agrees almost everywhere with that same indicator multiplied by the conditional mean of the regime outcome given the treatment-and-covariate history through stage n-1.

Formal statement
S :
PODTRSystem P n δ γ
hA :
S.Assumptions
dbar :
Fin n → δ
hn :
0 < n
(fun ω => S.innerReg dbar 0 ω * S.indD dbar (n-1) ω)
=ᵐ[P.μ] (fun ω => S.indD dbar (n-1) ω * (S.historyBundle (n-1) (sub_lt hn one_pos)).condExpGiven (S.Y_of dbar) P.μ ω)
Proof (Lean source)
theorem cdtr_base [StandardBorelSpace P.Ω] [IsFiniteMeasure P.μ] (S : PODTRSystem P n δ γ) (hA : S.Assumptions) (dbar : Fin n → δ) (hn : 0 < n) : (fun ω => S.innerReg dbar 0 ω * S.indD dbar (n-1) ω) =ᵐ[P.μ] (fun ω => S.indD dbar (n-1) ω * (S.historyBundle (n-1) (Nat.sub_lt hn Nat.one_pos)).condExpGiven (S.Y_of dbar) P.μ ω) := by -- Abbreviations. set m : ℕ := n - 1 with hm_def have hm_lt : m < n := Nat.sub_lt hn Nat.one_pos have hm_succ : m + 1 = n := by omega -- Index for the last-stage treatment. set kLast : Fin n := ⟨m, hm_lt⟩ with hkLast_def have hB := S.historyBundle m hm_lt have hσ_le : (S.historyBundle m hm_lt).sigma ≤ (inferInstance : MeasurableSpace P.Ω) := (S.historyBundle m hm_lt).sigma_le -- Integrability prerequisites. have hYof_int : Integrable (S.Y_of dbar) P.μ := hA.integrable_Y dbar have hindD_n_int : Integrable (S.indD dbar n) P.μ := S.indD_integrable dbar n have hindD_m_int : Integrable (S.indD dbar m) P.μ := S.indD_integrable dbar m have hindLast_int : Integrable ((S.dVar kLast).indicator (dbar kLast)) P.μ := (S.dVar kLast).integrable_indicator (dbar kLast) (measurableSet_singleton _) have hYindD_int : Integrable (fun ω => S.factualY ω * S.indD dbar n ω) P.μ := by refine hA.integrable_factualY.mono (S.measurable_factualY.mul (S.measurable_indD dbar n)).aestronglyMeasurable ?_ refine Filter.Eventually.of_forall (fun ω => ?_) rcases S.indD_eq_zero_or_one dbar n ω with h | h <;> simp [h] have hYof_indD_int : Integrable (fun ω => S.Y_of dbar ω * S.indD dbar n ω) P.μ := (S.indD_mul_Y_integrable dbar n hYof_int).congr (Filter.Eventually.of_forall (fun ω => by ring)) have hYof_indLast_int : Integrable (fun ω => S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) P.μ := by exact (S.dVar kLast).integrable_mul_indicator (dbar kLast) (measurableSet_singleton _) hYof_int -- (a) Consistency: factualY · indD n =ᵐ Y_of · indD n. have hConsistency : (fun ω => S.factualY ω * S.indD dbar n ω) = (fun ω => S.Y_of dbar ω * S.indD dbar n ω) := by -- Multi-target consistency over the event {factualD i = dbar i for all i}. have h := POVar.factual_mul_indicator_eq_cf_mul_indicator hA.consistency S.yVar (S.regime dbar) (S.yVar_notMem_regime dbar) {ω | ∀ i : Fin n, S.factualD i ω = dbar i} (S.factualAgrees_regime dbar) -- Replace the set-indicator by `indD dbar n` using indD_eq_indicator_event. have hrewrite : S.indD dbar n = ({ω | ∀ i : Fin n, S.factualD i ω = dbar i}).indicator (fun _ => (1:ℝ)) := by have := S.indD_eq_indicator_event dbar n (le_refl n) -- Translate `i.val < n` to `True` (all `i : Fin n` satisfy `i.val < n`). have h_set_eq : ({ω | ∀ i : Fin n, i.val < n → S.factualD i ω = dbar i}) = {ω | ∀ i : Fin n, S.factualD i ω = dbar i} := by ext ω refine ⟨fun h i => h i i.isLt, fun h i _ => h i⟩ rw [this, h_set_eq] rw [hrewrite] exact h -- (b) Factorisation `indD n = indD m · (dVar kLast).indicator`. have hFactor : S.indD dbar n = fun ω => S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω := by funext ω -- Compute `S.indD dbar n ω` directly. Since `n = m + 1`, unfold. have h_eq : S.indD dbar n ω = S.indD dbar (m + 1) ω := by rw [hm_succ] rw [h_eq] -- `indD (m+1) ω = indD m ω * indicator ...`. have hsplit := congr_fun (S.indD_factor_split dbar m hm_lt) ω exact hsplit -- (c) Rewrite the numerator's integrand: -- `factualY · indD n = indD m · (Y_of · (dVar kLast).indicator)`. have hN_arg_eq : (fun ω => S.factualY ω * S.indD dbar n ω) = (fun ω => S.indD dbar m ω * (S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω)) := by rw [hConsistency, hFactor] funext ω; ring -- (d) Pull `indD m` out of the numerator condExp. have hN_pullout : (S.historyBundle m hm_lt).condExpGiven (fun ω => S.indD dbar m ω * (S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω)) P.μ =ᵐ[P.μ] (fun ω => S.indD dbar m ω * (S.historyBundle m hm_lt).condExpGiven (fun ω' => S.Y_of dbar ω' * (S.dVar kLast).indicator (dbar kLast) ω') P.μ ω) := by have hindD_m_sm : StronglyMeasurable[(S.historyBundle m hm_lt).sigma] (S.indD dbar m) := S.stronglyMeasurable_indD_sigma_history m hm_lt dbar m (le_refl m) -- product integrability have hprod_int : Integrable (S.indD dbar m * fun ω => S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) P.μ := by have heq : (S.indD dbar m * fun ω => S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) = fun ω => S.indD dbar m ω * (S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) := rfl rw [heq] have h_indD_Y_int : Integrable (fun ω => S.indD dbar m ω * S.Y_of dbar ω) P.μ := S.indD_mul_Y_integrable dbar m hYof_int have hmul := (S.dVar kLast).integrable_mul_indicator (dbar kLast) (measurableSet_singleton _) h_indD_Y_int exact hmul.congr (Filter.Eventually.of_forall (fun ω => by ring)) have hpull := (S.historyBundle m hm_lt).condExpGiven_mul_of_stronglyMeasurable_left (f := S.indD dbar m) (g := fun ω => S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) hindD_m_sm hprod_int hYof_indLast_int -- `hpull` has shape `condExp (indD m * _) =ᵐ indD m * condExp _`. filter_upwards [hpull] with ω hω exact hω -- (e) Stage-`(n-1)` exchangeability + condExp_mul_of_condIndep. -- Project `hA.exch dbar kLast` onto `Y_of dbar` coordinate of `cfYBundle`. -- Index 0 in cfYBundle = singleton of `Y(dbar)`. have hcfY_n : (S.cfYBundle dbar).n = 1 := rfl let i0 : Fin (S.cfYBundle dbar).n := ⟨0, by rw [hcfY_n]; exact Nat.one_pos⟩ -- The type at index 0 reduces to ℝ; supply the projection via a coercion. let ψ : (∀ i : Fin (S.cfYBundle dbar).n, (S.cfYBundle dbar).type i) → ℝ := fun f => (f i0 : ℝ) have hψ_meas : Measurable ψ := by -- `ψ = (· : (cfYBundle dbar).type i0 → ℝ) ∘ (eval i0)`. Both measurable. -- Type at i0 reduces to ℝ definitionally. change Measurable (fun f : (∀ i, (S.cfYBundle dbar).type i) => (f i0 : ℝ)) exact measurable_pi_apply i0 have hYof_eq_proj : S.Y_of dbar = ψ ∘ (S.cfYBundle dbar).jointValue := by funext ω; rfl have hCI : CondIndepFun (S.historyBundle m hm_lt).sigma hσ_le (S.factualD kLast) (S.Y_of dbar) P.μ := by have hproj := (hA.exch dbar kLast).project (ψ := ψ) hψ_meas rw [hYof_eq_proj] -- `hproj : CondIndepFun σ_le factualD (ψ ∘ jointValue) μ`. -- Here factualD = (dVar kLast).value (via ofFactual). exact hproj -- Use `condExp_mul_of_condIndep` with u := indicator of {dbar kLast}, v := id. let u : δ → ℝ := ({dbar kLast} : Set δ).indicator (fun _ => (1 : ℝ)) have hu_meas : Measurable u := measurable_const.indicator (MeasurableSet.singleton _) have hu_eq : (fun ω => u (S.factualD kLast ω)) = (S.dVar kLast).indicator (dbar kLast) := by funext ω unfold POVar.indicator by_cases h : S.factualD kLast ω = dbar kLast · have h1 : S.factualD kLast ω ∈ ({dbar kLast} : Set δ) := h have h2 : ω ∈ (S.dVar kLast).event (dbar kLast) := h rw [show u (S.factualD kLast ω) = (1 : ℝ) from Set.indicator_of_mem h1 _, Set.indicator_of_mem h2] · have h1 : S.factualD kLast ω ∉ ({dbar kLast} : Set δ) := h have h2 : ω ∉ (S.dVar kLast).event (dbar kLast) := h rw [show u (S.factualD kLast ω) = (0 : ℝ) from Set.indicator_of_notMem h1 _, Set.indicator_of_notMem h2] have huv_int : Integrable (fun ω => u (S.factualD kLast ω) * S.Y_of dbar ω) P.μ := by have hEq : (fun ω => u (S.factualD kLast ω) * S.Y_of dbar ω) = (fun ω => (S.dVar kLast).indicator (dbar kLast) ω * S.Y_of dbar ω) := by funext ω; rw [congr_fun hu_eq ω] rw [hEq] refine hYof_int.mono (((S.dVar kLast).measurable_indicator (dbar kLast) (measurableSet_singleton _)).mul (S.measurable_Y_of dbar)).aestronglyMeasurable ?_ refine Filter.Eventually.of_forall (fun ω => ?_) rcases (S.dVar kLast).indicator_eq_one_or_zero (dbar kLast) ω with h | h <;> simp [h] have hfact : P.μ[fun ω => u (S.factualD kLast ω) * S.Y_of dbar ω | (S.historyBundle m hm_lt).sigma] =ᵐ[P.μ] P.μ[fun ω => u (S.factualD kLast ω) | (S.historyBundle m hm_lt).sigma] * P.μ[fun ω => S.Y_of dbar ω | (S.historyBundle m hm_lt).sigma] := condExp_mul_of_condIndep (μ := P.μ) (m := (S.historyBundle m hm_lt).sigma) hσ_le (f := S.factualD kLast) (g := S.Y_of dbar) (S.measurable_factualD kLast) (S.measurable_Y_of dbar) hCI (u := u) (v := id) hu_meas measurable_id (by rw [hu_eq]; exact hindLast_int) hYof_int huv_int -- Reshape `hfact` into condExpGiven form. have hfact' : (S.historyBundle m hm_lt).condExpGiven (fun ω => S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) P.μ =ᵐ[P.μ] (fun ω => (S.historyBundle m hm_lt).condExpGiven ((S.dVar kLast).indicator (dbar kLast)) P.μ ω * (S.historyBundle m hm_lt).condExpGiven (S.Y_of dbar) P.μ ω) := by unfold POCFBundle.condExpGiven have hprod_rw : (fun ω => u (S.factualD kLast ω) * S.Y_of dbar ω) = (fun ω => S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω) := by funext ω; rw [congr_fun hu_eq ω]; ring rw [hprod_rw, hu_eq] at hfact filter_upwards [hfact] with ω hω simpa [Pi.mul_apply] using hω -- (f) Combine into the full numerator expression. have hNum_eq : (S.historyBundle m hm_lt).condExpGiven (fun ω => S.factualY ω * S.indD dbar n ω) P.μ =ᵐ[P.μ] (fun ω => S.indD dbar m ω * ((S.historyBundle m hm_lt).condExpGiven ((S.dVar kLast).indicator (dbar kLast)) P.μ ω * (S.historyBundle m hm_lt).condExpGiven (S.Y_of dbar) P.μ ω)) := by -- First rewrite the integrand. have hstep1 : (S.historyBundle m hm_lt).condExpGiven (fun ω => S.factualY ω * S.indD dbar n ω) P.μ = (S.historyBundle m hm_lt).condExpGiven (fun ω => S.indD dbar m ω * (S.Y_of dbar ω * (S.dVar kLast).indicator (dbar kLast) ω)) P.μ := by rw [hN_arg_eq] rw [hstep1] refine hN_pullout.trans ?_ filter_upwards [hfact'] with ω hω rw [hω] -- (g) Denominator side: condExp of indD n = indD m · (dVar kLast).indicator. have hD_pullout : (S.historyBundle m hm_lt).condExpGiven (S.indD dbar n) P.μ =ᵐ[P.μ] (fun ω => S.indD dbar m ω * (S.historyBundle m hm_lt).condExpGiven ((S.dVar kLast).indicator (dbar kLast)) P.μ ω) := by have hindD_m_sm : StronglyMeasurable[(S.historyBundle m hm_lt).sigma] (S.indD dbar m) := S.stronglyMeasurable_indD_sigma_history m hm_lt dbar m (le_refl m) have hprod_int : Integrable (S.indD dbar m * (S.dVar kLast).indicator (dbar kLast)) P.μ := by have heq : (S.indD dbar m * (S.dVar kLast).indicator (dbar kLast)) = fun ω => S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω := rfl rw [heq, ← hFactor] exact hindD_n_int have hpull := (S.historyBundle m hm_lt).condExpGiven_mul_of_stronglyMeasurable_left -- … truncated; follow the source link for the rest …
1 supporting declaration (lemmas, instances)
  • cdtr_step theorem — The induction step moves the dynamic-regime cancellation identity one stage outward.
    S :
    PODTRSystem P n δ γ
    hA :
    S.Assumptions
    dbar :
    Fin n → δ
    j :
    hj :
    j + 1 < n
    hk :
    n - j - 2 < n
    hIH_int :
    Integrable (S.innerReg dbar j) P.μ
    IH :
    (fun ω => S.innerReg dbar j ω * S.indD dbar (n - j - 1) ω)
    =ᵐ[P.μ] (fun ω => S.indD dbar (n - j - 1) ω * (S.historyBundle (n - j - 1) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω)
    (fun ω => S.innerReg dbar (j + 1) ω * S.indD dbar (n - j - 2) ω)
    =ᵐ[P.μ] (fun ω => S.indD dbar (n - j - 2) ω * (S.historyBundle (n - j - 2) hk).condExpGiven (S.Y_of dbar) P.μ ω)
    Proof (Lean source)
    theorem cdtr_step [StandardBorelSpace P.Ω] [IsFiniteMeasure P.μ] (S : PODTRSystem P n δ γ) (hA : S.Assumptions) (dbar : Fin n → δ) (j : ℕ) (hj : j + 1 < n) (hk : n - j - 2 < n) (hIH_int : Integrable (S.innerReg dbar j) P.μ) (IH : (fun ω => S.innerReg dbar j ω * S.indD dbar (n - j - 1) ω) =ᵐ[P.μ] (fun ω => S.indD dbar (n - j - 1) ω * (S.historyBundle (n - j - 1) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω)) : (fun ω => S.innerReg dbar (j + 1) ω * S.indD dbar (n - j - 2) ω) =ᵐ[P.μ] (fun ω => S.indD dbar (n - j - 2) ω * (S.historyBundle (n - j - 2) hk).condExpGiven (S.Y_of dbar) P.μ ω) := by -- Abbreviations. set k : ℕ := n - j - 2 with hk_def have hk1 : k + 1 < n := by omega set kFin : Fin n := ⟨k, hk⟩ with hkFin_def set ind_k : P.Ω → ℝ := (S.dVar kFin).indicator (dbar kFin) with hind_k_def -- σ-algebra inclusion σ_k ≤ σ_{k+1}. have hσk_le : (S.historyBundle k hk).sigma ≤ (inferInstance : MeasurableSpace P.Ω) := (S.historyBundle k hk).sigma_le have hσ_step : (S.historyBundle k hk).sigma ≤ (S.historyBundle (k+1) hk1).sigma := S.historyBundle_sigma_mono_step k hk1 -- Strong-measurability of `indD k` (σ_k) and `ind_k` (σ_{k+1}). have hindDk_sm : StronglyMeasurable[(S.historyBundle k hk).sigma] (S.indD dbar k) := S.stronglyMeasurable_indD_sigma_history k hk dbar k (le_refl k) have hindk_sm_k1 : StronglyMeasurable[(S.historyBundle (k+1) hk1).sigma] ind_k := S.stronglyMeasurable_indicator_dVar_sigma_history (k+1) hk1 kFin (Nat.lt_succ_self _) (dbar kFin) -- Integrability prerequisites. have hYof_int : Integrable (S.Y_of dbar) P.μ := hA.integrable_Y dbar have hindk_int : Integrable ind_k P.μ := (S.dVar kFin).integrable_indicator (dbar kFin) (measurableSet_singleton _) have hindDk1_int : Integrable (S.indD dbar (k+1)) P.μ := S.indD_integrable dbar (k+1) have hYof_indk_int : Integrable (fun ω => S.Y_of dbar ω * ind_k ω) P.μ := by dsimp [ind_k] exact (S.dVar kFin).integrable_mul_indicator (dbar kFin) (measurableSet_singleton _) hYof_int have hindk_Yof_int : Integrable (fun ω => ind_k ω * S.Y_of dbar ω) P.μ := hYof_indk_int.congr (Filter.Eventually.of_forall (fun ω => by ring)) -- `n - j - 1 = k + 1`. have hk1_idx : n - j - 1 = k + 1 := by omega -- Pointwise factor split: indD (k+1) = indD k · ind_k. have hFactor : S.indD dbar (k+1) = fun ω => S.indD dbar k ω * ind_k ω := S.indD_factor_split dbar k hk -- Integrability of `innerReg j · indD (k+1)`: derived from IH RHS being integrable. have hCondExpY_k1_int : Integrable ((S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ) P.μ := (S.historyBundle (k+1) hk1).integrable_condExpGiven _ have hRHS_IH_int : Integrable (fun ω => S.indD dbar (k+1) ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) P.μ := by refine hCondExpY_k1_int.mono ((S.measurable_indD dbar (k+1)).mul ((S.historyBundle (k+1) hk1).stronglyMeasurable_condExpGiven _).measurable ).aestronglyMeasurable ?_ refine Filter.Eventually.of_forall (fun ω => ?_) rcases S.indD_eq_zero_or_one dbar (k+1) ω with h | h <;> simp [h] -- Cast IH from `n - j - 1` to `k + 1`. have IH' : (fun ω => S.innerReg dbar j ω * S.indD dbar (k+1) ω) =ᵐ[P.μ] (fun ω => S.indD dbar (k+1) ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) := by -- The indices `n - j - 1` and `k + 1` are equal (`hk1_idx`); rewrite via -- a heterogeneous-eq cast on the historyBundle. have hHB_eq : HEq ((S.historyBundle (n - j - 1) (by omega : n - j - 1 < n)).condExpGiven (S.Y_of dbar) P.μ) ((S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ) := by congr 1 simp [hk1_idx] have hHB_eq' : (S.historyBundle (n - j - 1) (by omega : n - j - 1 < n)).condExpGiven (S.Y_of dbar) P.μ = (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ := eq_of_heq hHB_eq have hindDeq : S.indD dbar (n - j - 1) = S.indD dbar (k + 1) := by rw [hk1_idx] have := IH rw [hindDeq] at this refine this.trans ?_ refine Filter.Eventually.of_forall (fun ω => ?_) rw [hHB_eq'] have hinnerReg_indD_int : Integrable (fun ω => S.innerReg dbar j ω * S.indD dbar (k+1) ω) P.μ := hRHS_IH_int.congr IH'.symm -- ====== Master identity ===================================================== -- Prove: μ[innerReg j · indD (k+1) | σ_k] =ᵐ -- indD k · μ[ind_k | σ_k] · μ[Y_of | σ_k]. -- Path: -- (a) condExpGiven_congr_ae of IH'. -- (b) Rewrite RHS integrand: indD (k+1) · μ[Y|σ_{k+1}] = indD k · (ind_k · μ[Y|σ_{k+1}]). -- (c) Pull indD k (σ_k-meas, bounded) out. -- (d) Reverse pullout of ind_k on σ_{k+1}. -- (e) Tower σ_k ≤ σ_{k+1}. -- (f) Stage-k exch. -- ============================================================================ -- (a) Apply σ_k-CE to both sides of IH'. have hStepA : (S.historyBundle k hk).condExpGiven (fun ω => S.innerReg dbar j ω * S.indD dbar (k+1) ω) P.μ =ᵐ[P.μ] (S.historyBundle k hk).condExpGiven (fun ω => S.indD dbar (k+1) ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) P.μ := (S.historyBundle k hk).condExpGiven_congr_ae IH' -- (b) Rewrite: indD (k+1) · X = indD k · (ind_k · X). have hRewriteRHS : (fun ω => S.indD dbar (k+1) ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) = (fun ω => S.indD dbar k ω * (ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω)) := by funext ω rw [show S.indD dbar (k+1) ω = S.indD dbar k ω * ind_k ω from congr_fun hFactor ω] ring -- (c) Pull indD k (σ_k-meas) out of σ_k-CE. have hindk_CE_int : Integrable (fun ω => ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) P.μ := by dsimp [ind_k] have hmul := (S.dVar kFin).integrable_mul_indicator (dbar kFin) (measurableSet_singleton _) hCondExpY_k1_int exact hmul.congr (Filter.Eventually.of_forall (fun ω => by ring)) have hindDk_indk_CE_int : Integrable (S.indD dbar k * fun ω => ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) P.μ := by have hrw : (S.indD dbar k * fun ω => ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) = fun ω => S.indD dbar (k+1) ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω := by funext ω change S.indD dbar k ω * (ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) = _ rw [show S.indD dbar (k+1) ω = S.indD dbar k ω * ind_k ω from congr_fun hFactor ω] ring rw [hrw]; exact hRHS_IH_int have hPullIndDk : (S.historyBundle k hk).condExpGiven (fun ω => S.indD dbar k ω * (ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω)) P.μ =ᵐ[P.μ] (fun ω => S.indD dbar k ω * (S.historyBundle k hk).condExpGiven (fun ω' => ind_k ω' * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω') P.μ ω) := by have hpull := (S.historyBundle k hk).condExpGiven_mul_of_stronglyMeasurable_left (f := S.indD dbar k) (g := fun ω => ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) hindDk_sm hindDk_indk_CE_int hindk_CE_int filter_upwards [hpull] with ω hω exact hω -- (d) Reverse pullout of ind_k on σ_{k+1}. have hRevPull : (fun ω => ind_k ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) =ᵐ[P.μ] (S.historyBundle (k+1) hk1).condExpGiven (fun ω => ind_k ω * S.Y_of dbar ω) P.μ := by have hfwd := (S.historyBundle (k+1) hk1).condExpGiven_mul_of_stronglyMeasurable_left (f := ind_k) (g := S.Y_of dbar) hindk_sm_k1 hindk_Yof_int hYof_int filter_upwards [hfwd] with ω hω exact hω.symm -- (e) Tower σ_k ≤ σ_{k+1}. haveI : IsFiniteMeasure (P.μ.trim (S.historyBundle (k+1) hk1).sigma_le) := isFiniteMeasure_trim _ have hTower : (S.historyBundle k hk).condExpGiven ((S.historyBundle (k+1) hk1).condExpGiven (fun ω => ind_k ω * S.Y_of dbar ω) P.μ) P.μ =ᵐ[P.μ] (S.historyBundle k hk).condExpGiven (fun ω => ind_k ω * S.Y_of dbar ω) P.μ := by have h := (S.historyBundle (k+1) hk1).condExpGiven_tower_of_le (g := fun ω => ind_k ω * S.Y_of dbar ω) (μ := P.μ) (m := (S.historyBundle k hk).sigma) hσ_step simpa [POCFBundle.condExpGiven] using h -- (f) Stage-k exchangeability. have hcfY_n : (S.cfYBundle dbar).n = 1 := rfl let i0 : Fin (S.cfYBundle dbar).n := ⟨0, by rw [hcfY_n]; exact Nat.one_pos⟩ let ψ : (∀ i : Fin (S.cfYBundle dbar).n, (S.cfYBundle dbar).type i) → ℝ := fun f => (f i0 : ℝ) have hψ_meas : Measurable ψ := by change Measurable (fun f : (∀ i, (S.cfYBundle dbar).type i) => (f i0 : ℝ)) exact measurable_pi_apply i0 have hYof_eq_proj : S.Y_of dbar = ψ ∘ (S.cfYBundle dbar).jointValue := by funext ω; rfl have hCI : CondIndepFun (S.historyBundle k hk).sigma hσk_le (S.factualD kFin) (S.Y_of dbar) P.μ := by have hproj := (hA.exch dbar kFin).project (ψ := ψ) hψ_meas rw [hYof_eq_proj]; exact hproj let u : δ → ℝ := ({dbar kFin} : Set δ).indicator (fun _ => (1 : ℝ)) have hu_meas : Measurable u := measurable_const.indicator (MeasurableSet.singleton _) have hu_eq : (fun ω => u (S.factualD kFin ω)) = ind_k := by funext ω show u (S.factualD kFin ω) = ind_k ω by_cases h : S.factualD kFin ω = dbar kFin · have h1 : S.factualD kFin ω ∈ ({dbar kFin} : Set δ) := h have h2 : ω ∈ (S.dVar kFin).event (dbar kFin) := h rw [show u (S.factualD kFin ω) = (1 : ℝ) from Set.indicator_of_mem h1 _, show ind_k ω = (1 : ℝ) from (S.dVar kFin).indicator_apply_eq_one h2] · have h1 : S.factualD kFin ω ∉ ({dbar kFin} : Set δ) := h have h2 : ω ∉ (S.dVar kFin).event (dbar kFin) := h rw [show u (S.factualD kFin ω) = (0 : ℝ) from Set.indicator_of_notMem h1 _, show ind_k ω = (0 : ℝ) from (S.dVar kFin).indicator_apply_eq_zero h2] have huv_int : Integrable (fun ω => u (S.factualD kFin ω) * S.Y_of dbar ω) P.μ := by have hEq : (fun ω => u (S.factualD kFin ω) * S.Y_of dbar ω) = (fun ω => ind_k ω * S.Y_of dbar ω) := by funext ω; rw [congr_fun hu_eq ω] rw [hEq]; exact hindk_Yof_int have hfact : P.μ[fun ω => u (S.factualD kFin ω) * S.Y_of dbar ω | (S.historyBundle k hk).sigma] =ᵐ[P.μ] P.μ[fun ω => u (S.factualD kFin ω) | (S.historyBundle k hk).sigma] * P.μ[fun ω => S.Y_of dbar ω | (S.historyBundle k hk).sigma] := condExp_mul_of_condIndep (μ := P.μ) (m := (S.historyBundle k hk).sigma) hσk_le (f := S.factualD kFin) (g := S.Y_of dbar) (S.measurable_factualD kFin) (S.measurable_Y_of dbar) hCI (u := u) (v := id) hu_meas measurable_id (by rw [hu_eq]; exact hindk_int) hYof_int huv_int have hExch : (S.historyBundle k hk).condExpGiven (fun ω => ind_k ω * S.Y_of dbar ω) P.μ -- … truncated; follow the source link for the rest …
    Causalean.PO.PODTRSystem.cdtr_step · Causalean/PO/ID/Exact/DTR/Induction.lean:404
Main 2 core · 1 supporting This file proves the general finite-horizon dynamic-treatment-regime backdoor identification theorem. ★ cdtr_backdoor★ dtr_backdoor

Dynamic Treatment Regime Backdoor Identification

This file proves the general finite-horizon dynamic-treatment-regime backdoor identification theorem. It combines the base and inductive cancellation steps into a backward induction argument and then integrates the resulting conditional mean identity.

The exported theorem cdtr_iter records the full induction invariant, cdtr_backdoor gives the conditional mean identification, and dtr_backdoor identifies the mean potential outcome with the adjusted dynamic-regime functional.

theorem cdtr_backdoor reviewed
Causalean.PO.PODTRSystem

General-n CDTR backdoor identification. Under the dynamic-treatment-regime identification assumptions, for a positive horizon n, the σ(historyBundle 0)-conditional mean of Y(dbar) equals the outermost iterated-CE functional innerReg dbar (n - 1).

Formal statement
S :
PODTRSystem P n δ γ
hA :
S.Assumptions
dbar :
Fin n → δ
hn :
0 < n
(S.historyBundle 0 hn).condExpGiven (S.Y_of dbar) P.μ =ᵐ[P.μ] S.innerReg dbar (n - 1)
Proof (Lean source)
theorem cdtr_backdoor [StandardBorelSpace P.Ω] [IsFiniteMeasure P.μ] (S : PODTRSystem P n δ γ) (hA : S.Assumptions) (dbar : Fin n → δ) (hn : 0 < n) : (S.historyBundle 0 hn).condExpGiven (S.Y_of dbar) P.μ =ᵐ[P.μ] S.innerReg dbar (n - 1) := by -- Specialize cdtr_iter at j = n - 1. Note `n - 1 - (n - 1) = 0` and -- `S.indD dbar 0 = fun _ => 1` by definition. have hjlt : n - 1 < n := sub_lt hn one_pos have hiter := S.cdtr_iter hA dbar hn (n - 1) hjlt have hzero : n - 1 - (n - 1) = 0 := by omega simp only [hzero] at hiter -- After specialization: `innerReg (n-1) · indD 0 =ᵐ indD 0 · μ[Y_of|σ_0]`. -- Both `· indD 0` factors are `· 1` by definition, so the equality reduces. have hindD0 : S.indD dbar 0 = fun _ => (1 : ℝ) := rfl rw [hindD0] at hiter -- Now hiter : `(fun ω => innerReg (n-1) ω * 1) =ᵐ (fun ω => 1 * μ[Y|σ_0] ω)`. filter_upwards [hiter] with ω hω simp only [mul_one, one_mul] at hω exact hω.symm
theorem dtr_backdoor reviewed
Causalean.PO.PODTRSystem

General-n integrated DTR backdoor identification. Under the dynamic-treatment-regime identification assumptions, for a positive horizon n, the mean potential outcome E[Y(dbar)] equals the integral of the outermost adjusted functional innerReg dbar (n - 1).

Formal statement
S :
PODTRSystem P n δ γ
hA :
S.Assumptions
dbar :
Fin n → δ
hn :
0 < n
S.dtrEffect dbar = S.adjustedDtr dbar
Proof (Lean source)
theorem dtr_backdoor [StandardBorelSpace P.Ω] [IsFiniteMeasure P.μ] (S : PODTRSystem P n δ γ) (hA : S.Assumptions) (dbar : Fin n → δ) (hn : 0 < n) : S.dtrEffect dbar = S.adjustedDtr dbar := by unfold PODTRSystem.dtrEffect PODTRSystem.adjustedDtr -- adjustedDtr branches on `0 < n`; pick the positive branch. rw [if_pos hn] -- ∫ Y_of dbar = ∫ μ[Y_of dbar | σ_0] = ∫ innerReg (n-1). have hCE : ∫ ω, S.Y_of dbar ω ∂P.μ = ∫ ω, (S.historyBundle 0 hn).condExpGiven (S.Y_of dbar) P.μ ω ∂P.μ := by unfold POCFBundle.condExpGiven exact (MeasureTheory.integral_condExp (S.historyBundle 0 hn).sigma_le).symm rw [hCE] exact MeasureTheory.integral_congr_ae (S.cdtr_backdoor hA dbar hn)
1 supporting declaration (lemmas, instances)
  • cdtr_iter theorem — Backward-induction iterate combining cdtr_base (j = 0) with cdtr_step (j → j + 1). At depth j, asserts that innerReg dbar j multiplied by the partial indicator product indD dbar (n - 1 - j) agrees a.e. with the conditional expectation (historyBundle (n - 1 - j)).condExpGiven (Y_of dbar) multiplied by the same partial indicator.
    S :
    PODTRSystem P n δ γ
    hA :
    S.Assumptions
    dbar :
    Fin n → δ
    hn :
    0 < n
    ∀ j : ℕ
    if
    j < n
    then
    (fun ω => S.innerReg dbar j ω * S.indD dbar (n - 1 - j) ω)
    =ᵐ[P.μ] (fun ω => S.indD dbar (n - 1 - j) ω * (S.historyBundle (n - 1 - j) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω)
    Proof (Lean source)
    theorem cdtr_iter [StandardBorelSpace P.Ω] [IsFiniteMeasure P.μ] (S : PODTRSystem P n δ γ) (hA : S.Assumptions) (dbar : Fin n → δ) (hn : 0 < n) : ∀ j : ℕ, j < n → (fun ω => S.innerReg dbar j ω * S.indD dbar (n - 1 - j) ω) =ᵐ[P.μ] (fun ω => S.indD dbar (n - 1 - j) ω * (S.historyBundle (n - 1 - j) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω) := by intro j hj induction j with | zero => have h := S.cdtr_base hA dbar hn -- `cdtr_base` produces the j = 0 case with `n - 1` on the indD side; -- `n - 1 - 0 = n - 1`, so the two statements coincide. have heq : n - 1 - 0 = n - 1 := by omega simp only [heq] convert h using 3 | succ j ih => have hj' : j < n := Nat.lt_of_succ_lt hj have ih' := ih hj' -- `cdtr_step` consumes IH at depth j (with index `n - j - 1` on indD) -- and produces depth j+1 (with index `n - j - 2`). Bridge `n - 1 - j` -- ↔ `n - j - 1` and `n - 1 - (j + 1)` ↔ `n - j - 2`. have heq1 : n - 1 - j = n - j - 1 := by omega have heq2 : n - 1 - (j + 1) = n - j - 2 := by omega have hk : n - j - 2 < n := by omega -- Reshape ih' to match cdtr_step's IH-shape. have ihStep : (fun ω => S.innerReg dbar j ω * S.indD dbar (n - j - 1) ω) =ᵐ[P.μ] (fun ω => S.indD dbar (n - j - 1) ω * (S.historyBundle (n - j - 1) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω) := by have := ih' simp only [heq1] at this convert this using 2 have hjlt : j < n := Nat.lt_of_succ_lt hj have hIH_int : Integrable (S.innerReg dbar j) P.μ := (S.cdtr_strong hA dbar hn j hjlt).2 have hStep := S.cdtr_step hA dbar j hj hk hIH_int ihStep -- Reshape `hStep`'s conclusion to the goal indices. simp only [heq2] convert hStep using 2
    Causalean.PO.PODTRSystem.cdtr_iter · Causalean/PO/ID/Exact/DTR/Main.lean:45
Strong­Cancellation 1 core · 1 supporting This file proves the strengthened cancellation identity needed for finite-horizon dynamic-treatment-regime identification under pointwise overlap. ★ cdtr_strong

Dynamic Treatment Regime Strong Cancellation

This file proves the strengthened cancellation identity needed for finite-horizon dynamic-treatment-regime identification under pointwise overlap. The main theorem PODTRSystem.cdtr_strong carries two facts through the same backward induction: innerReg dbar j is almost surely the product of the partial treatment-regime indicator indD dbar (n - 1 - j) and the conditional expectation of Y_of dbar given the corresponding history bundle, and innerReg dbar j is integrable.

The derived lemma PODTRSystem.innerReg_integrable recovers the public integrability statement from this stronger a.e. identity. This avoids any uniform-overlap bound: after cancellation, integrability follows from a bounded indicator multiplying an integrable conditional expectation.

theorem cdtr_strong reviewed
Causalean.PO.PODTRSystem

Joint inductive invariant for the strengthened cancellation. Consider a dynamic-treatment-regime system for which the identifying assumption bundle holds, fix a positive number of decision stages, and fix a treatment history dbar. Then for every stage index j below the horizon, the partial regression term innerReg dbar j agrees almost surely with the product of the treatment-regime indicator at the mirrored stage n - 1 - j and the conditional expectation of the outcome given the history up to that stage, and this term is integrable.

Formal statement
S :
PODTRSystem P n δ γ
hA :
S.Assumptions
dbar :
Fin n → δ
hn :
0 < n
∀ j : ℕ
if
j < n
then
((S.innerReg dbar j) =ᵐ[P.μ] (fun ω => S.indD dbar (n - 1 - j) ω * (S.historyBundle (n - 1 - j) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω)) ∧
Integrable (S.innerReg dbar j) P.μ
Proof (Lean source)
theorem cdtr_strong [StandardBorelSpace P.Ω] [IsFiniteMeasure P.μ] (S : PODTRSystem P n δ γ) (hA : S.Assumptions) (dbar : Fin n → δ) (hn : 0 < n) : ∀ j : ℕ, j < n → ((S.innerReg dbar j) =ᵐ[P.μ] (fun ω => S.indD dbar (n - 1 - j) ω * (S.historyBundle (n - 1 - j) (by omega)).condExpGiven (S.Y_of dbar) P.μ ω)) ∧ Integrable (S.innerReg dbar j) P.μ := by intro j hj induction j with | zero => -- ============================================================ -- Base case (j = 0). Strengthen `cdtr_base` via vanishing. -- ============================================================ set m : ℕ := n - 1 with hm_def have hm_lt : m < n := Nat.sub_lt hn Nat.one_pos have hm_succ : m + 1 = n := by omega have hzero_idx : n - 1 - 0 = m := by omega set kLast : Fin n := ⟨m, hm_lt⟩ with hkLast_def -- Helper integrabilities. have hYof_int : Integrable (S.Y_of dbar) P.μ := hA.integrable_Y dbar have hindLast_int : Integrable ((S.dVar kLast).indicator (dbar kLast)) P.μ := (S.dVar kLast).integrable_indicator (dbar kLast) (measurableSet_singleton _) have hindD_n_int : Integrable (S.indD dbar n) P.μ := S.indD_integrable dbar n have hYindLast_int : Integrable (fun ω => S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) P.μ := by exact (S.dVar kLast).integrable_mul_indicator (dbar kLast) (measurableSet_singleton _) hA.integrable_factualY have hindD_m_sm : StronglyMeasurable[(S.historyBundle m hm_lt).sigma] (S.indD dbar m) := S.stronglyMeasurable_indD_sigma_history m hm_lt dbar m (le_refl m) -- Pointwise factorisation indD n = indD m * indicator. have hFactor : S.indD dbar n = fun ω => S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω := by funext ω have h_eq : S.indD dbar n ω = S.indD dbar (m + 1) ω := by rw [hm_succ] rw [h_eq] exact congr_fun (S.indD_factor_split dbar m hm_lt) ω -- Numerator pull-out: μ[factualY · indD n | σ_m] -- =ᵐ indD m · μ[factualY · ind_last | σ_m]. have hYind_int : Integrable (fun ω => S.factualY ω * S.indD dbar n ω) P.μ := by refine hA.integrable_factualY.mono (S.measurable_factualY.mul (S.measurable_indD dbar n)).aestronglyMeasurable ?_ refine Filter.Eventually.of_forall (fun ω => ?_) rcases S.indD_eq_zero_or_one dbar n ω with h | h <;> simp [h] have hN_pull : (S.historyBundle m hm_lt).condExpGiven (fun ω => S.factualY ω * S.indD dbar n ω) P.μ =ᵐ[P.μ] (fun ω => S.indD dbar m ω * (S.historyBundle m hm_lt).condExpGiven (fun ω' => S.factualY ω' * (S.dVar kLast).indicator (dbar kLast) ω') P.μ ω) := by have hprod_int : Integrable (S.indD dbar m * fun ω => S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) P.μ := by have heq : (S.indD dbar m * fun ω => S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) = fun ω => S.factualY ω * S.indD dbar n ω := by funext ω change S.indD dbar m ω * (S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) = _ rw [show S.indD dbar n ω = S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω from congr_fun hFactor ω] ring rw [heq]; exact hYind_int have hpull := (S.historyBundle m hm_lt).condExpGiven_mul_of_stronglyMeasurable_left (f := S.indD dbar m) (g := fun ω => S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) hindD_m_sm hprod_int hYindLast_int have heqfun : (S.historyBundle m hm_lt).condExpGiven (fun ω => S.factualY ω * S.indD dbar n ω) P.μ = (S.historyBundle m hm_lt).condExpGiven (fun ω => S.indD dbar m ω * (S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω)) P.μ := by congr 1 funext ω rw [show S.indD dbar n ω = S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω from congr_fun hFactor ω] ring rw [heqfun] have hpull' := (S.historyBundle m hm_lt).condExpGiven_mul_of_stronglyMeasurable_left (f := S.indD dbar m) (g := fun ω => S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) hindD_m_sm (by have heq : (S.indD dbar m * fun ω => S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) = fun ω => S.indD dbar m ω * (S.factualY ω * (S.dVar kLast).indicator (dbar kLast) ω) := rfl rw [heq] at hprod_int ⊢ exact hprod_int) hYindLast_int filter_upwards [hpull'] with ω hω exact hω -- Denominator pull-out: μ[indD n | σ_m] =ᵐ indD m · μ[ind_last | σ_m]. have hD_pull : (S.historyBundle m hm_lt).condExpGiven (S.indD dbar n) P.μ =ᵐ[P.μ] (fun ω => S.indD dbar m ω * (S.historyBundle m hm_lt).condExpGiven ((S.dVar kLast).indicator (dbar kLast)) P.μ ω) := by have hprod_indD_int : Integrable (S.indD dbar m * (S.dVar kLast).indicator (dbar kLast)) P.μ := by have heq : S.indD dbar m * (S.dVar kLast).indicator (dbar kLast) = fun ω => S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω := rfl rw [heq, ← hFactor]; exact hindD_n_int have hpull := (S.historyBundle m hm_lt).condExpGiven_mul_of_stronglyMeasurable_left (f := S.indD dbar m) (g := (S.dVar kLast).indicator (dbar kLast)) hindD_m_sm hprod_indD_int hindLast_int have heqfun : (S.historyBundle m hm_lt).condExpGiven (S.indD dbar n) P.μ = (S.historyBundle m hm_lt).condExpGiven (fun ω => S.indD dbar m ω * (S.dVar kLast).indicator (dbar kLast) ω) P.μ := by rw [hFactor] rw [heqfun] filter_upwards [hpull] with ω hω exact hω -- The strong identity at j = 0 (independent of cdtr_base). have hStrong0 : (S.innerReg dbar 0) =ᵐ[P.μ] (fun ω => S.indD dbar m ω * (S.historyBundle m hm_lt).condExpGiven (S.Y_of dbar) P.μ ω) := by have hCE_base := S.cdtr_base hA dbar hn filter_upwards [hCE_base, hN_pull, hD_pull, hA.overlap dbar kLast] with ω hCE hNω hDω hov -- innerReg 0 ω = N(ω)/D(ω) (definitionally). have h_inner : S.innerReg dbar 0 ω = (S.historyBundle m hm_lt).condExpGiven (fun ω' => S.factualY ω' * S.indD dbar n ω') P.μ ω / (S.historyBundle m hm_lt).condExpGiven (S.indD dbar n) P.μ ω := by change (if h : 0 < n then _ else _) = _ rw [dif_pos hn] rcases S.indD_eq_zero_or_one dbar m ω with h0 | h1 · -- indD m ω = 0: both N and D vanish. rw [h_inner, hNω, hDω, h0] simp · -- indD m ω = 1: cdtr_base provides the equality directly. -- hCE : innerReg 0 ω · indD m ω = indD m ω · μ[Y_of|σ_m] ω -- with indD m ω = 1, both sides simplify. rw [show S.indD dbar m ω = (1 : ℝ) from h1] at hCE simp only [mul_one, one_mul] at hCE rw [hCE, h1, one_mul] -- Now assemble the final pair. refine ⟨?_, ?_⟩ · -- Strong identity at index n - 1 - 0. Bridge `m = n - 1 - 0`. have hbridge : (S.historyBundle (n - 1 - 0) (by omega : n - 1 - 0 < n)).condExpGiven (S.Y_of dbar) P.μ = (S.historyBundle m hm_lt).condExpGiven (S.Y_of dbar) P.μ := by have h_heq : HEq ((S.historyBundle (n - 1 - 0) (by omega : n - 1 - 0 < n)).condExpGiven (S.Y_of dbar) P.μ) ((S.historyBundle m hm_lt).condExpGiven (S.Y_of dbar) P.μ) := by congr 1 exact eq_of_heq h_heq have hindD_eq : S.indD dbar (n - 1 - 0) = S.indD dbar m := by rw [hzero_idx] filter_upwards [hStrong0] with ω hω rw [hω, ← hindD_eq, ← hbridge] · -- Integrability from strong identity + RHS integrability. have hRHS := S.indD_mul_condExpY_integrable dbar m hm_lt exact hRHS.congr hStrong0.symm | succ j ih => -- ============================================================ -- Step (j → j + 1). We use `cdtr_step` for the weak form, then -- strengthen via vanishing of `innerReg (j+1)` on `{indD k = 0}`. -- ============================================================ have hj' : j < n := lt_of_succ_lt hj obtain ⟨ihStrong, ihInt⟩ := ih hj' set k : ℕ := n - j - 2 with hk_def have hk_lt : k < n := by omega have hk1 : k + 1 < n := by omega set kFin : Fin n := ⟨k, hk_lt⟩ with hkFin_def set ind_k : P.Ω → ℝ := (S.dVar kFin).indicator (dbar kFin) with hind_k_def have hk1_idx : n - j - 1 = k + 1 := by omega have hkstep_idx : n - 1 - (j + 1) = k := by omega have hk_idx_old : n - 1 - j = k + 1 := by omega have hk1_eq_kp1 : n - j - 1 = k + 1 := by omega -- Bridge the historyBundle proof argument via Nat equality. have hbridge_kp1 : (S.historyBundle (n - 1 - j) (by omega : n - 1 - j < n)).condExpGiven (S.Y_of dbar) P.μ = (S.historyBundle (k + 1) hk1).condExpGiven (S.Y_of dbar) P.μ := by have h_heq : HEq ((S.historyBundle (n - 1 - j) (by omega : n - 1 - j < n)).condExpGiven (S.Y_of dbar) P.μ) ((S.historyBundle (k + 1) hk1).condExpGiven (S.Y_of dbar) P.μ) := by congr 1; simp [hk_idx_old] exact eq_of_heq h_heq have hbridge_kp1' : (S.historyBundle (n - j - 1) (by omega : n - j - 1 < n)).condExpGiven (S.Y_of dbar) P.μ = (S.historyBundle (k + 1) hk1).condExpGiven (S.Y_of dbar) P.μ := by have h_heq : HEq ((S.historyBundle (n - j - 1) (by omega : n - j - 1 < n)).condExpGiven (S.Y_of dbar) P.μ) ((S.historyBundle (k + 1) hk1).condExpGiven (S.Y_of dbar) P.μ) := by congr 1; simp [hk1_eq_kp1] exact eq_of_heq h_heq have hindD_eq_old : S.indD dbar (n - 1 - j) = S.indD dbar (k + 1) := by rw [hk_idx_old] have hindD_eq_new : S.indD dbar (n - j - 1) = S.indD dbar (k + 1) := by rw [hk1_eq_kp1] -- Recover the strong IH at index k+1. have ihStrong' : (S.innerReg dbar j) =ᵐ[P.μ] (fun ω => S.indD dbar (k+1) ω * (S.historyBundle (k+1) hk1).condExpGiven (S.Y_of dbar) P.μ ω) := by filter_upwards [ihStrong] with ω hω rw [hω, ← hbridge_kp1, hindD_eq_old] -- Recover the weak IH (for `cdtr_step`). have ihWeak : (fun ω => S.innerReg dbar j ω * S.indD dbar (n - j - 1) ω) -- … truncated; follow the source link for the rest …
1 supporting declaration (lemmas, instances)