l3lab/ntp-mathlib huggingface dataset:
theorem _root_.Polynomial.ker_mapRingHom (f : R →+* S) :
    LinearMap.ker (Polynomial.mapRingHom f).toSemilinearMap = f.ker.map (C : R →+* R[X]) := by
  ext
  simp only [LinearMap.mem_ker, RingHom.toSemilinearMap_apply, coe_mapRingHom]
  rw [mem_map_C_iff, Polynomial.ext_iff]
  simp_rw [RingHom.mem_ker f]
  

Proof state:
case h
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
f : R →+* S
x✝ : R[X]
⊢ (∀ (n : ℕ), coeff (OneHom.toFun (↑↑(mapRingHom f)) x✝) n = coeff 0 n) ↔ ∀ (n : ℕ), f (coeff x✝ n) = 0

Next tactic:
simp
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
x : R
⊢ x ∈ leadingCoeffNth I n ↔ ∃ p ∈ I, degree p ≤ ↑n ∧ Polynomial.leadingCoeff p = x

Next tactic:
simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
x : R
⊢ (∃ y, (degree y ≤ ↑n ∧ y ∈ ofPolynomial I) ∧ coeff y n = x) ↔ ∃ p ∈ I, degree p ≤ ↑n ∧ Polynomial.leadingCoeff p = x

Next tactic:
constructor
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · 

Proof state:
case mp
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
x : R
⊢ (∃ y, (degree y ≤ ↑n ∧ y ∈ ofPolynomial I) ∧ coeff y n = x) → ∃ p ∈ I, degree p ≤ ↑n ∧ Polynomial.leadingCoeff p = x

Next tactic:
rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    

Proof state:
case mp.intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpdeg : degree p ≤ ↑n
hpI : p ∈ ofPolynomial I
⊢ ∃ p_1 ∈ I, degree p_1 ≤ ↑n ∧ Polynomial.leadingCoeff p_1 = coeff p n

Next tactic:
rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · 

Proof state:
case mp.intro.intro.intro.inl
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpdeg✝ : degree p ≤ ↑n
hpI : p ∈ ofPolynomial I
hpdeg : degree p < ↑n
⊢ ∃ p_1 ∈ I, degree p_1 ≤ ↑n ∧ Polynomial.leadingCoeff p_1 = coeff p n

Next tactic:
refine' ⟨0, I.zero_mem, bot_le, _⟩
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      

Proof state:
case mp.intro.intro.intro.inl
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpdeg✝ : degree p ≤ ↑n
hpI : p ∈ ofPolynomial I
hpdeg : degree p < ↑n
⊢ Polynomial.leadingCoeff 0 = coeff p n

Next tactic:
rw [leadingCoeff_zero, eq_comm]
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      

Proof state:
case mp.intro.intro.intro.inl
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpdeg✝ : degree p ≤ ↑n
hpI : p ∈ ofPolynomial I
hpdeg : degree p < ↑n
⊢ coeff p n = 0

Next tactic:
exact coeff_eq_zero_of_degree_lt hpdeg
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · 

Proof state:
case mp.intro.intro.intro.inr
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpdeg✝ : degree p ≤ ↑n
hpI : p ∈ ofPolynomial I
hpdeg : degree p = ↑n
⊢ ∃ p_1 ∈ I, degree p_1 ≤ ↑n ∧ Polynomial.leadingCoeff p_1 = coeff p n

Next tactic:
refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      

Proof state:
case mp.intro.intro.intro.inr
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpdeg✝ : degree p ≤ ↑n
hpI : p ∈ ofPolynomial I
hpdeg : degree p = ↑n
⊢ Polynomial.leadingCoeff p = coeff p n

Next tactic:
rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · 

Proof state:
case mpr
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
x : R
⊢ (∃ p ∈ I, degree p ≤ ↑n ∧ Polynomial.leadingCoeff p = x) → ∃ y, (degree y ≤ ↑n ∧ y ∈ ofPolynomial I) ∧ coeff y n = x

Next tactic:
rintro ⟨p, hpI, hpdeg, rfl⟩
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · rintro ⟨p, hpI, hpdeg, rfl⟩
    

Proof state:
case mpr.intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑n
⊢ ∃ y, (degree y ≤ ↑n ∧ y ∈ ofPolynomial I) ∧ coeff y n = Polynomial.leadingCoeff p

Next tactic:
have : natDegree p + (n - natDegree p) = n :=
      add_tsub_cancel_of_le (natDegree_le_of_degree_le hpdeg)
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · rintro ⟨p, hpI, hpdeg, rfl⟩
    have : natDegree p + (n - natDegree p) = n :=
      add_tsub_cancel_of_le (natDegree_le_of_degree_le hpdeg)
    

