Finite Standard-Form Primal and Dual Linear Programs
Definitionpd_finite_lpThis module fixes the finite standard-form primal–dual pair underlying the online primal–dual method.
A finite standard-form pair consists of a coefficient matrix indexed by primal variables and constraints , a right-hand side , and a cost vector . The primal program minimizes subject to
and its dual maximizes subject to
The module defines both constraint values, both objectives, and the two feasibility predicates, together with the two-sided approximate complementary-slackness conditions with slack factor on primal variables and on dual variables. The extra nonnegativity of , , and that makes the pair a covering primal with packing dual is recorded as a separate predicate.
This is the shared interface through which the mission states weak duality, prefix feasibility, and the failure certificate; the covering–packing subclass is the one instantiated by the unrelated-machines linear program.
Formalization Note The index types and are arbitrary, with a Fintype instance assumed exactly where a finite sum is formed; no nonemptiness is assumed, and no sign conditions are built into the base structure.
import Mathlib.Data.Fintype.BigOperators
import Mathlib.Data.Real.Basic
namespace PrimalDual
open scoped BigOperators
/--
A finite standard-form primal/dual pair. The primal variables are indexed by `ι`,
the primal constraints (and dual variables) by `κ`.
-/
structure FinitePrimalDual (ι κ : Type*) where
coeff : ι → κ → ℝ
rhs : κ → ℝ
cost : ι → ℝ
namespace FinitePrimalDual
variable {ι κ : Type*} [Fintype ι] [Fintype κ]
/-- The value of primal constraint `j` at a primal vector `x`. -/
def primalConstraintValue (P : FinitePrimalDual ι κ) (x : ι → ℝ) (j : κ) : ℝ :=
∑ i, P.coeff i j * x i
/-- The value of dual constraint `i` at a dual vector `y`. -/
def dualConstraintValue (P : FinitePrimalDual ι κ) (y : κ → ℝ) (i : ι) : ℝ :=
∑ j, P.coeff i j * y j
/-- The minimization objective of the primal program. -/
def primalObjective (P : FinitePrimalDual ι κ) (x : ι → ℝ) : ℝ :=
∑ i, P.cost i * x i
/-- The maximization objective of the dual program. -/
def dualObjective (P : FinitePrimalDual ι κ) (y : κ → ℝ) : ℝ :=
∑ j, P.rhs j * y j
/-- Feasibility for the standard-form primal: `x >= 0` and `A x >= b`. -/
def PrimalFeasible (P : FinitePrimalDual ι κ) (x : ι → ℝ) : Prop :=
(∀ i, 0 ≤ x i) ∧ ∀ j, P.rhs j ≤ P.primalConstraintValue x j
/-- Feasibility for the standard-form dual: `y >= 0` and `A^T y <= c`. -/
def DualFeasible (P : FinitePrimalDual ι κ) (y : κ → ℝ) : Prop :=
(∀ j, 0 ≤ y j) ∧ ∀ i, P.dualConstraintValue y i ≤ P.cost i
/--
The two-sided primal-variable condition from approximate complementary slackness:
every positive primal variable has a dual constraint within a factor `α` of tight.
-/
def SatisfiesPrimalApproxCS (P : FinitePrimalDual ι κ) (α : ℝ)
(x : ι → ℝ) (y : κ → ℝ) : Prop :=
∀ i, 0 < x i →
P.cost i / α ≤ P.dualConstraintValue y i ∧
P.dualConstraintValue y i ≤ P.cost i
/--
The two-sided dual-variable condition from approximate complementary slackness:
every positive dual variable has a primal constraint within a factor `β` of tight.
-/
def SatisfiesDualApproxCS (P : FinitePrimalDual ι κ) (β : ℝ)
(x : ι → ℝ) (y : κ → ℝ) : Prop :=
∀ j, 0 < y j →
P.rhs j ≤ P.primalConstraintValue x j ∧
P.primalConstraintValue x j ≤ β * P.rhs j
/--
The additional nonnegativity assumptions that make a standard-form pair a
covering-primal/packing-dual pair. Weak duality and approximate complementary
slackness do not require these assumptions.
-/
structure IsCoveringPacking (P : FinitePrimalDual ι κ) : Prop where
coeff_nonneg : ∀ i j, 0 ≤ P.coeff i j
rhs_nonneg : ∀ j, 0 ≤ P.rhs j
cost_nonneg : ∀ i, 0 ≤ P.cost i
end FinitePrimalDual
end PrimalDual
Read-back
What the Lean code literally says, in plain math · gpt-5
PrimalDual.FinitePrimalDual: For arbitrary types and , with no finiteness, nonemptiness, or other typeclass assumptions, a finite-primal-dual datum consists of three unrestricted real-valued functions: coefficients , a right-hand side , and a cost . No sign or boundedness conditions are imposed. Either indexing type may be empty or infinite; for an empty domain the corresponding functions are the unique empty-domain functions.
PrimalDual.FinitePrimalDual.primalConstraintValue: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum with coefficients , an arbitrary vector , and an index , the primal constraint value is the real number . Neither nor is assumed nonnegative. If is empty, the sum is ; if is empty, there is no index at which this function can be evaluated.
PrimalDual.FinitePrimalDual.dualConstraintValue: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum with coefficients , an arbitrary vector , and an index , the dual constraint value is the real number . Neither nor is assumed nonnegative. If is empty, the sum is ; if is empty, there is no index at which this function can be evaluated.
PrimalDual.FinitePrimalDual.primalObjective: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum with cost , and an arbitrary vector , the primal objective is . No sign or feasibility assumptions are imposed on or . If is empty, this objective equals .
PrimalDual.FinitePrimalDual.dualObjective: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum with right-hand side , and an arbitrary vector , the dual objective is . No sign or feasibility assumptions are imposed on or . If is empty, this objective equals .
PrimalDual.FinitePrimalDual.PrimalFeasible: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum , and an arbitrary vector , primal feasibility is exactly the conjunction and . No separate sign assumptions are imposed on or , and does not occur in the condition. If is empty, the first clause is vacuous and every displayed sum is , so feasibility reduces to for every ; if is empty, the second clause is vacuous; if both are empty, the proposition holds.
PrimalDual.FinitePrimalDual.DualFeasible: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum , and an arbitrary vector , dual feasibility is exactly the conjunction and . No separate sign assumptions are imposed on or , and does not occur in the condition. If is empty, the first clause is vacuous and every displayed sum is , so feasibility reduces to for every ; if is empty, the second clause is vacuous; if both are empty, the proposition holds.
PrimalDual.FinitePrimalDual.SatisfiesPrimalApproxCS: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum , an arbitrary real number , and arbitrary vectors and , this proposition asserts that for every , implies both and . It assumes neither primal nor dual feasibility and imposes nothing at indices with ; hence it holds vacuously if is empty or has no positive component. The parameter may be any real number, including zero or a negative number; division is total, so . If is empty, each sum is .
PrimalDual.FinitePrimalDual.SatisfiesDualApproxCS: For arbitrary types , a chosen Fintype structure on but no finiteness assumption on , a datum , an arbitrary real number , and arbitrary vectors and , this proposition asserts that for every , implies both and . It assumes neither primal nor dual feasibility and imposes nothing at indices with ; hence it holds vacuously if is empty or has no positive component. The parameter may be any real number, including zero or a negative number. If is empty, each sum is .
PrimalDual.FinitePrimalDual.IsCoveringPacking: For arbitrary types , with no finiteness, nonemptiness, or other typeclass assumptions, and a datum , this proposition is a structure whose inhabitant supplies all three proofs , , and . If is empty, the coefficient and cost conditions are vacuous; if is empty, the coefficient and right-hand-side conditions are vacuous; if both are empty, all three conditions are vacuous.
Confirmed by the mission captain (proposal self-audit).