[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
⊢ rootMultiplicity t (↑derivative p) = rootMultiplicity t p - 1
[PROOFSTEP]
rcases eq_or_ne p 0 with (rfl | hp)
[GOAL]
case inl
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
t : R
hpt : IsRoot 0 t
⊢ rootMultiplicity t (↑derivative 0) = rootMultiplicity t 0 - 1
[PROOFSTEP]
simp
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
⊢ rootMultiplicity t (↑derivative p) = rootMultiplicity t p - 1
[PROOFSTEP]
nth_rw 1 [← p.divByMonic_mul_pow_rootMultiplicity_eq t]
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
⊢ rootMultiplicity t (↑derivative (p /ₘ (X - ↑C t) ^ rootMultiplicity t p * (X - ↑C t) ^ rootMultiplicity t p)) =
    rootMultiplicity t p - 1
[PROOFSTEP]
simp only [derivative_pow, derivative_mul, derivative_sub, derivative_X, derivative_C, sub_zero, mul_one]
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
⊢ rootMultiplicity t
      (↑derivative (p /ₘ (X - ↑C t) ^ rootMultiplicity t p) * (X - ↑C t) ^ rootMultiplicity t p +
        p /ₘ (X - ↑C t) ^ rootMultiplicity t p *
          (↑C ↑(rootMultiplicity t p) * (X - ↑C t) ^ (rootMultiplicity t p - 1))) =
    rootMultiplicity t p - 1
[PROOFSTEP]
set n := p.rootMultiplicity t - 1
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
⊢ rootMultiplicity t
      (↑derivative (p /ₘ (X - ↑C t) ^ rootMultiplicity t p) * (X - ↑C t) ^ rootMultiplicity t p +
        p /ₘ (X - ↑C t) ^ rootMultiplicity t p * (↑C ↑(rootMultiplicity t p) * (X - ↑C t) ^ n)) =
    n
[PROOFSTEP]
have hn : n + 1 = _ := tsub_add_cancel_of_le ((rootMultiplicity_pos hp).mpr hpt)
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
⊢ rootMultiplicity t
      (↑derivative (p /ₘ (X - ↑C t) ^ rootMultiplicity t p) * (X - ↑C t) ^ rootMultiplicity t p +
        p /ₘ (X - ↑C t) ^ rootMultiplicity t p * (↑C ↑(rootMultiplicity t p) * (X - ↑C t) ^ n)) =
    n
[PROOFSTEP]
rw [← hn]
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
⊢ rootMultiplicity t
      (↑derivative (p /ₘ (X - ↑C t) ^ (n + 1)) * (X - ↑C t) ^ (n + 1) +
        p /ₘ (X - ↑C t) ^ (n + 1) * (↑C ↑(n + 1) * (X - ↑C t) ^ n)) =
    n
[PROOFSTEP]
set q := p /ₘ (X - C t) ^ (n + 1) with _hq
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ rootMultiplicity t (↑derivative q * (X - ↑C t) ^ (n + 1) + q * (↑C ↑(n + 1) * (X - ↑C t) ^ n)) = n
[PROOFSTEP]
convert_to rootMultiplicity t ((X - C t) ^ n * (derivative q * (X - C t) + q * C ↑(n + 1))) = n
[GOAL]
case h.e'_2
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ rootMultiplicity t (↑derivative q * (X - ↑C t) ^ (n + 1) + q * (↑C ↑(n + 1) * (X - ↑C t) ^ n)) =
    rootMultiplicity t ((X - ↑C t) ^ n * (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)))
[PROOFSTEP]
congr
[GOAL]
case h.e'_2.e_p
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ ↑derivative q * (X - ↑C t) ^ (n + 1) + q * (↑C ↑(n + 1) * (X - ↑C t) ^ n) =
    (X - ↑C t) ^ n * (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1))
[PROOFSTEP]
rw [mul_add, mul_left_comm <| (X - C t) ^ n, ← pow_succ']
[GOAL]
case h.e'_2.e_p
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ ↑derivative q * (X - ↑C t) ^ (n + 1) + q * (↑C ↑(n + 1) * (X - ↑C t) ^ n) =
    ↑derivative q * (X - ↑C t) ^ (n + 1) + (X - ↑C t) ^ n * (q * ↑C ↑(n + 1))
[PROOFSTEP]
congr 1
[GOAL]
case h.e'_2.e_p.e_a
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ q * (↑C ↑(n + 1) * (X - ↑C t) ^ n) = (X - ↑C t) ^ n * (q * ↑C ↑(n + 1))
[PROOFSTEP]
rw [mul_left_comm <| (X - C t) ^ n, mul_comm <| (X - C t) ^ n]
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ rootMultiplicity t ((X - ↑C t) ^ n * (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1))) = n
[PROOFSTEP]
have h : eval t (derivative q * (X - C t) + q * C (R := R) ↑(n + 1)) ≠ 0 :=
  by
  suffices eval t q * ↑(n + 1) ≠ 0 by simpa
  refine' mul_ne_zero _ (Nat.cast_ne_zero.mpr n.succ_ne_zero)
  convert eval_divByMonic_pow_rootMultiplicity_ne_zero t hp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ eval t (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)) ≠ 0
[PROOFSTEP]
suffices eval t q * ↑(n + 1) ≠ 0 by simpa
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
this : eval t q * ↑(n + 1) ≠ 0
⊢ eval t (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)) ≠ 0
[PROOFSTEP]
simpa
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ eval t q * ↑(n + 1) ≠ 0
[PROOFSTEP]
refine' mul_ne_zero _ (Nat.cast_ne_zero.mpr n.succ_ne_zero)
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
⊢ eval t q ≠ 0
[PROOFSTEP]
convert eval_divByMonic_pow_rootMultiplicity_ne_zero t hp
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
h : eval t (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)) ≠ 0
⊢ rootMultiplicity t ((X - ↑C t) ^ n * (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1))) = n
[PROOFSTEP]
rw [rootMultiplicity_mul, rootMultiplicity_X_sub_C_pow, rootMultiplicity_eq_zero h, add_zero]
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
h : eval t (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)) ≠ 0
⊢ (X - ↑C t) ^ n * (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)) ≠ 0
[PROOFSTEP]
refine' mul_ne_zero (pow_ne_zero n <| X_sub_C_ne_zero t) _
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
h : eval t (↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1)) ≠ 0
⊢ ↑derivative q * (X - ↑C t) + q * ↑C ↑(n + 1) ≠ 0
[PROOFSTEP]
contrapose! h
[GOAL]
case inr
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
hpt : IsRoot p t
hp : p ≠ 0
n : ℕ := rootMultiplicity t p - 1
hn : n + 1 = rootMultiplicity t p
q : R[X] := p /ₘ (X - ↑C t) ^ (n + 1)
_hq : q = p /ₘ (X - ↑C t) ^ (n + 1)
h :
  ↑derivative (p /ₘ (X - ↑C t) ^ (n + 1)) * (X - ↑C t) +
      p /ₘ (X - ↑C t) ^ (n + 1) * ↑C ↑(rootMultiplicity t p - 1 + 1) =
    0
⊢ eval t
      (↑derivative (p /ₘ (X - ↑C t) ^ (n + 1)) * (X - ↑C t) +
        p /ₘ (X - ↑C t) ^ (n + 1) * ↑C ↑(rootMultiplicity t p - 1 + 1)) =
    0