Proof state:
case mpr.intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑n
this : natDegree p + (n - natDegree p) = n
⊢ ∃ y, (degree y ≤ ↑n ∧ y ∈ ofPolynomial I) ∧ coeff y n = Polynomial.leadingCoeff p

Next tactic:
refine' ⟨p * X ^ (n - natDegree p), ⟨_, I.mul_mem_right _ hpI⟩, _⟩
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · rintro ⟨p, hpI, hpdeg, rfl⟩
    have : natDegree p + (n - natDegree p) = n :=
      add_tsub_cancel_of_le (natDegree_le_of_degree_le hpdeg)
    refine' ⟨p * X ^ (n - natDegree p), ⟨_, I.mul_mem_right _ hpI⟩, _⟩
    · 

Proof state:
case mpr.intro.intro.intro.refine'_1
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑n
this : natDegree p + (n - natDegree p) = n
⊢ degree (p * X ^ (n - natDegree p)) ≤ ↑n

Next tactic:
apply le_trans (degree_mul_le _ _) _
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · rintro ⟨p, hpI, hpdeg, rfl⟩
    have : natDegree p + (n - natDegree p) = n :=
      add_tsub_cancel_of_le (natDegree_le_of_degree_le hpdeg)
    refine' ⟨p * X ^ (n - natDegree p), ⟨_, I.mul_mem_right _ hpI⟩, _⟩
    · apply le_trans (degree_mul_le _ _) _
      

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑n
this : natDegree p + (n - natDegree p) = n
⊢ degree p + degree (X ^ (n - natDegree p)) ≤ ↑n

Next tactic:
apply le_trans (add_le_add degree_le_natDegree (degree_X_pow_le _)) _
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · rintro ⟨p, hpI, hpdeg, rfl⟩
    have : natDegree p + (n - natDegree p) = n :=
      add_tsub_cancel_of_le (natDegree_le_of_degree_le hpdeg)
    refine' ⟨p * X ^ (n - natDegree p), ⟨_, I.mul_mem_right _ hpI⟩, _⟩
    · apply le_trans (degree_mul_le _ _) _
      apply le_trans (add_le_add degree_le_natDegree (degree_X_pow_le _)) _
      

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑n
this : natDegree p + (n - natDegree p) = n
⊢ ↑(natDegree p) + ↑(n - natDegree p) ≤ ↑n

