l3lab/ntp-mathlib huggingface dataset:
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · 

Proof state:
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

Next tactic:
cases L
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> 

Proof state:
case refine'_1.nil
q : Λ'
s : Option Γ'
c d : List Γ'
o : Option Γ' := List.casesOn [] none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList []) [] c d main = trNat (List.headI []) ∧ trList (List.tail []) = [])
    (fun a => natEnd a = true ∧ elim (trList []) [] c d main = trNat (List.headI []) ++ a :: trList (List.tail [])) o

Next tactic:
simp
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> 

Proof state:
case refine'_1.cons
q : Λ'
s : Option Γ'
c d : List Γ'
head✝ : ℕ
tail✝ : List ℕ
o : Option Γ' := List.casesOn (head✝ :: tail✝) none fun x x => some Γ'.cons
⊢ Option.elim'
    (elim (trList (head✝ :: tail✝)) [] c d main = trNat (List.headI (head✝ :: tail✝)) ∧
      trList (List.tail (head✝ :: tail✝)) = [])
    (fun a =>
      natEnd a = true ∧
        elim (trList (head✝ :: tail✝)) [] c d main =
          trNat (List.headI (head✝ :: tail✝)) ++ a :: trList (List.tail (head✝ :: tail✝)))
    o

Next tactic:
simp
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  

Proof state:
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 }

Next tactic:
simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  

Proof state:
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 }

Next tactic:
rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by 

Proof state:
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ

Next tactic:
cases L
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> 

Proof state:
case nil
q : Λ'
s : Option Γ'
c d : List Γ'
o : Option Γ' := List.casesOn [] none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ

Next tactic:
simp
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> 

Proof state:
case cons
q : Λ'
s : Option Γ'
c d : List Γ'
head✝ : ℕ
tail✝ : List ℕ
o : Option Γ' := List.casesOn (head✝ :: tail✝) none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ

Next tactic:
simp
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
  

Proof state:
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 }

Next tactic:
refine' (clear_ok (splitAtPred_eq _ _ _ none [] _ ⟨rfl, rfl⟩)).trans _
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
  refine' (clear_ok (splitAtPred_eq _ _ _ none [] _ ⟨rfl, rfl⟩)).trans _
  · 

Proof state:
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 ∈ elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d main,
    decide (x = Γ'.consₗ) = false

Next tactic:
exact fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
  refine' (clear_ok (splitAtPred_eq _ _ _ none [] _ ⟨rfl, rfl⟩)).trans _
  · exact fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)
  

Proof state:
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 }

Next tactic:
convert unrev_ok using 2
theorem head_main_ok {q s L} {c d : List Γ'} :
    Reaches₁ (TM2.step tr) ⟨some (head main q), s, K'.elim (trList L) [] c d⟩
      ⟨some q, none, K'.elim (trList [L.headI]) [] c d⟩ := by
  let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
  refine'
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
      (TransGen.head rfl (TransGen.head rfl _))
  · cases L <;> simp
  simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
  rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
  refine' (clear_ok (splitAtPred_eq _ _ _ none [] _ ⟨rfl, rfl⟩)).trans _
  · exact fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)
  convert unrev_ok using 2; 

Proof state:
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))

Next tactic:
simp [List.reverseAux_eq]
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  

Proof state:
q : Λ'
s : Option Γ'
L₁ L₂ : List ℕ
L₃ : List Γ'
⊢ Reaches₁ (TM2.step tr)
    { l := some (head stack q), var := s, stk := elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trList (List.headI L₂ :: L₁)) [] [] L₃ }

Next tactic:
cases' L₂ with a L₂
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · 

Proof state:
case nil
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ Reaches₁ (TM2.step tr)
    { l := some (head stack q), var := s, stk := elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trList (List.headI [] :: L₁)) [] [] L₃ }

Next tactic:
refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by 

Proof state:
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ stack ≠ rev

Next tactic:
decide
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by 

Proof state:
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ ∀ x ∈ [], natEnd x = false

Next tactic:
rintro _ ⟨⟩
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    

Proof state:
case nil
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ 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ₗ)) stack) (unrev q))
          (some Γ'.consₗ)))
      (some Γ'.consₗ)
      (update
        (update (update (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃)) stack L₃) rev
          (List.reverseAux [] (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃) rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) (some Γ'.consₗ) ::
          update (update (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃)) stack L₃) rev
            (List.reverseAux [] (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃) rev)) rev)))
    { l := some q, var := none, stk := elim (trList (List.headI [] :: L₁)) [] [] L₃ }

Next tactic:
simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    

Proof state:
case nil
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ 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 (unrev q), var := some Γ'.consₗ, stk := elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃ }
    { l := some q, var := none, stk := elim (Γ'.cons :: trList L₁) [] [] L₃ }

Next tactic:
convert unrev_ok using 2
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    

Proof state:
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ elim (Γ'.cons :: trList L₁) [] [] L₃ =
    update (update (elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃) rev []) main
      (List.reverseAux (elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃ rev)
        (elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃ main))

Next tactic:
simp
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · 

Proof state:
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ Reaches₁ (TM2.step tr)
    { l := some (head stack q), var := s, stk := elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trList (List.headI (a :: L₂) :: L₁)) [] [] L₃ }

Next tactic:
refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by simp⟩))
        (TransGen.head rfl (TransGen.head rfl _))
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by 

Proof state:
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ stack ≠ rev

Next tactic:
decide
theorem head_stack_ok {q s L₁ L₂ L₃} :
    Reaches₁ (TM2.step tr)
      ⟨some (head stack q), s, K'.elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃)⟩
      ⟨some q, none, K'.elim (trList (L₂.headI :: L₁)) [] [] L₃⟩ := by
  cases' L₂ with a L₂
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
        (TransGen.head rfl (TransGen.head rfl _))
    simp only [TM2.step, Option.mem_def, TM2.stepAux, ite_true, id_eq, trList, List.nil_append,
      elim_update_stack, elim_rev, List.reverseAux_nil, elim_update_rev, Function.update_same,
      List.headI_nil, trNat_default]
    convert unrev_ok using 2
    simp
  · refine'
      TransGen.trans
        (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃)
            (trNat_natEnd _) ⟨rfl, by 

Proof state:
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) stack =
    trNat a ++ Γ'.cons :: (trList L₂ ++ Γ'.consₗ :: L₃)

Next tactic:
simp