-- Mathlib/Computability/PostTuringMachine.lean
theorem tr_supports {S : Finset Λ} (ss : TM1.Supports M S) :
    TM0.Supports (tr M) ↑(trStmts M S)

Proof state:
case right.mk.some
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
q' : Λ' M
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
h₁ : (q', s) ∈ tr M (some q, v) a
h₂ : (some q, v) ∈ ↑(trStmts M S)
⊢ q' ∈ ↑(trStmts M S)

Tactic:
obtain ⟨q', v'⟩ := q'

Result:
case right.mk.some.mk
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
h₂ : (some q, v) ∈ ↑(trStmts M S)
q' : Option (TM1.Stmt Γ Λ σ)
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
⊢ (q', v') ∈ ↑(trStmts M S)

Proof state:
case right.mk.some.mk
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
q' : Option (TM1.Stmt Γ Λ σ)
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
h₂ : (some q, v).1 ∈ TM1.stmts M S ∧ (some q, v).2 ∈ Finset.univ
⊢ (q', v').1 ∈ TM1.stmts M S ∧ (q', v').2 ∈ Finset.univ

Tactic:
simp only [Finset.mem_univ, and_true] at h₂ ⊢

Result:
case right.mk.some.mk
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
q' : Option (TM1.Stmt Γ Λ σ)
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
h₂ : some q ∈ TM1.stmts M S
⊢ q' ∈ TM1.stmts M S

Proof state:
case right.mk.some.mk.some.branch.true
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v' : σ
val✝ : TM1.Stmt Γ Λ σ
p : Γ → σ → Bool
q₁ q₂ : TM1.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₂)

Tactic:
exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)

Result:
no goals

Proof state:
case right.mk.some.mk.some.load
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v' : σ
val✝ : TM1.Stmt Γ Λ σ
b : Γ → σ → σ
q : TM1.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
v : σ
h₂ : some (TM1.Stmt.load b q) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.load b q) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.load b q)
⊢ some val✝ ∈ TM1.stmts M S

Tactic:
refine IH _ (TM1.stmts_trans ?_ h₂) h₁ hs

Result:
case right.mk.some.mk.some.load
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v' : σ
val✝ : TM1.Stmt Γ Λ σ
b : Γ → σ → σ
q : TM1.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
v : σ
h₂ : some (TM1.Stmt.load b q) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.load b q) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.load b q)
⊢ q ∈ TM1.stmts₁ (TM1.Stmt.load b q)

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

Tactic:
revert this

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

Proof state:
case left.left
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
⊢ ∃ a ∈ S, M default ∈ TM1.stmts₁ (M a)

Tactic:
exact ⟨_, ss.1, TM1.stmts₁_self⟩

Result:
no goals

Proof state:
case right.mk.some.mk
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
q' : Option (TM1.Stmt Γ Λ σ)
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
h₂ : some q ∈ TM1.stmts M S
⊢ q' ∈ TM1.stmts M S

Tactic:
cases q'

Result:
case right.mk.some.mk.none
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
v' : σ
h₂ : some q ∈ TM1.stmts M S
h₁ : ((none, v'), s) ∈ tr M (some q, v) a
⊢ none ∈ TM1.stmts M S

case right.mk.some.mk.some
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v : σ
q : TM1.Stmt Γ Λ σ
v' : σ
h₂ : some q ∈ TM1.stmts M S
val✝ : TM1.Stmt Γ Λ σ
h₁ : ((some val✝, v'), s) ∈ tr M (some q, v) a
⊢ some val✝ ∈ TM1.stmts M S

Proof state:
case right.mk.some.mk.some.goto
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.Stmt Γ Λ σ
inst✝ : Fintype σ
S : Finset Λ
ss : TM1.Supports M S
a : Γ
s : TM0.Stmt Γ
v' : σ
val✝ : TM1.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

Tactic:
cases h₁

Result:
case right.mk.some.mk.some.goto.refl
Γ : Type u_1
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
M : Λ → TM1.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