l3lab/ntp-mathlib huggingface dataset:
theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
    (hn : n < (pmap f l h).length) :
    get (pmap f l h) ⟨n, hn⟩ =
      f (get l ⟨n, @length_pmap _ _ p f l h ▸ hn⟩)
        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) := by
  induction' l with hd tl hl generalizing n
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
h : ∀ (a : α), a ∈ [] → p a
n : ℕ
hn : n < length (pmap f [] h)
⊢ get (pmap f [] h) { val := n, isLt := hn } =
    f (get [] { val := n, isLt := (_ : n < length []) }) (_ : p (get [] { val := n, isLt := (_ : n < length []) }))

Next tactic:
simp only [length, pmap] at hn
theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
    (hn : n < (pmap f l h).length) :
    get (pmap f l h) ⟨n, hn⟩ =
      f (get l ⟨n, @length_pmap _ _ p f l h ▸ hn⟩)
        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) := by
  induction' l with hd tl hl generalizing n
  · simp only [length, pmap] at hn
    

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
h : ∀ (a : α), a ∈ [] → p a
n : ℕ
hn : n < 0
⊢ get (pmap f [] h) { val := n, isLt := hn } =
    f (get [] { val := n, isLt := (_ : n < length []) }) (_ : p (get [] { val := n, isLt := (_ : n < length []) }))

Next tactic:
exact absurd hn (not_lt_of_le n.zero_le)
theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
    (hn : n < (pmap f l h).length) :
    get (pmap f l h) ⟨n, hn⟩ =
      f (get l ⟨n, @length_pmap _ _ p f l h ▸ hn⟩)
        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) := by
  induction' l with hd tl hl generalizing n
  · simp only [length, pmap] at hn
    exact absurd hn (not_lt_of_le n.zero_le)
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) {n : ℕ} (hn : n < length (pmap f tl h)),
    get (pmap f tl h) { val := n, isLt := hn } =
      f (get tl { val := n, isLt := (_ : n < length tl) }) (_ : p (get tl { val := n, isLt := (_ : n < length tl) }))
h : ∀ (a : α), a ∈ hd :: tl → p a
n : ℕ
hn : n < length (pmap f (hd :: tl) h)
⊢ get (pmap f (hd :: tl) h) { val := n, isLt := hn } =
    f (get (hd :: tl) { val := n, isLt := (_ : n < length (hd :: tl)) })
      (_ : p (get (hd :: tl) { val := n, isLt := (_ : n < length (hd :: tl)) }))

Next tactic:
cases n
theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
    (hn : n < (pmap f l h).length) :
    get (pmap f l h) ⟨n, hn⟩ =
      f (get l ⟨n, @length_pmap _ _ p f l h ▸ hn⟩)
        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) := by
  induction' l with hd tl hl generalizing n
  · simp only [length, pmap] at hn
    exact absurd hn (not_lt_of_le n.zero_le)
  · cases n
    · 

Proof state:
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) {n : ℕ} (hn : n < length (pmap f tl h)),
    get (pmap f tl h) { val := n, isLt := hn } =
      f (get tl { val := n, isLt := (_ : n < length tl) }) (_ : p (get tl { val := n, isLt := (_ : n < length tl) }))
h : ∀ (a : α), a ∈ hd :: tl → p a
hn : zero < length (pmap f (hd :: tl) h)
⊢ get (pmap f (hd :: tl) h) { val := zero, isLt := hn } =
    f (get (hd :: tl) { val := zero, isLt := (_ : zero < length (hd :: tl)) })
      (_ : p (get (hd :: tl) { val := zero, isLt := (_ : zero < length (hd :: tl)) }))

Next tactic:
simp
theorem get_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) {n : ℕ}
    (hn : n < (pmap f l h).length) :
    get (pmap f l h) ⟨n, hn⟩ =
      f (get l ⟨n, @length_pmap _ _ p f l h ▸ hn⟩)
        (h _ (get_mem l n (@length_pmap _ _ p f l h ▸ hn))) := by
  induction' l with hd tl hl generalizing n
  · simp only [length, pmap] at hn
    exact absurd hn (not_lt_of_le n.zero_le)
  · cases n
    · simp
    · 

Proof state:
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) {n : ℕ} (hn : n < length (pmap f tl h)),
    get (pmap f tl h) { val := n, isLt := hn } =
      f (get tl { val := n, isLt := (_ : n < length tl) }) (_ : p (get tl { val := n, isLt := (_ : n < length tl) }))
