-- Mathlib/RingTheory/Polynomial/Chebyshev.lean
theorem T_mul_T (m k : ℤ) : 2 * T R m * T R k = T R (m + k) + T R (m - k)

Proof state:
case one
R : Type u_1
inst✝ : CommRing R
m : ℤ
⊢ 2 * T R m * X = 2 * X * T R m - T R (m - 1) + T R (m - 1)

Tactic:
ring

Result:
no goals

Proof state:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
h₁ : T R (m + ↑k + 2) = 2 * X * T R (m + ↑k + 1) - T R (m + ↑k)
h₂ : T R (m - ↑k - 2) = 2 * X * T R (m - ↑k - 1) - T R (m - ↑k)
h₃ : T R (↑k + 2) = 2 * X * T R (↑k + 1) - T R ↑k
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))

Tactic:
linear_combination (norm := ring_nf) 2 * T R m * h₃ - h₂ - h₁ - ih2 + 2 * (X : R[X]) * ih1

Result:
no goals

Proof state:
case one
R : Type u_1
inst✝ : CommRing R
m : ℤ
⊢ 2 * T R m * T R 1 = T R (m + 1) + T R (m - 1)

Tactic:
rw [T_add_one, T_one]

Result:
case one
R : Type u_1
inst✝ : CommRing R
m : ℤ
⊢ 2 * T R m * X = 2 * X * T R m - T R (m - 1) + T R (m - 1)

Proof state:
R : Type u_1
inst✝ : CommRing R
m k : ℤ
⊢ 2 * T R m * T R k = T R (m + k) + T R (m - k)

Tactic:
induction k using Polynomial.Chebyshev.induct with
| zero => simp [two_mul]
| one => rw [T_add_one, T_one]; ring
| add_two k ih1 ih2 =>
  have h₁ := T_add_two R (m + k)
  have h₂ := T_sub_two R (m - k)
  have h₃ := T_add_two R k
  linear_combination (norm := ring_nf) 2 * T R m * h₃ - h₂ - h₁ - ih2 + 2 * (X : R[X]) * ih1
| neg_add_one k ih1 ih2 =>
  have h₁ := T_add_two R (m + (-k - 1))
  have h₂ := T_sub_two R (m - (-k - 1))
  have h₃ := T_add_two R (-k - 1)
  linear_combination (norm := ring_nf) 2 * T R m * h₃ - h₂ - h₁ - ih2 + 2 * (X : R[X]) * ih1

Result:
no goals

Proof state:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
h₁ : T R (m + (-↑k - 1) + 2) = 2 * X * T R (m + (-↑k - 1) + 1) - T R (m + (-↑k - 1))
h₂ : T R (m - (-↑k - 1) - 2) = 2 * X * T R (m - (-↑k - 1) - 1) - T R (m - (-↑k - 1))
h₃ : T R (-↑k - 1 + 2) = 2 * X * T R (-↑k - 1 + 1) - T R (-↑k - 1)
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Tactic:
linear_combination (norm := ring_nf) 2 * T R m * h₃ - h₂ - h₁ - ih2 + 2 * (X : R[X]) * ih1

Result:
no goals

Proof state:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
h₁ : T R (m + ↑k + 2) = 2 * X * T R (m + ↑k + 1) - T R (m + ↑k)
h₂ : T R (m - ↑k - 2) = 2 * X * T R (m - ↑k - 1) - T R (m - ↑k)
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))

Tactic:
have h₃ := T_add_two R k

Result:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
h₁ : T R (m + ↑k + 2) = 2 * X * T R (m + ↑k + 1) - T R (m + ↑k)
h₂ : T R (m - ↑k - 2) = 2 * X * T R (m - ↑k - 1) - T R (m - ↑k)
h₃ : T R (↑k + 2) = 2 * X * T R (↑k + 1) - T R ↑k
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))

Proof state:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
h₁ : T R (m + (-↑k - 1) + 2) = 2 * X * T R (m + (-↑k - 1) + 1) - T R (m + (-↑k - 1))
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Tactic:
have h₂ := T_sub_two R (m - (-k - 1))

Result:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
h₁ : T R (m + (-↑k - 1) + 2) = 2 * X * T R (m + (-↑k - 1) + 1) - T R (m + (-↑k - 1))
h₂ : T R (m - (-↑k - 1) - 2) = 2 * X * T R (m - (-↑k - 1) - 1) - T R (m - (-↑k - 1))
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Proof state:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Tactic:
have h₁ := T_add_two R (m + (-k - 1))

Result:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
h₁ : T R (m + (-↑k - 1) + 2) = 2 * X * T R (m + (-↑k - 1) + 1) - T R (m + (-↑k - 1))
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Proof state:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
h₁ : T R (m + (-↑k - 1) + 2) = 2 * X * T R (m + (-↑k - 1) + 1) - T R (m + (-↑k - 1))
h₂ : T R (m - (-↑k - 1) - 2) = 2 * X * T R (m - (-↑k - 1) - 1) - T R (m - (-↑k - 1))
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Tactic:
have h₃ := T_add_two R (-k - 1)

Result:
case neg_add_one
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (-↑k) = T R (m + -↑k) + T R (m - -↑k)
ih2 : 2 * T R m * T R (-↑k + 1) = T R (m + (-↑k + 1)) + T R (m - (-↑k + 1))
h₁ : T R (m + (-↑k - 1) + 2) = 2 * X * T R (m + (-↑k - 1) + 1) - T R (m + (-↑k - 1))
h₂ : T R (m - (-↑k - 1) - 2) = 2 * X * T R (m - (-↑k - 1) - 1) - T R (m - (-↑k - 1))
h₃ : T R (-↑k - 1 + 2) = 2 * X * T R (-↑k - 1 + 1) - T R (-↑k - 1)
⊢ 2 * T R m * T R (-↑k - 1) = T R (m + (-↑k - 1)) + T R (m - (-↑k - 1))

Proof state:
case zero
R : Type u_1
inst✝ : CommRing R
m : ℤ
⊢ 2 * T R m * T R 0 = T R (m + 0) + T R (m - 0)

Tactic:
simp [two_mul]

Result:
no goals

Proof state:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
h₁ : T R (m + ↑k + 2) = 2 * X * T R (m + ↑k + 1) - T R (m + ↑k)
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))

Tactic:
have h₂ := T_sub_two R (m - k)

Result:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
h₁ : T R (m + ↑k + 2) = 2 * X * T R (m + ↑k + 1) - T R (m + ↑k)
h₂ : T R (m - ↑k - 2) = 2 * X * T R (m - ↑k - 1) - T R (m - ↑k)
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))

Proof state:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))

Tactic:
have h₁ := T_add_two R (m + k)

Result:
case add_two
R : Type u_1
inst✝ : CommRing R
m : ℤ
k : ℕ
ih1 : 2 * T R m * T R (↑k + 1) = T R (m + (↑k + 1)) + T R (m - (↑k + 1))
ih2 : 2 * T R m * T R ↑k = T R (m + ↑k) + T R (m - ↑k)
h₁ : T R (m + ↑k + 2) = 2 * X * T R (m + ↑k + 1) - T R (m + ↑k)
⊢ 2 * T R m * T R (↑k + 2) = T R (m + (↑k + 2)) + T R (m - (↑k + 2))