l3lab/ntp-mathlib huggingface dataset:
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      exact not_lt_of_ge degree_le_natDegree h
    · have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm
      

Proof state:
case neg.inr.inl
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : ↑n = degree f
this : natDegree f = n
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
rw [coeff_C_mul, coeff_X_pow, if_pos this.symm, mul_one, leadingCoeff, this, coeff_map]
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      exact not_lt_of_ge degree_le_natDegree h
    · have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm
      rw [coeff_C_mul, coeff_X_pow, if_pos this.symm, mul_one, leadingCoeff, this, coeff_map]
    · 

Proof state:
case neg.inr.inr
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : degree f < ↑n
⊢ coeff (map (mk P) f) n = coeff (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) n

Next tactic:
rw [coeff_eq_zero_of_degree_lt, coeff_eq_zero_of_degree_lt]
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      exact not_lt_of_ge degree_le_natDegree h
    · have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm
      rw [coeff_C_mul, coeff_X_pow, if_pos this.symm, mul_one, leadingCoeff, this, coeff_map]
    · rw [coeff_eq_zero_of_degree_lt, coeff_eq_zero_of_degree_lt]
      · 

Proof state:
case neg.inr.inr
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : degree f < ↑n
⊢ degree (C ((mk P) (leadingCoeff f)) * X ^ natDegree f) < ↑n

Next tactic:
refine' lt_of_le_of_lt (degree_C_mul_X_pow_le _ _) _
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      exact not_lt_of_ge degree_le_natDegree h
    · have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm
      rw [coeff_C_mul, coeff_X_pow, if_pos this.symm, mul_one, leadingCoeff, this, coeff_map]
    · rw [coeff_eq_zero_of_degree_lt, coeff_eq_zero_of_degree_lt]
      · refine' lt_of_le_of_lt (degree_C_mul_X_pow_le _ _) _
        

Proof state:
case neg.inr.inr
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : degree f < ↑n
⊢ ↑(natDegree f) < ↑n

Next tactic:
rwa [← degree_eq_natDegree hf0]
theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R}
    (hfP : ∀ n : ℕ, ↑n < f.degree → f.coeff n ∈ P) :
    map (mk P) f = C ((mk P) f.leadingCoeff) * X ^ f.natDegree :=
  Polynomial.ext fun n => by
    by_cases hf0 : f = 0
    · simp [hf0]
    rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h)
    · erw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg,
        mul_zero]
      rintro rfl
      exact not_lt_of_ge degree_le_natDegree h
    · have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm
      rw [coeff_C_mul, coeff_X_pow, if_pos this.symm, mul_one, leadingCoeff, this, coeff_map]
    · rw [coeff_eq_zero_of_degree_lt, coeff_eq_zero_of_degree_lt]
      · refine' lt_of_le_of_lt (degree_C_mul_X_pow_le _ _) _
        rwa [← degree_eq_natDegree hf0]
      · 

Proof state:
case neg.inr.inr
R : Type u_1
inst✝ : CommRing R
f : R[X]
P : Ideal R
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
n : ℕ
hf0 : ¬f = 0
h : degree f < ↑n
⊢ degree (map (mk P) f) < ↑n

