[GOAL]
R : Type u_1
inst✝ : CommSemiring R
p : R[X]
hp : Monic p
⊢ IsPrimitive p
[PROOFSTEP]
rintro r ⟨q, h⟩
[GOAL]
case intro
R : Type u_1
inst✝ : CommSemiring R
p : R[X]
hp : Monic p
r : R
q : R[X]
h : p = ↑C r * q
⊢ IsUnit r
[PROOFSTEP]
exact isUnit_of_mul_eq_one r (q.coeff p.natDegree) (by rwa [← coeff_C_mul, ← h])
[GOAL]
R : Type u_1
inst✝ : CommSemiring R
p : R[X]
hp : Monic p
r : R
q : R[X]
h : p = ↑C r * q
⊢ r * coeff q (natDegree p) = 1
[PROOFSTEP]
rwa [← coeff_C_mul, ← h]
[GOAL]
R : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
p : R[X]
hp : IsPrimitive p
⊢ p ≠ 0
[PROOFSTEP]
rintro rfl
[GOAL]
R : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
hp : IsPrimitive 0
⊢ False
[PROOFSTEP]
exact (hp 0 (dvd_zero (C 0))).ne_zero rfl
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
⊢ content p ∣ coeff p n
[PROOFSTEP]
by_cases h : n ∈ p.support
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : n ∈ support p
⊢ content p ∣ coeff p n
[PROOFSTEP]
apply Finset.gcd_dvd h
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : ¬n ∈ support p
⊢ content p ∣ coeff p n
[PROOFSTEP]
rw [mem_support_iff, Classical.not_not] at h 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : coeff p n = 0
⊢ content p ∣ coeff p n
[PROOFSTEP]
rw [h]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : coeff p n = 0
⊢ content p ∣ 0
[PROOFSTEP]
apply dvd_zero
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
⊢ content (↑C r) = ↑normalize r
[PROOFSTEP]
rw [content]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
⊢ Finset.gcd (support (↑C r)) (coeff (↑C r)) = ↑normalize r
[PROOFSTEP]
by_cases h0 : r = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : r = 0
⊢ Finset.gcd (support (↑C r)) (coeff (↑C r)) = ↑normalize r
[PROOFSTEP]
simp [h0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ Finset.gcd (support (↑C r)) (coeff (↑C r)) = ↑normalize r
[PROOFSTEP]
have h : (C r).support = {0} := support_monomial _ h0
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
h : support (↑C r) = {0}
⊢ Finset.gcd (support (↑C r)) (coeff (↑C r)) = ↑normalize r
[PROOFSTEP]
simp [h]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
⊢ content 0 = 0
[PROOFSTEP]
rw [← C_0, content_C, normalize_zero]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
⊢ content 1 = 1
[PROOFSTEP]
rw [← C_1, content_C, normalize_one]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ content (X * p) = content p
[PROOFSTEP]
rw [content, content, Finset.gcd_def, Finset.gcd_def]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ Multiset.gcd (Multiset.map (coeff (X * p)) (support (X * p)).val) =
    Multiset.gcd (Multiset.map (coeff p) (support p).val)
[PROOFSTEP]
refine' congr rfl _
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ Multiset.map (coeff (X * p)) (support (X * p)).val = Multiset.map (coeff p) (support p).val
[PROOFSTEP]
have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ :=
  by
  ext a
  simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
  cases' a with a
  · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
  rw [mul_comm, coeff_mul_X]
  constructor
  · intro h
    use a
  · rintro ⟨b, ⟨h1, h2⟩⟩
    rw [← Nat.succ_injective h2]
    apply h1
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
[PROOFSTEP]
ext a
[GOAL]
case a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ a ∈ support (X * p) ↔ a ∈ Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
[PROOFSTEP]
simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
[GOAL]
case a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff (X * p) a = 0 ↔ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = a
[PROOFSTEP]
cases' a with a
[GOAL]
case a.zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ ¬coeff (X * p) Nat.zero = 0 ↔ ∃ a, ¬coeff p a = 0 ∧ Nat.succ a = Nat.zero
[PROOFSTEP]
simp [coeff_X_mul_zero, Nat.succ_ne_zero]
[GOAL]
case a.succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff (X * p) (Nat.succ a) = 0 ↔ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a
[PROOFSTEP]
rw [mul_comm, coeff_mul_X]
[GOAL]
case a.succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff p a = 0 ↔ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a
[PROOFSTEP]
constructor
[GOAL]
case a.succ.mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff p a = 0 → ∃ a_2, ¬coeff p a_2 = 0 ∧ Nat.succ a_2 = Nat.succ a
[PROOFSTEP]
intro h
[GOAL]
case a.succ.mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
h : ¬coeff p a = 0
⊢ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a
[PROOFSTEP]
use a
[GOAL]
case a.succ.mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ (∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a) → ¬coeff p a = 0
[PROOFSTEP]
rintro ⟨b, ⟨h1, h2⟩⟩
[GOAL]
case a.succ.mpr.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a b : ℕ
h1 : ¬coeff p b = 0
h2 : Nat.succ b = Nat.succ a
⊢ ¬coeff p a = 0
[PROOFSTEP]
rw [← Nat.succ_injective h2]
[GOAL]
case a.succ.mpr.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a b : ℕ
h1 : ¬coeff p b = 0
h2 : Nat.succ b = Nat.succ a
⊢ ¬coeff p b = 0
[PROOFSTEP]
apply h1
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
⊢ Multiset.map (coeff (X * p)) (support (X * p)).val = Multiset.map (coeff p) (support p).val
[PROOFSTEP]
rw [h]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
⊢ Multiset.map (coeff (X * p)) (Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)).val =
    Multiset.map (coeff p) (support p).val
