Imports
/- Copyright (c) 2026 Terence Rokop. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Terence Rokop -/ module public import Geb.Prototypes.Computability.BitTree.Machine public import Geb.Prototypes.Computability.TreeScanner.Steps
set_option doc.verso true

Simulation of the bitstring-tree scanner

Each input bit takes one machine transition after initialization. The simulation relates machine configurations to prefixes of the pure scan.

Main statements

  • configs_scan identifies every scanning configuration and its empty output.

  • halts_at and outputString_eq give termination and the decision bit.

Implementation notes

The correspondence uses CSLib's input-symbol and execution APIs, which depend on classical choice. The scanner's data and transition function are constructive.

Tags

Turing machine, simulation, binary tree, recognizer

@[expose] public sectionnamespace Geb.BitTreeopen Turing MultiTapeTMopen Geb.TreeScanner (boolEmb step_of_state)

The first initialization step positions the counter head at one.

theorem init_step (w : List Bool) : unaryScanner.step (unaryScanner.initCfg (w.map boolEmb)) = plantCfg w := w:List BoolMultiTapeTM.step (initCfg (List.map (⇑boolEmb) w)) = plantCfg w w:List Bool{ state := (unaryScanner.tr 0 (initCfg (List.map (⇑boolEmb) w)).inputSymbol (initCfg (List.map (⇑boolEmb) w)).workTapeSymbols).q', inputPos := moveInputPos (initCfg (List.map (⇑boolEmb) w)).inputPos (unaryScanner.tr 0 (initCfg (List.map (⇑boolEmb) w)).inputSymbol (initCfg (List.map (⇑boolEmb) w)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 0 (initCfg (List.map (⇑boolEmb) w)).inputSymbol (initCfg (List.map (⇑boolEmb) w)).workTapeSymbols).workActions i).1 with | none => (initCfg (List.map (⇑boolEmb) w)).workTapes i | some s => Function.update ((initCfg (List.map (⇑boolEmb) w)).workTapes i) ((initCfg (List.map (⇑boolEmb) w)).workTapePos i) s, workTapePos := fun i (initCfg (List.map (⇑boolEmb) w)).workTapePos i + ((unaryScanner.tr 0 (initCfg (List.map (⇑boolEmb) w)).inputSymbol (initCfg (List.map (⇑boolEmb) w)).workTapeSymbols).workActions i).2 } = plantCfg w All goals completed! 🐙

The second initialization step installs the completion marker.

theorem plant_step (w : List Bool) : unaryScanner.step (plantCfg w) = scanCfg w 0 (w:List Bool0 w.length All goals completed! 🐙) (.tree, 1) := w:List BoolMultiTapeTM.step (plantCfg w) = scanCfg w 0 (Mode.tree, 1) w:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 } = scanCfg w 0 (Mode.tree, 1) w:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.state = (scanCfg w 0 (Mode.tree, 1)).statew:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.inputPos = (scanCfg w 0 (Mode.tree, 1)).inputPosw:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.workTapes = (scanCfg w 0 (Mode.tree, 1)).workTapesw:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.workTapePos = (scanCfg w 0 (Mode.tree, 1)).workTapePos w:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.state = (scanCfg w 0 (Mode.tree, 1)).state All goals completed! 🐙 w:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.inputPos = (scanCfg w 0 (Mode.tree, 1)).inputPos All goals completed! 🐙 w:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.workTapes = (scanCfg w 0 (Mode.tree, 1)).workTapes w:List Booli:Fin 1z:{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.workTapes i z = (scanCfg w 0 (Mode.tree, 1)).workTapes i z All goals completed! 🐙 w:List Bool{ state := (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).q', inputPos := moveInputPos (plantCfg w).inputPos (unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).1 with | none => (plantCfg w).workTapes i | some s => Function.update ((plantCfg w).workTapes i) ((plantCfg w).workTapePos i) s, workTapePos := fun i (plantCfg w).workTapePos i + ((unaryScanner.tr 1 (plantCfg w).inputSymbol (plantCfg w).workTapeSymbols).workActions i).2 }.workTapePos = (scanCfg w 0 (Mode.tree, 1)).workTapePos All goals completed! 🐙

The scanned prefix determines the next input symbol.

theorem scanCfg_inputSymbol (w : List Bool) (t : ) (h : t < w.length) (s : State) : (scanCfg w t (w:List Boolt:h:t < w.lengths:Statet w.length All goals completed! 🐙) s).inputSymbol = some (boolEmb w[t]) := w:List Boolt:h:t < w.lengths:State(scanCfg w t s).inputSymbol = some (boolEmb w[t]) All goals completed! 🐙

A complete scan reads the right end marker.

theorem scanCfg_inputSymbol_end (w : List Bool) (s : State) : (scanCfg w w.length (w:List Bools:Statew.length w.length All goals completed! 🐙) s).inputSymbol = none := w:List Bools:State(scanCfg w w.length s).inputSymbol = none w:List Bools:State(if h₁ : (scanCfg w w.length s).inputPos = 0 then none else if h₂ : (scanCfg w w.length s).inputPos = (List.map (⇑boolEmb) w).length + 1 then none else some (List.map (⇑boolEmb) w)[(scanCfg w w.length s).inputPos - 1]) = none w:List Bools:Stateh✝:(scanCfg w w.length s).inputPos = 0none = nonew:List Bools:Stateh✝¹:¬(scanCfg w w.length s).inputPos = 0h✝:(scanCfg w w.length s).inputPos = (List.map (⇑boolEmb) w).length + 1none = nonew:List Bools:Stateh✝¹:¬(scanCfg w w.length s).inputPos = 0h✝:¬(scanCfg w w.length s).inputPos = (List.map (⇑boolEmb) w).length + 1False w:List Bools:Stateh✝:(scanCfg w w.length s).inputPos = 0none = nonew:List Bools:Stateh✝¹:¬(scanCfg w w.length s).inputPos = 0h✝:(scanCfg w w.length s).inputPos = (List.map (⇑boolEmb) w).length + 1none = nonew:List Bools:Stateh✝¹:¬(scanCfg w w.length s).inputPos = 0h✝:¬(scanCfg w w.length s).inputPos = (List.map (⇑boolEmb) w).length + 1False All goals completed! 🐙

A scanning transition consumes one bit and updates exactly the pure state.

theorem scanCfg_step (w : List Bool) (t : ) (h : t < w.length) (s : State) (hs : s.1 = .string 0 < s.2) : unaryScanner.step (scanCfg w t (w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2t w.length All goals completed! 🐙) s) = scanCfg w (t + 1) h (step s w[t]) := w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2MultiTapeTM.step (scanCfg w t s) = scanCfg w (t + 1) h (step s w[t]) w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else noneMultiTapeTM.step (scanCfg w t s) = scanCfg w (t + 1) h (step s w[t]) w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 } = scanCfg w (t + 1) h (step s w[t]) w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.state = (scanCfg w (t + 1) h (step s w[t])).statew:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.inputPos = (scanCfg w (t + 1) h (step s w[t])).inputPosw:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.workTapes = (scanCfg w (t + 1) h (step s w[t])).workTapesw:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.workTapePos = (scanCfg w (t + 1) h (step s w[t])).workTapePos w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.state = (scanCfg w (t + 1) h (step s w[t])).state All goals completed! 🐙 w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.inputPos = (scanCfg w (t + 1) h (step s w[t])).inputPos w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else nonemoveInputPos (scanCfg w t s).inputPos SignType.pos = (scanCfg w (t + 1) h (step s w[t])).inputPos w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none(scanCfg w t s).inputPos + 1, = (scanCfg w (t + 1) h (step s w[t])).inputPos All goals completed! 🐙 w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.workTapes = (scanCfg w (t + 1) h (step s w[t])).workTapes All goals completed! 🐙 w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else none{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.workTapePos = (scanCfg w (t + 1) h (step s w[t])).workTapePos w:List Boolt:h:t < w.lengths:Statehs:s.1 = Mode.string 0 < s.2hw:(scanCfg w t s).workTapeSymbols = fun x if s.2 = 1 then some 0 else nonei:Fin 1{ state := (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).q', inputPos := moveInputPos (scanCfg w t s).inputPos (consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).1 with | none => (scanCfg w t s).workTapes i | some s_1 => Function.update ((scanCfg w t s).workTapes i) ((scanCfg w t s).workTapePos i) s_1, workTapePos := fun i (scanCfg w t s).workTapePos i + ((consume (modeState (step (s.1, s.2) w[t]).1) (counterMove s.1 w[t])).workActions i).2 }.workTapePos i = (scanCfg w (t + 1) h (step s w[t])).workTapePos i All goals completed! 🐙

Scanning a bit emits no output.

theorem outputSymbol_scanCfg (w : List Bool) (t : ) (h : t < w.length) (s : State) : unaryScanner.outputSymbol (scanCfg w t (w:List Boolt:h:t < w.lengths:Statet w.length All goals completed! 🐙) s) = none := w:List Boolt:h:t < w.lengths:StateoutputSymbol (scanCfg w t s) = none w:List Boolt:h:t < w.lengths:State(match (scanCfg w t s).state with | none => none | some q => (unaryScanner.tr q (scanCfg w t s).inputSymbol (scanCfg w t s).workTapeSymbols).outS) = none w:List Boolt:h:t < w.lengths:State(unaryScanner.tr (modeState s.1) (scanCfg w t s).inputSymbol (scanCfg w t s).workTapeSymbols).outS = none w:List Boolt:h:t < w.lengths:State(unaryScanner.tr (modeState s.1) (some (boolEmb w[t])) (scanCfg w t s).workTapeSymbols).outS = none w:List Boolt:h:t < w.lengthm:Moden:(unaryScanner.tr (modeState (m, n).1) (some (boolEmb w[t])) (scanCfg w t (m, n)).workTapeSymbols).outS = none w:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.tree, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.tree, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.string, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.string, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.bit, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.bit, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.done, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.done, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.dead, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.dead, n)).workTapeSymbols).outS = none w:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.tree, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.tree, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.string, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.string, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.bit, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.bit, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.done, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.done, n)).workTapeSymbols).outS = nonew:List Boolt:h:t < w.lengthn:(unaryScanner.tr (modeState (Mode.dead, n).1) (some (boolEmb w[t])) (scanCfg w t (Mode.dead, n)).workTapeSymbols).outS = none All goals completed! 🐙 w:List Boolt:h:t < w.lengthn:(if boolEmb w[t] = 0 then { inputMove := 1, workActions := fun x (none, 0), outS := none, q' := some 3 } else { inputMove := 1, workActions := fun x (none, 1), outS := none, q' := some 2 }).outS = nonew:List Boolt:h:t < w.lengthn:(if boolEmb w[t] = 0 then { inputMove := 1, workActions := fun x (none, -1), outS := none, q' := some (if (scanCfg w t (Mode.string, n)).workTapeSymbols 0 = some 0 then 5 else 2) } else { inputMove := 1, workActions := fun x (none, 0), outS := none, q' := some 4 }).outS = none w:List Boolt:h:t < w.lengthn:h✝¹:boolEmb w[t] = 0h✝:(scanCfg w t (Mode.string, n)).workTapeSymbols 0 = some 0{ inputMove := 1, workActions := fun x (none, -1), outS := none, q' := some 5 }.outS = nonew:List Boolt:h:t < w.lengthn:h✝¹:boolEmb w[t] = 0h✝:¬(scanCfg w t (Mode.string, n)).workTapeSymbols 0 = some 0{ inputMove := 1, workActions := fun x (none, -1), outS := none, q' := some 2 }.outS = nonew:List Boolt:h:t < w.lengthn:h✝:¬boolEmb w[t] = 0{ inputMove := 1, workActions := fun x (none, 0), outS := none, q' := some 4 }.outS = none w:List Boolt:h:t < w.lengthn:h✝:boolEmb w[t] = 0{ inputMove := 1, workActions := fun x (none, 0), outS := none, q' := some 3 }.outS = nonew:List Boolt:h:t < w.lengthn:h✝:¬boolEmb w[t] = 0{ inputMove := 1, workActions := fun x (none, 1), outS := none, q' := some 2 }.outS = nonew:List Boolt:h:t < w.lengthn:h✝¹:boolEmb w[t] = 0h✝:(scanCfg w t (Mode.string, n)).workTapeSymbols 0 = some 0{ inputMove := 1, workActions := fun x (none, -1), outS := none, q' := some 5 }.outS = nonew:List Boolt:h:t < w.lengthn:h✝¹:boolEmb w[t] = 0h✝:¬(scanCfg w t (Mode.string, n)).workTapeSymbols 0 = some 0{ inputMove := 1, workActions := fun x (none, -1), outS := none, q' := some 2 }.outS = nonew:List Boolt:h:t < w.lengthn:h✝:¬boolEmb w[t] = 0{ inputMove := 1, workActions := fun x (none, 0), outS := none, q' := some 4 }.outS = none All goals completed! 🐙

