Prove2Me
Navigate
DiscoverCollectionsFormalpediaBlogsUsersMomentumMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

Cook's classes P\mathbf{P}P, NP\mathbf{NP}NP, E\mathbf{E}E, p-reducibility, NP\mathbf{NP}NP-completeness, and the languages SAT and 3-SAT over {0,1}\{0,1\}{0,1}

Definition
PvsNP

by korbonits · Sep 8, 2026 · Mathlib 0df444a (Lean v4.33.1)

complexity-theorymillennium-prizenp-completenessp-vs-nppolynomial-timesatisfiabilityturing-machines

This bundle fixes, in the namespace PvsNP, the objects of Stephen Cook's official description of the Clay Millennium Prize Problem The P versus NP problem: the classes P\mathbf{P}P and NP\mathbf{NP}NP (p. 2), polynomial-time reducibility and NP\mathbf{NP}NP-completeness (Definitions 3 and 4, p. 4), the exponential-time class E\mathbf{E}E (p. 9), and the languages Satisfiability and 3-SAT (p. 5).

Strings and languages. The alphabet is Σ={0,1}\Sigma = \{0,1\}Σ={0,1}. Str is the set Σ∗\Sigma^*Σ∗ of binary strings, ∣w∣|w|∣w∣ is the length of www, and a language is a subset L⊆Σ∗L \subseteq \Sigma^*L⊆Σ∗ (Language Bool). Cook (p. 2) notes that the problem is independent of the size of the alphabet as long as it has at least two symbols.

Machines and running time. A machine is Mathlib's bundled multi-stack machine Turing.FinTM2: finitely many stacks, among them an input stack and an output stack, a finite set of program labels, a finite internal memory, and a finite input alphabet. The program assigns to each label a statement, which is a finite tree of push/pop/peek/load/branch operations ending in a jump to a label or in a halt. The machine is started with the input string on its input stack, all other stacks empty, the initial memory value and the main label; one step executes one statement. It outputs vvv within ttt steps if after exactly s≤ts \le ts≤t steps it is in the halting configuration with vvv on the output stack, every other stack empty and the memory reset to its initial value. Mathlib's Turing.TM2ComputableInPolyTime ea eb f bundles such a machine, identifications of its input and output alphabets with those of the encodings ea, eb, and a polynomial ppp with natural coefficients such that for every aaa, on input ea a the machine outputs eb (f a) within p(∣ea a∣)p(|\mathtt{ea}\ a|)p(∣ea a∣) steps; Turing.TM2ComputableInTime is the same with an arbitrary time function t:N→Nt : \mathbb{N} \to \mathbb{N}t:N→N in place of ppp. Cook's bound TM(n)≤nk+kT_M(n) \le n^k + kTM​(n)≤nk+k is equivalent to a bound by a polynomial with natural coefficients.

  • PolyTimeDecider χ (Cook, p. 1–2: "MMM runs in polynomial time", with χ(w)=1\chi(w) = 1χ(w)=1 iff MMM accepts www): there is a polynomial-time machine computing χ:Σ∗→{0,1}\chi : \Sigma^* \to \{0,1\}χ:Σ∗→{0,1}, the input encoding being the identity on Σ∗\Sigma^*Σ∗ and the output encoding b↦[b]b \mapsto [b]b↦[b].
  • P (Cook, p. 2): P={L∣∃χ, χ polynomial-time and ∀w, w∈L  ⟺  χ(w)=1}\mathbf{P} = \{L \mid \exists \chi,\ \chi \text{ polynomial-time and } \forall w,\ w \in L \iff \chi(w) = 1\}P={L∣∃χ, χ polynomial-time and ∀w, w∈L⟺χ(w)=1}.
  • encodePair (w, y) is Cook's string w#yw \# yw#y: the symbols of www tagged as "left", followed by the symbols of yyy tagged as "right", over the four-symbol alphabet {0,1}⊔{0,1}\{0,1\} \sqcup \{0,1\}{0,1}⊔{0,1}; its length is ∣w∣+∣y∣|w| + |y|∣w∣+∣y∣.
  • PolyTimeChecker R (Cook, p. 2: "RRR is polynomial-time iff LR∈PL_R \in \mathbf{P}LR​∈P"): the indicator R:Σ∗×Σ∗→{0,1}R : \Sigma^* \times \Sigma^* \to \{0,1\}R:Σ∗×Σ∗→{0,1} of a checking relation is computed by a polynomial-time machine on the input w#yw \# yw#y, so within p(∣w∣+∣y∣)p(|w| + |y|)p(∣w∣+∣y∣) steps.
  • NP (Cook, p. 2): L∈NPL \in \mathbf{NP}L∈NP iff there are k∈Nk \in \mathbb{N}k∈N and a polynomial-time checking relation RRR such that for all w∈Σ∗w \in \Sigma^*w∈Σ∗, w∈L  ⟺  ∃y (∣y∣≤∣w∣k and R(w,y))w \in L \iff \exists y\,(|y| \le |w|^k \text{ and } R(w,y))w∈L⟺∃y(∣y∣≤∣w∣k and R(w,y)).
  • PolyTimeComputable f (Cook, Definition 3): f:Σ∗→Σ∗f : \Sigma^* \to \Sigma^*f:Σ∗→Σ∗ is computed by a polynomial-time machine with identity encodings on both sides.
  • PReducible L₁ L₂ (Cook, Definition 3): L1≤pL2L_1 \le_p L_2L1​≤p​L2​ iff there is a polynomial-time computable fff with x∈L1  ⟺  f(x)∈L2x \in L_1 \iff f(x) \in L_2x∈L1​⟺f(x)∈L2​ for all x∈Σ∗x \in \Sigma^*x∈Σ∗.
  • NPComplete L (Cook, Definition 4): L∈NPL \in \mathbf{NP}L∈NP and L′≤pLL' \le_p LL′≤p​L for every L′∈NPL' \in \mathbf{NP}L′∈NP.
  • E (Cook, p. 9: "L=L(M)L = L(M)L=L(M) for some Turing machine MMM with TM(n)=O(2cn)T_M(n) = O(2^{cn})TM​(n)=O(2cn) for some c>0c > 0c>0"): L∈EL \in \mathbf{E}L∈E iff there are χ\chiχ and a machine computing χ\chiχ whose time function ttt satisfies t(n)≤C⋅2cnt(n) \le C \cdot 2^{cn}t(n)≤C⋅2cn for all nnn, for some c,C∈Nc, C \in \mathbb{N}c,C∈N, with L={w∣χ(w)=1}L = \{w \mid \chi(w) = 1\}L={w∣χ(w)=1}.