Next tactic:
exact lt_of_le_of_lt (degree_map_le _ _) h
theorem le_natDegree_of_map_eq_mul_X_pow {n : ℕ} {P : Ideal R} (hP : P.IsPrime) {q : R[X]}
    {c : Polynomial (R ⧸ P)} (hq : map (mk P) q = c * X ^ n) (hc0 : c.degree = 0) :
    n ≤ q.natDegree :=
  Nat.cast_le.1
    (calc
      ↑n = degree (q.map (mk P)) := by
        

Proof state:
R : Type u_1
inst✝ : CommRing R
n : ℕ
P : Ideal R
hP : Ideal.IsPrime P
q : R[X]
c : (R ⧸ P)[X]
hq : map (mk P) q = c * X ^ n
hc0 : degree c = 0
⊢ ↑n = degree (map (mk P) q)

Next tactic:
rw [hq, degree_mul, hc0, zero_add, degree_pow, degree_X, nsmul_one]
theorem eval_zero_mem_ideal_of_eq_mul_X_pow {n : ℕ} {P : Ideal R} {q : R[X]}
    {c : Polynomial (R ⧸ P)} (hq : map (mk P) q = c * X ^ n) (hn0 : 0 < n) : eval 0 q ∈ P := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
n : ℕ
P : Ideal R
q : R[X]
c : (R ⧸ P)[X]
hq : map (mk P) q = c * X ^ n
hn0 : 0 < n
⊢ eval 0 q ∈ P

Next tactic:
rw [← coeff_zero_eq_eval_zero, ← eq_zero_iff_mem, ← coeff_map, hq,
    coeff_zero_eq_eval_zero, eval_mul, eval_pow, eval_X, zero_pow hn0, mul_zero]
theorem isUnit_of_natDegree_eq_zero_of_isPrimitive {p q : R[X]}
    --Porting note: stated using `IsPrimitive` which is defeq to old statement.
    (hu : IsPrimitive (p * q)) (hpm : p.natDegree = 0) : IsUnit p := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
p q : R[X]
hu : IsPrimitive (p * q)
hpm : natDegree p = 0
⊢ IsUnit p

Next tactic:
rw [eq_C_of_degree_le_zero (natDegree_eq_zero_iff_degree_le_zero.1 hpm), isUnit_C]
theorem isUnit_of_natDegree_eq_zero_of_isPrimitive {p q : R[X]}
    --Porting note: stated using `IsPrimitive` which is defeq to old statement.
    (hu : IsPrimitive (p * q)) (hpm : p.natDegree = 0) : IsUnit p := by
  rw [eq_C_of_degree_le_zero (natDegree_eq_zero_iff_degree_le_zero.1 hpm), isUnit_C]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
p q : R[X]
hu : IsPrimitive (p * q)
hpm : natDegree p = 0
⊢ IsUnit (coeff p 0)

Next tactic:
refine' hu _ _
theorem isUnit_of_natDegree_eq_zero_of_isPrimitive {p q : R[X]}
    --Porting note: stated using `IsPrimitive` which is defeq to old statement.
    (hu : IsPrimitive (p * q)) (hpm : p.natDegree = 0) : IsUnit p := by
  rw [eq_C_of_degree_le_zero (natDegree_eq_zero_iff_degree_le_zero.1 hpm), isUnit_C]
  refine' hu _ _
  

Proof state:
R : Type u_1
inst✝ : CommRing R
p q : R[X]
hu : IsPrimitive (p * q)
hpm : natDegree p = 0
⊢ C (coeff p 0) ∣ p * q

Next tactic:
rw [← eq_C_of_degree_le_zero (natDegree_eq_zero_iff_degree_le_zero.1 hpm)]
theorem isUnit_of_natDegree_eq_zero_of_isPrimitive {p q : R[X]}
    --Porting note: stated using `IsPrimitive` which is defeq to old statement.
    (hu : IsPrimitive (p * q)) (hpm : p.natDegree = 0) : IsUnit p := by
  rw [eq_C_of_degree_le_zero (natDegree_eq_zero_iff_degree_le_zero.1 hpm), isUnit_C]
  refine' hu _ _
  rw [← eq_C_of_degree_le_zero (natDegree_eq_zero_iff_degree_le_zero.1 hpm)]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
p q : R[X]
hu : IsPrimitive (p * q)
hpm : natDegree p = 0
⊢ p ∣ p * q

Next tactic:
exact dvd_mul_right _ _
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by 

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f : R[X]
P : Ideal R
hP : Ideal.IsPrime P
hfl : leadingCoeff f ∉ P
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
hfd0 : 0 < degree f
h0 : coeff f 0 ∉ P ^ 2
hu : IsPrimitive f
x✝ : f = 0
⊢ False

Next tactic:
simp_all only [not_true, Submodule.zero_mem, coeff_zero]
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by 

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f : R[X]
P : Ideal R
hP : Ideal.IsPrime P
hfl : leadingCoeff f ∉ P
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
hfd0✝ : 0 < degree f
h0 : coeff f 0 ∉ P ^ 2
hu : IsPrimitive f
hf0 : f ≠ 0
hf : map (mk P) f = C ((mk P) (leadingCoeff f)) * X ^ natDegree f
hfd0 : 0 < natDegree f
h : degree f = 0
⊢ False

Next tactic:
simp_all only [lt_irrefl]
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f : R[X]
P : Ideal R
hP : Ideal.IsPrime P
hfl : leadingCoeff f ∉ P
hfP : ∀ (n : ℕ), ↑n < degree f → coeff f n ∈ P
hfd0✝ : 0 < degree f
h0 : coeff f 0 ∉ P ^ 2
hu : IsPrimitive f
hf0 : f ≠ 0
hf : map (mk P) f = C ((mk P) (leadingCoeff f)) * X ^ natDegree f
hfd0 : 0 < natDegree f
⊢ ∀ (a b : R[X]), f = a * b → IsUnit a ∨ IsUnit b

Next tactic:
rintro p q rfl
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) (p * q) = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
⊢ IsUnit p ∨ IsUnit q

