Simulating the bounded-tape model on ⊢ w ⊣ (the ε-carrying half of CS = LBA) #
The canonical model for the context-sensitive languages is the endmarker LBA (is_LBA,
Automata/LinearBounded/Definition.lean), which decides the empty word with the machine itself
(running on ⊢⊣). This file builds the simMachine that runs a bounded-tape machine M
(Automata/LinearBounded/Positive.lean) on ⊢ w ⊣, together with language_simMachine_eq; this
is the tool used in Equivalence/EndmarkerToFlag.lean to assemble CS ⊆ LBA (and the whole
CS = LBA).
Strategy #
simMachine M b runs M on the interior cells 1 … |w|; when a simulated move would step onto an
endmarker it bounces back, exactly reproducing M's boundary clamping. The empty word is decided
on ⊢⊣ directly by the bit b (always instantiated to decide (ε ∈ L)), so no flag lives on the
machine. The result is language_simMachine_eq: LanguageEnd (simMachine M b) = (b ∧ ·=[]) ∨ LanguageViaEmbed M (some ∘ inl).
States of the endmarker machine simulating a marker-free flag LBA M:
start/entry walk past the left marker and split off the empty-word case, run q simulates
M in state q on the interior cells (bouncing off the markers to mimic M's clamping), and
acc/rej are the empty-word sinks.
- start {Λ : Type u_4} : SimState Λ
- entry {Λ : Type u_4} : SimState Λ
- run {Λ : Type u_4} (q : Λ) : SimState Λ
- acc {Λ : Type u_4} : SimState Λ
- rej {Λ : Type u_4} : SimState Λ
Instances For
Equations
- LBA.instDecidableEqSimState.decEq LBA.SimState.start LBA.SimState.start = isTrue ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.start LBA.SimState.entry = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.start (LBA.SimState.run q) = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.start LBA.SimState.acc = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.start LBA.SimState.rej = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.entry LBA.SimState.start = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.entry LBA.SimState.entry = isTrue ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.entry (LBA.SimState.run q) = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.entry LBA.SimState.acc = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.entry LBA.SimState.rej = isFalse ⋯
- LBA.instDecidableEqSimState.decEq (LBA.SimState.run q) LBA.SimState.start = isFalse ⋯
- LBA.instDecidableEqSimState.decEq (LBA.SimState.run q) LBA.SimState.entry = isFalse ⋯
- LBA.instDecidableEqSimState.decEq (LBA.SimState.run a) (LBA.SimState.run b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- LBA.instDecidableEqSimState.decEq (LBA.SimState.run q) LBA.SimState.acc = isFalse ⋯
- LBA.instDecidableEqSimState.decEq (LBA.SimState.run q) LBA.SimState.rej = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.acc LBA.SimState.start = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.acc LBA.SimState.entry = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.acc (LBA.SimState.run q) = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.acc LBA.SimState.acc = isTrue ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.acc LBA.SimState.rej = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.rej LBA.SimState.start = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.rej LBA.SimState.entry = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.rej (LBA.SimState.run q) = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.rej LBA.SimState.acc = isFalse ⋯
- LBA.instDecidableEqSimState.decEq LBA.SimState.rej LBA.SimState.rej = isTrue ⋯
Instances For
Transition of the endmarker machine simulating the marker-free flag LBA M (flag b):
walk past ⊢; on ⊣ immediately at entry decide ε by the flag; otherwise simulate M's
transitions on the interior, bouncing off either marker to reproduce M's boundary clamping.
Equations
- LBA.simTransition M b LBA.SimState.start (Sum.inr false) = {(LBA.SimState.entry, LBA.leftMark, DLBA.Dir.right)}
- LBA.simTransition M b LBA.SimState.entry (Sum.inr true) = if b = true then {(LBA.SimState.acc, LBA.rightMark, DLBA.Dir.stay)} else {(LBA.SimState.rej, LBA.rightMark, DLBA.Dir.stay)}
- LBA.simTransition M b LBA.SimState.entry (Sum.inl c) = {(LBA.SimState.run M.initial, Sum.inl c, DLBA.Dir.stay)}
- LBA.simTransition M b (LBA.SimState.run q) (Sum.inl c) = {x : LBA.SimState Λ × LBA.EndAlpha T Γ × DLBA.Dir | ∃ p ∈ M.transition q c, x = (LBA.SimState.run p.1, Sum.inl p.2.1, p.2.2)}
- LBA.simTransition M b (LBA.SimState.run q) (Sum.inr false) = {(LBA.SimState.run q, LBA.leftMark, DLBA.Dir.right)}
- LBA.simTransition M b (LBA.SimState.run q) (Sum.inr true) = {(LBA.SimState.run q, LBA.rightMark, DLBA.Dir.left)}
- LBA.simTransition M b s a = ∅
Instances For
Encoding a marker-free configuration as an endmarker configuration #
The simulator runs M on the interior cells 1 … n+1 of an (n+3)-cell endmarker tape, with
⊢ at cell 0 and ⊣ at cell n+2. enc brackets an (n+1)-cell marker-free tape, encHead
shifts a head position into the interior, and φ packages an M-configuration as the
corresponding run-phase simulator configuration.
Transition equation lemmas (definitional). #
Forward simulation: each M-step is matched by one or two simulator steps. #
A single M-step is simulated by one or two simulator steps (two when M's head clamps at a
boundary, where the simulator bounces off the corresponding endmarker).
Backward simulation: a single decoding invariant. #
Good c₀ s says the simulator configuration s, reached from the start on ⊢ c₀ ⊣, decodes to
a genuine M-configuration reachable from M's start on c₀. The three branches are the two
pre-run setup states and the run phase; in the run phase the head is either on the encoded interior
cell or sitting on a marker mid-bounce (recording where M's head clamped).
From the invariant, an accepting simulator state yields an accepting M-run.
The decoding invariant is preserved by a simulator step.
Every simulator configuration reachable from the start on ⊢ c₀ ⊣ satisfies the invariant.
The two setup steps: from ⊢ c₀ ⊣ the simulator walks onto the interior and enters the run
phase at M.initial, reaching the encoding of M's start configuration.
Key bisimulation. On the bracketed tape ⊢ c₀ ⊣, the endmarker simulator accepts iff the
underlying flag machine M accepts on c₀ — dimension-clean, no empty-word subtlety.
The empty word: decided by the machine itself on the two-cell tape ⊢⊣. #
Invariant for the empty-word run on ⊢⊣: contents stay ⊢⊣, and the state/head track the
fixed two-step protocol, ending in acc exactly when the flag b is set.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Assembling the language equivalence. #
Connecting the dimension-clean sim_accepts_iff to the canonical loadEnd/initCfgList
configurations requires one transport across (w.map embed).length = w.length (List.length_map),
handled here once via HEq.
Heterogeneous tape equality from a dimension equality, heterogeneous contents and equal head.
On a non-empty input, the endmarker simulator on ⊢ w ⊣ accepts iff the flag machine M
accepts on the canonically loaded w — connecting sim_accepts_iff to the canonical tapes.