l3lab/ntp-mathlib huggingface dataset:
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
len : ℕ
e : length (l₁ ++ l₂) = len
⊢ mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
revert l₁ l₂ arr
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
⊢ ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
induction' len with len ih
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> 

Proof state:
case zero
α : Type u
β : Type v
f : ℕ → α → β
⊢ ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = Nat.zero → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
intros l₁ l₂ arr h
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> 

Proof state:
case succ
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
⊢ ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = Nat.succ len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
intros l₁ l₂ arr h
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · 

Proof state:
case zero
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.zero
⊢ mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by 

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.zero
⊢ l₁ = []

Next tactic:
cases l₁
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; 

Proof state:
case nil
α : Type u
β : Type v
f : ℕ → α → β
l₂ : List α
arr : Array β
h : length ([] ++ l₂) = Nat.zero
⊢ [] = []
case cons
α : Type u
β : Type v
f : ℕ → α → β
l₂ : List α
arr : Array β
head✝ : α
tail✝ : List α
h : length (head✝ :: tail✝ ++ l₂) = Nat.zero
⊢ head✝ :: tail✝ = []

Next tactic:
rfl
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
l₂ : List α
arr : Array β
head✝ : α
tail✝ : List α
h : length (head✝ :: tail✝ ++ l₂) = Nat.zero
⊢ head✝ :: tail✝ = []

Next tactic:
contradiction
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    

Proof state:
case zero
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.zero
l₁_nil : l₁ = []
⊢ mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by 

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.zero
l₁_nil : l₁ = []
⊢ l₂ = []

Next tactic:
cases l₂
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; 

Proof state:
case nil
α : Type u
β : Type v
f : ℕ → α → β
l₁ : List α
arr : Array β
l₁_nil : l₁ = []
h : length (l₁ ++ []) = Nat.zero
⊢ [] = []
case cons
α : Type u
β : Type v
f : ℕ → α → β
l₁ : List α
arr : Array β
l₁_nil : l₁ = []
head✝ : α
tail✝ : List α
h : length (l₁ ++ head✝ :: tail✝) = Nat.zero
⊢ head✝ :: tail✝ = []

Next tactic:
rfl
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
l₁ : List α
arr : Array β
l₁_nil : l₁ = []
head✝ : α
tail✝ : List α
h : length (l₁ ++ head✝ :: tail✝) = Nat.zero
⊢ head✝ :: tail✝ = []

Next tactic:
rw [List.length_append] at h
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
l₁ : List α
arr : Array β
l₁_nil : l₁ = []
head✝ : α
tail✝ : List α
h : length l₁ + length (head✝ :: tail✝) = Nat.zero
⊢ head✝ :: tail✝ = []

Next tactic:
contradiction
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    

Proof state:
case zero
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.zero
l₁_nil : l₁ = []
l₂_nil : l₂ = []
⊢ mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
rw [l₁_nil, l₂_nil]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; 

Proof state:
case zero
α : Type u
β : Type v
f : ℕ → α → β
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.zero
l₁_nil : l₁ = []
l₂_nil : l₂ = []
⊢ mapIdx.go f ([] ++ []) arr = mapIdx.go f [] (toArray (mapIdx.go f [] arr))

Next tactic:
simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · 

Proof state:
case succ
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₁ l₂ : List α
arr : Array β
h : length (l₁ ++ l₂) = Nat.succ len
⊢ mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))

Next tactic:
cases' l₁ with head tail
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> 

Proof state:
case succ.nil
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
h : length ([] ++ l₂) = Nat.succ len
⊢ mapIdx.go f ([] ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f [] arr))

Next tactic:
simp only [mapIdx.go]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> 

Proof state:
case succ.cons
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
head : α
tail : List α
h : length (head :: tail ++ l₂) = Nat.succ len
⊢ mapIdx.go f (head :: tail ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f (head :: tail) arr))

Next tactic:
simp only [mapIdx.go]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> simp only [mapIdx.go]
    · 

Proof state:
case succ.nil
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
h : length ([] ++ l₂) = Nat.succ len
⊢ mapIdx.go f ([] ++ l₂) arr = mapIdx.go f l₂ (toArray (Array.toList arr))

Next tactic:
simp only [nil_append, Array.toList_eq, Array.toArray_data]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> simp only [mapIdx.go]
    · simp only [nil_append, Array.toList_eq, Array.toArray_data]
    · 