Next tactic:
rw [Polynomial.map_mul] at hf
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    rw [Polynomial.map_mul] at hf
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) p * map (mk P) q = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
⊢ IsUnit p ∨ IsUnit q

Next tactic:
rcases mul_eq_mul_prime_pow
        (show Prime (X : Polynomial (R ⧸ P)) from monic_X.prime_of_degree_eq_one degree_X) hf with
      ⟨m, n, b, c, hmnd, hbc, hp, hq⟩
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    rw [Polynomial.map_mul] at hf
    rcases mul_eq_mul_prime_pow
        (show Prime (X : Polynomial (R ⧸ P)) from monic_X.prime_of_degree_eq_one degree_X) hf with
      ⟨m, n, b, c, hmnd, hbc, hp, hq⟩
    

Proof state:
case intro.intro.intro.intro.intro.intro.intro
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) p * map (mk P) q = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
m n : ℕ
b c : (R ⧸ P)[X]
hmnd : m + n = natDegree (p * q)
hbc : C ((mk P) (leadingCoeff (p * q))) = b * c
hp : map (mk P) p = b * X ^ m
hq : map (mk P) q = c * X ^ n
⊢ IsUnit p ∨ IsUnit q

Next tactic:
have hmn : 0 < m → 0 < n → False := by
      intro hm0 hn0
      refine' h0 _
      rw [coeff_zero_eq_eval_zero, eval_mul, sq]
      exact
        Ideal.mul_mem_mul (eval_zero_mem_ideal_of_eq_mul_X_pow hp hm0)
          (eval_zero_mem_ideal_of_eq_mul_X_pow hq hn0)
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    rw [Polynomial.map_mul] at hf
    rcases mul_eq_mul_prime_pow
        (show Prime (X : Polynomial (R ⧸ P)) from monic_X.prime_of_degree_eq_one degree_X) hf with
      ⟨m, n, b, c, hmnd, hbc, hp, hq⟩
    have hmn : 0 < m → 0 < n → False := by
      

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) p * map (mk P) q = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
m n : ℕ
b c : (R ⧸ P)[X]
hmnd : m + n = natDegree (p * q)
hbc : C ((mk P) (leadingCoeff (p * q))) = b * c
hp : map (mk P) p = b * X ^ m
hq : map (mk P) q = c * X ^ n
⊢ 0 < m → 0 < n → False

Next tactic:
intro hm0 hn0
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    rw [Polynomial.map_mul] at hf
    rcases mul_eq_mul_prime_pow
        (show Prime (X : Polynomial (R ⧸ P)) from monic_X.prime_of_degree_eq_one degree_X) hf with
      ⟨m, n, b, c, hmnd, hbc, hp, hq⟩
    have hmn : 0 < m → 0 < n → False := by
      intro hm0 hn0
      

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) p * map (mk P) q = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
m n : ℕ
b c : (R ⧸ P)[X]
hmnd : m + n = natDegree (p * q)
hbc : C ((mk P) (leadingCoeff (p * q))) = b * c
hp : map (mk P) p = b * X ^ m
hq : map (mk P) q = c * X ^ n
hm0 : 0 < m
hn0 : 0 < n
⊢ False

