-- Mathlib/RingTheory/EisensteinCriterion.lean
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

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

Tactic:
have hmp : m ≤ natDegree p := le_natDegree_of_map_eq_mul_X_pow hP hp hbc0.1

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

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

Tactic:
rw [coeff_zero_eq_eval_zero, eval_mul, sq]

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

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

Tactic:
rwa [pos_iff_ne_zero, pos_iff_ne_zero, imp_false, Classical.not_not, ← or_iff_not_imp_left]
  at hmn

Result:
no goals

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

Tactic:
rw [natDegree_mul hp0 hq0] at hmnd

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

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

Tactic:
refine h0 ?_

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