Proof state:
case succ.cons
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
head : α
tail : List α
h : length (head :: tail ++ l₂) = Nat.succ len
⊢ mapIdx.go f (List.append tail l₂) (Array.push arr (f (Array.size arr) head)) =
    mapIdx.go f l₂ (toArray (mapIdx.go f tail (Array.push arr (f (Array.size arr) head))))

Next tactic:
simp only [List.append_eq]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> simp only [mapIdx.go]
    · simp only [nil_append, Array.toList_eq, Array.toArray_data]
    · simp only [List.append_eq]
      

Proof state:
case succ.cons
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
head : α
tail : List α
h : length (head :: tail ++ l₂) = Nat.succ len
⊢ mapIdx.go f (tail ++ l₂) (Array.push arr (f (Array.size arr) head)) =
    mapIdx.go f l₂ (toArray (mapIdx.go f tail (Array.push arr (f (Array.size arr) head))))

Next tactic:
rw [ih]
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> simp only [mapIdx.go]
    · simp only [nil_append, Array.toList_eq, Array.toArray_data]
    · simp only [List.append_eq]
      rw [ih]
      · 

Proof state:
case succ.cons.e
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
head : α
tail : List α
h : length (head :: tail ++ l₂) = Nat.succ len
⊢ length (tail ++ l₂) = len

Next tactic:
simp only [cons_append, length_cons, length_append, Nat.succ.injEq] at h
theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β),
    mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by
  intros f l₁ l₂ arr
  generalize e : (l₁ ++ l₂).length = len
  revert l₁ l₂ arr
  induction' len with len ih <;> intros l₁ l₂ arr h
  · have l₁_nil : l₁ = [] := by cases l₁; rfl; contradiction
    have l₂_nil : l₂ = [] := by cases l₂; rfl; rw [List.length_append] at h; contradiction
    rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, Array.toList_eq, Array.toArray_data]
  · cases' l₁ with head tail <;> simp only [mapIdx.go]
    · simp only [nil_append, Array.toList_eq, Array.toArray_data]
    · simp only [List.append_eq]
      rw [ih]
      · simp only [cons_append, length_cons, length_append, Nat.succ.injEq] at h
        

Proof state:
case succ.cons.e
α : Type u
β : Type v
f : ℕ → α → β
len : ℕ
ih :
  ∀ (l₁ l₂ : List α) (arr : Array β),
    length (l₁ ++ l₂) = len → mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (toArray (mapIdx.go f l₁ arr))
l₂ : List α
arr : Array β
head : α
tail : List α
h : length tail + length l₂ = len
⊢ length (tail ++ l₂) = len

Next tactic:
simp only [length_append, h]
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  

Proof state:
α : Type u
β : Type v
⊢ ∀ (f : ℕ → α → β) (l : List α) (arr : Array β), length (mapIdx.go f l arr) = length l + Array.size arr

Next tactic:
intro f l
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l : List α
⊢ ∀ (arr : Array β), length (mapIdx.go f l arr) = length l + Array.size arr

Next tactic:
induction' l with head tail ih
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · 

Proof state:
case nil
α : Type u
β : Type v
f : ℕ → α → β
⊢ ∀ (arr : Array β), length (mapIdx.go f [] arr) = length [] + Array.size arr

Next tactic:
intro
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · intro; 

Proof state:
case nil
α : Type u
β : Type v
f : ℕ → α → β
arr✝ : Array β
⊢ length (mapIdx.go f [] arr✝) = length [] + Array.size arr✝

Next tactic:
simp only [mapIdx.go, Array.toList_eq, length_nil, zero_add]
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · intro; simp only [mapIdx.go, Array.toList_eq, length_nil, zero_add]
  · 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
head : α
tail : List α
ih : ∀ (arr : Array β), length (mapIdx.go f tail arr) = length tail + Array.size arr
⊢ ∀ (arr : Array β), length (mapIdx.go f (head :: tail) arr) = length (head :: tail) + Array.size arr

Next tactic:
intro
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · intro; simp only [mapIdx.go, Array.toList_eq, length_nil, zero_add]
  · intro; 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
head : α
tail : List α
ih : ∀ (arr : Array β), length (mapIdx.go f tail arr) = length tail + Array.size arr
arr✝ : Array β
⊢ length (mapIdx.go f (head :: tail) arr✝) = length (head :: tail) + Array.size arr✝