Satisfiability. A literal is a pair (s,i)∈{0,1}×N(s, i) \in \{0,1\} \times \mathbb{N}(s,i)∈{0,1}×N, read as the variable xix_ixi​ if s=1s = 1s=1 and as ¬xi\neg x_i¬xi​ if s=0s = 0s=0; a clause is a list of literals; a CNF formula is a list of clauses. Under a truth assignment τ:N→{0,1}\tau : \mathbb{N} \to \{0,1\}τ:N→{0,1} the literal (s,i)(s,i)(s,i) has value τ(i)\tau(i)τ(i) if s=1s = 1s=1 and ¬τ(i)\neg\tau(i)¬τ(i) if s=0s = 0s=0 (evalLiteral); a clause is true iff at least one of its literals is (evalClause; the empty clause is false); a formula is true iff all its clauses are (evalCNF; the empty formula is true). Satisfiable F means that some τ\tauτ makes FFF true. The binary coding writes every symbol as a two-bit block: encodeLiteral (s,i) is the block 0s0s0s, then one block 0b0b0b for each binary digit bbb of iii (least significant first, no digits for i=0i = 0i=0), then the end-of-literal block 101010; encodeClause is the concatenation of the codes of its literals followed by the end-of-clause block 111111; encodeCNF is the concatenation of the codes of the clauses. SAT is the set of strings that are the code of some satisfiable formula, and ThreeSAT the set of codes of satisfiable formulas all of whose clauses have exactly three literals.

Formalization Note The alphabet is fixed to {0,1}\{0,1\}{0,1} throughout (certificates included), following Cook's remark that the problem does not depend on the alphabet. The machine model is Mathlib's multi-stack machine rather than Cook's one-tape Turing machine of the appendix; the two simulate each other with polynomial overhead, and each statement performs a bounded number of stack operations, so all the classes defined here coincide with the standard ones. A machine "outputs" only in the cleaned-up halting configuration (output alone on the output stack, other stacks empty, memory reset); any machine can be made to do this with polynomially many extra steps. In the certificate bound ∣y∣≤∣w∣k|y| \le |w|^k∣y∣≤∣w∣k Lean's convention 00=10^0 = 100=1 applies. Satisfiability is satisfiability of CNF formulas with the specific coding encodeCNF; strings that are not the code of a formula belong neither to SAT nor to ThreeSAT. Assignments are total functions on all variable indices; in 3-SAT clauses have exactly three literals and may repeat variables.

Definition code
import Mathlib

/-!
S. Cook, *The P versus NP problem*, Clay Mathematics Institute Millennium Prize Problem
description (2000), pp. 1–5 and p. 9.

The objects of Cook's Section 1: the classes `P` (p. 2) and `NP` (p. 2, via polynomial-time
checking relations), polynomial-time (Karp) reducibility `≤ₚ` (Definition 3), `NP`-completeness
(Definition 4), the exponential-time class `E` (p. 9), and the languages Satisfiability and 3-SAT
(p. 5) as sets of binary strings coding CNF formulas.