[PROOFSTEP]
simp only [Finset.map_val, Function.comp_apply, Function.Embedding.coeFn_mk, Multiset.map_map]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
⊢ Multiset.map (fun x => coeff (X * p) (Nat.succ x)) (support p).val = Multiset.map (coeff p) (support p).val
[PROOFSTEP]
refine' congr (congr rfl _) rfl
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
⊢ (fun x => coeff (X * p) (Nat.succ x)) = coeff p
[PROOFSTEP]
ext a
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
a : ℕ
⊢ coeff (X * p) (Nat.succ a) = coeff p a
[PROOFSTEP]
rw [mul_comm]
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
a : ℕ
⊢ coeff (p * X) (Nat.succ a) = coeff p a
[PROOFSTEP]
simp [coeff_mul_X]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
k : ℕ
⊢ content (X ^ k) = 1
[PROOFSTEP]
induction' k with k hi
[GOAL]
case zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
⊢ content (X ^ Nat.zero) = 1
[PROOFSTEP]
simp
[GOAL]
case succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
k : ℕ
hi : content (X ^ k) = 1
⊢ content (X ^ Nat.succ k) = 1
[PROOFSTEP]
rw [pow_succ, content_X_mul, hi]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
⊢ content X = 1
[PROOFSTEP]
rw [← mul_one X, content_X_mul, content_one]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
⊢ content (↑C r * p) = ↑normalize r * content p
[PROOFSTEP]
by_cases h0 : r = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : r = 0
⊢ content (↑C r * p) = ↑normalize r * content p
[PROOFSTEP]
simp [h0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
⊢ content (↑C r * p) = ↑normalize r * content p
[PROOFSTEP]
rw [content]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
⊢ Finset.gcd (support (↑C r * p)) (coeff (↑C r * p)) = ↑normalize r * content p
[PROOFSTEP]
rw [content]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
⊢ Finset.gcd (support (↑C r * p)) (coeff (↑C r * p)) = ↑normalize r * Finset.gcd (support p) (coeff p)
[PROOFSTEP]
rw [← Finset.gcd_mul_left]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
⊢ Finset.gcd (support (↑C r * p)) (coeff (↑C r * p)) = Finset.gcd (support p) fun x => r * coeff p x
[PROOFSTEP]
refine' congr (congr rfl _) _
[GOAL]
case neg.refine'_1
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
⊢ support (↑C r * p) = support p
[PROOFSTEP]
ext
[GOAL]
case neg.refine'_2
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
⊢ coeff (↑C r * p) = fun x => r * coeff p x
[PROOFSTEP]
ext
[GOAL]
case neg.refine'_1.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
a✝ : ℕ
⊢ a✝ ∈ support (↑C r * p) ↔ a✝ ∈ support p
[PROOFSTEP]
simp [h0, mem_support_iff]
[GOAL]
case neg.refine'_2.h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
p : R[X]
h0 : ¬r = 0
x✝ : ℕ
⊢ coeff (↑C r * p) x✝ = r * coeff p x✝
[PROOFSTEP]
simp [h0, mem_support_iff]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
k : ℕ
⊢ content (↑(monomial k) r) = ↑normalize r
[PROOFSTEP]
rw [← C_mul_X_pow_eq_monomial, content_C_mul, content_X_pow, mul_one]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ content p = 0 ↔ p = 0
[PROOFSTEP]
rw [content, Finset.gcd_eq_zero_iff]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ (∀ (x : ℕ), x ∈ support p → coeff p x = 0) ↔ p = 0
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ (∀ (x : ℕ), x ∈ support p → coeff p x = 0) → p = 0
[PROOFSTEP]
intro h
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ p = 0 → ∀ (x : ℕ), x ∈ support p → coeff p x = 0
[PROOFSTEP]
intro h
[GOAL]
case mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ∀ (x : ℕ), x ∈ support p → coeff p x = 0
⊢ p = 0
[PROOFSTEP]
ext n
[GOAL]
case mp.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ∀ (x : ℕ), x ∈ support p → coeff p x = 0
n : ℕ
⊢ coeff p n = coeff 0 n
[PROOFSTEP]
by_cases h0 : n ∈ p.support
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ∀ (x : ℕ), x ∈ support p → coeff p x = 0
n : ℕ
h0 : n ∈ support p
⊢ coeff p n = coeff 0 n
[PROOFSTEP]
rw [h n h0, coeff_zero]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ∀ (x : ℕ), x ∈ support p → coeff p x = 0
n : ℕ
h0 : ¬n ∈ support p
⊢ coeff p n = coeff 0 n
[PROOFSTEP]
rw [mem_support_iff] at h0 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ∀ (x : ℕ), x ∈ support p → coeff p x = 0
n : ℕ
h0 : ¬coeff p n ≠ 0
⊢ coeff p n = coeff 0 n
[PROOFSTEP]
push_neg at h0 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ∀ (x : ℕ), x ∈ support p → coeff p x = 0
n : ℕ
h0 : coeff p n = 0
⊢ coeff p n = coeff 0 n
[PROOFSTEP]
simp [h0]
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : p = 0
⊢ ∀ (x : ℕ), x ∈ support p → coeff p x = 0
[PROOFSTEP]
intro x
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : p = 0
x : ℕ
⊢ x ∈ support p → coeff p x = 0
[PROOFSTEP]
simp [h]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ normUnit (content p) = 1
[PROOFSTEP]
by_cases hp0 : p.content = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp0 : content p = 0
⊢ normUnit (content p) = 1
[PROOFSTEP]
simp [hp0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp0 : ¬content p = 0
⊢ normUnit (content p) = 1
[PROOFSTEP]
ext
[GOAL]
case neg.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp0 : ¬content p = 0
⊢ ↑(normUnit (content p)) = ↑1
[PROOFSTEP]
apply mul_left_cancel₀ hp0
[GOAL]
case neg.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp0 : ¬content p = 0
⊢ content p * ↑(normUnit (content p)) = content p * ↑1
[PROOFSTEP]
erw [← normalize_apply, normalize_content, mul_one]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
⊢ content p = Finset.gcd (Finset.range n) (coeff p)
[PROOFSTEP]
apply dvd_antisymm_of_normalize_eq normalize_content Finset.normalize_gcd
[GOAL]
case hab
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
⊢ content p ∣ Finset.gcd (Finset.range n) (coeff p)
[PROOFSTEP]
rw [Finset.dvd_gcd_iff]
[GOAL]
case hab
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
⊢ ∀ (b : ℕ), b ∈ Finset.range n → content p ∣ coeff p b
[PROOFSTEP]
intro i _
[GOAL]
case hab
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
i : ℕ
a✝ : i ∈ Finset.range n
⊢ content p ∣ coeff p i
[PROOFSTEP]
apply content_dvd_coeff _
[GOAL]
case hba
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
⊢ Finset.gcd (Finset.range n) (coeff p) ∣ content p
[PROOFSTEP]
apply Finset.gcd_mono
[GOAL]
case hba.h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
⊢ support p ⊆ Finset.range n
[PROOFSTEP]
intro i
[GOAL]
case hba.h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
i : ℕ
⊢ i ∈ support p → i ∈ Finset.range n
[PROOFSTEP]
simp only [Nat.lt_succ_iff, mem_support_iff, Ne.def, Finset.mem_range]
[GOAL]
case hba.h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
i : ℕ
⊢ ¬coeff p i = 0 → i < n
[PROOFSTEP]
contrapose!
[GOAL]
case hba.h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
i : ℕ
⊢ n ≤ i → coeff p i = 0
[PROOFSTEP]
intro h1
[GOAL]
case hba.h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : natDegree p < n
i : ℕ
h1 : n ≤ i
⊢ coeff p i = 0
[PROOFSTEP]
apply coeff_eq_zero_of_natDegree_lt (lt_of_lt_of_le h h1)
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ content p = gcd (leadingCoeff p) (content (eraseLead p))
[PROOFSTEP]
by_cases h : p = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : p = 0
⊢ content p = gcd (leadingCoeff p) (content (eraseLead p))
[PROOFSTEP]
simp [h]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬p = 0
⊢ content p = gcd (leadingCoeff p) (content (eraseLead p))
[PROOFSTEP]
rw [← leadingCoeff_eq_zero, leadingCoeff, ← Ne.def, ← mem_support_iff] at h 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : natDegree p ∈ support p
⊢ content p = gcd (leadingCoeff p) (content (eraseLead p))
[PROOFSTEP]
rw [content, ← Finset.insert_erase h, Finset.gcd_insert, leadingCoeff, content, eraseLead_support]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : natDegree p ∈ support p
⊢ gcd (coeff p (natDegree p)) (Finset.gcd (Finset.erase (support p) (natDegree p)) (coeff p)) =
    gcd (coeff p (natDegree p)) (Finset.gcd (Finset.erase (support p) (natDegree p)) (coeff (eraseLead p)))
[PROOFSTEP]
refine' congr rfl (Finset.gcd_congr rfl fun i hi => _)
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : natDegree p ∈ support p
i : ℕ
hi : i ∈ Finset.erase (support p) (natDegree p)
⊢ coeff p i = coeff (eraseLead p) i
[PROOFSTEP]
rw [Finset.mem_erase] at hi 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : natDegree p ∈ support p
i : ℕ
hi : i ≠ natDegree p ∧ i ∈ support p
⊢ coeff p i = coeff (eraseLead p) i
[PROOFSTEP]
rw [eraseLead_coeff, if_neg hi.1]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
⊢ r ∣ content p ↔ ↑C r ∣ p
[PROOFSTEP]
rw [C_dvd_iff_dvd_coeff]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
⊢ r ∣ content p ↔ ∀ (i : ℕ), r ∣ coeff p i
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
⊢ r ∣ content p → ∀ (i : ℕ), r ∣ coeff p i
[PROOFSTEP]
intro h i
[GOAL]
case mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
h : r ∣ content p
i : ℕ
⊢ r ∣ coeff p i
[PROOFSTEP]
apply h.trans (content_dvd_coeff _)
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
⊢ (∀ (i : ℕ), r ∣ coeff p i) → r ∣ content p
[PROOFSTEP]
intro h
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
h : ∀ (i : ℕ), r ∣ coeff p i
⊢ r ∣ content p
[PROOFSTEP]
rw [content, Finset.dvd_gcd_iff]
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
h : ∀ (i : ℕ), r ∣ coeff p i
⊢ ∀ (b : ℕ), b ∈ support p → r ∣ coeff p b
[PROOFSTEP]
intro i _
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
r : R
h : ∀ (i : ℕ), r ∣ coeff p i
i : ℕ
a✝ : i ∈ support p
⊢ r ∣ coeff p i
[PROOFSTEP]
apply h i
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ IsPrimitive p ↔ content p = 1
[PROOFSTEP]
rw [← normalize_content, normalize_eq_one, IsPrimitive]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ (∀ (r : R), ↑C r ∣ p → IsUnit r) ↔ IsUnit (content p)
[PROOFSTEP]
simp_rw [← dvd_content_iff_C_dvd]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ (∀ (r : R), r ∣ content p → IsUnit r) ↔ IsUnit (content p)
[PROOFSTEP]
exact ⟨fun h => h p.content (dvd_refl p.content), fun h r hdvd => isUnit_of_dvd_unit hdvd h⟩
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ p = ↑C (content p) * primPart p
[PROOFSTEP]
by_cases h : p = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : p = 0
⊢ p = ↑C (content p) * primPart p
[PROOFSTEP]
simp [h]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬p = 0
⊢ p = ↑C (content p) * primPart p
[PROOFSTEP]
rw [primPart, if_neg h, ← Classical.choose_spec (C_content_dvd p)]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ IsPrimitive (primPart p)
[PROOFSTEP]
by_cases h : p = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : p = 0
⊢ IsPrimitive (primPart p)
[PROOFSTEP]
simp [h]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬p = 0
⊢ IsPrimitive (primPart p)
[PROOFSTEP]
rw [← content_eq_zero_iff] at h 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h✝ : ¬p = 0
h : ¬content p = 0
⊢ IsPrimitive (primPart p)
[PROOFSTEP]
rw [isPrimitive_iff_content_eq_one]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h✝ : ¬p = 0
h : ¬content p = 0
⊢ content (primPart p) = 1
[PROOFSTEP]
apply mul_left_cancel₀ h
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h✝ : ¬p = 0
h : ¬content p = 0
⊢ content p * content (primPart p) = content p * 1
[PROOFSTEP]
conv_rhs => rw [p.eq_C_content_mul_primPart, mul_one, content_C_mul, normalize_content]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h✝ : ¬p = 0
h : ¬content p = 0
| content p * 1
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, mul_one, content_C_mul, normalize_content]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h✝ : ¬p = 0
h : ¬content p = 0
| content p * 1
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, mul_one, content_C_mul, normalize_content]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h✝ : ¬p = 0
h : ¬content p = 0
| content p * 1
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, mul_one, content_C_mul, normalize_content]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ natDegree (primPart p) = natDegree p
[PROOFSTEP]
by_cases h : C p.content = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ↑C (content p) = 0
⊢ natDegree (primPart p) = natDegree p
[PROOFSTEP]
rw [C_eq_zero, content_eq_zero_iff] at h 
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : p = 0
⊢ natDegree (primPart p) = natDegree p
[PROOFSTEP]
simp [h]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬↑C (content p) = 0
⊢ natDegree (primPart p) = natDegree p
[PROOFSTEP]
conv_rhs => rw [p.eq_C_content_mul_primPart, natDegree_mul h p.primPart_ne_zero, natDegree_C, zero_add]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬↑C (content p) = 0
| natDegree p
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, natDegree_mul h p.primPart_ne_zero, natDegree_C, zero_add]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬↑C (content p) = 0
| natDegree p
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, natDegree_mul h p.primPart_ne_zero, natDegree_C, zero_add]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : ¬↑C (content p) = 0
| natDegree p
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, natDegree_mul h p.primPart_ne_zero, natDegree_C, zero_add]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp : IsPrimitive p
⊢ primPart p = p
[PROOFSTEP]
rw [← one_mul p.primPart, ← C_1, ← hp.content_eq_one, ← p.eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
⊢ IsUnit (primPart (↑C r))
[PROOFSTEP]
by_cases h0 : r = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : r = 0
⊢ IsUnit (primPart (↑C r))
[PROOFSTEP]
simp [h0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ IsUnit (primPart (↑C r))
[PROOFSTEP]
unfold IsUnit
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ ∃ u, ↑u = primPart (↑C r)
[PROOFSTEP]
refine'
  ⟨⟨C ↑(normUnit r)⁻¹, C ↑(normUnit r), by rw [← RingHom.map_mul, Units.inv_mul, C_1], by
      rw [← RingHom.map_mul, Units.mul_inv, C_1]⟩,
    _⟩
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ ↑C ↑(normUnit r)⁻¹ * ↑C ↑(normUnit r) = 1
[PROOFSTEP]
rw [← RingHom.map_mul, Units.inv_mul, C_1]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ ↑C ↑(normUnit r) * ↑C ↑(normUnit r)⁻¹ = 1
[PROOFSTEP]
rw [← RingHom.map_mul, Units.mul_inv, C_1]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ ↑{ val := ↑C ↑(normUnit r)⁻¹, inv := ↑C ↑(normUnit r), val_inv := (_ : ↑C ↑(normUnit r)⁻¹ * ↑C ↑(normUnit r) = 1),
        inv_val := (_ : ↑C ↑(normUnit r) * ↑C ↑(normUnit r)⁻¹ = 1) } =
    primPart (↑C r)
[PROOFSTEP]
rw [← normalize_eq_zero, ← C_eq_zero] at h0 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
⊢ ↑{ val := ↑C ↑(normUnit r)⁻¹, inv := ↑C ↑(normUnit r), val_inv := (_ : ↑C ↑(normUnit r)⁻¹ * ↑C ↑(normUnit r) = 1),
        inv_val := (_ : ↑C ↑(normUnit r) * ↑C ↑(normUnit r)⁻¹ = 1) } =
    primPart (↑C r)
[PROOFSTEP]
apply mul_left_cancel₀ h0
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
⊢ ↑C (↑normalize r) *
      ↑{ val := ↑C ↑(normUnit r)⁻¹, inv := ↑C ↑(normUnit r), val_inv := (_ : ↑C ↑(normUnit r)⁻¹ * ↑C ↑(normUnit r) = 1),
          inv_val := (_ : ↑C ↑(normUnit r) * ↑C ↑(normUnit r)⁻¹ = 1) } =
    ↑C (↑normalize r) * primPart (↑C r)
[PROOFSTEP]
conv_rhs => rw [← content_C, ← (C r).eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
| ↑C (↑normalize r) * primPart (↑C r)
[PROOFSTEP]
rw [← content_C, ← (C r).eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
| ↑C (↑normalize r) * primPart (↑C r)
[PROOFSTEP]
rw [← content_C, ← (C r).eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
| ↑C (↑normalize r) * primPart (↑C r)
[PROOFSTEP]
rw [← content_C, ← (C r).eq_C_content_mul_primPart]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
⊢ ↑C (↑normalize r) *
      ↑{ val := ↑C ↑(normUnit r)⁻¹, inv := ↑C ↑(normUnit r), val_inv := (_ : ↑C ↑(normUnit r)⁻¹ * ↑C ↑(normUnit r) = 1),
          inv_val := (_ : ↑C ↑(normUnit r) * ↑C ↑(normUnit r)⁻¹ = 1) } =
    ↑C r
[PROOFSTEP]
simp only [Units.val_mk, normalize_apply, RingHom.map_mul]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0✝ : ¬r = 0
h0 : ¬↑C (↑normalize r) = 0
⊢ ↑C r * ↑C ↑(normUnit r) * ↑C ↑(normUnit r)⁻¹ = ↑C r
[PROOFSTEP]
rw [mul_assoc, ← RingHom.map_mul, Units.mul_inv, C_1, mul_one]
[GOAL]
R : Type u_1
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : NormalizedGCDMonoid R
S : Type u_2
inst✝³ : Ring S
inst✝² : IsDomain S
inst✝¹ : Algebra R S
inst✝ : NoZeroSMulDivisors R S
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑(aeval s) p = 0
⊢ ↑(aeval s) (primPart p) = 0
[PROOFSTEP]
rw [eq_C_content_mul_primPart p, map_mul, aeval_C] at hp 
[GOAL]
R : Type u_1
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : NormalizedGCDMonoid R
S : Type u_2
inst✝³ : Ring S
inst✝² : IsDomain S
inst✝¹ : Algebra R S
inst✝ : NoZeroSMulDivisors R S
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑(algebraMap R S) (content p) * ↑(aeval s) (primPart p) = 0
⊢ ↑(aeval s) (primPart p) = 0
[PROOFSTEP]
have hcont : p.content ≠ 0 := fun h => hpzero (content_eq_zero_iff.1 h)
[GOAL]
R : Type u_1
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : NormalizedGCDMonoid R
S : Type u_2
inst✝³ : Ring S
inst✝² : IsDomain S
inst✝¹ : Algebra R S
inst✝ : NoZeroSMulDivisors R S
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑(algebraMap R S) (content p) * ↑(aeval s) (primPart p) = 0
hcont : content p ≠ 0
⊢ ↑(aeval s) (primPart p) = 0
[PROOFSTEP]
replace hcont := Function.Injective.ne (NoZeroSMulDivisors.algebraMap_injective R S) hcont
[GOAL]
R : Type u_1
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : NormalizedGCDMonoid R
S : Type u_2
inst✝³ : Ring S
inst✝² : IsDomain S
inst✝¹ : Algebra R S
inst✝ : NoZeroSMulDivisors R S
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑(algebraMap R S) (content p) * ↑(aeval s) (primPart p) = 0
hcont : ↑(algebraMap R S) (content p) ≠ ↑(algebraMap R S) 0
⊢ ↑(aeval s) (primPart p) = 0
[PROOFSTEP]
rw [map_zero] at hcont 
[GOAL]
R : Type u_1
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : NormalizedGCDMonoid R
S : Type u_2
inst✝³ : Ring S
inst✝² : IsDomain S
inst✝¹ : Algebra R S
inst✝ : NoZeroSMulDivisors R S
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑(algebraMap R S) (content p) * ↑(aeval s) (primPart p) = 0
hcont : ↑(algebraMap R S) (content p) ≠ 0
⊢ ↑(aeval s) (primPart p) = 0
[PROOFSTEP]
exact eq_zero_of_ne_zero_of_mul_left_eq_zero hcont hp
[GOAL]
R : Type u_1
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : NormalizedGCDMonoid R
S : Type u_2
inst✝¹ : CommRing S
inst✝ : IsDomain S
f : R →+* S
hinj : Function.Injective ↑f
p : R[X]
s : S
hpzero : p ≠ 0
hp : eval₂ f s p = 0
⊢ eval₂ f s (primPart p) = 0
[PROOFSTEP]
rw [eq_C_content_mul_primPart p, eval₂_mul, eval₂_C] at hp 
[GOAL]
R : Type u_1
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : NormalizedGCDMonoid R
S : Type u_2
inst✝¹ : CommRing S
inst✝ : IsDomain S
f : R →+* S
hinj : Function.Injective ↑f
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑f (content p) * eval₂ f s (primPart p) = 0
⊢ eval₂ f s (primPart p) = 0
[PROOFSTEP]
have hcont : p.content ≠ 0 := fun h => hpzero (content_eq_zero_iff.1 h)
[GOAL]
R : Type u_1
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : NormalizedGCDMonoid R
S : Type u_2
inst✝¹ : CommRing S
inst✝ : IsDomain S
f : R →+* S
hinj : Function.Injective ↑f
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑f (content p) * eval₂ f s (primPart p) = 0
hcont : content p ≠ 0
⊢ eval₂ f s (primPart p) = 0
[PROOFSTEP]
replace hcont := Function.Injective.ne hinj hcont
[GOAL]
R : Type u_1
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : NormalizedGCDMonoid R
S : Type u_2
inst✝¹ : CommRing S
inst✝ : IsDomain S
f : R →+* S
hinj : Function.Injective ↑f
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑f (content p) * eval₂ f s (primPart p) = 0
hcont : ↑f (content p) ≠ ↑f 0
⊢ eval₂ f s (primPart p) = 0
[PROOFSTEP]
rw [map_zero] at hcont 
[GOAL]
R : Type u_1
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : NormalizedGCDMonoid R
S : Type u_2
inst✝¹ : CommRing S
inst✝ : IsDomain S
f : R →+* S
hinj : Function.Injective ↑f
p : R[X]
s : S
hpzero : p ≠ 0
hp : ↑f (content p) * eval₂ f s (primPart p) = 0
hcont : ↑f (content p) ≠ 0
⊢ eval₂ f s (primPart p) = 0
[PROOFSTEP]
exact eq_zero_of_ne_zero_of_mul_left_eq_zero hcont hp
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
h : ↑C a ∣ p - q
⊢ gcd a (content p) = gcd a (content q)
[PROOFSTEP]
rw [content_eq_gcd_range_of_lt p (max p.natDegree q.natDegree).succ
    (lt_of_le_of_lt (le_max_left _ _) (Nat.lt_succ_self _))]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
h : ↑C a ∣ p - q
⊢ gcd a (Finset.gcd (Finset.range (Nat.succ (max (natDegree p) (natDegree q)))) (coeff p)) = gcd a (content q)
[PROOFSTEP]
rw [content_eq_gcd_range_of_lt q (max p.natDegree q.natDegree).succ
    (lt_of_le_of_lt (le_max_right _ _) (Nat.lt_succ_self _))]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
h : ↑C a ∣ p - q
⊢ gcd a (Finset.gcd (Finset.range (Nat.succ (max (natDegree p) (natDegree q)))) (coeff p)) =
    gcd a (Finset.gcd (Finset.range (Nat.succ (max (natDegree p) (natDegree q)))) (coeff q))
[PROOFSTEP]
apply Finset.gcd_eq_of_dvd_sub
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
h : ↑C a ∣ p - q
⊢ ∀ (x : ℕ), x ∈ Finset.range (Nat.succ (max (natDegree p) (natDegree q))) → a ∣ coeff p x - coeff q x
[PROOFSTEP]
intro x _
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
h : ↑C a ∣ p - q
x : ℕ
a✝ : x ∈ Finset.range (Nat.succ (max (natDegree p) (natDegree q)))
⊢ a ∣ coeff p x - coeff q x
[PROOFSTEP]
cases' h with w hw
[GOAL]
case h.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
x : ℕ
a✝ : x ∈ Finset.range (Nat.succ (max (natDegree p) (natDegree q)))
w : (fun x => R[X]) a
hw : p - q = ↑C a * w
⊢ a ∣ coeff p x - coeff q x
[PROOFSTEP]
use w.coeff x
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
a : R
p q : R[X]
x : ℕ
a✝ : x ∈ Finset.range (Nat.succ (max (natDegree p) (natDegree q)))
w : (fun x => R[X]) a
hw : p - q = ↑C a * w
⊢ coeff p x - coeff q x = a * coeff w x
[PROOFSTEP]
rw [← coeff_sub, hw, coeff_C_mul]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ gcd (content (eraseLead (p * q))) (leadingCoeff p) = gcd (content (eraseLead p * q)) (leadingCoeff p)
[PROOFSTEP]
rw [gcd_comm (content _) _, gcd_comm (content _) _]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ gcd (leadingCoeff p) (content (eraseLead (p * q))) = gcd (leadingCoeff p) (content (eraseLead p * q))
[PROOFSTEP]
apply gcd_content_eq_of_dvd_sub
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ ↑C (leadingCoeff p) ∣ eraseLead (p * q) - eraseLead p * q
[PROOFSTEP]
rw [← self_sub_C_mul_X_pow, ← self_sub_C_mul_X_pow, sub_mul, sub_sub, add_comm, sub_add, sub_sub_cancel,
  leadingCoeff_mul, RingHom.map_mul, mul_assoc, mul_assoc]
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ ↑C (leadingCoeff p) ∣
    ↑C (leadingCoeff p) * (X ^ natDegree p * q) - ↑C (leadingCoeff p) * (↑C (leadingCoeff q) * X ^ natDegree (p * q))
[PROOFSTEP]
apply dvd_sub (Dvd.intro _ rfl) (Dvd.intro _ rfl)
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ content (p * q) = content p * content q
[PROOFSTEP]
classical
suffices h : ∀ (n : ℕ) (p q : R[X]), (p * q).degree < n → (p * q).content = p.content * q.content
· apply h
  apply lt_of_le_of_lt degree_le_natDegree (WithBot.coe_lt_coe.2 (Nat.lt_succ_self _))
intro n
induction' n with n ih
· intro p q hpq
  dsimp at hpq 
  rw [Nat.cast_withBot, WithBot.coe_zero, Nat.WithBot.lt_zero_iff, degree_eq_bot, mul_eq_zero] at hpq 
  rcases hpq with (rfl | rfl) <;> simp
intro p q hpq
by_cases p0 : p = 0
· simp [p0]
by_cases q0 : q = 0
· simp [q0]
rw [degree_eq_natDegree (mul_ne_zero p0 q0), Nat.cast_withBot, Nat.cast_withBot, WithBot.coe_lt_coe,
  Nat.lt_succ_iff_lt_or_eq, ← WithBot.coe_lt_coe, ← Nat.cast_withBot, ← degree_eq_natDegree (mul_ne_zero p0 q0),
  natDegree_mul p0 q0] at hpq 
rcases hpq with (hlt | heq)
· apply ih _ _ hlt
rw [← p.natDegree_primPart, ← q.natDegree_primPart, ← WithBot.coe_eq_coe, WithBot.coe_add, ← Nat.cast_withBot, ←
  degree_eq_natDegree p.primPart_ne_zero, ← Nat.cast_withBot, ← degree_eq_natDegree q.primPart_ne_zero] at heq 
rw [p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
suffices h : (q.primPart * p.primPart).content = 1
·
  rw [mul_assoc, content_C_mul, content_C_mul, mul_comm p.primPart, mul_assoc, content_C_mul, content_C_mul, h, mul_one,
    content_primPart, content_primPart, mul_one, mul_one]
rw [← normalize_content, normalize_eq_one, isUnit_iff_dvd_one, content_eq_gcd_leadingCoeff_content_eraseLead,
  leadingCoeff_mul, gcd_comm]
apply (gcd_mul_dvd_mul_gcd _ _ _).trans
rw [content_mul_aux, ih, content_primPart, mul_one, gcd_comm, ← content_eq_gcd_leadingCoeff_content_eraseLead,
  content_primPart, one_mul, mul_comm q.primPart, content_mul_aux, ih, content_primPart, mul_one, gcd_comm, ←
  content_eq_gcd_leadingCoeff_content_eraseLead, content_primPart]
· rw [Nat.cast_withBot, ← heq, degree_mul, WithBot.add_lt_add_iff_right]
  · apply degree_erase_lt p.primPart_ne_zero
  · rw [Ne.def, degree_eq_bot]
    apply q.primPart_ne_zero
· rw [mul_comm, Nat.cast_withBot, ← heq, degree_mul, WithBot.add_lt_add_iff_left]
  · apply degree_erase_lt q.primPart_ne_zero
  · rw [Ne.def, degree_eq_bot]
    apply p.primPart_ne_zero
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ content (p * q) = content p * content q
[PROOFSTEP]
suffices h : ∀ (n : ℕ) (p q : R[X]), (p * q).degree < n → (p * q).content = p.content * q.content
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h : ∀ (n : ℕ) (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
⊢ content (p * q) = content p * content q
[PROOFSTEP]
apply h
[GOAL]
case a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h : ∀ (n : ℕ) (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
⊢ degree (p * q) < ↑?n
case n
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h : ∀ (n : ℕ) (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
⊢ ℕ
[PROOFSTEP]
apply lt_of_le_of_lt degree_le_natDegree (WithBot.coe_lt_coe.2 (Nat.lt_succ_self _))
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ ∀ (n : ℕ) (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
[PROOFSTEP]
intro n
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
n : ℕ
⊢ ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
[PROOFSTEP]
induction' n with n ih
[GOAL]
case h.zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ ∀ (p q : R[X]), degree (p * q) < ↑Nat.zero → content (p * q) = content p * content q
[PROOFSTEP]
intro p q hpq
[GOAL]
case h.zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ p q : R[X]
hpq : degree (p * q) < ↑Nat.zero
⊢ content (p * q) = content p * content q
[PROOFSTEP]
dsimp at hpq 
[GOAL]
case h.zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ p q : R[X]
hpq : degree (p * q) < ↑0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
rw [Nat.cast_withBot, WithBot.coe_zero, Nat.WithBot.lt_zero_iff, degree_eq_bot, mul_eq_zero] at hpq 
[GOAL]
case h.zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ p q : R[X]
hpq : p = 0 ∨ q = 0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
rcases hpq with (rfl | rfl)
[GOAL]
case h.zero.inl
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q✝ q : R[X]
⊢ content (0 * q) = content 0 * content q
[PROOFSTEP]
simp
[GOAL]
case h.zero.inr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q p : R[X]
⊢ content (p * 0) = content p * content 0
[PROOFSTEP]
simp
[GOAL]
case h.succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
⊢ ∀ (p q : R[X]), degree (p * q) < ↑(Nat.succ n) → content (p * q) = content p * content q
[PROOFSTEP]
intro p q hpq
[GOAL]
case h.succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
hpq : degree (p * q) < ↑(Nat.succ n)
⊢ content (p * q) = content p * content q
[PROOFSTEP]
by_cases p0 : p = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
hpq : degree (p * q) < ↑(Nat.succ n)
p0 : p = 0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
simp [p0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
hpq : degree (p * q) < ↑(Nat.succ n)
p0 : ¬p = 0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
by_cases q0 : q = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
hpq : degree (p * q) < ↑(Nat.succ n)
p0 : ¬p = 0
q0 : q = 0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
simp [q0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
hpq : degree (p * q) < ↑(Nat.succ n)
p0 : ¬p = 0
q0 : ¬q = 0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
rw [degree_eq_natDegree (mul_ne_zero p0 q0), Nat.cast_withBot, Nat.cast_withBot, WithBot.coe_lt_coe,
  Nat.lt_succ_iff_lt_or_eq, ← WithBot.coe_lt_coe, ← Nat.cast_withBot, ← degree_eq_natDegree (mul_ne_zero p0 q0),
  natDegree_mul p0 q0] at hpq 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
hpq : degree (p * q) < ↑n ∨ natDegree p + natDegree q = n
p0 : ¬p = 0
q0 : ¬q = 0
⊢ content (p * q) = content p * content q
[PROOFSTEP]
rcases hpq with (hlt | heq)
[GOAL]
case neg.inl
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
hlt : degree (p * q) < ↑n
⊢ content (p * q) = content p * content q
[PROOFSTEP]
apply ih _ _ hlt
[GOAL]
case neg.inr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : natDegree p + natDegree q = n
⊢ content (p * q) = content p * content q
[PROOFSTEP]
rw [← p.natDegree_primPart, ← q.natDegree_primPart, ← WithBot.coe_eq_coe, WithBot.coe_add, ← Nat.cast_withBot, ←
  degree_eq_natDegree p.primPart_ne_zero, ← Nat.cast_withBot, ← degree_eq_natDegree q.primPart_ne_zero] at heq 
[GOAL]
case neg.inr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ content (p * q) = content p * content q
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
[GOAL]
case neg.inr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ content (↑C (content p) * primPart p * (↑C (content q) * primPart q)) =
    content (↑C (content p) * primPart p) * content (↑C (content q) * primPart q)
[PROOFSTEP]
suffices h : (q.primPart * p.primPart).content = 1
[GOAL]
case neg.inr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
h : content (primPart q * primPart p) = 1
⊢ content (↑C (content p) * primPart p * (↑C (content q) * primPart q)) =
    content (↑C (content p) * primPart p) * content (↑C (content q) * primPart q)
[PROOFSTEP]
rw [mul_assoc, content_C_mul, content_C_mul, mul_comm p.primPart, mul_assoc, content_C_mul, content_C_mul, h, mul_one,
  content_primPart, content_primPart, mul_one, mul_one]
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ content (primPart q * primPart p) = 1
[PROOFSTEP]
rw [← normalize_content, normalize_eq_one, isUnit_iff_dvd_one, content_eq_gcd_leadingCoeff_content_eraseLead,
  leadingCoeff_mul, gcd_comm]
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ gcd (content (eraseLead (primPart q * primPart p))) (leadingCoeff (primPart q) * leadingCoeff (primPart p)) ∣ 1
[PROOFSTEP]
apply (gcd_mul_dvd_mul_gcd _ _ _).trans
[GOAL]
case h
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ gcd (content (eraseLead (primPart q * primPart p))) (leadingCoeff (primPart q)) *
      gcd (content (eraseLead (primPart q * primPart p))) (leadingCoeff (primPart p)) ∣
    1
[PROOFSTEP]
rw [content_mul_aux, ih, content_primPart, mul_one, gcd_comm, ← content_eq_gcd_leadingCoeff_content_eraseLead,
  content_primPart, one_mul, mul_comm q.primPart, content_mul_aux, ih, content_primPart, mul_one, gcd_comm, ←
  content_eq_gcd_leadingCoeff_content_eraseLead, content_primPart]
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ degree (eraseLead (primPart p) * primPart q) < ↑n
[PROOFSTEP]
rw [Nat.cast_withBot, ← heq, degree_mul, WithBot.add_lt_add_iff_right]
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ degree (eraseLead (primPart p)) < degree (primPart p)
[PROOFSTEP]
apply degree_erase_lt p.primPart_ne_zero
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ degree (primPart q) ≠ ⊥
[PROOFSTEP]
rw [Ne.def, degree_eq_bot]
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ ¬primPart q = 0
[PROOFSTEP]
apply q.primPart_ne_zero
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ degree (eraseLead (primPart q) * primPart p) < ↑n
[PROOFSTEP]
rw [mul_comm, Nat.cast_withBot, ← heq, degree_mul, WithBot.add_lt_add_iff_left]
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ degree (eraseLead (primPart q)) < degree (primPart q)
[PROOFSTEP]
apply degree_erase_lt q.primPart_ne_zero
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ degree (primPart p) ≠ ⊥
[PROOFSTEP]
rw [Ne.def, degree_eq_bot]
[GOAL]
case h.a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p✝ q✝ : R[X]
n : ℕ
ih : ∀ (p q : R[X]), degree (p * q) < ↑n → content (p * q) = content p * content q
p q : R[X]
p0 : ¬p = 0
q0 : ¬q = 0
heq : degree (primPart p) + degree (primPart q) = ↑n
⊢ ¬primPart p = 0
[PROOFSTEP]
apply p.primPart_ne_zero
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
⊢ IsPrimitive (p * q)
[PROOFSTEP]
rw [isPrimitive_iff_content_eq_one, content_mul, hp.content_eq_one, hq.content_eq_one, mul_one]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0 : p * q ≠ 0
⊢ primPart (p * q) = primPart p * primPart q
[PROOFSTEP]
rw [Ne.def, ← content_eq_zero_iff, ← C_eq_zero] at h0 
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
⊢ primPart (p * q) = primPart p * primPart q
[PROOFSTEP]
apply mul_left_cancel₀ h0
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
⊢ ↑C (content (p * q)) * primPart (p * q) = ↑C (content (p * q)) * (primPart p * primPart q)
[PROOFSTEP]
conv_lhs => rw [← (p * q).eq_C_content_mul_primPart, p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
| ↑C (content (p * q)) * primPart (p * q)
[PROOFSTEP]
rw [← (p * q).eq_C_content_mul_primPart, p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
| ↑C (content (p * q)) * primPart (p * q)
[PROOFSTEP]
rw [← (p * q).eq_C_content_mul_primPart, p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
| ↑C (content (p * q)) * primPart (p * q)
[PROOFSTEP]
rw [← (p * q).eq_C_content_mul_primPart, p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
⊢ ↑C (content p) * primPart p * (↑C (content q) * primPart q) = ↑C (content (p * q)) * (primPart p * primPart q)
[PROOFSTEP]
rw [content_mul, RingHom.map_mul]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
h0✝ : ¬p * q = 0
h0 : ¬↑C (content (p * q)) = 0
⊢ ↑C (content p) * primPart p * (↑C (content q) * primPart q) =
    ↑C (content p) * ↑C (content q) * (primPart p * primPart q)
[PROOFSTEP]
ring
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : q ≠ 0
⊢ p ∣ primPart q ↔ p ∣ q
[PROOFSTEP]
refine' ⟨fun h => h.trans (Dvd.intro_left _ q.eq_C_content_mul_primPart.symm), fun h => _⟩
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : q ≠ 0
h : p ∣ q
⊢ p ∣ primPart q
[PROOFSTEP]
rcases h with ⟨r, rfl⟩
[GOAL]
case intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp : IsPrimitive p
r : R[X]
hq : p * r ≠ 0
⊢ p ∣ primPart (p * r)
[PROOFSTEP]
apply Dvd.intro _
[GOAL]
case intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp : IsPrimitive p
r : R[X]
hq : p * r ≠ 0
⊢ p * ?m.658553 = primPart (p * r)
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp : IsPrimitive p
r : R[X]
hq : p * r ≠ 0
⊢ R[X]
[PROOFSTEP]
rw [primPart_mul hq, hp.primPart_eq]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
⊢ ∃ r, IsPrimitive r ∧ ∀ (s : R[X]), p ∣ s ∧ q ∣ s ↔ r ∣ s
[PROOFSTEP]
classical
have h : ∃ (n : ℕ) (r : R[X]), r.natDegree = n ∧ r.IsPrimitive ∧ p ∣ r ∧ q ∣ r :=
  ⟨(p * q).natDegree, p * q, rfl, hp.mul hq, dvd_mul_right _ _, dvd_mul_left _ _⟩
rcases Nat.find_spec h with ⟨r, rdeg, rprim, pr, qr⟩
refine' ⟨r, rprim, fun s => ⟨_, fun rs => ⟨pr.trans rs, qr.trans rs⟩⟩⟩
suffices hs : ∀ (n : ℕ) (s : R[X]), s.natDegree = n → p ∣ s ∧ q ∣ s → r ∣ s
· apply hs s.natDegree s rfl
clear s
by_contra' con
rcases Nat.find_spec con with ⟨s, sdeg, ⟨ps, qs⟩, rs⟩
have s0 : s ≠ 0 := by
  contrapose! rs
  simp [rs]
have hs :=
  Nat.find_min' h
    ⟨_, s.natDegree_primPart, s.isPrimitive_primPart, (hp.dvd_primPart_iff_dvd s0).2 ps,
      (hq.dvd_primPart_iff_dvd s0).2 qs⟩
rw [← rdeg] at hs 
by_cases sC : s.natDegree ≤ 0
· rw [eq_C_of_natDegree_le_zero (le_trans hs sC), isPrimitive_iff_content_eq_one, content_C, normalize_eq_one] at rprim 
  rw [eq_C_of_natDegree_le_zero (le_trans hs sC), ← dvd_content_iff_C_dvd] at rs 
  apply rs rprim.dvd
have hcancel := natDegree_cancelLeads_lt_of_natDegree_le_natDegree hs (lt_of_not_ge sC)
rw [sdeg] at hcancel 
apply Nat.find_min con hcancel
refine' ⟨_, rfl, ⟨dvd_cancelLeads_of_dvd_of_dvd pr ps, dvd_cancelLeads_of_dvd_of_dvd qr qs⟩, fun rcs => rs _⟩
rw [← rprim.dvd_primPart_iff_dvd s0]
rw [cancelLeads, tsub_eq_zero_iff_le.mpr hs, pow_zero, mul_one] at rcs 
have h := dvd_add rcs (Dvd.intro_left (C (leadingCoeff s) * X ^ (natDegree s - natDegree r)) rfl)
have hC0 := rprim.ne_zero
rw [Ne.def, ← leadingCoeff_eq_zero, ← C_eq_zero] at hC0 
rw [sub_add_cancel, ← rprim.dvd_primPart_iff_dvd (mul_ne_zero hC0 s0)] at h 
rcases isUnit_primPart_C r.leadingCoeff with ⟨u, hu⟩
apply h.trans (Associated.symm ⟨u, _⟩).dvd
rw [primPart_mul (mul_ne_zero hC0 s0), hu, mul_comm]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
⊢ ∃ r, IsPrimitive r ∧ ∀ (s : R[X]), p ∣ s ∧ q ∣ s ↔ r ∣ s
[PROOFSTEP]
have h : ∃ (n : ℕ) (r : R[X]), r.natDegree = n ∧ r.IsPrimitive ∧ p ∣ r ∧ q ∣ r :=
  ⟨(p * q).natDegree, p * q, rfl, hp.mul hq, dvd_mul_right _ _, dvd_mul_left _ _⟩
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
⊢ ∃ r, IsPrimitive r ∧ ∀ (s : R[X]), p ∣ s ∧ q ∣ s ↔ r ∣ s
[PROOFSTEP]
rcases Nat.find_spec h with ⟨r, rdeg, rprim, pr, qr⟩
[GOAL]
case intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
⊢ ∃ r, IsPrimitive r ∧ ∀ (s : R[X]), p ∣ s ∧ q ∣ s ↔ r ∣ s
[PROOFSTEP]
refine' ⟨r, rprim, fun s => ⟨_, fun rs => ⟨pr.trans rs, qr.trans rs⟩⟩⟩
[GOAL]
case intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
s : R[X]
⊢ p ∣ s ∧ q ∣ s → r ∣ s
[PROOFSTEP]
suffices hs : ∀ (n : ℕ) (s : R[X]), s.natDegree = n → p ∣ s ∧ q ∣ s → r ∣ s
[GOAL]
case intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
s : R[X]
hs : ∀ (n : ℕ) (s : R[X]), natDegree s = n → p ∣ s ∧ q ∣ s → r ∣ s
⊢ p ∣ s ∧ q ∣ s → r ∣ s
[PROOFSTEP]
apply hs s.natDegree s rfl
[GOAL]
case hs
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
s : R[X]
⊢ ∀ (n : ℕ) (s : R[X]), natDegree s = n → p ∣ s ∧ q ∣ s → r ∣ s
[PROOFSTEP]
clear s
[GOAL]
case hs
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
⊢ ∀ (n : ℕ) (s : R[X]), natDegree s = n → p ∣ s ∧ q ∣ s → r ∣ s
[PROOFSTEP]
by_contra' con
[GOAL]
case hs
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
⊢ False
[PROOFSTEP]
rcases Nat.find_spec con with ⟨s, sdeg, ⟨ps, qs⟩, rs⟩
[GOAL]
case hs.intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
⊢ False
[PROOFSTEP]
have s0 : s ≠ 0 := by
  contrapose! rs
  simp [rs]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
⊢ s ≠ 0
[PROOFSTEP]
contrapose! rs
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
ps : p ∣ s
qs : q ∣ s
rs : s = 0
⊢ r ∣ s
[PROOFSTEP]
simp [rs]
[GOAL]
case hs.intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
⊢ False
[PROOFSTEP]
have hs :=
  Nat.find_min' h
    ⟨_, s.natDegree_primPart, s.isPrimitive_primPart, (hp.dvd_primPart_iff_dvd s0).2 ps,
      (hq.dvd_primPart_iff_dvd s0).2 qs⟩
[GOAL]
case hs.intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : Nat.find h ≤ natDegree s
⊢ False
[PROOFSTEP]
rw [← rdeg] at hs 
[GOAL]
case hs.intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
⊢ False
[PROOFSTEP]
by_cases sC : s.natDegree ≤ 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : natDegree s ≤ 0
⊢ False
[PROOFSTEP]
rw [eq_C_of_natDegree_le_zero (le_trans hs sC), isPrimitive_iff_content_eq_one, content_C, normalize_eq_one] at rprim 
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim✝ : IsPrimitive (↑C (coeff r 0))
rprim : IsUnit (coeff r 0)
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : natDegree s ≤ 0
⊢ False
[PROOFSTEP]
rw [eq_C_of_natDegree_le_zero (le_trans hs sC), ← dvd_content_iff_C_dvd] at rs 
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim✝ : IsPrimitive (↑C (coeff r 0))
rprim : IsUnit (coeff r 0)
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs✝ : ¬↑C (coeff r 0) ∣ s
rs : ¬coeff r 0 ∣ content s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : natDegree s ≤ 0
⊢ False
[PROOFSTEP]
apply rs rprim.dvd
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
⊢ False
[PROOFSTEP]
have hcancel := natDegree_cancelLeads_lt_of_natDegree_le_natDegree hs (lt_of_not_ge sC)
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < natDegree s
⊢ False
[PROOFSTEP]
rw [sdeg] at hcancel 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
⊢ False
[PROOFSTEP]
apply Nat.find_min con hcancel
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
⊢ ∃ s_1, natDegree s_1 = natDegree (cancelLeads r s) ∧ (p ∣ s_1 ∧ q ∣ s_1) ∧ ¬r ∣ s_1
[PROOFSTEP]
refine' ⟨_, rfl, ⟨dvd_cancelLeads_of_dvd_of_dvd pr ps, dvd_cancelLeads_of_dvd_of_dvd qr qs⟩, fun rcs => rs _⟩
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ cancelLeads r s
⊢ r ∣ s
[PROOFSTEP]
rw [← rprim.dvd_primPart_iff_dvd s0]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ cancelLeads r s
⊢ r ∣ primPart s
[PROOFSTEP]
rw [cancelLeads, tsub_eq_zero_iff_le.mpr hs, pow_zero, mul_one] at rcs 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
⊢ r ∣ primPart s
[PROOFSTEP]
have h := dvd_add rcs (Dvd.intro_left (C (leadingCoeff s) * X ^ (natDegree s - natDegree r)) rfl)
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h✝ : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h✝
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
h :
  r ∣
    ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r +
      ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
⊢ r ∣ primPart s
[PROOFSTEP]
have hC0 := rprim.ne_zero
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h✝ : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h✝
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
h :
  r ∣
    ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r +
      ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
hC0 : r ≠ 0
⊢ r ∣ primPart s
[PROOFSTEP]
rw [Ne.def, ← leadingCoeff_eq_zero, ← C_eq_zero] at hC0 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h✝ : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h✝
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
h :
  r ∣
    ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r +
      ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
hC0 : ¬↑C (leadingCoeff r) = 0
⊢ r ∣ primPart s
[PROOFSTEP]
rw [sub_add_cancel, ← rprim.dvd_primPart_iff_dvd (mul_ne_zero hC0 s0)] at h 
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h✝ : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h✝
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
h : r ∣ primPart (↑C (leadingCoeff r) * s)
hC0 : ¬↑C (leadingCoeff r) = 0
⊢ r ∣ primPart s
[PROOFSTEP]
rcases isUnit_primPart_C r.leadingCoeff with ⟨u, hu⟩
[GOAL]
case neg.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h✝ : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h✝
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
h : r ∣ primPart (↑C (leadingCoeff r) * s)
hC0 : ¬↑C (leadingCoeff r) = 0
u : R[X]ˣ
hu : ↑u = primPart (↑C (leadingCoeff r))
⊢ r ∣ primPart s
[PROOFSTEP]
apply h.trans (Associated.symm ⟨u, _⟩).dvd
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hp : IsPrimitive p
hq : IsPrimitive q
h✝ : ∃ n r, natDegree r = n ∧ IsPrimitive r ∧ p ∣ r ∧ q ∣ r
r : R[X]
rdeg : natDegree r = Nat.find h✝
rprim : IsPrimitive r
pr : p ∣ r
qr : q ∣ r
con : ∃ n s, natDegree s = n ∧ (p ∣ s ∧ q ∣ s) ∧ ¬r ∣ s
s : R[X]
sdeg : natDegree s = Nat.find con
rs : ¬r ∣ s
ps : p ∣ s
qs : q ∣ s
s0 : s ≠ 0
hs : natDegree r ≤ natDegree s
sC : ¬natDegree s ≤ 0
hcancel : natDegree (cancelLeads r s) < Nat.find con
rcs : r ∣ ↑C (leadingCoeff r) * s - ↑C (leadingCoeff s) * X ^ (natDegree s - natDegree r) * r
h : r ∣ primPart (↑C (leadingCoeff r) * s)
hC0 : ¬↑C (leadingCoeff r) = 0
u : R[X]ˣ
hu : ↑u = primPart (↑C (leadingCoeff r))
⊢ primPart s * ↑u = primPart (↑C (leadingCoeff r) * s)
[PROOFSTEP]
rw [primPart_mul (mul_ne_zero hC0 s0), hu, mul_comm]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
⊢ p ∣ q ↔ content p ∣ content q ∧ primPart p ∣ primPart q
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
⊢ p ∣ q → content p ∣ content q ∧ primPart p ∣ primPart q
[PROOFSTEP]
intro h
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
⊢ content p ∣ content q ∧ primPart p ∣ primPart q → p ∣ q
[PROOFSTEP]
intro h
[GOAL]
case mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
h : p ∣ q
⊢ content p ∣ content q ∧ primPart p ∣ primPart q
[PROOFSTEP]
rcases h with ⟨r, rfl⟩
[GOAL]
case mp.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p r : R[X]
hq : p * r ≠ 0
⊢ content p ∣ content (p * r) ∧ primPart p ∣ primPart (p * r)
[PROOFSTEP]
rw [content_mul, p.isPrimitive_primPart.dvd_primPart_iff_dvd hq]
[GOAL]
case mp.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p r : R[X]
hq : p * r ≠ 0
⊢ content p ∣ content p * content r ∧ primPart p ∣ p * r
[PROOFSTEP]
exact ⟨Dvd.intro _ rfl, p.primPart_dvd.trans (Dvd.intro _ rfl)⟩
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
h : content p ∣ content q ∧ primPart p ∣ primPart q
⊢ p ∣ q
[PROOFSTEP]
rw [p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart]
[GOAL]
case mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
h : content p ∣ content q ∧ primPart p ∣ primPart q
⊢ ↑C (content p) * primPart p ∣ ↑C (content q) * primPart q
[PROOFSTEP]
exact mul_dvd_mul (RingHom.map_dvd C h.1) h.2
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
⊢ ∃ c, ∀ (d : R[X]), p ∣ d ∧ q ∣ d ↔ c ∣ d
[PROOFSTEP]
rcases exists_primitive_lcm_of_isPrimitive p.isPrimitive_primPart q.isPrimitive_primPart with ⟨r, rprim, hr⟩
[GOAL]
case intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
⊢ ∃ c, ∀ (d : R[X]), p ∣ d ∧ q ∣ d ↔ c ∣ d
[PROOFSTEP]
refine' ⟨C (lcm p.content q.content) * r, fun s => _⟩
[GOAL]
case intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
by_cases hs : s = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : s = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
simp [hs]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
by_cases hpq : C (lcm p.content q.content) = 0
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ↑C (lcm (content p) (content q)) = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
rw [C_eq_zero, lcm_eq_zero_iff, content_eq_zero_iff, content_eq_zero_iff] at hpq 
[GOAL]
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : p = 0 ∨ q = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
rcases hpq with (hpq | hpq)
[GOAL]
case pos.inl
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : p = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
simp [hpq, hs]
[GOAL]
case pos.inr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : q = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
simp [hpq, hs]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ¬↑C (lcm (content p) (content q)) = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
iterate 3 rw [dvd_iff_content_dvd_content_and_primPart_dvd_primPart hs]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ¬↑C (lcm (content p) (content q)) = 0
⊢ p ∣ s ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
rw [dvd_iff_content_dvd_content_and_primPart_dvd_primPart hs]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ¬↑C (lcm (content p) (content q)) = 0
⊢ (content p ∣ content s ∧ primPart p ∣ primPart s) ∧ q ∣ s ↔ ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
rw [dvd_iff_content_dvd_content_and_primPart_dvd_primPart hs]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ¬↑C (lcm (content p) (content q)) = 0
⊢ (content p ∣ content s ∧ primPart p ∣ primPart s) ∧ content q ∣ content s ∧ primPart q ∣ primPart s ↔
    ↑C (lcm (content p) (content q)) * r ∣ s
[PROOFSTEP]
rw [dvd_iff_content_dvd_content_and_primPart_dvd_primPart hs]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ¬↑C (lcm (content p) (content q)) = 0
⊢ (content p ∣ content s ∧ primPart p ∣ primPart s) ∧ content q ∣ content s ∧ primPart q ∣ primPart s ↔
    content (↑C (lcm (content p) (content q)) * r) ∣ content s ∧
      primPart (↑C (lcm (content p) (content q)) * r) ∣ primPart s
[PROOFSTEP]
rw [content_mul, rprim.content_eq_one, mul_one, content_C, normalize_lcm, lcm_dvd_iff,
  primPart_mul (mul_ne_zero hpq rprim.ne_zero), rprim.primPart_eq,
  IsUnit.mul_left_dvd _ _ _ (isUnit_primPart_C (lcm p.content q.content)), ← hr s.primPart]
[GOAL]
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q r : R[X]
rprim : IsPrimitive r
hr : ∀ (s : R[X]), primPart p ∣ s ∧ primPart q ∣ s ↔ r ∣ s
s : R[X]
hs : ¬s = 0
hpq : ¬↑C (lcm (content p) (content q)) = 0
⊢ (content p ∣ content s ∧ primPart p ∣ primPart s) ∧ content q ∣ content s ∧ primPart q ∣ primPart s ↔
    (content p ∣ content s ∧ content q ∣ content s) ∧ primPart p ∣ primPart s ∧ primPart q ∣ primPart s
[PROOFSTEP]
tauto
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp : p ≠ 0
q : R[X]
⊢ degree (gcd p q) ≤ degree p
[PROOFSTEP]
have := natDegree_le_iff_degree_le.mp (natDegree_le_of_dvd (gcd_dvd_left p q) hp)
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
hp : p ≠ 0
q : R[X]
this : degree (gcd p q) ≤ ↑(natDegree p)
⊢ degree (gcd p q) ≤ degree p
[PROOFSTEP]
rwa [degree_eq_natDegree hp]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
⊢ degree (gcd p q) ≤ degree q
[PROOFSTEP]
rw [gcd_comm]
[GOAL]
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p q : R[X]
hq : q ≠ 0
⊢ degree (gcd q p) ≤ degree q
[PROOFSTEP]
exact degree_gcd_le_left hq p
