Theorem: Complex.exp_add
File: Mathlib/Data/Complex/Exponential.lean

tactic: have hj : ∀ j : ℕ, (∑ m in range j, (x + y) ^ m / m.factorial) =
      ∑ i in range j, ∑ k in range (i + 1), x ^ k / k.factorial *
        (y ^ (i - k) / (i - k).factorial) := by
  intro j
  refine' Finset.sum_congr rfl fun m _ => _
  rw [add_pow, div_eq_mul_inv, sum_mul]
  refine' Finset.sum_congr rfl fun I hi => _
  have h₁ : (m.choose I : ℂ) ≠ 0 :=
    Nat.cast_ne_zero.2 (pos_iff_ne_zero.1 (Nat.choose_pos (Nat.le_of_lt_succ (mem_range.1 hi))))
  have h₂ := Nat.choose_mul_factorial_mul_factorial (Nat.le_of_lt_succ <| Finset.mem_range.1 hi)
  rw [← h₂, Nat.cast_mul, Nat.cast_mul, mul_inv, mul_inv]
  simp only [mul_left_comm (m.choose I : ℂ), mul_assoc, mul_left_comm (m.choose I : ℂ)⁻¹,
    mul_comm (m.choose I : ℂ)]
  rw [inv_mul_cancel h₁]
  simp [div_eq_mul_inv, mul_comm, mul_assoc, mul_left_comm]
state_before: x y : ℂ
⊢ exp (x + y) = exp x * exp y

tactic: simp_rw [exp, exp', lim_mul_lim]
state_before: x y : ℂ
hj :
  ∀ (j : ℕ),
    ∑ m in range j, (x + y) ^ m / ↑(Nat.factorial m) =
      ∑ i in range j, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))
⊢ exp (x + y) = exp x * exp y

tactic: apply (lim_eq_lim_of_equiv _).symm
state_before: x y : ℂ
hj :
  ∀ (j : ℕ),
    ∑ m in range j, (x + y) ^ m / ↑(Nat.factorial m) =
      ∑ i in range j, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))
⊢ CauSeq.lim
      { val := fun n => ∑ m in range n, (x + y) ^ m / ↑(Nat.factorial m),
        property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, (x + y) ^ m / ↑(Nat.factorial m)) } =
    CauSeq.lim
      ({ val := fun n => ∑ m in range n, x ^ m / ↑(Nat.factorial m),
          property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, x ^ m / ↑(Nat.factorial m)) } *
        { val := fun n => ∑ m in range n, y ^ m / ↑(Nat.factorial m),
          property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, y ^ m / ↑(Nat.factorial m)) })

tactic: simp only [hj]
state_before: x y : ℂ
hj :
  ∀ (j : ℕ),
    ∑ m in range j, (x + y) ^ m / ↑(Nat.factorial m) =
      ∑ i in range j, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))
⊢ { val := fun n => ∑ m in range n, x ^ m / ↑(Nat.factorial m),
        property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, x ^ m / ↑(Nat.factorial m)) } *
      { val := fun n => ∑ m in range n, y ^ m / ↑(Nat.factorial m),
        property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, y ^ m / ↑(Nat.factorial m)) } ≈
    { val := fun n => ∑ m in range n, (x + y) ^ m / ↑(Nat.factorial m),
      property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, (x + y) ^ m / ↑(Nat.factorial m)) }

tactic: exact cauchy_product (isCauSeq_abs_exp x) (isCauSeq_exp y)
state_before: x y : ℂ
hj :
  ∀ (j : ℕ),
    ∑ m in range j, (x + y) ^ m / ↑(Nat.factorial m) =
      ∑ i in range j, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))
⊢ { val := fun n => ∑ m in range n, x ^ m / ↑(Nat.factorial m),
        property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, x ^ m / ↑(Nat.factorial m)) } *
      { val := fun n => ∑ m in range n, y ^ m / ↑(Nat.factorial m),
        property := (_ : IsCauSeq ↑abs fun n => ∑ m in range n, y ^ m / ↑(Nat.factorial m)) } ≈
    {
      val := fun n =>
        ∑ i in range n, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k))),
      property :=
        (_ :
          (fun f => IsCauSeq (↑abs) f) fun n =>
            ∑ i in range n,
              ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))) }

tactic: intro j
state_before: x y : ℂ
⊢ ∀ (j : ℕ),
    ∑ m in range j, (x + y) ^ m / ↑(Nat.factorial m) =
      ∑ i in range j, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))

tactic: refine' Finset.sum_congr rfl fun m _ => _
state_before: x y : ℂ
j : ℕ
⊢ ∑ m in range j, (x + y) ^ m / ↑(Nat.factorial m) =
    ∑ i in range j, ∑ k in range (i + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (i - k) / ↑(Nat.factorial (i - k)))

