l3lab/ntp-mathlib huggingface dataset:
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        

Proof state:
case true
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ),
    some q₁ ∈ TM1.stmts M S →
      some (trAux M a q₁ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S q₁ → some val✝ ∈ TM1.stmts M S
IH₂ :
  ∀ (v : σ),
    some q₂ ∈ TM1.stmts M S →
      some (trAux M a q₂ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S q₂ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.branch p q₁ q₂) ∈ TM1.stmts M S
h₁ : some (bif true then trAux M a q₁ v else trAux M a q₂ v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch p q₁ q₂)
h : p a v = true
⊢ q₁ ∈ insert (TM1.Stmt.branch p q₁ q₂) (TM1.stmts₁ q₁ ∪ TM1.stmts₁ q₂)

Next tactic:
exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    

Proof state:
case right.mk.some.mk.some.goto
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
a✝ : Γ → σ → Λ
v : σ
h₂ : some (TM1.Stmt.goto a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.goto a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.goto a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
v : σ
h₂ : some TM1.Stmt.halt ∈ TM1.stmts M S
h₁ : some (trAux M a TM1.Stmt.halt v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S TM1.Stmt.halt
⊢ some val✝ ∈ TM1.stmts M S

Next tactic:
case goto l =>
      cases h₁
      exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    

Proof state:
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
l : Γ → σ → Λ
v : σ
h₂ : some (TM1.Stmt.goto l) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.goto l) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.goto l)
⊢ some val✝ ∈ TM1.stmts M S

Next tactic:
case goto l =>
      cases h₁
      exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    case goto l =>
      

Proof state:
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
l : Γ → σ → Λ
v : σ
h₂ : some (TM1.Stmt.goto l) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.goto l) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.goto l)
⊢ some val✝ ∈ TM1.stmts M S

Next tactic:
cases h₁
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    case goto l =>
      cases h₁
      

