l3lab/ntp-mathlib huggingface dataset:
theorem get_map {f : α → β} :
    ∀ {n : ℕ} {as : List α}, n < as.length → get n (as.map f) = f (get n as)
  | _, [], h => by cases h
  | 0, a :: as, _ => rfl
  | n + 1, _ :: as, h1 => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
head✝ : α
as : List α
h1 : n + 1 < length (head✝ :: as)
⊢ get (n + 1) (map f (head✝ :: as)) = f (get (n + 1) (head✝ :: as))

Next tactic:
have h2 : n < length as := by
      rw [← Nat.succ_le_iff, ← Nat.lt_succ_iff]
      apply h1
theorem get_map {f : α → β} :
    ∀ {n : ℕ} {as : List α}, n < as.length → get n (as.map f) = f (get n as)
  | _, [], h => by cases h
  | 0, a :: as, _ => rfl
  | n + 1, _ :: as, h1 => by
    have h2 : n < length as := by
      

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
head✝ : α
as : List α
h1 : n + 1 < length (head✝ :: as)
⊢ n < length as

Next tactic:
rw [← Nat.succ_le_iff, ← Nat.lt_succ_iff]
theorem get_map {f : α → β} :
    ∀ {n : ℕ} {as : List α}, n < as.length → get n (as.map f) = f (get n as)
  | _, [], h => by cases h
  | 0, a :: as, _ => rfl
  | n + 1, _ :: as, h1 => by
    have h2 : n < length as := by
      rw [← Nat.succ_le_iff, ← Nat.lt_succ_iff]
      

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
head✝ : α
as : List α
h1 : n + 1 < length (head✝ :: as)
⊢ Nat.succ n < Nat.succ (length as)

Next tactic:
apply h1
theorem get_map {f : α → β} :
    ∀ {n : ℕ} {as : List α}, n < as.length → get n (as.map f) = f (get n as)
  | _, [], h => by cases h
  | 0, a :: as, _ => rfl
  | n + 1, _ :: as, h1 => by
    have h2 : n < length as := by
      rw [← Nat.succ_le_iff, ← Nat.lt_succ_iff]
      apply h1
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
head✝ : α
as : List α
h1 : n + 1 < length (head✝ :: as)
h2 : n < length as
⊢ get (n + 1) (map f (head✝ :: as)) = f (get (n + 1) (head✝ :: as))

Next tactic:
apply get_map h2
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
⊢ f default = default → get n (map f as) = f (get n as)

Next tactic:
intro h1
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  intro h1; 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
h1 : f default = default
⊢ get n (map f as) = f (get n as)

Next tactic:
by_cases h2 : n < as.length
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  intro h1; by_cases h2 : n < as.length
  · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
h1 : f default = default
h2 : n < length as
⊢ get n (map f as) = f (get n as)

Next tactic:
apply get_map h2
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  intro h1; by_cases h2 : n < as.length
  · apply get_map h2
  · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
h1 : f default = default
h2 : ¬n < length as
⊢ get n (map f as) = f (get n as)

Next tactic:
rw [not_lt] at h2
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  intro h1; by_cases h2 : n < as.length
  · apply get_map h2
  · rw [not_lt] at h2
    

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
h1 : f default = default
h2 : length as ≤ n
⊢ get n (map f as) = f (get n as)

Next tactic:
rw [get_eq_default_of_le _ h2, get_eq_default_of_le, h1]
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  intro h1; by_cases h2 : n < as.length
  · apply get_map h2
  · rw [not_lt] at h2
    rw [get_eq_default_of_le _ h2, get_eq_default_of_le, h1]
    

Proof state:
case neg.a
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
h1 : f default = default
h2 : length as ≤ n
⊢ length (map f as) ≤ n

Next tactic:
rw [length_map]
theorem get_map' {f : α → β} {n : ℕ} {as : List α} :
    f default = default → get n (as.map f) = f (get n as) := by
  intro h1; by_cases h2 : n < as.length
  · apply get_map h2
  · rw [not_lt] at h2
    rw [get_eq_default_of_le _ h2, get_eq_default_of_le, h1]
    rw [length_map]
    

Proof state:
case neg.a
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
n : ℕ
as : List α
h1 : f default = default
h2 : length as ≤ n
⊢ length as ≤ n

Next tactic:
apply h2
theorem forall_val_of_forall_mem {as : List α} {p : α → Prop} :
    p default → (∀ x ∈ as, p x) → ∀ n, p (get n as) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
