Theorem: Turing.PartrecToTM2.head_main_ok
File: Mathlib/Computability/TMToPartrec.lean

Proof steps:
state_before: 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 [L.headI]) [] c d }
state_after: 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 [L.headI]) [] c d }
tactic: let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
state_before: 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 [L.headI]) [] c d }
state_after: 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 L.headI ∧ trList L.tail = [])
    (fun a => natEnd a = true ∧ elim (trList L) [] c d main = trNat L.headI ++ a :: trList L.tail) 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 =>
              (if s = some Γ'.consₗ then id else Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q))
          o))
      o
      (update
        (update (update (elim (trList L) [] c d) main (trList L.tail)) rev
          ((trNat L.headI).reverseAux (elim (trList L) [] c d rev)))
        rev
        ((fun s => ((fun x => some Γ'.cons) s).iget) o ::
          update (update (elim (trList L) [] c d) main (trList L.tail)) rev
            ((trNat L.headI).reverseAux (elim (trList L) [] c d rev)) rev)))
    { l := some q, var := none, stk := elim (trList [L.headI]) [] c d }
tactic: refine
    (move_ok (by decide)
          (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) ?_)).trans
      (TransGen.head rfl (TransGen.head rfl ?_))
state_before: 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 =>
              (if s = some Γ'.consₗ then id else Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q))
          o))
      o
      (update
        (update (update (elim (trList L) [] c d) main (trList L.tail)) rev
          ((trNat L.headI).reverseAux (elim (trList L) [] c d rev)))
        rev
        ((fun s => ((fun x => some Γ'.cons) s).iget) o ::
          update (update (elim (trList L) [] c d) main (trList L.tail)) rev
            ((trNat L.headI).reverseAux (elim (trList L) [] c d rev)) rev)))
    { l := some q, var := none, stk := elim (trList [L.headI]) [] c d }
state_after: 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 ((if o = some Γ'.consₗ then id else Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q)),
      var := o, stk := elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d }
    { l := some q, var := none, stk := elim (trNat L.headI ++ [Γ'.cons]) [] c d }
tactic: simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev,
    Function.update_same, trList]
state_before: 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 ((if o = some Γ'.consₗ then id else Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q)),
      var := o, stk := elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d }
    { l := some q, var := none, stk := elim (trNat L.headI ++ [Γ'.cons]) [] c d }
state_after: 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 := o,
      stk := elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d }
    { l := some q, var := none, stk := elim (trNat L.headI ++ [Γ'.cons]) [] c d }
tactic: rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp [o])]
state_before: 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 := o,
      stk := elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d }
    { l := some q, var := none, stk := elim (trNat L.headI ++ [Γ'.cons]) [] c d }
state_after: 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 L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) 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 L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main [] }
    { l := some q, var := none, stk := elim (trNat L.headI ++ [Γ'.cons]) [] c d }
tactic: refine (clear_ok (splitAtPred_eq _ _ _ none [] ?_ ⟨rfl, rfl⟩)).trans ?_
state_before: 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 L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main [] }
    { l := some q, var := none, stk := elim (trNat L.headI ++ [Γ'.cons]) [] c d }
state_after: 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 L.headI ++ [Γ'.cons]) [] c d =
    update
      (update (update (elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main []) rev [])
      main
      ((update (elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main [] rev).reverseAux
        (update (elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main [] main))
tactic: convert unrev_ok using 2
state_before: 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 L.headI ++ [Γ'.cons]) [] c d =
    update
      (update (update (elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main []) rev [])
      main
      ((update (elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main [] rev).reverseAux
        (update (elim (trList L.tail) ((some Γ'.cons).iget :: (trNat L.headI).reverseAux []) c d) main [] main))
state_after: no goals
tactic: simp [List.reverseAux_eq]