CSG → LBA (Kuroda): completeness #
This file proves the completeness half: a derivation [S] ⇒* w of the grammar is replayed
in reverse by an accepting run of kMachine g₀ (kMachine_complete).
The core is applyRule_pass_gen, a single backward rule-application pass that rewrites one
output-occurrence on the work track to the rule's input pattern patList, skipping blanks.
The Complete section then repositions the head freely (sim_reaches), locates the rewrite
window (list_split_filterMap), chains one pass per derivation step (step_back, derive_back)
and finishes with the accept check.
applyRule single-pass steps #
Every element of a ℕ-list is ≤ its foldr max 0.
From sim, begin applying rule ri at the current cell (echo, stay).
Skip a blank during the rule-application pass (echo, move right, keep the match position).
Match the k-th output symbol and write the replacement, continuing the pass (k+1 < |out|).
Match the last output symbol (k+1 = |out|); the replacement is written and the pass ends
(return to sim).
Match the last output symbol when the cell is the rightmost (i.val = n); moving right
clamps, so the head stays at n.
The rule-application pass (contiguous window). From applyRule ri k at cell start+k,
where the window holds output_string[k..], scan to the end writing the replacement, reaching
sim with the work function updated on [start+k, start+q) to patList[·]?.
The general rule-application pass (skips interspersed blanks). From applyRule ri k at
cell pos, where the non-blank cells from pos begin with output_string[k..] followed by v,
scan right (skipping blanks, matching each output symbol and writing the replacement) and reach
sim with the work track's non-blank tail now patList[k..] ++ v, leaving cells < pos fixed.
Replaying a derivation backwards (completeness) #
In sim, the head may move one cell right (the tape is unchanged).
In sim, the head may move one cell left (the tape is unchanged).
From sim at any cell, reach sim at the left end (cell 0).
From sim at the left end, reach sim at any cell j (sweep right).
From sim, the head may be repositioned to any cell.
Locate a tape split point realizing a given prefix of the decoded form: if a list of
work cells filters to u ++ z with z non-empty, some position p (a valid cell index)
splits the tape with u to the left and z to the right.
One backward derivation step. If the work track decodes to u ++ output ++ v for some
rule r (output non-empty by non-contraction), the simulator can reposition, run one backward
applyRule pass, and arrive in sim with the track decoding to u ++ patList r ++ v — i.e. it
undoes the forward step u ++ patList r ++ v ⇒ u ++ output ++ v.
Replaying a whole derivation backwards. If β ⇒* γ and the work track decodes to γ,
the simulator reaches sim with the track decoding to β.
Completeness of the simulator. A derivation [S] ⇒* w is replayed in reverse on the
tape (convert input, repeatedly bubble blanks and apply rules backward, then verify [S]),
yielding an accepting run. Non-contraction keeps every sentential form within |w| cells.