Theorem: Polynomial.exists_prod_multiset_X_sub_C_mul
File: Mathlib/Algebra/Polynomial/Roots.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.map (fun a => X - C a) p.roots).prod * q = p ∧
      Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0
state_after: 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.map (fun a => X - C a) p.roots).prod * q
⊢ ∃ q,
    (Multiset.map (fun a => X - C a) p.roots).prod * q = p ∧
      Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 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.map (fun a => X - C a) p.roots).prod * q
⊢ ∃ q,
    (Multiset.map (fun a => X - C a) p.roots).prod * q = p ∧
      Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0
state_after: case 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.map (fun a => X - C a) p.roots).prod * q
⊢ Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0

tactic: obtain rfl | hq := eq_or_ne q 0
state_before: case 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.map (fun a => X - C a) p.roots).prod * q
⊢ Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0
state_after: case right.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.map (fun a => X - C a) p.roots).prod * 0
⊢ Multiset.card p.roots + natDegree 0 = p.natDegree ∧ roots 0 = 0

case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0

tactic: constructor
state_before: case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0
state_after: case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ Multiset.card p.roots + q.natDegree = p.natDegree

case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ q.roots = 0

tactic: rw [mul_zero] at he
state_before: case right.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.map (fun a => X - C a) p.roots).prod * 0
⊢ Multiset.card p.roots + natDegree 0 = p.natDegree ∧ roots 0 = 0
state_after: case right.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 p.roots + natDegree 0 = p.natDegree ∧ roots 0 = 0

tactic: subst he
state_before: case right.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 p.roots + natDegree 0 = p.natDegree ∧ roots 0 = 0
state_after: case right.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: simp
state_before: case right.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
state_after: no goals

tactic: conv_rhs => rw [he]
state_before: case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ Multiset.card p.roots + q.natDegree = p.natDegree
state_after: case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ Multiset.card p.roots + q.natDegree = ((Multiset.map (fun a => X - C a) p.roots).prod * q).natDegree

tactic: rw [monic_prod_multiset_X_sub_C.natDegree_mul' hq, natDegree_multiset_prod_X_sub_C_eq_card]
state_before: case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ Multiset.card p.roots + q.natDegree = ((Multiset.map (fun a => X - C a) p.roots).prod * q).natDegree
state_after: no goals

tactic: replace he := congr_arg roots he.symm
state_before: case right.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.map (fun a => X - C a) p.roots).prod * q
hq : q ≠ 0
⊢ q.roots = 0
state_after: case right.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 : ((Multiset.map (fun a => X - C a) p.roots).prod * q).roots = p.roots
⊢ q.roots = 0

tactic: rw [roots_mul, roots_multiset_prod_X_sub_C] at he
state_before: case right.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 : ((Multiset.map (fun a => X - C a) p.roots).prod * q).roots = p.roots
⊢ q.roots = 0
state_after: case right.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 : p.roots + q.roots = p.roots
⊢ q.roots = 0

case right.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 : ((Multiset.map (fun a => X - C a) p.roots).prod * q).roots = p.roots
⊢ (Multiset.map (fun a => X - C a) p.roots).prod * 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 right.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 : p.roots + q.roots = p.roots
⊢ q.roots = 0

case right.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 : ((Multiset.map (fun a => X - C a) p.roots).prod * q).roots = p.roots
⊢ (Multiset.map (fun a => X - C a) p.roots).prod * q ≠ 0
state_after: no goals