h : ∀ (a : α), a ∈ hd :: tl → p a
n✝ : ℕ
hn : succ n✝ < length (pmap f (hd :: tl) h)
⊢ get (pmap f (hd :: tl) h) { val := succ n✝, isLt := hn } =
    f (get (hd :: tl) { val := succ n✝, isLt := (_ : succ n✝ < length (hd :: tl)) })
      (_ : p (get (hd :: tl) { val := succ n✝, isLt := (_ : succ n✝ < length (hd :: tl)) }))

Next tactic:
simp [hl]
theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
    (h : ∀ a ∈ l₁ ++ l₂, p a) :
    (l₁ ++ l₂).pmap f h =
      (l₁.pmap f fun a ha => h a (mem_append_left l₂ ha)) ++
        l₂.pmap f fun a ha => h a (mem_append_right l₁ ha) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₁ l₂ : List ι
h : ∀ (a : ι), a ∈ l₁ ++ l₂ → p a
⊢ pmap f (l₁ ++ l₂) h = pmap f l₁ (_ : ∀ (a : ι), a ∈ l₁ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)

Next tactic:
induction' l₁ with _ _ ih
theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
    (h : ∀ a ∈ l₁ ++ l₂, p a) :
    (l₁ ++ l₂).pmap f h =
      (l₁.pmap f fun a ha => h a (mem_append_left l₂ ha)) ++
        l₂.pmap f fun a ha => h a (mem_append_right l₁ ha) := by
  induction' l₁ with _ _ ih
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₂ : List ι
h : ∀ (a : ι), a ∈ [] ++ l₂ → p a
⊢ pmap f ([] ++ l₂) h = pmap f [] (_ : ∀ (a : ι), a ∈ [] → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)

Next tactic:
rfl
theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
    (h : ∀ a ∈ l₁ ++ l₂, p a) :
    (l₁ ++ l₂).pmap f h =
      (l₁.pmap f fun a ha => h a (mem_append_left l₂ ha)) ++
        l₂.pmap f fun a ha => h a (mem_append_right l₁ ha) := by
  induction' l₁ with _ _ ih
  · rfl
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₂ : List ι
head✝ : ι
tail✝ : List ι
ih :
  ∀ (h : ∀ (a : ι), a ∈ tail✝ ++ l₂ → p a),
    pmap f (tail✝ ++ l₂) h = pmap f tail✝ (_ : ∀ (a : ι), a ∈ tail✝ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
h : ∀ (a : ι), a ∈ head✝ :: tail✝ ++ l₂ → p a
⊢ pmap f (head✝ :: tail✝ ++ l₂) h =
    pmap f (head✝ :: tail✝) (_ : ∀ (a : ι), a ∈ head✝ :: tail✝ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)

Next tactic:
dsimp only [pmap, cons_append]
theorem pmap_append {p : ι → Prop} (f : ∀ a : ι, p a → α) (l₁ l₂ : List ι)
    (h : ∀ a ∈ l₁ ++ l₂, p a) :
    (l₁ ++ l₂).pmap f h =
      (l₁.pmap f fun a ha => h a (mem_append_left l₂ ha)) ++
        l₂.pmap f fun a ha => h a (mem_append_right l₁ ha) := by
  induction' l₁ with _ _ ih
  · rfl
  · dsimp only [pmap, cons_append]
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₂ : List ι
head✝ : ι
tail✝ : List ι
ih :
  ∀ (h : ∀ (a : ι), a ∈ tail✝ ++ l₂ → p a),
    pmap f (tail✝ ++ l₂) h = pmap f tail✝ (_ : ∀ (a : ι), a ∈ tail✝ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
h : ∀ (a : ι), a ∈ head✝ :: tail✝ ++ l₂ → p a
⊢ f head✝ (_ : p head✝) :: pmap f (tail✝ ++ l₂) (_ : ∀ (x : ι), x ∈ tail✝ ++ l₂ → p x) =
    f head✝ (_ : p head✝) :: (pmap f tail✝ (_ : ∀ (x : ι), x ∈ tail✝ → p x) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a))

Next tactic:
rw [ih]
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
a : α
H : find? p l = some a
⊢ a ∈ l

Next tactic:
induction' l with b l IH
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
a : α
H : find? p [] = some a
⊢ a ∈ []

Next tactic:
contradiction
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · contradiction
  

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p (b :: l) = some a
⊢ a ∈ b :: l

Next tactic:
by_cases h : p b
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · contradiction
  by_cases h : p b
  · 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p (b :: l) = some a
h : p b = true
⊢ a ∈ b :: l

Next tactic:
rw [find?_cons_of_pos _ h] at H
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · contradiction
  by_cases h : p b
  · rw [find?_cons_of_pos _ h] at H
    

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a b : α
l : List α
IH : find? p l = some a → a ∈ l
H : some b = some a
h : p b = true
⊢ a ∈ b :: l

Next tactic:
cases H
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · contradiction
  by_cases h : p b
  · rw [find?_cons_of_pos _ h] at H
    cases H
    

Proof state:
case pos.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
l : List α
IH : find? p l = some a → a ∈ l
h : p a = true
⊢ a ∈ a :: l

Next tactic:
apply mem_cons_self
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · contradiction
  by_cases h : p b
  · rw [find?_cons_of_pos _ h] at H
    cases H
    apply mem_cons_self
  · 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p (b :: l) = some a
h : ¬p b = true
⊢ a ∈ b :: l

Next tactic:
rw [find?_cons_of_neg _ h] at H
@[simp]
theorem find?_mem (H : find? p l = some a) : a ∈ l := by
  induction' l with b l IH; · contradiction
  by_cases h : p b
  · rw [find?_cons_of_pos _ h] at H
    cases H
    apply mem_cons_self
  · rw [find?_cons_of_neg _ h] at H
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p l = some a
h : ¬p b = true
⊢ a ∈ b :: l

Next tactic:
exact mem_cons_of_mem _ (IH H)
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
l : List α
acc : Array α
⊢ go f l acc = Array.toListAppend acc (lookmap f l)

Next tactic:
cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
    | some a => rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
⊢ go f [] acc = Array.toListAppend acc (lookmap f [])

Next tactic:
| nil => rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
⊢ go f [] acc = Array.toListAppend acc (lookmap f [])

Next tactic:
rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ go f (hd :: tl) acc = Array.toListAppend acc (lookmap f (hd :: tl))

Next tactic:
| cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
    | some a => rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ go f (hd :: tl) acc = Array.toListAppend acc (lookmap f (hd :: tl))

Next tactic:
rw [lookmap, go, go]
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ (match f hd with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match f hd with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))

