Theorem: List.map_enumFrom_eq_zipWith
File: Mathlib/Data/List/Indexes.lean

tactic: intro l
state_before: α : Type u
β : Type v
⊢ ∀ (l : List α) (n : ℕ) (f : ℕ → α → β),
    map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range l.length) l
state_after: α : Type u
β : Type v
l : List α
⊢ ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range l.length) l

tactic: generalize e : l.length = len
state_before: α : Type u
β : Type v
l : List α
⊢ ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range l.length) l
state_after: α : Type u
β : Type v
l : List α
len : ℕ
e : l.length = len
⊢ ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l

tactic: revert l
state_before: α : Type u
β : Type v
l : List α
len : ℕ
e : l.length = len
⊢ ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
state_after: α : Type u
β : Type v
len : ℕ
⊢ ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l

tactic: induction' len with len ih <;> intros l e n f
state_before: α : Type u
β : Type v
len : ℕ
⊢ ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
state_after: case zero
α : Type u
β : Type v
l : List α
e : l.length = 0
n : ℕ
f : ℕ → α → β
⊢ map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range 0) l

case succ
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
l : List α
e : l.length = len + 1
n : ℕ
f : ℕ → α → β
⊢ map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range (len + 1)) l

tactic: rw [this]
state_before: case zero
α : Type u
β : Type v
l : List α
e : l.length = 0
n : ℕ
f : ℕ → α → β
this : l = []
⊢ map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range 0) l
state_after: case zero
α : Type u
β : Type v
l : List α
e : l.length = 0
n : ℕ
f : ℕ → α → β
this : l = []
⊢ map (uncurry f) (enumFrom n []) = zipWith (fun i => f (i + n)) (range 0) []

tactic: rfl
state_before: case zero
α : Type u
β : Type v
l : List α
e : l.length = 0
n : ℕ
f : ℕ → α → β
this : l = []
⊢ map (uncurry f) (enumFrom n []) = zipWith (fun i => f (i + n)) (range 0) []
state_after: no goals

tactic: cases l
state_before: α : Type u
β : Type v
l : List α
e : l.length = 0
n : ℕ
f : ℕ → α → β
⊢ l = []
state_after: case nil
α : Type u
β : Type v
n : ℕ
f : ℕ → α → β
e : [].length = 0
⊢ [] = []

case cons
α : Type u
β : Type v
n : ℕ
f : ℕ → α → β
head✝ : α
tail✝ : List α
e : (head✝ :: tail✝).length = 0
⊢ head✝ :: tail✝ = []

tactic: rfl
state_before: case nil
α : Type u
β : Type v
n : ℕ
f : ℕ → α → β
e : [].length = 0
⊢ [] = []
state_after: no goals

tactic: contradiction
state_before: case cons
α : Type u
β : Type v
n : ℕ
f : ℕ → α → β
head✝ : α
tail✝ : List α
e : (head✝ :: tail✝).length = 0
⊢ head✝ :: tail✝ = []
state_after: no goals

tactic: cases' l with head tail
state_before: case succ
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
l : List α
e : l.length = len + 1
n : ℕ
f : ℕ → α → β
⊢ map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range (len + 1)) l
state_after: case succ.nil
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
e : [].length = len + 1
⊢ map (uncurry f) (enumFrom n []) = zipWith (fun i => f (i + n)) (range (len + 1)) []

case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ map (uncurry f) (enumFrom n (head :: tail)) = zipWith (fun i => f (i + n)) (range (len + 1)) (head :: tail)

tactic: contradiction
state_before: case succ.nil
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
e : [].length = len + 1
⊢ map (uncurry f) (enumFrom n []) = zipWith (fun i => f (i + n)) (range (len + 1)) []
state_after: no goals

tactic: simp only [map, uncurry_apply_pair, range_succ_eq_map, zipWith, Nat.zero_add,
  zipWith_map_left]
state_before: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ map (uncurry f) (enumFrom n (head :: tail)) = zipWith (fun i => f (i + n)) (range (len + 1)) (head :: tail)
state_after: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ f n head :: map (uncurry f) (enumFrom (n + 1) tail) =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail

tactic: rw [ih]
state_before: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ f n head :: map (uncurry f) (enumFrom (n + 1) tail) =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail
state_after: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ f n head :: zipWith (fun i => f (i + (n + 1))) (range len) tail =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail

case succ.cons.e
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ tail.length = len

tactic: simp only [length_cons, Nat.succ.injEq] at e
state_before: case succ.cons.e
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ tail.length = len
state_after: case succ.cons.e
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : tail.length = len
⊢ tail.length = len

tactic: exact e
state_before: case succ.cons.e
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : tail.length = len
⊢ tail.length = len
state_after: no goals

tactic: suffices (fun i ↦ f (i + (n + 1))) = ((fun i ↦ f (i + n)) ∘ Nat.succ) by
  rw [this]
  rfl
state_before: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ f n head :: zipWith (fun i => f (i + (n + 1))) (range len) tail =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail
state_after: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ (fun i => f (i + (n + 1))) = (fun i => f (i + n)) ∘ Nat.succ

tactic: funext n' a
state_before: case succ.cons
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
⊢ (fun i => f (i + (n + 1))) = (fun i => f (i + n)) ∘ Nat.succ
state_after: case succ.cons.h.h
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
n' : ℕ
a : α
⊢ f (n' + (n + 1)) a = ((fun i => f (i + n)) ∘ Nat.succ) n' a

tactic: simp only [comp, Nat.add_assoc, Nat.add_comm, Nat.add_succ]
state_before: case succ.cons.h.h
α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
n' : ℕ
a : α
⊢ f (n' + (n + 1)) a = ((fun i => f (i + n)) ∘ Nat.succ) n' a
state_after: no goals

tactic: rw [this]
state_before: α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
this : (fun i => f (i + (n + 1))) = (fun i => f (i + n)) ∘ Nat.succ
⊢ f n head :: zipWith (fun i => f (i + (n + 1))) (range len) tail =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail
state_after: α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
this : (fun i => f (i + (n + 1))) = (fun i => f (i + n)) ∘ Nat.succ
⊢ f n head :: zipWith ((fun i => f (i + n)) ∘ Nat.succ) (range len) tail =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail

tactic: rfl
state_before: α : Type u
β : Type v
len : ℕ
ih :
  ∀ (l : List α),
    l.length = len →
      ∀ (n : ℕ) (f : ℕ → α → β), map (uncurry f) (enumFrom n l) = zipWith (fun i => f (i + n)) (range len) l
n : ℕ
f : ℕ → α → β
head : α
tail : List α
e : (head :: tail).length = len + 1
this : (fun i => f (i + (n + 1))) = (fun i => f (i + n)) ∘ Nat.succ
⊢ f n head :: zipWith ((fun i => f (i + n)) ∘ Nat.succ) (range len) tail =
    f n head :: zipWith (fun a b => f (a.succ + n) b) (range len) tail
state_after: no goals