Checking one tape window against its successor #
⚠️ Unreviewed by Bolton
A configuration of the simulated machine is held in registers, one per field, and the machine checks a guessed successor rather than computing one — on a nondeterministic machine that is free, and checking is a scan.
This file is the part of that check concerning one tape window. The window is a marked block: one chunk per cell, each chunk three bits, the head marker first so that a rightward scan knows whether the head is on a cell before it reads that cell's symbol. The checks are
- the marker is on exactly one chunk,
- the symbols agree everywhere except under the marker, where the new window carries the written symbol — except at cell zero, where a write is a no-op,
- the new marker sits where the direction says.
Each is a fold over chunks, and Complexity.Scanner.cellFold_chunk turns it into the cell-level
fold a Complexity.Scanner runs.
Main definitions #
Complexity.markOf,Complexity.symOf— the marker and symbol of a chunkComplexity.markCount— how many chunks carry the markerComplexity.markStep,Complexity.agreeStep— the marker-count and symbol foldsComplexity.stayStep,Complexity.rightStep,Complexity.leftStep— one fold per directionComplexity.dirStep,Complexity.movedMark— the three folded into one, and where the marker must landComplexity.HoldsWindow,Complexity.HoldsBits— a register whose cells spell out an encoded window, or any bitstringComplexity.inHeadStep,Complexity.inHeadEmit— the input-head check, all three directionsComplexity.blockStep,Complexity.blockEmit— the four checks run togetherComplexity.SuccParams,Complexity.succParamsCodec— what the check is handed, and its layout
Main results #
Complexity.markStep_run— the count fold reports whether there are none, one, or moreComplexity.agreeStep_run,Complexity.agreeOk_iff— what the symbol check reportsComplexity.stayStep_run,Complexity.rightStep_run,Complexity.leftStep_state— what each displacement check reportsComplexity.dirEmit_run— and what the combined displacement check reports, whichever way the head movesComplexity.blockEmit_run— and what all four together report on one blockComplexity.markOf_of_holds,Complexity.symOf_of_holds— what a scan reads off an encoded windowComplexity.markCount_eq— an encoded window carries exactly one markerComplexity.eq_run_of_holds,Complexity.eq_run_state— the comparison scan decides equality of what two registers hold, and so decides the state fieldComplexity.valUpTo_of_holds— what a scan reads a register as, as a numberComplexity.tableSlice_eq,Complexity.ofTable_of_holdsBits,Complexity.ofTable_of_holds— and through a codec, as a value: whatever bits a register holds, and when they are an encodingComplexity.plusOne_of_holds,Complexity.plusOne_of_holds_fin— the increment scan decides the input-head fieldComplexity.inHeadEmit_of_holds— and the input-head check, whichever way the head movesComplexity.moved_of_holds,Complexity.sym_of_holds— the displacement and symbol conditions, read as statements about the decoded windowsComplexity.blockEmit_holds— and the whole check: the scan accepts exactly when the new window is the old one steppedComplexity.mem_codeSucc_iff— a successor code is the code of one stepComplexity.succCode_state,Complexity.succCode_inputHead,Complexity.succCode_work_head,Complexity.succCode_work_cells,Complexity.succCode_output_head,Complexity.succCode_output_cells— a successor's fields, one by oneComplexity.eq_succCode_iff— and all of them at once: under the space bound a code is a successor exactly when every field is what the transition makes itComplexity.params_eq— the guessed parameters are pinned by the checks themselvesComplexity.eq_succCode_of_checks— so the conditions the checks establish say exactly that one code is the successor of anotherComplexity.mem_codeSucc_of_checks— and hence that it is a successor at all
How many of the first m chunks carry the marker.
Equations
- Complexity.markCount cols off r 0 = 0
- Complexity.markCount cols off r p.succ = Complexity.markCount cols off r p + if Complexity.markOf cols off r p = true then 1 else 0
Instances For
The symbols #
What the new window should carry at chunk p.
Equations
- Complexity.wantSym cols off a wrB p = if (Complexity.markOf cols off a p && decide (0 < p)) = true then wrB else Complexity.symOf cols off a p
Instances For
The symbol-agreement fold. Its second component remembers that chunk zero has gone by, which is what suppresses the write there.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Where the marker moves #
The head stays: the markers must agree.
Equations
- Complexity.stayStep a b x c1 _c2 _c3 = (x && decide (c1 a = Complexity.Γ.one) == decide (c1 b = Complexity.Γ.one))
Instances For
The head moves right: the new marker is one chunk on.
Equations
- Complexity.rightStep a b x c1 _c2 _c3 = (x.1 && decide (c1 b = Complexity.Γ.one) == x.2, decide (c1 a = Complexity.Γ.one))
Instances For
The head moves left: the new marker is one chunk back, except from chunk zero, where moving left stays put. The fold carries the previous chunk's new marker, whether chunk zero has gone by, and whether the old marker was on chunk zero.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The state of the leftward-move check.
One displacement check, whichever way the head moves #
The displacement check for one block, in the direction the transition dictates. The three directions need different amounts of memory; this gives them all the widest state.
Equations
- Complexity.dirStep a b Complexity.Dir3.stay x c1 c2 c3 = (Complexity.stayStep a b x.1 c1 c2 c3, x.2)
- Complexity.dirStep a b Complexity.Dir3.right x c1 c2 c3 = ((Complexity.rightStep a b (x.1, x.2.1) c1 c2 c3).1, (Complexity.rightStep a b (x.1, x.2.1) c1 c2 c3).2, x.2.2)
- Complexity.dirStep a b Complexity.Dir3.left x c1 c2 c3 = Complexity.leftStep a b x c1 c2 c3
Instances For
The verdict of the displacement check.
Equations
- Complexity.dirEmit Complexity.Dir3.stay x = x.1
- Complexity.dirEmit Complexity.Dir3.right x = x.1
- Complexity.dirEmit Complexity.Dir3.left x = if x.2.2.2 = true then x.1 else x.1 && !x.2.1
Instances For
Where the marker must sit in the new block, given the direction.
Equations
- Complexity.movedMark cols off a Complexity.Dir3.stay p = Complexity.markOf cols off a p
- Complexity.movedMark cols off a Complexity.Dir3.right p = Complexity.prevMark cols off a p
- Complexity.movedMark cols off a Complexity.Dir3.left p = if Complexity.markOf cols off a 0 = true then decide (p = 0) else Complexity.markOf cols off a (p + 1)
Instances For
A register that holds an encoded window #
Where the head lands.
Equations
Instances For
What the displacement condition says about the decoded heads.
What the symbol condition says about the decoded windows.
Registers that hold a bitstring #
Holding a list of bits means holding any prefix of it: a register guessed one bit wider than a field still holds the field.
Holding a list means holding what follows a prefix of it, read from after that prefix. A register whose field sits after a block of padding is read this way: the scan that checks the field starts where the padding ends.
The state check. Two registers holding encoded states agree exactly when the states do.
Reading a register as a number #
Complexity.Scanner.plusOne speaks in Complexity.Scanner.valUpTo, the value of the bits a scan
has passed; Complexity.finCodec stores a number as Complexity.bitsOfLenLE, whose value is
Complexity.binValLE. Both are little-endian, so they agree.
Reading a value off a register with a scan #
What a scan has in its table: the bits the register holds.
What a scan reads a register as, through a codec, whatever bits it holds.
The same, when the register holds an encoding.
The same, for a scan that starts at the first cell.
The input head, whichever way it moves #
The input-head check, in the direction the transition dictates. The three directions share a
common state: stay compares, right checks an increment, and left checks one with the
registers swapped, since v = u - 1 with u > 0 is u = v + 1.
Equations
- Complexity.inHeadStep r r' Complexity.Dir3.stay x col = ((Complexity.Scanner.eq j r r').stepR x.1 col, x.2)
- Complexity.inHeadStep r r' Complexity.Dir3.right x col = (Complexity.Scanner.plusOne j r r').stepR x col
- Complexity.inHeadStep r r' Complexity.Dir3.left x col = (Complexity.Scanner.plusOne j r' r).stepR x col
Instances For
The verdict of the input-head check.
Equations
- Complexity.inHeadEmit Complexity.Dir3.stay x = x.1
- Complexity.inHeadEmit Complexity.Dir3.right x = (!x.1 && x.2)
- Complexity.inHeadEmit Complexity.Dir3.left x = (!x.1 && x.2)
Instances For
What the input-head check reports.
The whole check on one block #
The four checks on one block, run together: the marker counts on each register, the symbols, and the displacement.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The combined verdict: one marker on each register, the symbols right, the head moved right.
Equations
- Complexity.blockEmit d x = (x.1.1 && !x.1.2 && (x.2.1.1 && !x.2.1.2) && x.2.2.1.1 && Complexity.dirEmit d x.2.2.2)
Instances For
What the whole block check reports.
The block check, as a statement about decoded windows. The scan accepts exactly when the new window is the old one stepped: the symbol under the head is the one the transition was computed from, the cells are unchanged except under the head, where the written symbol appears — save at cell zero, where a write is a no-op — and the head has moved as the direction says.
The parameters a successor check is handed #
The check does not guess what the simulated machine does — it guesses only what the machine
sees, and computes the transition itself. The state is verified against the old code's state
field, and each head symbol by the block check's own symOk conjunct, so nothing here is taken on
trust.
SuccParams is a plain record, so it lays out as a product. The symbol under the input head
comes first: it is the one field a machine checks against its own input tape rather than by
scanning, and TM.inMatchTM reads the two cells at the start of the register.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The layout of a parameter block.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The symbol the simulated machine writes on work tape i.
Equations
- Complexity.succWrite tm p i = ((Complexity.succTrans tm p).2.1 i).toΓ
Instances For
Which way work head i moves.
Equations
- Complexity.succDir tm p i = (Complexity.succTrans tm p).2.2.2.2.1 i
Instances For
The state the simulated machine moves to.
Equations
- Complexity.succState tm p = (Complexity.succTrans tm p).1
Instances For
What the successor relation on codes says #
Complexity.NTM.codeSucc is cfgCode ∘ stepCfg ∘ decodeCfg. Decoding reads the transition's
inputs straight off the code's fields, so a successor is determined by the code and the choice
bit — which is what lets the check guess only what the machine sees.
The symbol under the simulated input head.
Equations
- Complexity.inSymOf tm x S a = (Complexity.Tape.init (List.map Complexity.Γ.ofBool x)).cells ↑a.2.1
Instances For
What the simulated machine sees, read off a code.
Equations
- Complexity.paramsOf tm x S a β = { beta := β, q := a.1, inSym := Complexity.inSymOf tm x S a, wSym := Complexity.wSymOf tm x S a, oSym := Complexity.oSymOf tm x S a }
Instances For
The successor of a code under one choice.
Equations
- Complexity.succCode tm x S β a = Complexity.cfgCode x.length S (tm.stepCfg β (Complexity.decodeCfg x S a))
Instances For
A successor, field by field. Under the space bound the clamps in cfgCode are inert, so a
code is the successor of another exactly when every field is what the transition makes it — which
is what the scans check.
The guessed parameters are forced. Each field of what the check was handed is pinned by
one of the checks: the state by the comparison against the old code's state field, each head
symbol by that block's own symOk conjunct, and the input symbol by the machine reading its own
input head.
A successor, from the conditions the checks establish.
Membership in codeSucc, from the conditions the checks establish.