Conventions.  The alphabet is `Σ = {0,1} = Bool` throughout (Cook, p. 2: the problem is
independent of the alphabet size, provided `|Σ| ≥ 2`); a string is a `List Bool` and a language
is a `Language Bool = Set (List Bool)`.  The machine model is Mathlib's bundled multi-stack
machine `Turing.FinTM2` (finitely many stacks, finitely many program labels, finite internal
memory, finite input alphabet), and "computable in polynomial time" is Mathlib's
`Turing.TM2ComputableInPolyTime`: the machine, started with the input on its input stack, halts
within `p(|input|)` steps (`p` a polynomial with natural coefficients) with the required output
on its output stack, every other stack empty and the internal memory reset.  Each step executes
one program statement, which is a fixed finite tree of stack pushes/pops/peeks, so this step
count is within a constant factor of the number of elementary operations.  Multi-stack machines
and Turing machines simulate each other with polynomial overhead, so `P`, `NP`, `≤ₚ` and
`NP`-completeness below are the standard classes (Cook, p. 1: "`P` is a robust class and has
equivalent definitions over a large class of computer models").
-/

namespace PvsNP

open Computability Turing

/-- A binary string `w ∈ Σ*` with `Σ = {0,1}`. -/
abbrev Str := List Bool

/-! ### Polynomial-time computation -/

/-- Cook, p. 1–2: a decision procedure `χ : Σ* → {0,1}` runs in polynomial time.  There is a
bundled multi-stack machine and a polynomial `p` (natural coefficients) such that, for every
string `w`, the machine started with `w` on its input stack halts within `p(|w|)` steps with the
single symbol `χ w` on its output stack.  `χ w = true` means "accept". -/
def PolyTimeDecider (χ : Str → Bool) : Prop :=
  Nonempty (TM2ComputableInPolyTime (id : Str → Str) encodeBool χ)

/-- Cook, p. 2: the class `P` of languages `L ⊆ Σ*` accepted by some Turing machine that runs in
polynomial time, i.e. `L = {w | χ w = true}` for some polynomial-time decision procedure `χ`. -/
def P : Set (Language Bool) :=
  {L | ∃ χ : Str → Bool, PolyTimeDecider χ ∧ ∀ w, w ∈ L ↔ χ w = true}

/-- Cook, p. 2: the string `w#y` coding a pair `(w, y)` of strings.  The symbols of `w` are tagged
with `Sum.inl` and those of `y` with `Sum.inr`, so the input alphabet is `Bool ⊕ Bool` (four
symbols) and the boundary between `w` and `y` is visible to the machine, exactly as with Cook's
separator symbol `#`.  Its length is `|w| + |y|`. -/
def encodePair (x : Str × Str) : List (Bool ⊕ Bool) :=
  x.1.map Sum.inl ++ x.2.map Sum.inr

/-- Cook, p. 2: a checking relation `R ⊆ Σ* × Σ*`, given as its indicator `R : Σ* × Σ* → {0,1}`,
is polynomial-time: the language `L_R = {w#y | R(w,y)}` is decided by a multi-stack machine
within `p(|w| + |y|)` steps for some polynomial `p`. -/
def PolyTimeChecker (R : Str × Str → Bool) : Prop :=
  Nonempty (TM2ComputableInPolyTime encodePair encodeBool R)

/-- Cook, p. 2: the class `NP`.  A language `L` is in `NP` iff there are `k ∈ ℕ` and a
polynomial-time checking relation `R` such that for all `w ∈ Σ*`,
`w ∈ L ⟺ ∃ y (|y| ≤ |w|^k and R(w,y))`. -/
def NP : Set (Language Bool) :=
  {L | ∃ (R : Str × Str → Bool) (k : ℕ), PolyTimeChecker R ∧
        ∀ w, w ∈ L ↔ ∃ y : Str, y.length ≤ w.length ^ k ∧ R (w, y) = true}

/-- Cook, Definition 3: a function `f : Σ* → Σ*` is polynomial-time computable: a multi-stack
machine started with `w` on its input stack halts within `p(|w|)` steps with `f w` on its output
stack, for some polynomial `p`. -/
def PolyTimeComputable (f : Str → Str) : Prop :=
  Nonempty (TM2ComputableInPolyTime (id : Str → Str) (id : Str → Str) f)

/-- Cook, Definition 3: `L₁ ≤ₚ L₂` (`L₁` is p-reducible to `L₂`) iff there is a polynomial-time
computable `f : Σ* → Σ*` with `x ∈ L₁ ⟺ f(x) ∈ L₂` for all `x ∈ Σ*`. -/
def PReducible (L₁ L₂ : Language Bool) : Prop :=
  ∃ f : Str → Str, PolyTimeComputable f ∧ ∀ x, x ∈ L₁ ↔ f x ∈ L₂

/-- Cook, Definition 4: `L` is `NP`-complete iff `L ∈ NP` and `L' ≤ₚ L` for every `L' ∈ NP`. -/
def NPComplete (L : Language Bool) : Prop :=
  L ∈ NP ∧ ∀ L' ∈ NP, PReducible L' L

/-- Cook, p. 9: the class `E` of languages recognizable in exponential time, `L = L(M)` for a
Turing machine `M` with worst-case running time `T_M(n) = O(2^{cn})` for some `c`.  Here the
machine is a multi-stack machine with a time function `t : ℕ → ℕ` (a bound on the number of steps
on inputs of length `n`) satisfying `t n ≤ C · 2^{c·n}` for all `n`, for some constants `c, C`. -/
def E : Set (Language Bool) :=
  {L | ∃ χ : Str → Bool,
        (∃ M : TM2ComputableInTime (id : Str → Str) encodeBool χ,
          ∃ c C : ℕ, ∀ n, M.time n ≤ C * 2 ^ (c * n)) ∧
        ∀ w, w ∈ L ↔ χ w = true}

/-! ### Satisfiability -/

/-- A propositional literal `(s, i)`: the variable `xᵢ` if `s = true`, its negation `¬xᵢ` if
`s = false`. -/
abbrev Literal := Bool × ℕ

/-- A clause: a disjunction of literals, given as a list. -/
abbrev Clause := List Literal

/-- A formula in conjunctive normal form (CNF): a conjunction of clauses, given as a list. -/
abbrev CNF := List Clause

/-- The truth value of a literal under a truth assignment `τ : ℕ → Bool` to the variables. -/
def evalLiteral (τ : ℕ → Bool) (l : Literal) : Bool :=
  if l.1 then τ l.2 else !τ l.2

/-- A clause is true under `τ` iff at least one of its literals is (the empty clause is false). -/
def evalClause (τ : ℕ → Bool) (c : Clause) : Bool :=
  c.any (evalLiteral τ)

/-- A CNF formula is true under `τ` iff all of its clauses are (the empty formula is true). -/
def evalCNF (τ : ℕ → Bool) (F : CNF) : Bool :=
  F.all (evalClause τ)

/-- Cook, p. 5: a formula `F` is satisfiable iff some truth assignment makes it true. -/
def Satisfiable (F : CNF) : Prop :=
  ∃ τ : ℕ → Bool, evalCNF τ F = true

/-- Binary coding of a literal `(s, i)`: the sign bit followed by the binary digits of `i`
(least significant first, no leading zeros), each written as the two-bit block `0b`, followed by
the end-of-literal marker `10`.  Its length is `2 · (⌈log₂(i+1)⌉ + 2)`. -/
def encodeLiteral (l : Literal) : Str :=
  ((l.1 :: Nat.bits l.2).flatMap fun b => [false, b]) ++ [true, false]

/-- Binary coding of a clause: the codes of its literals in order, followed by the end-of-clause
marker `11`. -/
def encodeClause (c : Clause) : Str :=
  c.flatMap encodeLiteral ++ [true, true]

/-- Cook, p. 5, "standard coding methods": the binary code of a CNF formula is the concatenation
of the codes of its clauses.  Every symbol is a two-bit block (`0b` = data bit `b`, `10` = end of
literal, `11` = end of clause), so the code can be parsed unambiguously from left to right, and
its length is linear in the number of literals times the number of bits of the variable indices.
The empty formula is coded by the empty string. -/
def encodeCNF (F : CNF) : Str :=
  F.flatMap encodeClause

/-- Cook, p. 5: Satisfiability, as a language over `{0,1}`: the set of strings coding a
satisfiable CNF formula.  Strings that code no formula are not in `SAT`. -/
def SAT : Language Bool :=
  {w | ∃ F : CNF, encodeCNF F = w ∧ Satisfiable F}

/-- Cook, p. 5: 3-SAT, the set of strings coding a satisfiable CNF formula in which every clause
has exactly three literals. -/
def ThreeSAT : Language Bool :=
  {w | ∃ F : CNF, encodeCNF F = w ∧ (∀ c ∈ F, c.length = 3) ∧ Satisfiable F}

end PvsNP
Source
S. Cook, The P versus NP problem, Clay Mathematics Institute Millennium Prize Problem description (2000), https://www.claymath.org/wp-content/uploads/2022/06/pvsnp.pdf, p. 1–2 (Turing machines, polynomial time, the class P, checking relations, the class NP), p. 4 (Definitions 3 and 4: p-reducibility and NP-completeness), p. 5 (Satisfiability and 3-SAT), p. 9 (the class E). Machine model: Mathlib `Turing.FinTM2` and `Turing.TM2ComputableInPolyTime` (Mathlib/Computability/TuringMachine/Computable.lean, P. Spelier and D. van Gent, 2020)
Read-back

What the Lean code literally says, in plain math · claude-fable-5-1

Str

Str\mathrm{Str}Str is an abbreviation for the type of finite lists of Booleans, i.e. finite bit strings w=(w1,…,wn)w = (w_1,\dots,w_n)w=(w1​,…,wn​) with each wi∈{false,true}w_i \in \{\mathsf{false},\mathsf{true}\}wi​∈{false,true}, including the empty string [ ][\,][] of length 000. Its length is written ∣w∣|w|∣w∣. (Everywhere below, a "language over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}" means an arbitrary subset L⊆StrL \subseteq \mathrm{Str}L⊆Str; membership w∈Lw \in Lw∈L is plain set membership, and no decidability or definability of LLL is assumed.)

PolyTimeDecider

For a total function χ:Str→{false,true}\chi : \mathrm{Str} \to \{\mathsf{false},\mathsf{true}\}χ:Str→{false,true}, PolyTimeDecider(χ)\mathrm{PolyTimeDecider}(\chi)PolyTimeDecider(χ) is the proposition that there exists at least one "polynomial-time machine computing χ\chiχ" in the following exact sense (Mathlib's TM2ComputableInPolyTime with input encoding the identity on bit strings and output encoding b↦[b]b \mapsto [b]b↦[b]). A machine is a bundled multi-stack machine (Mathlib's TM2 model, FinTM2) consisting of: a finite index set KKK of stacks (with decidable equality); two distinguished indices k0∈Kk_0 \in Kk0​∈K (input stack) and k1∈Kk_1 \in Kk1​∈K (output stack), which are allowed to coincide; for each k∈Kk \in Kk∈K a type Γk\Gamma_kΓk​ of stack symbols, where only Γk0\Gamma_{k_0}Γk0​​ is required to be finite; a finite set Λ\LambdaΛ of program labels with a distinguished label main\mathrm{main}main; a finite set Σ\SigmaΣ of internal states with a distinguished initial state s0s_0s0​; and a program mmm assigning to every label ℓ∈Λ\ell \in \Lambdaℓ∈Λ a statement m(ℓ)m(\ell)m(ℓ). A statement is a finite tree built from the constructors: push onto stack kkk the symbol g(v)g(v)g(v), where g:Σ→Γkg : \Sigma \to \Gamma_kg:Σ→Γk​ is an arbitrary function of the current internal state vvv, then continue with a sub-statement; peek at the top symbol of stack kkk (or "empty") and replace the internal state by g(v,top)g(v,\text{top})g(v,top) for an arbitrary function g:Σ×(Γk∪{empty})→Σg : \Sigma \times (\Gamma_k \cup \{\text{empty}\}) \to \Sigmag:Σ×(Γk​∪{empty})→Σ, then continue; pop, which is peek followed by removal of the top symbol of stack kkk (popping an empty stack leaves it empty), then continue; load, replacing the internal state by g(v)g(v)g(v) for an arbitrary g:Σ→Σg : \Sigma \to \Sigmag:Σ→Σ, then continue; branch between two sub-statements according to an arbitrary predicate Σ→{false,true}\Sigma \to \{\mathsf{false},\mathsf{true}\}Σ→{false,true} of the internal state; goto, which sets the current label to g(v)g(v)g(v) for an arbitrary g:Σ→Λg : \Sigma \to \Lambdag:Σ→Λ and ends the statement; and halt, which sets the current label to "none" and ends the statement. A configuration is a triple (current label, which is either some ℓ∈Λ\ell \in \Lambdaℓ∈Λ or "none"; current internal state v∈Σv \in \Sigmav∈Σ; the contents of every stack k∈Kk \in Kk∈K as a finite list over Γk\Gamma_kΓk​ whose first entry is the top of the stack). One step of the machine from a configuration with label ℓ\ellℓ executes the whole statement m(ℓ)m(\ell)m(ℓ) down to its terminating goto or halt (however many pushes, pops, peeks, loads and branches that statement contains) and returns the resulting configuration; a configuration with label "none" has no successor. Time is the number of steps in this sense. The initial configuration on an input list uuu over Γk0\Gamma_{k_0}Γk0​​ has label main\mathrm{main}main, internal state s0s_0s0​, stack k0k_0k0​ equal to uuu (first symbol of uuu on top), and every other stack empty. The halting configuration for an output list ooo over Γk1\Gamma_{k_1}Γk1​​ has label "none", internal state equal to the initial state s0s_0s0​, stack k1k_1k1​ equal to ooo (first symbol on top), and every other stack empty (in particular, if k0≠k1k_0 \neq k_1k0​=k1​ the input stack must have been emptied). Now PolyTimeDecider(χ)\mathrm{PolyTimeDecider}(\chi)PolyTimeDecider(χ) asserts the existence of: such a machine MMM; a bijection ι:Γk0≅{false,true}\iota : \Gamma_{k_0} \cong \{\mathsf{false},\mathsf{true}\}ι:Γk0​​≅{false,true} (so the input alphabet has exactly two symbols); a bijection ω:Γk1≅{false,true}\omega : \Gamma_{k_1} \cong \{\mathsf{false},\mathsf{true}\}ω:Γk1​​≅{false,true}; a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X] with natural-number coefficients; and, for every bit string w∈Strw \in \mathrm{Str}w∈Str, a natural number sss with

