PO.ID.Partial.LP

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

Conic­Duality 9 core · 2 supporting This file develops general conic linear-programming duality over real Hilbert spaces. ★ farkas★ strong_duality_primal_attained★ strong_duality_zero_gap

Conic Duality

This file develops general conic linear-programming duality over real Hilbert spaces. It 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 declarations have no causal or partial-identification hypotheses and no consumer in this subtree. 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

A conic linear program on real Hilbert decision and constraint spaces stores a proper constraint cone, a continuous linear constraint operator, its right-hand side, and an objective direction.

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

Primal feasibility for a conic program on real Hilbert decision and constraint spaces means that a candidate decision vector satisfies the linear equality constraint and belongs to the 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:66 · uses ConicProgram
def DualFeasible reviewed
Causalean.PartialID.ConicProgram

Dual feasibility for a conic program on real Hilbert decision and constraint spaces means that a candidate dual multiplier leaves a reduced cost in the dual 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:75 · uses ConicProgram
def primalValue reviewed
Causalean.PartialID.ConicProgram

The primal optimal value of a conic program on real Hilbert decision and constraint spaces is the infimum of its objective 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:84 · uses ConicProgram
def dualValue reviewed
Causalean.PartialID.ConicProgram

The dual optimal value of a conic program on real Hilbert decision and constraint spaces is the supremum of the pairing 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:92 · uses ConicProgram
theorem farkas reviewed
Causalean.PartialID.ConicProgram

Farkas alternative. For a conic program on real Hilbert decision and constraint spaces, a target point lies in the closed image cone exactly when it pairs nonnegatively with every dual direction whose pullback lies in the dual constraint cone.

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:132 · uses ConicProgram
def augmentedImage reviewed
Causalean.PartialID.ConicProgram

The augmented image of a conic program on real Hilbert decision and constraint spaces pairs each feasible cone vector's constraint image with its objective value.

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:147 · uses ConicProgram
theorem strong_duality_primal_attained reviewed
Causalean.PartialID.ConicProgram

Strong duality I — primal attainment. For a conic program on real Hilbert decision and constraint spaces, nonempty primal feasibility, a lower bound on feasible objective values, and closedness of the augmented image ensure that a primal-feasible point attains the primal optimal value.

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:157 · uses ConicProgram , PrimalFeasible , augmentedImage , primalValue
theorem strong_duality_zero_gap reviewed
Causalean.PartialID.ConicProgram

Strong duality II — zero gap. For a conic program on real Hilbert decision and constraint spaces, nonempty primal feasibility, a lower bound on feasible objective values, and closedness of the augmented image imply equality of the primal and dual optimal values.

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). For a conic program on real Hilbert decision and constraint spaces, a primal-feasible decision vector and a dual-feasible multiplier satisfy the dual objective value being no larger than the primal 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:100
  • dualValue_le_primalValue theorem — Weak duality (value form). For a conic program on real Hilbert decision and constraint spaces, nonempty primal feasibility and nonempty dual feasibility imply that the dual optimal value is no larger than the primal optimal value. Boundedness is unnecessary because pointwise weak duality gives an explicit bound.
    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:117