Theory AlphabetReduction_Delta

theory AlphabetReduction_Delta
  imports AlphabetReduction_Stage
begin

subsection ‹Substep transition relations›

text ‹The output machine's δ'› is defined as a
  union of five per-substep transition relations, mirroring
  AE's alphabet_enlarge_delta› shape.  Each substep
  relation is a set of substrate-shape 5-tuples
  ((q, stg), a, (q', stg'), a', d)› where
  q› ranges over Q_tm M›, stg›
  over 'a ar_stage›, a› /
  a'› over nat ⇒ sym4›, and
  d› over nat ⇒ dir›.  The five substep
  relations are defined below, one per simulation phase.

  No validation cluster: AR's language theorem is quantified
  over encoder-image inputs only, so non-canonical sym4 inputs
  are outside the theorem's scope and M''s behaviour on them is
  unconstrained.

  The union is intersected with two global restrictions:
  LE-preservation (no transition forges LE4› out of
  a non-LE4› cell, matching the substrate's
  δLE› invariant) and
  ar_valid_stage›-membership on both source and
  target stages (matching the non-product Q'› shape).
  Throughout, b› abbreviates block_width Γ› (the per-symbol cell width).›

definition ar_delta_read ::
  "('q, 'a) mttm
     (('q × 'a ar_stage)
        × (nat  sym4)
        × ('q × 'a ar_stage)
        × (nat  sym4)
        × (nat  dir)) set" where
  "ar_delta_read M =
    ― ‹LE-arm, non-last tape: head at position 0
       reads LE4›, sets buf tk := le_tm M›
       directly (no accumulator needed for the single
       LE-cell), advances R› on tk› to
       position 1, and transitions to the next tape's read.
       posk tk› stays AR_AtLE›
       throughout this substep — SimAdvance› will
       update it later when the head leaves the LE region.›
    {((q, AR_SimRead, tk, 0, buf, dvec, posk), a,
       (q, AR_SimRead, k_succ tk, 0,
        buf(tk := le_tm M), dvec, posk), a, d) |
     q tk buf dvec posk a d.
       q  Q_tm M
        ¬ is_last_k M tk
        posk tk = AR_AtLE
        a tk = LE4
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹LE-arm, last tape: same single-substep
       LE-read, transitions to AR_SimCompute›
       instead of the next tape.›
    {((q, AR_SimRead, tk, 0, buf, dvec, posk), a,
       (q, AR_SimCompute, k_unidx 0, 0,
        buf(tk := le_tm M), dvec, posk), a, d) |
     q tk buf dvec posk a d.
       q  Q_tm M
        is_last_k M tk
        posk tk = AR_AtLE
        a tk = LE4
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹Proper-arm look-back step 1
       (i = 0›): head at sim_pos(p)›
       moves L› on tk› to
       sim_pos(p) - 1›.  The cell at
       sim_pos(p)› is some BIT0› /
       BIT1› / BLANK4› (not
       LE4›; enforced as a δLE›
       precondition).  Buf, posk, dvec unchanged; substep
       transitions to i = 1›.›
    {((q, AR_SimRead, tk, 0, buf, dvec, posk), a,
       (q, AR_SimRead, tk, Suc 0, buf, dvec, posk), a, d) |
     q tk buf dvec posk a d.
       q  Q_tm M
        posk tk  {AR_AtFirstProper, AR_AtFurtherProper}
        a tk  LE4
        d = (λkk. if kk = tk then dir.L else dir.N)}
    
    ― ‹Proper-arm look-back step 2
       (i = 1›): head at sim_pos(p) - 1›
       reads the cell there; if LE4›, the head was
       at sim_pos 1 = 1› in the previous step so
       refine posk tk := AR_AtFirstProper›;
       otherwise refine to AR_AtFurtherProper›.
       Reset buf tk := gamma_unenum Γ bl 0›
       (the partial-decoded ``0› bits read so far''
       symbol) to prepare for the per-bit accumulator below.
       R›-move back to sim_pos(p)›;
       δLE› with a tk = LE4› is
       fine because the direction is R›.
       Transitions to i = 2›.›
    {((q, AR_SimRead, tk, Suc 0, buf, dvec, posk), a,
       (q, AR_SimRead, tk, Suc (Suc 0),
        buf(tk := gamma_unenum (Γ_tm M) (bl_tm M) 0),
        dvec,
        posk(tk := if a tk = LE4 then AR_AtFirstProper
                                  else AR_AtFurtherProper)), a, d) |
     q tk buf dvec posk a d.
       q  Q_tm M
        posk tk  {AR_AtFirstProper, AR_AtFurtherProper}
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹Proper-arm per-bit stepping
       (2 ≤ i ≤ b›): head at
       sim_pos(p) + (i - 2)›, read cell, accumulate
       bit_value› into the partial-decoded
       buf tk› via the gamma_enum›
       /gamma_unenum› roundtrip
       partial' = 2 ⋅ gamma_enum (buf tk) +
       bit_value (a tk)›, buf' tk :=
       gamma_unenum partial'›.  R›-move on
       tk›.  Transitions to i + 1›
       within AR_SimRead›; the next per-bit
       substep continues the accumulator chain.›
    {((q, AR_SimRead, tk, i, buf, dvec, posk), a,
       (q, AR_SimRead, tk, Suc i,
        buf(tk := gamma_unenum (Γ_tm M) (bl_tm M)
                    (2 * gamma_enum (Γ_tm M) (bl_tm M) (buf tk)
                       + bit_value (a tk))),
        dvec, posk), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        posk tk  {AR_AtFirstProper, AR_AtFurtherProper}
        2  i
        Suc i  Suc (block_width (Γ_tm M))
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹Proper-arm per-bit boundary
       (i = Suc (b)›), non-last tape:
       same accumulator step as above on the last bit
       (j = b - 1›), buf' tk› holds the
       fully-decoded M›-symbol (∈
       Γ› for valid encoder images; falls back to
       bl_tm M› for non-encoder inputs), then
       transitions to the same phase on k_succ tk›
       with bit-counter reset to 0›.›
    {((q, AR_SimRead, tk, i, buf, dvec, posk), a,
       (q, AR_SimRead, k_succ tk, 0,
        buf(tk := gamma_unenum (Γ_tm M) (bl_tm M)
                    (2 * gamma_enum (Γ_tm M) (bl_tm M) (buf tk)
                       + bit_value (a tk))),
        dvec, posk), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        ¬ is_last_k M tk
        posk tk  {AR_AtFirstProper, AR_AtFurtherProper}
        i = Suc (block_width (Γ_tm M))
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹Proper-arm per-bit boundary, last tape: same
       last-bit accumulator step, transitions to
       AR_SimCompute› with current-tape reset to
       k_unidx 0›.›
    {((q, AR_SimRead, tk, i, buf, dvec, posk), a,
       (q, AR_SimCompute, k_unidx 0, 0,
        buf(tk := gamma_unenum (Γ_tm M) (bl_tm M)
                    (2 * gamma_enum (Γ_tm M) (bl_tm M) (buf tk)
                       + bit_value (a tk))),
        dvec, posk), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        is_last_k M tk
        posk tk  {AR_AtFirstProper, AR_AtFurtherProper}
        i = Suc (block_width (Γ_tm M))
        d = (λkk. if kk = tk then dir.R else dir.N)}"

definition ar_delta_compute ::
  "('q, 'a) mttm
     (('q × 'a ar_stage)
        × (nat  sym4)
        × ('q × 'a ar_stage)
        × (nat  sym4)
        × (nat  dir)) set" where
  "ar_delta_compute M =
    {((q, AR_SimCompute, tk, i, buf, dvec, posk), a,
       (q', AR_SimWrite, 0, 0, m_a', m_d, posk), a, d) |
     q buf q' m_a' m_d tk i dvec posk a d.
       (q, buf, q', m_a', m_d)  delta_tm M
        d = (λ_. dir.N)}"
  ― ‹One δ'›-tuple per M›'s
     δ›-tuple.  Matches the source-stage buf›
     field (the decoded per-tape symbol vector, produced by
     AR_SimRead›) against the M-side read symbol
     vector of the M›-δ›-tuple
     (q, buf, q', m_a', m_d)›, and threads the M-side
     output: new M-state q'›, write-back vector
     m_a'› (next phase's per-tape symbols to encode),
     and direction-vector m_d› (consumed by
     AR_SimAdvance›).  The substrate-side read a›
     and write a' = a› are unconstrained at this
     substep (no head moves, no writes); direction is constant
     N›.  The per-tape posk› carries
     through unchanged (head positions don't change during
     compute).  No halt-state shortcut: M-side halt detection
     is centralised at ar_delta_next›'s three-arm
     dispatch.›

definition ar_delta_write ::
  "('q, 'a) mttm
     (('q × 'a ar_stage)
        × (nat  sym4)
        × ('q × 'a ar_stage)
        × (nat  sym4)
        × (nat  dir)) set" where
  "ar_delta_write M =
    ― ‹LE-arm, non-last tape: posk tk = AR_AtLE›
       means tape tk›'s head sits on the reduced boundary
       (sim_pos 0 = 0›), whose LE4› cell need not be
       rewritten (δLE› requires writing le›
       back, which is exactly the present cell).  Keyed on the
       position-kind flag, not on buf tk = le_tm M›, so a
       source machine that writes le› off the boundary (a tape
       cut) is handled by the proper arm below, as ordinary data.
       Skip the per-tape write phase entirely: single substep with
       all directions N›, transitioning to the same phase on
       the next tape with bit-counter still at 0›.›
    {((q, AR_SimWrite, tk, 0, buf, dvec, posk), a,
       (q, AR_SimWrite, k_succ tk, 0, buf, dvec, posk), a, d) |
     q tk buf dvec posk a d.
       q  Q_tm M
        posk tk = AR_AtLE
        ¬ is_last_k M tk
        d = (λ_. dir.N)}
    
    ― ‹LE-arm, last tape: transitions to
       AR_SimAdvance› with the current-tape index
       reset to k_unidx 0›.›
    {((q, AR_SimWrite, tk, 0, buf, dvec, posk), a,
       (q, AR_SimAdvance, k_unidx 0, 0, buf, dvec, posk), a, d) |
     q tk buf dvec posk a d.
       q  Q_tm M
        posk tk = AR_AtLE
        is_last_k M tk
        d = (λ_. dir.N)}
    
    ― ‹Proper-arm, back-walk phase
       (0 ≤ i < b›): head moves
       L› on tk›, N›
       elsewhere; no writes.  At i = b - 1› the
       substep transitions to i = b›, starting the
       forward-write phase below.  Both phases share the
       AR_SimWrite› substep tag; the bit-counter
       distinguishes them.  a tk ≠ LE4›
       enforced for δLE›.›
    {((q, AR_SimWrite, tk, i, buf, dvec, posk), a,
       (q, AR_SimWrite, tk, Suc i, buf, dvec, posk), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        posk tk  AR_AtLE
        a tk  LE4
        Suc i  block_width (Γ_tm M)
        d = (λkk. if kk = tk then dir.L else dir.N)}
    
    ― ‹Proper-arm, forward-write stepping phase
       (b ≤ i < 2b - 1›): write
       write_bit Γ bl (buf tk) (i - b)› at
       tk›, R› on tk›,
       N› elsewhere.  All other tapes have their
       cells preserved.  The bit-counter advances; the next
       substep continues forward-write.›
    {((q, AR_SimWrite, tk, i, buf, dvec, posk), a,
       (q, AR_SimWrite, tk, Suc i, buf, dvec, posk), a', d) |
     q tk i buf dvec posk a a' d.
       q  Q_tm M
        posk tk  AR_AtLE
        block_width (Γ_tm M)  i
        Suc i < 2 * block_width (Γ_tm M)
        a' = (λkk. if kk = tk
                       then write_bit (Γ_tm M) (bl_tm M)
                                       (buf tk)
                                       (i - block_width (Γ_tm M))
                       else a kk)
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹Proper-arm, forward-write boundary
       (Suc i = 2b›), non-last tape: last cell of
       cell_repr (buf tk)› is written, head moves
       R› on tk›, transitions to the
       same phase on k_succ tk› with bit-counter
       reset.  Cells on other tapes preserved.›
    {((q, AR_SimWrite, tk, i, buf, dvec, posk), a,
       (q, AR_SimWrite, k_succ tk, 0, buf, dvec, posk), a', d) |
     q tk i buf dvec posk a a' d.
       q  Q_tm M
        posk tk  AR_AtLE
        ¬ is_last_k M tk
        Suc i = 2 * block_width (Γ_tm M)
        a' = (λkk. if kk = tk
                       then write_bit (Γ_tm M) (bl_tm M)
                                       (buf tk)
                                       (i - block_width (Γ_tm M))
                       else a kk)
        d = (λkk. if kk = tk then dir.R else dir.N)}
    
    ― ‹Proper-arm, forward-write boundary, last tape:
       same last-cell write as above, transitions to
       AR_SimAdvance› with the current-tape index
       reset to k_unidx 0›.›
    {((q, AR_SimWrite, tk, i, buf, dvec, posk), a,
       (q, AR_SimAdvance, k_unidx 0, 0, buf, dvec, posk), a', d) |
     q tk i buf dvec posk a a' d.
       q  Q_tm M
        posk tk  AR_AtLE
        is_last_k M tk
        Suc i = 2 * block_width (Γ_tm M)
        a' = (λkk. if kk = tk
                       then write_bit (Γ_tm M) (bl_tm M)
                                       (buf tk)
                                       (i - block_width (Γ_tm M))
                       else a kk)
        d = (λkk. if kk = tk then dir.R else dir.N)}"

definition ar_delta_advance ::
  "('q, 'a) mttm
     (('q × 'a ar_stage)
        × (nat  sym4)
        × ('q × 'a ar_stage)
        × (nat  sym4)
        × (nat  dir)) set" where
  "ar_delta_advance M =
    ― ‹Stepping arm: head moves L› on tape
       tk›, N› elsewhere; stays in
       AR_SimAdvance› with the bit-counter
       advanced.  Active when Suc i› is strictly
       below the per-tape displacement
       ar_disp b (dvec tk) (posk tk)›; the
       R›- and L›-from-AR_AtLE›
       cases have displacement 0›, so no stepping
       tuple fires; for N›-from-AR_AtLE›
       the displacement is 1›, so stepping never
       fires and the single substep goes through one of the
       boundary arms.  The read symbol on tk› must
       not be LE4› (δLE›: an
       L›-move from a tape reading LE4›
       is forbidden).›
    {((q, AR_SimAdvance, tk, i, buf, dvec, posk), a,
       (q, AR_SimAdvance, tk, Suc i, buf, dvec, posk), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        a tk  LE4
        Suc i < ar_disp (block_width (Γ_tm M)) (dvec tk) (posk tk)
        d = (λkk. if kk = tk then dir.L else dir.N)}
    
    ― ‹Boundary arm, non-last tape.  Two firing
       sub-cases: the R›-direction case (zero
       displacement, no L›-move; i = 0›
       and the entire direction vector is N›), and
       the non-R› case at Suc i› equal to
       the displacement (one last L›-move on
       tk›; a tk ≠ LE4› enforced for
       δLE›).  Both sub-cases transition to
       the same phase on the next tape k_succ tk›
       (bit-counter reset to 0›) with
       posk tk› updated by ar_newpos›;
       all other tapes' posk› entries are
       preserved.›
    {((q, AR_SimAdvance, tk, i, buf, dvec, posk), a,
       (q, AR_SimAdvance, k_succ tk, 0, buf, dvec,
        posk(tk := ar_newpos (dvec tk) (posk tk))), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        ¬ is_last_k M tk
        ((dvec tk = dir.R  i = 0)
           (dvec tk  dir.R
               a tk  LE4
               Suc i = ar_disp (block_width (Γ_tm M))
                                  (dvec tk) (posk tk)))
        d = (λkk. if kk = tk  dvec tk  dir.R
                      then dir.L else dir.N)}
    
    ― ‹Boundary arm, last tape.  Same firing
       sub-cases as the non-last-tape arm; transitions to
       AR_SimNext› instead of advancing
       tk›.  The current-tape field is reset to
       k_unidx 0› (the first tape in the
       enumeration; matches AR_SimNext›'s starting
       convention and the next AR_SimRead›'s
       initial tape).›
    {((q, AR_SimAdvance, tk, i, buf, dvec, posk), a,
       (q, AR_SimNext, k_unidx 0, 0, buf, dvec,
        posk(tk := ar_newpos (dvec tk) (posk tk))), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M
        is_last_k M tk
        ((dvec tk = dir.R  i = 0)
           (dvec tk  dir.R
               a tk  LE4
               Suc i = ar_disp (block_width (Γ_tm M))
                                  (dvec tk) (posk tk)))
        d = (λkk. if kk = tk  dvec tk  dir.R
                      then dir.L else dir.N)}"

definition ar_delta_next ::
  "('q, 'a) mttm
     (('q × 'a ar_stage)
        × (nat  sym4)
        × ('q × 'a ar_stage)
        × (nat  sym4)
        × (nat  dir)) set" where
  "ar_delta_next M =
    {((q, AR_SimNext, tk, i, buf, dvec, posk), a,
       (q, AR_SimRead, 0, 0, buf, dvec, posk), a, d) |
     q tk i buf dvec posk a d.
       q  Q_tm M  q  t_tm M  q  r_tm M
        d = (λ_. dir.N)}
    
    {((q, AR_SimNext, tk, i, buf, dvec, posk), a,
       (q, AR_HaltAccept, 0, 0,
        (λ_. bl_tm M), (λ_. dir.N), (λ_. AR_AtLE)), a, d) |
     q tk i buf dvec posk a d.
       q = t_tm M
        d = (λ_. dir.N)}
    
    {((q, AR_SimNext, tk, i, buf, dvec, posk), a,
       (q, AR_HaltReject, 0, 0,
        (λ_. bl_tm M), (λ_. dir.N), (λ_. AR_AtLE)), a, d) |
     q tk i buf dvec posk a d.
       q = r_tm M
        d = (λ_. dir.N)}"
  ― ‹End-of-M-step handshake.  Three arms dispatch on the
     M-state q›: non-terminal routes to
     AR_SimRead› for the next M-step (with bit-counter
     and current-tape both reset to 0); q = t_tm M›
     routes to the canonical accept stage; q = r_tm M›
     routes to the canonical reject stage.  The non-terminal
     arm preserves buf›, the direction-vector field
     dvec› (residual from the just-completed M-step; no
     longer consulted), and the per-tape position-kind
     posk› (carries the head-region across M-steps so the
     next AR_SimRead›'s LE-vs-proper dispatch sees the
     correct value).  The two terminal arms instead reset
     buf› / dvec› / posk› to the canonical
     halt values (λ_. bl_tm M› / λ_.
     dir.N› / λ_. AR_AtLE›), so the target stage
     is exactly ar_accept_stage (bl_tm M)› /
     ar_reject_stage (bl_tm M)› and the handshake lands
     on M'›'s halt state t_tm M'› / r_tm
     M'›.  Lang_mttm› matches the full mt_state›
     (tape and heads free), so this canonical landing is what
     makes M'› acceptance / rejection detectable; the reset
     is semantically free (the residual fields are never read
     after halting).  The direction vector is all N›
     (no head moves at the handshake); cell vectors
     a' = a› (no writes), so LE-preservation passes
     trivially.›

text ‹The output machine's full transition relation: union of
  the five per-substep relations, intersected with three global
  restrictions — δLE›-backward (no transition forges
  LE4› out of a non-LE4› cell),
  δLE›-forward (every transition reading LE4›
  on tape k› rewrites LE4› back on the same tape
  and moves N› or R›), and
  ar_valid_stage›-membership on both source and target
  stages.  The two δLE› filters together discharge
  the substrate's bidirectional δLE› invariant
  uniformly — without per-arm a tk ≠ LE4›
  preconditions on every arm that performs a write distinct from
  the read cell (proper-arm forward-write in particular).  The
  per-arm a tk ≠ LE4› constraints that do appear (in
  look-back step 1, back-walk, and advance L-step) reflect the
  simulation invariant rather than the bare δLE›
  requirement: those arms move L› on the current tape,
  which the substrate forbids from an LE4› cell
  regardless of write content.›

definition alphabet_reduce_delta ::
  "('q, 'a) mttm
     (('q × 'a ar_stage)
        × (nat  sym4)
        × ('q × 'a ar_stage)
        × (nat  sym4)
        × (nat  dir)) set" where
  "alphabet_reduce_delta M =
     (ar_delta_read M  ar_delta_compute M
         ar_delta_write M  ar_delta_advance M
         ar_delta_next M)
      {(s, a, s', a', d).
           k. a' k = LE4  a k = LE4}
      {(s, a, s', a', d).
           k. a k = LE4  a' k = LE4  d k  {dir.N, dir.R}}
      {(s, a, s', a', d).
           ar_valid_stage (Γ_tm M) (bl_tm M) (snd s)
            ar_valid_stage (Γ_tm M) (bl_tm M) (snd s')}
      {(s, a, s', a', d).
           j  k_tm M. a j = BLANK4  a' j = BLANK4  d j = dir.N}
      {(s, a, s', a', d).
           ar_stage_bounded (bl_tm M) (k_tm M) (snd s)
            ar_stage_bounded (bl_tm M) (k_tm M) (snd s')}"


text ‹Initial / halt stages used to populate the output
  machine's s'› / t'› / r'›
  components.  All three share the same shape: substep-counter
  i = 0›, current-tape 0›
  placeholder (per-tape phase fields are inactive in
  AR_SimRead›'s initial entry and inactive in halt
  states), per-tape buf› initialised to
  bl› (any value in Γ ∪ ⦃bl⦄› would
  satisfy ar_valid_stage›; bl› is the
  canonical placeholder), per-tape direction-vector
  dir.N› (irrelevant outside AR_SimAdvance›),
  per-tape position-kind AR_AtLE› (the initial
  head position is 0›; for halt states the field is
  vestigial).  The three stages differ only in their
  ar_substep_idx› tag.›

definition ar_init_stage ::
  "'a  'a ar_stage" where
  "ar_init_stage bl =
     (AR_SimRead, 0, 0, (λ_. bl), (λ_. dir.N), (λ_. AR_AtLE))"

definition ar_accept_stage ::
  "'a  'a ar_stage" where
  "ar_accept_stage bl =
     (AR_HaltAccept, 0, 0, (λ_. bl), (λ_. dir.N), (λ_. AR_AtLE))"

definition ar_reject_stage ::
  "'a  'a ar_stage" where
  "ar_reject_stage bl =
     (AR_HaltReject, 0, 0, (λ_. bl), (λ_. dir.N), (λ_. AR_AtLE))"

text ‹Positivity of the block width: b› is bounded below
  by 1› via the max› on the right-hand side.  Used
  below to discharge the i < 2 ⋅ b› conjunct of
  ar_valid_stage› at i = 0›, and downstream by
  the per-substep step-count lemmas.›

lemma block_width_pos: "1  block_width Γ"
  unfolding block_width_def by simp

text ‹The three stage constants used to populate s'›,
  t'›, and r'› all satisfy
  ar_valid_stage Γ bl› for any Γ›
  and bl›: the bit-counter is 0 < 2 ⋅ b›
  (since b ≥ 1›) and the buf field is constantly
  bl ∈ Γ ∪ ⦃bl⦄›.›

lemma ar_valid_stage_init: "ar_valid_stage Γ bl (ar_init_stage bl)"
proof -
  have "(0 :: nat) < 2 * block_width Γ" using block_width_pos[of Γ] by linarith
  thus ?thesis
    unfolding ar_valid_stage_def ar_init_stage_def by simp
qed

lemma ar_valid_stage_accept: "ar_valid_stage Γ bl (ar_accept_stage bl)"
proof -
  have "(0 :: nat) < 2 * block_width Γ" using block_width_pos[of Γ] by linarith
  thus ?thesis
    unfolding ar_valid_stage_def ar_accept_stage_def by simp
qed

lemma ar_valid_stage_reject: "ar_valid_stage Γ bl (ar_reject_stage bl)"
proof -
  have "(0 :: nat) < 2 * block_width Γ" using block_width_pos[of Γ] by linarith
  thus ?thesis
    unfolding ar_valid_stage_def ar_reject_stage_def by simp
qed


text ‹The alphabet-reduction combinator.  Input: mttm› over
  'a›, with tape alphabet Γ_tm M› a finite subset of
  'a› (via valid_mttm›) of cardinality ≥ 4›.
  Output: mttm› over sym4›, with state set
  'q × 'a ar_stage›.  Tape count k_tm M› is preserved.

  Output components:
   Q'› = Q_M × ⦃stg. ar_valid_stage Γ_M bl_M stg⦄›
    (the non-product Q-shape);
   Σ'› = ⦃BIT0, BIT1⦄›
    (the encoded input alphabet);
   Γ'› = UNIV :: sym4 set›
    (all four cell shapes — BIT0, BIT1, BLANK4, LE4);
   bl'› = BLANK4›, le'› = LE4›;
   δ'› = alphabet_reduce_delta M›
    (the five-substep union under the global LE-preservation
    and ar_valid_stage› filters);
   s'› = (s_M, ar_init_stage bl_M)›,
    t'› = (t_M, ar_accept_stage bl_M)›,
    r'› = (r_M, ar_reject_stage bl_M)›
    (M's start / accept / reject states paired with the
    matching ar_substep_idx› tag).›

definition alphabet_reduce ::
  "('q, 'a) mttm
     ('q × 'a ar_stage, sym4) mttm"
  where
    "alphabet_reduce M =
       (case M of MTTM Q_M _ Γ_M bl_M _ _ s_M t_M r_M k_M 
          MTTM (Q_M × {stg. ar_valid_stage Γ_M bl_M stg
                               ar_stage_bounded bl_M k_M stg})
               {BIT0, BIT1}
               (UNIV :: sym4 set)
               BLANK4
               LE4
               (alphabet_reduce_delta M)
               (s_M, ar_init_stage bl_M)
               (t_M, ar_accept_stage bl_M)
               (r_M, ar_reject_stage bl_M)
               k_M)"

text ‹Projection-simp lemmas for the reduced machine: each
  structural accessor reads straight off the MTTM› the
  combinator builds.  Marked [simp]› so the language and
  time proofs never re-derive them via cases M›; the
  accept-state projection in particular is the bridge that makes
  the simulation engine's terminal state syntactically equal to
  t_tm (alphabet_reduce M)›.›

lemma alphabet_reduce_Sigma [simp]:
  "Sigma_tm (alphabet_reduce M) = {BIT0, BIT1}"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_Gamma [simp]:
  "Γ_tm (alphabet_reduce M) = (UNIV :: sym4 set)"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_bl [simp]:
  "bl_tm (alphabet_reduce M) = BLANK4"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_le [simp]:
  "le_tm (alphabet_reduce M) = LE4"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_start [simp]:
  "s_tm (alphabet_reduce M) = (s_tm M, ar_init_stage (bl_tm M))"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_accept [simp]:
  "t_tm (alphabet_reduce M) = (t_tm M, ar_accept_stage (bl_tm M))"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_reject [simp]:
  "r_tm (alphabet_reduce M) = (r_tm M, ar_reject_stage (bl_tm M))"
  by (cases M) (simp add: alphabet_reduce_def)

lemma alphabet_reduce_delta [simp]:
  "delta_tm (alphabet_reduce M) = alphabet_reduce_delta M"
  by (cases M) (simp add: alphabet_reduce_def)

end