Next tactic:
simp only [mapIdx.go]
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · intro; simp only [mapIdx.go, Array.toList_eq, length_nil, zero_add]
  · intro; simp only [mapIdx.go]; 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
head : α
tail : List α
ih : ∀ (arr : Array β), length (mapIdx.go f tail arr) = length tail + Array.size arr
arr✝ : Array β
⊢ length (mapIdx.go f tail (Array.push arr✝ (f (Array.size arr✝) head))) = length (head :: tail) + Array.size arr✝

Next tactic:
rw [ih]
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · intro; simp only [mapIdx.go, Array.toList_eq, length_nil, zero_add]
  · intro; simp only [mapIdx.go]; rw [ih]; 

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
head : α
tail : List α
ih : ∀ (arr : Array β), length (mapIdx.go f tail arr) = length tail + Array.size arr
arr✝ : Array β
⊢ length tail + Array.size (Array.push arr✝ (f (Array.size arr✝) head)) = length (head :: tail) + Array.size arr✝

Next tactic:
simp only [Array.size_push, length_cons]
theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β),
    length (mapIdx.go f l arr) = length l + arr.size := by
  intro f l
  induction' l with head tail ih
  · intro; simp only [mapIdx.go, Array.toList_eq, length_nil, zero_add]
  · intro; simp only [mapIdx.go]; rw [ih]; simp only [Array.size_push, length_cons];
    

Proof state:
case cons
α : Type u
β : Type v
f : ℕ → α → β
head : α
tail : List α
ih : ∀ (arr : Array β), length (mapIdx.go f tail arr) = length tail + Array.size arr
arr✝ : Array β
⊢ length tail + (Array.size arr✝ + 1) = Nat.succ (length tail) + Array.size arr✝

Next tactic:
simp only [Nat.add_succ, add_zero, Nat.add_comm]
theorem mapIdx_append_one : ∀ (f : ℕ → α → β) (l : List α) (e : α),
    mapIdx f (l ++ [e]) = mapIdx f l ++ [f l.length e] := by
  

Proof state:
α : Type u
β : Type v
⊢ ∀ (f : ℕ → α → β) (l : List α) (e : α), mapIdx f (l ++ [e]) = mapIdx f l ++ [f (length l) e]

Next tactic:
intros f l e
theorem mapIdx_append_one : ∀ (f : ℕ → α → β) (l : List α) (e : α),
    mapIdx f (l ++ [e]) = mapIdx f l ++ [f l.length e] := by
  intros f l e
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l : List α
e : α
⊢ mapIdx f (l ++ [e]) = mapIdx f l ++ [f (length l) e]

Next tactic:
unfold mapIdx
theorem mapIdx_append_one : ∀ (f : ℕ → α → β) (l : List α) (e : α),
    mapIdx f (l ++ [e]) = mapIdx f l ++ [f l.length e] := by
  intros f l e
  unfold mapIdx
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l : List α
e : α
⊢ mapIdx.go f (l ++ [e]) #[] = mapIdx.go f l #[] ++ [f (length l) e]

Next tactic:
rw [mapIdxGo_append f l [e]]
theorem mapIdx_append_one : ∀ (f : ℕ → α → β) (l : List α) (e : α),
    mapIdx f (l ++ [e]) = mapIdx f l ++ [f l.length e] := by
  intros f l e
  unfold mapIdx
  rw [mapIdxGo_append f l [e]]
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
l : List α
e : α
⊢ mapIdx.go f [e] (toArray (mapIdx.go f l #[])) = mapIdx.go f l #[] ++ [f (length l) e]

Next tactic:
simp only [mapIdx.go, Array.size_toArray, mapIdxGo_length, length_nil, add_zero, Array.toList_eq,
    Array.push_data, Array.data_toArray]
protected theorem new_def_eq_old_def :
    ∀ (f : ℕ → α → β) (l : List α), l.mapIdx f = List.oldMapIdx f l := by
  

Proof state:
α : Type u
β : Type v
⊢ ∀ (f : ℕ → α → β) (l : List α), mapIdx f l = List.oldMapIdx f l

Next tactic:
intro f
protected theorem new_def_eq_old_def :
    ∀ (f : ℕ → α → β) (l : List α), l.mapIdx f = List.oldMapIdx f l := by
  intro f
  

Proof state:
α : Type u
β : Type v
f : ℕ → α → β
⊢ ∀ (l : List α), mapIdx f l = List.oldMapIdx f l

Next tactic:
apply list_reverse_induction