q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ Reaches₁ (TM2.step tr) { l := some (head main q), var := s, stk := elim (trList L) [] c d }
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (head main q), var := s, stk := elim (trList L) [] c d }
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
case refine'_1
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList L) [] c d main = trNat (List.headI L) ∧ trList (List.tail L) = [])
    (fun a => natEnd a = true ∧ elim (trList L) [] c d main = trNat (List.headI L) ++ a :: trList (List.tail L)) o

case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux
      (tr
        ((fun x =>
            Λ'.read fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q))
          o))
      o
      (update
        (update (update (elim (trList L) [] c d) main (trList (List.tail L))) rev
          (List.reverseAux (trNat (List.headI L)) (elim (trList L) [] c d rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) o ::
          update (update (elim (trList L) [] c d) main (trList (List.tail L))) rev
            (List.reverseAux (trNat (List.headI L)) (elim (trList L) [] c d rev)) rev)))
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ Reaches₁ (TM2.step tr) { l := some (head main q), var := s, stk := elim (trList L) [] c d }
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
refine'
  (move_ok (by decide)
        (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
    (TransGen.head rfl (TransGen.head rfl _))
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    {
      l :=
        some
          (ite (List.rec none (fun head tail tail_ih => some Γ'.cons) L = some Γ'.consₗ) id
            (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q)),
      var := List.rec none (fun head tail tail_ih => some Γ'.cons) L,
      stk := elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux
      (tr
        ((fun x =>
            Λ'.read fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q))
          o))
      o
      (update
        (update (update (elim (trList L) [] c d) main (trList (List.tail L))) rev
          (List.reverseAux (trNat (List.headI L)) (elim (trList L) [] c d rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) o ::
          update (update (elim (trList L) [] c d) main (trList (List.tail L))) rev
            (List.reverseAux (trNat (List.headI L)) (elim (trList L) [] c d rev)) rev)))
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
simp
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main (unrev q)),
      var := List.rec none (fun head tail tail_ih => some Γ'.cons) L,
      stk := elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    {
      l :=
        some
          (ite (List.rec none (fun head tail tail_ih => some Γ'.cons) L = some Γ'.consₗ) id
            (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q)),
      var := List.rec none (fun head tail tail_ih => some Γ'.cons) L,
      stk := elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
case refine'_2.refine'_1
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ ∀ (x : Γ'),
    x ∈ elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d main →
      decide (x = Γ'.consₗ) = false

case refine'_2.refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (unrev q), var := none,
      stk :=
        update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main (unrev q)),
      var := List.rec none (fun head tail tail_ih => some Γ'.cons) L,
      stk := elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
refine' (clear_ok (splitAtPred_eq _ _ _ none [] _ ⟨rfl, rfl⟩)).trans _
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d =
    update
      (update
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [])
        rev [])
      main
      (List.reverseAux
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] rev)
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] main))
case refine'_2.refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (unrev q), var := none,
      stk :=
        update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
convert unrev_ok using 2
no goals
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d =
    update
      (update
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [])
        rev [])
      main
      (List.reverseAux
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] rev)
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] main))
simp [List.reverseAux_eq]
no goals
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ main ≠ rev
decide
no goals
case refine'_1
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList L) [] c d main = trNat (List.headI L) ∧ trList (List.tail L) = [])
    (fun a => natEnd a = true ∧ elim (trList L) [] c d main = trNat (List.headI L) ++ a :: trList (List.tail L)) o
cases L <;> simp
no goals
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ
cases L <;> simp
no goals
case refine'_2.refine'_1
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ ∀ (x : Γ'),
    x ∈ elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d main →
      decide (x = Γ'.consₗ) = false
exact fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)