PO.ID.Exact.Heckman­Roy

The Heckman/Roy selection model: identification of treatment parameters under self-selection.

Setup 23 core · 9 supporting This file defines the potential-outcome data layer for the Heckman-Vytlacil generalized Roy instrumental-variables model. ★ POHeckmanRoySystem★ measurable_DofZ

Heckman-Roy IV Setup

This file defines the potential-outcome data layer for the Heckman-Vytlacil generalized Roy instrumental-variables model. It packages the instrument, treatment, outcome, latent selection rank, threshold-crossing assumptions, interval-complier event, and latent interval average treatment effect used by the Wald identification proof.

structure POHeckmanRoySystem reviewed
Causalean.PO

The Heckman–Vytlacil / generalized Roy instrumental-variable model in the potential-outcome framework, packaging an instrument, a binary treatment taken when a latent selection rank U falls below a propensity threshold p(Z) valued in [0,1], and a real outcome with potential outcomes Y(0) and Y(1), where the four nodes are pairwise distinct. This is the setup behind pairwise-Wald / LATE-type identification of treatment effects from instrument-induced variation in participation (def:po-iv-heckman-roy-system).

Definition (Lean source)
Z :
P.V
D :
P.V
Y :
P.V
Latent selection rank.
U :
P.V
hZ :
P.X Z ≃ᵐ α
hDbool :
P.X D ≃ᵐ Bool
hYreal :
P.X Y ≃ᵐ ℝ
hUreal :
P.X U ≃ᵐ ℝ
hZD :
Z ≠ D
hZY :
Z ≠ Y
hZU :
Z ≠ U
hDY :
D ≠ Y
hDU :
D ≠ U
hYU :
Y ≠ U
Propensity-score map `p : α → [0,1]`.
p :
α → ℝ
hp_mem :
∀ z, p z ∈ Icc (0:ℝ) 1
Causalean.PO.POHeckmanRoySystem · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:43 · uses POSystem
def zVar reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the instrument potential-outcome variable is its instrument node with its instrument-value representation.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
zVar S :
POVar P α
⟨S.Z, S.hZ⟩
def dVar reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the binary treatment potential-outcome variable is its treatment node with its binary representation.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
dVar S :
⟨S.D, S.hDbool⟩
def yVar reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the real-valued outcome potential-outcome variable is its outcome node with its real-valued representation.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
yVar S :
POVar P ℝ
⟨S.Y, S.hYreal⟩
def uVar reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the latent-rank potential-outcome variable is its latent selection-rank node with its real-valued representation.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
uVar S :
POVar P ℝ
⟨S.U, S.hUreal⟩
def instrumentRegime reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and an instrument value, the instrument intervention regime fixes the instrument to that value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
instrumentRegime S z :
Regime P.V P.X
Regime.single S.Z (S.hZ.symm z)
Causalean.PO.POHeckmanRoySystem.instrumentRegime · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:97 · uses POHeckmanRoySystem , POSystem , Regime
def treatmentRegime reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and a treatment value, the treatment intervention regime fixes treatment to that value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
d :
treatmentRegime S d :
Regime P.V P.X
Regime.single S.D (S.hDbool.symm d)
Causalean.PO.POHeckmanRoySystem.treatmentRegime · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:101 · uses POHeckmanRoySystem , POSystem , Regime
def DofZ reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and an instrument value, the potential treatment assigns each unit the treatment it would take under that instrument value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
DofZ S z :
P.Ω → Bool
S.dVar.cfUnder S.zVar z
def YofD reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and a treatment value, the potential outcome assigns each unit the outcome it would have under that treatment value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
d :
YofD S d :
P.Ω → ℝ
S.yVar.cfUnder S.dVar d
def factualZ reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the factual instrument assigns each unit its observed instrument value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
factualZ S :
P.Ω → α
S.zVar.factual
def factualD reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the factual treatment assigns each unit its observed binary treatment.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
factualD S :
P.Ω → Bool
S.dVar.factual
def factualY reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the factual outcome assigns each unit its observed real outcome.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
factualY S :
P.Ω → ℝ
S.yVar.factual
def factualU reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the factual latent selection rank assigns each unit its latent real-valued rank.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
factualU S :
P.Ω → ℝ
S.uVar.factual
def zEvent reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and an instrument value, the instrument event is the set of units whose observed instrument equals that value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
zEvent S z :
Set P.Ω
S.zVar.event z
def intervalComplierEvent reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and two instrument values, the interval-complier event is the set of units whose latent rank is strictly above the first propensity threshold and no greater than the second.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z₀ z₁ :
α
intervalComplierEvent S z₀ z₁ :
Set P.Ω
{ ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁ }
Causalean.PO.POHeckmanRoySystem.intervalComplierEvent · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:126 · uses POHeckmanRoySystem , POSystem
lemma measurable_DofZ reviewed
Causalean.PO.POHeckmanRoySystem

For a fixed instrument value z, the potential treatment D(z) is measurable.

