Theory AlphabetEnlargement_ForwardStep

theory AlphabetEnlargement_ForwardStep
  imports AlphabetEnlargement_ForwardCells
begin

subsection ‹Forward-stage SS5--SS8 super-step›

text ‹The middle link of the forward-stage chain
  ForwardCells → ForwardStep → ForwardStage›: the
  SS5→›SS8 substep chain of
  ae_simulates_forward_stage_general›.  From the SS5-entry config
  c4› (its invariant ae_inv_ss5›, the
  γ›-block and buffer side-bands, and the per-tape
  regime data) it runs the four substeps ae_delta_ss5_ss6›,
  ae_delta_ss6_ss7›, ae_delta_ss7_ss8›,
  ae_delta_ss8_ss1›, exposing the intermediate configs
  c5›, c6›, c7›, c8›, their shared
  SS-stage state tuple (q5, ofs5, buf5, dest5)› =
  (q6, ofs6, buf6, dest6)›, and the per-tape position and
  tape-content facts the reconstruction leaves
  (AlphabetEnlargement_ForwardCells›) consume.
  Carved out of ae_simulates_forward_stage_general› as its
  widest single seam (17 assumptions, 29 conclusions); the call site
  re-binds the named facts verbatim.›
lemma ae_forward_stage_step_chain:
  fixes M :: "('q, 'a) mttm"
    and cM :: "('a, 'q) mt_config"
    and c' c1 c2 c3 c4 :: "('c :: enum  'a,
                'q × ('a, 'c) ae_stage) mt_config"
  assumes vM:        "valid_mttm M"
      and le_anchor:
      "k<k_tm M. mt_tape c' k 0 = LE_block (le_tm M)"
      and no_le_per_tape:
      "k. (mt_pos c' k  2
       (i. i < 3 * card (UNIV :: 'c set)
       mt_tape cM k
      ((mt_pos c' k - 2) * card (UNIV :: 'c set) + 1 + i)
       le_tm M))
       (mt_pos c' k = 1
       (i. i < 2 * card (UNIV :: 'c set)
       mt_tape cM k (Suc i)  le_tm M))
       (mt_pos c' k = 0
       (i. i < card (UNIV :: 'c set)
       mt_tape cM k (Suc i)  le_tm M))"
      and tape_corr: "k<k_tm M. ae_tape_correspondence (le_tm M)
      (mt_tape cM k) (mt_tape c' k)"
      and step1_sub: "(c', c1)  mttm_step (ae_delta_ss1_ss2 M)"
      and step2_sub: "(c1, c2)  mttm_step (ae_delta_ss2_ss3 M)"
      and step3_sub: "(c2, c3)  mttm_step (ae_delta_ss3_ss4 M)"
      and c_ge_1: "1  card (UNIV :: 'c set)"
      and c_eq_len: "card (UNIV :: 'c set) = length (enum_class.enum :: 'c list)"
      and home_classification:
      "k<k_tm M. (mt_pos c' k = 0
       mt_tape c' k (mt_pos c' k) = LE_block (le_tm M))
       (mt_pos c' k  1
       mt_tape c' k (mt_pos c' k)  LE_block (le_tm M))"
      and c3_pos: "k. k < k_tm M  mt_pos c3 k = mt_pos c' k + 1"
      and bl_neq_le:
      "(bl_block (bl_tm M) :: 'c  'a)  LE_block (le_tm M)"
      and step4_sub: "(c3, c4)  mttm_step (ae_delta_ss4_ss5 M)"
      and c4_buf_not_le_per_tape:
      "case mt_state c4 of (_, _, b, _, _) 
      kk<k_tm M. (mt_pos c' kk = 0
       fst (b kk)  LE_block (le_tm M)
       snd (snd (b kk))  LE_block (le_tm M))
       (mt_pos c' kk = 1
       fst (snd (b kk))  LE_block (le_tm M)
       snd (snd (b kk))  LE_block (le_tm M))
       (mt_pos c' kk  2
       fst (b kk)  LE_block (le_tm M)
       fst (snd (b kk))  LE_block (le_tm M)
       snd (snd (b kk))  LE_block (le_tm M))"
      and inv_ss5: "ae_inv_ss5 M c4"
      and gamma_c4: "ae_tape_in_gamma_block M c4"
      and buf_gamma_c4: "ae_buffer_in_gamma_block M c4"
  obtains c5 q5 ofs5 buf5 dest5 c6 c7 q6 ofs6 buf6 dest6 c8
    where "(c4, c5)  mttm_step (ae_delta_ss5_ss6 M)"
      and "(c4, c5)  mttm_step (alphabet_enlarge_delta M)"
      and "mt_state c4 = (q5, ofs5, buf5, dest5, SS5)"
      and "mt_state c5 = (q5, ofs5, buf5, dest5, SS6)"
      and "mt_tape c4 = mt_tape c'"
      and
      "k<k_tm M. (mt_pos c' k = 0
       fst (buf5 k)  LE_block (le_tm M)
       snd (snd (buf5 k))  LE_block (le_tm M))
       (mt_pos c' k = 1
       fst (snd (buf5 k))  LE_block (le_tm M)
       snd (snd (buf5 k))  LE_block (le_tm M))
       (mt_pos c' k  2
       fst (buf5 k)  LE_block (le_tm M)
       fst (snd (buf5 k))  LE_block (le_tm M)
       snd (snd (buf5 k))  LE_block (le_tm M))"
      and
      "k. mt_tape c' k (mt_pos c' k + 1)  LE_block (le_tm M)"
      and "kk. kk < k_tm M  mt_pos c4 kk = mt_pos c' kk"
      and "k<k_tm M. mt_tape c5 k 0 = LE_block (le_tm M)"
      and
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk  AE_Left
       mt_pos c5 kk = 0"
      and "(c5, c6)  mttm_step (ae_delta_ss6_ss7 M)"
      and "(c5, c6)  mttm_step (alphabet_enlarge_delta M)"
      and "(c6, c7)  mttm_step (ae_delta_ss7_ss8 M)"
      and "(c6, c7)  mttm_step (alphabet_enlarge_delta M)"
      and "ae_tape_in_gamma_block M c7"
      and "ae_buffer_in_gamma_block M c7"
      and "mt_state c6 = (q6, ofs6, buf6, dest6, SS7)"
      and "mt_state c7 = (q6, ofs6, buf6, dest6, SS8)"
      and "buf6 = buf5"
      and "q6 = q5"
      and "ofs6 = ofs5"
      and "dest6 = dest5"
      and
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
       mt_pos c5 kk = 2"
      and
      "kk. kk < k_tm M  mt_pos c' kk = 1
       mt_tape c5 kk 1 = fst (snd (buf5 kk))"
      and
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
       mt_pos c6 kk = 1"
      and
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
       mt_pos c7 kk = 0"
      and
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
       mt_tape c7 kk 0 = LE_block (le_tm M)"
      and "(c7, c8)  mttm_step (ae_delta_ss8_ss1 M)"
      and "(c7, c8)  mttm_step (alphabet_enlarge_delta M)"
