[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : List Γ
⊢ l = l ++ List.replicate 0 default
[PROOFSTEP]
simp
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
⊢ BlankExtends l₁ l₂ → BlankExtends l₂ l₃ → BlankExtends l₁ l₃
[PROOFSTEP]
rintro ⟨i, rfl⟩ ⟨j, rfl⟩
[GOAL]
case intro.intro
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ : List Γ
i j : ℕ
⊢ BlankExtends l₁ (l₁ ++ List.replicate i default ++ List.replicate j default)
[PROOFSTEP]
exact ⟨i + j, by simp [List.replicate_add]⟩
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ : List Γ
i j : ℕ
⊢ l₁ ++ List.replicate i default ++ List.replicate j default = l₁ ++ List.replicate (i + j) default
[PROOFSTEP]
simp [List.replicate_add]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l l₁ l₂ : List Γ
⊢ BlankExtends l l₁ → BlankExtends l l₂ → List.length l₁ ≤ List.length l₂ → BlankExtends l₁ l₂
[PROOFSTEP]
rintro ⟨i, rfl⟩ ⟨j, rfl⟩ h
[GOAL]
case intro.intro
Γ : Type u_1
inst✝ : Inhabited Γ
l : List Γ
i j : ℕ
h : List.length (l ++ List.replicate i default) ≤ List.length (l ++ List.replicate j default)
⊢ BlankExtends (l ++ List.replicate i default) (l ++ List.replicate j default)
[PROOFSTEP]
use j - i
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l : List Γ
i j : ℕ
h : List.length (l ++ List.replicate i default) ≤ List.length (l ++ List.replicate j default)
⊢ l ++ List.replicate j default = l ++ List.replicate i default ++ List.replicate (j - i) default
[PROOFSTEP]
simp only [List.length_append, add_le_add_iff_left, List.length_replicate] at h
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l : List Γ
i j : ℕ
h : i ≤ j
⊢ l ++ List.replicate j default = l ++ List.replicate i default ++ List.replicate (j - i) default
[PROOFSTEP]
simp only [← List.replicate_add, add_tsub_cancel_of_le h, List.append_assoc]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l l₁ l₂ : List Γ
⊢ BlankExtends l₁ l → BlankExtends l₂ l → List.length l₁ ≤ List.length l₂ → BlankExtends l₁ l₂
[PROOFSTEP]
rintro ⟨i, rfl⟩ ⟨j, e⟩ h
[GOAL]
case intro.intro
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
i j : ℕ
e : l₁ ++ List.replicate i default = l₂ ++ List.replicate j default
h : List.length l₁ ≤ List.length l₂
⊢ BlankExtends l₁ l₂
[PROOFSTEP]
use i - j
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
i j : ℕ
e : l₁ ++ List.replicate i default = l₂ ++ List.replicate j default
h : List.length l₁ ≤ List.length l₂
⊢ l₂ = l₁ ++ List.replicate (i - j) default
[PROOFSTEP]
refine' List.append_right_cancel (e.symm.trans _)
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
i j : ℕ
e : l₁ ++ List.replicate i default = l₂ ++ List.replicate j default
h : List.length l₁ ≤ List.length l₂
⊢ l₁ ++ List.replicate i default = l₁ ++ List.replicate (i - j) default ++ List.replicate j default
[PROOFSTEP]
rw [List.append_assoc, ← List.replicate_add, tsub_add_cancel_of_le]
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
i j : ℕ
e : l₁ ++ List.replicate i default = l₂ ++ List.replicate j default
h : List.length l₁ ≤ List.length l₂
⊢ j ≤ i
[PROOFSTEP]
apply_fun List.length at e
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
i j : ℕ
h : List.length l₁ ≤ List.length l₂
e : List.length (l₁ ++ List.replicate i default) = List.length (l₂ ++ List.replicate j default)
⊢ j ≤ i
[PROOFSTEP]
simp only [List.length_append, List.length_replicate] at e
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
i j : ℕ
h : List.length l₁ ≤ List.length l₂
e : List.length l₁ + i = List.length l₂ + j
⊢ j ≤ i
[PROOFSTEP]
rwa [← add_le_add_iff_left, e, add_le_add_iff_right]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
⊢ BlankRel l₁ l₂ → BlankRel l₂ l₃ → BlankRel l₁ l₃
[PROOFSTEP]
rintro (h₁ | h₁) (h₂ | h₂)
[GOAL]
case inl.inl
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₁ l₂
h₂ : BlankExtends l₂ l₃
⊢ BlankRel l₁ l₃
[PROOFSTEP]
exact Or.inl (h₁.trans h₂)
[GOAL]
case inl.inr
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₁ l₂
h₂ : BlankExtends l₃ l₂
⊢ BlankRel l₁ l₃
[PROOFSTEP]
cases' le_total l₁.length l₃.length with h h
[GOAL]
case inl.inr.inl
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₁ l₂
h₂ : BlankExtends l₃ l₂
h : List.length l₁ ≤ List.length l₃
⊢ BlankRel l₁ l₃
[PROOFSTEP]
exact Or.inl (h₁.above_of_le h₂ h)
[GOAL]
case inl.inr.inr
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₁ l₂
h₂ : BlankExtends l₃ l₂
h : List.length l₃ ≤ List.length l₁
⊢ BlankRel l₁ l₃
[PROOFSTEP]
exact Or.inr (h₂.above_of_le h₁ h)
[GOAL]
case inr.inl
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₂ l₁
h₂ : BlankExtends l₂ l₃
⊢ BlankRel l₁ l₃
[PROOFSTEP]
cases' le_total l₁.length l₃.length with h h
[GOAL]
case inr.inl.inl
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₂ l₁
h₂ : BlankExtends l₂ l₃
h : List.length l₁ ≤ List.length l₃
⊢ BlankRel l₁ l₃
[PROOFSTEP]
exact Or.inl (h₁.below_of_le h₂ h)
[GOAL]
case inr.inl.inr
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₂ l₁
h₂ : BlankExtends l₂ l₃
h : List.length l₃ ≤ List.length l₁
⊢ BlankRel l₁ l₃
[PROOFSTEP]
exact Or.inr (h₂.below_of_le h₁ h)
[GOAL]
case inr.inr
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ l₃ : List Γ
h₁ : BlankExtends l₂ l₁
h₂ : BlankExtends l₃ l₂
⊢ BlankRel l₁ l₃
[PROOFSTEP]
exact Or.inr (h₂.trans h₁)
[GOAL]
Γ : Type ?u.9261
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
⊢ { l // BlankExtends l₁ l ∧ BlankExtends l₂ l }
[PROOFSTEP]
refine'
  if hl : l₁.length ≤ l₂.length then ⟨l₂, Or.elim h id fun h' ↦ _, BlankExtends.refl _⟩
  else ⟨l₁, BlankExtends.refl _, Or.elim h (fun h' ↦ _) id⟩
[GOAL]
case refine'_1
Γ : Type ?u.9261
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
hl : List.length l₁ ≤ List.length l₂
h' : BlankExtends l₂ l₁
⊢ BlankExtends l₁ l₂
case refine'_2
Γ : Type ?u.9261
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
hl : ¬List.length l₁ ≤ List.length l₂
h' : BlankExtends l₁ l₂
⊢ BlankExtends l₂ l₁
[PROOFSTEP]
exact (BlankExtends.refl _).above_of_le h' hl
[GOAL]
case refine'_2
Γ : Type ?u.9261
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
hl : ¬List.length l₁ ≤ List.length l₂
h' : BlankExtends l₁ l₂
⊢ BlankExtends l₂ l₁
[PROOFSTEP]
exact (BlankExtends.refl _).above_of_le h' (le_of_not_ge hl)
[GOAL]
Γ : Type ?u.10721
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
⊢ { l // BlankExtends l l₁ ∧ BlankExtends l l₂ }
[PROOFSTEP]
refine'
  if hl : l₁.length ≤ l₂.length then ⟨l₁, BlankExtends.refl _, Or.elim h id fun h' ↦ _⟩
  else ⟨l₂, Or.elim h (fun h' ↦ _) id, BlankExtends.refl _⟩
[GOAL]
case refine'_1
Γ : Type ?u.10721
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
hl : List.length l₁ ≤ List.length l₂
h' : BlankExtends l₂ l₁
⊢ BlankExtends l₁ l₂
case refine'_2
Γ : Type ?u.10721
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
hl : ¬List.length l₁ ≤ List.length l₂
h' : BlankExtends l₁ l₂
⊢ BlankExtends l₂ l₁
[PROOFSTEP]
exact (BlankExtends.refl _).above_of_le h' hl
[GOAL]
case refine'_2
Γ : Type ?u.10721
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
h : BlankRel l₁ l₂
hl : ¬List.length l₁ ≤ List.length l₂
h' : BlankExtends l₁ l₂
⊢ BlankExtends l₂ l₁
[PROOFSTEP]
exact (BlankExtends.refl _).above_of_le h' (le_of_not_ge hl)
[GOAL]
Γ : Type ?u.13118
inst✝ : Inhabited Γ
α : Sort ?u.13130
l : ListBlank Γ
f : List Γ → α
H : ∀ (a b : List Γ), BlankExtends a b → f a = f b
⊢ ∀ (a b : List Γ), Setoid.r a b → f a = f b
[PROOFSTEP]
rintro a b (h | h) <;> [exact H _ _ h; exact (H _ _ h).symm]
[GOAL]
Γ : Type ?u.13118
inst✝ : Inhabited Γ
α : Sort ?u.13130
l : ListBlank Γ
f : List Γ → α
H : ∀ (a b : List Γ), BlankExtends a b → f a = f b
⊢ ∀ (a b : List Γ), Setoid.r a b → f a = f b
[PROOFSTEP]
rintro a b (h | h)
[GOAL]
case inl
Γ : Type ?u.13118
inst✝ : Inhabited Γ
α : Sort ?u.13130
l : ListBlank Γ
f : List Γ → α
H : ∀ (a b : List Γ), BlankExtends a b → f a = f b
a b : List Γ
h : BlankExtends a b
⊢ f a = f b
[PROOFSTEP]
exact H _ _ h
[GOAL]
case inr
Γ : Type ?u.13118
inst✝ : Inhabited Γ
α : Sort ?u.13130
l : ListBlank Γ
f : List Γ → α
H : ∀ (a b : List Γ), BlankExtends a b → f a = f b
a b : List Γ
h : BlankExtends b a
⊢ f a = f b
[PROOFSTEP]
exact (H _ _ h).symm
[GOAL]
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ Γ
[PROOFSTEP]
apply l.liftOn List.headI
[GOAL]
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ ∀ (a b : List Γ), BlankExtends a b → List.headI a = List.headI b
[PROOFSTEP]
rintro a _ ⟨i, rfl⟩
[GOAL]
case intro
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
a : List Γ
i : ℕ
⊢ List.headI a = List.headI (a ++ List.replicate i default)
[PROOFSTEP]
cases a
[GOAL]
case intro.nil
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
i : ℕ
⊢ List.headI [] = List.headI ([] ++ List.replicate i default)
[PROOFSTEP]
cases i
[GOAL]
case intro.nil.zero
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ List.headI [] = List.headI ([] ++ List.replicate Nat.zero default)
[PROOFSTEP]
rfl
[GOAL]
case intro.nil.succ
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
n✝ : ℕ
⊢ List.headI [] = List.headI ([] ++ List.replicate (Nat.succ n✝) default)
[PROOFSTEP]
rfl
[GOAL]
case intro.cons
Γ : Type ?u.14152
inst✝ : Inhabited Γ
l : ListBlank Γ
i : ℕ
head✝ : Γ
tail✝ : List Γ
⊢ List.headI (head✝ :: tail✝) = List.headI (head✝ :: tail✝ ++ List.replicate i default)
[PROOFSTEP]
rfl
[GOAL]
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ ListBlank Γ
[PROOFSTEP]
apply l.liftOn (fun l ↦ ListBlank.mk l.tail)
[GOAL]
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ ∀ (a b : List Γ), BlankExtends a b → mk (List.tail a) = mk (List.tail b)
[PROOFSTEP]
rintro a _ ⟨i, rfl⟩
[GOAL]
case intro
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
a : List Γ
i : ℕ
⊢ mk (List.tail a) = mk (List.tail (a ++ List.replicate i default))
[PROOFSTEP]
refine' Quotient.sound' (Or.inl _)
[GOAL]
case intro
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
a : List Γ
i : ℕ
⊢ BlankExtends (List.tail a) (List.tail (a ++ List.replicate i default))
[PROOFSTEP]
cases a
[GOAL]
case intro.nil
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
i : ℕ
⊢ BlankExtends (List.tail []) (List.tail ([] ++ List.replicate i default))
[PROOFSTEP]
cases' i with i <;> [exact ⟨0, rfl⟩; exact ⟨i, rfl⟩]
[GOAL]
case intro.nil
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
i : ℕ
⊢ BlankExtends (List.tail []) (List.tail ([] ++ List.replicate i default))
[PROOFSTEP]
cases' i with i
[GOAL]
case intro.nil.zero
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ BlankExtends (List.tail []) (List.tail ([] ++ List.replicate Nat.zero default))
[PROOFSTEP]
exact ⟨0, rfl⟩
[GOAL]
case intro.nil.succ
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
i : ℕ
⊢ BlankExtends (List.tail []) (List.tail ([] ++ List.replicate (Nat.succ i) default))
[PROOFSTEP]
exact ⟨i, rfl⟩
[GOAL]
case intro.cons
Γ : Type ?u.14936
inst✝ : Inhabited Γ
l : ListBlank Γ
i : ℕ
head✝ : Γ
tail✝ : List Γ
⊢ BlankExtends (List.tail (head✝ :: tail✝)) (List.tail (head✝ :: tail✝ ++ List.replicate i default))
[PROOFSTEP]
exact ⟨i, rfl⟩
[GOAL]
Γ : Type ?u.15941
inst✝ : Inhabited Γ
a : Γ
l : ListBlank Γ
⊢ ListBlank Γ
[PROOFSTEP]
apply l.liftOn (fun l ↦ ListBlank.mk (List.cons a l))
[GOAL]
Γ : Type ?u.15941
inst✝ : Inhabited Γ
a : Γ
l : ListBlank Γ
⊢ ∀ (a_1 b : List Γ), BlankExtends a_1 b → mk (a :: a_1) = mk (a :: b)
[PROOFSTEP]
rintro _ _ ⟨i, rfl⟩
[GOAL]
case intro
Γ : Type ?u.15941
inst✝ : Inhabited Γ
a : Γ
l : ListBlank Γ
a✝ : List Γ
i : ℕ
⊢ mk (a :: a✝) = mk (a :: (a✝ ++ List.replicate i default))
[PROOFSTEP]
exact Quotient.sound' (Or.inl ⟨i, rfl⟩)
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
⊢ ∀ (l : ListBlank Γ), cons (head l) (tail l) = l
[PROOFSTEP]
apply Quotient.ind'
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
⊢ ∀ (a : List Γ), cons (head (Quotient.mk'' a)) (tail (Quotient.mk'' a)) = Quotient.mk'' a
[PROOFSTEP]
refine' fun l ↦ Quotient.sound' (Or.inr _)
[GOAL]
case h
Γ : Type u_1
inst✝ : Inhabited Γ
l : List Γ
⊢ BlankExtends l (head (Quotient.mk'' l) :: List.tail l)
[PROOFSTEP]
cases l
[GOAL]
case h.nil
Γ : Type u_1
inst✝ : Inhabited Γ
⊢ BlankExtends [] (head (Quotient.mk'' []) :: List.tail [])
[PROOFSTEP]
exact ⟨1, rfl⟩
[GOAL]
case h.cons
Γ : Type u_1
inst✝ : Inhabited Γ
head✝ : Γ
tail✝ : List Γ
⊢ BlankExtends (head✝ :: tail✝) (head (Quotient.mk'' (head✝ :: tail✝)) :: List.tail (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
⊢ Γ
[PROOFSTEP]
apply l.liftOn (fun l ↦ List.getI l n)
[GOAL]
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
⊢ ∀ (a b : List Γ), BlankExtends a b → List.getI a n = List.getI b n
[PROOFSTEP]
rintro l _ ⟨i, rfl⟩
[GOAL]
case intro
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l✝ : ListBlank Γ
n : ℕ
l : List Γ
i : ℕ
⊢ List.getI l n = List.getI (l ++ List.replicate i default) n
[PROOFSTEP]
cases' lt_or_le n _ with h h
[GOAL]
case intro.inl
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l✝ : ListBlank Γ
n : ℕ
l : List Γ
i : ℕ
h : n < ?m.17919
⊢ List.getI l n = List.getI (l ++ List.replicate i default) n
[PROOFSTEP]
rw [List.getI_append _ _ _ h]
[GOAL]
case intro.inr
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l✝ : ListBlank Γ
n : ℕ
l : List Γ
i : ℕ
h : List.length l ≤ n
⊢ List.getI l n = List.getI (l ++ List.replicate i default) n
[PROOFSTEP]
rw [List.getI_eq_default _ h]
[GOAL]
case intro.inr
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l✝ : ListBlank Γ
n : ℕ
l : List Γ
i : ℕ
h : List.length l ≤ n
⊢ default = List.getI (l ++ List.replicate i default) n
[PROOFSTEP]
cases' le_or_lt _ n with h₂ h₂
[GOAL]
case intro.inr.inl
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l✝ : ListBlank Γ
n : ℕ
l : List Γ
i : ℕ
h : List.length l ≤ n
h₂ : ?m.18386 ≤ n
⊢ default = List.getI (l ++ List.replicate i default) n
[PROOFSTEP]
rw [List.getI_eq_default _ h₂]
[GOAL]
case intro.inr.inr
Γ : Type ?u.17656
inst✝ : Inhabited Γ
l✝ : ListBlank Γ
n : ℕ
l : List Γ
i : ℕ
h : List.length l ≤ n
h₂ : n < List.length (l ++ List.replicate i default)
⊢ default = List.getI (l ++ List.replicate i default) n
[PROOFSTEP]
rw [List.getI_eq_get _ h₂, List.get_append_right' h, List.get_replicate]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ nth l 0 = head l
[PROOFSTEP]
conv => lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
| nth l 0 = head l
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
| nth l 0 = head l
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
| nth l 0 = head l
[PROOFSTEP]
lhs
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
| nth l 0
[PROOFSTEP]
rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
⊢ nth (cons (head l) (tail l)) 0 = head l
[PROOFSTEP]
exact Quotient.inductionOn' l.tail fun l ↦ rfl
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
⊢ nth l (n + 1) = nth (tail l) n
[PROOFSTEP]
conv => lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
| nth l (n + 1) = nth (tail l) n
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
| nth l (n + 1) = nth (tail l) n
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
| nth l (n + 1) = nth (tail l) n
[PROOFSTEP]
lhs
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
| nth l (n + 1)
[PROOFSTEP]
rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l : ListBlank Γ
n : ℕ
⊢ nth (cons (head l) (tail l)) (n + 1) = nth (tail l) n
[PROOFSTEP]
exact Quotient.inductionOn' l.tail fun l ↦ rfl
[GOAL]
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
⊢ (∀ (i_1 : ℕ), nth L₁ i_1 = nth L₂ i_1) → L₁ = L₂
[PROOFSTEP]
refine' ListBlank.induction_on L₁ fun l₁ ↦ ListBlank.induction_on L₂ fun l₂ H ↦ _
[GOAL]
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
⊢ mk l₁ = mk l₂
[PROOFSTEP]
wlog h : l₁.length ≤ l₂.length
[GOAL]
case inr
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
⊢ mk l₁ = mk l₂
[PROOFSTEP]
cases le_total l₁.length l₂.length <;> [skip; symm]
[GOAL]
case inr
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
⊢ mk l₁ = mk l₂
[PROOFSTEP]
cases le_total l₁.length l₂.length
[GOAL]
case inr.inl
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ mk l₁ = mk l₂
[PROOFSTEP]
skip
[GOAL]
case inr.inr
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ mk l₁ = mk l₂
[PROOFSTEP]
symm
[GOAL]
case inr.inl
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ mk l₁ = mk l₂
[PROOFSTEP]
apply this
[GOAL]
case inr.inr
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ mk l₂ = mk l₁
[PROOFSTEP]
apply this
[GOAL]
case inr.inl.L₁
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ ListBlank Γ
[PROOFSTEP]
try assumption
[GOAL]
case inr.inl.L₁
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ ListBlank Γ
[PROOFSTEP]
assumption
[GOAL]
case inr.inl.L₂
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ ListBlank Γ
[PROOFSTEP]
try assumption
[GOAL]
case inr.inl.L₂
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ ListBlank Γ
[PROOFSTEP]
assumption
[GOAL]
case inr.inl.H
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
[PROOFSTEP]
try assumption
[GOAL]
case inr.inl.H
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
[PROOFSTEP]
assumption
[GOAL]
case inr.inl.h
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ List.length l₁ ≤ List.length l₂
[PROOFSTEP]
try assumption
[GOAL]
case inr.inl.h
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₁ ≤ List.length l₂
⊢ List.length l₁ ≤ List.length l₂
[PROOFSTEP]
assumption
[GOAL]
case inr.inr.L₁
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ListBlank Γ
[PROOFSTEP]
try assumption
[GOAL]
case inr.inr.L₁
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ListBlank Γ
[PROOFSTEP]
assumption
[GOAL]
case inr.inr.L₂
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ListBlank Γ
[PROOFSTEP]
try assumption
[GOAL]
case inr.inr.L₂
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ListBlank Γ
[PROOFSTEP]
assumption
[GOAL]
case inr.inr.H
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ∀ (i_1 : ℕ), nth (mk l₂) i_1 = nth (mk l₁) i_1
[PROOFSTEP]
try assumption
[GOAL]
case inr.inr.H
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ∀ (i_1 : ℕ), nth (mk l₂) i_1 = nth (mk l₁) i_1
[PROOFSTEP]
assumption
[GOAL]
case inr.inr.h
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ List.length l₂ ≤ List.length l₁
[PROOFSTEP]
try assumption
[GOAL]
case inr.inr.h
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ List.length l₂ ≤ List.length l₁
[PROOFSTEP]
assumption
[GOAL]
case inr.inr.H
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
⊢ ∀ (i_1 : ℕ), nth (mk l₂) i_1 = nth (mk l₁) i_1
[PROOFSTEP]
intro
[GOAL]
case inr.inr.H
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
this :
  ∀ {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : ListBlank Γ} (l₁ l₂ : List Γ),
    (∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1) → List.length l₁ ≤ List.length l₂ → mk l₁ = mk l₂
h : ¬List.length l₁ ≤ List.length l₂
h✝ : List.length l₂ ≤ List.length l₁
i✝ : ℕ
⊢ nth (mk l₂) i✝ = nth (mk l₁) i✝
[PROOFSTEP]
rw [H]
[GOAL]
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
h : List.length l₁ ≤ List.length l₂
⊢ mk l₁ = mk l₂
[PROOFSTEP]
refine' Quotient.sound' (Or.inl ⟨l₂.length - l₁.length, _⟩)
[GOAL]
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
h : List.length l₁ ≤ List.length l₂
⊢ l₂ = l₁ ++ List.replicate (List.length l₂ - List.length l₁) default
[PROOFSTEP]
refine' List.ext_get _ fun i h h₂ ↦ Eq.symm _
[GOAL]
case refine'_1
Γ : Type u_1
i : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i_1 : ℕ), nth (mk l₁) i_1 = nth (mk l₂) i_1
h : List.length l₁ ≤ List.length l₂
⊢ List.length l₂ = List.length (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default)
[PROOFSTEP]
simp only [add_tsub_cancel_of_le h, List.length_append, List.length_replicate]
[GOAL]
case refine'_2
Γ : Type u_1
i✝ : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i : ℕ), nth (mk l₁) i = nth (mk l₂) i
h✝ : List.length l₁ ≤ List.length l₂
i : ℕ
h : i < List.length l₂
h₂ : i < List.length (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default)
⊢ List.get (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default) { val := i, isLt := h₂ } =
    List.get l₂ { val := i, isLt := h }
[PROOFSTEP]
simp only [ListBlank.nth_mk] at H
[GOAL]
case refine'_2
Γ : Type u_1
i✝ : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i : ℕ), List.getI l₁ i = List.getI l₂ i
h✝ : List.length l₁ ≤ List.length l₂
i : ℕ
h : i < List.length l₂
h₂ : i < List.length (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default)
⊢ List.get (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default) { val := i, isLt := h₂ } =
    List.get l₂ { val := i, isLt := h }
[PROOFSTEP]
cases' lt_or_le i l₁.length with h' h'
[GOAL]
case refine'_2.inl
Γ : Type u_1
i✝ : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i : ℕ), List.getI l₁ i = List.getI l₂ i
h✝ : List.length l₁ ≤ List.length l₂
i : ℕ
h : i < List.length l₂
h₂ : i < List.length (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default)
h' : i < List.length l₁
⊢ List.get (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default) { val := i, isLt := h₂ } =
    List.get l₂ { val := i, isLt := h }
[PROOFSTEP]
simp only [List.get_append _ h', List.get?_eq_get h, List.get?_eq_get h', ← List.getI_eq_get _ h, ←
  List.getI_eq_get _ h', H]
[GOAL]
case refine'_2.inr
Γ : Type u_1
i✝ : Inhabited Γ
L₁ L₂ : ListBlank Γ
l₁ l₂ : List Γ
H : ∀ (i : ℕ), List.getI l₁ i = List.getI l₂ i
h✝ : List.length l₁ ≤ List.length l₂
i : ℕ
h : i < List.length l₂
h₂ : i < List.length (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default)
h' : List.length l₁ ≤ i
⊢ List.get (l₁ ++ List.replicate (List.length l₂ - List.length l₁) default) { val := i, isLt := h₂ } =
    List.get l₂ { val := i, isLt := h }
[PROOFSTEP]
simp only [List.get_append_right' h', List.get_replicate, List.get?_eq_get h, List.get?_len_le h', ←
  List.getI_eq_default _ h', H, List.getI_eq_get _ h]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
n i : ℕ
L : ListBlank Γ
⊢ nth (modifyNth f n L) i = if i = n then f (nth L i) else nth L i
[PROOFSTEP]
induction' n with n IH generalizing i L
[GOAL]
case zero
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i✝ : ℕ
L✝ : ListBlank Γ
i : ℕ
L : ListBlank Γ
⊢ nth (modifyNth f Nat.zero L) i = if i = Nat.zero then f (nth L i) else nth L i
[PROOFSTEP]
cases i
[GOAL]
case zero.zero
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i : ℕ
L✝ L : ListBlank Γ
⊢ nth (modifyNth f Nat.zero L) Nat.zero = if Nat.zero = Nat.zero then f (nth L Nat.zero) else nth L Nat.zero
[PROOFSTEP]
simp only [ListBlank.nth_zero, if_true, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.nth_succ, if_false,
  ListBlank.tail_cons, Nat.zero_eq]
[GOAL]
case zero.succ
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i : ℕ
L✝ L : ListBlank Γ
n✝ : ℕ
⊢ nth (modifyNth f Nat.zero L) (Nat.succ n✝) =
    if Nat.succ n✝ = Nat.zero then f (nth L (Nat.succ n✝)) else nth L (Nat.succ n✝)
[PROOFSTEP]
simp only [ListBlank.nth_zero, if_true, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.nth_succ, if_false,
  ListBlank.tail_cons, Nat.zero_eq]
[GOAL]
case succ
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i✝ : ℕ
L✝ : ListBlank Γ
n : ℕ
IH : ∀ (i : ℕ) (L : ListBlank Γ), nth (modifyNth f n L) i = if i = n then f (nth L i) else nth L i
i : ℕ
L : ListBlank Γ
⊢ nth (modifyNth f (Nat.succ n) L) i = if i = Nat.succ n then f (nth L i) else nth L i
[PROOFSTEP]
cases i
[GOAL]
case succ.zero
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i : ℕ
L✝ : ListBlank Γ
n : ℕ
IH : ∀ (i : ℕ) (L : ListBlank Γ), nth (modifyNth f n L) i = if i = n then f (nth L i) else nth L i
L : ListBlank Γ
⊢ nth (modifyNth f (Nat.succ n) L) Nat.zero = if Nat.zero = Nat.succ n then f (nth L Nat.zero) else nth L Nat.zero
[PROOFSTEP]
rw [if_neg (Nat.succ_ne_zero _).symm]
[GOAL]
case succ.zero
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i : ℕ
L✝ : ListBlank Γ
n : ℕ
IH : ∀ (i : ℕ) (L : ListBlank Γ), nth (modifyNth f n L) i = if i = n then f (nth L i) else nth L i
L : ListBlank Γ
⊢ nth (modifyNth f (Nat.succ n) L) Nat.zero = nth L Nat.zero
[PROOFSTEP]
simp only [ListBlank.nth_zero, ListBlank.head_cons, ListBlank.modifyNth, Nat.zero_eq]
[GOAL]
case succ.succ
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
i : ℕ
L✝ : ListBlank Γ
n : ℕ
IH : ∀ (i : ℕ) (L : ListBlank Γ), nth (modifyNth f n L) i = if i = n then f (nth L i) else nth L i
L : ListBlank Γ
n✝ : ℕ
⊢ nth (modifyNth f (Nat.succ n) L) (Nat.succ n✝) =
    if Nat.succ n✝ = Nat.succ n then f (nth L (Nat.succ n✝)) else nth L (Nat.succ n✝)
[PROOFSTEP]
simp only [IH, ListBlank.modifyNth, ListBlank.nth_succ, ListBlank.tail_cons, Nat.succ.injEq]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : List Γ
⊢ List.headI (List.map f.f l) = Turing.PointedMap.f f (List.headI l)
[PROOFSTEP]
cases l <;> [exact (PointedMap.map_pt f).symm; rfl]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : List Γ
⊢ List.headI (List.map f.f l) = Turing.PointedMap.f f (List.headI l)
[PROOFSTEP]
cases l
[GOAL]
case nil
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
⊢ List.headI (List.map f.f []) = Turing.PointedMap.f f (List.headI [])
[PROOFSTEP]
exact (PointedMap.map_pt f).symm
[GOAL]
case cons
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
head✝ : Γ
tail✝ : List Γ
⊢ List.headI (List.map f.f (head✝ :: tail✝)) = Turing.PointedMap.f f (List.headI (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
Γ : Type ?u.27995
Γ' : Type ?u.27994
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
⊢ ListBlank Γ'
[PROOFSTEP]
apply l.liftOn (fun l ↦ ListBlank.mk (List.map f l))
[GOAL]
Γ : Type ?u.27995
Γ' : Type ?u.27994
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
⊢ ∀ (a b : List Γ), BlankExtends a b → mk (List.map f.f a) = mk (List.map f.f b)
[PROOFSTEP]
rintro l _ ⟨i, rfl⟩
[GOAL]
case intro
Γ : Type ?u.27995
Γ' : Type ?u.27994
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
l : List Γ
i : ℕ
⊢ mk (List.map f.f l) = mk (List.map f.f (l ++ List.replicate i default))
[PROOFSTEP]
refine' Quotient.sound' (Or.inl ⟨i, _⟩)
[GOAL]
case intro
Γ : Type ?u.27995
Γ' : Type ?u.27994
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
l : List Γ
i : ℕ
⊢ List.map f.f (l ++ List.replicate i default) = List.map f.f l ++ List.replicate i default
[PROOFSTEP]
simp only [PointedMap.map_pt, List.map_append, List.map_replicate]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
⊢ head (map f l) = PointedMap.f f (head l)
[PROOFSTEP]
conv => lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| head (map f l) = PointedMap.f f (head l)
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| head (map f l) = PointedMap.f f (head l)
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| head (map f l) = PointedMap.f f (head l)
[PROOFSTEP]
lhs
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| head (map f l)
[PROOFSTEP]
rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
⊢ head (map f (cons (head l) (tail l))) = PointedMap.f f (head l)
[PROOFSTEP]
exact Quotient.inductionOn' l fun a ↦ rfl
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
⊢ tail (map f l) = map f (tail l)
[PROOFSTEP]
conv => lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| tail (map f l) = map f (tail l)
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| tail (map f l) = map f (tail l)
[PROOFSTEP]
lhs; rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| tail (map f l) = map f (tail l)
[PROOFSTEP]
lhs
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
| tail (map f l)
[PROOFSTEP]
rw [← ListBlank.cons_head_tail l]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
⊢ tail (map f (cons (head l) (tail l))) = map f (tail l)
[PROOFSTEP]
exact Quotient.inductionOn' l fun a ↦ rfl
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
a : Γ
⊢ map f (cons a l) = cons (PointedMap.f f a) (map f l)
[PROOFSTEP]
refine' (ListBlank.cons_head_tail _).symm.trans _
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
a : Γ
⊢ cons (head (map f (cons a l))) (tail (map f (cons a l))) = cons (PointedMap.f f a) (map f l)
[PROOFSTEP]
simp only [ListBlank.head_map, ListBlank.head_cons, ListBlank.tail_map, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l : ListBlank Γ
n : ℕ
⊢ nth (map f l) n = PointedMap.f f (nth l n)
[PROOFSTEP]
refine'
  l.inductionOn fun l ↦
    _
      -- Porting note: Added `suffices` to get `simp` to work.
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
n : ℕ
l : List Γ
⊢ nth (map f (Quotient.mk (BlankRel.setoid Γ) l)) n = PointedMap.f f (nth (Quotient.mk (BlankRel.setoid Γ) l) n)
[PROOFSTEP]
suffices ((mk l).map f).nth n = f ((mk l).nth n) by exact this
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
n : ℕ
l : List Γ
this : nth (map f (mk l)) n = PointedMap.f f (nth (mk l) n)
⊢ nth (map f (Quotient.mk (BlankRel.setoid Γ) l)) n = PointedMap.f f (nth (Quotient.mk (BlankRel.setoid Γ) l) n)
[PROOFSTEP]
exact this
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
n : ℕ
l : List Γ
⊢ nth (map f (mk l)) n = PointedMap.f f (nth (mk l) n)
[PROOFSTEP]
simp only [List.get?_map, ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
n : ℕ
l : List Γ
⊢ Option.iget (Option.map f.f (List.get? l n)) = PointedMap.f f (Option.iget (List.get? l n))
[PROOFSTEP]
cases l.get? n
[GOAL]
case none
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
n : ℕ
l : List Γ
⊢ Option.iget (Option.map f.f none) = PointedMap.f f (Option.iget none)
[PROOFSTEP]
exact f.2.symm
[GOAL]
case some
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
l✝ : ListBlank Γ
n : ℕ
l : List Γ
val✝ : Γ
⊢ Option.iget (Option.map f.f (some val✝)) = PointedMap.f f (Option.iget (some val✝))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
Γ : ι → Type u_2
inst✝ : (i : ι) → Inhabited (Γ i)
i : ι
L : ListBlank ((i : ι) → Γ i)
n : ℕ
⊢ ListBlank.nth (ListBlank.map (proj i) L) n = ListBlank.nth L n i
[PROOFSTEP]
rw [ListBlank.nth_map]
[GOAL]
ι : Type u_1
Γ : ι → Type u_2
inst✝ : (i : ι) → Inhabited (Γ i)
i : ι
L : ListBlank ((i : ι) → Γ i)
n : ℕ
⊢ PointedMap.f (proj i) (ListBlank.nth L n) = ListBlank.nth L n i
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
F : PointedMap Γ Γ'
f : Γ → Γ
f' : Γ' → Γ'
H : ∀ (x : Γ), PointedMap.f F (f x) = f' (PointedMap.f F x)
n : ℕ
L : ListBlank Γ
⊢ map F (modifyNth f n L) = modifyNth f' n (map F L)
[PROOFSTEP]
induction' n with n IH generalizing L
[GOAL]
case zero
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
F : PointedMap Γ Γ'
f : Γ → Γ
f' : Γ' → Γ'
H : ∀ (x : Γ), PointedMap.f F (f x) = f' (PointedMap.f F x)
L✝ L : ListBlank Γ
⊢ map F (modifyNth f Nat.zero L) = modifyNth f' Nat.zero (map F L)
[PROOFSTEP]
simp only [*, ListBlank.head_map, ListBlank.modifyNth, ListBlank.map_cons, ListBlank.tail_map]
[GOAL]
case succ
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
F : PointedMap Γ Γ'
f : Γ → Γ
f' : Γ' → Γ'
H : ∀ (x : Γ), PointedMap.f F (f x) = f' (PointedMap.f F x)
L✝ : ListBlank Γ
n : ℕ
IH : ∀ (L : ListBlank Γ), map F (modifyNth f n L) = modifyNth f' n (map F L)
L : ListBlank Γ
⊢ map F (modifyNth f (Nat.succ n) L) = modifyNth f' (Nat.succ n) (map F L)
[PROOFSTEP]
simp only [*, ListBlank.head_map, ListBlank.modifyNth, ListBlank.map_cons, ListBlank.tail_map]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
⊢ append l₁ (mk l₂) = mk (l₁ ++ l₂)
[PROOFSTEP]
induction l₁
[GOAL]
case nil
Γ : Type u_1
inst✝ : Inhabited Γ
l₂ : List Γ
⊢ append [] (mk l₂) = mk ([] ++ l₂)
[PROOFSTEP]
simp only [*, ListBlank.append, List.nil_append, List.cons_append, ListBlank.cons_mk]
[GOAL]
case cons
Γ : Type u_1
inst✝ : Inhabited Γ
l₂ : List Γ
head✝ : Γ
tail✝ : List Γ
tail_ih✝ : append tail✝ (mk l₂) = mk (tail✝ ++ l₂)
⊢ append (head✝ :: tail✝) (mk l₂) = mk (head✝ :: tail✝ ++ l₂)
[PROOFSTEP]
simp only [*, ListBlank.append, List.nil_append, List.cons_append, ListBlank.cons_mk]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
l₃ : ListBlank Γ
⊢ append (l₁ ++ l₂) l₃ = append l₁ (append l₂ l₃)
[PROOFSTEP]
refine'
  l₃.inductionOn fun l ↦
    _
      -- Porting note: Added `suffices` to get `simp` to work.
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
l₃ : ListBlank Γ
l : List Γ
⊢ append (l₁ ++ l₂) (Quotient.mk (BlankRel.setoid Γ) l) = append l₁ (append l₂ (Quotient.mk (BlankRel.setoid Γ) l))
[PROOFSTEP]
suffices append (l₁ ++ l₂) (mk l) = append l₁ (append l₂ (mk l)) by exact this
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
l₃ : ListBlank Γ
l : List Γ
this : append (l₁ ++ l₂) (mk l) = append l₁ (append l₂ (mk l))
⊢ append (l₁ ++ l₂) (Quotient.mk (BlankRel.setoid Γ) l) = append l₁ (append l₂ (Quotient.mk (BlankRel.setoid Γ) l))
[PROOFSTEP]
exact this
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
l₁ l₂ : List Γ
l₃ : ListBlank Γ
l : List Γ
⊢ append (l₁ ++ l₂) (mk l) = append l₁ (append l₂ (mk l))
[PROOFSTEP]
simp only [ListBlank.append_mk, List.append_assoc]
[GOAL]
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
⊢ ListBlank Γ'
[PROOFSTEP]
apply l.liftOn (fun l ↦ ListBlank.mk (List.bind l f))
[GOAL]
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
⊢ ∀ (a b : List Γ), BlankExtends a b → mk (List.bind a f) = mk (List.bind b f)
[PROOFSTEP]
rintro l _ ⟨i, rfl⟩
[GOAL]
case intro
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
l : List Γ
i : ℕ
⊢ mk (List.bind l f) = mk (List.bind (l ++ List.replicate i default) f)
[PROOFSTEP]
cases' hf with n e
[GOAL]
case intro.intro
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
i n : ℕ
e : f default = List.replicate n default
⊢ mk (List.bind l f) = mk (List.bind (l ++ List.replicate i default) f)
[PROOFSTEP]
refine' Quotient.sound' (Or.inl ⟨i * n, _⟩)
[GOAL]
case intro.intro
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
i n : ℕ
e : f default = List.replicate n default
⊢ List.bind (l ++ List.replicate i default) f = List.bind l f ++ List.replicate (i * n) default
[PROOFSTEP]
rw [List.append_bind, mul_comm]
[GOAL]
case intro.intro
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
i n : ℕ
e : f default = List.replicate n default
⊢ List.bind l f ++ List.bind (List.replicate i default) f = List.bind l f ++ List.replicate (n * i) default
[PROOFSTEP]
congr
[GOAL]
case intro.intro.e_a
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
i n : ℕ
e : f default = List.replicate n default
⊢ List.bind (List.replicate i default) f = List.replicate (n * i) default
[PROOFSTEP]
induction' i with i IH
[GOAL]
case intro.intro.e_a.zero
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
n : ℕ
e : f default = List.replicate n default
⊢ List.bind (List.replicate Nat.zero default) f = List.replicate (n * Nat.zero) default
case intro.intro.e_a.succ
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
n : ℕ
e : f default = List.replicate n default
i : ℕ
IH : List.bind (List.replicate i default) f = List.replicate (n * i) default
⊢ List.bind (List.replicate (Nat.succ i) default) f = List.replicate (n * Nat.succ i) default
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.e_a.succ
Γ : Type ?u.36140
Γ' : Type ?u.36152
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
l✝ : ListBlank Γ
f : Γ → List Γ'
l : List Γ
n : ℕ
e : f default = List.replicate n default
i : ℕ
IH : List.bind (List.replicate i default) f = List.replicate (n * i) default
⊢ List.bind (List.replicate (Nat.succ i) default) f = List.replicate (n * Nat.succ i) default
[PROOFSTEP]
simp only [IH, e, List.replicate_add, Nat.mul_succ, add_comm, List.replicate_succ, List.cons_bind]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
a : Γ
l : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
⊢ bind (cons a l) f hf = append (f a) (bind l f hf)
[PROOFSTEP]
refine'
  l.inductionOn fun l ↦
    _
      -- Porting note: Added `suffices` to get `simp` to work.
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
a : Γ
l✝ : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
l : List Γ
⊢ bind (cons a (Quotient.mk (BlankRel.setoid Γ) l)) f hf = append (f a) (bind (Quotient.mk (BlankRel.setoid Γ) l) f hf)
[PROOFSTEP]
suffices ((mk l).cons a).bind f hf = ((mk l).bind f hf).append (f a) by exact this
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
a : Γ
l✝ : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
l : List Γ
this : bind (cons a (mk l)) f hf = append (f a) (bind (mk l) f hf)
⊢ bind (cons a (Quotient.mk (BlankRel.setoid Γ) l)) f hf = append (f a) (bind (Quotient.mk (BlankRel.setoid Γ) l) f hf)
[PROOFSTEP]
exact this
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
a : Γ
l✝ : ListBlank Γ
f : Γ → List Γ'
hf : ∃ n, f default = List.replicate n default
l : List Γ
⊢ bind (cons a (mk l)) f hf = append (f a) (bind (mk l) f hf)
[PROOFSTEP]
simp only [ListBlank.append_mk, ListBlank.bind_mk, ListBlank.cons_mk, List.cons_bind]
[GOAL]
Γ : Type ?u.39827
inst✝ : Inhabited Γ
⊢ Tape Γ
[PROOFSTEP]
constructor
[GOAL]
case head
Γ : Type ?u.39827
inst✝ : Inhabited Γ
⊢ Γ
[PROOFSTEP]
apply default
[GOAL]
case left
Γ : Type ?u.39827
inst✝ : Inhabited Γ
⊢ ListBlank Γ
[PROOFSTEP]
apply default
[GOAL]
case right
Γ : Type ?u.39827
inst✝ : Inhabited Γ
⊢ ListBlank Γ
[PROOFSTEP]
apply default
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
⊢ move Dir.right (move Dir.left T) = T
[PROOFSTEP]
cases T
[GOAL]
case mk
Γ : Type u_1
inst✝ : Inhabited Γ
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ move Dir.right (move Dir.left { head := head✝, left := left✝, right := right✝ }) =
    { head := head✝, left := left✝, right := right✝ }
[PROOFSTEP]
simp [Tape.move]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
⊢ move Dir.left (move Dir.right T) = T
[PROOFSTEP]
cases T
[GOAL]
case mk
Γ : Type u_1
inst✝ : Inhabited Γ
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ move Dir.left (move Dir.right { head := head✝, left := left✝, right := right✝ }) =
    { head := head✝, left := left✝, right := right✝ }
[PROOFSTEP]
simp [Tape.move]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
⊢ mk' T.left (right₀ T) = T
[PROOFSTEP]
cases T
[GOAL]
case mk
Γ : Type u_1
inst✝ : Inhabited Γ
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ mk' { head := head✝, left := left✝, right := right✝ }.left
      (right₀ { head := head✝, left := left✝, right := right✝ }) =
    { head := head✝, left := left✝, right := right✝ }
[PROOFSTEP]
simp only [Tape.right₀, Tape.mk', ListBlank.head_cons, ListBlank.tail_cons, eq_self_iff_true, and_self_iff]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
L R : ListBlank Γ
⊢ move Dir.left (mk' L R) = mk' (ListBlank.tail L) (ListBlank.cons (ListBlank.head L) R)
[PROOFSTEP]
simp only [Tape.move, Tape.mk', ListBlank.head_cons, eq_self_iff_true, ListBlank.cons_head_tail, and_self_iff,
  ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
L R : ListBlank Γ
⊢ move Dir.right (mk' L R) = mk' (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R)
[PROOFSTEP]
simp only [Tape.move, Tape.mk', ListBlank.head_cons, eq_self_iff_true, ListBlank.cons_head_tail, and_self_iff,
  ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
n : ℕ
⊢ ListBlank.nth (right₀ T) n = nth T ↑n
[PROOFSTEP]
cases n
[GOAL]
case zero
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
⊢ ListBlank.nth (right₀ T) Nat.zero = nth T ↑Nat.zero
[PROOFSTEP]
simp only [Tape.nth, Tape.right₀, Int.ofNat_zero, ListBlank.nth_zero, ListBlank.nth_succ, ListBlank.head_cons,
  ListBlank.tail_cons, Nat.zero_eq]
[GOAL]
case succ
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
n✝ : ℕ
⊢ ListBlank.nth (right₀ T) (Nat.succ n✝) = nth T ↑(Nat.succ n✝)
[PROOFSTEP]
simp only [Tape.nth, Tape.right₀, Int.ofNat_zero, ListBlank.nth_zero, ListBlank.nth_succ, ListBlank.head_cons,
  ListBlank.tail_cons, Nat.zero_eq]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
L R : ListBlank Γ
n : ℕ
⊢ nth (mk' L R) ↑n = ListBlank.nth R n
[PROOFSTEP]
rw [← Tape.right₀_nth, Tape.mk'_right₀]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
a : Γ
L R : ListBlank Γ
n : ℕ
⊢ nth (move Dir.left { head := a, left := L, right := R }) (↑(n + 1) + 1) =
    nth { head := a, left := L, right := R } (↑(n + 1) + 1 - 1)
[PROOFSTEP]
rw [add_sub_cancel]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
a : Γ
L R : ListBlank Γ
n : ℕ
⊢ nth (move Dir.left { head := a, left := L, right := R }) (↑(n + 1) + 1) =
    nth { head := a, left := L, right := R } ↑(n + 1)
[PROOFSTEP]
change (R.cons a).nth (n + 1) = R.nth n
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
a : Γ
L R : ListBlank Γ
n : ℕ
⊢ ListBlank.nth (ListBlank.cons a R) (n + 1) = ListBlank.nth R n
[PROOFSTEP]
rw [ListBlank.nth_succ, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℤ
⊢ nth (move Dir.right T) i = nth T (i + 1)
[PROOFSTEP]
conv => rhs; rw [← T.move_right_left]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℤ
| nth (move Dir.right T) i = nth T (i + 1)
[PROOFSTEP]
rhs; rw [← T.move_right_left]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℤ
| nth (move Dir.right T) i = nth T (i + 1)
[PROOFSTEP]
rhs; rw [← T.move_right_left]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℤ
| nth (move Dir.right T) i = nth T (i + 1)
[PROOFSTEP]
rhs
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℤ
| nth T (i + 1)
[PROOFSTEP]
rw [← T.move_right_left]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℤ
⊢ nth (move Dir.right T) i = nth (move Dir.left (move Dir.right T)) (i + 1)
[PROOFSTEP]
rw [Tape.move_left_nth, add_sub_cancel]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
i : ℕ
⊢ ((move Dir.right)^[i] T).head = nth T ↑i
[PROOFSTEP]
induction i generalizing T
[GOAL]
case zero
Γ : Type u_1
inst✝ : Inhabited Γ
T : Tape Γ
⊢ ((move Dir.right)^[Nat.zero] T).head = nth T ↑Nat.zero
[PROOFSTEP]
rfl
[GOAL]
case succ
Γ : Type u_1
inst✝ : Inhabited Γ
n✝ : ℕ
n_ih✝ : ∀ (T : Tape Γ), ((move Dir.right)^[n✝] T).head = nth T ↑n✝
T : Tape Γ
⊢ ((move Dir.right)^[Nat.succ n✝] T).head = nth T ↑(Nat.succ n✝)
[PROOFSTEP]
simp only [*, Tape.move_right_nth, Int.ofNat_succ, iterate_succ, Function.comp_apply]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
⊢ ∀ (T : Tape Γ), write T.head T = T
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case mk
Γ : Type u_1
inst✝ : Inhabited Γ
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ write { head := head✝, left := left✝, right := right✝ }.head { head := head✝, left := left✝, right := right✝ } =
    { head := head✝, left := left✝, right := right✝ }
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
a b : Γ
L R : ListBlank Γ
⊢ write b (mk' L (ListBlank.cons a R)) = mk' L (ListBlank.cons b R)
[PROOFSTEP]
simp only [Tape.write, Tape.mk', ListBlank.head_cons, ListBlank.tail_cons, eq_self_iff_true, and_self_iff]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
⊢ ∀ (T : Tape Γ), (map f T).head = PointedMap.f f T.head
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case mk
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ (map f { head := head✝, left := left✝, right := right✝ }).head =
    PointedMap.f f { head := head✝, left := left✝, right := right✝ }.head
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
b : Γ
⊢ ∀ (T : Tape Γ), map f (write b T) = write (PointedMap.f f b) (map f T)
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case mk
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
b head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ map f (write b { head := head✝, left := left✝, right := right✝ }) =
    write (PointedMap.f f b) (map f { head := head✝, left := left✝, right := right✝ })
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
L R : ListBlank Γ
n : ℕ
⊢ write (f (ListBlank.nth R n)) ((move Dir.right)^[n] (mk' L R)) =
    (move Dir.right)^[n] (mk' L (ListBlank.modifyNth f n R))
[PROOFSTEP]
induction' n with n IH generalizing L R
[GOAL]
case zero
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
L✝ R✝ L R : ListBlank Γ
⊢ write (f (ListBlank.nth R Nat.zero)) ((move Dir.right)^[Nat.zero] (mk' L R)) =
    (move Dir.right)^[Nat.zero] (mk' L (ListBlank.modifyNth f Nat.zero R))
[PROOFSTEP]
simp only [ListBlank.nth_zero, ListBlank.modifyNth, iterate_zero_apply, Nat.zero_eq]
[GOAL]
case zero
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
L✝ R✝ L R : ListBlank Γ
⊢ write (f (ListBlank.head R)) (mk' L R) = mk' L (ListBlank.cons (f (ListBlank.head R)) (ListBlank.tail R))
[PROOFSTEP]
rw [← Tape.write_mk', ListBlank.cons_head_tail]
[GOAL]
case succ
Γ : Type u_1
inst✝ : Inhabited Γ
f : Γ → Γ
L✝ R✝ : ListBlank Γ
n : ℕ
IH :
  ∀ (L R : ListBlank Γ),
    write (f (ListBlank.nth R n)) ((move Dir.right)^[n] (mk' L R)) =
      (move Dir.right)^[n] (mk' L (ListBlank.modifyNth f n R))
L R : ListBlank Γ
⊢ write (f (ListBlank.nth R (Nat.succ n))) ((move Dir.right)^[Nat.succ n] (mk' L R)) =
    (move Dir.right)^[Nat.succ n] (mk' L (ListBlank.modifyNth f (Nat.succ n) R))
[PROOFSTEP]
simp only [ListBlank.head_cons, ListBlank.nth_succ, ListBlank.modifyNth, Tape.move_right_mk', ListBlank.tail_cons,
  iterate_succ_apply, IH]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
T : Tape Γ
d : Dir
⊢ map f (move d T) = move d (map f T)
[PROOFSTEP]
cases T
[GOAL]
case mk
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
d : Dir
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ map f (move d { head := head✝, left := left✝, right := right✝ }) =
    move d (map f { head := head✝, left := left✝, right := right✝ })
[PROOFSTEP]
cases d
[GOAL]
case mk.left
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ map f (move Dir.left { head := head✝, left := left✝, right := right✝ }) =
    move Dir.left (map f { head := head✝, left := left✝, right := right✝ })
[PROOFSTEP]
simp only [Tape.move, Tape.map, ListBlank.head_map, eq_self_iff_true, ListBlank.map_cons, and_self_iff,
  ListBlank.tail_map]
[GOAL]
case mk.right
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
head✝ : Γ
left✝ right✝ : ListBlank Γ
⊢ map f (move Dir.right { head := head✝, left := left✝, right := right✝ }) =
    move Dir.right (map f { head := head✝, left := left✝, right := right✝ })
[PROOFSTEP]
simp only [Tape.move, Tape.map, ListBlank.head_map, eq_self_iff_true, ListBlank.map_cons, and_self_iff,
  ListBlank.tail_map]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
L R : ListBlank Γ
⊢ map f (mk' L R) = mk' (ListBlank.map f L) (ListBlank.map f R)
[PROOFSTEP]
simp only [Tape.mk', Tape.map, ListBlank.head_map, eq_self_iff_true, and_self_iff, ListBlank.tail_map]
[GOAL]
Γ : Type u_1
Γ' : Type u_2
inst✝¹ : Inhabited Γ
inst✝ : Inhabited Γ'
f : PointedMap Γ Γ'
L R : List Γ
⊢ map f (mk₂ L R) = mk₂ (List.map f.f L) (List.map f.f R)
[PROOFSTEP]
simp only [Tape.mk₂, Tape.map_mk', ListBlank.map_mk]
[GOAL]
σ : Type u_1
f : σ → Option σ
a b c : σ
h : f a = f b
⊢ (∃ b_1, b_1 ∈ f b ∧ ReflTransGen (fun a b => b ∈ f a) b_1 c) ↔ ∃ b, b ∈ f a ∧ ReflTransGen (fun a b => b ∈ f a) b c
[PROOFSTEP]
rw [h]
[GOAL]
σ : Type u_1
f : σ → Option σ
a b c : σ
h₁ : Reaches₁ f a c
h₂ : b ∈ f a
⊢ Reaches f b c
[PROOFSTEP]
rcases TransGen.head'_iff.1 h₁ with ⟨b', hab, hbc⟩
[GOAL]
case intro.intro
σ : Type u_1
f : σ → Option σ
a b c : σ
h₁ : Reaches₁ f a c
h₂ : b ∈ f a
b' : σ
hab : b' ∈ f a
hbc : ReflTransGen (fun a b => b ∈ f a) b' c
⊢ Reaches f b c
[PROOFSTEP]
cases Option.mem_unique hab h₂
[GOAL]
case intro.intro.refl
σ : Type u_1
f : σ → Option σ
a b c : σ
h₁ : Reaches₁ f a c
h₂ hab : b ∈ f a
hbc : ReflTransGen (fun a b => b ∈ f a) b c
⊢ Reaches f b c
[PROOFSTEP]
exact hbc
[GOAL]
σ : Type ?u.63381
f : σ → Option σ
b : σ
C : σ → Sort u_1
a : σ
h : b ∈ eval f a
H : (a : σ) → b ∈ eval f a → ((a' : σ) → f a = some a' → C a') → C a
a' : σ
ha' : b ∈ PFun.fix (fun s => Part.some (Option.elim (f s) (Sum.inl s) Sum.inr)) a'
h' : (a'' : σ) → Sum.inr a'' ∈ Part.some (Option.elim (f a') (Sum.inl a') Sum.inr) → C a''
b' : σ
e : f a' = some b'
⊢ Sum.inr b' = Option.elim (f a') (Sum.inl a') Sum.inr
[PROOFSTEP]
rw [e]
[GOAL]
σ : Type ?u.63381
f : σ → Option σ
b : σ
C : σ → Sort u_1
a : σ
h : b ∈ eval f a
H : (a : σ) → b ∈ eval f a → ((a' : σ) → f a = some a' → C a') → C a
a' : σ
ha' : b ∈ PFun.fix (fun s => Part.some (Option.elim (f s) (Sum.inl s) Sum.inr)) a'
h' : (a'' : σ) → Sum.inr a'' ∈ Part.some (Option.elim (f a') (Sum.inl a') Sum.inr) → C a''
b' : σ
e : f a' = some b'
⊢ Sum.inr b' = Option.elim (some b') (Sum.inl a') Sum.inr
[PROOFSTEP]
rfl
[GOAL]
σ : Type u_1
f : σ → Option σ
a b : σ
⊢ b ∈ eval f a ↔ Reaches f a b ∧ f b = none
[PROOFSTEP]
refine' ⟨fun h ↦ _, fun ⟨h₁, h₂⟩ ↦ _⟩
[GOAL]
case refine'_1
σ : Type u_1
f : σ → Option σ
a b : σ
h : b ∈ eval f a
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
refine' @evalInduction _ _ _ (fun a ↦ Reaches f a b ∧ f b = none) _ h fun a h IH ↦ _
[GOAL]
case refine'_1
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝ : b ∈ eval f a✝
a : σ
h : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
⊢ (fun a => Reaches f a b ∧ f b = none) a
[PROOFSTEP]
cases' e : f a with a'
[GOAL]
case refine'_1.none
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝ : b ∈ eval f a✝
a : σ
h : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
e : f a = none
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
rw [Part.mem_unique h (PFun.mem_fix_iff.2 <| Or.inl <| Part.mem_some_iff.2 <| by rw [e] <;> rfl)]
[GOAL]
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝ : b ∈ eval f a✝
a : σ
h : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
e : f a = none
⊢ Sum.inl ?m.64287 = Option.elim (f a) (Sum.inl a) Sum.inr
[PROOFSTEP]
rw [e]
[GOAL]
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝ : b ∈ eval f a✝
a : σ
h : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
e : f a = none
⊢ Sum.inl ?m.64287 = Option.elim none (Sum.inl a) Sum.inr
[PROOFSTEP]
rfl
[GOAL]
case refine'_1.none
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝ : b ∈ eval f a✝
a : σ
h : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
e : f a = none
⊢ Reaches f a a ∧ f a = none
[PROOFSTEP]
exact ⟨ReflTransGen.refl, e⟩
[GOAL]
case refine'_1.some
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝ : b ∈ eval f a✝
a : σ
h : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
rcases PFun.mem_fix_iff.1 h with (h | ⟨_, h, _⟩)
[GOAL]
case refine'_1.some.inl
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝¹ : b ∈ eval f a✝
a : σ
h✝ : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
h : Sum.inl b ∈ Part.some (Option.elim (f a) (Sum.inl a) Sum.inr)
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
rw [e] at h
[GOAL]
case refine'_1.some.inr.intro.intro
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝¹ : b ∈ eval f a✝
a : σ
h✝ : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
w✝ : σ
h : Sum.inr w✝ ∈ Part.some (Option.elim (f a) (Sum.inl a) Sum.inr)
right✝ : b ∈ PFun.fix (fun s => Part.some (Option.elim (f s) (Sum.inl s) Sum.inr)) w✝
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
rw [e] at h
[GOAL]
case refine'_1.some.inl
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝¹ : b ∈ eval f a✝
a : σ
h✝ : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
h : Sum.inl b ∈ Part.some (Option.elim (some a') (Sum.inl a) Sum.inr)
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
cases Part.mem_some_iff.1 h
[GOAL]
case refine'_1.some.inr.intro.intro
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝¹ : b ∈ eval f a✝
a : σ
h✝ : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
w✝ : σ
h : Sum.inr w✝ ∈ Part.some (Option.elim (some a') (Sum.inl a) Sum.inr)
right✝ : b ∈ PFun.fix (fun s => Part.some (Option.elim (f s) (Sum.inl s) Sum.inr)) w✝
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
cases Part.mem_some_iff.1 h
[GOAL]
case refine'_1.some.inr.intro.intro.refl
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝¹ : b ∈ eval f a✝
a : σ
h✝ : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
h : Sum.inr a' ∈ Part.some (Option.elim (some a') (Sum.inl a) Sum.inr)
right✝ : b ∈ PFun.fix (fun s => Part.some (Option.elim (f s) (Sum.inl s) Sum.inr)) a'
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
cases' IH a' e with h₁ h₂
[GOAL]
case refine'_1.some.inr.intro.intro.refl.intro
σ : Type u_1
f : σ → Option σ
a✝ b : σ
h✝¹ : b ∈ eval f a✝
a : σ
h✝ : b ∈ eval f a
IH : ∀ (a' : σ), f a = some a' → (fun a => Reaches f a b ∧ f b = none) a'
a' : σ
e : f a = some a'
h : Sum.inr a' ∈ Part.some (Option.elim (some a') (Sum.inl a) Sum.inr)
right✝ : b ∈ PFun.fix (fun s => Part.some (Option.elim (f s) (Sum.inl s) Sum.inr)) a'
h₁ : Reaches f a' b
h₂ : f b = none
⊢ Reaches f a b ∧ f b = none
[PROOFSTEP]
exact ⟨ReflTransGen.head e h₁, h₂⟩
[GOAL]
case refine'_2
σ : Type u_1
f : σ → Option σ
a b : σ
x✝ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
⊢ b ∈ eval f a
[PROOFSTEP]
refine' ReflTransGen.head_induction_on h₁ _ fun h _ IH ↦ _
[GOAL]
case refine'_2.refine'_1
σ : Type u_1
f : σ → Option σ
a b : σ
x✝ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
⊢ b ∈ eval f b
[PROOFSTEP]
refine' PFun.mem_fix_iff.2 (Or.inl _)
[GOAL]
case refine'_2.refine'_1
σ : Type u_1
f : σ → Option σ
a b : σ
x✝ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
⊢ Sum.inl b ∈ Part.some (Option.elim (f b) (Sum.inl b) Sum.inr)
[PROOFSTEP]
rw [h₂]
[GOAL]
case refine'_2.refine'_1
σ : Type u_1
f : σ → Option σ
a b : σ
x✝ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
⊢ Sum.inl b ∈ Part.some (Option.elim none (Sum.inl b) Sum.inr)
[PROOFSTEP]
apply Part.mem_some
[GOAL]
case refine'_2.refine'_2
σ : Type u_1
f : σ → Option σ
a b : σ
x✝¹ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
a✝ c✝ : σ
h : c✝ ∈ f a✝
x✝ : ReflTransGen (fun a b => b ∈ f a) c✝ b
IH : b ∈ eval f c✝
⊢ b ∈ eval f a✝
[PROOFSTEP]
refine' PFun.mem_fix_iff.2 (Or.inr ⟨_, _, IH⟩)
[GOAL]
case refine'_2.refine'_2
σ : Type u_1
f : σ → Option σ
a b : σ
x✝¹ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
a✝ c✝ : σ
h : c✝ ∈ f a✝
x✝ : ReflTransGen (fun a b => b ∈ f a) c✝ b
IH : b ∈ eval f c✝
⊢ Sum.inr c✝ ∈ Part.some (Option.elim (f a✝) (Sum.inl a✝) Sum.inr)
[PROOFSTEP]
rw [h]
[GOAL]
case refine'_2.refine'_2
σ : Type u_1
f : σ → Option σ
a b : σ
x✝¹ : Reaches f a b ∧ f b = none
h₁ : Reaches f a b
h₂ : f b = none
a✝ c✝ : σ
h : c✝ ∈ f a✝
x✝ : ReflTransGen (fun a b => b ∈ f a) c✝ b
IH : b ∈ eval f c✝
⊢ Sum.inr c✝ ∈ Part.some (Option.elim (some c✝) (Sum.inl a✝) Sum.inr)
[PROOFSTEP]
apply Part.mem_some
[GOAL]
σ : Type u_1
f : σ → Option σ
a b : σ
h : b ∈ eval f a
c : σ
x✝ : Reaches₁ f b c
bc : Reaches₁ f b c := x✝
⊢ False
[PROOFSTEP]
let ⟨_, b0⟩ := mem_eval.1 h
[GOAL]
σ : Type u_1
f : σ → Option σ
a b : σ
h : b ∈ eval f a
c : σ
x✝ : Reaches₁ f b c
bc : Reaches₁ f b c := x✝
left✝ : Reaches f a b
b0 : f b = none
⊢ False
[PROOFSTEP]
let ⟨b', h', _⟩ := TransGen.head'_iff.1 bc
[GOAL]
σ : Type u_1
f : σ → Option σ
a b : σ
h : b ∈ eval f a
c : σ
x✝ : Reaches₁ f b c
bc : Reaches₁ f b c := x✝
left✝ : Reaches f a b
b0 : f b = none
b' : σ
h' : b' ∈ f b
right✝ : ReflTransGen (fun a b => b ∈ f a) b' c
⊢ False
[PROOFSTEP]
cases b0.symm.trans h'
[GOAL]
σ : Type u_1
f : σ → Option σ
a b : σ
h : b ∈ eval f a
c : σ
left✝ : Reaches f a b
b0 : f b = none
b' : σ
h' : b' ∈ f b
⊢ False
[PROOFSTEP]
cases b0.symm.trans h'
[GOAL]
σ : Type u_1
f : σ → Option σ
a b : σ
ab : Reaches f a b
⊢ eval f a = eval f b
[PROOFSTEP]
refine' Part.ext fun _ ↦ ⟨fun h ↦ _, fun h ↦ _⟩
[GOAL]
case refine'_1
σ : Type u_1
f : σ → Option σ
a b : σ
ab : Reaches f a b
x✝ : σ
h : x✝ ∈ eval f a
⊢ x✝ ∈ eval f b
[PROOFSTEP]
have ⟨ac, c0⟩ := mem_eval.1 h
[GOAL]
case refine'_1
σ : Type u_1
f : σ → Option σ
a b : σ
ab : Reaches f a b
x✝ : σ
h : x✝ ∈ eval f a
ac : Reaches f a x✝
c0 : f x✝ = none
⊢ x✝ ∈ eval f b
[PROOFSTEP]
exact mem_eval.2 ⟨(or_iff_left_of_imp fun cb ↦ (eval_maximal h).1 cb ▸ ReflTransGen.refl).1 (reaches_total ab ac), c0⟩
[GOAL]
case refine'_2
σ : Type u_1
f : σ → Option σ
a b : σ
ab : Reaches f a b
x✝ : σ
h : x✝ ∈ eval f b
⊢ x✝ ∈ eval f a
[PROOFSTEP]
have ⟨bc, c0⟩ := mem_eval.1 h
[GOAL]
case refine'_2
σ : Type u_1
f : σ → Option σ
a b : σ
ab : Reaches f a b
x✝ : σ
h : x✝ ∈ eval f b
bc : Reaches f b x✝
c0 : f x✝ = none
⊢ x✝ ∈ eval f a
[PROOFSTEP]
exact mem_eval.2 ⟨ab.trans bc, c0⟩
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ : σ₁
ab : Reaches₁ f₁ a₁ b₁
⊢ ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
induction' ab with c₁ ac c₁ d₁ _ cd IH
[GOAL]
case single
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ : σ₁
ac : c₁ ∈ f₁ a₁
⊢ ∃ b₂, tr c₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
have := H aa
[GOAL]
case single
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ : σ₁
ac : c₁ ∈ f₁ a₁
this :
  match f₁ a₁ with
  | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
  | none => f₂ a₂ = none
⊢ ∃ b₂, tr c₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
rwa [show f₁ a₁ = _ from ac] at this
[GOAL]
case tail
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ d₁ : σ₁
a✝ : TransGen (fun a b => b ∈ f₁ a) a₁ c₁
cd : d₁ ∈ f₁ c₁
IH : ∃ b₂, tr c₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
⊢ ∃ b₂, tr d₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
rcases IH with ⟨c₂, cc, ac₂⟩
[GOAL]
case tail.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ d₁ : σ₁
a✝ : TransGen (fun a b => b ∈ f₁ a) a₁ c₁
cd : d₁ ∈ f₁ c₁
c₂ : σ₂
cc : tr c₁ c₂
ac₂ : Reaches₁ f₂ a₂ c₂
⊢ ∃ b₂, tr d₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
have := H cc
[GOAL]
case tail.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ d₁ : σ₁
a✝ : TransGen (fun a b => b ∈ f₁ a) a₁ c₁
cd : d₁ ∈ f₁ c₁
c₂ : σ₂
cc : tr c₁ c₂
ac₂ : Reaches₁ f₂ a₂ c₂
this :
  match f₁ c₁ with
  | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ c₂ b₂
  | none => f₂ c₂ = none
⊢ ∃ b₂, tr d₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
rw [show f₁ c₁ = _ from cd] at this
[GOAL]
case tail.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ d₁ : σ₁
a✝ : TransGen (fun a b => b ∈ f₁ a) a₁ c₁
cd : d₁ ∈ f₁ c₁
c₂ : σ₂
cc : tr c₁ c₂
ac₂ : Reaches₁ f₂ a₂ c₂
this :
  match some d₁ with
  | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ c₂ b₂
  | none => f₂ c₂ = none
⊢ ∃ b₂, tr d₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
rcases this with ⟨d₂, dd, cd₂⟩
[GOAL]
case tail.intro.intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ c₁ d₁ : σ₁
a✝ : TransGen (fun a b => b ∈ f₁ a) a₁ c₁
cd : d₁ ∈ f₁ c₁
c₂ : σ₂
cc : tr c₁ c₂
ac₂ : Reaches₁ f₂ a₂ c₂
d₂ : σ₂
dd : tr d₁ d₂
cd₂ : Reaches₁ f₂ c₂ d₂
⊢ ∃ b₂, tr d₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
[PROOFSTEP]
exact ⟨_, dd, ac₂.trans cd₂⟩
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ : σ₁
ab : Reaches f₁ a₁ b₁
⊢ ∃ b₂, tr b₁ b₂ ∧ Reaches f₂ a₂ b₂
[PROOFSTEP]
rcases reflTransGen_iff_eq_or_transGen.1 ab with (rfl | ab)
[GOAL]
case inl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₂ : σ₂
b₁ : σ₁
aa : tr b₁ a₂
ab : Reaches f₁ b₁ b₁
⊢ ∃ b₂, tr b₁ b₂ ∧ Reaches f₂ a₂ b₂
[PROOFSTEP]
exact ⟨_, aa, ReflTransGen.refl⟩
[GOAL]
case inr
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ : σ₁
ab✝ : Reaches f₁ a₁ b₁
ab : TransGen (fun a b => b ∈ f₁ a) a₁ b₁
⊢ ∃ b₂, tr b₁ b₂ ∧ Reaches f₂ a₂ b₂
[PROOFSTEP]
have ⟨b₂, bb, h⟩ := tr_reaches₁ H aa ab
[GOAL]
case inr
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₁ : σ₁
ab✝ : Reaches f₁ a₁ b₁
ab : TransGen (fun a b => b ∈ f₁ a) a₁ b₁
b₂ : σ₂
bb : tr b₁ b₂
h : Reaches₁ f₂ a₂ b₂
⊢ ∃ b₂, tr b₁ b₂ ∧ Reaches f₂ a₂ b₂
[PROOFSTEP]
exact ⟨b₂, bb, h.to_reflTransGen⟩
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ : σ₂
ab : Reaches f₂ a₂ b₂
⊢ ∃ c₁ c₂, Reaches f₂ b₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
induction' ab with c₂ d₂ _ cd IH
[GOAL]
case refl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ : σ₂
⊢ ∃ c₁ c₂, Reaches f₂ a₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
exact ⟨_, _, ReflTransGen.refl, aa, ReflTransGen.refl⟩
[GOAL]
case tail
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
IH : ∃ c₁ c₂_1, Reaches f₂ c₂ c₂_1 ∧ tr c₁ c₂_1 ∧ Reaches f₁ a₁ c₁
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
rcases IH with ⟨e₁, e₂, ce, ee, ae⟩
[GOAL]
case tail.intro.intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
e₂ : σ₂
ce : Reaches f₂ c₂ e₂
ee : tr e₁ e₂
ae : Reaches f₁ a₁ e₁
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
rcases ReflTransGen.cases_head ce with (rfl | ⟨d', cd', de⟩)
[GOAL]
case tail.intro.intro.intro.intro.inl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
have := H ee
[GOAL]
case tail.intro.intro.intro.intro.inl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
this :
  match f₁ e₁ with
  | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ c₂ b₂
  | none => f₂ c₂ = none
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
revert this
[GOAL]
case tail.intro.intro.intro.intro.inl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
⊢ (match f₁ e₁ with
    | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ c₂ b₂
    | none => f₂ c₂ = none) →
    ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
cases' eg : f₁ e₁ with g₁
[GOAL]
case tail.intro.intro.intro.intro.inl.none
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
eg : f₁ e₁ = none
⊢ (match none with
    | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ c₂ b₂
    | none => f₂ c₂ = none) →
    ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
simp only [Respects, and_imp, exists_imp]
[GOAL]
case tail.intro.intro.intro.intro.inl.some
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
g₁ : σ₁
eg : f₁ e₁ = some g₁
⊢ (match some g₁ with
    | some b₁ => ∃ b₂, tr b₁ b₂ ∧ Reaches₁ f₂ c₂ b₂
    | none => f₂ c₂ = none) →
    ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
simp only [Respects, and_imp, exists_imp]
[GOAL]
case tail.intro.intro.intro.intro.inl.none
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
eg : f₁ e₁ = none
⊢ f₂ c₂ = none → ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
intro c0
[GOAL]
case tail.intro.intro.intro.intro.inl.none
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
eg : f₁ e₁ = none
c0 : f₂ c₂ = none
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
cases cd.symm.trans c0
[GOAL]
case tail.intro.intro.intro.intro.inl.some
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
g₁ : σ₁
eg : f₁ e₁ = some g₁
⊢ ∀ (x : σ₂), tr g₁ x → Reaches₁ f₂ c₂ x → ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
intro g₂ gg cg
[GOAL]
case tail.intro.intro.intro.intro.inl.some
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
g₁ : σ₁
eg : f₁ e₁ = some g₁
g₂ : σ₂
gg : tr g₁ g₂
cg : Reaches₁ f₂ c₂ g₂
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
rcases TransGen.head'_iff.1 cg with ⟨d', cd', dg⟩
[GOAL]
case tail.intro.intro.intro.intro.inl.some.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
g₁ : σ₁
eg : f₁ e₁ = some g₁
g₂ : σ₂
gg : tr g₁ g₂
cg : Reaches₁ f₂ c₂ g₂
d' : σ₂
cd' : d' ∈ f₂ c₂
dg : ReflTransGen (fun a b => b ∈ f₂ a) d' g₂
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
cases Option.mem_unique cd cd'
[GOAL]
case tail.intro.intro.intro.intro.inl.some.intro.intro.refl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
ae : Reaches f₁ a₁ e₁
ce : Reaches f₂ c₂ c₂
ee : tr e₁ c₂
g₁ : σ₁
eg : f₁ e₁ = some g₁
g₂ : σ₂
gg : tr g₁ g₂
cg : Reaches₁ f₂ c₂ g₂
cd' : d₂ ∈ f₂ c₂
dg : ReflTransGen (fun a b => b ∈ f₂ a) d₂ g₂
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
exact ⟨_, _, dg, gg, ae.tail eg⟩
[GOAL]
case tail.intro.intro.intro.intro.inr.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
e₂ : σ₂
ce : Reaches f₂ c₂ e₂
ee : tr e₁ e₂
ae : Reaches f₁ a₁ e₁
d' : σ₂
cd' : d' ∈ f₂ c₂
de : ReflTransGen (fun a b => b ∈ f₂ a) d' e₂
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
cases Option.mem_unique cd cd'
[GOAL]
case tail.intro.intro.intro.intro.inr.intro.intro.refl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
b₂ c₂ d₂ : σ₂
a✝ : ReflTransGen (fun a b => b ∈ f₂ a) a₂ c₂
cd : d₂ ∈ f₂ c₂
e₁ : σ₁
e₂ : σ₂
ce : Reaches f₂ c₂ e₂
ee : tr e₁ e₂
ae : Reaches f₁ a₁ e₁
cd' : d₂ ∈ f₂ c₂
de : ReflTransGen (fun a b => b ∈ f₂ a) d₂ e₂
⊢ ∃ c₁ c₂, Reaches f₂ d₂ c₂ ∧ tr c₁ c₂ ∧ Reaches f₁ a₁ c₁
[PROOFSTEP]
exact ⟨_, _, de, ee, ae⟩
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ b₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
ab : b₁ ∈ eval f₁ a₁
⊢ ∃ b₂, tr b₁ b₂ ∧ b₂ ∈ eval f₂ a₂
[PROOFSTEP]
cases' mem_eval.1 ab with ab b0
[GOAL]
case intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ b₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₁ ∈ eval f₁ a₁
ab : Reaches f₁ a₁ b₁
b0 : f₁ b₁ = none
⊢ ∃ b₂, tr b₁ b₂ ∧ b₂ ∈ eval f₂ a₂
[PROOFSTEP]
rcases tr_reaches H aa ab with ⟨b₂, bb, ab⟩
[GOAL]
case intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ b₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
ab✝¹ : b₁ ∈ eval f₁ a₁
ab✝ : Reaches f₁ a₁ b₁
b0 : f₁ b₁ = none
b₂ : σ₂
bb : tr b₁ b₂
ab : Reaches f₂ a₂ b₂
⊢ ∃ b₂, tr b₁ b₂ ∧ b₂ ∈ eval f₂ a₂
[PROOFSTEP]
refine' ⟨_, bb, mem_eval.2 ⟨ab, _⟩⟩
[GOAL]
case intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ b₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
ab✝¹ : b₁ ∈ eval f₁ a₁
ab✝ : Reaches f₁ a₁ b₁
b0 : f₁ b₁ = none
b₂ : σ₂
bb : tr b₁ b₂
ab : Reaches f₂ a₂ b₂
⊢ f₂ b₂ = none
[PROOFSTEP]
have := H bb
[GOAL]
case intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ b₁ : σ₁
a₂ : σ₂
aa : tr a₁ a₂
ab✝¹ : b₁ ∈ eval f₁ a₁
ab✝ : Reaches f₁ a₁ b₁
b0 : f₁ b₁ = none
b₂ : σ₂
bb : tr b₁ b₂
ab : Reaches f₂ a₂ b₂
this :
  match f₁ b₁ with
  | some b₁ => ∃ b₂_1, tr b₁ b₂_1 ∧ Reaches₁ f₂ b₂ b₂_1
  | none => f₂ b₂ = none
⊢ f₂ b₂ = none
[PROOFSTEP]
rwa [b0] at this
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab : b₂ ∈ eval f₂ a₂
⊢ ∃ b₁, tr b₁ b₂ ∧ b₁ ∈ eval f₁ a₁
[PROOFSTEP]
cases' mem_eval.1 ab with ab b0
[GOAL]
case intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
⊢ ∃ b₁, tr b₁ b₂ ∧ b₁ ∈ eval f₁ a₁
[PROOFSTEP]
rcases tr_reaches_rev H aa ab with ⟨c₁, c₂, bc, cc, ac⟩
[GOAL]
case intro.intro.intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
c₂ : σ₂
bc : Reaches f₂ b₂ c₂
cc : tr c₁ c₂
ac : Reaches f₁ a₁ c₁
⊢ ∃ b₁, tr b₁ b₂ ∧ b₁ ∈ eval f₁ a₁
[PROOFSTEP]
cases (reflTransGen_iff_eq (Option.eq_none_iff_forall_not_mem.1 b0)).1 bc
[GOAL]
case intro.intro.intro.intro.intro.refl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
⊢ ∃ b₁, tr b₁ b₂ ∧ b₁ ∈ eval f₁ a₁
[PROOFSTEP]
refine' ⟨_, cc, mem_eval.2 ⟨ac, _⟩⟩
[GOAL]
case intro.intro.intro.intro.intro.refl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
⊢ f₁ c₁ = none
[PROOFSTEP]
have := H cc
[GOAL]
case intro.intro.intro.intro.intro.refl
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
this :
  match f₁ c₁ with
  | some b₁ => ∃ b₂_1, tr b₁ b₂_1 ∧ Reaches₁ f₂ b₂ b₂_1
  | none => f₂ b₂ = none
⊢ f₁ c₁ = none
[PROOFSTEP]
cases' hfc : f₁ c₁ with d₁
[GOAL]
case intro.intro.intro.intro.intro.refl.none
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
this :
  match f₁ c₁ with
  | some b₁ => ∃ b₂_1, tr b₁ b₂_1 ∧ Reaches₁ f₂ b₂ b₂_1
  | none => f₂ b₂ = none
hfc : f₁ c₁ = none
⊢ none = none
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.intro.intro.intro.refl.some
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
this :
  match f₁ c₁ with
  | some b₁ => ∃ b₂_1, tr b₁ b₂_1 ∧ Reaches₁ f₂ b₂ b₂_1
  | none => f₂ b₂ = none
d₁ : σ₁
hfc : f₁ c₁ = some d₁
⊢ some d₁ = none
[PROOFSTEP]
rw [hfc] at this
[GOAL]
case intro.intro.intro.intro.intro.refl.some
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
d₁ : σ₁
this :
  match some d₁ with
  | some b₁ => ∃ b₂_1, tr b₁ b₂_1 ∧ Reaches₁ f₂ b₂ b₂_1
  | none => f₂ b₂ = none
hfc : f₁ c₁ = some d₁
⊢ some d₁ = none
[PROOFSTEP]
rcases this with ⟨d₂, _, bd⟩
[GOAL]
case intro.intro.intro.intro.intro.refl.some.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
d₁ : σ₁
hfc : f₁ c₁ = some d₁
d₂ : σ₂
left✝ : tr d₁ d₂
bd : Reaches₁ f₂ b₂ d₂
⊢ some d₁ = none
[PROOFSTEP]
rcases TransGen.head'_iff.1 bd with ⟨e, h, _⟩
[GOAL]
case intro.intro.intro.intro.intro.refl.some.intro.intro.intro.intro
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂ → Prop
H : Respects f₁ f₂ tr
a₁ : σ₁
b₂ a₂ : σ₂
aa : tr a₁ a₂
ab✝ : b₂ ∈ eval f₂ a₂
ab : Reaches f₂ a₂ b₂
b0 : f₂ b₂ = none
c₁ : σ₁
ac : Reaches f₁ a₁ c₁
bc : Reaches f₂ b₂ b₂
cc : tr c₁ b₂
d₁ : σ₁
hfc : f₁ c₁ = some d₁
d₂ : σ₂
left✝ : tr d₁ d₂
bd : Reaches₁ f₂ b₂ d₂
e : σ₂
h : e ∈ f₂ b₂
right✝ : ReflTransGen (fun a b => b ∈ f₂ a) e d₂
⊢ some d₁ = none
[PROOFSTEP]
cases b0.symm.trans h
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
a₂ b₂ : σ₂
h : f₂ a₂ = f₂ b₂
⊢ FRespects f₂ tr a₂ none ↔ FRespects f₂ tr b₂ none
[PROOFSTEP]
unfold FRespects
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
a₂ b₂ : σ₂
h : f₂ a₂ = f₂ b₂
⊢ (match none with
    | some b₁ => Reaches₁ f₂ a₂ (tr b₁)
    | none => f₂ a₂ = none) ↔
    match none with
    | some b₁ => Reaches₁ f₂ b₂ (tr b₁)
    | none => f₂ b₂ = none
[PROOFSTEP]
rw [h]
[GOAL]
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
a₁ : σ₁
⊢ (∀ ⦃a₂ : σ₂⦄,
      (fun a b => tr a = b) a₁ a₂ →
        match f₁ a₁ with
        | some b₁ => ∃ b₂, (fun a b => tr a = b) b₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
        | none => f₂ a₂ = none) ↔
    FRespects f₂ tr (tr a₁) (f₁ a₁)
[PROOFSTEP]
cases f₁ a₁
[GOAL]
case none
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
a₁ : σ₁
⊢ (∀ ⦃a₂ : σ₂⦄,
      (fun a b => tr a = b) a₁ a₂ →
        match none with
        | some b₁ => ∃ b₂, (fun a b => tr a = b) b₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
        | none => f₂ a₂ = none) ↔
    FRespects f₂ tr (tr a₁) none
[PROOFSTEP]
simp only [FRespects, Respects, exists_eq_left', forall_eq']
[GOAL]
case some
σ₁ : Type u_1
σ₂ : Type u_2
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
a₁ val✝ : σ₁
⊢ (∀ ⦃a₂ : σ₂⦄,
      (fun a b => tr a = b) a₁ a₂ →
        match some val✝ with
        | some b₁ => ∃ b₂, (fun a b => tr a = b) b₁ b₂ ∧ Reaches₁ f₂ a₂ b₂
        | none => f₂ a₂ = none) ↔
    FRespects f₂ tr (tr a₁) (some val✝)
[PROOFSTEP]
simp only [FRespects, Respects, exists_eq_left', forall_eq']
[GOAL]
σ₁ σ₂ : Type u_1
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
H : Respects f₁ f₂ fun a b => tr a = b
a₁ : σ₁
b₂ : σ₂
h : b₂ ∈ tr <$> eval f₁ a₁
⊢ b₂ ∈ eval f₂ (tr a₁)
[PROOFSTEP]
rcases(Part.mem_map_iff _).1 h with ⟨b₁, ab, bb⟩
[GOAL]
case intro.intro
σ₁ σ₂ : Type u_1
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
H : Respects f₁ f₂ fun a b => tr a = b
a₁ : σ₁
b₂ : σ₂
h : b₂ ∈ tr <$> eval f₁ a₁
b₁ : σ₁
ab : b₁ ∈ eval f₁ a₁
bb : tr b₁ = b₂
⊢ b₂ ∈ eval f₂ (tr a₁)
[PROOFSTEP]
rcases tr_eval H rfl ab with ⟨_, rfl, h⟩
[GOAL]
case intro.intro.intro.intro
σ₁ σ₂ : Type u_1
f₁ : σ₁ → Option σ₁
f₂ : σ₂ → Option σ₂
tr : σ₁ → σ₂
H : Respects f₁ f₂ fun a b => tr a = b
a₁ : σ₁
b₂ : σ₂
h✝ : b₂ ∈ tr <$> eval f₁ a₁
b₁ : σ₁
ab : b₁ ∈ eval f₁ a₁
bb : tr b₁ = b₂
h : tr b₁ ∈ eval f₂ (tr a₁)
⊢ b₂ ∈ eval f₂ (tr a₁)
[PROOFSTEP]
rwa [bb] at h
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
⊢ Inhabited Machine₀
[PROOFSTEP]
unfold Machine
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
⊢ Inhabited (Λ → Γ → Option (Λ × Stmt₀))
[PROOFSTEP]
infer_instance
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
S : Set Λ
ss : Supports M S
⊢ ∀ {c c' : Cfg₀}, c' ∈ step M c → c.q ∈ S → c'.q ∈ S
[PROOFSTEP]
intro ⟨q, T⟩ c' h₁ h₂
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
S : Set Λ
ss : Supports M S
q : Λ
T : Tape Γ
c' : Cfg₀
h₁ : c' ∈ step M { q := q, Tape := T }
h₂ : { q := q, Tape := T }.q ∈ S
⊢ c'.q ∈ S
[PROOFSTEP]
rcases Option.map_eq_some'.1 h₁ with ⟨⟨q', a⟩, h, rfl⟩
[GOAL]
case intro.mk.intro
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
S : Set Λ
ss : Supports M S
q : Λ
T : Tape Γ
h₂ : { q := q, Tape := T }.q ∈ S
q' : Λ
a : Stmt₀
h : M q T.head = some (q', a)
h₁ :
  (fun x =>
        match x with
        | (q', a) =>
          { q := q',
            Tape :=
              match a with
              | Stmt.move d => Tape.move d T
              | Stmt.write a => Tape.write a T })
      (q', a) ∈
    step M { q := q, Tape := T }
⊢ ((fun x =>
          match x with
          | (q', a) =>
            { q := q',
              Tape :=
                match a with
                | Stmt.move d => Tape.move d T
                | Stmt.write a => Tape.write a T })
        (q', a)).q ∈
    S
[PROOFSTEP]
exact ss.2 h h₂
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
⊢ Supports M Set.univ
[PROOFSTEP]
constructor
[GOAL]
case left
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
⊢ default ∈ Set.univ
[PROOFSTEP]
intros
[GOAL]
case right
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
⊢ ∀ {q : Λ} {a : Γ} {q' : Λ} {s : Stmt₀}, (q', s) ∈ M q a → q ∈ Set.univ → q' ∈ Set.univ
[PROOFSTEP]
intros
[GOAL]
case left
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
⊢ default ∈ Set.univ
[PROOFSTEP]
apply Set.mem_univ
[GOAL]
case right
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : Machine₀
q✝ : Λ
a✝² : Γ
q'✝ : Λ
s✝ : Stmt₀
a✝¹ : (q'✝, s✝) ∈ M q✝ a✝²
a✝ : q✝ ∈ Set.univ
⊢ q'✝ ∈ Set.univ
[PROOFSTEP]
apply Set.mem_univ
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
⊢ Option.map (Cfg.map f₁ g₁) (step M { q := q, Tape := T }) =
    step (map M f₁ f₂ g₁ g₂) (Cfg.map f₁ g₁ { q := q, Tape := T })
[PROOFSTEP]
unfold step Machine.map Cfg.map
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
⊢ Option.map
      (fun x =>
        match x with
        | { q := q, Tape := T } => { q := g₁ q, Tape := Tape.map f₁ T })
      (match { q := q, Tape := T } with
      | { q := q, Tape := T } =>
        Option.map
          (fun x =>
            match x with
            | (q', a) =>
              { q := q',
                Tape :=
                  match a with
                  | Stmt.move d => Tape.move d T
                  | Stmt.write a => Tape.write a T })
          (M q T.head)) =
    match
      match { q := q, Tape := T } with
      | { q := q, Tape := T } => { q := g₁ q, Tape := Tape.map f₁ T } with
    | { q := q, Tape := T } =>
      Option.map
        (fun x =>
          match x with
          | (q', a) =>
            { q := q',
              Tape :=
                match a with
                | Stmt.move d => Tape.move d T
                | Stmt.write a => Tape.write a T })
        (match q, T.head with
        | q, l => Option.map (Prod.map g₁ (Stmt.map f₁)) (M (g₂ q) (PointedMap.f f₂ l)))
[PROOFSTEP]
simp only [Turing.Tape.map_fst, g₂₁ q h, f₂₁ _]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
⊢ Option.map (fun x => { q := g₁ x.q, Tape := Tape.map f₁ x.Tape })
      (Option.map
        (fun x =>
          { q := x.fst,
            Tape :=
              match x.snd with
              | Stmt.move d => Tape.move d T
              | Stmt.write a => Tape.write a T })
        (M q T.head)) =
    Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | Stmt.move d => Tape.move d (Tape.map f₁ T)
            | Stmt.write a => Tape.write a (Tape.map f₁ T) })
      (Option.map (Prod.map g₁ (Stmt.map f₁)) (M q T.head))
[PROOFSTEP]
rcases M q T.1 with (_ | ⟨q', d | a⟩)
[GOAL]
case none
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
⊢ Option.map (fun x => { q := g₁ x.q, Tape := Tape.map f₁ x.Tape })
      (Option.map
        (fun x =>
          { q := x.fst,
            Tape :=
              match x.snd with
              | Stmt.move d => Tape.move d T
              | Stmt.write a => Tape.write a T })
        none) =
    Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | Stmt.move d => Tape.move d (Tape.map f₁ T)
            | Stmt.write a => Tape.write a (Tape.map f₁ T) })
      (Option.map (Prod.map g₁ (Stmt.map f₁)) none)
[PROOFSTEP]
rfl
[GOAL]
case some.mk.move
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
q' : Λ
d : Dir
⊢ Option.map (fun x => { q := g₁ x.q, Tape := Tape.map f₁ x.Tape })
      (Option.map
        (fun x =>
          { q := x.fst,
            Tape :=
              match x.snd with
              | Stmt.move d => Tape.move d T
              | Stmt.write a => Tape.write a T })
        (some (q', Stmt.move d))) =
    Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | Stmt.move d => Tape.move d (Tape.map f₁ T)
            | Stmt.write a => Tape.write a (Tape.map f₁ T) })
      (Option.map (Prod.map g₁ (Stmt.map f₁)) (some (q', Stmt.move d)))
[PROOFSTEP]
simp only [step, Cfg.map, Option.map_some', Tape.map_move f₁]
[GOAL]
case some.mk.move
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
q' : Λ
d : Dir
⊢ some { q := g₁ q', Tape := Tape.move d (Tape.map f₁ T) } =
    some
      { q := (Prod.map g₁ (Stmt.map f₁) (q', Stmt.move d)).fst,
        Tape :=
          match (Prod.map g₁ (Stmt.map f₁) (q', Stmt.move d)).snd with
          | Stmt.move d => Tape.move d (Tape.map f₁ T)
          | Stmt.write a => Tape.write a (Tape.map f₁ T) }
[PROOFSTEP]
rfl
[GOAL]
case some.mk.write
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
q' : Λ
a : Γ
⊢ Option.map (fun x => { q := g₁ x.q, Tape := Tape.map f₁ x.Tape })
      (Option.map
        (fun x =>
          { q := x.fst,
            Tape :=
              match x.snd with
              | Stmt.move d => Tape.move d T
              | Stmt.write a => Tape.write a T })
        (some (q', Stmt.write a))) =
    Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | Stmt.move d => Tape.move d (Tape.map f₁ T)
            | Stmt.write a => Tape.write a (Tape.map f₁ T) })
      (Option.map (Prod.map g₁ (Stmt.map f₁)) (some (q', Stmt.write a)))
[PROOFSTEP]
simp only [step, Cfg.map, Option.map_some', Tape.map_write]
[GOAL]
case some.mk.write
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁ : Λ → Λ'
g₂ : Λ' → Λ
S : Set Λ
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (g₁ q) = q
q : Λ
T : Tape Γ
h : { q := q, Tape := T }.q ∈ S
q' : Λ
a : Γ
⊢ some { q := g₁ q', Tape := Tape.write (PointedMap.f f₁ a) (Tape.map f₁ T) } =
    some
      { q := (Prod.map g₁ (Stmt.map f₁) (q', Stmt.write a)).fst,
        Tape :=
          match (Prod.map g₁ (Stmt.map f₁) (q', Stmt.write a)).snd with
          | Stmt.move d => Tape.move d (Tape.map f₁ T)
          | Stmt.write a => Tape.write a (Tape.map f₁ T) }
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
⊢ Respects (step M) (step (map M f₁ f₂ g₁.f g₂)) fun a b => a.q ∈ S ∧ Cfg.map f₁ g₁.f a = b
[PROOFSTEP]
intro c _ ⟨cs, rfl⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
c : Cfg Γ Λ
a₂✝ : Cfg Γ' Λ'
cs : c.q ∈ S
⊢ match step M c with
  | some b₁ =>
    ∃ b₂,
      (fun a b => a.q ∈ S ∧ Cfg.map f₁ g₁.f a = b) b₁ b₂ ∧ Reaches₁ (step (map M f₁ f₂ g₁.f g₂)) (Cfg.map f₁ g₁.f c) b₂
  | none => step (map M f₁ f₂ g₁.f g₂) (Cfg.map f₁ g₁.f c) = none
[PROOFSTEP]
cases e : step M c
[GOAL]
case none
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
c : Cfg Γ Λ
a₂✝ : Cfg Γ' Λ'
cs : c.q ∈ S
e : step M c = none
⊢ match none with
  | some b₁ =>
    ∃ b₂,
      (fun a b => a.q ∈ S ∧ Cfg.map f₁ g₁.f a = b) b₁ b₂ ∧ Reaches₁ (step (map M f₁ f₂ g₁.f g₂)) (Cfg.map f₁ g₁.f c) b₂
  | none => step (map M f₁ f₂ g₁.f g₂) (Cfg.map f₁ g₁.f c) = none
[PROOFSTEP]
rw [← M.map_step f₁ f₂ g₁ g₂ f₂₁ g₂₁ _ cs, e]
[GOAL]
case none
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
c : Cfg Γ Λ
a₂✝ : Cfg Γ' Λ'
cs : c.q ∈ S
e : step M c = none
⊢ match none with
  | some b₁ =>
    ∃ b₂,
      (fun a b => a.q ∈ S ∧ Cfg.map f₁ g₁.f a = b) b₁ b₂ ∧ Reaches₁ (step (map M f₁ f₂ g₁.f g₂)) (Cfg.map f₁ g₁.f c) b₂
  | none => Option.map (Cfg.map f₁ g₁.f) none = none
[PROOFSTEP]
rfl
[GOAL]
case some
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
c : Cfg Γ Λ
a₂✝ : Cfg Γ' Λ'
cs : c.q ∈ S
val✝ : Cfg Γ Λ
e : step M c = some val✝
⊢ match some val✝ with
  | some b₁ =>
    ∃ b₂,
      (fun a b => a.q ∈ S ∧ Cfg.map f₁ g₁.f a = b) b₁ b₂ ∧ Reaches₁ (step (map M f₁ f₂ g₁.f g₂)) (Cfg.map f₁ g₁.f c) b₂
  | none => step (map M f₁ f₂ g₁.f g₂) (Cfg.map f₁ g₁.f c) = none
[PROOFSTEP]
refine' ⟨_, ⟨step_supports M ss e cs, rfl⟩, TransGen.single _⟩
[GOAL]
case some
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
c : Cfg Γ Λ
a₂✝ : Cfg Γ' Λ'
cs : c.q ∈ S
val✝ : Cfg Γ Λ
e : step M c = some val✝
⊢ Cfg.map f₁ g₁.f val✝ ∈ step (map M f₁ f₂ g₁.f g₂) (Cfg.map f₁ g₁.f c)
[PROOFSTEP]
rw [← M.map_step f₁ f₂ g₁ g₂ f₂₁ g₂₁ _ cs, e]
[GOAL]
case some
Γ : Type u_1
inst✝³ : Inhabited Γ
Γ' : Type u_2
inst✝² : Inhabited Γ'
Λ : Type u_3
inst✝¹ : Inhabited Λ
Λ' : Type u_4
inst✝ : Inhabited Λ'
M : Machine Γ Λ
f₁ : PointedMap Γ Γ'
f₂ : PointedMap Γ' Γ
g₁✝ : Λ → Λ'
g₂✝ : Λ' → Λ
g₁ : PointedMap Λ Λ'
g₂ : Λ' → Λ
S : Set Λ
ss : Supports M S
f₂₁ : Function.RightInverse f₁.f f₂.f
g₂₁ : ∀ (q : Λ), q ∈ S → g₂ (PointedMap.f g₁ q) = q
c : Cfg Γ Λ
a₂✝ : Cfg Γ' Λ'
cs : c.q ∈ S
val✝ : Cfg Γ Λ
e : step M c = some val✝
⊢ Cfg.map f₁ g₁.f val✝ ∈ Option.map (Cfg.map f₁ g₁.f) (some val✝)
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q : Stmt₁
⊢ q ∈ stmts₁ q
[PROOFSTEP]
cases q
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
a✝¹ : Dir
a✝ : Stmt₁
⊢ move a✝¹ a✝ ∈ stmts₁ (move a✝¹ a✝)
[PROOFSTEP]
simp only [stmts₁, Finset.mem_insert_self, Finset.mem_singleton_self]
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
a✝¹ : Γ → σ → Γ
a✝ : Stmt₁
⊢ write a✝¹ a✝ ∈ stmts₁ (write a✝¹ a✝)
[PROOFSTEP]
simp only [stmts₁, Finset.mem_insert_self, Finset.mem_singleton_self]
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
⊢ load a✝¹ a✝ ∈ stmts₁ (load a✝¹ a✝)
[PROOFSTEP]
simp only [stmts₁, Finset.mem_insert_self, Finset.mem_singleton_self]
[GOAL]
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
⊢ branch a✝² a✝¹ a✝ ∈ stmts₁ (branch a✝² a✝¹ a✝)
[PROOFSTEP]
simp only [stmts₁, Finset.mem_insert_self, Finset.mem_singleton_self]
[GOAL]
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
a✝ : Γ → σ → Λ
⊢ goto a✝ ∈ stmts₁ (goto a✝)
[PROOFSTEP]
simp only [stmts₁, Finset.mem_insert_self, Finset.mem_singleton_self]
[GOAL]
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
⊢ halt ∈ stmts₁ halt
[PROOFSTEP]
simp only [stmts₁, Finset.mem_insert_self, Finset.mem_singleton_self]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
⊢ q₁ ∈ stmts₁ q₂ → stmts₁ q₁ ⊆ stmts₁ q₂
[PROOFSTEP]
intro h₁₂ q₀ h₀₁
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
⊢ q₀ ∈ stmts₁ q₂
[PROOFSTEP]
induction' q₂ with _ q IH _ q IH _ q IH
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (move a✝ q)
⊢ q₀ ∈ stmts₁ (move a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (write a✝ q)
⊢ q₀ ∈ stmts₁ (write a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (load a✝ q)
⊢ q₀ ∈ stmts₁ (load a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ ∈ stmts₁ (branch a✝² a✝¹ a✝)
⊢ q₀ ∈ stmts₁ (branch a✝² a✝¹ a✝)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ ∈ stmts₁ (goto a✝)
⊢ q₀ ∈ stmts₁ (goto a✝)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ ∈ stmts₁ halt
⊢ q₀ ∈ stmts₁ halt
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (move a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (move a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h₁₂
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (write a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h₁₂
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (load a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h₁₂
[GOAL]
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h₁₂
[GOAL]
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ ∈ {goto a✝}
⊢ q₀ ∈ {goto a✝}
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h₁₂
[GOAL]
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ ∈ {halt}
⊢ q₀ ∈ {halt}
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h₁₂
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = move a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (move a✝ q) (stmts₁ q)
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
iterate 3
  rcases h₁₂ with (rfl | h₁₂)
  · unfold stmts₁ at h₀₁
    exact h₀₁
  · exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = move a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (move a✝ q) (stmts₁ q)
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case move.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
a✝ : Dir
q : Stmt₁
h₁₂ : move a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (move a✝ q)
IH : move a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (move a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case move.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
a✝ : Dir
q : Stmt₁
h₁₂ : move a✝ q ∈ stmts₁ q₂
IH : move a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (move a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (move a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case move.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (move a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case write.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
a✝ : Γ → σ → Γ
q : Stmt₁
h₁₂ : write a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (write a✝ q)
IH : write a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case write.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
a✝ : Γ → σ → Γ
q : Stmt₁
h₁₂ : write a✝ q ∈ stmts₁ q₂
IH : write a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (write a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case write.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (write a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case load.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
a✝ : Γ → σ → σ
q : Stmt₁
h₁₂ : load a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (load a✝ q)
IH : load a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case load.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
a✝ : Γ → σ → σ
q : Stmt₁
h₁₂ : load a✝ q ∈ stmts₁ q₂
IH : load a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (load a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case load.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  rcases h₁₂ with (rfl | h₁₂ | h₁₂)
  · unfold stmts₁ at h₀₁
    exact h₀₁
  · exact Finset.mem_insert_of_mem (Finset.mem_union_left _ <| IH₁ h₁₂)
  · exact Finset.mem_insert_of_mem (Finset.mem_union_right _ <| IH₂ h₁₂)
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁✝ q₂✝ : Stmt₁
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ = branch p q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  rcases h₁₂ with (rfl | h₁₂ | h₁₂)
  · unfold stmts₁ at h₀₁
    exact h₀₁
  · exact Finset.mem_insert_of_mem (Finset.mem_union_left _ <| IH₁ h₁₂)
  · exact Finset.mem_insert_of_mem (Finset.mem_union_right _ <| IH₂ h₁₂)
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁✝ q₂✝ : Stmt₁
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ = branch p q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂ | h₁₂)
[GOAL]
case inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂✝ q₀ : Stmt₁
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
h₁₂ : branch p q₁ q₂ ∈ stmts₁ q₂✝
h₀₁ : q₀ ∈ stmts₁ (branch p q₁ q₂)
IH₁ : branch p q₁ q₂ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : branch p q₁ q₂ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂✝ q₀ : Stmt₁
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
h₁₂ : branch p q₁ q₂ ∈ stmts₁ q₂✝
IH₁ : branch p q₁ q₂ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : branch p q₁ q₂ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₀₁ : q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
⊢ q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
exact h₀₁
[GOAL]
case inr.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁✝ q₂✝ : Stmt₁
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ ∈ stmts₁ q₁
⊢ q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (Finset.mem_union_left _ <| IH₁ h₁₂)
[GOAL]
case inr.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁✝ q₂✝ : Stmt₁
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch p q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (Finset.mem_union_right _ <| IH₂ h₁₂)
[GOAL]
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : Γ → σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case goto l => subst h₁₂; exact h₀₁
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
l : Γ → σ → Λ
h₁₂ : q₁ = goto l
⊢ q₀ ∈ {goto l}
[PROOFSTEP]
case goto l => subst h₁₂; exact h₀₁
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
l : Γ → σ → Λ
h₁₂ : q₁ = goto l
⊢ q₀ ∈ {goto l}
[PROOFSTEP]
subst h₁₂
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
l : Γ → σ → Λ
h₁₂ : goto l ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (goto l)
⊢ q₀ ∈ {goto l}
[PROOFSTEP]
exact h₀₁
[GOAL]
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case halt => subst h₁₂; exact h₀₁
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case halt => subst h₁₂; exact h₀₁
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₁ q₂ : Stmt₁
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₁
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
subst h₁₂
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
q₂ q₀ : Stmt₁
h₁₂ : halt ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
exact h₀₁
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h : q₁ ∈ stmts₁ q₂
hs : SupportsStmt S q₂
⊢ SupportsStmt S q₁
[PROOFSTEP]
induction' q₂ with _ q IH _ q IH _ q IH
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (move a✝ q)
hs : SupportsStmt S (move a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (write a✝ q)
hs : SupportsStmt S (write a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (load a✝ q)
hs : SupportsStmt S (load a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (branch a✝² a✝¹ a✝)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
h : q₁ ∈ stmts₁ (goto a✝)
hs : SupportsStmt S (goto a✝)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
h : q₁ ∈ stmts₁ halt
hs : SupportsStmt S halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = move a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), a✝ a v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
iterate 3 rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = move a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), a✝ a v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case move
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = move a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case move.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₂ : Stmt₁
hs✝ : SupportsStmt S q₂
a✝ : Dir
q : Stmt₁
hs : SupportsStmt S q
h : move a✝ q ∈ stmts₁ q₂
IH : move a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (move a✝ q)
⊢ SupportsStmt S (move a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case move.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Dir
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), a✝ a v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case write
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = write a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case write.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₂ : Stmt₁
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
hs : SupportsStmt S q
h : write a✝ q ∈ stmts₁ q₂
IH : write a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (write a✝ q)
⊢ SupportsStmt S (write a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case write.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Γ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), a✝ a v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case load
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case load.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₂ : Stmt₁
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
hs : SupportsStmt S q
h : load a✝ q ∈ stmts₁ q₂
IH : load a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (load a✝ q)
⊢ SupportsStmt S (load a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case load.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → σ
q : Stmt₁
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case branch
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), a✝ a v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ => rcases h with (rfl | h | h); exacts [hs, IH₁ h hs.1, IH₂ h hs.2]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁✝ q₂✝ : Stmt₁
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ = branch p q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ SupportsStmt S q₁✝
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ => rcases h with (rfl | h | h); exacts [hs, IH₁ h hs.1, IH₂ h hs.2]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁✝ q₂✝ : Stmt₁
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ = branch p q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ SupportsStmt S q₁✝
[PROOFSTEP]
rcases h with (rfl | h | h)
[GOAL]
case inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₂✝ : Stmt₁
hs✝ : SupportsStmt S q₂✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : branch p q₁ q₂ ∈ stmts₁ q₂✝
IH₁ : branch p q₁ q₂ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S (branch p q₁ q₂)
IH₂ : branch p q₁ q₂ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S (branch p q₁ q₂)
⊢ SupportsStmt S (branch p q₁ q₂)
case inr.inl
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁✝ q₂✝ : Stmt₁
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ ∈ stmts₁ q₁
⊢ SupportsStmt S q₁✝
case inr.inr
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁✝ q₂✝ : Stmt₁
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ ∈ stmts₁ q₂
⊢ SupportsStmt S q₁✝
[PROOFSTEP]
exacts [hs, IH₁ h hs.1, IH₂ h hs.2]
[GOAL]
case goto
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), a✝ a v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case goto l => subst h; exact hs
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
l : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), l a v ∈ S
h : q₁ = goto l
⊢ SupportsStmt S q₁
[PROOFSTEP]
case goto l => subst h; exact hs
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
l : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), l a v ∈ S
h : q₁ = goto l
⊢ SupportsStmt S q₁
[PROOFSTEP]
subst h
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₂ : Stmt₁
hs✝ : SupportsStmt S q₂
l : Γ → σ → Λ
hs : ∀ (a : Γ) (v : σ), l a v ∈ S
h : goto l ∈ stmts₁ q₂
⊢ SupportsStmt S (goto l)
[PROOFSTEP]
exact hs
[GOAL]
case halt
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case halt => subst h; trivial
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case halt => subst h; trivial
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₁ q₂ : Stmt₁
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
subst h
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
S : Finset Λ
q₂ : Stmt₁
hs✝ : SupportsStmt S q₂
hs : True
h : halt ∈ stmts₁ q₂
⊢ SupportsStmt S halt
[PROOFSTEP]
trivial
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
M : Λ → Stmt₁
S : Finset Λ
q₁ q₂ : Stmt₁
h₁ : q₁ ∈ stmts₁ q₂
⊢ some q₂ ∈ stmts M S → some q₁ ∈ stmts M S
[PROOFSTEP]
simp only [stmts, Finset.mem_insertNone, Finset.mem_biUnion, Option.mem_def, Option.some.injEq, forall_eq', exists_imp,
  and_imp]
[GOAL]
Γ : Type u_1
inst✝ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
M : Λ → Stmt₁
S : Finset Λ
q₁ q₂ : Stmt₁
h₁ : q₁ ∈ stmts₁ q₂
⊢ ∀ (x : Λ), x ∈ S → q₂ ∈ stmts₁ (M x) → ∃ a, a ∈ S ∧ q₁ ∈ stmts₁ (M a)
[PROOFSTEP]
exact fun l ls h₂ ↦ ⟨_, ls, stmts₁_trans h₂ h₁⟩
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
q : Stmt₁
ss : Supports M S
⊢ some q ∈ stmts M S → SupportsStmt S q
[PROOFSTEP]
simp only [stmts, Finset.mem_insertNone, Finset.mem_biUnion, Option.mem_def, Option.some.injEq, forall_eq', exists_imp,
  and_imp]
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
q : Stmt₁
ss : Supports M S
⊢ ∀ (x : Λ), x ∈ S → q ∈ stmts₁ (M x) → SupportsStmt S q
[PROOFSTEP]
exact fun l ls h ↦ stmts₁_supportsStmt_mono h (ss.2 _ ls)
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : Tape Γ
c' : Cfg₁
h₁ : c' ∈ step M { l := some l₁, var := v, Tape := T }
h₂ : { l := some l₁, var := v, Tape := T }.l ∈ ↑Finset.insertNone S
⊢ c'.l ∈ ↑Finset.insertNone S
[PROOFSTEP]
replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : Tape Γ
c' : Cfg₁
h₁ : c' ∈ step M { l := some l₁, var := v, Tape := T }
h₂ : SupportsStmt S (M l₁)
⊢ c'.l ∈ ↑Finset.insertNone S
[PROOFSTEP]
simp only [step, Option.mem_def, Option.some.injEq] at h₁
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : Tape Γ
c' : Cfg₁
h₂ : SupportsStmt S (M l₁)
h₁ : stepAux (M l₁) v T = c'
⊢ c'.l ∈ ↑Finset.insertNone S
[PROOFSTEP]
subst c'
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : Tape Γ
h₂ : SupportsStmt S (M l₁)
⊢ (stepAux (M l₁) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
revert h₂
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : Tape Γ
⊢ SupportsStmt S (M l₁) → (stepAux (M l₁) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
induction' M l₁ with _ q IH _ q IH _ q IH generalizing v T
[GOAL]
case move
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Dir
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
⊢ SupportsStmt S (move a✝ q) → (stepAux (move a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case write
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Γ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
⊢ SupportsStmt S (write a✝ q) → (stepAux (write a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case load
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → σ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
⊢ SupportsStmt S (load a✝ q) → (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case branch
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
⊢ SupportsStmt S (branch a✝² a✝¹ a✝) → (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ SupportsStmt S (goto a✝) → (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
⊢ SupportsStmt S halt → (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case move
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Dir
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (move a✝ q)
⊢ (stepAux (move a✝ q) v T).l ∈ ↑Finset.insertNone S
case write
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Γ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (write a✝ q)
⊢ (stepAux (write a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → σ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
iterate 3 exact IH _ _ hs
[GOAL]
case move
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Dir
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (move a✝ q)
⊢ (stepAux (move a✝ q) v T).l ∈ ↑Finset.insertNone S
case write
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Γ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (write a✝ q)
⊢ (stepAux (write a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → σ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case write
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Γ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (write a✝ q)
⊢ (stepAux (write a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → σ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case load
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → σ
q : Stmt₁
IH : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case branch
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case branch p q₁' q₂' IH₁ IH₂ =>
  unfold stepAux; cases p T.1 v
  · exact IH₂ _ _ hs.2
  · exact IH₁ _ _ hs.1
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
p : Γ → σ → Bool
q₁' q₂' : Stmt₁
IH₁ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (stepAux (branch p q₁' q₂') v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case branch p q₁' q₂' IH₁ IH₂ =>
  unfold stepAux; cases p T.1 v
  · exact IH₂ _ _ hs.2
  · exact IH₁ _ _ hs.1
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
p : Γ → σ → Bool
q₁' q₂' : Stmt₁
IH₁ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (stepAux (branch p q₁' q₂') v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
unfold stepAux
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
p : Γ → σ → Bool
q₁' q₂' : Stmt₁
IH₁ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (bif p T.head v then stepAux q₁' v T else stepAux q₂' v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
cases p T.1 v
[GOAL]
case false
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
p : Γ → σ → Bool
q₁' q₂' : Stmt₁
IH₁ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (bif false then stepAux q₁' v T else stepAux q₂' v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH₂ _ _ hs.2
[GOAL]
case true
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
p : Γ → σ → Bool
q₁' q₂' : Stmt₁
IH₁ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : Tape Γ), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : Tape Γ
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (bif true then stepAux q₁' v T else stepAux q₂' v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH₁ _ _ hs.1
[GOAL]
case goto
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case goto => exact Finset.some_mem_insertNone.2 (hs _ _)
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case goto => exact Finset.some_mem_insertNone.2 (hs _ _)
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact Finset.some_mem_insertNone.2 (hs _ _)
[GOAL]
case halt
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case halt => apply Multiset.mem_cons_self
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case halt => apply Multiset.mem_cons_self
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
σ : Type u_3
inst✝ : Inhabited Λ
M : Λ → Stmt₁
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : Tape Γ
v : σ
T : Tape Γ
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
apply Multiset.mem_cons_self
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
l₁ : Option Λ
v : σ
T : Tape Γ
⊢ FRespects (TM0.step (tr M)) (fun c₁ => trCfg M c₁) (trCfg M { l := l₁, var := v, Tape := T })
    (TM1.step M { l := l₁, var := v, Tape := T })
[PROOFSTEP]
cases' l₁ with l₁
[GOAL]
case none
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v : σ
T : Tape Γ
⊢ FRespects (TM0.step (tr M)) (fun c₁ => trCfg M c₁) (trCfg M { l := none, var := v, Tape := T })
    (TM1.step M { l := none, var := v, Tape := T })
[PROOFSTEP]
exact rfl
[GOAL]
case some
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v : σ
T : Tape Γ
l₁ : Λ
⊢ FRespects (TM0.step (tr M)) (fun c₁ => trCfg M c₁) (trCfg M { l := some l₁, var := v, Tape := T })
    (TM1.step M { l := some l₁, var := v, Tape := T })
[PROOFSTEP]
simp only [trCfg, TM1.step, FRespects, Option.map]
[GOAL]
case some
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v : σ
T : Tape Γ
l₁ : Λ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (M l₁), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (M l₁) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (M l₁) v T).var),
      Tape := (TM1.stepAux (M l₁) v T).Tape }
[PROOFSTEP]
induction' M l₁ with _ q IH _ q IH _ q IH generalizing v T
[GOAL]
case some.move
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Dir
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.move a✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.move a✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.move a✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.move a✝ q) v T).Tape }
case some.write
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.write a✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.write a✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.write a✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.write a✝ q) v T).Tape }
case some.load
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.load a✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.load a✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.load a✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.load a✝ q) v T).Tape }
case some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝¹, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝¹ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝¹ v T).var),
        Tape := (TM1.stepAux a✝¹ v T).Tape }
a_ih✝ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝ v T).var),
        Tape := (TM1.stepAux a✝ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch a✝² a✝¹ a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).Tape }
case some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.goto a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.goto a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.goto a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.goto a✝) v T).Tape }
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
case move d q IH => exact TransGen.head rfl (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
d : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Dir
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.move IH✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.move IH✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.move IH✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.move IH✝ q) v T).Tape }
[PROOFSTEP]
case move d q IH => exact TransGen.head rfl (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
d : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Dir
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.move IH✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.move IH✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.move IH✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.move IH✝ q) v T).Tape }
[PROOFSTEP]
exact TransGen.head rfl (IH _ _)
[GOAL]
case some.write
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.write a✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.write a✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.write a✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.write a✝ q) v T).Tape }
case some.load
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.load a✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.load a✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.load a✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.load a✝ q) v T).Tape }
case some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝¹, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝¹ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝¹ v T).var),
        Tape := (TM1.stepAux a✝¹ v T).Tape }
a_ih✝ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝ v T).var),
        Tape := (TM1.stepAux a✝ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch a✝² a✝¹ a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).Tape }
case some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.goto a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.goto a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.goto a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.goto a✝) v T).Tape }
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
case write a q IH => exact TransGen.head rfl (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
a : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.write IH✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.write IH✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.write IH✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.write IH✝ q) v T).Tape }
[PROOFSTEP]
case write a q IH => exact TransGen.head rfl (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
a : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.write IH✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.write IH✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.write IH✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.write IH✝ q) v T).Tape }
[PROOFSTEP]
exact TransGen.head rfl (IH _ _)
[GOAL]
case some.load
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.load a✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.load a✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.load a✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.load a✝ q) v T).Tape }
case some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝¹, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝¹ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝¹ v T).var),
        Tape := (TM1.stepAux a✝¹ v T).Tape }
a_ih✝ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝ v T).var),
        Tape := (TM1.stepAux a✝ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch a✝² a✝¹ a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).Tape }
case some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.goto a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.goto a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.goto a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.goto a✝) v T).Tape }
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
case load a q IH => exact (reaches₁_eq (by rfl)).2 (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
a : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.load IH✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.load IH✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.load IH✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.load IH✝ q) v T).Tape }
[PROOFSTEP]
case load a q IH => exact (reaches₁_eq (by rfl)).2 (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
a : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.load IH✝ q), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.load IH✝ q) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.load IH✝ q) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.load IH✝ q) v T).Tape }
[PROOFSTEP]
exact (reaches₁_eq (by rfl)).2 (IH _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
a : σ
q✝ : Tape Γ
l₁ : Λ
IH✝ : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q v T).var),
        Tape := (TM1.stepAux q v T).Tape }
v : σ
T : Tape Γ
⊢ TM0.step (tr M) { q := (some (TM1.Stmt.load IH✝ q), v), Tape := T } =
    TM0.step (tr M) { q := (some q, IH✝ T.head v), Tape := T }
[PROOFSTEP]
rfl
[GOAL]
case some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝¹, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝¹ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝¹ v T).var),
        Tape := (TM1.stepAux a✝¹ v T).Tape }
a_ih✝ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some a✝, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux a✝ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux a✝ v T).var),
        Tape := (TM1.stepAux a✝ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch a✝² a✝¹ a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.branch a✝² a✝¹ a✝) v T).Tape }
case some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.goto a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.goto a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.goto a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.goto a✝) v T).Tape }
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  unfold TM1.stepAux; cases e : p T.1 v
  · exact (reaches₁_eq (by simp only [TM0.step, tr, trAux, e]; rfl)).2 (IH₂ _ _)
  · exact (reaches₁_eq (by simp only [TM0.step, tr, trAux, e]; rfl)).2 (IH₁ _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.branch p q₁ q₂) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.branch p q₁ q₂) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.branch p q₁ q₂) v T).Tape }
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  unfold TM1.stepAux; cases e : p T.1 v
  · exact (reaches₁_eq (by simp only [TM0.step, tr, trAux, e]; rfl)).2 (IH₂ _ _)
  · exact (reaches₁_eq (by simp only [TM0.step, tr, trAux, e]; rfl)).2 (IH₁ _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.branch p q₁ q₂) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.branch p q₁ q₂) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.branch p q₁ q₂) v T).Tape }
[PROOFSTEP]
unfold TM1.stepAux
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T }
    {
      q :=
        (match (bif p T.head v then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).l with
          | some x => some (M x)
          | none => none,
          (bif p T.head v then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).var),
      Tape := (bif p T.head v then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).Tape }
[PROOFSTEP]
cases e : p T.1 v
[GOAL]
case false
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
e : p T.head v = false
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T }
    {
      q :=
        (match (bif false then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).l with
          | some x => some (M x)
          | none => none,
          (bif false then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).var),
      Tape := (bif false then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).Tape }
[PROOFSTEP]
exact (reaches₁_eq (by simp only [TM0.step, tr, trAux, e]; rfl)).2 (IH₂ _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
e : p T.head v = false
⊢ TM0.step (tr M) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T } =
    TM0.step (tr M) { q := (some q₂, v), Tape := T }
[PROOFSTEP]
simp only [TM0.step, tr, trAux, e]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
e : p T.head v = false
⊢ Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | move d => Tape.move d T
            | write a => Tape.write a T })
      (some (bif false then trAux M T.head q₁ v else trAux M T.head q₂ v)) =
    Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | move d => Tape.move d T
            | write a => Tape.write a T })
      (some (trAux M T.head q₂ v))
[PROOFSTEP]
rfl
[GOAL]
case true
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
e : p T.head v = true
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T }
    {
      q :=
        (match (bif true then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).l with
          | some x => some (M x)
          | none => none,
          (bif true then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).var),
      Tape := (bif true then TM1.stepAux q₁ v T else TM1.stepAux q₂ v T).Tape }
[PROOFSTEP]
exact (reaches₁_eq (by simp only [TM0.step, tr, trAux, e]; rfl)).2 (IH₁ _ _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
e : p T.head v = true
⊢ TM0.step (tr M) { q := (some (TM1.Stmt.branch p q₁ q₂), v), Tape := T } =
    TM0.step (tr M) { q := (some q₁, v), Tape := T }
[PROOFSTEP]
simp only [TM0.step, tr, trAux, e]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₁, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₁ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₁ v T).var),
        Tape := (TM1.stepAux q₁ v T).Tape }
IH₂ :
  ∀ (v : σ) (T : Tape Γ),
    Reaches₁ (TM0.step (tr M)) { q := (some q₂, v), Tape := T }
      {
        q :=
          (match (TM1.stepAux q₂ v T).l with
            | some x => some (M x)
            | none => none,
            (TM1.stepAux q₂ v T).var),
        Tape := (TM1.stepAux q₂ v T).Tape }
v : σ
T : Tape Γ
e : p T.head v = true
⊢ Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | move d => Tape.move d T
            | write a => Tape.write a T })
      (some (bif true then trAux M T.head q₁ v else trAux M T.head q₂ v)) =
    Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | move d => Tape.move d T
            | write a => Tape.write a T })
      (some (trAux M T.head q₁ v))
[PROOFSTEP]
rfl
[GOAL]
case some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.goto a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.goto a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.goto a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.goto a✝) v T).Tape }
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
iterate 2 exact TransGen.single (congr_arg some (congr (congr_arg TM0.Cfg.mk rfl) (Tape.write_self T)))
[GOAL]
case some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
a✝ : Γ → σ → Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some (TM1.Stmt.goto a✝), v), Tape := T }
    {
      q :=
        (match (TM1.stepAux (TM1.Stmt.goto a✝) v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux (TM1.Stmt.goto a✝) v T).var),
      Tape := (TM1.stepAux (TM1.Stmt.goto a✝) v T).Tape }
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
exact TransGen.single (congr_arg some (congr (congr_arg TM0.Cfg.mk rfl) (Tape.write_self T)))
[GOAL]
case some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
x✝ : Cfg₁
v✝ : σ
T✝ : Tape Γ
l₁ : Λ
v : σ
T : Tape Γ
⊢ Reaches₁ (TM0.step (tr M)) { q := (some TM1.Stmt.halt, v), Tape := T }
    {
      q :=
        (match (TM1.stepAux TM1.Stmt.halt v T).l with
          | some x => some (M x)
          | none => none,
          (TM1.stepAux TM1.Stmt.halt v T).var),
      Tape := (TM1.stepAux TM1.Stmt.halt v T).Tape }
[PROOFSTEP]
exact TransGen.single (congr_arg some (congr (congr_arg TM0.Cfg.mk rfl) (Tape.write_self T)))
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
l : List Γ
⊢ Part.map (fun c => Tape.right₀ c.Tape)
      ((fun a => trCfg M a) <$> eval (TM1.step M) { l := some default, var := default, Tape := Tape.mk₁ l }) =
    TM1.eval M l
[PROOFSTEP]
rw [Part.map_eq_map, Part.map_map, TM1.eval]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
M : Λ → Stmt₁
l : List Γ
⊢ Part.map ((fun c => Tape.right₀ c.Tape) ∘ fun a => trCfg M a)
      (eval (TM1.step M) { l := some default, var := default, Tape := Tape.mk₁ l }) =
    Part.map (fun c => Tape.right₀ c.Tape) (eval (TM1.step M) (TM1.init l))
[PROOFSTEP]
congr with ⟨⟩
[GOAL]
Γ : 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
⊢ TM0.Supports (tr M) ↑(trStmts M S)
[PROOFSTEP]
constructor
[GOAL]
case left
Γ : 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
⊢ default ∈ ↑(trStmts M S)
[PROOFSTEP]
apply Finset.mem_product.2
[GOAL]
case left
Γ : 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
⊢ default.fst ∈ TM1.stmts M S ∧ default.snd ∈ Finset.univ
[PROOFSTEP]
constructor
[GOAL]
case left.left
Γ : 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
⊢ default.fst ∈ TM1.stmts M S
[PROOFSTEP]
simp only [default, TM1.stmts, Finset.mem_insertNone, Option.mem_def, Option.some_inj, forall_eq', Finset.mem_biUnion]
[GOAL]
case left.left
Γ : 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, a ∈ S ∧ M default ∈ TM1.stmts₁ (M a)
[PROOFSTEP]
exact ⟨_, ss.1, TM1.stmts₁_self⟩
[GOAL]
case left.right
Γ : 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
⊢ default.snd ∈ Finset.univ
[PROOFSTEP]
apply Finset.mem_univ
[GOAL]
case right
Γ : 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
⊢ ∀ {q : Λ'₁₀} {a : Γ} {q' : Λ'₁₀} {s : Stmt₀}, (q', s) ∈ tr M q a → q ∈ ↑(trStmts M S) → q' ∈ ↑(trStmts M S)
[PROOFSTEP]
intro q a q' s h₁ h₂
[GOAL]
case right
Γ : 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
q : Λ'₁₀
a : Γ
q' : Λ'₁₀
s : Stmt₀
h₁ : (q', s) ∈ tr M q a
h₂ : q ∈ ↑(trStmts M S)
⊢ q' ∈ ↑(trStmts M S)
[PROOFSTEP]
rcases q with ⟨_ | q, v⟩
[GOAL]
case right.mk.none
Γ : 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 : Γ
q' : Λ'₁₀
s : Stmt₀
v : σ
h₁ : (q', s) ∈ tr M (none, v) a
h₂ : (none, v) ∈ ↑(trStmts M S)
⊢ q' ∈ ↑(trStmts M S)
[PROOFSTEP]
cases h₁
[GOAL]
case right.mk.some
Γ : 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 : Γ
q' : Λ'₁₀
s : Stmt₀
v : σ
q : Stmt₁
h₁ : (q', s) ∈ tr M (some q, v) a
h₂ : (some q, v) ∈ ↑(trStmts M S)
⊢ q' ∈ ↑(trStmts M S)
[PROOFSTEP]
cases' q' with q' v'
[GOAL]
case right.mk.some.mk
Γ : 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 : σ
q : Stmt₁
h₂ : (some q, v) ∈ ↑(trStmts M S)
q' : Option Stmt₁
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
⊢ (q', v') ∈ ↑(trStmts M S)
[PROOFSTEP]
simp only [trStmts, Finset.mem_coe] at h₂ ⊢
[GOAL]
case right.mk.some.mk
Γ : 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 : σ
q : Stmt₁
q' : Option Stmt₁
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
h₂ : (some q, v) ∈ TM1.stmts M S ×ˢ Finset.univ
⊢ (q', v') ∈ TM1.stmts M S ×ˢ Finset.univ
[PROOFSTEP]
rw [Finset.mem_product] at h₂ ⊢
[GOAL]
case right.mk.some.mk
Γ : 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 : σ
q : Stmt₁
q' : Option Stmt₁
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
h₂ : (some q, v).fst ∈ TM1.stmts M S ∧ (some q, v).snd ∈ Finset.univ
⊢ (q', v').fst ∈ TM1.stmts M S ∧ (q', v').snd ∈ Finset.univ
[PROOFSTEP]
simp only [Finset.mem_univ, and_true_iff] at h₂ ⊢
[GOAL]
case right.mk.some.mk
Γ : 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 : σ
q : Stmt₁
q' : Option Stmt₁
v' : σ
h₁ : ((q', v'), s) ∈ tr M (some q, v) a
h₂ : some q ∈ TM1.stmts M S
⊢ q' ∈ TM1.stmts M S
[PROOFSTEP]
cases q'
[GOAL]
case right.mk.some.mk.none
Γ : 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 : σ
q : Stmt₁
v' : σ
h₂ : some q ∈ TM1.stmts M S
h₁ : ((none, v'), s) ∈ tr M (some q, v) a
⊢ none ∈ TM1.stmts M S
[PROOFSTEP]
exact Multiset.mem_cons_self _ _
[GOAL]
case right.mk.some.mk.some
Γ : 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 : σ
q : Stmt₁
v' : σ
h₂ : some q ∈ TM1.stmts M S
val✝ : Stmt₁
h₁ : ((some val✝, v'), s) ∈ tr M (some q, v) a
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
simp only [tr, Option.mem_def] at h₁
[GOAL]
case right.mk.some.mk.some
Γ : 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 : σ
q : Stmt₁
v' : σ
h₂ : some q ∈ TM1.stmts M S
val✝ : Stmt₁
h₁ : some (trAux M a q v) = some ((some val✝, v'), s)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
have := TM1.stmts_supportsStmt ss h₂
[GOAL]
case right.mk.some.mk.some
Γ : 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 : σ
q : Stmt₁
v' : σ
h₂ : some q ∈ TM1.stmts M S
val✝ : Stmt₁
h₁ : some (trAux M a q v) = some ((some val✝, v'), s)
this : TM1.SupportsStmt S q
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
revert this
[GOAL]
case right.mk.some.mk.some
Γ : 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 : σ
q : Stmt₁
v' : σ
h₂ : some q ∈ TM1.stmts M S
val✝ : Stmt₁
h₁ : some (trAux M a q v) = some ((some val✝, v'), s)
⊢ TM1.SupportsStmt S q → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
induction q generalizing v
[GOAL]
case right.mk.some.mk.some.move
Γ : 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✝¹ : Dir
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.move a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.move a✝¹ a✝) v) = some ((some val✝, v'), s)
⊢ TM1.SupportsStmt S (TM1.Stmt.move a✝¹ a✝) → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
intro hs
[GOAL]
case right.mk.some.mk.some.write
Γ : 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✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.write a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.write a✝¹ a✝) v) = some ((some val✝, v'), s)
⊢ TM1.SupportsStmt S (TM1.Stmt.write a✝¹ a✝) → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
intro hs
[GOAL]
case right.mk.some.mk.some.load
Γ : 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✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.load a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.load a✝¹ a✝) v) = some ((some val✝, v'), s)
⊢ TM1.SupportsStmt S (TM1.Stmt.load a✝¹ a✝) → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
intro hs
[GOAL]
case right.mk.some.mk.some.branch
Γ : 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✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ),
    some a✝¹ ∈ TM1.stmts M S →
      some (trAux M a a✝¹ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝¹ → some val✝ ∈ TM1.stmts M S
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.branch a✝² a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.branch a✝² a✝¹ a✝) v) = some ((some val✝, v'), s)
⊢ TM1.SupportsStmt S (TM1.Stmt.branch a✝² a✝¹ a✝) → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
intro hs
[GOAL]
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)
⊢ TM1.SupportsStmt S (TM1.Stmt.goto a✝) → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
intro hs
[GOAL]
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)
⊢ TM1.SupportsStmt S TM1.Stmt.halt → some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
intro hs
[GOAL]
case right.mk.some.mk.some.move
Γ : 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✝¹ : Dir
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.move a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.move a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.move a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.write
Γ : 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✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.write a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.write a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.load
Γ : 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✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.load a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.load a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.load a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.branch
Γ : 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✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ),
    some a✝¹ ∈ TM1.stmts M S →
      some (trAux M a a✝¹ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝¹ → some val✝ ∈ TM1.stmts M S
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.branch a✝² a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.branch a✝² a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch a✝² a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
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
[PROOFSTEP]
case move d q =>
  cases h₁; refine' TM1.stmts_trans _ h₂
  unfold TM1.stmts₁
  exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
Γ : 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✝ : Dir
d : Stmt₁
q :
  ∀ (v : σ),
    some d ∈ TM1.stmts M S →
      some (trAux M a d v) = some ((some val✝, v'), s) → TM1.SupportsStmt S d → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.move a✝ d) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.move a✝ d) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.move a✝ d)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
case move d q =>
  cases h₁; refine' TM1.stmts_trans _ h₂
  unfold TM1.stmts₁
  exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
Γ : 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✝ : Dir
d : Stmt₁
q :
  ∀ (v : σ),
    some d ∈ TM1.stmts M S →
      some (trAux M a d v) = some ((some val✝, v'), s) → TM1.SupportsStmt S d → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.move a✝ d) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.move a✝ d) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.move a✝ d)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
cases h₁
[GOAL]
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' : σ
val✝ : Stmt₁
a✝ : Dir
h₂ : some (TM1.Stmt.move a✝ val✝) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.move a✝ val✝)
q :
  ∀ (v : σ),
    some val✝ ∈ TM1.stmts M S →
      some (trAux M a val✝ v) = some ((some val✝, v'), move a✝) → TM1.SupportsStmt S val✝ → some val✝ ∈ TM1.stmts M S
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
refine' TM1.stmts_trans _ h₂
[GOAL]
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' : σ
val✝ : Stmt₁
a✝ : Dir
h₂ : some (TM1.Stmt.move a✝ val✝) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.move a✝ val✝)
q :
  ∀ (v : σ),
    some val✝ ∈ TM1.stmts M S →
      some (trAux M a val✝ v) = some ((some val✝, v'), move a✝) → TM1.SupportsStmt S val✝ → some val✝ ∈ TM1.stmts M S
⊢ val✝ ∈ TM1.stmts₁ (TM1.Stmt.move a✝ val✝)
[PROOFSTEP]
unfold TM1.stmts₁
[GOAL]
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' : σ
val✝ : Stmt₁
a✝ : Dir
h₂ : some (TM1.Stmt.move a✝ val✝) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.move a✝ val✝)
q :
  ∀ (v : σ),
    some val✝ ∈ TM1.stmts M S →
      some (trAux M a val✝ v) = some ((some val✝, v'), move a✝) → TM1.SupportsStmt S val✝ → some val✝ ∈ TM1.stmts M S
⊢ val✝ ∈ insert (TM1.Stmt.move a✝ val✝) (TM1.stmts₁ val✝)
[PROOFSTEP]
exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
case right.mk.some.mk.some.write
Γ : 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✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.write a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.write a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.load
Γ : 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✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.load a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.load a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.load a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.branch
Γ : 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✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ),
    some a✝¹ ∈ TM1.stmts M S →
      some (trAux M a a✝¹ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝¹ → some val✝ ∈ TM1.stmts M S
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.branch a✝² a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.branch a✝² a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch a✝² a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
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
[PROOFSTEP]
case write b q =>
  cases h₁; refine' TM1.stmts_trans _ h₂
  unfold TM1.stmts₁
  exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
Γ : 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✝ : Γ → σ → Γ
b : Stmt₁
q :
  ∀ (v : σ),
    some b ∈ TM1.stmts M S →
      some (trAux M a b v) = some ((some val✝, v'), s) → TM1.SupportsStmt S b → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.write a✝ b) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.write a✝ b) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝ b)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
case write b q =>
  cases h₁; refine' TM1.stmts_trans _ h₂
  unfold TM1.stmts₁
  exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
Γ : 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✝ : Γ → σ → Γ
b : Stmt₁
q :
  ∀ (v : σ),
    some b ∈ TM1.stmts M S →
      some (trAux M a b v) = some ((some val✝, v'), s) → TM1.SupportsStmt S b → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.write a✝ b) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.write a✝ b) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝ b)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
cases h₁
[GOAL]
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' : σ
val✝ : Stmt₁
a✝ : Γ → σ → Γ
h₂ : some (TM1.Stmt.write a✝ val✝) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝ val✝)
q :
  ∀ (v : σ),
    some val✝ ∈ TM1.stmts M S →
      some (trAux M a val✝ v) = some ((some val✝, v'), write (a✝ a v')) →
        TM1.SupportsStmt S val✝ → some val✝ ∈ TM1.stmts M S
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
refine' TM1.stmts_trans _ h₂
[GOAL]
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' : σ
val✝ : Stmt₁
a✝ : Γ → σ → Γ
h₂ : some (TM1.Stmt.write a✝ val✝) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝ val✝)
q :
  ∀ (v : σ),
    some val✝ ∈ TM1.stmts M S →
      some (trAux M a val✝ v) = some ((some val✝, v'), write (a✝ a v')) →
        TM1.SupportsStmt S val✝ → some val✝ ∈ TM1.stmts M S
⊢ val✝ ∈ TM1.stmts₁ (TM1.Stmt.write a✝ val✝)
[PROOFSTEP]
unfold TM1.stmts₁
[GOAL]
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' : σ
val✝ : Stmt₁
a✝ : Γ → σ → Γ
h₂ : some (TM1.Stmt.write a✝ val✝) ∈ TM1.stmts M S
hs : TM1.SupportsStmt S (TM1.Stmt.write a✝ val✝)
q :
  ∀ (v : σ),
    some val✝ ∈ TM1.stmts M S →
      some (trAux M a val✝ v) = some ((some val✝, v'), write (a✝ a v')) →
        TM1.SupportsStmt S val✝ → some val✝ ∈ TM1.stmts M S
⊢ val✝ ∈ insert (TM1.Stmt.write a✝ val✝) (TM1.stmts₁ val✝)
[PROOFSTEP]
exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
case right.mk.some.mk.some.load
Γ : 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✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.load a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.load a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.load a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
case right.mk.some.mk.some.branch
Γ : 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✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ),
    some a✝¹ ∈ TM1.stmts M S →
      some (trAux M a a✝¹ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝¹ → some val✝ ∈ TM1.stmts M S
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.branch a✝² a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.branch a✝² a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch a✝² a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
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
[PROOFSTEP]
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
[GOAL]
Γ : 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₁
b : Γ → σ → σ
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
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
[PROOFSTEP]
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
[GOAL]
Γ : 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₁
b : Γ → σ → σ
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
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
[PROOFSTEP]
refine' IH _ (TM1.stmts_trans _ h₂) h₁ hs
[GOAL]
Γ : 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₁
b : Γ → σ → σ
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
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)
[PROOFSTEP]
unfold TM1.stmts₁
[GOAL]
Γ : 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₁
b : Γ → σ → σ
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
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 ∈ insert (TM1.Stmt.load b q) (TM1.stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem TM1.stmts₁_self
[GOAL]
case right.mk.some.mk.some.branch
Γ : 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✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ),
    some a✝¹ ∈ TM1.stmts M S →
      some (trAux M a a✝¹ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝¹ → some val✝ ∈ TM1.stmts M S
a_ih✝ :
  ∀ (v : σ),
    some a✝ ∈ TM1.stmts M S →
      some (trAux M a a✝ v) = some ((some val✝, v'), s) → TM1.SupportsStmt S a✝ → some val✝ ∈ TM1.stmts M S
v : σ
h₂ : some (TM1.Stmt.branch a✝² a✝¹ a✝) ∈ TM1.stmts M S
h₁ : some (trAux M a (TM1.Stmt.branch a✝² a✝¹ a✝) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch a✝² a✝¹ a✝)
⊢ some val✝ ∈ TM1.stmts M S
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
[PROOFSTEP]
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)
[GOAL]
Γ : 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 (trAux M a (TM1.Stmt.branch p q₁ q₂) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch p q₁ q₂)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
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)
[GOAL]
Γ : 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 (trAux M a (TM1.Stmt.branch p q₁ q₂) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch p q₁ q₂)
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
cases h : p a v
[GOAL]
case false
Γ : 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 (trAux M a (TM1.Stmt.branch p q₁ q₂) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch p q₁ q₂)
h : p a v = false
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
rw [trAux, h] at h₁
[GOAL]
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 (trAux M a (TM1.Stmt.branch p q₁ q₂) v) = some ((some val✝, v'), s)
hs : TM1.SupportsStmt S (TM1.Stmt.branch p q₁ q₂)
h : p a v = true
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
rw [trAux, h] at h₁
[GOAL]
case false
Γ : 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 false 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 = false
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
refine' IH₂ _ (TM1.stmts_trans _ h₂) h₁ hs.2
[GOAL]
case false
Γ : 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 false 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 = false
⊢ q₂ ∈ TM1.stmts₁ (TM1.Stmt.branch p q₁ q₂)
[PROOFSTEP]
unfold TM1.stmts₁
[GOAL]
case false
Γ : 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 false 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 = false
⊢ q₂ ∈ insert (TM1.Stmt.branch p q₁ q₂) (TM1.stmts₁ q₁ ∪ TM1.stmts₁ q₂)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (Finset.mem_union_right _ TM1.stmts₁_self)
[GOAL]
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
⊢ some val✝ ∈ TM1.stmts M S
[PROOFSTEP]
refine' IH₁ _ (TM1.stmts_trans _ h₂) h₁ hs.1
[GOAL]
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₁ ∈ TM1.stmts₁ (TM1.Stmt.branch p q₁ q₂)
[PROOFSTEP]
unfold TM1.stmts₁
[GOAL]
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₂)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (Finset.mem_union_left _ TM1.stmts₁_self)
[GOAL]
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
[PROOFSTEP]
case goto l =>
  cases h₁
  exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
[GOAL]
Γ : 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
[PROOFSTEP]
case goto l =>
  cases h₁
  exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
[GOAL]
Γ : 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
[PROOFSTEP]
cases h₁
[GOAL]
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
[PROOFSTEP]
exact Finset.some_mem_insertNone.2 (Finset.mem_biUnion.2 ⟨_, hs _ _, TM1.stmts₁_self⟩)
[GOAL]
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
[PROOFSTEP]
case halt => cases h₁
[GOAL]
Γ : 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
[PROOFSTEP]
case halt => cases h₁
[GOAL]
Γ : 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
[PROOFSTEP]
cases h₁
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
inst✝ : Fintype Γ
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a
[PROOFSTEP]
letI := Classical.decEq Γ
[GOAL]
Γ : 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
[PROOFSTEP]
let n := Fintype.card Γ
[GOAL]
Γ : 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
[PROOFSTEP]
obtain ⟨F⟩ := Fintype.truncEquivFin Γ
[GOAL]
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
[PROOFSTEP]
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⟩
[GOAL]
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
[PROOFSTEP]
let H := (F.toEmbedding.trans G).trans (Equiv.vectorEquivFin _ _).symm.toEmbedding
[GOAL]
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
[PROOFSTEP]
classical
let enc := H.setValue default (Vector.replicate n false)
exact ⟨_, enc, Function.invFun enc, H.setValue_eq _ _, Function.leftInverse_invFun enc.2⟩
[GOAL]
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
[PROOFSTEP]
let enc := H.setValue default (Vector.replicate n false)
[GOAL]
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)
enc : Γ ↪ Vector Bool n := Function.Embedding.setValue H default (Vector.replicate n false)
⊢ ∃ n enc dec, enc default = Vector.replicate n false ∧ ∀ (a : Γ), dec (enc a) = a
[PROOFSTEP]
exact ⟨_, enc, Function.invFun enc, H.setValue_eq _ _, Function.leftInverse_invFun enc.2⟩
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T : Tape Bool
⊢ stepAux (move d q) v T = stepAux q v ((Tape.move d)^[n] T)
[PROOFSTEP]
suffices : ∀ i, stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T : Tape Bool
this : ∀ (i : ℕ), stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
⊢ stepAux (move d q) v T = stepAux q v ((Tape.move d)^[n] T)
case this
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T : Tape Bool
⊢ ∀ (i : ℕ), stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
[PROOFSTEP]
exact this n
[GOAL]
case this
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T : Tape Bool
⊢ ∀ (i : ℕ), stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
[PROOFSTEP]
intro i
[GOAL]
case this
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T : Tape Bool
i : ℕ
⊢ stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
[PROOFSTEP]
induction' i with i IH generalizing T
[GOAL]
case this.zero
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T✝ T : Tape Bool
⊢ stepAux ((Stmt.move d)^[Nat.zero] q) v T = stepAux q v ((Tape.move d)^[Nat.zero] T)
[PROOFSTEP]
rfl
[GOAL]
case this.succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T✝ : Tape Bool
i : ℕ
IH : ∀ (T : Tape Bool), stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
T : Tape Bool
⊢ stepAux ((Stmt.move d)^[Nat.succ i] q) v T = stepAux q v ((Tape.move d)^[Nat.succ i] T)
[PROOFSTEP]
rw [iterate_succ', iterate_succ]
[GOAL]
case this.succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T✝ : Tape Bool
i : ℕ
IH : ∀ (T : Tape Bool), stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
T : Tape Bool
⊢ stepAux ((Stmt.move d ∘ (Stmt.move d)^[i]) q) v T = stepAux q v (((Tape.move d)^[i] ∘ Tape.move d) T)
[PROOFSTEP]
simp only [stepAux, Function.comp_apply]
[GOAL]
case this.succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
d : Dir
q : Stmt Bool Λ' σ
v : σ
T✝ : Tape Bool
i : ℕ
IH : ∀ (T : Tape Bool), stepAux ((Stmt.move d)^[i] q) v T = stepAux q v ((Tape.move d)^[i] T)
T : Tape Bool
⊢ stepAux ((Stmt.move d)^[i] q) v (Tape.move d T) = stepAux q v ((Tape.move d)^[i] (Tape.move d T))
[PROOFSTEP]
rw [IH]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
d : Dir
q : Stmt Bool Λ' σ
⊢ SupportsStmt S (move d q) = SupportsStmt S q
[PROOFSTEP]
suffices ∀ {i}, SupportsStmt S ((Stmt.move d)^[i] q) = _ from this
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
d : Dir
q : Stmt Bool Λ' σ
⊢ ∀ {i : ℕ}, SupportsStmt S ((Stmt.move d)^[i] q) = SupportsStmt S q
[PROOFSTEP]
intro i
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
d : Dir
q : Stmt Bool Λ' σ
i : ℕ
⊢ SupportsStmt S ((Stmt.move d)^[i] q) = SupportsStmt S q
[PROOFSTEP]
induction i generalizing q
[GOAL]
case zero
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
d : Dir
q : Stmt Bool Λ' σ
⊢ SupportsStmt S ((Stmt.move d)^[Nat.zero] q) = SupportsStmt S q
[PROOFSTEP]
simp only [*, iterate]
[GOAL]
case succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
d : Dir
n✝ : ℕ
n_ih✝ : ∀ {q : Stmt Bool Λ' σ}, SupportsStmt S ((Stmt.move d)^[n✝] q) = SupportsStmt S q
q : Stmt Bool Λ' σ
⊢ SupportsStmt S ((Stmt.move d)^[Nat.succ n✝] q) = SupportsStmt S q
[PROOFSTEP]
simp only [*, iterate]
[GOAL]
case succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
d : Dir
n✝ : ℕ
n_ih✝ : ∀ {q : Stmt Bool Λ' σ}, SupportsStmt S ((Stmt.move d)^[n✝] q) = SupportsStmt S q
q : Stmt Bool Λ' σ
⊢ SupportsStmt S (Stmt.move d q) = SupportsStmt S q
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
l : List Bool
q : Stmt Bool Λ' σ
⊢ SupportsStmt S (write l q) = SupportsStmt S q
[PROOFSTEP]
induction' l with _ l IH
[GOAL]
case nil
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
q : Stmt Bool Λ' σ
⊢ SupportsStmt S (write [] q) = SupportsStmt S q
[PROOFSTEP]
simp only [write, SupportsStmt, *]
[GOAL]
case cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
q : Stmt Bool Λ' σ
head✝ : Bool
l : List Bool
IH : SupportsStmt S (write l q) = SupportsStmt S q
⊢ SupportsStmt S (write (head✝ :: l) q) = SupportsStmt S q
[PROOFSTEP]
simp only [write, SupportsStmt, *]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝ : Γ → Stmt Bool Λ' σ
i : ℕ
f : Vector Bool i → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool i), SupportsStmt S (f v)
⊢ SupportsStmt S (readAux i f)
[PROOFSTEP]
induction' i with i IH
[GOAL]
case zero
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i : ℕ
f✝ : Vector Bool i → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i), SupportsStmt S (f✝ v)
f : Vector Bool Nat.zero → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool Nat.zero), SupportsStmt S (f v)
⊢ SupportsStmt S (readAux Nat.zero f)
[PROOFSTEP]
exact hf _
[GOAL]
case succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
⊢ SupportsStmt S (readAux (Nat.succ i) f)
[PROOFSTEP]
constructor
[GOAL]
case succ.left
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
⊢ SupportsStmt S (Stmt.move Dir.right (readAux i fun v => f (true ::ᵥ v)))
[PROOFSTEP]
apply IH
[GOAL]
case succ.right
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
⊢ SupportsStmt S (Stmt.move Dir.right (readAux i fun v => f (false ::ᵥ v)))
[PROOFSTEP]
apply IH
[GOAL]
case succ.left.hf
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
⊢ ∀ (v : Vector Bool i), SupportsStmt S (f (true ::ᵥ v))
[PROOFSTEP]
intro
[GOAL]
case succ.right.hf
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
⊢ ∀ (v : Vector Bool i), SupportsStmt S (f (false ::ᵥ v))
[PROOFSTEP]
intro
[GOAL]
case succ.left.hf
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
v✝ : Vector Bool i
⊢ SupportsStmt S (f (true ::ᵥ v✝))
[PROOFSTEP]
apply hf
[GOAL]
case succ.right.hf
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝¹ : Γ → Stmt Bool Λ' σ
i✝ : ℕ
f✝ : Vector Bool i✝ → Stmt Bool Λ' σ
hf✝ : ∀ (v : Vector Bool i✝), SupportsStmt S (f✝ v)
i : ℕ
IH :
  ∀ (f : Vector Bool i → Stmt Bool Λ' σ), (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
f : Vector Bool (Nat.succ i) → Stmt Bool Λ' σ
hf : ∀ (v : Vector Bool (Nat.succ i)), SupportsStmt S (f v)
v✝ : Vector Bool i
⊢ SupportsStmt S (f (false ::ᵥ v✝))
[PROOFSTEP]
apply hf
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝ : Γ → Stmt Bool Λ' σ
this :
  ∀ (i : ℕ) (f : Vector Bool i → Stmt Bool Λ' σ),
    (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
hf : ∀ (a : Γ), SupportsStmt S (f✝ a)
⊢ ∀ (v : Vector Bool n), SupportsStmt S (move Dir.left (f✝ (dec v)))
[PROOFSTEP]
intro
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
S : Finset Λ'
f✝ : Γ → Stmt Bool Λ' σ
this :
  ∀ (i : ℕ) (f : Vector Bool i → Stmt Bool Λ' σ),
    (∀ (v : Vector Bool i), SupportsStmt S (f v)) → SupportsStmt S (readAux i f)
hf : ∀ (a : Γ), SupportsStmt S (f✝ a)
v✝ : Vector Bool n
⊢ SupportsStmt S (move Dir.left (f✝ (dec v✝)))
[PROOFSTEP]
simp only [supportsStmt_move, hf]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
L R : ListBlank Γ
⊢ Tape Bool
[PROOFSTEP]
refine' Tape.mk' (L.bind (fun x ↦ (enc x).toList.reverse) ⟨n, _⟩) (R.bind (fun x ↦ (enc x).toList) ⟨n, _⟩)
[GOAL]
case refine'_1
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
L R : ListBlank Γ
⊢ (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n default
[PROOFSTEP]
simp only [enc0, Vector.replicate, List.reverse_replicate, Bool.default_bool, Vector.toList_mk]
[GOAL]
case refine'_2
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
L R : ListBlank Γ
⊢ (fun x => Vector.toList (enc x)) default = List.replicate n default
[PROOFSTEP]
simp only [enc0, Vector.replicate, List.reverse_replicate, Bool.default_bool, Vector.toList_mk]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
L R : ListBlank Γ
⊢ trTape enc0 (Tape.mk' L R) = trTape' enc0 L R
[PROOFSTEP]
simp only [trTape, Tape.mk'_left, Tape.mk'_right₀]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
⊢ (Tape.move Dir.left)^[n] (trTape' enc0 L R) = trTape' enc0 (ListBlank.tail L) (ListBlank.cons (ListBlank.head L) R)
[PROOFSTEP]
obtain ⟨a, L, rfl⟩ := L.exists_cons
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
⊢ (Tape.move Dir.left)^[n] (trTape' enc0 (ListBlank.cons a L) R) =
    trTape' enc0 (ListBlank.tail (ListBlank.cons a L)) (ListBlank.cons (ListBlank.head (ListBlank.cons a L)) R)
[PROOFSTEP]
simp only [trTape', ListBlank.cons_bind, ListBlank.head_cons, ListBlank.tail_cons]
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
⊢ (Tape.move Dir.left)^[n]
      (Tape.mk'
        (ListBlank.append (List.reverse (Vector.toList (enc a)))
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default))) =
    Tape.mk'
      (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
        (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
      (ListBlank.append (Vector.toList (enc a))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
suffices
  ∀ {L' R' l₁ l₂} (_ : Vector.toList (enc a) = List.reverseAux l₁ l₂),
    (Tape.move Dir.left)^[l₁.length] (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      Tape.mk' L' (ListBlank.append (Vector.toList (enc a)) R')
  by simpa only [List.length_reverse, Vector.toList_length] using this (List.reverse_reverse _).symm
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
this :
  ∀ {L' R' : ListBlank Bool} {l₁ l₂ : List Bool},
    Vector.toList (enc a) = List.reverseAux l₁ l₂ →
      (Tape.move Dir.left)^[List.length l₁] (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
        Tape.mk' L' (ListBlank.append (Vector.toList (enc a)) R')
⊢ (Tape.move Dir.left)^[n]
      (Tape.mk'
        (ListBlank.append (List.reverse (Vector.toList (enc a)))
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default))) =
    Tape.mk'
      (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
        (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
      (ListBlank.append (Vector.toList (enc a))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
simpa only [List.length_reverse, Vector.toList_length] using this (List.reverse_reverse _).symm
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
⊢ ∀ {L' R' : ListBlank Bool} {l₁ l₂ : List Bool},
    Vector.toList (enc a) = List.reverseAux l₁ l₂ →
      (Tape.move Dir.left)^[List.length l₁] (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
        Tape.mk' L' (ListBlank.append (Vector.toList (enc a)) R')
[PROOFSTEP]
intro _ _ l₁ l₂ e
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
L'✝ R'✝ : ListBlank Bool
l₁ l₂ : List Bool
e : Vector.toList (enc a) = List.reverseAux l₁ l₂
⊢ (Tape.move Dir.left)^[List.length l₁] (Tape.mk' (ListBlank.append l₁ L'✝) (ListBlank.append l₂ R'✝)) =
    Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
[PROOFSTEP]
induction' l₁ with b l₁ IH generalizing l₂
[GOAL]
case intro.intro.nil
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
L'✝ R'✝ : ListBlank Bool
l₁ l₂✝ : List Bool
e✝ : Vector.toList (enc a) = List.reverseAux l₁ l₂✝
l₂ : List Bool
e : Vector.toList (enc a) = List.reverseAux [] l₂
⊢ (Tape.move Dir.left)^[List.length []] (Tape.mk' (ListBlank.append [] L'✝) (ListBlank.append l₂ R'✝)) =
    Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
[PROOFSTEP]
cases e
[GOAL]
case intro.intro.nil.refl
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
L'✝ R'✝ : ListBlank Bool
l₁ l₂ : List Bool
e : Vector.toList (enc a) = List.reverseAux l₁ l₂
⊢ (Tape.move Dir.left)^[List.length []] (Tape.mk' (ListBlank.append [] L'✝) (ListBlank.append (enc a).1 R'✝)) =
    Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
L'✝ R'✝ : ListBlank Bool
l₁✝ l₂✝ : List Bool
e✝ : Vector.toList (enc a) = List.reverseAux l₁✝ l₂✝
b : Bool
l₁ : List Bool
IH :
  ∀ {l₂ : List Bool},
    Vector.toList (enc a) = List.reverseAux l₁ l₂ →
      (Tape.move Dir.left)^[List.length l₁] (Tape.mk' (ListBlank.append l₁ L'✝) (ListBlank.append l₂ R'✝)) =
        Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
l₂ : List Bool
e : Vector.toList (enc a) = List.reverseAux (b :: l₁) l₂
⊢ (Tape.move Dir.left)^[List.length (b :: l₁)] (Tape.mk' (ListBlank.append (b :: l₁) L'✝) (ListBlank.append l₂ R'✝)) =
    Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
[PROOFSTEP]
simp only [List.length, List.cons_append, iterate_succ_apply]
[GOAL]
case intro.intro.cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
L'✝ R'✝ : ListBlank Bool
l₁✝ l₂✝ : List Bool
e✝ : Vector.toList (enc a) = List.reverseAux l₁✝ l₂✝
b : Bool
l₁ : List Bool
IH :
  ∀ {l₂ : List Bool},
    Vector.toList (enc a) = List.reverseAux l₁ l₂ →
      (Tape.move Dir.left)^[List.length l₁] (Tape.mk' (ListBlank.append l₁ L'✝) (ListBlank.append l₂ R'✝)) =
        Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
l₂ : List Bool
e : Vector.toList (enc a) = List.reverseAux (b :: l₁) l₂
⊢ (Tape.move Dir.left)^[List.length l₁]
      (Tape.move Dir.left (Tape.mk' (ListBlank.append (b :: l₁) L'✝) (ListBlank.append l₂ R'✝))) =
    Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
[PROOFSTEP]
convert IH e
[GOAL]
case h.e'_2.h.e'_4
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
R : ListBlank Γ
a : Γ
L : ListBlank Γ
L'✝ R'✝ : ListBlank Bool
l₁✝ l₂✝ : List Bool
e✝ : Vector.toList (enc a) = List.reverseAux l₁✝ l₂✝
b : Bool
l₁ : List Bool
IH :
  ∀ {l₂ : List Bool},
    Vector.toList (enc a) = List.reverseAux l₁ l₂ →
      (Tape.move Dir.left)^[List.length l₁] (Tape.mk' (ListBlank.append l₁ L'✝) (ListBlank.append l₂ R'✝)) =
        Tape.mk' L'✝ (ListBlank.append (Vector.toList (enc a)) R'✝)
l₂ : List Bool
e : Vector.toList (enc a) = List.reverseAux (b :: l₁) l₂
⊢ Tape.move Dir.left (Tape.mk' (ListBlank.append (b :: l₁) L'✝) (ListBlank.append l₂ R'✝)) =
    Tape.mk' (ListBlank.append l₁ L'✝) (ListBlank.append (b :: l₂) R'✝)
[PROOFSTEP]
simp only [ListBlank.tail_cons, ListBlank.append, Tape.move_left_mk', ListBlank.head_cons]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
⊢ (Tape.move Dir.right)^[n] (trTape' enc0 L R) = trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R)
[PROOFSTEP]
suffices ∀ i L, (Tape.move Dir.right)^[i] ((Tape.move Dir.left)^[i] L) = L
  by
  refine' (Eq.symm _).trans (this n _)
  simp only [trTape'_move_left, ListBlank.cons_head_tail, ListBlank.head_cons, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
this : ∀ (i : ℕ) (L : Tape (?m.366455 i)), (Tape.move Dir.right)^[i] ((Tape.move Dir.left)^[i] L) = L
⊢ (Tape.move Dir.right)^[n] (trTape' enc0 L R) = trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R)
[PROOFSTEP]
refine' (Eq.symm _).trans (this n _)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
this : ∀ (i : ℕ) (L : Tape Bool), (Tape.move Dir.right)^[i] ((Tape.move Dir.left)^[i] L) = L
⊢ (Tape.move Dir.right)^[n]
      ((Tape.move Dir.left)^[n] (trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R))) =
    (Tape.move Dir.right)^[n] (trTape' enc0 L R)
[PROOFSTEP]
simp only [trTape'_move_left, ListBlank.cons_head_tail, ListBlank.head_cons, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
⊢ ∀ (i : ℕ) (L : Tape Bool), (Tape.move Dir.right)^[i] ((Tape.move Dir.left)^[i] L) = L
[PROOFSTEP]
intro i _
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
i : ℕ
L✝ : Tape Bool
⊢ (Tape.move Dir.right)^[i] ((Tape.move Dir.left)^[i] L✝) = L✝
[PROOFSTEP]
induction' i with i IH
[GOAL]
case zero
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
L✝ : Tape Bool
⊢ (Tape.move Dir.right)^[Nat.zero] ((Tape.move Dir.left)^[Nat.zero] L✝) = L✝
[PROOFSTEP]
rfl
[GOAL]
case succ
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
L R : ListBlank Γ
L✝ : Tape Bool
i : ℕ
IH : (Tape.move Dir.right)^[i] ((Tape.move Dir.left)^[i] L✝) = L✝
⊢ (Tape.move Dir.right)^[Nat.succ i] ((Tape.move Dir.left)^[Nat.succ i] L✝) = L✝
[PROOFSTEP]
rw [iterate_succ_apply, iterate_succ_apply', Tape.move_left_right, IH]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
a b : Γ
L R : ListBlank Γ
⊢ stepAux (write (Vector.toList (enc a)) q) v (trTape' enc0 L (ListBlank.cons b R)) =
    stepAux q v (trTape' enc0 (ListBlank.cons a L) R)
[PROOFSTEP]
simp only [trTape', ListBlank.cons_bind]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
a b : Γ
L R : ListBlank Γ
⊢ stepAux (write (Vector.toList (enc a)) q) v
      (Tape.mk'
        (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
          (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
        (ListBlank.append (Vector.toList (enc b))
          (ListBlank.bind R (fun x => Vector.toList (enc x))
            (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))) =
    stepAux q v
      (Tape.mk'
        (ListBlank.append (List.reverse (Vector.toList (enc a)))
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
suffices
  ∀ {L' R'} (l₁ l₂ l₂' : List Bool) (_ : l₂'.length = l₂.length),
    stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
      stepAux q v (Tape.mk' (L'.append (List.reverseAux l₂ l₁)) R')
  by refine' this [] _ _ ((enc b).2.trans (enc a).2.symm)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
a b : Γ
L R : ListBlank Γ
this :
  ∀ {L' R' : ListBlank Bool} (l₁ l₂ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
⊢ stepAux (write (Vector.toList (enc a)) q) v
      (Tape.mk'
        (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
          (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
        (ListBlank.append (Vector.toList (enc b))
          (ListBlank.bind R (fun x => Vector.toList (enc x))
            (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))) =
    stepAux q v
      (Tape.mk'
        (ListBlank.append (List.reverse (Vector.toList (enc a)))
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
refine' this [] _ _ ((enc b).2.trans (enc a).2.symm)
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
a b : Γ
L R : ListBlank Γ
⊢ ∀ {L' R' : ListBlank Bool} (l₁ l₂ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
clear a b L R
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
⊢ ∀ {L' R' : ListBlank Bool} (l₁ l₂ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
intro L' R' l₁ l₂ l₂' e
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁ l₂ l₂' : List Bool
e : List.length l₂' = List.length l₂
⊢ stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
induction' l₂ with a l₂ IH generalizing l₁ l₂'
[GOAL]
case nil
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂ l₂'✝ : List Bool
e✝ : List.length l₂'✝ = List.length l₂
l₁ l₂' : List Bool
e : List.length l₂' = List.length []
⊢ stepAux (write [] q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux [] l₁) L') R')
[PROOFSTEP]
cases List.length_eq_zero.1 e
[GOAL]
case nil.refl
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂ l₂' : List Bool
e✝ : List.length l₂' = List.length l₂
l₁ : List Bool
e : List.length [] = List.length []
⊢ stepAux (write [] q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append [] R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux [] l₁) L') R')
[PROOFSTEP]
rfl
[GOAL]
case cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ l₂'✝ : List Bool
e✝ : List.length l₂'✝ = List.length l₂✝
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ l₂' : List Bool
e : List.length l₂' = List.length (a :: l₂)
⊢ stepAux (write (a :: l₂) q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
cases' l₂' with b l₂'
[GOAL]
case cons.nil
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ l₂' : List Bool
e✝ : List.length l₂' = List.length l₂✝
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
e : List.length [] = List.length (a :: l₂)
⊢ stepAux (write (a :: l₂) q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append [] R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
simp only [List.length_nil, List.length_cons, Nat.succ_inj'] at e
[GOAL]
case cons.cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ l₂'✝ : List Bool
e✝ : List.length l₂'✝ = List.length l₂✝
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
b : Bool
l₂' : List Bool
e : List.length (b :: l₂') = List.length (a :: l₂)
⊢ stepAux (write (a :: l₂) q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append (b :: l₂') R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
simp only [List.length_nil, List.length_cons, Nat.succ_inj'] at e
[GOAL]
case cons.cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ l₂'✝ : List Bool
e✝ : List.length l₂'✝ = List.length l₂✝
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
b : Bool
l₂' : List Bool
e : List.length l₂' = List.length l₂
⊢ stepAux (write (a :: l₂) q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append (b :: l₂') R')) =
    stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
rw [List.reverseAux, ← IH (a :: l₁) l₂' e]
[GOAL]
case cons.cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
q : Stmt Bool Λ' σ
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ l₂'✝ : List Bool
e✝ : List.length l₂'✝ = List.length l₂✝
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ l₂' : List Bool),
    List.length l₂' = List.length l₂ →
      stepAux (write l₂ q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂' R')) =
        stepAux q v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
b : Bool
l₂' : List Bool
e : List.length l₂' = List.length l₂
⊢ stepAux (write (a :: l₂) q) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append (b :: l₂') R')) =
    stepAux (write l₂ q) v (Tape.mk' (ListBlank.append (a :: l₁) L') (ListBlank.append l₂' R'))
[PROOFSTEP]
simp only [stepAux, ListBlank.append, Tape.write_mk', Tape.move_right_mk', ListBlank.head_cons, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L R : ListBlank Γ
⊢ stepAux (read dec f) v (trTape' enc0 L R) = stepAux (f (ListBlank.head R)) v (trTape' enc0 L R)
[PROOFSTEP]
suffices
  ∀ f, stepAux (readAux n f) v (trTape' enc0 L R) = stepAux (f (enc R.head)) v (trTape' enc0 (L.cons R.head) R.tail)
  by
  rw [read, this, stepAux_move, encdec, trTape'_move_left enc0]
  simp only [ListBlank.head_cons, ListBlank.cons_head_tail, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L R : ListBlank Γ
this :
  ∀ (f : Vector Bool n → Stmt Bool Λ' σ),
    stepAux (readAux n f) v (trTape' enc0 L R) =
      stepAux (f (enc (ListBlank.head R))) v (trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R))
⊢ stepAux (read dec f) v (trTape' enc0 L R) = stepAux (f (ListBlank.head R)) v (trTape' enc0 L R)
[PROOFSTEP]
rw [read, this, stepAux_move, encdec, trTape'_move_left enc0]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L R : ListBlank Γ
this :
  ∀ (f : Vector Bool n → Stmt Bool Λ' σ),
    stepAux (readAux n f) v (trTape' enc0 L R) =
      stepAux (f (enc (ListBlank.head R))) v (trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R))
⊢ stepAux (f (ListBlank.head R)) v
      (trTape' enc0 (ListBlank.tail (ListBlank.cons (ListBlank.head R) L))
        (ListBlank.cons (ListBlank.head (ListBlank.cons (ListBlank.head R) L)) (ListBlank.tail R))) =
    stepAux (f (ListBlank.head R)) v (trTape' enc0 L R)
[PROOFSTEP]
simp only [ListBlank.head_cons, ListBlank.cons_head_tail, ListBlank.tail_cons]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L R : ListBlank Γ
⊢ ∀ (f : Vector Bool n → Stmt Bool Λ' σ),
    stepAux (readAux n f) v (trTape' enc0 L R) =
      stepAux (f (enc (ListBlank.head R))) v (trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R))
[PROOFSTEP]
obtain ⟨a, R, rfl⟩ := R.exists_cons
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
⊢ ∀ (f : Vector Bool n → Stmt Bool Λ' σ),
    stepAux (readAux n f) v (trTape' enc0 L (ListBlank.cons a R)) =
      stepAux (f (enc (ListBlank.head (ListBlank.cons a R)))) v
        (trTape' enc0 (ListBlank.cons (ListBlank.head (ListBlank.cons a R)) L) (ListBlank.tail (ListBlank.cons a R)))
[PROOFSTEP]
simp only [ListBlank.head_cons, ListBlank.tail_cons, trTape', ListBlank.cons_bind, ListBlank.append_assoc]
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
⊢ ∀ (f : Vector Bool n → Stmt Bool Λ' σ),
    stepAux (readAux n f) v
        (Tape.mk'
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
          (ListBlank.append (Vector.toList (enc a))
            (ListBlank.bind R (fun x => Vector.toList (enc x))
              (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))) =
      stepAux (f (enc a)) v
        (Tape.mk'
          (ListBlank.append (List.reverse (Vector.toList (enc a)))
            (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
              (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
          (ListBlank.bind R (fun x => Vector.toList (enc x))
            (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
suffices
  ∀ i f L' R' l₁ l₂ h,
    stepAux (readAux i f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f ⟨l₂, h⟩) v (Tape.mk' (ListBlank.append (l₂.reverseAux l₁) L') R')
  by
  intro f
  exact this n f (L.bind (fun x => (enc x).1.reverse) _) (R.bind (fun x => (enc x).1) _) [] _ (enc a).2
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
this :
  ∀ (i : ℕ) (f : Vector Bool i → Stmt Bool Λ' σ) (L' R' : ListBlank Bool) (l₁ l₂ : List Bool) (h : List.length l₂ = i),
    stepAux (readAux i f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := h }) v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
⊢ ∀ (f : Vector Bool n → Stmt Bool Λ' σ),
    stepAux (readAux n f) v
        (Tape.mk'
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
          (ListBlank.append (Vector.toList (enc a))
            (ListBlank.bind R (fun x => Vector.toList (enc x))
              (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))) =
      stepAux (f (enc a)) v
        (Tape.mk'
          (ListBlank.append (List.reverse (Vector.toList (enc a)))
            (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
              (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
          (ListBlank.bind R (fun x => Vector.toList (enc x))
            (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
intro f
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f✝ : Γ → Stmt Bool Λ' σ
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
this :
  ∀ (i : ℕ) (f : Vector Bool i → Stmt Bool Λ' σ) (L' R' : ListBlank Bool) (l₁ l₂ : List Bool) (h : List.length l₂ = i),
    stepAux (readAux i f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := h }) v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
f : Vector Bool n → Stmt Bool Λ' σ
⊢ stepAux (readAux n f) v
      (Tape.mk'
        (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
          (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default))
        (ListBlank.append (Vector.toList (enc a))
          (ListBlank.bind R (fun x => Vector.toList (enc x))
            (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))) =
    stepAux (f (enc a)) v
      (Tape.mk'
        (ListBlank.append (List.reverse (Vector.toList (enc a)))
          (ListBlank.bind L (fun x => List.reverse (Vector.toList (enc x)))
            (_ : ∃ n_1, (fun x => List.reverse (Vector.toList (enc x))) default = List.replicate n_1 default)))
        (ListBlank.bind R (fun x => Vector.toList (enc x))
          (_ : ∃ n_1, (fun x => Vector.toList (enc x)) default = List.replicate n_1 default)))
[PROOFSTEP]
exact this n f (L.bind (fun x => (enc x).1.reverse) _) (R.bind (fun x => (enc x).1) _) [] _ (enc a).2
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
f : Γ → Stmt Bool Λ' σ
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
⊢ ∀ (i : ℕ) (f : Vector Bool i → Stmt Bool Λ' σ) (L' R' : ListBlank Bool) (l₁ l₂ : List Bool) (h : List.length l₂ = i),
    stepAux (readAux i f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := h }) v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
clear f L a R
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
⊢ ∀ (i : ℕ) (f : Vector Bool i → Stmt Bool Λ' σ) (L' R' : ListBlank Bool) (l₁ l₂ : List Bool) (h : List.length l₂ = i),
    stepAux (readAux i f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := h }) v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
intro i f L' R' l₁ l₂ _
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
i : ℕ
f : Vector Bool i → Stmt Bool Λ' σ
L' R' : ListBlank Bool
l₁ l₂ : List Bool
h✝ : List.length l₂ = i
⊢ stepAux (readAux i f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
    stepAux (f { val := l₂, property := h✝ }) v (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
subst i
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁ l₂ : List Bool
f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ
⊢ stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
    stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
      (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
[PROOFSTEP]
induction' l₂ with a l₂ IH generalizing l₁
[GOAL]
case intro.intro.nil
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂ : List Bool
f✝ : Vector Bool (List.length l₂) → Stmt Bool Λ' σ
l₁ : List Bool
f : Vector Bool (List.length []) → Stmt Bool Λ' σ
⊢ stepAux (readAux (List.length []) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append [] R')) =
    stepAux (f { val := [], property := (_ : List.length [] = List.length []) }) v
      (Tape.mk' (ListBlank.append (List.reverseAux [] l₁) L') R')
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.cons
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (a :: l₂)) → Stmt Bool Λ' σ
⊢ stepAux (readAux (List.length (a :: l₂)) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append (a :: l₂) R')) =
    stepAux (f { val := a :: l₂, property := (_ : List.length (a :: l₂) = List.length (a :: l₂)) }) v
      (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
trans stepAux (readAux l₂.length fun v ↦ f (a ::ᵥ v)) v (Tape.mk' ((L'.append l₁).cons a) (R'.append l₂))
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (a :: l₂)) → Stmt Bool Λ' σ
⊢ stepAux (readAux (List.length (a :: l₂)) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append (a :: l₂) R')) =
    stepAux (readAux (List.length l₂) fun v => f (a ::ᵥ v)) v
      (Tape.mk' (ListBlank.cons a (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
[PROOFSTEP]
dsimp [readAux, stepAux]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (a :: l₂)) → Stmt Bool Λ' σ
⊢ (bif ListBlank.head (ListBlank.cons a (ListBlank.append l₂ R')) then
      stepAux (readAux (List.length l₂) fun v => f (true ::ᵥ v)) v
        (Tape.move Dir.right (Tape.mk' (ListBlank.append l₁ L') (ListBlank.cons a (ListBlank.append l₂ R'))))
    else
      stepAux (readAux (List.length l₂) fun v => f (false ::ᵥ v)) v
        (Tape.move Dir.right (Tape.mk' (ListBlank.append l₁ L') (ListBlank.cons a (ListBlank.append l₂ R'))))) =
    stepAux (readAux (List.length l₂) fun v => f (a ::ᵥ v)) v
      (Tape.mk' (ListBlank.cons a (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
[PROOFSTEP]
simp
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (a :: l₂)) → Stmt Bool Λ' σ
⊢ (bif a then
      stepAux (readAux (List.length l₂) fun v => f (true ::ᵥ v)) v
        (Tape.mk' (ListBlank.cons a (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
    else
      stepAux (readAux (List.length l₂) fun v => f (false ::ᵥ v)) v
        (Tape.mk' (ListBlank.cons a (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))) =
    stepAux (readAux (List.length l₂) fun v => f (a ::ᵥ v)) v
      (Tape.mk' (ListBlank.cons a (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
[PROOFSTEP]
cases a
[GOAL]
case false
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (false :: l₂)) → Stmt Bool Λ' σ
⊢ (bif false then
      stepAux (readAux (List.length l₂) fun v => f (true ::ᵥ v)) v
        (Tape.mk' (ListBlank.cons false (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
    else
      stepAux (readAux (List.length l₂) fun v => f (false ::ᵥ v)) v
        (Tape.mk' (ListBlank.cons false (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))) =
    stepAux (readAux (List.length l₂) fun v => f (false ::ᵥ v)) v
      (Tape.mk' (ListBlank.cons false (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
[PROOFSTEP]
rfl
[GOAL]
case true
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (true :: l₂)) → Stmt Bool Λ' σ
⊢ (bif true then
      stepAux (readAux (List.length l₂) fun v => f (true ::ᵥ v)) v
        (Tape.mk' (ListBlank.cons true (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
    else
      stepAux (readAux (List.length l₂) fun v => f (false ::ᵥ v)) v
        (Tape.mk' (ListBlank.cons true (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))) =
    stepAux (readAux (List.length l₂) fun v => f (true ::ᵥ v)) v
      (Tape.mk' (ListBlank.cons true (ListBlank.append l₁ L')) (ListBlank.append l₂ R'))
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (a :: l₂)) → Stmt Bool Λ' σ
⊢ stepAux (readAux (List.length l₂) fun v => f (a ::ᵥ v)) v
      (Tape.mk' (ListBlank.cons a (ListBlank.append l₁ L')) (ListBlank.append l₂ R')) =
    stepAux (f { val := a :: l₂, property := (_ : List.length (a :: l₂) = List.length (a :: l₂)) }) v
      (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
rw [← ListBlank.append, IH]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
v : σ
L' R' : ListBlank Bool
l₁✝ l₂✝ : List Bool
f✝ : Vector Bool (List.length l₂✝) → Stmt Bool Λ' σ
a : Bool
l₂ : List Bool
IH :
  ∀ (l₁ : List Bool) (f : Vector Bool (List.length l₂) → Stmt Bool Λ' σ),
    stepAux (readAux (List.length l₂) f) v (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) =
      stepAux (f { val := l₂, property := (_ : List.length l₂ = List.length l₂) }) v
        (Tape.mk' (ListBlank.append (List.reverseAux l₂ l₁) L') R')
l₁ : List Bool
f : Vector Bool (List.length (a :: l₂)) → Stmt Bool Λ' σ
⊢ stepAux (f (a ::ᵥ { val := l₂, property := (_ : List.length l₂ = List.length l₂) })) v
      (Tape.mk' (ListBlank.append (List.reverseAux l₂ (a :: l₁)) L') R') =
    stepAux (f { val := a :: l₂, property := (_ : List.length (a :: l₂) = List.length (a :: l₂)) }) v
      (Tape.mk' (ListBlank.append (List.reverseAux (a :: l₂) l₁) L') R')
[PROOFSTEP]
rfl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
l₁ : Option Λ
v : σ
T : Tape Γ
⊢ FRespects (step (tr enc dec M)) (fun c₁ => trCfg enc enc₀ c₁) (trCfg enc enc₀ { l := l₁, var := v, Tape := T })
    (step M { l := l₁, var := v, Tape := T })
[PROOFSTEP]
obtain ⟨L, R, rfl⟩ := T.exists_mk'
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
l₁ : Option Λ
v : σ
L R : ListBlank Γ
⊢ FRespects (step (tr enc dec M)) (fun c₁ => trCfg enc enc₀ c₁)
    (trCfg enc enc₀ { l := l₁, var := v, Tape := Tape.mk' L R }) (step M { l := l₁, var := v, Tape := Tape.mk' L R })
[PROOFSTEP]
cases' l₁ with l₁
[GOAL]
case intro.intro.none
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L R : ListBlank Γ
⊢ FRespects (step (tr enc dec M)) (fun c₁ => trCfg enc enc₀ c₁)
    (trCfg enc enc₀ { l := none, var := v, Tape := Tape.mk' L R })
    (step M { l := none, var := v, Tape := Tape.mk' L R })
[PROOFSTEP]
exact rfl
[GOAL]
case intro.intro.some
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L R : ListBlank Γ
l₁ : Λ
⊢ FRespects (step (tr enc dec M)) (fun c₁ => trCfg enc enc₀ c₁)
    (trCfg enc enc₀ { l := some l₁, var := v, Tape := Tape.mk' L R })
    (step M { l := some l₁, var := v, Tape := Tape.mk' L R })
[PROOFSTEP]
suffices
  ∀ q R,
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
  by
  refine' TransGen.head' rfl _
  rw [trTape_mk']
  exact this _ R
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L R : ListBlank Γ
l₁ : Λ
this :
  ∀ (q : Stmt₁) (R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
⊢ FRespects (step (tr enc dec M)) (fun c₁ => trCfg enc enc₀ c₁)
    (trCfg enc enc₀ { l := some l₁, var := v, Tape := Tape.mk' L R })
    (step M { l := some l₁, var := v, Tape := Tape.mk' L R })
[PROOFSTEP]
refine' TransGen.head' rfl _
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L R : ListBlank Γ
l₁ : Λ
this :
  ∀ (q : Stmt₁) (R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
⊢ ReflTransGen (fun a b => b ∈ step (tr enc dec M) a)
    (stepAux (tr enc dec M (Λ'.normal l₁)) v (trTape enc₀ (Tape.mk' L R)))
    ((fun c₁ => trCfg enc enc₀ c₁) (stepAux (M l₁) v (Tape.mk' L R)))
[PROOFSTEP]
rw [trTape_mk']
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L R : ListBlank Γ
l₁ : Λ
this :
  ∀ (q : Stmt₁) (R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
⊢ ReflTransGen (fun a b => b ∈ step (tr enc dec M) a) (stepAux (tr enc dec M (Λ'.normal l₁)) v (trTape' enc₀ L R))
    ((fun c₁ => trCfg enc enc₀ c₁) (stepAux (M l₁) v (Tape.mk' L R)))
[PROOFSTEP]
exact this _ R
[GOAL]
case intro.intro.some
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L R : ListBlank Γ
l₁ : Λ
⊢ ∀ (q : Stmt₁) (R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
[PROOFSTEP]
clear R l₁
[GOAL]
case intro.intro.some
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L : ListBlank Γ
⊢ ∀ (q : Stmt₁) (R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
[PROOFSTEP]
intro q R
[GOAL]
case intro.intro.some
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v : σ
L : ListBlank Γ
q : Stmt₁
R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
[PROOFSTEP]
induction' q generalizing v L R
[GOAL]
case intro.intro.some.move
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝¹ : Dir
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.move a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.move a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.write
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.write a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.write a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.load
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.load a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.load a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝¹) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝¹ v (Tape.mk' L R)))
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.branch a✝² a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝ : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto a✝) v (Tape.mk' L R)))
case intro.intro.some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case move d q IH =>
  cases d <;>
      simp only [trNormal, iterate, stepAux_move, stepAux, ListBlank.head_cons, Tape.move_left_mk',
        ListBlank.cons_head_tail, ListBlank.tail_cons, trTape'_move_left enc0, trTape'_move_right enc0] <;>
    apply IH
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
d : Dir
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.move d q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.move d q) v (Tape.mk' L R)))
[PROOFSTEP]
case move d q IH =>
  cases d <;>
      simp only [trNormal, iterate, stepAux_move, stepAux, ListBlank.head_cons, Tape.move_left_mk',
        ListBlank.cons_head_tail, ListBlank.tail_cons, trTape'_move_left enc0, trTape'_move_right enc0] <;>
    apply IH
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
d : Dir
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.move d q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.move d q) v (Tape.mk' L R)))
[PROOFSTEP]
cases d
[GOAL]
case left
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.move Dir.left q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.move Dir.left q) v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, iterate, stepAux_move, stepAux, ListBlank.head_cons, Tape.move_left_mk', ListBlank.cons_head_tail,
  ListBlank.tail_cons, trTape'_move_left enc0, trTape'_move_right enc0]
[GOAL]
case right
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.move Dir.right q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.move Dir.right q) v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, iterate, stepAux_move, stepAux, ListBlank.head_cons, Tape.move_left_mk', ListBlank.cons_head_tail,
  ListBlank.tail_cons, trTape'_move_left enc0, trTape'_move_right enc0]
[GOAL]
case left
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (stepAux (trNormal dec q) v (trTape' enc0 (ListBlank.tail L) (ListBlank.cons (ListBlank.head L) R)))
    (trCfg enc enc0 (stepAux q v (Tape.mk' (ListBlank.tail L) (ListBlank.cons (ListBlank.head L) R))))
[PROOFSTEP]
apply IH
[GOAL]
case right
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (stepAux (trNormal dec q) v (trTape' enc0 (ListBlank.cons (ListBlank.head R) L) (ListBlank.tail R)))
    (trCfg enc enc0 (stepAux q v (Tape.move Dir.right (Tape.mk' L R))))
[PROOFSTEP]
apply IH
[GOAL]
case intro.intro.some.write
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.write a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.write a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.load
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.load a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.load a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝¹) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝¹ v (Tape.mk' L R)))
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.branch a✝² a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝ : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto a✝) v (Tape.mk' L R)))
case intro.intro.some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case write f q IH =>
  simp only [trNormal, stepAux_read dec enc0 encdec, stepAux]
  refine' ReflTransGen.head rfl _
  obtain ⟨a, R, rfl⟩ := R.exists_cons
  rw [tr, Tape.mk'_head, stepAux_write, ListBlank.head_cons, stepAux_move, trTape'_move_left enc0, ListBlank.head_cons,
    ListBlank.tail_cons, Tape.write_mk']
  apply IH
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
f : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.write f q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.write f q) v (Tape.mk' L R)))
[PROOFSTEP]
case write f q IH =>
  simp only [trNormal, stepAux_read dec enc0 encdec, stepAux]
  refine' ReflTransGen.head rfl _
  obtain ⟨a, R, rfl⟩ := R.exists_cons
  rw [tr, Tape.mk'_head, stepAux_write, ListBlank.head_cons, stepAux_move, trTape'_move_left enc0, ListBlank.head_cons,
    ListBlank.tail_cons, Tape.write_mk']
  apply IH
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
f : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.write f q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.write f q) v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, stepAux_read dec enc0 encdec, stepAux]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
f : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) { l := some (Λ'.write (f (ListBlank.head R) v) q), var := v, Tape := trTape' enc0 L R }
    (trCfg enc enc0 (stepAux q v (Tape.write (f (Tape.mk' L R).head v) (Tape.mk' L R))))
[PROOFSTEP]
refine' ReflTransGen.head rfl _
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
f : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ ReflTransGen (fun a b => b ∈ step (tr enc dec M) a)
    (stepAux (tr enc dec M (Λ'.write (f (ListBlank.head R) v) q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux q v (Tape.write (f (Tape.mk' L R).head v) (Tape.mk' L R))))
[PROOFSTEP]
obtain ⟨a, R, rfl⟩ := R.exists_cons
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
f : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
⊢ ReflTransGen (fun a b => b ∈ step (tr enc dec M) a)
    (stepAux (tr enc dec M (Λ'.write (f (ListBlank.head (ListBlank.cons a R)) v) q)) v
      (trTape' enc0 L (ListBlank.cons a R)))
    (trCfg enc enc0
      (stepAux q v (Tape.write (f (Tape.mk' L (ListBlank.cons a R)).head v) (Tape.mk' L (ListBlank.cons a R)))))
[PROOFSTEP]
rw [tr, Tape.mk'_head, stepAux_write, ListBlank.head_cons, stepAux_move, trTape'_move_left enc0, ListBlank.head_cons,
  ListBlank.tail_cons, Tape.write_mk']
[GOAL]
case intro.intro
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
f : Γ → σ → Γ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L : ListBlank Γ
a : Γ
R : ListBlank Γ
⊢ ReflTransGen (fun a b => b ∈ step (tr enc dec M) a)
    (stepAux (trNormal dec q) v (trTape' enc0 L (ListBlank.cons (f a v) R)))
    (trCfg enc enc0 (stepAux q v (Tape.mk' L (ListBlank.cons (f a v) R))))
[PROOFSTEP]
apply IH
[GOAL]
case intro.intro.some.load
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.load a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.load a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝¹) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝¹ v (Tape.mk' L R)))
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.branch a✝² a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝ : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto a✝) v (Tape.mk' L R)))
case intro.intro.some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case load a q IH =>
  simp only [trNormal, stepAux_read dec enc0 encdec]
  apply IH
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.load a q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.load a q) v (Tape.mk' L R)))
[PROOFSTEP]
case load a q IH =>
  simp only [trNormal, stepAux_read dec enc0 encdec]
  apply IH
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.load a q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.load a q) v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, stepAux_read dec enc0 encdec]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a : Γ → σ → σ
q : Stmt₁
IH :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (stepAux (Stmt.load (fun x s => a (ListBlank.head R) s) (trNormal dec q)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.load a q) v (Tape.mk' L R)))
[PROOFSTEP]
apply IH
[GOAL]
case intro.intro.some.branch
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝¹) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝¹ v (Tape.mk' L R)))
a_ih✝ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec a✝) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux a✝ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.branch a✝² a✝¹ a✝) v (Tape.mk' L R)))
case intro.intro.some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝ : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto a✝) v (Tape.mk' L R)))
case intro.intro.some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  simp only [trNormal, stepAux_read dec enc0 encdec, stepAux]
  cases p R.head v <;> [apply IH₂; apply IH₁]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₁) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₁ v (Tape.mk' L R)))
IH₂ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₂) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₂ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.branch p q₁ q₂)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.branch p q₁ q₂) v (Tape.mk' L R)))
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  simp only [trNormal, stepAux_read dec enc0 encdec, stepAux]
  cases p R.head v <;> [apply IH₂; apply IH₁]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₁) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₁ v (Tape.mk' L R)))
IH₂ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₂) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₂ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.branch p q₁ q₂)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.branch p q₁ q₂) v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, stepAux_read dec enc0 encdec, stepAux]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₁) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₁ v (Tape.mk' L R)))
IH₂ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₂) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₂ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (bif p (ListBlank.head R) v then stepAux (trNormal dec q₁) v (trTape' enc0 L R)
    else stepAux (trNormal dec q₂) v (trTape' enc0 L R))
    (trCfg enc enc0 (bif p (Tape.mk' L R).head v then stepAux q₁ v (Tape.mk' L R) else stepAux q₂ v (Tape.mk' L R)))
[PROOFSTEP]
cases p R.head v <;> [apply IH₂; apply IH₁]
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₁) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₁ v (Tape.mk' L R)))
IH₂ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₂) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₂ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (bif p (ListBlank.head R) v then stepAux (trNormal dec q₁) v (trTape' enc0 L R)
    else stepAux (trNormal dec q₂) v (trTape' enc0 L R))
    (trCfg enc enc0 (bif p (Tape.mk' L R).head v then stepAux q₁ v (Tape.mk' L R) else stepAux q₂ v (Tape.mk' L R)))
[PROOFSTEP]
cases p R.head v
[GOAL]
case false
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₁) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₁ v (Tape.mk' L R)))
IH₂ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₂) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₂ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (bif false then stepAux (trNormal dec q₁) v (trTape' enc0 L R) else stepAux (trNormal dec q₂) v (trTape' enc0 L R))
    (trCfg enc enc0 (bif false then stepAux q₁ v (Tape.mk' L R) else stepAux q₂ v (Tape.mk' L R)))
[PROOFSTEP]
apply IH₂
[GOAL]
case true
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₁) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₁ v (Tape.mk' L R)))
IH₂ :
  ∀ (v : σ) (L R : ListBlank Γ),
    Reaches (step (tr enc dec M)) (stepAux (trNormal dec q₂) v (trTape' enc0 L R))
      (trCfg enc enc0 (stepAux q₂ v (Tape.mk' L R)))
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M))
    (bif true then stepAux (trNormal dec q₁) v (trTape' enc0 L R) else stepAux (trNormal dec q₂) v (trTape' enc0 L R))
    (trCfg enc enc0 (bif true then stepAux q₁ v (Tape.mk' L R) else stepAux q₂ v (Tape.mk' L R)))
[PROOFSTEP]
apply IH₁
[GOAL]
case intro.intro.some.goto
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
a✝ : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto a✝)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto a✝) v (Tape.mk' L R)))
case intro.intro.some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case goto l =>
  simp only [trNormal, stepAux_read dec enc0 encdec, stepAux, trCfg, trTape_mk']
  apply ReflTransGen.refl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
l : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto l)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto l) v (Tape.mk' L R)))
[PROOFSTEP]
case goto l =>
  simp only [trNormal, stepAux_read dec enc0 encdec, stepAux, trCfg, trTape_mk']
  apply ReflTransGen.refl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
l : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec (Stmt.goto l)) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux (Stmt.goto l) v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, stepAux_read dec enc0 encdec, stepAux, trCfg, trTape_mk']
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
l : Γ → σ → Λ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) { l := some (Λ'.normal (l (ListBlank.head R) v)), var := v, Tape := trTape' enc0 L R }
    { l := Option.map Λ'.normal (some (l (Tape.mk' L R).head v)), var := v, Tape := trTape' enc0 L R }
[PROOFSTEP]
apply ReflTransGen.refl
[GOAL]
case intro.intro.some.halt
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case
  halt =>
  simp only [trNormal, stepAux, trCfg, stepAux_move, trTape'_move_left enc0, trTape'_move_right enc0, trTape_mk']
  apply ReflTransGen.refl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
case
  halt =>
  simp only [trNormal, stepAux, trCfg, stepAux_move, trTape'_move_left enc0, trTape'_move_right enc0, trTape_mk']
  apply ReflTransGen.refl
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) (stepAux (trNormal dec Stmt.halt) v (trTape' enc0 L R))
    (trCfg enc enc0 (stepAux Stmt.halt v (Tape.mk' L R)))
[PROOFSTEP]
simp only [trNormal, stepAux, trCfg, stepAux_move, trTape'_move_left enc0, trTape'_move_right enc0, trTape_mk']
[GOAL]
Γ : Type u_1
inst✝² : Inhabited Γ
Λ : Type u_2
inst✝¹ : Inhabited Λ
σ : Type u_3
inst✝ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
enc₀ : enc default = Vector.replicate n false
x✝ : Cfg₁
v✝ : σ
L✝ R✝ : ListBlank Γ
v : σ
L R : ListBlank Γ
⊢ Reaches (step (tr enc dec M)) { l := none, var := v, Tape := trTape' enc0 L R }
    { l := Option.map Λ'.normal none, var := v, Tape := trTape' enc0 L R }
[PROOFSTEP]
apply ReflTransGen.refl
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (tr enc dec M q)
[PROOFSTEP]
suffices
  ∀ q,
    SupportsStmt S q →
      (∀ q' ∈ writes q, q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ q' ∈ writes q, SupportsStmt (trSupp M S) (tr enc dec M q')
  by
  rcases Finset.mem_biUnion.1 h with ⟨l, hl, h⟩
  have := this _ (ss.2 _ hl) fun q' hq ↦ Finset.mem_biUnion.2 ⟨_, hl, Finset.mem_insert_of_mem hq⟩
  rcases Finset.mem_insert.1 h with (rfl | h)
  exacts [this.1, this.2 _ h]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
this :
  ∀ (q : Stmt₁),
    SupportsStmt S q →
      (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧
          ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (tr enc dec M q)
[PROOFSTEP]
rcases Finset.mem_biUnion.1 h with ⟨l, hl, h⟩
[GOAL]
case intro.intro
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h✝ : q ∈ trSupp M S
this :
  ∀ (q : Stmt₁),
    SupportsStmt S q →
      (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧
          ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
l : Λ
hl : l ∈ S
h : q ∈ insert (Λ'.normal l) (writes (M l))
⊢ SupportsStmt (trSupp M S) (tr enc dec M q)
[PROOFSTEP]
have := this _ (ss.2 _ hl) fun q' hq ↦ Finset.mem_biUnion.2 ⟨_, hl, Finset.mem_insert_of_mem hq⟩
[GOAL]
case intro.intro
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h✝ : q ∈ trSupp M S
this✝ :
  ∀ (q : Stmt₁),
    SupportsStmt S q →
      (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧
          ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
l : Λ
hl : l ∈ S
h : q ∈ insert (Λ'.normal l) (writes (M l))
this :
  SupportsStmt (trSupp M S) (trNormal dec (M l)) ∧
    ∀ (q' : Λ'), q' ∈ writes (M l) → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (tr enc dec M q)
[PROOFSTEP]
rcases Finset.mem_insert.1 h with (rfl | h)
[GOAL]
case intro.intro.inl
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
this✝ :
  ∀ (q : Stmt₁),
    SupportsStmt S q →
      (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧
          ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
l : Λ
hl : l ∈ S
this :
  SupportsStmt (trSupp M S) (trNormal dec (M l)) ∧
    ∀ (q' : Λ'), q' ∈ writes (M l) → SupportsStmt (trSupp M S) (tr enc dec M q')
h✝ : Λ'.normal l ∈ trSupp M S
h : Λ'.normal l ∈ insert (Λ'.normal l) (writes (M l))
⊢ SupportsStmt (trSupp M S) (tr enc dec M (Λ'.normal l))
case intro.intro.inr
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h✝¹ : q ∈ trSupp M S
this✝ :
  ∀ (q : Stmt₁),
    SupportsStmt S q →
      (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧
          ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
l : Λ
hl : l ∈ S
h✝ : q ∈ insert (Λ'.normal l) (writes (M l))
this :
  SupportsStmt (trSupp M S) (trNormal dec (M l)) ∧
    ∀ (q' : Λ'), q' ∈ writes (M l) → SupportsStmt (trSupp M S) (tr enc dec M q')
h : q ∈ writes (M l)
⊢ SupportsStmt (trSupp M S) (tr enc dec M q)
[PROOFSTEP]
exacts [this.1, this.2 _ h]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
⊢ ∀ (q : Stmt₁),
    SupportsStmt S q →
      (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
        SupportsStmt (trSupp M S) (trNormal dec q) ∧
          ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
intro q hs hw
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
q : Stmt₁
hs : SupportsStmt S q
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
induction q
[GOAL]
case move
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝¹ : Dir
a✝ : Stmt₁
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.move a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.move a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.move a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case write
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.write a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.write a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.write a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case load
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.load a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.load a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.load a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case branch
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  SupportsStmt S a✝¹ →
    (∀ (q' : Λ'), q' ∈ writes a✝¹ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝¹) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝¹ → SupportsStmt (trSupp M S) (tr enc dec M q')
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch a✝² a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case goto
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝ : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case move d q IH =>
  unfold writes at hw ⊢
  replace IH := IH hs hw; refine' ⟨_, IH.2⟩
  cases d <;> simp only [trNormal, iterate, supportsStmt_move, IH]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
d : Dir
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.move d q)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.move d q) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move d q)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.move d q) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case move d q IH =>
  unfold writes at hw ⊢
  replace IH := IH hs hw; refine' ⟨_, IH.2⟩
  cases d <;> simp only [trNormal, iterate, supportsStmt_move, IH]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
d : Dir
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.move d q)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.move d q) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move d q)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.move d q) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
unfold writes at hw ⊢
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
d : Dir
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.move d q)
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move d q)) ∧
    ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
replace IH := IH hs hw
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
d : Dir
q : Stmt₁
hs : SupportsStmt S (Stmt.move d q)
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move d q)) ∧
    ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
refine' ⟨_, IH.2⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
d : Dir
q : Stmt₁
hs : SupportsStmt S (Stmt.move d q)
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move d q))
[PROOFSTEP]
cases d
[GOAL]
case left
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
q : Stmt₁
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.move Dir.left q)
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move Dir.left q))
[PROOFSTEP]
simp only [trNormal, iterate, supportsStmt_move, IH]
[GOAL]
case right
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
q : Stmt₁
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.move Dir.right q)
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.move Dir.right q))
[PROOFSTEP]
simp only [trNormal, iterate, supportsStmt_move, IH]
[GOAL]
case write
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝¹ : Γ → σ → Γ
a✝ : Stmt₁
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.write a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.write a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.write a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case load
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.load a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.load a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.load a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case branch
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  SupportsStmt S a✝¹ →
    (∀ (q' : Λ'), q' ∈ writes a✝¹ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝¹) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝¹ → SupportsStmt (trSupp M S) (tr enc dec M q')
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch a✝² a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case goto
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝ : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case write f q IH =>
  unfold writes at hw ⊢
  simp only [Finset.mem_image, Finset.mem_union, Finset.mem_univ, exists_prop, true_and_iff] at hw ⊢
  replace IH := IH hs fun q hq ↦ hw q (Or.inr hq)
  refine' ⟨supportsStmt_read _ fun a _ s ↦ hw _ (Or.inl ⟨_, rfl⟩), fun q' hq ↦ _⟩
  rcases hq with (⟨a, q₂, rfl⟩ | hq)
  · simp only [tr, supportsStmt_write, supportsStmt_move, IH.1]
  · exact IH.2 _ hq
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.write f q) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write f q)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.write f q) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case write f q IH =>
  unfold writes at hw ⊢
  simp only [Finset.mem_image, Finset.mem_union, Finset.mem_univ, exists_prop, true_and_iff] at hw ⊢
  replace IH := IH hs fun q hq ↦ hw q (Or.inr hq)
  refine' ⟨supportsStmt_read _ fun a _ s ↦ hw _ (Or.inl ⟨_, rfl⟩), fun q' hq ↦ _⟩
  rcases hq with (⟨a, q₂, rfl⟩ | hq)
  · simp only [tr, supportsStmt_write, supportsStmt_move, IH.1]
  · exact IH.2 _ hq
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.write f q) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write f q)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.write f q) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
unfold writes at hw ⊢
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), q' ∈ Finset.image (fun a => Λ'.write a q) Finset.univ ∪ writes q → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write f q)) ∧
    ∀ (q' : Λ'),
      q' ∈ Finset.image (fun a => Λ'.write a q) Finset.univ ∪ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
simp only [Finset.mem_image, Finset.mem_union, Finset.mem_univ, exists_prop, true_and_iff] at hw ⊢
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write f q)) ∧
    ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
replace IH := IH hs fun q hq ↦ hw q (Or.inr hq)
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.write f q)) ∧
    ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
refine' ⟨supportsStmt_read _ fun a _ s ↦ hw _ (Or.inl ⟨_, rfl⟩), fun q' hq ↦ _⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
q' : Λ'
hq : (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q
⊢ SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
rcases hq with (⟨a, q₂, rfl⟩ | hq)
[GOAL]
case inl.intro.refl
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
a : Γ
⊢ SupportsStmt (trSupp M S) (tr enc dec M (Λ'.write a q))
[PROOFSTEP]
simp only [tr, supportsStmt_write, supportsStmt_move, IH.1]
[GOAL]
case inr
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
f : Γ → σ → Γ
q : Stmt₁
hs : SupportsStmt S (Stmt.write f q)
hw : ∀ (q' : Λ'), (∃ a, Λ'.write a q = q') ∨ q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
q' : Λ'
hq : q' ∈ writes q
⊢ SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
exact IH.2 _ hq
[GOAL]
case load
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝¹ : Γ → σ → σ
a✝ : Stmt₁
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.load a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.load a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.load a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case branch
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  SupportsStmt S a✝¹ →
    (∀ (q' : Λ'), q' ∈ writes a✝¹ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝¹) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝¹ → SupportsStmt (trSupp M S) (tr enc dec M q')
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch a✝² a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case goto
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝ : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case load a q IH =>
  unfold writes at hw ⊢
  replace IH := IH hs hw
  refine' ⟨supportsStmt_read _ fun _ ↦ IH.1, IH.2⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
a : Γ → σ → σ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.load a q)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.load a q) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a q)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.load a q) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case load a q IH =>
  unfold writes at hw ⊢
  replace IH := IH hs hw
  refine' ⟨supportsStmt_read _ fun _ ↦ IH.1, IH.2⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
a : Γ → σ → σ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.load a q)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.load a q) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a q)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.load a q) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
unfold writes at hw ⊢
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
a : Γ → σ → σ
q : Stmt₁
IH :
  SupportsStmt S q →
    (∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q) ∧
        ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.load a q)
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a q)) ∧
    ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
replace IH := IH hs hw
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q✝ : Λ'
h : q✝ ∈ trSupp M S
a : Γ → σ → σ
q : Stmt₁
hs : SupportsStmt S (Stmt.load a q)
hw : ∀ (q' : Λ'), q' ∈ writes q → q' ∈ trSupp M S
IH :
  SupportsStmt (trSupp M S) (trNormal dec q) ∧ ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.load a q)) ∧
    ∀ (q' : Λ'), q' ∈ writes q → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
refine' ⟨supportsStmt_read _ fun _ ↦ IH.1, IH.2⟩
[GOAL]
case branch
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝² : Γ → σ → Bool
a✝¹ a✝ : Stmt₁
a_ih✝¹ :
  SupportsStmt S a✝¹ →
    (∀ (q' : Λ'), q' ∈ writes a✝¹ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝¹) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝¹ → SupportsStmt (trSupp M S) (tr enc dec M q')
a_ih✝ :
  SupportsStmt S a✝ →
    (∀ (q' : Λ'), q' ∈ writes a✝ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec a✝) ∧
        ∀ (q' : Λ'), q' ∈ writes a✝ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch a✝² a✝¹ a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch a✝² a✝¹ a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.branch a✝² a✝¹ a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case goto
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝ : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  unfold writes at hw ⊢
  simp only [Finset.mem_union] at hw ⊢
  replace IH₁ := IH₁ hs.1 fun q hq ↦ hw q (Or.inl hq)
  replace IH₂ := IH₂ hs.2 fun q hq ↦ hw q (Or.inr hq)
  exact ⟨supportsStmt_read _ fun _ ↦ ⟨IH₁.1, IH₂.1⟩, fun q ↦ Or.rec (IH₁.2 _) (IH₂.2 _)⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  SupportsStmt S q₁ →
    (∀ (q' : Λ'), q' ∈ writes q₁ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₁) ∧
        ∀ (q' : Λ'), q' ∈ writes q₁ → SupportsStmt (trSupp M S) (tr enc dec M q')
IH₂ :
  SupportsStmt S q₂ →
    (∀ (q' : Λ'), q' ∈ writes q₂ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₂) ∧
        ∀ (q' : Λ'), q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch p q₁ q₂)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.branch p q₁ q₂) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch p q₁ q₂)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.branch p q₁ q₂) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case branch p q₁ q₂ IH₁ IH₂ =>
  unfold writes at hw ⊢
  simp only [Finset.mem_union] at hw ⊢
  replace IH₁ := IH₁ hs.1 fun q hq ↦ hw q (Or.inl hq)
  replace IH₂ := IH₂ hs.2 fun q hq ↦ hw q (Or.inr hq)
  exact ⟨supportsStmt_read _ fun _ ↦ ⟨IH₁.1, IH₂.1⟩, fun q ↦ Or.rec (IH₁.2 _) (IH₂.2 _)⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  SupportsStmt S q₁ →
    (∀ (q' : Λ'), q' ∈ writes q₁ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₁) ∧
        ∀ (q' : Λ'), q' ∈ writes q₁ → SupportsStmt (trSupp M S) (tr enc dec M q')
IH₂ :
  SupportsStmt S q₂ →
    (∀ (q' : Λ'), q' ∈ writes q₂ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₂) ∧
        ∀ (q' : Λ'), q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch p q₁ q₂)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.branch p q₁ q₂) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch p q₁ q₂)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.branch p q₁ q₂) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
unfold writes at hw ⊢
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  SupportsStmt S q₁ →
    (∀ (q' : Λ'), q' ∈ writes q₁ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₁) ∧
        ∀ (q' : Λ'), q' ∈ writes q₁ → SupportsStmt (trSupp M S) (tr enc dec M q')
IH₂ :
  SupportsStmt S q₂ →
    (∀ (q' : Λ'), q' ∈ writes q₂ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₂) ∧
        ∀ (q' : Λ'), q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch p q₁ q₂)
hw : ∀ (q' : Λ'), q' ∈ writes q₁ ∪ writes q₂ → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch p q₁ q₂)) ∧
    ∀ (q' : Λ'), q' ∈ writes q₁ ∪ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
simp only [Finset.mem_union] at hw ⊢
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₁ :
  SupportsStmt S q₁ →
    (∀ (q' : Λ'), q' ∈ writes q₁ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₁) ∧
        ∀ (q' : Λ'), q' ∈ writes q₁ → SupportsStmt (trSupp M S) (tr enc dec M q')
IH₂ :
  SupportsStmt S q₂ →
    (∀ (q' : Λ'), q' ∈ writes q₂ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₂) ∧
        ∀ (q' : Λ'), q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch p q₁ q₂)
hw : ∀ (q' : Λ'), q' ∈ writes q₁ ∨ q' ∈ writes q₂ → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch p q₁ q₂)) ∧
    ∀ (q' : Λ'), q' ∈ writes q₁ ∨ q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
replace IH₁ := IH₁ hs.1 fun q hq ↦ hw q (Or.inl hq)
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
IH₂ :
  SupportsStmt S q₂ →
    (∀ (q' : Λ'), q' ∈ writes q₂ → q' ∈ trSupp M S) →
      SupportsStmt (trSupp M S) (trNormal dec q₂) ∧
        ∀ (q' : Λ'), q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
hs : SupportsStmt S (Stmt.branch p q₁ q₂)
hw : ∀ (q' : Λ'), q' ∈ writes q₁ ∨ q' ∈ writes q₂ → q' ∈ trSupp M S
IH₁ :
  SupportsStmt (trSupp M S) (trNormal dec q₁) ∧
    ∀ (q' : Λ'), q' ∈ writes q₁ → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch p q₁ q₂)) ∧
    ∀ (q' : Λ'), q' ∈ writes q₁ ∨ q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
replace IH₂ := IH₂ hs.2 fun q hq ↦ hw q (Or.inr hq)
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
p : Γ → σ → Bool
q₁ q₂ : Stmt₁
hs : SupportsStmt S (Stmt.branch p q₁ q₂)
hw : ∀ (q' : Λ'), q' ∈ writes q₁ ∨ q' ∈ writes q₂ → q' ∈ trSupp M S
IH₁ :
  SupportsStmt (trSupp M S) (trNormal dec q₁) ∧
    ∀ (q' : Λ'), q' ∈ writes q₁ → SupportsStmt (trSupp M S) (tr enc dec M q')
IH₂ :
  SupportsStmt (trSupp M S) (trNormal dec q₂) ∧
    ∀ (q' : Λ'), q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.branch p q₁ q₂)) ∧
    ∀ (q' : Λ'), q' ∈ writes q₁ ∨ q' ∈ writes q₂ → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
exact ⟨supportsStmt_read _ fun _ ↦ ⟨IH₁.1, IH₂.1⟩, fun q ↦ Or.rec (IH₁.2 _) (IH₂.2 _)⟩
[GOAL]
case goto
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
a✝ : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto a✝)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto a✝)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto a✝) → SupportsStmt (trSupp M S) (tr enc dec M q')
case halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case goto l =>
  simp only [writes, Finset.not_mem_empty]; refine' ⟨_, fun _ ↦ False.elim⟩
  refine' supportsStmt_read _ fun a _ s ↦ _
  exact Finset.mem_biUnion.2 ⟨_, hs _ _, Finset.mem_insert_self _ _⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
l : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto l)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto l)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case goto l =>
  simp only [writes, Finset.not_mem_empty]; refine' ⟨_, fun _ ↦ False.elim⟩
  refine' supportsStmt_read _ fun a _ s ↦ _
  exact Finset.mem_biUnion.2 ⟨_, hs _ _, Finset.mem_insert_self _ _⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
l : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto l)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto l)) ∧
    ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
simp only [writes, Finset.not_mem_empty]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
l : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto l)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto l)) ∧
    ∀ (q' : Λ'), False → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
refine' ⟨_, fun _ ↦ False.elim⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
l : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto l)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec (Stmt.goto l))
[PROOFSTEP]
refine' supportsStmt_read _ fun a _ s ↦ _
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
l : Γ → σ → Λ
hs : SupportsStmt S (Stmt.goto l)
hw : ∀ (q' : Λ'), q' ∈ writes (Stmt.goto l) → q' ∈ trSupp M S
a : Γ
x✝ : Bool
s : σ
⊢ (fun x s => Λ'.normal (l a s)) x✝ s ∈ trSupp M S
[PROOFSTEP]
exact Finset.mem_biUnion.2 ⟨_, hs _ _, Finset.mem_insert_self _ _⟩
[GOAL]
case halt
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case halt =>
  simp only [writes, Finset.not_mem_empty]; refine' ⟨_, fun _ ↦ False.elim⟩
  simp only [SupportsStmt, supportsStmt_move, trNormal]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
case halt =>
  simp only [writes, Finset.not_mem_empty]; refine' ⟨_, fun _ ↦ False.elim⟩
  simp only [SupportsStmt, supportsStmt_move, trNormal]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧
    ∀ (q' : Λ'), q' ∈ writes Stmt.halt → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
simp only [writes, Finset.not_mem_empty]
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt) ∧ ∀ (q' : Λ'), False → SupportsStmt (trSupp M S) (tr enc dec M q')
[PROOFSTEP]
refine' ⟨_, fun _ ↦ False.elim⟩
[GOAL]
Γ : Type u_1
inst✝³ : Inhabited Γ
Λ : Type u_2
inst✝² : Inhabited Λ
σ : Type u_3
inst✝¹ : Inhabited σ
n : ℕ
enc : Γ → Vector Bool n
dec : Vector Bool n → Γ
enc0 : enc default = Vector.replicate n false
M : Λ → Stmt₁
encdec : ∀ (a : Γ), dec (enc a) = a
inst✝ : Fintype Γ
S : Finset Λ
ss : Supports M S
q : Λ'
h : q ∈ trSupp M S
hs : SupportsStmt S Stmt.halt
hw : ∀ (q' : Λ'), q' ∈ writes Stmt.halt → q' ∈ trSupp M S
⊢ SupportsStmt (trSupp M S) (trNormal dec Stmt.halt)
[PROOFSTEP]
simp only [SupportsStmt, supportsStmt_move, trNormal]
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
⊢ FRespects (TM1.step (tr M)) (fun a => trCfg M a) (trCfg M { q := q, Tape := T }) (TM0.step M { q := q, Tape := T })
[PROOFSTEP]
cases' e : M q T.1 with val
[GOAL]
case none
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
e : M q T.head = none
⊢ FRespects (TM1.step (tr M)) (fun a => trCfg M a) (trCfg M { q := q, Tape := T }) (TM0.step M { q := q, Tape := T })
[PROOFSTEP]
simp only [TM0.step, trCfg, e]
[GOAL]
case none
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
e : M q T.head = none
⊢ FRespects (TM1.step (tr M))
    (fun a =>
      { l := bif Option.isSome (M a.q a.Tape.head) then some (Λ'.normal a.q) else none, var := (), Tape := a.Tape })
    { l := bif Option.isSome none then some (Λ'.normal q) else none, var := (), Tape := T }
    (Option.map
      (fun x =>
        { q := x.fst,
          Tape :=
            match x.snd with
            | TM0.Stmt.move d => Tape.move d T
            | TM0.Stmt.write a => Tape.write a T })
      none)
[PROOFSTEP]
exact Eq.refl none
[GOAL]
case some
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
val : Λ × TM0.Stmt Γ
e : M q T.head = some val
⊢ FRespects (TM1.step (tr M)) (fun a => trCfg M a) (trCfg M { q := q, Tape := T }) (TM0.step M { q := q, Tape := T })
[PROOFSTEP]
cases' val with q' s
[GOAL]
case some.mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
e : M q T.head = some (q', s)
⊢ FRespects (TM1.step (tr M)) (fun a => trCfg M a) (trCfg M { q := q, Tape := T }) (TM0.step M { q := q, Tape := T })
[PROOFSTEP]
simp only [FRespects, TM0.step, trCfg, e, Option.isSome, cond, Option.map_some']
[GOAL]
case some.mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
e : M q T.head = some (q', s)
⊢ Reaches₁ (TM1.step (tr M)) { l := some (Λ'.normal q), var := (), Tape := T }
    {
      l :=
        match
          match
            M q'
              (match s with
                | TM0.Stmt.move d => Tape.move d T
                | TM0.Stmt.write a => Tape.write a T).head with
          | some val => true
          | none => false with
        | true => some (Λ'.normal q')
        | false => none,
      var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
revert e
[GOAL]
case some.mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
⊢ M q T.head = some (q', s) →
    Reaches₁ (TM1.step (tr M)) { l := some (Λ'.normal q), var := (), Tape := T }
      {
        l :=
          match
            match
              M q'
                (match s with
                  | TM0.Stmt.move d => Tape.move d T
                  | TM0.Stmt.write a => Tape.write a T).head with
            | some val => true
            | none => false with
          | true => some (Λ'.normal q')
          | false => none,
        var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
have :
  TM1.step (tr M) ⟨some (Λ'.act s q'), (), T⟩ =
    some
      ⟨some (Λ'.normal q'), (),
        match s with
        | TM0.Stmt.move d => T.move d
        | TM0.Stmt.write a => T.write a⟩ :=
  by cases' s with d a <;> rfl
[GOAL]
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
⊢ TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
cases' s with d a
[GOAL]
case move
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
d : Dir
⊢ TM1.step (tr M) { l := some (Λ'.act (TM0.Stmt.move d) q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match TM0.Stmt.move d with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
rfl
[GOAL]
case write
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
a : Γ
⊢ TM1.step (tr M) { l := some (Λ'.act (TM0.Stmt.write a) q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match TM0.Stmt.write a with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
rfl
[GOAL]
case some.mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
⊢ M q T.head = some (q', s) →
    Reaches₁ (TM1.step (tr M)) { l := some (Λ'.normal q), var := (), Tape := T }
      {
        l :=
          match
            match
              M q'
                (match s with
                  | TM0.Stmt.move d => Tape.move d T
                  | TM0.Stmt.write a => Tape.write a T).head with
            | some val => true
            | none => false with
          | true => some (Λ'.normal q')
          | false => none,
        var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
intro e
[GOAL]
case some.mk
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
⊢ Reaches₁ (TM1.step (tr M)) { l := some (Λ'.normal q), var := (), Tape := T }
    {
      l :=
        match
          match
            M q'
              (match s with
                | TM0.Stmt.move d => Tape.move d T
                | TM0.Stmt.write a => Tape.write a T).head with
          | some val => true
          | none => false with
        | true => some (Λ'.normal q')
        | false => none,
      var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
refine' TransGen.head _ (TransGen.head' this _)
[GOAL]
case some.mk.refine'_1
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
⊢ { l := some (Λ'.act s q'), var := (), Tape := T } ∈ TM1.step (tr M) { l := some (Λ'.normal q), var := (), Tape := T }
[PROOFSTEP]
simp only [TM1.step, TM1.stepAux]
[GOAL]
case some.mk.refine'_1
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
⊢ { l := some (Λ'.act s q'), var := (), Tape := T } ∈
    some
      (bif Option.isNone (M q T.head) then { l := none, var := (), Tape := T }
      else
        {
          l :=
            some
              (match M q T.head with
              | none => default
              | some (q', s) => Λ'.act s q'),
          var := (), Tape := T })
[PROOFSTEP]
rw [e]
[GOAL]
case some.mk.refine'_1
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
⊢ { l := some (Λ'.act s q'), var := (), Tape := T } ∈
    some
      (bif Option.isNone (some (q', s)) then { l := none, var := (), Tape := T }
      else
        {
          l :=
            some
              (match some (q', s) with
              | none => default
              | some (q', s) => Λ'.act s q'),
          var := (), Tape := T })
[PROOFSTEP]
rfl
[GOAL]
case some.mk.refine'_2
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
⊢ ReflTransGen (fun a b => b ∈ TM1.step (tr M) a)
    { l := some (Λ'.normal q'), var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
    {
      l :=
        match
          match
            M q'
              (match s with
                | TM0.Stmt.move d => Tape.move d T
                | TM0.Stmt.write a => Tape.write a T).head with
          | some val => true
          | none => false with
        | true => some (Λ'.normal q')
        | false => none,
      var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
cases e' : M q' _
[GOAL]
case some.mk.refine'_2.none
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
e' :
  M q'
      (match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T).head =
    none
⊢ ReflTransGen (fun a b => b ∈ TM1.step (tr M) a)
    { l := some (Λ'.normal q'), var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
    {
      l :=
        match
          match none with
          | some val => true
          | none => false with
        | true => some (Λ'.normal q')
        | false => none,
      var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
apply ReflTransGen.single
[GOAL]
case some.mk.refine'_2.none.hab
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
e' :
  M q'
      (match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T).head =
    none
⊢ {
      l :=
        match
          match none with
          | some val => true
          | none => false with
        | true => some (Λ'.normal q')
        | false => none,
      var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T } ∈
    TM1.step (tr M)
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
simp only [TM1.step, TM1.stepAux]
[GOAL]
case some.mk.refine'_2.none.hab
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
e' :
  M q'
      (match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T).head =
    none
⊢ { l := none, var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T } ∈
    some
      (bif
          Option.isNone
            (M q'
              (match s with
                | TM0.Stmt.move d => Tape.move d T
                | TM0.Stmt.write a => Tape.write a T).head) then
        { l := none, var := (),
          Tape :=
            match s with
            | TM0.Stmt.move d => Tape.move d T
            | TM0.Stmt.write a => Tape.write a T }
      else
        {
          l :=
            some
              (match
                M q'
                  (match s with
                    | TM0.Stmt.move d => Tape.move d T
                    | TM0.Stmt.write a => Tape.write a T).head with
              | none => default
              | some (q', s) => Λ'.act s q'),
          var := (),
          Tape :=
            match s with
            | TM0.Stmt.move d => Tape.move d T
            | TM0.Stmt.write a => Tape.write a T })
[PROOFSTEP]
rw [e']
[GOAL]
case some.mk.refine'_2.none.hab
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
e' :
  M q'
      (match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T).head =
    none
⊢ { l := none, var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T } ∈
    some
      (bif Option.isNone none then
        { l := none, var := (),
          Tape :=
            match s with
            | TM0.Stmt.move d => Tape.move d T
            | TM0.Stmt.write a => Tape.write a T }
      else
        {
          l :=
            some
              (match none with
              | none => default
              | some (q', s) => Λ'.act s q'),
          var := (),
          Tape :=
            match s with
            | TM0.Stmt.move d => Tape.move d T
            | TM0.Stmt.write a => Tape.write a T })
[PROOFSTEP]
rfl
[GOAL]
case some.mk.refine'_2.some
Γ : Type u_1
inst✝¹ : Inhabited Γ
Λ : Type u_2
inst✝ : Inhabited Λ
M : TM0.Machine Γ Λ
x✝ : Cfg₀
q : Λ
T : Tape Γ
q' : Λ
s : TM0.Stmt Γ
this :
  TM1.step (tr M) { l := some (Λ'.act s q'), var := (), Tape := T } =
    some
      { l := some (Λ'.normal q'), var := (),
        Tape :=
          match s with
          | TM0.Stmt.move d => Tape.move d T
          | TM0.Stmt.write a => Tape.write a T }
e : M q T.head = some (q', s)
val✝ : Λ × TM0.Stmt Γ
e' :
  M q'
      (match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T).head =
    some val✝
⊢ ReflTransGen (fun a b => b ∈ TM1.step (tr M) a)
    { l := some (Λ'.normal q'), var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
    {
      l :=
        match
          match some val✝ with
          | some val => true
          | none => false with
        | true => some (Λ'.normal q')
        | false => none,
      var := (),
      Tape :=
        match s with
        | TM0.Stmt.move d => Tape.move d T
        | TM0.Stmt.write a => Tape.write a T }
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q : Stmt₂
⊢ q ∈ stmts₁ q
[PROOFSTEP]
cases q
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
k✝ : K
a✝¹ : σ → Γ k✝
a✝ : Stmt₂
⊢ push k✝ a✝¹ a✝ ∈ stmts₁ (push k✝ a✝¹ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
k✝ : K
a✝¹ : σ → Option (Γ k✝) → σ
a✝ : Stmt₂
⊢ peek k✝ a✝¹ a✝ ∈ stmts₁ (peek k✝ a✝¹ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
k✝ : K
a✝¹ : σ → Option (Γ k✝) → σ
a✝ : Stmt₂
⊢ pop k✝ a✝¹ a✝ ∈ stmts₁ (pop k✝ a✝¹ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
a✝¹ : σ → σ
a✝ : Stmt₂
⊢ load a✝¹ a✝ ∈ stmts₁ (load a✝¹ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
⊢ branch a✝² a✝¹ a✝ ∈ stmts₁ (branch a✝² a✝¹ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
a✝ : σ → Λ
⊢ goto a✝ ∈ stmts₁ (goto a✝)
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
⊢ halt ∈ stmts₁ halt
[PROOFSTEP]
simp only [Finset.mem_insert_self, Finset.mem_singleton_self, stmts₁]
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
⊢ q₁ ∈ stmts₁ q₂ → stmts₁ q₁ ⊆ stmts₁ q₂
[PROOFSTEP]
intro h₁₂ q₀ h₀₁
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
⊢ q₀ ∈ stmts₁ q₂
[PROOFSTEP]
induction' q₂ with _ _ q IH _ _ q IH _ _ q IH _ q IH
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (push k✝ a✝ q)
⊢ q₀ ∈ stmts₁ (push k✝ a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (peek k✝ a✝ q)
⊢ q₀ ∈ stmts₁ (peek k✝ a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (pop k✝ a✝ q)
⊢ q₀ ∈ stmts₁ (pop k✝ a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ (load a✝ q)
⊢ q₀ ∈ stmts₁ (load a✝ q)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ ∈ stmts₁ (branch a✝² a✝¹ a✝)
⊢ q₀ ∈ stmts₁ (branch a✝² a✝¹ a✝)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ ∈ stmts₁ (goto a✝)
⊢ q₀ ∈ stmts₁ (goto a✝)
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ ∈ stmts₁ halt
⊢ q₀ ∈ stmts₁ halt
[PROOFSTEP]
simp only [stmts₁] at h₁₂ ⊢
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (push k✝ a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ insert (load a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ ∈ {goto a✝}
⊢ q₀ ∈ {goto a✝}
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ ∈ {halt}
⊢ q₀ ∈ {halt}
[PROOFSTEP]
simp only [Finset.mem_insert, Finset.mem_singleton, Finset.mem_union] at h₁₂
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = push k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
iterate 4
  rcases h₁₂ with (rfl | h₁₂)
  · unfold stmts₁ at h₀₁
    exact h₀₁
  · exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = push k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case push.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
h₁₂ : push k✝ a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (push k✝ a✝ q)
IH : push k✝ a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case push.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
h₁₂ : push k✝ a✝ q ∈ stmts₁ q₂
IH : push k✝ a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case push.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (push k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case peek.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
h₁₂ : peek k✝ a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (peek k✝ a✝ q)
IH : peek k✝ a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case peek.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
h₁₂ : peek k✝ a✝ q ∈ stmts₁ q₂
IH : peek k✝ a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case peek.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (peek k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case pop.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
h₁₂ : pop k✝ a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (pop k✝ a✝ q)
IH : pop k✝ a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case pop.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
h₁₂ : pop k✝ a✝ q ∈ stmts₁ q₂
IH : pop k✝ a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case pop.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (pop k✝ a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂)
[GOAL]
case load.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
a✝ : σ → σ
q : Stmt₂
h₁₂ : load a✝ q ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (load a✝ q)
IH : load a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case load.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
a✝ : σ → σ
q : Stmt₂
h₁₂ : load a✝ q ∈ stmts₁ q₂
IH : load a✝ q ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₀₁ : q₀ ∈ insert (load a✝ q) (stmts₁ q)
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
exact h₀₁
[GOAL]
case load.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → q₀ ∈ stmts₁ q
h₁₂ : q₁ ∈ stmts₁ q
⊢ q₀ ∈ insert (load a✝ q) (stmts₁ q)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (IH h₁₂)
[GOAL]
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → q₀ ∈ stmts₁ a✝¹
a_ih✝ : q₁ ∈ stmts₁ a✝ → q₀ ∈ stmts₁ a✝
h₁₂ : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ q₀ ∈ insert (branch a✝² a✝¹ a✝) (stmts₁ a✝¹ ∪ stmts₁ a✝)
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case branch f q₁ q₂ IH₁ IH₂ =>
  rcases h₁₂ with (rfl | h₁₂ | h₁₂)
  · unfold stmts₁ at h₀₁
    exact h₀₁
  · exact Finset.mem_insert_of_mem (Finset.mem_union_left _ (IH₁ h₁₂))
  · exact Finset.mem_insert_of_mem (Finset.mem_union_right _ (IH₂ h₁₂))
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁✝ q₂✝ : Stmt₂
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ = branch f q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
case branch f q₁ q₂ IH₁ IH₂ =>
  rcases h₁₂ with (rfl | h₁₂ | h₁₂)
  · unfold stmts₁ at h₀₁
    exact h₀₁
  · exact Finset.mem_insert_of_mem (Finset.mem_union_left _ (IH₁ h₁₂))
  · exact Finset.mem_insert_of_mem (Finset.mem_union_right _ (IH₂ h₁₂))
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁✝ q₂✝ : Stmt₂
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ = branch f q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
rcases h₁₂ with (rfl | h₁₂ | h₁₂)
[GOAL]
case inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂✝ q₀ : Stmt₂
f : σ → Bool
q₁ q₂ : Stmt₂
h₁₂ : branch f q₁ q₂ ∈ stmts₁ q₂✝
h₀₁ : q₀ ∈ stmts₁ (branch f q₁ q₂)
IH₁ : branch f q₁ q₂ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : branch f q₁ q₂ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
unfold stmts₁ at h₀₁
[GOAL]
case inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂✝ q₀ : Stmt₂
f : σ → Bool
q₁ q₂ : Stmt₂
h₁₂ : branch f q₁ q₂ ∈ stmts₁ q₂✝
IH₁ : branch f q₁ q₂ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : branch f q₁ q₂ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₀₁ : q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
⊢ q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
exact h₀₁
[GOAL]
case inr.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁✝ q₂✝ : Stmt₂
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ ∈ stmts₁ q₁
⊢ q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (Finset.mem_union_left _ (IH₁ h₁₂))
[GOAL]
case inr.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁✝ q₂✝ : Stmt₂
h₁₂✝ : q₁✝ ∈ stmts₁ q₂✝
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → q₀ ∈ stmts₁ q₁
IH₂ : q₁✝ ∈ stmts₁ q₂ → q₀ ∈ stmts₁ q₂
h₁₂ : q₁✝ ∈ stmts₁ q₂
⊢ q₀ ∈ insert (branch f q₁ q₂) (stmts₁ q₁ ∪ stmts₁ q₂)
[PROOFSTEP]
exact Finset.mem_insert_of_mem (Finset.mem_union_right _ (IH₂ h₁₂))
[GOAL]
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
a✝ : σ → Λ
h₁₂ : q₁ = goto a✝
⊢ q₀ ∈ {goto a✝}
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case goto l => subst h₁₂; exact h₀₁
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
l : σ → Λ
h₁₂ : q₁ = goto l
⊢ q₀ ∈ {goto l}
[PROOFSTEP]
case goto l => subst h₁₂; exact h₀₁
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
l : σ → Λ
h₁₂ : q₁ = goto l
⊢ q₀ ∈ {goto l}
[PROOFSTEP]
subst h₁₂
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
l : σ → Λ
h₁₂ : goto l ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ (goto l)
⊢ q₀ ∈ {goto l}
[PROOFSTEP]
exact h₀₁
[GOAL]
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case halt => subst h₁₂; exact h₀₁
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
case halt => subst h₁₂; exact h₀₁
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₁ q₂ : Stmt₂
h₁₂✝ : q₁ ∈ stmts₁ q₂
q₀ : Stmt₂
h₀₁ : q₀ ∈ stmts₁ q₁
h₁₂ : q₁ = halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
subst h₁₂
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
q₂ q₀ : Stmt₂
h₁₂ : halt ∈ stmts₁ q₂
h₀₁ : q₀ ∈ stmts₁ halt
⊢ q₀ ∈ {halt}
[PROOFSTEP]
exact h₀₁
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h : q₁ ∈ stmts₁ q₂
hs : SupportsStmt S q₂
⊢ SupportsStmt S q₁
[PROOFSTEP]
induction' q₂ with _ _ q IH _ _ q IH _ _ q IH _ q IH
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (push k✝ a✝ q)
hs : SupportsStmt S (push k✝ a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (peek k✝ a✝ q)
hs : SupportsStmt S (peek k✝ a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (pop k✝ a✝ q)
hs : SupportsStmt S (pop k✝ a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (load a✝ q)
hs : SupportsStmt S (load a✝ q)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
h : q₁ ∈ stmts₁ (branch a✝² a✝¹ a✝)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
h : q₁ ∈ stmts₁ (goto a✝)
hs : SupportsStmt S (goto a✝)
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
h : q₁ ∈ stmts₁ halt
hs : SupportsStmt S halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
simp only [stmts₁, SupportsStmt, Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] at h hs
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = push k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
iterate 4 rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = push k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case push
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = push k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case push.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂ : Stmt₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
hs : SupportsStmt S q
h : push k✝ a✝ q ∈ stmts₁ q₂
IH : push k✝ a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (push k✝ a✝ q)
⊢ SupportsStmt S (push k✝ a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case push.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case peek
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = peek k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case peek.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂ : Stmt₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
hs : SupportsStmt S q
h : peek k✝ a✝ q ∈ stmts₁ q₂
IH : peek k✝ a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (peek k✝ a✝ q)
⊢ SupportsStmt S (peek k✝ a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case peek.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case pop
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = pop k✝ a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case pop.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂ : Stmt₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
hs : SupportsStmt S q
h : pop k✝ a✝ q ∈ stmts₁ q₂
IH : pop k✝ a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (pop k✝ a✝ q)
⊢ SupportsStmt S (pop k✝ a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case pop.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h) <;> [exact hs; exact IH h hs]
[GOAL]
case load
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ = load a✝ q ∨ q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
rcases h with (rfl | h)
[GOAL]
case load.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂ : Stmt₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
hs : SupportsStmt S q
h : load a✝ q ∈ stmts₁ q₂
IH : load a✝ q ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S (load a✝ q)
⊢ SupportsStmt S (load a✝ q)
[PROOFSTEP]
exact hs
[GOAL]
case load.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → σ
q : Stmt₂
IH : q₁ ∈ stmts₁ q → SupportsStmt S q → SupportsStmt S q₁
hs : SupportsStmt S q
h : q₁ ∈ stmts₁ q
⊢ SupportsStmt S q₁
[PROOFSTEP]
exact IH h hs
[GOAL]
case branch
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : q₁ ∈ stmts₁ a✝¹ → SupportsStmt S a✝¹ → SupportsStmt S q₁
a_ih✝ : q₁ ∈ stmts₁ a✝ → SupportsStmt S a✝ → SupportsStmt S q₁
hs : SupportsStmt S a✝¹ ∧ SupportsStmt S a✝
h : q₁ = branch a✝² a✝¹ a✝ ∨ q₁ ∈ stmts₁ a✝¹ ∨ q₁ ∈ stmts₁ a✝
⊢ SupportsStmt S q₁
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case branch f q₁ q₂ IH₁ IH₂ => rcases h with (rfl | h | h); exacts [hs, IH₁ h hs.1, IH₂ h hs.2]
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁✝ q₂✝ : Stmt₂
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ = branch f q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ SupportsStmt S q₁✝
[PROOFSTEP]
case branch f q₁ q₂ IH₁ IH₂ => rcases h with (rfl | h | h); exacts [hs, IH₁ h hs.1, IH₂ h hs.2]
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁✝ q₂✝ : Stmt₂
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ = branch f q₁ q₂ ∨ q₁✝ ∈ stmts₁ q₁ ∨ q₁✝ ∈ stmts₁ q₂
⊢ SupportsStmt S q₁✝
[PROOFSTEP]
rcases h with (rfl | h | h)
[GOAL]
case inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂✝ : Stmt₂
hs✝ : SupportsStmt S q₂✝
f : σ → Bool
q₁ q₂ : Stmt₂
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : branch f q₁ q₂ ∈ stmts₁ q₂✝
IH₁ : branch f q₁ q₂ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S (branch f q₁ q₂)
IH₂ : branch f q₁ q₂ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S (branch f q₁ q₂)
⊢ SupportsStmt S (branch f q₁ q₂)
case inr.inl
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁✝ q₂✝ : Stmt₂
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ ∈ stmts₁ q₁
⊢ SupportsStmt S q₁✝
case inr.inr
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁✝ q₂✝ : Stmt₂
h✝ : q₁✝ ∈ stmts₁ q₂✝
hs✝ : SupportsStmt S q₂✝
f : σ → Bool
q₁ q₂ : Stmt₂
IH₁ : q₁✝ ∈ stmts₁ q₁ → SupportsStmt S q₁ → SupportsStmt S q₁✝
IH₂ : q₁✝ ∈ stmts₁ q₂ → SupportsStmt S q₂ → SupportsStmt S q₁✝
hs : SupportsStmt S q₁ ∧ SupportsStmt S q₂
h : q₁✝ ∈ stmts₁ q₂
⊢ SupportsStmt S q₁✝
[PROOFSTEP]
exacts [hs, IH₁ h hs.1, IH₂ h hs.2]
[GOAL]
case goto
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
a✝ : σ → Λ
hs : ∀ (v : σ), a✝ v ∈ S
h : q₁ = goto a✝
⊢ SupportsStmt S q₁
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case goto l => subst h; exact hs
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
l : σ → Λ
hs : ∀ (v : σ), l v ∈ S
h : q₁ = goto l
⊢ SupportsStmt S q₁
[PROOFSTEP]
case goto l => subst h; exact hs
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
l : σ → Λ
hs : ∀ (v : σ), l v ∈ S
h : q₁ = goto l
⊢ SupportsStmt S q₁
[PROOFSTEP]
subst h
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂ : Stmt₂
hs✝ : SupportsStmt S q₂
l : σ → Λ
hs : ∀ (v : σ), l v ∈ S
h : goto l ∈ stmts₁ q₂
⊢ SupportsStmt S (goto l)
[PROOFSTEP]
exact hs
[GOAL]
case halt
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case halt => subst h; trivial
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
case halt => subst h; trivial
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₁ q₂ : Stmt₂
h✝ : q₁ ∈ stmts₁ q₂
hs✝ : SupportsStmt S q₂
hs : True
h : q₁ = halt
⊢ SupportsStmt S q₁
[PROOFSTEP]
subst h
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
S : Finset Λ
q₂ : Stmt₂
hs✝ : SupportsStmt S q₂
hs : True
h : halt ∈ stmts₁ q₂
⊢ SupportsStmt S halt
[PROOFSTEP]
trivial
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
M : Λ → Stmt₂
S : Finset Λ
q₁ q₂ : Stmt₂
h₁ : q₁ ∈ stmts₁ q₂
⊢ some q₂ ∈ stmts M S → some q₁ ∈ stmts M S
[PROOFSTEP]
simp only [stmts, Finset.mem_insertNone, Finset.mem_biUnion, Option.mem_def, Option.some.injEq, forall_eq', exists_imp,
  and_imp]
[GOAL]
K : Type u_1
inst✝ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
M : Λ → Stmt₂
S : Finset Λ
q₁ q₂ : Stmt₂
h₁ : q₁ ∈ stmts₁ q₂
⊢ ∀ (x : Λ), x ∈ S → q₂ ∈ stmts₁ (M x) → ∃ a, a ∈ S ∧ q₁ ∈ stmts₁ (M a)
[PROOFSTEP]
exact fun l ls h₂ ↦ ⟨_, ls, stmts₁_trans h₂ h₁⟩
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
q : Stmt₂
ss : Supports M S
⊢ some q ∈ stmts M S → SupportsStmt S q
[PROOFSTEP]
simp only [stmts, Finset.mem_insertNone, Finset.mem_biUnion, Option.mem_def, Option.some.injEq, forall_eq', exists_imp,
  and_imp]
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
q : Stmt₂
ss : Supports M S
⊢ ∀ (x : Λ), x ∈ S → q ∈ stmts₁ (M x) → SupportsStmt S q
[PROOFSTEP]
exact fun l ls h ↦ stmts₁_supportsStmt_mono h (ss.2 _ ls)
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : (k : K) → List (Γ k)
c' : Cfg₂
h₁ : c' ∈ step M { l := some l₁, var := v, stk := T }
h₂ : { l := some l₁, var := v, stk := T }.l ∈ ↑Finset.insertNone S
⊢ c'.l ∈ ↑Finset.insertNone S
[PROOFSTEP]
replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : (k : K) → List (Γ k)
c' : Cfg₂
h₁ : c' ∈ step M { l := some l₁, var := v, stk := T }
h₂ : SupportsStmt S (M l₁)
⊢ c'.l ∈ ↑Finset.insertNone S
[PROOFSTEP]
simp only [step, Option.mem_def, Option.some.injEq] at h₁
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : (k : K) → List (Γ k)
c' : Cfg₂
h₂ : SupportsStmt S (M l₁)
h₁ : stepAux (M l₁) v T = c'
⊢ c'.l ∈ ↑Finset.insertNone S
[PROOFSTEP]
subst c'
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : (k : K) → List (Γ k)
h₂ : SupportsStmt S (M l₁)
⊢ (stepAux (M l₁) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
revert h₂
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (M l₁) → (stepAux (M l₁) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T
[GOAL]
case push
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (push k✝ a✝ q) → (stepAux (push k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case peek
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (peek k✝ a✝ q) → (stepAux (peek k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case pop
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (pop k✝ a✝ q) → (stepAux (pop k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case load
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (load a✝ q) → (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (branch a✝² a✝¹ a✝) → (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S (goto a✝) → (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
⊢ SupportsStmt S halt → (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
intro hs
[GOAL]
case push
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (push k✝ a✝ q)
⊢ (stepAux (push k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case peek
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (peek k✝ a✝ q)
⊢ (stepAux (peek k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case pop
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (pop k✝ a✝ q)
⊢ (stepAux (pop k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
iterate 4 exact IH _ _ hs
[GOAL]
case push
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Γ k✝
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (push k✝ a✝ q)
⊢ (stepAux (push k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case peek
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (peek k✝ a✝ q)
⊢ (stepAux (peek k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case pop
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (pop k✝ a✝ q)
⊢ (stepAux (pop k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case peek
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (peek k✝ a✝ q)
⊢ (stepAux (peek k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case pop
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (pop k✝ a✝ q)
⊢ (stepAux (pop k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case pop
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
k✝ : K
a✝ : σ → Option (Γ k✝) → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (pop k✝ a✝ q)
⊢ (stepAux (pop k✝ a✝ q) v T).l ∈ ↑Finset.insertNone S
case load
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case load
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → σ
q : Stmt₂
IH : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q → (stepAux q v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (load a✝ q)
⊢ (stepAux (load a✝ q) v T).l ∈ ↑Finset.insertNone S
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH _ _ hs
[GOAL]
case branch
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝² : σ → Bool
a✝¹ a✝ : Stmt₂
a_ih✝¹ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝¹ → (stepAux a✝¹ v T).l ∈ ↑Finset.insertNone S
a_ih✝ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S a✝ → (stepAux a✝ v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch a✝² a✝¹ a✝)
⊢ (stepAux (branch a✝² a✝¹ a✝) v T).l ∈ ↑Finset.insertNone S
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case branch p q₁' q₂' IH₁ IH₂ =>
  unfold stepAux; cases p v
  · exact IH₂ _ _ hs.2
  · exact IH₁ _ _ hs.1
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
p : σ → Bool
q₁' q₂' : Stmt₂
IH₁ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (stepAux (branch p q₁' q₂') v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case branch p q₁' q₂' IH₁ IH₂ =>
  unfold stepAux; cases p v
  · exact IH₂ _ _ hs.2
  · exact IH₁ _ _ hs.1
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
p : σ → Bool
q₁' q₂' : Stmt₂
IH₁ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (stepAux (branch p q₁' q₂') v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
unfold stepAux
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
p : σ → Bool
q₁' q₂' : Stmt₂
IH₁ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (bif p v then stepAux q₁' v T else stepAux q₂' v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
cases p v
[GOAL]
case false
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
p : σ → Bool
q₁' q₂' : Stmt₂
IH₁ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (bif false then stepAux q₁' v T else stepAux q₂' v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH₂ _ _ hs.2
[GOAL]
case true
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
p : σ → Bool
q₁' q₂' : Stmt₂
IH₁ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₁' → (stepAux q₁' v T).l ∈ ↑Finset.insertNone S
IH₂ : ∀ (v : σ) (T : (k : K) → List (Γ k)), SupportsStmt S q₂' → (stepAux q₂' v T).l ∈ ↑Finset.insertNone S
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (branch p q₁' q₂')
⊢ (bif true then stepAux q₁' v T else stepAux q₂' v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact IH₁ _ _ hs.1
[GOAL]
case goto
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case goto => exact Finset.some_mem_insertNone.2 (hs _)
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case goto => exact Finset.some_mem_insertNone.2 (hs _)
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
exact Finset.some_mem_insertNone.2 (hs _)
[GOAL]
case halt
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case halt => apply Multiset.mem_cons_self
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
case halt => apply Multiset.mem_cons_self
[GOAL]
K : Type u_1
inst✝¹ : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
σ : Type u_4
inst✝ : Inhabited Λ
M : Λ → Stmt₂
S : Finset Λ
ss : Supports M S
l₁ : Λ
v✝ : σ
T✝ : (k : K) → List (Γ k)
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ ↑Finset.insertNone S
[PROOFSTEP]
apply Multiset.mem_cons_self
[GOAL]
K : Type u_1
Γ : K → Type u_2
L : ListBlank ((k : K) → Option (Γ k))
k : K
S : List (Γ k)
n : ℕ
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
⊢ ListBlank.nth L n k = List.get? (List.reverse S) n
[PROOFSTEP]
rw [← proj_map_nth, hL, ← List.map_reverse, ListBlank.nth_mk, List.getI_eq_iget_get?, List.get?_map]
[GOAL]
K : Type u_1
Γ : K → Type u_2
L : ListBlank ((k : K) → Option (Γ k))
k : K
S : List (Γ k)
n : ℕ
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
⊢ Option.iget (Option.map some (List.get? (List.reverse S) n)) = List.get? (List.reverse S) n
[PROOFSTEP]
cases S.reverse.get? n
[GOAL]
case none
K : Type u_1
Γ : K → Type u_2
L : ListBlank ((k : K) → Option (Γ k))
k : K
S : List (Γ k)
n : ℕ
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
⊢ Option.iget (Option.map some none) = none
[PROOFSTEP]
rfl
[GOAL]
case some
K : Type u_1
Γ : K → Type u_2
L : ListBlank ((k : K) → Option (Γ k))
k : K
S : List (Γ k)
n : ℕ
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
val✝ : Γ k
⊢ Option.iget (Option.map some (some val✝)) = some val✝
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
⊢ default.snd = default
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
⊢ ListBlank.map { f := Prod.snd, map_pt' := (_ : default.snd = default.snd) } (addBottom L) = L
[PROOFSTEP]
simp only [addBottom, ListBlank.map_cons]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
⊢ ListBlank.cons (ListBlank.head L)
      (ListBlank.map { f := Prod.snd, map_pt' := (_ : default.snd = default.snd) }
        (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }
          (ListBlank.tail L))) =
    L
[PROOFSTEP]
convert ListBlank.cons_head_tail L
[GOAL]
case h.e'_2.h.e'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
⊢ ListBlank.map { f := Prod.snd, map_pt' := (_ : default.snd = default.snd) }
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (ListBlank.tail L)) =
    ListBlank.tail L
[PROOFSTEP]
generalize ListBlank.tail L = L'
[GOAL]
case h.e'_2.h.e'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L L' : ListBlank ((k : K) → Option (Γ k))
⊢ ListBlank.map { f := Prod.snd, map_pt' := (_ : default.snd = default.snd) }
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } L') =
    L'
[PROOFSTEP]
refine' L'.induction_on fun l ↦ _
[GOAL]
case h.e'_2.h.e'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L L' : ListBlank ((k : K) → Option (Γ k))
l : List ((k : K) → Option (Γ k))
⊢ ListBlank.map { f := Prod.snd, map_pt' := (_ : default.snd = default.snd) }
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (ListBlank.mk l)) =
    ListBlank.mk l
[PROOFSTEP]
simp
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
⊢ ListBlank.modifyNth (fun a => (a.fst, f a.snd)) n (addBottom L) = addBottom (ListBlank.modifyNth f n L)
[PROOFSTEP]
cases n
[GOAL]
case zero
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
⊢ ListBlank.modifyNth (fun a => (a.fst, f a.snd)) Nat.zero (addBottom L) = addBottom (ListBlank.modifyNth f Nat.zero L)
[PROOFSTEP]
simp only [addBottom, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.tail_cons]
[GOAL]
case succ
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n✝ : ℕ
⊢ ListBlank.modifyNth (fun a => (a.fst, f a.snd)) (Nat.succ n✝) (addBottom L) =
    addBottom (ListBlank.modifyNth f (Nat.succ n✝) L)
[PROOFSTEP]
simp only [addBottom, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.tail_cons]
[GOAL]
case succ
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n✝ : ℕ
⊢ ListBlank.cons (true, ListBlank.head L)
      (ListBlank.modifyNth (fun a => (a.fst, f a.snd)) n✝
        (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }
          (ListBlank.tail L))) =
    ListBlank.cons (true, ListBlank.head L)
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }
        (ListBlank.modifyNth f n✝ (ListBlank.tail L)))
[PROOFSTEP]
congr
[GOAL]
case succ.e_l
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n✝ : ℕ
⊢ ListBlank.modifyNth (fun a => (a.fst, f a.snd)) n✝
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (ListBlank.tail L)) =
    ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }
      (ListBlank.modifyNth f n✝ (ListBlank.tail L))
[PROOFSTEP]
symm
[GOAL]
case succ.e_l
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n✝ : ℕ
⊢ ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }
      (ListBlank.modifyNth f n✝ (ListBlank.tail L)) =
    ListBlank.modifyNth (fun a => (a.fst, f a.snd)) n✝
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (ListBlank.tail L))
[PROOFSTEP]
apply ListBlank.map_modifyNth
[GOAL]
case succ.e_l.H
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n✝ : ℕ
⊢ ∀ (x : (k : K) → Option (Γ k)),
    PointedMap.f { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (f x) =
      ((PointedMap.f { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } x).fst,
        f (PointedMap.f { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } x).snd)
[PROOFSTEP]
intro
[GOAL]
case succ.e_l.H
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
f : ((k : K) → Option (Γ k)) → (k : K) → Option (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
n✝ : ℕ
x✝ : (k : K) → Option (Γ k)
⊢ PointedMap.f { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (f x✝) =
    ((PointedMap.f { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } x✝).fst,
      f (PointedMap.f { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } x✝).snd)
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
⊢ (ListBlank.nth (addBottom L) n).snd = ListBlank.nth L n
[PROOFSTEP]
conv => rhs; rw [← addBottom_map L, ListBlank.nth_map]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
| (ListBlank.nth (addBottom L) n).snd = ListBlank.nth L n
[PROOFSTEP]
rhs; rw [← addBottom_map L, ListBlank.nth_map]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
| (ListBlank.nth (addBottom L) n).snd = ListBlank.nth L n
[PROOFSTEP]
rhs; rw [← addBottom_map L, ListBlank.nth_map]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
| (ListBlank.nth (addBottom L) n).snd = ListBlank.nth L n
[PROOFSTEP]
rhs
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
| ListBlank.nth L n
[PROOFSTEP]
rw [← addBottom_map L, ListBlank.nth_map]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
⊢ (ListBlank.nth (addBottom L) (n + 1)).fst = false
[PROOFSTEP]
rw [ListBlank.nth_succ, addBottom, ListBlank.tail_cons, ListBlank.nth_map]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
L : ListBlank ((k : K) → Option (Γ k))
⊢ (ListBlank.head (addBottom L)).fst = true
[PROOFSTEP]
rw [addBottom, ListBlank.head_cons]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
S : Finset Λ
k : K
s : StAct k
q : Stmt₂
⊢ TM2.SupportsStmt S (stRun s q) ↔ TM2.SupportsStmt S q
[PROOFSTEP]
cases s
[GOAL]
case push
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
S : Finset Λ
k : K
q : Stmt₂
a✝ : σ → Γ k
⊢ TM2.SupportsStmt S (stRun (push a✝) q) ↔ TM2.SupportsStmt S q
[PROOFSTEP]
rfl
[GOAL]
case peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
S : Finset Λ
k : K
q : Stmt₂
a✝ : σ → Option (Γ k) → σ
⊢ TM2.SupportsStmt S (stRun (peek a✝) q) ↔ TM2.SupportsStmt S q
[PROOFSTEP]
rfl
[GOAL]
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
S : Finset Λ
k : K
q : Stmt₂
a✝ : σ → Option (Γ k) → σ
⊢ TM2.SupportsStmt S (stRun (pop a✝) q) ↔ TM2.SupportsStmt S q
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
v : σ
S : (k : K) → List (Γ k)
f : σ → Option (Γ k) → σ
⊢ TM2.stepAux (stRun (StAct.peek f) q) v S =
    TM2.stepAux q (stVar v (S k) (StAct.peek f)) (update S k (stWrite v (S k) (StAct.peek f)))
[PROOFSTEP]
unfold stWrite
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
v : σ
S : (k : K) → List (Γ k)
f : σ → Option (Γ k) → σ
⊢ TM2.stepAux (stRun (StAct.peek f) q) v S =
    TM2.stepAux q (stVar v (S k) (StAct.peek f))
      (update S k
        (match StAct.peek f with
        | StAct.push f => f v :: S k
        | StAct.peek a => S k
        | StAct.pop a => List.tail (S k)))
[PROOFSTEP]
rw [Function.update_eq_self]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
v : σ
S : (k : K) → List (Γ k)
f : σ → Option (Γ k) → σ
⊢ TM2.stepAux (stRun (StAct.peek f) q) v S = TM2.stepAux q (stVar v (S k) (StAct.peek f)) S
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
s : StAct k
q : Stmt₂
⊢ trNormal (stRun s q) = goto fun x x => go k s q
[PROOFSTEP]
cases s
[GOAL]
case push
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
a✝ : σ → Γ k
⊢ trNormal (stRun (StAct.push a✝) q) = goto fun x x => go k (StAct.push a✝) q
[PROOFSTEP]
rfl
[GOAL]
case peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
a✝ : σ → Option (Γ k) → σ
⊢ trNormal (stRun (StAct.peek a✝) q) = goto fun x x => go k (StAct.peek a✝) q
[PROOFSTEP]
rfl
[GOAL]
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
a✝ : σ → Option (Γ k) → σ
⊢ trNormal (stRun (StAct.pop a✝) q) = goto fun x x => go k (StAct.pop a✝) q
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
s : StAct k
q : Stmt₂
⊢ trStmts₁ (stRun s q) = {go k s q, ret q} ∪ trStmts₁ q
[PROOFSTEP]
cases s
[GOAL]
case push
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
a✝ : σ → Γ k
⊢ trStmts₁ (stRun (StAct.push a✝) q) = {go k (StAct.push a✝) q, ret q} ∪ trStmts₁ q
[PROOFSTEP]
simp only [trStmts₁]
[GOAL]
case peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
a✝ : σ → Option (Γ k) → σ
⊢ trStmts₁ (stRun (StAct.peek a✝) q) = {go k (StAct.peek a✝) q, ret q} ∪ trStmts₁ q
[PROOFSTEP]
simp only [trStmts₁]
[GOAL]
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : Stmt₂
a✝ : σ → Option (Γ k) → σ
⊢ trStmts₁ (stRun (StAct.pop a✝) q) = {go k (StAct.pop a✝) q, ret q} ∪ trStmts₁ q
[PROOFSTEP]
simp only [trStmts₁]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
⊢ let v' := stVar v (S k) o;
  let Sk' := stWrite v (S k) o;
  let S' := update S k Sk';
  ∃ L',
    (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S' k)))) ∧
      TM1.stepAux (trStAct q o) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
        TM1.stepAux q v' ((Tape.move Dir.right)^[List.length (S' k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
dsimp only
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' =
          ListBlank.mk (List.reverse (List.map some (update S k (stWrite v (S k) o) k_1)))) ∧
      TM1.stepAux (trStAct q o) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
        TM1.stepAux q (stVar v (S k) o)
          ((Tape.move Dir.right)^[List.length (update S k (stWrite v (S k) o) k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
simp
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' =
          ListBlank.mk (List.reverse (List.map some (update S k (stWrite v (S k) o) k_1)))) ∧
      TM1.stepAux (trStAct q o) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
        TM1.stepAux q (stVar v (S k) o)
          ((Tape.move Dir.right)^[List.length (stWrite v (S k) o)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
cases o
[GOAL]
case push
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Γ k
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' =
          ListBlank.mk (List.reverse (List.map some (update S k (stWrite v (S k) (StAct.push a✝)) k_1)))) ∧
      TM1.stepAux (trStAct q (StAct.push a✝)) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
        TM1.stepAux q (stVar v (S k) (StAct.push a✝))
          ((Tape.move Dir.right)^[List.length (stWrite v (S k) (StAct.push a✝))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
simp only [stWrite, stVar, trStAct, TM1.stepAux]
[GOAL]
case peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' =
          ListBlank.mk (List.reverse (List.map some (update S k (stWrite v (S k) (StAct.peek a✝)) k_1)))) ∧
      TM1.stepAux (trStAct q (StAct.peek a✝)) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
        TM1.stepAux q (stVar v (S k) (StAct.peek a✝))
          ((Tape.move Dir.right)^[List.length (stWrite v (S k) (StAct.peek a✝))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
simp only [stWrite, stVar, trStAct, TM1.stepAux]
[GOAL]
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' =
          ListBlank.mk (List.reverse (List.map some (update S k (stWrite v (S k) (StAct.pop a✝)) k_1)))) ∧
      TM1.stepAux (trStAct q (StAct.pop a✝)) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
        TM1.stepAux q (stVar v (S k) (StAct.pop a✝))
          ((Tape.move Dir.right)^[List.length (stWrite v (S k) (StAct.pop a✝))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
simp only [stWrite, stVar, trStAct, TM1.stepAux]
[GOAL]
case push
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Γ k
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (a✝ v :: S k) k_1)))) ∧
      TM1.stepAux q v
          (Tape.move Dir.right
            (Tape.write
              (((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst,
                update ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.snd k (some (a✝ v)))
              ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q v ((Tape.move Dir.right)^[List.length (a✝ v :: S k)] (Tape.mk' ∅ (addBottom L')))
case peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K), ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (S k) k_1)))) ∧
      TM1.stepAux q
          (a✝ v
            (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
              k))
          (Tape.move Dir.right
            (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q (a✝ v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L')))
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (List.tail (S k)) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (a✝ v none) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (a✝ v
              (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update
                  (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.snd k
                  none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (a✝ v (List.head? (S k)))
          ((Tape.move Dir.right)^[List.length (List.tail (S k))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
case push f =>
  have := Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k (some (f v)))
  refine'
    ⟨_, fun k' ↦ _, by
      -- Porting note: `rw [...]` to `erw [...]; rfl`.
              -- https://github.com/leanprover-community/mathlib4/issues/5164
      erw [Tape.move_right_n_head, List.length, Tape.mk'_nth_nat, this,
        addBottom_modifyNth fun a ↦ update a k (some (f v)), Nat.add_one, iterate_succ']
      rfl⟩
  refine' ListBlank.ext fun i ↦ _
  rw [ListBlank.nth_map, ListBlank.nth_modifyNth, proj, PointedMap.mk_val]
  by_cases h' : k' = k
  · subst k'
    split_ifs with h <;>
      simp only [List.reverse_cons, Function.update_same, ListBlank.nth_mk, List.map]
        -- Porting note: `le_refl` is required.
    ·
      rw [List.getI_eq_get, List.get_append_right'] <;>
        simp only [h, List.get_singleton, List.length_map, List.length_reverse, Nat.succ_pos', List.length_append,
          lt_add_iff_pos_right, List.length, le_refl]
    rw [← proj_map_nth, hL, ListBlank.nth_mk]
    cases' lt_or_gt_of_ne h with h h
    · rw [List.getI_append]
      simpa only [List.length_map, List.length_reverse] using h
    · rw [gt_iff_lt] at h
      rw [List.getI_eq_default, List.getI_eq_default] <;>
        simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append,
          List.length_map]
  · split_ifs <;> rw [Function.update_noteq h', ← proj_map_nth, hL]
    rw [Function.update_noteq h']
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k_1)))) ∧
      TM1.stepAux q v
          (Tape.move Dir.right
            (Tape.write
              (((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst,
                update ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.snd k (some (f v)))
              ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q v ((Tape.move Dir.right)^[List.length (f v :: S k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
case push f =>
  have := Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k (some (f v)))
  refine'
    ⟨_, fun k' ↦ _, by
      -- Porting note: `rw [...]` to `erw [...]; rfl`.
              -- https://github.com/leanprover-community/mathlib4/issues/5164
      erw [Tape.move_right_n_head, List.length, Tape.mk'_nth_nat, this,
        addBottom_modifyNth fun a ↦ update a k (some (f v)), Nat.add_one, iterate_succ']
      rfl⟩
  refine' ListBlank.ext fun i ↦ _
  rw [ListBlank.nth_map, ListBlank.nth_modifyNth, proj, PointedMap.mk_val]
  by_cases h' : k' = k
  · subst k'
    split_ifs with h <;>
      simp only [List.reverse_cons, Function.update_same, ListBlank.nth_mk, List.map]
        -- Porting note: `le_refl` is required.
    ·
      rw [List.getI_eq_get, List.get_append_right'] <;>
        simp only [h, List.get_singleton, List.length_map, List.length_reverse, Nat.succ_pos', List.length_append,
          lt_add_iff_pos_right, List.length, le_refl]
    rw [← proj_map_nth, hL, ListBlank.nth_mk]
    cases' lt_or_gt_of_ne h with h h
    · rw [List.getI_append]
      simpa only [List.length_map, List.length_reverse] using h
    · rw [gt_iff_lt] at h
      rw [List.getI_eq_default, List.getI_eq_default] <;>
        simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append,
          List.length_map]
  · split_ifs <;> rw [Function.update_noteq h', ← proj_map_nth, hL]
    rw [Function.update_noteq h']
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k_1)))) ∧
      TM1.stepAux q v
          (Tape.move Dir.right
            (Tape.write
              (((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst,
                update ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.snd k (some (f v)))
              ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q v ((Tape.move Dir.right)^[List.length (f v :: S k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
have := Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k (some (f v)))
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k_1)))) ∧
      TM1.stepAux q v
          (Tape.move Dir.right
            (Tape.write
              (((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst,
                update ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.snd k (some (f v)))
              ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q v ((Tape.move Dir.right)^[List.length (f v :: S k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
refine'
  ⟨_, fun k' ↦ _, by
    -- Porting note: `rw [...]` to `erw [...]; rfl`.
            -- https://github.com/leanprover-community/mathlib4/issues/5164
    erw [Tape.move_right_n_head, List.length, Tape.mk'_nth_nat, this,
      addBottom_modifyNth fun a ↦ update a k (some (f v)), Nat.add_one, iterate_succ']
    rfl⟩
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ TM1.stepAux q v
      (Tape.move Dir.right
        (Tape.write
          (((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst,
            update ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.snd k (some (f v)))
          ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
    TM1.stepAux q v ((Tape.move Dir.right)^[List.length (f v :: S k)] (Tape.mk' ∅ (addBottom ?m.655566)))
[PROOFSTEP]
erw [Tape.move_right_n_head, List.length, Tape.mk'_nth_nat, this, addBottom_modifyNth fun a ↦ update a k (some (f v)),
  Nat.add_one, iterate_succ']
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ TM1.stepAux q v
      (Tape.move Dir.right
        ((Tape.move Dir.right)^[List.length (S k)]
          (Tape.mk' ∅ (addBottom (ListBlank.modifyNth (fun a => update a k (some (f v))) (List.length (S k)) L))))) =
    TM1.stepAux q v
      ((Tape.move Dir.right ∘ (Tape.move Dir.right)^[List.length (S k)]) (Tape.mk' ∅ (addBottom ?m.655566)))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
⊢ ListBlank ((k : K) → Option (Γ k))
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
⊢ ListBlank.map (proj k') (ListBlank.modifyNth (fun a => update a k (some (f v))) (List.length (S k)) L) =
    ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))
[PROOFSTEP]
refine' ListBlank.ext fun i ↦ _
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
⊢ ListBlank.nth (ListBlank.map (proj k') (ListBlank.modifyNth (fun a => update a k (some (f v))) (List.length (S k)) L))
      i =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
rw [ListBlank.nth_map, ListBlank.nth_modifyNth, proj, PointedMap.mk_val]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
⊢ ite (i = List.length (S k)) (update (ListBlank.nth L i) k (some (f v))) (ListBlank.nth L i) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
by_cases h' : k' = k
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
h' : k' = k
⊢ ite (i = List.length (S k)) (update (ListBlank.nth L i) k (some (f v))) (ListBlank.nth L i) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
subst k'
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
⊢ ite (i = List.length (S k)) (update (ListBlank.nth L i) k (some (f v))) (ListBlank.nth L i) k =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k)))) i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : i = List.length (S k)
⊢ update (ListBlank.nth L i) k (some (f v)) k =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k)))) i
[PROOFSTEP]
simp only [List.reverse_cons, Function.update_same, ListBlank.nth_mk, List.map]
  -- Porting note: `le_refl` is required.
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : ¬i = List.length (S k)
⊢ ListBlank.nth L i k = ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k)))) i
[PROOFSTEP]
simp only [List.reverse_cons, Function.update_same, ListBlank.nth_mk, List.map]
  -- Porting note: `le_refl` is required.
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : i = List.length (S k)
⊢ some (f v) = List.getI (List.reverse (List.map some (S k)) ++ [some (f v)]) i
[PROOFSTEP]
rw [List.getI_eq_get, List.get_append_right']
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : i = List.length (S k)
⊢ some (f v) =
    List.get [some (f v)]
      { val := i - List.length (List.reverse (List.map some (S k))),
        isLt := (_ : i - List.length (List.reverse (List.map some (S k))) < List.length [some (f v)]) }
[PROOFSTEP]
simp only [h, List.get_singleton, List.length_map, List.length_reverse, Nat.succ_pos', List.length_append,
  lt_add_iff_pos_right, List.length, le_refl]
[GOAL]
case pos.h₁
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : i = List.length (S k)
⊢ List.length (List.reverse (List.map some (S k))) ≤ i
[PROOFSTEP]
simp only [h, List.get_singleton, List.length_map, List.length_reverse, Nat.succ_pos', List.length_append,
  lt_add_iff_pos_right, List.length, le_refl]
[GOAL]
case pos.h₂
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : i = List.length (S k)
⊢ i < List.length (List.reverse (List.map some (S k)) ++ [some (f v)])
[PROOFSTEP]
simp only [h, List.get_singleton, List.length_map, List.length_reverse, Nat.succ_pos', List.length_append,
  lt_add_iff_pos_right, List.length, le_refl]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : ¬i = List.length (S k)
⊢ ListBlank.nth L i k = List.getI (List.reverse (List.map some (S k)) ++ [some (f v)]) i
[PROOFSTEP]
rw [← proj_map_nth, hL, ListBlank.nth_mk]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h : ¬i = List.length (S k)
⊢ List.getI (List.reverse (List.map some (S k))) i = List.getI (List.reverse (List.map some (S k)) ++ [some (f v)]) i
[PROOFSTEP]
cases' lt_or_gt_of_ne h with h h
[GOAL]
case neg.inl
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h✝ : ¬i = List.length (S k)
h : i < List.length (S k)
⊢ List.getI (List.reverse (List.map some (S k))) i = List.getI (List.reverse (List.map some (S k)) ++ [some (f v)]) i
[PROOFSTEP]
rw [List.getI_append]
[GOAL]
case neg.inl.h
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h✝ : ¬i = List.length (S k)
h : i < List.length (S k)
⊢ i < List.length (List.reverse (List.map some (S k)))
[PROOFSTEP]
simpa only [List.length_map, List.length_reverse] using h
[GOAL]
case neg.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h✝ : ¬i = List.length (S k)
h : i > List.length (S k)
⊢ List.getI (List.reverse (List.map some (S k))) i = List.getI (List.reverse (List.map some (S k)) ++ [some (f v)]) i
[PROOFSTEP]
rw [gt_iff_lt] at h
[GOAL]
case neg.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h✝ : ¬i = List.length (S k)
h : List.length (S k) < i
⊢ List.getI (List.reverse (List.map some (S k))) i = List.getI (List.reverse (List.map some (S k)) ++ [some (f v)]) i
[PROOFSTEP]
rw [List.getI_eq_default, List.getI_eq_default]
[GOAL]
case neg.inr.hn
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h✝ : ¬i = List.length (S k)
h : List.length (S k) < i
⊢ List.length (List.reverse (List.map some (S k)) ++ [some (f v)]) ≤ i
[PROOFSTEP]
simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append, List.length_map]
[GOAL]
case neg.inr.hn
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
i : ℕ
h✝ : ¬i = List.length (S k)
h : List.length (S k) < i
⊢ List.length (List.reverse (List.map some (S k))) ≤ i
[PROOFSTEP]
simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append, List.length_map]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
h' : ¬k' = k
⊢ ite (i = List.length (S k)) (update (ListBlank.nth L i) k (some (f v))) (ListBlank.nth L i) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
split_ifs
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
h' : ¬k' = k
h✝ : i = List.length (S k)
⊢ update (ListBlank.nth L i) k (some (f v)) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
rw [Function.update_noteq h', ← proj_map_nth, hL]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
h' : ¬k' = k
h✝ : ¬i = List.length (S k)
⊢ ListBlank.nth L i k' = ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
rw [Function.update_noteq h', ← proj_map_nth, hL]
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Γ k
this :
  ∀ (L R : ListBlank Γ') (n : ℕ),
    Tape.write ((ListBlank.nth R n).fst, update (ListBlank.nth R n).snd k (some (f v)))
        ((Tape.move Dir.right)^[n] (Tape.mk' L R)) =
      (Tape.move Dir.right)^[n] (Tape.mk' L (ListBlank.modifyNth (fun a => (a.fst, update a.snd k (some (f v)))) n R))
k' : K
i : ℕ
h' : ¬k' = k
h✝ : i = List.length (S k)
⊢ ListBlank.nth (ListBlank.mk (List.reverse (List.map some (S k')))) i =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (f v :: S k) k')))) i
[PROOFSTEP]
rw [Function.update_noteq h']
[GOAL]
case peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K), ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (S k) k_1)))) ∧
      TM1.stepAux q
          (a✝ v
            (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
              k))
          (Tape.move Dir.right
            (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q (a✝ v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L')))
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (List.tail (S k)) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (a✝ v none) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (a✝ v
              (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update
                  (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.snd k
                  none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (a✝ v (List.head? (S k)))
          ((Tape.move Dir.right)^[List.length (List.tail (S k))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
case peek f =>
  rw [Function.update_eq_self]
  use L, hL; rw [Tape.move_left_right]; congr
  cases e : S k; · rfl
  rw [List.length_cons, iterate_succ', Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
    addBottom_nth_snd, stk_nth_val _ (hL k), e, List.reverse_cons, ← List.length_reverse, List.get?_concat_length]
  rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K), ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (S k) k_1)))) ∧
      TM1.stepAux q
          (f v
            (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
              k))
          (Tape.move Dir.right
            (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q (f v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
case peek f =>
  rw [Function.update_eq_self]
  use L, hL; rw [Tape.move_left_right]; congr
  cases e : S k; · rfl
  rw [List.length_cons, iterate_succ', Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
    addBottom_nth_snd, stk_nth_val _ (hL k), e, List.reverse_cons, ← List.length_reverse, List.get?_concat_length]
  rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K), ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (S k) k_1)))) ∧
      TM1.stepAux q
          (f v
            (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
              k))
          (Tape.move Dir.right
            (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q (f v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
rw [Function.update_eq_self]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S k)))) ∧
      TM1.stepAux q
          (f v
            (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
              k))
          (Tape.move Dir.right
            (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
        TM1.stepAux q (f v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
use L, hL
[GOAL]
case right
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ TM1.stepAux q
      (f v
        (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head k))
      (Tape.move Dir.right
        (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))))) =
    TM1.stepAux q (f v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
[PROOFSTEP]
rw [Tape.move_left_right]
[GOAL]
case right
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ TM1.stepAux q
      (f v
        (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head k))
      ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))) =
    TM1.stepAux q (f v (List.head? (S k))) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
[PROOFSTEP]
congr
[GOAL]
case right.e_a.e_a
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head k =
    List.head? (S k)
[PROOFSTEP]
cases e : S k
[GOAL]
case right.e_a.e_a.nil
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
e : S k = []
⊢ Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L)))).head k =
    List.head? []
[PROOFSTEP]
rfl
[GOAL]
case right.e_a.e_a.cons
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
head✝ : Γ k
tail✝ : List (Γ k)
e : S k = head✝ :: tail✝
⊢ Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (head✝ :: tail✝)] (Tape.mk' ∅ (addBottom L)))).head
      k =
    List.head? (head✝ :: tail✝)
[PROOFSTEP]
rw [List.length_cons, iterate_succ', Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
  addBottom_nth_snd, stk_nth_val _ (hL k), e, List.reverse_cons, ← List.length_reverse, List.get?_concat_length]
[GOAL]
case right.e_a.e_a.cons
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
head✝ : Γ k
tail✝ : List (Γ k)
e : S k = head✝ :: tail✝
⊢ some head✝ = List.head? (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
case pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
a✝ : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (List.tail (S k)) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (a✝ v none) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (a✝ v
              (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update
                  (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.snd k
                  none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (a✝ v (List.head? (S k)))
          ((Tape.move Dir.right)^[List.length (List.tail (S k))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
case pop f =>
  cases' e : S k with hd tl
  · simp only [Tape.mk'_head, ListBlank.head_cons, Tape.move_left_mk', List.length, Tape.write_mk', List.head?,
      iterate_zero_apply, List.tail_nil]
    rw [← e, Function.update_eq_self]
    exact ⟨L, hL, by rw [addBottom_head_fst, cond]⟩
  · refine'
      ⟨_, fun k' ↦ _, by
        erw [List.length_cons, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_succ_fst, cond, iterate_succ',
          Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
          Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k none), addBottom_modifyNth fun a ↦ update a k none,
          addBottom_nth_snd, stk_nth_val _ (hL k), e,
          show (List.cons hd tl).reverse.get? tl.length = some hd by
            rw [List.reverse_cons, ← List.length_reverse, List.get?_concat_length],
          List.head?, List.tail]⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.nth_map, ListBlank.nth_modifyNth, proj, PointedMap.mk_val]
    by_cases h' : k' = k
    · subst k'
      split_ifs with h <;> simp only [Function.update_same, ListBlank.nth_mk, List.tail]
      · rw [List.getI_eq_default]
        · rfl
        rw [h, List.length_reverse, List.length_map]
      rw [← proj_map_nth, hL, ListBlank.nth_mk, e, List.map, List.reverse_cons]
      cases' lt_or_gt_of_ne h with h h
      · rw [List.getI_append]
        simpa only [List.length_map, List.length_reverse] using h
      · rw [gt_iff_lt] at h
        rw [List.getI_eq_default, List.getI_eq_default] <;>
          simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append,
            List.length_map]
    · split_ifs <;> rw [Function.update_noteq h', ← proj_map_nth, hL]
      rw [Function.update_noteq h']
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (List.tail (S k)) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (f v none) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (f v
              (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update
                  (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.snd k
                  none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (f v (List.head? (S k)))
          ((Tape.move Dir.right)^[List.length (List.tail (S k))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
case pop f =>
  cases' e : S k with hd tl
  · simp only [Tape.mk'_head, ListBlank.head_cons, Tape.move_left_mk', List.length, Tape.write_mk', List.head?,
      iterate_zero_apply, List.tail_nil]
    rw [← e, Function.update_eq_self]
    exact ⟨L, hL, by rw [addBottom_head_fst, cond]⟩
  · refine'
      ⟨_, fun k' ↦ _, by
        erw [List.length_cons, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_succ_fst, cond, iterate_succ',
          Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
          Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k none), addBottom_modifyNth fun a ↦ update a k none,
          addBottom_nth_snd, stk_nth_val _ (hL k), e,
          show (List.cons hd tl).reverse.get? tl.length = some hd by
            rw [List.reverse_cons, ← List.length_reverse, List.get?_concat_length],
          List.head?, List.tail]⟩
    refine' ListBlank.ext fun i ↦ _
    rw [ListBlank.nth_map, ListBlank.nth_modifyNth, proj, PointedMap.mk_val]
    by_cases h' : k' = k
    · subst k'
      split_ifs with h <;> simp only [Function.update_same, ListBlank.nth_mk, List.tail]
      · rw [List.getI_eq_default]
        · rfl
        rw [h, List.length_reverse, List.length_map]
      rw [← proj_map_nth, hL, ListBlank.nth_mk, e, List.map, List.reverse_cons]
      cases' lt_or_gt_of_ne h with h h
      · rw [List.getI_append]
        simpa only [List.length_map, List.length_reverse] using h
      · rw [gt_iff_lt] at h
        rw [List.getI_eq_default, List.getI_eq_default] <;>
          simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append,
            List.length_map]
    · split_ifs <;> rw [Function.update_noteq h', ← proj_map_nth, hL]
      rw [Function.update_noteq h']
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (List.tail (S k)) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (f v none) ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (f v
              (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update
                  (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))).head.snd k
                  none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (f v (List.head? (S k)))
          ((Tape.move Dir.right)^[List.length (List.tail (S k))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
cases' e : S k with hd tl
[GOAL]
case nil
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
e : S k = []
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k (List.tail []) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (f v none) ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (f v
              (Prod.snd (Tape.move Dir.left ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update (Tape.move Dir.left ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L)))).head.snd
                  k none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length []] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (f v (List.head? []))
          ((Tape.move Dir.right)^[List.length (List.tail [])] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
simp only [Tape.mk'_head, ListBlank.head_cons, Tape.move_left_mk', List.length, Tape.write_mk', List.head?,
  iterate_zero_apply, List.tail_nil]
[GOAL]
case nil
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
e : S k = []
⊢ ∃ L',
    (∀ (k_1 : K), ListBlank.map (proj k_1) L' = ListBlank.mk (List.reverse (List.map some (update S k [] k_1)))) ∧
      (bif (ListBlank.head (addBottom L)).fst then TM1.stepAux q (f v none) (Tape.mk' ∅ (addBottom L))
        else
          TM1.stepAux q (f v (Prod.snd (ListBlank.head ∅) k))
            (Tape.mk' (ListBlank.tail ∅)
              (ListBlank.cons ((ListBlank.head ∅).fst, update (ListBlank.head ∅).snd k none) (addBottom L)))) =
        TM1.stepAux q (f v none) (Tape.mk' ∅ (addBottom L'))
[PROOFSTEP]
rw [← e, Function.update_eq_self]
[GOAL]
case nil
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
e : S k = []
⊢ ∃ L',
    (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S k)))) ∧
      (bif (ListBlank.head (addBottom L)).fst then TM1.stepAux q (f v none) (Tape.mk' ∅ (addBottom L))
        else
          TM1.stepAux q (f v (Prod.snd (ListBlank.head ∅) k))
            (Tape.mk' (ListBlank.tail ∅)
              (ListBlank.cons ((ListBlank.head ∅).fst, update (ListBlank.head ∅).snd k none) (addBottom L)))) =
        TM1.stepAux q (f v none) (Tape.mk' ∅ (addBottom L'))
[PROOFSTEP]
exact ⟨L, hL, by rw [addBottom_head_fst, cond]⟩
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
e : S k = []
⊢ (bif (ListBlank.head (addBottom L)).fst then TM1.stepAux q (f v none) (Tape.mk' ∅ (addBottom L))
    else
      TM1.stepAux q (f v (Prod.snd (ListBlank.head ∅) k))
        (Tape.mk' (ListBlank.tail ∅)
          (ListBlank.cons ((ListBlank.head ∅).fst, update (ListBlank.head ∅).snd k none) (addBottom L)))) =
    TM1.stepAux q (f v none) (Tape.mk' ∅ (addBottom L))
[PROOFSTEP]
rw [addBottom_head_fst, cond]
[GOAL]
case cons
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
⊢ ∃ L',
    (∀ (k_1 : K),
        ListBlank.map (proj k_1) L' =
          ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k_1)))) ∧
      (bif ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L))).head.fst then
          TM1.stepAux q (f v none) ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))
        else
          TM1.stepAux q
            (f v
              (Prod.snd
                (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))).head
                k))
            (Tape.write
              ((Tape.move Dir.left
                      ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))).head.fst,
                update
                  (Tape.move Dir.left
                        ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))).head.snd
                  k none)
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))))) =
        TM1.stepAux q (f v (List.head? (hd :: tl)))
          ((Tape.move Dir.right)^[List.length (List.tail (hd :: tl))] (Tape.mk' ∅ (addBottom L')))
[PROOFSTEP]
refine'
  ⟨_, fun k' ↦ _, by
    erw [List.length_cons, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_succ_fst, cond, iterate_succ',
      Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
      Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k none), addBottom_modifyNth fun a ↦ update a k none,
      addBottom_nth_snd, stk_nth_val _ (hL k), e,
      show (List.cons hd tl).reverse.get? tl.length = some hd by
        rw [List.reverse_cons, ← List.length_reverse, List.get?_concat_length],
      List.head?, List.tail]⟩
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
⊢ (bif ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L))).head.fst then
      TM1.stepAux q (f v none) ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))
    else
      TM1.stepAux q
        (f v
          (Prod.snd
            (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))).head k))
        (Tape.write
          ((Tape.move Dir.left ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))).head.fst,
            update
              (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))).head.snd
              k none)
          (Tape.move Dir.left ((Tape.move Dir.right)^[List.length (hd :: tl)] (Tape.mk' ∅ (addBottom L)))))) =
    TM1.stepAux q (f v (List.head? (hd :: tl)))
      ((Tape.move Dir.right)^[List.length (List.tail (hd :: tl))] (Tape.mk' ∅ (addBottom ?m.672274)))
[PROOFSTEP]
erw [List.length_cons, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_succ_fst, cond, iterate_succ',
  Function.comp, Tape.move_right_left, Tape.move_right_n_head, Tape.mk'_nth_nat,
  Tape.write_move_right_n fun a : Γ' ↦ (a.1, update a.2 k none), addBottom_modifyNth fun a ↦ update a k none,
  addBottom_nth_snd, stk_nth_val _ (hL k), e,
  show (List.cons hd tl).reverse.get? tl.length = some hd by
    rw [List.reverse_cons, ← List.length_reverse, List.get?_concat_length],
  List.head?, List.tail]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
⊢ List.get? (List.reverse (hd :: tl)) (List.length tl) = some hd
[PROOFSTEP]
rw [List.reverse_cons, ← List.length_reverse, List.get?_concat_length]
[GOAL]
case cons
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
⊢ ListBlank.map (proj k') (ListBlank.modifyNth (fun a => update a k none) (List.length tl) L) =
    ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))
[PROOFSTEP]
refine' ListBlank.ext fun i ↦ _
[GOAL]
case cons
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
⊢ ListBlank.nth (ListBlank.map (proj k') (ListBlank.modifyNth (fun a => update a k none) (List.length tl) L)) i =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
rw [ListBlank.nth_map, ListBlank.nth_modifyNth, proj, PointedMap.mk_val]
[GOAL]
case cons
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
⊢ ite (i = List.length tl) (update (ListBlank.nth L i) k none) (ListBlank.nth L i) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
by_cases h' : k' = k
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
h' : k' = k
⊢ ite (i = List.length tl) (update (ListBlank.nth L i) k none) (ListBlank.nth L i) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
subst k'
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
⊢ ite (i = List.length tl) (update (ListBlank.nth L i) k none) (ListBlank.nth L i) k =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k)))) i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : i = List.length tl
⊢ update (ListBlank.nth L i) k none k =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k)))) i
[PROOFSTEP]
simp only [Function.update_same, ListBlank.nth_mk, List.tail]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : ¬i = List.length tl
⊢ ListBlank.nth L i k =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k)))) i
[PROOFSTEP]
simp only [Function.update_same, ListBlank.nth_mk, List.tail]
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : i = List.length tl
⊢ none = List.getI (List.reverse (List.map some tl)) i
[PROOFSTEP]
rw [List.getI_eq_default]
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : i = List.length tl
⊢ none = default
[PROOFSTEP]
rfl
[GOAL]
case pos.hn
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : i = List.length tl
⊢ List.length (List.reverse (List.map some tl)) ≤ i
[PROOFSTEP]
rw [h, List.length_reverse, List.length_map]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : ¬i = List.length tl
⊢ ListBlank.nth L i k = List.getI (List.reverse (List.map some tl)) i
[PROOFSTEP]
rw [← proj_map_nth, hL, ListBlank.nth_mk, e, List.map, List.reverse_cons]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h : ¬i = List.length tl
⊢ List.getI (List.reverse (List.map some tl) ++ [some hd]) i = List.getI (List.reverse (List.map some tl)) i
[PROOFSTEP]
cases' lt_or_gt_of_ne h with h h
[GOAL]
case neg.inl
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h✝ : ¬i = List.length tl
h : i < List.length tl
⊢ List.getI (List.reverse (List.map some tl) ++ [some hd]) i = List.getI (List.reverse (List.map some tl)) i
[PROOFSTEP]
rw [List.getI_append]
[GOAL]
case neg.inl.h
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h✝ : ¬i = List.length tl
h : i < List.length tl
⊢ i < List.length (List.reverse (List.map some tl))
[PROOFSTEP]
simpa only [List.length_map, List.length_reverse] using h
[GOAL]
case neg.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h✝ : ¬i = List.length tl
h : i > List.length tl
⊢ List.getI (List.reverse (List.map some tl) ++ [some hd]) i = List.getI (List.reverse (List.map some tl)) i
[PROOFSTEP]
rw [gt_iff_lt] at h
[GOAL]
case neg.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h✝ : ¬i = List.length tl
h : List.length tl < i
⊢ List.getI (List.reverse (List.map some tl) ++ [some hd]) i = List.getI (List.reverse (List.map some tl)) i
[PROOFSTEP]
rw [List.getI_eq_default, List.getI_eq_default]
[GOAL]
case neg.inr.hn
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h✝ : ¬i = List.length tl
h : List.length tl < i
⊢ List.length (List.reverse (List.map some tl)) ≤ i
[PROOFSTEP]
simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append, List.length_map]
[GOAL]
case neg.inr.hn
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
i : ℕ
h✝ : ¬i = List.length tl
h : List.length tl < i
⊢ List.length (List.reverse (List.map some tl) ++ [some hd]) ≤ i
[PROOFSTEP]
simp only [Nat.add_one_le_iff, h, List.length, le_of_lt, List.length_reverse, List.length_append, List.length_map]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
h' : ¬k' = k
⊢ ite (i = List.length tl) (update (ListBlank.nth L i) k none) (ListBlank.nth L i) k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
split_ifs
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
h' : ¬k' = k
h✝ : i = List.length tl
⊢ update (ListBlank.nth L i) k none k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
rw [Function.update_noteq h', ← proj_map_nth, hL]
[GOAL]
case neg
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
h' : ¬k' = k
h✝ : ¬i = List.length tl
⊢ ListBlank.nth L i k' =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
rw [Function.update_noteq h', ← proj_map_nth, hL]
[GOAL]
case pos
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
k : K
q : TM1.Stmt Γ' Λ' σ
v : σ
S : (k : K) → List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ∀ (k : K), ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some (S k)))
f : σ → Option (Γ k) → σ
hd : Γ k
tl : List (Γ k)
e : S k = hd :: tl
k' : K
i : ℕ
h' : ¬k' = k
h✝ : i = List.length tl
⊢ ListBlank.nth (ListBlank.mk (List.reverse (List.map some (S k')))) i =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some (update S k (List.tail (hd :: tl)) k')))) i
[PROOFSTEP]
rw [Function.update_noteq h']
[GOAL]
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n : ℕ
H : n ≤ List.length S
⊢ Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n : ℕ
H✝ : n ≤ List.length S
H : Nat.zero ≤ List.length S
⊢ Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[Nat.zero] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
rfl
[GOAL]
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[Nat.succ n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
apply (IH (le_of_lt H)).tail
[GOAL]
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[Nat.succ n] (Tape.mk' ∅ (addBottom L)) } ∈
    TM1.step (tr M) { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
rw [iterate_succ_apply']
[GOAL]
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ { l := some (go k o q), var := v,
      Tape := Tape.move Dir.right ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L))) } ∈
    TM1.step (tr M) { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
simp only [TM1.step, TM1.stepAux, tr, Tape.mk'_nth_nat, Tape.move_right_n_head, addBottom_nth_snd, Option.mem_def]
[GOAL]
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ some
      (bif Option.isNone (ListBlank.nth L n k) then
        TM1.stepAux (trStAct (goto fun x x => ret q) o) v ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)))
      else
        { l := some (go k o q), var := v,
          Tape := Tape.move Dir.right ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L))) }) =
    some
      { l := some (go k o q), var := v,
        Tape := Tape.move Dir.right ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L))) }
[PROOFSTEP]
rw [stk_nth_val _ hL, List.get?_eq_get]
[GOAL]
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ some
      (bif Option.isNone (some (List.get (List.reverse S) { val := n, isLt := ?succ })) then
        TM1.stepAux (trStAct (goto fun x x => ret q) o) v ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)))
      else
        { l := some (go k o q), var := v,
          Tape := Tape.move Dir.right ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L))) }) =
    some
      { l := some (go k o q), var := v,
        Tape := Tape.move Dir.right ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L))) }
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ n < List.length (List.reverse S)
[PROOFSTEP]
rfl
[GOAL]
case succ
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
o : StAct k
q : Stmt₂
v : σ
S : List (Γ k)
L : ListBlank ((k : K) → Option (Γ k))
hL : ListBlank.map (proj k) L = ListBlank.mk (List.reverse (List.map some S))
n✝ : ℕ
H✝ : n✝ ≤ List.length S
n : ℕ
IH :
  n ≤ List.length S →
    Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
      { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
H : Nat.succ n ≤ List.length S
⊢ n < List.length (List.reverse S)
[PROOFSTEP]
rwa [List.length_reverse]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : Stmt₂
v : σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
⊢ Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : Stmt₂
v : σ
L : ListBlank ((k : K) → Option (Γ k))
⊢ Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[Nat.zero] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
[PROOFSTEP]
rfl
[GOAL]
case succ
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : Stmt₂
v : σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
IH :
  Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
⊢ Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[Nat.succ n] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
[PROOFSTEP]
refine' Reaches₀.head _ IH
[GOAL]
case succ
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : Stmt₂
v : σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
IH :
  Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
⊢ { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) } ∈
    TM1.step (tr M)
      { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[Nat.succ n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
simp only [Option.mem_def, TM1.step]
[GOAL]
case succ
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : Stmt₂
v : σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
IH :
  Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
⊢ some (TM1.stepAux (tr M (ret q)) v ((Tape.move Dir.right)^[Nat.succ n] (Tape.mk' ∅ (addBottom L)))) =
    some { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
rw [Option.some_inj, tr, TM1.stepAux, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_succ_fst, TM1.stepAux,
  iterate_succ', Function.comp_apply, Tape.move_right_left]
[GOAL]
case succ
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : Stmt₂
v : σ
L : ListBlank ((k : K) → Option (Γ k))
n : ℕ
IH :
  Reaches₀ (TM1.step (tr M))
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
    { l := some (ret q), var := v, Tape := Tape.mk' ∅ (addBottom L) }
⊢ (bif false then
      TM1.stepAux (trNormal q) v (Tape.move Dir.right ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L))))
    else TM1.stepAux (goto fun x x => ret q) v ((Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)))) =
    { l := some (ret q), var := v, Tape := (Tape.move Dir.right)^[n] (Tape.mk' ∅ (addBottom L)) }
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
⊢ ∃ b,
    TrCfg (TM2.stepAux (stRun o q) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (stRun o q)) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
simp only [trNormal_run, step_run]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
⊢ ∃ b,
    TrCfg (TM2.stepAux q (stVar v (S k) o) (update S k (stWrite v (S k) o))) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (goto fun x x => go k o q) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
have hgo := tr_respects_aux₁ M o q v (hT k) _ le_rfl
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
⊢ ∃ b,
    TrCfg (TM2.stepAux q (stVar v (S k) o) (update S k (stWrite v (S k) o))) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (goto fun x x => go k o q) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
obtain ⟨T', hT', hrun⟩ := tr_respects_aux₂ hT o
[GOAL]
case intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
T' : ListBlank ((k : K) → Option (Γ k))
hT' :
  ∀ (k_1 : K),
    ListBlank.map (proj k_1) T' =
      ListBlank.mk (List.reverse (List.map some (update (fun k => S k) k (stWrite ?m.705248 (S k) o) k_1)))
hrun :
  TM1.stepAux (trStAct ?m.705247 o) ?m.705248 ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))) =
    TM1.stepAux ?m.705247 (stVar ?m.705248 (S k) o)
      ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite ?m.705248 (S k) o) k)]
        (Tape.mk' ∅ (addBottom T')))
⊢ ∃ b,
    TrCfg (TM2.stepAux q (stVar v (S k) o) (update S k (stWrite v (S k) o))) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (goto fun x x => go k o q) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
have := hgo.tail' rfl
[GOAL]
case intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
T' : ListBlank ((k : K) → Option (Γ k))
hT' :
  ∀ (k_1 : K),
    ListBlank.map (proj k_1) T' =
      ListBlank.mk (List.reverse (List.map some (update (fun k => S k) k (stWrite ?m.705248 (S k) o) k_1)))
hrun :
  TM1.stepAux (trStAct ?m.705247 o) ?m.705248 ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))) =
    TM1.stepAux ?m.705247 (stVar ?m.705248 (S k) o)
      ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite ?m.705248 (S k) o) k)]
        (Tape.mk' ∅ (addBottom T')))
this :
  Reaches₁ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    (TM1.stepAux (tr M (go k o q)) v ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))))
⊢ ∃ b,
    TrCfg (TM2.stepAux q (stVar v (S k) o) (update S k (stWrite v (S k) o))) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (goto fun x x => go k o q) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
rw [tr, TM1.stepAux, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_snd, stk_nth_val _ (hT k),
  List.get?_len_le (le_of_eq (List.length_reverse _)), Option.isNone, cond, hrun, TM1.stepAux] at this
[GOAL]
case intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
T' : ListBlank ((k : K) → Option (Γ k))
hT' :
  ∀ (k_1 : K),
    ListBlank.map (proj k_1) T' =
      ListBlank.mk (List.reverse (List.map some (update (fun k => S k) k (stWrite v (S k) o) k_1)))
hrun :
  TM1.stepAux (trStAct (goto fun x x => ret q) o) v
      ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))) =
    TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
      ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)] (Tape.mk' ∅ (addBottom T')))
this :
  Reaches₁ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    (match
      match none with
      | some val => false
      | none => true with
    | true =>
      TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
        ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)]
          (Tape.mk' ∅ (addBottom T')))
    | false =>
      TM1.stepAux (goto fun x x => go k o q) v
        (Tape.move Dir.right ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)))))
⊢ ∃ b,
    TrCfg (TM2.stepAux q (stVar v (S k) o) (update S k (stWrite v (S k) o))) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (goto fun x x => go k o q) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
obtain ⟨c, gc, rc⟩ := IH hT'
[GOAL]
case intro.intro.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
T' : ListBlank ((k : K) → Option (Γ k))
hT' :
  ∀ (k_1 : K),
    ListBlank.map (proj k_1) T' =
      ListBlank.mk (List.reverse (List.map some (update (fun k => S k) k (stWrite v (S k) o) k_1)))
hrun :
  TM1.stepAux (trStAct (goto fun x x => ret q) o) v
      ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))) =
    TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
      ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)] (Tape.mk' ∅ (addBottom T')))
this :
  Reaches₁ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    (match
      match none with
      | some val => false
      | none => true with
    | true =>
      TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
        ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)]
          (Tape.mk' ∅ (addBottom T')))
    | false =>
      TM1.stepAux (goto fun x x => go k o q) v
        (Tape.move Dir.right ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)))))
c : TM1.Cfg Γ' Λ' σ
gc : TrCfg (TM2.stepAux q ?m.709134 fun k_1 => update (fun k => S k) k (stWrite v (S k) o) k_1) c
rc : Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q) ?m.709134 (Tape.mk' ∅ (addBottom T'))) c
⊢ ∃ b,
    TrCfg (TM2.stepAux q (stVar v (S k) o) (update S k (stWrite v (S k) o))) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (goto fun x x => go k o q) v (Tape.mk' ∅ (addBottom T))) b
[PROOFSTEP]
refine' ⟨c, gc, (this.to₀.trans (tr_respects_aux₃ M _) c (TransGen.head' rfl _)).to_reflTransGen⟩
[GOAL]
case intro.intro.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
T' : ListBlank ((k : K) → Option (Γ k))
hT' :
  ∀ (k_1 : K),
    ListBlank.map (proj k_1) T' =
      ListBlank.mk (List.reverse (List.map some (update (fun k => S k) k (stWrite v (S k) o) k_1)))
hrun :
  TM1.stepAux (trStAct (goto fun x x => ret q) o) v
      ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))) =
    TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
      ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)] (Tape.mk' ∅ (addBottom T')))
this :
  Reaches₁ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    (match
      match none with
      | some val => false
      | none => true with
    | true =>
      TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
        ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)]
          (Tape.mk' ∅ (addBottom T')))
    | false =>
      TM1.stepAux (goto fun x x => go k o q) v
        (Tape.move Dir.right ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)))))
c : TM1.Cfg Γ' Λ' σ
gc : TrCfg (TM2.stepAux q (stVar v (S k) o) fun k_1 => update (fun k => S k) k (stWrite v (S k) o) k_1) c
rc : Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q) (stVar v (S k) o) (Tape.mk' ∅ (addBottom T'))) c
⊢ ReflTransGen (fun a b => b ∈ TM1.step (tr M) a)
    (TM1.stepAux (tr M (ret q)) (stVar v (S k) o) (Tape.mk' ∅ (addBottom T'))) c
[PROOFSTEP]
rw [tr, TM1.stepAux, Tape.mk'_head, addBottom_head_fst]
[GOAL]
case intro.intro.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
q : TM2.Stmt (fun k => Γ k) Λ σ
v : σ
T : ListBlank ((i : K) → Option (Γ i))
k : K
S : (k : K) → List (Γ k)
hT : ∀ (k : K), ListBlank.map (proj k) T = ListBlank.mk (List.reverse (List.map some (S k)))
o : StAct k
IH :
  ∀ {v : σ} {S : (k : K) → List (Γ k)} {T : ListBlank ((k : K) → Option (Γ k))},
    (∀ (k : K), ListBlank.map (proj k) T = 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 T))) b
hgo :
  Reaches₀ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    { l := some (go k o q), var := v, Tape := (Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)) }
T' : ListBlank ((k : K) → Option (Γ k))
hT' :
  ∀ (k_1 : K),
    ListBlank.map (proj k_1) T' =
      ListBlank.mk (List.reverse (List.map some (update (fun k => S k) k (stWrite v (S k) o) k_1)))
hrun :
  TM1.stepAux (trStAct (goto fun x x => ret q) o) v
      ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T))) =
    TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
      ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)] (Tape.mk' ∅ (addBottom T')))
this :
  Reaches₁ (TM1.step (tr M)) { l := some (go k o q), var := v, Tape := Tape.mk' ∅ (addBottom T) }
    (match
      match none with
      | some val => false
      | none => true with
    | true =>
      TM1.stepAux (goto fun x x => ret q) (stVar v (S k) o)
        ((Tape.move Dir.right)^[List.length (update (fun k => S k) k (stWrite v (S k) o) k)]
          (Tape.mk' ∅ (addBottom T')))
    | false =>
      TM1.stepAux (goto fun x x => go k o q) v
        (Tape.move Dir.right ((Tape.move Dir.right)^[List.length (S k)] (Tape.mk' ∅ (addBottom T)))))
c : TM1.Cfg Γ' Λ' σ
gc : TrCfg (TM2.stepAux q (stVar v (S k) o) fun k_1 => update (fun k => S k) k (stWrite v (S k) o) k_1) c
rc : Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal q) (stVar v (S k) o) (Tape.mk' ∅ (addBottom T'))) c
⊢ ReflTransGen (fun a b => b ∈ TM1.step (tr M) a)
    (bif true then TM1.stepAux (trNormal q) (stVar v (S k) o) (Tape.mk' ∅ (addBottom T'))
    else TM1.stepAux (move Dir.left (goto fun x x => ret q)) (stVar v (S k) o) (Tape.mk' ∅ (addBottom T')))
    c
[PROOFSTEP]
exact rc
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
⊢ Respects (TM2.step M) (TM1.step (tr M)) TrCfg
[PROOFSTEP]
intro c₁ c₂ h
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
c₁ : Cfg₂
c₂ : TM1.Cfg Γ' Λ' σ
h : TrCfg c₁ c₂
⊢ match TM2.step M c₁ with
  | some b₁ => ∃ b₂, TrCfg b₁ b₂ ∧ Reaches₁ (TM1.step (tr M)) c₂ b₂
  | none => TM1.step (tr M) c₂ = none
[PROOFSTEP]
cases' h with l v S L hT
[GOAL]
case mk
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
l : Option Λ
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)))
⊢ match TM2.step M { l := l, var := v, stk := S } with
  | some b₁ =>
    ∃ b₂,
      TrCfg b₁ b₂ ∧
        Reaches₁ (TM1.step (tr M)) { l := Option.map normal l, var := v, Tape := Tape.mk' ∅ (addBottom L) } b₂
  | none => TM1.step (tr M) { l := Option.map normal l, var := v, Tape := Tape.mk' ∅ (addBottom L) } = none
[PROOFSTEP]
cases' l with l
[GOAL]
case mk.none
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
⊢ match TM2.step M { l := none, var := v, stk := S } with
  | some b₁ =>
    ∃ b₂,
      TrCfg b₁ b₂ ∧
        Reaches₁ (TM1.step (tr M)) { l := Option.map normal none, var := v, Tape := Tape.mk' ∅ (addBottom L) } b₂
  | none => TM1.step (tr M) { l := Option.map normal none, var := v, Tape := Tape.mk' ∅ (addBottom L) } = none
[PROOFSTEP]
constructor
[GOAL]
case mk.some
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
⊢ match TM2.step M { l := some l, var := v, stk := S } with
  | some b₁ =>
    ∃ b₂,
      TrCfg b₁ b₂ ∧
        Reaches₁ (TM1.step (tr M)) { l := Option.map normal (some l), var := v, Tape := Tape.mk' ∅ (addBottom L) } b₂
  | none => TM1.step (tr M) { l := Option.map normal (some l), var := v, Tape := Tape.mk' ∅ (addBottom L) } = none
[PROOFSTEP]
simp only [TM2.step, Respects, Option.map_some']
[GOAL]
case mk.some
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
⊢ ∃ b₂,
    TrCfg (TM2.stepAux (M l) v S) b₂ ∧
      Reaches₁ (TM1.step (tr M)) { l := some (normal l), var := v, Tape := Tape.mk' ∅ (addBottom L) } b₂
[PROOFSTEP]
rsuffices ⟨b, c, r⟩ : ∃ b, _ ∧ Reaches (TM1.step (tr M)) _ _
[GOAL]
case mk.some.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
b : ?m.714525
c : ?m.714852 b
r : Reaches (TM1.step (tr M)) (?m.714853 b) (?m.714854 b)
⊢ ∃ b₂,
    TrCfg (TM2.stepAux (M l) v S) b₂ ∧
      Reaches₁ (TM1.step (tr M)) { l := some (normal l), var := v, Tape := Tape.mk' ∅ (addBottom L) } b₂
[PROOFSTEP]
exact ⟨b, c, TransGen.head' rfl r⟩
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
⊢ ∃ b,
    TrCfg (TM2.stepAux (M l) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (tr M (normal l)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
simp only [tr]
  -- Porting note: `refine'` failed because of implicit lambda, so `induction` is used.
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
⊢ ∃ b,
    TrCfg (TM2.stepAux (M l) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (M l)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
generalize M l = N
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
N : Stmt₂
⊢ ∃ b, TrCfg (TM2.stepAux N v S) b ∧ Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal N) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
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₅ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
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)))
l : Λ
N : Stmt₂
⊢ ∃ b, TrCfg (TM2.stepAux N v S) b ∧ Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal N) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
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₅ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
[GOAL]
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 : Λ
k : K
s : StAct k
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
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 (stRun s q) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (stRun s q)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]

| H₁ k s q IH => exact tr_respects_aux M hT s @IH
[GOAL]
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 : Λ
k : K
s : StAct k
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
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 (stRun s q) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (stRun s q)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
exact tr_respects_aux M hT s @IH
[GOAL]
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 : Λ
a : σ → σ
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
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.load a q✝) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (TM2.Stmt.load a q✝)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]

| H₂ a _ IH => exact IH _ hT
[GOAL]
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 : Λ
a : σ → σ
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
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.load a q✝) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (TM2.Stmt.load a q✝)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
exact IH _ hT
[GOAL]
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 (TM2.stepAux (TM2.Stmt.branch p q₁ q₂) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (TM2.Stmt.branch p q₁ q₂)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]

| H₃ p q₁ q₂ IH₁ IH₂ =>
  unfold TM2.stepAux trNormal TM1.stepAux
  simp only []
  cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
[GOAL]
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 (TM2.stepAux (TM2.Stmt.branch p q₁ q₂) v S) b ∧
      Reaches (TM1.step (tr M)) (TM1.stepAux (trNormal (TM2.Stmt.branch p q₁ q₂)) v (Tape.mk' ∅ (addBottom L))) b
[PROOFSTEP]
unfold TM2.stepAux trNormal TM1.stepAux
[GOAL]
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 (fun x => p) (Tape.mk' ∅ (addBottom L)).head v then TM1.stepAux (trNormal q₁) v (Tape.mk' ∅ (addBottom L))
        else TM1.stepAux (trNormal q₂) v (Tape.mk' ∅ (addBottom L)))
        b
[PROOFSTEP]
simp only []
[GOAL]
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
[PROOFSTEP]
cases p v <;> [exact IH₂ _ hT; exact IH₁ _ hT]
[GOAL]
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
[PROOFSTEP]
cases p v
[GOAL]
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
[PROOFSTEP]
exact IH₂ _ hT
[GOAL]
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
[PROOFSTEP]
exact IH₁ _ hT
[GOAL]
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
[PROOFSTEP]

| H₄ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
[GOAL]
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
[PROOFSTEP]
exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
[GOAL]
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
[PROOFSTEP]

| H₅ => exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
[GOAL]
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
[PROOFSTEP]
exact ⟨_, ⟨_, hT⟩, ReflTransGen.refl⟩
[GOAL]
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))
[PROOFSTEP]
rw [(_ : TM1.init _ = _)]
[GOAL]
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.724426
[PROOFSTEP]
refine' ⟨ListBlank.mk (L.reverse.map fun a ↦ update default k (some a)), fun k' ↦ _⟩
[GOAL]
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')))
[PROOFSTEP]
refine' ListBlank.ext fun i ↦ _
[GOAL]
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
[PROOFSTEP]
rw [ListBlank.map_mk, ListBlank.nth_mk, List.getI_eq_iget_get?, List.map_map]
[GOAL]
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
[PROOFSTEP]
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
[GOAL]
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
[PROOFSTEP]
rw [this, List.get?_map, proj, PointedMap.mk_val]
[GOAL]
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
[PROOFSTEP]
simp only []
[GOAL]
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
[PROOFSTEP]
by_cases h : k' = k
[GOAL]
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
[PROOFSTEP]
subst k'
[GOAL]
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
[PROOFSTEP]
simp only [Function.update_same]
[GOAL]
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
[PROOFSTEP]
rw [ListBlank.nth_mk, List.getI_eq_iget_get?, ← List.map_reverse, List.get?_map]
[GOAL]
case neg
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
[PROOFSTEP]
simp only [Function.update_noteq h]
[GOAL]
case neg
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 => default k') (List.get? (List.reverse L) i)) =
    ListBlank.nth (ListBlank.mk (List.reverse (List.map some []))) i
[PROOFSTEP]
rw [ListBlank.nth_mk, List.getI_eq_iget_get?, List.map, List.reverse_nil]
[GOAL]
case neg
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 => default k') (List.get? (List.reverse L) i)) = Option.iget (List.get? [] i)
[PROOFSTEP]
cases L.reverse.get? i
[GOAL]
case neg.none
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 => default k') none) = Option.iget (List.get? [] i)
[PROOFSTEP]
rfl
[GOAL]
case neg.some
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
val✝ : Γ k
⊢ Option.iget (Option.map (fun a => default k') (some val✝)) = Option.iget (List.get? [] i)
[PROOFSTEP]
rfl
[GOAL]
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)
⊢ TM1.init (trInit k L) =
    { l := Option.map normal (some default), var := default,
      Tape := Tape.mk' ∅ (addBottom (ListBlank.mk (List.map (fun a => update default k (some a)) (List.reverse L)))) }
[PROOFSTEP]
rw [trInit, TM1.init]
[GOAL]
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)
⊢ { l := some default, var := default,
      Tape :=
        Tape.mk₁
          (let L' := List.map (fun a => (false, update (fun x => none) k (some a))) (List.reverse L);
          (true, (List.headI L').snd) :: List.tail L') } =
    { l := Option.map normal (some default), var := default,
      Tape := Tape.mk' ∅ (addBottom (ListBlank.mk (List.map (fun a => update default k (some a)) (List.reverse L)))) }
[PROOFSTEP]
dsimp only
[GOAL]
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)
⊢ { l := some default, var := default,
      Tape :=
        Tape.mk₁
          ((true, (List.headI (List.map (fun a => (false, update (fun x => none) k (some a))) (List.reverse L))).snd) ::
            List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) (List.reverse L))) } =
    { l := Option.map normal (some default), var := default,
      Tape := Tape.mk' ∅ (addBottom (ListBlank.mk (List.map (fun a => update default k (some a)) (List.reverse L)))) }
[PROOFSTEP]
congr
[GOAL]
case e_Tape.e_l.e_head.e_snd
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)
⊢ (List.headI (List.map (fun a => (false, update (fun x => none) k (some a))) (List.reverse L))).snd =
    ListBlank.head (ListBlank.mk (List.map (fun a => update default k (some a)) (List.reverse L)))
[PROOFSTEP]
cases L.reverse
[GOAL]
case e_Tape.e_l.e_tail
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)
⊢ List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) (List.reverse L)) =
    List.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }.f
      (List.tail (List.map (fun a => update default k (some a)) (List.reverse L)))
[PROOFSTEP]
cases L.reverse
[GOAL]
case e_Tape.e_l.e_head.e_snd.nil
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)
⊢ (List.headI (List.map (fun a => (false, update (fun x => none) k (some a))) [])).snd =
    ListBlank.head (ListBlank.mk (List.map (fun a => update default k (some a)) []))
[PROOFSTEP]
try rfl
[GOAL]
case e_Tape.e_l.e_head.e_snd.nil
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)
⊢ (List.headI (List.map (fun a => (false, update (fun x => none) k (some a))) [])).snd =
    ListBlank.head (ListBlank.mk (List.map (fun a => update default k (some a)) []))
[PROOFSTEP]
rfl
[GOAL]
case e_Tape.e_l.e_head.e_snd.cons
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)
head✝ : Γ k
tail✝ : List (Γ k)
⊢ (List.headI (List.map (fun a => (false, update (fun x => none) k (some a))) (head✝ :: tail✝))).snd =
    ListBlank.head (ListBlank.mk (List.map (fun a => update default k (some a)) (head✝ :: tail✝)))
[PROOFSTEP]
try rfl
[GOAL]
case e_Tape.e_l.e_head.e_snd.cons
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)
head✝ : Γ k
tail✝ : List (Γ k)
⊢ (List.headI (List.map (fun a => (false, update (fun x => none) k (some a))) (head✝ :: tail✝))).snd =
    ListBlank.head (ListBlank.mk (List.map (fun a => update default k (some a)) (head✝ :: tail✝)))
[PROOFSTEP]
rfl
[GOAL]
case e_Tape.e_l.e_tail.nil
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)
⊢ List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) []) =
    List.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }.f
      (List.tail (List.map (fun a => update default k (some a)) []))
[PROOFSTEP]
try rfl
[GOAL]
case e_Tape.e_l.e_tail.nil
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)
⊢ List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) []) =
    List.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }.f
      (List.tail (List.map (fun a => update default k (some a)) []))
[PROOFSTEP]
rfl
[GOAL]
case e_Tape.e_l.e_tail.cons
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)
head✝ : Γ k
tail✝ : List (Γ k)
⊢ List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) (head✝ :: tail✝)) =
    List.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }.f
      (List.tail (List.map (fun a => update default k (some a)) (head✝ :: tail✝)))
[PROOFSTEP]
try rfl
[GOAL]
case e_Tape.e_l.e_tail.cons
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)
head✝ : Γ k
tail✝ : List (Γ k)
⊢ List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) (head✝ :: tail✝)) =
    List.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }.f
      (List.tail (List.map (fun a => update default k (some a)) (head✝ :: tail✝)))
[PROOFSTEP]
rfl
[GOAL]
case e_Tape.e_l.e_tail.cons
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)
head✝ : Γ k
tail✝ : List (Γ k)
⊢ List.tail (List.map (fun a => (false, update (fun x => none) k (some a))) (head✝ :: tail✝)) =
    List.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }.f
      (List.tail (List.map (fun a => update default k (some a)) (head✝ :: tail✝)))
[PROOFSTEP]
simp only [List.map_map, List.tail_cons, List.map]
[GOAL]
case e_Tape.e_l.e_tail.cons
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)
head✝ : Γ k
tail✝ : List (Γ k)
⊢ List.map (fun a => (false, update (fun x => none) k (some a))) tail✝ =
    List.map (Prod.mk false ∘ fun a => update default k (some a)) tail✝
[PROOFSTEP]
rfl
[GOAL]
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)
L₁ : ListBlank Γ'
L₂ : List (Γ k)
H₁ : L₁ ∈ TM1.eval (tr M) (trInit k L)
H₂ : L₂ ∈ TM2.eval M k L
⊢ ∃ S L',
    addBottom L' = L₁ ∧
      (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S k)))) ∧ S k = L₂
[PROOFSTEP]
obtain ⟨c₁, h₁, rfl⟩ := (Part.mem_map_iff _).1 H₁
[GOAL]
case intro.intro
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 L₂ : List (Γ k)
H₂ : L₂ ∈ TM2.eval M k L
c₁ : TM1.Cfg Γ' Λ' σ
h₁ : c₁ ∈ eval (TM1.step (tr M)) (TM1.init (trInit k L))
H₁ : Tape.right₀ c₁.Tape ∈ TM1.eval (tr M) (trInit k L)
⊢ ∃ S L',
    addBottom L' = Tape.right₀ c₁.Tape ∧
      (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S k)))) ∧ S k = L₂
[PROOFSTEP]
obtain ⟨c₂, h₂, rfl⟩ := (Part.mem_map_iff _).1 H₂
[GOAL]
case intro.intro.intro.intro
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)
c₁ : TM1.Cfg Γ' Λ' σ
h₁ : c₁ ∈ eval (TM1.step (tr M)) (TM1.init (trInit k L))
H₁ : Tape.right₀ c₁.Tape ∈ TM1.eval (tr M) (trInit k L)
c₂ : Cfg₂
h₂ : c₂ ∈ eval (TM2.step M) (TM2.init k L)
H₂ : TM2.Cfg.stk c₂ k ∈ TM2.eval M k L
⊢ ∃ S L',
    addBottom L' = Tape.right₀ c₁.Tape ∧
      (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S k)))) ∧
        S k = TM2.Cfg.stk c₂ k
[PROOFSTEP]
obtain ⟨_, ⟨L', hT⟩, h₃⟩ := Turing.tr_eval (tr_respects M) (trCfg_init k L) h₂
[GOAL]
case intro.intro.intro.intro.intro.intro.mk
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)
c₁ : TM1.Cfg Γ' Λ' σ
h₁ : c₁ ∈ eval (TM1.step (tr M)) (TM1.init (trInit k L))
H₁ : Tape.right₀ c₁.Tape ∈ TM1.eval (tr M) (trInit k L)
q✝ : Option Λ
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)))
h₂ : { l := q✝, var := v✝, stk := S✝ } ∈ eval (TM2.step M) (TM2.init k L)
H₂ : TM2.Cfg.stk { l := q✝, var := v✝, stk := S✝ } k ∈ TM2.eval M k L
h₃ :
  { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') } ∈
    eval (TM1.step (tr M)) (TM1.init (trInit k L))
⊢ ∃ S L',
    addBottom L' = Tape.right₀ c₁.Tape ∧
      (∀ (k : K), ListBlank.map (proj k) L' = ListBlank.mk (List.reverse (List.map some (S k)))) ∧
        S k = TM2.Cfg.stk { l := q✝, var := v✝, stk := S✝ } k
[PROOFSTEP]
cases Part.mem_unique h₁ h₃
[GOAL]
case intro.intro.intro.intro.intro.intro.mk.refl
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)
q✝ : Option Λ
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)))
h₂ : { l := q✝, var := v✝, stk := S✝ } ∈ eval (TM2.step M) (TM2.init k L)
H₂ : TM2.Cfg.stk { l := q✝, var := v✝, stk := S✝ } k ∈ TM2.eval M k L
h₃ :
  { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') } ∈
    eval (TM1.step (tr M)) (TM1.init (trInit k L))
h₁ :
  { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') } ∈
    eval (TM1.step (tr M)) (TM1.init (trInit k L))
H₁ :
  Tape.right₀ { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') }.Tape ∈
    TM1.eval (tr M) (trInit k L)
⊢ ∃ S L'_1,
    addBottom L'_1 = Tape.right₀ { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') }.Tape ∧
      (∀ (k : K), ListBlank.map (proj k) L'_1 = ListBlank.mk (List.reverse (List.map some (S k)))) ∧
        S k = TM2.Cfg.stk { l := q✝, var := v✝, stk := S✝ } k
[PROOFSTEP]
exact ⟨_, L', by simp only [Tape.mk'_right₀], hT, rfl⟩
[GOAL]
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)
q✝ : Option Λ
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)))
h₂ : { l := q✝, var := v✝, stk := S✝ } ∈ eval (TM2.step M) (TM2.init k L)
H₂ : TM2.Cfg.stk { l := q✝, var := v✝, stk := S✝ } k ∈ TM2.eval M k L
h₃ :
  { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') } ∈
    eval (TM1.step (tr M)) (TM1.init (trInit k L))
h₁ :
  { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') } ∈
    eval (TM1.step (tr M)) (TM1.init (trInit k L))
H₁ :
  Tape.right₀ { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') }.Tape ∈
    TM1.eval (tr M) (trInit k L)
⊢ addBottom L' = Tape.right₀ { l := Option.map normal q✝, var := v✝, Tape := Tape.mk' ∅ (addBottom L') }.Tape
[PROOFSTEP]
simp only [Tape.mk'_right₀]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h : l' ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
suffices
  ∀ (q) (_ : TM2.SupportsStmt S q) (_ : ∀ x ∈ trStmts₁ q, x ∈ trSupp M S),
    TM1.SupportsStmt (trSupp M S) (trNormal q) ∧ ∀ l' ∈ trStmts₁ q, TM1.SupportsStmt (trSupp M S) (tr M l')
  by
  rcases Finset.mem_biUnion.1 h with ⟨l, lS, h⟩
  have := this _ (ss.2 l lS) fun x hx ↦ Finset.mem_biUnion.2 ⟨_, lS, Finset.mem_insert_of_mem hx⟩
  rcases Finset.mem_insert.1 h with (rfl | h) <;> [exact this.1; exact this.2 _ h]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h : l' ∈ trSupp M S
this :
  ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
rcases Finset.mem_biUnion.1 h with ⟨l, lS, h⟩
[GOAL]
case intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h✝ : l' ∈ trSupp M S
this :
  ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ
lS : l ∈ S
h : l' ∈ insert (normal l) (trStmts₁ (M l))
⊢ TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
have := this _ (ss.2 l lS) fun x hx ↦ Finset.mem_biUnion.2 ⟨_, lS, Finset.mem_insert_of_mem hx⟩
[GOAL]
case intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h✝ : l' ∈ trSupp M S
this✝ :
  ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ
lS : l ∈ S
h : l' ∈ insert (normal l) (trStmts₁ (M l))
this :
  TM1.SupportsStmt (trSupp M S) (trNormal (M l)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (M l) → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
rcases Finset.mem_insert.1 h with (rfl | h) <;> [exact this.1; exact this.2 _ h]
[GOAL]
case intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h✝ : l' ∈ trSupp M S
this✝ :
  ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ
lS : l ∈ S
h : l' ∈ insert (normal l) (trStmts₁ (M l))
this :
  TM1.SupportsStmt (trSupp M S) (trNormal (M l)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (M l) → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
rcases Finset.mem_insert.1 h with (rfl | h)
[GOAL]
case intro.intro.inl
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
this✝ :
  ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ
lS : l ∈ S
this :
  TM1.SupportsStmt (trSupp M S) (trNormal (M l)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (M l) → TM1.SupportsStmt (trSupp M S) (tr M l')
h✝ : normal l ∈ trSupp M S
h : normal l ∈ insert (normal l) (trStmts₁ (M l))
⊢ TM1.SupportsStmt (trSupp M S) (tr M (normal l))
[PROOFSTEP]
exact this.1
[GOAL]
case intro.intro.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h✝¹ : l' ∈ trSupp M S
this✝ :
  ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ
lS : l ∈ S
h✝ : l' ∈ insert (normal l) (trStmts₁ (M l))
this :
  TM1.SupportsStmt (trSupp M S) (trNormal (M l)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (M l) → TM1.SupportsStmt (trSupp M S) (tr M l')
h : l' ∈ trStmts₁ (M l)
⊢ TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
exact this.2 _ h
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l' : Λ'
h : l' ∈ trSupp M S
⊢ ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
clear h l'
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
⊢ ∀ (q : Stmt₂),
    TM2.SupportsStmt S q →
      (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
refine' stmtStRec _ _ _ _ _
[GOAL]
case refine'_1
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
⊢ ∀ (k : K) (s : StAct k) (q : Stmt₂),
    (TM2.SupportsStmt S q →
        (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
          TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
            ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')) →
      TM2.SupportsStmt S (stRun s q) →
        (∀ (x : Λ'), x ∈ trStmts₁ (stRun s q) → x ∈ trSupp M S) →
          TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q)) ∧
            ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
intro _ s _ IH ss' sub
[GOAL]
case refine'_1
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (stRun s q✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ (stRun s q✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
rw [TM2to1.supports_run] at ss'
[GOAL]
case refine'_1
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), x ∈ trStmts₁ (stRun s q✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
simp only [TM2to1.trStmts₁_run, Finset.mem_union, Finset.mem_insert, Finset.mem_singleton] at sub
[GOAL]
case refine'_1
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
have hgo := sub _ (Or.inl <| Or.inl rfl)
[GOAL]
case refine'_1
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
have hret := sub _ (Or.inl <| Or.inr rfl)
[GOAL]
case refine'_1
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
cases' IH ss' fun x hx ↦ sub x <| Or.inr hx with IH₁ IH₂
[GOAL]
case refine'_1.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (stRun s q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
refine' ⟨by simp only [trNormal_run, TM1.SupportsStmt]; intros; exact hgo, fun l h ↦ _⟩
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (stRun s q✝))
[PROOFSTEP]
simp only [trNormal_run, TM1.SupportsStmt]
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ Γ' → σ → go k✝ s q✝ ∈ trSupp M S
[PROOFSTEP]
intros
[GOAL]
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
a✝ : Γ'
v✝ : σ
⊢ go k✝ s q✝ ∈ trSupp M S
[PROOFSTEP]
exact hgo
[GOAL]
case refine'_1.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : l ∈ trStmts₁ (stRun s q✝)
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
rw [trStmts₁_run] at h
[GOAL]
case refine'_1.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : l ∈ {go k✝ s q✝, ret q✝} ∪ trStmts₁ q✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
simp only [TM2to1.trStmts₁_run, Finset.mem_union, Finset.mem_insert, Finset.mem_singleton] at h
[GOAL]
case refine'_1.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : (l = go k✝ s q✝ ∨ l = ret q✝) ∨ l ∈ trStmts₁ q✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
rcases h with (⟨rfl | rfl⟩ | h)
[GOAL]
case refine'_1.intro.inl.inl
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (tr M (go k✝ s q✝))
[PROOFSTEP]
cases s
[GOAL]
case refine'_1.intro.inl.inl.push
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
a✝ : σ → Γ k✝
sub : ∀ (x : Λ'), (x = go k✝ (StAct.push a✝) q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ (StAct.push a✝) q✝ ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (tr M (go k✝ (StAct.push a✝) q✝))
[PROOFSTEP]
exact ⟨fun _ _ ↦ hret, fun _ _ ↦ hgo⟩
[GOAL]
case refine'_1.intro.inl.inl.peek
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
a✝ : σ → Option (Γ k✝) → σ
sub : ∀ (x : Λ'), (x = go k✝ (StAct.peek a✝) q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ (StAct.peek a✝) q✝ ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (tr M (go k✝ (StAct.peek a✝) q✝))
[PROOFSTEP]
exact ⟨fun _ _ ↦ hret, fun _ _ ↦ hgo⟩
[GOAL]
case refine'_1.intro.inl.inl.pop
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
a✝ : σ → Option (Γ k✝) → σ
sub : ∀ (x : Λ'), (x = go k✝ (StAct.pop a✝) q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ (StAct.pop a✝) q✝ ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (tr M (go k✝ (StAct.pop a✝) q✝))
[PROOFSTEP]
exact ⟨⟨fun _ _ ↦ hret, fun _ _ ↦ hret⟩, fun _ _ ↦ hgo⟩
[GOAL]
case refine'_1.intro.inl.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (tr M (ret q✝))
[PROOFSTEP]
unfold TM1.SupportsStmt TM2to1.tr
[GOAL]
case refine'_1.intro.inl.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ match
    match ret q✝ with
    | normal q => trNormal (M q)
    | go k s q =>
      branch (fun a x => Option.isNone (Prod.snd a k)) (trStAct (goto fun x x => ret q) s)
        (move Dir.right (goto fun x x => go k s q))
    | ret q => branch (fun a x => a.fst) (trNormal q) (move Dir.left (goto fun x x => ret q)) with
  | move a q => TM1.SupportsStmt (trSupp M S) q
  | write a q => TM1.SupportsStmt (trSupp M S) q
  | load a q => TM1.SupportsStmt (trSupp M S) q
  | branch a q₁ q₂ => TM1.SupportsStmt (trSupp M S) q₁ ∧ TM1.SupportsStmt (trSupp M S) q₂
  | goto l => ∀ (a : Γ') (v : σ), l a v ∈ trSupp M S
  | halt => True
[PROOFSTEP]
exact ⟨IH₁, fun _ _ ↦ hret⟩
[GOAL]
case refine'_1.intro.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
k✝ : K
s : StAct k✝
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S q✝
sub : ∀ (x : Λ'), (x = go k✝ s q✝ ∨ x = ret q✝) ∨ x ∈ trStmts₁ q✝ → x ∈ trSupp M S
hgo : go k✝ s q✝ ∈ trSupp M S
hret : ret q✝ ∈ trSupp M S
IH₁ : TM1.SupportsStmt (trSupp M S) (trNormal q✝)
IH₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : l ∈ trStmts₁ q✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
exact IH₂ _ h
[GOAL]
case refine'_2
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
⊢ ∀ (a : σ → σ) (q : Stmt₂),
    (TM2.SupportsStmt S q →
        (∀ (x : Λ'), x ∈ trStmts₁ q → x ∈ trSupp M S) →
          TM1.SupportsStmt (trSupp M S) (trNormal q) ∧
            ∀ (l' : Λ'), l' ∈ trStmts₁ q → TM1.SupportsStmt (trSupp M S) (tr M l')) →
      TM2.SupportsStmt S (TM2.Stmt.load a q) →
        (∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.load a q) → x ∈ trSupp M S) →
          TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.load a q)) ∧
            ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.load a q) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
intro _ _ IH ss' sub
[GOAL]
case refine'_2
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
a✝ : σ → σ
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.load a✝ q✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.load a✝ q✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.load a✝ q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.load a✝ q✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
unfold TM2to1.trStmts₁ at ss' sub ⊢
[GOAL]
case refine'_2
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
a✝ : σ → σ
q✝ : Stmt₂
IH :
  TM2.SupportsStmt S q✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.load a✝ q✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q✝ → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.load a✝ q✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ q✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
exact IH ss' sub
[GOAL]
case refine'_3
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
⊢ ∀ (p : σ → Bool) (q₁ q₂ : Stmt₂),
    (TM2.SupportsStmt S q₁ →
        (∀ (x : Λ'), x ∈ trStmts₁ q₁ → x ∈ trSupp M S) →
          TM1.SupportsStmt (trSupp M S) (trNormal q₁) ∧
            ∀ (l' : Λ'), l' ∈ trStmts₁ q₁ → TM1.SupportsStmt (trSupp M S) (tr M l')) →
      (TM2.SupportsStmt S q₂ →
          (∀ (x : Λ'), x ∈ trStmts₁ q₂ → x ∈ trSupp M S) →
            TM1.SupportsStmt (trSupp M S) (trNormal q₂) ∧
              ∀ (l' : Λ'), l' ∈ trStmts₁ q₂ → TM1.SupportsStmt (trSupp M S) (tr M l')) →
        TM2.SupportsStmt S (TM2.Stmt.branch p q₁ q₂) →
          (∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.branch p q₁ q₂) → x ∈ trSupp M S) →
            TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.branch p q₁ q₂)) ∧
              ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.branch p q₁ q₂) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
intro _ _ _ IH₁ IH₂ ss' sub
[GOAL]
case refine'_3
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.branch p✝ q₁✝ q₂✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.branch p✝ q₁✝ q₂✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.branch p✝ q₁✝ q₂✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
unfold TM2to1.trStmts₁ at sub
[GOAL]
case refine'_3
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.branch p✝ q₁✝ q₂✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.branch p✝ q₁✝ q₂✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
cases' IH₁ ss'.1 fun x hx ↦ sub x <| Finset.mem_union_left _ hx with IH₁₁ IH₁₂
[GOAL]
case refine'_3.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.branch p✝ q₁✝ q₂✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.branch p✝ q₁✝ q₂✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
cases' IH₂ ss'.2 fun x hx ↦ sub x <| Finset.mem_union_right _ hx with IH₂₁ IH₂₂
[GOAL]
case refine'_3.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₂✝)
IH₂₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.branch p✝ q₁✝ q₂✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.branch p✝ q₁✝ q₂✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
refine' ⟨⟨IH₁₁, IH₂₁⟩, fun l h ↦ _⟩
[GOAL]
case refine'_3.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₂✝)
IH₂₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : l ∈ trStmts₁ (TM2.Stmt.branch p✝ q₁✝ q₂✝)
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
rw [trStmts₁] at h
[GOAL]
case refine'_3.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₂✝)
IH₂₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : l ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
rcases Finset.mem_union.1 h with (h | h) <;> [exact IH₁₂ _ h; exact IH₂₂ _ h]
[GOAL]
case refine'_3.intro.intro
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₂✝)
IH₂₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h : l ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
rcases Finset.mem_union.1 h with (h | h)
[GOAL]
case refine'_3.intro.intro.inl
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₂✝)
IH₂₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h✝ : l ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝
h : l ∈ trStmts₁ q₁✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
exact IH₁₂ _ h
[GOAL]
case refine'_3.intro.intro.inr
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
p✝ : σ → Bool
q₁✝ q₂✝ : Stmt₂
IH₁ :
  TM2.SupportsStmt S q₁✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₁✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₁✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂ :
  TM2.SupportsStmt S q₂✝ →
    (∀ (x : Λ'), x ∈ trStmts₁ q₂✝ → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal q₂✝) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
ss' : TM2.SupportsStmt S (TM2.Stmt.branch p✝ q₁✝ q₂✝)
sub : ∀ (x : Λ'), x ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝ → x ∈ trSupp M S
IH₁₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₁✝)
IH₁₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₁✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
IH₂₁ : TM1.SupportsStmt (trSupp M S) (trNormal q₂✝)
IH₂₂ : ∀ (l' : Λ'), l' ∈ trStmts₁ q₂✝ → TM1.SupportsStmt (trSupp M S) (tr M l')
l : Λ'
h✝ : l ∈ trStmts₁ q₁✝ ∪ trStmts₁ q₂✝
h : l ∈ trStmts₁ q₂✝
⊢ TM1.SupportsStmt (trSupp M S) (tr M l)
[PROOFSTEP]
exact IH₂₂ _ h
[GOAL]
case refine'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
⊢ ∀ (l : σ → Λ),
    TM2.SupportsStmt S (TM2.Stmt.goto l) →
      (∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.goto l) → x ∈ trSupp M S) →
        TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.goto l)) ∧
          ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.goto l) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
intro _ ss'
  _
    -- goto
[GOAL]
case refine'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l✝ : σ → Λ
ss' : TM2.SupportsStmt S (TM2.Stmt.goto l✝)
x✝ : ∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.goto l✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.goto l✝)) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ (TM2.Stmt.goto l✝) → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
simp only [trStmts₁, Finset.not_mem_empty]
[GOAL]
case refine'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l✝ : σ → Λ
ss' : TM2.SupportsStmt S (TM2.Stmt.goto l✝)
x✝ : ∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.goto l✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.goto l✝)) ∧
    ∀ (l' : Λ'), False → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
refine' ⟨_, fun _ ↦ False.elim⟩
[GOAL]
case refine'_4
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
l✝ : σ → Λ
ss' : TM2.SupportsStmt S (TM2.Stmt.goto l✝)
x✝ : ∀ (x : Λ'), x ∈ trStmts₁ (TM2.Stmt.goto l✝) → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal (TM2.Stmt.goto l✝))
[PROOFSTEP]
exact fun _ v ↦ Finset.mem_biUnion.2 ⟨_, ss' v, Finset.mem_insert_self _ _⟩
[GOAL]
case refine'_5
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
⊢ TM2.SupportsStmt S TM2.Stmt.halt →
    (∀ (x : Λ'), x ∈ trStmts₁ TM2.Stmt.halt → x ∈ trSupp M S) →
      TM1.SupportsStmt (trSupp M S) (trNormal TM2.Stmt.halt) ∧
        ∀ (l' : Λ'), l' ∈ trStmts₁ TM2.Stmt.halt → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
intro _
  _
    -- halt
[GOAL]
case refine'_5
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
x✝¹ : TM2.SupportsStmt S TM2.Stmt.halt
x✝ : ∀ (x : Λ'), x ∈ trStmts₁ TM2.Stmt.halt → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal TM2.Stmt.halt) ∧
    ∀ (l' : Λ'), l' ∈ trStmts₁ TM2.Stmt.halt → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
simp only [trStmts₁, Finset.not_mem_empty]
[GOAL]
case refine'_5
K : Type u_1
inst✝² : DecidableEq K
Γ : K → Type u_2
Λ : Type u_3
inst✝¹ : Inhabited Λ
σ : Type u_4
inst✝ : Inhabited σ
M : Λ → Stmt₂
S : Finset Λ
ss : TM2.Supports M S
x✝¹ : TM2.SupportsStmt S TM2.Stmt.halt
x✝ : ∀ (x : Λ'), x ∈ trStmts₁ TM2.Stmt.halt → x ∈ trSupp M S
⊢ TM1.SupportsStmt (trSupp M S) (trNormal TM2.Stmt.halt) ∧ ∀ (l' : Λ'), False → TM1.SupportsStmt (trSupp M S) (tr M l')
[PROOFSTEP]
exact ⟨trivial, fun _ ↦ False.elim⟩