l3lab/ntp-mathlib huggingface dataset:
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    

Proof state:
case H₃
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
p : σ → Bool
q₁ q₂ : Stmt₂
IH₁ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₁ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))) b
IH₂ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₂ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L))) b
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (bif p v then TM2.stepAux q₁ v S else TM2.stepAux q₂ v S) b ∧
      Reaches (TM1.step (tr M))
        (bif p v then TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))
        else TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L)))
        b

Next tactic:
cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    

Proof state:
case H₃
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
p : σ → Bool
q₁ q₂ : Stmt₂
IH₁ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₁ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))) b
IH₂ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₂ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L))) b
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (bif p v then TM2.stepAux q₁ v S else TM2.stepAux q₂ v S) b ∧
      Reaches (TM1.step (tr M))
        (bif p v then TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))
        else TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L)))
        b

Next tactic:
cases p v
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    cases p v <;> [

Proof state:
case H₃.false
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
p : σ → Bool
q₁ q₂ : Stmt₂
IH₁ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₁ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))) b
IH₂ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₂ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L))) b
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (bif false then TM2.stepAux q₁ v S else TM2.stepAux q₂ v S) b ∧
      Reaches (TM1.step (tr M))
        (bif false then TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))
        else TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L)))
        b

Next tactic:
exact IH₂ _ hT
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    cases p v <;> [exact IH₂ _ hT; 

Proof state:
case H₃.true
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
p : σ → Bool
q₁ q₂ : Stmt₂
IH₁ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₁ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))) b
IH₂ :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} (L : ListBlank ((k : K) → Option (Γ k))),
    (∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))) →
      ∃ b,
        TrCfg (TM2.stepAux q₂ v S) b ∧
          Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L))) b
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (bif true then TM2.stepAux q₁ v S else TM2.stepAux q₂ v S) b ∧
      Reaches (TM1.step (tr M))
        (bif true then TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))
        else TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L)))
        b

Next tactic:
exact IH₁ _ hT
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
  