[PROOFSTEP]
rw [h, eval_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
⊢ rootMultiplicity t p - 1 ≤ rootMultiplicity t (↑derivative p)
[PROOFSTEP]
by_cases p.IsRoot t
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
⊢ rootMultiplicity t p - 1 ≤ rootMultiplicity t (↑derivative p)
[PROOFSTEP]
by_cases p.IsRoot t
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
h : IsRoot p t
⊢ rootMultiplicity t p - 1 ≤ rootMultiplicity t (↑derivative p)
[PROOFSTEP]
exact (derivative_rootMultiplicity_of_root h).symm.le
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
h : ¬IsRoot p t
⊢ rootMultiplicity t p - 1 ≤ rootMultiplicity t (↑derivative p)
[PROOFSTEP]
rw [rootMultiplicity_eq_zero h, zero_tsub]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CharZero R
p : R[X]
t : R
h : ¬IsRoot p t
⊢ 0 ≤ rootMultiplicity t (↑derivative p)
[PROOFSTEP]
exact zero_le _
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
p : R[X]
⊢ ↑C ↑(normUnit (leadingCoeff p)) * ↑C ↑(normUnit (leadingCoeff p))⁻¹ = 1
[PROOFSTEP]
rw [← RingHom.map_mul, Units.mul_inv, C_1]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
p : R[X]
⊢ ↑C ↑(normUnit (leadingCoeff p))⁻¹ * ↑C ↑(normUnit (leadingCoeff p)) = 1
[PROOFSTEP]
rw [← RingHom.map_mul, Units.inv_mul, C_1]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
⊢ ↑((fun p =>
          { val := ↑C ↑(normUnit (leadingCoeff p)), inv := ↑C ↑(normUnit (leadingCoeff p))⁻¹,
            val_inv := (_ : ↑C ↑(normUnit (leadingCoeff p)) * ↑C ↑(normUnit (leadingCoeff p))⁻¹ = 1),
            inv_val := (_ : ↑C ↑(normUnit (leadingCoeff p))⁻¹ * ↑C ↑(normUnit (leadingCoeff p)) = 1) })
        0) =
    ↑1
[PROOFSTEP]
simp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
a✝ b✝ : R[X]
hp0 : a✝ ≠ 0
hq0 : b✝ ≠ 0
⊢ ↑((fun p =>
          { val := ↑C ↑(normUnit (leadingCoeff p)), inv := ↑C ↑(normUnit (leadingCoeff p))⁻¹,
            val_inv := (_ : ↑C ↑(normUnit (leadingCoeff p)) * ↑C ↑(normUnit (leadingCoeff p))⁻¹ = 1),
            inv_val := (_ : ↑C ↑(normUnit (leadingCoeff p))⁻¹ * ↑C ↑(normUnit (leadingCoeff p)) = 1) })
        (a✝ * b✝)) =
    ↑((fun p =>
            { val := ↑C ↑(normUnit (leadingCoeff p)), inv := ↑C ↑(normUnit (leadingCoeff p))⁻¹,
              val_inv := (_ : ↑C ↑(normUnit (leadingCoeff p)) * ↑C ↑(normUnit (leadingCoeff p))⁻¹ = 1),
              inv_val := (_ : ↑C ↑(normUnit (leadingCoeff p))⁻¹ * ↑C ↑(normUnit (leadingCoeff p)) = 1) })
          a✝ *
        (fun p =>
            { val := ↑C ↑(normUnit (leadingCoeff p)), inv := ↑C ↑(normUnit (leadingCoeff p))⁻¹,
              val_inv := (_ : ↑C ↑(normUnit (leadingCoeff p)) * ↑C ↑(normUnit (leadingCoeff p))⁻¹ = 1),
              inv_val := (_ : ↑C ↑(normUnit (leadingCoeff p))⁻¹ * ↑C ↑(normUnit (leadingCoeff p)) = 1) })
          b✝)
[PROOFSTEP]
dsimp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
a✝ b✝ : R[X]
hp0 : a✝ ≠ 0
hq0 : b✝ ≠ 0
⊢ ↑C ↑(normUnit (leadingCoeff (a✝ * b✝))) = ↑C ↑(normUnit (leadingCoeff a✝)) * ↑C ↑(normUnit (leadingCoeff b✝))
[PROOFSTEP]
rw [Ne.def, ← leadingCoeff_eq_zero] at *
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
a✝ b✝ : R[X]
hp0 : ¬leadingCoeff a✝ = 0
hq0 : ¬leadingCoeff b✝ = 0
⊢ ↑C ↑(normUnit (leadingCoeff (a✝ * b✝))) = ↑C ↑(normUnit (leadingCoeff a✝)) * ↑C ↑(normUnit (leadingCoeff b✝))
[PROOFSTEP]
rw [leadingCoeff_mul, normUnit_mul hp0 hq0, Units.val_mul, C_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
u : R[X]ˣ
⊢ ↑((fun p =>
          { val := ↑C ↑(normUnit (leadingCoeff p)), inv := ↑C ↑(normUnit (leadingCoeff p))⁻¹,
            val_inv := (_ : ↑C ↑(normUnit (leadingCoeff p)) * ↑C ↑(normUnit (leadingCoeff p))⁻¹ = 1),
            inv_val := (_ : ↑C ↑(normUnit (leadingCoeff p))⁻¹ * ↑C ↑(normUnit (leadingCoeff p)) = 1) })
        ↑u) =
    ↑u⁻¹
[PROOFSTEP]
dsimp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
u : R[X]ˣ
⊢ ↑C ↑(normUnit (leadingCoeff ↑u)) = ↑u⁻¹
[PROOFSTEP]
rw [← mul_one u⁻¹, Units.val_mul, Units.eq_inv_mul_iff_mul_eq]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
u : R[X]ˣ
⊢ ↑u * ↑C ↑(normUnit (leadingCoeff ↑u)) = ↑1
[PROOFSTEP]
rcases Polynomial.isUnit_iff.1 ⟨u, rfl⟩ with ⟨_, ⟨w, rfl⟩, h2⟩
[GOAL]
case intro.intro.intro
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
u : R[X]ˣ
w : Rˣ
h2 : ↑C ↑w = ↑u
⊢ ↑u * ↑C ↑(normUnit (leadingCoeff ↑u)) = ↑1
[PROOFSTEP]
rw [← h2, leadingCoeff_C, normUnit_coe_units, ← C_mul, Units.mul_inv, C_1]
[GOAL]
case intro.intro.intro
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
u : R[X]ˣ
w : Rˣ
h2 : ↑C ↑w = ↑u
⊢ 1 = ↑1
[PROOFSTEP]
rfl
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
p : R[X]
⊢ ↑(normUnit p) = ↑C ↑(normUnit (leadingCoeff p))
[PROOFSTEP]
simp [normUnit]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
p : R[X]
⊢ leadingCoeff (↑normalize p) = ↑normalize (leadingCoeff p)
[PROOFSTEP]
simp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
p : R[X]
hp : Monic p
⊢ ↑normalize p = p
[PROOFSTEP]
simp only [Polynomial.coe_normUnit, normalize_apply, hp.leadingCoeff, normUnit_one, Units.val_one, Polynomial.C.map_one,
  mul_one]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizationMonoid R
p : R[X]
⊢ roots (↑normalize p) = roots p
[PROOFSTEP]
rw [normalize_apply, mul_comm, coe_normUnit, roots_C_mul _ (normUnit (leadingCoeff p)).ne_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : DivisionRing R
p q : R[X]
hp0 : p ≠ 0
hp : ¬IsUnit p
h : 0 ≥ degree p
⊢ False
[PROOFSTEP]
rw [eq_C_of_degree_le_zero h] at hp0 hp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : DivisionRing R
p q : R[X]
hp0 : ↑C (coeff p 0) ≠ 0
hp : ¬IsUnit (↑C (coeff p 0))
h : 0 ≥ degree p
⊢ False
[PROOFSTEP]
exact hp (IsUnit.map C (IsUnit.mk0 (coeff p 0) (mt C_inj.2 (by simpa using hp0))))
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : DivisionRing R
p q : R[X]
hp0 : ↑C (coeff p 0) ≠ 0
hp : ¬IsUnit (↑C (coeff p 0))
h : 0 ≥ degree p
⊢ ¬↑C (coeff p 0) = ↑C 0
[PROOFSTEP]
simpa using hp0
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : DivisionRing R
p q : R[X]
h : p ≠ 0
⊢ Monic (p * ↑C (leadingCoeff p)⁻¹)
[PROOFSTEP]
rw [Monic, leadingCoeff_mul, leadingCoeff_C, mul_inv_cancel (show leadingCoeff p ≠ 0 from mt leadingCoeff_eq_zero.1 h)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : DivisionRing R
p✝ q p : R[X]
h : q ≠ 0
⊢ degree (p * ↑C (leadingCoeff q)⁻¹) = degree p
[PROOFSTEP]
have h₁ : (leadingCoeff q)⁻¹ ≠ 0 := inv_ne_zero (mt leadingCoeff_eq_zero.1 h)
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : DivisionRing R
p✝ q p : R[X]
h : q ≠ 0
h₁ : (leadingCoeff q)⁻¹ ≠ 0
⊢ degree (p * ↑C (leadingCoeff q)⁻¹) = degree p
[PROOFSTEP]
rw [degree_mul, degree_C h₁, add_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : DivisionRing R
p q : R[X]
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
⊢ map f p = 0 ↔ p = 0
[PROOFSTEP]
simp only [Polynomial.ext_iff]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : DivisionRing R
p q : R[X]
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
⊢ (∀ (n : ℕ), coeff (map f p) n = coeff 0 n) ↔ ∀ (n : ℕ), coeff p n = coeff 0 n
[PROOFSTEP]
congr!
[GOAL]
case a.h.a
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : DivisionRing R
p q : R[X]
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
a✝ : ℕ
⊢ coeff (map f p) a✝ = coeff 0 a✝ ↔ coeff p a✝ = coeff 0 a✝
[PROOFSTEP]
simp [map_eq_zero, coeff_map, coeff_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : DivisionRing R
p q : R[X]
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
⊢ leadingCoeff (map f p) = ↑f (leadingCoeff p)
[PROOFSTEP]
simp only [← coeff_natDegree, coeff_map f, natDegree_map]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : DivisionRing R
p✝ q : R[X]
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
p : R[X]
⊢ Monic (map f p) ↔ Monic p
[PROOFSTEP]
rw [Monic, leadingCoeff_map, ← f.map_one, Function.Injective.eq_iff f.injective, Monic]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
⊢ degree p ≤ 0
[PROOFSTEP]
simp [*, le_refl]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 = 0
⊢ False
[PROOFSTEP]
rw [eq_C_of_degree_le_zero this, hc] at h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree (↑C 0) = 0
this : degree p ≤ 0
hc : coeff p 0 = 0
⊢ False
[PROOFSTEP]
simp at h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
⊢ 1 = p * ↑C (coeff p 0)⁻¹
[PROOFSTEP]
conv in p => rw [eq_C_of_degree_le_zero this]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
| p
[PROOFSTEP]
rw [eq_C_of_degree_le_zero this]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
| p
[PROOFSTEP]
rw [eq_C_of_degree_le_zero this]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
| p
[PROOFSTEP]
rw [eq_C_of_degree_le_zero this]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
⊢ 1 = ↑C (coeff p 0) * ↑C (coeff p 0)⁻¹
[PROOFSTEP]
rw [← C_mul, _root_.mul_inv_cancel hc, C_1]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
⊢ q * div p q + mod p q = p
[PROOFSTEP]
by_cases h : q = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : q = 0
⊢ q * div p q + mod p q = p
[PROOFSTEP]
simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
⊢ q * div p q + mod p q = p
[PROOFSTEP]
conv =>
  rhs
  rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| q * div p q + mod p q = p
[PROOFSTEP]
  rhs
  rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| q * div p q + mod p q = p
[PROOFSTEP]
  rhs
  rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| q * div p q + mod p q = p
[PROOFSTEP]
rhs
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| p
[PROOFSTEP]
rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
⊢ q * div p q + mod p q =
    p %ₘ (q * ↑C (leadingCoeff q)⁻¹) + q * ↑C (leadingCoeff q)⁻¹ * (p /ₘ (q * ↑C (leadingCoeff q)⁻¹))
[PROOFSTEP]
rw [div, mod, add_comm, mul_assoc]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : q ≠ 0
⊢ degree (mod p q) < degree q
[PROOFSTEP]
rw [← degree_mul_leadingCoeff_inv q hq]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : q ≠ 0
⊢ degree (mod p q) < degree (q * ↑C (leadingCoeff q)⁻¹)
[PROOFSTEP]
exact degree_modByMonic_lt p (monic_mul_leadingCoeff_inv hq)
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : Monic q
⊢ p %ₘ q = p %ₘ (q * ↑C (leadingCoeff q)⁻¹)
[PROOFSTEP]
simp only [Monic.def.1 hq, inv_one, mul_one, C_1]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : Monic q
⊢ p /ₘ q = ↑C (leadingCoeff q)⁻¹ * (p /ₘ (q * ↑C (leadingCoeff q)⁻¹))
[PROOFSTEP]
simp only [Monic.def.1 hq, inv_one, C_1, one_mul, mul_one]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
src✝¹ : CommRing R[X] := commRing
src✝ : Nontrivial R[X] := nontrivial
⊢ ∀ (a : R[X]), (fun x x_1 => x / x_1) a 0 = 0
[PROOFSTEP]
simp [div_def]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ p % q = p
[PROOFSTEP]
classical
have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p := not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
unfold divModByMonicAux
dsimp
simp only [this, false_and_iff, if_false]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ p % q = p
[PROOFSTEP]
have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p := not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ degree (q * ↑C (leadingCoeff q)⁻¹) > degree p
[PROOFSTEP]
rwa [degree_mul_leadingCoeff_inv q hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p
⊢ p % q = p
[PROOFSTEP]
rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p
⊢ (divModByMonicAux p (_ : Monic (q * ↑C (leadingCoeff q)⁻¹))).snd = p
[PROOFSTEP]
unfold divModByMonicAux
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p
⊢ (if h : degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p ∧ p ≠ 0 then
        let z := ↑C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * ↑C (leadingCoeff q)⁻¹));
        let_fun _wf :=
          (_ :
            degree
                (p -
                  ↑C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * ↑C (leadingCoeff q)⁻¹)) *
                    (q * ↑C (leadingCoeff q)⁻¹)) <
              degree p);
        let dm := divModByMonicAux (p - z * (q * ↑C (leadingCoeff q)⁻¹)) (_ : Monic (q * ↑C (leadingCoeff q)⁻¹));
        (z + dm.fst, dm.snd)
      else (0, p)).snd =
    p
[PROOFSTEP]
dsimp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p
⊢ (if degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p ∧ ¬p = 0 then
        (↑C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * ↑C (leadingCoeff q)⁻¹)) +
            (divModByMonicAux
                (p -
                  ↑C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * ↑C (leadingCoeff q)⁻¹)) *
                    (q * ↑C (leadingCoeff q)⁻¹))
                (_ : Monic (q * ↑C (leadingCoeff q)⁻¹))).fst,
          (divModByMonicAux
              (p -
                ↑C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * ↑C (leadingCoeff q)⁻¹)) *
                  (q * ↑C (leadingCoeff q)⁻¹))
              (_ : Monic (q * ↑C (leadingCoeff q)⁻¹))).snd)
      else (0, p)).snd =
    p
