Documentation

Complexitylib.Models.TuringMachine.Subroutines.Internal

TM Subroutines: proof internals #

Simulation lemmas and HoareTime proofs for the rewind, blank, clear, and copy subroutine machines defined in Complexitylib.Models.TuringMachine.Subroutines. Each subroutine gets a basic Hoare-style spec, and where needed a rich "frame" variant that threads an arbitrary predicate P on the untouched tapes through the run.

Main results #

theorem Complexity.TM.writeTM_hoareTime {n : } (sym : Γw) (B : ) :
(writeTM sym).HoareTime (fun (x : Tape) (x_1 : Fin nTape) (out : Tape) => out.cells 0 = Γ.start (∀ j1, out.cells j Γ.start) out.head B) (fun (x : Tape) (x_1 : Fin nTape) (out : Tape) => out.cells 1 = sym.toΓ) (B + 3)

writeTM sym writes sym.toΓ to output cell 1 and halts. Pre: output tape well-formed (cell 0 = ▷, cells ≥ 1 ≠ ▷), head ≤ B. Post: output cell 1 = sym.toΓ. Time: B + 3 steps.

theorem Complexity.TM.rewindWorkTM_hoareTime {n : } (idx : Fin n) (B : ) :
(rewindWorkTM idx).HoareTime (fun (x : Tape) (work : Fin nTape) (x_1 : Tape) => (work idx).cells 0 = Γ.start (∀ j1, (work idx).cells j Γ.start) (work idx).head B) (fun (x : Tape) (work : Fin nTape) (x_1 : Tape) => (work idx).head = 1) (B + 2)

rewindWorkTM idx rewinds work tape idx to cell 1 and halts. Pre: work tape idx well-formed (cell 0 = ▷, cells ≥ 1 ≠ ▷), head ≤ B. Post: work tape idx head = 1. Time: B + 2 steps.

theorem Complexity.TM.rewindInputTM_hoareTime {n : } (B : ) :
rewindInputTM.HoareTime (fun (inp : Tape) (x : Fin nTape) (x_1 : Tape) => inp.cells 0 = Γ.start (∀ j1, inp.cells j Γ.start) inp.head B) (fun (inp : Tape) (x : Fin nTape) (x_1 : Tape) => inp.head = 1) (B + 2)

rewindInputTM rewinds the input tape to cell 1 and halts. Pre: input tape well-formed (cell 0 = ▷, cells ≥ 1 ≠ ▷), head ≤ B. Post: input head = 1. Time: B + 2 steps.