Proof state:
case H₄
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
l✝ : σ → Λ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (TM2.stepAux (TM2.Stmt.goto l✝) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (TM2.Stmt.goto l✝)) v (Tape.mk' ∅ (addBottom L))) b

Next tactic:
| H₄ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
  | H₄ => 

Proof state:
case H₄
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
l✝ : σ → Λ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (TM2.stepAux (TM2.Stmt.goto l✝) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (TM2.Stmt.goto l✝)) v (Tape.mk' ∅ (addBottom L))) b

Next tactic:
exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
  | H₄ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
  

Proof state:
case H₅
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (TM2.stepAux TM2.Stmt.halt v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal TM2.Stmt.halt) v (Tape.mk' ∅ (addBottom L))) b

Next tactic:
| H₅ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by
  -- Porting note: `simp only`s are required for beta reductions.
  intro c₁ c₂ h
  cases' h with l v S L hT
  cases' l with l; · constructor
  simp only [TM2.step, Respects, Option.map_some']
  rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
  · exact ⟨b, c, TransGen.head' rfl r⟩
  simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
  generalize M l = N
  induction N using stmtStRec generalizing v S L hT with
  | H₁ k s q IH => exact tr_respects_aux M hT s @IH
  | H₂ a _ IH => exact IH _ hT
  | H₃ p q₁ q₂ IH₁ IH₂ =>
    unfold TM2.stepAux trNormal TM1.stepAux
    simp only []
    cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
  | H₄ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
  | H₅ => 

Proof state:
case H₅
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Λ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hT : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
⊢ ∃ b,
    TrCfg (TM2.stepAux TM2.Stmt.halt v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal TM2.Stmt.halt) v (Tape.mk' ∅ (addBottom L))) b

Next tactic:
exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
⊢ TrCfg (TM2.init k L) (TM1.init (trInit k L))

Next tactic:
rw [(_ : TM1.init _ = _)]
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · 

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
⊢ TrCfg (TM2.init k L) ?m.810125

Next tactic:
refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
⊢ ListBlank.map (proj k') (ListBlank.mk (List.map (fun a => update default k (some a)) (List.reverse L))) =
    ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))

Next tactic:
refine' ListBlank.ext fun i ↦ _
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
i : ℕ
⊢ ListBlank.nth
      (ListBlank.map (proj k') (ListBlank.mk (List.map (fun a => update default k (some a)) (List.reverse L)))) i =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))) i

Next tactic:
rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
i : ℕ
⊢ Option.iget (List.get? (List.map ((proj k').f ∘ fun a => update default k (some a)) (List.reverse L)) i) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))) i

Next tactic:
have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
    

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
i : ℕ
this : ((proj k').f ∘ fun a => update default k (some a)) = fun a => PointedMap.f (proj k') (update default k (some a))
⊢ Option.iget (List.get? (List.map ((proj k').f ∘ fun a => update default k (some a)) (List.reverse L)) i) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))) i

Next tactic:
rw [this, List.get?_map, proj, PointedMap.mk_val]
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
    rw [this, List.get?_map, proj, PointedMap.mk_val]
    

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
i : ℕ
this : ((proj k').f ∘ fun a => update default k (some a)) = fun a => PointedMap.f (proj k') (update default k (some a))
⊢ Option.iget (Option.map (fun a => update default k (some a) k') (List.get? (List.reverse L) i)) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))) i

Next tactic:
simp only []
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
    rw [this, List.get?_map, proj, PointedMap.mk_val]
    simp only []
    

Proof state:
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
i : ℕ
this : ((proj k').f ∘ fun a => update default k (some a)) = fun a => PointedMap.f (proj k') (update default k (some a))
⊢ Option.iget (Option.map (fun a => update default k (some a) k') (List.get? (List.reverse L) i)) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))) i

Next tactic:
by_cases h : k' = k
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
    rw [this, List.get?_map, proj, PointedMap.mk_val]
    simp only []
    by_cases h : k' = k
    · 

Proof state:
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
k' : K
i : ℕ
this : ((proj k').f ∘ fun a => update default k (some a)) = fun a => PointedMap.f (proj k') (update default k (some a))
h : k' = k
⊢ Option.iget (Option.map (fun a => update default k (some a) k') (List.get? (List.reverse L) i)) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k')))) i

Next tactic:
subst k'
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
    rw [this, List.get?_map, proj, PointedMap.mk_val]
    simp only []
    by_cases h : k' = k
    · subst k'
      

Proof state:
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
i : ℕ
this : ((proj k).f ∘ fun a => update default k (some a)) = fun a => PointedMap.f (proj k) (update default k (some a))
⊢ Option.iget (Option.map (fun a => update default k (some a) k) (List.get? (List.reverse L) i)) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update (fun x => []) k L k)))) i

Next tactic:
simp only [Function.update_same]
theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : Cfg₂₁) := by
  rw [(_ : TM1.init _ = _)]
  · refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
    have : ((proj k').f ∘ fun a => update (β := fun k => Option (Γ k)) default k (some a))
      = fun a => (proj k').f (update (β := fun k => Option (Γ k)) default k (some a)) := rfl
    rw [this, List.get?_map, proj, PointedMap.mk_val]
    simp only []
    by_cases h : k' = k
    · subst k'
      simp only [Function.update_same]
      

Proof state:
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
k : K
L : List (Γ k)
i : ℕ
this : ((proj k).f ∘ fun a => update default k (some a)) = fun a => PointedMap.f (proj k) (update default k (some a))
⊢ Option.iget (Option.map (fun a => some a) (List.get? (List.reverse L) i)) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some L))) i

Next tactic:
rw [ListBlank.nth_mk, List.getI_eq_iget_get?, ← List.map_reverse, List.get?_map]