Next tactic:
rw [← Nat.cast_add, this]
theorem mem_leadingCoeffNth (n : ℕ) (x) :
    x ∈ I.leadingCoeffNth n ↔ ∃ p ∈ I, degree p ≤ n ∧ p.leadingCoeff = x := by
  simp only [leadingCoeffNth, degreeLE, Submodule.mem_map, lcoeff_apply, Submodule.mem_inf,
    mem_degreeLE]
  constructor
  · rintro ⟨p, ⟨hpdeg, hpI⟩, rfl⟩
    rcases lt_or_eq_of_le hpdeg with hpdeg | hpdeg
    · refine' ⟨0, I.zero_mem, bot_le, _⟩
      rw [leadingCoeff_zero, eq_comm]
      exact coeff_eq_zero_of_degree_lt hpdeg
    · refine' ⟨p, hpI, le_of_eq hpdeg, _⟩
      rw [Polynomial.leadingCoeff, natDegree, hpdeg, Nat.cast_withBot, WithBot.unbot'_coe]
  · rintro ⟨p, hpI, hpdeg, rfl⟩
    have : natDegree p + (n - natDegree p) = n :=
      add_tsub_cancel_of_le (natDegree_le_of_degree_le hpdeg)
    refine' ⟨p * X ^ (n - natDegree p), ⟨_, I.mul_mem_right _ hpI⟩, _⟩
    · apply le_trans (degree_mul_le _ _) _
      apply le_trans (add_le_add degree_le_natDegree (degree_X_pow_le _)) _
      rw [← Nat.cast_add, this]
    · 

Proof state:
case mpr.intro.intro.intro.refine'_2
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
n : ℕ
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑n
this : natDegree p + (n - natDegree p) = n
⊢ coeff (p * X ^ (n - natDegree p)) n = Polynomial.leadingCoeff p

Next tactic:
rw [Polynomial.leadingCoeff, ← coeff_mul_X_pow p (n - natDegree p), this]
theorem mem_leadingCoeffNth_zero (x) : x ∈ I.leadingCoeffNth 0 ↔ C x ∈ I :=
  (mem_leadingCoeffNth _ _ _).trans
    ⟨fun ⟨p, hpI, hpdeg, hpx⟩ => by
      

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
x✝ : ∃ p ∈ I, degree p ≤ ↑0 ∧ Polynomial.leadingCoeff p = x
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑0
hpx : Polynomial.leadingCoeff p = x
⊢ C x ∈ I

Next tactic:
rwa [← hpx, Polynomial.leadingCoeff,
        Nat.eq_zero_of_le_zero (natDegree_le_of_degree_le hpdeg), ← eq_C_of_degree_le_zero hpdeg]
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
⊢ leadingCoeffNth I m ≤ leadingCoeffNth I n

Next tactic:
intro r hr
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  intro r hr
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
r : R
hr : r ∈ leadingCoeffNth I m
⊢ r ∈ leadingCoeffNth I n

Next tactic:
simp only [SetLike.mem_coe, mem_leadingCoeffNth] at hr ⊢
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  intro r hr
  simp only [SetLike.mem_coe, mem_leadingCoeffNth] at hr ⊢
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
r : R
hr : ∃ p ∈ I, degree p ≤ ↑m ∧ Polynomial.leadingCoeff p = r
⊢ ∃ p ∈ I, degree p ≤ ↑n ∧ Polynomial.leadingCoeff p = r

Next tactic:
rcases hr with ⟨p, hpI, hpdeg, rfl⟩
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  intro r hr
  simp only [SetLike.mem_coe, mem_leadingCoeffNth] at hr ⊢
  rcases hr with ⟨p, hpI, hpdeg, rfl⟩
  

Proof state:
case intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑m
⊢ ∃ p_1 ∈ I, degree p_1 ≤ ↑n ∧ Polynomial.leadingCoeff p_1 = Polynomial.leadingCoeff p

Next tactic:
refine' ⟨p * X ^ (n - m), I.mul_mem_right _ hpI, _, leadingCoeff_mul_X_pow⟩
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  intro r hr
  simp only [SetLike.mem_coe, mem_leadingCoeffNth] at hr ⊢
  rcases hr with ⟨p, hpI, hpdeg, rfl⟩
  refine' ⟨p * X ^ (n - m), I.mul_mem_right _ hpI, _, leadingCoeff_mul_X_pow⟩
  

Proof state:
case intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑m
⊢ degree (p * X ^ (n - m)) ≤ ↑n

Next tactic:
refine' le_trans (degree_mul_le _ _) _
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  intro r hr
  simp only [SetLike.mem_coe, mem_leadingCoeffNth] at hr ⊢
  rcases hr with ⟨p, hpI, hpdeg, rfl⟩
  refine' ⟨p * X ^ (n - m), I.mul_mem_right _ hpI, _, leadingCoeff_mul_X_pow⟩
  refine' le_trans (degree_mul_le _ _) _
  

Proof state:
case intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑m
⊢ degree p + degree (X ^ (n - m)) ≤ ↑n

Next tactic:
refine' le_trans (add_le_add hpdeg (degree_X_pow_le _)) _
theorem leadingCoeffNth_mono {m n : ℕ} (H : m ≤ n) : I.leadingCoeffNth m ≤ I.leadingCoeffNth n := by
  intro r hr
  simp only [SetLike.mem_coe, mem_leadingCoeffNth] at hr ⊢
  rcases hr with ⟨p, hpI, hpdeg, rfl⟩
  refine' ⟨p * X ^ (n - m), I.mul_mem_right _ hpI, _, leadingCoeff_mul_X_pow⟩
  refine' le_trans (degree_mul_le _ _) _
  refine' le_trans (add_le_add hpdeg (degree_X_pow_le _)) _
  

Proof state:
case intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
m n : ℕ
H : m ≤ n
p : R[X]
hpI : p ∈ I
hpdeg : degree p ≤ ↑m
⊢ ↑m + ↑(n - m) ≤ ↑n

Next tactic:
rw [← Nat.cast_add, add_tsub_cancel_of_le H]
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ x ∈ leadingCoeff I ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x

Next tactic:
rw [leadingCoeff, Submodule.mem_iSup_of_directed]
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ (∃ i, x ∈ leadingCoeffNth I i) ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x
case H
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ Directed (fun x x_1 => x ≤ x_1) fun n => leadingCoeffNth I n

Next tactic:
simp only [mem_leadingCoeffNth]
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · 

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ (∃ i, ∃ p ∈ I, degree p ≤ ↑i ∧ Polynomial.leadingCoeff p = x) ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x

Next tactic:
constructor
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · constructor
    · 

Proof state:
case mp
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ (∃ i, ∃ p ∈ I, degree p ≤ ↑i ∧ Polynomial.leadingCoeff p = x) → ∃ p ∈ I, Polynomial.leadingCoeff p = x

Next tactic:
rintro ⟨i, p, hpI, _, rfl⟩
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · constructor
    · rintro ⟨i, p, hpI, _, rfl⟩
      

Proof state:
case mp.intro.intro.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
i : ℕ
p : R[X]
hpI : p ∈ I
left✝ : degree p ≤ ↑i
⊢ ∃ p_1 ∈ I, Polynomial.leadingCoeff p_1 = Polynomial.leadingCoeff p

Next tactic:
exact ⟨p, hpI, rfl⟩
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · constructor
    · rintro ⟨i, p, hpI, _, rfl⟩
      exact ⟨p, hpI, rfl⟩
    

Proof state:
case mpr
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ (∃ p ∈ I, Polynomial.leadingCoeff p = x) → ∃ i, ∃ p ∈ I, degree p ≤ ↑i ∧ Polynomial.leadingCoeff p = x

Next tactic:
rintro ⟨p, hpI, rfl⟩
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · constructor
    · rintro ⟨i, p, hpI, _, rfl⟩
      exact ⟨p, hpI, rfl⟩
    rintro ⟨p, hpI, rfl⟩
    

Proof state:
case mpr.intro.intro
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
p : R[X]
hpI : p ∈ I
⊢ ∃ i, ∃ p_1 ∈ I, degree p_1 ≤ ↑i ∧ Polynomial.leadingCoeff p_1 = Polynomial.leadingCoeff p

Next tactic:
exact ⟨natDegree p, p, hpI, degree_le_natDegree, rfl⟩
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · constructor
    · rintro ⟨i, p, hpI, _, rfl⟩
      exact ⟨p, hpI, rfl⟩
    rintro ⟨p, hpI, rfl⟩
    exact ⟨natDegree p, p, hpI, degree_le_natDegree, rfl⟩
  

Proof state:
case H
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
⊢ Directed (fun x x_1 => x ≤ x_1) fun n => leadingCoeffNth I n

Next tactic:
intro i j
theorem mem_leadingCoeff (x) : x ∈ I.leadingCoeff ↔ ∃ p ∈ I, Polynomial.leadingCoeff p = x := by
  rw [leadingCoeff, Submodule.mem_iSup_of_directed]
  simp only [mem_leadingCoeffNth]
  · constructor
    · rintro ⟨i, p, hpI, _, rfl⟩
      exact ⟨p, hpI, rfl⟩
    rintro ⟨p, hpI, rfl⟩
    exact ⟨natDegree p, p, hpI, degree_le_natDegree, rfl⟩
  intro i j
  

Proof state:
case H
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I : Ideal R[X]
x : R
i j : ℕ
⊢ ∃ z,
    (fun x x_1 => x ≤ x_1) ((fun n => leadingCoeffNth I n) i) ((fun n => leadingCoeffNth I n) z) ∧
      (fun x x_1 => x ≤ x_1) ((fun n => leadingCoeffNth I n) j) ((fun n => leadingCoeffNth I n) z)

Next tactic:
exact
    ⟨i + j, I.leadingCoeffNth_mono (Nat.le_add_right _ _),
      I.leadingCoeffNth_mono (Nat.le_add_left _ _)⟩
/-- If `I` is an ideal, and `pᵢ` is a finite family of polynomials each satisfying
`∀ k, (pᵢ)ₖ ∈ Iⁿⁱ⁻ᵏ` for some `nᵢ`, then `p = ∏ pᵢ` also satisfies `∀ k, pₖ ∈ Iⁿ⁻ᵏ` with `n = ∑ nᵢ`.
-/
theorem _root_.Polynomial.coeff_prod_mem_ideal_pow_tsub {ι : Type*} (s : Finset ι) (f : ι → R[X])
    (I : Ideal R) (n : ι → ℕ) (h : ∀ i ∈ s, ∀ (k), (f i).coeff k ∈ I ^ (n i - k)) (k : ℕ) :
    (s.prod f).coeff k ∈ I ^ (s.sum n - k) := by
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Semiring S
I✝ : Ideal R[X]
ι : Type u_2
s : Finset ι
f : ι → R[X]
I : Ideal R
n : ι → ℕ
h : ∀ i ∈ s, ∀ (k : ℕ), coeff (f i) k ∈ I ^ (n i - k)
k : ℕ
⊢ coeff (Finset.prod s f) k ∈ I ^ (Finset.sum s n - k)

Next tactic:
classical
    induction' s using Finset.induction with a s ha hs generalizing k
    · rw [sum_empty, prod_empty, coeff_one, zero_tsub, pow_zero, Ideal.one_eq_top]
      exact Submodule.mem_top
    · rw [sum_insert ha, prod_insert ha, coeff_mul]
      apply sum_mem
      rintro ⟨i, j⟩ e
      obtain rfl : i + j = k := mem_antidiagonal.mp e
      apply Ideal.pow_le_pow_right add_tsub_add_le_tsub_add_tsub
      rw [pow_add]
      exact
        Ideal.mul_mem_mul (h _ (Finset.mem_insert.mpr <| Or.inl rfl) _)
          (hs (fun i hi k => h _ (Finset.mem_insert.mpr <| Or.inr hi) _) j)