l3lab/ntp-mathlib huggingface dataset:
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ 0 + 0 + 0 + 0 = 0
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 0
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 1
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 2
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 3

Next tactic:
any_goals linarith only [hn]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ 0 + 0 + 0 + 0 = 0

Next tactic:
linarith only [hn]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals 

Proof state:
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 0

Next tactic:
linarith only [hn]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals 

Proof state:
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 1

Next tactic:
linarith only [hn]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals 

Proof state:
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 2

Next tactic:
linarith only [hn]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals 

Proof state:
case hnc
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ ¬n = 3

Next tactic:
linarith only [hn]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals linarith only [hn]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ 0 + 0 + 0 + 0 = 0

Next tactic:
repeat' rw [zero_add]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals linarith only [hn]
  repeat' 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ 0 + 0 + 0 + 0 = 0

Next tactic:
rw [zero_add]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals linarith only [hn]
  repeat' 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ 0 + 0 + 0 = 0

Next tactic:
rw [zero_add]
private theorem coeffs : (∀ n > 3, P.toPoly.coeff n = 0) ∧ P.toPoly.coeff 3 = P.a ∧
    P.toPoly.coeff 2 = P.b ∧ P.toPoly.coeff 1 = P.c ∧ P.toPoly.coeff 0 = P.d := by
  simp only [toPoly, coeff_add, coeff_C, coeff_C_mul_X, coeff_C_mul_X_pow]
  norm_num
  intro n hn
  repeat' rw [if_neg]
  any_goals linarith only [hn]
  repeat' 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
n : ℕ
hn : 3 < n
⊢ 0 + 0 = 0

Next tactic:
rw [zero_add]
theorem a_of_eq (h : P.toPoly = Q.toPoly) : P.a = Q.a := by 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h : toPoly P = toPoly Q
⊢ P.a = Q.a

Next tactic:
rw [← coeff_eq_a, h, coeff_eq_a]
theorem b_of_eq (h : P.toPoly = Q.toPoly) : P.b = Q.b := by 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h : toPoly P = toPoly Q
⊢ P.b = Q.b

Next tactic:
rw [← coeff_eq_b, h, coeff_eq_b]
theorem c_of_eq (h : P.toPoly = Q.toPoly) : P.c = Q.c := by 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h : toPoly P = toPoly Q
⊢ P.c = Q.c

Next tactic:
rw [← coeff_eq_c, h, coeff_eq_c]
theorem d_of_eq (h : P.toPoly = Q.toPoly) : P.d = Q.d := by 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h : toPoly P = toPoly Q
⊢ P.d = Q.d

Next tactic:
rw [← coeff_eq_d, h, coeff_eq_d]
theorem of_a_eq_zero (ha : P.a = 0) : P.toPoly = C P.b * X ^ 2 + C P.c * X + C P.d := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
⊢ toPoly P = C P.b * X ^ 2 + C P.c * X + C P.d

Next tactic:
rw [toPoly, ha, C_0, zero_mul, zero_add]
theorem of_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) : P.toPoly = C P.c * X + C P.d := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
⊢ toPoly P = C P.c * X + C P.d

Next tactic:
rw [of_a_eq_zero ha, hb, C_0, zero_mul, zero_add]
theorem of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) : P.toPoly = C P.d := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c = 0
⊢ toPoly P = C P.d

Next tactic:
rw [of_b_eq_zero ha hb, hc, C_0, zero_mul, zero_add]
theorem of_d_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 0) :
    P.toPoly = 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c = 0
hd : P.d = 0
⊢ toPoly P = 0

Next tactic:
rw [of_c_eq_zero ha hb hc, hd, C_0]
theorem toPoly_eq_zero_iff (P : Cubic R) : P.toPoly = 0 ↔ P = 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P✝ Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
P : Cubic R
⊢ toPoly P = 0 ↔ P = 0

