Cook-Levin: the precomputation, composed with the assembled generator
Counter-view additions: decrement, multi-target transfer, the power loop
DefinitionUnit targets of a multi-target transfer#✓fully proved
For a list \(y_1, \dots, y_j\) of counters, the list of transfer targets that pushes one unit on each counter \(y_i\), in the same order.
def tg (ys : List C) : List (Σ k, SΓ C k) := ys.map fun y => ⟨.c y, ()⟩
abbrev SΓ (C : Type) : SK C → Type
| .out => Bool
| .c _ => Unit
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:63
Uses 2 · Used by 4
DefinitionCounters after a multi-target transfer#✓fully proved
Given counter values \(F : C \to \mathbb{N}\), a counter \(x \in C\) and a list \(Y\) of counters, the counter values after transferring \(x\) to \(Y\) form the function that sends \(x\) to \(0\), sends every \(z \ne x\) occurring in \(Y\) to \(F(z) + F(x)\), and sends every other \(z\) to \(F(z)\).
def xf (F : C → ℕ) (x : C) (ys : List C) : C → ℕ :=
fun z => if z = x then 0 else if z ∈ ys then F z + F x else F z
Used by 4
TheoremMulti-target transfer#✓fully proved
Let \(M\) be a counter machine with counters indexed by \(C\), a Boolean output stack and a Boolean state, let \(x \in C\), and let \(Y\) be a list of distinct counters not containing \(x\). Suppose the instruction at label \(\ell\) is the transfer loop that pops counter \(x\) and pushes one unit on every counter of \(Y\), returning to \(\ell\) while \(x\) is nonempty and continuing at label \(\ell'\) once it is empty. Then for all counter values \(F : C \to \mathbb{N}\), every state bit \(v\) and every output stack \(o\), the machine runs in exactly \(F(x) + 1\) steps from label \(\ell\) with state \(v\), counter values \(F\) and output stack \(o\) to label \(\ell'\) with state false, output stack \(o\) and the counter values after transferring \(x\) to \(Y\): counter \(x\) becomes \(0\), each counter of \(Y\) gains \(F(x)\), and every other counter keeps its value.
theorem xferS {self next : Λ} {x : C} {ys : List C} (hp : M self = xfer (.c x) (tg ys) self next)
(hnd : ys.Nodup) (hx : x ∉ ys) (F : C → ℕ) (v : Bool) (o : List Bool) :
Run M (F x + 1) ⟨some self, v, st F o⟩ ⟨some next, false, st (xf F x ys) o⟩
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 tg (ys : List C) : List (Σ k, SΓ C k) := ys.map fun y => ⟨.c y, ()⟩
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:82
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 st (f : C → ℕ) (o : List Bool) : ∀ k, List (SΓ C k)
| .out => o
| .c x => cnt () (f x)
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:72
def xf (F : C → ℕ) (x : C) (ys : List C) : C → ℕ :=
fun z => if z = x then 0 else if z ∈ ys then F z + F x else F z
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:108
Uses 11 · Used by 3
InductiveStages of the power loop#✓fully proved
The labels of one power-loop site: a head stage, a multiplication stage \(\mathrm{mul}(s)\) for each stage \(s\) of a multiplication site, a drain stage and a move stage.
inductive PW
| hd
| mul (s : MS)
| drn
| mv
deriving DecidableEq, Fintype
inductive MS | head | body | l2 | rest
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:49
Uses 1 · Used by 10
DefinitionPower-loop program#✓fully proved
Given six counters \(b\), \(k\), \(p\), \(q\), \(a\), \(t\), a label for each power-loop stage and an exit label, the power loop is the following program on the stages. At the head stage it pops one unit from \(k\); if \(k\) was empty it goes to the exit label, otherwise to the first multiplication stage. The multiplication stages add \(p \cdot b\) to \(q\) (a multiplication site with index counter \(a\) and scratch counter \(t\)) and then go to the drain stage. The drain stage empties \(p\) and goes to the move stage. The move stage moves the contents of \(q\) onto \(p\) and returns to the head stage.
When the six counters are distinct and \(q = a = t = 0\) at the start, each round multiplies \(p\) by \(b\), so the loop replaces \(p\) by \(p \cdot b^k\) and ends with \(k = 0\).
def powS (b kc p q ad t : C) (mk : PW → Λ) (exit : Λ) : PW → TM2.Stmt (SΓ C) Λ Bool
| .hd => decr (.c kc) exit (mk (.mul .head))
| .mul s => mulS p ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c p) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [p]) (mk .mv) (mk .hd)
inductive PW
| hd
| mul (s : MS)
| drn
| mv
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:131
abbrev SΓ (C : Type) : SK C → Type
| .out => Bool
| .c _ => Unit
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:63
def decr (k : K) (ifZero ifPos : Λ) : TM2.Stmt Γ Λ σ :=
.pop k (fun _ o => Flag.tag o.isSome)
(.branch Flag.untag (.goto fun _ => ifPos) (.goto fun _ => ifZero))
MathlibExt/Computability/TuringMachine/Program.lean:141
def mulS (a ad b c t : C) (mk : MS → Λ) (next : Λ) : MS → TM2.Stmt (SΓ C) Λ Bool
| .head => forHead (.c a) (.c ad) () (mk .body) (mk .rest)
| .body => xfer (.c b) [⟨.c c, ()⟩, ⟨.c t, ()⟩] (mk .body) (mk .l2)
| .l2 => xfer (.c t) [⟨.c b, ()⟩] (mk .l2) (mk .head)
| .rest => xfer (.c ad) [⟨.c a, ()⟩] (mk .rest) next
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:154
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 tg (ys : List C) : List (Σ k, SΓ C k) := ys.map fun y => ⟨.c y, ()⟩
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:82
Uses 9 · Used by 2
DefinitionStep budget of the power loop#✓fully proved
For natural numbers \(j\) (the number of rounds), \(p\) (the start value) and \(b\) (the base), the step budget of the power loop is \(j \, (p \, (b + 1)^j \, (3 b + 5) + 5) + 1\).
def powB (j p b : ℕ) : ℕ := j * (p * (b + 1) ^ j * (3 * b + 5) + 5) + 1
Used by 3
TheoremThe power loop#✓fully proved
Let \(b, k, p, q, a, t\) be pairwise distinct counters of a counter machine \(M\), let \(\mu\) assign a label to each power-loop stage and let \(\nu\) be a label. Suppose that for every power-loop stage \(s\) the label \(\mu(s)\) runs the power-loop program for \(b, k, p, q, a, t\) with stage labels \(\mu\) and exit label \(\nu\) at stage \(s\). Let \(j \in \mathbb{N}\), let \(F\) be counter values with \(F(k) = j\) and \(F(q) = F(a) = F(t) = 0\), let \(v\) be a flag and \(o\) an output. Then \(M\) runs from the head stage \(\mu(\mathrm{hd})\) with flag \(v\), counters \(F\) and output \(o\) to the label \(\nu\) with flag false, output \(o\), and counters \(F\) except that \(p\) holds \(F(p) \cdot F(b)^j\) and \(k\) holds \(0\), within \(j\,(F(p)\,(F(b) + 1)^j\,(3F(b) + 5) + 5) + 1\) steps, the step budget of the power loop for \(j\) rounds, start value \(F(p)\) and base \(F(b)\).
theorem pow_run {b kc p q ad t : C} {mk : PW → Λ} {exit : Λ}
(hp : ∀ s, M (mk s) = powS b kc p q ad t mk exit s)
(hnd : [b, kc, p, q, ad, t].Nodup) :
∀ (j : ℕ) (F : C → ℕ), F kc = j → F q = 0 → F ad = 0 → F t = 0 → ∀ (v : Bool) (o : List Bool),
RunLe M (powB j (F p) (F b)) ⟨some (mk .hd), v, st F o⟩
⟨some exit, false, st (update (update F p (F p * F b ^ j)) kc 0) o⟩
inductive PW
| hd
| mul (s : MS)
| drn
| mv
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:131
def powS (b kc p q ad t : C) (mk : PW → Λ) (exit : Λ) : PW → TM2.Stmt (SΓ C) Λ Bool
| .hd => decr (.c kc) exit (mk (.mul .head))
| .mul s => mulS p ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c p) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [p]) (mk .mv) (mk .hd)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:139
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
def powB (j p b : ℕ) : ℕ := j * (p * (b + 1) ^ j * (3 * b + 5) + 5) + 1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:146
def st (f : C → ℕ) (o : List Bool) : ∀ k, List (SΓ C k)
| .out => o
| .c x => cnt () (f x)
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:72
Uses 20 · Used by 1
Horner evaluation of a polynomial on counters
InductiveStages of a Horner round#✓fully proved
The Horner-round stages are \(\mathsf{mul}(s)\), one for each stage \(s\) of a multiplication site, and the three stages \(\mathsf{drn}\), \(\mathsf{mv}\) and \(\mathsf{add}\). In a Horner round they label the multiplication, draining the accumulator, moving the product into the accumulator, and adding the coefficient.
inductive HW
| mul (s : MS)
| drn
| mv
| add
deriving DecidableEq, Fintype
inductive MS | head | body | l2 | rest
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:49
Uses 1 · Used by 12
DefinitionThe statements of one Horner round#✓fully proved
For counters \(b, \mathit{acc}, q, d, t\), a number \(a \in \mathbb{N}\), stage labels \(\mu\) and an exit label \(\nu\): the statements performing \(\mathit{acc} \leftarrow \mathit{acc} \cdot b + a\) in four stages, each stage reaching the next through \(\mu\). The multiplication stages add \(\mathit{acc} \cdot b\) to \(q\) (with index counter \(d\) and scratch counter \(t\)), then the drain stage empties \(\mathit{acc}\), the move stage transfers \(q\) into \(\mathit{acc}\), and the add stage pushes \(a\) units onto \(\mathit{acc}\) and continues at \(\nu\).
def hornS (b acc q ad t : C) (a : ℕ) (mk : HW → Λ) (next : Λ) : HW → TM2.Stmt (SΓ C) Λ Bool
| .mul s => mulS acc ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c acc) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [acc]) (mk .mv) (mk .add)
| .add => emitR (.c acc) (List.replicate a ()) next
inductive HW
| mul (s : MS)
| drn
| mv
| add
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:247
abbrev SΓ (C : Type) : SK C → Type
| .out => Bool
| .c _ => Unit
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:63
def mulS (a ad b c t : C) (mk : MS → Λ) (next : Λ) : MS → TM2.Stmt (SΓ C) Λ Bool
| .head => forHead (.c a) (.c ad) () (mk .body) (mk .rest)
| .body => xfer (.c b) [⟨.c c, ()⟩, ⟨.c t, ()⟩] (mk .body) (mk .l2)
| .l2 => xfer (.c t) [⟨.c b, ()⟩] (mk .l2) (mk .head)
| .rest => xfer (.c ad) [⟨.c a, ()⟩] (mk .rest) next
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:154
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 tg (ys : List C) : List (Σ k, SΓ C k) := ys.map fun y => ⟨.c y, ()⟩
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:82
def emitR (k : K) (ys : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ := emit k ys.reverse next
MathlibExt/Computability/TuringMachine/Program.lean:698
Uses 9 · Used by 4
DefinitionStep count of one Horner round#✓fully proved
For an accumulator value \(A\) and a base \(b\), the number \(A(2b + 3) + A + 2 + (A + 1) + (Ab + 1) + 1\): the exact number of steps one Horner round takes from \(\mathit{acc} = A\) with base \(b\).
def hornStep (A b : ℕ) : ℕ := A * (2 * b + 3) + A + 2 + (A + 1) + (A * b + 1) + 1
Used by 4
TheoremOne Horner round#✓fully proved
Let \(b, \mathit{acc}, q, d, t\) be pairwise distinct counters of a counter machine \(M\), let \(a \in \mathbb{N}\), let \(\mu\) assign a label to each Horner-round stage and let \(\nu\) be a label. Suppose that for every Horner-round stage \(s\) the label \(\mu(s)\) runs the Horner-round statement for \(b, \mathit{acc}, q, d, t, a\) with stage labels \(\mu\) and exit label \(\nu\) at stage \(s\). Let \(F\) be counter values with \(F(q) = F(d) = F(t) = 0\), let \(v\) be a flag and \(o\) an output, and let \(h\) be the step count of one Horner round. Then \(M\) runs from the first multiplication stage \(\mu(\mathrm{mul\ head})\) with flag \(v\), counters \(F\) and output \(o\) in exactly \(h(F(\mathit{acc}), F(b))\) steps to the label \(\nu\) with flag false, output \(o\), and counters \(F\) except that \(\mathit{acc}\) holds \(F(\mathit{acc}) \cdot F(b) + a\).
theorem horn_round {b acc q ad t : C} {a : ℕ} {mk : HW → Λ} {next : Λ}
(hp : ∀ s, M (mk s) = hornS b acc q ad t a mk next s)
(hnd : [b, acc, q, ad, t].Nodup) (F : C → ℕ) (hq : F q = 0) (had : F ad = 0)
(ht : F t = 0) (v : Bool) (o : List Bool) :
Run M (hornStep (F acc) (F b)) ⟨some (mk (.mul .head)), v, st F o⟩
⟨some next, false, st (update F acc (F acc * F b + a)) o⟩
inductive HW
| mul (s : MS)
| drn
| mv
| add
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:247
def hornS (b acc q ad t : C) (a : ℕ) (mk : HW → Λ) (next : Λ) : HW → TM2.Stmt (SΓ C) Λ Bool
| .mul s => mulS acc ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c acc) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [acc]) (mk .mv) (mk .add)
| .add => emitR (.c acc) (List.replicate a ()) next
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:256
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 hornStep (A b : ℕ) : ℕ := A * (2 * b + 3) + A + 2 + (A + 1) + (A * b + 1) + 1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:263
def st (f : C → ℕ) (o : List Bool) : ∀ k, List (SΓ C k)
| .out => o
| .c x => cnt () (f x)
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:72
Uses 21 · Used by 1
DefinitionHorner value#✓fully proved
For a list \(c_1, \dots, c_\ell\) of natural numbers and natural numbers \(b\) and \(A\), the Horner value of \(c_1, \dots, c_\ell\) with base \(b\) from accumulator \(A\) is the number obtained from the starting value \(x = A\) by replacing \(x\) by \(x b + c_i\) for \(i = 1, \dots, \ell\) in turn; for the empty list it is \(A\).
def hornVal (cs : List ℕ) (b A : ℕ) : ℕ := cs.foldl (fun A a => A * b + a) A
DefinitionStep count of the Horner rounds#✓fully proved
For a list \(cs\) of coefficients, a base \(b\) and an accumulator value \(A\): \(0\) if \(cs\) is empty, and if \(cs\) is \(a\) followed by \(cs'\), the step count \(h(A, b)\) of one Horner round from \(A\) with base \(b\) plus the step count of \(cs'\) with base \(b\) from accumulator \(A b + a\). This is the exact number of steps of the Horner rounds.
def hornT : List ℕ → ℕ → ℕ → ℕ
| [], _, _ => 0
| a :: cs, b, A => hornStep A b + hornT cs b (A * b + a)
def hornStep (A b : ℕ) : ℕ := A * (2 * b + 3) + A + 2 + (A + 1) + (A * b + 1) + 1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:263
Uses 1 · Used by 7
TheoremHorner rounds#✓fully proved
Let \(b, \mathit{acc}, q, d, t\) be pairwise distinct counters of a counter machine \(M\), let \(c_0, \dots, c_{\ell-1}\) be natural numbers, let \(\mu\) assign a label \(\mu(i, s)\) to each \(i \in \mathbb{N}\) and each Horner-round stage \(s\), and let \(\nu\) be a label. Suppose that for every \(i < \ell\) and every stage \(s\) the label \(\mu(i, s)\) runs, at stage \(s\), the statement of one Horner round for \(b, \mathit{acc}, q, d, t\) and the number \(c_i\), with stage labels \(\mu(i, \cdot)\) and exit label \(\mu(i + 1, \mathrm{mul\ head})\) if \(i + 1 < \ell\) and \(\nu\) otherwise. Then for all \(i, j \in \mathbb{N}\) with \(i + j = \ell\), all counter values \(F\) with \(F(q) = F(d) = F(t) = 0\), every flag \(v\) and every output \(o\), there is a flag \(v'\) such that \(M\) runs in exactly \(h\) steps from the label \(\mu(i, \mathrm{mul\ head})\) if \(i < \ell\) and \(\nu\) otherwise, with flag \(v\), counters \(F\) and output \(o\), to the label \(\nu\) with flag \(v'\), output \(o\), and counters \(F\) except that \(\mathit{acc}\) holds the Horner value of \(c_i, \dots, c_{\ell-1}\) with base \(F(b)\) from accumulator \(F(\mathit{acc})\). Here \(h\) is the step count of the Horner rounds over \(c_i, \dots, c_{\ell-1}\) with base \(F(b)\) from accumulator \(F(\mathit{acc})\).
theorem horner_run {b acc q ad t : C} (cs : List ℕ) {mk : ℕ → HW → Λ} {exit : Λ}
(hp : ∀ i (hi : i < cs.length) s, M (mk i s) = hornS b acc q ad t cs[i] (mk i)
(if i + 1 < cs.length then mk (i + 1) (.mul .head) else exit) s)
(hnd : [b, acc, q, ad, t].Nodup) :
∀ (j i : ℕ), i + j = cs.length → ∀ (F : C → ℕ), F q = 0 → F ad = 0 → F t = 0 →
∀ (v : Bool) (o : List Bool),
∃ v' : Bool, Run M (hornT (cs.drop i) (F b) (F acc))
⟨some (if i < cs.length then mk i (.mul .head) else exit), v, st F o⟩
⟨some exit, v', st (update F acc (hornVal (cs.drop i) (F b) (F acc))) o⟩
inductive HW
| mul (s : MS)
| drn
| mv
| add
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:247
def hornS (b acc q ad t : C) (a : ℕ) (mk : HW → Λ) (next : Λ) : HW → TM2.Stmt (SΓ C) Λ Bool
| .mul s => mulS acc ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c acc) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [acc]) (mk .mv) (mk .add)
| .add => emitR (.c acc) (List.replicate a ()) next
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:256
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 hornT : List ℕ → ℕ → ℕ → ℕ
| [], _, _ => 0
| a :: cs, b, A => hornStep A b + hornT cs b (A * b + a)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:310
def st (f : C → ℕ) (o : List Bool) : ∀ k, List (SΓ C k)
| .out => o
| .c x => cnt () (f x)
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:72
def hornVal (cs : List ℕ) (b A : ℕ) : ℕ := cs.foldl (fun A a => A * b + a) A
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:307
Uses 11 · Used by 1
TheoremSplitting off the starting accumulator in Horner evaluation#✓fully proved
For a list \(c_1, \dots, c_\ell\) of natural numbers and natural numbers \(b\) and \(A\), write \(h(x)\) for the Horner value of \(c_1, \dots, c_\ell\) with base \(b\) from accumulator \(x\): the number obtained from the starting value \(x\) by replacing the current value \(y\) by \(y b + c_i\) for \(i = 1, \dots, \ell\) in turn. Then \(h(A) = A b^{\ell} + h(0)\).
theorem hornVal_eq (cs : List ℕ) (b A : ℕ) :
hornVal cs b A = A * b ^ cs.length + hornVal cs b 0
def hornVal (cs : List ℕ) (b A : ℕ) : ℕ := cs.foldl (fun A a => A * b + a) A
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:307
Uses 1 · Used by 1
DefinitionCoefficient list of a polynomial#✓fully proved
For a polynomial \(p\) with natural-number coefficients and natural degree \(d\) (where \(d = 0\) when \(p = 0\)), the coefficient list of \(p\) is \([p_d, p_{d-1}, \dots, p_1, p_0]\), where \(p_i\) is the coefficient of \(X^i\) in \(p\).
noncomputable def coeffs (p : Polynomial ℕ) : List ℕ :=
(List.range (p.natDegree + 1)).reverse.map p.coeff
Used by 15
TheoremHorner's rule#✓fully proved
For every polynomial \(p\) with natural coefficients and every \(b \in \mathbb{N}\), running Horner rounds with base \(b\) on the coefficients of \(p\) (highest degree first), starting from accumulator \(0\), yields \(p(b)\).
theorem hornVal_coeffs (p : Polynomial ℕ) (b : ℕ) : hornVal (coeffs p) b 0 = p.eval b
def hornVal (cs : List ℕ) (b A : ℕ) : ℕ := cs.foldl (fun A a => A * b + a) A
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:307
noncomputable def coeffs (p : Polynomial ℕ) : List ℕ :=
(List.range (p.natDegree + 1)).reverse.map p.coeff
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:369
Uses 3 · Used by 1
The precomputation's counter program
InductiveScratch counters of the counter program#✓fully proved
The type of the twelve private counters of the precomputation's counter program, with constructors \(N\), \(P\), \(Q\), \(AD\), \(TMP\), \(KC\), \(Mc\), \(B\), \(Tc\), \(Fx\), \(Dd\), \(Hc\).
inductive PS
| N | P | Q | AD | TMP | KC | Mc | B | Tc | Fx | Dd | Hc
deriving DecidableEq
Used by 26
InductiveTarget counters of the counter program#✓fully proved
The type of the twelve counters that the precomputation's counter program loads for the host, with constructors \(uT\), \(uH\), \(sT\), \(sH\), \(hT\), \(hH\), \(aT\), \(aH\), \(iT\), \(iX\), \(iE\), \(iF\).
They hold the twelve preloads of the assembled generator's run.
inductive PT
| uT | uH | sT | sH | hT | hH | aT | aH | iT | iX | iE | iF
deriving DecidableEq
Used by 14
InductiveCounters of the counter program#✓fully proved
A counter of the counter program is either a scratch counter \(s(x)\), for one of the twelve scratch counter names \(x\), or a target counter \(t(y)\), for one of the twelve target counter names \(y\): the counters are the disjoint union of the scratch counters and the target counters.
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
inductive PS
| N | P | Q | AD | TMP | KC | Mc | B | Tc | Fx | Dd | Hc
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:395
inductive PT
| uT | uH | sT | sH | hT | hH | aT | aH | iT | iX | iE | iF
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:404
Uses 2 · Used by 11
InductiveLabels of the counter program#✓fully proved
For \(D \in \mathbb{N}\), the number of Horner rounds, the labels of the counter program are \(p_1\); a label \(\mathrm{hr}(i, s)\) for each round \(i < D\) and each Horner-round stage \(s\); the labels \(x_1, x_2, x_3, x_4, c_1, c_2, x_6, x_7, x_8\); a label \(w_2(s)\) for each power-loop stage \(s\); \(x_9\); a label \(\mathrm{ml}(s)\) for each stage \(s\) of a multiplication site; the labels \(x_{10}, x_{11}, x_{12}, x_{13}, x_{14}\); and \(\mathrm{done}\).
inductive PL (D : ℕ)
| p1 | hr (i : Fin D) (s : HW) | x1 | x2 | x3 | x4 | c1 | c2 | x6 | x7 | x8 | w2 (s : PW) | x9
| ml (s : MS) | x10 | x11 | x12 | x13 | x14 | done
deriving DecidableEq, Fintype
inductive HW
| mul (s : MS)
| drn
| mv
| add
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:247
inductive PW
| hd
| mul (s : MS)
| drn
| mv
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:131
inductive MS | head | body | l2 | rest
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:49
Uses 3 · Used by 11
DefinitionHorner-round labels indexed by natural numbers#✓fully proved
For a number \(D\) of Horner rounds, \(i \in \mathbb{N}\) and a Horner-round stage \(s\): the counter-program label for stage \(s\) of Horner round \(i\) if \(i < D\), and otherwise the label \(x_1\) that follows the Horner rounds.
Indices \(i \ge D\) are never reached.
def hlab {D : ℕ} (i : ℕ) (s : HW) : PL D := if h : i < D then .hr ⟨i, h⟩ s else .x1
inductive HW
| mul (s : MS)
| drn
| mv
| add
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:247
inductive PL (D : ℕ)
| p1 | hr (i : Fin D) (s : HW) | x1 | x2 | x3 | x4 | c1 | c2 | x6 | x7 | x8 | w2 (s : PW) | x9
| ml (s : MS) | x10 | x11 | x12 | x13 | x14 | done
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:419
Uses 2 · Used by 2
DefinitionThe counter program#✓fully proved
For a polynomial \(k\) with natural-number coefficients, whose coefficient list \(\kappa_0, \dots, \kappa_{D-1}\) has length \(D\), and \(c, e, d \in \mathbb{N}\), the counter program is the program with the labels of the counter program for \(D\) Horner rounds that acts on a Boolean output stack and on the scratch and target counters of the counter program as follows. It runs \(D\) Horner rounds, round \(i\) with coefficient \(\kappa_i\), base \(N\), accumulator \(P\), product counter \(Q\), index counter \(AD\) and scratch counter \(TMP\). It moves \(P\) onto both \(Mc\) and the target \(iE\), moves \(N\) onto both \(Mc\) and the target \(iX\), and adds one unit to each of \(Mc\) and \(iX\). It adds \(Mc\) to \(B\), restoring \(Mc\) through \(TMP\), adds \(c\) units to \(B\), \(e\) units to \(KC\) and one unit to \(Tc\), and runs the power loop with base \(B\), round counter \(KC\), accumulator \(Tc\), product counter \(Q\), index counter \(AD\) and scratch counter \(TMP\). It adds \(d\) units to \(Dd\), adds \(Dd \cdot Tc\) to \(Fx\) (index counter \(AD\), scratch counter \(TMP\)) and adds \(d + 1\) more units to \(Fx\). It moves \(Fx\) onto both \(Hc\) and the target \(iF\) and moves \(Mc\) onto \(Hc\). Finally it moves \(Tc\) onto each of the targets \(uT, sT, hT, aT, iT\), moves \(Hc\) onto each of the targets \(uH, sH, hH, aH\), and halts.
Started with \(n\) on \(N\) and every other counter empty, the program computes \(P = k(n)\) by Horner's rule, \(m = n + 1 + k(n)\) on \(Mc\), \(T = (m + c)^e\) on \(Tc\), \(dT + d + 1\) on \(Fx\) and \(m + dT + d + 1\) on \(Hc\), and so loads the twelve target counters.
Cslib.Complexity.CookLevin.Precompute.cprog · 23 lines
noncomputable def cprog (k : Polynomial ℕ) (c e d : ℕ) :
PL (coeffs k).length → TM2.Stmt (SΓ CC) (PL (coeffs k).length) Bool
| .p1 => emitR (.c (s P)) (List.replicate 0 ()) (if 0 < (coeffs k).length then hlab 0 (.mul .head) else .x1)
| .hr i q => hornS (s N) (s P) (s Q) (s AD) (s TMP) (coeffs k)[i] (hlab i.1)
(if i.1 + 1 < (coeffs k).length then hlab (i.1 + 1) (.mul .head) else .x1) q
| .x1 => xfer (.c (s P)) (tg [s Mc, t iE]) .x1 .x2
| .x2 => xfer (.c (s N)) (tg [s Mc, t iX]) .x2 .x3
| .x3 => emitR (.c (s Mc)) (List.replicate 1 ()) .x4
| .x4 => emitR (.c (t iX)) (List.replicate 1 ()) .c1
| .c1 => xfer (.c (s Mc)) [⟨.c (s B), ()⟩, ⟨.c (s TMP), ()⟩] .c1 .c2
| .c2 => xfer (.c (s TMP)) [⟨.c (s Mc), ()⟩] .c2 .x6
| .x6 => emitR (.c (s B)) (List.replicate c ()) .x7
| .x7 => emitR (.c (s KC)) (List.replicate e ()) .x8
| .x8 => emitR (.c (s Tc)) (List.replicate 1 ()) (.w2 .hd)
| .w2 q => powS (s B) (s KC) (s Tc) (s Q) (s AD) (s TMP) PL.w2 .x9 q
| .x9 => emitR (.c (s Dd)) (List.replicate d ()) (.ml .head)
| .ml q => mulS (s Dd) (s AD) (s Tc) (s Fx) (s TMP) PL.ml .x10 q
| .x10 => emitR (.c (s Fx)) (List.replicate (d + 1) ()) .x11
| .x11 => xfer (.c (s Fx)) (tg [s Hc, t iF]) .x11 .x12
| .x12 => xfer (.c (s Mc)) (tg [s Hc]) .x12 .x13
| .x13 => xfer (.c (s Tc)) (tg [t uT, t sT, t hT, t aT, t iT]) .x13 .x14
| .x14 => xfer (.c (s Hc)) (tg [t uH, t sH, t hH, t aH]) .x14 .done
| .done => .halt
inductive PL (D : ℕ)
| p1 | hr (i : Fin D) (s : HW) | x1 | x2 | x3 | x4 | c1 | c2 | x6 | x7 | x8 | w2 (s : PW) | x9
| ml (s : MS) | x10 | x11 | x12 | x13 | x14 | done
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:419
noncomputable def coeffs (p : Polynomial ℕ) : List ℕ :=
(List.range (p.natDegree + 1)).reverse.map p.coeff
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:369
abbrev SΓ (C : Type) : SK C → Type
| .out => Bool
| .c _ => Unit
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:63
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
def emitR (k : K) (ys : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ := emit k ys.reverse next
MathlibExt/Computability/TuringMachine/Program.lean:698
def hlab {D : ℕ} (i : ℕ) (s : HW) : PL D := if h : i < D then .hr ⟨i, h⟩ s else .x1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:425
def hornS (b acc q ad t : C) (a : ℕ) (mk : HW → Λ) (next : Λ) : HW → TM2.Stmt (SΓ C) Λ Bool
| .mul s => mulS acc ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c acc) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [acc]) (mk .mv) (mk .add)
| .add => emitR (.c acc) (List.replicate a ()) next
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:256
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 tg (ys : List C) : List (Σ k, SΓ C k) := ys.map fun y => ⟨.c y, ()⟩
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:82
def powS (b kc p q ad t : C) (mk : PW → Λ) (exit : Λ) : PW → TM2.Stmt (SΓ C) Λ Bool
| .hd => decr (.c kc) exit (mk (.mul .head))
| .mul s => mulS p ad b q t (fun s => mk (.mul s)) (mk .drn) s
| .drn => xfer (.c p) [] (mk .drn) (mk .mv)
| .mv => xfer (.c q) (tg [p]) (mk .mv) (mk .hd)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:139
def mulS (a ad b c t : C) (mk : MS → Λ) (next : Λ) : MS → TM2.Stmt (SΓ C) Λ Bool
| .head => forHead (.c a) (.c ad) () (mk .body) (mk .rest)
| .body => xfer (.c b) [⟨.c c, ()⟩, ⟨.c t, ()⟩] (mk .body) (mk .l2)
| .l2 => xfer (.c t) [⟨.c b, ()⟩] (mk .l2) (mk .head)
| .rest => xfer (.c ad) [⟨.c a, ()⟩] (mk .rest) next
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:154
Uses 18 · Used by 3
DefinitionTotal length bound#✓fully proved
For a polynomial \(k\) with natural-number coefficients and \(n \in \mathbb{N}\), the total length bound is \(m = n + 1 + k(n)\).
So a word \(x\) of length \(n + 1\) followed by a word \(y\) has length at most \(m\) exactly when \(y\) has length at most \(k(n)\).
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
Used by 16
DefinitionThe precomputed time bound#✓fully proved
For a polynomial \(k\) with natural coefficients and \(c, e, n \in \mathbb{N}\), the time bound is \(T = (m + c)^e\), where \(m = n + 1 + k(n)\).
def TOf (k : Polynomial ℕ) (c e n : ℕ) : ℕ := (mOf k n + c) ^ e
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:455
Uses 1 · Used by 13
DefinitionStart counter values#✓fully proved
For a natural number \(n\), the start counter values of the counter program give the scratch counter \(N\) the value \(n\) and every other counter the value \(0\).
def F0 (n : ℕ) : CC → ℕ
| .s .N => n
| _ => 0
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
Uses 3 · Used by 2
DefinitionCounter values after the Horner loop#✓fully proved
For a polynomial \(k\) with natural-number coefficients and \(n \in \mathbb{N}\), this is the assignment of values to the counters of the counter program that gives the scratch counter \(N\) the value \(n\), the scratch counter \(P\) the value \(k(n)\), and every other counter the value \(0\).
The counter program reaches these values after its Horner loop has evaluated \(k(n)\).
def F1 (k : Polynomial ℕ) (n : ℕ) : CC → ℕ
| .s .N => n
| .s .P => k.eval n
| _ => 0
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
Uses 3 · Used by 1
DefinitionCounter values before the power loop#✓fully proved
For a polynomial \(k\) with natural-number coefficients and \(c, e, n \in \mathbb{N}\), write \(m = n + 1 + k(n)\). This is the assignment of values to the counters of the counter program that gives the scratch counters \(\mathit{Mc}\), \(B\), \(\mathit{KC}\) and \(\mathit{Tc}\) the values \(m\), \(m + c\), \(e\) and \(1\), the target counters \(\mathit{iX}\) and \(\mathit{iE}\) the values \(n + 1\) and \(k(n)\), and every other counter the value \(0\).
def F2 (k : Polynomial ℕ) (c e n : ℕ) : CC → ℕ
| .s .Mc => mOf k n
| .s .B => mOf k n + c
| .s .KC => e
| .s .Tc => 1
| .t .iX => n + 1
| .t .iE => k.eval n
| _ => 0
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:455
Uses 4 · Used by 1
DefinitionCounter values after the power loop#✓fully proved
For a polynomial \(k\) with natural-number coefficients and \(c, e, n \in \mathbb{N}\), write \(m = n + 1 + k(n)\). This is the assignment of values to the counters of the counter program that gives the scratch counters \(\mathit{Mc}\), \(B\) and \(\mathit{Tc}\) the values \(m\), \(m + c\) and \((m + c)^e\), the target counters \(\mathit{iX}\) and \(\mathit{iE}\) the values \(n + 1\) and \(k(n)\), and every other counter the value \(0\).
def F3 (k : Polynomial ℕ) (c e n : ℕ) : CC → ℕ
| .s .Mc => mOf k n
| .s .B => mOf k n + c
| .s .Tc => TOf k c e n
| .t .iX => n + 1
| .t .iE => k.eval n
| _ => 0
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
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 1
DefinitionTarget counter values#✓fully proved
For a polynomial \(k\) with natural-number coefficients and natural numbers \(c, e, d, n\), let \(m = n + 1 + k(n)\), \(T = (m + c)^e\) and let \(H = m + (T + 1)d + 1\) be the stack cap. The target values on the twelve target counters assign \(T\) to each of \(u_T, s_T, h_T, a_T, i_T\), assign \(H\) to each of \(u_H, s_H, h_H, a_H\), and assign \(n + 1\) to \(i_X\), \(k(n)\) to \(i_E\) and \((T + 1)d + 1\) to \(i_F\).
In particular the value at \(i_F\) is \(H - m\).
def tv (k : Polynomial ℕ) (c e d n : ℕ) : PT → ℕ
| .uT | .sT | .hT | .aT | .iT => TOf k c e n
| .uH | .sH | .hH | .aH => Situation.capH (mOf k n) (TOf k c e n) d
| .iX => n + 1
| .iE => k.eval n
| .iF => (TOf k c e n + 1) * d + 1
inductive PT
| uT | uH | sT | sH | hT | hH | aT | aH | iT | iX | iE | iF
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:404
def TOf (k : Polynomial ℕ) (c e n : ℕ) : ℕ := (mOf k n + c) ^ e
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:458
def capH (m T d : ℕ) : ℕ := m + (T + 1) * d + 1
CSLibExt/Computability/Complexity/CookLevin/Situation.lean:1420
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:455
Uses 4 · Used by 3
DefinitionCounter values at the end of the counter program#✓fully proved
For a polynomial \(k\) with natural-number coefficients and \(c, e, d, n \in \mathbb{N}\), write \(m = n + 1 + k(n)\) and \(T = (m + c)^e\). This is the assignment of values to the counters of the counter program that gives the scratch counters \(B\) and \(\mathit{Dd}\) the values \(m + c\) and \(d\), gives each target counter its target value (\(T\) for \(\mathit{uT}\), \(\mathit{sT}\), \(\mathit{hT}\), \(\mathit{aT}\) and \(\mathit{iT}\); \(m + (T + 1)d + 1\) for \(\mathit{uH}\), \(\mathit{sH}\), \(\mathit{hH}\) and \(\mathit{aH}\); \(n + 1\) for \(\mathit{iX}\); \(k(n)\) for \(\mathit{iE}\); \((T + 1)d + 1\) for \(\mathit{iF}\)), and gives every other scratch counter the value \(0\).
def F4 (k : Polynomial ℕ) (c e d n : ℕ) : CC → ℕ
| .s .B => mOf k n + c
| .s .Dd => d
| .t y => tv k c e d n y
| _ => 0
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:455
def tv (k : Polynomial ℕ) (c e d n : ℕ) : PT → ℕ
| .uT | .sT | .hT | .aT | .iT => TOf k c e n
| .uH | .sH | .hH | .aH => Situation.capH (mOf k n) (TOf k c e n) d
| .iX => n + 1
| .iE => k.eval n
| .iF => (TOf k c e n + 1) * d + 1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:491
Uses 5 · Used by 2
DefinitionStep budget of the counter program#✓fully proved
For a polynomial \(k\) with natural-number coefficients and natural numbers \(c, e, d, n\), let \(m = n + 1 + k(n)\), \(T = (m + c)^e\) and \(H = m + (T + 1)d + 1\). The step budget of the counter program at \((k, c, e, d, n)\) is
where \(h\) is the exact step count of the Horner rounds over the coefficient list of \(k\) with base \(n\) from accumulator \(0\), and \(p = e\left((m + c + 1)^e (3(m + c) + 5) + 5\right) + 1\) is the step budget of the power loop with \(e\) rounds, start value \(1\) and base \(m + c\).
noncomputable def cB (k : Polynomial ℕ) (c e d n : ℕ) : ℕ :=
1 + hornT (coeffs k) n 0 + (k.eval n + 1) + (n + 1) + 2 + (2 * mOf k n + 2) + 3 + powB e 1 (mOf k n + c) +
1 + (d * (2 * TOf k c e n + 3) + d + 2) + 1 + (d * TOf k c e n + d + 2) + (mOf k n + 1) +
(TOf k c e n + 1) + (Situation.capH (mOf k n) (TOf k c e n) d + 1)
def hornT : List ℕ → ℕ → ℕ → ℕ
| [], _, _ => 0
| a :: cs, b, A => hornStep A b + hornT cs b (A * b + a)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:310
noncomputable def coeffs (p : Polynomial ℕ) : List ℕ :=
(List.range (p.natDegree + 1)).reverse.map p.coeff
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:369
def mOf (k : Polynomial ℕ) (n : ℕ) : ℕ := n + 1 + k.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:455
def powB (j p b : ℕ) : ℕ := j * (p * (b + 1) ^ j * (3 * b + 5) + 5) + 1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:146
def TOf (k : Polynomial ℕ) (c e n : ℕ) : ℕ := (mOf k n + c) ^ e
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:458
def capH (m T d : ℕ) : ℕ := m + (T + 1) * d + 1
CSLibExt/Computability/Complexity/CookLevin/Situation.lean:1420
Uses 6 · Used by 7
TheoremThe counter program's run#✓fully proved
Let \(k\) be a polynomial with natural-number coefficients, let \(c, e, d, n\) be natural numbers, and put \(m = n + 1 + k(n)\) and \(T = (m + c)^e\). Start the counter program for \(k, c, e, d\) at its first label with any flag, any output stack \(o\), the scratch counter \(N\) equal to \(n\) and every other counter equal to \(0\). Then, in a number of steps at most the step budget of the counter program at \((k, c, e, d, n)\), it reaches its label \(\mathrm{done}\) with flag false, output stack \(o\), and counter values \(T\) on the targets \(uT, sT, hT, aT, iT\); \(m + (T + 1)d + 1\) on the targets \(uH, sH, hH, aH\); \(n + 1\) on \(iX\); \(k(n)\) on \(iE\); \((T + 1)d + 1\) on \(iF\); \(m + c\) on the scratch counter \(B\); \(d\) on the scratch counter \(Dd\); and \(0\) on every other counter.
theorem cprog_run (k : Polynomial ℕ) (c e d n : ℕ) (v : Bool) (o : List Bool) :
RunLe (cprog k c e d) (cB k c e d n) ⟨some .p1, v, st (F0 n) o⟩
⟨some .done, false, st (F4 k c e d n) o⟩
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 cprog (k : Polynomial ℕ) (c e d : ℕ) :
PL (coeffs k).length → TM2.Stmt (SΓ CC) (PL (coeffs k).length) Bool
| .p1 => emitR (.c (s P)) (List.replicate 0 ()) (if 0 < (coeffs k).length then hlab 0 (.mul .head) else .x1)
| .hr i q => hornS (s N) (s P) (s Q) (s AD) (s TMP) (coeffs k)[i] (hlab i.1)
(if i.1 + 1 < (coeffs k).length then hlab (i.1 + 1) (.mul .head) else .x1) q
| .x1 => xfer (.c (s P)) (tg [s Mc, t iE]) .x1 .x2
| .x2 => xfer (.c (s N)) (tg [s Mc, t iX]) .x2 .x3
| .x3 => emitR (.c (s Mc)) (List.replicate 1 ()) .x4
| .x4 => emitR (.c (t iX)) (List.replicate 1 ()) .c1
| .c1 => xfer (.c (s Mc)) [⟨.c (s B), ()⟩, ⟨.c (s TMP), ()⟩] .c1 .c2
| .c2 => xfer (.c (s TMP)) [⟨.c (s Mc), ()⟩] .c2 .x6
| .x6 => emitR (.c (s B)) (List.replicate c ()) .x7
⋯
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:430
noncomputable def cB (k : Polynomial ℕ) (c e d n : ℕ) : ℕ :=
1 + hornT (coeffs k) n 0 + (k.eval n + 1) + (n + 1) + 2 + (2 * mOf k n + 2) + 3 + powB e 1 (mOf k n + c) +
1 + (d * (2 * TOf k c e n + 3) + d + 2) + 1 + (d * TOf k c e n + d + 2) + (mOf k n + 1) +
(TOf k c e n + 1) + (Situation.capH (mOf k n) (TOf k c e n) d + 1)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:506
def st (f : C → ℕ) (o : List Bool) : ∀ k, List (SΓ C k)
| .out => o
| .c x => cnt () (f x)
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:72
def F0 (n : ℕ) : CC → ℕ
| .s .N => n
| _ => 0
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:461
def F4 (k : Polynomial ℕ) (c e d n : ℕ) : CC → ℕ
| .s .B => mOf k n + c
| .s .Dd => d
| .t y => tv k c e d n y
| _ => 0
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:499
Uses 44 · Used by 1
The full machine: read loop, counter program, host
InductiveStacks of the full machine#✓fully proved
The full machine has one stack for each host stack, one stack for the raw input, and one stack for each scratch counter of the counter program.
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
inductive HK
| out
| inp
| up (x : Family.CK)
| sd (x : Family.CK)
| sh (x : Shift.CK)
| ac (x : Accept.CK)
| ini (x : InitFamily.CK)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:57
inductive PS
| N | P | Q | AD | TMP | KC | Mc | B | Tc | Fx | Dd | Hc
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:395
Uses 2 · Used by 24
AbbreviationAlphabets of the full machine#✓fully proved
For natural numbers \(g, r\), the alphabet of a stack of the full machine is the host's alphabet with \(g\) input codes on each host stack, \(\{0, 1, \dots, r - 1\}\) on the raw input stack, and the one-point type on each private counter.
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:569
abbrev HΓ (g : ℕ) : HK → Type
| .out => Bool
| .inp => Fin g
| .up _ => Unit
| .sd _ => Unit
| .sh _ => Unit
| .ac _ => Unit
| .ini _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:68
Uses 4 · Used by 16
InductiveLabels of the full machine#✓fully proved
For \(D \in \mathbb{N}\) and a type \(\Lambda\) of host labels, the labels of the full machine are the read-loop label, one label for each label of the counter program with \(D\) Horner rounds, and one label for each element of \(\Lambda\).
inductive FL (D : ℕ) (Λ : Type)
| rd
| pre (l : PL D)
| h (l : Λ)
deriving DecidableEq, Fintype
inductive PL (D : ℕ)
| p1 | hr (i : Fin D) (s : HW) | x1 | x2 | x3 | x4 | c1 | c2 | x6 | x7 | x8 | w2 (s : PW) | x9
| ml (s : MS) | x10 | x11 | x12 | x13 | x14 | done
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:419
Uses 1 · Used by 11
DefinitionHost counter of each target#✓fully proved
The map from the twelve targets to host stacks: \(uT\) and \(uH\) go to the counters \(T_n\) and \(H_s\) of the update generator's block, \(sT\) and \(sH\) to those of the situation-definition generator's block, \(hT\) and \(hH\) to those of the shift generator's block, \(aT\) and \(aH\) to those of the accept generator's block, and \(iT\), \(iX\), \(iE\), \(iF\) to the counters \(T_n\), \(X_n\), \(E_n\), \(F_n\) of the init generator's block.
def tgt : PT → HK
| .uT => .up .Tn
| .uH => .up .Hs
| .sT => .sd .Tn
| .sH => .sd .Hs
| .hT => .sh .Tn
| .hH => .sh .Hs
| .aT => .ac .Tn
| .aH => .ac .Hs
| .iT => .ini .Tn
| .iX => .ini .Xn
| .iE => .ini .En
| .iF => .ini .Fn
inductive PT
| uT | uH | sT | sH | hT | hH | aT | aH | iT | iX | iE | iF
deriving DecidableEq
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:404
inductive HK
| out
| inp
| up (x : Family.CK)
| sd (x : Family.CK)
| sh (x : Shift.CK)
| ac (x : Accept.CK)
| ini (x : InitFamily.CK)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:57
DefinitionStack renaming of the counter program#✓fully proved
The stack renaming of the counter program into the full machine sends the output stack to the host's output stack, each scratch counter \(x\) to the full machine's private counter for \(x\), and each target counter \(y\) to the host counter that receives \(y\).
def eC : SK CC → FK
| .out => .h .out
| .c (.s x) => .pc x
| .c (.t y) => .h (tgt y)
inductive SK (C : Type)
| out
| c (x : C)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:57
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:569
def tgt : PT → HK
| .uT => .up .Tn
| .uH => .up .Hs
| .sT => .sd .Tn
| .sH => .sd .Hs
| .hT => .sh .Tn
| .hH => .sh .Hs
| .aT => .ac .Tn
| .aH => .ac .Hs
| .iT => .ini .Tn
| .iX => .ini .Xn
| .iE => .ini .En
⋯
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:589
DefinitionEmbedding of the counter program's stacks#✓fully proved
For natural numbers \(g, r\), the stack embedding of the counter program into the full machine with \(g\) input codes and \(r\) raw input symbols renames stacks by the stack renaming of the counter program and identifies the alphabet of each stack with that of its image by the identity (Booleans on the output stack, the one-point type on each counter).
Cslib.Complexity.CookLevin.Precompute.embC · 17 lines
def embC : SEmb (SΓ CC) (FΓ g r) where
e := eC
inj := by
intro a b h
rcases a with _ | (x | y) <;> rcases b with _ | (x' | y') <;>
simp only [eC, FK.h.injEq, FK.pc.injEq, reduceCtorEq] at h ⊢
all_goals first
| exact h
| (subst h; rfl)
| (cases y <;> cases h)
| (cases y' <;> cases h)
| (cases y <;> cases y' <;> first | rfl | cases h)
ι := fun k => match k with
| .out => Equiv.refl _
| .c (.s _) => Equiv.refl _
| .c (.t y) => match y with
| .uT | .uH | .sT | .sH | .hT | .hH | .aT | .aH | .iT | .iX | .iE | .iF => 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
abbrev SΓ (C : Type) : SK C → Type
| .out => Bool
| .c _ => Unit
CSLibExt/Computability/Complexity/CookLevin/CounterView.lean:63
inductive CC
| s (x : PS)
| t (y : PT)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:413
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
def eC : SK CC → FK
| .out => .h .out
| .c (.s x) => .pc x
| .c (.t y) => .h (tgt y)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:604
Uses 15 · Used by 2
DefinitionEmbedding of the host's stacks#✓fully proved
For natural numbers \(g, r\), the stack embedding of the host into the full machine with \(g\) input codes and \(r\) raw input symbols sends each host stack to the same host stack of the full machine and identifies their alphabets by the identity.
def embH : SEmb (HΓ g) (FΓ g r) where
e := FK.h
inj := fun _ _ h => by cases h; rfl
ι := 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
abbrev HΓ (g : ℕ) : HK → Type
| .out => Bool
| .inp => Fin g
| .up _ => Unit
| .sd _ => Unit
| .sh _ => Unit
| .ac _ => Unit
| .ini _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:68
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
inductive FK
| h (k : HK)
| raw
| pc (x : PS)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:569
Uses 6 · Used by 2
DefinitionThe read loop#✓fully proved
Given a code map \(c_f\) from the raw alphabet \(\mathrm{Fin}\,r\) to the code alphabet \(\mathrm{Fin}\,g\), a separator code \(c_s\) and a list \(L\) of raw symbols, the read-loop statement tests the symbols \(i\) of \(L\) in order against the top of the raw input stack. At the first \(i\) found on top, it pops it, pushes \(c_f(i)\) on the host input stack and one unit on the scratch counter \(N\), and goes back to the read-loop label (with the flag true). If no symbol of \(L\) is on top, in particular when the raw input is empty, it pushes \(c_s\) on the input stack, sets the flag to false and goes to the first label of the counter program.
The full program takes \(L\) to be all of \(\mathrm{Fin}\,r\), so each step reads one input symbol.
def rdT (cf : Fin r → Fin g) (cs : Fin g) : List (Fin r) → TM2.Stmt (FΓ g r) (FL D Λ) Bool
| [] => .push (.h .inp) (fun _ => cs) (.load (fun _ => false) (.goto fun _ => .pre .p1))
| i :: L => .peek .raw (fun _ o => decide (o = some i))
(.branch id (.pop .raw (fun v _ => v) (.push (.h .inp) (fun _ => cf i)
(.push (.pc .N) (fun _ => ()) (.goto fun _ => .rd)))) (rdT cf cs L))
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
inductive FL (D : ℕ) (Λ : Type)
| rd
| pre (l : PL D)
| h (l : Λ)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:582
Uses 6 · Used by 2
DefinitionStacks during the read loop#✓fully proved
For a list \(s\) of raw symbols in \(\mathrm{Fin}\,r\), a list \(w\) of input codes in \(\mathrm{Fin}\,g\), \(n \in \mathbb{N}\) and a list \(o\) of booleans, these are the stack contents of the full machine in which the raw-input stack holds \(s\), the host input stack holds \(w\), the host output stack holds \(o\), the scratch counter \(N\) holds \(n\) units, and every other stack is empty.
During the read loop, \(s\) is the unread rest of the input and \(w\) holds the codes read so far.
def fst (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (o : List Bool) : ∀ k, List (FΓ g r k)
| .raw => s
| .h .inp => ins
| .h .out => o
| .pc .N => cnt () n
| _ => []
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
abbrev cnt {α : Type} (u : α) (n : ℕ) : List α := List.replicate n u
MathlibExt/Computability/TuringMachine/Program.lean:115
Uses 9 · Used by 6
TheoremThe read loop's run#✓fully proved
Let \(M\) be a program of the full machine whose read-loop label carries the read loop over all of \(\mathrm{Fin}\,r\), with code map \(c_f\) and separator code \(c_s\), and let \(o\) be a list of booleans. For every raw input \(s = s_1 \cdots s_\ell\), list of codes \(w\), \(n \in \mathbb{N}\) and flag \(v\): started at the read-loop label with flag \(v\), raw input stack \(s\), input stack \(w\), scratch counter \(N = n\), output stack \(o\) and every other stack empty, \(M\) runs in exactly \(\ell + 1\) steps to the counter program's first label, with flag false, raw input stack empty, input stack \(c_s, c_f(s_\ell), \dots, c_f(s_1)\) followed by \(w\), scratch counter \(N = n + \ell\), output stack \(o\) and every other stack empty.
theorem read_run {M : FL D Λ → TM2.Stmt (FΓ g r) (FL D Λ) Bool} {cf : Fin r → Fin g} {cs : Fin g}
(hM : M .rd = rdT cf cs (List.finRange r)) (o : List Bool) :
∀ (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (v : Bool),
Run M (s.length + 1) ⟨some .rd, v, fst s ins n o⟩
⟨some (.pre .p1), false, fst [] (cs :: ((s.map cf).reverse ++ ins)) (n + s.length) o⟩
inductive FL (D : ℕ) (Λ : Type)
| rd
| pre (l : PL D)
| h (l : Λ)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:582
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
def rdT (cf : Fin r → Fin g) (cs : Fin g) : List (Fin r) → TM2.Stmt (FΓ g r) (FL D Λ) Bool
| [] => .push (.h .inp) (fun _ => cs) (.load (fun _ => false) (.goto fun _ => .pre .p1))
| i :: L => .peek .raw (fun _ o => decide (o = some i))
(.branch id (.pop .raw (fun v _ => v) (.push (.h .inp) (fun _ => cf i)
(.push (.pc .N) (fun _ => ()) (.goto fun _ => .rd)))) (rdT cf cs L))
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:647
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 fst (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (o : List Bool) : ∀ k, List (FΓ g r k)
| .raw => s
| .h .inp => ins
| .h .out => o
| .pc .N => cnt () n
| _ => []
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:654
Uses 15 · Used by 1
The full program and its run
DefinitionThe full program#✓fully proved
Let \(\gamma : \mathrm{Fin}\,r \to \mathrm{Fin}\,g\) code the raw symbols, let \(\sigma \in \mathrm{Fin}\,g\) be a separator code, let \(k\) be a polynomial with natural-number coefficients, let \(c, e, d \in \mathbb{N}\), and let \(h\) be a host program with labels \(\Lambda\) and start label \(\lambda_0 \in \Lambda\). The full program, whose counter-program labels have \(D\) Horner rounds for \(D\) the length of the coefficient list of \(k\), runs at the read-loop label the read loop for \(\gamma\) and \(\sigma\) over all raw symbols; at a counter-program label \(l\) other than the final one, the counter program for \(k, c, e, d\) at \(l\), embedded with its scratch counters on the full machine's private counters, its target counters on the corresponding host counters and its output on the host output; at the final counter-program label, a step that sets the state to false and jumps to the host label \(\lambda_0\); and at a host label \(l\), the statement \(h(l)\) on the host stacks.
noncomputable def fprog (cf : Fin r → Fin g) (cs : Fin g) (k : Polynomial ℕ) (c e d : ℕ) (hp : Λ → TM2.Stmt (HΓ g) Λ Bool)
(start : Λ) : FL (coeffs k).length Λ → TM2.Stmt (FΓ g r) (FL (coeffs k).length Λ) Bool
| .rd => rdT cf cs (List.finRange r)
| .pre l => if l = .done then .load (fun _ => false) (.goto fun _ => .h start)
else mapS (embC g r) FL.pre (cprog k c e d l)
| .h l => mapS (embH g r) FL.h (hp l)
abbrev HΓ (g : ℕ) : HK → Type
| .out => Bool
| .inp => Fin g
| .up _ => Unit
| .sd _ => Unit
| .sh _ => Unit
| .ac _ => Unit
| .ini _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:68
inductive FL (D : ℕ) (Λ : Type)
| rd
| pre (l : PL D)
| h (l : Λ)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:582
noncomputable def coeffs (p : Polynomial ℕ) : List ℕ :=
(List.range (p.natDegree + 1)).reverse.map p.coeff
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:369
abbrev FΓ (g r : ℕ) : FK → Type
| .h k => HΓ g k
| .raw => Fin r
| .pc _ => Unit
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:576
def rdT (cf : Fin r → Fin g) (cs : Fin g) : List (Fin r) → TM2.Stmt (FΓ g r) (FL D Λ) Bool
| [] => .push (.h .inp) (fun _ => cs) (.load (fun _ => false) (.goto fun _ => .pre .p1))
| i :: L => .peek .raw (fun _ o => decide (o = some i))
(.branch id (.pop .raw (fun v _ => v) (.push (.h .inp) (fun _ => cf i)
(.push (.pc .N) (fun _ => ()) (.goto fun _ => .rd)))) (rdT cf cs L))
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:647
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 embC : SEmb (SΓ CC) (FΓ g r) where
e := eC
inj := by
intro a b h
rcases a with _ | (x | y) <;> rcases b with _ | (x' | y') <;>
simp only [eC, FK.h.injEq, FK.pc.injEq, reduceCtorEq] at h ⊢
all_goals first
| exact h
| (subst h; rfl)
| (cases y <;> cases h)
| (cases y' <;> cases h)
| (cases y <;> cases y' <;> first | rfl | cases h)
⋯
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:614
noncomputable def cprog (k : Polynomial ℕ) (c e d : ℕ) :
PL (coeffs k).length → TM2.Stmt (SΓ CC) (PL (coeffs k).length) Bool
| .p1 => emitR (.c (s P)) (List.replicate 0 ()) (if 0 < (coeffs k).length then hlab 0 (.mul .head) else .x1)
| .hr i q => hornS (s N) (s P) (s Q) (s AD) (s TMP) (coeffs k)[i] (hlab i.1)
(if i.1 + 1 < (coeffs k).length then hlab (i.1 + 1) (.mul .head) else .x1) q
| .x1 => xfer (.c (s P)) (tg [s Mc, t iE]) .x1 .x2
| .x2 => xfer (.c (s N)) (tg [s Mc, t iX]) .x2 .x3
| .x3 => emitR (.c (s Mc)) (List.replicate 1 ()) .x4
| .x4 => emitR (.c (t iX)) (List.replicate 1 ()) .c1
| .c1 => xfer (.c (s Mc)) [⟨.c (s B), ()⟩, ⟨.c (s TMP), ()⟩] .c1 .c2
| .c2 => xfer (.c (s TMP)) [⟨.c (s Mc), ()⟩] .c2 .x6
| .x6 => emitR (.c (s B)) (List.replicate c ()) .x7
⋯
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:430
def embH : SEmb (HΓ g) (FΓ g r) where
e := FK.h
inj := fun _ _ h => by cases h; rfl
ι := fun _ => Equiv.refl _
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:633
Uses 18 · Used by 3
TheoremThe precomputation#✓fully proved
Fix the full program built from a code map \(c_f\) from the raw alphabet \(\mathrm{Fin}\,r\) to the code alphabet \(\mathrm{Fin}\,g\), a separator code \(c_s\), a polynomial \(k\) with natural coefficients, constants \(c, e, d \in \mathbb{N}\), a host program and its start label. Let \(s = s_1 \cdots s_n\) be a raw input word and \(o\) a list of booleans. Started at the read-loop label with flag false, raw input stack \(s\), output stack \(o\) and every other stack empty, the full program reaches the host's start label with flag false within \(n + 1 + B + 1\) steps, where \(B\) is the counter program's step budget for \(k, c, e, d\) at \(n\). The stacks it reaches satisfy: the output stack is still \(o\); the input stack is \(c_s, c_f(s_n), \dots, c_f(s_1)\); for every target \(y\), the host counter receiving \(y\) has length equal to the target value of \(y\) for \(k, c, e, d\) at \(n\); and every host stack other than the output stack, the input stack and the host counters receiving targets is empty.
These are the preloads that the assembled generator's run expects.
theorem pre_run (s : List (Fin r)) (o : List Bool) :
∃ S : ∀ k, List (FΓ g r k),
RunLe (fprog cf cs k c e d hp start) (s.length + 1 + cB k c e d s.length + 1)
⟨some .rd, false, fst s [] 0 o⟩ ⟨some (.h start), false, S⟩ ∧
S (.h .out) = o ∧ S (.h .inp) = cs :: (s.map cf).reverse ∧
(∀ y, (S (.h (tgt y))).length = tv k c e d s.length y) ∧
(∀ hk, (∀ y, tgt y ≠ hk) → hk ≠ .out → hk ≠ .inp → S (.h hk) = [])
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 fprog (cf : Fin r → Fin g) (cs : Fin g) (k : Polynomial ℕ) (c e d : ℕ) (hp : Λ → TM2.Stmt (HΓ g) Λ Bool)
(start : Λ) : FL (coeffs k).length Λ → TM2.Stmt (FΓ g r) (FL (coeffs k).length Λ) Bool
| .rd => rdT cf cs (List.finRange r)
| .pre l => if l = .done then .load (fun _ => false) (.goto fun _ => .h start)
else mapS (embC g r) FL.pre (cprog k c e d l)
| .h l => mapS (embH g r) FL.h (hp l)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:741
noncomputable def cB (k : Polynomial ℕ) (c e d n : ℕ) : ℕ :=
1 + hornT (coeffs k) n 0 + (k.eval n + 1) + (n + 1) + 2 + (2 * mOf k n + 2) + 3 + powB e 1 (mOf k n + c) +
1 + (d * (2 * TOf k c e n + 3) + d + 2) + 1 + (d * TOf k c e n + d + 2) + (mOf k n + 1) +
(TOf k c e n + 1) + (Situation.capH (mOf k n) (TOf k c e n) d + 1)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:506
def fst (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (o : List Bool) : ∀ k, List (FΓ g r k)
| .raw => s
| .h .inp => ins
| .h .out => o
| .pc .N => cnt () n
| _ => []
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:654
def tgt : PT → HK
| .uT => .up .Tn
| .uH => .up .Hs
| .sT => .sd .Tn
| .sH => .sd .Hs
| .hT => .sh .Tn
| .hH => .sh .Hs
| .aT => .ac .Tn
| .aH => .ac .Hs
| .iT => .ini .Tn
| .iX => .ini .Xn
| .iE => .ini .En
⋯
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:589
def tv (k : Polynomial ℕ) (c e d n : ℕ) : PT → ℕ
| .uT | .sT | .hT | .aT | .iT => TOf k c e n
| .uH | .sH | .hH | .aH => Situation.capH (mOf k n) (TOf k c e n) d
| .iX => n + 1
| .iE => k.eval n
| .iF => (TOf k c e n + 1) * d + 1
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:491
Uses 41 · Used by 1
The full machine on the real generators: raw input to emitted formula
AbbreviationThe full program on the real generators#✓fully proved
For an encoding \(E\) of a machine \(M\), a list \(Y\) of symbols of the input stack alphabet of \(M\), a symbol \(a\) of the output stack alphabet of \(M\), a map \(\iota\) from the raw symbols \(\mathrm{Fin}\,r\) to input stack symbols of \(M\), an input stack symbol \(\sigma\) of \(M\) (the separator), a polynomial \(k\) with natural-number coefficients and \(c, e \in \mathbb{N}\), this is the full program in which each raw symbol \(i\) is coded by the code of \(\iota(i)\) under \(E\), the separator code is the code of \(\sigma\) under \(E\), \(d = \operatorname{depth} M\), the host program is the host running the real generators of \(M\) for \(Y\) and \(a\), and the host starts at the start label of its initial-row generator.
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))
noncomputable def fprog (cf : Fin r → Fin g) (cs : Fin g) (k : Polynomial ℕ) (c e d : ℕ) (hp : Λ → TM2.Stmt (HΓ g) Λ Bool)
(start : Λ) : FL (coeffs k).length Λ → TM2.Stmt (FΓ g r) (FL (coeffs k).length Λ) Bool
| .rd => rdT cf cs (List.finRange r)
| .pre l => if l = .done then .load (fun _ => false) (.goto fun _ => .h start)
else mapS (embC g r) FL.pre (cprog k c e d l)
| .h l => mapS (embH g r) FL.h (hp l)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:741
def encF (z : M.Γ M.k₀) : Fin E.layout.g := ⟨E.enc M.k₀ z, E.enc_lt _ z (E.input_mem z)⟩
CSLibExt/Computability/Complexity/CookLevin/InitFamily.lean:1495
def depth (M : FinTM2) : ℕ :=
letI := M.ΛFin
Finset.univ.sup fun l => ops (M.m l)
CSLibExt/Computability/Complexity/CookLevin/Situation.lean:231
noncomputable abbrev realProg (Ys : List (M.Γ M.k₀)) (acc : M.Γ M.k₁) :=
hprog (Family.prog E.layout E.la E.na E.wa E.N) (Family.prog E.layout E.la E.sa E.wa E.N)
(Shift.prog E.layout E.sa E.pl E.cn E.pu E.N)
(Accept.prog E.layout E.A0 E.acode (E.kc M.k₁) (E.enc M.k₁ acc))
(InitFamily.iprog E.layout (E.lc (some M.main,
M.initialState)) (E.kc M.k₀) (InitFamily.ycs E Ys))
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:362
Uses 17 · Used by 5
DefinitionStep bound of the full machine#✓fully proved
For an encoding \(E\) of a machine \(M\), a list \(Y\) of symbols of the input stack alphabet of \(M\), a polynomial \(k\) with natural-number coefficients and \(c, e, n \in \mathbb{N}\), write \(m = n + 1 + k(n)\) and \(T = (m + c)^e\). The bound is \(n + 1 + C + 1 + R\), where \(C\) is the step budget of the counter program for \(k\), \(c\), \(e\), \(d = \operatorname{depth} M\) and \(n\), and \(R\) is the host's step bound for \(E\) and \(Y\) at \(m\) and \(T\).
It bounds the number of steps of the full machine on a raw input of length \(n\).
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)
noncomputable def cB (k : Polynomial ℕ) (c e d n : ℕ) : ℕ :=
1 + hornT (coeffs k) n 0 + (k.eval n + 1) + (n + 1) + 2 + (2 * mOf k n + 2) + 3 + powB e 1 (mOf k n + c) +
1 + (d * (2 * TOf k c e n + 3) + d + 2) + 1 + (d * TOf k c e n + d + 2) + (mOf k n + 1) +
(TOf k c e n + 1) + (Situation.capH (mOf k n) (TOf k c e n) d + 1)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:506
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 realB (Ys : List (M.Γ M.k₀)) (m T : ℕ) : ℕ :=
InitFamily.initC E.layout (InitFamily.ycs E Ys).length (E.kc M.k₀) * (T + capH m T (depth M) + 1) ^ 5 +
Family.genC E.layout E.N * (T + capH m T (depth M) + 1) ^ 5 +
Family.genC E.layout E.N * (T + capH m T (depth M) + 1) ^ 5 +
Shift.shC E.layout E.N * (T + capH m T (depth M) + 1) ^ 6 +
Accept.accC E.layout E.A0 (E.kc M.k₁) * (T + capH m T (depth M) + 1) ^ 4 + 5
CSLibExt/Computability/Complexity/CookLevin/Assembly.lean:378
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 6 · Used by 6
TheoremThe composed machine, raw input to formula#✓fully proved
From the raw input s (all other stacks
empty, output o), the full machine halts its host part at fin within fullB steps, having
prepended exactly encodeCNF (Phi …) for x = s.map ι ++ [sep], m = |s| + 1 + k(|s|),
T = (m + c)^e. No hypotheses (|x| ≤ m is discharged here).
theorem full_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)) (o : List Bool) :
∃ (v : Bool) (S : ∀ k, List (FΓ E.layout.g r k)),
RunLe (fullProg E Ys acc ι sep k c e) (fullB E Ys k c e s.length)
⟨some .rd, false, fst s [] 0 o⟩ ⟨some (.h .fin), v, S⟩ ∧
S (.h .out) = encodeCNF (Phi E (s.map ι ++ [sep]) Ys acc (mOf k s.length)
(TOf k c e s.length)) ++ o
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 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
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
def fst (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (o : List Bool) : ∀ k, List (FΓ g r k)
| .raw => s
| .h .inp => ins
| .h .out => o
| .pc .N => cnt () n
| _ => []
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:654
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 53 · Used by 2
DefinitionThe full machine as a finite multi-stack Turing machine#✓fully proved
Given \(r \in \mathbb{N}\), an encoding \(E\) of the machine \(M\), a list \(Y_s\) of input symbols of \(M\), an output symbol \(a\) of \(M\), a map \(\iota\) from \(\{0, \dots, r - 1\}\) to input symbols of \(M\), an input symbol \(\sigma\) of \(M\) (the separator), a polynomial \(k\) with natural coefficients and \(c, e \in \mathbb{N}\): the finite multi-stack machine whose stacks are the full stacks (the host's stacks, the raw input stack and the scratch counters) with the full alphabets, whose labels are the full labels, with start label the read label, internal states the booleans with initial state false, and program the full program built from these data. Its input stack is the raw input stack and its output stack is the host's output stack.
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
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 FL (D : ℕ) (Λ : Type)
| rd
| pre (l : PL D)
| h (l : Λ)
deriving DecidableEq, Fintype
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:582
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 41 · Used by 5
TheoremInitial configuration of the full machine#✓fully proved
Let \(E\) be encoding data for a finite multi-stack Turing machine \(M\), and let \(r\) be a natural number. Fix a list \(Y\) of input-stack symbols of \(M\), an output-stack symbol \(a\) of \(M\), a map \(\iota\) from \(\{0, \dots, r-1\}\) to input-stack symbols of \(M\), a separator input-stack symbol \(\sigma\) of \(M\), a polynomial \(k\) with natural-number coefficients and natural numbers \(c\) and \(e\). On every raw input \(s\), a word over \(\{0, \dots, r-1\}\), the initial configuration of the full machine built from these data is at the read-loop label with internal state false, its raw-input stack holds \(s\), and all its other stacks (the code stack, the output stack, the scratch counters and the remaining host stacks) are empty.
theorem initList_full (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)) :
initList (fullTM E Ys acc ι sep k c e) s = ⟨some .rd, false, fst s [] 0 []⟩
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
def fst (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (o : List Bool) : ∀ k, List (FΓ g r k)
| .raw => s
| .h .inp => ins
| .h .out => o
| .pc .N => cnt () n
| _ => []
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:654
Uses 18 · Used by 1
The step bound is a polynomial in |s|
DefinitionPolynomial functions on the naturals#✓fully proved
A function \(f : \mathbb{N} \to \mathbb{N}\) is polynomial when there is a polynomial \(p\) with natural-number coefficients such that \(f(n) = p(n)\) for every \(n \in \mathbb{N}\).
def IsPoly (f : ℕ → ℕ) : Prop := ∃ p : Polynomial ℕ, ∀ n, f n = p.eval n
TheoremThe Horner step count is polynomial#✓fully proved
Let \(cs\) be a list of natural numbers and let \(A : \mathbb{N} \to \mathbb{N}\) be a polynomial function, that is, there is a polynomial \(q\) with natural-number coefficients such that \(A(n) = q(n)\) for all \(n\). Then \(n \mapsto h(n, A(n))\) is a polynomial function in the same sense, where \(h(b, a)\) is the step count of the Horner rounds over \(cs\) with base \(b\) from accumulator \(a\).
theorem hornT (cs : List ℕ) : ∀ {A : ℕ → ℕ}, IsPoly A → IsPoly fun n => Precompute.hornT cs n (A n)
def IsPoly (f : ℕ → ℕ) : Prop := ∃ p : Polynomial ℕ, ∀ n, f n = p.eval n
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:917
def hornT : List ℕ → ℕ → ℕ → ℕ
| [], _, _ => 0
| a :: cs, b, A => hornStep A b + hornT cs b (A * b + a)
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:310
Uses 3 · Used by 3
TheoremPolynomial time bound of the composed machine#✓fully proved
Let \(M\) be a finite multi-stack machine with encoding data \(E\), let \(Y\) be a list of symbols of the input stack of \(M\), \(a\) a symbol of its output stack, \(\iota\) a map from the raw symbols \(\mathrm{Fin}\,r\) to symbols of the input stack, \(\sigma\) a symbol of the input stack (the separator), \(k\) a polynomial with natural-number coefficients and \(c, e \in \mathbb{N}\). Then there is a polynomial \(p\) with natural-number coefficients such that the following holds for every raw input \(s = s_1 \cdots s_n\) over \(\mathrm{Fin}\,r\) and every list \(o\) of booleans. Write \(m = n + 1 + k(n)\), \(T = (m + c)^e\) and \(x = \iota(s_1) \cdots \iota(s_n)\,\sigma\). The full program on the real generators for \(E\), \(Y\), \(a\), \(\iota\), \(\sigma\), \(k\), \(c\) and \(e\), started at its read-loop label with flag false, \(s\) on the raw input stack, \(o\) on the host output stack and every other stack empty, reaches the host's final label within \(p(n)\) steps, with some flag and some stack contents in which the host output stack holds the dense encoding of the formula \(\Phi(x, Y, a, m, T)\) emitted by the host, followed by \(o\).
theorem full_time_poly {r : ℕ} {M : FinTM2} (E : Situation.Enc M) (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)) (o : List Bool), ∃ (v : Bool) (S : ∀ k,
List (FΓ E.layout.g r k)),
RunLe (fullProg E Ys acc ι sep k c e) (p.eval s.length)
⟨some .rd, false, fst s [] 0 o⟩ ⟨some (.h .fin), v, S⟩ ∧
S (.h .out) = encodeCNF (Phi E (s.map ι ++ [sep]) Ys acc (mOf k s.length)
(TOf k c e s.length)) ++ o
structure Enc (M : FinTM2) where
/-- Number of stacks. -/
KK : ℕ
/-- Stack numbering. -/
kc : M.K → ℕ
/-- Inverse of the stack numbering. -/
kd : ℕ → M.K
kc_lt : ∀ k, kc k < KK
kd_kc : ∀ k, kd (kc k) = k
kc_kd : ∀ n < KK, kc (kd n) = n
/-- Number of (label, state) codes. -/
A0 : ℕ
⋯
CSLibExt/Computability/Complexity/CookLevin/Situation.lean:201
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 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
def fst (s : List (Fin r)) (ins : List (Fin g)) (n : ℕ) (o : List Bool) : ∀ k, List (FΓ g r k)
| .raw => s
| .h .inp => ins
| .h .out => o
| .pc .N => cnt () n
| _ => []
CSLibExt/Computability/Complexity/CookLevin/Precompute.lean:654
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 37
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.