Time hierarchy theorem
DefinitionDeciding within a time bound#✓fully proved
A code \(c\) decides a decision problem \(L\) within the time bound \(t : \mathbb{N} \to \mathbb{N}\) when, on every bit list \(x\), the machine of \(c\) started on the input word of \(x\) halts within \(t(|x|)\) steps, and its tape from the head rightwards, without trailing blanks, is the single symbol of the answer \(L(x)\): \(2\) for true and \(1\) for false.
def Code.DecidesWithin (c : Code) (L : DecisionProblem) (t : ℕ → ℕ) : Prop :=
∀ x, c.evalSteps x (t x.length) = some [bitSym (L x)]
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
Uses 4 · Used by 7
DefinitionTime classes on codes#✓fully proved
For \(t : \mathbb{N} \to \mathbb{N}\), \(\mathrm{CodeTime}(t)\) is the class of decision problems \(L\) such that some code decides \(L\) within \(t(|x|)\) steps on every input \(x\).
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
abbrev DecisionComplexityClass := Set DecisionProblem
MathlibExt/Computability/Complexity.lean:174
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
Uses 4 · Used by 7
TheoremDeciding within a larger time bound#✓fully proved
If a code \(c\) decides a decision problem \(L\) within a time bound \(t : \mathbb{N} \to \mathbb{N}\), and \(t' : \mathbb{N} \to \mathbb{N}\) satisfies \(t(n) \le t'(n)\) for every \(n\), then \(c\) decides \(L\) within \(t'\).
theorem Code.DecidesWithin.mono {c : Code} {L : DecisionProblem} {t t' : ℕ → ℕ}
(h : c.DecidesWithin L t) (ht : t ≤ t') : c.DecidesWithin L t'
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
Uses 5 · Used by 2
TheoremMonotonicity of time classes on codes#✓fully proved
Let \(t, t' : \mathbb{N} \to \mathbb{N}\) with \(t(n) \le t'(n)\) for every \(n\). Then every decision problem that some code decides within \(t(|x|)\) steps on every input \(x\) is decided by some code within \(t'(|x|)\) steps on every input \(x\): \(\mathrm{CodeTime}(t) \subseteq \mathrm{CodeTime}(t')\).
theorem codeTime_mono {t t' : ℕ → ℕ} (ht : t ≤ t') : CodeTime t ⊆ CodeTime t'
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:116
Uses 6 · Used by 1
DefinitionThe constant-false code#✓fully proved
The code whose table has a single row, for state \(0\): on the blank \(0\) it writes the symbol \(1\), the symbol of the bit false, and enters state \(1\); on the input symbols \(1\) and \(2\) it moves right and stays in state \(0\); on every other symbol it halts. State \(1\) has no row, so the machine halts there. This code answers false on every input.
def Code.constFalse : Code := ⟨[[some (1, 3), some (0, 1), some (0, 1)]]⟩
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
Uses 1 · Used by 2
TheoremThe constant-false code decides the empty language#✓fully proved
Let \(c\) be the code whose table has one row, for state \(0\): on the input symbols \(1\) and \(2\) it moves right and stays in state \(0\), and on the blank \(0\) it writes \(1\), the symbol of the bit \(\mathrm{false}\), and enters state \(1\), which has no row, so that \(c\) halts. Then \(c\) decides the empty language within \(n + 1\) steps on every input of length \(n\).
theorem Code.constFalse_decidesWithin : Code.constFalse.DecidesWithin (fun _ ↦ false) (· + 1)
def Code.constFalse : Code := ⟨[[some (1, 3), some (0, 1), some (0, 1)]]⟩
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:133
Uses 13 · Used by 1
TheoremTime classes are not empty once the bound exceeds the input length#✓fully proved
Let \(f : \mathbb{N} \to \mathbb{N}\) satisfy \(n + 1 \le f(n)\) for every \(n\). Then the empty language, the decision problem that answers false on every bit list, belongs to the time class of \(f\): some code decides it within \(f(|x|)\) steps on every input \(x\), where \(|x|\) is the length of \(x\).
TheoremSome step is needed#✓fully proved
Let \(f : \mathbb{N} \to \mathbb{N}\) with \(f(0) = 0\). Then no decision problem is decided by a code within \(f(|x|)\) steps on every input \(x\): the time class \(\mathrm{CodeTime}(f)\) is empty. With no step on the empty input, the tape stays blank and holds no answer bit.
theorem codeTime_eq_empty {f : ℕ → ℕ} (hf : f 0 = 0) : CodeTime f = ∅
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:116
Uses 12
TheoremThe code stack determines the table lookups#✓fully proved
If two codes \(c\) and \(c'\) have the same code stack, then for every state \(q\) and every symbol \(a\), the table entry of \(c\) at \((q, a)\) equals the table entry of \(c'\) at \((q, a)\).
theorem Code.lookup_eq_of_codeCells_eq {c c' : Code} (h : codeCells c = codeCells c') :
c.lookup = c'.lookup
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
Uses 10 · Used by 1
TheoremThe code stack determines the clocked semantics#✓fully proved
Codes with the same code stack have the same clocked evaluator.
theorem Code.evalSteps_eq_of_codeCells_eq {c c' : Code} (h : codeCells c = codeCells c') :
c.evalSteps = c'.evalSteps
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
Uses 12 · Used by 1
TheoremReading a unary length prefix reads one cell#✓fully proved
For bit lists \(x\) and \(r\) and a natural number \(n\), reading a unary length prefix of \(x\) returns \(n\) together with the rest \(r\) if and only if \(x\) is the cell of \(n\) (that is, \(n\) copies of \(\mathrm{true}\) followed by \(\mathrm{false}\)) followed by \(r\).
theorem readUnaryLength_eq_some_iff_cell {x r : List Bool} {n : ℕ} :
readUnaryLength x = some (n, r) ↔ x = cell n ++ r
def readUnaryLength : List Bool → Option (Nat × List Bool)
| [] => none
| false :: rest => some (0, rest)
| true :: rest => (readUnaryLength rest).map fun result => (result.1 + 1, result.2)
CSLibExt/Computability/CookLevin.lean:46
def cell (n : ℕ) : List Bool := cnt true n ++ [false]
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:81
Uses 3 · Used by 7
DefinitionDecoding a list of cells#✓fully proved
For a bit list \(x\), the list of natural numbers \(l\) whose cells are \(x\), if there is one, and nothing otherwise. Here the cells of \(l\) are its numbers written in order, each number \(n\) as \(n\) copies of \(\mathrm{true}\) followed by one \(\mathrm{false}\); distinct lists have distinct cells. The decoder reads one cell at a time with the unary length reader.
def cellsDecode (x : List Bool) : Option (List ℕ) :=
match x with
| [] => some []
| b :: x' =>
match h : readUnaryLength (b :: x') with
| none => none
| some (n, r) =>
have : r.length < (b :: x').length := by
rw [readUnaryLength_eq_some_iff_cell.1 h]
simp [cell]
omega
(cellsDecode r).map (n :: ·)
termination_by x.length
def readUnaryLength : List Bool → Option (Nat × List Bool)
| [] => none
| false :: rest => some (0, rest)
| true :: rest => (readUnaryLength rest).map fun result => (result.1 + 1, result.2)
CSLibExt/Computability/CookLevin.lean:46
Uses 4 · Used by 4
DefinitionReading entries from numbers#✓fully proved
A list of natural numbers is read as a list of entries \((q, a, q', s)\), four consecutive numbers per entry, if possible: the empty list gives no entries; a list that starts with \(q, a, q', s\) and continues with \(l\) gives the entry \((q, a, q', s)\) followed by the entries read from \(l\), if that succeeds; and the reading fails when the length of the list is not a multiple of \(4\).
DefinitionAscending keys of a list of entries#✓fully proved
For natural numbers \(p_q\), \(p_a\) and a list of entries \((q, a, q', s) \in \mathbb{N}^4\), this Boolean test is true exactly when the keys \((q, a)\) of the entries strictly increase in lexicographic order and the first key, if there is one, is at least \((p_q, p_a)\) in that order.
DefinitionThe code of a list of entries#✓fully proved
Let \(E\) be a list of entries \((q, a, q', s)\) of natural numbers, and let \(Q\) and \(M\) be the sums, over the entries of \(E\) counted with multiplicity, of \(q + 1\) and of \(a + 1\) respectively. The code of \(E\) has a table with \(Q\) rows and \(M\) columns, and for \(q < Q\) and \(a < M\) its position \((q, a)\) holds \((q', s)\) for the first entry \((q, a, q', s)\) of \(E\) with key \((q, a)\), and is empty (halting) if \(E\) has no entry with that key.
def codeOfEntries (es : List (ℕ × ℕ × ℕ × ℕ)) : Code :=
⟨(List.range (es.map fun e ↦ e.1 + 1).sum).map fun q ↦
(List.range (es.map fun e ↦ e.2.1 + 1).sum).map fun a ↦ findEntry q a es⟩
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def findEntry (q a : ℕ) : List (ℕ × ℕ × ℕ × ℕ) → Option (ℕ × ℕ)
| [] => none
| e :: es => if e.1 = q ∧ e.2.1 = a then some (e.2.2.1, e.2.2.2) else findEntry q a es
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:227
Uses 2 · Used by 4
DefinitionDecoding a code stack#✓fully proved
For a bit list \(x\), the decoding of \(x\) as a code is defined as follows. Write the cell of a number \(n\) for the \(n\) bits true followed by one bit false, and the cells of a list of numbers for the cells of its numbers in order. If \(x\) is the cells of a list \(l\) of natural numbers (such an \(l\) is unique), the length of \(l\) is a multiple of \(4\), and the keys \((q, a)\) of the entries \((q, a, q', s)\) formed by the consecutive groups of four numbers of \(l\) strictly increase in lexicographic order, then the decoding of \(x\) is the code of these entries. Otherwise the decoding returns no code.
The code stack of a code is the cells of the numbers \(q, a, q', s\) of its entries \((q, a, q', s)\), listed by increasing key \((q, a)\); codes with the same code stack have the same clocked evaluator.
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def cellsDecode (x : List Bool) : Option (List ℕ) :=
match x with
| [] => some []
| b :: x' =>
match h : readUnaryLength (b :: x') with
| none => none
| some (n, r) =>
have : r.length < (b :: x').length := by
rw [readUnaryLength_eq_some_iff_cell.1 h]
simp [cell]
omega
(cellsDecode r).map (n :: ·)
⋯
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:275
def entriesOfNums : List ℕ → Option (List (ℕ × ℕ × ℕ × ℕ))
| [] => some []
| q :: a :: q' :: s :: l => (entriesOfNums l).map ((q, a, q', s) :: ·)
| _ => none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:291
def keysAscendFrom (pq pa : ℕ) : List (ℕ × ℕ × ℕ × ℕ) → Bool
| [] => true
| e :: es => decide (pq < e.1 ∨ pq = e.1 ∧ pa ≤ e.2.1) && keysAscendFrom e.1 (e.2.1 + 1) es
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:298
def codeOfEntries (es : List (ℕ × ℕ × ℕ × ℕ)) : Code :=
⟨(List.range (es.map fun e ↦ e.1 + 1).sum).map fun q ↦
(List.range (es.map fun e ↦ e.2.1 + 1).sum).map fun a ↦ findEntry q a es⟩
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:305
Uses 5 · Used by 12
DefinitionThe diagonal language#✓fully proved
For \(f : \mathbb{N} \to \mathbb{N}\), the diagonal language of \(f\) holds at a bit list \(x\) iff \(x\) encodes a code \(c\) and the clocked evaluator, running \(c\) on \(x\) for at most \(f(|x|)\) steps, does not return the output \([2]\), the symbol of the answer true: either \(c\) does not halt on \(x\) within \(f(|x|)\) steps, or it halts with another output. Bit lists that encode no code are not in the language. This is the diagonal language of the proof of Sipser's Theorem 9.10.
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
Uses 5 · Used by 11
TheoremDecoding inverts the code stack#✓fully proved
For every bit list \(x\) and every code \(c\), if \(x\) decodes to \(c\), then the code stack of \(c\) is \(x\).
theorem codeCells_of_decodeCodeCells_eq_some {x : List Bool} {c : Code}
(h : decodeCodeCells x = some c) :
codeCells c = x
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
Uses 17 · Used by 4
TheoremCode stacks are recognized#✓fully proved
For every bit list \(x\), the decoding of \(x\) as a code succeeds iff \(x\) is the code stack of some code.
theorem isSome_decodeCodeCells_iff (x : List Bool) :
(decodeCodeCells x).isSome ↔ ∃ c : Code, codeCells c = x
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
Uses 16 · Used by 1
TheoremCode stacks, entry by entry#✓fully proved
A bit list \(x\) encodes a code (its decoding succeeds) iff there is a list of entries \((q, a, q', s)\) of natural numbers whose keys \((q, a)\) strictly increase in lexicographic order, such that \(x\) is the list of cells of the numbers of these entries, four numbers per entry.
theorem isSome_decodeCodeCells_iff_entries (x : List Bool) : (decodeCodeCells x).isSome ↔
∃ es, x = cells (entryNums es) ∧ keysAscendFrom 0 0 es = true
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
def cells (l : List ℕ) : List Bool := l.flatMap cell
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:84
def entryNums (es : List (ℕ × ℕ × ℕ × ℕ)) : List ℕ :=
es.flatMap fun e ↦ [e.1, e.2.1, e.2.2.1, e.2.2.2]
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:300
def keysAscendFrom (pq pa : ℕ) : List (ℕ × ℕ × ℕ × ℕ) → Bool
| [] => true
| e :: es => decide (pq < e.1 ∨ pq = e.1 ∧ pa ≤ e.2.1) && keysAscendFrom e.1 (e.2.1 + 1) es
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:298
Uses 12 · Used by 1
TheoremCode stacks decode to codes with the same code stack#✓fully proved
For every code \(c\), decoding the code stack of \(c\) succeeds and returns a code \(c'\) whose code stack equals the code stack of \(c\).
theorem decodeCodeCells_codeCells (c : Code) :
∃ c', decodeCodeCells (codeCells c) = some c' ∧ codeCells c' = codeCells c
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
Uses 5 · Used by 1
TheoremThe diagonal language on a code stack#✓fully proved
For every time bound \(f : \mathbb{N} \to \mathbb{N}\) and every code \(c\) with code stack \(x\), the bit list \(x\) belongs to the diagonal language for \(f\) iff it is not the case that \(c\), run on \(x\), halts within \(f(|x|)\) steps with output the single symbol \(2\) of the bit true.
theorem diag_codeCells (f : ℕ → ℕ) (c : Code) :
diag f (codeCells c) =
decide (c.evalSteps (codeCells c) (f (codeCells c).length) ≠ some [bitSym true])
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
Uses 8 · Used by 2
TheoremBit lists that encode no code are outside the diagonal language#✓fully proved
For every \(f : \mathbb{N} \to \mathbb{N}\) and every bit list \(x\) that is the code stack of no code, \(x\) is not in the diagonal language of \(f\).
theorem diag_eq_false {f : ℕ → ℕ} {x : List Bool} (hx : ∀ c : Code, codeCells c ≠ x) :
diag f x = false
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
Uses 7
TheoremThe diagonal language through the universal machine#✓fully proved
For every time bound \(f : \mathbb{N} \to \mathbb{N}\) and every code \(c\) with code stack \(x\), the bit list \(x\) belongs to the diagonal language for \(f\) iff the output encoding of the result of running \(c\) on \(x\) for at most \(f(|x|)\) steps differs from the output encoding of the result whose output is the single symbol \(2\) of the bit true.
The clocked universal machine reads the input encoding of a code, an input and a clock \(T\) and writes the output encoding of the result of running the code on the input for at most \(T\) steps, so the condition is read from its output on \(c\), \(x\) and \(f(|x|)\).
theorem diag_codeCells_eq_encOut (f : ℕ → ℕ) (c : Code) :
diag f (codeCells c) = decide
(encOut (c.evalSteps (codeCells c) (f (codeCells c).length)) ≠
encOut (some [bitSym true]))
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
def codeCells (c : Code) : List Bool := cells (entryNums (entries c))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:304
def encOut : Option (List ℕ) → List Bool
| none => [false]
| some l => true :: cells l
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1263
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
TheoremThe diagonal argument#✓fully proved
For every \(f : \mathbb{N} \to \mathbb{N}\), the diagonal language of \(f\) is not in the time class of \(f\) on codes: no code decides it on every input \(x\) within \(f(|x|)\) steps. This is the argument from the proof of Sipser's Theorem 9.10: a code \(c\) deciding it would, on its own code stack, answer the opposite of the diagonal language of \(f\).
theorem diag_not_mem_codeTime (f : ℕ → ℕ) : diag f ∉ CodeTime f
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:116
Uses 10 · Used by 3
TheoremA hierarchy within codes, given an upper bound#✓fully proved
Let \(f, g : \mathbb{N} \to \mathbb{N}\) with \(f(n) \le g(n)\) for every \(n\), and for a time bound \(t\) let \(\mathrm{CodeTime}(t)\) be the class of decision problems that some code decides within \(t(|x|)\) steps on every input \(x\). If the diagonal language \(\mathrm{diag}(f)\) belongs to \(\mathrm{CodeTime}(g)\), then \(\mathrm{CodeTime}(f)\) is a proper subclass of \(\mathrm{CodeTime}(g)\).
theorem codeTime_ssubset_of_diag_mem {f g : ℕ → ℕ} (hfg : f ≤ g) (h : diag f ∈ CodeTime g) :
CodeTime f ⊂ CodeTime g
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:116
Uses 6
DefinitionThe universal machine's argument for the diagonal language#✓fully proved
For a time bound \(f : \mathbb{N} \to \mathbb{N}\) and a bit list \(x\), the argument is a triple of a code, an input and a clock. If \(x\) decodes to a code \(c\), it is \((c, x, f(|x|))\). Otherwise it is the code with the empty table, the input consisting of the single bit true, and the clock \(0\); that code halts at once with the answer true, so that the diagonal answer is false there.
def diagArg (f : ℕ → ℕ) (x : List Bool) : Code × List Bool × ℕ :=
match decodeCodeCells x with
| some c => (c, x, f x.length)
| none => (⟨[]⟩, [true], 0)
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
Uses 2 · Used by 5
TheoremThe reformatting function in bits#✓fully proved
For \(f : \mathbb{N} \to \mathbb{N}\) and a bit list \(x\), the input bits of the clocked universal machine on its argument for the diagonal language of \(f\) on \(x\) are, when \(x\) encodes a code, the cell of \(f(|x|)\), then the cells of the input symbols of \(x\), then the bit false, then \(x\) reversed; when \(x\) encodes no code, they are the fixed list \([\mathrm{false}, \mathrm{true}, \mathrm{true}, \mathrm{false}, \mathrm{false}]\).
theorem encIn_diagArg (f : ℕ → ℕ) (x : List Bool) :
encIn (diagArg f x).1 (diagArg f x).2.1 (diagArg f x).2.2 =
if (decodeCodeCells x).isSome then
cell (f x.length) ++ (cells (input x) ++ (false :: x.reverse))
else [false, true, true, false, false]
def encIn (c : Code) (x : List Bool) (T : ℕ) : List Bool :=
cell T ++ (cells (input x) ++ (false :: (codeCells c).reverse))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1176
def diagArg (f : ℕ → ℕ) (x : List Bool) : Code × List Bool × ℕ :=
match decodeCodeCells x with
| some c => (c, x, f x.length)
| none => (⟨[]⟩, [true], 0)
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:625
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
def cell (n : ℕ) : List Bool := cnt true n ++ [false]
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:81
def cells (l : List ℕ) : List Bool := l.flatMap cell
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:84
def input (x : List Bool) : List ℕ := x.map bitSym
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:120
Uses 9 · Used by 1
DefinitionThe diagonal answer#✓fully proved
For a clocked result \(o\), either a timeout or the output of a halted run, the diagonal answer of \(o\) is false if \(o\) is the output consisting of the single symbol \(2\), the symbol of the bit true, and true otherwise, including on a timeout.
TheoremThe diagonal answer read from the encoded output#✓fully proved
For every clocked result \(o\), either a timeout or the output of a halted run, the diagonal answer of \(o\) is true exactly when the output encoding of \(o\) differs from the output encoding of the result whose output is the single symbol \(2\) of the bit true, which is the bit list true, true, true, false.
theorem diagAnswer_eq_decide_encOut (o : Option (List ℕ)) :
diagAnswer o = decide (encOut o ≠ encOut (some [bitSym true]))
def diagAnswer (o : Option (List ℕ)) : Bool := decide (o ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:646
def encOut : Option (List ℕ) → List Bool
| none => [false]
| some l => true :: cells l
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1263
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
Uses 6 · Used by 1
TheoremThe diagonal language through the clocked evaluator#✓fully proved
For every \(f : \mathbb{N} \to \mathbb{N}\) and every bit list \(x\), let \((c, y, T)\) be the universal machine's argument for the diagonal language of \(f\) on \(x\). Then the diagonal language of \(f\) holds at \(x\) iff the clocked evaluator, running \(c\) on \(y\) for at most \(T\) steps, does not return the output \([2]\), the symbol of the answer true.
theorem diag_eq_comp (f : ℕ → ℕ) :
diag f = diagAnswer ∘ (fun a : Code × List Bool × ℕ ↦ a.1.evalSteps a.2.1 a.2.2) ∘
diagArg f
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
def diagAnswer (o : Option (List ℕ)) : Bool := decide (o ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:646
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def diagArg (f : ℕ → ℕ) (x : List Bool) : Code × List Bool × ℕ :=
match decodeCodeCells x with
| some c => (c, x, f x.length)
| none => (⟨[]⟩, [true], 0)
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:625
Uses 8 · Used by 1
InductiveStacks of the readout machine#✓fully proved
The readout machine, which reads the answer of the diagonal language off the output of the clocked universal machine, has exactly two stacks: the input stack \(X\) and the output stack \(O\).
inductive K | X | O
deriving DecidableEq
InductiveLabels of the readout machine#✓fully proved
The readout machine has eight labels: \(r_0\), \(r_1\), \(r_2\) and \(r_3\) read in turn the bits \(\mathrm{true}, \mathrm{true}, \mathrm{true}, \mathrm{false}\), which encode, at the output of the clocked universal machine, a halt whose output is the single symbol of the bit \(\mathrm{true}\); \(r_4\) checks that no bit follows; \(\mathrm{hit}\) and \(\mathrm{miss}\) write the answer; and \(\mathrm{done}\) stops.
inductive Lab | r0 | r1 | r2 | r3 | r4 | hit | miss | done
deriving DecidableEq
AbbreviationStack alphabet of the readout machine#✓fully proved
Every stack of the readout machine, namely the input stack \(X\) and the output stack \(O\), has the alphabet of bits.
abbrev Γ : K → Type := fun _ => Bool
inductive K | X | O
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:668
Uses 1 · Used by 5
DefinitionExpecting a bit in the readout machine#✓fully proved
For a bit \(b\) and a label \(\ell\), the statement that pops the top of the input stack \(X\) and goes to \(\ell\) if the popped symbol is \(b\), and to the label miss otherwise, including when \(X\) is empty.
def expect (b : Bool) (next : Lab) : TM2.Stmt Γ Lab Bool :=
.pop .X (fun _ o ↦ o == some b) (.branch id (.goto fun _ ↦ next) (.goto fun _ ↦ .miss))
inductive Lab | r0 | r1 | r2 | r3 | r4 | hit | miss | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:678
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:687
Uses 3 · Used by 1
DefinitionProgram of the readout machine#✓fully proved
The readout machine pops the bits of its input stack \(X\) one at a time and compares them with \(\mathrm{true}, \mathrm{true}, \mathrm{true}, \mathrm{false}\), which encode, at the output of the clocked universal machine, a halt whose output is the single symbol of the bit \(\mathrm{true}\). If the input is exactly this list, it pushes \(\mathrm{false}\) onto its output stack \(O\); otherwise (at the first bit that differs, when the input ends early, or when a fifth bit follows) it pushes \(\mathrm{true}\). Then it halts.
def prog : Lab → TM2.Stmt Γ Lab Bool
| .r0 => expect true .r1
| .r1 => expect true .r2
| .r2 => expect true .r3
| .r3 => expect false .r4
| .r4 => .pop .X (fun _ o ↦ o.isNone) (.branch id (.goto fun _ ↦ .hit) (.goto fun _ ↦ .miss))
| .hit => .push .O (fun _ ↦ false) (.goto fun _ ↦ .done)
| .miss => .push .O (fun _ ↦ true) (.goto fun _ ↦ .done)
| .done => .halt
inductive Lab | r0 | r1 | r2 | r3 | r4 | hit | miss | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:678
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:687
def expect (b : Bool) (next : Lab) : TM2.Stmt Γ Lab Bool :=
.pop .X (fun _ o ↦ o == some b) (.branch id (.goto fun _ ↦ next) (.goto fun _ ↦ .miss))
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:690
AbbreviationThe readout machine as a host component#✓fully proved
The component machine whose stacks are the input \(X\) and the output \(O\), each over the alphabet of bits, whose labels and program are those of the readout machine, which checks whether \(X\) holds exactly \((\mathrm{true}, \mathrm{true}, \mathrm{true}, \mathrm{false})\) and pushes \(\mathrm{false}\) on \(O\) if so and \(\mathrm{true}\) otherwise, and whose list of stacks is \((X, O)\).
abbrev comp : Complexity.Host.Comp where
K := K
Γ := Γ
finΓ := fun _ ↦ inferInstanceAs (Fintype Bool)
L := Lab
prog := prog
ks := [.X, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> decide
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | X | O
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:668
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:687
inductive Lab | r0 | r1 | r2 | r3 | r4 | hit | miss | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:678
def prog : Lab → TM2.Stmt Γ Lab Bool
| .r0 => expect true .r1
| .r1 => expect true .r2
| .r2 => expect true .r3
| .r3 => expect false .r4
| .r4 => .pop .X (fun _ o ↦ o.isNone) (.branch id (.goto fun _ ↦ .hit) (.goto fun _ ↦ .miss))
| .hit => .push .O (fun _ ↦ false) (.goto fun _ ↦ .done)
| .miss => .push .O (fun _ ↦ true) (.goto fun _ ↦ .done)
| .done => .halt
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:695
Uses 5 · Used by 1
TheoremThe readout run#✓fully proved
Let \(l\) be a bit list, and start the readout machine at the label \(r_0\) with its internal Boolean variable set to \(\mathrm{false}\), \(l\) on the input stack \(X\) and the output stack \(O\) empty. Then the machine reaches the label \(\mathrm{done}\) within \(6\) steps, and \(O\) then holds exactly one bit, which is \(\mathrm{true}\) if and only if \(l \ne [\mathrm{true}, \mathrm{true}, \mathrm{true}, \mathrm{false}]\), the list that encodes, at the output of the clocked universal machine, a halt whose output is the single symbol of the bit \(\mathrm{true}\).
theorem run (l : List Bool) :
∃ v S', RunLe prog 6 ⟨some .r0, false, update (fun _ ↦ []) .X l⟩ ⟨some .done, v, S'⟩ ∧
S' .O = [decide (l ≠ encOut (some [bitSym true]))]
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 prog : Lab → TM2.Stmt Γ Lab Bool
| .r0 => expect true .r1
| .r1 => expect true .r2
| .r2 => expect true .r3
| .r3 => expect false .r4
| .r4 => .pop .X (fun _ o ↦ o.isNone) (.branch id (.goto fun _ ↦ .hit) (.goto fun _ ↦ .miss))
| .hit => .push .O (fun _ ↦ false) (.goto fun _ ↦ .done)
| .miss => .push .O (fun _ ↦ true) (.goto fun _ ↦ .done)
| .done => .halt
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:695
def encOut : Option (List ℕ) → List Bool
| none => [false]
| some l => true :: cells l
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1263
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
Uses 8 · Used by 1
DefinitionThe readout on raw bits in polynomial time#✓fully proved
A finite multi-stack Turing machine, whose input and output alphabets are identified with the bits, together with a polynomial time bound, such that for every bit list \(l\), given \(l\) as its input, it halts within the bound, evaluated at \(|l|\), with output the one-bit list \([b]\), where \(b\) is true if and only if \(l\) differs from the output encoding of the result whose output is the single symbol \(2\) of the bit true, that is, from the list true, true, true, false.
noncomputable def bitsPolyTime :
TM2ComputableInPolyTime (fun l : List Bool ↦ l) (fun l : List Bool ↦ l)
(fun l ↦ [decide (l ≠ encOut (some [bitSym true]))]) :=
Complexity.Host.reduction (c := comp) (cX := .X) (cO := .O) (gX := id) (start := .r0)
(done := .done) (Equiv.refl Bool) _ (Polynomial.C 6) rfl fun l ↦ by
obtain ⟨v, S', hr, hO⟩ := run l
exact ⟨v, S', by simpa using hr, by simpa using hO⟩
def encOut : Option (List ℕ) → List Bool
| none => [false]
| some l => true :: cells l
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1263
def bitSym (b : Bool) : ℕ := cond b 2 1
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:117
noncomputable def reduction (eO : c.Γ cO ≃ Bool) (f : List Bool → List Bool) (p : Polynomial ℕ)
(hdone : c.prog done = .halt)
(hrun : ∀ x, ∃ v S', RunLe c.prog (p.eval x.length)
⟨some start, false, update (fun _ => []) cX (x.map gX)⟩ ⟨some done, v, S'⟩ ∧
S' cO = (f x).map eO.symm) :
TM2ComputableInPolyTime (fun l : List Bool => l) (fun l : List Bool => l) f where
tm := rtm c cX cO gX start done
inputAlphabet := Equiv.refl Bool
outputAlphabet := eO
time := rtime c cX cO gX start done p
outputsFun := fun x => by
have h := rprog_run eO f p hdone hrun x
⋯
CSLibExt/Computability/Complexity/Host.lean:348
abbrev comp : Complexity.Host.Comp where
K := K
Γ := Γ
finΓ := fun _ ↦ inferInstanceAs (Fintype Bool)
L := Lab
prog := prog
ks := [.X, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> decide
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:706
Uses 11 · Used by 1
DefinitionThe readout in polynomial time#✓fully proved
A finite multi-stack Turing machine, given the output encoding \(\mathrm{encOut}(o)\) of a result \(o\) of the clocked universal function (a list of symbols, or a timeout), outputs the one-bit list \([\mathrm{diagAnswer}(o)]\) within a number of steps polynomial in the length of \(\mathrm{encOut}(o)\). Here \(\mathrm{diagAnswer}(o)\) is \(\mathrm{true}\) unless \(o\) is a halt whose output is the single symbol of the bit \(\mathrm{true}\).
noncomputable def polyTime : TM2ComputableInPolyTime encOut (fun b : Bool ↦ [b]) diagAnswer where
toTM2ComputableAux := bitsPolyTime.toTM2ComputableAux
time := bitsPolyTime.time
outputsFun o := by
have h := bitsPolyTime.outputsFun (encOut o)
rwa [← diagAnswer_eq_decide_encOut] at h
def encOut : Option (List ℕ) → List Bool
| none => [false]
| some l => true :: cells l
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1263
def diagAnswer (o : Option (List ℕ)) : Bool := decide (o ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:646
noncomputable def bitsPolyTime :
TM2ComputableInPolyTime (fun l : List Bool ↦ l) (fun l : List Bool ↦ l)
(fun l ↦ [decide (l ≠ encOut (some [bitSym true]))]) :=
Complexity.Host.reduction (c := comp) (cX := .X) (cO := .O) (gX := id) (start := .r0)
(done := .done) (Equiv.refl Bool) _ (Polynomial.C 6) rfl fun l ↦ by
obtain ⟨v, S', hr, hO⟩ := run l
exact ⟨v, S', by simpa using hr, by simpa using hO⟩
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:730
Uses 5 · Used by 1
TheoremThe diagonal language in polynomial time, given the reformatting machine#✓fully proved
Let \(f : \mathbb{N} \to \mathbb{N}\). Suppose that a finite multi-stack Turing machine, the reformatting machine, computes in polynomial time, from a bit list \(x\) given as itself, the input \(\mathrm{encIn}(c, y, T)\) of the clocked universal machine, where \((c, y, T) = \mathrm{diagArg}_f(x)\) is the argument of the clocked universal function for the diagonal language \(\mathrm{diag}_f\) on \(x\). Then a finite multi-stack Turing machine computes \(\mathrm{diag}_f\) in polynomial time: on every bit list \(x\), given as itself, it outputs the one-bit list \([\mathrm{diag}_f(x)]\).
The machine runs the reformatting machine, then the clocked universal machine, then the readout machine.
theorem nonempty_diag_polyTime {f : ℕ → ℕ}
(hR : TM2ComputableInPolyTime (fun x : List Bool ↦ x)
(fun a : Code × List Bool × ℕ ↦ encIn a.1 a.2.1 a.2.2) (diagArg f)) :
Nonempty (TM2ComputableInPolyTime (fun x : List Bool ↦ x) (fun b : Bool ↦ [b]) (diag f))
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def encIn (c : Code) (x : List Bool) (T : ℕ) : List Bool :=
cell T ++ (cells (input x) ++ (false :: (codeCells c).reverse))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1176
def diagArg (f : ℕ → ℕ) (x : List Bool) : Code × List Bool × ℕ :=
match decodeCodeCells x with
| some c => (c, x, f x.length)
| none => (⟨[]⟩, [true], 0)
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:625
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
Uses 12 · Used by 1
DefinitionCell-by-cell check of a code stack#✓fully proved
The check of a bit list \(x\) from a key \((p_q, p_a)\) of natural numbers is defined as follows. The empty list passes. Otherwise, calling the cell of a number \(n\) the \(n\) bits \(\mathrm{true}\) followed by one bit \(\mathrm{false}\), read four cells off the front of \(x\), those of \(q\), \(a\), \(q'\) and \(s\) in this order, leaving the rest \(r\). The check fails if one of these cells cannot be read because what remains contains no bit \(\mathrm{false}\), or if the key \((q, a)\) is lexicographically below \((p_q, p_a)\), that is, unless \(p_q < q\), or \(p_q = q\) and \(p_a \le a\). Otherwise its result is the check of \(r\) from the key \((q, a + 1)\).
The reformatting machine checks its input this way.
Cslib.Turing.Universal.Diag.chkFrom · 28 lines
def chkFrom (pq pa : ℕ) (x : List Bool) : Bool :=
match x with
| [] => true
| b :: x' =>
match _h1 : readUnaryLength (b :: x') with
| none => false
| some (q, x1) =>
match _h2 : readUnaryLength x1 with
| none => false
| some (a, x2) =>
if pq < q ∨ pq = q ∧ pa ≤ a then
match _h3 : readUnaryLength x2 with
| none => false
| some (_, x3) =>
match h4 : readUnaryLength x3 with
| none => false
| some (_, x4) => chkFrom q (a + 1) x4
else false
termination_by x.length
decreasing_by
have e1 := congrArg List.length (readUnaryLength_eq_some_iff_cell.1 _h1)
have e2 := congrArg List.length (readUnaryLength_eq_some_iff_cell.1 _h2)
have e3 := congrArg List.length (readUnaryLength_eq_some_iff_cell.1 _h3)
have e4 := congrArg List.length (readUnaryLength_eq_some_iff_cell.1 h4)
simp only [cell, List.length_append, List.length_replicate, List.length_cons,
List.length_nil] at e1 e2 e3 e4
simp only [List.length_cons]
omega
def readUnaryLength : List Bool → Option (Nat × List Bool)
| [] => none
| false :: rest => some (0, rest)
| true :: rest => (readUnaryLength rest).map fun result => (result.1 + 1, result.2)
CSLibExt/Computability/CookLevin.lean:46
Uses 4 · Used by 5
TheoremThe cell-by-cell check recognizes code stacks#✓fully proved
For all natural numbers \(p_q, p_a\) and every bit list \(x\), the cell-by-cell check of \(x\) from the key \((p_q, p_a)\) succeeds if and only if there is a list of \(m \ge 0\) entries \((q_1, a_1, q'_1, s_1), \dots, (q_m, a_m, q'_m, s_m)\) of natural numbers such that \(x\) is the concatenation of the cells of \(q_1, a_1, q'_1, s_1, \dots, q_m, a_m, q'_m, s_m\), in this order, and the keys \((q_i, a_i)\) strictly increase in lexicographic order, starting at \((p_q, p_a)\) or above. Here the cell of a number \(n\) is \(n\) bits \(\mathrm{true}\) followed by one bit \(\mathrm{false}\).
theorem chkFrom_iff (pq pa : ℕ) (x : List Bool) :
chkFrom pq pa x = true ↔ ∃ es, x = cells (entryNums es) ∧ keysAscendFrom pq pa es = true
def chkFrom (pq pa : ℕ) (x : List Bool) : Bool :=
match x with
| [] => true
| b :: x' =>
match _h1 : readUnaryLength (b :: x') with
| none => false
| some (q, x1) =>
match _h2 : readUnaryLength x1 with
| none => false
| some (a, x2) =>
if pq < q ∨ pq = q ∧ pa ≤ a then
match _h3 : readUnaryLength x2 with
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:100
def cells (l : List ℕ) : List Bool := l.flatMap cell
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:84
def entryNums (es : List (ℕ × ℕ × ℕ × ℕ)) : List ℕ :=
es.flatMap fun e ↦ [e.1, e.2.1, e.2.2.1, e.2.2.2]
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:300
def keysAscendFrom (pq pa : ℕ) : List (ℕ × ℕ × ℕ × ℕ) → Bool
| [] => true
| e :: es => decide (pq < e.1 ∨ pq = e.1 ∧ pa ≤ e.2.1) && keysAscendFrom e.1 (e.2.1 + 1) es
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:298
Uses 8 · Used by 1
InductiveStacks of the checking machine#✓fully proved
The checking machine has twelve stacks, named \(X, Y, W, V, Q, A, P_Q, P_A, T_1, T_2, J, O\).
inductive K | X | Y | W | V | Q | A | PQ | PA | T1 | T2 | J | O
deriving DecidableEq
InductiveLabels of the checking machine#✓fully proved
The labels of the checking machine: 23 labels without arguments and four families of labels indexed by the outcome of a comparison (\(<\), \(=\) or \(>\)), 35 distinct labels in all.
inductive Lab
| dupP | dupQ | cpy | lp | rq0 | rq1 | ra0 | ra1
| cq | cqR (o : Ordering) | cqRB (o : Ordering) | ca | caR (o : Ordering) | caRB (o : Ordering)
| sk0 | sk1 | sk2 | sk3 | dr0 | dr1 | mv0 | mv1 | inc | okO | okT | bad | done
deriving DecidableEq
AbbreviationStack alphabet of the layout machine#✓fully proved
Every stack of the layout machine holds bits: the alphabet of each stack is the type of Booleans.
abbrev Γ : K → Type := fun _ => Bool
inductive K | X | Y | W | V | Q | A | PQ | PA | T1 | T2 | J | O
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:390
Uses 1 · Used by 4
DefinitionBranch after comparing states#✓fully proved
The label the checking machine goes to after comparing the bound \(p\) for the state (the state of the previous key, or \(0\) at the first entry) with the state \(q\) of the current key: if \(p < q\), the label \(\mathsf{sk0}\), where it starts skipping the rest of the entry; if \(p = q\), the label \(\mathsf{ca}\), where it compares the symbols; if \(p > q\), the label \(\mathsf{bad}\), where it rejects.
def outQ : Ordering → Lab
| .lt => .sk0
| .eq => .ca
| .gt => .bad
inductive Lab
| dupP | dupQ | cpy | lp | rq0 | rq1 | ra0 | ra1
| cq | cqR (o : Ordering) | cqRB (o : Ordering) | ca | caR (o : Ordering) | caRB (o : Ordering)
| sk0 | sk1 | sk2 | sk3 | dr0 | dr1 | mv0 | mv1 | inc | okO | okT | bad | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:399
Uses 1 · Used by 2
DefinitionBranch after comparing symbols#✓fully proved
The label the checking machine goes to after comparing the bound \(p\) for the symbol with the symbol \(a\) of the current key: if \(p > a\), the label \(\mathsf{bad}\), where it rejects; if \(p < a\) or \(p = a\), the label \(\mathsf{sk0}\), where it starts skipping the rest of the entry.
def outA : Ordering → Lab
| .gt => .bad
| _ => .sk0
inductive Lab
| dupP | dupQ | cpy | lp | rq0 | rq1 | ra0 | ra1
| cq | cqR (o : Ordering) | cqRB (o : Ordering) | ca | caR (o : Ordering) | caRB (o : Ordering)
| sk0 | sk1 | sk2 | sk3 | dr0 | dr1 | mv0 | mv1 | inc | okO | okT | bad | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:399
Uses 1 · Used by 2
DefinitionProgram of the checking machine#✓fully proved
Writing \(1\) for true and \(0\) for false, this is the program of a multi-stack machine whose stacks \(X, Y, W, V, Q, A, P_Q, P_A, T_1, T_2, J, O\) all hold bits. To read a cell from \(V\) onto a stack \(S\) means to pop the leading \(1\)s of \(V\), pushing a \(1\) on \(S\) for each, and then to pop the \(0\) that follows; if \(V\) is empty at that point, the machine rejects. From its first label the program pops the bits of \(X\) one at a time, pushing each onto both \(Y\) and \(W\), and then pops the bits of \(W\) one at a time onto \(V\). Then it loops. If \(V\) is empty, it pops the bits of \(Y\) one at a time onto \(O\), pushes a \(1\) on \(O\) and halts. Otherwise it reads a cell from \(V\) onto \(Q\) and then one onto \(A\). With \(p_Q\), \(q\), \(p_A\), \(a\) the numbers of bits on \(P_Q\), \(Q\), \(P_A\), \(A\), it compares \(p_Q\) with \(q\) and, if they are equal, \(p_A\) with \(a\), afterwards pushing back as many \(1\)s as it popped from each. If \(p_Q > q\), or \(p_Q = q\) and \(p_A > a\), it rejects; otherwise it reads two more cells from \(V\) onto \(J\), empties \(P_Q\) and \(P_A\), moves \(Q\) onto \(P_Q\) and \(A\) onto \(P_A\) (pushing a \(1\) for each bit popped), pushes one more \(1\) on \(P_A\) and loops again. Rejecting pushes a single \(0\) on \(O\) and halts.
Cslib.Turing.Universal.Diag.Check.prog · 30 lines
def prog : Lab → TM2.Stmt Γ Lab Bool
| .dupP => .peek .X (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .dupQ) (.goto fun _ ↦ .cpy))
| .dupQ => .pop .X (fun _ o ↦ o.getD false) (.branch id
(.push .Y (fun _ ↦ true) (.push .W (fun _ ↦ true) (.goto fun _ ↦ .dupP)))
(.push .Y (fun _ ↦ false) (.push .W (fun _ ↦ false) (.goto fun _ ↦ .dupP))))
| .cpy => moveB .W .V some id .cpy .lp
| .lp => .peek .V (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .rq0) (.goto fun _ ↦ .okO))
| .rq0 => moveB .V .Q dU (fun _ ↦ true) .rq0 .rq1
| .rq1 => decr .V .bad .ra0
| .ra0 => moveB .V .A dU (fun _ ↦ true) .ra0 .ra1
| .ra1 => decr .V .bad .cq
| .cq => cmpStep .PQ .Q .T1 .T2 true true .cq (.cqR .lt) (.cqR .eq) (.cqR .gt)
| .cqR o => xfer .T1 [⟨.PQ, true⟩] (.cqR o) (.cqRB o)
| .cqRB o => xfer .T2 [⟨.Q, true⟩] (.cqRB o) (outQ o)
| .ca => cmpStep .PA .A .T1 .T2 true true .ca (.caR .lt) (.caR .eq) (.caR .gt)
| .caR o => xfer .T1 [⟨.PA, true⟩] (.caR o) (.caRB o)
| .caRB o => xfer .T2 [⟨.A, true⟩] (.caRB o) (outA o)
| .sk0 => moveB .V .J dU (fun _ ↦ true) .sk0 .sk1
| .sk1 => decr .V .bad .sk2
| .sk2 => moveB .V .J dU (fun _ ↦ true) .sk2 .sk3
| .sk3 => decr .V .bad .dr0
| .dr0 => xfer .PQ [] .dr0 .dr1
| .dr1 => xfer .PA [] .dr1 .mv0
| .mv0 => xfer .Q [⟨.PQ, true⟩] .mv0 .mv1
| .mv1 => xfer .A [⟨.PA, true⟩] .mv1 .inc
| .inc => incr .PA true .lp
| .okO => moveB .Y .O some id .okO .okT
| .okT => incr .O true .done
| .bad => emit .O [false] .done
| .done => .halt
inductive Lab
| dupP | dupQ | cpy | lp | rq0 | rq1 | ra0 | ra1
| cq | cqR (o : Ordering) | cqRB (o : Ordering) | ca | caR (o : Ordering) | caRB (o : Ordering)
| sk0 | sk1 | sk2 | sk3 | dr0 | dr1 | mv0 | mv1 | inc | okO | okT | bad | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:399
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:417
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
def dU (b : Bool) : Option Bool := if b then some true else none
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:135
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 cmpStep (a b ta tb : K) (uta : Γ ta) (utb : Γ tb)
(self lt eq gt : Λ) : TM2.Stmt Γ Λ σ :=
.pop a (fun _ o => Flag.tag o.isSome) <| .branch Flag.untag
(.pop b (fun _ o => Flag.tag o.isSome) <| .branch Flag.untag
(.push ta (fun _ => uta) <| .push tb (fun _ => utb) <| .goto fun _ => self)
(.push ta (fun _ => uta) <| .goto fun _ => gt))
(.pop b (fun _ o => Flag.tag o.isSome) <| .branch Flag.untag
(.push tb (fun _ => utb) <| .goto fun _ => lt)
(.goto fun _ => eq))
MathlibExt/Computability/TuringMachine/Program.lean:291
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 outQ : Ordering → Lab
| .lt => .sk0
| .eq => .ca
| .gt => .bad
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:420
def outA : Ordering → Lab
| .gt => .bad
| _ => .sk0
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:426
def incr (k : K) (u : Γ k) (next : Λ) : TM2.Stmt Γ Λ σ :=
.push k (fun _ => u) (.goto fun _ => next)
MathlibExt/Computability/TuringMachine/Program.lean:137
def emit (k : K) (xs : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ :=
pushList k xs (.goto fun _ => next)
MathlibExt/Computability/TuringMachine/Program.lean:547
Uses 13 · Used by 3
DefinitionAnswer of the checking machine#✓fully proved
For a bit list \(x\), the answer is the list \(x\) with the bit \(\mathrm{true}\) put in front if the cell-by-cell check of \(x\) from the key \((0, 0)\) succeeds, and the one-bit list \([\mathrm{false}]\) otherwise.
def answer (x : List Bool) : List Bool := if chkFrom 0 0 x then true :: x else [false]
def chkFrom (pq pa : ℕ) (x : List Bool) : Bool :=
match x with
| [] => true
| b :: x' =>
match _h1 : readUnaryLength (b :: x') with
| none => false
| some (q, x1) =>
match _h2 : readUnaryLength x1 with
| none => false
| some (a, x2) =>
if pq < q ∨ pq = q ∧ pa ≤ a then
match _h3 : readUnaryLength x2 with
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:100
Uses 1 · Used by 4
TheoremThe checking run#✓fully proved
For every bit list \(x\), the checking machine, started at the label \(\mathsf{dupP}\) with internal state false, with \(x\) on its input stack \(X\) and every other stack empty, reaches the label \(\mathsf{done}\) within \(33(|x| + 1)^2\) steps, with some internal state and stacks in which the output stack \(O\) holds the answer of the checking machine on \(x\).
theorem run (x : List Bool) :
∃ v S', RunLe prog (33 * (x.length + 1) ^ 2)
⟨some .dupP, false, update (fun _ ↦ []) .X x⟩ ⟨some .done, v, S'⟩ ∧ S' .O = answer x
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 prog : Lab → TM2.Stmt Γ Lab Bool
| .dupP => .peek .X (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .dupQ) (.goto fun _ ↦ .cpy))
| .dupQ => .pop .X (fun _ o ↦ o.getD false) (.branch id
(.push .Y (fun _ ↦ true) (.push .W (fun _ ↦ true) (.goto fun _ ↦ .dupP)))
(.push .Y (fun _ ↦ false) (.push .W (fun _ ↦ false) (.goto fun _ ↦ .dupP))))
| .cpy => moveB .W .V some id .cpy .lp
| .lp => .peek .V (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .rq0) (.goto fun _ ↦ .okO))
| .rq0 => moveB .V .Q dU (fun _ ↦ true) .rq0 .rq1
| .rq1 => decr .V .bad .ra0
| .ra0 => moveB .V .A dU (fun _ ↦ true) .ra0 .ra1
| .ra1 => decr .V .bad .cq
| .cq => cmpStep .PQ .Q .T1 .T2 true true .cq (.cqR .lt) (.cqR .eq) (.cqR .gt)
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:431
def answer (x : List Bool) : List Bool := if chkFrom 0 0 x then true :: x else [false]
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:685
Uses 27 · Used by 1
AbbreviationThe checking machine as a host component#✓fully proved
The component machine with the twelve stacks \(X, Y, W, V, Q, A, P_Q, P_A, T_1, T_2, J, O\) of the checking machine, each holding bits, with the labels and the program of the checking machine, and with its stacks listed in the order \(X, Y, W, V, Q, A, P_Q, P_A, T_1, T_2, J, O\).
abbrev comp : Complexity.Host.Comp where
K := K
Γ := Γ
finΓ := fun _ ↦ inferInstanceAs (Fintype Bool)
L := Lab
prog := prog
ks := [.X, .Y, .W, .V, .Q, .A, .PQ, .PA, .T1, .T2, .J, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> decide
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | X | Y | W | V | Q | A | PQ | PA | T1 | T2 | J | O
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:390
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:417
inductive Lab
| dupP | dupQ | cpy | lp | rq0 | rq1 | ra0 | ra1
| cq | cqR (o : Ordering) | cqRB (o : Ordering) | ca | caR (o : Ordering) | caRB (o : Ordering)
| sk0 | sk1 | sk2 | sk3 | dr0 | dr1 | mv0 | mv1 | inc | okO | okT | bad | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:399
def prog : Lab → TM2.Stmt Γ Lab Bool
| .dupP => .peek .X (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .dupQ) (.goto fun _ ↦ .cpy))
| .dupQ => .pop .X (fun _ o ↦ o.getD false) (.branch id
(.push .Y (fun _ ↦ true) (.push .W (fun _ ↦ true) (.goto fun _ ↦ .dupP)))
(.push .Y (fun _ ↦ false) (.push .W (fun _ ↦ false) (.goto fun _ ↦ .dupP))))
| .cpy => moveB .W .V some id .cpy .lp
| .lp => .peek .V (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .rq0) (.goto fun _ ↦ .okO))
| .rq0 => moveB .V .Q dU (fun _ ↦ true) .rq0 .rq1
| .rq1 => decr .V .bad .ra0
| .ra0 => moveB .V .A dU (fun _ ↦ true) .ra0 .ra1
| .ra1 => decr .V .bad .cq
| .cq => cmpStep .PQ .Q .T1 .T2 true true .cq (.cqR .lt) (.cqR .eq) (.cqR .gt)
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:431
Uses 5 · Used by 1
DefinitionThe checking machine in polynomial time#✓fully proved
A finite multi-stack Turing machine with a polynomial time bound that computes the checking answer: given a bit list \(x\) as its input, it halts within the bound, evaluated at \(|x|\), with the checking answer on \(x\) as its output.
noncomputable def polyTime :
TM2ComputableInPolyTime (fun l : List Bool ↦ l) (fun l : List Bool ↦ l) answer :=
Complexity.Host.reduction (c := comp) (cX := .X) (cO := .O) (gX := id) (start := .dupP)
(done := .done) (Equiv.refl Bool) _ (Polynomial.C 33 * (Polynomial.X + 1) ^ 2) rfl
fun x ↦ by
obtain ⟨v, S', hr, hO⟩ := run x
exact ⟨v, S', by simpa [Polynomial.eval_mul, Polynomial.eval_pow] using hr,
by simpa using hO⟩
def answer (x : List Bool) : List Bool := if chkFrom 0 0 x then true :: x else [false]
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:685
noncomputable def reduction (eO : c.Γ cO ≃ Bool) (f : List Bool → List Bool) (p : Polynomial ℕ)
(hdone : c.prog done = .halt)
(hrun : ∀ x, ∃ v S', RunLe c.prog (p.eval x.length)
⟨some start, false, update (fun _ => []) cX (x.map gX)⟩ ⟨some done, v, S'⟩ ∧
S' cO = (f x).map eO.symm) :
TM2ComputableInPolyTime (fun l : List Bool => l) (fun l : List Bool => l) f where
tm := rtm c cX cO gX start done
inputAlphabet := Equiv.refl Bool
outputAlphabet := eO
time := rtime c cX cO gX start done p
outputsFun := fun x => by
have h := rprog_run eO f p hdone hrun x
⋯
CSLibExt/Computability/Complexity/Host.lean:348
abbrev comp : Complexity.Host.Comp where
K := K
Γ := Γ
finΓ := fun _ ↦ inferInstanceAs (Fintype Bool)
L := Lab
prog := prog
ks := [.X, .Y, .W, .V, .Q, .A, .PQ, .PA, .T1, .T2, .J, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> decide
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:731
Uses 10 · Used by 1
InductiveStacks of the layout machine#✓fully proved
The layout machine has twelve stacks, named \(X, Z, P, P_2, U, N, A_2, B_2, D, C, T, O\).
inductive K | X | Z | P | P2 | U | N | A2 | B2 | D | C | T | O
deriving DecidableEq
InductiveLabels of the layout machine#✓fully proved
The layout machine has 17 labels, named \(\mathsf{s0}\), \(\mathsf{mvZ}\), \(\mathsf{cp0}\), \(\mathsf{cp1}\), \(\mathsf{lo0}\), \(\mathsf{lo1}\), \(\mathsf{lo2}\), \(\mathsf{lo3}\), \(\mathsf{lo4}\), \(\mathsf{mh}\), \(\mathsf{mb}\), \(\mathsf{mk}\), \(\mathsf{mr}\), \(\mathsf{lo5}\), \(\mathsf{lo6}\), \(\mathsf{bad}\) and \(\mathsf{done}\).
inductive Lab
| s0 | mvZ | cp0 | cp1 | lo0 | lo1 | lo2 | lo3 | lo4 | mh | mb | mk | mr | lo5 | lo6 | bad | done
deriving DecidableEq
AbbreviationStack symbols of the layout machine#✓fully proved
Every stack of the layout machine holds bits: the alphabet of each of its stacks is the type of Booleans.
abbrev Γ : K → Type := fun _ => Bool
inductive K | X | Z | P | P2 | U | N | A2 | B2 | D | C | T | O
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:760
Uses 1 · Used by 4
DefinitionProgram of the layout machine#✓fully proved
Writing \(1\) for true and \(0\) for false, this is the program of a multi-stack machine whose stacks \(X, Z, P, P_2, U, N, A_2, B_2, D, C, T, O\) all hold bits. To move a stack \(S\) onto a stack \(S'\) means to pop the bits of \(S\) one at a time, pushing each onto \(S'\), until \(S\) is empty; to transfer \(S\) to some stacks means to pop \(S\) until it is empty, pushing a \(1\) on each of these stacks for every bit popped. From the label \(\mathsf{s0}\) the program pops \(X\). If \(X\) was empty or the popped bit is \(0\), it pushes \(0, 0, 1, 1, 0\) on \(O\) in this order and halts. Otherwise it moves \(X\) onto \(Z\), and then, as long as \(Z\) is nonempty, it pops a bit \(b\) from \(Z\), pushes \(b\) on \(U\) and a \(1\) on \(N\), and pushes \(0, 1, 1\) on \(P\) in this order if \(b = 1\) and \(0, 1\) if \(b = 0\). Then it moves \(U\) onto \(O\), pushes a \(0\) on \(O\), moves \(P\) onto \(P_2\) and then \(P_2\) onto \(O\), and transfers \(N\) to \(A_2\) and \(B_2\). Then it loops: it pops \(A_2\); if a bit was popped, it pushes a \(1\) on \(D\), transfers \(B_2\) to \(C\) and \(T\), transfers \(T\) to \(B_2\) and loops again; if \(A_2\) was empty, it transfers \(D\) to \(A_2\). Finally it pushes \(0, 1\) on \(O\) in this order, transfers \(C\) to \(O\) and halts.
Cslib.Turing.Universal.Diag.Layout.prog · 23 lines
def prog : Lab → TM2.Stmt Γ Lab Bool
| .s0 => .pop .X (fun _ o ↦ o == some true)
(.branch id (.goto fun _ ↦ .mvZ) (.goto fun _ ↦ .bad))
| .mvZ => moveB .X .Z some id .mvZ .cp0
| .cp0 => .peek .Z (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .cp1) (.goto fun _ ↦ .lo0))
| .cp1 => .pop .Z (fun _ o ↦ o.getD false) (.branch id
(.push .U (fun _ ↦ true) (.push .N (fun _ ↦ true) (.push .P (fun _ ↦ false)
(.push .P (fun _ ↦ true) (.push .P (fun _ ↦ true) (.goto fun _ ↦ .cp0))))))
(.push .U (fun _ ↦ false) (.push .N (fun _ ↦ true) (.push .P (fun _ ↦ false)
(.push .P (fun _ ↦ true) (.goto fun _ ↦ .cp0))))))
| .lo0 => moveB .U .O some id .lo0 .lo1
| .lo1 => incr .O false .lo2
| .lo2 => moveB .P .P2 some id .lo2 .lo3
| .lo3 => moveB .P2 .O some id .lo3 .lo4
| .lo4 => xfer .N [⟨.A2, true⟩, ⟨.B2, true⟩] .lo4 .mh
| .mh => forHead .A2 .D true .mb .mr
| .mb => xfer .B2 [⟨.C, true⟩, ⟨.T, true⟩] .mb .mk
| .mk => xfer .T [⟨.B2, true⟩] .mk .mh
| .mr => xfer .D [⟨.A2, true⟩] .mr .lo5
| .lo5 => emitR .O [true, false] .lo6
| .lo6 => xfer .C [⟨.O, true⟩] .lo6 .done
| .bad => emitR .O [false, true, true, false, false] .done
| .done => .halt
inductive Lab
| s0 | mvZ | cp0 | cp1 | lo0 | lo1 | lo2 | lo3 | lo4 | mh | mb | mk | mr | lo5 | lo6 | bad | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:769
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:780
def moveB (a b : K) (d : Γ a → Option Bool) (g : Bool → Γ b) (self next : Λ) :
TM2.Stmt Γ Λ σ :=
.peek a (fun _ o => Flag.tag (isBit d o))
(.branch Flag.untag
(.pop a (fun _ o => Flag.tag (bitOf d o))
(.branch Flag.untag
(.push b (fun _ => g true) (.goto fun _ => self))
(.push b (fun _ => g false) (.goto fun _ => self))))
(.goto fun _ => next))
MathlibExt/Computability/TuringMachine/BitOps.lean:86
def incr (k : K) (u : Γ k) (next : Λ) : TM2.Stmt Γ Λ σ :=
.push k (fun _ => u) (.goto fun _ => next)
MathlibExt/Computability/TuringMachine/Program.lean:137
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 forHead (c cd : K) (ucd : Γ cd) (body rest : Λ) : TM2.Stmt Γ Λ σ :=
.pop c (fun _ o => Flag.tag o.isSome) <| .branch Flag.untag
(.push cd (fun _ => ucd) <| .goto fun _ => body) (.goto fun _ => rest)
MathlibExt/Computability/TuringMachine/Program.lean:461
def emitR (k : K) (ys : List (Γ k)) (next : Λ) : TM2.Stmt Γ Λ σ := emit k ys.reverse next
MathlibExt/Computability/TuringMachine/Program.lean:698
DefinitionThe layout function#✓fully proved
Write \(\mathrm{cell}(n)\) for the bit list of \(n\) bits \(\mathrm{true}\) followed by one bit \(\mathrm{false}\). On a bit list \(\mathrm{true} :: x\), the layout function returns \(\mathrm{cell}(|x|^2 + 1)\), then the cells \(\mathrm{cell}(s)\) of the symbols \(s\) of the input word of \(x\) (the symbol \(2\) for each bit \(\mathrm{true}\) and \(1\) for each bit \(\mathrm{false}\)), then the bit \(\mathrm{false}\), then the reverse of \(x\). On every other bit list, that is, the empty list or a list starting with \(\mathrm{false}\), it returns the list \([\mathrm{false}, \mathrm{true}, \mathrm{true}, \mathrm{false}, \mathrm{false}]\).
def layout : List Bool → List Bool
| true :: x => cell (x.length ^ 2 + 1) ++ (cells (input x) ++ (false :: x.reverse))
| _ => [false, true, true, false, false]
def cell (n : ℕ) : List Bool := cnt true n ++ [false]
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:81
def cells (l : List ℕ) : List Bool := l.flatMap cell
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:84
def input (x : List Bool) : List ℕ := x.map bitSym
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:120
TheoremThe layout run#✓fully proved
For every bit list \(y\), the layout machine, started at the label \(\mathsf{s0}\) with internal state false, with \(y\) on its input stack \(X\) and every other stack empty, reaches the label \(\mathsf{done}\) within \(18(|y| + 1)^2\) steps, with some internal state and stacks in which the output stack \(O\) holds the layout of \(y\).
theorem run (y : List Bool) :
∃ v S', RunLe prog (18 * (y.length + 1) ^ 2)
⟨some .s0, false, update (fun _ ↦ []) .X y⟩ ⟨some .done, v, S'⟩ ∧ S' .O = layout y
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 prog : Lab → TM2.Stmt Γ Lab Bool
| .s0 => .pop .X (fun _ o ↦ o == some true)
(.branch id (.goto fun _ ↦ .mvZ) (.goto fun _ ↦ .bad))
| .mvZ => moveB .X .Z some id .mvZ .cp0
| .cp0 => .peek .Z (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .cp1) (.goto fun _ ↦ .lo0))
| .cp1 => .pop .Z (fun _ o ↦ o.getD false) (.branch id
(.push .U (fun _ ↦ true) (.push .N (fun _ ↦ true) (.push .P (fun _ ↦ false)
(.push .P (fun _ ↦ true) (.push .P (fun _ ↦ true) (.goto fun _ ↦ .cp0))))))
(.push .U (fun _ ↦ false) (.push .N (fun _ ↦ true) (.push .P (fun _ ↦ false)
(.push .P (fun _ ↦ true) (.goto fun _ ↦ .cp0))))))
| .lo0 => moveB .U .O some id .lo0 .lo1
| .lo1 => incr .O false .lo2
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:784
def layout : List Bool → List Bool
| true :: x => cell (x.length ^ 2 + 1) ++ (cells (input x) ++ (false :: x.reverse))
| _ => [false, true, true, false, false]
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:850
Uses 22 · Used by 1
TheoremThe cell-by-cell check agrees with code-stack decoding#✓fully proved
For every bit list \(x\), the cell-by-cell check of \(x\) from the key \((0, 0)\) succeeds if and only if the decoding of \(x\) as a code stack returns a code.
theorem chkFrom_zero (x : List Bool) : chkFrom 0 0 x = (decodeCodeCells x).isSome
def chkFrom (pq pa : ℕ) (x : List Bool) : Bool :=
match x with
| [] => true
| b :: x' =>
match _h1 : readUnaryLength (b :: x') with
| none => false
| some (q, x1) =>
match _h2 : readUnaryLength x1 with
| none => false
| some (a, x2) =>
if pq < q ∨ pq = q ∧ pa ≤ a then
match _h3 : readUnaryLength x2 with
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:100
def decodeCodeCells (x : List Bool) : Option Code :=
((cellsDecode x).bind entriesOfNums).bind fun es ↦
if keysAscendFrom 0 0 es then some (codeOfEntries es) else none
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:508
Uses 8 · Used by 1
AbbreviationThe layout machine as a host component#✓fully proved
The component machine with the twelve stacks \(X, Z, P, P_2, U, N, A_2, B_2, D, C, T, O\) of the layout machine, each holding bits, with the labels and the program of the layout machine, and with its stacks listed in the order \(X, Z, P, P_2, U, N, A_2, B_2, D, C, T, O\).
abbrev comp : Complexity.Host.Comp where
K := K
Γ := Γ
finΓ := fun _ ↦ inferInstanceAs (Fintype Bool)
L := Lab
prog := prog
ks := [.X, .Z, .P, .P2, .U, .N, .A2, .B2, .D, .C, .T, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> decide
structure Comp where
/-- Stack indices. -/
K : Type
/-- Decidable equality of stack indices. -/
[decK : DecidableEq K]
/-- Finitely many stacks. -/
[finK : Fintype K]
/-- Stack alphabets. -/
Γ : K → Type
/-- Finite alphabets. -/
[finΓ : ∀ k, Fintype (Γ k)]
/-- Labels. -/
⋯
CSLibExt/Computability/Complexity/Host.lean:53
inductive K | X | Z | P | P2 | U | N | A2 | B2 | D | C | T | O
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:760
abbrev Γ : K → Type := fun _ => Bool
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:780
inductive Lab
| s0 | mvZ | cp0 | cp1 | lo0 | lo1 | lo2 | lo3 | lo4 | mh | mb | mk | mr | lo5 | lo6 | bad | done
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:769
def prog : Lab → TM2.Stmt Γ Lab Bool
| .s0 => .pop .X (fun _ o ↦ o == some true)
(.branch id (.goto fun _ ↦ .mvZ) (.goto fun _ ↦ .bad))
| .mvZ => moveB .X .Z some id .mvZ .cp0
| .cp0 => .peek .Z (fun _ o ↦ o.isSome) (.branch id (.goto fun _ ↦ .cp1) (.goto fun _ ↦ .lo0))
| .cp1 => .pop .Z (fun _ o ↦ o.getD false) (.branch id
(.push .U (fun _ ↦ true) (.push .N (fun _ ↦ true) (.push .P (fun _ ↦ false)
(.push .P (fun _ ↦ true) (.push .P (fun _ ↦ true) (.goto fun _ ↦ .cp0))))))
(.push .U (fun _ ↦ false) (.push .N (fun _ ↦ true) (.push .P (fun _ ↦ false)
(.push .P (fun _ ↦ true) (.goto fun _ ↦ .cp0))))))
| .lo0 => moveB .U .O some id .lo0 .lo1
| .lo1 => incr .O false .lo2
⋯
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:784
Uses 5 · Used by 1
DefinitionThe layout in polynomial time#✓fully proved
A finite multi-stack Turing machine, whose input and output alphabets are identified with the bits, together with a polynomial time bound, that computes the layout function: given a bit list \(y\) as its input, it halts within the bound, evaluated at \(|y|\), with the layout of \(y\) as its output.
noncomputable def polyTime :
TM2ComputableInPolyTime (fun l : List Bool ↦ l) (fun l : List Bool ↦ l) layout :=
Complexity.Host.reduction (c := comp) (cX := .X) (cO := .O) (gX := id) (start := .s0)
(done := .done) (Equiv.refl Bool) _ (Polynomial.C 18 * (Polynomial.X + 1) ^ 2) rfl
fun y ↦ by
obtain ⟨v, S', hr, hO⟩ := run y
exact ⟨v, S', by simpa [Polynomial.eval_mul, Polynomial.eval_pow] using hr,
by simpa using hO⟩
def layout : List Bool → List Bool
| true :: x => cell (x.length ^ 2 + 1) ++ (cells (input x) ++ (false :: x.reverse))
| _ => [false, true, true, false, false]
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:850
noncomputable def reduction (eO : c.Γ cO ≃ Bool) (f : List Bool → List Bool) (p : Polynomial ℕ)
(hdone : c.prog done = .halt)
(hrun : ∀ x, ∃ v S', RunLe c.prog (p.eval x.length)
⟨some start, false, update (fun _ => []) cX (x.map gX)⟩ ⟨some done, v, S'⟩ ∧
S' cO = (f x).map eO.symm) :
TM2ComputableInPolyTime (fun l : List Bool => l) (fun l : List Bool => l) f where
tm := rtm c cX cO gX start done
inputAlphabet := Equiv.refl Bool
outputAlphabet := eO
time := rtime c cX cO gX start done p
outputsFun := fun x => by
have h := rprog_run eO f p hdone hrun x
⋯
CSLibExt/Computability/Complexity/Host.lean:348
abbrev comp : Complexity.Host.Comp where
K := K
Γ := Γ
finΓ := fun _ ↦ inferInstanceAs (Fintype Bool)
L := Lab
prog := prog
ks := [.X, .Z, .P, .P2, .U, .N, .A2, .B2, .D, .C, .T, .O]
ks_nodup := by decide
mem_ks k := by cases k <;> decide
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:968
Uses 10 · Used by 1
TheoremLayout after checking gives the universal machine's input#✓fully proved
For every bit list \(x\), let \((c, y, T)\) be the universal machine's argument for the diagonal language of \(f(n) = n^2 + 1\) on \(x\). Then the layout function applied to the checking machine's answer on \(x\) equals the input bit list of the clocked universal machine for the code \(c\), the input \(y\) and the clock \(T\).
theorem layout_answer (x : List Bool) :
Layout.layout (Check.answer x) =
encIn (diagArg (fun n ↦ n ^ 2 + 1) x).1 (diagArg (fun n ↦ n ^ 2 + 1) x).2.1
(diagArg (fun n ↦ n ^ 2 + 1) x).2.2
def layout : List Bool → List Bool
| true :: x => cell (x.length ^ 2 + 1) ++ (cells (input x) ++ (false :: x.reverse))
| _ => [false, true, true, false, false]
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:850
def answer (x : List Bool) : List Bool := if chkFrom 0 0 x then true :: x else [false]
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:685
def encIn (c : Code) (x : List Bool) (T : ℕ) : List Bool :=
cell T ++ (cells (input x) ++ (false :: (codeCells c).reverse))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1176
def diagArg (f : ℕ → ℕ) (x : List Bool) : Code × List Bool × ℕ :=
match decodeCodeCells x with
| some c => (c, x, f x.length)
| none => (⟨[]⟩, [true], 0)
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:625
Uses 12 · Used by 1
DefinitionThe reformatting machine for \(n \mapsto n^2 + 1\)#✓fully proved
Let \(f(n) = n^2 + 1\). This is a finite multi-stack Turing machine whose input and output alphabets are identified with the bits, together with a polynomial \(p\), such that for every bit list \(x\), started with \(x\) on its input stack it halts within \(p(|x|)\) steps with output the clocked universal machine's input bits for the universal machine's argument \((c, w, T)\) for the diagonal language of \(f\) at \(x\): the clock \(T\) as a cell, the cells of the input symbols of \(w\), a blank cell and the code stack of \(c\) reversed. It runs the checking machine and then the layout machine.
noncomputable def reformat :
TM2ComputableInPolyTime (fun x : List Bool ↦ x)
(fun a : Code × List Bool × ℕ ↦ encIn a.1 a.2.1 a.2.2) (diagArg (fun n ↦ n ^ 2 + 1)) :=
let H := MetaMathlibExt.TM2Composition.compComputable Check.polyTime Layout.polyTime
{ toTM2ComputableAux := H.toTM2ComputableAux
time := H.time
outputsFun := fun x ↦ by
have h := H.outputsFun x
simp only [Function.comp_apply, layout_answer] at h
exact h }
structure Code where
/-- The transition table, indexed by state, then by symbol. -/
table : List (List (Option (ℕ × ℕ)))
deriving DecidableEq
CSLibExt/Computability/Machines/Turing/Universal/Code.lean:105
def encIn (c : Code) (x : List Bool) (T : ℕ) : List Bool :=
cell T ++ (cells (input x) ++ (false :: (codeCells c).reverse))
CSLibExt/Computability/Machines/Turing/Universal/Clocked.lean:1176
def diagArg (f : ℕ → ℕ) (x : List Bool) : Code × List Bool × ℕ :=
match decodeCodeCells x with
| some c => (c, x, f x.length)
| none => (⟨[]⟩, [true], 0)
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:625
noncomputable def compComputable (h₁ : TM2ComputableInPolyTime eα eβ f)
(h₂ : TM2ComputableInPolyTime eβ eγ g) : TM2ComputableInPolyTime eα eγ (g ∘ f) where
tm := compTM h₁.tm h₂.tm (glue h₁ h₂)
inputAlphabet := h₁.inputAlphabet
outputAlphabet := h₂.outputAlphabet
time := compTime h₁ h₂
outputsFun := compOutputs h₁ h₂
MathlibExt/Computability/TuringMachine/Composition.lean:615
noncomputable def polyTime :
TM2ComputableInPolyTime (fun l : List Bool ↦ l) (fun l : List Bool ↦ l) answer :=
Complexity.Host.reduction (c := comp) (cX := .X) (cO := .O) (gX := id) (start := .dupP)
(done := .done) (Equiv.refl Bool) _ (Polynomial.C 33 * (Polynomial.X + 1) ^ 2) rfl
fun x ↦ by
obtain ⟨v, S', hr, hO⟩ := run x
exact ⟨v, S', by simpa [Polynomial.eval_mul, Polynomial.eval_pow] using hr,
by simpa using hO⟩
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:742
noncomputable def polyTime :
TM2ComputableInPolyTime (fun l : List Bool ↦ l) (fun l : List Bool ↦ l) layout :=
Complexity.Host.reduction (c := comp) (cX := .X) (cO := .O) (gX := id) (start := .s0)
(done := .done) (Equiv.refl Bool) _ (Polynomial.C 18 * (Polynomial.X + 1) ^ 2) rfl
fun y ↦ by
obtain ⟨v, S', hr, hO⟩ := run y
exact ⟨v, S', by simpa [Polynomial.eval_mul, Polynomial.eval_pow] using hr,
by simpa using hO⟩
CSLibExt/Computability/Machines/Turing/Universal/DiagonalDecider.lean:979
Uses 9 · Used by 1
TheoremDeciding the diagonal language on raw bits in polynomial time#✓fully proved
Let \(D\) be the diagonal language for the time bound \(f(n) = n^2 + 1\). There is a finite multi-stack Turing machine that, given a bit list \(x\) as its input, halts within a number of steps polynomial in \(|x|\) with the single bit \(D(x)\) as its output.
theorem nonempty_diag_sq_add_one_polyTime :
Nonempty (TM2ComputableInPolyTime (fun x : List Bool ↦ x) (fun b : Bool ↦ [b])
(diag (fun n ↦ n ^ 2 + 1)))
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
Uses 3 · Used by 1
TheoremThe quadratic diagonal language is in P#✓fully proved
The diagonal language for the time bound \(f(n) = n^2 + 1\), the set of bit lists \(x\) that encode a code which does not halt on \(x\) within \(|x|^2 + 1\) steps with the answer \(\mathrm{true}\), is in the class P of decision problems decidable in polynomial time.
The decider decodes the canonical encoding of bit lists and then runs a polynomial-time decider on the raw bits.
theorem diag_sq_add_one_mem_P : diag (fun n ↦ n ^ 2 + 1) ∈ P
def diag (f : ℕ → ℕ) : DecisionProblem := fun x ↦
match decodeCodeCells x with
| none => false
| some c => decide (c.evalSteps x (f x.length) ≠ some [bitSym true])
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:515
def P : DecisionComplexityClass :=
{ L | IsPolyTime L }
MathlibExt/Computability/Complexity.lean:194
Uses 15 · Used by 2
TheoremDiagonalization across models#✓fully proved
There is a decision problem in the class P that no code decides within \(n^2 + 1\) steps: no code halts on every input \(x\) within \(|x|^2 + 1\) steps with the answer for \(x\) as its output.
The diagonal language for the time bound \(n \mapsto n^2 + 1\) is such a problem. The class of problems that codes decide within \(n^2 + 1\) steps is not empty: it contains the problem whose answer is always \(\mathrm{false}\).
theorem exists_mem_P_not_mem_codeTime_sq_add_one :
∃ L ∈ P, L ∉ CodeTime (fun n ↦ n ^ 2 + 1)
def P : DecisionComplexityClass :=
{ L | IsPolyTime L }
MathlibExt/Computability/Complexity.lean:194
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:116
Uses 7
TheoremPolynomial time is not contained in code time \(n^2 + 1\)#✓fully proved
Some decision problem in \(\mathsf{P}\) is decided by no code within \(n^2 + 1\) steps on every input of length \(n\); that is, \(\mathsf{P}\) is not a subset of the class \(\mathrm{CodeTime}(n \mapsto n^2 + 1)\).
theorem not_P_subset_codeTime_sq_add_one : ¬ P ⊆ CodeTime (fun n ↦ n ^ 2 + 1)
def P : DecisionComplexityClass :=
{ L | IsPolyTime L }
MathlibExt/Computability/Complexity.lean:194
def CodeTime (t : ℕ → ℕ) : DecisionComplexityClass :=
{L | ∃ c : Code, c.DecidesWithin L t}
CSLibExt/Computability/Machines/Turing/Universal/Diagonalization.lean:116
Uses 7
TheoremThere is an EXP language outside P (time-hierarchy separation)#●ready to prove
There is a decision problem that belongs to the class EXP but not to the complexity class P.
Only this separation is stated; the containment of P in EXP is not part of the statement.
public theorem_wanted p_ne_exp :
∃ L : MetaMathlibExt.ComplexityTheory.DecisionProblem,
L ∈ EXP ∧ L ∉ MetaMathlibExt.ComplexityTheory.P
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
def EXP : DecisionComplexityClass :=
{L | ∃ d, langOf L ∈ Cslib.Turing.MultiTapeTM.DTIME (fun n => 2 ^ (n ^ d))}
CSLibExt/Computability/Complexity/Classes.lean:121
def P : DecisionComplexityClass :=
{ L | IsPolyTime L }
MathlibExt/Computability/Complexity.lean:194
Sources
- J. Hartmanis and R. E. Stearns, "On the computational complexity of algorithms", Transactions of the American Mathematical Society 117 (1965), 285-306; S. Arora and B. Barak, Computational Complexity: A Modern Approach, 2009, Corollary 3.5.
Uses 4
TheoremDeterministic time hierarchy: quadratic versus linear time#●ready to prove
There is a language \(L\) of bitstrings that lies in the multi-tape deterministic time class \(\mathrm{DTIME}(n^2)\) but not in \(\mathrm{DTIME}(n)\).
public theorem_wanted time_hierarchy :
∃ L : Set (List Bool), L ∈ Cslib.Turing.MultiTapeTM.DTIME (fun n => n ^ 2) ∧
L ∉ Cslib.Turing.MultiTapeTM.DTIME (fun n => n)
def DTIME (t : ℕ → ℕ) : Set (Set (List Bool)) :=
{L | ∃ c₁ c₂ : ℕ, ∃ s : ℕ → ℕ, MultiTapeTM.DecidableInTimeAndSpace L
(Function.Embedding.refl _) (fun w ↦ c₁ * t w.length + c₂) (fun w ↦ s w.length)}
CSLibExt/Computability/Machines/Turing/MultiTape/TimeSpace.lean:142
Sources
- J. Hartmanis and R. E. Stearns, "On the computational complexity of algorithms", Transactions of the American Mathematical Society 117 (1965), 285-306.
Uses 1
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.