Formal statement
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
Measurable (S.DofZ z)
Proof (Lean source)
@[fun_prop] lemma measurable_DofZ (z : α) : Measurable (S.DofZ z) := S.dVar.measurable_cfUnder S.zVar z
Causalean.PO.POHeckmanRoySystem.measurable_DofZ · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:132 · uses POHeckmanRoySystem , DofZ , POSystem
def YofDofZ reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and an instrument value, the outcome under the instrument-induced treatment assigns each unit its treated potential outcome if that instrument induces treatment and its untreated potential outcome otherwise.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
YofDofZ S z :
P.Ω → ℝ
fun ω => if S.DofZ z ω then S.YofD true ω else S.YofD false ω
def condExpDZ reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and an instrument value, the conditional treatment mean is the event-conditional mean of observed treatment among units with that instrument value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
condExpDZ S z :
eventCondExp P.μ (S.zEvent z) (fun ω => ((S.factualD ω).toNat : ℝ))
Causalean.PO.POHeckmanRoySystem.condExpDZ · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:188 · uses POHeckmanRoySystem , POSystem
def condExpYZ reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and an instrument value, the conditional outcome mean is the event-conditional mean of the observed outcome among units with that instrument value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z :
α
condExpYZ S z :
eventCondExp P.μ (S.zEvent z) S.factualY
Causalean.PO.POHeckmanRoySystem.condExpYZ · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:195 · uses POHeckmanRoySystem , POSystem
def yUnderD reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and a treatment value, the outcome under the treatment regime is the potential outcome represented together with the intervention fixing treatment to that value.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
d :
yUnderD S d :
⟨S.yVar, Regime.single S.D (S.hDbool.symm d)⟩
def cfBundle reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system, the counterfactual bundle contains the latent rank and the potential outcomes under treatment and control.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
cfBundle S :
POCFBundle.cons (RegimedVar.ofFactual S.uVar) <| POCFBundle.cons (S.yUnderD true) <| POCFBundle.cons (S.yUnderD false) <| POCFBundle.nil P
structure Assumptions reviewed
Causalean.PO.POHeckmanRoySystem

Heckman–Roy IV identifying assumptions (def:po-iv-heckman-roy-assumptions). Bundles consistency of the underlying potential-outcome system, exogeneity of the instrument, independent of the latent selection rank and the two potential outcomes, threshold-crossing selection: the potential treatment under instrument value z equals true exactly when the latent rank falls at or below the propensity p(z), and the latent rank being uniformly distributed on [0,1].

Definition (Lean source)
P :
shared
α :
Type u_1
shared
consistency :
P.Consistency

Consistency of the underlying PO system.

instrumentIndep :
P.IndepCF (RegimedVar.ofFactual S.zVar) S.cfBundle P.μ

Instrument exogeneity: Z ⟂ (U, Y(1), Y(0)).

thresholdCrossing :
∀ z : α, ∀ᵐ ω ∂P.μ, (S.DofZ z ω = true ↔ S.factualU ω ≤ S.p z)

Threshold crossing: D(z) = 1_{U ≤ p(z)} a.s., for every z : α.

uniformU :
∀ q ∈ Icc (0:ℝ) 1, P.μ {ω | S.factualU ω ≤ q} = ofReal q

Uniform-rank lemma: μ {U ≤ q} = ENNReal.ofReal q for q ∈ [0,1]. Captures U ~ Unif[0,1] exactly at the granularity used in the proof (avoids a Mathlib IsUniform detour); see remark rem:po-iv-heckman-roy-uniform.

Causalean.PO.POHeckmanRoySystem.Assumptions · Causalean/PO/ID/Exact/HeckmanRoy/Setup.lean:224 · uses POHeckmanRoySystem , POSystem
def LATE reviewed
Causalean.PO.POHeckmanRoySystem

For a Heckman--Roy system and two instrument values, the latent interval average treatment effect is the mean difference between treated and untreated potential outcomes among units whose latent ranks lie strictly above the first propensity threshold and no greater than the second, with value zero when that event has zero probability.

Definition (Lean source)
P :
shared
α :
Type u_1
shared
S :
shared
z₀ z₁ :
α
LATE S z₀ z₁ :
(∫ ω in S.intervalComplierEvent z₀ z₁, (S.YofD true ω - S.YofD false ω) ∂P.μ) / (P.μ (S.intervalComplierEvent z₀ z₁)).toReal
9 supporting declarations (lemmas, instances)
Wald 1 core · 8 supporting This file proves the pairwise Wald identification theorem for the Heckman-Vytlacil generalized Roy instrumental-variables model. ★ wald_pairwise

Heckman-Roy Wald Identification

This file proves the pairwise Wald identification theorem for the Heckman-Vytlacil generalized Roy instrumental-variables model. For two instrument values with ordered propensities, it identifies the observable Wald ratio with the latent interval average treatment effect.

theorem wald_pairwise reviewed
Causalean.PO.POHeckmanRoySystem

