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

tactic: rcases eq_or_ne (derivative p) 0 with hp' | hp'
state_before: p : ℝ[X]
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1
state_after: case inl
p : ℝ[X]
hp' : derivative p = 0
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1

case inr
p : ℝ[X]
hp' : derivative p ≠ 0
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1

tactic: have hp : p ≠ 0 := ne_of_apply_ne derivative (by rwa [derivative_zero])
state_before: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1
state_after: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1

tactic: refine Finset.card_le_diff_of_interleaved fun x hx y hy hxy hxy' => ?_
state_before: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1
state_after: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : x ∈ p.roots.toFinset
y : ℝ
hy : y ∈ p.roots.toFinset
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
⊢ ∃ z ∈ (derivative p).roots.toFinset, x < z ∧ z < y

tactic: rw [Multiset.mem_toFinset, mem_roots hp] at hx hy
state_before: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : x ∈ p.roots.toFinset
y : ℝ
hy : y ∈ p.roots.toFinset
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
⊢ ∃ z ∈ (derivative p).roots.toFinset, x < z ∧ z < y
state_after: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : p.IsRoot x
y : ℝ
hy : p.IsRoot y
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
⊢ ∃ z ∈ (derivative p).roots.toFinset, x < z ∧ z < y

tactic: obtain ⟨z, hz1, hz2⟩ := exists_deriv_eq_zero hxy p.continuousOn (hx.trans hy.symm)
state_before: case inr
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : p.IsRoot x
y : ℝ
hy : p.IsRoot y
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
⊢ ∃ z ∈ (derivative p).roots.toFinset, x < z ∧ z < y
state_after: case inr.intro.intro
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : p.IsRoot x
y : ℝ
hy : p.IsRoot y
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
z : ℝ
hz1 : z ∈ Set.Ioo x y
hz2 : deriv (fun x => eval x p) z = 0
⊢ ∃ z ∈ (derivative p).roots.toFinset, x < z ∧ z < y

tactic: refine ⟨z, ?_, hz1⟩
state_before: case inr.intro.intro
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : p.IsRoot x
y : ℝ
hy : p.IsRoot y
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
z : ℝ
hz1 : z ∈ Set.Ioo x y
hz2 : deriv (fun x => eval x p) z = 0
⊢ ∃ z ∈ (derivative p).roots.toFinset, x < z ∧ z < y
state_after: case inr.intro.intro
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : p.IsRoot x
y : ℝ
hy : p.IsRoot y
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
z : ℝ
hz1 : z ∈ Set.Ioo x y
hz2 : deriv (fun x => eval x p) z = 0
⊢ z ∈ (derivative p).roots.toFinset

tactic: rwa [Multiset.mem_toFinset, mem_roots hp', IsRoot, ← p.deriv]
state_before: case inr.intro.intro
p : ℝ[X]
hp' : derivative p ≠ 0
hp : p ≠ 0
x : ℝ
hx : p.IsRoot x
y : ℝ
hy : p.IsRoot y
hxy : x < y
hxy' : ∀ z ∈ p.roots.toFinset, z ∉ Set.Ioo x y
z : ℝ
hz1 : z ∈ Set.Ioo x y
hz2 : deriv (fun x => eval x p) z = 0
⊢ z ∈ (derivative p).roots.toFinset
state_after: no goals

tactic: rw [eq_C_of_derivative_eq_zero hp', roots_C, Multiset.toFinset_zero, Finset.card_empty]
state_before: case inl
p : ℝ[X]
hp' : derivative p = 0
⊢ p.roots.toFinset.card ≤ ((derivative p).roots.toFinset \ p.roots.toFinset).card + 1
state_after: case inl
p : ℝ[X]
hp' : derivative p = 0
⊢ 0 ≤ ((derivative (C (p.coeff 0))).roots.toFinset \ ∅).card + 1

tactic: exact zero_le _
state_before: case inl
p : ℝ[X]
hp' : derivative p = 0
⊢ 0 ≤ ((derivative (C (p.coeff 0))).roots.toFinset \ ∅).card + 1
state_after: no goals

tactic: rwa [derivative_zero]
state_before: p : ℝ[X]
hp' : derivative p ≠ 0
⊢ derivative p ≠ derivative 0
state_after: no goals