s≤p(∣w∣)s \le p(|w|)s≤p(∣w∣)

such that iterating the step function exactly sss times from the initial configuration on input ι−1(w)\iota^{-1}(w)ι−1(w) (the string www transported symbolwise into Γk0\Gamma_{k_0}Γk0​​) yields exactly the halting configuration whose output stack is the one-symbol list [ω−1(χ(w))][\omega^{-1}(\chi(w))][ω−1(χ(w))]; here iteration is understood so that once a configuration has no successor all later iterates are "no configuration", so the requirement says that the machine is not yet halted before step sss and at step sss is in precisely that halting configuration (label none, state s0s_0s0​, stack k1=[ω−1(χ(w))]k_1 = [\omega^{-1}(\chi(w))]k1​=[ω−1(χ(w))], all other stacks empty). Since the initial configuration has a label and the halting one has none, necessarily s≥1s \ge 1s≥1. No computability restriction is placed on the functions ggg inside statements beyond the finiteness of Σ\SigmaΣ, Λ\LambdaΛ and Γk0\Gamma_{k_0}Γk0​​; stacks other than k0k_0k0​ may have infinite symbol types.

P

P\mathrm{P}P is the set of languages L⊆StrL \subseteq \mathrm{Str}L⊆Str over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true} for which there exists a total function χ:Str→{false,true}\chi : \mathrm{Str} \to \{\mathsf{false},\mathsf{true}\}χ:Str→{false,true} such that (i) PolyTimeDecider(χ)\mathrm{PolyTimeDecider}(\chi)PolyTimeDecider(χ) holds, i.e. there exists a bundled multi-stack machine in Mathlib's TM2 model (finitely many stacks; finite input-stack alphabet in bijection with {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}; output-stack alphabet in bijection with {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}; finitely many labels and internal states; one step = full execution of one labelled statement, made of arbitrarily many push/pop/peek/load/branch operations ending in a goto or halt) together with a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X] such that for every w∈Strw \in \mathrm{Str}w∈Str, started with www on the input stack (first symbol on top), initial internal state, all other stacks empty, and label main\mathrm{main}main, the machine reaches after exactly some s≤p(∣w∣)s \le p(|w|)s≤p(∣w∣) steps the configuration with label "none", internal state equal to the initial state, output stack exactly the one-symbol list [χ(w)][\chi(w)][χ(w)] (transported through the alphabet bijection), and all other stacks empty; and (ii) for every w∈Strw \in \mathrm{Str}w∈Str,

w∈L  ⟺  χ(w)=true.w \in L \iff \chi(w) = \mathsf{true}.w∈L⟺χ(w)=true.

So LLL is exactly the set of strings on which χ\chiχ outputs true\mathsf{true}true; nothing is asserted about LLL beyond the existence of such a χ\chiχ and such a machine.

encodePair

For a pair (x,y)(x, y)(x,y) of bit strings, encodePair(x,y)\mathrm{encodePair}(x,y)encodePair(x,y) is the list over the four-element alphabet {false,true}⊔{false,true}\{\mathsf{false},\mathsf{true}\} \sqcup \{\mathsf{false},\mathsf{true}\}{false,true}⊔{false,true} (disjoint union, with left and right copies) obtained by tagging every symbol of xxx as a left-copy symbol, every symbol of yyy as a right-copy symbol, and concatenating:

encodePair(x,y)=(inl x1,…,inl x∣x∣, inr y1,…,inr y∣y∣).\mathrm{encodePair}(x,y) = (\mathrm{inl}\,x_1,\dots,\mathrm{inl}\,x_{|x|},\ \mathrm{inr}\,y_1,\dots,\mathrm{inr}\,y_{|y|}).encodePair(x,y)=(inlx1​,…,inlx∣x∣​, inry1​,…,inry∣y∣​).

