Theorem: Polynomial.irreducible_of_mirror
File: Mathlib/Data/Polynomial/Mirror.lean

tactic: constructor
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
⊢ Irreducible f

tactic: exact h1
state_before: case not_unit
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
⊢ ¬IsUnit f

tactic: intro g h fgh
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
⊢ ∀ (a b : R[X]), f = a * b → IsUnit a ∨ IsUnit b

tactic: let k := g * h.mirror
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
⊢ IsUnit g ∨ IsUnit h

tactic: have key : f * f.mirror = k * k.mirror := by
  rw [fgh, mirror_mul_of_domain, mirror_mul_of_domain, mirror_mirror, mul_assoc, mul_comm h,
    mul_comm g.mirror, mul_assoc, ← mul_assoc]
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
⊢ IsUnit g ∨ IsUnit h

tactic: have g_dvd_f : g ∣ f := by
  rw [fgh]
  exact dvd_mul_right g h
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
⊢ IsUnit g ∨ IsUnit h

tactic: have h_dvd_f : h ∣ f := by
  rw [fgh]
  exact dvd_mul_left h g
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
⊢ IsUnit g ∨ IsUnit h

tactic: have g_dvd_k : g ∣ k := dvd_mul_right g h.mirror
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
⊢ IsUnit g ∨ IsUnit h

tactic: have h_dvd_k_rev : h ∣ k.mirror := by
  rw [mirror_mul_of_domain, mirror_mirror]
  exact dvd_mul_left h g.mirror
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
⊢ IsUnit g ∨ IsUnit h

tactic: have hk := h2 k key
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
⊢ IsUnit g ∨ IsUnit h

tactic: rcases hk with (hk | hk | hk | hk)
state_before: case isUnit_or_isUnit'
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
⊢ IsUnit g ∨ IsUnit h

tactic: rw [fgh, mirror_mul_of_domain, mirror_mul_of_domain, mirror_mirror, mul_assoc, mul_comm h,
  mul_comm g.mirror, mul_assoc, ← mul_assoc]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
⊢ f * mirror f = k * mirror k

tactic: rw [fgh]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
⊢ g ∣ f

tactic: exact dvd_mul_right g h
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
⊢ g ∣ g * h

tactic: rw [fgh]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
⊢ h ∣ f

tactic: exact dvd_mul_left h g
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
⊢ h ∣ g * h

tactic: rw [mirror_mul_of_domain, mirror_mirror]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
⊢ h ∣ mirror k

tactic: exact dvd_mul_left h g.mirror
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
⊢ h ∣ mirror g * h

tactic: exact Or.inr (h3 h h_dvd_f (by rwa [← hk]))
state_before: case isUnit_or_isUnit'.inl
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = f
⊢ IsUnit g ∨ IsUnit h

tactic: rwa [← hk]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = f
⊢ h ∣ mirror f

tactic: exact Or.inr (h3 h h_dvd_f (by rwa [← neg_eq_iff_eq_neg.mpr hk, mirror_neg, dvd_neg]))
state_before: case isUnit_or_isUnit'.inr.inl
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = -f
⊢ IsUnit g ∨ IsUnit h

tactic: rwa [← neg_eq_iff_eq_neg.mpr hk, mirror_neg, dvd_neg]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = -f
⊢ h ∣ mirror f

tactic: exact Or.inl (h3 g g_dvd_f (by rwa [← hk]))
state_before: case isUnit_or_isUnit'.inr.inr.inl
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = mirror f
⊢ IsUnit g ∨ IsUnit h

tactic: rwa [← hk]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = mirror f
⊢ g ∣ mirror f

tactic: exact Or.inl (h3 g g_dvd_f (by rwa [← neg_eq_iff_eq_neg.mpr hk, dvd_neg]))
state_before: case isUnit_or_isUnit'.inr.inr.inr
R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = -mirror f
⊢ IsUnit g ∨ IsUnit h

tactic: rwa [← neg_eq_iff_eq_neg.mpr hk, dvd_neg]
state_before: R : Type u_1
inst✝¹ : CommRing R
inst✝ : NoZeroDivisors R
f : R[X]
h1 : ¬IsUnit f
h2 : ∀ (k : R[X]), f * mirror f = k * mirror k → k = f ∨ k = -f ∨ k = mirror f ∨ k = -mirror f
h3 : ∀ (g : R[X]), g ∣ f → g ∣ mirror f → IsUnit g
g h : R[X]
fgh : f = g * h
k : R[X] := g * mirror h
key : f * mirror f = k * mirror k
g_dvd_f : g ∣ f
h_dvd_f : h ∣ f
g_dvd_k : g ∣ k
h_dvd_k_rev : h ∣ mirror k
hk : k = -mirror f
⊢ g ∣ mirror f