Next tactic:
cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
    | some a => rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
x✝ : Option α
⊢ (match x✝ with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match x✝ with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))

Next tactic:
cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
    | some a => rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    

Proof state:
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ (match none with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match none with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))

Next tactic:
| none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    | none => 

Proof state:
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ (match none with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match none with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))

Next tactic:
simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; 

Proof state:
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ acc.data ++ ([hd] ++ lookmap f tl) = acc.data ++ (#[].data ++ ([hd] ++ lookmap f tl))

Next tactic:
rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
    

Proof state:
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
a : α
⊢ (match some a with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match some a with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))

Next tactic:
| some a => rfl
theorem lookmap.go_append (l : List α) (acc : Array α) :
    lookmap.go f l acc = acc.toListAppend (lookmap f l) := by
  cases l with
  | nil => rfl
  | cons hd tl =>
    rw [lookmap, go, go]
    cases f hd with
    | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
    | some a => 

Proof state:
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
a : α
⊢ (match some a with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match some a with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))

Next tactic:
rfl
@[simp]
theorem lookmap_cons_none {a : α} (l : List α) (h : f a = none) :
    (a :: l).lookmap f = a :: l.lookmap f := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
a : α
l : List α
h : f a = none
⊢ lookmap f (a :: l) = a :: lookmap f l

Next tactic:
simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
@[simp]
theorem lookmap_cons_none {a : α} (l : List α) (h : f a = none) :
    (a :: l).lookmap f = a :: l.lookmap f := by
  simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