Proof state:
case refl
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
v' : σ
l : Γ → σ → Λ
h₂ : some (TM1.Stmt.goto l) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.goto l)
⊢ some (M (l a v')) ∈ TM1.stmts M S

Next tactic:
exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    case goto l =>
      cases h₁
      exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
    

Proof state:
case right.mk.some.mk.some.halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
v : σ
h₂ : some TM1.Stmt.halt ∈ TM1.stmts M S
h₁ : some (trAux M a TM1.Stmt.halt v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S TM1.Stmt.halt
⊢ some val✝ ∈ TM1.stmts M S

Next tactic:
case halt => cases h₁
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    case goto l =>
      cases h₁
      exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
    

Proof state:
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
v : σ
h₂ : some TM1.Stmt.halt ∈ TM1.stmts M S
h₁ : some (trAux M a TM1.Stmt.halt v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S TM1.Stmt.halt
⊢ some val✝ ∈ TM1.stmts M S

Next tactic:
case halt => cases h₁
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S) := by
  constructor
  · apply Finset.mem_product.2
    constructor
    · simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj,
        forall_eq', Finset.mem_biUnion]
      exact ⟨_, ss.1, TM1.stmts₁_self⟩
    · apply Finset.mem_univ
  · intro q a q' s h₁ h₂
    rcases q with ⟨_ | q, v⟩; · cases h₁
    cases' q' with q' v'
    simp only [trStmts, Finset.mem_coe] at h₂ ⊢
    rw [Finset.mem_product] at h₂ ⊢
    simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
    cases q'; · exact Multiset.mem_cons_self _ _
    simp only [tr, Option.mem_def] at h₁
    have := TM1.stmts_supportsStmt ss h₂
    revert this; induction q generalizing v <;> intro hs
    case move d q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case write b q =>
      cases h₁; refine' TM1.stmts_trans _ h₂
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case load b q IH =>
      refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
      unfold TM1.stmts₁
      exact Finset.mem_insert_of_mem TM1.stmts₁_self
    case branch p q₁ q₂ IH₁ IH₂ =>
      cases h : p a v <;> rw [trAux, h] at h₁
      · refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
      · refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
        unfold TM1.stmts₁
        exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
    case goto l =>
      cases h₁
      exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
    case halt => 

Proof state:
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → Stmt₁
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : Stmt₀
v' : σ
val✝ : Stmt₁
v : σ
h₂ : some TM1.Stmt.halt ∈ TM1.stmts M S
h₁ : some (trAux M a TM1.Stmt.halt v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S TM1.Stmt.halt
⊢ some val✝ ∈ TM1.stmts M S

Next tactic:
cases h₁
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  

Proof state:
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
letI := Classical.decEq Γ
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  letI := Classical.decEq Γ
  

Proof state:
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
this : DecidableEq Γ := Classical.decEq Γ
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
let n := Fintype.card Γ
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  letI := Classical.decEq Γ
  let n := Fintype.card Γ
  

Proof state:
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
this : DecidableEq Γ := Classical.decEq Γ
n : ℕ := Fintype.card Γ
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
obtain ⟨F⟩ := Fintype.truncEquivFin Γ
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  letI := Classical.decEq Γ
  let n := Fintype.card Γ
  obtain ⟨F⟩ := Fintype.truncEquivFin Γ
  

Proof state:
case mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
this : DecidableEq Γ := Classical.decEq Γ
n : ℕ := Fintype.card Γ
x✝ : Trunc (Γ ≃ Fin (Fintype.card Γ))
F : Γ ≃ Fin (Fintype.card Γ)
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
let G : Fin n ↪ Fin n → Bool :=
    ⟨fun a b ↦ a = b, fun a b h ↦
      Bool.of_decide_true <| (congr_fun h b).trans <| Bool.decide_true rfl⟩
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  letI := Classical.decEq Γ
  let n := Fintype.card Γ
  obtain ⟨F⟩ := Fintype.truncEquivFin Γ
  let G : Fin n ↪ Fin n → Bool :=
    ⟨fun a b ↦ a = b, fun a b h ↦
      Bool.of_decide_true <| (congr_fun h b).trans <| Bool.decide_true rfl⟩
  

Proof state:
case mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
this : DecidableEq Γ := Classical.decEq Γ
n : ℕ := Fintype.card Γ
x✝ : Trunc (Γ ≃ Fin (Fintype.card Γ))
F : Γ ≃ Fin (Fintype.card Γ)
G : Fin n ↪ Fin n → Bool :=
  { toFun := fun a b => decide (a = b),
    inj' := (_ : ∀ (a b : Fin n), (fun a b => decide (a = b)) a = (fun a b => decide (a = b)) b → a = b) }
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
let H := (F.toEmbedding.trans G).trans (Equiv.vectorEquivFin _ _).symm.toEmbedding
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  letI := Classical.decEq Γ
  let n := Fintype.card Γ
  obtain ⟨F⟩ := Fintype.truncEquivFin Γ
  let G : Fin n ↪ Fin n → Bool :=
    ⟨fun a b ↦ a = b, fun a b h ↦
      Bool.of_decide_true <| (congr_fun h b).trans <| Bool.decide_true rfl⟩
  let H := (F.toEmbedding.trans G).trans (Equiv.vectorEquivFin _ _).symm.toEmbedding
  

Proof state:
case mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
this : DecidableEq Γ := Classical.decEq Γ
n : ℕ := Fintype.card Γ
x✝ : Trunc (Γ ≃ Fin (Fintype.card Γ))
F : Γ ≃ Fin (Fintype.card Γ)
G : Fin n ↪ Fin n → Bool :=
  { toFun := fun a b => decide (a = b),
    inj' := (_ : ∀ (a b : Fin n), (fun a b => decide (a = b)) a = (fun a b => decide (a = b)) b → a = b) }
H : Γ ↪ Vector Bool n :=
  Function.Embedding.trans (Function.Embedding.trans (Equiv.toEmbedding F) G)
    (Equiv.toEmbedding (Equiv.vectorEquivFin Bool n).symm)
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
classical
    let enc := H.setValue default (Vector.replicate n false)
    exact ⟨_, enc, Function.invFun enc, H.setValue_eq _ _, Function.leftInverse_invFun enc.2⟩
theorem exists_enc_dec [Fintype Γ] : ∃ (n : ℕ) (enc : Γ → Vector Bool n) (dec : Vector Bool n → Γ),
    enc default = Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by
  letI := Classical.decEq Γ
  let n := Fintype.card Γ
  obtain ⟨F⟩ := Fintype.truncEquivFin Γ
  let G : Fin n ↪ Fin n → Bool :=
    ⟨fun a b ↦ a = b, fun a b h ↦
      Bool.of_decide_true <| (congr_fun h b).trans <| Bool.decide_true rfl⟩
  let H := (F.toEmbedding.trans G).trans (Equiv.vectorEquivFin _ _).symm.toEmbedding
  classical
    

Proof state:
case mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
this : DecidableEq Γ := Classical.decEq Γ
n : ℕ := Fintype.card Γ
x✝ : Trunc (Γ ≃ Fin (Fintype.card Γ))
F : Γ ≃ Fin (Fintype.card Γ)
G : Fin n ↪ Fin n → Bool :=
  { toFun := fun a b => decide (a = b),
    inj' := (_ : ∀ (a b : Fin n), (fun a b => decide (a = b)) a = (fun a b => decide (a = b)) b → a = b) }
H : Γ ↪ Vector Bool n :=
  Function.Embedding.trans (Function.Embedding.trans (Equiv.toEmbedding F) G)
    (Equiv.toEmbedding (Equiv.vectorEquivFin Bool n).symm)
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a

Next tactic:
let enc := H.setValue default (Vector.replicate n false)