l3lab/ntp-mathlib huggingface dataset:
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 

Proof state:
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₁ : Λ
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₁ : Λ
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₁ : Λ
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)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ Finset.insertNone S

Next tactic:
exact IH _ _ hs
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    

Proof state:
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₁ : Λ
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₁ : Λ
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)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ Finset.insertNone S

Next tactic:
case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    

Proof state:
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₁ : Λ
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

Next tactic:
case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      

Proof state:
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₁ : Λ
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

Next tactic:
unfold stepAux
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; 

Proof state:
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₁ : Λ
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

Next tactic:
cases p v
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · 

Proof state:
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₁ : Λ
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

Next tactic:
exact IH₂ _ _ hs.2
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · 

Proof state:
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₁ : Λ
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

Next tactic:
exact IH₁ _ _ hs.1
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
    

Proof state:
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₁ : Λ
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)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ Finset.insertNone S

Next tactic:
case goto => exact Finset.some_mem_insertNone.2 (hs _)
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
    

Proof state:
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₁ : Λ
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ Finset.insertNone S

Next tactic:
case goto => exact Finset.some_mem_insertNone.2 (hs _)
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
    case goto => 

Proof state:
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₁ : Λ
a✝ : σ → Λ
v : σ
T : (k : K) → List (Γ k)
hs : SupportsStmt S (goto a✝)
⊢ (stepAux (goto a✝) v T).l ∈ Finset.insertNone S

Next tactic:
exact Finset.some_mem_insertNone.2 (hs _)
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
    case goto => exact Finset.some_mem_insertNone.2 (hs _)
    

Proof state:
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)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ Finset.insertNone S

Next tactic:
case halt => apply Multiset.mem_cons_self
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
    case goto => exact Finset.some_mem_insertNone.2 (hs _)
    

Proof state:
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)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ Finset.insertNone S

Next tactic:
case halt => apply Multiset.mem_cons_self
theorem step_supports (M : Λ → Stmt₂) {S : Finset Λ} (ss : Supports M S) :
    ∀ {c c' : Cfg₂}, c' ∈ step M c → c.l ∈ Finset.insertNone S → c'.l ∈ Finset.insertNone S
  | ⟨some l₁, v, T⟩, c', h₁, h₂ => by
    replace h₂ := ss.2 _ (Finset.some_mem_insertNone.1 h₂)
    simp only [step, Option.mem_def, Option.some.injEq] at h₁; subst c'
    revert h₂; induction' M l₁ with _ _ q IH _ _ q IH _ _ q IH _ q IH generalizing v T <;> intro hs
    iterate 4 exact IH _ _ hs
    case branch p q₁' q₂' IH₁ IH₂ =>
      unfold stepAux; cases p v
      · exact IH₂ _ _ hs.2
      · exact IH₁ _ _ hs.1
    case goto => exact Finset.some_mem_insertNone.2 (hs _)
    case halt => 

Proof state:
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)
hs : SupportsStmt S halt
⊢ (stepAux halt v T).l ∈ Finset.insertNone S

Next tactic:
apply Multiset.mem_cons_self
theorem stk_nth_val {K : Type*} {Γ : K → Type*} {L : ListBlank (∀ k, Option (Γ k))} {k S} (n)
    (hL : ListBlank.map (proj k) L = ListBlank.mk (List.map some S).reverse) :
    L.nth n k = S.reverse.get? n := by
  

Proof state:
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

Next tactic:
rw [← proj_map_nth, hL, ← List.map_reverse, ListBlank.nth_mk, List.getI_eq_iget_get?,
    List.get?_map]
theorem stk_nth_val {K : Type*} {Γ : K → Type*} {L : ListBlank (∀ k, Option (Γ k))} {k S} (n)
    (hL : ListBlank.map (proj k) L = ListBlank.mk (List.map some S).reverse) :
    L.nth n k = S.reverse.get? n := by
  rw [← proj_map_nth, hL, ← List.map_reverse, ListBlank.nth_mk, List.getI_eq_iget_get?,
    List.get?_map]
  

Proof state:
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

Next tactic:
cases S.reverse.get? n
theorem stk_nth_val {K : Type*} {Γ : K → Type*} {L : ListBlank (∀ k, Option (Γ k))} {k S} (n)
    (hL : ListBlank.map (proj k) L = ListBlank.mk (List.map some S).reverse) :
    L.nth n k = S.reverse.get? n := by
  rw [← proj_map_nth, hL, ← List.map_reverse, ListBlank.nth_mk, List.getI_eq_iget_get?,
    List.get?_map]
  cases S.reverse.get? n <;> 

Proof state:
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

Next tactic:
rfl
theorem stk_nth_val {K : Type*} {Γ : K → Type*} {L : ListBlank (∀ k, Option (Γ k))} {k S} (n)
    (hL : ListBlank.map (proj k) L = ListBlank.mk (List.map some S).reverse) :
    L.nth n k = S.reverse.get? n := by
  rw [← proj_map_nth, hL, ← List.map_reverse, ListBlank.nth_mk, List.getI_eq_iget_get?,
    List.get?_map]
  cases S.reverse.get? n <;> 

