TM–NTM embedding: proof internals #
Helper lemmas for TM.toNTM_accepts_iff, showing that the DTM step function
and the NTM trace on toNTM compute the same thing.
theorem
Complexity.TM.toNTM_decidesInTime
{n : ℕ}
(tm : TM n)
{L : Language}
{f : ℕ → ℕ}
(h : tm.DecidesInTime L f)
:
tm.toNTM.DecidesInTime L f
If a DTM decides L in time f, then its NTM embedding also decides L
in time f. This is the key internal lemma for DTIME ⊆ NTIME.
If a DTM is a transducer, so is its NTM embedding.
theorem
Complexity.TM.toNTM_decidesInSpace
{n : ℕ}
(tm : TM n)
{L : Language}
{f : ℕ → ℕ}
(h : tm.DecidesInSpace L f)
:
tm.toNTM.DecidesInSpace L f
If a DTM decides L in space f, then its NTM embedding also decides L
in space f. The uniform time bound is constructed as the maximum halting
time over all inputs of each length.
theorem
Complexity.Tape.StartInvariant.step
{n : ℕ}
(tm : TM n)
{c c' : Cfg n tm.Q}
(hstep : tm.step c = some c')
(hinp : c.input.StartInvariant)
(hwork : ∀ (i : Fin n), (c.work i).StartInvariant)
(hout : c.output.StartInvariant)
:
The invariant is preserved across one DTM step, on every tape.
theorem
Complexity.NTM.trace_add
{n : ℕ}
(tm : NTM n)
(T U : ℕ)
(choices : Fin (T + U) → Bool)
(c : Cfg n tm.Q)
:
tm.trace (T + U) choices c = tm.trace U (fun (i : Fin U) => choices (Fin.natAdd T i)) (tm.trace T (fun (i : Fin T) => choices (Fin.castLE ⋯ i)) c)
Split the first T steps off a trace.
This version uses Fin.castLE/Fin.natAdd for the prefix and suffix choice
sequences, which keeps later proofs away from ad-hoc dependent index casts.