l3lab/ntp-mathlib huggingface dataset:
theorem interpolate_eq_sum_interpolate_insert_sdiff (hvt : Set.InjOn v t) (hs : s.Nonempty)
    (hst : s ⊆ t) :
    interpolate t v r = ∑ i in s, interpolate (insert i (t \ s)) v r * Lagrange.basis s v i := by
  symm
  refine' eq_interpolate_of_eval_eq _ hvt (lt_of_le_of_lt (degree_sum_le _ _) _) fun i hi => _
  · simp_rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe t.card), degree_mul]
    intro i hi
    have hs : 1 ≤ s.card := Nonempty.card_pos ⟨_, hi⟩
    have hst' : s.card ≤ t.card := card_le_of_subset hst
    have H : t.card = 1 + (t.card - s.card) + (s.card - 1) := by
      rw [add_assoc, tsub_add_tsub_cancel hst' hs, ← add_tsub_assoc_of_le (hs.trans hst'),
        Nat.succ_add_sub_one, zero_add]
    rw [degree_basis (Set.InjOn.mono hst hvt) hi, H, WithBot.coe_add, Nat.cast_withBot,
      WithBot.add_lt_add_iff_right (@WithBot.coe_ne_bot _ (s.card - 1))]
    convert degree_interpolate_lt _
        (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hst hi, sdiff_subset _ _⟩)))
    rw [card_insert_of_not_mem (not_mem_sdiff_of_mem_right hi), card_sdiff hst, add_comm]
  · simp_rw [eval_finset_sum, eval_mul]
    by_cases hi' : i ∈ s
    · rw [← add_sum_erase _ _ hi', eval_basis_self (hvt.mono hst) hi',
        eval_interpolate_at_node _
          (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hi, sdiff_subset _ _⟩)))
          (mem_insert_self _ _),
        mul_one, add_right_eq_self]
      refine' sum_eq_zero fun j hj => _
      rcases mem_erase.mp hj with ⟨hij, _⟩
      rw [eval_basis_of_ne hij hi', mul_zero]
    · have H : (∑ j in s, eval (v i) (Lagrange.basis s v j)) = 1 := by
        

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i✝ j : ι
v r r' : ι → F
hvt : Set.InjOn v ↑t
hs : Finset.Nonempty s
hst : s ⊆ t
i : ι
hi : i ∈ t
hi' : i ∉ s
⊢ ∑ j in s, eval (v i) (Lagrange.basis s v j) = 1

Next tactic:
rw [← eval_finset_sum, sum_basis (hvt.mono hst) hs, eval_one]
theorem interpolate_eq_sum_interpolate_insert_sdiff (hvt : Set.InjOn v t) (hs : s.Nonempty)
    (hst : s ⊆ t) :
    interpolate t v r = ∑ i in s, interpolate (insert i (t \ s)) v r * Lagrange.basis s v i := by
  symm
  refine' eq_interpolate_of_eval_eq _ hvt (lt_of_le_of_lt (degree_sum_le _ _) _) fun i hi => _
  · simp_rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe t.card), degree_mul]
    intro i hi
    have hs : 1 ≤ s.card := Nonempty.card_pos ⟨_, hi⟩
    have hst' : s.card ≤ t.card := card_le_of_subset hst
    have H : t.card = 1 + (t.card - s.card) + (s.card - 1) := by
      rw [add_assoc, tsub_add_tsub_cancel hst' hs, ← add_tsub_assoc_of_le (hs.trans hst'),
        Nat.succ_add_sub_one, zero_add]
    rw [degree_basis (Set.InjOn.mono hst hvt) hi, H, WithBot.coe_add, Nat.cast_withBot,
      WithBot.add_lt_add_iff_right (@WithBot.coe_ne_bot _ (s.card - 1))]
    convert degree_interpolate_lt _
        (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hst hi, sdiff_subset _ _⟩)))
    rw [card_insert_of_not_mem (not_mem_sdiff_of_mem_right hi), card_sdiff hst, add_comm]
  · simp_rw [eval_finset_sum, eval_mul]
    by_cases hi' : i ∈ s
    · rw [← add_sum_erase _ _ hi', eval_basis_self (hvt.mono hst) hi',
        eval_interpolate_at_node _
          (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hi, sdiff_subset _ _⟩)))
          (mem_insert_self _ _),
        mul_one, add_right_eq_self]
      refine' sum_eq_zero fun j hj => _
      rcases mem_erase.mp hj with ⟨hij, _⟩
      rw [eval_basis_of_ne hij hi', mul_zero]
    · have H : (∑ j in s, eval (v i) (Lagrange.basis s v j)) = 1 := by
        rw [← eval_finset_sum, sum_basis (hvt.mono hst) hs, eval_one]
      

Proof state:
case neg
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i✝ j : ι
v r r' : ι → F
hvt : Set.InjOn v ↑t
hs : Finset.Nonempty s
hst : s ⊆ t
i : ι
hi : i ∈ t
hi' : i ∉ s
H : ∑ j in s, eval (v i) (Lagrange.basis s v j) = 1
⊢ ∑ x in s, eval (v i) ((interpolate (insert x (t \ s)) v) r) * eval (v i) (Lagrange.basis s v x) = r i

Next tactic:
rw [← mul_one (r i), ← H, mul_sum]
theorem interpolate_eq_sum_interpolate_insert_sdiff (hvt : Set.InjOn v t) (hs : s.Nonempty)
    (hst : s ⊆ t) :
    interpolate t v r = ∑ i in s, interpolate (insert i (t \ s)) v r * Lagrange.basis s v i := by
  symm
  refine' eq_interpolate_of_eval_eq _ hvt (lt_of_le_of_lt (degree_sum_le _ _) _) fun i hi => _
  · simp_rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe t.card), degree_mul]
    intro i hi
    have hs : 1 ≤ s.card := Nonempty.card_pos ⟨_, hi⟩
    have hst' : s.card ≤ t.card := card_le_of_subset hst
    have H : t.card = 1 + (t.card - s.card) + (s.card - 1) := by
      rw [add_assoc, tsub_add_tsub_cancel hst' hs, ← add_tsub_assoc_of_le (hs.trans hst'),
        Nat.succ_add_sub_one, zero_add]
    rw [degree_basis (Set.InjOn.mono hst hvt) hi, H, WithBot.coe_add, Nat.cast_withBot,
      WithBot.add_lt_add_iff_right (@WithBot.coe_ne_bot _ (s.card - 1))]
    convert degree_interpolate_lt _
        (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hst hi, sdiff_subset _ _⟩)))
    rw [card_insert_of_not_mem (not_mem_sdiff_of_mem_right hi), card_sdiff hst, add_comm]
  · simp_rw [eval_finset_sum, eval_mul]
    by_cases hi' : i ∈ s
    · rw [← add_sum_erase _ _ hi', eval_basis_self (hvt.mono hst) hi',
        eval_interpolate_at_node _
          (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hi, sdiff_subset _ _⟩)))
          (mem_insert_self _ _),
        mul_one, add_right_eq_self]
      refine' sum_eq_zero fun j hj => _
      rcases mem_erase.mp hj with ⟨hij, _⟩
      rw [eval_basis_of_ne hij hi', mul_zero]
    · have H : (∑ j in s, eval (v i) (Lagrange.basis s v j)) = 1 := by
        rw [← eval_finset_sum, sum_basis (hvt.mono hst) hs, eval_one]
      rw [← mul_one (r i), ← H, mul_sum]
      

Proof state:
case neg
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i✝ j : ι
v r r' : ι → F
hvt : Set.InjOn v ↑t
hs : Finset.Nonempty s
hst : s ⊆ t
i : ι
hi : i ∈ t
hi' : i ∉ s
H : ∑ j in s, eval (v i) (Lagrange.basis s v j) = 1
⊢ ∑ x in s, eval (v i) ((interpolate (insert x (t \ s)) v) r) * eval (v i) (Lagrange.basis s v x) =
    ∑ x in s, r i * eval (v i) (Lagrange.basis s v x)

Next tactic:
refine' sum_congr rfl fun j hj => _
theorem interpolate_eq_sum_interpolate_insert_sdiff (hvt : Set.InjOn v t) (hs : s.Nonempty)
    (hst : s ⊆ t) :
    interpolate t v r = ∑ i in s, interpolate (insert i (t \ s)) v r * Lagrange.basis s v i := by
  symm
  refine' eq_interpolate_of_eval_eq _ hvt (lt_of_le_of_lt (degree_sum_le _ _) _) fun i hi => _
  · simp_rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe t.card), degree_mul]
    intro i hi
    have hs : 1 ≤ s.card := Nonempty.card_pos ⟨_, hi⟩
    have hst' : s.card ≤ t.card := card_le_of_subset hst
    have H : t.card = 1 + (t.card - s.card) + (s.card - 1) := by
      rw [add_assoc, tsub_add_tsub_cancel hst' hs, ← add_tsub_assoc_of_le (hs.trans hst'),
        Nat.succ_add_sub_one, zero_add]
    rw [degree_basis (Set.InjOn.mono hst hvt) hi, H, WithBot.coe_add, Nat.cast_withBot,
      WithBot.add_lt_add_iff_right (@WithBot.coe_ne_bot _ (s.card - 1))]
    convert degree_interpolate_lt _
        (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hst hi, sdiff_subset _ _⟩)))
    rw [card_insert_of_not_mem (not_mem_sdiff_of_mem_right hi), card_sdiff hst, add_comm]
  · simp_rw [eval_finset_sum, eval_mul]
    by_cases hi' : i ∈ s
    · rw [← add_sum_erase _ _ hi', eval_basis_self (hvt.mono hst) hi',
        eval_interpolate_at_node _
          (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hi, sdiff_subset _ _⟩)))
          (mem_insert_self _ _),
        mul_one, add_right_eq_self]
      refine' sum_eq_zero fun j hj => _
      rcases mem_erase.mp hj with ⟨hij, _⟩
      rw [eval_basis_of_ne hij hi', mul_zero]
    · have H : (∑ j in s, eval (v i) (Lagrange.basis s v j)) = 1 := by
        rw [← eval_finset_sum, sum_basis (hvt.mono hst) hs, eval_one]
      rw [← mul_one (r i), ← H, mul_sum]
      refine' sum_congr rfl fun j hj => _
      

Proof state:
case neg
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i✝ j✝ : ι
v r r' : ι → F
hvt : Set.InjOn v ↑t
hs : Finset.Nonempty s
hst : s ⊆ t
i : ι
hi : i ∈ t
hi' : i ∉ s
H : ∑ j in s, eval (v i) (Lagrange.basis s v j) = 1
j : ι
hj : j ∈ s
⊢ eval (v i) ((interpolate (insert j (t \ s)) v) r) * eval (v i) (Lagrange.basis s v j) =
    r i * eval (v i) (Lagrange.basis s v j)

Next tactic:
congr
theorem interpolate_eq_sum_interpolate_insert_sdiff (hvt : Set.InjOn v t) (hs : s.Nonempty)
    (hst : s ⊆ t) :
    interpolate t v r = ∑ i in s, interpolate (insert i (t \ s)) v r * Lagrange.basis s v i := by
  symm
  refine' eq_interpolate_of_eval_eq _ hvt (lt_of_le_of_lt (degree_sum_le _ _) _) fun i hi => _
  · simp_rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe t.card), degree_mul]
    intro i hi
    have hs : 1 ≤ s.card := Nonempty.card_pos ⟨_, hi⟩
    have hst' : s.card ≤ t.card := card_le_of_subset hst
    have H : t.card = 1 + (t.card - s.card) + (s.card - 1) := by
      rw [add_assoc, tsub_add_tsub_cancel hst' hs, ← add_tsub_assoc_of_le (hs.trans hst'),
        Nat.succ_add_sub_one, zero_add]
    rw [degree_basis (Set.InjOn.mono hst hvt) hi, H, WithBot.coe_add, Nat.cast_withBot,
      WithBot.add_lt_add_iff_right (@WithBot.coe_ne_bot _ (s.card - 1))]
    convert degree_interpolate_lt _
        (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hst hi, sdiff_subset _ _⟩)))
    rw [card_insert_of_not_mem (not_mem_sdiff_of_mem_right hi), card_sdiff hst, add_comm]
  · simp_rw [eval_finset_sum, eval_mul]
    by_cases hi' : i ∈ s
    · rw [← add_sum_erase _ _ hi', eval_basis_self (hvt.mono hst) hi',
        eval_interpolate_at_node _
          (hvt.mono (coe_subset.mpr (insert_subset_iff.mpr ⟨hi, sdiff_subset _ _⟩)))
          (mem_insert_self _ _),
        mul_one, add_right_eq_self]
      refine' sum_eq_zero fun j hj => _
      rcases mem_erase.mp hj with ⟨hij, _⟩
      rw [eval_basis_of_ne hij hi', mul_zero]
    · have H : (∑ j in s, eval (v i) (Lagrange.basis s v j)) = 1 := by
        rw [← eval_finset_sum, sum_basis (hvt.mono hst) hs, eval_one]
      rw [← mul_one (r i), ← H, mul_sum]
      refine' sum_congr rfl fun j hj => _
      congr
      

Proof state:
case neg.e_a
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i✝ j✝ : ι
v r r' : ι → F
hvt : Set.InjOn v ↑t
hs : Finset.Nonempty s
hst : s ⊆ t
i : ι
hi : i ∈ t
hi' : i ∉ s
H : ∑ j in s, eval (v i) (Lagrange.basis s v j) = 1
j : ι
hj : j ∈ s
⊢ eval (v i) ((interpolate (insert j (t \ s)) v) r) = r i

Next tactic:
exact
        eval_interpolate_at_node _ (hvt.mono (insert_subset_iff.mpr ⟨hst hj, sdiff_subset _ _⟩))
          (mem_insert.mpr (Or.inr (mem_sdiff.mpr ⟨hi, hi'⟩)))
theorem interpolate_eq_add_interpolate_erase (hvs : Set.InjOn v s) (hi : i ∈ s) (hj : j ∈ s)
    (hij : i ≠ j) :
    interpolate s v r =
      interpolate (s.erase j) v r * basisDivisor (v i) (v j) +
        interpolate (s.erase i) v r * basisDivisor (v j) (v i) := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i j : ι
v r r' : ι → F
hvs : Set.InjOn v ↑s
hi : i ∈ s
hj : j ∈ s
hij : i ≠ j
⊢ (interpolate s v) r =
    (interpolate (Finset.erase s j) v) r * basisDivisor (v i) (v j) +
      (interpolate (Finset.erase s i) v) r * basisDivisor (v j) (v i)

Next tactic:
rw [interpolate_eq_sum_interpolate_insert_sdiff _ hvs ⟨i, mem_insert_self i {j}⟩ _,
    sum_insert (not_mem_singleton.mpr hij), sum_singleton, basis_pair_left hij,
    basis_pair_right hij, sdiff_insert_insert_of_mem_of_not_mem hi (not_mem_singleton.mpr hij),
    sdiff_singleton_eq_erase, pair_comm,
    sdiff_insert_insert_of_mem_of_not_mem hj (not_mem_singleton.mpr hij.symm),
    sdiff_singleton_eq_erase]
theorem interpolate_eq_add_interpolate_erase (hvs : Set.InjOn v s) (hi : i ∈ s) (hj : j ∈ s)
    (hij : i ≠ j) :
    interpolate s v r =
      interpolate (s.erase j) v r * basisDivisor (v i) (v j) +
        interpolate (s.erase i) v r * basisDivisor (v j) (v i) := by
  rw [interpolate_eq_sum_interpolate_insert_sdiff _ hvs ⟨i, mem_insert_self i {j}⟩ _,
    sum_insert (not_mem_singleton.mpr hij), sum_singleton, basis_pair_left hij,
    basis_pair_right hij, sdiff_insert_insert_of_mem_of_not_mem hi (not_mem_singleton.mpr hij),
    sdiff_singleton_eq_erase, pair_comm,
    sdiff_insert_insert_of_mem_of_not_mem hj (not_mem_singleton.mpr hij.symm),
    sdiff_singleton_eq_erase]
  · 

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s t : Finset ι
i j : ι
v r r' : ι → F
hvs : Set.InjOn v ↑s
hi : i ∈ s
hj : j ∈ s
hij : i ≠ j
⊢ {i, j} ⊆ s

Next tactic:
exact insert_subset_iff.mpr ⟨hi, singleton_subset_iff.mpr hj⟩
@[simp]
theorem nodal_empty : nodal ∅ v = 1 := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
⊢ nodal ∅ v = 1

Next tactic:
rfl
@[simp]
theorem natDegree_nodal [Nontrivial R] : (nodal s v).natDegree = s.card := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : Nontrivial R
⊢ natDegree (nodal s v) = card s

Next tactic:
simp_rw [nodal, natDegree_prod_of_monic (h := fun i _ => monic_X_sub_C (v i)),
    natDegree_X_sub_C, sum_const, smul_eq_mul, mul_one]
theorem nodal_ne_zero [Nontrivial R] : nodal s v ≠ 0 := by


Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : Nontrivial R
⊢ nodal s v ≠ 0

Next tactic:
rcases s.eq_empty_or_nonempty with (rfl | h)
theorem nodal_ne_zero [Nontrivial R] : nodal s v ≠ 0 := by
rcases s.eq_empty_or_nonempty with (rfl | h)
· 

Proof state:
case inl
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
v : ι → R
inst✝ : Nontrivial R
⊢ nodal ∅ v ≠ 0

Next tactic:
exact one_ne_zero
theorem nodal_ne_zero [Nontrivial R] : nodal s v ≠ 0 := by
rcases s.eq_empty_or_nonempty with (rfl | h)
· exact one_ne_zero
· 

Proof state:
case inr
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : Nontrivial R
h : Finset.Nonempty s
⊢ nodal s v ≠ 0

Next tactic:
apply ne_zero_of_natDegree_gt (n := 0)
theorem nodal_ne_zero [Nontrivial R] : nodal s v ≠ 0 := by
rcases s.eq_empty_or_nonempty with (rfl | h)
· exact one_ne_zero
· apply ne_zero_of_natDegree_gt (n := 0)
  

Proof state:
case inr
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : Nontrivial R
h : Finset.Nonempty s
⊢ 0 < natDegree (nodal s v)

Next tactic:
simp only [natDegree_nodal, h.card_pos]
@[simp]
theorem degree_nodal [Nontrivial R] : (nodal s v).degree = s.card := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : Nontrivial R
⊢ degree (nodal s v) = ↑(card s)

Next tactic:
simp_rw [degree_eq_natDegree (nodal_ne_zero), natDegree_nodal]
theorem eval_nodal {x : R} : (nodal s v).eval x = ∏ i in s, (x - v i) := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
x : R
⊢ eval x (nodal s v) = ∏ i in s, (x - v i)

Next tactic:
simp_rw [nodal, eval_prod, eval_sub, eval_X, eval_C]
theorem eval_nodal_at_node {i : ι} (hi : i ∈ s) : eval (v i) (nodal s v) = 0 := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
i : ι
hi : i ∈ s
⊢ eval (v i) (nodal s v) = 0

Next tactic:
rw [eval_nodal]
theorem eval_nodal_at_node {i : ι} (hi : i ∈ s) : eval (v i) (nodal s v) = 0 := by
  rw [eval_nodal]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
i : ι
hi : i ∈ s
⊢ ∏ i_1 in s, (v i - v i_1) = 0

Next tactic:
exact s.prod_eq_zero hi (sub_self (v i))
theorem eval_nodal_not_at_node [Nontrivial R] [NoZeroDivisors R] {x : R}
    (hx : ∀ i ∈ s, x ≠ v i) : eval x (nodal s v) ≠ 0 := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝¹ : Nontrivial R
inst✝ : NoZeroDivisors R
x : R
hx : ∀ i ∈ s, x ≠ v i
⊢ eval x (nodal s v) ≠ 0

Next tactic:
simp_rw [nodal, eval_prod, prod_ne_zero_iff, eval_sub, eval_X, eval_C, sub_ne_zero]
theorem eval_nodal_not_at_node [Nontrivial R] [NoZeroDivisors R] {x : R}
    (hx : ∀ i ∈ s, x ≠ v i) : eval x (nodal s v) ≠ 0 := by
  simp_rw [nodal, eval_prod, prod_ne_zero_iff, eval_sub, eval_X, eval_C, sub_ne_zero]
  

Proof state:
R : Type u_1
inst✝² : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝¹ : Nontrivial R
inst✝ : NoZeroDivisors R
x : R
hx : ∀ i ∈ s, x ≠ v i
⊢ ∀ a ∈ s, x ≠ v a

Next tactic:
exact hx
theorem nodal_eq_mul_nodal_erase [DecidableEq ι] {i : ι} (hi : i ∈ s) :
    nodal s v = (X - C (v i)) * nodal (s.erase i) v := by
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
hi : i ∈ s
⊢ nodal s v = (X - C (v i)) * nodal (Finset.erase s i) v

Next tactic:
simp_rw [nodal, Finset.mul_prod_erase _ (fun x => X - C (v x)) hi]
theorem X_sub_C_dvd_nodal (v : ι → R) {i : ι} (hi : i ∈ s) : X - C (v i) ∣ nodal s v :=
  ⟨_, by 

Proof state:
R : Type u_1
inst✝ : CommRing R
ι : Type u_2
s : Finset ι
v✝ v : ι → R
i : ι
hi : i ∈ s
⊢ nodal s v = (X - C (v i)) * ?m.450851 v hi

Next tactic:
classical exact nodal_eq_mul_nodal_erase hi
theorem X_sub_C_dvd_nodal (v : ι → R) {i : ι} (hi : i ∈ s) : X - C (v i) ∣ nodal s v :=
  ⟨_, by classical 

Proof state:
R : Type u_1
inst✝ : CommRing R
ι : Type u_2
s : Finset ι
v✝ v : ι → R
i : ι
hi : i ∈ s
⊢ nodal s v = (X - C (v i)) * ?m.450851 v hi

Next tactic:
exact nodal_eq_mul_nodal_erase hi
theorem nodal_insert_eq_nodal [DecidableEq ι] {i : ι} (hi : i ∉ s) :
    nodal (insert i s) v = (X - C (v i)) * nodal s v := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
hi : i ∉ s
⊢ nodal (insert i s) v = (X - C (v i)) * nodal s v

Next tactic:
simp_rw [nodal, prod_insert hi]
theorem derivative_nodal [DecidableEq ι] :
    derivative (nodal s v) = ∑ i in s, nodal (s.erase i) v := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
⊢ derivative (nodal s v) = ∑ i in s, nodal (Finset.erase s i) v

Next tactic:
refine' s.induction_on _ fun i t hit IH => _
theorem derivative_nodal [DecidableEq ι] :
    derivative (nodal s v) = ∑ i in s, nodal (s.erase i) v := by
  refine' s.induction_on _ fun i t hit IH => _
  · 

Proof state:
case refine'_1
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
⊢ derivative (nodal ∅ v) = ∑ i in ∅, nodal (Finset.erase ∅ i) v

Next tactic:
rw [nodal_empty, derivative_one, sum_empty]
theorem derivative_nodal [DecidableEq ι] :
    derivative (nodal s v) = ∑ i in s, nodal (s.erase i) v := by
  refine' s.induction_on _ fun i t hit IH => _
  · rw [nodal_empty, derivative_one, sum_empty]
  · 

Proof state:
case refine'_2
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
t : Finset ι
hit : i ∉ t
IH : derivative (nodal t v) = ∑ i in t, nodal (Finset.erase t i) v
⊢ derivative (nodal (insert i t) v) = ∑ i_1 in insert i t, nodal (Finset.erase (insert i t) i_1) v

Next tactic:
rw [nodal_insert_eq_nodal hit, derivative_mul, IH, derivative_sub, derivative_X, derivative_C,
      sub_zero, one_mul, sum_insert hit, mul_sum, erase_insert hit, add_right_inj]
theorem derivative_nodal [DecidableEq ι] :
    derivative (nodal s v) = ∑ i in s, nodal (s.erase i) v := by
  refine' s.induction_on _ fun i t hit IH => _
  · rw [nodal_empty, derivative_one, sum_empty]
  · rw [nodal_insert_eq_nodal hit, derivative_mul, IH, derivative_sub, derivative_X, derivative_C,
      sub_zero, one_mul, sum_insert hit, mul_sum, erase_insert hit, add_right_inj]
    

Proof state:
case refine'_2
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
t : Finset ι
hit : i ∉ t
IH : derivative (nodal t v) = ∑ i in t, nodal (Finset.erase t i) v
⊢ ∑ x in t, (X - C (v i)) * nodal (Finset.erase t x) v = ∑ x in t, nodal (Finset.erase (insert i t) x) v

Next tactic:
refine' sum_congr rfl fun j hjt => _
theorem derivative_nodal [DecidableEq ι] :
    derivative (nodal s v) = ∑ i in s, nodal (s.erase i) v := by
  refine' s.induction_on _ fun i t hit IH => _
  · rw [nodal_empty, derivative_one, sum_empty]
  · rw [nodal_insert_eq_nodal hit, derivative_mul, IH, derivative_sub, derivative_X, derivative_C,
      sub_zero, one_mul, sum_insert hit, mul_sum, erase_insert hit, add_right_inj]
    refine' sum_congr rfl fun j hjt => _
    

Proof state:
case refine'_2
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
t : Finset ι
hit : i ∉ t
IH : derivative (nodal t v) = ∑ i in t, nodal (Finset.erase t i) v
j : ι
hjt : j ∈ t
⊢ (X - C (v i)) * nodal (Finset.erase t j) v = nodal (Finset.erase (insert i t) j) v

Next tactic:
rw [t.erase_insert_of_ne (ne_of_mem_of_not_mem hjt hit).symm,
      nodal_insert_eq_nodal (mem_of_mem_erase.mt hit)]
theorem eval_nodal_derivative_eval_node_eq [DecidableEq ι] {i : ι} (hi : i ∈ s) :
    eval (v i) (derivative (nodal s v)) = eval (v i) (nodal (s.erase i) v) := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
hi : i ∈ s
⊢ eval (v i) (derivative (nodal s v)) = eval (v i) (nodal (Finset.erase s i) v)

Next tactic:
rw [derivative_nodal, eval_finset_sum, ← add_sum_erase _ _ hi, add_right_eq_self]
theorem eval_nodal_derivative_eval_node_eq [DecidableEq ι] {i : ι} (hi : i ∈ s) :
    eval (v i) (derivative (nodal s v)) = eval (v i) (nodal (s.erase i) v) := by
  rw [derivative_nodal, eval_finset_sum, ← add_sum_erase _ _ hi, add_right_eq_self]
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝ : DecidableEq ι
i : ι
hi : i ∈ s
⊢ ∑ x in Finset.erase s i, eval (v i) (nodal (Finset.erase s x) v) = 0

Next tactic:
exact sum_eq_zero fun j hj => (eval_nodal_at_node (mem_erase.mpr ⟨(mem_erase.mp hj).1.symm, hi⟩))
/-- The vanishing polynomial on a multiplicative subgroup is of the form X ^ n - 1. -/
@[simp] theorem nodal_subgroup_eq_X_pow_card_sub_one [IsDomain R]
  (G : Subgroup Rˣ) [Fintype G] :
  nodal (G : Set Rˣ).toFinset ((↑) : Rˣ → R) = X ^ (Fintype.card G) - 1 := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝¹ : IsDomain R
G : Subgroup Rˣ
inst✝ : Fintype ↥G
⊢ nodal (Set.toFinset ↑G) Units.val = X ^ Fintype.card ↥G - 1

Next tactic:
have h : degree (1 : R[X]) < degree ((X : R[X]) ^ Fintype.card G) := by simp [Fintype.card_pos]
/-- The vanishing polynomial on a multiplicative subgroup is of the form X ^ n - 1. -/
@[simp] theorem nodal_subgroup_eq_X_pow_card_sub_one [IsDomain R]
  (G : Subgroup Rˣ) [Fintype G] :
  nodal (G : Set Rˣ).toFinset ((↑) : Rˣ → R) = X ^ (Fintype.card G) - 1 := by
  have h : degree (1 : R[X]) < degree ((X : R[X]) ^ Fintype.card G) := by 

Proof state:
R : Type u_1
inst✝² : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝¹ : IsDomain R
G : Subgroup Rˣ
inst✝ : Fintype ↥G
⊢ degree 1 < degree (X ^ Fintype.card ↥G)

Next tactic:
simp [Fintype.card_pos]
/-- The vanishing polynomial on a multiplicative subgroup is of the form X ^ n - 1. -/
@[simp] theorem nodal_subgroup_eq_X_pow_card_sub_one [IsDomain R]
  (G : Subgroup Rˣ) [Fintype G] :
  nodal (G : Set Rˣ).toFinset ((↑) : Rˣ → R) = X ^ (Fintype.card G) - 1 := by
  have h : degree (1 : R[X]) < degree ((X : R[X]) ^ Fintype.card G) := by simp [Fintype.card_pos]
  

Proof state:
R : Type u_1
inst✝² : CommRing R
ι : Type u_2
s : Finset ι
v : ι → R
inst✝¹ : IsDomain R
G : Subgroup Rˣ
inst✝ : Fintype ↥G
h : degree 1 < degree (X ^ Fintype.card ↥G)
⊢ nodal (Set.toFinset ↑G) Units.val = X ^ Fintype.card ↥G - 1

Next tactic:
apply eq_of_degree_le_of_eval_index_eq (v := ((↑) : Rˣ → R)) (G : Set Rˣ).toFinset