PO.ID.Partial.LP

The linear-programming representation of bound computations over finite outcome spaces.

Conic­Duality 9 core · 2 supporting This file develops the conic linear-programming duality backbone for partial identification bounds. ★ farkas★ strong_duality_primal_attained★ strong_duality_zero_gap

Conic Duality

This file develops the conic linear-programming duality backbone for partial identification bounds. It treats sharp bounds as optimal values of linear programs over a cone in real Hilbert spaces and proves weak duality, a Farkas feasibility alternative, primal attainment under a closedness qualification, and zero duality gap under the same qualification.

The main structure ConicProgram packages the cone K, constraint operator A, right-hand side b, and objective direction c. The predicates PrimalFeasible and DualFeasible define the primal and dual feasible sets, while primalValue and dualValue record the corresponding optimal values. The theorem weak_duality gives the pointwise inequality, and dualValue_le_primalValue lifts it to values.

The theorem farkas restates conic separation as a feasibility alternative. The set augmentedImage is the closedness constraint qualification used by strong_duality_primal_attained and strong_duality_zero_gap, which provide primal attainment and no duality gap for feasible bounded-below programs.

The Hilbert-space formulation covers infinite-dimensional function spaces used by proxy and bridge problems. Measure-cone weak-star duality is intentionally left outside this module; the module note at the end explains the missing signed-measure and cone infrastructure.

structure ConicProgram reviewed
Causalean.PartialID

Primal data of a conic linear program over real Hilbert spaces: minimize ⟪c, x⟫ subject to A x = b and x ∈ K.

Definition (Lean source)
The constraint cone (nonnegativity / shape restrictions).
K :
The linear constraint operator.
A :
E →L[ℝ] F
The right-hand side (observed-data target).
b :
F
The objective direction.
c :
E
Causalean.PartialID.ConicProgram · Causalean/PO/ID/Partial/LP/ConicDuality.lean:44
def PrimalFeasible reviewed
Causalean.PartialID.ConicProgram

In complete real inner-product decision and constraint spaces, for a conic program and a candidate decision vector, the primal-feasibility predicate holds precisely when the vector satisfies the program's linear equality constraint and belongs to its constraint cone.

Definition (Lean source)
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
x :
E
PrimalFeasible P x :
Prop
clause 1
P.A x = P.b
clause 2
x ∈ P.K
Causalean.PartialID.ConicProgram.PrimalFeasible · Causalean/PO/ID/Partial/LP/ConicDuality.lean:62 · uses ConicProgram
def DualFeasible reviewed
Causalean.PartialID.ConicProgram

In complete real inner-product decision and constraint spaces, for a conic program and a candidate dual multiplier, the dual-feasibility predicate holds precisely when the program's objective direction minus the adjoint constraint operator applied to that multiplier belongs to the dual of the constraint cone.

Definition (Lean source)
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
y :
F
DualFeasible P y :
Prop
P.c - (adjoint P.A) y ∈ innerDual (P.K : Set E)
Causalean.PartialID.ConicProgram.DualFeasible · Causalean/PO/ID/Partial/LP/ConicDuality.lean:70 · uses ConicProgram
def primalValue reviewed
Causalean.PartialID.ConicProgram

In complete real inner-product decision and constraint spaces, for a conic program, its primal optimal value is the infimum of the objective inner products over all primal-feasible decision vectors.

Definition (Lean source)
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
primalValue P :
sInf ((fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x})
Causalean.PartialID.ConicProgram.primalValue · Causalean/PO/ID/Partial/LP/ConicDuality.lean:80 · uses ConicProgram
def dualValue reviewed
Causalean.PartialID.ConicProgram

In complete real inner-product decision and constraint spaces, for a conic program, its dual optimal value is the supremum of the inner products between its right-hand side and all dual-feasible multipliers.

Definition (Lean source)
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
dualValue P :
sSup ((fun y => ⟪P.b, y⟫) '' {y | P.DualFeasible y})
Causalean.PartialID.ConicProgram.dualValue · Causalean/PO/ID/Partial/LP/ConicDuality.lean:87 · uses ConicProgram
theorem farkas reviewed
Causalean.PartialID.ConicProgram

