l3lab/ntp-mathlib huggingface dataset:
/-- 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.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 }) (1 + 1) =
    coeff (↑f) (1 + 1)

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.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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (1 + 1 + 1) =
    coeff (↑f) (1 + 1 + 1)

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.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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (n + 3 + 1) =
    coeff (↑f) (n + 3 + 1)

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] <;> ring_nf
      <;> 

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:
try simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> try 

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:
simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> 

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 }) 1 = coeff (↑f) 1

Next tactic:
try simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> try 

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 }) 1 = coeff (↑f) 1

Next tactic:
simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> 

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) 2 = coeff (↑f) 2

Next tactic:
try simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> try 

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) 2 = coeff (↑f) 2

Next tactic:
simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> 

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) 3 = coeff (↑f) 3

Next tactic:
try simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> try 

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) 3 = coeff (↑f) 3

Next tactic:
simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> 

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (4 + n) =
    coeff (↑f) (4 + n)

Next tactic:
try simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> try 

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (4 + n) =
    coeff (↑f) (4 + n)

Next tactic:
simp only [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.
    ext (_ | _ | _ | _ | n) <;> simp only [Nat.zero_eq, Nat.succ_eq_add_one] <;> ring_nf
      <;> try simp only [coeffs]
    

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 (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (4 + n) =
    coeff (↑f) (4 + n)

Next tactic:
have h3 : 3 < 4 + n := by linarith only
/-- 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] <;> ring_nf
      <;> try simp only [coeffs]
    have h3 : 3 < 4 + n := 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
f : { p // degree p ≤ 3 }
n : ℕ
⊢ 3 < 4 + n

Next tactic:
linarith only
/-- 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] <;> ring_nf
      <;> try simp only [coeffs]
    have h3 : 3 < 4 + n := by linarith only
    

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 : ℕ
h3 : 3 < 4 + n
⊢ coeff (toPoly { a := coeff (↑f) 3, b := coeff (↑f) 2, c := coeff (↑f) 1, d := coeff (↑f) 0 }) (4 + n) =
    coeff (↑f) (4 + n)

Next tactic:
rw [coeff_eq_zero h3,
      (degree_le_iff_coeff_zero (f : R[X]) 3).mp f.2 _ <| WithBot.coe_lt_coe.mpr (by exact h3)]
/-- 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] <;> ring_nf
      <;> try simp only [coeffs]
    have h3 : 3 < 4 + n := by linarith only
    rw [coeff_eq_zero h3,
      (degree_le_iff_coeff_zero (f : R[X]) 3).mp f.2 _ <| WithBot.coe_lt_coe.mpr (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
f : { p // degree p ≤ 3 }
n : ℕ
h3 : 3 < 4 + n
⊢ ↑3 < ↑(4 + n)

Next tactic:
exact h3
theorem degree_of_a_eq_zero (ha : P.a = 0) : P.toPoly.degree ≤ 2 := 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
⊢ degree (toPoly P) ≤ 2

Next tactic:
simpa only [of_a_eq_zero ha] using degree_quadratic_le
@[simp]
theorem degree_of_b_ne_zero (ha : P.a = 0) (hb : P.b ≠ 0) : P.toPoly.degree = 2 := 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
⊢ degree (toPoly P) = 2

Next tactic:
rw [of_a_eq_zero ha, degree_quadratic hb]
theorem degree_of_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) : P.toPoly.degree ≤ 1 := 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
⊢ degree (toPoly P) ≤ 1

Next tactic:
simpa only [of_b_eq_zero ha hb] using degree_linear_le
@[simp]
theorem degree_of_c_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) : P.toPoly.degree = 1 := 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
⊢ degree (toPoly P) = 1

Next tactic:
rw [of_b_eq_zero ha hb, degree_linear hc]
theorem degree_of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) : P.toPoly.degree ≤ 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
⊢ degree (toPoly P) ≤ 0

Next tactic:
simpa only [of_c_eq_zero ha hb hc] using degree_C_le
@[simp]
theorem degree_of_d_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d ≠ 0) :
    P.toPoly.degree = 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
⊢ degree (toPoly P) = 0

Next tactic:
rw [of_c_eq_zero ha hb hc, degree_C hd]
@[simp]
theorem degree_of_d_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 0) :
    P.toPoly.degree = ⊥ := 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
⊢ degree (toPoly P) = ⊥

Next tactic:
rw [of_d_eq_zero ha hb hc hd, degree_zero]
theorem natDegree_of_a_eq_zero (ha : P.a = 0) : P.toPoly.natDegree ≤ 2 := 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
⊢ natDegree (toPoly P) ≤ 2

Next tactic:
simpa only [of_a_eq_zero ha] using natDegree_quadratic_le
@[simp]
theorem natDegree_of_b_ne_zero (ha : P.a = 0) (hb : P.b ≠ 0) : P.toPoly.natDegree = 2 := 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
⊢ natDegree (toPoly P) = 2

Next tactic:
rw [of_a_eq_zero ha, natDegree_quadratic hb]
theorem natDegree_of_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) : P.toPoly.natDegree ≤ 1 := 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
⊢ natDegree (toPoly P) ≤ 1

Next tactic:
simpa only [of_b_eq_zero ha hb] using natDegree_linear_le
@[simp]
theorem natDegree_of_c_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) :
    P.toPoly.natDegree = 1 := 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
⊢ natDegree (toPoly P) = 1