[PROOFSTEP]
simp only [this, false_and_iff, if_false]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : p / q = 0
⊢ degree p < degree q
[PROOFSTEP]
have := EuclideanDomain.div_add_mod p q
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : p / q = 0
this : q * (p / q) + p % q = p
⊢ degree p < degree q
[PROOFSTEP]
rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ p / q = 0
[PROOFSTEP]
have hlt : degree p < degree (q * C (leadingCoeff q)⁻¹) := by rwa [degree_mul_leadingCoeff_inv q hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ degree p < degree (q * ↑C (leadingCoeff q)⁻¹)
[PROOFSTEP]
rwa [degree_mul_leadingCoeff_inv q hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
hlt : degree p < degree (q * ↑C (leadingCoeff q)⁻¹)
⊢ p / q = 0
[PROOFSTEP]
have hm : Monic (q * C (leadingCoeff q)⁻¹) := monic_mul_leadingCoeff_inv hq0
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
hlt : degree p < degree (q * ↑C (leadingCoeff q)⁻¹)
hm : Monic (q * ↑C (leadingCoeff q)⁻¹)
⊢ p / q = 0
[PROOFSTEP]
rw [div_def, (divByMonic_eq_zero_iff hm).2 hlt, mul_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
⊢ degree q + degree (p / q) = degree p
[PROOFSTEP]
have : degree (p % q) < degree (q * (p / q)) :=
  calc
    degree (p % q) < degree q := EuclideanDomain.mod_lt _ hq0
    _ ≤ _ := degree_le_mul_left _ (mt (div_eq_zero_iff hq0).1 (not_lt_of_ge hpq))
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
this : degree (p % q) < degree (q * (p / q))
⊢ degree q + degree (p / q) = degree p
[PROOFSTEP]
conv_rhs => rw [← EuclideanDomain.div_add_mod p q, degree_add_eq_left_of_degree_lt this, degree_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
this : degree (p % q) < degree (q * (p / q))
| degree p
[PROOFSTEP]
rw [← EuclideanDomain.div_add_mod p q, degree_add_eq_left_of_degree_lt this, degree_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
this : degree (p % q) < degree (q * (p / q))
| degree p
[PROOFSTEP]
rw [← EuclideanDomain.div_add_mod p q, degree_add_eq_left_of_degree_lt this, degree_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
this : degree (p % q) < degree (q * (p / q))
| degree p
[PROOFSTEP]
rw [← EuclideanDomain.div_add_mod p q, degree_add_eq_left_of_degree_lt this, degree_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
⊢ degree (p / q) ≤ degree p
[PROOFSTEP]
by_cases hq : q = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
hq : q = 0
⊢ degree (p / q) ≤ degree p
[PROOFSTEP]
simp [hq]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
hq : ¬q = 0
⊢ degree (p / q) ≤ degree p
[PROOFSTEP]
rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
hq : ¬q = 0
⊢ degree (p /ₘ (q * ↑C (leadingCoeff q)⁻¹)) ≤ degree p
[PROOFSTEP]
exact degree_divByMonic_le _ _
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
⊢ degree (p / q) < degree p
[PROOFSTEP]
have hq0 : q ≠ 0 := fun hq0 => by simp [hq0] at hq
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q = 0
⊢ False
[PROOFSTEP]
simp [hq0] at hq
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ degree (p / q) < degree p
[PROOFSTEP]
rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ degree (p /ₘ (q * ↑C (leadingCoeff q)⁻¹)) < degree p
[PROOFSTEP]
exact degree_divByMonic_lt _ (monic_mul_leadingCoeff_inv hq0) hp (by rw [degree_mul_leadingCoeff_inv _ hq0]; exact hq)
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ 0 < degree (q * ↑C (leadingCoeff q)⁻¹)
[PROOFSTEP]
rw [degree_mul_leadingCoeff_inv _ hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ 0 < degree q
[PROOFSTEP]
exact hq
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ IsUnit (map f p) ↔ IsUnit p
[PROOFSTEP]
simp_rw [isUnit_iff_degree_eq_zero, degree_map]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ map f (p / q) = map f p / map f q
[PROOFSTEP]
if hq0 : q = 0 then simp [hq0]
else
  rw [div_def, div_def, Polynomial.map_mul, map_divByMonic f (monic_mul_leadingCoeff_inv hq0), Polynomial.map_mul,
    map_C, leadingCoeff_map, map_inv₀]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : q = 0
⊢ map f (p / q) = map f p / map f q
[PROOFSTEP]
simp [hq0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : ¬q = 0
⊢ map f (p / q) = map f p / map f q
[PROOFSTEP]
rw [div_def, div_def, Polynomial.map_mul, map_divByMonic f (monic_mul_leadingCoeff_inv hq0), Polynomial.map_mul, map_C,
  leadingCoeff_map, map_inv₀]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ map f (p % q) = map f p % map f q
[PROOFSTEP]
by_cases hq0 : q = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : q = 0
⊢ map f (p % q) = map f p % map f q
[PROOFSTEP]
simp [hq0]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : ¬q = 0
⊢ map f (p % q) = map f p % map f q
[PROOFSTEP]
rw [mod_def, mod_def, leadingCoeff_map f, ← map_inv₀ f, ← map_C f, ← Polynomial.map_mul f,
  map_modByMonic f (monic_mul_leadingCoeff_inv hq0)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : Field k
inst✝¹ : DecidableEq R
inst✝ : DecidableEq k
f : R →+* k
x : R[X]
⊢ EuclideanDomain.gcd (map f 0) (map f x) = map f (EuclideanDomain.gcd 0 x)
[PROOFSTEP]
simp_rw [Polynomial.map_zero, EuclideanDomain.gcd_zero_left]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : Field k
inst✝¹ : DecidableEq R
inst✝ : DecidableEq k
f : R →+* k
x y : R[X]
x✝ : x ≠ 0
ih : EuclideanDomain.gcd (map f (y % x)) (map f x) = map f (EuclideanDomain.gcd (y % x) x)
⊢ EuclideanDomain.gcd (map f x) (map f y) = map f (EuclideanDomain.gcd x y)
[PROOFSTEP]
rw [gcd_val, ← map_mod, ih, ← gcd_val]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : Field R
p q : R[X]
inst✝¹ : CommSemiring k
inst✝ : DecidableEq R
ϕ : R →+* k
f g : R[X]
α : k
hf : eval₂ ϕ α f = 0
hg : eval₂ ϕ α g = 0
⊢ eval₂ ϕ α (EuclideanDomain.gcd f g) = 0
[PROOFSTEP]
rw [EuclideanDomain.gcd_eq_gcd_ab f g, Polynomial.eval₂_add, Polynomial.eval₂_mul, Polynomial.eval₂_mul, hf, hg,
  zero_mul, zero_mul, zero_add]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : Field R
p q : R[X]
inst✝¹ : CommSemiring k
inst✝ : DecidableEq R
ϕ : R →+* k
f g : R[X]
α : k
hα : eval₂ ϕ α (EuclideanDomain.gcd f g) = 0
⊢ eval₂ ϕ α f = 0
[PROOFSTEP]
cases' EuclideanDomain.gcd_dvd_left f g with p hp
[GOAL]
case intro
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : Field R
p✝ q : R[X]
inst✝¹ : CommSemiring k
inst✝ : DecidableEq R
ϕ : R →+* k
f g : R[X]
α : k
hα : eval₂ ϕ α (EuclideanDomain.gcd f g) = 0
p : R[X]
hp : f = EuclideanDomain.gcd f g * p
⊢ eval₂ ϕ α f = 0
[PROOFSTEP]
rw [hp, Polynomial.eval₂_mul, hα, zero_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : Field R
p q : R[X]
inst✝¹ : CommSemiring k
inst✝ : DecidableEq R
ϕ : R →+* k
f g : R[X]
α : k
hα : eval₂ ϕ α (EuclideanDomain.gcd f g) = 0
⊢ eval₂ ϕ α g = 0
[PROOFSTEP]
cases' EuclideanDomain.gcd_dvd_right f g with p hp
[GOAL]
case intro
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : Field R
p✝ q : R[X]
inst✝¹ : CommSemiring k
inst✝ : DecidableEq R
ϕ : R →+* k
f g : R[X]
α : k
hα : eval₂ ϕ α (EuclideanDomain.gcd f g) = 0
p : R[X]
hp : g = EuclideanDomain.gcd f g * p
⊢ eval₂ ϕ α g = 0
[PROOFSTEP]
rw [hp, Polynomial.eval₂_mul, hα, zero_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ IsCoprime (map f p) (map f q) ↔ IsCoprime p q
[PROOFSTEP]
classical rw [← EuclideanDomain.gcd_isUnit_iff, ← EuclideanDomain.gcd_isUnit_iff, gcd_map, isUnit_map]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ IsCoprime (map f p) (map f q) ↔ IsCoprime p q
[PROOFSTEP]
rw [← EuclideanDomain.gcd_isUnit_iff, ← EuclideanDomain.gcd_isUnit_iff, gcd_map, isUnit_map]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : Field R
p q : R[X]
inst✝¹ : CommRing k
inst✝ : IsDomain k
f : R →+* k
x : k
hp : p ≠ 0
⊢ x ∈ roots (map f p) ↔ eval₂ f x p = 0
[PROOFSTEP]
rw [mem_roots (map_ne_zero hp), IsRoot, Polynomial.eval_map]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n✝ : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
n : ℕ
hn : n ≠ 0
a : R
ha : a ≠ 0
⊢ rootSet (↑(monomial n) a) S = {0}
[PROOFSTEP]
classical rw [rootSet, map_monomial, roots_monomial ((_root_.map_ne_zero (algebraMap R S)).2 ha),
  Multiset.toFinset_nsmul _ _ hn, Multiset.toFinset_singleton, Finset.coe_singleton]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n✝ : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
n : ℕ
hn : n ≠ 0
a : R
ha : a ≠ 0
⊢ rootSet (↑(monomial n) a) S = {0}
[PROOFSTEP]
rw [rootSet, map_monomial, roots_monomial ((_root_.map_ne_zero (algebraMap R S)).2 ha), Multiset.toFinset_nsmul _ _ hn,
  Multiset.toFinset_singleton, Finset.coe_singleton]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n✝ : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
n : ℕ
hn : n ≠ 0
a : R
ha : a ≠ 0
⊢ rootSet (↑C a * X ^ n) S = {0}
[PROOFSTEP]
rw [C_mul_X_pow_eq_monomial, rootSet_monomial hn ha]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
n : ℕ
hn : n ≠ 0
⊢ rootSet (X ^ n) S = {0}
[PROOFSTEP]
rw [← one_mul (X ^ n : R[X]), ← C_1, rootSet_C_mul_X_pow hn]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
n : ℕ
hn : n ≠ 0
⊢ 1 ≠ 0
[PROOFSTEP]
exact one_ne_zero
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
ι : Type u_1
f : ι → R[X]
s : Finset ι
h : Finset.prod s f ≠ 0
⊢ rootSet (Finset.prod s f) S = ⋃ (i : ι) (_ : i ∈ s), rootSet (f i) S
[PROOFSTEP]
classical
simp only [rootSet, ← Finset.mem_coe]
rw [Polynomial.map_prod, roots_prod, Finset.bind_toFinset, s.val_toFinset, Finset.coe_biUnion]
rwa [← Polynomial.map_prod, Ne, map_eq_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
ι : Type u_1
f : ι → R[X]
s : Finset ι
h : Finset.prod s f ≠ 0
⊢ rootSet (Finset.prod s f) S = ⋃ (i : ι) (_ : i ∈ s), rootSet (f i) S
[PROOFSTEP]
simp only [rootSet, ← Finset.mem_coe]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
ι : Type u_1
f : ι → R[X]
s : Finset ι
h : Finset.prod s f ≠ 0
⊢ ↑(Multiset.toFinset (roots (map (algebraMap R S) (Finset.prod s f)))) =
    ⋃ (i : ι) (_ : i ∈ ↑s), ↑(Multiset.toFinset (roots (map (algebraMap R S) (f i))))
[PROOFSTEP]
rw [Polynomial.map_prod, roots_prod, Finset.bind_toFinset, s.val_toFinset, Finset.coe_biUnion]
[GOAL]
case a
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Field R
p q : R[X]
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra R S
ι : Type u_1
f : ι → R[X]
s : Finset ι
h : Finset.prod s f ≠ 0
⊢ ∏ i in s, map (algebraMap R S) (f i) ≠ 0
[PROOFSTEP]
rwa [← Polynomial.map_prod, Ne, map_eq_zero]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
⊢ IsRoot p (-(coeff p 0 / coeff p 1))
[PROOFSTEP]
have : p.coeff 1 ≠ 0 := by
  have h' := natDegree_eq_of_degree_eq_some h
  change natDegree p = 1 at h' ; rw [← h']
  exact mt leadingCoeff_eq_zero.1 fun h0 => by simp [h0] at h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
⊢ coeff p 1 ≠ 0
[PROOFSTEP]
have h' := natDegree_eq_of_degree_eq_some h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
h' : natDegree p = One.one
⊢ coeff p 1 ≠ 0
[PROOFSTEP]
change natDegree p = 1 at h'
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
h' : natDegree p = 1
⊢ coeff p 1 ≠ 0
[PROOFSTEP]
rw [← h']
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
h' : natDegree p = 1
⊢ coeff p (natDegree p) ≠ 0
[PROOFSTEP]
exact mt leadingCoeff_eq_zero.1 fun h0 => by simp [h0] at h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
h' : natDegree p = 1
h0 : p = 0
⊢ False
[PROOFSTEP]
simp [h0] at h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
this : coeff p 1 ≠ 0
⊢ IsRoot p (-(coeff p 0 / coeff p 1))
[PROOFSTEP]
conv in p => rw [eq_X_add_C_of_degree_le_one (show degree p ≤ 1 by rw [h])]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
this : coeff p 1 ≠ 0
| p
[PROOFSTEP]
rw [eq_X_add_C_of_degree_le_one (show degree p ≤ 1 by rw [h])]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
this : coeff p 1 ≠ 0
| p
[PROOFSTEP]
rw [eq_X_add_C_of_degree_le_one (show degree p ≤ 1 by rw [h])]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
this : coeff p 1 ≠ 0
| p
[PROOFSTEP]
rw [eq_X_add_C_of_degree_le_one (show degree p ≤ 1 by rw [h])]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
this : coeff p 1 ≠ 0
⊢ degree p ≤ 1
[PROOFSTEP]
rw [h]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 1
this : coeff p 1 ≠ 0
⊢ IsRoot (↑C (coeff p 1) * X + ↑C (coeff p 0)) (-(coeff p 0 / coeff p 1))
[PROOFSTEP]
simp [IsRoot, mul_div_cancel' _ this]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Field R
p q : R[X]
u : R[X]ˣ
n : ℕ
⊢ (coeff (↑u) n)⁻¹ = coeff (↑u⁻¹) n
[PROOFSTEP]
rw [eq_C_of_degree_eq_zero (degree_coe_units u), eq_C_of_degree_eq_zero (degree_coe_units u⁻¹), coeff_C, coeff_C,
  inv_eq_one_div]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Field R
p q : R[X]
u : R[X]ˣ
n : ℕ
⊢ (1 / if n = 0 then coeff (↑u) 0 else 0) = if n = 0 then coeff (↑u⁻¹) 0 else 0
[PROOFSTEP]
split_ifs
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Field R
p q : R[X]
u : R[X]ˣ
n : ℕ
h✝ : n = 0
⊢ 1 / coeff (↑u) 0 = coeff (↑u⁻¹) 0
[PROOFSTEP]
rw [div_eq_iff_mul_eq (coeff_coe_units_zero_ne_zero u), coeff_zero_eq_eval_zero, coeff_zero_eq_eval_zero, ← eval_mul, ←
  Units.val_mul, inv_mul_self]
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Field R
p q : R[X]
u : R[X]ˣ
n : ℕ
h✝ : n = 0
⊢ eval 0 ↑1 = 1
[PROOFSTEP]
simp
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Field R
p q : R[X]
u : R[X]ˣ
n : ℕ
h✝ : ¬n = 0
⊢ 1 / 0 = 0
[PROOFSTEP]
simp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
hp0 : p ≠ 0
⊢ Monic (↑normalize p)
[PROOFSTEP]
rw [Ne.def, ← leadingCoeff_eq_zero, ← Ne.def, ← isUnit_iff_ne_zero] at hp0
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
hp0 : IsUnit (leadingCoeff p)
⊢ Monic (↑normalize p)
[PROOFSTEP]
rw [Monic, leadingCoeff_normalize, normalize_eq_one]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
hp0 : IsUnit (leadingCoeff p)
⊢ IsUnit (leadingCoeff p)
[PROOFSTEP]
apply hp0
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hpq : degree q ≤ degree p
⊢ leadingCoeff (p / q) = leadingCoeff p / leadingCoeff q
[PROOFSTEP]
by_cases hq : q = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hpq : degree q ≤ degree p
hq : q = 0
⊢ leadingCoeff (p / q) = leadingCoeff p / leadingCoeff q
[PROOFSTEP]
simp [hq]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hpq : degree q ≤ degree p
hq : ¬q = 0
⊢ leadingCoeff (p / q) = leadingCoeff p / leadingCoeff q
[PROOFSTEP]
rw [div_def, leadingCoeff_mul, leadingCoeff_C, leadingCoeff_divByMonic_of_monic (monic_mul_leadingCoeff_inv hq) _,
  mul_comm, div_eq_mul_inv]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hpq : degree q ≤ degree p
hq : ¬q = 0
⊢ degree (q * ↑C (leadingCoeff q)⁻¹) ≤ degree p
[PROOFSTEP]
rwa [degree_mul_leadingCoeff_inv q hq]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
⊢ p / (↑C a * q) = ↑C a⁻¹ * (p / q)
[PROOFSTEP]
by_cases ha : a = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
ha : a = 0
⊢ p / (↑C a * q) = ↑C a⁻¹ * (p / q)
[PROOFSTEP]
simp [ha]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
ha : ¬a = 0
⊢ p / (↑C a * q) = ↑C a⁻¹ * (p / q)
[PROOFSTEP]
simp only [div_def, leadingCoeff_mul, mul_inv, leadingCoeff_C, C.map_mul, mul_assoc]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
ha : ¬a = 0
⊢ ↑C a⁻¹ * (↑C (leadingCoeff q)⁻¹ * (p /ₘ (↑C a * (q * (↑C a⁻¹ * ↑C (leadingCoeff q)⁻¹))))) =
    ↑C a⁻¹ * (↑C (leadingCoeff q)⁻¹ * (p /ₘ (q * ↑C (leadingCoeff q)⁻¹)))
[PROOFSTEP]
congr 3
[GOAL]
case neg.e_a.e_a.e_q
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
ha : ¬a = 0
⊢ ↑C a * (q * (↑C a⁻¹ * ↑C (leadingCoeff q)⁻¹)) = q * ↑C (leadingCoeff q)⁻¹
[PROOFSTEP]
rw [mul_left_comm q, ← mul_assoc, ← C.map_mul, mul_inv_cancel ha, C.map_one, one_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
ha : a ≠ 0
x✝ : p ∣ q
r : R[X]
hr : q = p * r
⊢ q = ↑C a * p * (↑C a⁻¹ * r)
[PROOFSTEP]
rw [mul_assoc, mul_left_comm p, ← mul_assoc, ← C.map_mul, _root_.mul_inv_cancel ha, C.map_one, one_mul, hr]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
ha : a ≠ 0
x✝ : p ∣ ↑C a * q
r : R[X]
hr : ↑C a * q = p * r
⊢ q = p * (↑C a⁻¹ * r)
[PROOFSTEP]
rw [mul_left_comm p, ← hr, ← mul_assoc, ← C.map_mul, _root_.inv_mul_cancel ha, C.map_one, one_mul]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
hp : p ≠ 0
⊢ ↑(normUnit p) = ↑C (leadingCoeff p)⁻¹
[PROOFSTEP]
have : p.leadingCoeff ≠ 0 := mt leadingCoeff_eq_zero.mp hp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
hp : p ≠ 0
this : leadingCoeff p ≠ 0
⊢ ↑(normUnit p) = ↑C (leadingCoeff p)⁻¹
[PROOFSTEP]
simp [CommGroupWithZero.coe_normUnit _ this]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
h : Monic p
⊢ ↑normalize p = p
[PROOFSTEP]
simp [h]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
x y : R[X]
⊢ map f x ∣ map f y ↔ x ∣ y
[PROOFSTEP]
by_cases H : x = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
x y : R[X]
H : x = 0
⊢ map f x ∣ map f y ↔ x ∣ y
[PROOFSTEP]
rw [H, Polynomial.map_zero, zero_dvd_iff, zero_dvd_iff, map_eq_zero]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
x y : R[X]
H : ¬x = 0
⊢ map f x ∣ map f y ↔ x ∣ y
[PROOFSTEP]
classical rw [← normalize_dvd_iff, ← @normalize_dvd_iff R[X], normalize_apply, normalize_apply,
  coe_normUnit_of_ne_zero H, coe_normUnit_of_ne_zero (mt (map_eq_zero f).1 H), leadingCoeff_map, ← map_inv₀ f, ← map_C,
  ← Polynomial.map_mul, map_dvd_map _ f.injective (monic_mul_leadingCoeff_inv H)]
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
x y : R[X]
H : ¬x = 0
⊢ map f x ∣ map f y ↔ x ∣ y
[PROOFSTEP]
rw [← normalize_dvd_iff, ← @normalize_dvd_iff R[X], normalize_apply, normalize_apply, coe_normUnit_of_ne_zero H,
  coe_normUnit_of_ne_zero (mt (map_eq_zero f).1 H), leadingCoeff_map, ← map_inv₀ f, ← map_C, ← Polynomial.map_mul,
  map_dvd_map _ f.injective (monic_mul_leadingCoeff_inv H)]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : DecidableEq R
⊢ degree (↑normalize p) = degree p
[PROOFSTEP]
simp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp1 : degree p = 1
⊢ Prime p
[PROOFSTEP]
classical
have : Prime (normalize p) :=
  Monic.prime_of_degree_eq_one (hp1 ▸ degree_normalize) (monic_normalize fun hp0 => absurd hp1 (hp0.symm ▸ by simp))
exact (normalize_associated _).prime this
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp1 : degree p = 1
⊢ Prime p
[PROOFSTEP]
have : Prime (normalize p) :=
  Monic.prime_of_degree_eq_one (hp1 ▸ degree_normalize) (monic_normalize fun hp0 => absurd hp1 (hp0.symm ▸ by simp))
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp1 : degree p = 1
hp0 : p = 0
⊢ ¬degree 0 = 1
[PROOFSTEP]
simp
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp1 : degree p = 1
this : Prime (↑normalize p)
⊢ Prime p
[PROOFSTEP]
exact (normalize_associated _).prime this
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
x : R
⊢ ¬Irreducible (↑C x)
[PROOFSTEP]
by_cases H : x = 0
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
x : R
H : x = 0
⊢ ¬Irreducible (↑C x)
[PROOFSTEP]
rw [H, C_0]
[GOAL]
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
x : R
H : x = 0
⊢ ¬Irreducible 0
[PROOFSTEP]
exact not_irreducible_zero
[GOAL]
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
x : R
H : ¬x = 0
⊢ ¬Irreducible (↑C x)
[PROOFSTEP]
exact fun hx => Irreducible.not_unit hx <| isUnit_C.2 <| isUnit_iff_ne_zero.2 H
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
⊢ (X - ↑C a) * (f /ₘ (X - ↑C a)) = f - f %ₘ (X - ↑C a)
[PROOFSTEP]
rw [eq_sub_iff_add_eq, ← eq_sub_iff_add_eq', modByMonic_eq_sub_mul_div]
[GOAL]
case _hq
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
⊢ Monic (X - ↑C a)
[PROOFSTEP]
exact monic_X_sub_C a
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
⊢ f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
[PROOFSTEP]
have key := by apply congrArg derivative <| X_sub_C_mul_divByMonic_eq_sub_modByMonic f a
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
⊢ ?m.1574688
[PROOFSTEP]
apply congrArg derivative <| X_sub_C_mul_divByMonic_eq_sub_modByMonic f a
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
key : ↑derivative ((X - ↑C a) * (f /ₘ (X - ↑C a))) = ↑derivative (f - f %ₘ (X - ↑C a))
⊢ f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
[PROOFSTEP]
rw [modByMonic_X_sub_C_eq_C_eval] at key
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
key : ↑derivative ((X - ↑C a) * (f /ₘ (X - ↑C a))) = ↑derivative (f - ↑C (eval a f))
⊢ f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
[PROOFSTEP]
rw [derivative_mul, derivative_sub, derivative_X, derivative_sub] at key
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
key :
  (1 - ↑derivative (↑C a)) * (f /ₘ (X - ↑C a)) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) =
    ↑derivative f - ↑derivative (↑C (eval a f))
⊢ f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
[PROOFSTEP]
rw [derivative_C, sub_zero, one_mul] at key
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
key : f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f - ↑derivative (↑C (eval a f))
⊢ f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
[PROOFSTEP]
rw [derivative_C, sub_zero] at key
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
key : f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
⊢ f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
[PROOFSTEP]
assumption
  /- Porting note: factored out another have statement from
  isCoprime_of_is_root_of_eval_derivative_ne_zero because the original proof was timing out -/
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf : X - ↑C a ∣ f /ₘ (X - ↑C a)
⊢ X - ↑C a ∣ ↑derivative f
[PROOFSTEP]
have key := divByMonic_add_X_sub_C_mul_derivate_divByMonic_eq_derivative f a
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf : X - ↑C a ∣ f /ₘ (X - ↑C a)
key : f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
⊢ X - ↑C a ∣ ↑derivative f
[PROOFSTEP]
have ⟨u, hu⟩ := hf
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf : X - ↑C a ∣ f /ₘ (X - ↑C a)
key : f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
u : K[X]
hu : f /ₘ (X - ↑C a) = (X - ↑C a) * u
⊢ X - ↑C a ∣ ↑derivative f
[PROOFSTEP]
rw [← key, hu, ← mul_add (X - C a) u _]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf : X - ↑C a ∣ f /ₘ (X - ↑C a)
key : f /ₘ (X - ↑C a) + (X - ↑C a) * ↑derivative (f /ₘ (X - ↑C a)) = ↑derivative f
u : K[X]
hu : f /ₘ (X - ↑C a) = (X - ↑C a) * u
⊢ X - ↑C a ∣ (X - ↑C a) * (u + ↑derivative ((X - ↑C a) * u))
[PROOFSTEP]
use(u + derivative ((X - C a) * u))
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf' : eval a (↑derivative f) ≠ 0
⊢ IsCoprime (X - ↑C a) (f /ₘ (X - ↑C a))
[PROOFSTEP]
classical
refine
  Or.resolve_left
    (EuclideanDomain.dvd_or_coprime (X - C a) (f /ₘ (X - C a))
      (irreducible_of_degree_eq_one (Polynomial.degree_X_sub_C a)))
    ?_
contrapose! hf' with h
have : X - C a ∣ derivative f := X_sub_C_dvd_derivative_of_X_sub_C_dvd_divByMonic f h
rw [← dvd_iff_modByMonic_eq_zero (monic_X_sub_C _), modByMonic_X_sub_C_eq_C_eval] at this
rwa [← C_inj, C_0]
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf' : eval a (↑derivative f) ≠ 0
⊢ IsCoprime (X - ↑C a) (f /ₘ (X - ↑C a))
[PROOFSTEP]
refine
  Or.resolve_left
    (EuclideanDomain.dvd_or_coprime (X - C a) (f /ₘ (X - C a))
      (irreducible_of_degree_eq_one (Polynomial.degree_X_sub_C a)))
    ?_
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
hf' : eval a (↑derivative f) ≠ 0
⊢ ¬X - ↑C a ∣ f /ₘ (X - ↑C a)
[PROOFSTEP]
contrapose! hf' with h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
h : X - ↑C a ∣ f /ₘ (X - ↑C a)
⊢ eval a (↑derivative f) = 0
[PROOFSTEP]
have : X - C a ∣ derivative f := X_sub_C_dvd_derivative_of_X_sub_C_dvd_divByMonic f h
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
h : X - ↑C a ∣ f /ₘ (X - ↑C a)
this : X - ↑C a ∣ ↑derivative f
⊢ eval a (↑derivative f) = 0
[PROOFSTEP]
rw [← dvd_iff_modByMonic_eq_zero (monic_X_sub_C _), modByMonic_X_sub_C_eq_C_eval] at this
[GOAL]
R : Type u
S : Type v
k : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
K : Type u_1
inst✝ : Field K
f : K[X]
a : K
h : X - ↑C a ∣ f /ₘ (X - ↑C a)
this : ↑C (eval a (↑derivative f)) = 0
⊢ eval a (↑derivative f) = 0
[PROOFSTEP]
rwa [← C_inj, C_0]


[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
⊢ Associated (↑(Algebra.norm R) f) (∏ i : ι, smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)
[PROOFSTEP]
have hI := span_singleton_eq_bot.not.2 hf
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
⊢ Associated (↑(Algebra.norm R) f) (∏ i : ι, smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)
[PROOFSTEP]
let b' := ringBasis b (span { f }) hI
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
⊢ Associated (↑(Algebra.norm R) f) (∏ i : ι, smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)
[PROOFSTEP]
classical
rw [← Matrix.det_diagonal, ← LinearMap.det_toLin b']
let e := (b'.equiv ((span { f }).selfBasis b hI) <| Equiv.refl _).trans ((LinearEquiv.coord S S f hf).restrictScalars R)
refine (LinearMap.associated_det_of_eq_comp e _ _ ?_).symm
dsimp only [LinearEquiv.trans_apply]
simp_rw [← LinearEquiv.coe_toLinearMap, ← LinearMap.comp_apply, ← LinearMap.ext_iff]
refine b'.ext fun i => ?_
simp_rw [LinearMap.comp_apply, LinearEquiv.coe_toLinearMap, Matrix.toLin_apply, Basis.repr_self,
  Finsupp.single_eq_pi_single, Matrix.diagonal_mulVec_single, Pi.single_apply, ite_smul, zero_smul, Finset.sum_ite_eq',
  mul_one, if_pos (Finset.mem_univ _), b'.equiv_apply]
change _ = f * _
rw [mul_comm, ← smul_eq_mul, LinearEquiv.restrictScalars_apply, LinearEquiv.coord_apply_smul, Ideal.selfBasis_def]
rfl
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
⊢ Associated (↑(Algebra.norm R) f) (∏ i : ι, smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)
[PROOFSTEP]
rw [← Matrix.det_diagonal, ← LinearMap.det_toLin b']
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
⊢ Associated (↑(Algebra.norm R) f)
    (↑LinearMap.det (↑(Matrix.toLin b' b') (Matrix.diagonal fun i => smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)))
[PROOFSTEP]
let e := (b'.equiv ((span { f }).selfBasis b hI) <| Equiv.refl _).trans ((LinearEquiv.coord S S f hf).restrictScalars R)
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
⊢ Associated (↑(Algebra.norm R) f)
    (↑LinearMap.det (↑(Matrix.toLin b' b') (Matrix.diagonal fun i => smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)))
[PROOFSTEP]
refine (LinearMap.associated_det_of_eq_comp e _ _ ?_).symm
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
⊢ ∀ (x : S),
    ↑(↑(Matrix.toLin b' b') (Matrix.diagonal fun i => smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)) x =
      ↑(↑↑↑(Algebra.lmul R S) f) (↑e x)
[PROOFSTEP]
dsimp only [LinearEquiv.trans_apply]
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
⊢ ∀ (x : S),
    ↑(↑(Matrix.toLin (ringBasis b (span {f}) hI) (ringBasis b (span {f}) hI))
            (Matrix.diagonal fun i => smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i))
        x =
      ↑(↑↑↑(Algebra.lmul R S) f)
        (↑(LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
          (↑(Basis.equiv (ringBasis b (span {f}) hI) (selfBasis b (span {f}) hI) (Equiv.refl ι)) x))
[PROOFSTEP]
simp_rw [← LinearEquiv.coe_toLinearMap, ← LinearMap.comp_apply, ← LinearMap.ext_iff]
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
⊢ ↑↑(Matrix.toLin (ringBasis b (span {f}) hI) (ringBasis b (span {f}) hI))
      (Matrix.diagonal fun i => smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i) =
    LinearMap.comp (↑↑↑(Algebra.lmul R S) f)
      (LinearMap.comp ↑(LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
        ↑(Basis.equiv (ringBasis b (span {f}) hI) (selfBasis b (span {f}) hI) (Equiv.refl ι)))
[PROOFSTEP]
refine b'.ext fun i => ?_
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
i : ι
⊢ ↑(↑↑(Matrix.toLin (ringBasis b (span {f}) hI) (ringBasis b (span {f}) hI))
          (Matrix.diagonal fun i => smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i))
      (↑b' i) =
    ↑(LinearMap.comp (↑↑↑(Algebra.lmul R S) f)
          (LinearMap.comp ↑(LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
            ↑(Basis.equiv (ringBasis b (span {f}) hI) (selfBasis b (span {f}) hI) (Equiv.refl ι))))
      (↑b' i)
[PROOFSTEP]
simp_rw [LinearMap.comp_apply, LinearEquiv.coe_toLinearMap, Matrix.toLin_apply, Basis.repr_self,
  Finsupp.single_eq_pi_single, Matrix.diagonal_mulVec_single, Pi.single_apply, ite_smul, zero_smul, Finset.sum_ite_eq',
  mul_one, if_pos (Finset.mem_univ _), b'.equiv_apply]
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
i : ι
⊢ smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i • ↑(ringBasis b (span {f}) hI) i =
    ↑(↑↑↑(Algebra.lmul R S) f)
      (↑(LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf)) (↑(selfBasis b (span {f}) hI) (↑(Equiv.refl ι) i)))
[PROOFSTEP]
change _ = f * _
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
i : ι
⊢ smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i • ↑(ringBasis b (span {f}) hI) i =
    f * ↑(LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf)) (↑(selfBasis b (span {f}) hI) (↑(Equiv.refl ι) i))
[PROOFSTEP]
rw [mul_comm, ← smul_eq_mul, LinearEquiv.restrictScalars_apply, LinearEquiv.coord_apply_smul, Ideal.selfBasis_def]
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : CommRing F
inst✝³ : Algebra F R
inst✝² : Algebra F S
inst✝¹ : IsScalarTower F R S
inst✝ : Fintype ι
b : Basis ι R S
f : S
hf : f ≠ 0
hI : ¬span {f} = ⊥
b' : Basis ι R S := ringBasis b (span {f}) hI
e : S ≃ₗ[R] S :=
  LinearEquiv.trans (Basis.equiv b' (selfBasis b (span {f}) hI) (Equiv.refl ι))
    (LinearEquiv.restrictScalars R (LinearEquiv.coord S S f hf))
i : ι
⊢ smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i • ↑(ringBasis b (span {f}) hI) i =
    smithCoeffs b (span {f}) hI (↑(Equiv.refl ι) i) • ↑(ringBasis b (span {f}) hI) (↑(Equiv.refl ι) i)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : IsDomain R
inst✝⁶ : IsPrincipalIdealRing R
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Algebra R S
F : Type u_4
inst✝² : Field F
inst✝¹ : Algebra F[X] S
inst✝ : Finite ι
b : Basis ι F[X] S
I : Ideal S
hI : I ≠ ⊥
i : ι
⊢ FiniteDimensional F (F[X] ⧸ span {smithCoeffs b I hI i})
[PROOFSTEP]
refine PowerBasis.finiteDimensional ?_
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : IsDomain R
inst✝⁶ : IsPrincipalIdealRing R
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Algebra R S
F : Type u_4
inst✝² : Field F
inst✝¹ : Algebra F[X] S
inst✝ : Finite ι
b : Basis ι F[X] S
I : Ideal S
hI : I ≠ ⊥
i : ι
⊢ PowerBasis F (F[X] ⧸ span {smithCoeffs b I hI i})
[PROOFSTEP]
refine AdjoinRoot.powerBasis ?_
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : IsDomain R
inst✝⁶ : IsPrincipalIdealRing R
inst✝⁵ : CommRing S
inst✝⁴ : IsDomain S
inst✝³ : Algebra R S
F : Type u_4
inst✝² : Field F
inst✝¹ : Algebra F[X] S
inst✝ : Finite ι
b : Basis ι F[X] S
I : Ideal S
hI : I ≠ ⊥
i : ι
⊢ smithCoeffs b I hI i ≠ 0
[PROOFSTEP]
refine I.smithCoeffs_ne_zero b hI i
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : Field F
inst✝³ : Algebra F[X] S
inst✝² : Finite ι
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F F[X] S
b : Basis ι F[X] S
f : S
hf : f ≠ 0
⊢ FiniteDimensional.finrank F (S ⧸ span {f}) = natDegree (↑(Algebra.norm F[X]) f)
[PROOFSTEP]
haveI := Fintype.ofFinite ι
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : Field F
inst✝³ : Algebra F[X] S
inst✝² : Finite ι
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F F[X] S
b : Basis ι F[X] S
f : S
hf : f ≠ 0
this : Fintype ι
⊢ FiniteDimensional.finrank F (S ⧸ span {f}) = natDegree (↑(Algebra.norm F[X]) f)
[PROOFSTEP]
have h := span_singleton_eq_bot.not.2 hf
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : Field F
inst✝³ : Algebra F[X] S
inst✝² : Finite ι
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F F[X] S
b : Basis ι F[X] S
f : S
hf : f ≠ 0
this : Fintype ι
h : ¬span {f} = ⊥
⊢ FiniteDimensional.finrank F (S ⧸ span {f}) = natDegree (↑(Algebra.norm F[X]) f)
[PROOFSTEP]
rw [natDegree_eq_of_degree_eq (degree_eq_degree_of_associated <| associated_norm_prod_smith b hf)]
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : Field F
inst✝³ : Algebra F[X] S
inst✝² : Finite ι
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F F[X] S
b : Basis ι F[X] S
f : S
hf : f ≠ 0
this : Fintype ι
h : ¬span {f} = ⊥
⊢ FiniteDimensional.finrank F (S ⧸ span {f}) = natDegree (∏ i : ι, smithCoeffs b (span {f}) (_ : ¬span {f} = ⊥) i)
[PROOFSTEP]
rw [natDegree_prod _ _ fun i _ => smithCoeffs_ne_zero b _ h i, finrank_quotient_eq_sum F h b]
  -- finrank_quotient_eq_sum slow
[GOAL]
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : Field F
inst✝³ : Algebra F[X] S
inst✝² : Finite ι
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F F[X] S
b : Basis ι F[X] S
f : S
hf : f ≠ 0
this : Fintype ι
h : ¬span {f} = ⊥
⊢ ∑ i : ι, FiniteDimensional.finrank F (F[X] ⧸ span {smithCoeffs b (span {f}) h i}) =
    ∑ i : ι, natDegree (smithCoeffs b (span {f}) h i)
[PROOFSTEP]
congr with i
[GOAL]
case e_f.h
R : Type u_1
S : Type u_2
ι : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : IsDomain R
inst✝⁸ : IsPrincipalIdealRing R
inst✝⁷ : CommRing S
inst✝⁶ : IsDomain S
inst✝⁵ : Algebra R S
F : Type u_4
inst✝⁴ : Field F
inst✝³ : Algebra F[X] S
inst✝² : Finite ι
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F F[X] S
b : Basis ι F[X] S
f : S
hf : f ≠ 0
this : Fintype ι
h : ¬span {f} = ⊥
i : ι
⊢ FiniteDimensional.finrank F (F[X] ⧸ span {smithCoeffs b (span {f}) h i}) = natDegree (smithCoeffs b (span {f}) h i)
[PROOFSTEP]
exact (AdjoinRoot.powerBasis <| smithCoeffs_ne_zero b _ h i).finrank