theorem Complexity.TM.rewindInputTM_hoareTime_frame {n : } (B_input : ) {P : Tape(Fin nTape)TapeProp} (hP_preserved : ∀ (inp : Tape) (work : Fin nTape) (out inp' : Tape) (work' : Fin nTape) (out' : Tape), P inp work outinp'.cells = inp.cellsinp'.head = 1work' = workout' = outP inp' work' out') :
rewindInputTM.HoareTime (fun (inp : Tape) (work : Fin nTape) (out : Tape) => inp.cells 0 = Γ.start (∀ j1, inp.cells j Γ.start) inp.head B_input out.read Γ.start out.head 1 (∀ (i : Fin n), (work i).read Γ.start (work i).head 1) P inp work out) (fun (inp : Tape) (work : Fin nTape) (out : Tape) => inp.head = 1 P inp work out) (B_input + 2)

Rich HoareTime for rewindInputTM that preserves an arbitrary predicate P through the rewind, provided P is stable when the input cells are unchanged and the input head is reset to 1. Work and output tapes are preserved exactly under the usual non-start-under-head side conditions.

theorem Complexity.TM.rewindInputTM_toNTM_hoareTime {n : } (B : ) :
rewindInputTM.toNTM.HoareTime (fun (inp : Tape) (x : Fin nTape) (x_1 : Tape) => inp.cells 0 = Γ.start (∀ j1, inp.cells j Γ.start) inp.head B) (fun (inp : Tape) (x : Fin nTape) (x_1 : Tape) => inp.head = 1) (B + 2)

Nondeterministic form of rewindInputTM_hoareTime, for phase compositions that run deterministic setup subroutines through TM.toNTM.

theorem Complexity.TM.rewindInputTM_toNTM_hoareTime_frame {n : } (B_input : ) {P : Tape(Fin nTape)TapeProp} (hP_preserved : ∀ (inp : Tape) (work : Fin nTape) (out inp' : Tape) (work' : Fin nTape) (out' : Tape), P inp work outinp'.cells = inp.cellsinp'.head = 1work' = workout' = outP inp' work' out') :
rewindInputTM.toNTM.HoareTime (fun (inp : Tape) (work : Fin nTape) (out : Tape) => inp.cells 0 = Γ.start (∀ j1, inp.cells j Γ.start) inp.head B_input out.read Γ.start out.head 1 (∀ (i : Fin n), (work i).read Γ.start (work i).head 1) P inp work out) (fun (inp : Tape) (work : Fin nTape) (out : Tape) => inp.head = 1 P inp work out) (B_input + 2)

Nondeterministic form of rewindInputTM_hoareTime_frame.

theorem Complexity.TM.rewindWorkTM_hoareTime_frame {n : } (idx : Fin n) (B_tape : ) {P : Tape(Fin nTape)TapeProp} (hP_preserved : ∀ (inp : Tape) (work : Fin nTape) (out inp' : Tape) (work' : Fin nTape) (out' : Tape), P inp work out(work' idx).cells = (work idx).cells(work' idx).head = 1(∀ (i : Fin n), i idxwork' i = work i)inp' = inpout'.cells = out.cellsout'.head = out.headP inp' work' out') :
(rewindWorkTM idx).HoareTime (fun (inp : Tape) (work : Fin nTape) (out : Tape) => (work idx).cells 0 = Γ.start (∀ j1, (work idx).cells j Γ.start) (work idx).head B_tape inp.read Γ.start out.read Γ.start out.head 1 (∀ (i : Fin n), i idx(work i).read Γ.start (work i).head 1) P inp work out) (fun (inp : Tape) (work : Fin nTape) (out : Tape) => (work idx).head = 1 P inp work out) (B_tape + 2)

Rich HoareTime for rewindWorkTM that preserves an arbitrary predicate P through the rewind, provided P depends on cells (not heads) of the target tape. This is the key tool for threading invariants (e.g., simulation state, encoded data) through rewind steps in seqTM compositions.

The caller provides hP_preserved showing that P is stable under:

  • target tape cells unchanged, head set to 1
  • all other work tapes unchanged
  • input and output unchanged
theorem Complexity.TM.blankWorkTM_started_hoareTime {n : } (idx : Fin n) (x : List Bool) :
(blankWorkTM idx).HoareTime (fun (_inp : Tape) (work : Fin nTape) (_out : Tape) => work idx = (Tape.init (List.map Γ.ofBool x)).move Dir3.right) (fun (_inp : Tape) (work : Fin nTape) (_out : Tape) => (work idx).head = x.length + 1 (work idx).cells 0 = Γ.start ∀ (i : ), (work idx).cells (i + 1) = Γ.blank) (x.length + 1)

If work tape idx holds a started Boolean string x, then blankWorkTM idx clears that tape in |x| + 1 steps and leaves the head at the first blank cell after the erased string.

theorem Complexity.TM.blankWorkTM_hoareTime_frame_of_binaryString {n : } (idx : Fin n) (x : List Bool) {P : Tape(Fin nTape)TapeProp} (hP_preserved : ∀ (inp : Tape) (work : Fin nTape) (out inp' : Tape) (work' : Fin nTape) (out' : Tape), P inp work out(work' idx).head = x.length + 1(work' idx).cells 0 = Γ.start(∀ (i : ), (work' idx).cells (i + 1) = Γ.blank)inp' = inpout' = out(∀ (i : Fin n), i idxwork' i = work i)P inp' work' out') :
(blankWorkTM idx).HoareTime (fun (inp : Tape) (work : Fin nTape) (out : Tape) => work idx = (Tape.init (List.map Γ.ofBool x)).move Dir3.right inp.read Γ.start out.read Γ.start out.head 1 (∀ (i : Fin n), i idx(work i).read Γ.start (work i).head 1) P inp work out) (fun (inp : Tape) (work : Fin nTape) (out : Tape) => (work idx).head = x.length + 1 (work idx).cells 0 = Γ.start (∀ (i : ), (work idx).cells (i + 1) = Γ.blank) P inp work out) (x.length + 1)

Rich HoareTime for blankWorkTM: erase a started Boolean work tape while preserving arbitrary frame data on the input tape, output tape, and all other work tapes. This is the form needed to recycle a staged work tape inside a larger verifier pipeline.

theorem Complexity.TM.clearWorkTM_hoareTime_frame_of_binaryString {n : } (idx : Fin n) (x : List Bool) {P : Tape(Fin nTape)TapeProp} (hP_preserved : ∀ (inp : Tape) (work : Fin nTape) (out inp' : Tape) (work' : Fin nTape) (out' : Tape), P inp work outwork' idx = (Tape.init []).move Dir3.rightinp' = inpout' = out(∀ (i : Fin n), i idxwork' i = work i)P inp' work' out') :
(clearWorkTM idx).HoareTime (fun (inp : Tape) (work : Fin nTape) (out : Tape) => work idx = (Tape.init (List.map Γ.ofBool x)).move Dir3.right inp.read Γ.start out.read Γ.start out.head 1 (∀ (i : Fin n), i idx(work i).read Γ.start (work i).head 1) P inp work out) (fun (inp : Tape) (work : Fin nTape) (out : Tape) => work idx = (Tape.init []).move Dir3.right P inp work out) (x.length + 1 + 1 + (x.length + 1 + 2))

Rich HoareTime for clearWorkTM: erase a started Boolean work tape and rewind it to the standard started blank tape while preserving the external frame. The user predicate only needs to be stable once the target tape has reached the final started blank configuration.

theorem Complexity.TM.copyInputToWorkTM_started_hoareTime {n : } (idx : Fin n) (x : List Bool) :
(copyInputToWorkTM idx).HoareTime (fun (inp : Tape) (work : Fin nTape) (_out : Tape) => inp = (Tape.init (List.map Γ.ofBool x)).move Dir3.right (work idx).HasBinaryPrefix []) (fun (inp : Tape) (work : Fin nTape) (_out : Tape) => inp.cells = (Tape.init (List.map Γ.ofBool x)).cells inp.head = x.length + 1 (work idx).HasBinaryPrefix x) (x.length + 1)

copyInputToWorkTM idx can be started with the input and target work tape already positioned at cell 1: it copies the entire Boolean input to a binary prefix on work tape idx and halts within |x| + 1 steps.

theorem Complexity.TM.copyWorkToWorkTM_started_hoareTime {n : } (src dst : Fin n) (hne : src dst) (x : List Bool) :
(copyWorkToWorkTM src dst).HoareTime (fun (_inp : Tape) (work : Fin nTape) (_out : Tape) => work src = (Tape.init (List.map Γ.ofBool x)).move Dir3.right (work dst).HasBinaryPrefix []) (fun (_inp : Tape) (work : Fin nTape) (_out : Tape) => (work src).cells = (Tape.init (List.map Γ.ofBool x)).cells (work src).head = x.length + 1 (work dst).HasBinaryPrefix x) (x.length + 1)

If src holds a started Boolean string x and dst is a started blank work tape, then copyWorkToWorkTM src dst copies x onto dst within |x| + 1 steps. The source contents are preserved, while its head advances to the first blank cell after the copied data.

theorem Complexity.TM.copyWorkToWorkTM_hoareTime_frame_of_binaryString {n : } (src dst : Fin n) (hne : src dst) (x : List Bool) {P : Tape(Fin nTape)TapeProp} (hP_preserved : ∀ (inp : Tape) (work : Fin nTape) (out inp' : Tape) (work' : Fin nTape) (out' : Tape), P inp work out(work' src).cells = (Tape.init (List.map Γ.ofBool x)).cells(work' src).head = x.length + 1(work' dst).HasBinaryPrefix x(work' dst).cells 0 = Γ.startinp' = inpout' = out(∀ (i : Fin n), i srci dstwork' i = work i)P inp' work' out') :
(copyWorkToWorkTM src dst).HoareTime (fun (inp : Tape) (work : Fin nTape) (out : Tape) => work src = (Tape.init (List.map Γ.ofBool x)).move Dir3.right work dst = (Tape.init []).move Dir3.right inp.read Γ.start out.read Γ.start out.head 1 (∀ (i : Fin n), i srci dst(work i).read Γ.start (work i).head 1) P inp work out) (fun (inp : Tape) (work : Fin nTape) (out : Tape) => (work src).cells = (Tape.init (List.map Γ.ofBool x)).cells (work src).head = x.length + 1 (work dst).HasBinaryPrefix x (work dst).cells 0 = Γ.start P inp work out) (x.length + 1)

Rich HoareTime for copyWorkToWorkTM: copy a started Boolean work tape to another started blank work tape while preserving arbitrary frame data on the input tape, output tape, and all unrelated work tapes. The source cells are preserved while its head advances to the first blank after the copied string, and the destination accumulates the copied prefix without losing its left-end marker.