Cook-Levin: halting cleanup and packaging of the reduction machine
A generic drain phase
TheoremDraining a stack with the transfer loop#✓fully proved
Let \(M\) be a TM2 machine whose state type carries a flag bit, and suppose that the statement of \(M\) at label \(\ell\) is the transfer loop that pops stack \(k\) with no target stacks, returning to \(\ell\) while the pop succeeds and going to label \(\ell'\) once stack \(k\) is empty. Then for every state \(v\) and every stack assignment \(S\), writing \(S_k\) for the contents of stack \(k\) under \(S\) and \(|S_k|\) for its length, in exactly \(|S_k| + 1\) steps the machine goes from label \(\ell\) with state \(v\) and stacks \(S\) to label \(\ell'\) with the state that stores the flag bit false and the stacks of \(S\) with stack \(k\) replaced by the empty list, all other stacks unchanged.
theorem xfer_drain {self next : Λ} {k : K} (hp : M self = xfer k [] self next) :
∀ (l : List (Γ k)) (v : σ) (S : ∀ k, List (Γ k)), S k = l →
Run M (l.length + 1) ⟨some self, v, S⟩ ⟨some next, Flag.tag false, update S k []⟩
def xfer (k : K) (ps : List (Σ k, Γ k)) (self next : Λ) : TM2.Stmt Γ Λ σ :=
.pop k (fun _ o => Flag.tag o.isSome)
(.branch Flag.untag (pushAll ps (.goto fun _ => self)) (.goto fun _ => next))
MathlibExt/Computability/TuringMachine/Program.lean:232
def Run (n : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
(flip bind (TM2.step M))^[n] (some c) = some d
MathlibExt/Computability/TuringMachine/Program.lean:84
tag : Bool → σ
MathlibExt/Computability/TuringMachine/Program.lean:59
Uses 5 · Used by 1
DefinitionThe drain program#✓fully proved
Given a list \(k_0, \dots, k_{m-1}\) of stacks, a type \(\Lambda\) of labels and labels \(\lambda : \mathbb{N} \to \Lambda\), stage \(i\) of the drain program is as follows. For \(i < m\) it pops stack \(k_i\), recording in the state whether a symbol was popped, and jumps to \(\lambda(i)\) if one was and to \(\lambda(i + 1)\) if the stack was empty; repeated, this empties \(k_i\). For \(i \ge m\) it sets the state to store the flag bit false and halts.
def drainS (ks : List K) (lab : ℕ → Λ) (i : ℕ) : TM2.Stmt Γ Λ σ :=
match ks[i]? with
| some k => xfer k [] (lab i) (lab (i + 1))
| none => .load (fun _ => Flag.tag false) .halt
def xfer (k : K) (ps : List (Σ k, Γ k)) (self next : Λ) : TM2.Stmt Γ Λ σ :=
.pop k (fun _ o => Flag.tag o.isSome)
(.branch Flag.untag (pushAll ps (.goto fun _ => self)) (.goto fun _ => next))
MathlibExt/Computability/TuringMachine/Program.lean:232
tag : Bool → σ
MathlibExt/Computability/TuringMachine/Program.lean:59
Uses 2 · Used by 3
DefinitionDrain step count#✓fully proved
For a list \(k_1, \dots, k_m\) of stacks and contents \(S\) assigning a list \(S_k\) to each stack \(k\), the drain step count is \(1 + \sum_{i=1}^{m} (|S_{k_i}| + 1)\).
TheoremThe drain#✓fully proved
Let \(M\) be a multi-stack machine program with labels in a type \(\Lambda\), let \(k_0, \dots, k_{m-1}\) be a list of distinct stacks, and let \(\lambda : \mathbb{N} \to \Lambda\) be labels such that for every \(i \le m\) the instruction of \(M\) at \(\lambda(i)\) is stage \(i\) of the drain program for this list and these labels. Then for every state \(v\) and stack contents \(S\), the machine runs in exactly \(1 + \sum_{i < m} (|S_{k_i}| + 1)\) steps from label \(\lambda(0)\), state \(v\) and contents \(S\) to the halted configuration whose state stores the flag bit false and whose contents are empty on each \(k_i\) and equal to \(S\) on every other stack.
theorem drain_run :
∀ (ks : List K) (lab : ℕ → Λ), ks.Nodup → (∀ i ≤ ks.length, M (lab i) = drainS ks lab i) →
∀ (v : σ) (S : ∀ k, List (Γ k)),
Run M (drainB ks S) ⟨some (lab 0), v, S⟩
⟨none, Flag.tag false, fun k => if k ∈ ks then [] else S k⟩
def drainS (ks : List K) (lab : ℕ → Λ) (i : ℕ) : TM2.Stmt Γ Λ σ :=
match ks[i]? with
| some k => xfer k [] (lab i) (lab (i + 1))
| none => .load (fun _ => Flag.tag false) .halt
CSLibExt/Computability/Complexity/CookLevin/Package.lean:98
def Run (n : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
(flip bind (TM2.step M))^[n] (some c) = some d
MathlibExt/Computability/TuringMachine/Program.lean:84
def drainB (ks : List K) (S : ∀ k, List (Γ k)) : ℕ :=
(ks.map fun k => (S k).length + 1).sum + 1
CSLibExt/Computability/Complexity/CookLevin/Package.lean:104
tag : Bool → σ
MathlibExt/Computability/TuringMachine/Program.lean:59
Uses 7 · Used by 1
The composed machine: full machine, then the drain
InductiveLabels of the composed machine#✓fully proved
For a type \(\Lambda\) of labels and \(n \in \mathbb{N}\), a label of the composed machine is either a label \(l \in \Lambda\) of the original machine or a drain stage \(i \in \{0, \dots, n\}\).
inductive DL (Λ : Type) (n : ℕ)
| f (l : Λ)
| dr (i : Fin (n + 1))
deriving DecidableEq, Fintype
DefinitionDrain-stage label#✓fully proved
For \(n, j \in \mathbb{N}\), the label of the composed machine with drain stages \(0, \dots, n\) that names drain stage \(\min(j, n)\).
def dlab {Λ : Type} (n j : ℕ) : DL Λ n := .dr ⟨min j n, by omega⟩
inductive DL (Λ : Type) (n : ℕ)
| f (l : Λ)
| dr (i : Fin (n + 1))
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Package.lean:148
Uses 1 · Used by 2
DefinitionThe identity stack embedding#✓fully proved
For a family of stack alphabets \(\Gamma\) indexed by \(K\), the identity stack embedding of \(\Gamma\) into itself sends every stack to itself and identifies every alphabet with itself by the identity bijection: a pure relabelling.
def idE {K : Type} (Γ : K → Type) : SEmb Γ Γ := ⟨id, injective_id, fun _ => Equiv.refl _⟩
structure SEmb {K K' : Type} (Γ : K → Type) (Γ' : K' → Type) where
/-- The stack renaming. -/
e : K → K'
/-- Distinct sub-machine stacks go to distinct host stacks. -/
inj : Injective e
/-- The alphabet of each sub-machine stack, identified with its host stack's. -/
ι : ∀ k, Γ k ≃ Γ' (e k)
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:51
Uses 1 · Used by 2
DefinitionStacks to drain#✓fully proved
The list of all stacks of the full machine other than its output stack, each appearing exactly once, in an unspecified order. These are the stacks that the drain empties before the composed machine halts.
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:569
Uses 7 · Used by 9
TheoremOnly the output stack survives the drain#✓fully proved
For any alphabets and any assignment \(T\) of contents to the stacks of the full machine, the contents that are empty on every stack to drain and agree with \(T\) elsewhere are the contents that agree with \(T\) on the output stack and are empty on every other stack.
theorem drained {Γ : FK → Type} (T : ∀ k, List (Γ k)) :
(fun q => if q ∈ dks then [] else T q) = fun q => if q = FK.h .out then T q else []
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:569
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
CSLibExt/Computability/Complexity/CookLevin/Package.lean:160
Uses 8 · Used by 1
DefinitionThe composed program#✓fully proved
Let \(g, r \in \mathbb{N}\), let \(P\) be a program with labels \(\Lambda\) and Boolean state over the stacks of the full machine with alphabets \(F\Gamma_{g,r}\), and let \(\mathit{fin} \in \Lambda\). The composed program has as labels the labels of \(P\) and the drain stages \(0, \dots, n\), where \(n\) is the number of stacks other than the output stack. At a label \(\ell \ne \mathit{fin}\) it runs \(P(\ell)\) with every jump target relabelled; at \(\mathit{fin}\) it jumps to drain stage \(0\); at drain stage \(i < n\) it empties the \(i\)-th stack other than the output stack (in a fixed order) and moves to stage \(i + 1\), and at stage \(n\) it sets the state to false and halts.
noncomputable def gprog (P : Λ → TM2.Stmt (FΓ g r) Λ Bool) (fin : Λ) :
DL Λ dks.length → TM2.Stmt (FΓ g r) (DL Λ dks.length) Bool
| .f l => if l = fin then .goto (fun _ => dlab _ 0) else mapS (idE _) DL.f (P l)
| .dr i => drainS dks (dlab _) i.val
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
inductive DL (Λ : Type) (n : ℕ)
| f (l : Λ)
| dr (i : Fin (n + 1))
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Package.lean:148
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
CSLibExt/Computability/Complexity/CookLevin/Package.lean:160
def dlab {Λ : Type} (n j : ℕ) : DL Λ n := .dr ⟨min j n, by omega⟩
CSLibExt/Computability/Complexity/CookLevin/Package.lean:154
def mapS : TM2.Stmt Γ Λ σ → TM2.Stmt Γ' Λ' σ
| .push k f q => .push (E.e k) (fun s => E.ι k (f s)) (mapS q)
| .peek k f q => .peek (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .pop k f q => .pop (E.e k) (fun s o => f s (o.map (E.ι k).symm)) (mapS q)
| .load a q => .load a (mapS q)
| .branch f q₁ q₂ => .branch f (mapS q₁) (mapS q₂)
| .goto f => .goto fun s => φ (f s)
| .halt => .halt
MathlibExt/Computability/TuringMachine/StackEmbedding.lean:65
def idE {K : Type} (Γ : K → Type) : SEmb Γ Γ := ⟨id, injective_id, fun _ => Equiv.refl _⟩
CSLibExt/Computability/Complexity/CookLevin/Package.lean:157
def drainS (ks : List K) (lab : ℕ → Λ) (i : ℕ) : TM2.Stmt Γ Λ σ :=
match ks[i]? with
| some k => xfer k [] (lab i) (lab (i + 1))
| none => .load (fun _ => Flag.tag false) .halt
CSLibExt/Computability/Complexity/CookLevin/Package.lean:98
TheoremRunning a program, then the drain#✓fully proved
Let \(g, r \in \mathbb{N}\), let \(P\) be a program with labels \(\Lambda\) and Boolean state over the stacks of the full machine with alphabets \(F\Gamma_{g,r}\), and let \(\mathit{fin}\) be a label with \(P(\mathit{fin}) = \mathrm{halt}\). Suppose \(P\) goes in at most \(B\) steps from the configuration with label \(\ell\), state \(v\) and stacks \(S\) to the configuration with label \(\mathit{fin}\), state \(v'\) and stacks \(T\). Then the composed program of \(P\) and \(\mathit{fin}\) goes in at most \(B + 1 + d(T)\) steps from label \(\ell\) (as a label of the composed program), state \(v\) and stacks \(S\) to the halted configuration with state false in which every stack other than the output stack is empty and the output stack is that of \(T\). Here \(d(T)\), the step count of the drain, is \(1\) plus the sum of \(|T_q| + 1\) over the stacks \(q\) other than the output stack.
theorem g_run_gen {P : Λ → TM2.Stmt (FΓ g r) Λ Bool} {fin : Λ} (hfin : P fin = .halt)
{B : ℕ} {l : Λ} {v v' : Bool} {S T : ∀ k, List (FΓ g r k)}
(h : RunLe P B ⟨some l, v, S⟩ ⟨some fin, v', T⟩) :
RunLe (gprog P fin) (B + 1 + drainB dks T) ⟨some (.f l), v, S⟩
⟨none, false, fun k => if k ∈ dks then [] else T k⟩
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
noncomputable def gprog (P : Λ → TM2.Stmt (FΓ g r) Λ Bool) (fin : Λ) :
DL Λ dks.length → TM2.Stmt (FΓ g r) (DL Λ dks.length) Bool
| .f l => if l = fin then .goto (fun _ => dlab _ 0) else mapS (idE _) DL.f (P l)
| .dr i => drainS dks (dlab _) i.val
CSLibExt/Computability/Complexity/CookLevin/Package.lean:178
def drainB (ks : List K) (S : ∀ k, List (Γ k)) : ℕ :=
(ks.map fun k => (S k).length + 1).sum + 1
CSLibExt/Computability/Complexity/CookLevin/Package.lean:104
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
CSLibExt/Computability/Complexity/CookLevin/Package.lean:160
Uses 26 · Used by 1
TheoremStep bound for draining bounded stacks#✓fully proved
Let \(g, r, h \in \mathbb{N}\) and let \(T\) assign to every stack \(k\) of the full machine (with alphabets \(\Gamma_{g,r}\)) a list \(T_k\) of length at most \(h\). Let \(L\) be the number of stacks other than the output stack. Then the drain step count \(1 + \sum_k (|T_k| + 1)\), summed over the stacks \(k\) other than the output stack, is at most \(L(h + 1) + 1\).
theorem drainB_le {T : ∀ k, List (FΓ g r k)} {h : ℕ} (hT : ∀ k, (T k).length ≤ h) :
drainB dks T ≤ dks.length * (h + 1) + 1
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
def drainB (ks : List K) (S : ∀ k, List (Γ k)) : ℕ :=
(ks.map fun k => (S k).length + 1).sum + 1
CSLibExt/Computability/Complexity/CookLevin/Package.lean:104
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
CSLibExt/Computability/Complexity/CookLevin/Package.lean:160
Uses 4 · Used by 1
The composed machine on the real generators
DefinitionThe reduction machine#✓fully proved
Fix \(r \in \mathbb{N}\), a finite TM2 machine \(M\) with an encoding \(E\), a list \(Y\) of input symbols of \(M\), an output symbol \(a\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input symbols, an input symbol \(\mathit{sep}\), a polynomial \(k\) with coefficients in \(\mathbb{N}\) and \(c, e \in \mathbb{N}\). The reduction machine is the finite TM2 machine with the stacks and alphabets of the full machine, input on the raw-input stack and output on the output stack; its labels are those of the full machine together with the drain stages \(0, \dots, n\), where \(n\) is the number of stacks other than the output stack; it starts at the read-loop label with state false; and its program is the composed program of the full machine's program and its final label: the full machine, followed by the drain.
noncomputable def gTM (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) : FinTM2 where
K := FK
k₀ := .raw
k₁ := .h .out
Γ := FΓ E.layout.g r
Λ := DL (FL _ _) dks.length
main := .f .rd
σ := Bool
initialState := false
m := gprog (fullProg E Ys acc ι sep k c e) (.h .fin)
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:569
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
inductive DL (Λ : Type) (n : ℕ)
| f (l : Λ)
| dr (i : Fin (n + 1))
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Package.lean:148
inductive FL (D : ℕ) (Λ : Type)
| rd
| pre (l : PL D)
| h (l : Λ)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:582
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
CSLibExt/Computability/Complexity/CookLevin/Package.lean:160
noncomputable def gprog (P : Λ → TM2.Stmt (FΓ g r) Λ Bool) (fin : Λ) :
DL Λ dks.length → TM2.Stmt (FΓ g r) (DL Λ dks.length) Bool
| .f l => if l = fin then .goto (fun _ => dlab _ 0) else mapS (idE _) DL.f (P l)
| .dr i => drainS dks (dlab _) i.val
CSLibExt/Computability/Complexity/CookLevin/Package.lean:178
noncomputable abbrev fullProg (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) :=
fprog (fun i => InitFamily.encF E (ι i)) (InitFamily.encF E sep) k c e (depth M) (realProg E Ys acc)
(.ini (.pre1 .eg))
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:819
Uses 44 · Used by 3
DefinitionThe formula emitted on a raw input#✓fully proved
Fix \(r \in \mathbb{N}\), a finite TM2 machine \(M\) with an encoding \(E\), a list \(Y\) of input symbols of \(M\), an output symbol \(a\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input symbols, an input symbol \(\mathit{sep}\), a polynomial \(k\) with coefficients in \(\mathbb{N}\) and \(c, e \in \mathbb{N}\). For a raw input \(s\), a list over \(\{0, \dots, r-1\}\), let \(x\) be \(s\) with each symbol mapped by \(\iota\), followed by \(\mathit{sep}\), let \(m = |s| + 1 + k(|s|)\) and \(T = (m + c)^e\). The emitted formula for \(s\) is the bit-string encoding of the assembled Cook–Levin formula \(\Phi_E(x, Y, a, m, T)\).
noncomputable def phiOf (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) (s : List (Fin r)) : List Bool :=
encodeCNF (Phi E (s.map ι ++ [sep]) Ys acc (mOf k s.length) (TOf k c e s.length))
def encodeCNF (φ : CNF) : List Bool := φ.flatMap encodeClause
CSLibExt/Computability/Complexity/DenseSAT.lean:90
noncomputable def Phi (x Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (m T : ℕ) : CNF :=
E.accFamily acc T (capH m T (depth M)) ++
(Shift.shFamily E.layout E.sa E.pl E.cn E.pu E.N T (capH m T (depth M)) ++
(Family.family E.layout E.la E.sa E.wa T (capH m T (depth M)) E.N ++
(Family.family E.layout E.la E.na E.wa T (capH m T (depth M)) E.N ++
E.initFamily x Ys m T (capH m T (depth M)))))
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:370
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:455
def TOf (k : Polynomial ℕ) (c e n : ℕ) : ℕ := (mOf k n + c) ^ e
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:458
Uses 5 · Used by 4
DefinitionStep bound of the composed machine#✓fully proved
Fix the verifier data (an encoding \(E\) of a stack machine \(M\), a list \(Y\) of input symbols, an output symbol \(\mathrm{acc}\), a map \(\iota\) into the input alphabet, a separator \(\mathrm{sep}\), a polynomial \(k\) and \(c, e \in \mathbb{N}\)) and an input length \(n\). Let \(B(n)\) be the step bound of the full machine on inputs of length \(n\), let \(D\) be the depth of the full machine (the most push, peek and pop operations on any path of one of its instructions), and let \(L\) be the number of stacks other than the output stack. The step bound of the composed machine is \(B(n) + 1 + (L(n + B(n) D + 1) + 1)\).
noncomputable def gB (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e n : ℕ) : ℕ :=
fullB E Ys k c e n + 1 +
(dks.length * (n + fullB E Ys k c e n * depth (fullTM E Ys acc ι sep k c e) + 1) + 1)
noncomputable def fullB (Ys : List (M.Γ M.k₀)) (k : Polynomial ℕ) (c e n : ℕ) : ℕ :=
n + 1 + cB k c e (depth M) n + 1 + realB E Ys (mOf k n) (TOf k c e n)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:825
noncomputable def dks : List FK := (Finset.univ.erase (FK.h .out)).toList
CSLibExt/Computability/Complexity/CookLevin/Package.lean:160
def depth (M : FinTM2) : ℕ :=
letI := M.ΛFin
Finset.univ.sup fun l => ops (M.m l)
CSLibExt/Computability/Complexity/CookLevin/Situation.lean:231
noncomputable def fullTM (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) : FinTM2 where
K := FK
k₀ := .raw
k₁ := .h .out
Γ := FΓ E.layout.g r
Λ := FL _ _
main := .rd
σ := Bool
initialState := false
m := fullProg E Ys acc ι sep k c e
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:888
Uses 6 · Used by 3
TheoremThe reduction machine halts with the emitted formula#✓fully proved
Fix \(r \in \mathbb{N}\), a finite TM2 machine \(M\) with an encoding \(E\), a list \(Y\) of input symbols of \(M\), an output symbol \(a\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input symbols, an input symbol \(\mathit{sep}\), a polynomial \(k\) with coefficients in \(\mathbb{N}\) and \(c, e \in \mathbb{N}\). For every raw input \(s\), a list over \(\{0, \dots, r-1\}\), the program of the reduction machine goes in at most \(g_B(|s|)\) steps from the initial configuration on input \(s\) to the halting configuration with output the emitted formula for \(s\) (no label, the initial state, that formula on the output stack and every other stack empty), where \(g_B\) is the step bound of the composed machine.
No assumption on the verifier data is needed.
theorem g_run (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) (s : List (Fin r)) :
RunLe (gTM E Ys acc ι sep k c e).m (gB E Ys acc ι sep k c e s.length)
(initList (gTM E Ys acc ι sep k c e) s)
(haltList (gTM E Ys acc ι sep k c e) (phiOf E Ys acc ι sep k c e s))
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
noncomputable def gTM (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) : FinTM2 where
K := FK
k₀ := .raw
k₁ := .h .out
Γ := FΓ E.layout.g r
Λ := DL (FL _ _) dks.length
main := .f .rd
σ := Bool
initialState := false
m := gprog (fullProg E Ys acc ι sep k c e) (.h .fin)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:231
noncomputable def gB (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e n : ℕ) : ℕ :=
fullB E Ys k c e n + 1 +
(dks.length * (n + fullB E Ys k c e n * depth (fullTM E Ys acc ι sep k c e) + 1) + 1)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:249
noncomputable def phiOf (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) (s : List (Fin r)) : List Bool :=
encodeCNF (Phi E (s.map ι ++ [sep]) Ys acc (mOf k s.length) (TOf k c e s.length))
CSLibExt/Computability/Complexity/CookLevin/Package.lean:244
Uses 66 · Used by 2
Output in time and polynomial-time computability
DefinitionA bounded halting run certifies the output#✓fully proved
Let \(M\) be a finite TM2 machine, \(l\) a list over its input alphabet, \(l'\) a list over its output alphabet and \(B \in \mathbb{N}\). If the program of \(M\) goes in at most \(B\) steps from the initial configuration on input \(l\) (its start label, its initial state, \(l\) on the input stack and every other stack empty) to the halting configuration with output \(l'\) (no label, the initial state, \(l'\) on the output stack and every other stack empty), then \(M\) outputs \(l'\) on input \(l\) within \(B\) steps.
noncomputable def outputsOfRunLe {tm : FinTM2} {l : List (tm.Γ tm.k₀)} {l' : List (tm.Γ tm.k₁)}
{B : ℕ} (h : RunLe tm.m B (initList tm l) (haltList tm l')) :
TM2OutputsInTime tm l (some l') B where
steps := Classical.choose h
evals_in_steps := (Classical.choose_spec h).2
steps_le_m := (Classical.choose_spec h).1
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
Uses 2 · Used by 2
DefinitionA bounded halting run certifies the output, up to an equal output#✓fully proved
Let \(M\) be a finite TM2 machine, \(l\) a list over its input alphabet, \(l'\) and \(l''\) lists over its output alphabet and \(B \in \mathbb{N}\). If the program of \(M\) goes in at most \(B\) steps from the initial configuration on input \(l\) to the halting configuration with output \(l''\), and \(l'' = l'\), then \(M\) outputs \(l'\) on input \(l\) within \(B\) steps.
noncomputable def outputsOfRunLe' {tm : FinTM2} {l : List (tm.Γ tm.k₀)}
{l' l'' : List (tm.Γ tm.k₁)} {B : ℕ} (h : RunLe tm.m B (initList tm l) (haltList tm l''))
(he : l'' = l') : TM2OutputsInTime tm l (some l') B :=
outputsOfRunLe (he ▸ h)
def RunLe (M : Λ → TM2.Stmt Γ Λ σ) (B : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
∃ n, n ≤ B ∧ Run M n c d
MathlibExt/Computability/TuringMachine/Program.lean:901
noncomputable def outputsOfRunLe {tm : FinTM2} {l : List (tm.Γ tm.k₀)} {l' : List (tm.Γ tm.k₁)}
{B : ℕ} (h : RunLe tm.m B (initList tm l) (haltList tm l')) :
TM2OutputsInTime tm l (some l') B where
steps := Classical.choose h
evals_in_steps := (Classical.choose_spec h).2
steps_le_m := (Classical.choose_spec h).1
CSLibExt/Computability/Complexity/CookLevin/Package.lean:315
Uses 2 · Used by 1
TheoremOne polynomial bounds the reduction machine#✓fully proved
Fix \(r \in \mathbb{N}\), a finite TM2 machine \(M\) with an encoding \(E\), a list \(Y\) of input symbols of \(M\), an output symbol \(a\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input symbols, an input symbol \(\mathit{sep}\), a polynomial \(k\) with coefficients in \(\mathbb{N}\) and \(c, e \in \mathbb{N}\). There is a polynomial \(p\) with coefficients in \(\mathbb{N}\) such that for every raw input \(s\), a list over \(\{0, \dots, r-1\}\), the reduction machine on input \(s\) outputs the emitted formula for \(s\) within \(p(|s|)\) steps.
theorem g_outputs (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) :
∃ p : Polynomial ℕ, ∀ s : List (Fin r),
Nonempty (TM2OutputsInTime (gTM E Ys acc ι sep k c e) s
(some (phiOf E Ys acc ι sep k c e s)) (p.eval s.length))
noncomputable def gTM (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) : FinTM2 where
K := FK
k₀ := .raw
k₁ := .h .out
Γ := FΓ E.layout.g r
Λ := DL (FL _ _) dks.length
main := .f .rd
σ := Bool
initialState := false
m := gprog (fullProg E Ys acc ι sep k c e) (.h .fin)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:231
noncomputable def phiOf (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) (s : List (Fin r)) : List Bool :=
encodeCNF (Phi E (s.map ι ++ [sep]) Ys acc (mOf k s.length) (TOf k c e s.length))
CSLibExt/Computability/Complexity/CookLevin/Package.lean:244
Uses 28
DefinitionThe Cook–Levin reduction function#✓fully proved
Fix \(r \in \mathbb{N}\), a finite TM2 machine \(M\) with an encoding \(E\), a list \(Y\) of input symbols of \(M\), an output symbol \(\mathrm{acc}\) of \(M\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input symbols of \(M\), an input symbol \(\mathit{sep}\) of \(M\), a polynomial \(k\) with coefficients in \(\mathbb{N}\) and \(c, e \in \mathbb{N}\). Let \(\mathit{ea}\) encode the elements of a type \(\alpha\) as lists over an alphabet \(\Sigma\), and let \(\mathit{eqv}\) be a bijection from \(\{0, \dots, r-1\}\) to \(\Sigma\). The reduction function sends \(u \in \alpha\) to the emitted formula for the raw input \(s\) obtained by applying \(\mathit{eqv}^{-1}\) to each symbol of \(\mathit{ea}(u)\): the dense encoding of the assembled Cook–Levin formula \(\Phi_E(x, Y, \mathrm{acc}, m, T)\), where \(x\) is \(s\) with each symbol mapped by \(\iota\), followed by \(\mathit{sep}\), \(m = |s| + 1 + k(|s|)\) and \(T = (m + c)^e\).
noncomputable def fR {α αΓ : Type} (ea : α → List αΓ) (eqv : Fin r ≃ αΓ)
(Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀) (sep : M.Γ M.k₀)
(k : Polynomial ℕ) (c e : ℕ) (a : α) : List Bool :=
phiOf E Ys acc ι sep k c e ((ea a).map eqv.invFun)
noncomputable def phiOf (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) (s : List (Fin r)) : List Bool :=
encodeCNF (Phi E (s.map ι ++ [sep]) Ys acc (mOf k s.length) (TOf k c e s.length))
CSLibExt/Computability/Complexity/CookLevin/Package.lean:244
DefinitionThe reduction machine as a polynomial-time computation#✓fully proved
Fix \(r \in \mathbb{N}\), a finite TM2 machine \(M\) with an encoding \(E\), a list \(Y\) of input symbols of \(M\), an output symbol \(a\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input symbols, an input symbol \(\mathit{sep}\), a polynomial \(k\) with coefficients in \(\mathbb{N}\) and \(c, e \in \mathbb{N}\). Let \(\mathit{ea}\) encode the elements of a type \(\alpha\) as lists over an alphabet \(\Sigma\), and let \(\mathit{eqv}\) be a bijection from \(\{0, \dots, r-1\}\) to \(\Sigma\). This is a polynomial-time TM2 computation of the reduction function \(f_R\), which sends \(u \in \alpha\) to the emitted formula for the raw input obtained by applying \(\mathit{eqv}^{-1}\) to each symbol of \(\mathit{ea}(u)\), from the encoding \(\mathit{ea}\) to the identity encoding of bit strings: the machine is the reduction machine, its input alphabet is identified with \(\Sigma\) by \(\mathit{eqv}\), its output alphabet with the Booleans by the identity, and its time bound is a polynomial \(p\) with \(p(n) = g_B(n)\) for all \(n\), where \(g_B\) is the step bound of the composed machine.
noncomputable def gComp {α αΓ : Type} (ea : α → List αΓ) (eqv : Fin r ≃ αΓ)
(Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀) (sep : M.Γ M.k₀)
(k : Polynomial ℕ) (c e : ℕ) :
TM2ComputableInPolyTime ea (fun l : List Bool => l)
(fR E ea eqv Ys acc ι sep k c e) where
tm := gTM E Ys acc ι sep k c e
inputAlphabet := eqv
outputAlphabet := Equiv.refl Bool
time := Classical.choose (gB_poly E Ys acc ι sep k c e)
outputsFun a := outputsOfRunLe' (by
have h := g_run E Ys acc ι sep k c e ((ea a).map eqv.invFun)
rw [List.length_map, Classical.choose_spec (gB_poly E Ys acc ι sep k c e)] at h
exact h) (List.map_id _).symm
noncomputable def fR {α αΓ : Type} (ea : α → List αΓ) (eqv : Fin r ≃ αΓ)
(Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀) (sep : M.Γ M.k₀)
(k : Polynomial ℕ) (c e : ℕ) (a : α) : List Bool :=
phiOf E Ys acc ι sep k c e ((ea a).map eqv.invFun)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:349
noncomputable def gTM (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) : FinTM2 where
K := FK
k₀ := .raw
k₁ := .h .out
Γ := FΓ E.layout.g r
Λ := DL (FL _ _) dks.length
main := .f .rd
σ := Bool
initialState := false
m := gprog (fullProg E Ys acc ι sep k c e) (.h .fin)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:231
theorem gB_poly (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) (ι : Fin r → M.Γ M.k₀)
(sep : M.Γ M.k₀) (k : Polynomial ℕ) (c e : ℕ) : IsPoly (gB E Ys acc ι sep k c e)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:330
noncomputable def outputsOfRunLe' {tm : FinTM2} {l : List (tm.Γ tm.k₀)}
{l' l'' : List (tm.Γ tm.k₁)} {B : ℕ} (h : RunLe tm.m B (initList tm l) (haltList tm l''))
(he : l'' = l') : TM2OutputsInTime tm l (some l') B :=
outputsOfRunLe (he ▸ h)
CSLibExt/Computability/Complexity/CookLevin/Package.lean:323
Uses 28 · Used by 1
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.