Farkas alternative / feasibility engine. For a target point b, b lies in the closed image cone A(K) if and only if every dual direction y whose pullback Aᵀ y lies in the dual cone of K pairs nonnegatively with b.

Formal statement
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
b :
F
b ∈ map P.A P.K
↔ ∀ y : F, (adjoint P.A) y ∈ innerDual (P.K : Set E) → 0 ≤ ⟪b, y⟫
Proof (Lean source)
theorem farkas {b : F} : b ∈ ProperCone.map P.A P.K ↔ ∀ y : F, (adjoint P.A) y ∈ innerDual (P.K : Set E) → 0 ≤ ⟪b, y⟫ := ProperCone.relative_hyperplane_separation
Causalean.PartialID.ConicProgram.farkas · Causalean/PO/ID/Partial/LP/ConicDuality.lean:122 · uses ConicProgram
def augmentedImage reviewed
Causalean.PartialID.ConicProgram

In complete real inner-product decision and constraint spaces, for a conic program, the augmented image is the set of pairs consisting of the constraint-operator image and objective inner product of each decision vector in its constraint cone.

Definition (Lean source)
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
augmentedImage P :
Set (F × ℝ)
(fun x => (P.A x, ⟪P.c, x⟫)) '' (P.K : Set E)
Causalean.PartialID.ConicProgram.augmentedImage · Causalean/PO/ID/Partial/LP/ConicDuality.lean:137 · uses ConicProgram
theorem strong_duality_primal_attained reviewed
Causalean.PartialID.ConicProgram

Strong duality I — primal attainment (closedness CQ). For a conic program that is primal feasible and whose feasible objective values are bounded below, if the augmented image cone {(Ax, ⟪c,x⟫) : x ∈ K} is closed — the constraint qualification separating attained optima from mere infima — then the primal optimum is attained: some primal-feasible point x achieves the objective value ⟪c,x⟫ = primalValue exactly. This is the "there is an extremal data-generating distribution" half of sharpness.

Formal statement
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
hP :
{x | P.PrimalFeasible x}.Nonempty
hbdd :
BddBelow ((fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x})
hCQ :
IsClosed P.augmentedImage
∃ x,
conclusion 1
P.PrimalFeasible x
conclusion 2
⟪P.c, x⟫ = P.primalValue
Proof (Lean source)
theorem strong_duality_primal_attained (hP : {x | P.PrimalFeasible x}.Nonempty) (hbdd : BddBelow ((fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x})) (hCQ : IsClosed P.augmentedImage) : ∃ x, P.PrimalFeasible x ∧ ⟪P.c, x⟫ = P.primalValue := by have hSeq : (fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x} = (fun r : ℝ => (P.b, r)) ⁻¹' P.augmentedImage := by ext r constructor · rintro ⟨x, hx, rfl⟩ exact ⟨x, hx.2, by simp only [hx.1]⟩ · rintro ⟨x, hxK, hxeq⟩ exact ⟨x, ⟨(Prod.ext_iff.mp hxeq).1, hxK⟩, (Prod.ext_iff.mp hxeq).2⟩ have hScl : IsClosed ((fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x}) := by rw [hSeq]; exact hCQ.preimage (by fun_prop) have hmem := hScl.csInf_mem (hP.image _) hbdd obtain ⟨x, hx, hxval⟩ := hmem exact ⟨x, hx, hxval⟩
Causalean.PartialID.ConicProgram.strong_duality_primal_attained · Causalean/PO/ID/Partial/LP/ConicDuality.lean:147 · uses ConicProgram , PrimalFeasible , augmentedImage , primalValue
theorem strong_duality_zero_gap reviewed
Causalean.PartialID.ConicProgram

Strong duality II — zero gap (closedness CQ). For a conic program that is primal feasible and whose feasible objective values are bounded below, if the augmented image cone is closed — the same constraint qualification as primal attainment — then there is no duality gap: the primal optimal value equals the dual optimal value, primalValue = dualValue.