At the right end marker the machine halts.

theorem scanCfg_halts (w : List Bool) (s : State) : (unaryScanner.step (scanCfg w w.length (w:List Bools:Statew.length w.length All goals completed! 🐙) s)).state = none := w:List Bools:State(MultiTapeTM.step (scanCfg w w.length s)).state = none w:List Bools:State{ state := (unaryScanner.tr (modeState s.1) none (scanCfg w w.length s).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length s).inputPos (unaryScanner.tr (modeState s.1) none (scanCfg w w.length s).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState s.1) none (scanCfg w w.length s).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length s).workTapes i | some s_1 => Function.update ((scanCfg w w.length s).workTapes i) ((scanCfg w w.length s).workTapePos i) s_1, workTapePos := fun i (scanCfg w w.length s).workTapePos i + ((unaryScanner.tr (modeState s.1) none (scanCfg w w.length s).workTapeSymbols).workActions i).2 }.state = none w:List Boolm:Moden:{ state := (unaryScanner.tr (modeState (m, n).1) none (scanCfg w w.length (m, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (m, n)).inputPos (unaryScanner.tr (modeState (m, n).1) none (scanCfg w w.length (m, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (m, n).1) none (scanCfg w w.length (m, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (m, n)).workTapes i | some s => Function.update ((scanCfg w w.length (m, n)).workTapes i) ((scanCfg w w.length (m, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (m, n)).workTapePos i + ((unaryScanner.tr (modeState (m, n).1) none (scanCfg w w.length (m, n)).workTapeSymbols).workActions i).2 }.state = none w:List Booln:{ state := (unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.tree, n)).inputPos (unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.tree, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.tree, n)).workTapes i) ((scanCfg w w.length (Mode.tree, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.tree, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.string, n)).inputPos (unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.string, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.string, n)).workTapes i) ((scanCfg w w.length (Mode.string, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.string, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.bit, n)).inputPos (unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.bit, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.bit, n)).workTapes i) ((scanCfg w w.length (Mode.bit, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.bit, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.done, n)).inputPos (unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.done, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.done, n)).workTapes i) ((scanCfg w w.length (Mode.done, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.done, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.dead, n)).inputPos (unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.dead, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.dead, n)).workTapes i) ((scanCfg w w.length (Mode.dead, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.dead, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).workActions i).2 }.state = none w:List Booln:{ state := (unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.tree, n)).inputPos (unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.tree, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.tree, n)).workTapes i) ((scanCfg w w.length (Mode.tree, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.tree, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.string, n)).inputPos (unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.string, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.string, n)).workTapes i) ((scanCfg w w.length (Mode.string, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.string, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.bit, n)).inputPos (unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.bit, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.bit, n)).workTapes i) ((scanCfg w w.length (Mode.bit, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.bit, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.done, n)).inputPos (unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.done, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.done, n)).workTapes i) ((scanCfg w w.length (Mode.done, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.done, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).workActions i).2 }.state = nonew:List Booln:{ state := (unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).q', inputPos := moveInputPos (scanCfg w w.length (Mode.dead, n)).inputPos (unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).inputMove, workTapes := fun i match (motive := Option (Option (Fin 2)) Option (Fin 2)) ((unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).workActions i).1 with | none => (scanCfg w w.length (Mode.dead, n)).workTapes i | some s => Function.update ((scanCfg w w.length (Mode.dead, n)).workTapes i) ((scanCfg w w.length (Mode.dead, n)).workTapePos i) s, workTapePos := fun i (scanCfg w w.length (Mode.dead, n)).workTapePos i + ((unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).workActions i).2 }.state = none All goals completed! 🐙

The right end marker emits the decision of the pure scanner state.

theorem outputSymbol_scanCfg_end (w : List Bool) (s : State) : unaryScanner.outputSymbol (scanCfg w w.length (w:List Bools:Statew.length w.length All goals completed! 🐙) s) = some (boolEmb (decide (s.1 = .done))) := w:List Bools:StateoutputSymbol (scanCfg w w.length s) = some (boolEmb (decide (s.1 = Mode.done))) w:List Bools:State(match (scanCfg w w.length s).state with | none => none | some q => (unaryScanner.tr q (scanCfg w w.length s).inputSymbol (scanCfg w w.length s).workTapeSymbols).outS) = some (boolEmb (decide (s.1 = Mode.done))) w:List Bools:State(unaryScanner.tr (modeState s.1) (scanCfg w w.length s).inputSymbol (scanCfg w w.length s).workTapeSymbols).outS = some (boolEmb (decide (s.1 = Mode.done))) w:List Bools:State(unaryScanner.tr (modeState s.1) none (scanCfg w w.length s).workTapeSymbols).outS = some (boolEmb (decide (s.1 = Mode.done))) w:List Boolm:Moden:(unaryScanner.tr (modeState (m, n).1) none (scanCfg w w.length (m, n)).workTapeSymbols).outS = some (boolEmb (decide ((m, n).1 = Mode.done))) w:List Booln:(unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.tree, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.string, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.bit, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.done, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.dead, n).1 = Mode.done))) w:List Booln:(unaryScanner.tr (modeState (Mode.tree, n).1) none (scanCfg w w.length (Mode.tree, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.tree, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.string, n).1) none (scanCfg w w.length (Mode.string, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.string, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.bit, n).1) none (scanCfg w w.length (Mode.bit, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.bit, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.done, n).1) none (scanCfg w w.length (Mode.done, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.done, n).1 = Mode.done)))w:List Booln:(unaryScanner.tr (modeState (Mode.dead, n).1) none (scanCfg w w.length (Mode.dead, n)).workTapeSymbols).outS = some (boolEmb (decide ((Mode.dead, n).1 = Mode.done))) All goals completed! 🐙