as : List α
p : α → Prop
⊢ p default → (∀ (x : α), x ∈ as → p x) → ∀ (n : ℕ), p (get n as)

Next tactic:
intro h1 h2 n
theorem forall_val_of_forall_mem {as : List α} {p : α → Prop} :
    p default → (∀ x ∈ as, p x) → ∀ n, p (get n as) := by
  intro h1 h2 n
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
as : List α
p : α → Prop
h1 : p default
h2 : ∀ (x : α), x ∈ as → p x
n : ℕ
⊢ p (get n as)

Next tactic:
by_cases h3 : n < as.length
theorem forall_val_of_forall_mem {as : List α} {p : α → Prop} :
    p default → (∀ x ∈ as, p x) → ∀ n, p (get n as) := by
  intro h1 h2 n
  by_cases h3 : n < as.length
  · 

Proof state:
case pos
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
as : List α
p : α → Prop
h1 : p default
h2 : ∀ (x : α), x ∈ as → p x
n : ℕ
h3 : n < length as
⊢ p (get n as)

Next tactic:
apply h2 _ (mem_get_of_le h3)
theorem forall_val_of_forall_mem {as : List α} {p : α → Prop} :
    p default → (∀ x ∈ as, p x) → ∀ n, p (get n as) := by
  intro h1 h2 n
  by_cases h3 : n < as.length
  · apply h2 _ (mem_get_of_le h3)
  · 

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
as : List α
p : α → Prop
h1 : p default
h2 : ∀ (x : α), x ∈ as → p x
n : ℕ
h3 : ¬n < length as
⊢ p (get n as)

Next tactic:
rw [not_lt] at h3
theorem forall_val_of_forall_mem {as : List α} {p : α → Prop} :
    p default → (∀ x ∈ as, p x) → ∀ n, p (get n as) := by
  intro h1 h2 n
  by_cases h3 : n < as.length
  · apply h2 _ (mem_get_of_le h3)
  · rw [not_lt] at h3
    

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
as : List α
p : α → Prop
h1 : p default
h2 : ∀ (x : α), x ∈ as → p x
n : ℕ
h3 : length as ≤ n
⊢ p (get n as)

Next tactic:
rw [get_eq_default_of_le _ h3]
theorem forall_val_of_forall_mem {as : List α} {p : α → Prop} :
    p default → (∀ x ∈ as, p x) → ∀ n, p (get n as) := by
  intro h1 h2 n
  by_cases h3 : n < as.length
  · apply h2 _ (mem_get_of_le h3)
  · rw [not_lt] at h3
    rw [get_eq_default_of_le _ h3]
    

Proof state:
case neg
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
as : List α
p : α → Prop
h1 : p default
h2 : ∀ (x : α), x ∈ as → p x
n : ℕ
h3 : length as ≤ n
⊢ p default

Next tactic:
apply h1
theorem equiv_of_eq : as1 = as2 → Equiv as1 as2 := by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
⊢ as1 = as2 → Equiv as1 as2

Next tactic:
intro h1
theorem equiv_of_eq : as1 = as2 → Equiv as1 as2 := by intro h1; 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
h1 : as1 = as2
⊢ Equiv as1 as2

Next tactic:
rw [h1]
theorem equiv_of_eq : as1 = as2 → Equiv as1 as2 := by intro h1; rw [h1]; 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
h1 : as1 = as2
⊢ Equiv as2 as2

Next tactic:
apply equiv_refl
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
head✝ : α
tail✝ : List α
h1 : length (head✝ :: tail✝) = length []
x✝ : Equiv (head✝ :: tail✝) []
⊢ head✝ :: tail✝ = []

Next tactic:
cases h1
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
head✝ : α
tail✝ : List α
h1 : length [] = length (head✝ :: tail✝)
x✝ : Equiv [] (head✝ :: tail✝)
⊢ [] = head✝ :: tail✝

Next tactic:
cases h1
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
⊢ a1 :: as1 = a2 :: as2

Next tactic:
congr
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    congr
    · 

Proof state:
case e_head
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
⊢ a1 = a2

Next tactic:
apply h2 0
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    congr
    · apply h2 0
    · 

Proof state:
case e_tail
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
⊢ as1 = as2

Next tactic:
have h3 : as1.length = as2.length := by simpa [add_left_inj, add_comm, length] using h1
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    congr
    · apply h2 0
    · have h3 : as1.length = as2.length := by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