Next tactic:
rw [← zero, toPoly_injective]
private theorem ne_zero (h0 : P.a ≠ 0 ∨ P.b ≠ 0 ∨ P.c ≠ 0 ∨ P.d ≠ 0) : P.toPoly ≠ 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h0 : P.a ≠ 0 ∨ P.b ≠ 0 ∨ P.c ≠ 0 ∨ P.d ≠ 0
⊢ toPoly P ≠ 0

Next tactic:
contrapose! h0
private theorem ne_zero (h0 : P.a ≠ 0 ∨ P.b ≠ 0 ∨ P.c ≠ 0 ∨ P.d ≠ 0) : P.toPoly ≠ 0 := by
  contrapose! h0
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h0 : toPoly P = 0
⊢ P.a = 0 ∧ P.b = 0 ∧ P.c = 0 ∧ P.d = 0

Next tactic:
rw [(toPoly_eq_zero_iff P).mp h0]
private theorem ne_zero (h0 : P.a ≠ 0 ∨ P.b ≠ 0 ∨ P.c ≠ 0 ∨ P.d ≠ 0) : P.toPoly ≠ 0 := by
  contrapose! h0
  rw [(toPoly_eq_zero_iff P).mp h0]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
h0 : toPoly P = 0
⊢ 0.a = 0 ∧ 0.b = 0 ∧ 0.c = 0 ∧ 0.d = 0

Next tactic:
exact ⟨rfl, rfl, rfl, rfl⟩
@[simp]
theorem leadingCoeff_of_b_ne_zero (ha : P.a = 0) (hb : P.b ≠ 0) : P.toPoly.leadingCoeff = P.b := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b ≠ 0
⊢ leadingCoeff (toPoly P) = P.b

Next tactic:
rw [of_a_eq_zero ha, leadingCoeff_quadratic hb]
@[simp]
theorem leadingCoeff_of_c_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) :
    P.toPoly.leadingCoeff = P.c := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c ≠ 0
⊢ leadingCoeff (toPoly P) = P.c

Next tactic:
rw [of_b_eq_zero ha hb, leadingCoeff_linear hc]
@[simp]
theorem leadingCoeff_of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) :
    P.toPoly.leadingCoeff = P.d := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c = 0
⊢ leadingCoeff (toPoly P) = P.d

Next tactic:
rw [of_c_eq_zero ha hb hc, leadingCoeff_C]
theorem monic_of_a_eq_one (ha : P.a = 1) : P.toPoly.Monic := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 1
⊢ Monic (toPoly P)

Next tactic:
nontriviality R
theorem monic_of_a_eq_one (ha : P.a = 1) : P.toPoly.Monic := by
  nontriviality R
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 1
✝ : Nontrivial R
⊢ Monic (toPoly P)

Next tactic:
rw [Monic, leadingCoeff_of_a_ne_zero (ha ▸ one_ne_zero), ha]
theorem monic_of_b_eq_one (ha : P.a = 0) (hb : P.b = 1) : P.toPoly.Monic := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 1
⊢ Monic (toPoly P)

Next tactic:
nontriviality R
theorem monic_of_b_eq_one (ha : P.a = 0) (hb : P.b = 1) : P.toPoly.Monic := by
  nontriviality R
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 1
✝ : Nontrivial R
⊢ Monic (toPoly P)

Next tactic:
rw [Monic, leadingCoeff_of_b_ne_zero ha (hb ▸ one_ne_zero), hb]
theorem monic_of_c_eq_one (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 1) : P.toPoly.Monic := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c = 1
⊢ Monic (toPoly P)

Next tactic:
nontriviality R
theorem monic_of_c_eq_one (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 1) : P.toPoly.Monic := by
  nontriviality R
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c = 1
✝ : Nontrivial R
⊢ Monic (toPoly P)

Next tactic:
rw [Monic, leadingCoeff_of_c_ne_zero ha hb (hc ▸ one_ne_zero), hc]
theorem monic_of_d_eq_one (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 1) :
    P.toPoly.Monic := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
ha : P.a = 0
hb : P.b = 0
hc : P.c = 0
hd : P.d = 1
⊢ Monic (toPoly P)