Formal statement
E :
Type u_1
shared
F :
Type u_2
shared
P :
shared
hP :
{x | P.PrimalFeasible x}.Nonempty
hbdd :
BddBelow ((fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x})
hCQ :
IsClosed P.augmentedImage
P.primalValue = P.dualValue
Proof (Lean source)
theorem strong_duality_zero_gap (hP : {x | P.PrimalFeasible x}.Nonempty) (hbdd : BddBelow ((fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x})) (hCQ : IsClosed P.augmentedImage) : P.primalValue = P.dualValue := by -- The augmented operator `à x = (A x, ⟪c, x⟫)`. set à : E →L[ℝ] (F × ℝ) := (P.A).prod (innerSL ℝ P.c) with hÃdef have hÃapp : ∀ x : E, à x = (P.A x, ⟪P.c, x⟫) := fun x => rfl -- The underlying `PointedCone.map` image set is exactly the augmented image. have hpcimg : ((PointedCone.map (à : E →ₗ[ℝ] (F × ℝ)) (P.K : PointedCone ℝ E)) : Set (F × ℝ)) = P.augmentedImage := by rw [PointedCone.coe_map] ext z simp only [augmentedImage, Set.mem_image] constructor · rintro ⟨x, hx, rfl⟩; exact ⟨x, hx, (hÃapp x).symm⟩ · rintro ⟨x, hx, rfl⟩; exact ⟨x, hx, hÃapp x⟩ -- `p* := primalValue` is a finite lower bound for the feasible objective values. set S : Set ℝ := (fun x => ⟪P.c, x⟫) '' {x | P.PrimalFeasible x} with hSdef have hSne : S.Nonempty := hP.image _ have hlb : ∀ x : E, P.PrimalFeasible x → P.primalValue ≤ ⟪P.c, x⟫ := by intro x hx exact csInf_le hbdd ⟨x, hx, rfl⟩ -- (A) dualValue ≤ primalValue: every dual-feasible value is ≤ every feasible objective, -- hence ≤ the infimum p*. have hA : ∀ y : F, P.DualFeasible y → ⟪P.b, y⟫ ≤ P.primalValue := by intro y hy refine le_csInf hSne ?_ rintro _ ⟨x, hx, rfl⟩ exact P.weak_duality hx hy -- (B) primalValue ≤ dualValue, via separation. -- First: for every ε > 0 there is a dual-feasible ȳ with ⟪b, ȳ⟫ > p* - ε. have hB : ∀ ε : ℝ, 0 < ε → ∃ y : F, P.DualFeasible y ∧ P.primalValue - ε < ⟪P.b, y⟫ := by intro ε hε -- The point (b, p* - ε) is not in the map cone. have hnotmem : (P.b, P.primalValue - ε) ∉ map à P.K := by intro hmem have hcl : (P.b, P.primalValue - ε) ∈ (PointedCone.map (à : E →ₗ[ℝ] (F × ℝ)) (P.K : PointedCone ℝ E)).closure := ProperCone.mem_map.mp hmem rw [PointedCone.mem_closure] at hcl -- closure of the augmented image is itself, since it is closed. have : (P.b, P.primalValue - ε) ∈ P.augmentedImage := by have hset : closure ((PointedCone.map (à : E →ₗ[ℝ] (F × ℝ)) (P.K : PointedCone ℝ E)) : Set (F × ℝ)) = P.augmentedImage := by rw [hpcimg]; exact hCQ.closure_eq rwa [hset] at hcl obtain ⟨x, hxK, hxeq⟩ := this have h1 : P.A x = P.b := (Prod.ext_iff.mp hxeq).1 have h2 : ⟪P.c, x⟫ = P.primalValue - ε := (Prod.ext_iff.mp hxeq).2 have hfeas : P.PrimalFeasible x := ⟨h1, hxK⟩ have := hlb x hfeas rw [h2] at this linarith -- Separate. obtain ⟨g, hgpos, hgneg⟩ := ProperCone.hyperplane_separation_point (map à P.K) hnotmem -- Decompose g into the F-part (Riesz) and the ℝ-part s := g(0,1). set s : ℝ := g (0, 1) with hsdef set φ : F →L[ℝ] ℝ := g.comp ((ContinuousLinearMap.inl ℝ F ℝ)) with hφdef -- φ v = g (v, 0); Riesz representative y₀. set y₀ : F := (InnerProductSpace.toDual ℝ F).symm φ with hy₀def have hφapp : ∀ v : F, φ v = ⟪y₀, v⟫ := by intro v rw [hy₀def] rw [InnerProductSpace.toDual_symm_apply] -- g decomposes: g (v, t) = ⟪y₀, v⟫ + t * s. have hgdecomp : ∀ (v : F) (t : ℝ), g (v, t) = ⟪y₀, v⟫ + s * t := by intro v t have hvt : ((v, t) : F × ℝ) = (v, 0) + t • (0, 1) := by simp rw [hvt, map_add, map_smul] have hv : g (v, 0) = ⟪y₀, v⟫ := by rw [← hφapp v]; rfl rw [hv] simp only [hsdef, smul_eq_mul] ring -- (i): ∀ x ∈ K, 0 ≤ ⟪y₀, A x⟫ + s * ⟪c, x⟫. have hi : ∀ x : E, x ∈ P.K → 0 ≤ ⟪y₀, P.A x⟫ + s * ⟪P.c, x⟫ := by intro x hx have hxmem : à x ∈ map à P.K := by apply ProperCone.mem_map.mpr rw [PointedCone.mem_closure] apply subset_closure -- à x ∈ (PointedCone.map ↑à ↑P.K : Set _) = augmentedImage rw [hpcimg] exact ⟨x, hx, rfl⟩ have := hgpos (à x) hxmem rw [hÃapp x, hgdecomp] at this exact this -- (ii): ⟪y₀, b⟫ + (p* - ε) * s < 0. have hii : ⟪y₀, P.b⟫ + s * (P.primalValue - ε) < 0 := by have := hgneg rw [hgdecomp] at this exact this -- Get a feasible point x₀. obtain ⟨x₀, hx₀⟩ := hP have hx₀K : x₀ ∈ P.K := hx₀.2 have hx₀A : P.A x₀ = P.b := hx₀.1 have hx₀val : P.primalValue ≤ ⟪P.c, x₀⟫ := hlb x₀ hx₀ -- Case on s. rcases lt_trichotomy s 0 with hs | hs | hs · -- s < 0 impossible. exfalso have h1 := hi x₀ hx₀K rw [hx₀A] at h1 -- 0 ≤ ⟪y₀, b⟫ + s * ⟪c, x₀⟫ -- since s < 0 and ⟪c,x₀⟫ ≥ p*: s * ⟪c,x₀⟫ ≤ s * p* have hmul : s * ⟪P.c, x₀⟫ ≤ s * P.primalValue := by apply mul_le_mul_of_nonpos_left hx₀val (le_of_lt hs) -- (ii): ⟪y₀,b⟫ + (p*-ε)*s < 0, i.e. ⟪y₀,b⟫ + s*p* - s*ε < 0 nlinarith [hii, h1, hmul, hε, hs] · -- s = 0 impossible. exfalso have h1 := hi x₀ hx₀K rw [hx₀A, hs] at h1 simp only [zero_mul, add_zero] at h1 -- h1 : 0 ≤ ⟪y₀, b⟫ have h2 := hii rw [hs] at h2 simp only [zero_mul, add_zero] at h2 -- h2 : ⟪y₀, b⟫ < 0 linarith · -- s > 0: ȳ := -(1/s) • y₀ is dual feasible with ⟪b, ȳ⟫ > p* - ε. refine ⟨-(1/s) • y₀, ?_, ?_⟩ · -- dual feasibility rw [DualFeasible, ProperCone.mem_innerDual] intro x hx have hred : ⟪x, P.c - (adjoint P.A) (-(1/s) • y₀)⟫ = (1/s) * (⟪y₀, P.A x⟫ + s * ⟪P.c, x⟫) := by rw [inner_sub_right] rw [map_smul, inner_smul_right] rw [ContinuousLinearMap.adjoint_inner_right] rw [real_inner_comm x P.c, real_inner_comm (P.A x) y₀] field_simp ring rw [hred] have hpos : (0 : ℝ) ≤ 1/s := le_of_lt (by positivity) exact mul_nonneg hpos (hi x hx) · -- value bound have hval : ⟪P.b, -(1/s) • y₀⟫ = -(1/s) * ⟪y₀, P.b⟫ := by rw [inner_smul_right, real_inner_comm P.b y₀] rw [hval] -- from (ii): ⟪y₀, b⟫ + s*(p*-ε) < 0; multiply by 1/s > 0. have hsinv : (0:ℝ) < 1 / s := by positivity have key : (1/s) * (⟪y₀, P.b⟫ + s * (P.primalValue - ε)) < (1/s) * 0 := mul_lt_mul_of_pos_left hii hsinv have hexp : (1/s) * (⟪y₀, P.b⟫ + s * (P.primalValue - ε)) = (1/s) * ⟪y₀, P.b⟫ + (P.primalValue - ε) := by field_simp rw [hexp, mul_zero] at key linarith [key] -- Assemble: dualValue ≥ p* and dualValue ≤ p*. have hDne : {y | P.DualFeasible y}.Nonempty := by obtain ⟨y, hy, _⟩ := hB 1 (by norm_num) exact ⟨y, hy⟩ -- dualValue ≤ primalValue have hle : P.dualValue ≤ P.primalValue := by rw [dualValue] refine csSup_le (hDne.image _) ?_ rintro _ ⟨y, hy, rfl⟩ exact hA y hy -- primalValue ≤ dualValue have hge : P.primalValue ≤ P.dualValue := by refine le_of_forall_pos_lt_add ?_ intro ε hε obtain ⟨y, hy, hyval⟩ := hB ε hε have hbdd' : BddAbove ((fun y => ⟪P.b, y⟫) '' {y | P.DualFeasible y}) := by refine ⟨P.primalValue, ?_⟩ rintro _ ⟨z, hz, rfl⟩ exact hA z hz have : ⟪P.b, y⟫ ≤ P.dualValue := le_csSup hbdd' ⟨y, hy, rfl⟩ linarith linarith
2 supporting declarations (lemmas, instances)
  • weak_duality theorem — Weak duality (pointwise). Any dual-feasible objective value lower-bounds any primal-feasible objective value.
    E :
    Type u_1
    shared
    F :
    Type u_2
    shared
    P :
    shared
    x :
    E
    y :
    F
    hx :
    P.PrimalFeasible x
    hy :
    P.DualFeasible y
    ⟪P.b, y⟫ ≤ ⟪P.c, x⟫
    Proof (Lean source)
    theorem weak_duality {x : E} {y : F} (hx : P.PrimalFeasible x) (hy : P.DualFeasible y) : ⟪P.b, y⟫ ≤ ⟪P.c, x⟫ := by -- Dual feasibility says `0 ≤ ⟪x, c - Aᵀ y⟫` for `x ∈ K`. have h0 : 0 ≤ ⟪x, P.c - (adjoint P.A) y⟫ := ProperCone.mem_innerDual.mp hy hx.2 have e1 : ⟪x, P.c - (adjoint P.A) y⟫ = ⟪x, P.c⟫ - ⟪P.A x, y⟫ := by rw [inner_sub_right, ContinuousLinearMap.adjoint_inner_right] rw [e1, hx.1] at h0 -- h0 : 0 ≤ ⟪x, P.c⟫ - ⟪P.b, y⟫ have ec := real_inner_comm x P.c linarith
    Causalean.PartialID.ConicProgram.weak_duality · Causalean/PO/ID/Partial/LP/ConicDuality.lean:94
  • dualValue_le_primalValue theorem — Weak duality (value form). When both programs are feasible, dualValue ≤ primalValue. (Boundedness is not needed: the pointwise bound exhibits primalValue as an explicit upper bound for the dual values.)
    E :
    Type u_1
    shared
    F :
    Type u_2
    shared
    P :
    shared
    hP :
    {x | P.PrimalFeasible x}.Nonempty
    hD :
    {y | P.DualFeasible y}.Nonempty
    P.dualValue ≤ P.primalValue
    Proof (Lean source)
    theorem dualValue_le_primalValue (hP : {x | P.PrimalFeasible x}.Nonempty) (hD : {y | P.DualFeasible y}.Nonempty) : P.dualValue ≤ P.primalValue := by rw [dualValue, primalValue] refine csSup_le (hD.image _) ?_ rintro _ ⟨y, hy, rfl⟩ refine le_csInf (hP.image _) ?_ rintro _ ⟨x, hx, rfl⟩ exact P.weak_duality hx hy
    Causalean.PartialID.ConicProgram.dualValue_le_primalValue · Causalean/PO/ID/Partial/LP/ConicDuality.lean:109