Initialization takes two steps and emits nothing.

theorem init_run (w : List Bool) : unaryScanner.configs (unaryScanner.initCfg (w.map boolEmb)) 2 = scanCfg w 0 (w:List Bool0 w.length All goals completed! 🐙) (.tree, 1) unaryScanner.outputString (unaryScanner.initCfg (w.map boolEmb)) 2 = [] := w:List Boolconfigs (initCfg (List.map (⇑boolEmb) w)) 2 = scanCfg w 0 (Mode.tree, 1) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) 2 = [] w:List Boolconfigs (initCfg (List.map (⇑boolEmb) w)) 2 = scanCfg w 0 (Mode.tree, 1)w:List BoolunaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) 2 = [] w:List Boolconfigs (initCfg (List.map (⇑boolEmb) w)) 2 = scanCfg w 0 (Mode.tree, 1) w:List Boolconfigs (initCfg (List.map (⇑boolEmb) w)) (0 + 1 + 1) = scanCfg w 0 (Mode.tree, 1) All goals completed! 🐙 w:List BoolunaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) 2 = [] All goals completed! 🐙

At every prefix boundary the machine realizes the pure scanner without output.

theorem configs_scan (w : List Bool) : t, h : t w.length, unaryScanner.configs (unaryScanner.initCfg (w.map boolEmb)) (t + 2) = scanCfg w t h (scan (w.take t)) unaryScanner.outputString (unaryScanner.initCfg (w.map boolEmb)) (t + 2) = [] := w:List Bool (t : ) (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = [] w:List Bool (h : Nat.zero w.length), configs (initCfg (List.map (⇑boolEmb) w)) (Nat.zero + 2) = scanCfg w Nat.zero h (scan (List.take Nat.zero w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (Nat.zero + 2) = []w:List Bool (n : ), (∀ (h : n w.length), configs (initCfg (List.map (⇑boolEmb) w)) (n + 2) = scanCfg w n h (scan (List.take n w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (n + 2) = []) (h : n.succ w.length), configs (initCfg (List.map (⇑boolEmb) w)) (n.succ + 2) = scanCfg w n.succ h (scan (List.take n.succ w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (n.succ + 2) = [] w:List Bool (h : Nat.zero w.length), configs (initCfg (List.map (⇑boolEmb) w)) (Nat.zero + 2) = scanCfg w Nat.zero h (scan (List.take Nat.zero w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (Nat.zero + 2) = [] w:List Boolh:Nat.zero w.lengthconfigs (initCfg (List.map (⇑boolEmb) w)) (Nat.zero + 2) = scanCfg w Nat.zero h (scan (List.take Nat.zero w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (Nat.zero + 2) = [] All goals completed! 🐙 w:List Bool (n : ), (∀ (h : n w.length), configs (initCfg (List.map (⇑boolEmb) w)) (n + 2) = scanCfg w n h (scan (List.take n w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (n + 2) = []) (h : n.succ w.length), configs (initCfg (List.map (⇑boolEmb) w)) (n.succ + 2) = scanCfg w n.succ h (scan (List.take n.succ w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (n.succ + 2) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthconfigs (initCfg (List.map (⇑boolEmb) w)) (t.succ + 2) = scanCfg w t.succ h (scan (List.take t.succ w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t.succ + 2) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []configs (initCfg (List.map (⇑boolEmb) w)) (t.succ + 2) = scanCfg w t.succ h (scan (List.take t.succ w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t.succ + 2) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.lengthconfigs (initCfg (List.map (⇑boolEmb) w)) (t.succ + 2) = scanCfg w t.succ h (scan (List.take t.succ w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t.succ + 2) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.lengthconfigs (initCfg (List.map (⇑boolEmb) w)) (t + 2 + 1) = scanCfg w t.succ h (scan (List.take t.succ w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2 + 1) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.lengthconfigs (initCfg (List.map (⇑boolEmb) w)) (t + 2 + 1) = scanCfg w t.succ h (scan (List.take t.succ w))w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.lengthunaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2 + 1) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.lengthconfigs (initCfg (List.map (⇑boolEmb) w)) (t + 2 + 1) = scanCfg w t.succ h (scan (List.take t.succ w)) All goals completed! 🐙 w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.lengthunaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2 + 1) = [] w:List Boolt:ih: (h : t w.length), configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t h (scan (List.take t w)) unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []h:t.succ w.lengthhc:configs (initCfg (List.map (⇑boolEmb) w)) (t + 2) = scanCfg w t (scan (List.take t w))ho:unaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (t + 2) = []ht:t < w.length[] ++ none.toList = [] All goals completed! 🐙

The recognizer halts after one transition per bit and three fixed transitions.

theorem halts_at (w : List Bool) : (unaryScanner.configs (unaryScanner.initCfg (w.map boolEmb)) (w.length + 3)).state = none := w:List Bool(configs (initCfg (List.map (⇑boolEmb) w)) (w.length + 3)).state = none w:List Bool(MultiTapeTM.step (scanCfg w w.length (scan (List.take w.length w)))).state = none All goals completed! 🐙

The sole output is the scanner's decision bit.

theorem outputString_eq (w : List Bool) : unaryScanner.outputString (unaryScanner.initCfg (w.map boolEmb)) (w.length + 3) = [boolEmb (validBool w)] := w:List BoolunaryScanner.outputString (initCfg (List.map (⇑boolEmb) w)) (w.length + 3) = [boolEmb (validBool w)] w:List Bool[] ++ (some (boolEmb (decide ((scan (List.take w.length w)).1 = Mode.done)))).toList = [boolEmb (validBool w)] All goals completed! 🐙
end Geb.BitTree