Next tactic:
rw [Monic, leadingCoeff_of_c_eq_zero ha hb hc, hd]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P✝ Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
P : Cubic R
⊢ (fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 })
      ((fun P => { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
        P) =
    P

Next tactic:
ext
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> 

Proof state:
case a
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P✝ Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
P : Cubic R
⊢ ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 })
        ((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          P)).a =
    P.a

Next tactic:
simp only [Subtype.coe_mk, coeffs]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> 

Proof state:
case b
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P✝ Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
P : Cubic R
⊢ ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 })
        ((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          P)).b =
    P.b

Next tactic:
simp only [Subtype.coe_mk, coeffs]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> 

Proof state:
case c
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P✝ Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
P : Cubic R
⊢ ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 })
        ((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          P)).c =
    P.c

Next tactic:
simp only [Subtype.coe_mk, coeffs]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> 

Proof state:
case d
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P✝ Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
P : Cubic R
⊢ ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 })
        ((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          P)).d =
    P.d

Next tactic:
simp only [Subtype.coe_mk, coeffs]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ (fun P => { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
      ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) f) =
    f

Next tactic:
ext (_ | _ | _ | _ | n)
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> 

Proof state:
case a.a.zero
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ coeff
      (↑((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) f)))
      Nat.zero =
    coeff (↑f) Nat.zero

Next tactic:
simp only [Nat.zero_eq, Nat.succ_eq_add_one]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> 

Proof state:
case a.a.succ.zero
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ coeff
      (↑((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) f)))
      (Nat.succ Nat.zero) =
    coeff (↑f) (Nat.succ Nat.zero)

Next tactic:
simp only [Nat.zero_eq, Nat.succ_eq_add_one]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> 

Proof state:
case a.a.succ.succ.zero
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ coeff
      (↑((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) f)))
      (Nat.succ (Nat.succ Nat.zero)) =
    coeff (↑f) (Nat.succ (Nat.succ Nat.zero))

Next tactic:
simp only [Nat.zero_eq, Nat.succ_eq_add_one]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> 

Proof state:
case a.a.succ.succ.succ.zero
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ coeff
      (↑((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) f)))
      (Nat.succ (Nat.succ (Nat.succ Nat.zero))) =
    coeff (↑f) (Nat.succ (Nat.succ (Nat.succ Nat.zero)))

Next tactic:
simp only [Nat.zero_eq, Nat.succ_eq_add_one]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> 

Proof state:
case a.a.succ.succ.succ.succ
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
n : ℕ
⊢ coeff
      (↑((fun P =>
            { val := toPoly P, property := (_ : degree (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) ≤ 3) })
          ((fun f => { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) f)))
      (Nat.succ (Nat.succ (Nat.succ (Nat.succ n)))) =
    coeff (↑f) (Nat.succ (Nat.succ (Nat.succ (Nat.succ n))))

Next tactic:
simp only [Nat.zero_eq, Nat.succ_eq_add_one]
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> 

Proof state:
case a.a.zero
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ coeff (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) 0 = coeff (↑f) 0

Next tactic:
ring_nf
/-- The equivalence between cubic polynomials and polynomials of degree at most three. -/
@[simps]
def equiv : Cubic R ≃ { p : R[X] // p.degree ≤ 3 } where
  toFun P := ⟨P.toPoly, degree_cubic_le⟩
  invFun f := ⟨coeff f 3, coeff f 2, coeff f 1, coeff f 0⟩
  left_inv P := by ext <;> simp only [Subtype.coe_mk, coeffs]
  right_inv f := by
    -- Porting note: Added `simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf`
    -- There's probably a better way to do this.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> 

Proof state:
case a.a.succ.zero
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P Q : Cubic R
a b c d a' b' c' d' : R
inst✝ : Semiring R
f : { p // degree p ≤ 3 }
⊢ coeff (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (0 + 1) =
    coeff (↑f) (0 + 1)

Next tactic:
ring_nf