proof -
  obtain c5 where
      step5_sub: "(c4, c5)  mttm_step (ae_delta_ss5_ss6 M)"
    and step5: "(c4, c5)  mttm_step (alphabet_enlarge_delta M)"
    using ae_step_ss5_ss6_exists[OF inv_ss5 gamma_c4 buf_gamma_c4] by blast
  have inv_ss6: "ae_inv_ss6 M c5"
    using ae_step_ss5_ss6_invariant[OF vM inv_ss5 step5_sub] .
  have gamma_c5: "ae_tape_in_gamma_block M c5"
    using ae_step_alphabet_enlarge_gamma_preserve[OF gamma_c4 step5] .
  have buf_gamma_c5: "ae_buffer_in_gamma_block M c5"
    using ae_step_alphabet_enlarge_buffer_gamma_preserve[OF vM buf_gamma_c4
                                                            gamma_c4 step5] .

  ― ‹State shapes at c4› (idx SS5) and c5› (idx SS6).
      Identical derivation across regimes; the substep preserves
      (q, ofs, buf, dest)› and flips only the stage index.›
  obtain q5 ofs5 buf5 dest5 where
      c4_state: "mt_state c4 = (q5, ofs5, buf5, dest5, SS5)"
    using inv_ss5 unfolding ae_inv_ss5_def
    by (cases "mt_state c4") auto
  have c5_state: "mt_state c5 = (q5, ofs5, buf5, dest5, SS6)"
    using step5_sub c4_state
    by (auto simp: ae_delta_ss5_ss6_def elim: mttm_step.cases)

  ― ‹Sub-step 5b: M'-tape preservation through SS1→›SS2 →›
      …› →›SS5.  Each sub-delta has a' = a› (idempotent
      on M'›-tape), so the cumulative tape is unchanged through
      c1›…›c4›.  Uniform across regimes.›
  have nw_12: "q a q' a' d.
                  (q, a, q', a', d)  ae_delta_ss1_ss2 M  a' = a"
    by (auto simp: ae_delta_ss1_ss2_def)
  have nw_23: "q a q' a' d.
                  (q, a, q', a', d)  ae_delta_ss2_ss3 M  a' = a"
    by (auto simp: ae_delta_ss2_ss3_def)
  have nw_34: "q a q' a' d.
                  (q, a, q', a', d)  ae_delta_ss3_ss4 M  a' = a"
    by (auto simp: ae_delta_ss3_ss4_def)
  have nw_45: "q a q' a' d.
                  (q, a, q', a', d)  ae_delta_ss4_ss5 M  a' = a"
    by (auto simp: ae_delta_ss4_ss5_def)
  have tape_c1_eq: "mt_tape c1 = mt_tape c'"
    using mttm_step_no_write_tape[OF step1_sub nw_12] .
  have tape_c2_eq: "mt_tape c2 = mt_tape c1"
    using mttm_step_no_write_tape[OF step2_sub nw_23] .
  have tape_c3_eq: "mt_tape c3 = mt_tape c2"
    using mttm_step_no_write_tape[OF step3_sub nw_34] .
  have tape_c4_eq: "mt_tape c4 = mt_tape c3"
    using mttm_step_no_write_tape[OF step4_sub nw_45] .
  have tape_c4_eq_c': "mt_tape c4 = mt_tape c'"
    using tape_c1_eq tape_c2_eq tape_c3_eq tape_c4_eq by simp

  ― ‹Buf5 per-tape regime-aware non-LE shape, transferred from
      c4_buf_not_le_per_tape› via c4_state›.  Pos=0 tapes have
      left+right non-LE; pos=1 tapes have home+right non-LE; pos≥›2
      tapes have all three non-LE.  This is the regime-aware
      generalisation of buf5_not_le_lr› (le0) and buf5_not_le_hr›
      (le1) and the steady-state full buf5_not_le›.›
  have buf5_not_le_per_tape:
      "k<k_tm M. (mt_pos c' k = 0
              fst (buf5 k)  LE_block (le_tm M)
                 snd (snd (buf5 k))  LE_block (le_tm M))
            (mt_pos c' k = 1
                 fst (snd (buf5 k))  LE_block (le_tm M)
                   snd (snd (buf5 k))  LE_block (le_tm M))
            (mt_pos c' k  2
                 fst (buf5 k)  LE_block (le_tm M)
                   fst (snd (buf5 k))  LE_block (le_tm M)
                   snd (snd (buf5 k))  LE_block (le_tm M))"
    using c4_buf_not_le_per_tape c4_state by simp

  ― ‹Sub-step 5c: right_not_le_c'›.  The unified "right-of-home
      not LE" fact at c'›: for every tape, the block at
      mt_pos c' k + 1› is not LE_block›.  Powers the SS4→›SS5
      head-trajectory derivation (c3› reads at mt_pos c3 = mt_pos c' + 1›,
      direction L› when read ≠ LE›).  Per-tape case-split on regime:
      pos=0 uses no_le› i=0 (cell 1); pos=1 uses no_le› i=c (cell c+1);
      pos≥›2 uses no_le› i=2c (cell pos⋅›c+1).  All three cell
      indices coincide with the correspondence-derived address
      mt_pos c' k ⋅ c + 1›.›
  have right_not_le_c':
      "k. mt_tape c' k (mt_pos c' k + 1)  LE_block (le_tm M)"
  proof (intro allI)
    fix k :: nat
    show "mt_tape c' k (mt_pos c' k + 1)  LE_block (le_tm M)"
    proof (cases "k < k_tm M")
      case True
    let ?x = "(enum_class.enum :: 'c list) ! 0"
    let ?c = "card (UNIV :: 'c set)"
    have zero_lt_len: "0 < length (enum_class.enum :: 'c list)"
      using c_ge_1 c_eq_len by linarith
    have x_idx0: "c_idx ?x = 0"
      using c_idx_enum_nth[OF zero_lt_len] .
    have tc_k: "ae_tape_correspondence (le_tm M) (mt_tape cM k) (mt_tape c' k)"
      using tape_corr[rule_format, OF True] .
    have addr_via_tc:
        "mt_tape cM k (mt_pos c' k * ?c + 1)
          = mt_tape c' k (mt_pos c' k + 1) ?x"
    proof -
      from tc_k have unf:
          "s1. i. mt_tape cM k ((s - 1) * ?c + c_idx i + 1)
                      = mt_tape c' k s i"
        unfolding ae_tape_correspondence_def by simp
      have s_ge1: "mt_pos c' k + 1  1" by simp
      from unf s_ge1 have eq:
          "mt_tape cM k ((mt_pos c' k + 1 - 1) * ?c + c_idx ?x + 1)
            = mt_tape c' k (mt_pos c' k + 1) ?x"
        by blast
      thus ?thesis using x_idx0 by simp
    qed
    consider (le0) "mt_pos c' k = 0"
           | (le1) "mt_pos c' k = 1"
           | (steady) "mt_pos c' k  2"
      by linarith
    hence "mt_tape c' k (mt_pos c' k + 1) ?x  le_tm M"
    proof cases
      case le0
      have idx_lt: "(0 :: nat) < ?c" using c_ge_1 by simp
      have nle: "mt_tape cM k (Suc 0)  le_tm M"
        using no_le_per_tape le0 idx_lt by blast
      thus ?thesis using addr_via_tc le0 by simp
    next
      case le1
      have idx_lt: "?c < 2 * ?c" using c_ge_1 by simp
      have nle: "mt_tape cM k (Suc ?c)  le_tm M"
        using no_le_per_tape le1 idx_lt by blast
      hence "mt_tape cM k (1 * ?c + 1)  le_tm M" by simp
      thus ?thesis using addr_via_tc le1 by simp
    next
      case steady
      have idx_lt: "2 * ?c < 3 * ?c" using c_ge_1 by simp
      have addr_eq:
          "(mt_pos c' k - 2) * ?c + 1 + 2 * ?c = mt_pos c' k * ?c + 1"
        using steady by (simp add: algebra_simps diff_mult_distrib)
      have nle: "mt_tape cM k ((mt_pos c' k - 2) * ?c + 1 + 2 * ?c)  le_tm M"
        using no_le_per_tape steady idx_lt by blast
      thus ?thesis using addr_via_tc addr_eq by simp
    qed
    thus "mt_tape c' k (mt_pos c' k + 1)  LE_block (le_tm M)"
      unfolding LE_block_def by auto
    next
      case False
      hence kge: "k_tm M  k" by simp
      have "mt_tape c' k (mt_pos c' k + 1) = bl_block (bl_tm M)"
        using gamma_c4 kge
        unfolding ae_tape_in_gamma_block_def tape_c4_eq_c'[symmetric]
        by simp
      thus ?thesis using bl_neq_le by simp
    qed
  qed

  ― ‹Sub-step 5d: SS4→›SS5 head trajectory.  At c3›'s head
      position mt_pos c3 k = mt_pos c' k + 1›, the M'-tape reads
      mt_tape c' k (mt_pos c' k + 1)› (via tape_c3_eq_c'›) which
      is not LE_block› by right_not_le_c'›.  Hence
      ae_delta_ss4_ss5›'s direction is L›, landing c4›'s head
      at mt_pos c' k›.  Uniform across regimes: pos=0 lands at 0,
      pos=1 lands at 1, pos≥›2 lands at pos.›
  have tape_c3_eq_c': "mt_tape c3 = mt_tape c'"
    using tape_c1_eq tape_c2_eq tape_c3_eq by simp
  have c4_pos: "kk. kk < k_tm M  mt_pos c4 kk = mt_pos c' kk"
  proof -
    fix kk assume kklt: "kk < k_tm M"
    obtain qq tts nn qq' aa4 dr4 where
        c3_eq4: "c3 = ConfigM qq tts nn"
      and c4_eq: "c4 = ConfigM qq'
                          (λk. (tts k)(nn k := aa4 k))
                          (λk. go_dir (dr4 k) (nn k))"
      and tr_in: "(qq, λk. tts k (nn k), qq', aa4, dr4)
                     ae_delta_ss4_ss5 M"
      using step4_sub by (auto elim: mttm_step.cases)
    have dr4_eq:
        "dr4 = (λk. if k < k_tm M
                     then (if tts k (nn k) = LE_block (le_tm M)
                           then dir.N else dir.L)
                     else dir.N)"
      using tr_in by (auto simp: ae_delta_ss4_ss5_def)
    have nn_kk: "nn kk = mt_pos c3 kk" using c3_eq4 by simp
    have tts_kk: "tts kk (nn kk) = mt_tape c3 kk (mt_pos c3 kk)"
      using c3_eq4 nn_kk by simp
    have c3_kk: "mt_pos c3 kk = mt_pos c' kk + 1"
      using c3_pos kklt by simp
    have read_at_c3:
        "tts kk (nn kk) = mt_tape c' kk (mt_pos c' kk + 1)"
      using tts_kk c3_kk tape_c3_eq_c' by simp
    have read_ne_LE: "tts kk (nn kk)  LE_block (le_tm M)"
      using read_at_c3 right_not_le_c' by simp
    have dr4_L: "dr4 kk = dir.L"
      using dr4_eq read_ne_LE kklt by simp
    have "mt_pos c4 kk = go_dir (dr4 kk) (nn kk)" using c4_eq by simp
    also have " = (nn kk) - 1" using dr4_L by simp
    also have " = (mt_pos c3 kk) - 1" using nn_kk by simp
    also have " = (mt_pos c' kk + 1) - 1" using c3_kk by simp
    also have " = mt_pos c' kk" by simp
    finally show "mt_pos c4 kk = mt_pos c' kk" .
  qed

  ― ‹Sub-step 5e: tape_c5_zero_le›.  The M'-tape cell 0 stays
      LE_block› across SS5.  For pos≥›1 tapes c4_pos ≠ 0›, so
      cell 0 is off-head and preserved from c4› (which equals c'›
      by tape_c4_eq_c'›, hence LE_block› by le_anchor›).  For pos=0
      tapes c4_pos = 0›, so the SS5 action fires at cell 0; but the
      LE-guard fires (read = LE_block› via le_anchor›) and
      idempotently writes LE_block› back.  Either way cell 0 stays.›
  have tape_c5_zero_le: "k<k_tm M. mt_tape c5 k 0 = LE_block (le_tm M)"
  proof (intro allI impI)
    fix k assume klt: "k < k_tm M"
    consider (le0) "mt_pos c' k = 0" | (rest) "mt_pos c' k  1" by linarith
    thus "mt_tape c5 k 0 = LE_block (le_tm M)"
    proof cases
      case rest
      have c4_kk_ne0: "mt_pos c4 k  0"
        using c4_pos[OF klt] rest by simp
      have zero_ne_pos: "(0 :: nat)  mt_pos c4 k" using c4_kk_ne0 by simp
      have c5_zero_eq_c4: "mt_tape c5 k 0 = mt_tape c4 k 0"
        using mttm_step_tape_off_head[OF step5 zero_ne_pos] .
      have "mt_tape c4 k 0 = mt_tape c' k 0"
        using tape_c4_eq_c' by simp
      also have " = LE_block (le_tm M)"
        using le_anchor[rule_format, OF klt] by simp
      finally show ?thesis using c5_zero_eq_c4 by simp
    next
      case le0
      have c4_pos_kk: "mt_pos c4 k = 0"
        using c4_pos[OF klt] le0 by simp
      obtain qq tts nn qq' aa5 dr5 where
          c4_eq5: "c4 = ConfigM qq tts nn"
        and c5_eq: "c5 = ConfigM qq'
                            (λk. (tts k)(nn k := aa5 k))
                            (λk. go_dir (dr5 k) (nn k))"
        and tr_in: "(qq, λk. tts k (nn k), qq', aa5, dr5)
                       ae_delta_ss5_ss6 M"
        using step5_sub by (auto elim: mttm_step.cases)
      obtain q ofs buf dest where
          qq_eq: "qq = (q, ofs, buf, dest, SS5)"
        and aa5_eq: "aa5 = (λk. if k < k_tm M
                                  then fst (ae_ss5_action (le_tm M)
                                             (tts k (nn k)) (buf k) (dest k))
                                  else bl_block (bl_tm M))"
        using tr_in by (auto simp: ae_delta_ss5_ss6_def)
      have nn_kk: "nn k = mt_pos c4 k" using c4_eq5 by simp
      have nn_kk_0: "nn k = 0" using nn_kk c4_pos_kk by simp
      have tts_kk: "tts k (nn k) = mt_tape c4 k (mt_pos c4 k)"
        using c4_eq5 nn_kk by simp
      have read_at: "tts k (nn k) = mt_tape c' k 0"
        using tts_kk c4_pos_kk tape_c4_eq_c' by simp
      have read_LE: "tts k (nn k) = LE_block (le_tm M)"
        using read_at le_anchor[rule_format, OF klt] by simp
      obtain l h r where buf_k: "buf k = (l, h, r)"
        by (cases "buf k") auto
      have aa5_LE: "aa5 k = LE_block (le_tm M)"
        using aa5_eq read_LE buf_k klt by simp
      have step_apply: "mt_tape c5 k 0 = ((tts k)(nn k := aa5 k)) 0"
        using c5_eq by simp
      have hit: "((tts k)(nn k := aa5 k)) 0 = aa5 k"
        using nn_kk_0 by simp
      show ?thesis using step_apply hit aa5_LE by simp
    qed
  qed

  ― ‹Sub-step 5f: head trajectory at SS5 for pos=1 tapes.  When
      the regime is pos=1 and dest5 k ≠ AE_Left›, the SS5 action
      moves L›, landing c5›'s head at block 0 (the LE
      position).  Read at c4_pos = 1› is mt_tape c' k 1 ≠ LE›
      (via home_classification› pos≥›1 branch); buf5 home ≠ LE›
      (via buf5_not_le_per_tape› pos=1 branch).  Neither LE-guard
      in ae_ss5_action› fires; direction is L› when
      dest ≠ AE_Left›.›
  have c5_pos_for_pos1:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk  AE_Left
             mt_pos c5 kk = 0"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    assume dest_ne: "dest5 kk  AE_Left"
    obtain qq tts nn qq' aa5 dr5 where
        c4_eq5: "c4 = ConfigM qq tts nn"
      and c5_eq: "c5 = ConfigM qq'
                          (λk. (tts k)(nn k := aa5 k))
                          (λk. go_dir (dr5 k) (nn k))"
      and tr_in: "(qq, λk. tts k (nn k), qq', aa5, dr5)
                     ae_delta_ss5_ss6 M"
      using step5_sub by (auto elim: mttm_step.cases)
    obtain q ofs buf dest where
        qq_eq: "qq = (q, ofs, buf, dest, SS5)"
      and dr5_eq:
          "dr5 = (λk. if k < k_tm M
                       then snd (ae_ss5_action (le_tm M)
                                  (tts k (nn k)) (buf k) (dest k))
                       else dir.N)"
      using tr_in by (auto simp: ae_delta_ss5_ss6_def)
    have qq_state: "qq = (q5, ofs5, buf5, dest5, SS5)"
      using c4_state c4_eq5 by simp
    have buf_eq: "buf = buf5" using qq_eq qq_state by simp
    have dest_eq: "dest = dest5" using qq_eq qq_state by simp
    have nn_kk: "nn kk = mt_pos c4 kk" using c4_eq5 by simp
    have c4_kk: "mt_pos c4 kk = 1" using c4_pos kklt pos_kk by simp
    have tts_kk: "tts kk (nn kk) = mt_tape c4 kk (mt_pos c4 kk)"
      using c4_eq5 nn_kk by simp
    have read_at_home:
        "tts kk (nn kk) = mt_tape c' kk 1"
      using tts_kk c4_kk tape_c4_eq_c' by simp
    have home_ne_LE: "mt_tape c' kk 1  LE_block (le_tm M)"
    proof -
      have pos_ge1: "(1 :: nat)  mt_pos c' kk" using pos_kk by simp
      have "mt_tape c' kk (mt_pos c' kk)  LE_block (le_tm M)"
        using home_classification[rule_format, OF kklt] pos_ge1 by blast
      thus ?thesis using pos_kk by simp
    qed
    have read_ne_LE: "tts kk (nn kk)  LE_block (le_tm M)"
      using read_at_home home_ne_LE by simp
    obtain ll hh rr where buf5_kk: "buf5 kk = (ll, hh, rr)"
      using prod.exhaust by metis
    have h_ne_LE: "hh  LE_block (le_tm M)"
    proof -
      have "fst (snd (buf5 kk))  LE_block (le_tm M)"
        using buf5_not_le_per_tape[rule_format, OF kklt] pos_kk by blast
      thus ?thesis using buf5_kk by simp
    qed
    have dr5_kk:
        "dr5 kk = (if dest5 kk = AE_Left then dir.R else dir.L)"
      using dr5_eq buf_eq dest_eq buf5_kk read_ne_LE h_ne_LE kklt by simp
    have dr5_kk_L: "dr5 kk = dir.L"
      using dr5_kk dest_ne by simp
    have "mt_pos c5 kk = go_dir (dr5 kk) (nn kk)"
      using c5_eq by simp
    also have " = (nn kk) - 1" using dr5_kk_L by simp
    also have " = mt_pos c4 kk - 1" using nn_kk by simp
    also have " = 1 - 1" using c4_kk by simp
    also have " = 0" by simp
    finally show "mt_pos c5 kk = 0" .
  qed

  ― ‹Sub-step 5g: pos_link_c5›.  Discharges
      ae_position_link M c5› from regime-aware buffer facts +
      head trajectory.  Two conjuncts at idx=SS6: right-slot non-LE
      (uniform, follows from each regime branch of
      buf5_not_le_per_tape›) and the SS6 conditional
      (dest ≠ AE_Left› + fst (buf k) = LE_block› implies
      head reads LE_block›).  The SS6 conditional case-splits
      per-tape: pos=0/≥›2 tapes have fst (buf5 k) ≠ LE_block›
      so the antecedent is false (vacuous); pos=1 tapes use
      c5_pos_for_pos1› + tape_c5_zero_le› for the substantive
      case.›
  have pos_link_c5: "ae_position_link M c5"
  proof -
    have r_not_le: "k<k_tm M. snd (snd (buf5 k))  LE_block (le_tm M)"
    proof (intro allI impI)
      fix k
      assume klt: "k < k_tm M"
      consider (le0) "mt_pos c' k = 0"
             | (le1) "mt_pos c' k = 1"
             | (steady) "mt_pos c' k  2"
        by linarith
      thus "snd (snd (buf5 k))  LE_block (le_tm M)"
      proof cases
        case le0    thus ?thesis using buf5_not_le_per_tape[rule_format, OF klt] by blast
      next
        case le1    thus ?thesis using buf5_not_le_per_tape[rule_format, OF klt] by blast
      next
        case steady thus ?thesis using buf5_not_le_per_tape[rule_format, OF klt] by blast
      qed
    qed
    have ss6_cond:
        "k<k_tm M. dest5 k  AE_Left
                 fst (buf5 k) = LE_block (le_tm M)
                 mt_tape c5 k (mt_pos c5 k) = LE_block (le_tm M)"
    proof (intro allI impI)
      fix k
      assume klt: "k < k_tm M"
      assume dest_ne: "dest5 k  AE_Left"
      assume l_eq_le: "fst (buf5 k) = LE_block (le_tm M)"
      consider (le0) "mt_pos c' k = 0"
             | (le1) "mt_pos c' k = 1"
             | (steady) "mt_pos c' k  2"
        by linarith
      thus "mt_tape c5 k (mt_pos c5 k) = LE_block (le_tm M)"
      proof cases
        case le0
        have "fst (buf5 k)  LE_block (le_tm M)"
          using buf5_not_le_per_tape[rule_format, OF klt] le0 by blast
        thus ?thesis using l_eq_le by simp
      next
        case le1
        have c5_pos_zero: "mt_pos c5 k = 0"
          using c5_pos_for_pos1[OF klt le1 dest_ne] .
        have "mt_tape c5 k 0 = LE_block (le_tm M)"
          using tape_c5_zero_le[rule_format, OF klt] by simp
        thus ?thesis using c5_pos_zero by simp
      next
        case steady
        have "fst (buf5 k)  LE_block (le_tm M)"
          using buf5_not_le_per_tape[rule_format, OF klt] steady by blast
        thus ?thesis using l_eq_le by simp
      qed
    qed
    show ?thesis
      unfolding ae_position_link_def
      using r_not_le ss6_cond c5_state by simp
  qed

  ― ‹Sub-step 5h: SS6→›SS7 invocation.  Discharge ae_le_compat_ss6›
      from pos_link_c5›; invoke ae_step_ss6_ss7_exists›.  Propagate
      pos_link› from c5› (idx SS6) to c6› via the arm-agnostic
      preservation lemma (the three aux conditionals are vacuous: idx-pre
      is SS6, not SS4/5/7).  Identical to the corresponding le0/le1 / steady
      blocks.›
  have le_compat_ss6_c5: "ae_le_compat_ss6 M c5"
    using ae_position_link_discharges_ss6[OF inv_ss6 pos_link_c5] .
  obtain c6 where
      step6_sub: "(c5, c6)  mttm_step (ae_delta_ss6_ss7 M)"
    and step6: "(c5, c6)  mttm_step (alphabet_enlarge_delta M)"
    using ae_step_ss6_ss7_exists[OF inv_ss6 gamma_c5 buf_gamma_c5
                                    le_compat_ss6_c5] by blast
  have inv_ss7: "ae_inv_ss7 M c6"
    using ae_step_ss6_ss7_invariant[OF vM inv_ss6 step6_sub] .
  have gamma_c6: "ae_tape_in_gamma_block M c6"
    using ae_step_alphabet_enlarge_gamma_preserve[OF gamma_c5 step6] .
  have buf_gamma_c6: "ae_buffer_in_gamma_block M c6"
    using ae_step_alphabet_enlarge_buffer_gamma_preserve[OF vM buf_gamma_c5
                                                            gamma_c5 step6] .
  have c5_idx_ss6: "snd (snd (snd (snd (mt_state c5)))) = SS6"
    using c5_state by simp
  have aux_45_at_c5: "(c5, c6)  mttm_step (ae_delta_ss4_ss5 M)
                         ae_position_link M c6"
    using ae_pos_link_aux_void_ss4_ss5[where M = M and c_pre = c5 and c_post = c6]
          c5_idx_ss6 by simp
  have aux_56_at_c5: "(c5, c6)  mttm_step (ae_delta_ss5_ss6 M)
                         ae_position_link M c6"
    using ae_pos_link_aux_void_ss5_ss6[where M = M and c_pre = c5 and c_post = c6]
          c5_idx_ss6 by simp
  have aux_78_at_c5: "(c5, c6)  mttm_step (ae_delta_ss7_ss8 M)
                         ae_position_link M c6"
    using ae_pos_link_aux_void_ss7_ss8[where M = M and c_pre = c5 and c_post = c6]
          c5_idx_ss6 by simp
  have pos_link_c6: "ae_position_link M c6"
    using ae_step_alphabet_enlarge_position_link_preserve[OF pos_link_c5
            step6 aux_45_at_c5 aux_56_at_c5 aux_78_at_c5] .

  ― ‹Sub-step 5i: SS7→›SS8 invocation.  Discharge ae_le_compat_ss7›
      from pos_link_c6›; invoke ae_step_ss7_ss8_exists›.  Buffer
      content is preserved across SS5→›SS6→›SS7 (the substeps
      change only the tape and stage index, not the buffer component),
      so the buf5› per-tape non-LE shape transfers to buf6 = buf5›
      and c7›'s state inherits the same buffer triple.›
  have le_compat_ss7_c6: "ae_le_compat_ss7 M c6"
    using ae_position_link_discharges_ss7[OF inv_ss7 pos_link_c6] .
  obtain c7 where
      step7_sub: "(c6, c7)  mttm_step (ae_delta_ss7_ss8 M)"
    and step7: "(c6, c7)  mttm_step (alphabet_enlarge_delta M)"
    using ae_step_ss7_ss8_exists[OF inv_ss7 gamma_c6 buf_gamma_c6
                                    le_compat_ss7_c6] by blast
  have inv_ss8: "ae_inv_ss8 M c7"
    using ae_step_ss7_ss8_invariant[OF vM inv_ss7 step7_sub] .
  have gamma_c7: "ae_tape_in_gamma_block M c7"
    using ae_step_alphabet_enlarge_gamma_preserve[OF gamma_c6 step7] .
  have buf_gamma_c7: "ae_buffer_in_gamma_block M c7"
    using ae_step_alphabet_enlarge_buffer_gamma_preserve[OF vM buf_gamma_c6
                                                            gamma_c6 step7] .

  obtain q6 ofs6 buf6 dest6 where
      c5_state_eq: "mt_state c5 = (q6, ofs6, buf6, dest6, SS6)"
    using inv_ss6 unfolding ae_inv_ss6_def
    by (cases "mt_state c5") auto
  have c6_state: "mt_state c6 = (q6, ofs6, buf6, dest6, SS7)"
    using step6_sub c5_state_eq
    by (auto simp: ae_delta_ss6_ss7_def elim: mttm_step.cases)
  have c7_state: "mt_state c7 = (q6, ofs6, buf6, dest6, SS8)"
    using step7_sub c6_state
    by (auto simp: ae_delta_ss7_ss8_def elim: mttm_step.cases)
  have buf6_eq_buf5: "buf6 = buf5"
    using c5_state_eq c5_state by simp
  have q6_eq_q5: "q6 = q5"
    using c5_state_eq c5_state by simp
  have ofs6_eq_ofs5: "ofs6 = ofs5"
    using c5_state_eq c5_state by simp
  have dest6_eq_dest5: "dest6 = dest5"
    using c5_state_eq c5_state by simp

  ― ‹Sub-step 5j: head trajectory at SS5 for pos=1 tapes under
      dest = AE_Left›.  Mirror of c5_pos_for_pos1› with R-direction
      (when dest = AE_Left›, ae_ss5_action›'s else-branch returns
      (h, R)›); head lands at block 2.  Plus tape_c5_at_one_pos1›:
      the SS5 write at c4_pos = 1› records the home buffer slot
      fst (snd (buf5 k))› at c5›'s cell 1.›
  have c5_pos_for_pos1_dest_left:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
             mt_pos c5 kk = 2"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    assume dest_eq: "dest5 kk = AE_Left"
    obtain qq tts nn qq' aa5 dr5 where
        c4_eq5: "c4 = ConfigM qq tts nn"
      and c5_eq: "c5 = ConfigM qq'
                          (λk. (tts k)(nn k := aa5 k))
                          (λk. go_dir (dr5 k) (nn k))"
      and tr_in: "(qq, λk. tts k (nn k), qq', aa5, dr5)
                     ae_delta_ss5_ss6 M"
      using step5_sub by (auto elim: mttm_step.cases)
    obtain q ofs buf dest where
        qq_eq: "qq = (q, ofs, buf, dest, SS5)"
      and dr5_eq:
          "dr5 = (λk. if k < k_tm M
                       then snd (ae_ss5_action (le_tm M)
                                  (tts k (nn k)) (buf k) (dest k))
                       else dir.N)"
      using tr_in by (auto simp: ae_delta_ss5_ss6_def)
    have qq_state: "qq = (q5, ofs5, buf5, dest5, SS5)"
      using c4_state c4_eq5 by simp
    have buf_eq: "buf = buf5" using qq_eq qq_state by simp
    have dest_eq2: "dest = dest5" using qq_eq qq_state by simp
    have nn_kk: "nn kk = mt_pos c4 kk" using c4_eq5 by simp
    have c4_kk: "mt_pos c4 kk = 1" using c4_pos kklt pos_kk by simp
    have tts_kk: "tts kk (nn kk) = mt_tape c4 kk (mt_pos c4 kk)"
      using c4_eq5 nn_kk by simp
    have read_at_home: "tts kk (nn kk) = mt_tape c' kk 1"
      using tts_kk c4_kk tape_c4_eq_c' by simp
    have home_ne_LE: "mt_tape c' kk 1  LE_block (le_tm M)"
    proof -
      have pos_ge1: "(1 :: nat)  mt_pos c' kk" using pos_kk by simp
      have "mt_tape c' kk (mt_pos c' kk)  LE_block (le_tm M)"
        using home_classification[rule_format, OF kklt] pos_ge1 by blast
      thus ?thesis using pos_kk by simp
    qed
    have read_ne_LE: "tts kk (nn kk)  LE_block (le_tm M)"
      using read_at_home home_ne_LE by simp
    obtain ll hh rr where buf5_kk: "buf5 kk = (ll, hh, rr)"
      using prod.exhaust by metis
    have h_ne_LE: "hh  LE_block (le_tm M)"
    proof -
      have "fst (snd (buf5 kk))  LE_block (le_tm M)"
        using buf5_not_le_per_tape[rule_format, OF kklt] pos_kk by blast
      thus ?thesis using buf5_kk by simp
    qed
    have dr5_kk:
        "dr5 kk = (if dest5 kk = AE_Left then dir.R else dir.L)"
      using dr5_eq buf_eq dest_eq2 buf5_kk read_ne_LE h_ne_LE kklt by simp
    have dr5_kk_R: "dr5 kk = dir.R"
      using dr5_kk dest_eq by simp
    have "mt_pos c5 kk = go_dir (dr5 kk) (nn kk)"
      using c5_eq by simp
    also have " = Suc (nn kk)" using dr5_kk_R by simp
    also have " = Suc (mt_pos c4 kk)" using nn_kk by simp
    also have " = Suc 1" using c4_kk by simp
    also have " = 2" by simp
    finally show "mt_pos c5 kk = 2" .
  qed

  have tape_c5_at_one_pos1:
      "kk. kk < k_tm M  mt_pos c' kk = 1
             mt_tape c5 kk 1 = fst (snd (buf5 kk))"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    obtain qq tts nn qq' aa5 dr5 where
        c4_eq5: "c4 = ConfigM qq tts nn"
      and c5_eq: "c5 = ConfigM qq'
                          (λk. (tts k)(nn k := aa5 k))
                          (λk. go_dir (dr5 k) (nn k))"
      and tr_in: "(qq, λk. tts k (nn k), qq', aa5, dr5)
                     ae_delta_ss5_ss6 M"
      using step5_sub by (auto elim: mttm_step.cases)
    obtain q ofs buf dest where
        qq_eq: "qq = (q, ofs, buf, dest, SS5)"
      and aa5_eq:
          "aa5 = (λk. if k < k_tm M then fst (ae_ss5_action (le_tm M)
                              (tts k (nn k)) (buf k) (dest k)) else bl_block (bl_tm M))"
      using tr_in by (auto simp: ae_delta_ss5_ss6_def)
    have qq_state: "qq = (q5, ofs5, buf5, dest5, SS5)"
      using c4_state c4_eq5 by simp
    have buf_eq: "buf = buf5" using qq_eq qq_state by simp
    have dest_eq: "dest = dest5" using qq_eq qq_state by simp
    have nn_kk: "nn kk = mt_pos c4 kk" using c4_eq5 by simp
    have c4_kk: "mt_pos c4 kk = 1" using c4_pos kklt pos_kk by simp
    have tts_kk: "tts kk (nn kk) = mt_tape c4 kk (mt_pos c4 kk)"
      using c4_eq5 nn_kk by simp
    have read_at_home: "tts kk (nn kk) = mt_tape c' kk 1"
      using tts_kk c4_kk tape_c4_eq_c' by simp
    have home_ne_LE: "mt_tape c' kk 1  LE_block (le_tm M)"
    proof -
      have pos_ge1: "(1 :: nat)  mt_pos c' kk" using pos_kk by simp
      have "mt_tape c' kk (mt_pos c' kk)  LE_block (le_tm M)"
        using home_classification[rule_format, OF kklt] pos_ge1 by blast
      thus ?thesis using pos_kk by simp
    qed
    have read_ne_LE: "tts kk (nn kk)  LE_block (le_tm M)"
      using read_at_home home_ne_LE by simp
    obtain ll hh rr where buf5_kk: "buf5 kk = (ll, hh, rr)"
      using prod.exhaust by metis
    have h_ne_LE: "hh  LE_block (le_tm M)"
    proof -
      have "fst (snd (buf5 kk))  LE_block (le_tm M)"
        using buf5_not_le_per_tape[rule_format, OF kklt] pos_kk by blast
      thus ?thesis using buf5_kk by simp
    qed
    have aa5_kk: "aa5 kk = fst (snd (buf5 kk))"
      using aa5_eq buf_eq dest_eq buf5_kk read_ne_LE h_ne_LE kklt by simp
    have c5_tape_kk: "mt_tape c5 kk = (tts kk)(nn kk := aa5 kk)"
      using c5_eq by simp
    have step_apply: "mt_tape c5 kk 1 = ((tts kk)(nn kk := aa5 kk)) 1"
      using c5_tape_kk by simp
    have hit: "((tts kk)(nn kk := aa5 kk)) 1 = aa5 kk"
      using nn_kk c4_kk by simp
    show "mt_tape c5 kk 1 = fst (snd (buf5 kk))"
      using step_apply hit aa5_kk by simp
  qed

  ― ‹Sub-step 5k: c6 trajectory for pos=1 + dest=AE_Left›.
      c5_pos = 2›; SS6 reads mt_tape c5 k 2› which is off-head
      from SS5's write at c4_pos = 1›, so = mt_tape c4 k 2
      = mt_tape c' k 2›.  right_not_le_c'› instantiated at pos=1
      gives ≠ LE_block›.  Buf5 home ≠ LE› (buf5_not_le_per_tape›).
      ae_ss6_action›'s else-branch fires with ds = AE_Left›:
      writes r›, direction L›; head lands at c6_pos = c5_pos - 1
      = 1›.  Plus tape_c6_zero_le_pos1_dest_left›: cell 0
      is off-head from SS6's write at c5_pos = 2›, hence = LE›
      via tape_c5_zero_le›.›
  have c6_pos_for_pos1_dest_left:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
             mt_pos c6 kk = 1"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    assume dest_eq: "dest5 kk = AE_Left"
    obtain qq tts nn qq' aa6 dr6 where
        c5_eq6: "c5 = ConfigM qq tts nn"
      and c6_eq: "c6 = ConfigM qq'
                          (λk. (tts k)(nn k := aa6 k))
                          (λk. go_dir (dr6 k) (nn k))"
      and tr_in: "(qq, λk. tts k (nn k), qq', aa6, dr6)
                     ae_delta_ss6_ss7 M"
      using step6_sub by (auto elim: mttm_step.cases)
    obtain q ofs buf dest where
        qq_eq: "qq = (q, ofs, buf, dest, SS6)"
      and dr6_eq:
          "dr6 = (λk. if k < k_tm M then snd (ae_ss6_action (le_tm M)
                              (tts k (nn k)) (buf k) (dest k)) else dir.N)"
      using tr_in by (auto simp: ae_delta_ss6_ss7_def)
    have qq_state: "qq = (q5, ofs5, buf5, dest5, SS6)"
      using c5_state c5_eq6 by simp
    have buf_eq: "buf = buf5" using qq_eq qq_state by simp
    have dest_eq2: "dest = dest5" using qq_eq qq_state by simp
    have nn_kk: "nn kk = mt_pos c5 kk" using c5_eq6 by simp
    have c5_kk: "mt_pos c5 kk = 2"
      using c5_pos_for_pos1_dest_left[OF kklt pos_kk dest_eq] .
    have tts_kk: "tts kk (nn kk) = mt_tape c5 kk (mt_pos c5 kk)"
      using c5_eq6 nn_kk by simp
    have c5_tape_at_2: "mt_tape c5 kk 2 = mt_tape c4 kk 2"
    proof -
      have two_ne_pos_c4: "(2 :: nat)  mt_pos c4 kk"
        using c4_pos kklt pos_kk by simp
      show ?thesis
        using mttm_step_tape_off_head[OF step5 two_ne_pos_c4] .
    qed
    have c4_tape_at_2: "mt_tape c4 kk 2 = mt_tape c' kk 2"
      using tape_c4_eq_c' by simp
    have read_at_right:
        "tts kk (nn kk) = mt_tape c' kk 2"
      using tts_kk c5_kk c5_tape_at_2 c4_tape_at_2 by simp
    have right_ne_LE_pos1: "mt_tape c' kk 2  LE_block (le_tm M)"
    proof -
      have "mt_tape c' kk (mt_pos c' kk + 1)  LE_block (le_tm M)"
        using right_not_le_c' by blast
      thus ?thesis using pos_kk by (simp add: numeral_2_eq_2)
    qed
    have read_ne_LE: "tts kk (nn kk)  LE_block (le_tm M)"
      using read_at_right right_ne_LE_pos1 by simp
    obtain ll hh rr where buf5_kk: "buf5 kk = (ll, hh, rr)"
      using prod.exhaust by metis
    have h_ne_LE: "hh  LE_block (le_tm M)"
    proof -
      have "fst (snd (buf5 kk))  LE_block (le_tm M)"
        using buf5_not_le_per_tape[rule_format, OF kklt] pos_kk by blast
      thus ?thesis using buf5_kk by simp
    qed
    have dr6_kk:
        "dr6 kk = (if dest5 kk = AE_Left then dir.L else dir.R)"
      using dr6_eq buf_eq dest_eq2 buf5_kk read_ne_LE h_ne_LE kklt by simp
    have dr6_kk_L: "dr6 kk = dir.L"
      using dr6_kk dest_eq by simp
    have "mt_pos c6 kk = go_dir (dr6 kk) (nn kk)"
      using c6_eq by simp
    also have " = (nn kk) - 1" using dr6_kk_L by simp
    also have " = (mt_pos c5 kk) - 1" using nn_kk by simp
    also have " = 2 - 1" using c5_kk by simp
    also have " = 1" by simp
    finally show "mt_pos c6 kk = 1" .
  qed

  have tape_c6_zero_le_pos1_dest_left:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
             mt_tape c6 kk 0 = LE_block (le_tm M)"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    assume dest_eq: "dest5 kk = AE_Left"
    have zero_ne_pos_c5: "(0 :: nat)  mt_pos c5 kk"
      using c5_pos_for_pos1_dest_left[OF kklt pos_kk dest_eq] by simp
    have c6_zero_eq_c5:
        "mt_tape c6 kk 0 = mt_tape c5 kk 0"
      using mttm_step_tape_off_head[OF step6 zero_ne_pos_c5] .
    have c5_zero_le: "mt_tape c5 kk 0 = LE_block (le_tm M)"
      using tape_c5_zero_le[rule_format, OF kklt] by simp
    show "mt_tape c6 kk 0 = LE_block (le_tm M)"
      using c6_zero_eq_c5 c5_zero_le by simp
  qed

  ― ‹Sub-step 5l: c7 trajectory for pos=1 + dest=AE_Left›.  c6_pos = 1›;
      SS7 reads mt_tape c6 k 1 = mt_tape c5 k 1› (off-head from SS6's
      write at c5_pos = 2›), and mt_tape c5 k 1 = fst (snd (buf5 k))›
      (via tape_c5_at_one_pos1›) = home buffer slot, ≠ LE›.
      ae_ss7_action›'s else-branch fires with ds = AE_Left›:
      writes a›, direction L›; c7_pos = c6_pos - 1 = 0›.  Plus
      tape_c7_zero_le›: cell 0 off-head from SS7's write at c6_pos = 1›,
      so = LE› via tape_c6_zero_le_pos1_dest_left›.›
  have c7_pos_for_pos1_dest_left:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
             mt_pos c7 kk = 0"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    assume dest_eq: "dest5 kk = AE_Left"
    obtain qq tts nn qq' aa7 dr7 where
        c6_eq7: "c6 = ConfigM qq tts nn"
      and c7_eq: "c7 = ConfigM qq'
                          (λk. (tts k)(nn k := aa7 k))
                          (λk. go_dir (dr7 k) (nn k))"
      and tr_in: "(qq, λk. tts k (nn k), qq', aa7, dr7)
                     ae_delta_ss7_ss8 M"
      using step7_sub by (auto elim: mttm_step.cases)
    obtain q ofs buf dest where
        qq_eq: "qq = (q, ofs, buf, dest, SS7)"
      and dr7_eq:
          "dr7 = (λk. if k < k_tm M then snd (ae_ss7_action (le_tm M)
                              (tts k (nn k)) (buf k) (dest k)) else dir.N)"
      using tr_in by (auto simp: ae_delta_ss7_ss8_def)
    have qq_state: "qq = (q5, ofs5, buf5, dest5, SS7)"
      using c6_state c6_eq7 q6_eq_q5 ofs6_eq_ofs5
            buf6_eq_buf5 dest6_eq_dest5 by simp
    have buf_eq: "buf = buf5" using qq_eq qq_state by simp
    have dest_eq2: "dest = dest5" using qq_eq qq_state by simp
    have nn_kk: "nn kk = mt_pos c6 kk" using c6_eq7 by simp
    have c6_kk: "mt_pos c6 kk = 1"
      using c6_pos_for_pos1_dest_left[OF kklt pos_kk dest_eq] .
    have tts_kk: "tts kk (nn kk) = mt_tape c6 kk (mt_pos c6 kk)"
      using c6_eq7 nn_kk by simp
    have one_ne_pos_c5: "(1 :: nat)  mt_pos c5 kk"
      using c5_pos_for_pos1_dest_left[OF kklt pos_kk dest_eq] by simp
    have c6_at_one: "mt_tape c6 kk 1 = mt_tape c5 kk 1"
      using mttm_step_tape_off_head[OF step6 one_ne_pos_c5] .
    have c6_at_one_eq_h:
        "mt_tape c6 kk 1 = fst (snd (buf5 kk))"
      using c6_at_one tape_c5_at_one_pos1[OF kklt pos_kk] by simp
    obtain ll hh rr where buf5_kk: "buf5 kk = (ll, hh, rr)"
      using prod.exhaust by metis
    have h_ne_LE: "hh  LE_block (le_tm M)"
    proof -
      have "fst (snd (buf5 kk))  LE_block (le_tm M)"
        using buf5_not_le_per_tape[rule_format, OF kklt] pos_kk by blast
      thus ?thesis using buf5_kk by simp
    qed
    have read_ne_LE: "tts kk (nn kk)  LE_block (le_tm M)"
      using tts_kk c6_kk c6_at_one_eq_h buf5_kk h_ne_LE by simp
    have dr7_kk:
        "dr7 kk = (if dest5 kk = AE_Left then dir.L else dir.R)"
      using dr7_eq buf_eq dest_eq2 buf5_kk read_ne_LE h_ne_LE kklt by simp
    have dr7_kk_L: "dr7 kk = dir.L"
      using dr7_kk dest_eq by simp
    have "mt_pos c7 kk = go_dir (dr7 kk) (nn kk)"
      using c7_eq by simp
    also have " = (nn kk) - 1" using dr7_kk_L by simp
    also have " = (mt_pos c6 kk) - 1" using nn_kk by simp
    also have " = 1 - 1" using c6_kk by simp
    also have " = 0" by simp
    finally show "mt_pos c7 kk = 0" .
  qed

  have tape_c7_zero_le_pos1_dest_left:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
             mt_tape c7 kk 0 = LE_block (le_tm M)"
  proof -
    fix kk
    assume kklt: "kk < k_tm M"
    assume pos_kk: "mt_pos c' kk = 1"
    assume dest_eq: "dest5 kk = AE_Left"
    have zero_ne_pos_c6: "(0 :: nat)  mt_pos c6 kk"
      using c6_pos_for_pos1_dest_left[OF kklt pos_kk dest_eq] by simp
    have c7_zero_eq_c6:
        "mt_tape c7 kk 0 = mt_tape c6 kk 0"
      using mttm_step_tape_off_head[OF step7 zero_ne_pos_c6] .
    show "mt_tape c7 kk 0 = LE_block (le_tm M)"
      using c7_zero_eq_c6 tape_c6_zero_le_pos1_dest_left[OF kklt pos_kk dest_eq]
      by simp
  qed

  ― ‹Sub-step 5m: pos_link_c7› + SS8→›SS1 invocation.  Mirror
      of pos_link_c5›: right-slot uniform non-LE from buf5
      (= buf6) regime case-split; SS8 conditional substantive only
      for pos=1 + dest=AE_Left›, vacuous for pos=0/≥›2.
      Then le_compat_ss8› from pos_link_c7›, invoke
      ae_step_ss8_ss1_exists›.›
  have pos_link_c7: "ae_position_link M c7"
  proof -
    have r_not_le: "k<k_tm M. snd (snd (buf6 k))  LE_block (le_tm M)"
    proof (intro allI impI)
      fix k
      assume klt: "k < k_tm M"
      consider (le0) "mt_pos c' k = 0"
             | (le1) "mt_pos c' k = 1"
             | (steady) "mt_pos c' k  2"
        by linarith
      thus "snd (snd (buf6 k))  LE_block (le_tm M)"
      proof cases
        case le0    thus ?thesis using buf5_not_le_per_tape[rule_format, OF klt] buf6_eq_buf5 by blast
      next
        case le1    thus ?thesis using buf5_not_le_per_tape[rule_format, OF klt] buf6_eq_buf5 by blast
      next
        case steady thus ?thesis using buf5_not_le_per_tape[rule_format, OF klt] buf6_eq_buf5 by blast
      qed
    qed
    have ss8_cond:
        "k<k_tm M. dest6 k = AE_Left
                 fst (buf6 k) = LE_block (le_tm M)
                 mt_tape c7 k (mt_pos c7 k) = LE_block (le_tm M)"
    proof (intro allI impI)
      fix k
      assume klt: "k < k_tm M"
      assume dest_eq: "dest6 k = AE_Left"
      assume l_eq_le: "fst (buf6 k) = LE_block (le_tm M)"
      have dest5_eq: "dest5 k = AE_Left" using dest_eq dest6_eq_dest5 by simp
      have l_eq_le_buf5: "fst (buf5 k) = LE_block (le_tm M)"
        using l_eq_le buf6_eq_buf5 by simp
      consider (le0) "mt_pos c' k = 0"
             | (le1) "mt_pos c' k = 1"
             | (steady) "mt_pos c' k  2"
        by linarith
      thus "mt_tape c7 k (mt_pos c7 k) = LE_block (le_tm M)"
      proof cases
        case le0
        have "fst (buf5 k)  LE_block (le_tm M)"
          using buf5_not_le_per_tape[rule_format, OF klt] le0 by blast
        thus ?thesis using l_eq_le_buf5 by simp
      next
        case le1
        have c7_pos_k: "mt_pos c7 k = 0"
          using c7_pos_for_pos1_dest_left[OF klt le1 dest5_eq] .
        have "mt_tape c7 k 0 = LE_block (le_tm M)"
          using tape_c7_zero_le_pos1_dest_left[OF klt le1 dest5_eq] .
        thus ?thesis using c7_pos_k by simp
      next
        case steady
        have "fst (buf5 k)  LE_block (le_tm M)"
          using buf5_not_le_per_tape[rule_format, OF klt] steady by blast
        thus ?thesis using l_eq_le_buf5 by simp
      qed
    qed
    show ?thesis
      unfolding ae_position_link_def
      using r_not_le ss8_cond c7_state by simp
  qed

  have le_compat_ss8_c7: "ae_le_compat_ss8 M c7"
    using ae_position_link_discharges_ss8[OF inv_ss8 pos_link_c7] .
  obtain c8 where
      step8_sub: "(c7, c8)  mttm_step (ae_delta_ss8_ss1 M)"
    and step8: "(c7, c8)  mttm_step (alphabet_enlarge_delta M)"
    using ae_step_ss8_ss1_exists[OF vM inv_ss8 gamma_c7 buf_gamma_c7
                                    le_compat_ss8_c7] by blast
  ― ‹Re-express the per-tape ⋀kk› facts as object-level
      ∀kk› before feeding that›: the nested meta-implication
      under the obtains witness binders defeats elim-resolution at the call
      site.  The call site recovers the
      ⋀kk› form via [rule_format]›.›
  have c4_pos_all: "kk. kk < k_tm M  mt_pos c4 kk = mt_pos c' kk"
    using c4_pos by blast
  have c5_pos_for_pos1_all:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk  AE_Left
        mt_pos c5 kk = 0"
    using c5_pos_for_pos1 by blast
  have c5_pos_for_pos1_dest_left_all:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
        mt_pos c5 kk = 2"
    using c5_pos_for_pos1_dest_left by blast
  have tape_c5_at_one_pos1_all:
      "kk. kk < k_tm M  mt_pos c' kk = 1
        mt_tape c5 kk 1 = fst (snd (buf5 kk))"
    using tape_c5_at_one_pos1 by blast
  have c6_pos_for_pos1_dest_left_all:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
        mt_pos c6 kk = 1"
    using c6_pos_for_pos1_dest_left by blast
  have c7_pos_for_pos1_dest_left_all:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
        mt_pos c7 kk = 0"
    using c7_pos_for_pos1_dest_left by blast
  have tape_c7_zero_le_pos1_dest_left_all:
      "kk. kk < k_tm M  mt_pos c' kk = 1  dest5 kk = AE_Left
        mt_tape c7 kk 0 = LE_block (le_tm M)"
    using tape_c7_zero_le_pos1_dest_left by blast
  show thesis by (rule that[OF step5_sub step5 c4_state c5_state tape_c4_eq_c'
        buf5_not_le_per_tape right_not_le_c' c4_pos_all tape_c5_zero_le
        c5_pos_for_pos1_all step6_sub step6 step7_sub step7 gamma_c7 buf_gamma_c7
        c6_state c7_state buf6_eq_buf5 q6_eq_q5 ofs6_eq_ofs5 dest6_eq_dest5
        c5_pos_for_pos1_dest_left_all tape_c5_at_one_pos1_all
        c6_pos_for_pos1_dest_left_all c7_pos_for_pos1_dest_left_all
        tape_c7_zero_le_pos1_dest_left_all step8_sub step8])
qed

end