Pairwise Wald identification of LATE (prop:po-iv-heckman-roy-wald). Under the Heckman–Roy identifying assumption bundle, for instrument values z₀, z₁ at which the event {Z = z₀} has positive probability, the event {Z = z₁} has positive probability, and the latent selection threshold at z₀ is strictly below the threshold at z₁, provided the potential outcome under treatment and the potential outcome under control are integrable, the Wald ratio of the conditional-mean outcome and treatment contrasts between Z = z₁ and Z = z₀ equals the pairwise local average treatment effect LATE z₀ z₁.

Formal statement
P :
shared
α :
Type u_1
shared
S :
shared
hA :
S.Assumptions
z₀ z₁ :
α
hZ0 :
0 < (P.μ (S.zEvent z₀)).toReal
hZ1 :
0 < (P.μ (S.zEvent z₁)).toReal
hpz :
S.p z₀ < S.p z₁
hY1 :
Integrable (S.YofD true) P.μ
hY0 :
Integrable (S.YofD false) P.μ
(S.condExpYZ z₁ - S.condExpYZ z₀) / (S.condExpDZ z₁ - S.condExpDZ z₀) = S.LATE z₀ z₁
Proof (Lean source)
theorem wald_pairwise (hA : S.Assumptions) (z₀ z₁ : α) (hZ0 : 0 < (P.μ (S.zEvent z₀)).toReal) (hZ1 : 0 < (P.μ (S.zEvent z₁)).toReal) (hpz : S.p z₀ < S.p z₁) (hY1 : Integrable (S.YofD true) P.μ) (hY0 : Integrable (S.YofD false) P.μ) : (S.condExpYZ z₁ - S.condExpYZ z₀) / (S.condExpDZ z₁ - S.condExpDZ z₀) = S.LATE z₀ z₁ := by rw [S.first_stage_identity hA z₀ z₁ hZ0 hZ1 hpz] rw [S.reduced_form_identity hA z₀ z₁ hZ0 hZ1 hY1 hY0] rw [MeasureTheory.integral_congr_ae (S.pointwise_threshold_identity hA z₀ z₁ (le_of_lt hpz))] rw [S.event_conditioning_identity z₀ z₁] rw [S.complier_measure hA z₀ z₁ hpz] have hp_ne : S.p z₁ - S.p z₀ ≠ 0 := sub_ne_zero.mpr (ne_of_gt hpz) field_simp
8 supporting declarations (lemmas, instances)
  • DofZ_eq_factualD_on_zEvent lemma — Pointwise D-consistency on {Z = z}: D(z)(ω) = D(ω). One-line specialisation of POVar.cf_eq_factual_on_event. Analogue of POIVSystem.DofZ_eq_factualD_on_zEvent in LATE.lean.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    hA :
    S.Assumptions
    z :
    α
    ω :
    P.Ω
    :
    ω ∈ S.zEvent z
    S.DofZ z ω = S.factualD ω
    Proof (Lean source)
    lemma DofZ_eq_factualD_on_zEvent (hA : S.Assumptions) (z : α) {ω : P.Ω} (hω : ω ∈ S.zEvent z) : S.DofZ z ω = S.factualD ω := POVar.cf_eq_factual_on_event hA.consistency S.dVar S.zVar z S.hZD.symm hω
    Causalean.PO.POHeckmanRoySystem.DofZ_eq_factualD_on_zEvent · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:45
  • factualY_eq_YofD_factualD lemma — Pointwise Y-consistency: Y(ω) = Y(D(ω))(ω) for every ω. One-line specialisation of POVar.factual_eq_cfUnder_self_selected.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    hA :
    S.Assumptions
    ω :
    P.Ω
    S.factualY ω = S.YofD (S.factualD ω) ω
    Proof (Lean source)
    lemma factualY_eq_YofD_factualD (hA : S.Assumptions) (ω : P.Ω) : S.factualY ω = S.YofD (S.factualD ω) ω := POVar.factual_eq_cfUnder_self_selected hA.consistency S.yVar S.dVar S.hDY.symm ω
    Causalean.PO.POHeckmanRoySystem.factualY_eq_YofD_factualD · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:53
  • interval_indicator_sub lemma — Pointwise: for q₀ ≤ q₁, 1_{U ω ≤ q₁} - 1_{U ω ≤ q₀} = 1_{q₀ < U ω ≤ q₁}.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    z₀ z₁ :
    α
    hpz :
    S.p z₀ ≤ S.p z₁
    ω :
    P.Ω
    (if S.factualU ω ≤ S.p z₁ then (1:ℝ) else 0)
    - (if S.factualU ω ≤ S.p z₀ then (1:ℝ) else 0)
    = (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω
    Proof (Lean source)
    lemma interval_indicator_sub (z₀ z₁ : α) (hpz : S.p z₀ ≤ S.p z₁) (ω : P.Ω) : (if S.factualU ω ≤ S.p z₁ then (1:ℝ) else 0) - (if S.factualU ω ≤ S.p z₀ then (1:ℝ) else 0) = (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω := by -- Pure pointwise indicator algebra: case-split on `U ω ≤ p z₀` and -- `U ω ≤ p z₁`, then unfold `intervalComplierEvent`. unfold intervalComplierEvent by_cases h₁ : S.factualU ω ≤ S.p z₁ · by_cases h₀ : S.factualU ω ≤ S.p z₀ · have hnC : ω ∉ {ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁} := by intro hω exact (not_lt_of_ge h₀) hω.1 rw [Set.indicator_of_notMem hnC] simp [h₀, h₁] · have h₀' : S.p z₀ < S.factualU ω := lt_of_not_ge h₀ have hC : ω ∈ {ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁} := ⟨h₀', h₁⟩ simp [h₀, h₁, Set.indicator_of_mem hC] · have h₁' : S.p z₁ < S.factualU ω := lt_of_not_ge h₁ have h₀ : ¬ S.factualU ω ≤ S.p z₀ := fun h => (not_le_of_gt h₁') (le_trans h hpz) have hnC : ω ∉ {ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁} := by intro hω exact (not_le_of_gt h₁') hω.2 rw [Set.indicator_of_notMem hnC] simp [h₀, h₁]
    Causalean.PO.POHeckmanRoySystem.interval_indicator_sub · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:61
  • complier_measure lemma — Real-valued measure of the interval complier event: (μ {p z₀ < U ≤ p z₁}).toReal = p z₁ - p z₀, provided 0 ≤ p z₀ ≤ p z₁ ≤ 1 (which holds because p lands in [0,1] by S.hp_mem, plus the user-supplied ordering p z₀ < p z₁).
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    hA :
    S.Assumptions
    z₀ z₁ :
    α
    hpz :
    S.p z₀ < S.p z₁
    (P.μ (S.intervalComplierEvent z₀ z₁)).toReal = S.p z₁ - S.p z₀
    Proof (Lean source)
    lemma complier_measure (hA : S.Assumptions) (z₀ z₁ : α) (hpz : S.p z₀ < S.p z₁) : (P.μ (S.intervalComplierEvent z₀ z₁)).toReal = S.p z₁ - S.p z₀ := by -- Evaluate the two threshold sets with `uniformU`, subtract the lower set -- from the upper set, and convert the finite ENNReal difference to a real -- difference. `S.hp_mem z₀`, `S.hp_mem z₁`, and `hpz` discharge the -- `q ∈ [0,1]` side conditions. have hC_eq : S.intervalComplierEvent z₀ z₁ = {ω | S.factualU ω ≤ S.p z₁} \ {ω | S.factualU ω ≤ S.p z₀} := by ext ω constructor · rintro ⟨h₀, h₁⟩ refine ⟨h₁, ?_⟩ intro h exact (lt_irrefl _ (lt_of_lt_of_le h₀ h)) · rintro ⟨h₁, h₀⟩ refine ⟨?_, h₁⟩ exact lt_of_not_ge h₀ have hp0 : S.p z₀ ∈ Icc (0 : ℝ) 1 := S.hp_mem z₀ have hp1 : S.p z₁ ∈ Icc (0 : ℝ) 1 := S.hp_mem z₁ have h_sub : {ω | S.factualU ω ≤ S.p z₀} ⊆ {ω | S.factualU ω ≤ S.p z₁} := fun _ h => le_trans h (le_of_lt hpz) have hμ0 : P.μ {ω | S.factualU ω ≤ S.p z₀} = ofReal (S.p z₀) := hA.uniformU _ hp0 have hμ1 : P.μ {ω | S.factualU ω ≤ S.p z₁} = ofReal (S.p z₁) := hA.uniformU _ hp1 have hμ0_finite : P.μ {ω | S.factualU ω ≤ S.p z₀} ≠ ⊤ := by rw [hμ0] exact ENNReal.ofReal_ne_top rw [hC_eq, MeasureTheory.measure_diff h_sub (measurableSet_le S.measurable_factualU measurable_const).nullMeasurableSet hμ0_finite, hμ1, hμ0] rw [ENNReal.toReal_sub_of_le] · simp [ENNReal.toReal_ofReal hp1.1, ENNReal.toReal_ofReal hp0.1] · exact ENNReal.ofReal_le_ofReal (le_of_lt hpz) · exact ENNReal.ofReal_ne_top
    Causalean.PO.POHeckmanRoySystem.complier_measure · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:95
  • first_stage_identity theorem — First-stage identity: E[D | Z=z₁] - E[D | Z=z₀] = p z₁ - p z₀.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    hA :
    S.Assumptions
    z₀ z₁ :
    α
    hZ0 :
    0 < (P.μ (S.zEvent z₀)).toReal
    hZ1 :
    0 < (P.μ (S.zEvent z₁)).toReal
    hpz :
    S.p z₀ < S.p z₁
    S.condExpDZ z₁ - S.condExpDZ z₀ = S.p z₁ - S.p z₀
    Proof (Lean source)
    theorem first_stage_identity (hA : S.Assumptions) (z₀ z₁ : α) (hZ0 : 0 < (P.μ (S.zEvent z₀)).toReal) (hZ1 : 0 < (P.μ (S.zEvent z₁)).toReal) (hpz : S.p z₀ < S.p z₁) : S.condExpDZ z₁ - S.condExpDZ z₀ = S.p z₁ - S.p z₀ := by classical have hμne_zero : ∀ z, 0 < (P.μ (S.zEvent z)).toReal → P.μ (S.zVar.event z) ≠ 0 := fun z hZ h => absurd hZ (by simp [show S.zEvent z = S.zVar.event z from rfl, h]) have hμne_top : ∀ z, P.μ (S.zVar.event z) ≠ ⊤ := fun _ => measure_ne_top _ _ have hDofZ_to_indicator : ∀ z, ∀ᵐ ω ∂P.μ, ((S.DofZ z ω).toNat : ℝ) = (if S.factualU ω ≤ S.p z then (1:ℝ) else 0) := by intro z filter_upwards [hA.thresholdCrossing z] with ω hω by_cases hu : S.factualU ω ≤ S.p z · have hD : S.DofZ z ω = true := hω.mpr hu simp [hD, hu] · have hD : S.DofZ z ω = false := by cases hd : S.DofZ z ω · rfl · exact absurd (hω.mp hd) hu simp [hD, hu] have hCE : ∀ z (_hZ : 0 < (P.μ (S.zEvent z)).toReal), S.condExpDZ z = ∫ ω, (if S.factualU ω ≤ S.p z then (1:ℝ) else 0) ∂P.μ := by intro z hZ let getU : (∀ i : Fin S.cfBundle.n, S.cfBundle.type i) → ℝ := fun f => by exact f (0 : Fin 3) have hgetU_meas : Measurable getU := by -- Instance search no longer unfolds `cfBundle` to see `n = 3`, so supply -- the coordinate measurable-space family at index type `Fin 3` directly. let _ : ∀ i : Fin 3, MeasurableSpace (S.cfBundle.type i) := fun i => S.cfBundle.inst i change Measurable fun f : ∀ i : Fin S.cfBundle.n, S.cfBundle.type i => f (0 : Fin 3) exact measurable_pi_apply (0 : Fin 3) have hgetU_joint : ∀ ω, getU (S.cfBundle.jointValue ω) = S.factualU ω := by intro ω rfl let h_proj : (∀ i : Fin S.cfBundle.n, S.cfBundle.type i) → ℝ := fun f => if getU f ≤ S.p z then (1:ℝ) else 0 have hh_meas : Measurable h_proj := by refine Measurable.ite ?_ measurable_const measurable_const exact measurableSet_le hgetU_meas measurable_const have h_cons : ∀ ω ∈ S.zVar.event z, (if S.factualU ω ≤ S.p z then (1:ℝ) else 0) = h_proj (S.cfBundle.jointValue ω) := by intro ω _ dsimp [h_proj] rw [hgetU_joint] have hcond_d : S.condExpDZ z = eventCondExp P.μ (S.zVar.event z) (fun ω => ((S.DofZ z ω).toNat : ℝ)) := by unfold POHeckmanRoySystem.condExpDZ eventCondExp congr 1 refine MeasureTheory.setIntegral_congr_fun (S.measurableSet_zEvent z) ?_ intro ω hω exact congrArg (fun d : Bool => ((d.toNat : ℝ))) (S.DofZ_eq_factualD_on_zEvent hA z hω).symm have hcond_ind : eventCondExp P.μ (S.zVar.event z) (fun ω => ((S.DofZ z ω).toNat : ℝ)) = eventCondExp P.μ (S.zVar.event z) (fun ω => if S.factualU ω ≤ S.p z then (1:ℝ) else 0) := by unfold eventCondExp congr 1 refine MeasureTheory.setIntegral_congr_ae (S.measurableSet_zEvent z) ?_ filter_upwards [hDofZ_to_indicator z] with ω hω _ exact hω rw [hcond_d, hcond_ind, POSystem.eventCondExp_of_consistency_IndepCF hA.instrumentIndep (a := S.zVar) hh_meas (MeasurableSet.singleton z) (ae_restrict_of_forall_mem (S.measurableSet_zEvent z) h_cons) (hμne_zero z hZ) (hμne_top z)] refine MeasureTheory.integral_congr_ae (Filter.Eventually.of_forall ?_) intro ω dsimp [h_proj] rw [hgetU_joint] rw [hCE z₁ hZ1, hCE z₀ hZ0] have hbdd : ∀ z, ∀ ω, |if S.factualU ω ≤ S.p z then (1:ℝ) else 0| ≤ 1 := by intro z ω by_cases h : S.factualU ω ≤ S.p z <;> simp [h] have hint : ∀ z, Integrable (fun ω => if S.factualU ω ≤ S.p z then (1:ℝ) else 0) P.μ := by intro z refine (MeasureTheory.integrable_const (1:ℝ)).mono' ?_ (Filter.Eventually.of_forall (hbdd z)) exact (Measurable.ite (measurableSet_le S.measurable_factualU measurable_const) measurable_const measurable_const).aestronglyMeasurable rw [← MeasureTheory.integral_sub (hint z₁) (hint z₀)] rw [MeasureTheory.integral_congr_ae (Filter.Eventually.of_forall (S.interval_indicator_sub z₀ z₁ (le_of_lt hpz)))] rw [MeasureTheory.integral_indicator_const (1:ℝ) (S.measurableSet_intervalComplierEvent z₀ z₁)] simpa [MeasureTheory.measureReal_def] using S.complier_measure hA z₀ z₁ hpz
    Causalean.PO.POHeckmanRoySystem.first_stage_identity · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:143
  • reduced_form_identity theorem — Reduced-form identity: E[Y | Z=z₁] - E[Y | Z=z₀] = ∫ (Y(D(z₁)) - Y(D(z₀))) ∂μ.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    hA :
    S.Assumptions
    z₀ z₁ :
    α
    hZ0 :
    0 < (P.μ (S.zEvent z₀)).toReal
    hZ1 :
    0 < (P.μ (S.zEvent z₁)).toReal
    hY1 :
    Integrable (S.YofD true) P.μ
    hY0 :
    Integrable (S.YofD false) P.μ
    S.condExpYZ z₁ - S.condExpYZ z₀ = ∫ ω, (S.YofDofZ z₁ ω - S.YofDofZ z₀ ω) ∂P.μ
    Proof (Lean source)
    theorem reduced_form_identity (hA : S.Assumptions) (z₀ z₁ : α) (hZ0 : 0 < (P.μ (S.zEvent z₀)).toReal) (hZ1 : 0 < (P.μ (S.zEvent z₁)).toReal) (hY1 : Integrable (S.YofD true) P.μ) (hY0 : Integrable (S.YofD false) P.μ) : S.condExpYZ z₁ - S.condExpYZ z₀ = ∫ ω, (S.YofDofZ z₁ ω - S.YofDofZ z₀ ω) ∂P.μ := by have hYDZ_meas : ∀ z, Measurable (S.YofDofZ z) := fun z => S.measurable_YofDofZ z have hYDZ_bdd : ∀ z, ∀ ω, |S.YofDofZ z ω| ≤ |S.YofD true ω| + |S.YofD false ω| := fun z ω => by have h1 := abs_nonneg (S.YofD true ω) have h0 := abs_nonneg (S.YofD false ω) unfold YofDofZ cases S.DofZ z ω <;> simp [h1, h0] have hYDZ_int : ∀ z, Integrable (S.YofDofZ z) P.μ := fun z => (hY1.norm.add hY0.norm).mono' (hYDZ_meas z).aestronglyMeasurable (Filter.Eventually.of_forall (hYDZ_bdd z)) have hμne_zero : ∀ z, 0 < (P.μ (S.zEvent z)).toReal → P.μ (S.zVar.event z) ≠ 0 := fun z hZ h => absurd hZ (by simp [show S.zEvent z = S.zVar.event z from rfl, h]) have hμne_top : ∀ z, P.μ (S.zVar.event z) ≠ ⊤ := fun _ => measure_ne_top _ _ have h_factualY_ae : ∀ z, ∀ᵐ ω ∂P.μ, (ω ∈ S.zEvent z) → S.factualY ω = (if S.factualU ω ≤ S.p z then S.YofD true ω else S.YofD false ω) := by intro z filter_upwards [hA.thresholdCrossing z] with ω hth hω rw [S.factualY_eq_YofD_factualD hA ω, ← S.DofZ_eq_factualD_on_zEvent hA z hω] by_cases hu : S.factualU ω ≤ S.p z · have hD : S.DofZ z ω = true := hth.mpr hu simp [hD, hu] · have hD : S.DofZ z ω = false := by cases hd : S.DofZ z ω · rfl · exact absurd (hth.mp hd) hu simp [hD, hu] have hCE : ∀ z (_hZ : 0 < (P.μ (S.zEvent z)).toReal), S.condExpYZ z = ∫ ω, (if S.factualU ω ≤ S.p z then S.YofD true ω else S.YofD false ω) ∂P.μ := by intro z hZ let getU : (∀ i : Fin S.cfBundle.n, S.cfBundle.type i) → ℝ := fun f => by exact f (0 : Fin 3) have hgetU_meas : Measurable getU := by -- Instance search no longer unfolds `cfBundle` to see `n = 3`, so supply -- the coordinate measurable-space family at index type `Fin 3` directly. let _ : ∀ i : Fin 3, MeasurableSpace (S.cfBundle.type i) := fun i => S.cfBundle.inst i change Measurable fun f : ∀ i : Fin S.cfBundle.n, S.cfBundle.type i => f (0 : Fin 3) exact measurable_pi_apply (0 : Fin 3) have hgetU_joint : ∀ ω, getU (S.cfBundle.jointValue ω) = S.factualU ω := by intro ω rfl let h_proj : (∀ i : Fin S.cfBundle.n, S.cfBundle.type i) → ℝ := fun f => if getU f ≤ S.p z then ((f (1 : Fin 3)) : ℝ) else ((f (2 : Fin 3)) : ℝ) have hh_meas : Measurable h_proj := by let _ : ∀ i : Fin 3, MeasurableSpace (S.cfBundle.type i) := fun i => S.cfBundle.inst i change Measurable fun f : ∀ i : Fin S.cfBundle.n, S.cfBundle.type i => if getU f ≤ S.p z then ((f (1 : Fin 3)) : ℝ) else ((f (2 : Fin 3)) : ℝ) refine Measurable.ite ?_ ?_ ?_ · exact measurableSet_le hgetU_meas measurable_const · exact measurable_pi_apply (1 : Fin 3) · exact measurable_pi_apply (2 : Fin 3) have h_cons : ∀ ω ∈ S.zVar.event z, (if S.factualU ω ≤ S.p z then S.YofD true ω else S.YofD false ω) = h_proj (S.cfBundle.jointValue ω) := by intro ω _ dsimp [h_proj] rw [hgetU_joint] have hJV1 : (S.cfBundle.jointValue ω (1 : Fin 3) : ℝ) = S.YofD true ω := rfl have hJV2 : (S.cfBundle.jointValue ω (2 : Fin 3) : ℝ) = S.YofD false ω := rfl rw [hJV1, hJV2] have hbridge : S.condExpYZ z = eventCondExp P.μ (S.zVar.event z) (fun ω => if S.factualU ω ≤ S.p z then S.YofD true ω else S.YofD false ω) := by unfold POHeckmanRoySystem.condExpYZ eventCondExp change (∫ ω in S.zEvent z, S.factualY ω ∂P.μ) / (P.μ (S.zEvent z)).toReal = (∫ ω in S.zVar.event z, (if S.factualU ω ≤ S.p z then S.YofD true ω else S.YofD false ω) ∂P.μ) / (P.μ (S.zVar.event z)).toReal have hzev : S.zEvent z = S.zVar.event z := rfl rw [hzev] congr 1 refine MeasureTheory.setIntegral_congr_ae (S.measurableSet_zEvent z) ?_ filter_upwards [h_factualY_ae z] with ω hω hin rw [show S.zEvent z = S.zVar.event z from rfl] at hω exact hω hin rw [hbridge, POSystem.eventCondExp_of_consistency_IndepCF hA.instrumentIndep (a := S.zVar) hh_meas (MeasurableSet.singleton z) (ae_restrict_of_forall_mem (S.measurableSet_zEvent z) h_cons) (hμne_zero z hZ) (hμne_top z)] refine MeasureTheory.integral_congr_ae (Filter.Eventually.of_forall ?_) intro ω dsimp [h_proj] rw [hgetU_joint] have hJV1 : (S.cfBundle.jointValue ω (1 : Fin 3) : ℝ) = S.YofD true ω := rfl have hJV2 : (S.cfBundle.jointValue ω (2 : Fin 3) : ℝ) = S.YofD false ω := rfl rw [hJV1, hJV2] have hAlt_eq : ∀ z, (∫ ω, (if S.factualU ω ≤ S.p z then S.YofD true ω else S.YofD false ω) ∂P.μ) = ∫ ω, S.YofDofZ z ω ∂P.μ := by intro z refine MeasureTheory.integral_congr_ae ?_ filter_upwards [hA.thresholdCrossing z] with ω hth unfold YofDofZ by_cases hu : S.factualU ω ≤ S.p z · have hD : S.DofZ z ω = true := hth.mpr hu simp [hD, hu] · have hD : S.DofZ z ω = false := by cases hd : S.DofZ z ω · rfl · exact absurd (hth.mp hd) hu simp [hD, hu] rw [hCE z₁ hZ1, hCE z₀ hZ0, hAlt_eq z₁, hAlt_eq z₀] rw [← MeasureTheory.integral_sub (hYDZ_int z₁) (hYDZ_int z₀)]
    Causalean.PO.POHeckmanRoySystem.reduced_form_identity · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:251
  • pointwise_threshold_identity theorem — Pointwise threshold identity: Y(D(z₁)) - Y(D(z₀)) = (Y(1) - Y(0)) · 1_{p z₀ < U ≤ p z₁} a.s.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    hA :
    S.Assumptions
    z₀ z₁ :
    α
    hpz :
    S.p z₀ ≤ S.p z₁
    ∀ᵐ ω ∂P.μ, S.YofDofZ z₁ ω - S.YofDofZ z₀ ω
    = (S.YofD true ω - S.YofD false ω) * (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω
    Proof (Lean source)
    theorem pointwise_threshold_identity (hA : S.Assumptions) (z₀ z₁ : α) (hpz : S.p z₀ ≤ S.p z₁) : ∀ᵐ ω ∂P.μ, S.YofDofZ z₁ ω - S.YofDofZ z₀ ω = (S.YofD true ω - S.YofD false ω) * (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω := by -- Combine threshold crossing at `z₀` and `z₁`; then unfold `YofDofZ` and -- case-split on `U ω ≤ p z₀` and `U ω ≤ p z₁`, using -- `intervalComplierEvent` membership in each case. filter_upwards [hA.thresholdCrossing z₀, hA.thresholdCrossing z₁] with ω h₀ h₁ unfold YofDofZ intervalComplierEvent by_cases hu1 : S.factualU ω ≤ S.p z₁ · by_cases hu0 : S.factualU ω ≤ S.p z₀ · have hD0 : S.DofZ z₀ ω = true := h₀.mpr hu0 have hD1 : S.DofZ z₁ ω = true := h₁.mpr hu1 have hnC : ω ∉ ({ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁} : Set P.Ω) := by intro hω exact (not_lt_of_ge hu0) hω.1 simp [hD0, hD1, Set.indicator_of_notMem hnC] · have hu0' : S.p z₀ < S.factualU ω := lt_of_not_ge hu0 have hD0 : S.DofZ z₀ ω = false := by cases hd : S.DofZ z₀ ω · rfl · exact absurd (h₀.mp hd) hu0 have hD1 : S.DofZ z₁ ω = true := h₁.mpr hu1 have hC : ω ∈ ({ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁} : Set P.Ω) := ⟨hu0', hu1⟩ simp [hD0, hD1, Set.indicator_of_mem hC] · have hu0 : ¬ S.factualU ω ≤ S.p z₀ := fun h => hu1 (le_trans h hpz) have hD0 : S.DofZ z₀ ω = false := by cases hd : S.DofZ z₀ ω · rfl · exact absurd (h₀.mp hd) hu0 have hD1 : S.DofZ z₁ ω = false := by cases hd : S.DofZ z₁ ω · rfl · exact absurd (h₁.mp hd) hu1 have hnC : ω ∉ ({ω | S.p z₀ < S.factualU ω ∧ S.factualU ω ≤ S.p z₁} : Set P.Ω) := by intro hω exact hu1 hω.2 simp [hD0, hD1, Set.indicator_of_notMem hnC]
    Causalean.PO.POHeckmanRoySystem.pointwise_threshold_identity · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:381
  • event_conditioning_identity theorem — Event-conditioning identity: ∫ (Y(1) - Y(0)) · 1_{C(z₀,z₁)} ∂μ = μ(C(z₀,z₁)).toReal · LATE z₀ z₁.
    P :
    shared
    α :
    Type u_1
    shared
    S :
    shared
    z₀ z₁ :
    α
    ∫ ω, (S.YofD true ω - S.YofD false ω) * (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω ∂P.μ
    = (P.μ (S.intervalComplierEvent z₀ z₁)).toReal * S.LATE z₀ z₁
    Proof (Lean source)
    theorem event_conditioning_identity (z₀ z₁ : α) : ∫ ω, (S.YofD true ω - S.YofD false ω) * (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω ∂P.μ = (P.μ (S.intervalComplierEvent z₀ z₁)).toReal * S.LATE z₀ z₁ := by -- Same event-conditioning algebra as binary LATE, with the interval -- complier event in place of the binary complier event. unfold LATE have hC : MeasurableSet (S.intervalComplierEvent z₀ z₁) := S.measurableSet_intervalComplierEvent z₀ z₁ have h_rw : (fun ω => (S.YofD true ω - S.YofD false ω) * (S.intervalComplierEvent z₀ z₁).indicator (fun _ => (1:ℝ)) ω) = (S.intervalComplierEvent z₀ z₁).indicator (fun ω => S.YofD true ω - S.YofD false ω) := by funext ω by_cases hω : ω ∈ S.intervalComplierEvent z₀ z₁ · simp [Set.indicator_of_mem hω] · simp [Set.indicator_of_notMem hω] rw [h_rw, MeasureTheory.integral_indicator hC] by_cases hμ : (P.μ (S.intervalComplierEvent z₀ z₁)).toReal = 0 · rw [hμ, zero_mul] have hμ0 : P.μ (S.intervalComplierEvent z₀ z₁) = 0 := by have hne : P.μ (S.intervalComplierEvent z₀ z₁) ≠ ⊤ := measure_ne_top _ _ exact (ENNReal.toReal_eq_zero_iff _).mp hμ |>.resolve_right hne have hrest : P.μ.restrict (S.intervalComplierEvent z₀ z₁) = 0 := by rw [MeasureTheory.Measure.restrict_eq_zero]; exact hμ0 simp [hrest] · field_simp
    Causalean.PO.POHeckmanRoySystem.event_conditioning_identity · Causalean/PO/ID/Exact/HeckmanRoy/Wald.lean:433