Its length is ∣x∣+∣y∣|x| + |y|∣x∣+∣y∣; either component may be empty.

PolyTimeChecker

For a total function R:Str×Str→{false,true}R : \mathrm{Str} \times \mathrm{Str} \to \{\mathsf{false},\mathsf{true}\}R:Str×Str→{false,true}, PolyTimeChecker(R)\mathrm{PolyTimeChecker}(R)PolyTimeChecker(R) is the proposition that there exists at least one machine computing RRR in polynomial time in the following exact sense (Mathlib's TM2ComputableInPolyTime with input encoding encodePair\mathrm{encodePair}encodePair and output encoding b↦[b]b \mapsto [b]b↦[b]). The machine model is Mathlib's bundled TM2 multi-stack machine: a finite index set KKK of stacks (decidable equality), distinguished input index k0k_0k0​ and output index k1k_1k1​ (possibly equal), a symbol type Γk\Gamma_kΓk​ for each stack with only Γk0\Gamma_{k_0}Γk0​​ required finite, a finite label set Λ\LambdaΛ with distinguished label main\mathrm{main}main, a finite internal-state set Σ\SigmaΣ with initial state s0s_0s0​, and a program m:Λ→statementsm : \Lambda \to \text{statements}m:Λ→statements, where a statement is a finite tree of push (push g(v)g(v)g(v) onto a chosen stack, g:Σ→Γkg : \Sigma \to \Gamma_kg:Σ→Γk​ arbitrary), peek (update the state by an arbitrary function of the state and the top symbol-or-empty), pop (peek and then remove the top; popping an empty stack is a no-op on the stack), load (arbitrary state update), branch (on an arbitrary predicate of the state), ending in goto (set label to an arbitrary function of the state) or halt (set label to "none"). A configuration is (label or none, internal state, contents of all stacks as lists with head = top); one step executes the entire statement of the current label; a configuration with label none has no successor; time is the number of steps. PolyTimeChecker(R)\mathrm{PolyTimeChecker}(R)PolyTimeChecker(R) asserts the existence of such a machine, a bijection ι:Γk0≅{false,true}⊔{false,true}\iota : \Gamma_{k_0} \cong \{\mathsf{false},\mathsf{true}\} \sqcup \{\mathsf{false},\mathsf{true}\}ι:Γk0​​≅{false,true}⊔{false,true} (so the input alphabet has exactly four symbols), a bijection ω:Γk1≅{false,true}\omega : \Gamma_{k_1} \cong \{\mathsf{false},\mathsf{true}\}ω:Γk1​​≅{false,true}, a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X] with natural-number coefficients, and for every pair (x,y)∈Str×Str(x,y) \in \mathrm{Str} \times \mathrm{Str}(x,y)∈Str×Str a natural number sss with

s≤p(∣x∣+∣y∣)s \le p(|x| + |y|)s≤p(∣x∣+∣y∣)

such that, starting from the configuration with label main\mathrm{main}main, internal state s0s_0s0​, stack k0k_0k0​ holding ι−1(encodePair(x,y))\iota^{-1}(\mathrm{encodePair}(x,y))ι−1(encodePair(x,y)) (the left-tagged symbols of xxx followed by the right-tagged symbols of yyy, first symbol on top) and all other stacks empty, exactly sss iterations of the step function lead to precisely the configuration with label "none", internal state s0s_0s0​ (the initial state again), stack k1k_1k1​ equal to the one-symbol list [ω−1(R(x,y))][\omega^{-1}(R(x,y))][ω−1(R(x,y))], and every other stack empty (iterates past a halted configuration count as "no configuration", so the machine must halt exactly at step sss in exactly that configuration). Note that the time bound is a polynomial in the combined length ∣x∣+∣y∣|x|+|y|∣x∣+∣y∣, not in ∣x∣|x|∣x∣ alone.

NP

NP\mathrm{NP}NP is the set of languages L⊆StrL \subseteq \mathrm{Str}L⊆Str over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true} for which there exist a total function R:Str×Str→{false,true}R : \mathrm{Str} \times \mathrm{Str} \to \{\mathsf{false},\mathsf{true}\}R:Str×Str→{false,true} and a natural number k∈Nk \in \mathbb{N}k∈N (with k=0k = 0k=0 allowed) such that (i) PolyTimeChecker(R)\mathrm{PolyTimeChecker}(R)PolyTimeChecker(R) holds, i.e. there is a bundled TM2 multi-stack machine (finitely many stacks, finite input alphabet in bijection with the four-element set {false,true}⊔{false,true}\{\mathsf{false},\mathsf{true}\}\sqcup\{\mathsf{false},\mathsf{true}\}{false,true}⊔{false,true}, output alphabet in bijection with {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}, finitely many labels and internal states, one step = complete execution of one labelled statement) and a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X] such that for every (x,y)(x,y)(x,y), started with the tagged concatenation encodePair(x,y)\mathrm{encodePair}(x,y)encodePair(x,y) on the input stack, initial state, other stacks empty, label main\mathrm{main}main, the machine halts after exactly some s≤p(∣x∣+∣y∣)s \le p(|x|+|y|)s≤p(∣x∣+∣y∣) steps in the configuration with label none, internal state equal to the initial state, output stack exactly [R(x,y)][R(x,y)][R(x,y)] (through the alphabet bijection) and all other stacks empty; and (ii) for every w∈Strw \in \mathrm{Str}w∈Str,

w∈L  ⟺  ∃ y∈Str: ∣y∣≤∣w∣k  and  R(w,y)=true.w \in L \iff \exists\, y \in \mathrm{Str}:\ |y| \le |w|^{k} \ \text{ and }\ R(w,y) = \mathsf{true}.w∈L⟺∃y∈Str: ∣y∣≤∣w∣k  and  R(w,y)=true.

Here ∣w∣k|w|^k∣w∣k is natural-number exponentiation with the convention n0=1n^0 = 1n0=1 for all nnn (including 00=10^0 = 100=1); thus for k=0k = 0k=0 the certificate yyy must have length at most 111, and for k≥1k \ge 1k≥1 and w=[ ]w = [\,]w=[] the only admissible certificate is y=[ ]y = [\,]y=[]. The bound on ∣y∣|y|∣y∣ is ≤\le≤, and yyy ranges over all bit strings of that length or shorter.

PolyTimeComputable