⊢ length as1 = length as2

Next tactic:
simpa [add_left_inj, add_comm, length] using h1
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    congr
    · apply h2 0
    · have h3 : as1.length = as2.length := by simpa [add_left_inj, add_comm, length] using h1
      

Proof state:
case e_tail
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
h3 : length as1 = length as2
⊢ as1 = as2

Next tactic:
apply eq_of_equiv h3
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    congr
    · apply h2 0
    · have h3 : as1.length = as2.length := by simpa [add_left_inj, add_comm, length] using h1
      apply eq_of_equiv h3
      

Proof state:
case e_tail
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
h3 : length as1 = length as2
⊢ Equiv as1 as2

Next tactic:
intro m
theorem eq_of_equiv : ∀ {as1 as2 : List α}, as1.length = as2.length → Equiv as1 as2 → as1 = as2
  | [], [], _, _ => rfl
  | _ :: _, [], h1, _ => by cases h1
  | [], _ :: _, h1, _ => by cases h1
  | a1 :: as1, a2 :: as2, h1, h2 => by
    congr
    · apply h2 0
    · have h3 : as1.length = as2.length := by simpa [add_left_inj, add_comm, length] using h1
      apply eq_of_equiv h3
      intro m
      

Proof state:
case e_tail
α : Type u
β : Type v
γ : Type w
a : α
as as1✝ as2✝ as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a1 : α
as1 : List α
a2 : α
as2 : List α
h1 : length (a1 :: as1) = length (a2 :: as2)
h2 : Equiv (a1 :: as1) (a2 :: as2)
h3 : length as1 = length as2
m : ℕ
⊢ get m as1 = get m as2

Next tactic:
apply h2 (m + 1)
@[simp]
theorem get_neg [AddGroup α] {k : ℕ} {as : List α} : @get α ⟨0⟩ k (neg as) = -@get α ⟨0⟩ k as := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : AddGroup α
k : ℕ
as : List α
⊢ get k (neg as) = -get k as

Next tactic:
unfold neg
@[simp]
theorem get_neg [AddGroup α] {k : ℕ} {as : List α} : @get α ⟨0⟩ k (neg as) = -@get α ⟨0⟩ k as := by
  unfold neg
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : AddGroup α
k : ℕ
as : List α
⊢ get k (map (fun a => -a) as) = -get k as