Proof state:
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✝

Next tactic:
rfl
theorem addBottom_map (L : ListBlank (∀ k, Option (Γ k))) :
    (addBottom L).map ⟨Prod.snd, by 

Proof state:
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.2 = default

Next tactic:
rfl
theorem addBottom_map (L : ListBlank (∀ k, Option (Γ k))) :
    (addBottom L).map ⟨Prod.snd, by rfl⟩ = L := by
  

Proof state:
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.2 = default.2) } (addBottom L) = L

Next tactic:
simp only [addBottom, ListBlank.map_cons]
theorem addBottom_map (L : ListBlank (∀ k, Option (Γ k))) :
    (addBottom L).map ⟨Prod.snd, by rfl⟩ = L := by
  simp only [addBottom, ListBlank.map_cons]
  

Proof state:
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.2 = default.2) }
        (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) }
          (ListBlank.tail L))) =
    L

Next tactic:
convert ListBlank.cons_head_tail L
theorem addBottom_map (L : ListBlank (∀ k, Option (Γ k))) :
    (addBottom L).map ⟨Prod.snd, by rfl⟩ = L := by
  simp only [addBottom, ListBlank.map_cons]
  convert ListBlank.cons_head_tail L
  

Proof state:
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.2 = default.2) }
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (ListBlank.tail L)) =
    ListBlank.tail L

Next tactic:
generalize ListBlank.tail L = L'
theorem addBottom_map (L : ListBlank (∀ k, Option (Γ k))) :
    (addBottom L).map ⟨Prod.snd, by rfl⟩ = L := by
  simp only [addBottom, ListBlank.map_cons]
  convert ListBlank.cons_head_tail L
  generalize ListBlank.tail L = L'
  

Proof state:
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.2 = default.2) }
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } L') =
    L'

Next tactic:
refine' L'.induction_on fun l ↦ _
theorem addBottom_map (L : ListBlank (∀ k, Option (Γ k))) :
    (addBottom L).map ⟨Prod.snd, by rfl⟩ = L := by
  simp only [addBottom, ListBlank.map_cons]
  convert ListBlank.cons_head_tail L
  generalize ListBlank.tail L = L'
  refine' L'.induction_on fun l ↦ _; 

Proof state:
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.2 = default.2) }
      (ListBlank.map { f := Prod.mk false, map_pt' := (_ : (false, default) = (false, default)) } (ListBlank.mk l)) =
    ListBlank.mk l

Next tactic:
simp
theorem addBottom_modifyNth (f : (∀ k, Option (Γ k)) → ∀ k, Option (Γ k))
    (L : ListBlank (∀ k, Option (Γ k))) (n : ℕ) :
    (addBottom L).modifyNth (fun a ↦ (a.1, f a.2)) n = addBottom (L.modifyNth f n) := by
  

Proof state:
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.1, f a.2)) n (addBottom L) = addBottom (ListBlank.modifyNth f n L)

Next tactic:
cases n
theorem addBottom_modifyNth (f : (∀ k, Option (Γ k)) → ∀ k, Option (Γ k))
    (L : ListBlank (∀ k, Option (Γ k))) (n : ℕ) :
    (addBottom L).modifyNth (fun a ↦ (a.1, f a.2)) n = addBottom (L.modifyNth f n) := by
  cases n <;>
    

Proof state:
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.1, f a.2)) Nat.zero (addBottom L) = addBottom (ListBlank.modifyNth f Nat.zero L)

Next tactic:
simp only [addBottom, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.tail_cons]
theorem addBottom_modifyNth (f : (∀ k, Option (Γ k)) → ∀ k, Option (Γ k))
    (L : ListBlank (∀ k, Option (Γ k))) (n : ℕ) :
    (addBottom L).modifyNth (fun a ↦ (a.1, f a.2)) n = addBottom (L.modifyNth f n) := by
  cases n <;>
    

Proof state:
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.1, f a.2)) (Nat.succ n✝) (addBottom L) =
    addBottom (ListBlank.modifyNth f (Nat.succ n✝) L)

Next tactic:
simp only [addBottom, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.tail_cons]
theorem addBottom_modifyNth (f : (∀ k, Option (Γ k)) → ∀ k, Option (Γ k))
    (L : ListBlank (∀ k, Option (Γ k))) (n : ℕ) :
    (addBottom L).modifyNth (fun a ↦ (a.1, f a.2)) n = addBottom (L.modifyNth f n) := by
  cases n <;>
    simp only [addBottom, ListBlank.head_cons, ListBlank.modifyNth, ListBlank.tail_cons]
  

Proof state:
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.1, f a.2)) 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)))

Next tactic:
congr