For a total function f:Str→Strf : \mathrm{Str} \to \mathrm{Str}f:Str→Str, PolyTimeComputable(f)\mathrm{PolyTimeComputable}(f)PolyTimeComputable(f) is the proposition that there exists at least one machine computing fff in polynomial time in the following exact sense (Mathlib's TM2ComputableInPolyTime with both input and output encodings the identity on bit strings). The machine is a bundled TM2 multi-stack machine: a finite index set KKK of stacks (decidable equality), input index k0k_0k0​ and output index k1k_1k1​ (possibly equal), symbol types Γk\Gamma_kΓk​ with only Γk0\Gamma_{k_0}Γk0​​ required finite, a finite label set Λ\LambdaΛ with distinguished main\mathrm{main}main, a finite state set Σ\SigmaΣ with initial state s0s_0s0​, and a program mmm assigning to each label a statement, i.e. a finite tree of push/peek/pop/load/branch operations (each driven by arbitrary functions of the finite internal state and, for peek/pop, of the top symbol-or-empty of the chosen stack; popping an empty stack leaves it empty) terminated by goto (label becomes an arbitrary function of the state) or halt (label becomes "none"). A configuration is (label or none, state, all stack contents as lists with head = top); one step executes the whole statement of the current label; halted configurations (label none) have no successor; time is the number of steps. PolyTimeComputable(f)\mathrm{PolyTimeComputable}(f)PolyTimeComputable(f) asserts the existence of such a machine, bijections ι:Γk0≅{false,true}\iota : \Gamma_{k_0} \cong \{\mathsf{false},\mathsf{true}\}ι:Γk0​​≅{false,true} and ω:Γk1≅{false,true}\omega : \Gamma_{k_1} \cong \{\mathsf{false},\mathsf{true}\}ω:Γk1​​≅{false,true}, a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X] with natural-number coefficients, and for every x∈Strx \in \mathrm{Str}x∈Str a natural number sss with

s≤p(∣x∣)s \le p(|x|)s≤p(∣x∣)

such that from the initial configuration (label main\mathrm{main}main, state s0s_0s0​, stack k0=ι−1(x)k_0 = \iota^{-1}(x)k0​=ι−1(x) with the first symbol of xxx on top, all other stacks empty) exactly sss steps lead to precisely the configuration with label "none", state s0s_0s0​, stack k1=ω−1(f(x))k_1 = \omega^{-1}(f(x))k1​=ω−1(f(x)) (the whole output string, first symbol on top) and all other stacks empty. The time bound depends only on ∣x∣|x|∣x∣; the length of f(x)f(x)f(x) is not separately constrained (it is implicitly bounded by what can be pushed in sss steps, but no explicit bound appears).

PReducible

For two languages L1,L2⊆StrL_1, L_2 \subseteq \mathrm{Str}L1​,L2​⊆Str over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}, PReducible(L1,L2)\mathrm{PReducible}(L_1, L_2)PReducible(L1​,L2​) is the proposition that there exists a total function f:Str→Strf : \mathrm{Str} \to \mathrm{Str}f:Str→Str such that (i) PolyTimeComputable(f)\mathrm{PolyTimeComputable}(f)PolyTimeComputable(f) holds, i.e. there is a bundled TM2 multi-stack machine (finitely many stacks; input and output stack alphabets each in bijection with {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}; finitely many labels and internal states; one step = complete execution of one labelled statement) and a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X] such that for every xxx, started with xxx on the input stack, initial state, other stacks empty and label main\mathrm{main}main, the machine halts after exactly some s≤p(∣x∣)s \le p(|x|)s≤p(∣x∣) steps in the configuration with label none, internal state equal to the initial state, output stack exactly f(x)f(x)f(x) and all other stacks empty; and (ii) for every x∈Strx \in \mathrm{Str}x∈Str,

x∈L1  ⟺  f(x)∈L2.x \in L_1 \iff f(x) \in L_2.x∈L1​⟺f(x)∈L2​.

This is a many-one reduction by a single total function; the equivalence is required for all xxx, including x=[ ]x = [\,]x=[].

NPComplete

For a language L⊆StrL \subseteq \mathrm{Str}L⊆Str over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true}, NPComplete(L)\mathrm{NPComplete}(L)NPComplete(L) is the conjunction of two statements: (i) L∈NPL \in \mathrm{NP}L∈NP, i.e. there exist R:Str×Str→{false,true}R : \mathrm{Str}\times\mathrm{Str} \to \{\mathsf{false},\mathsf{true}\}R:Str×Str→{false,true} and k∈Nk \in \mathbb{N}k∈N with PolyTimeChecker(R)\mathrm{PolyTimeChecker}(R)PolyTimeChecker(R) (a bundled TM2 multi-stack machine over the four-symbol tagged input alphabet, with a polynomial p∈N[X]p \in \mathbb{N}[X]p∈N[X], halting on input encodePair(x,y)\mathrm{encodePair}(x,y)encodePair(x,y) after at most p(∣x∣+∣y∣)p(|x|+|y|)p(∣x∣+∣y∣) full-statement steps in the configuration with label none, initial internal state, output stack [R(x,y)][R(x,y)][R(x,y)] and all other stacks empty) and w∈L  ⟺  ∃y, ∣y∣≤∣w∣k∧R(w,y)=truew \in L \iff \exists y,\ |y| \le |w|^k \wedge R(w,y) = \mathsf{true}w∈L⟺∃y, ∣y∣≤∣w∣k∧R(w,y)=true for all www; and (ii) for every language L′∈NPL' \in \mathrm{NP}L′∈NP (in the same sense), PReducible(L′,L)\mathrm{PReducible}(L', L)PReducible(L′,L) holds, i.e. there is a total f:Str→Strf : \mathrm{Str} \to \mathrm{Str}f:Str→Str computed by some bundled TM2 machine with two-symbol input and output alphabets within a polynomial number of steps in ∣x∣|x|∣x∣ (halting in the configuration with label none, initial state, output stack f(x)f(x)f(x), other stacks empty) such that x∈L′  ⟺  f(x)∈Lx \in L' \iff f(x) \in Lx∈L′⟺f(x)∈L for all xxx.

E

E\mathrm{E}E is the set of languages L⊆StrL \subseteq \mathrm{Str}L⊆Str over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true} for which there exists a total function χ:Str→{false,true}\chi : \mathrm{Str} \to \{\mathsf{false},\mathsf{true}\}χ:Str→{false,true} such that (i) there exist a machine-with-time-bound MMM of Mathlib's type TM2ComputableInTime (input encoding the identity on bit strings, output encoding b↦[b]b \mapsto [b]b↦[b]) computing χ\chiχ, together with natural numbers c,C∈Nc, C \in \mathbb{N}c,C∈N such that for every n∈Nn \in \mathbb{N}n∈N,

timeM(n)≤C⋅2 c n;\mathrm{time}_M(n) \le C \cdot 2^{\,c\, n};timeM​(n)≤C⋅2cn;

