Documentation

Complexitylib.Models.TuringMachine.Subroutines.PairSplit.Internal

Pair-splitting machine — proof internals #

This file proves the stepwise decoding and exact-time correctness facts for pairSplitCoreTM. Stable statements are re-exposed by Complexitylib.Models.TuringMachine.Subroutines.PairSplit.

theorem Complexity.TM.pairSplitCoreTM_from_scanX_initTape_move_right_internal {k : } (xIdx yIdx : Fin k) (hne : xIdx yIdx) (x y : List Bool) (c : Cfg k (pairSplitCoreTM xIdx yIdx).Q) (hst : c.state = PairSplitPhase.scanX) (hinp : c.input = (Tape.init (List.map Γ.ofBool (pair x y))).move Dir3.right) (hxw : c.work xIdx = (Tape.init []).move Dir3.right) (hyw : c.work yIdx = (Tape.init []).move Dir3.right) :
∃ (c' : Cfg k (pairSplitCoreTM xIdx yIdx).Q), (pairSplitCoreTM xIdx yIdx).reachesIn (2 * x.length + y.length + 3) c c' (pairSplitCoreTM xIdx yIdx).halted c' c'.input.head = (pair x y).length + 1 c'.input.cells = (Tape.init (List.map Γ.ofBool (pair x y))).cells (c'.work xIdx).head = 1 + x.length (c'.work xIdx).cells 0 = Γ.start (∀ (i : ) (h : i < x.length), (c'.work xIdx).cells (i + 1) = Γ.ofBool x[i]) (∀ (i : ), x.length i(c'.work xIdx).cells (i + 1) = Γ.blank) (c'.work yIdx).head = 1 + y.length (c'.work yIdx).cells 0 = Γ.start (∀ (i : ) (h : i < y.length), (c'.work yIdx).cells (i + 1) = Γ.ofBool y[i]) ∀ (i : ), y.length i(c'.work yIdx).cells (i + 1) = Γ.blank

Core correctness for valid started inputs. Beginning in .scanX with pair x y on the input tape and empty started work tapes, pairSplitCoreTM halts after decoding the doubled x prefix onto xIdx and copying the suffix y onto yIdx. The two work heads finish just past the strings they wrote.

theorem Complexity.TM.pairSplit_init_step_all_started_internal {k : } (xIdx yIdx : Fin k) (c : Cfg k (pairSplitCoreTM xIdx yIdx).Q) (hst : c.state = PairSplitPhase.init) (hinp : c.input.read Γ.start) (hx : (c.work xIdx).read Γ.start) (hy : (c.work yIdx).read Γ.start) :
∃ (c' : Cfg k (pairSplitCoreTM xIdx yIdx).Q), (pairSplitCoreTM xIdx yIdx).step c = some c' c'.state = PairSplitPhase.scanX c'.input = c.input c'.work xIdx = c.work xIdx c'.work yIdx = c.work yIdx

Variant of the init step for phase composition: if the input tape and the two tracked work tapes are already positioned past , the .init state advances to .scanX without changing those tapes.

theorem Complexity.TM.pairSplitCoreTM_from_init_initTape_move_right_internal {k : } (xIdx yIdx : Fin k) (hne : xIdx yIdx) (x y : List Bool) (c : Cfg k (pairSplitCoreTM xIdx yIdx).Q) (hst : c.state = PairSplitPhase.init) (hinp : c.input = (Tape.init (List.map Γ.ofBool (pair x y))).move Dir3.right) (hxw : c.work xIdx = (Tape.init []).move Dir3.right) (hyw : c.work yIdx = (Tape.init []).move Dir3.right) :
∃ (c' : Cfg k (pairSplitCoreTM xIdx yIdx).Q), (pairSplitCoreTM xIdx yIdx).reachesIn (pairSplitCoreTime x.length y.length) c c' (pairSplitCoreTM xIdx yIdx).halted c' c'.input.head = (pair x y).length + 1 c'.input.cells = (Tape.init (List.map Γ.ofBool (pair x y))).cells (c'.work xIdx).head = 1 + x.length (c'.work xIdx).cells 0 = Γ.start (∀ (i : ) (h : i < x.length), (c'.work xIdx).cells (i + 1) = Γ.ofBool x[i]) (∀ (i : ), x.length i(c'.work xIdx).cells (i + 1) = Γ.blank) (c'.work yIdx).head = 1 + y.length (c'.work yIdx).cells 0 = Γ.start (∀ (i : ) (h : i < y.length), (c'.work yIdx).cells (i + 1) = Γ.ofBool y[i]) ∀ (i : ), y.length i(c'.work yIdx).cells (i + 1) = Γ.blank

Starting from .init with pair x y already on a started input tape and empty started work tapes, pairSplitCoreTM halts within pairSplitCoreTime, leaving xIdx holding x and yIdx holding y, with both heads just past the written strings.

theorem Complexity.TM.pairSplitCoreTM_toNTM_trace_preserves_output_internal {k : } (xIdx yIdx : Fin k) (T : ) (choices : Fin TBool) (c : Cfg k (pairSplitCoreTM xIdx yIdx).Q) (hread : c.output.read Γ.start) :
((pairSplitCoreTM xIdx yIdx).toNTM.trace T choices c).output = c.output

Every lifted pair-split trace preserves an off-start output tape.

theorem Complexity.TM.pairSplitCoreTM_toNTM_trace_preserves_other_work_internal {k : } (xIdx yIdx otherIdx : Fin k) (T : ) (choices : Fin TBool) (c : Cfg k (pairSplitCoreTM xIdx yIdx).Q) (hx : otherIdx xIdx) (hy : otherIdx yIdx) (hread : (c.work otherIdx).read Γ.start) :
((pairSplitCoreTM xIdx yIdx).toNTM.trace T choices c).work otherIdx = c.work otherIdx

Every lifted pair-split trace preserves an off-start work tape other than the two destination tapes.

theorem Complexity.TM.pairSplitCoreTM_from_initCfg_internal {k : } (xIdx yIdx : Fin k) (hne : xIdx yIdx) (x y : List Bool) :
∃ (c' : Cfg k (pairSplitCoreTM xIdx yIdx).Q), (pairSplitCoreTM xIdx yIdx).reachesIn (pairSplitCoreTime x.length y.length) ((pairSplitCoreTM xIdx yIdx).initCfg (pair x y)) c' (pairSplitCoreTM xIdx yIdx).halted c' c'.input.head = (pair x y).length + 1 c'.input.cells = (Tape.init (List.map Γ.ofBool (pair x y))).cells (c'.work xIdx).head = 1 + x.length (c'.work xIdx).cells 0 = Γ.start (∀ (i : ) (h : i < x.length), (c'.work xIdx).cells (i + 1) = Γ.ofBool x[i]) (∀ (i : ), x.length i(c'.work xIdx).cells (i + 1) = Γ.blank) (c'.work yIdx).head = 1 + y.length (c'.work yIdx).cells 0 = Γ.start (∀ (i : ) (h : i < y.length), (c'.work yIdx).cells (i + 1) = Γ.ofBool y[i]) (∀ (i : ), y.length i(c'.work yIdx).cells (i + 1) = Γ.blank) (∀ (i : Fin k), i xIdxi yIdxc'.work i = (Tape.init []).move Dir3.right) c'.output = (Tape.init []).move Dir3.right

Exact pair-split correctness from the machine's genuine initial configuration. In addition to decoding the target tapes, the theorem frames the output and every unrelated work tape as started and blank.