Body machine: the match-loop induction #
The final piece of the body correctness: from cmpQ f at the start of the
entry region, the machine walks the takeField segment split exactly as
machFind does (BodyLookup.lean) — per segment either the full
key-and-value scan succeeds (cmpQ → cmpS → copyQ' → copyAct →
appRewScr), or the first failure point diverts to the uniform mismatch
path (skipSeg → segCheck → mmScr → rewindSt) and the loop resumes
at the next segment; an empty next segment sends the machine to the
default path (dfScr) with the sanitized default moves applied (trick 4).
matchLoop packages both outcomes against machFind:
machFind … = some seg— the machine reachesappRewScr fwith the matched segment's value slice on the scratch tape;machFind … = none— the machine reachesdfScrhaving applied the default moves, scratch confined and blank beyond its head.
Corner (empty first segment). machFind/parseEntries treat a region
that starts with □ as an exhausted table. The machine, started at
cmpQ on such a region, instead steps past the empty segment
(cmpQ→skipSeg→segCheck at the next cell) — it only recognizes the
table terminator as a □ read by segCheck. On R = □ :: s :: … with
s ≠ □ the two genuinely diverge: the machine goes on to scan the
segments after the empty one while machFind returns none. matchLoop
therefore carries the hypothesis that an empty head segment is a real
terminator (R = □ :: s :: … → s = □). Every region the loop actually
sees satisfies it: canonical descriptions (TMDesc.syms) have entry
regions of the form entry □ ⋯ □ □ (head symbol is an entry bit) or □
(empty table), and the loop re-enters cmpQ only through segCheck,
which has just read the next region's head symbol and found it non-□.
The match-loop induction (design appendix 2, machine side): from
cmpQ f at the start of the entry region suffix R (desc cells at
pos + j hold R's symbols, blank-padded; an empty head segment of
R, if any, is a real terminator — see the module docstring), with
the state tape holding stSyms at head 1, a clean scratch tape, and
the three virtual tapes stationary with live reads v0/v1/v2:
- if
machFindaccepts a segmentseg, the machine reachesappRewScr fwithseg's value slice (thew + 10cells after its key) on the scratch tape, the state tape restored, desc cells unchanged, and the virtual tapes untouched; - if
machFindrejects (none), the machine reachesdfScrhaving applied the sanitized default moves (trick 4) to the three virtual tapes, with state and desc cells unchanged and the scratch confined (▷-free, blank at and beyond its head, head ≤w + 11) — the shapedefaultTailconsumes;
in either case within (|R| + 2)·(4·|stSyms| + 60) steps.