a : α
l : List α
h : f a = none
⊢ (match f a with
    | some b => b :: l
    | none => lookmap.go f l (Array.push #[] a)) =
    a :: lookmap.go f l #[]

Next tactic:
rw [lookmap.go_append, h]
@[simp]
theorem lookmap_cons_none {a : α} (l : List α) (h : f a = none) :
    (a :: l).lookmap f = a :: l.lookmap f := by
  simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
  rw [lookmap.go_append, h]; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
a : α
l : List α
h : f a = none
⊢ (match none with
    | some b => b :: l
    | none => Array.toListAppend (Array.push #[] a) (lookmap f l)) =
    a :: lookmap.go f l #[]

Next tactic:
rfl
@[simp]
theorem lookmap_cons_some {a b : α} (l : List α) (h : f a = some b) :
    (a :: l).lookmap f = b :: l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
a b : α
l : List α
h : f a = some b
⊢ lookmap f (a :: l) = b :: l

Next tactic:
simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
@[simp]
theorem lookmap_cons_some {a b : α} (l : List α) (h : f a = some b) :
    (a :: l).lookmap f = b :: l := by
  simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
a b : α
l : List α
h : f a = some b
⊢ (match f a with
    | some b => b :: l
    | none => lookmap.go f l (Array.push #[] a)) =
    b :: l

Next tactic:
rw [h]
theorem lookmap_congr {f g : α → Option α} :
    ∀ {l : List α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g
  | [], _ => rfl
  | a :: l, H => by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
⊢ lookmap f (a :: l) = lookmap g (a :: l)

Next tactic:
cases' forall_mem_cons.1 H with H₁ H₂
theorem lookmap_congr {f g : α → Option α} :
    ∀ {l : List α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g
  | [], _ => rfl
  | a :: l, H => by
    cases' forall_mem_cons.1 H with H₁ H₂
    

Proof state:
case intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
H₁ : f a = g a
H₂ : ∀ (x : α), x ∈ l → f x = g x
⊢ lookmap f (a :: l) = lookmap g (a :: l)

Next tactic:
cases' h : g a with b
theorem lookmap_congr {f g : α → Option α} :
    ∀ {l : List α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g
  | [], _ => rfl
  | a :: l, H => by
    cases' forall_mem_cons.1 H with H₁ H₂
    cases' h : g a with b
    · 

Proof state:
case intro.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
H₁ : f a = g a
H₂ : ∀ (x : α), x ∈ l → f x = g x
h : g a = none
⊢ lookmap f (a :: l) = lookmap g (a :: l)

Next tactic:
simp [h, H₁.trans h, lookmap_congr H₂]
theorem lookmap_congr {f g : α → Option α} :
    ∀ {l : List α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g
  | [], _ => rfl
  | a :: l, H => by
    cases' forall_mem_cons.1 H with H₁ H₂
    cases' h : g a with b
    · simp [h, H₁.trans h, lookmap_congr H₂]
    · 

Proof state:
case intro.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
H₁ : f a = g a
H₂ : ∀ (x : α), x ∈ l → f x = g x
b : α
h : g a = some b
⊢ lookmap f (a :: l) = lookmap g (a :: l)

Next tactic:
simp [lookmap_cons_some _ _ h, lookmap_cons_some _ _ (H₁.trans h)]
theorem lookmap_map_eq (g : α → β) (h : ∀ (a), ∀ b ∈ f a, g a = g b) :
    ∀ l : List α, map g (l.lookmap f) = map g l
  | [] => rfl
  | a :: l => by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
⊢ map g (lookmap f (a :: l)) = map g (a :: l)

Next tactic:
cases' h' : f a with b
theorem lookmap_map_eq (g : α → β) (h : ∀ (a), ∀ b ∈ f a, g a = g b) :
    ∀ l : List α, map g (l.lookmap f) = map g l
  | [] => rfl
  | a :: l => by
    cases' h' : f a with b
    · 

Proof state:
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
h' : f a = none
⊢ map g (lookmap f (a :: l)) = map g (a :: l)

Next tactic:
simp [h']
theorem lookmap_map_eq (g : α → β) (h : ∀ (a), ∀ b ∈ f a, g a = g b) :
    ∀ l : List α, map g (l.lookmap f) = map g l
  | [] => rfl
  | a :: l => by
    cases' h' : f a with b
    · simp [h']; 

Proof state:
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
h' : f a = none
⊢ map g (lookmap f l) = map g l

Next tactic:
exact lookmap_map_eq _ h l
theorem lookmap_map_eq (g : α → β) (h : ∀ (a), ∀ b ∈ f a, g a = g b) :
    ∀ l : List α, map g (l.lookmap f) = map g l
  | [] => rfl
  | a :: l => by
    cases' h' : f a with b
    · simp [h']; exact lookmap_map_eq _ h l
    · 

Proof state:
case some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
b : α
h' : f a = some b
⊢ map g (lookmap f (a :: l)) = map g (a :: l)

Next tactic:
simp [lookmap_cons_some _ _ h', h _ _ h']
theorem lookmap_id' (h : ∀ (a), ∀ b ∈ f a, a = b) (l : List α) : l.lookmap f = l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → Option α
h : ∀ (a b : α), b ∈ f a → a = b
l : List α
⊢ lookmap f l = l

Next tactic:
rw [← map_id (l.lookmap f), lookmap_map_eq, map_id]