Theorem: Polynomial.card_roots_le_derivative
File: Mathlib/Analysis/Calculus/LocalExtr/Polynomial.lean

tactic: simp only [Finset.sum_add_distrib, Finset.card_eq_sum_ones, count_roots]
state_before: p : ℝ[X]
⊢ ∑ x ∈ p.roots.toFinset, (Multiset.count x p.roots - 1 + 1) =
    ∑ x ∈ p.roots.toFinset, (rootMultiplicity x p - 1) + p.roots.toFinset.card
state_after: no goals

tactic: simp only [← count_roots]
state_before: p : ℝ[X]
⊢ ∑ x ∈ p.roots.toFinset, rootMultiplicity x (derivative p) +
      (((derivative p).roots.toFinset \ p.roots.toFinset).card + 1) ≤
    ∑ x ∈ p.roots.toFinset, Multiset.count x (derivative p).roots +
      (∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, Multiset.count x (derivative p).roots + 1)
state_after: p : ℝ[X]
⊢ ∑ x ∈ p.roots.toFinset, Multiset.count x (derivative p).roots +
      (((derivative p).roots.toFinset \ p.roots.toFinset).card + 1) ≤
    ∑ x ∈ p.roots.toFinset, Multiset.count x (derivative p).roots +
      (∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, Multiset.count x (derivative p).roots + 1)

tactic: refine add_le_add_left (add_le_add_right ((Finset.card_eq_sum_ones _).trans_le ?_) _) _
state_before: p : ℝ[X]
⊢ ∑ x ∈ p.roots.toFinset, Multiset.count x (derivative p).roots +
      (((derivative p).roots.toFinset \ p.roots.toFinset).card + 1) ≤
    ∑ x ∈ p.roots.toFinset, Multiset.count x (derivative p).roots +
      (∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, Multiset.count x (derivative p).roots + 1)
state_after: p : ℝ[X]
⊢ ∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, 1 ≤
    ∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, Multiset.count x (derivative p).roots

tactic: refine Finset.sum_le_sum fun x hx => Nat.succ_le_iff.2 <| ?_
state_before: p : ℝ[X]
⊢ ∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, 1 ≤
    ∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, Multiset.count x (derivative p).roots
state_after: p : ℝ[X]
x : ℝ
hx : x ∈ (derivative p).roots.toFinset \ p.roots.toFinset
⊢ 0 < Multiset.count x (derivative p).roots

tactic: rw [Multiset.count_pos, ← Multiset.mem_toFinset]
state_before: p : ℝ[X]
x : ℝ
hx : x ∈ (derivative p).roots.toFinset \ p.roots.toFinset
⊢ 0 < Multiset.count x (derivative p).roots
state_after: p : ℝ[X]
x : ℝ
hx : x ∈ (derivative p).roots.toFinset \ p.roots.toFinset
⊢ x ∈ (derivative p).roots.toFinset

tactic: exact (Finset.mem_sdiff.1 hx).1
state_before: p : ℝ[X]
x : ℝ
hx : x ∈ (derivative p).roots.toFinset \ p.roots.toFinset
⊢ x ∈ (derivative p).roots.toFinset
state_after: no goals

tactic: rw [← add_assoc, ← Finset.sum_union Finset.disjoint_sdiff, Finset.union_sdiff_self_eq_union, ←
  Multiset.toFinset_sum_count_eq, ← Finset.sum_subset Finset.subset_union_right]
state_before: p : ℝ[X]
⊢ ∑ x ∈ p.roots.toFinset, Multiset.count x (derivative p).roots +
      (∑ x ∈ (derivative p).roots.toFinset \ p.roots.toFinset, Multiset.count x (derivative p).roots + 1) =
    Multiset.card (derivative p).roots + 1
state_after: p : ℝ[X]
⊢ ∀ x ∈ p.roots.toFinset ∪ (derivative p).roots.toFinset,
    x ∉ (derivative p).roots.toFinset → Multiset.count x (derivative p).roots = 0

tactic: intro x _ hx₂
state_before: p : ℝ[X]
⊢ ∀ x ∈ p.roots.toFinset ∪ (derivative p).roots.toFinset,
    x ∉ (derivative p).roots.toFinset → Multiset.count x (derivative p).roots = 0
state_after: p : ℝ[X]
x : ℝ
a✝ : x ∈ p.roots.toFinset ∪ (derivative p).roots.toFinset
hx₂ : x ∉ (derivative p).roots.toFinset
⊢ Multiset.count x (derivative p).roots = 0

tactic: simpa only [Multiset.mem_toFinset, Multiset.count_eq_zero] using hx₂
state_before: p : ℝ[X]
x : ℝ
a✝ : x ∈ p.roots.toFinset ∪ (derivative p).roots.toFinset
hx₂ : x ∉ (derivative p).roots.toFinset
⊢ Multiset.count x (derivative p).roots = 0
state_after: no goals