Sundogcert/SATNPHard.lean — MILESTONE 1 of the 3SAT ≤ 3DM marathon.
WHAT THIS FILE PROVIDES (the FOUNDATION — definitions + concrete validation, no reduction yet):
* Literal n — a variable index Fin n plus a sign (true = xᵢ, false = ¬xᵢ).
* Assignment n — a Boolean assignment Fin n → Bool.
* evalLiteral — evaluate one literal under an assignment.
* Clause n — an ORDERED triple of literals (Fin 3 → Literal n; cleaner than a
Finset for the downstream gadget's variable-wheel / clause indexing).
* clauseSat — a clause is satisfied iff at least one of its 3 literals is true.
* Formula n m — a 3-CNF formula: m indexed clauses.
* formulaSat — every clause holds.
* Satisfiable — 3-SAT: some assignment satisfies the formula.
Decidability of clauseSat/formulaSat/Satisfiable on concrete instances is AUTOMATIC: the
∃/∀ range over Fin _ and Assignment n = Fin n → Bool (Fintypes with DecidableEq),
and evalLiteral … = true is decidable. This lets decide kernel-reduce the two concrete
examples below — AXIOM-CLEAN (no Lean.ofReduceBool; we use decide, never native_decide).
CONCRETE VALIDATION (locks the encoding):
* ex_sat — Satisfiable fSat for fSat (n=2, m=1, clause x₀ ∨ x₁ ∨ x₀).
* ex_unsat — ¬ Satisfiable fUnsat for fUnsat (n=1, m=2, clauses x₀∨x₀∨x₀,
¬x₀∨¬x₀∨¬x₀).
THE IMPORTED WALL (named, NOT proved — mathlib has no complexity framework):
* the NP complexity class itself, and poly-time-ness of any reduction;
* 3SAT's OWN NP-hardness — Cook–Levin, the DEEP TERMINAL WALL, a multi-year formalization,
named forever as the ultimate source of every Karp-reduction hardness claim in this chain.
STANDING LIMIT: this file defines the 3SAT problem and validates the encoding. The gadget
reduction (variable wheel, clause gadget, garbage) landing on Sundog.MatchingNPHard.ThreeDM,
and its correctness, is the work to come — milestones 2+ of 3SAT ≤ 3DM ≤ X3C ≤ Decodes.
A literal: a variable index plus a sign (true = positive xᵢ, false = negated).
Equations
- Sundog.SATNPHard.Literal n = (Fin n × Bool)
Instances For
A Boolean assignment.
Equations
- Sundog.SATNPHard.Assignment n = (Fin n → Bool)
Instances For
Evaluate a literal under an assignment.
Instances For
A 3-clause: an ORDERED triple of literals (Fin 3 → Literal — cleaner than a Finset
for the downstream gadget's indexing).
Equations
- Sundog.SATNPHard.Clause n = (Fin 3 → Sundog.SATNPHard.Literal n)
Instances For
A clause is satisfied iff at least one of its 3 literals is true.
Equations
- Sundog.SATNPHard.clauseSat a c = ∃ (k : Fin 3), Sundog.SATNPHard.evalLiteral a (c k) = true
Instances For
A 3-CNF formula: m clauses, indexed.
Equations
- Sundog.SATNPHard.Formula n m = (Fin m → Sundog.SATNPHard.Clause n)
Instances For
A formula is satisfied iff every clause is.
Equations
- Sundog.SATNPHard.formulaSat a f = ∀ (k : Fin m), Sundog.SATNPHard.clauseSat a (f k)
Instances For
3-SAT: a formula is satisfiable iff some assignment satisfies it.
Equations
Instances For
Decidability. #
`evalLiteral … = true` is decidable (`DecidableEq Bool`); the bounded `∃`/`∀` over `Fin _`
and `Assignment n = Fin n → Bool` (a Fintype) then make `clauseSat`/`formulaSat`/`Satisfiable`
decidable via `Fintype.decidableExistsFintype` / `Fintype.decidableForallFintype`. These
instances let `decide` kernel-reduce the concrete examples below — no `native_decide`.
Concrete validation (A): a SATISFIABLE formula. #
`n = 2, m = 1`; the single clause is `x₀ ∨ x₁ ∨ x₀`, i.e. literals
`(0, true), (1, true), (0, true)`. Satisfiable: take `a = ![true, true]` (or any `a` with
`a 0 = true`). `∃` ranges over the 4 assignments of `Fin 2 → Bool` — decidable.
The satisfiable formula with one clause.
Instances For
Concrete validation (B): an UNSATISFIABLE formula. #
`n = 1, m = 2`; clauses `x₀ ∨ x₀ ∨ x₀` and `¬x₀ ∨ ¬x₀ ∨ ¬x₀`. No assignment of the single
variable can satisfy both. `¬∃` ranges over the 2 assignments of `Fin 1 → Bool` —
decidable.
The unsatisfiable formula with the two contradictory clauses.
Instances For
Axiom audit. #
Expect `[propext, Classical.choice, Quot.sound]` (or a subset) — NO `sorryAx`, and NO
`Lean.ofReduceBool` (the latter would signal a `native_decide`, which we deliberately avoid).