Next tactic:
rw [of_b_eq_zero ha hb, natDegree_linear hc]
@[simp]
theorem natDegree_of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) :
    P.toPoly.natDegree = 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
⊢ natDegree (toPoly P) = 0

Next tactic:
rw [of_c_eq_zero ha hb hc, natDegree_C]
theorem map_toPoly : (map φ P).toPoly = Polynomial.map φ P.toPoly := 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
inst✝ : Semiring S
φ : R →+* S
⊢ toPoly (map φ P) = Polynomial.map φ (toPoly P)

Next tactic:
simp only [map, toPoly, map_C, map_X, Polynomial.map_add, Polynomial.map_mul, Polynomial.map_pow]
theorem map_roots [IsDomain S] : (map φ P).roots = (Polynomial.map φ P.toPoly).roots := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝² : CommRing R
inst✝¹ : CommRing S
φ : R →+* S
inst✝ : IsDomain S
⊢ roots (map φ P) = Polynomial.roots (Polynomial.map φ (toPoly P))

Next tactic:
rw [roots, map_toPoly]
theorem mem_roots_iff [IsDomain R] (h0 : P.toPoly ≠ 0) (x : R) :
    x ∈ P.roots ↔ P.a * x ^ 3 + P.b * x ^ 2 + P.c * x + P.d = 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝² : CommRing R
inst✝¹ : CommRing S
φ : R →+* S
inst✝ : IsDomain R
h0 : toPoly P ≠ 0
x : R
⊢ x ∈ roots P ↔ P.a * x ^ 3 + P.b * x ^ 2 + P.c * x + P.d = 0

Next tactic:
rw [roots, mem_roots h0, IsRoot, toPoly]
theorem mem_roots_iff [IsDomain R] (h0 : P.toPoly ≠ 0) (x : R) :
    x ∈ P.roots ↔ P.a * x ^ 3 + P.b * x ^ 2 + P.c * x + P.d = 0 := by
  rw [roots, mem_roots h0, IsRoot, toPoly]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝² : CommRing R
inst✝¹ : CommRing S
φ : R →+* S
inst✝ : IsDomain R
h0 : toPoly P ≠ 0
x : R
⊢ eval x (C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d) = 0 ↔ P.a * x ^ 3 + P.b * x ^ 2 + P.c * x + P.d = 0

Next tactic:
simp only [eval_C, eval_X, eval_add, eval_mul, eval_pow]
theorem card_roots_le [IsDomain R] [DecidableEq R] : P.roots.toFinset.card ≤ 3 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝³ : CommRing R
inst✝² : CommRing S
φ : R →+* S
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
⊢ Finset.card (toFinset (roots P)) ≤ 3

Next tactic:
apply (toFinset_card_le P.toPoly.roots).trans
theorem card_roots_le [IsDomain R] [DecidableEq R] : P.roots.toFinset.card ≤ 3 := by
  apply (toFinset_card_le P.toPoly.roots).trans
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝³ : CommRing R
inst✝² : CommRing S
φ : R →+* S
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
⊢ card (Polynomial.roots (toPoly P)) ≤ 3

Next tactic:
by_cases hP : P.toPoly = 0
theorem card_roots_le [IsDomain R] [DecidableEq R] : P.roots.toFinset.card ≤ 3 := by
  apply (toFinset_card_le P.toPoly.roots).trans
  by_cases hP : P.toPoly = 0
  · 

Proof state:
case pos
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝³ : CommRing R
inst✝² : CommRing S
φ : R →+* S
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
hP : toPoly P = 0
⊢ card (Polynomial.roots (toPoly P)) ≤ 3

Next tactic:
exact (card_roots' P.toPoly).trans (by rw [hP, natDegree_zero]; exact zero_le 3)
theorem card_roots_le [IsDomain R] [DecidableEq R] : P.roots.toFinset.card ≤ 3 := by
  apply (toFinset_card_le P.toPoly.roots).trans
  by_cases hP : P.toPoly = 0
  · exact (card_roots' P.toPoly).trans (by 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝³ : CommRing R
inst✝² : CommRing S
φ : R →+* S
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
hP : toPoly P = 0
⊢ natDegree (toPoly P) ≤ 3

Next tactic:
rw [hP, natDegree_zero]
theorem card_roots_le [IsDomain R] [DecidableEq R] : P.roots.toFinset.card ≤ 3 := by
  apply (toFinset_card_le P.toPoly.roots).trans
  by_cases hP : P.toPoly = 0
  · exact (card_roots' P.toPoly).trans (by rw [hP, natDegree_zero]; 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝³ : CommRing R
inst✝² : CommRing S
φ : R →+* S
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
hP : toPoly P = 0
⊢ 0 ≤ 3

Next tactic:
exact zero_le 3
theorem card_roots_le [IsDomain R] [DecidableEq R] : P.roots.toFinset.card ≤ 3 := by
  apply (toFinset_card_le P.toPoly.roots).trans
  by_cases hP : P.toPoly = 0
  · exact (card_roots' P.toPoly).trans (by rw [hP, natDegree_zero]; exact zero_le 3)
  · 

Proof state:
case neg
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic R
inst✝³ : CommRing R
inst✝² : CommRing S
φ : R →+* S
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
hP : ¬toPoly P = 0
⊢ card (Polynomial.roots (toPoly P)) ≤ 3

Next tactic:
exact WithBot.coe_le_coe.1 ((card_roots hP).trans degree_cubic_le)