Next tactic:
refine' h0 _
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    rw [Polynomial.map_mul] at hf
    rcases mul_eq_mul_prime_pow
        (show Prime (X : Polynomial (R ⧸ P)) from monic_X.prime_of_degree_eq_one degree_X) hf with
      ⟨m, n, b, c, hmnd, hbc, hp, hq⟩
    have hmn : 0 < m → 0 < n → False := by
      intro hm0 hn0
      refine' h0 _
      

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) p * map (mk P) q = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
m n : ℕ
b c : (R ⧸ P)[X]
hmnd : m + n = natDegree (p * q)
hbc : C ((mk P) (leadingCoeff (p * q))) = b * c
hp : map (mk P) p = b * X ^ m
hq : map (mk P) q = c * X ^ n
hm0 : 0 < m
hn0 : 0 < n
⊢ coeff (p * q) 0 ∈ P ^ 2

Next tactic:
rw [coeff_zero_eq_eval_zero, eval_mul, sq]
/-- If `f` is a non constant polynomial with coefficients in `R`, and `P` is a prime ideal in `R`,
then if every coefficient in `R` except the leading coefficient is in `P`, and
the trailing coefficient is not in `P^2` and no non units in `R` divide `f`, then `f` is
irreducible. -/
theorem irreducible_of_eisenstein_criterion {f : R[X]} {P : Ideal R} (hP : P.IsPrime)
    (hfl : f.leadingCoeff ∉ P) (hfP : ∀ n : ℕ, ↑n < degree f → f.coeff n ∈ P) (hfd0 : 0 < degree f)
    (h0 : f.coeff 0 ∉ P ^ 2) (hu : f.IsPrimitive) : Irreducible f :=
  have hf0 : f ≠ 0 := fun _ => by simp_all only [not_true, Submodule.zero_mem, coeff_zero]
  have hf : f.map (mk P) = C (mk P (leadingCoeff f)) * X ^ natDegree f :=
    map_eq_C_mul_X_pow_of_forall_coeff_mem hfP
  have hfd0 : 0 < f.natDegree := WithBot.coe_lt_coe.1 (lt_of_lt_of_le hfd0 degree_le_natDegree)
  ⟨mt degree_eq_zero_of_isUnit fun h => by simp_all only [lt_irrefl], by
    rintro p q rfl
    rw [Polynomial.map_mul] at hf
    rcases mul_eq_mul_prime_pow
        (show Prime (X : Polynomial (R ⧸ P)) from monic_X.prime_of_degree_eq_one degree_X) hf with
      ⟨m, n, b, c, hmnd, hbc, hp, hq⟩
    have hmn : 0 < m → 0 < n → False := by
      intro hm0 hn0
      refine' h0 _
      rw [coeff_zero_eq_eval_zero, eval_mul, sq]
      

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
P : Ideal R
hP : Ideal.IsPrime P
p q : R[X]
hfl : leadingCoeff (p * q) ∉ P
hfP : ∀ (n : ℕ), ↑n < degree (p * q) → coeff (p * q) n ∈ P
hfd0✝ : 0 < degree (p * q)
h0 : coeff (p * q) 0 ∉ P ^ 2
hu : IsPrimitive (p * q)
hf0 : p * q ≠ 0
hf : map (mk P) p * map (mk P) q = C ((mk P) (leadingCoeff (p * q))) * X ^ natDegree (p * q)
hfd0 : 0 < natDegree (p * q)
m n : ℕ
b c : (R ⧸ P)[X]
hmnd : m + n = natDegree (p * q)
hbc : C ((mk P) (leadingCoeff (p * q))) = b * c
hp : map (mk P) p = b * X ^ m
hq : map (mk P) q = c * X ^ n
hm0 : 0 < m
hn0 : 0 < n
⊢ eval 0 p * eval 0 q ∈ P * P

Next tactic:
exact
        Ideal.mul_mem_mul (eval_zero_mem_ideal_of_eq_mul_X_pow hp hm0)
          (eval_zero_mem_ideal_of_eq_mul_X_pow hq hn0)