tactic: rw [add_pow, div_eq_mul_inv, sum_mul]
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
⊢ (x + y) ^ m / ↑(Nat.factorial m) =
    ∑ k in range (m + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (m - k) / ↑(Nat.factorial (m - k)))

tactic: refine' Finset.sum_congr rfl fun I hi => _
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
⊢ ∑ x_1 in range (m + 1), x ^ x_1 * y ^ (m - x_1) * ↑(Nat.choose m x_1) * (↑(Nat.factorial m))⁻¹ =
    ∑ k in range (m + 1), x ^ k / ↑(Nat.factorial k) * (y ^ (m - k) / ↑(Nat.factorial (m - k)))

tactic: have h₁ : (m.choose I : ℂ) ≠ 0 :=
  Nat.cast_ne_zero.2 (pos_iff_ne_zero.1 (Nat.choose_pos (Nat.le_of_lt_succ (mem_range.1 hi))))
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
I : ℕ
hi : I ∈ range (m + 1)
⊢ x ^ I * y ^ (m - I) * ↑(Nat.choose m I) * (↑(Nat.factorial m))⁻¹ =
    x ^ I / ↑(Nat.factorial I) * (y ^ (m - I) / ↑(Nat.factorial (m - I)))

tactic: have h₂ := Nat.choose_mul_factorial_mul_factorial (Nat.le_of_lt_succ <| Finset.mem_range.1 hi)
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
I : ℕ
hi : I ∈ range (m + 1)
h₁ : ↑(Nat.choose m I) ≠ 0
⊢ x ^ I * y ^ (m - I) * ↑(Nat.choose m I) * (↑(Nat.factorial m))⁻¹ =
    x ^ I / ↑(Nat.factorial I) * (y ^ (m - I) / ↑(Nat.factorial (m - I)))

tactic: rw [← h₂, Nat.cast_mul, Nat.cast_mul, mul_inv, mul_inv]
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
I : ℕ
hi : I ∈ range (m + 1)
h₁ : ↑(Nat.choose m I) ≠ 0
h₂ : Nat.choose m I * Nat.factorial I * Nat.factorial (m - I) = Nat.factorial m
⊢ x ^ I * y ^ (m - I) * ↑(Nat.choose m I) * (↑(Nat.factorial m))⁻¹ =
    x ^ I / ↑(Nat.factorial I) * (y ^ (m - I) / ↑(Nat.factorial (m - I)))

tactic: simp only [mul_left_comm (m.choose I : ℂ), mul_assoc, mul_left_comm (m.choose I : ℂ)⁻¹,
  mul_comm (m.choose I : ℂ)]
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
I : ℕ
hi : I ∈ range (m + 1)
h₁ : ↑(Nat.choose m I) ≠ 0
h₂ : Nat.choose m I * Nat.factorial I * Nat.factorial (m - I) = Nat.factorial m
⊢ x ^ I * y ^ (m - I) * ↑(Nat.choose m I) *
      ((↑(Nat.choose m I))⁻¹ * (↑(Nat.factorial I))⁻¹ * (↑(Nat.factorial (m - I)))⁻¹) =
    x ^ I / ↑(Nat.factorial I) * (y ^ (m - I) / ↑(Nat.factorial (m - I)))

tactic: rw [inv_mul_cancel h₁]
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
I : ℕ
hi : I ∈ range (m + 1)
h₁ : ↑(Nat.choose m I) ≠ 0
h₂ : Nat.choose m I * Nat.factorial I * Nat.factorial (m - I) = Nat.factorial m
⊢ x ^ I *
      (y ^ (m - I) *
        ((↑(Nat.factorial I))⁻¹ * ((↑(Nat.factorial (m - I)))⁻¹ * ((↑(Nat.choose m I))⁻¹ * ↑(Nat.choose m I))))) =
    x ^ I / ↑(Nat.factorial I) * (y ^ (m - I) / ↑(Nat.factorial (m - I)))

tactic: simp [div_eq_mul_inv, mul_comm, mul_assoc, mul_left_comm]
state_before: x y : ℂ
j m : ℕ
x✝ : m ∈ range j
I : ℕ
hi : I ∈ range (m + 1)
h₁ : ↑(Nat.choose m I) ≠ 0
h₂ : Nat.choose m I * Nat.factorial I * Nat.factorial (m - I) = Nat.factorial m
⊢ x ^ I * (y ^ (m - I) * ((↑(Nat.factorial I))⁻¹ * ((↑(Nat.factorial (m - I)))⁻¹ * 1))) =
    x ^ I / ↑(Nat.factorial I) * (y ^ (m - I) / ↑(Nat.factorial (m - I)))