Simulating an endmarker LBA on the bounded |w|-cell tape (the LBA ⊆ CS half) #
This is the converse simulation to Equivalence/EndmarkerTape.lean: an endmarker LBA M' on the
|w|+2-cell bracketed tape ⊢ w ⊣ is simulated by a marker-free machine flagMachine M' on the
|w| input cells. The deliverable is language_flagMachine_eq:
LanguageRecognized (flagMachine M') (some ∘ inl) (decide (M' accepts ⊢⊣)) = LanguageEnd M'.
Equivalence/ContextSensitive.lean combines it with the Myhill grammar to assemble LBA ⊆ CS,
hence the headline CS = LBA (CS_eq_LBA).
Construction (the "fold") #
M' uses |w|+2 cells; M has only |w|. We keep M''s interior cells 1 … |w| on M's
cells 0 … |w|-1 (cell i ↔ interior cell i+1), and fold the two read-only-position marker
cells into the boundary cells: cell 0 additionally stores M'-cell 0's content (the ⊢ cell)
and the last cell additionally stores M'-cell |w|+1's content (the ⊣ cell). A work cell is
therefore a FoldCell = (cur, leftEnd?, rightEnd?): the interior content cur, plus an optional
⊢-cell content (present only at cell 0) and optional ⊣-cell content (present only at the last
cell).
M's head is always on the cell holding the content M' reads; a finite FMode records whether
M''s head is on the folded ⊢ (onLeft), the interior (mid), or the folded ⊣ (onRight).
Because the markers are folded into the same boundary cell as the adjacent interior cell, mode
switches at the boundary keep M's head stationary — so one M'-step is exactly one M-step
(no bounce). Boundary clamping of M' is reproduced by the onLeft/onRight transitions staying
put.
Init phase (setup/scan/verify/rewind) #
M starts at cell 0, which it knows is the left end, and marks it (leftEnd := some ⊢). It then
scans right and nondeterministically guesses the last cell, marking it (rightEnd := some ⊣);
moving right off that cell clamps iff the guess was correct, so re-reading a rightEnd-marked
cell verifies the guess (a wrong guess reads an unmarked cell and dies). It then rewinds left to
the leftEnd-marked cell 0 and enters the simulation at M'.initial with the head on ⊢
(onLeft).
The bisimulation (init reaches the encoded M' start config; simulation mirrors M' steps; a
backward invariant rules out wrong-guess branches reaching acceptance) is the remaining work.
A folded work cell of the simulating flag machine: the interior content cur of the
corresponding M'-interior cell, plus the ⊢-cell content (Some only at cell 0) and the
⊣-cell content (Some only at the last cell).
Equations
- LBA.FoldCell T Γ = (LBA.EndAlpha T Γ × Option (LBA.EndAlpha T Γ) × Option (LBA.EndAlpha T Γ))
Instances For
Tape alphabet of the simulating flag machine: canonical marker-free alphabet with work
alphabet FoldCell T Γ.
Equations
- LBA.FAlpha T Γ = Option (T ⊕ LBA.FoldCell T Γ)
Instances For
Equations
- LBA.instFintypeFMode = { elems := {LBA.FMode.onLeft, LBA.FMode.mid, LBA.FMode.onRight}, complete := ⋯ }
States of the simulating flag machine: the four init-phase states and the simulation states
sim q mode carrying the simulated M'-state q and the head mode.
- setup {Λ : Type u_4} : FState Λ
- scan {Λ : Type u_4} : FState Λ
- verify {Λ : Type u_4} : FState Λ
- rewind {Λ : Type u_4} : FState Λ
- sim {Λ : Type u_4} (q : Λ) (mode : FMode) : FState Λ
Instances For
Equations
- LBA.instDecidableEqFState.decEq LBA.FState.setup LBA.FState.setup = isTrue ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.setup LBA.FState.scan = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.setup LBA.FState.verify = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.setup LBA.FState.rewind = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.setup (LBA.FState.sim q mode) = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.scan LBA.FState.setup = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.scan LBA.FState.scan = isTrue ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.scan LBA.FState.verify = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.scan LBA.FState.rewind = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.scan (LBA.FState.sim q mode) = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.verify LBA.FState.setup = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.verify LBA.FState.scan = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.verify LBA.FState.verify = isTrue ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.verify LBA.FState.rewind = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.verify (LBA.FState.sim q mode) = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.rewind LBA.FState.setup = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.rewind LBA.FState.scan = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.rewind LBA.FState.verify = isFalse ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.rewind LBA.FState.rewind = isTrue ⋯
- LBA.instDecidableEqFState.decEq LBA.FState.rewind (LBA.FState.sim q mode) = isFalse ⋯
- LBA.instDecidableEqFState.decEq (LBA.FState.sim q mode) LBA.FState.setup = isFalse ⋯
- LBA.instDecidableEqFState.decEq (LBA.FState.sim q mode) LBA.FState.scan = isFalse ⋯
- LBA.instDecidableEqFState.decEq (LBA.FState.sim q mode) LBA.FState.verify = isFalse ⋯
- LBA.instDecidableEqFState.decEq (LBA.FState.sim q mode) LBA.FState.rewind = isFalse ⋯
- LBA.instDecidableEqFState.decEq (LBA.FState.sim a a_1) (LBA.FState.sim b b_1) = if h : a = b then h ▸ if h : a_1 = b_1 then h ▸ isTrue ⋯ else isFalse ⋯ else isFalse ⋯
Instances For
The interior content M' would see at this cell: an input cell reads as interior input, a work
cell reads its stored cur, a blank reads as interior blank.
Equations
Instances For
The folded ⊢-cell content, present only at cell 0.
Equations
- LBA.cellLeft (some (Sum.inr fc)) = fc.2.1
- LBA.cellLeft x✝ = none
Instances For
The folded ⊣-cell content, present only at the last cell.
Equations
- LBA.cellRight (some (Sum.inr fc)) = fc.2.2
- LBA.cellRight x✝ = none
Instances For
Transition of the simulating flag machine. Init phase: setup marks cell 0 (and may mark it
as the last cell too, for |w|=1); scan moves right, nondeterministically marking the guessed
last cell; verify accepts the guess iff the right move clamped back onto the marked cell;
rewind returns left to cell 0. Simulation phase: replay M' on the folded tape, switching
FMode at the boundaries with the head stationary.
Equations
- One or more equations did not get rendered due to their size.
- LBA.flagTransition M' LBA.FState.setup r = {(LBA.FState.scan, some (Sum.inr (LBA.cellCur r, some LBA.leftMark, none)), DLBA.Dir.right)}
- LBA.flagTransition M' LBA.FState.verify r = if (LBA.cellRight r).isSome = true then {(LBA.FState.rewind, r, DLBA.Dir.left)} else ∅
- LBA.flagTransition M' LBA.FState.rewind r = if (LBA.cellLeft r).isSome = true then {(LBA.FState.sim M'.initial LBA.FMode.onLeft, r, DLBA.Dir.stay)} else {(LBA.FState.rewind, r, DLBA.Dir.left)}
Instances For
The marker-free flag machine simulating the endmarker machine M' (work alphabet
FoldCell T Γ). It accepts exactly when the simulated M'-state is accepting.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The fold encoding of an M'-configuration. #
The head mode determined by where M''s head sits.
Equations
- LBA.foldMode p = if ↑p = 0 then LBA.FMode.onLeft else if ↑p = m + 2 then LBA.FMode.onRight else LBA.FMode.mid
Instances For
Encode an M'-configuration (on m+2 dim, m+3 cells) as the corresponding flagMachine
configuration (on m dim, m+1 cells) in the simulation phase.
Equations
- LBA.fold cfg = { state := LBA.FState.sim cfg.state (LBA.foldMode cfg.tape.head), tape := { contents := LBA.foldContents cfg.tape.contents, head := LBA.foldHead cfg.tape.head } }
Instances For
Writing at the head cell only affects the folded cell at foldHead p.
Head-projection lemmas (definitional). #
Simulation-phase single-step correctness (one M'-step = one flagMachine-step). #
One M'-step is matched by exactly one flagMachine-step on the folded configuration.
Backward simulation. Every flagMachine step out of a folded configuration fold cfg
decodes to a genuine M'-step: it lands on fold cfg' for some cfg' with Step M' cfg cfg'.
Init phase: the flag machine sets up the folded tape. #
From the input tape c, M converts each cell to its folded form (foldedTape), marking cell 0
with ⊢ and the last cell with ⊣, then rewinds to cell 0 and enters the simulation.
One scan step converts the cell at an interior position k and moves right.
The scan phase: from cell 1 to the last cell m, converting each interior cell.
setup: mark cell 0 with ⊢ and step right (case m ≥ 1, so cell 0 is not the last).
The last scan step (at cell m): mark it ⊣ and clamp, entering verify.
verify confirms the guess (the right move clamped back onto the ⊣-marked cell).
One rewind step at an interior cell k ≥ 1 (no left marker): move left.
The rewind phase: from cell j back down to cell 0.
The final rewind step at cell 0: the ⊢ mark is found, entering the simulation.
The whole init phase: from the input tape c, reach the simulation start at M'.initial
on the head (⊢), with the tape fully folded.
Backward invariant: every reachable flagMachine configuration is sound. #
GoodF enumerates the configurations reachable from the start ⟨setup, c₀⟩: the init-phase
configurations (all non-accepting — setup, the partial/over scans, the dead and successful
verify, the rewind), and the simulation-phase configurations, which are exactly fold-images
of M'-configurations reachable from M''s start on e₀.
An accepting GoodF configuration yields an accepting M'-run from M''s start on e₀.
The invariant is preserved by a flagMachine step.
Every configuration reachable from the start satisfies the invariant.
Assembly: the flag machine recognizes the same language. #
The endmarker tape ⊢ (interior of c) ⊣ that the flag input c decodes to.
Equations
- LBA.expand c k = if ↑k = 0 then LBA.leftMark else if h : ↑k - 1 < m + 1 then LBA.cellCur (c ⟨↑k - 1, h⟩) else LBA.rightMark
Instances For
The folded input tape equals the fold of its endmarker expansion — so init_reach lands
exactly on fold of the M'-start configuration on ⊢ w ⊣.
Bisimulation (abstract). On the raw input tape c₀, the flag machine accepts iff M'
accepts on the endmarker expansion ⊢ c₀ ⊣.
Bisimulation (canonical). On a non-empty input w, the flag machine on the canonically
loaded w accepts iff M' accepts on ⊢ w ⊣.
The flag machine flagMachine M' (with empty-word flag b) recognizes exactly LanguageEnd M',
provided b decides membership of ε.