Documentation

Complexitylib.Classes.Containments.Internal.SuccMachine

Assembling the successor check #

⚠️ Unreviewed by Bolton

Complexitylib.Classes.Containments.Internal.BlockScan proves what the scans decide, in terms of what the registers hold. Complexitylib.Models.TuringMachine.GuessAssembly proves what the guess machinery puts on a register. This file is where the two meet: a block of guesses written onto a register is a register the scans can read.

Main results #

Main definitions #

instance Complexity.instNonemptyNTMQ {kk : } (tm : NTM kk) :

A machine's state type is nonempty: it has a start state.

theorem Complexity.holdsBits_of_guessBlock {m : } (r : Fin (m + 1)) (hr : r Fin.last m) (n : ) (W : Fin (m + 1)Tape) (hinv : ∀ (i : Fin (m + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (m + 1)), 1 (W i).head) (hr1 : (W r).head = 1) (b : Bool) (hg : pn, (W (Fin.last m)).cells ((W (Fin.last m)).head + p) = Γ.ofBool (b p)) :
HoldsBits (fun (p : ) (i : Fin (m + 1)) => (TM.guessBlockTapes r n W i).cells p) 0 r (List.ofFn fun (q : Fin (n + 1)) => b q)

A block of guesses is a register the scans can read. Writing n + 1 guessed bits onto a register parked at cell one leaves it holding exactly those bits.

theorem Complexity.holdsBits_of_guessBlocks {m : } (j : Fin (m + 1)) (hj : ∀ (p : ), j p Fin.last m) (w : ) (t : ) (W : Fin (m + 1)Tape) (hinv : ∀ (i : Fin (m + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (m + 1)), 1 (W i).head) (hinj : ∀ (p q : ), p < tq < tj p = j qp = q) (hr1 : p < t, (W (j p)).head = 1) (b : Bool) (hg : p < t, qw p, (W (Fin.last m)).cells ((W (Fin.last m)).head + TM.guessOffset w p + q) = Γ.ofBool (b p q)) (p : ) :
p < tHoldsBits (fun (c : ) (i : Fin (m + 1)) => (TM.guessBlocksTapes j w t W i).cells c) 0 (j p) (List.ofFn fun (q : Fin (w p + 1)) => b p q)

Several blocks of guesses give several registers to read. Each target register, parked at cell one, ends up holding the bits guessed for its own block.

Which register holds which field #

structure Complexity.CodeRegs (kk jj : ) :

The layout of a configuration code across registers: one for the state, one for the input head, one per work window, and one for the output window.

  • st : Fin (jj + 1)

    The register holding the state.

  • hd : Fin (jj + 1)

    The register holding the input head.

  • wk : Fin kkFin (jj + 1)

    The registers holding the work windows.

  • ot : Fin (jj + 1)

    The register holding the output window.

Instances For
    def Complexity.HoldsCode {kk : } (tm : NTM kk) (x : List Bool) (S : ) {jj : } (cols : Fin (jj + 1)Γ) (off : ) (R : CodeRegs kk jj) (a : Code tm.Q kk x.length S) :

    Those registers hold the code a.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem Complexity.HoldsCode.state {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a : Code tm.Q kk x.length S} (h : HoldsCode tm x S cols off R a) :
      HoldsBits (fun (q : ) => cols (off + q)) 0 R.st ((qCodec tm.Q).enc a.1)
      theorem Complexity.HoldsCode.inputHead {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a : Code tm.Q kk x.length S} (h : HoldsCode tm x S cols off R a) :
      HoldsBits (fun (q : ) => cols (off + q)) 0 R.hd ((finCodec (x.length + S + 2)).enc a.2.1)
      theorem Complexity.HoldsCode.work {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a : Code tm.Q kk x.length S} (h : HoldsCode tm x S cols off R a) (i : Fin kk) :
      HoldsWindow (fun (q : ) => cols (off + q)) 0 (R.wk i) (a.2.2.1 i).1 (a.2.2.1 i).2
      theorem Complexity.HoldsCode.output {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a : Code tm.Q kk x.length S} (h : HoldsCode tm x S cols off R a) :
      HoldsWindow (fun (q : ) => cols (off + q)) 0 R.ot a.2.2.2.1 a.2.2.2.2

      Guessing a whole code #

      noncomputable def Complexity.codeWidthRaw {kk : } (tm : NTM kk) (nn S p : ) :

      The raw width of block p of a code: the state, the input head, the kk work windows, then the output window.

      Equations
      Instances For
        noncomputable def Complexity.codeWidth {kk : } (tm : NTM kk) (nn S p : ) :

        The block width a code guess passes to TM.guessBlocksTM, which writes n + 1 bits for a block of n. A field of width zero is guessed one bit wide and its (empty) contents read back off the prefix.

        Equations
        Instances For
          noncomputable def Complexity.codeBlock {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (p : ) :

          The bits block p of a code guess should hold.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            @[simp]
            theorem Complexity.codeBlock_st {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) :
            codeBlock tm x S a 0 = (qCodec tm.Q).enc a.1
            @[simp]
            theorem Complexity.codeBlock_hd {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) :
            codeBlock tm x S a 1 = (finCodec (x.length + S + 2)).enc a.2.1
            @[simp]
            theorem Complexity.codeBlock_wk {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (i : Fin kk) :
            codeBlock tm x S a (i + 2) = (tapeCodec (S + 1)).enc (a.2.2.1 i)
            @[simp]
            theorem Complexity.codeBlock_ot {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) :
            codeBlock tm x S a (kk + 2) = (tapeCodec (S + 2)).enc a.2.2.2
            theorem Complexity.codeBlock_length {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (p : ) :
            (codeBlock tm x S a p).length = codeWidthRaw tm x.length S p
            def Complexity.codeRegsOf {kk jj : } (j : Fin (jj + 1)) :
            CodeRegs kk jj

            The registers a code guess writes to: one block each, in the order of codeBlock.

            Equations
            Instances For

              The registers determine the code #

              theorem Complexity.HoldsWindow.inj {m : } [NeZero m] {jj : } {cols : Fin (jj + 1)Γ} {off : } {r : Fin (jj + 1)} {hd hd' : Fin m} {cl cl' : Fin mΓ} (h : HoldsWindow cols off r hd cl) (h' : HoldsWindow cols off r hd' cl') :
              (hd, cl) = (hd', cl')

              A register holding an encoded window determines the window.

              theorem Complexity.HoldsCode.inj {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a b : Code tm.Q kk x.length S} (ha : HoldsCode tm x S cols off R a) (hb : HoldsCode tm x S cols off R b) :
              a = b

              The registers determine the code. The same registers cannot hold two different codes, so comparing registers compares codes — which is what the walk's "stay" step and the final comparison need.

              theorem Complexity.HoldsWindow.bits {m : } [NeZero m] {jj : } {cols : Fin (jj + 1)Γ} {off : } {r : Fin (jj + 1)} {hd : Fin m} {cl : Fin mΓ} (h : HoldsWindow cols off r hd cl) :
              HoldsBits cols off r ((tapeCodec m).enc (hd, cl))

              A register holding an encoded window holds the corresponding bits.

              theorem Complexity.HoldsWindow.of_bits {m : } [NeZero m] {jj : } {cols : Fin (jj + 1)Γ} {off : } {r : Fin (jj + 1)} {hd : Fin m} {cl : Fin mΓ} (h : HoldsBits cols off r ((tapeCodec m).enc (hd, cl))) :
              HoldsWindow cols off r hd cl

              A register holding an encoded window holds that window.

              theorem Complexity.holdsCode_of_blocks {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (j : Fin (jj + 1)) (a : Code tm.Q kk x.length S) (h : p < kk + 3, HoldsBits (fun (q : ) => cols (0 + q)) 0 (j p) (codeBlock tm x S a p)) :
              HoldsCode tm x S cols 0 (codeRegsOf j) a

              Blocks on the right registers are a code.

              theorem Complexity.holdsCode_of_guessBlocks {kk : } (tm : NTM kk) (x : List Bool) (S : ) {m : } (j : Fin (m + 1)) (hj : ∀ (p : ), j p Fin.last m) (W : Fin (m + 1)Tape) (hinv : ∀ (i : Fin (m + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (m + 1)), 1 (W i).head) (hinj : ∀ (p q : ), p < kk + 3q < kk + 3j p = j qp = q) (hr1 : p < kk + 3, (W (j p)).head = 1) (a : Code tm.Q kk x.length S) (hg : p < kk + 3, qcodeWidth tm x.length S p, (W (Fin.last m)).cells ((W (Fin.last m)).head + TM.guessOffset (codeWidth tm x.length S) p + q) = Γ.ofBool ((codeBlock tm x S a p).getD q false)) :
              HoldsCode tm x S (fun (c : ) (i : Fin (m + 1)) => (TM.guessBlocksTapes j (codeWidth tm x.length S) (kk + 3) W i).cells c) 0 (codeRegsOf j) a

              A guess stage can lay down any code. Given a guess tape whose bits, block by block, are the code's own encoding, the kk + 3 guessed registers hold that code. Together with Complexity.NTM.exists_loadTape this is how a nondeterministic step is taken: guess a code, then check it.

              theorem Complexity.holdsCode_of_stage {kk : } (tm : NTM kk) (x : List Bool) (S : ) {m : } (j : Fin (m + 1)) (hj : ∀ (p : ), j p Fin.last m) (W : Fin (m + 1)Tape) (hinv : ∀ (i : Fin (m + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (m + 1)), 1 (W i).head) (hinj : ∀ (p q : ), p < kk + 3q < kk + 3j p = j qp = q) (hr1 : p < kk + 3, (W (j p)).head = 1) (b : Bool) (g : Bool) (hs : TM.StageBlocks (codeWidth tm x.length S) (kk + 3) b g) (s : ) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (codeWidth tm x.length S) (kk + 3) + q)) (W (Fin.last m))) (a : Code tm.Q kk x.length S) (hb : p < kk + 3, qcodeWidth tm x.length S p, b s p q = (codeBlock tm x S a p).getD q false) :
              HoldsCode tm x S (fun (c : ) (i : Fin (m + 1)) => (TM.guessBlocksTapes j (codeWidth tm x.length S) (kk + 3) W i).cells c) 0 (codeRegsOf j) a

              A stage of the loop lays down the code its stream names. The guess-tape clause of the walk's invariant feeds exactly this.

              theorem Complexity.HoldsCode.of_cells_eq {kk jj : } {tm : NTM kk} {x : List Bool} {S : } {cols cols' : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a : Code tm.Q kk x.length S} (h : HoldsCode tm x S cols off R a) (hc : ∀ (q : ) (i : Fin (jj + 1)), cols' q i = cols q i) :
              HoldsCode tm x S cols' off R a

              Holding a code depends only on the registers' cells, not on their heads — which is why a rewind between the guess and the checks is harmless.

              theorem Complexity.holdsCode_of_guessStage {kk : } (tm : NTM kk) (x : List Bool) (S : ) {m : } (j : Fin (m + 1)) (hj : ∀ (p : ), j p Fin.last m) (W : Fin (m + 1)Tape) (hinv : ∀ (i : Fin (m + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (m + 1)), 1 (W i).head) (hinj : ∀ (p q : ), p < kk + 3q < kk + 3j p = j qp = q) (hr1 : p < kk + 3, (W (j p)).head = 1) (a : Code tm.Q kk x.length S) (hg : p < kk + 3, qcodeWidth tm x.length S p, (W (Fin.last m)).cells ((W (Fin.last m)).head + TM.guessOffset (codeWidth tm x.length S) p + q) = Γ.ofBool ((codeBlock tm x S a p).getD q false)) (work : Fin (m + 1)Tape) (hcells : ∀ (i : Fin (m + 1)), (work i).cells = (TM.guessBlocksTapes j (codeWidth tm x.length S) (kk + 3) W i).cells) :
              HoldsCode tm x S (fun (c : ) (i : Fin (m + 1)) => (work i).cells c) 0 (codeRegsOf j) a

              After a code-guessing stage the registers hold the code. The stage rewinds the guessed registers so the scans can read them; the rewind moves heads, and a code is held in cells.

              The layout the walk's scan reads #

              A check reads the guessed transition from the first cells of the parameter register, and the fields it checks from the cells after that. So every register except the state's — whose check reads it alongside the parameters — carries a block of padding as wide as the parameter block, and its field begins where the padding ends.

              noncomputable def Complexity.codeBlockScan {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (p : ) :

              The bits block p of a code guess holds in the walk's layout.

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                noncomputable def Complexity.codeWidthScan {kk : } (tm : NTM kk) (nn S p : ) :

                The block widths that layout guesses.

                Equations
                Instances For
                  def Complexity.HoldsCodeScan {kk : } (tm : NTM kk) (x : List Bool) (S : ) {jj : } (cols : Fin (jj + 1)Γ) (R : CodeRegs kk jj) (a : Code tm.Q kk x.length S) :

                  The registers hold code a where the walk's scan looks for it.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    theorem Complexity.markOf_end {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (p m : ) (hp : p 0) (hlen : (codeBlock tm x S a p).length = 3 * m) (cols : Fin (jj + 1)Γ) (r : Fin (jj + 1)) (h : HoldsBits cols 0 r (codeBlockScan tm x S a p)) :
                    markOf cols (succParamsCodec tm.Q kk).width r m = false

                    The block ends with a cell carrying no head marker. The window checks need to know that the chunk just past the window is unmarked; rather than reason about untouched tape, the guess writes one more zero and the check reads it.

                    theorem Complexity.holdsCodeScan_of_blocks {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (j : Fin (jj + 1)) (a : Code tm.Q kk x.length S) (h : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) :
                    HoldsCodeScan tm x S cols (codeRegsOf j) a

                    Blocks in the walk's layout are a code the scan can read.

                    What each scan says about the code the registers hold #

                    theorem Complexity.ofTable_state {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {R : CodeRegs kk jj} {a : Code tm.Q kk x.length S} (h : HoldsCode tm x S cols off R a) (s w : ) (regs : Fin sFin (jj + 1)) (t : Fin s) (ht : regs t = R.st) (hc : (qCodec tm.Q).width w) (x₀ : Fin sFin wBool) :
                    (qCodec tm.Q).ofTable (tableSlice (Scanner.auxRun (0, , x₀) (Scanner.bitsStep s w regs) (fun (q : ) => cols (off + q)) w).2 t (qCodec tm.Q).width hc) = a.1

                    The state a scan reads off a code's state register.

                    theorem Complexity.blockEmit_work {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {Ra Rb : CodeRegs kk jj} {a b : Code tm.Q kk x.length S} (ha : HoldsCode tm x S cols off Ra a) (hb : HoldsCode tm x S cols off Rb b) (P : SuccParams tm.Q kk) (i : Fin kk) (hend : markOf (fun (q : ) => cols (off + q)) 0 (Ra.wk i) (S + 1) = false) :
                    blockEmit (succDir tm P i) (Scanner.chunkRun (blockStep (Ra.wk i) (Rb.wk i) (gammaBits (P.wSym i)) (gammaBits (succWrite tm P i)) (succDir tm P i)) (fun (q : ) => cols (off + q)) 0 blockStart (S + 1)) = true (a.2.2.1 i).2 (a.2.2.1 i).1 = P.wSym i (∀ (p : Fin (S + 1)), (b.2.2.1 i).2 p = if p = (a.2.2.1 i).1 0 < p then succWrite tm P i else (a.2.2.1 i).2 p) (b.2.2.1 i).1 = movedIdx (succDir tm P i) (a.2.2.1 i).1

                    What the work-window scan says.

                    theorem Complexity.blockEmit_output {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {Ra Rb : CodeRegs kk jj} {a b : Code tm.Q kk x.length S} (ha : HoldsCode tm x S cols off Ra a) (hb : HoldsCode tm x S cols off Rb b) (P : SuccParams tm.Q kk) (hend : markOf (fun (q : ) => cols (off + q)) 0 Ra.ot (S + 2) = false) :
                    blockEmit (succTrans tm P).2.2.2.2.2 (Scanner.chunkRun (blockStep Ra.ot Rb.ot (gammaBits P.oSym) (gammaBits (succTrans tm P).2.2.1.toΓ) (succTrans tm P).2.2.2.2.2) (fun (q : ) => cols (off + q)) 0 blockStart (S + 2)) = true a.2.2.2.2 a.2.2.2.1 = P.oSym (∀ (p : Fin (S + 2)), b.2.2.2.2 p = if p = a.2.2.2.1 0 < p then (succTrans tm P).2.2.1.toΓ else a.2.2.2.2 p) b.2.2.2.1 = movedIdx (succTrans tm P).2.2.2.2.2 a.2.2.2.1

                    What the output-window scan says.

                    theorem Complexity.inHeadEmit_code {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {Ra Rb : CodeRegs kk jj} {a b : Code tm.Q kk x.length S} (ha : HoldsCode tm x S cols off Ra a) (hb : HoldsCode tm x S cols off Rb b) (d : Dir3) (hleft : d = Dir3.left0 < a.2.1) :
                    inHeadEmit d (Scanner.cellFold (inHeadStep Ra.hd Rb.hd d) cols off (true, true) (bitWidth (x.length + S + 2))) = true b.2.1 = movedIdx d a.2.1

                    What the input-head scan says.

                    theorem Complexity.mem_codeSucc_of_scans {kk : } {tm : NTM kk} {x : List Bool} {S jj : } {cols : Fin (jj + 1)Γ} {off : } {Ra Rb : CodeRegs kk jj} {a b : Code tm.Q kk x.length S} (ha : HoldsCode tm x S cols off Ra a) (hb : HoldsCode tm x S cols off Rb b) (P : SuccParams tm.Q kk) (hne : a.1 tm.qhalt) (hq : a.1 = P.q) (hstate : b.1 = succState tm P) (hin : P.inSym = inSymOf tm x S a) (hclampIn : movedIdx (succTrans tm P).2.2.2.1 a.2.1 x.length + S + 1) (hclampW : ∀ (i : Fin kk), movedIdx (succDir tm P i) (a.2.2.1 i).1 S) (hclampO : movedIdx (succTrans tm P).2.2.2.2.2 a.2.2.2.1 S + 1) (hleft : (succTrans tm P).2.2.2.1 = Dir3.left0 < a.2.1) (hendW : ∀ (i : Fin kk), markOf (fun (q : ) => cols (off + q)) 0 (Ra.wk i) (S + 1) = false) (hendO : markOf (fun (q : ) => cols (off + q)) 0 Ra.ot (S + 2) = false) (vhead : inHeadEmit (succTrans tm P).2.2.2.1 (Scanner.cellFold (inHeadStep Ra.hd Rb.hd (succTrans tm P).2.2.2.1) cols off (true, true) (bitWidth (x.length + S + 2))) = true) (vwork : ∀ (i : Fin kk), blockEmit (succDir tm P i) (Scanner.chunkRun (blockStep (Ra.wk i) (Rb.wk i) (gammaBits (P.wSym i)) (gammaBits (succWrite tm P i)) (succDir tm P i)) (fun (q : ) => cols (off + q)) 0 blockStart (S + 1)) = true) (vout : blockEmit (succTrans tm P).2.2.2.2.2 (Scanner.chunkRun (blockStep Ra.ot Rb.ot (gammaBits P.oSym) (gammaBits (succTrans tm P).2.2.1.toΓ) (succTrans tm P).2.2.2.2.2) (fun (q : ) => cols (off + q)) 0 blockStart (S + 2)) = true) :
                    b tm.codeSucc x S a

                    The successor check, assembled. Every scan verdict says what its field must, and together they say the guessed code is a successor of the held one.

                    What the loops establish #

                    The walk and the counting are stated here in the form the loops produce them: a walk as a sequence of codes each either kept or stepped, and a round list as an injective enumeration.

                    theorem Complexity.mem_reachCodes_of_walk {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a₀ : Code tm.Q kk x.length S) (i : ) (f : Code tm.Q kk x.length S) (h0 : f 0 = a₀) (hstep : j < i, f (j + 1) = f j f (j + 1) tm.codeSucc x S (f j)) :
                    f i tm.reachCodes x S a₀ i

                    What a walk establishes. A sequence of codes, each either equal to its predecessor or a verified successor of it, lands in the round its length names.

                    theorem Complexity.roundList_of_inj {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a₀ : Code tm.Q kk x.length S) (i N : ) (g : Fin NCode tm.Q kk x.length S) (hinj : Function.Injective g) (hmem : ∀ (t : Fin N), g t tm.reachCodes x S a₀ i) (hcard : (tm.reachCodes x S a₀ i).card N) :
                    tm.RoundList x S a₀ i (List.ofFn g)

                    What the counting establishes. Codes enumerated without repetition, each verified to be in the round, and at least as many of them as the round holds, form a round list — which is what licenses concluding that a code not among them is not in the round.

                    The shape of a loop invariant #

                    TM.loopTM_hoareTime_indexed asks for a family of tape predicates E j, a step from E j to E (j + 1), and a stop at E N. For the walk, E j says the counter holds j and the code registers hold the j-th code of the walk — so the loop's own index is the walk's index.

                    def Complexity.counterVal {jj : } (cnt : Fin (jj + 1)) (wc : ) (work : Fin (jj + 1)Tape) :

                    The reading of a counter register as a number.

                    Equations
                    Instances For
                      def Complexity.HoldsCounter {jj : } (cnt : Fin (jj + 1)) (wc v : ) :
                      TM.TapePred (jj + 1)

                      A tape predicate pinning a counter register to a value. The bound v < 2 ^ wc is part of it: past that point a fixed-width counter wraps, and a loop rule needs the counter to name its index.

                      Equations
                      Instances For
                        def Complexity.WalkInv {kk : } (tm : NTM kk) (x : List Bool) (S : ) {jj : } (R : CodeRegs kk jj) (cnt : Fin (jj + 1)) (wc : ) (f : Code tm.Q kk x.length S) (j : ) :
                        TM.TapePred (jj + 1)

                        The walk loop's invariant. The bound j < 2 ^ wc is part of it: past that point the counter would wrap, and the loop rule needs the counter to name the index.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          theorem Complexity.counterVal_of_walkInv {kk : } (tm : NTM kk) (x : List Bool) (S : ) {jj : } (R : CodeRegs kk jj) (cnt : Fin (jj + 1)) (wc : ) (f : Code tm.Q kk x.length S) (j : ) (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape) (h : WalkInv tm x S R cnt wc f j inp work out) :
                          counterVal cnt wc work = j

                          The counter reads back the index. This is the idx obligation of the indexed loop rule: a tape predicate that pins the counter determines the loop's index.

                          The scanner that checks one window #

                          Three tapes are scanned: the parameter block, the old window, the new window; the verdict goes to a fourth. The parameters come first, so by the time the windows are reached the transition is known.

                          @[reducible, inline]

                          The state of a window check: a chunk position, two buffered columns, and the four running checks.

                          Equations
                          Instances For
                            @[instance_reducible]

                            Equality of window states is decidable; the machine need not be computable.

                            Equations
                            @[reducible, inline]
                            abbrev Complexity.ParamAcc {kk : } (tm : NTM kk) :

                            The state a parameter reader accumulates: how many cells it has read, and the bits.

                            Equations
                            Instances For
                              noncomputable def Complexity.paramsOfTable {kk : } (tm : NTM kk) (a : ParamAcc tm) :

                              The parameters a window check has read.

                              Equations
                              Instances For
                                noncomputable def Complexity.windowScanner {kk : } (tm : NTM kk) (i : Fin kk) :

                                The window checker.

                                Equations
                                • One or more equations did not get rendered due to their size.
                                Instances For
                                  noncomputable def Complexity.windowParams {kk : } (tm : NTM kk) (cols : Fin 3Γ) :

                                  The parameters a window scan reads off the tapes it is given.

                                  Equations
                                  • One or more equations did not get rendered due to their size.
                                  Instances For
                                    theorem Complexity.windowScanner_run {kk : } (tm : NTM kk) (i : Fin kk) (cols : Fin 3Γ) (S : ) :
                                    (windowScanner tm i).emit ((windowScanner tm i).run cols ((succParamsCodec tm.Q kk).width + 3 * (S + 1))) = blockEmit (succDir tm (windowParams tm cols) i) (Scanner.chunkRun (blockStep 1 2 (gammaBits ((windowParams tm cols).wSym i)) (gammaBits (succWrite tm (windowParams tm cols) i)) (succDir tm (windowParams tm cols) i)) cols (succParamsCodec tm.Q kk).width blockStart (S + 1))

                                    What the window checker computes: the block check, with the parameters it read.

                                    noncomputable def Complexity.outputScanner {kk : } (tm : NTM kk) :

                                    The output-window checker. The same scanner as for a work tape, with the transition's output write and direction.

                                    Equations
                                    • One or more equations did not get rendered due to their size.
                                    Instances For
                                      theorem Complexity.outputScanner_run {kk : } (tm : NTM kk) (cols : Fin 3Γ) (S : ) :
                                      (outputScanner tm).emit ((outputScanner tm).run cols ((succParamsCodec tm.Q kk).width + 3 * (S + 2))) = blockEmit (succTrans tm (windowParams tm cols)).2.2.2.2.2 (Scanner.chunkRun (blockStep 1 2 (gammaBits (windowParams tm cols).oSym) (gammaBits (succTrans tm (windowParams tm cols)).2.2.1.toΓ) (succTrans tm (windowParams tm cols)).2.2.2.2.2) cols (succParamsCodec tm.Q kk).width blockStart (S + 2))

                                      What the output checker computes.

                                      noncomputable def Complexity.headScanner {kk : } (tm : NTM kk) :

                                      The input-head checker. Two tapes are scanned: the parameter block and, after it, the two input-head registers — the direction is known by the time they are reached.

                                      Equations
                                      • One or more equations did not get rendered due to their size.
                                      Instances For
                                        theorem Complexity.headScanner_run {kk : } (tm : NTM kk) (cols : Fin 3Γ) (w : ) :
                                        (headScanner tm).emit ((headScanner tm).run cols ((succParamsCodec tm.Q kk).width + w)) = inHeadEmit (succTrans tm (windowParams tm cols)).2.2.2.1 (Scanner.cellFold (inHeadStep 1 2 (succTrans tm (windowParams tm cols)).2.2.2.1) cols (succParamsCodec tm.Q kk).width (true, true) w)

                                        What the input-head checker computes.

                                        The state checks #

                                        Unlike the window and head checks, these read both registers during the parameter phase — a state field is a constant number of cells — so the check lives entirely in the accumulated table and the per-cell state is trivial.

                                        noncomputable def Complexity.stateWidth {kk : } (tm : NTM kk) :

                                        The width a state check scans: enough for the parameter block and for a state field.

                                        Equations
                                        Instances For
                                          @[reducible, inline]
                                          abbrev Complexity.StateAcc {kk : } (tm : NTM kk) :

                                          What a state check has accumulated.

                                          Equations
                                          Instances For
                                            noncomputable def Complexity.stateOfTable {kk : } (tm : NTM kk) (a : StateAcc tm) :
                                            tm.Q

                                            The state a state check has read off the code's register.

                                            Equations
                                            Instances For
                                              noncomputable def Complexity.paramsOfStateTable {kk : } (tm : NTM kk) (a : StateAcc tm) :

                                              The parameters a state check has read.

                                              Equations
                                              Instances For
                                                noncomputable def Complexity.stateScanner {kk : } (tm : NTM kk) (isNew : Bool) :

                                                The state checker. With isNew = false it checks the old code's state against the guessed one; with isNew = true, the new code's state against the one the transition produces.

                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For
                                                  noncomputable def Complexity.stateTable {kk : } (tm : NTM kk) (cols : Fin 2Γ) :

                                                  The table a state check accumulates from given tapes.

                                                  Equations
                                                  • One or more equations did not get rendered due to their size.
                                                  Instances For
                                                    theorem Complexity.stateWidth_pos {kk : } (tm : NTM kk) :
                                                    theorem Complexity.stateScanner_run {kk : } (tm : NTM kk) (isNew : Bool) (cols : Fin 2Γ) :
                                                    (stateScanner tm isNew).emit ((stateScanner tm isNew).run cols (stateWidth tm)) = decide (stateOfTable tm (stateTable tm cols) = if isNew = true then succState tm (paramsOfStateTable tm (stateTable tm cols)) else (paramsOfStateTable tm (stateTable tm cols)).q)

                                                    What a state checker computes.

                                                    When the simulated input head is at the marker #

                                                    A machine cannot keep its own input head on cell zero: reading forces that head right on every step. But it need not — a simulated head at cell zero reads , which the code's own head field already says. So the input symbol is checked against the tape only when the head field is nonzero; when it is zero the check is on the parameter register alone.

                                                    noncomputable def Complexity.headZeroScanner {kk jj : } (tm : NTM kk) (nn S : ) (hd : Fin (jj + 1)) :

                                                    The scan that decides whether a code's input-head field is zero: every bit of the field is a zero.

                                                    Equations
                                                    • One or more equations did not get rendered due to their size.
                                                    Instances For

                                                      A string of zeros has value zero.

                                                      theorem Complexity.bitsOfLenLE_all_false_iff (v : ) (hv : v < 2 ^ ) :
                                                      (∀ (q : ) (hq : q < ), (bitsOfLenLE v)[q] = false) v = 0

                                                      A fixed-width encoding is all zeros exactly when it encodes zero.

                                                      theorem Complexity.headZeroScanner_decides {kk jj : } (tm : NTM kk) (nn S : ) (hd : Fin (jj + 1)) (cols : Fin (jj + 1)Γ) (len : ) (hlen : (succParamsCodec tm.Q kk).width + (finCodec (nn + S + 2)).width len) (u : Fin (nn + S + 2)) (hu : HoldsBits cols (succParamsCodec tm.Q kk).width hd ((finCodec (nn + S + 2)).enc u)) :
                                                      (headZeroScanner tm nn S hd).emit ((headZeroScanner tm nn S hd).run cols len) = true u = 0

                                                      The zero-head scan decides that the code's input head is at the marker.

                                                      noncomputable def Complexity.headNonZeroScanner {kk jj : } (tm : NTM kk) (nn S : ) (hd : Fin (jj + 1)) :

                                                      The scan that decides a code's input-head field is not zero.

                                                      Equations
                                                      • One or more equations did not get rendered due to their size.
                                                      Instances For
                                                        theorem Complexity.headNonZeroScanner_decides {kk jj : } (tm : NTM kk) (nn S : ) (hd : Fin (jj + 1)) (cols : Fin (jj + 1)Γ) (len : ) (hlen : (succParamsCodec tm.Q kk).width + (finCodec (nn + S + 2)).width len) (u : Fin (nn + S + 2)) (hu : HoldsBits cols (succParamsCodec tm.Q kk).width hd ((finCodec (nn + S + 2)).enc u)) :
                                                        (headNonZeroScanner tm nn S hd).emit ((headNonZeroScanner tm nn S hd).run cols len) = true u 0

                                                        The nonzero-head scan decides that the code's input head is off the marker.

                                                        The direction the input head takes #

                                                        TM.inMoveTM reads the direction to move the input head from a single cell, because a direction fits in one writable symbol. That cell is guessed, so a check has to pin it against the guessed transition — and unlike every other check this one reads a raw symbol rather than a bit.

                                                        @[reducible, inline]
                                                        abbrev Complexity.DirAcc {kk : } (tm : NTM kk) :

                                                        What a direction check accumulates: the parameters, and the symbol it saw on the direction register's first cell.

                                                        Equations
                                                        Instances For
                                                          noncomputable def Complexity.dirRead {kk : } (tm : NTM kk) (a : DirAcc tm) (col : Fin 2Γ) :

                                                          The direction check's reader: read the parameter block, and capture the direction register's first cell as it goes past.

                                                          Equations
                                                          Instances For
                                                            noncomputable def Complexity.dirScanner {kk : } (tm : NTM kk) (enc : Dir3Γ) :

                                                            The direction checker. It accepts when the direction register's first cell names the way the guessed transition moves the input head.

                                                            Equations
                                                            • One or more equations did not get rendered due to their size.
                                                            Instances For
                                                              theorem Complexity.dirRead_fst {kk : } (tm : NTM kk) (cols : Fin 2Γ) (g₀ : Γ) (x₀ : Fin 1Fin (succParamsCodec tm.Q kk).widthBool) (p : ) :
                                                              (Scanner.auxRun ((0, , x₀), g₀) (dirRead tm) cols p).1 = Scanner.auxRun (0, , x₀) (Scanner.bitsStep 1 (succParamsCodec tm.Q kk).width fun (x : Fin 1) => 0) cols p

                                                              The reader's parameter half is the ordinary parameter reader.

                                                              theorem Complexity.dirRead_snd {kk : } (tm : NTM kk) (cols : Fin 2Γ) (g₀ : Γ) (x₀ : Fin 1Fin (succParamsCodec tm.Q kk).widthBool) (p : ) :
                                                              1 p(Scanner.auxRun ((0, , x₀), g₀) (dirRead tm) cols p).2 = cols 1 1 (Scanner.auxRun ((0, , x₀), g₀) (dirRead tm) cols p).1.1 0

                                                              The reader's captured half is the direction register's first cell, and its counter has left zero behind — so nothing later overwrites the capture.

                                                              noncomputable def Complexity.dirParams {kk : } (tm : NTM kk) (cols : Fin 2Γ) :

                                                              The parameters a direction check reads.

                                                              Equations
                                                              • One or more equations did not get rendered due to their size.
                                                              Instances For
                                                                theorem Complexity.dirScanner_run {kk : } (tm : NTM kk) (enc : Dir3Γ) (cols : Fin 2Γ) :
                                                                (dirScanner tm enc).emit ((dirScanner tm enc).run cols (succParamsCodec tm.Q kk).width) = decide (cols 1 1 = enc (succTrans tm (dirParams tm cols)).2.2.2.1)

                                                                What the direction checker computes.

                                                                theorem Complexity.dirScanner_decides {kk : } (tm : NTM kk) (enc : Dir3Γ) (cols : Fin 2Γ) (P : SuccParams tm.Q kk) (hpar : HoldsBits cols 0 0 ((succParamsCodec tm.Q kk).enc P)) :
                                                                (dirScanner tm enc).emit ((dirScanner tm enc).run cols (succParamsCodec tm.Q kk).width) = true cols 1 1 = enc (succTrans tm P).2.2.2.1

                                                                The direction checker decides that the guessed direction is the one the transition takes.

                                                                The symbol under the input head #

                                                                Of every field of a guessed transition, this is the one no scan can check: it has to agree with the machine's own input tape. So it is laid out first in the parameter block, where TM.inMatchTM reads it.

                                                                theorem Complexity.inSym_cells {kk : } (tm : NTM kk) {jj : } (cols : Fin (jj + 1)Γ) (par : Fin (jj + 1)) (P : SuccParams tm.Q kk) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) :
                                                                cols 1 par = Γ.ofBool (gammaBits P.inSym).1 cols 2 par = Γ.ofBool (gammaBits P.inSym).2

                                                                The parameter register opens with the guessed input symbol.

                                                                theorem Complexity.inMatchVerdict_of_inSym {kk : } (tm : NTM kk) {jj : } (cols : Fin (jj + 1)Γ) (par : Fin (jj + 1)) (P : SuccParams tm.Q kk) (g : Γ) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (hin : P.inSym = g) :
                                                                TM.inMatchVerdict gammaBits g (cols 1 par) (cols 2 par) = true

                                                                The input check passes when the guess is right. The converse of Complexity.inSym_eq_of_inMatch: this is what the completeness direction needs, since the certificate names the symbol the simulated head is really over.

                                                                theorem Complexity.inSym_eq_of_inMatch {kk : } (tm : NTM kk) {jj : } (cols : Fin (jj + 1)Γ) (par : Fin (jj + 1)) (P : SuccParams tm.Q kk) (g : Γ) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (hv : TM.inMatchVerdict gammaBits g (cols 1 par) (cols 2 par) = true) :
                                                                P.inSym = g

                                                                The input check pins the guessed input symbol. When the machine's own input head sits where the simulated one does, the verdict of TM.inMatchTM on the parameter register says exactly that the guess was right.

                                                                theorem Complexity.parStart_iff {kk jj : } (tm : NTM kk) (cols : Fin (jj + 1)Γ) (par : Fin (jj + 1)) (P : SuccParams tm.Q kk) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) :
                                                                (∀ (q : ), 1 qq 2cols q par = Γ.one) P.inSym = Γ.start

                                                                The parameter register opens with two ones exactly when the guessed symbol is the marker.

                                                                What each scanner decides #

                                                                theorem Complexity.windowScanner_decides {kk : } (tm : NTM kk) (i : Fin kk) (cols : Fin 3Γ) (S : ) (hd hd' : Fin (S + 1)) (cl cl' : Fin (S + 1)Γ) (ha : HoldsWindow cols (succParamsCodec tm.Q kk).width 1 hd cl) (hb : HoldsWindow cols (succParamsCodec tm.Q kk).width 2 hd' cl') (hend : markOf cols (succParamsCodec tm.Q kk).width 1 (S + 1) = false) :
                                                                (windowScanner tm i).emit ((windowScanner tm i).run cols ((succParamsCodec tm.Q kk).width + 3 * (S + 1))) = true cl hd = (windowParams tm cols).wSym i (∀ (p : Fin (S + 1)), cl' p = if p = hd 0 < p then succWrite tm (windowParams tm cols) i else cl p) hd' = movedIdx (succDir tm (windowParams tm cols) i) hd

                                                                The window checker decides the window condition.

                                                                theorem Complexity.outputScanner_decides {kk : } (tm : NTM kk) (cols : Fin 3Γ) (S : ) (hd hd' : Fin (S + 2)) (cl cl' : Fin (S + 2)Γ) (ha : HoldsWindow cols (succParamsCodec tm.Q kk).width 1 hd cl) (hb : HoldsWindow cols (succParamsCodec tm.Q kk).width 2 hd' cl') (hend : markOf cols (succParamsCodec tm.Q kk).width 1 (S + 2) = false) :
                                                                (outputScanner tm).emit ((outputScanner tm).run cols ((succParamsCodec tm.Q kk).width + 3 * (S + 2))) = true cl hd = (windowParams tm cols).oSym (∀ (p : Fin (S + 2)), cl' p = if p = hd 0 < p then (succTrans tm (windowParams tm cols)).2.2.1.toΓ else cl p) hd' = movedIdx (succTrans tm (windowParams tm cols)).2.2.2.2.2 hd

                                                                The output checker decides the output-window condition.

                                                                theorem Complexity.headScanner_decides {kk : } (tm : NTM kk) (cols : Fin 3Γ) (w u v : ) (hu : u < 2 ^ w) (hv : v < 2 ^ w) (ha : HoldsBits (fun (t : ) => cols ((succParamsCodec tm.Q kk).width + t)) 0 1 (bitsOfLenLE w u)) (hb : HoldsBits (fun (t : ) => cols ((succParamsCodec tm.Q kk).width + t)) 0 2 (bitsOfLenLE w v)) (hleft : (succTrans tm (windowParams tm cols)).2.2.2.1 = Dir3.left0 < u) :
                                                                (headScanner tm).emit ((headScanner tm).run cols ((succParamsCodec tm.Q kk).width + w)) = true v = movedIdx (succTrans tm (windowParams tm cols)).2.2.2.1 u

                                                                The input-head checker decides the input-head condition.

                                                                theorem Complexity.stateScanner_decides {kk : } (tm : NTM kk) (isNew : Bool) (cols : Fin 2Γ) (q : tm.Q) (h : HoldsBits cols 0 1 ((qCodec tm.Q).enc q)) :
                                                                (stateScanner tm isNew).emit ((stateScanner tm isNew).run cols (stateWidth tm)) = true q = if isNew = true then succState tm (paramsOfStateTable tm (stateTable tm cols)) else (paramsOfStateTable tm (stateTable tm cols)).q

                                                                The state checker decides the state condition.

                                                                The checks as machines #

                                                                Each check is TM.checkTM of its scanner: the scanner names the columns it reads, so the checked registers need not be adjacent and no check needs a private copy of them. The checks never consult the guess tape — they are built on the register tapes alone, and the guess tape is added once, at the very end, by TM.liftLast, which is where their TM.GuessProtocol comes from. Only the stages that write guesses carry advancing states.

                                                                Complexity.windowScanner_decides and its siblings are stated about the three columns a check reads, which is exactly the restriction TM.checkTM_hoareTime leaves in its postcondition, so they apply to a full-width check unchanged.

                                                                Combining the verdicts #

                                                                One scan over every tape, looking only at the result registers' first cells. No placement, so the registers need not be adjacent.

                                                                noncomputable def Complexity.combineTM (N : ) (P : Fin (N + 1)Bool) :
                                                                TM (N + 2)

                                                                The machine that combines the verdicts.

                                                                Equations
                                                                Instances For
                                                                  theorem Complexity.combineTM_hoareTime (N : ) (P : Fin (N + 1)Bool) (cells : Fin (N + 1)Γ) (len : ) (inp₀ out₀ res₀ : Tape) (hok : TM.ScanOk inp₀ res₀ out₀) (ht : TM.ScanTape cells len) :
                                                                  (combineTM N P).HoareTime (fun (inp : Tape) (work : Fin (N + 2)Tape) (out : Tape) => inp = inp₀ out = out₀ work = Fin.snoc (fun (i : Fin (N + 1)) => { head := 1, cells := cells i }) res₀) (fun (inp : Tape) (work : Fin (N + 2)Tape) (out : Tape) => inp = inp₀ out = out₀ work = Fin.snoc (fun (i : Fin (N + 1)) => { head := 1, cells := cells i }) (res₀.write (Γ.ofBool ((Scanner.andFirst N P).emit ((Scanner.andFirst N P).run (TM.scanCol cells) len))))) (2 * len + 3)

                                                                  The combining machine's contract.

                                                                  theorem Complexity.combineTM_verdict (N : ) (P : Fin (N + 1)Bool) (cells : Fin (N + 1)Γ) (len : ) (hlen : 0 < len) :
                                                                  (Scanner.andFirst N P).emit ((Scanner.andFirst N P).run (TM.scanCol cells) len) = true ∀ (i : Fin (N + 1)), P i = truecells i 1 = Γ.one

                                                                  The bit the combining machine writes: whether every designated register said yes.

                                                                  The equality and increment checks #

                                                                  The walk may keep a configuration as well as step it, and keeping is register equality — decided by the comparison scanner, one register pair at a time. A counter advances the same way: the next value is guessed into a second register and Complexity.Scanner.plusOne checks it. Both scanners already take arbitrary register indices at any width, so neither needs TM.checkTM.

                                                                  One walk step, as a single scan #

                                                                  A machine has one result tape, so the checks of a walk step run together: one automaton whose state is the tuple of theirs, each component frozen at its own length by Complexity.Scanner.upTo and reading its own registers through Complexity.Scanner.comap.

                                                                  def Complexity.windowCols {kk jj : } (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) (i : Fin kk) :
                                                                  Fin 3Fin (jj + 1)

                                                                  The columns a window check reads: the parameter block, then the old and new windows.

                                                                  Equations
                                                                  Instances For
                                                                    def Complexity.outputCols {kk jj : } (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) :
                                                                    Fin 3Fin (jj + 1)

                                                                    The columns the output-window check reads.

                                                                    Equations
                                                                    Instances For
                                                                      def Complexity.headCols {kk jj : } (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) :
                                                                      Fin 3Fin (jj + 1)

                                                                      The columns the input-head check reads.

                                                                      Equations
                                                                      Instances For
                                                                        def Complexity.stateCols {kk jj : } (par : Fin (jj + 1)) (R : CodeRegs kk jj) :
                                                                        Fin 2Fin (jj + 1)

                                                                        The columns a state check reads.

                                                                        Equations
                                                                        Instances For
                                                                          noncomputable def Complexity.blockLen {kk : } (tm : NTM kk) (nn S p : ) :

                                                                          The width of block p in the walk's layout: the field's own width, and for every register but the state's the parameter-block padding in front of it.

                                                                          Equations
                                                                          Instances For
                                                                            theorem Complexity.codeBlockScan_length {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (p : ) :
                                                                            (codeBlockScan tm x S a p).length = blockLen tm x.length S p
                                                                            noncomputable def Complexity.eqScanner {kk jj : } (tm : NTM kk) (nn S : ) (j j' : Fin (jj + 1)) :

                                                                            The scan that decides that two register tuples hold the same code: one comparison per block, each frozen at that block's width.

                                                                            Equations
                                                                            Instances For
                                                                              noncomputable def Complexity.walkScanLen {kk : } (tm : NTM kk) (nn S : ) :

                                                                              A length that covers every check of a walk step.

                                                                              Equations
                                                                              • One or more equations did not get rendered due to their size.
                                                                              Instances For
                                                                                theorem Complexity.blockLen_le {kk : } (tm : NTM kk) (nn S p : ) :
                                                                                blockLen tm nn S p walkScanLen tm nn S
                                                                                theorem Complexity.one_le_walkScanLen {kk : } (tm : NTM kk) (nn S : ) :
                                                                                1 walkScanLen tm nn S
                                                                                theorem Complexity.headField_le_walkScanLen {kk : } (tm : NTM kk) (nn S : ) :
                                                                                (succParamsCodec tm.Q kk).width + (finCodec (nn + S + 2)).width walkScanLen tm nn S
                                                                                theorem Complexity.two_le_walkScanLen {kk : } (tm : NTM kk) (nn S : ) :
                                                                                2 walkScanLen tm nn S
                                                                                noncomputable def Complexity.inSymScanner {kk jj : } (tm : NTM kk) (nn S : ) (par hd res : Fin (jj + 1)) :

                                                                                The scan that checks the guessed input symbol, conditional on where the simulated head is: against the parameter register alone when the head is at the marker, and against the machine's own input tape — through TM.inMatchTM's verdict — when it is not.

                                                                                Equations
                                                                                • One or more equations did not get rendered due to their size.
                                                                                Instances For
                                                                                  theorem Complexity.eqScanner_decides {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (j j' : Fin (jj + 1)) (a b : Code tm.Q kk x.length S) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S b p)) (hv : (eqScanner tm x.length S j j').emit ((eqScanner tm x.length S j j').run cols (walkScanLen tm x.length S)) = true) :
                                                                                  a = b

                                                                                  The equality scan decides that two guesses are the same code.

                                                                                  theorem Complexity.eqScanner_accepts {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (j j' : Fin (jj + 1)) (a : Code tm.Q kk x.length S) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S a p)) :
                                                                                  (eqScanner tm x.length S j j').emit ((eqScanner tm x.length S j j').run cols (walkScanLen tm x.length S)) = true

                                                                                  The equality scan accepts two guesses of the same code.

                                                                                  theorem Complexity.inSymScanner_decides {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par hd res : Fin (jj + 1)) (P : SuccParams tm.Q kk) (a : Code tm.Q kk x.length S) (g : Γ) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (hhd : HoldsBits cols (succParamsCodec tm.Q kk).width hd ((finCodec (x.length + S + 2)).enc a.2.1)) (hres : cols 1 res = Γ.ofBool (TM.inMatchVerdict gammaBits g (cols 1 par) (cols 2 par))) (hg : a.2.1 0g = inSymOf tm x S a) (hv : (inSymScanner tm x.length S par hd res).emit ((inSymScanner tm x.length S par hd res).run cols (walkScanLen tm x.length S)) = true) :
                                                                                  P.inSym = inSymOf tm x S a

                                                                                  The input-symbol scan decides the guessed symbol.

                                                                                  theorem Complexity.inSymScanner_accepts {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par hd res : Fin (jj + 1)) (P : SuccParams tm.Q kk) (a : Code tm.Q kk x.length S) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (hhd : HoldsBits cols (succParamsCodec tm.Q kk).width hd ((finCodec (x.length + S + 2)).enc a.2.1)) (hin : P.inSym = inSymOf tm x S a) (hres : a.2.1 0cols 1 res = Γ.one) :
                                                                                  (inSymScanner tm x.length S par hd res).emit ((inSymScanner tm x.length S par hd res).run cols (walkScanLen tm x.length S)) = true

                                                                                  The input-symbol scan accepts a correct guess.

                                                                                  noncomputable def Complexity.succScanner {kk jj : } (tm : NTM kk) (nn S : ) (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) :

                                                                                  The scan that decides a successor step: one check per work window, the output window, the input head, and the two state fields — all against the parameters in the same register.

                                                                                  Equations
                                                                                  • One or more equations did not get rendered due to their size.
                                                                                  Instances For
                                                                                    theorem Complexity.windowParams_congr {kk : } (tm : NTM kk) (cols cols' : Fin 3Γ) (h : ∀ (q : ), cols q 0 = cols' q 0) :
                                                                                    windowParams tm cols = windowParams tm cols'

                                                                                    The parameters a check reads depend only on the register it reads them from. Every check of a walk step reads the same parameter register, so they all work against the same guessed transition — which is what lets one guess serve five checks.

                                                                                    theorem Complexity.params_of_holds {kk : } (tm : NTM kk) (P : SuccParams tm.Q kk) (colsW : Fin 3Γ) (colsS : Fin 2Γ) (hW : HoldsBits colsW 0 0 ((succParamsCodec tm.Q kk).enc P)) (hS : HoldsBits colsS 0 0 ((succParamsCodec tm.Q kk).enc P)) :
                                                                                    windowParams tm colsW = P paramsOfStateTable tm (stateTable tm colsS) = P

                                                                                    Both readers of the parameter register read the same parameters. The window, output and input-head checks read the guessed transition with one reader; the state checks read it with another, over a wider block. When the register holds an encoding, the two agree — which is what lets the state checks be checks against the same guess as the rest.

                                                                                    theorem Complexity.walkParams_eq {kk jj : } (tm : NTM kk) (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) (cols : Fin (jj + 1)Γ) (i : Fin kk) :
                                                                                    ((windowParams tm fun (q : ) (c : Fin 3) => cols q (windowCols par Ra Rb i c)) = windowParams tm fun (q : ) (c : Fin 3) => cols q (outputCols par Ra Rb c)) (windowParams tm fun (q : ) (c : Fin 3) => cols q (windowCols par Ra Rb i c)) = windowParams tm fun (q : ) (c : Fin 3) => cols q (headCols par Ra Rb c)

                                                                                    Every check of a walk step reads the same parameters.

                                                                                    theorem Complexity.succScanner_verdicts {kk jj : } (tm : NTM kk) (nn S : ) (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) (cols : Fin (jj + 1)Γ) (hv : (succScanner tm nn S par Ra Rb).emit ((succScanner tm nn S par Ra Rb).run cols (walkScanLen tm nn S)) = true) :
                                                                                    (∀ (i : Fin kk), (windowScanner tm i).emit ((windowScanner tm i).run (fun (q : ) (c : Fin (2 + 1)) => cols q (windowCols par Ra Rb i c)) ((succParamsCodec tm.Q kk).width + 3 * (S + 1))) = true) (outputScanner tm).emit ((outputScanner tm).run (fun (q : ) (c : Fin (2 + 1)) => cols q (outputCols par Ra Rb c)) ((succParamsCodec tm.Q kk).width + 3 * (S + 2))) = true (headScanner tm).emit ((headScanner tm).run (fun (q : ) (c : Fin (2 + 1)) => cols q (headCols par Ra Rb c)) ((succParamsCodec tm.Q kk).width + (finCodec (nn + S + 2)).width)) = true (stateScanner tm false).emit ((stateScanner tm false).run (fun (q : ) (c : Fin (1 + 1)) => cols q (stateCols par Ra c)) (stateWidth tm)) = true (stateScanner tm true).emit ((stateScanner tm true).run (fun (q : ) (c : Fin (1 + 1)) => cols q (stateCols par Rb c)) (stateWidth tm)) = true

                                                                                    A successor scan's verdict is the verdict of each of its checks. Each component reads its own registers, over its own cells, exactly as it would have alone.

                                                                                    theorem Complexity.succScanner_accepts {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (ha : HoldsCodeScan tm x S cols Ra a) (hb : HoldsCodeScan tm x S cols Rb b) (hendW : ∀ (i : Fin kk), markOf (fun (q : ) (c : Fin (2 + 1)) => cols q (windowCols par Ra Rb i c)) (succParamsCodec tm.Q kk).width 1 (S + 1) = false) (hendO : markOf (fun (q : ) (c : Fin (2 + 1)) => cols q (outputCols par Ra Rb c)) (succParamsCodec tm.Q kk).width 1 (S + 2) = false) (hq : a.1 = P.q) (hstate : b.1 = succState tm P) (hwsym : ∀ (i : Fin kk), (a.2.2.1 i).2 (a.2.2.1 i).1 = P.wSym i) (hosym : a.2.2.2.2 a.2.2.2.1 = P.oSym) (hhead : b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1) (hwork : ∀ (i : Fin kk), (b.2.2.1 i).1 = movedIdx (succDir tm P i) (a.2.2.1 i).1 ∀ (p : Fin (S + 1)), (b.2.2.1 i).2 p = if p = (a.2.2.1 i).1 0 < p then succWrite tm P i else (a.2.2.1 i).2 p) (hout : b.2.2.2.1 = movedIdx (succTrans tm P).2.2.2.2.2 a.2.2.2.1 ∀ (p : Fin (S + 2)), b.2.2.2.2 p = if p = a.2.2.2.1 0 < p then (succTrans tm P).2.2.1.toΓ else a.2.2.2.2 p) (hleft : (succTrans tm P).2.2.2.1 = Dir3.left0 < a.2.1) :
                                                                                    (succScanner tm x.length S par Ra Rb).emit ((succScanner tm x.length S par Ra Rb).run cols (walkScanLen tm x.length S)) = true

                                                                                    The successor scan accepts a genuine successor. The converse of Complexity.succScanner_decides: when the registers really do hold a code and the code the transition makes of it, every check passes. This is the direction a completeness proof needs — it says the right guess exists.

                                                                                    theorem Complexity.succScanner_decides {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par : Fin (jj + 1)) (Ra Rb : CodeRegs kk jj) (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (ha : HoldsCodeScan tm x S cols Ra a) (hb : HoldsCodeScan tm x S cols Rb b) (hne : a.1 tm.qhalt) (hendW : ∀ (i : Fin kk), markOf (fun (q : ) (c : Fin (2 + 1)) => cols q (windowCols par Ra Rb i c)) (succParamsCodec tm.Q kk).width 1 (S + 1) = false) (hendO : markOf (fun (q : ) (c : Fin (2 + 1)) => cols q (outputCols par Ra Rb c)) (succParamsCodec tm.Q kk).width 1 (S + 2) = false) (hin : P.inSym = inSymOf tm x S a) (hv : (succScanner tm x.length S par Ra Rb).emit ((succScanner tm x.length S par Ra Rb).run cols (walkScanLen tm x.length S)) = true) :
                                                                                    b tm.codeSucc x S a b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1

                                                                                    The successor scan decides a successor step. Given that the parameter register holds a guessed transition, the scan's verdict says exactly that the second code is what that transition makes of the first. What the scan cannot see is left to the caller: the symbol under the simulated input head, which the machine reads from its own input tape, and that the step stays inside the space window.

                                                                                    def Complexity.dirCols {jj : } (par dr : Fin (jj + 1)) :
                                                                                    Fin 2Fin (jj + 1)

                                                                                    The columns the direction check reads: the parameter block, then the direction register.

                                                                                    Equations
                                                                                    Instances For
                                                                                      noncomputable def Complexity.counterStepScanner {jj : } (cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) :

                                                                                      The counter check of a walk step: the counter either stays as it was or advances by one. Only the second step of a pair advances it, so that the counter names the loop's iteration.

                                                                                      Equations
                                                                                      Instances For
                                                                                        theorem Complexity.rightOnly_plusOne (jj : ) (a b : Fin (jj + 1)) :
                                                                                        theorem Complexity.counterStepScanner_decides {jj : } (cntOld cntNew : Fin (jj + 1)) (wc len : ) (advance : Bool) (hw : wc len) (cols : Fin (jj + 1)Γ) (u v : ) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hold : HoldsBits cols 0 cntOld (bitsOfLenLE wc u)) (hnew : HoldsBits cols 0 cntNew (bitsOfLenLE wc v)) (hverdict : (counterStepScanner cntOld cntNew wc advance).emit ((counterStepScanner cntOld cntNew wc advance).run cols len) = true) :
                                                                                        if advance = true then v = u + 1 else u = v

                                                                                        The counter check decides what it should.

                                                                                        An encoding of directions in two guessed cells that TM.inMoveTM can read back. A guessed cell holds a bit, so one cell cannot name one of three directions; the first cell says whether to move at all and the second which way.

                                                                                        Instances For

                                                                                          The direction codec: the first cell is 1 exactly when the head moves, the second 1 for right and 0 for left.

                                                                                          Equations
                                                                                          • One or more equations did not get rendered due to their size.
                                                                                          Instances For

                                                                                            A bit-valued cell reads back as itself.

                                                                                            The direction that takes max h 1 to max (movedIdx d h) 1.

                                                                                            Equations
                                                                                            Instances For
                                                                                              noncomputable def Complexity.dirCheckScanner {kk jj : } (tm : NTM kk) (nn S : ) (par mv dr hdOld hdNew : Fin (jj + 1)) (dc : DirCodec) :

                                                                                              The scan that pins the direction register, conditional on both head fields being off the marker.

                                                                                              Equations
                                                                                              • One or more equations did not get rendered due to their size.
                                                                                              Instances For
                                                                                                theorem Complexity.dirCheckScanner_decides {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr hdOld hdNew : Fin (jj + 1)) (dc : DirCodec) (P : SuccParams tm.Q kk) (a b : Code tm.Q kk x.length S) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (hhdOld : HoldsBits cols (succParamsCodec tm.Q kk).width hdOld ((finCodec (x.length + S + 2)).enc a.2.1)) (hhdNew : HoldsBits cols (succParamsCodec tm.Q kk).width hdNew ((finCodec (x.length + S + 2)).enc b.2.1)) (hmove : b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1) (hv : (dirCheckScanner tm x.length S par mv dr hdOld hdNew dc).emit ((dirCheckScanner tm x.length S par mv dr hdOld hdNew dc).run cols (walkScanLen tm x.length S)) = true) :
                                                                                                cols 1 mv = dc.encMove (adjustedDir (succTrans tm P).2.2.2.1 a.2.1) cols 1 dr = dc.enc (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)

                                                                                                The direction check pins the register to the direction the machine must actually take.

                                                                                                theorem Complexity.dirCheckScanner_accepts {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr hdOld hdNew : Fin (jj + 1)) (dc : DirCodec) (P : SuccParams tm.Q kk) (a b : Code tm.Q kk x.length S) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (hhdOld : HoldsBits cols (succParamsCodec tm.Q kk).width hdOld ((finCodec (x.length + S + 2)).enc a.2.1)) (hhdNew : HoldsBits cols (succParamsCodec tm.Q kk).width hdNew ((finCodec (x.length + S + 2)).enc b.2.1)) (hmove : b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1) (hmv : cols 1 mv = dc.encMove (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)) (hdr : cols 1 dr = dc.enc (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)) :
                                                                                                (dirCheckScanner tm x.length S par mv dr hdOld hdNew dc).emit ((dirCheckScanner tm x.length S par mv dr hdOld hdNew dc).run cols (walkScanLen tm x.length S)) = true

                                                                                                The direction check accepts the direction the machine must take.

                                                                                                noncomputable def Complexity.walkCodeScanner {kk jj : } (tm : NTM kk) (nn S : ) (par mv dr res : Fin (jj + 1)) (dc : DirCodec) (j j' : Fin (jj + 1)) :

                                                                                                The code half of a walk step's scan.

                                                                                                Equations
                                                                                                • One or more equations did not get rendered due to their size.
                                                                                                Instances For
                                                                                                  theorem Complexity.counterStepScanner_accepts {jj : } (cntOld cntNew : Fin (jj + 1)) (wc len : ) (advance : Bool) (hw : wc len) (cols : Fin (jj + 1)Γ) (u v : ) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hold : HoldsBits cols 0 cntOld (bitsOfLenLE wc u)) (hnew : HoldsBits cols 0 cntNew (bitsOfLenLE wc v)) (hmove : if advance = true then v = u + 1 else u = v) :
                                                                                                  (counterStepScanner cntOld cntNew wc advance).emit ((counterStepScanner cntOld cntNew wc advance).run cols len) = true

                                                                                                  The counter check accepts the move it is meant to.

                                                                                                  theorem Complexity.walkCodeScanner_decides {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res : Fin (jj + 1)) (dc : DirCodec) (j j' : Fin (jj + 1)) (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (g : Γ) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S b p)) (hne : a.1 tm.qhalt) (hres : cols 1 res = Γ.ofBool (TM.inMatchVerdict gammaBits g (cols 1 par) (cols 2 par))) (hg : a.2.1 0g = inSymOf tm x S a) (hv : (walkCodeScanner tm x.length S par mv dr res dc j j').emit ((walkCodeScanner tm x.length S par mv dr res dc j j').run cols (walkScanLen tm x.length S)) = true) :
                                                                                                  b = a cols 1 mv = dc.encMove Dir3.stay cols 1 dr = dc.enc Dir3.stay b tm.codeSucc x S a b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1 cols 1 mv = dc.encMove (adjustedDir (succTrans tm P).2.2.2.1 a.2.1) cols 1 dr = dc.enc (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)

                                                                                                  The code half of a walk step's scan decides a walk step, and says how the input head moves. The symbol under the simulated input head is not scanned but read from the machine's own input tape by TM.inMatchTM, whose verdict the scan requires on register res; hg is the invariant that the machine's input head sits where the simulated one does.

                                                                                                  theorem Complexity.walkCodeScanner_accepts_stay {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res : Fin (jj + 1)) (dc : DirCodec) (j j' : Fin (jj + 1)) (a : Code tm.Q kk x.length S) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S a p)) (hmv : cols 1 mv = dc.encMove Dir3.stay) (hdr : cols 1 dr = dc.enc Dir3.stay) :
                                                                                                  (walkCodeScanner tm x.length S par mv dr res dc j j').emit ((walkCodeScanner tm x.length S par mv dr res dc j j').run cols (walkScanLen tm x.length S)) = true

                                                                                                  The walk-step scan accepts a step that stays put.

                                                                                                  theorem Complexity.walkCodeScanner_accepts_succ {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res : Fin (jj + 1)) (dc : DirCodec) (j j' : Fin (jj + 1)) (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S b p)) (hq : a.1 = P.q) (hstate : b.1 = succState tm P) (hwsym : ∀ (i : Fin kk), (a.2.2.1 i).2 (a.2.2.1 i).1 = P.wSym i) (hosym : a.2.2.2.2 a.2.2.2.1 = P.oSym) (hhead : b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1) (hwork : ∀ (i : Fin kk), (b.2.2.1 i).1 = movedIdx (succDir tm P i) (a.2.2.1 i).1 ∀ (p : Fin (S + 1)), (b.2.2.1 i).2 p = if p = (a.2.2.1 i).1 0 < p then succWrite tm P i else (a.2.2.1 i).2 p) (hout : b.2.2.2.1 = movedIdx (succTrans tm P).2.2.2.2.2 a.2.2.2.1 ∀ (p : Fin (S + 2)), b.2.2.2.2 p = if p = a.2.2.2.1 0 < p then (succTrans tm P).2.2.1.toΓ else a.2.2.2.2 p) (hleft : (succTrans tm P).2.2.2.1 = Dir3.left0 < a.2.1) (hdr : (dirCheckScanner tm x.length S par mv dr (codeRegsOf j).hd (codeRegsOf j').hd dc).emit ((dirCheckScanner tm x.length S par mv dr (codeRegsOf j).hd (codeRegsOf j').hd dc).run cols (walkScanLen tm x.length S)) = true) (hres : (inSymScanner tm x.length S par (codeRegsOf j).hd res).emit ((inSymScanner tm x.length S par (codeRegsOf j).hd res).run cols (walkScanLen tm x.length S)) = true) :
                                                                                                  (walkCodeScanner tm x.length S par mv dr res dc j j').emit ((walkCodeScanner tm x.length S par mv dr res dc j j').run cols (walkScanLen tm x.length S)) = true

                                                                                                  The walk-step scan accepts a step that advances.

                                                                                                  noncomputable def Complexity.walkStepScanner {kk jj : } (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (j j' : Fin (jj + 1)) :

                                                                                                  One walk step, as a single scan. Either the guessed code repeats the old one and the input head is told to stay, or it is a successor and the input head is told to move the way the transition does. The direction is part of the step because the machine's own input head tracks the simulated one — TM.inMoveTM reads exactly the cell this check pins.

                                                                                                  Equations
                                                                                                  • One or more equations did not get rendered due to their size.
                                                                                                  Instances For
                                                                                                    theorem Complexity.walkStepScanner_decides {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (j j' : Fin (jj + 1)) (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (g : Γ) (u v : ) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S b p)) (hne : a.1 tm.qhalt) (hres : cols 1 res = Γ.ofBool (TM.inMatchVerdict gammaBits g (cols 1 par) (cols 2 par))) (hg : a.2.1 0g = inSymOf tm x S a) (hwc : wc walkScanLen tm x.length S) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hcntOld : HoldsBits cols 0 cntOld (bitsOfLenLE wc u)) (hcntNew : HoldsBits cols 0 cntNew (bitsOfLenLE wc v)) (hverdict : (walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').emit ((walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').run cols (walkScanLen tm x.length S)) = true) :
                                                                                                    (b = a cols 1 mv = dc.encMove Dir3.stay cols 1 dr = dc.enc Dir3.stay b tm.codeSucc x S a b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1 cols 1 mv = dc.encMove (adjustedDir (succTrans tm P).2.2.2.1 a.2.1) cols 1 dr = dc.enc (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)) if advance = true then v = u + 1 else u = v

                                                                                                    The walk-step scan decides a step of the walk, how the input head moves, and what the counter does.

                                                                                                    theorem Complexity.walkStepScanner_accepts {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (j j' : Fin (jj + 1)) (hwc : wc walkScanLen tm x.length S) (u v : ) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hold : HoldsBits cols 0 cntOld (bitsOfLenLE wc u)) (hnew : HoldsBits cols 0 cntNew (bitsOfLenLE wc v)) (hmove : if advance = true then v = u + 1 else u = v) (hcode : (walkCodeScanner tm x.length S par mv dr res dc j j').emit ((walkCodeScanner tm x.length S par mv dr res dc j j').run cols (walkScanLen tm x.length S)) = true) :
                                                                                                    (walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').emit ((walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').run cols (walkScanLen tm x.length S)) = true

                                                                                                    The walk-step scan accepts a genuine step.

                                                                                                    The check phase #

                                                                                                    The input check and the scan, in sequence: the check leaves its verdict on a register, and the scan — which reads every register — takes that verdict into account along with everything else.

                                                                                                    noncomputable def Complexity.checkedCells {jj : } (cells : Fin (jj + 1)Γ) (par res : Fin (jj + 1)) (g : Γ) :
                                                                                                    Fin (jj + 1)Γ

                                                                                                    The registers after the input check: only the verdict register changes.

                                                                                                    Equations
                                                                                                    • One or more equations did not get rendered due to their size.
                                                                                                    Instances For
                                                                                                      @[simp]
                                                                                                      theorem Complexity.checkedCells_ne {jj : } (cells : Fin (jj + 1)Γ) (par res : Fin (jj + 1)) (g : Γ) (i : Fin (jj + 1)) (hi : i res) :
                                                                                                      checkedCells cells par res g i = cells i
                                                                                                      @[simp]
                                                                                                      theorem Complexity.checkedCells_res {jj : } (cells : Fin (jj + 1)Γ) (par res : Fin (jj + 1)) (g : Γ) :
                                                                                                      checkedCells cells par res g res 1 = Γ.ofBool (TM.inMatchVerdict gammaBits g (cells par 1) (cells par 2))
                                                                                                      theorem Complexity.scanTape_checked {jj : } {cells : Fin (jj + 1)Γ} {len : } (h : TM.ScanTape cells len) (par res : Fin (jj + 1)) (hres : res 0) (g : Γ) :
                                                                                                      TM.ScanTape (checkedCells cells par res g) len

                                                                                                      The input check leaves the scan well formed. It writes one bit on the verdict register, which is never the ruler.

                                                                                                      theorem Complexity.checked_cell {jj : } (cells : Fin (jj + 1)Γ) (par res : Fin (jj + 1)) (g : Γ) (r : Fin (jj + 1)) (hr : r res) (q : ) :
                                                                                                      checkedCells cells par res g r q = cells r q

                                                                                                      A register other than the verdict's survives the input check.

                                                                                                      theorem Complexity.holdsBits_checked {jj : } {cells : Fin (jj + 1)Γ} {par res : Fin (jj + 1)} {g : Γ} {r : Fin (jj + 1)} (hr : r res) {off : } {bits : List Bool} (h : HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) off r bits) :
                                                                                                      HoldsBits (fun (q : ) (i : Fin (jj + 1)) => checkedCells cells par res g i q) off r bits

                                                                                                      And so does what it holds.

                                                                                                      theorem Complexity.checkPhase_hoareTime {kk jj : } (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (cells : Fin (jj + 1)Γ) (len : ) (inp₀ out₀ resT : Tape) (hok : TM.ScanOk inp₀ resT out₀) (ht : TM.ScanTape cells len) (hresSI : resT.StartInvariant) (hresH : 1 resT.head) (hpr : par res) (ht' : TM.ScanTape (checkedCells cells par res inp₀.read) len) :
                                                                                                      ((TM.inMatchTM gammaBits par.castSucc res.castSucc).seqTM (TM.twoPassTM (walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew))).HoareTime (fun (inp : Tape) (work : Fin (jj + 1 + 1)Tape) (out : Tape) => inp = inp₀ out = out₀ work = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := cells i }) resT) (fun (inp : Tape) (work : Fin (jj + 1 + 1)Tape) (out : Tape) => inp = inp₀ out = out₀ work = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := checkedCells cells par res inp₀.read i }) (resT.write (Γ.ofBool ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).emit ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).run (TM.scanCol (checkedCells cells par res inp₀.read)) len))))) (2 + 1 + (2 * len + 3))

                                                                                                      The check phase's contract.

                                                                                                      noncomputable def Complexity.walkCheckTM {kk jj : } (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) :
                                                                                                      TM (jj + 2)

                                                                                                      The guess-free half of a walk step: check the guessed input symbol against the machine's own input tape, run the walk-step scan, and move the input head by the direction the scan pinned. The verdict is left on the result register, where the step's last stage conjoins it into the accumulator.

                                                                                                      Equations
                                                                                                      • One or more equations did not get rendered due to their size.
                                                                                                      Instances For
                                                                                                        theorem Complexity.checkMove_hoareTime {kk jj : } (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (cells : Fin (jj + 1)Γ) (len : ) (inp₀ out₀ resT : Tape) (hok : TM.ScanOk inp₀ resT out₀) (ht : TM.ScanTape cells len) (hresSI : resT.StartInvariant) (hresH : 1 resT.head) (hpr : par res) (ht' : TM.ScanTape (checkedCells cells par res inp₀.read) len) :
                                                                                                        (walkCheckTM tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).HoareTime (fun (inp : Tape) (work : Fin (jj + 2)Tape) (out : Tape) => inp = inp₀ out = out₀ work = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := cells i }) resT) (fun (inp : Tape) (work : Fin (jj + 2)Tape) (out : Tape) => inp = inp₀.move (dc.dec (checkedCells cells par res inp₀.read mv 1) (checkedCells cells par res inp₀.read dr 1)) out = out₀ work = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := checkedCells cells par res inp₀.read i }) (resT.write (Γ.ofBool ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).emit ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).run (TM.scanCol (checkedCells cells par res inp₀.read)) len))))) (2 + 1 + (2 * len + 3) + 1 + 1)

                                                                                                        The guess-free part of a walk step. The input check, the scan, and the move of the input head.

                                                                                                        noncomputable def Complexity.verdictCells {jj : } (cells : Fin (jj + 1)Γ) (acc : Fin (jj + 1)) (v : Bool) :
                                                                                                        Fin (jj + 1)Γ

                                                                                                        The registers after the scan's verdict is copied onto the accumulator.

                                                                                                        Equations
                                                                                                        Instances For
                                                                                                          @[simp]
                                                                                                          theorem Complexity.verdictCells_self {jj : } (cells : Fin (jj + 1)Γ) (acc : Fin (jj + 1)) (v : Bool) :
                                                                                                          verdictCells cells acc v acc 1 = Γ.ofBool v
                                                                                                          @[simp]
                                                                                                          theorem Complexity.verdictCells_ne {jj : } (cells : Fin (jj + 1)Γ) (acc : Fin (jj + 1)) (v : Bool) (i : Fin (jj + 1)) (hi : i acc) :
                                                                                                          verdictCells cells acc v i = cells i
                                                                                                          theorem Complexity.verdictCells_acc_one {jj : } (cells : Fin (jj + 1)Γ) (acc : Fin (jj + 1)) (v : Bool) :
                                                                                                          verdictCells cells acc v acc 1 = Γ.one v = true

                                                                                                          The accumulator reads one exactly when the scan accepted. This is the cell the loop's test looks at.

                                                                                                          One walk step, as a machine #

                                                                                                          Guess the next code (and the transition, and the direction), rewind the guessed registers, check the guessed input symbol against the machine's own input tape, run the walk-step scan, and move the input head. The guess tape is last; everything after the guess stage is guess-free and lifted past it.

                                                                                                          noncomputable def Complexity.walkStepTM {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) :
                                                                                                          TM (jj + 2 + r + 1)

                                                                                                          One walk step as a machine: guess every register, hold the enclosing loops' r tapes still, check and move, and conjoin the verdict into the accumulator.

                                                                                                          Equations
                                                                                                          • One or more equations did not get rendered due to their size.
                                                                                                          Instances For
                                                                                                            theorem Complexity.walkStepTM_hoareTime {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) (hnodup : targets.Nodup) (hall : ∀ (i : Fin (jj + 2)), Fin.castAdd r i targets) (haux : ∀ (c : Fin r), Fin.natAdd (jj + 2) ctargets) (hauxG : ∀ (p : ) (c : Fin r), p < tguessReg p (Fin.natAdd (jj + 2) c).castSucc) (haccReg : ∀ (i : Fin (jj + 2)), accIdx (Fin.castAdd r i).castSucc) (haccLast : accIdx Fin.last (jj + 2 + r)) (hj : ∀ (p : ), guessReg p Fin.last (jj + 2 + r)) (B : ) (hB : 1 B) (inp₀ out₀ : Tape) (W₀ : Fin (jj + 2 + r + 1)Tape) (hinpSI : inp₀.StartInvariant) (houtSI : out₀.StartInvariant) (hinp : inp₀.read Γ.start) (hout : out₀.read Γ.start) (hinvW : ∀ (i : Fin (jj + 2 + r + 1)), (W₀ i).StartInvariant) (hhW : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W₀ i).head) (hinj : ∀ (p q : ), p < tq < tguessReg p = guessReg qp = q) (hbound : itargets, (TM.guessBlocksTapes guessReg w t W₀ i.castSucc).head B) (len : ) (hok : TM.ScanOk (TM.parkTape inp₀) { head := 1, cells := (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r (Fin.last (jj + 1))).castSucc).cells } (TM.parkTape out₀)) (ht : TM.ScanTape (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) len) (hpr : par res) (ht' : TM.ScanTape (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read) len) (hmoved : ((TM.parkTape inp₀).move (dc.dec (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read mv 1) (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read dr 1))).read Γ.start) :
                                                                                                            (walkStepTM r tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew guessReg w t targets accIdx).HoareTime (fun (inp : Tape) (work : Fin (jj + 2 + r + 1)Tape) (out : Tape) => inp = inp₀ out = out₀ work = W₀) (fun (inp : Tape) (work : Fin (jj + 2 + r + 1)Tape) (out : Tape) => work (Fin.last (jj + 2 + r)) = TM.guessBlocksTapes guessReg w t W₀ (Fin.last (jj + 2 + r)) (∀ (c : Fin r), (Fin.natAdd (jj + 2) c).castSucc accIdxwork (Fin.natAdd (jj + 2) c).castSucc = W₀ (Fin.natAdd (jj + 2) c).castSucc) inp = (TM.parkTape inp₀).move (dc.dec (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read mv 1) (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read dr 1)) out = TM.parkTape out₀ (∀ (i : Fin (jj + 2)), work (Fin.castAdd r i).castSucc = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read i }) ({ head := 1, cells := (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r (Fin.last (jj + 1))).castSucc).cells }.write (Γ.ofBool ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).emit ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).run (TM.scanCol (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read)) len)))) i) work accIdx = { head := (W₀ accIdx).head, cells := Function.update (W₀ accIdx).cells (W₀ accIdx).head (if (walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).emit ((walkStepScanner tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew).run (TM.scanCol (checkedCells (fun (i : Fin (jj + 1)) => (TM.guessBlocksTapes guessReg w t W₀ (Fin.castAdd r i.castSucc).castSucc).cells) par res (TM.parkTape inp₀).read)) len) = true (W₀ accIdx).read = Γ.one then Γ.one else Γ.zero) }) (TM.guessBlocksTime w t + 1 + (1 + 1 + (targets.length * (B + 3) + 1)) + 1 + (2 + 1 + (2 * len + 3) + 1 + 1 + 1 + 1))

                                                                                                            The contract of a walk step. Guess every register, then check, move, and record. The guessed tapes are named by TM.guessBlocksTapes; what they contain is the caller's business, and Complexity.walkStepScanner_decides is what turns the resulting verdict into a step of the walk. The accumulator is not a register — no guess can reach it — and it only ever loses its one, which is what makes a single failed check final in a loop that cannot stop early.

                                                                                                            noncomputable def Complexity.walkStepAdv {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) :
                                                                                                            (walkStepTM r tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew guessReg w t targets accIdx).QBool

                                                                                                            Its advancing states: only the guess stage consumes guesses.

                                                                                                            Equations
                                                                                                            • One or more equations did not get rendered due to their size.
                                                                                                            Instances For
                                                                                                              theorem Complexity.guessProtocol_walkStepTM {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) (haccLast : accIdx Fin.last (jj + 2 + r)) :
                                                                                                              (walkStepTM r tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew guessReg w t targets accIdx).GuessProtocol (walkStepAdv r tm nn S par mv dr res cntOld cntNew wc advance dc jold jnew guessReg w t targets accIdx)

                                                                                                              A walk step respects the guess protocol. Only the guess stage advances the guess head; the checks and the input-head move never consult it.

                                                                                                              The loop's test #

                                                                                                              TM.loopTM decides whether to continue by reading cell one of the output tape, while a scan writes its verdict to a work register. So a test is a scan followed by TM.writeOutputBitTM, which publishes that register's bit on the output tape. The walk's test compares the counter against the register holding the target count.

                                                                                                              theorem Complexity.counterTest_verdict {jj : } (cnt target : Fin (jj + 1)) (wc len : ) (hw : wc len) (cols : Fin (jj + 1)Γ) :
                                                                                                              ((Scanner.eq jj cnt target).upTo wc).emit (((Scanner.eq jj cnt target).upTo wc).run cols len) = true ∀ (q : ), 1 qq wccols q cnt = cols q target

                                                                                                              What the test decides: the counter and the target agree over the counter's width.

                                                                                                              theorem Complexity.counterTest_decides {jj : } (cnt target : Fin (jj + 1)) (wc len : ) (hw : wc len) (cols : Fin (jj + 1)Γ) (u v : ) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hcnt : HoldsBits cols 0 cnt (bitsOfLenLE wc u)) (htar : HoldsBits cols 0 target (bitsOfLenLE wc v)) :
                                                                                                              ((Scanner.eq jj cnt target).upTo wc).emit (((Scanner.eq jj cnt target).upTo wc).run cols len) = true u = v

                                                                                                              The counter and the target agree exactly when they hold the same number.

                                                                                                              noncomputable def Complexity.loopTestScanner {jj : } (cnt target acc : Fin (jj + 1)) (wc : ) :

                                                                                                              The loop's test: stop when the counter reaches its target, or when a check has failed. A failed check leaves the loop early, with the counter short of its target, and the comparison afterwards rejects.

                                                                                                              Equations
                                                                                                              Instances For
                                                                                                                theorem Complexity.loopTestScanner_verdict {jj : } (cnt target acc : Fin (jj + 1)) (wc len : ) (hw : wc len) (h1 : 1 len) (cols : Fin (jj + 1)Γ) :
                                                                                                                (loopTestScanner cnt target acc wc).emit ((loopTestScanner cnt target acc wc).run cols len) = true (∀ (q : ), 1 qq wccols q cnt = cols q target) cols 1 acc Γ.one

                                                                                                                What the loop's test decides.

                                                                                                                theorem Complexity.loopTestScanner_decides {jj : } (cnt target acc : Fin (jj + 1)) (wc len : ) (hw : wc len) (h1 : 1 len) (cols : Fin (jj + 1)Γ) (u v : ) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hcnt : HoldsBits cols 0 cnt (bitsOfLenLE wc u)) (htgt : HoldsBits cols 0 target (bitsOfLenLE wc v)) (hacc : cols 1 acc = Γ.one) :
                                                                                                                (loopTestScanner cnt target acc wc).emit ((loopTestScanner cnt target acc wc).run cols len) = true u = v

                                                                                                                When the checks have passed, the loop stops exactly when the counter reaches its target.

                                                                                                                theorem Complexity.loopTestScanner_of_fail {jj : } (cnt target acc : Fin (jj + 1)) (wc len : ) (hw : wc len) (h1 : 1 len) (cols : Fin (jj + 1)Γ) (hacc : cols 1 acc Γ.one) :
                                                                                                                (loopTestScanner cnt target acc wc).emit ((loopTestScanner cnt target acc wc).run cols len) = true

                                                                                                                A failed check stops the loop.

                                                                                                                noncomputable def Complexity.loopTestTM {jj : } (cnt target acc : Fin (jj + 1)) (wc : ) :
                                                                                                                TM (jj + 2)

                                                                                                                The loop's test as a machine: the comparison, then the verdict published where TM.loopTM reads it.

                                                                                                                Equations
                                                                                                                Instances For
                                                                                                                  theorem Complexity.publishTestTM_hoareTime {jj : } (Sc : Scanner jj) (len : ) (cells : Fin (jj + 1)Γ) (inp₀ out₀ resT : Tape) (hok : TM.ScanOk inp₀ resT out₀) (ht : TM.ScanTape cells len) (hinpP : TM.Parked inp₀) (houtP : TM.Parked out₀) (hresSI : resT.StartInvariant) (hresH : resT.head = 1) :
                                                                                                                  ((TM.twoPassTM Sc).seqTM (TM.writeOutputBitTM (Fin.last (jj + 1)))).HoareTime (fun (inp : Tape) (work : Fin (jj + 2)Tape) (out : Tape) => inp = inp₀ out = out₀ work = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := cells i }) resT) (fun (inp : Tape) (work : Fin (jj + 2)Tape) (out : Tape) => inp = inp₀ work = Fin.snoc (fun (i : Fin (jj + 1)) => { head := 1, cells := cells i }) (resT.write (Γ.ofBool (Sc.emit (Sc.run (TM.scanCol cells) len)))) out = out₀.write (Γ.ofBool (Sc.emit (Sc.run (TM.scanCol cells) len)))) (2 * len + 3 + 1 + 1)

                                                                                                                  A published test's contract. The scan runs, and the publish step puts its verdict where TM.loopTM looks for it: cell one of the output tape.

                                                                                                                  The walk, as a machine #

                                                                                                                  A walk step guesses every register — that uniformity is what makes the guess stage's output match the scan's precondition — so the register holding the old code is overwritten each iteration, and nothing would pin it to the previous iteration's new code. Rather than copy a register, the loop's body runs two steps with the roles swapped: the first carries the code from jold to jnew, the second from jnew back to jold. After an iteration the code is where it started.

                                                                                                                  Walks of even length lose nothing, because a step may leave the code alone: a walk of any shorter length is one of these padded with stays.

                                                                                                                  The loop below is built on TM.loopTM, whose test channel is the output tape. That is fine for reasoning about the walk in isolation, but the machine NL_subset_coNL_of_counting asks for must be a transducer, and TM.loopTM rewinds the output tape. The final assembly therefore drives the same body with TM.binaryForTM, whose counter and limit live on binary work tapes and which IsTransducer.binaryForTM shows to be output-safe.

                                                                                                                  noncomputable def Complexity.walkPairTM {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cnt cnt' : Fin (jj + 1)) (wc : ) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg guessReg' : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) :
                                                                                                                  TM (jj + 2 + r + 1)

                                                                                                                  The body of the walk: two steps, with the code's registers — and the counter's — swapping roles. Only the second step advances the counter, so it names the loop's iteration.

                                                                                                                  Equations
                                                                                                                  • One or more equations did not get rendered due to their size.
                                                                                                                  Instances For
                                                                                                                    noncomputable def Complexity.walkPairAdv {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cnt cnt' : Fin (jj + 1)) (wc : ) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg guessReg' : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) :
                                                                                                                    (walkPairTM r tm nn S par mv dr res cnt cnt' wc dc jold jnew guessReg guessReg' w t targets accIdx).QBool

                                                                                                                    Its advancing states.

                                                                                                                    Equations
                                                                                                                    • One or more equations did not get rendered due to their size.
                                                                                                                    Instances For
                                                                                                                      theorem Complexity.guessProtocol_walkPairTM {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cnt cnt' : Fin (jj + 1)) (wc : ) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg guessReg' : Fin (jj + 2 + r + 1)) (w : ) (t : ) (targets : List (Fin (jj + 2 + r))) (accIdx : Fin (jj + 2 + r + 1)) (haccLast : accIdx Fin.last (jj + 2 + r)) :
                                                                                                                      (walkPairTM r tm nn S par mv dr res cnt cnt' wc dc jold jnew guessReg guessReg' w t targets accIdx).GuessProtocol (walkPairAdv r tm nn S par mv dr res cnt cnt' wc dc jold jnew guessReg guessReg' w t targets accIdx)

                                                                                                                      The paired step respects the guess protocol.

                                                                                                                      noncomputable def Complexity.walkLoopTM {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cnt cnt' : Fin (jj + 1)) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg guessReg' : Fin (jj + 2 + r + 1)) (w : ) (t wc : ) (targets : List (Fin (jj + 2 + r))) (accIdx counterIdx limitIdx : Fin (jj + 2 + r + 1)) :
                                                                                                                      TM (jj + 2 + r + 1)

                                                                                                                      The walk as a machine: paired steps, counted by the loop driver's own binary counter. TM.binaryForTM is output-safe, which TM.loopTM — whose test channel is the output tape — is not, and the whole machine has to be a transducer.

                                                                                                                      Equations
                                                                                                                      • One or more equations did not get rendered due to their size.
                                                                                                                      Instances For
                                                                                                                        theorem Complexity.guessProtocol_walkLoopTM {kk jj : } (r : ) (tm : NTM kk) (nn S : ) (par mv dr res cnt cnt' : Fin (jj + 1)) (dc : DirCodec) (jold jnew : Fin (jj + 1)) (guessReg guessReg' : Fin (jj + 2 + r + 1)) (w : ) (t wc : ) (targets : List (Fin (jj + 2 + r))) (accIdx counterIdx limitIdx : Fin (jj + 2 + r + 1)) (haccLast : accIdx Fin.last (jj + 2 + r)) (hcounter : counterIdx Fin.last (jj + 2 + r)) (hlimit : limitIdx Fin.last (jj + 2 + r)) :
                                                                                                                        (walkLoopTM r tm nn S par mv dr res cnt cnt' dc jold jnew guessReg guessReg' w t wc targets accIdx counterIdx limitIdx).GuessProtocol (TM.binaryForAdv (walkPairAdv r tm nn S par mv dr res cnt cnt' wc dc jold jnew guessReg guessReg' w t targets accIdx) counterIdx limitIdx)

                                                                                                                        The walk respects the guess protocol. Only the body's guess stage advances the guess head; the loop driver rewrites every tape it does not own and holds its head still.

                                                                                                                        theorem Complexity.mem_reachCodes_of_pairWalk {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a₀ : Code tm.Q kk x.length S) (N i : ) (hi : i 2 * N) (f : Code tm.Q kk x.length S) (h0 : f 0 = a₀) (hstep : j < i, f (j + 1) = f j f (j + 1) tm.codeSucc x S (f j)) :
                                                                                                                        f i tm.reachCodes x S a₀ (2 * N)

                                                                                                                        A walk taken two steps at a time reaches everything a walk of any shorter length does. The machine's loop body is a pair of steps, so its walks have even length; padding with steps that stay put covers the rest.

                                                                                                                        The input head follows the simulated one #

                                                                                                                        TM.inMoveTM moves the machine's own input head by the direction the walk step's check pinned. That direction is the one the simulated transition takes, and a tape's head moves exactly as Complexity.movedIdx says — including at the left marker, where both a leftward move and movedIdx stay put.

                                                                                                                        A tape's head moves as Complexity.movedIdx says.

                                                                                                                        theorem Complexity.move_head_of_dir (t : Tape) (C : DirCodec) (d : Dir3) (m g : Γ) (hm : m = C.encMove d) (hg : g = C.enc d) :
                                                                                                                        (t.move (C.dec m g)).head = movedIdx d t.head

                                                                                                                        The input head lands where the code says.

                                                                                                                        theorem Complexity.walkStepScanner_accepts_stay {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (j j' : Fin (jj + 1)) (a : Code tm.Q kk x.length S) (u v : ) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S a p)) (hmv : cols 1 mv = dc.encMove Dir3.stay) (hdr : cols 1 dr = dc.enc Dir3.stay) (hwc : wc walkScanLen tm x.length S) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hcntOld : HoldsBits cols 0 cntOld (bitsOfLenLE wc u)) (hcntNew : HoldsBits cols 0 cntNew (bitsOfLenLE wc v)) (hmove : if advance = true then v = u + 1 else u = v) :
                                                                                                                        (walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').emit ((walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').run cols (walkScanLen tm x.length S)) = true

                                                                                                                        A walk step's scan accepts a step that stays put.

                                                                                                                        theorem Complexity.walkStepScanner_accepts_succ {kk jj : } (tm : NTM kk) (x : List Bool) (S : ) (cols : Fin (jj + 1)Γ) (par mv dr res cntOld cntNew : Fin (jj + 1)) (wc : ) (advance : Bool) (dc : DirCodec) (j j' : Fin (jj + 1)) (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (u v : ) (hpar : HoldsBits cols 0 par ((succParamsCodec tm.Q kk).enc P)) (ha : p < kk + 3, HoldsBits cols 0 (j p) (codeBlockScan tm x S a p)) (hb : p < kk + 3, HoldsBits cols 0 (j' p) (codeBlockScan tm x S b p)) (hq : a.1 = P.q) (hstate : b.1 = succState tm P) (hwsym : ∀ (i : Fin kk), (a.2.2.1 i).2 (a.2.2.1 i).1 = P.wSym i) (hosym : a.2.2.2.2 a.2.2.2.1 = P.oSym) (hhead : b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1) (hwork : ∀ (i : Fin kk), (b.2.2.1 i).1 = movedIdx (succDir tm P i) (a.2.2.1 i).1 ∀ (p : Fin (S + 1)), (b.2.2.1 i).2 p = if p = (a.2.2.1 i).1 0 < p then succWrite tm P i else (a.2.2.1 i).2 p) (hout : b.2.2.2.1 = movedIdx (succTrans tm P).2.2.2.2.2 a.2.2.2.1 ∀ (p : Fin (S + 2)), b.2.2.2.2 p = if p = a.2.2.2.1 0 < p then (succTrans tm P).2.2.1.toΓ else a.2.2.2.2 p) (hleft : (succTrans tm P).2.2.2.1 = Dir3.left0 < a.2.1) (hmv : cols 1 mv = dc.encMove (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)) (hdr : cols 1 dr = dc.enc (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)) (hin : P.inSym = inSymOf tm x S a) (hres : a.2.1 0cols 1 res = Γ.one) (hwc : wc walkScanLen tm x.length S) (hu : u < 2 ^ wc) (hv : v < 2 ^ wc) (hcntOld : HoldsBits cols 0 cntOld (bitsOfLenLE wc u)) (hcntNew : HoldsBits cols 0 cntNew (bitsOfLenLE wc v)) (hmove : if advance = true then v = u + 1 else u = v) :
                                                                                                                        (walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').emit ((walkStepScanner tm x.length S par mv dr res cntOld cntNew wc advance dc j j').run cols (walkScanLen tm x.length S)) = true

                                                                                                                        A walk step's scan accepts a genuine advancing step. Everything the checks need is supplied: the registers' contents, the direction cells, the counter's move, and the input check's verdict.

                                                                                                                        The ruler register #

                                                                                                                        A two-pass scan turns around when it meets a blank on register 0, so that register fixes the scan's length: it must carry non-blank symbols for exactly as many cells as the scan is to read, and a blank immediately after. The guess writes it like any other register — a block of ones as wide as Complexity.walkScanLen — which is why register 0 of the layout is a ruler and the code's registers start at one.

                                                                                                                        The ruler register's contents: ones for the length of the scan.

                                                                                                                        Equations
                                                                                                                        Instances For
                                                                                                                          @[simp]
                                                                                                                          theorem Complexity.rulerBlock_getElem (len q : ) (hq : q < len) :
                                                                                                                          theorem Complexity.scanTape_of_ruler {jj : } (cells : Fin (jj + 1)Γ) (len : ) (hstart : ∀ (i : Fin (jj + 1)), cells i 0 = Γ.start) (hne : ∀ (i : Fin (jj + 1)) (q : ), 1 qcells i q Γ.start) (hruler : ∀ (q : ), 1 qq lencells 0 q = Γ.one) (hblank : cells 0 (len + 1) = Γ.blank) :
                                                                                                                          TM.ScanTape cells len

                                                                                                                          A register of ones as long as the scan makes the scan well formed. The blank just past the ruler is what stops the rightward pass; it is not written by the guess, so it is the one thing a caller must know about the tape rather than about the guess.

                                                                                                                          theorem Complexity.ruler_of_holds {jj : } (cols : Fin (jj + 1)Γ) (r : Fin (jj + 1)) (len : ) (h : HoldsBits cols 0 r (rulerBlock len)) (q : ) :
                                                                                                                          1 qq lencols q r = Γ.one

                                                                                                                          A register holding the ruler block is a ruler.

                                                                                                                          Moving a head that is pinned away from the marker #

                                                                                                                          The machine's input head sits at max h 1, so it must move by the direction that takes max h 1 to max h' 1 — which is the simulated direction only when both h and h' are off the marker, and "stay" otherwise. Both conditions are fields of the two codes, so both are decided by the same scan.

                                                                                                                          theorem Complexity.move_adjusted (t : Tape) (d : Dir3) (h : ) (ht : t.head = max h 1) :
                                                                                                                          (t.move (adjustedDir d h)).head = max (movedIdx d h) 1

                                                                                                                          The adjusted direction moves a pinned head to where it should be.

                                                                                                                          theorem Complexity.move_of_walkStep (C : DirCodec) (t : Tape) (h h' : ) (d : Dir3) (m g : Γ) (ht : t.head = max h 1) (hm : m = C.encMove (adjustedDir d h)) (hg : g = C.enc (adjustedDir d h)) (hh' : h' = movedIdx d h) :
                                                                                                                          t.move (C.dec m g) = { head := max h' 1, cells := t.cells }

                                                                                                                          One walk step carries the input head to where the next code says. Whichever branch the step took, the direction register holds Complexity.adjustedDir of the step's direction, and a head parked at max h 1 lands parked at max h' 1.

                                                                                                                          theorem Complexity.move_of_walkStay (C : DirCodec) (t : Tape) (h : ) (m g : Γ) (ht : t.head = max h 1) (hm : m = C.encMove Dir3.stay) (hg : g = C.enc Dir3.stay) :
                                                                                                                          t.move (C.dec m g) = { head := max h 1, cells := t.cells }

                                                                                                                          A step that stays put leaves the input head where it was.

                                                                                                                          theorem Complexity.walkStep_transports (C : DirCodec) {kk : } {tm : NTM kk} {x : List Bool} {S : } (a b : Code tm.Q kk x.length S) (P : SuccParams tm.Q kk) (t : Tape) (m g : Γ) (ht : t.head = max (↑a.2.1) 1) (hstep : b = a m = C.encMove Dir3.stay g = C.enc Dir3.stay b tm.codeSucc x S a b.2.1 = movedIdx (succTrans tm P).2.2.2.1 a.2.1 m = C.encMove (adjustedDir (succTrans tm P).2.2.2.1 a.2.1) g = C.enc (adjustedDir (succTrans tm P).2.2.2.1 a.2.1)) :
                                                                                                                          (b = a b tm.codeSucc x S a) t.move (C.dec m g) = { head := max (↑b.2.1) 1, cells := t.cells }

                                                                                                                          What one walk step establishes about the tapes. Either branch of the step leaves the input head parked where the new code says, and the code itself is one step of the walk.

                                                                                                                          The fields of a genuine successor #

                                                                                                                          The completeness direction starts from a walk that really happens and must produce the guesses that make every check pass. Complexity.paramsOf names the transition a code takes on a given choice, and its fields are what the checks compare against.

                                                                                                                          theorem Complexity.succ_fields_of_eq {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a b : Code tm.Q kk x.length S) (β : Bool) (hb : b = succCode tm x S β a) (hin : movedIdx (succTrans tm (paramsOf tm x S a β)).2.2.2.1 a.2.1 x.length + S + 1) (hw : ∀ (i : Fin kk), movedIdx (succDir tm (paramsOf tm x S a β) i) (a.2.2.1 i).1 S) (ho : movedIdx (succTrans tm (paramsOf tm x S a β)).2.2.2.2.2 a.2.2.2.1 S + 1) :
                                                                                                                          a.1 = (paramsOf tm x S a β).q b.1 = succState tm (paramsOf tm x S a β) (∀ (i : Fin kk), (a.2.2.1 i).2 (a.2.2.1 i).1 = (paramsOf tm x S a β).wSym i) a.2.2.2.2 a.2.2.2.1 = (paramsOf tm x S a β).oSym b.2.1 = movedIdx (succTrans tm (paramsOf tm x S a β)).2.2.2.1 a.2.1 (∀ (i : Fin kk), (b.2.2.1 i).1 = movedIdx (succDir tm (paramsOf tm x S a β) i) (a.2.2.1 i).1 ∀ (p : Fin (S + 1)), (b.2.2.1 i).2 p = if p = (a.2.2.1 i).1 0 < p then succWrite tm (paramsOf tm x S a β) i else (a.2.2.1 i).2 p) b.2.2.2.1 = movedIdx (succTrans tm (paramsOf tm x S a β)).2.2.2.2.2 a.2.2.2.1 ∀ (p : Fin (S + 2)), b.2.2.2.2 p = if p = a.2.2.2.1 0 < p then (succTrans tm (paramsOf tm x S a β)).2.2.1.toΓ else a.2.2.2.2 p

                                                                                                                          A genuine successor's fields are what the checks want. The clamps are the space discipline: the step must stay inside the window, which is where the codes live.

                                                                                                                          theorem Complexity.succ_inSym {kk : } (tm : NTM kk) (x : List Bool) (S : ) (a : Code tm.Q kk x.length S) (β : Bool) :
                                                                                                                          (paramsOf tm x S a β).inSym = inSymOf tm x S a

                                                                                                                          The input symbol a genuine successor's parameters name.

                                                                                                                          The walk's register layout #

                                                                                                                          Every register the walk uses is guessed, so the layout has to name them all and say how wide each block is. The roles are: the ruler that fixes the scan's length, the parameter block, the direction cell, the input check's verdict, the accumulator the loop's test reads, the two counter registers, the target the counter is compared against, and the two code register tuples.

                                                                                                                          inductive Complexity.BlockRole (kk : ) :

                                                                                                                          The role a guessed block plays in the walk.

                                                                                                                          Instances For
                                                                                                                            def Complexity.instDecidableEqBlockRole.decEq {kk✝ : } (x✝ x✝¹ : BlockRole kk✝) :
                                                                                                                            Decidable (x✝ = x✝¹)
                                                                                                                            Equations
                                                                                                                            • One or more equations did not get rendered due to their size.
                                                                                                                            Instances For
                                                                                                                              structure Complexity.WalkLayout (kk jj : ) :

                                                                                                                              Which register plays which role in the walk, and that the roles are distinct.

                                                                                                                              Instances For
                                                                                                                                theorem Complexity.WalkLayout.ruler_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The ruler is a block.

                                                                                                                                theorem Complexity.WalkLayout.par_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The parameter block is a block.

                                                                                                                                theorem Complexity.WalkLayout.mv_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The move cell is a block.

                                                                                                                                theorem Complexity.WalkLayout.dr_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The direction cell is a block.

                                                                                                                                theorem Complexity.WalkLayout.res_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The verdict register is a block.

                                                                                                                                theorem Complexity.WalkLayout.acc_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The accumulator is a block.

                                                                                                                                theorem Complexity.WalkLayout.cnt_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                The counter is a block.

                                                                                                                                theorem Complexity.WalkLayout.cnt'_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                So is its partner.

                                                                                                                                theorem Complexity.WalkLayout.target_lt {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                So is the target.

                                                                                                                                theorem Complexity.WalkLayout.codeA_lt {kk jj : } (L : WalkLayout kk jj) (p : ) :
                                                                                                                                p < kk + 3L.codeAIdx p < L.blocks

                                                                                                                                So is each of the old code's blocks.

                                                                                                                                theorem Complexity.WalkLayout.codeB_lt {kk jj : } (L : WalkLayout kk jj) (p : ) :
                                                                                                                                p < kk + 3L.codeBIdx p < L.blocks

                                                                                                                                And each of the new code's.

                                                                                                                                def Complexity.WalkLayout.stepIdx {kk jj : } (L : WalkLayout kk jj) (second : Bool) (p : ) :

                                                                                                                                The blocks one step of the pair guesses: the scratch, and one code tuple. The first step of a pair writes the new code's blocks and leaves the old code's registers alone; the second does the reverse. That is what chains a walk — the check of each step compares its guess against what the previous step really left behind — and what returns every code to its own registers after a pair.

                                                                                                                                Equations
                                                                                                                                Instances For

                                                                                                                                  How many blocks a step guesses.

                                                                                                                                  Equations
                                                                                                                                  Instances For
                                                                                                                                    theorem Complexity.WalkLayout.stepIdx_lt {kk jj : } (L : WalkLayout kk jj) (second : Bool) (p : ) (hp : p < L.stepBlocks) :
                                                                                                                                    L.stepIdx second p < L.blocks

                                                                                                                                    A step's blocks are blocks.

                                                                                                                                    theorem Complexity.WalkLayout.stepIdx_inj {kk jj : } (L : WalkLayout kk jj) (second : Bool) (p q : ) :
                                                                                                                                    p < L.stepBlocksq < L.stepBlocksL.stepIdx second p = L.stepIdx second qp = q

                                                                                                                                    A step guesses each of its blocks once.

                                                                                                                                    theorem Complexity.WalkLayout.stepIdx_codeA {kk jj : } (L : WalkLayout kk jj) (p : ) (hp : p < kk + 3) :

                                                                                                                                    The second step of a pair guesses the old code's blocks.

                                                                                                                                    theorem Complexity.WalkLayout.stepIdx_codeB {kk jj : } (L : WalkLayout kk jj) (p : ) (hp : p < kk + 3) :

                                                                                                                                    The first step guesses the new code's.

                                                                                                                                    theorem Complexity.WalkLayout.stepIdx_ne_codeA {kk jj : } (L : WalkLayout kk jj) (p q : ) (_hp : p < L.stepBlocks) (hq : q < kk + 3) :

                                                                                                                                    The first step guesses none of the old code's blocks.

                                                                                                                                    theorem Complexity.WalkLayout.stepIdx_ne_codeB {kk jj : } (L : WalkLayout kk jj) (p q : ) (hp : p < L.stepBlocks) (hq : q < kk + 3) :

                                                                                                                                    The second guesses none of the new code's.

                                                                                                                                    def Complexity.WalkLayout.par {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                    Fin (jj + 1)

                                                                                                                                    The parameter register.

                                                                                                                                    Equations
                                                                                                                                    Instances For
                                                                                                                                      def Complexity.WalkLayout.mv {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                      Fin (jj + 1)

                                                                                                                                      The move register.

                                                                                                                                      Equations
                                                                                                                                      Instances For
                                                                                                                                        def Complexity.WalkLayout.dr {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                        Fin (jj + 1)

                                                                                                                                        The direction register.

                                                                                                                                        Equations
                                                                                                                                        Instances For
                                                                                                                                          def Complexity.WalkLayout.res {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                          Fin (jj + 1)

                                                                                                                                          The input check's verdict register.

                                                                                                                                          Equations
                                                                                                                                          Instances For
                                                                                                                                            def Complexity.WalkLayout.acc {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                            Fin (jj + 1)

                                                                                                                                            The accumulator.

                                                                                                                                            Equations
                                                                                                                                            Instances For
                                                                                                                                              def Complexity.WalkLayout.cnt {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                              Fin (jj + 1)

                                                                                                                                              The counter.

                                                                                                                                              Equations
                                                                                                                                              Instances For
                                                                                                                                                def Complexity.WalkLayout.cnt' {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                Fin (jj + 1)

                                                                                                                                                The counter's partner.

                                                                                                                                                Equations
                                                                                                                                                Instances For
                                                                                                                                                  def Complexity.WalkLayout.target {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                  Fin (jj + 1)

                                                                                                                                                  The target.

                                                                                                                                                  Equations
                                                                                                                                                  Instances For
                                                                                                                                                    def Complexity.WalkLayout.codeA {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                    Fin (jj + 1)

                                                                                                                                                    The first code tuple's registers.

                                                                                                                                                    Equations
                                                                                                                                                    Instances For
                                                                                                                                                      def Complexity.WalkLayout.codeB {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                      Fin (jj + 1)

                                                                                                                                                      The second code tuple's registers.

                                                                                                                                                      Equations
                                                                                                                                                      Instances For
                                                                                                                                                        theorem Complexity.WalkLayout.reg_ne {kk jj : } (L : WalkLayout kk jj) {p q : } (hp : p < L.blocks) (hq : q < L.blocks) (h : L.role p L.role q) :
                                                                                                                                                        L.reg p L.reg q

                                                                                                                                                        Blocks with different roles live in different registers.

                                                                                                                                                        theorem Complexity.WalkLayout.codeA_ne_res {kk jj : } (L : WalkLayout kk jj) {r : } (hr : r < kk + 3) :
                                                                                                                                                        L.codeA r L.res

                                                                                                                                                        The verdict register is not a code register.

                                                                                                                                                        theorem Complexity.WalkLayout.codeB_ne_res {kk jj : } (L : WalkLayout kk jj) {r : } (hr : r < kk + 3) :
                                                                                                                                                        L.codeB r L.res

                                                                                                                                                        Nor is the other tuple's.

                                                                                                                                                        theorem Complexity.WalkLayout.par_ne_res {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                        L.par L.res

                                                                                                                                                        Nor the parameter block.

                                                                                                                                                        theorem Complexity.WalkLayout.mv_ne_res {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                        L.mv L.res

                                                                                                                                                        Nor the move cell.

                                                                                                                                                        theorem Complexity.WalkLayout.dr_ne_res {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                        L.dr L.res

                                                                                                                                                        Nor the direction cell.

                                                                                                                                                        theorem Complexity.WalkLayout.cnt_ne_res {kk jj : } (L : WalkLayout kk jj) :
                                                                                                                                                        L.cnt L.res

                                                                                                                                                        Nor either counter.

                                                                                                                                                        theorem Complexity.WalkLayout.cnt'_ne_res {kk jj : } (L : WalkLayout kk jj) :

                                                                                                                                                        Nor the counter's partner.

                                                                                                                                                        structure Complexity.WalkWidths (kk jj : ) (tm : NTM kk) (nn S wc : ) extends Complexity.WalkLayout kk jj :

                                                                                                                                                        The widths the layout's blocks are guessed at. A block of width n writes n + 1 bits, so a one-cell register — the direction, a verdict — has width zero.

                                                                                                                                                        Instances For
                                                                                                                                                          def Complexity.stepWidth {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (p : ) :

                                                                                                                                                          How wide that block is guessed. Both steps of a pair guess the same widths — a code's two tuples are laid out alike — so one width function serves both, and the guess stream advances by the same amount at every stage.

                                                                                                                                                          Equations
                                                                                                                                                          Instances For
                                                                                                                                                            theorem Complexity.stepWidth_scratch {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (p : ) (hp : p < L.scratch) :
                                                                                                                                                            stepWidth L p = L.width p

                                                                                                                                                            A scratch block is guessed at its own width.

                                                                                                                                                            theorem Complexity.stepWidth_code {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (p : ) (hp : p < kk + 3) :
                                                                                                                                                            stepWidth L (L.scratch + p) = codeWidthScan tm nn S p

                                                                                                                                                            A code block is guessed at the code's width.

                                                                                                                                                            theorem Complexity.width_stepIdx_false {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (p : ) (hp : p < L.stepBlocks) :

                                                                                                                                                            The first step of a pair guesses its blocks at those same widths.

                                                                                                                                                            noncomputable def Complexity.stageBits {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) :
                                                                                                                                                            Bool

                                                                                                                                                            What one stage of the walk must guess: the ruler, the transition's parameters, the two direction cells, the counters and the target, and the two code tuples. Everything else is a verdict register, whose guessed value is overwritten before it is read.

                                                                                                                                                            Equations
                                                                                                                                                            • One or more equations did not get rendered due to their size.
                                                                                                                                                            Instances For
                                                                                                                                                              theorem Complexity.stageBits_codeA {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) (r : ) (hr : r < kk + 3) (q : ) :
                                                                                                                                                              stageBits L x dc P d cOld cNew tgt accBit aOld aNew (L.codeAIdx r) q = (codeBlockScan tm x S aOld r).getD q false

                                                                                                                                                              The code blocks a stage guesses are the code's own.

                                                                                                                                                              theorem Complexity.stageBits_codeB {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) (r : ) (hr : r < kk + 3) (q : ) :
                                                                                                                                                              stageBits L x dc P d cOld cNew tgt accBit aOld aNew (L.codeBIdx r) q = (codeBlockScan tm x S aNew r).getD q false

                                                                                                                                                              And the other tuple's are the successor's.

                                                                                                                                                              theorem Complexity.stageBits_par {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) (q : ) :
                                                                                                                                                              stageBits L x dc P d cOld cNew tgt accBit aOld aNew L.parIdx q = ((succParamsCodec tm.Q kk).enc P).getD q false

                                                                                                                                                              The parameter block a stage guesses is the transition's encoding.

                                                                                                                                                              theorem Complexity.stageBits_cnt {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) (q : ) :
                                                                                                                                                              stageBits L x dc P d cOld cNew tgt accBit aOld aNew L.cntIdx q = (bitsOfLenLE wc cOld).getD q false

                                                                                                                                                              The counter a stage guesses holds its value.

                                                                                                                                                              theorem Complexity.stageBits_cnt' {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) (q : ) :
                                                                                                                                                              stageBits L x dc P d cOld cNew tgt accBit aOld aNew L.cnt'Idx q = (bitsOfLenLE wc cNew).getD q false

                                                                                                                                                              And its partner the next value.

                                                                                                                                                              theorem Complexity.stageBits_target {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (P : SuccParams tm.Q kk) (d : Dir3) (cOld cNew tgt : ) (accBit : Bool) (aOld aNew : Code tm.Q kk x.length S) (q : ) :
                                                                                                                                                              stageBits L x dc P d cOld cNew tgt accBit aOld aNew L.targetIdx q = (bitsOfLenLE wc tgt).getD q false

                                                                                                                                                              And the target its own.

                                                                                                                                                              noncomputable def Complexity.walkCert {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) :
                                                                                                                                                              Bool

                                                                                                                                                              The certificate for a whole walk: what every stage guesses, given the codes it visits, the transitions it takes, the directions those imply and the counter values.

                                                                                                                                                              Equations
                                                                                                                                                              Instances For
                                                                                                                                                                theorem Complexity.walkCert_codeA {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (s r : ) (hr : r < kk + 3) (q : ) :
                                                                                                                                                                walkCert L x dc Ps ds cOlds cNews tgt f s (L.codeAIdx r) q = (codeBlockScan tm x S (f s) r).getD q false

                                                                                                                                                                A stage's code blocks come off the certificate as that stage's codes.

                                                                                                                                                                theorem Complexity.walkCert_codeB {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (s r : ) (hr : r < kk + 3) (q : ) :
                                                                                                                                                                walkCert L x dc Ps ds cOlds cNews tgt f s (L.codeBIdx r) q = (codeBlockScan tm x S (f (s + 1)) r).getD q false

                                                                                                                                                                And the other tuple's as the next code's.

                                                                                                                                                                def Complexity.walkReg {jj r : } (i : Fin (jj + 1)) :
                                                                                                                                                                Fin (jj + 2 + r + 1)

                                                                                                                                                                Embed a register index into the walk machine's tape set: the registers, then the scan's result tape, then the guess tape.

                                                                                                                                                                Equations
                                                                                                                                                                Instances For

                                                                                                                                                                  How many guess bits an iteration of the walk consumes: one stage per step, two steps to an iteration.

                                                                                                                                                                  Equations
                                                                                                                                                                  Instances For
                                                                                                                                                                    theorem Complexity.walkReg_ne_last {jj r : } (i : Fin (jj + 1)) :
                                                                                                                                                                    walkReg i Fin.last (jj + 2 + r)

                                                                                                                                                                    A register of the walk is never the guess tape.

                                                                                                                                                                    theorem Complexity.walkReg_inj {jj r : } {i i' : Fin (jj + 1)} (h : walkReg i = walkReg i') :
                                                                                                                                                                    i = i'

                                                                                                                                                                    Distinct registers are distinct tapes.

                                                                                                                                                                    def Complexity.stepReg {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (second : Bool) (p : ) :
                                                                                                                                                                    Fin (jj + 2 + r + 1)

                                                                                                                                                                    The tape a step's p-th guessed block goes to.

                                                                                                                                                                    Equations
                                                                                                                                                                    Instances For
                                                                                                                                                                      theorem Complexity.blockLen_le_codeWidthScan {kk : } (tm : NTM kk) (nn S r : ) :
                                                                                                                                                                      blockLen tm nn S r codeWidthScan tm nn S r + 1

                                                                                                                                                                      A block's own bits fit in the width it is guessed at.

                                                                                                                                                                      theorem Complexity.holdsBits_block_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (b : Bool) (g : Bool) (hs : TM.StageBlocks L.width L.blocks b g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (p : ) (hp : p < L.blocks) (bits : List Bool) (hbits : ∀ (q : ) (hq : q < bits.length), b s p q = bits[q]) (hlen : bits.length L.width p + 1) :
                                                                                                                                                                      HoldsBits (fun (c : ) (i : Fin (jj + 2 + r + 1)) => (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W i).cells c) 0 (walkReg (L.reg p)) bits

                                                                                                                                                                      After a stage, each register holds the bits the certificate names for it.

                                                                                                                                                                      theorem Complexity.holdsBits_block_of_step {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (second : Bool) (b : Bool) (g : Bool) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks b g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L second p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (p : ) (hp : p < L.stepBlocks) (bits : List Bool) (hbits : ∀ (q : ) (hq : q < bits.length), b s p q = bits[q]) (hlen : bits.length stepWidth L p + 1) :
                                                                                                                                                                      HoldsBits (fun (c : ) (i : Fin (jj + 2 + r + 1)) => (TM.guessBlocksTapes (stepReg L second) (stepWidth L) L.stepBlocks W i).cells c) 0 (stepReg L second p) bits

                                                                                                                                                                      What a step's guess leaves on each of its own blocks. The stage version guesses every block; a step guesses only its own, and this says nothing about the rest — which is what lets the other code tuple survive the step untouched.

                                                                                                                                                                      theorem Complexity.holdsBits_codeA_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (r✝ : ) :
                                                                                                                                                                      r✝ < kk + 3HoldsBits (fun (c : ) (i : Fin (jj + 2 + r + 1)) => (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W i).cells c) 0 (walkReg (L.codeA r✝)) (codeBlockScan tm x S (f s) r✝)

                                                                                                                                                                      The old code's registers hold the code the certificate names.

                                                                                                                                                                      theorem Complexity.holdsBits_codeB_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (r✝ : ) :
                                                                                                                                                                      r✝ < kk + 3HoldsBits (fun (c : ) (i : Fin (jj + 2 + r + 1)) => (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W i).cells c) 0 (walkReg (L.codeB r✝)) (codeBlockScan tm x S (f (s + 1)) r✝)

                                                                                                                                                                      The new code's registers hold the next code.

                                                                                                                                                                      theorem Complexity.holdsBits_par_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                      HoldsBits (fun (c : ) (i : Fin (jj + 2 + r + 1)) => (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W i).cells c) 0 (walkReg L.par) ((succParamsCodec tm.Q kk).enc (Ps s))

                                                                                                                                                                      The parameter register holds the transition the certificate names.

                                                                                                                                                                      theorem Complexity.holdsBits_cnt_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                      HoldsBits (fun (c : ) (i : Fin (jj + 2 + r + 1)) => (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W i).cells c) 0 (walkReg L.cnt) (bitsOfLenLE wc (cOlds s))

                                                                                                                                                                      A counter register holds the value the certificate names.

                                                                                                                                                                      theorem Complexity.cell_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (b : Bool) (g : Bool) (hs : TM.StageBlocks L.width L.blocks b g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (p : ) (hp : p < L.blocks) (hw : L.width p = 0) (sym : Γ) (hbit : sym = Γ.zero sym = Γ.one) (hcert : b s p 0 = decide (sym = Γ.one)) :
                                                                                                                                                                      (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W (walkReg (L.reg p))).cells 1 = sym

                                                                                                                                                                      A one-cell register holds the symbol the certificate names.

                                                                                                                                                                      theorem Complexity.cell_mv_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                      (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W (walkReg L.mv)).cells 1 = dc.encMove (ds s)

                                                                                                                                                                      The move register holds what the certificate names.

                                                                                                                                                                      theorem Complexity.cell_dr_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                      (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W (walkReg L.dr)).cells 1 = dc.enc (ds s)

                                                                                                                                                                      The direction register holds what the certificate names.

                                                                                                                                                                      theorem Complexity.ruler_of_stage {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (q : ) :
                                                                                                                                                                      1 qq walkScanLen tm x.length S(TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W (walkReg (L.reg L.rulerIdx))).cells q = Γ.one

                                                                                                                                                                      The ruler register spans the scan. This is what makes the scan's length well defined.

                                                                                                                                                                      noncomputable def Complexity.stageCells {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (W : Fin (jj + 2 + r + 1)Tape) :
                                                                                                                                                                      Fin (jj + 1)Γ

                                                                                                                                                                      The registers a stage leaves behind, indexed by register.

                                                                                                                                                                      Equations
                                                                                                                                                                      Instances For
                                                                                                                                                                        noncomputable def Complexity.stageCols {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (W : Fin (jj + 2 + r + 1)Tape) :
                                                                                                                                                                        Fin (jj + 1)Γ

                                                                                                                                                                        The same, as the scan sees them: indexed by cell first.

                                                                                                                                                                        Equations
                                                                                                                                                                        Instances For
                                                                                                                                                                          theorem Complexity.walkReg_reg_inj {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (p q : ) :
                                                                                                                                                                          p < L.blocksq < L.blockswalkReg (L.reg p) = walkReg (L.reg q)p = q

                                                                                                                                                                          Distinct blocks are guessed into distinct tapes.

                                                                                                                                                                          theorem Complexity.stageCells_retained {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (i : Fin (jj + 1)) (hne : p < L.blocks, i L.reg p) :
                                                                                                                                                                          stageCells L W i = (W (walkReg i)).cells

                                                                                                                                                                          A register that no block is guessed into keeps what it held. This is what chains a walk: the step that guesses the new code leaves the old code's registers alone, so its check compares the guess against what the previous step really left behind, not against a fresh guess.

                                                                                                                                                                          noncomputable def Complexity.stepCells {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (second : Bool) (W : Fin (jj + 2 + r + 1)Tape) :
                                                                                                                                                                          Fin (jj + 1)Γ

                                                                                                                                                                          The registers a step's guess leaves behind: its own blocks as the certificate names them, every other tape exactly as it was.

                                                                                                                                                                          Equations
                                                                                                                                                                          Instances For
                                                                                                                                                                            noncomputable def Complexity.stepCert {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (aOld aNew : Code tm.Q kk x.length S) (second : Bool) :
                                                                                                                                                                            Bool

                                                                                                                                                                            The certificate a step guesses, read through the step's own block numbering. The two codes are given per stage, because which family is the old one alternates along a pair.

                                                                                                                                                                            Equations
                                                                                                                                                                            Instances For
                                                                                                                                                                              theorem Complexity.stepReg_scratch {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (second : Bool) (p : ) (hp : p < L.scratch) :
                                                                                                                                                                              stepReg L second p = walkReg (L.reg p)

                                                                                                                                                                              A scratch block keeps its own number in a step's numbering.

                                                                                                                                                                              theorem Complexity.stepCert_scratch {kk jj : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (x : List Bool) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (aOld aNew : Code tm.Q kk x.length S) (second : Bool) (s p : ) (hp : p < L.scratch) :
                                                                                                                                                                              stepCert L x dc Ps ds cOlds cNews tgt aOld aNew second s p = stageBits L x dc (Ps s) (ds s) (cOlds s) (cNews s) tgt true (aOld s) (aNew s) p

                                                                                                                                                                              And so does its certificate.

                                                                                                                                                                              theorem Complexity.stepCells_retained {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (second : Bool) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (i : Fin (jj + 1)) (hne : p < L.stepBlocks, walkReg i stepReg L second p) :
                                                                                                                                                                              stepCells L second W i = (W (walkReg i)).cells

                                                                                                                                                                              A register no block of the step is guessed into keeps what it held.

                                                                                                                                                                              theorem Complexity.stageCols_par {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                              HoldsBits (stageCols L W) 0 L.par ((succParamsCodec tm.Q kk).enc (Ps s))

                                                                                                                                                                              What a stage leaves on the parameter register, as the scan sees it.

                                                                                                                                                                              theorem Complexity.stageCols_codeA {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (r✝ : ) :
                                                                                                                                                                              r✝ < kk + 3HoldsBits (stageCols L W) 0 (L.codeA r✝) (codeBlockScan tm x S (f s) r✝)

                                                                                                                                                                              And on the old code's registers.

                                                                                                                                                                              theorem Complexity.stageCols_codeB {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) (r✝ : ) :
                                                                                                                                                                              r✝ < kk + 3HoldsBits (stageCols L W) 0 (L.codeB r✝) (codeBlockScan tm x S (f (s + 1)) r✝)

                                                                                                                                                                              And on the new code's.

                                                                                                                                                                              theorem Complexity.stageCols_cnt {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                              HoldsBits (stageCols L W) 0 L.cnt (bitsOfLenLE wc (cOlds s))

                                                                                                                                                                              And on the counter.

                                                                                                                                                                              theorem Complexity.stageCols_cnt' {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                              HoldsBits (stageCols L W) 0 L.cnt' (bitsOfLenLE wc (cNews s))

                                                                                                                                                                              And on the counter's partner.

                                                                                                                                                                              theorem Complexity.stageCols_target {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :

                                                                                                                                                                              And on the target the counter is compared against.

                                                                                                                                                                              theorem Complexity.stageCols_mv {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                              stageCols L W 1 L.mv = dc.encMove (ds s)

                                                                                                                                                                              And on the move cell.

                                                                                                                                                                              theorem Complexity.stageCols_dr {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                              stageCols L W 1 L.dr = dc.enc (ds s)

                                                                                                                                                                              And on the direction cell.

                                                                                                                                                                              structure Complexity.StageCols {kk jj : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (cA cB : Fin (jj + 1)) (cO cN : Fin (jj + 1)) (s : ) (cells : Fin (jj + 1)Γ) :

                                                                                                                                                                              What the registers hold when a stage's scan runs. The scan cannot tell whether a register was guessed at this stage or left behind by an earlier one, so the acceptance lemmas take this bundle rather than the guess that produced it.

                                                                                                                                                                              • par : HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) 0 L.par ((succParamsCodec tm.Q kk).enc (Ps s))

                                                                                                                                                                                The parameter block names the transition the step takes.

                                                                                                                                                                              • codeA (p : ) : p < kk + 3HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) 0 (cA p) (codeBlockScan tm x S (f s) p)

                                                                                                                                                                                The old code's registers hold the code the step starts from.

                                                                                                                                                                              • codeB (p : ) : p < kk + 3HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) 0 (cB p) (codeBlockScan tm x S (f (s + 1)) p)

                                                                                                                                                                                The new code's registers hold the code it reaches.

                                                                                                                                                                              • cnt : HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) 0 cO (bitsOfLenLE wc (cOlds s))

                                                                                                                                                                                The counter.

                                                                                                                                                                              • cnt' : HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) 0 cN (bitsOfLenLE wc (cNews s))

                                                                                                                                                                                Its partner, which the step compares it against.

                                                                                                                                                                              • target : HoldsBits (fun (q : ) (i : Fin (jj + 1)) => cells i q) 0 L.target (bitsOfLenLE wc tgt)

                                                                                                                                                                                The target the walk is counting towards.

                                                                                                                                                                              • mv : cells L.mv 1 = dc.encMove (ds s)

                                                                                                                                                                                The move cell of the guessed direction.

                                                                                                                                                                              • dr : cells L.dr 1 = dc.enc (ds s)

                                                                                                                                                                                Its direction cell.

                                                                                                                                                                              Instances For
                                                                                                                                                                                theorem Complexity.StageCols.swapCnt {kk jj : } {tm : NTM kk} {S wc : } {x : List Bool} {L : WalkWidths kk jj tm x.length S wc} {dc : DirCodec} {Ps : SuccParams tm.Q kk} {ds : Dir3} {cOlds cNews : } {tgt : } {f : Code tm.Q kk x.length S} {cA cB : Fin (jj + 1)} {cO cN : Fin (jj + 1)} {s : } {cells : Fin (jj + 1)Γ} (h : StageCols x L dc Ps ds cOlds cNews tgt f cA cB cO cN s cells) (hval : cNews s = cOlds s) :
                                                                                                                                                                                StageCols x L dc Ps ds cOlds cNews tgt f cA cB cN cO s cells

                                                                                                                                                                                When the two counter registers agree, their roles can be exchanged. The walk's counter registers are vestigial — TM.binaryForTM owns the loop's index — so both steps of a pair check only that the counter is unchanged, and it does not matter which register plays which role.

                                                                                                                                                                                theorem Complexity.stageCols_holds {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (hs : TM.StageBlocks L.width L.blocks (walkCert L x dc Ps ds cOlds cNews tgt f) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.blocks, (W (walkReg (L.reg p))).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                                StageCols x L dc Ps ds cOlds cNews tgt f L.codeA L.codeB L.cnt L.cnt' s (stageCells L W)

                                                                                                                                                                                A stage's guess establishes the bundle.

                                                                                                                                                                                theorem Complexity.cell_of_step {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (second : Bool) (b : Bool) (g : Bool) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks b g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L second p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (p : ) (hp : p < L.stepBlocks) (hw : stepWidth L p = 0) (sym : Γ) (hbit : sym = Γ.zero sym = Γ.one) (hcert : b s p 0 = decide (sym = Γ.one)) :
                                                                                                                                                                                (TM.guessBlocksTapes (stepReg L second) (stepWidth L) L.stepBlocks W (stepReg L second p)).cells 1 = sym

                                                                                                                                                                                A one-cell block of a step's guess.

                                                                                                                                                                                theorem Complexity.stepCols_holds {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f aOld aNew : Code tm.Q kk x.length S) (g : Bool) (second : Bool) (cA cB : Fin (jj + 1)) (s : ) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks (stepCert L x dc Ps ds cOlds cNews tgt aOld aNew second) g) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L second p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (hcB : p < kk + 3, stepReg L second (L.scratch + p) = walkReg (cB p)) (hcertB : p < kk + 3, ∀ (q : ), stepCert L x dc Ps ds cOlds cNews tgt aOld aNew second s (L.scratch + p) q = (codeBlockScan tm x S (f (s + 1)) p).getD q false) (hret : p < kk + 3, HoldsBits (fun (q : ) (i : Fin (jj + 1)) => (W (walkReg i)).cells q) 0 (cA p) (codeBlockScan tm x S (f s) p)) (hretReg : p < kk + 3, p' < L.stepBlocks, walkReg (cA p) stepReg L second p') :
                                                                                                                                                                                StageCols x L dc Ps ds cOlds cNews tgt f cA cB L.cnt L.cnt' s (stepCells L second W)

                                                                                                                                                                                What a step's registers hold when its scan runs. The step's own blocks come from the certificate; the other code tuple is whatever the previous step left behind, which the caller supplies. That is the chaining — each check compares a guess against a retained code, never two guesses against each other.

                                                                                                                                                                                theorem Complexity.stepCols_holds_first {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (s : ) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks (stepCert L x dc Ps ds cOlds cNews tgt f (fun (s : ) => f (s + 1)) false) g) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L false p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (hret : p < kk + 3, HoldsBits (fun (q : ) (i : Fin (jj + 1)) => (W (walkReg i)).cells q) 0 (L.codeA p) (codeBlockScan tm x S (f s) p)) :
                                                                                                                                                                                StageCols x L dc Ps ds cOlds cNews tgt f L.codeA L.codeB L.cnt L.cnt' s (stepCells L false W)

                                                                                                                                                                                The first step of a pair. It guesses the new code's registers and keeps the old code's, so its scan compares its guess against what the step before really left behind.

                                                                                                                                                                                theorem Complexity.stepCols_holds_second {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (g : Bool) (s : ) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks (stepCert L x dc Ps ds cOlds cNews tgt (fun (s : ) => f (s + 1)) f true) g) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L true p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (hret : p < kk + 3, HoldsBits (fun (q : ) (i : Fin (jj + 1)) => (W (walkReg i)).cells q) 0 (L.codeB p) (codeBlockScan tm x S (f s) p)) :
                                                                                                                                                                                StageCols x L dc Ps ds cOlds cNews tgt f L.codeB L.codeA L.cnt L.cnt' s (stepCells L true W)

                                                                                                                                                                                The second step of a pair. The families have swapped roles: it guesses the old code's registers and keeps the new code's, which is what returns each code to the registers it started in.

                                                                                                                                                                                theorem Complexity.stage_accepts_stay {kk jj : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (cA cB : Fin (jj + 1)) (cO cN : Fin (jj + 1)) (hcA : p < kk + 3, cA p L.res) (hcB : p < kk + 3, cB p L.res) (hcO : cO L.res) (hcN : cN L.res) (s : ) (cells : Fin (jj + 1)Γ) (hc : StageCols x L dc Ps ds cOlds cNews tgt f cA cB cO cN s cells) (advance : Bool) (gsym : Γ) (hstay : f (s + 1) = f s) (hd : ds s = Dir3.stay) (hwc : wc walkScanLen tm x.length S) (hu : cOlds s < 2 ^ wc) (hv : cNews s < 2 ^ wc) (hmove : if advance = true then cNews s = cOlds s + 1 else cOlds s = cNews s) :
                                                                                                                                                                                (walkStepScanner tm x.length S L.par L.mv L.dr L.res cO cN wc advance dc cA cB).emit ((walkStepScanner tm x.length S L.par L.mv L.dr L.res cO cN wc advance dc cA cB).run (fun (q : ) (i : Fin (jj + 1)) => checkedCells cells L.par L.res gsym i q) (walkScanLen tm x.length S)) = true

                                                                                                                                                                                A stage of a walk that stays put is accepted. Every hypothesis is now about the walk and the guess tape: the certificate supplies the registers, and the input check leaves them alone.

                                                                                                                                                                                theorem Complexity.stage_accepts_succ {kk jj : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (f : Code tm.Q kk x.length S) (cA cB : Fin (jj + 1)) (cO cN : Fin (jj + 1)) (hcA : p < kk + 3, cA p L.res) (hcB : p < kk + 3, cB p L.res) (hcO : cO L.res) (hcN : cN L.res) (s : ) (cells : Fin (jj + 1)Γ) (hc : StageCols x L dc Ps ds cOlds cNews tgt f cA cB cO cN s cells) (advance β : Bool) (hPs : Ps s = paramsOf tm x S (f s) β) (hsucc : f (s + 1) = succCode tm x S β (f s)) (hds : ds s = adjustedDir (succTrans tm (Ps s)).2.2.2.1 (f s).2.1) (hclampIn : movedIdx (succTrans tm (Ps s)).2.2.2.1 (f s).2.1 x.length + S + 1) (hclampW : ∀ (i : Fin kk), movedIdx (succDir tm (Ps s) i) ((f s).2.2.1 i).1 S) (hclampO : movedIdx (succTrans tm (Ps s)).2.2.2.2.2 (f s).2.2.2.1 S + 1) (hleft : (succTrans tm (Ps s)).2.2.2.1 = Dir3.left0 < (f s).2.1) (hwc : wc walkScanLen tm x.length S) (hu : cOlds s < 2 ^ wc) (hv : cNews s < 2 ^ wc) (hmove : if advance = true then cNews s = cOlds s + 1 else cOlds s = cNews s) :
                                                                                                                                                                                (walkStepScanner tm x.length S L.par L.mv L.dr L.res cO cN wc advance dc cA cB).emit ((walkStepScanner tm x.length S L.par L.mv L.dr L.res cO cN wc advance dc cA cB).run (fun (q : ) (i : Fin (jj + 1)) => checkedCells cells L.par L.res (inSymOf tm x S (f s)) i q) (walkScanLen tm x.length S)) = true

                                                                                                                                                                                A stage of a walk that advances is accepted. The input check's verdict is not assumed: it follows, because the certificate names the transition the code really takes, whose input symbol is the one the machine's own head is over.

                                                                                                                                                                                theorem Complexity.ruler_of_step {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (aOld aNew : Code tm.Q kk x.length S) (g : Bool) (second : Bool) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks (stepCert L x dc Ps ds cOlds cNews tgt aOld aNew second) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L second p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (q : ) :
                                                                                                                                                                                1 qq walkScanLen tm x.length SstepCells L second W (L.reg L.rulerIdx) q = Γ.one

                                                                                                                                                                                A step's ruler register spans the scan, which is what makes the scan well formed.

                                                                                                                                                                                theorem Complexity.scanTape_of_step {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (dc : DirCodec) (Ps : SuccParams tm.Q kk) (ds : Dir3) (cOlds cNews : ) (tgt : ) (aOld aNew : Code tm.Q kk x.length S) (g : Bool) (second : Bool) (hs : TM.StageBlocks (stepWidth L) L.stepBlocks (stepCert L x dc Ps ds cOlds cNews tgt aOld aNew second) g) (s : ) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (hr1 : p < L.stepBlocks, (W (stepReg L second p)).head = 1) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) (hblank : (W (walkReg (L.reg L.rulerIdx))).cells (walkScanLen tm x.length S + 1) = Γ.blank) :
                                                                                                                                                                                TM.ScanTape (stepCells L second W) (walkScanLen tm x.length S)

                                                                                                                                                                                A step's registers make a well-formed scan. The ruler spans the scan, and the blank that stops the scan is the ruler tape's own — the guess writes up to the ruler's width and no further, so a caller only has to know that the tape was blank there to begin with.

                                                                                                                                                                                theorem Complexity.guessFrom_after_step {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (second : Bool) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (g : Bool) (s : ) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                                TM.GuessFrom (fun (q : ) => g ((s + 1) * TM.guessOffset (stepWidth L) L.stepBlocks + q)) (TM.guessBlocksTapes (stepReg L second) (stepWidth L) L.stepBlocks W (Fin.last (jj + 2 + r)))

                                                                                                                                                                                A step advances the guess tape by exactly its own consumption, so the guess-tape clause of the walk's invariant is re-established one step further on.

                                                                                                                                                                                theorem Complexity.guessFrom_after_stage {kk jj r : } {tm : NTM kk} {nn S wc : } (L : WalkWidths kk jj tm nn S wc) (W : Fin (jj + 2 + r + 1)Tape) (hinv : ∀ (i : Fin (jj + 2 + r + 1)), (W i).StartInvariant) (hh : ∀ (i : Fin (jj + 2 + r + 1)), 1 (W i).head) (g : Bool) (s : ) (hgf : TM.GuessFrom (fun (q : ) => g (s * TM.guessOffset L.width L.blocks + q)) (W (Fin.last (jj + 2 + r)))) :
                                                                                                                                                                                TM.GuessFrom (fun (q : ) => g ((s + 1) * TM.guessOffset L.width L.blocks + q)) (TM.guessBlocksTapes (fun (p : ) => walkReg (L.reg p)) L.width L.blocks W (Fin.last (jj + 2 + r)))

                                                                                                                                                                                A stage advances the guess tape by exactly its own consumption. So the guess-tape clause of the invariant is re-established one stage further on.

                                                                                                                                                                                The walk loop's invariant #

                                                                                                                                                                                After j iterations the counter names j, the code registers hold the 2j-th code of the walk — two steps per iteration — and the machine's own input head sits where that code's input head does, which is what lets TM.inMatchTM check the guessed symbol against the real tape.

                                                                                                                                                                                def Complexity.WalkStepInv {kk jj r : } {tm : NTM kk} {S wc : } (x : List Bool) (L : WalkWidths kk jj tm x.length S wc) (cOld : Fin (jj + 1)) (f : Code tm.Q kk x.length S) (g : Bool) (s : ) :
                                                                                                                                                                                TM.TapePred (jj + 2 + r + 1)

                                                                                                                                                                                What holds between the steps of a walk. The registers are parked and the ruler tape's blank still stops the scan; the code the next step will check against sits in the family that step retains; the machine's own input head is where that code says; and the guess tape is positioned at the step's own share of the certificate.

                                                                                                                                                                                Equations
                                                                                                                                                                                • One or more equations did not get rendered due to their size.
                                                                                                                                                                                Instances For
                                                                                                                                                                                  def Complexity.WalkLoopInv {kk jj r : } (tm : NTM kk) (x : List Bool) (S : ) (cnt : Fin (jj + 1)) (wc : ) (jold : Fin (jj + 1)) (f : Code tm.Q kk x.length S) (g : Bool) (w : ) (t j : ) :
                                                                                                                                                                                  TM.TapePred (jj + 2 + r + 1)

                                                                                                                                                                                  The walk loop's invariant after j iterations.

                                                                                                                                                                                  Equations
                                                                                                                                                                                  • One or more equations did not get rendered due to their size.
                                                                                                                                                                                  Instances For
                                                                                                                                                                                    theorem Complexity.holdsCounter_of_walkLoopInv {kk jj r : } (tm : NTM kk) (x : List Bool) (S : ) (cnt : Fin (jj + 1)) (wc : ) (jold : Fin (jj + 1)) (f : Code tm.Q kk x.length S) (g : Bool) (w : ) (t j : ) (inp : Tape) (work : Fin (jj + 2 + r + 1)Tape) (out : Tape) (h : WalkLoopInv tm x S cnt wc jold f g w t j inp work out) :
                                                                                                                                                                                    HoldsCounter (walkReg cnt) wc j inp work out

                                                                                                                                                                                    The invariant pins the counter, so Complexity.counterLoop_hoareTime applies to the walk.

                                                                                                                                                                                    theorem Complexity.inSym_of_walkLoopInv {kk jj r : } (tm : NTM kk) (x : List Bool) (S : ) (cnt : Fin (jj + 1)) (wc : ) (jold : Fin (jj + 1)) (f : Code tm.Q kk x.length S) (g : Bool) (w : ) (t j : ) (inp : Tape) (work : Fin (jj + 2 + r + 1)Tape) (out : Tape) (h : WalkLoopInv tm x S cnt wc jold f g w t j inp work out) (hne : (f (2 * j)).2.1 0) :
                                                                                                                                                                                    inp.read = inSymOf tm x S (f (2 * j))

                                                                                                                                                                                    The invariant says what symbol the simulated input head is over, whenever that head is off the marker. At the marker no machine can keep its own head in place, and none needs to: the symbol there is , which the code's head field already says.

                                                                                                                                                                                    theorem Complexity.inp_read_ne_start_of_walkLoopInv {kk jj r : } (tm : NTM kk) (x : List Bool) (S : ) (cnt : Fin (jj + 1)) (wc : ) (jold : Fin (jj + 1)) (f : Code tm.Q kk x.length S) (g : Bool) (w : ) (t j : ) (inp : Tape) (work : Fin (jj + 2 + r + 1)Tape) (out : Tape) (h : WalkLoopInv tm x S cnt wc jold f g w t j inp work out) :

                                                                                                                                                                                    The machine's input head is never on the marker, which is what lets a step read it.

                                                                                                                                                                                    theorem Complexity.guessFrom_of_walkLoopInv {kk jj r : } (tm : NTM kk) (x : List Bool) (S : ) (cnt : Fin (jj + 1)) (wc : ) (jold : Fin (jj + 1)) (f : Code tm.Q kk x.length S) (g : Bool) (w : ) (t j : ) (inp : Tape) (work : Fin (jj + 2 + r + 1)Tape) (out : Tape) (h : WalkLoopInv tm x S cnt wc jold f g w t j inp work out) :
                                                                                                                                                                                    TM.GuessFrom (fun (q : ) => g (j * walkGuessStride w t + q)) (work (Fin.last (jj + 2 + r)))

                                                                                                                                                                                    The invariant says what the guess tape still holds, which is what lets an iteration find the guesses it needs.

                                                                                                                                                                                    The blocks an iteration guesses are read off the stream. The first stage of iteration j starts at j * walkGuessStride w t, the second a stage further on.

                                                                                                                                                                                    theorem Complexity.walkLoop_hoareTime {kk : } (tm : NTM kk) (x : List Bool) (S : ) {jj : } (R : CodeRegs kk jj) (cnt : Fin (jj + 1)) (wc : ) (f : Code tm.Q kk x.length S) (N b : ) (body test : TM (jj + 1)) {post : TM.TapePred (jj + 1)} (hstep : j < N, ∀ (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape), WalkInv tm x S R cnt wc f j inp work out∃ (inp' : Tape) (work' : Fin (jj + 1)Tape) (out' : Tape), tb, (body.loopTM test).reachesIn t { state := (body.loopTM test).qstart, input := inp, work := work, output := out } { state := (body.loopTM test).qstart, input := inp', work := work', output := out' } WalkInv tm x S R cnt wc f (j + 1) inp' work' out') (hstop : ∀ (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape), WalkInv tm x S R cnt wc f N inp work out∃ (c' : Cfg (jj + 1) (body.loopTM test).Q), tb, (body.loopTM test).reachesIn t { state := (body.loopTM test).qstart, input := inp, work := work, output := out } c' (body.loopTM test).halted c' post c'.input c'.work c'.output) :
                                                                                                                                                                                    (body.loopTM test).HoareTime (WalkInv tm x S R cnt wc f 0) post ((N + 1) * b)

                                                                                                                                                                                    The walk loop. Given a body that carries the invariant one step forward, and a test that halts at N, the loop carries the initial code to the N-th code of the walk. The counter names the loop's index, which is what makes the rule's variant decrease.

                                                                                                                                                                                    theorem Complexity.counterVal_of_holdsCounter {jj : } (cnt : Fin (jj + 1)) (wc v : ) (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape) (h : HoldsCounter cnt wc v inp work out) :
                                                                                                                                                                                    counterVal cnt wc work = v

                                                                                                                                                                                    The counter reads back the value a counter predicate pins.

                                                                                                                                                                                    theorem Complexity.counter_succ_of_plusOne {jj : } (cnt cnt' : Fin (jj + 1)) (wc u v : ) (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape) (hu : HoldsCounter cnt wc u inp work out) (hv : HoldsCounter cnt' wc v inp work out) (hscan : (Scanner.plusOne jj cnt cnt').emit ((Scanner.plusOne jj cnt cnt').run (fun (p : ) (i : Fin (jj + 1)) => (work i).cells p) wc) = true) :
                                                                                                                                                                                    v = u + 1

                                                                                                                                                                                    The increment check advances a counter. A loop does not compute its next index: it guesses it into a second register and checks it here.

                                                                                                                                                                                    theorem Complexity.counterLoop_hoareTime {jj : } (cnt : Fin (jj + 1)) (wc : ) (E : TM.TapePred (jj + 1)) (hE : ∀ (j : ) (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape), E j inp work outHoldsCounter cnt wc j inp work out) (N b : ) (body test : TM (jj + 1)) {post : TM.TapePred (jj + 1)} (hstep : j < N, ∀ (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape), E j inp work out∃ (inp' : Tape) (work' : Fin (jj + 1)Tape) (out' : Tape), tb, (body.loopTM test).reachesIn t { state := (body.loopTM test).qstart, input := inp, work := work, output := out } { state := (body.loopTM test).qstart, input := inp', work := work', output := out' } E (j + 1) inp' work' out') (hstop : ∀ (inp : Tape) (work : Fin (jj + 1)Tape) (out : Tape), E N inp work out∃ (c' : Cfg (jj + 1) (body.loopTM test).Q), tb, (body.loopTM test).reachesIn t { state := (body.loopTM test).qstart, input := inp, work := work, output := out } c' (body.loopTM test).halted c' post c'.input c'.work c'.output) :
                                                                                                                                                                                    (body.loopTM test).HoareTime (E 0) post ((N + 1) * b)

                                                                                                                                                                                    A counter-driven loop. Any invariant family whose members pin the counter to their index satisfies the indexed loop rule — the counter names the index, so the rule's variant decreases. The walk, the enumeration of codes and the enumeration of rounds all have this shape.