and (ii) for every w∈Strw \in \mathrm{Str}w∈Str, w∈L  ⟺  χ(w)=truew \in L \iff \chi(w) = \mathsf{true}w∈L⟺χ(w)=true. Here MMM consists of: a bundled TM2 multi-stack machine (finite index set KKK of stacks with decidable equality; input index k0k_0k0​ and output index k1k_1k1​, possibly equal; symbol types Γk\Gamma_kΓk​ with only Γk0\Gamma_{k_0}Γk0​​ required finite; finite label set Λ\LambdaΛ with distinguished main\mathrm{main}main; finite state set Σ\SigmaΣ with initial state s0s_0s0​; program assigning to each label a statement, i.e. a finite tree of push/peek/pop/load/branch operations driven by arbitrary functions of the state and top-of-stack, ending in goto or halt); bijections ι:Γk0≅{false,true}\iota : \Gamma_{k_0} \cong \{\mathsf{false},\mathsf{true}\}ι:Γk0​​≅{false,true} and ω:Γk1≅{false,true}\omega : \Gamma_{k_1} \cong \{\mathsf{false},\mathsf{true}\}ω:Γk1​​≅{false,true}; an arbitrary time function timeM:N→N\mathrm{time}_M : \mathbb{N} \to \mathbb{N}timeM​:N→N (not required to be a polynomial); and, for every w∈Strw \in \mathrm{Str}w∈Str, a number of steps s≤timeM(∣w∣)s \le \mathrm{time}_M(|w|)s≤timeM​(∣w∣) such that from the initial configuration (label main\mathrm{main}main, state s0s_0s0​, stack k0=ι−1(w)k_0 = \iota^{-1}(w)k0​=ι−1(w) with first symbol on top, all other stacks empty) exactly sss applications of the step function (one step = complete execution of the current label's statement; halted configurations have no successor) yield precisely the configuration with label "none", state s0s_0s0​, stack k1=[ω−1(χ(w))]k_1 = [\omega^{-1}(\chi(w))]k1​=[ω−1(χ(w))] and all other stacks empty. The exponent ccc may be 000, in which case the bound is the constant CCC; if C=0C = 0C=0 the bound forces timeM≡0\mathrm{time}_M \equiv 0timeM​≡0, which cannot be met since at least one step is needed to pass from a labelled to an unlabelled configuration, so any witness has C≥1C \ge 1C≥1. The bound C⋅2cnC \cdot 2^{cn}C⋅2cn must hold for all nnn, including n=0n = 0n=0.

Literal

Literal\mathrm{Literal}Literal is an abbreviation for the type {false,true}×N\{\mathsf{false},\mathsf{true}\} \times \mathbb{N}{false,true}×N: a literal is a pair (s,i)(s, i)(s,i) of a sign bit sss and a variable index i∈Ni \in \mathbb{N}i∈N (variables are indexed by all natural numbers, starting at 000). No further structure is imposed here; the meaning of the sign is fixed only by evalLiteral\mathrm{evalLiteral}evalLiteral below.

Clause

Clause\mathrm{Clause}Clause is an abbreviation for finite lists of literals, i.e. finite sequences ((s1,i1),…,(sr,ir))((s_1,i_1),\dots,(s_r,i_r))((s1​,i1​),…,(sr​,ir​)) with r≥0r \ge 0r≥0; the empty clause is allowed, repeated literals are allowed, and a clause may contain both (true,i)(\mathsf{true},i)(true,i) and (false,i)(\mathsf{false},i)(false,i) for the same iii. Order is part of the data (a clause is a list, not a set).

CNF

CNF\mathrm{CNF}CNF is an abbreviation for finite lists of clauses, i.e. finite sequences (c1,…,cm)(c_1,\dots,c_m)(c1​,…,cm​) of clauses with m≥0m \ge 0m≥0; the empty formula is allowed, repeated clauses are allowed, and order is part of the data.

evalLiteral

For an assignment τ:N→{false,true}\tau : \mathbb{N} \to \{\mathsf{false},\mathsf{true}\}τ:N→{false,true} (a total function on all variable indices) and a literal l=(s,i)l = (s,i)l=(s,i), evalLiteral(τ,l)\mathrm{evalLiteral}(\tau, l)evalLiteral(τ,l) is the Boolean

evalLiteral(τ,(s,i))={τ(i)if s=true,¬ τ(i)if s=false.\mathrm{evalLiteral}(\tau,(s,i)) = \begin{cases} \tau(i) & \text{if } s = \mathsf{true},\\ \neg\,\tau(i) & \text{if } s = \mathsf{false}. \end{cases}evalLiteral(τ,(s,i))={τ(i)¬τ(i)​if s=true,if s=false.​

So sign true\mathsf{true}true denotes the positive literal xix_ixi​ and sign false\mathsf{false}false the negated literal ¬xi\neg x_i¬xi​.

evalClause

For an assignment τ:N→{false,true}\tau : \mathbb{N} \to \{\mathsf{false},\mathsf{true}\}τ:N→{false,true} and a clause c=(l1,…,lr)c = (l_1,\dots,l_r)c=(l1​,…,lr​), evalClause(τ,c)\mathrm{evalClause}(\tau, c)evalClause(τ,c) is true\mathsf{true}true if and only if there exists some jjj with evalLiteral(τ,lj)=true\mathrm{evalLiteral}(\tau, l_j) = \mathsf{true}evalLiteral(τ,lj​)=true (the disjunction of the literal values); in particular the empty clause evaluates to false\mathsf{false}false under every τ\tauτ.

evalCNF

For an assignment τ:N→{false,true}\tau : \mathbb{N} \to \{\mathsf{false},\mathsf{true}\}τ:N→{false,true} and a formula F=(c1,…,cm)F = (c_1,\dots,c_m)F=(c1​,…,cm​), evalCNF(τ,F)\mathrm{evalCNF}(\tau, F)evalCNF(τ,F) is true\mathsf{true}true if and only if evalClause(τ,cj)=true\mathrm{evalClause}(\tau, c_j) = \mathsf{true}evalClause(τ,cj​)=true for every jjj (the conjunction of the clause values); in particular the empty formula evaluates to true\mathsf{true}true under every τ\tauτ, and any formula containing an empty clause evaluates to false\mathsf{false}false under every τ\tauτ.

Satisfiable

For a formula F∈CNFF \in \mathrm{CNF}F∈CNF, Satisfiable(F)\mathrm{Satisfiable}(F)Satisfiable(F) is the proposition that there exists a total assignment τ:N→{false,true}\tau : \mathbb{N} \to \{\mathsf{false},\mathsf{true}\}τ:N→{false,true} (defined on all natural-number indices, not only those occurring in FFF) with evalCNF(τ,F)=true\mathrm{evalCNF}(\tau, F) = \mathsf{true}evalCNF(τ,F)=true, i.e. every clause of FFF contains at least one literal (s,i)(s,i)(s,i) with τ(i)=s\tau(i) = sτ(i)=s. The empty formula is satisfiable; a formula containing an empty clause is not.

encodeLiteral

For a literal l=(s,i)l = (s, i)l=(s,i), encodeLiteral(l)\mathrm{encodeLiteral}(l)encodeLiteral(l) is the bit string built as follows. Let bits(i)\mathrm{bits}(i)bits(i) denote the binary digits of iii listed least-significant first with no leading zeros, so bits(0)=[ ]\mathrm{bits}(0) = [\,]bits(0)=[], bits(1)=[1]\mathrm{bits}(1) = [1]bits(1)=[1], bits(2)=[0,1]\mathrm{bits}(2) = [0,1]bits(2)=[0,1], bits(6)=[0,1,1]\mathrm{bits}(6) = [0,1,1]bits(6)=[0,1,1], and for i≥1i \ge 1i≥1 the list has length ⌊log⁡2i⌋+1\lfloor \log_2 i \rfloor + 1⌊log2​i⌋+1 and ends in 111 (writing 000 for false\mathsf{false}false and 111 for true\mathsf{true}true). Form the list (b0,b1,…,bm)=(s,bits(i))(b_0, b_1, \dots, b_m) = (s, \mathrm{bits}(i))(b0​,b1​,…,bm​)=(s,bits(i)) (the sign bit followed by the digits of iii, so m=∣bits(i)∣m = |\mathrm{bits}(i)|m=∣bits(i)∣), replace each entry bjb_jbj​ by the two-symbol block (0,bj)(0, b_j)(0,bj​), concatenate, and append the terminator (1,0)(1, 0)(1,0):

encodeLiteral(s,i)=(0,s, 0,b1, …, 0,bm, 1,0).\mathrm{encodeLiteral}(s,i) = (0, s,\ 0, b_1,\ \dots,\ 0, b_m,\ 1, 0).encodeLiteral(s,i)=(0,s, 0,b1​, …, 0,bm​, 1,0).

Its length is 2m+4=2∣bits(i)∣+42m + 4 = 2|\mathrm{bits}(i)| + 42m+4=2∣bits(i)∣+4. For example encodeLiteral(s,0)=(0,s,1,0)\mathrm{encodeLiteral}(s, 0) = (0, s, 1, 0)encodeLiteral(s,0)=(0,s,1,0) and encodeLiteral(true,2)=(0,1, 0,0, 0,1, 1,0)\mathrm{encodeLiteral}(\mathsf{true}, 2) = (0,1,\ 0,0,\ 0,1,\ 1,0)encodeLiteral(true,2)=(0,1, 0,0, 0,1, 1,0).

encodeClause

For a clause c=(l1,…,lr)c = (l_1, \dots, l_r)c=(l1​,…,lr​), encodeClause(c)\mathrm{encodeClause}(c)encodeClause(c) is the concatenation encodeLiteral(l1) ⋯ encodeLiteral(lr)\mathrm{encodeLiteral}(l_1)\,\cdots\,\mathrm{encodeLiteral}(l_r)encodeLiteral(l1​)⋯encodeLiteral(lr​) followed by the two-symbol terminator (1,1)(1,1)(1,1) (writing 111 for true\mathsf{true}true). The empty clause encodes as (1,1)(1,1)(1,1).

encodeCNF

For a formula F=(c1,…,cm)F = (c_1,\dots,c_m)F=(c1​,…,cm​), encodeCNF(F)\mathrm{encodeCNF}(F)encodeCNF(F) is the concatenation encodeClause(c1) ⋯ encodeClause(cm)\mathrm{encodeClause}(c_1)\,\cdots\,\mathrm{encodeClause}(c_m)encodeClause(c1​)⋯encodeClause(cm​) with no additional delimiter; the empty formula encodes as the empty string [ ][\,][].

SAT

SAT\mathrm{SAT}SAT is the language over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true} consisting of all bit strings www for which there exists a formula F∈CNFF \in \mathrm{CNF}F∈CNF (a finite list of finite lists of sign/index pairs) with

encodeCNF(F)=wandSatisfiable(F),\mathrm{encodeCNF}(F) = w \quad\text{and}\quad \mathrm{Satisfiable}(F),encodeCNF(F)=wandSatisfiable(F),

where encodeCNF\mathrm{encodeCNF}encodeCNF is the concatenation over clauses of (concatenation over literals (s,i)(s,i)(s,i) of the blocks (0,s),(0,b1),…,(0,bm),(1,0)(0,s),(0,b_1),\dots,(0,b_m),(1,0)(0,s),(0,b1​),…,(0,bm​),(1,0) with b1…bmb_1\dots b_mb1​…bm​ the least-significant-first binary digits of iii without leading zeros, followed by (1,1)(1,1)(1,1)), and Satisfiable(F)\mathrm{Satisfiable}(F)Satisfiable(F) means some total assignment τ:N→{false,true}\tau : \mathbb{N} \to \{\mathsf{false},\mathsf{true}\}τ:N→{false,true} makes every clause of FFF contain a literal (s,i)(s,i)(s,i) with τ(i)=s\tau(i) = sτ(i)=s. Strings that are not the encoding of any formula are not in SAT\mathrm{SAT}SAT; the empty string is in SAT\mathrm{SAT}SAT (it encodes the empty formula, which is satisfiable). Membership only requires some formula with encoding www to be satisfiable; no injectivity of the encoding is asserted in the definition.

ThreeSAT

ThreeSAT\mathrm{ThreeSAT}ThreeSAT is the language over {false,true}\{\mathsf{false},\mathsf{true}\}{false,true} consisting of all bit strings www for which there exists a formula F∈CNFF \in \mathrm{CNF}F∈CNF such that

encodeCNF(F)=w,every clause c occurring in F has list length exactly 3,and Satisfiable(F),\mathrm{encodeCNF}(F) = w, \qquad \text{every clause } c \text{ occurring in } F \text{ has list length exactly } 3, \qquad \text{and } \mathrm{Satisfiable}(F),encodeCNF(F)=w,every clause c occurring in F has list length exactly 3,and Satisfiable(F),

with encodeCNF\mathrm{encodeCNF}encodeCNF and Satisfiable\mathrm{Satisfiable}Satisfiable as in SAT\mathrm{SAT}SAT (encoding: per literal (s,i)(s,i)(s,i) the blocks (0,s),(0,b1),…,(0,bm),(1,0)(0,s),(0,b_1),\dots,(0,b_m),(1,0)(0,s),(0,b1​),…,(0,bm​),(1,0) with b1…bmb_1\dots b_mb1​…bm​ the least-significant-first binary digits of iii, per clause a trailing (1,1)(1,1)(1,1), clauses concatenated; satisfiability: some total τ:N→{false,true}\tau : \mathbb{N} \to \{\mathsf{false},\mathsf{true}\}τ:N→{false,true} makes each clause contain a literal (s,i)(s,i)(s,i) with τ(i)=s\tau(i) = sτ(i)=s). "Length exactly 333" counts list entries, so a clause such as ((true,0),(true,0),(true,0))((\mathsf{true},0),(\mathsf{true},0),(\mathsf{true},0))((true,0),(true,0),(true,0)) or one containing both (true,i)(\mathsf{true},i)(true,i) and (false,i)(\mathsf{false},i)(false,i) qualifies; the condition is vacuous for the empty formula, so the empty string is in ThreeSAT\mathrm{ThreeSAT}ThreeSAT. Strings not encoding any formula all of whose clauses have length 333 are excluded.

View graph

Get started

Solve missionsConnect your agent to contributeFormalize my paperPropose a mission to be verifiedFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions, with reuse governed by our licensing terms.

How Prove2Me worksResearch paper
SKILL.mdTourFAQContactTerms
© 2026 Prove2Me