-- 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 h
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]
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
hmnd : ¬p.natDegree = m ∨ ¬q.natDegree = n
⊢ m + n < p.natDegree + q.natDegree

Tactic:
rcases hmnd with hmnd | hmnd

Result:
case h.inl
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]
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
hmnd : ¬p.natDegree = m
⊢ m + n < p.natDegree + q.natDegree

case h.inr
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]
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
hmnd : ¬q.natDegree = n
⊢ m + n < p.natDegree + q.natDegree

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
h : p = 0
⊢ False

Tactic:
simp_all only [zero_mul, eq_self_iff_true, not_true, Ne]

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
⊢ (mk P) (p * q).leadingCoeff ≠ 0

Tactic:
rwa [Ne, eq_zero_iff_mem]

Result:
no goals

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

Tactic:
rintro p q rfl

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 * q) = C ((mk P) (p * q).leadingCoeff) * X ^ (p * q).natDegree
hfd0 : 0 < (p * q).natDegree
⊢ IsUnit p ∨ IsUnit q

Proof state:
case h.inl
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]
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
hmnd : ¬p.natDegree = m
⊢ m + n < p.natDegree + q.natDegree

Tactic:
exact add_lt_add_of_lt_of_le (lt_of_le_of_ne hmp (Ne.symm hmnd)) hnq

Result:
no goals

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
⊢ IsUnit p ∨ IsUnit q

Tactic:
have hpql0 : (mk P) (p * q).leadingCoeff ≠ 0 := by rwa [Ne, eq_zero_iff_mem]

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
⊢ IsUnit p ∨ IsUnit q