p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.push k₁ id (Λ'.move (fun x => false) rev k₂ q))) o
      (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))))
    { l := some q, var := none, stk := update (update S k₁ (Option.elim o id List.cons L₂)) k₂ (L₁ ++ S k₂) }
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (move₂ p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := none, stk := update (update S k₁ (Option.elim o id List.cons L₂)) k₂ (L₁ ++ S k₂) }
refine' (move_ok h₁.1 e).trans (TransGen.head rfl _)
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ 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)
    (bif Option.isSome o then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := o,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget o :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := o,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none,
      stk :=
        update
          (update S k₁
            ((match (motive := Option Γ' → (List Γ' → List Γ') → (Γ' → List Γ' → List Γ') → List Γ' → List Γ') o, id,
                List.cons with
              | some x, x_1, f => f x
              | none, y, x => y)
              L₂))
          k₂ (L₁ ++ S k₂) }
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.push k₁ id (Λ'.move (fun x => false) rev k₂ q))) o
      (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))))
    { l := some q, var := none, stk := update (update S k₁ (Option.elim o id List.cons L₂)) k₂ (L₁ ++ S k₂) }
simp
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ 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)
    (bif Option.isSome none then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget none :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none, stk := update (update S k₁ L₂) k₂ (L₁ ++ S k₂) }

case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ 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)
    (bif Option.isSome (some val✝) then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none, stk := update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) }
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ 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)
    (bif Option.isSome o then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := o,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget o :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := o,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none,
      stk :=
        update
          (update S k₁
            ((match (motive := Option Γ' → (List Γ' → List Γ') → (Γ' → List Γ' → List Γ') → List Γ' → List Γ') o, id,
                List.cons with
              | some x, x_1, f => f x
              | none, y, x => y)
              L₂))
          k₂ (L₁ ++ S k₂) }
cases o <;> simp only [Option.elim, id.def]
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ 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 (Λ'.move (fun x => false) rev k₂ q), var := none,
      stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) }
    { l := some q, var := none, stk := update (update S k₁ L₂) k₂ (L₁ ++ S k₂) }
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ 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)
    (bif Option.isSome none then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget none :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none, stk := update (update S k₁ L₂) k₂ (L₁ ++ S k₂) }
simp only [TM2.stepAux, Option.isSome, cond_false]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) rev []) k₂
      (List.reverseAux (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) rev)
        (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₂))
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ 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 (Λ'.move (fun x => false) rev k₂ q), var := none,
      stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) }
    { l := some q, var := none, stk := update (update S k₁ L₂) k₂ (L₁ ++ S k₂) }
convert move_ok h₁.2.1.symm (splitAtPred_false _) using 2
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update (update S rev []) k₁ L₂) k₂
      (List.reverseAux (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ rev)
        (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ k₂))
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) rev []) k₂
      (List.reverseAux (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) rev)
        (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₂))
simp only [Function.update_comm h₁.1, Function.update_idem]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update S k₁ L₂) k₂
      (List.reverseAux (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ rev)
        (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ k₂))
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update (update S rev []) k₁ L₂) k₂
      (List.reverseAux (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ rev)
        (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ k₂))
rw [show update S rev [] = S by rw [← h₂, Function.update_eq_self]]
no goals
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update S k₁ L₂) k₂
      (List.reverseAux (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ rev)
        (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ k₂))
simp only [Function.update_noteq h₁.2.2.symm, Function.update_noteq h₁.2.1,
  Function.update_noteq h₁.1.symm, List.reverseAux_eq, h₂, Function.update_same,
  List.append_nil, List.reverse_reverse]
no goals
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update S rev [] = S
rw [← h₂, Function.update_eq_self]
case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ 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 (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
      stk :=
        update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    { l := some q, var := none, stk := update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) }
case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ 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)
    (bif Option.isSome (some val✝) then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none, stk := update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) }
simp only [TM2.stepAux, Option.isSome, cond_true]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update
      (update
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁))
        rev [])
      k₂
      (List.reverseAux
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) rev)
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) k₂))
case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ 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 (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
      stk :=
        update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    { l := some q, var := none, stk := update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) }
convert move_ok h₁.2.1.symm (splitAtPred_false _) using 2
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update (update (update S rev []) k₁ (Option.iget (some val✝) :: L₂)) k₂
      (List.reverse (update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) rev) ++
        update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) k₂)
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update
      (update
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁))
        rev [])
      k₂
      (List.reverseAux
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) rev)
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) k₂))
simp only [h₂, Function.update_comm h₁.1, List.reverseAux_eq, Function.update_same,
  List.append_nil, Function.update_idem]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update (update S k₁ (Option.iget (some val✝) :: L₂)) k₂
      (List.reverse (update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) rev) ++
        update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) k₂)
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update (update (update S rev []) k₁ (Option.iget (some val✝) :: L₂)) k₂
      (List.reverse (update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) rev) ++
        update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) k₂)
rw [show update S rev [] = S by rw [← h₂, Function.update_eq_self]]
no goals
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update (update S k₁ (Option.iget (some val✝) :: L₂)) k₂
      (List.reverse (update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) rev) ++
        update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) k₂)
simp only [Function.update_noteq h₁.1.symm, Function.update_noteq h₁.2.2.symm,
  Function.update_noteq h₁.2.1, Function.update_same, List.reverse_reverse]
no goals
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update S rev [] = S
rw [← h₂, Function.update_eq_self]