Theorem: Polynomial.exists_prod_multiset_X_sub_C_mul
File: Mathlib/Data/Polynomial/RingDivision.lean

tactic: obtain ⟨q, he⟩ := p.prod_multiset_X_sub_C_dvd
state_before: R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
⊢ ∃ q,
    Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q = p ∧
      ↑Multiset.card (roots p) + natDegree q = natDegree p ∧ roots q = 0

tactic: use q, he.symm
state_before: case intro
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q
⊢ ∃ q,
    Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q = p ∧
      ↑Multiset.card (roots p) + natDegree q = natDegree p ∧ roots q = 0

tactic: obtain rfl | hq := eq_or_ne q 0
state_before: case intro
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q
⊢ ↑Multiset.card (roots p) + natDegree q = natDegree p ∧ roots q = 0

tactic: constructor
state_before: case intro.inr
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q
hq : q ≠ 0
⊢ ↑Multiset.card (roots p) + natDegree q = natDegree p ∧ roots q = 0

tactic: rw [MulZeroClass.mul_zero] at he
state_before: case intro.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * 0
⊢ ↑Multiset.card (roots p) + natDegree 0 = natDegree p ∧ roots 0 = 0

tactic: subst he
state_before: case intro.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
he : p = 0
⊢ ↑Multiset.card (roots p) + natDegree 0 = natDegree p ∧ roots 0 = 0

tactic: simp
state_before: case intro.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
⊢ ↑Multiset.card (roots 0) + natDegree 0 = natDegree 0 ∧ roots 0 = 0

tactic: conv_rhs => rw [he]
state_before: case intro.inr.left
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q
hq : q ≠ 0
⊢ ↑Multiset.card (roots p) + natDegree q = natDegree p

tactic: rw [monic_prod_multiset_X_sub_C.natDegree_mul' hq, natDegree_multiset_prod_X_sub_C_eq_card]
state_before: case intro.inr.left
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q
hq : q ≠ 0
⊢ ↑Multiset.card (roots p) + natDegree q = natDegree (Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q)

tactic: replace he := congr_arg roots he.symm
state_before: case intro.inr.right
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
he : p = Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q
hq : q ≠ 0
⊢ roots q = 0

tactic: rw [roots_mul, roots_multiset_prod_X_sub_C] at he
state_before: case intro.inr.right
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
hq : q ≠ 0
he : roots (Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q) = roots p
⊢ roots q = 0

tactic: exacts [add_right_eq_self.1 he, mul_ne_zero monic_prod_multiset_X_sub_C.ne_zero hq]
state_before: case intro.inr.right
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
hq : q ≠ 0
he : roots p + roots q = roots p
⊢ roots q = 0

case intro.inr.right
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q✝ p q : R[X]
hq : q ≠ 0
he : roots (Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q) = roots p
⊢ Multiset.prod (Multiset.map (fun a => X - ↑C a) (roots p)) * q ≠ 0