Next tactic:
rw [@get_map' α α ⟨0⟩ ⟨0⟩]
@[simp]
theorem get_neg [AddGroup α] {k : ℕ} {as : List α} : @get α ⟨0⟩ k (neg as) = -@get α ⟨0⟩ k as := by
  unfold neg
  rw [@get_map' α α ⟨0⟩ ⟨0⟩] -- porting note: had to add a `⟨0⟩` b/c of instance troubles
  

Proof state:
case a
α : Type u
β : Type v
γ : Type w
inst✝ : AddGroup α
k : ℕ
as : List α
⊢ -default = default

Next tactic:
apply neg_zero
@[simp]
theorem length_neg [Neg α] (as : List α) : (neg as).length = as.length := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : Neg α
as : List α
⊢ length (neg as) = length as

Next tactic:
simp only [neg, length_map]
theorem nil_pointwise {f : α → β → γ} : ∀ bs : List β, pointwise f [] bs = bs.map (f default)
  | [] => rfl
  | b :: bs => by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β → γ
b : β
bs : List β
⊢ pointwise f [] (b :: bs) = map (f default) (b :: bs)

Next tactic:
simp only [nil_pointwise bs, pointwise, eq_self_iff_true, and_self_iff, map]
theorem pointwise_nil {f : α → β → γ} :
    ∀ as : List α, pointwise f as [] = as.map fun a ↦ f a default
  | [] => rfl
  | a :: as => by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β → γ
a : α
as : List α
⊢ pointwise f (a :: as) [] = map (fun a => f a default) (a :: as)

Next tactic:
simp only [pointwise_nil as, pointwise, eq_self_iff_true, and_self_iff, List.map]
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
k : ℕ
⊢ get k (pointwise f [] []) = f (get k []) (get k [])

Next tactic:
simp only [h1, get_nil, pointwise, get]
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
b : β
tail✝ : List β
⊢ get 0 (pointwise f [] (b :: tail✝)) = f (get 0 []) (get 0 (b :: tail✝))

Next tactic:
simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
k : ℕ
b : β
bs : List β
⊢ get (k + 1) (pointwise f [] (b :: bs)) = f (get (k + 1) []) (get (k + 1) (b :: bs))

Next tactic:
have : get k (map (f default) bs) = f default (get k bs) := by
      simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    have : get k (map (f default) bs) = f default (get k bs) := by
      

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
k : ℕ
b : β
bs : List β
⊢ get k (map (f default) bs) = f default (get k bs)

Next tactic:
simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    have : get k (map (f default) bs) = f default (get k bs) := by
      simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
    

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
k : ℕ
b : β
bs : List β
this : get k (map (f default) bs) = f default (get k bs)
⊢ get (k + 1) (pointwise f [] (b :: bs)) = f (get (k + 1) []) (get (k + 1) (b :: bs))

Next tactic:
simpa [get, get_nil, pointwise, map]
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    have : get k (map (f default) bs) = f default (get k bs) := by
      simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
    simpa [get, get_nil, pointwise, map]
  | 0, a :: _, [] => by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
a : α
tail✝ : List α
⊢ get 0 (pointwise f (a :: tail✝) []) = f (get 0 (a :: tail✝)) (get 0 [])

Next tactic:
simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    have : get k (map (f default) bs) = f default (get k bs) := by
      simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
    simpa [get, get_nil, pointwise, map]
  | 0, a :: _, [] => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, a :: as, [] => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
k : ℕ
a : α
as : List α
⊢ get (k + 1) (pointwise f (a :: as) []) = f (get (k + 1) (a :: as)) (get (k + 1) [])

Next tactic:
simpa [get, get_nil, pointwise, map, pointwise_nil, get_nil] using get_pointwise h1 k as []
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    have : get k (map (f default) bs) = f default (get k bs) := by
      simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
    simpa [get, get_nil, pointwise, map]
  | 0, a :: _, [] => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, a :: as, [] => by
    simpa [get, get_nil, pointwise, map, pointwise_nil, get_nil] using get_pointwise h1 k as []
  | 0, a :: _, b :: _ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
a : α
tail✝¹ : List α
b : β
tail✝ : List β
⊢ get 0 (pointwise f (a :: tail✝¹) (b :: tail✝)) = f (get 0 (a :: tail✝¹)) (get 0 (b :: tail✝))

Next tactic:
simp only [pointwise, get]
theorem get_pointwise [Inhabited γ] {f : α → β → γ} (h1 : f default default = default) :
    ∀ (k : Nat) (as : List α) (bs : List β), get k (pointwise f as bs) = f (get k as) (get k bs)
  | k, [], [] => by simp only [h1, get_nil, pointwise, get]
  | 0, [], b :: _ => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, [], b :: bs => by
    have : get k (map (f default) bs) = f default (get k bs) := by
      simpa [nil_pointwise, get_nil] using get_pointwise h1 k [] bs
    simpa [get, get_nil, pointwise, map]
  | 0, a :: _, [] => by simp only [get_pointwise, get_nil, pointwise, get, Nat.zero_eq, map]
  | k + 1, a :: as, [] => by
    simpa [get, get_nil, pointwise, map, pointwise_nil, get_nil] using get_pointwise h1 k as []
  | 0, a :: _, b :: _ => by simp only [pointwise, get]
  | k + 1, _ :: as, _ :: bs => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : Inhabited α
inst✝¹ : Inhabited β
inst✝ : Inhabited γ
f : α → β → γ
h1 : f default default = default
k : ℕ
head✝¹ : α
as : List α
head✝ : β
bs : List β
⊢ get (k + 1) (pointwise f (head✝¹ :: as) (head✝ :: bs)) = f (get (k + 1) (head✝¹ :: as)) (get (k + 1) (head✝ :: bs))

Next tactic:
simp only [get, Nat.add_eq, add_zero, get_pointwise h1 k as bs]
theorem length_pointwise {f : α → β → γ} :
    ∀ {as : List α} {bs : List β}, (pointwise f as bs).length = max as.length bs.length
  | [], [] => rfl
  | [], _ :: bs => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β → γ
head✝ : β
bs : List β
⊢ length (pointwise f [] (head✝ :: bs)) = max (length []) (length (head✝ :: bs))

Next tactic:
simp only [pointwise, length, length_map, max_eq_right (Nat.zero_le (length bs + 1))]