l3lab/ntp-mathlib huggingface dataset:
theorem eq_zero_of_degree_lt_of_eval_index_eq_zero (hvs : Set.InjOn v s)
    (degree_f_lt : f.degree < s.card) (eval_f : ∀ i ∈ s, f.eval (v i) = 0) : f = 0 := by
  classical
    rw [← card_image_of_injOn hvs] at degree_f_lt
    refine' eq_zero_of_degree_lt_of_eval_finset_eq_zero _ degree_f_lt _
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_f_lt : degree f < ↑(card (image v s))
eval_f : ∀ i ∈ s, eval (v i) f = 0
⊢ ∀ x ∈ image v s, eval x f = 0

Next tactic:
intro x hx
theorem eq_zero_of_degree_lt_of_eval_index_eq_zero (hvs : Set.InjOn v s)
    (degree_f_lt : f.degree < s.card) (eval_f : ∀ i ∈ s, f.eval (v i) = 0) : f = 0 := by
  classical
    rw [← card_image_of_injOn hvs] at degree_f_lt
    refine' eq_zero_of_degree_lt_of_eval_finset_eq_zero _ degree_f_lt _
    intro x hx
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_f_lt : degree f < ↑(card (image v s))
eval_f : ∀ i ∈ s, eval (v i) f = 0
x : R
hx : x ∈ image v s
⊢ eval x f = 0

Next tactic:
rcases mem_image.mp hx with ⟨_, hj, rfl⟩
theorem eq_zero_of_degree_lt_of_eval_index_eq_zero (hvs : Set.InjOn v s)
    (degree_f_lt : f.degree < s.card) (eval_f : ∀ i ∈ s, f.eval (v i) = 0) : f = 0 := by
  classical
    rw [← card_image_of_injOn hvs] at degree_f_lt
    refine' eq_zero_of_degree_lt_of_eval_finset_eq_zero _ degree_f_lt _
    intro x hx
    rcases mem_image.mp hx with ⟨_, hj, rfl⟩
    

Proof state:
case intro.intro
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_f_lt : degree f < ↑(card (image v s))
eval_f : ∀ i ∈ s, eval (v i) f = 0
w✝ : ι
hj : w✝ ∈ s
hx : v w✝ ∈ image v s
⊢ eval (v w✝) f = 0

Next tactic:
exact eval_f _ hj
theorem eq_of_degree_sub_lt_of_eval_index_eq (hvs : Set.InjOn v s)
    (degree_fg_lt : (f - g).degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) :
    f = g := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_fg_lt : degree (f - g) < ↑(card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ f = g

Next tactic:
rw [← sub_eq_zero]
theorem eq_of_degree_sub_lt_of_eval_index_eq (hvs : Set.InjOn v s)
    (degree_fg_lt : (f - g).degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) :
    f = g := by
  rw [← sub_eq_zero]
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_fg_lt : degree (f - g) < ↑(card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ f - g = 0

Next tactic:
refine' eq_zero_of_degree_lt_of_eval_index_eq_zero _ hvs degree_fg_lt _
theorem eq_of_degree_sub_lt_of_eval_index_eq (hvs : Set.InjOn v s)
    (degree_fg_lt : (f - g).degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) :
    f = g := by
  rw [← sub_eq_zero]
  refine' eq_zero_of_degree_lt_of_eval_index_eq_zero _ hvs degree_fg_lt _
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_fg_lt : degree (f - g) < ↑(card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ ∀ i ∈ s, eval (v i) (f - g) = 0

Next tactic:
simp_rw [eval_sub, sub_eq_zero]
theorem eq_of_degree_sub_lt_of_eval_index_eq (hvs : Set.InjOn v s)
    (degree_fg_lt : (f - g).degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) :
    f = g := by
  rw [← sub_eq_zero]
  refine' eq_zero_of_degree_lt_of_eval_index_eq_zero _ hvs degree_fg_lt _
  simp_rw [eval_sub, sub_eq_zero]
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_fg_lt : degree (f - g) < ↑(card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ ∀ i ∈ s, eval (v i) f = eval (v i) g

Next tactic:
exact eval_fg
theorem eq_of_degrees_lt_of_eval_index_eq (hvs : Set.InjOn v s) (degree_f_lt : f.degree < s.card)
    (degree_g_lt : g.degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_f_lt : degree f < ↑(card s)
degree_g_lt : degree g < ↑(card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ f = g

Next tactic:
refine' eq_of_degree_sub_lt_of_eval_index_eq _ hvs _ eval_fg
theorem eq_of_degrees_lt_of_eval_index_eq (hvs : Set.InjOn v s) (degree_f_lt : f.degree < s.card)
    (degree_g_lt : g.degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
  refine' eq_of_degree_sub_lt_of_eval_index_eq _ hvs _ eval_fg
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_f_lt : degree f < ↑(card s)
degree_g_lt : degree g < ↑(card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ degree (f - g) < ↑(card s)

Next tactic:
rw [← mem_degreeLT] at degree_f_lt degree_g_lt ⊢
theorem eq_of_degrees_lt_of_eval_index_eq (hvs : Set.InjOn v s) (degree_f_lt : f.degree < s.card)
    (degree_g_lt : g.degree < s.card) (eval_fg : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
  refine' eq_of_degree_sub_lt_of_eval_index_eq _ hvs _ eval_fg
  rw [← mem_degreeLT] at degree_f_lt degree_g_lt ⊢
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
degree_f_lt : f ∈ degreeLT R (card s)
degree_g_lt : g ∈ degreeLT R (card s)
eval_fg : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ f - g ∈ degreeLT R (card s)

Next tactic:
exact Submodule.sub_mem _ degree_f_lt degree_g_lt
theorem eq_of_degree_le_of_eval_index_eq (hvs : Set.InjOn v s)
    (h_deg_le : f.degree ≤ s.card)
    (h_deg_eq : f.degree = g.degree)
    (hlc : f.leadingCoeff = g.leadingCoeff)
    (h_eval : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
h_deg_le : degree f ≤ ↑(card s)
h_deg_eq : degree f = degree g
hlc : leadingCoeff f = leadingCoeff g
h_eval : ∀ i ∈ s, eval (v i) f = eval (v i) g
⊢ f = g

Next tactic:
rcases eq_or_ne f 0 with rfl | hf
theorem eq_of_degree_le_of_eval_index_eq (hvs : Set.InjOn v s)
    (h_deg_le : f.degree ≤ s.card)
    (h_deg_eq : f.degree = g.degree)
    (hlc : f.leadingCoeff = g.leadingCoeff)
    (h_eval : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
  rcases eq_or_ne f 0 with rfl | hf
  · 

Proof state:
case inl
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
h_deg_le : degree 0 ≤ ↑(card s)
h_deg_eq : degree 0 = degree g
hlc : leadingCoeff 0 = leadingCoeff g
h_eval : ∀ i ∈ s, eval (v i) 0 = eval (v i) g
⊢ 0 = g

Next tactic:
rwa [degree_zero, eq_comm, degree_eq_bot, eq_comm] at h_deg_eq
theorem eq_of_degree_le_of_eval_index_eq (hvs : Set.InjOn v s)
    (h_deg_le : f.degree ≤ s.card)
    (h_deg_eq : f.degree = g.degree)
    (hlc : f.leadingCoeff = g.leadingCoeff)
    (h_eval : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
  rcases eq_or_ne f 0 with rfl | hf
  · rwa [degree_zero, eq_comm, degree_eq_bot, eq_comm] at h_deg_eq
  · 

Proof state:
case inr
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
f g : R[X]
ι : Type u_2
v : ι → R
s : Finset ι
hvs : Set.InjOn v ↑s
h_deg_le : degree f ≤ ↑(card s)
h_deg_eq : degree f = degree g
hlc : leadingCoeff f = leadingCoeff g
h_eval : ∀ i ∈ s, eval (v i) f = eval (v i) g
hf : f ≠ 0
⊢ f = g

Next tactic:
exact eq_of_degree_sub_lt_of_eval_index_eq s hvs
      (lt_of_lt_of_le (degree_sub_lt h_deg_eq hf hlc) h_deg_le)
      h_eval
theorem basisDivisor_self : basisDivisor x x = 0 := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
⊢ basisDivisor x x = 0

Next tactic:
simp only [basisDivisor, sub_self, inv_zero, map_zero, zero_mul]
theorem basisDivisor_inj (hxy : basisDivisor x y = 0) : x = y := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
hxy : basisDivisor x y = 0
⊢ x = y

Next tactic:
simp_rw [basisDivisor, mul_eq_zero, X_sub_C_ne_zero, or_false_iff, C_eq_zero, inv_eq_zero,
    sub_eq_zero] at hxy
theorem basisDivisor_inj (hxy : basisDivisor x y = 0) : x = y := by
  simp_rw [basisDivisor, mul_eq_zero, X_sub_C_ne_zero, or_false_iff, C_eq_zero, inv_eq_zero,
    sub_eq_zero] at hxy
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
hxy : x = y
⊢ x = y

Next tactic:
exact hxy
theorem basisDivisor_ne_zero_iff : basisDivisor x y ≠ 0 ↔ x ≠ y := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
⊢ basisDivisor x y ≠ 0 ↔ x ≠ y

Next tactic:
rw [Ne.def, basisDivisor_eq_zero_iff]
theorem degree_basisDivisor_of_ne (hxy : x ≠ y) : (basisDivisor x y).degree = 1 := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
hxy : x ≠ y
⊢ degree (basisDivisor x y) = 1

Next tactic:
rw [basisDivisor, degree_mul, degree_X_sub_C, degree_C, zero_add]
theorem degree_basisDivisor_of_ne (hxy : x ≠ y) : (basisDivisor x y).degree = 1 := by
  rw [basisDivisor, degree_mul, degree_X_sub_C, degree_C, zero_add]
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
hxy : x ≠ y
⊢ (x - y)⁻¹ ≠ 0

Next tactic:
exact inv_ne_zero (sub_ne_zero_of_ne hxy)
@[simp]
theorem degree_basisDivisor_self : (basisDivisor x x).degree = ⊥ := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
⊢ degree (basisDivisor x x) = ⊥

Next tactic:
rw [basisDivisor_self, degree_zero]
theorem natDegree_basisDivisor_self : (basisDivisor x x).natDegree = 0 := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
⊢ natDegree (basisDivisor x x) = 0

Next tactic:
rw [basisDivisor_self, natDegree_zero]
@[simp]
theorem eval_basisDivisor_right : eval y (basisDivisor x y) = 0 := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
⊢ eval y (basisDivisor x y) = 0

Next tactic:
simp only [basisDivisor, eval_mul, eval_C, eval_sub, eval_X, sub_self, mul_zero]
theorem eval_basisDivisor_left_of_ne (hxy : x ≠ y) : eval x (basisDivisor x y) = 1 := by
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
hxy : x ≠ y
⊢ eval x (basisDivisor x y) = 1

Next tactic:
simp only [basisDivisor, eval_mul, eval_C, eval_sub, eval_X]
theorem eval_basisDivisor_left_of_ne (hxy : x ≠ y) : eval x (basisDivisor x y) = 1 := by
  simp only [basisDivisor, eval_mul, eval_C, eval_sub, eval_X]
  

Proof state:
F : Type u_1
inst✝ : Field F
x y : F
hxy : x ≠ y
⊢ (x - y)⁻¹ * (x - y) = 1

Next tactic:
exact inv_mul_cancel (sub_ne_zero_of_ne hxy)
@[simp]
theorem basis_singleton (i : ι) : Lagrange.basis {i} v i = 1 := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i✝ j i : ι
⊢ Lagrange.basis {i} v i = 1

Next tactic:
rw [Lagrange.basis, erase_singleton, prod_empty]
@[simp]
theorem basis_pair_left (hij : i ≠ j) : Lagrange.basis {i, j} v i = basisDivisor (v i) (v j) := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hij : i ≠ j
⊢ Lagrange.basis {i, j} v i = basisDivisor (v i) (v j)

Next tactic:
simp only [Lagrange.basis, hij, erase_insert_eq_erase, erase_eq_of_not_mem, mem_singleton,
    not_false_iff, prod_singleton]
@[simp]
theorem basis_pair_right (hij : i ≠ j) : Lagrange.basis {i, j} v j = basisDivisor (v j) (v i) := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hij : i ≠ j
⊢ Lagrange.basis {i, j} v j = basisDivisor (v j) (v i)

Next tactic:
rw [pair_comm]
@[simp]
theorem basis_pair_right (hij : i ≠ j) : Lagrange.basis {i, j} v j = basisDivisor (v j) (v i) := by
  rw [pair_comm]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hij : i ≠ j
⊢ Lagrange.basis {j, i} v j = basisDivisor (v j) (v i)

Next tactic:
exact basis_pair_left hij.symm
theorem basis_ne_zero (hvs : Set.InjOn v s) (hi : i ∈ s) : Lagrange.basis s v i ≠ 0 := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ Lagrange.basis s v i ≠ 0

Next tactic:
simp_rw [Lagrange.basis, prod_ne_zero_iff, Ne.def, mem_erase]
theorem basis_ne_zero (hvs : Set.InjOn v s) (hi : i ∈ s) : Lagrange.basis s v i ≠ 0 := by
  simp_rw [Lagrange.basis, prod_ne_zero_iff, Ne.def, mem_erase]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ ∀ (a : ι), a ≠ i ∧ a ∈ s → ¬basisDivisor (v i) (v a) = 0

Next tactic:
rintro j ⟨hij, hj⟩
theorem basis_ne_zero (hvs : Set.InjOn v s) (hi : i ∈ s) : Lagrange.basis s v i ≠ 0 := by
  simp_rw [Lagrange.basis, prod_ne_zero_iff, Ne.def, mem_erase]
  rintro j ⟨hij, hj⟩
  

Proof state:
case intro
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
j : ι
hij : j ≠ i
hj : j ∈ s
⊢ ¬basisDivisor (v i) (v j) = 0

Next tactic:
rw [basisDivisor_eq_zero_iff, hvs.eq_iff hi hj]
theorem basis_ne_zero (hvs : Set.InjOn v s) (hi : i ∈ s) : Lagrange.basis s v i ≠ 0 := by
  simp_rw [Lagrange.basis, prod_ne_zero_iff, Ne.def, mem_erase]
  rintro j ⟨hij, hj⟩
  rw [basisDivisor_eq_zero_iff, hvs.eq_iff hi hj]
  

Proof state:
case intro
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
j : ι
hij : j ≠ i
hj : j ∈ s
⊢ ¬i = j

Next tactic:
exact hij.symm
@[simp]
theorem eval_basis_self (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).eval (v i) = 1 := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ eval (v i) (Lagrange.basis s v i) = 1

Next tactic:
rw [Lagrange.basis, eval_prod]
@[simp]
theorem eval_basis_self (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).eval (v i) = 1 := by
  rw [Lagrange.basis, eval_prod]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ ∏ j in Finset.erase s i, eval (v i) (basisDivisor (v i) (v j)) = 1

Next tactic:
refine' prod_eq_one fun j H => _
@[simp]
theorem eval_basis_self (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).eval (v i) = 1 := by
  rw [Lagrange.basis, eval_prod]
  refine' prod_eq_one fun j H => _
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
j : ι
H : j ∈ Finset.erase s i
⊢ eval (v i) (basisDivisor (v i) (v j)) = 1

Next tactic:
rw [eval_basisDivisor_left_of_ne]
@[simp]
theorem eval_basis_self (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).eval (v i) = 1 := by
  rw [Lagrange.basis, eval_prod]
  refine' prod_eq_one fun j H => _
  rw [eval_basisDivisor_left_of_ne]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
j : ι
H : j ∈ Finset.erase s i
⊢ v i ≠ v j

Next tactic:
rcases mem_erase.mp H with ⟨hij, hj⟩
@[simp]
theorem eval_basis_self (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).eval (v i) = 1 := by
  rw [Lagrange.basis, eval_prod]
  refine' prod_eq_one fun j H => _
  rw [eval_basisDivisor_left_of_ne]
  rcases mem_erase.mp H with ⟨hij, hj⟩
  

Proof state:
case intro
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
j : ι
H : j ∈ Finset.erase s i
hij : j ≠ i
hj : j ∈ s
⊢ v i ≠ v j

Next tactic:
exact mt (hvs hi hj) hij.symm
@[simp]
theorem eval_basis_of_ne (hij : i ≠ j) (hj : j ∈ s) : (Lagrange.basis s v i).eval (v j) = 0 := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hij : i ≠ j
hj : j ∈ s
⊢ eval (v j) (Lagrange.basis s v i) = 0

Next tactic:
simp_rw [Lagrange.basis, eval_prod, prod_eq_zero_iff]
@[simp]
theorem eval_basis_of_ne (hij : i ≠ j) (hj : j ∈ s) : (Lagrange.basis s v i).eval (v j) = 0 := by
  simp_rw [Lagrange.basis, eval_prod, prod_eq_zero_iff]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hij : i ≠ j
hj : j ∈ s
⊢ ∃ a ∈ Finset.erase s i, eval (v j) (basisDivisor (v i) (v a)) = 0

Next tactic:
exact ⟨j, ⟨mem_erase.mpr ⟨hij.symm, hj⟩, eval_basisDivisor_right⟩⟩
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ natDegree (Lagrange.basis s v i) = card s - 1

Next tactic:
have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ ∀ j ∈ Finset.erase s i, basisDivisor (v i) (v j) ≠ 0

Next tactic:
simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ ∀ (j : ι), j ≠ i ∧ j ∈ s → ¬v i = v j

Next tactic:
exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
H : ∀ j ∈ Finset.erase s i, basisDivisor (v i) (v j) ≠ 0
⊢ natDegree (Lagrange.basis s v i) = card s - 1

Next tactic:
rw [← card_erase_of_mem hi, card_eq_sum_ones]
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
  rw [← card_erase_of_mem hi, card_eq_sum_ones]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
H : ∀ j ∈ Finset.erase s i, basisDivisor (v i) (v j) ≠ 0
⊢ natDegree (Lagrange.basis s v i) = ∑ x in Finset.erase s i, 1

Next tactic:
convert natDegree_prod _ _ H using 1
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
  rw [← card_erase_of_mem hi, card_eq_sum_ones]
  convert natDegree_prod _ _ H using 1
  

Proof state:
case h.e'_3
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
H : ∀ j ∈ Finset.erase s i, basisDivisor (v i) (v j) ≠ 0
⊢ ∑ x in Finset.erase s i, 1 = ∑ i_1 in Finset.erase s i, natDegree (basisDivisor (v i) (v i_1))

Next tactic:
refine' sum_congr rfl fun j hj => (natDegree_basisDivisor_of_ne _).symm
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
  rw [← card_erase_of_mem hi, card_eq_sum_ones]
  convert natDegree_prod _ _ H using 1
  refine' sum_congr rfl fun j hj => (natDegree_basisDivisor_of_ne _).symm
  

Proof state:
case h.e'_3
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
H : ∀ j ∈ Finset.erase s i, basisDivisor (v i) (v j) ≠ 0
j : ι
hj : j ∈ Finset.erase s i
⊢ v i ≠ v j

Next tactic:
rw [Ne.def, ← basisDivisor_eq_zero_iff]
@[simp]
theorem natDegree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).natDegree = s.card - 1 := by
  have H : ∀ j, j ∈ s.erase i → basisDivisor (v i) (v j) ≠ 0 := by
    simp_rw [Ne.def, mem_erase, basisDivisor_eq_zero_iff]
    exact fun j ⟨hij₁, hj⟩ hij₂ => hij₁ (hvs hj hi hij₂.symm)
  rw [← card_erase_of_mem hi, card_eq_sum_ones]
  convert natDegree_prod _ _ H using 1
  refine' sum_congr rfl fun j hj => (natDegree_basisDivisor_of_ne _).symm
  rw [Ne.def, ← basisDivisor_eq_zero_iff]
  

Proof state:
case h.e'_3
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j✝ : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
H : ∀ j ∈ Finset.erase s i, basisDivisor (v i) (v j) ≠ 0
j : ι
hj : j ∈ Finset.erase s i
⊢ ¬basisDivisor (v i) (v j) = 0

Next tactic:
exact H _ hj
theorem degree_basis (hvs : Set.InjOn v s) (hi : i ∈ s) :
    (Lagrange.basis s v i).degree = ↑(s.card - 1) := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hi : i ∈ s
⊢ degree (Lagrange.basis s v i) = ↑(card s - 1)

Next tactic:
rw [degree_eq_natDegree (basis_ne_zero hvs hi), natDegree_basis hvs hi]
theorem sum_basis (hvs : Set.InjOn v s) (hs : s.Nonempty) :
    ∑ j in s, Lagrange.basis s v j = 1 := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hs : Finset.Nonempty s
⊢ ∑ j in s, Lagrange.basis s v j = 1

Next tactic:
refine' eq_of_degrees_lt_of_eval_index_eq s hvs (lt_of_le_of_lt (degree_sum_le _ _) _) _ _
theorem sum_basis (hvs : Set.InjOn v s) (hs : s.Nonempty) :
    ∑ j in s, Lagrange.basis s v j = 1 := by
  refine' eq_of_degrees_lt_of_eval_index_eq s hvs (lt_of_le_of_lt (degree_sum_le _ _) _) _ _
  · 

Proof state:
case refine'_1
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hs : Finset.Nonempty s
⊢ (sup s fun b => degree (Lagrange.basis s v b)) < ↑(card s)

Next tactic:
rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe s.card)]
theorem sum_basis (hvs : Set.InjOn v s) (hs : s.Nonempty) :
    ∑ j in s, Lagrange.basis s v j = 1 := by
  refine' eq_of_degrees_lt_of_eval_index_eq s hvs (lt_of_le_of_lt (degree_sum_le _ _) _) _ _
  · rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe s.card)]
    

Proof state:
case refine'_1
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i j : ι
hvs : Set.InjOn v ↑s
hs : Finset.Nonempty s
⊢ ∀ b ∈ s, degree (Lagrange.basis s v b) < ↑(card s)

Next tactic:
intro i hi
theorem sum_basis (hvs : Set.InjOn v s) (hs : s.Nonempty) :
    ∑ j in s, Lagrange.basis s v j = 1 := by
  refine' eq_of_degrees_lt_of_eval_index_eq s hvs (lt_of_le_of_lt (degree_sum_le _ _) _) _ _
  · rw [Nat.cast_withBot, Finset.sup_lt_iff (WithBot.bot_lt_coe s.card)]
    intro i hi
    

Proof state:
case refine'_1
F : Type u_1
inst✝¹ : Field F
ι : Type u_2
inst✝ : DecidableEq ι
s : Finset ι
v : ι → F
i✝ j : ι
hvs : Set.InjOn v ↑s
hs : Finset.Nonempty s
i : ι
hi : i ∈ s
⊢ degree (Lagrange.basis s v i) < ↑(card s)

Next tactic:
rw [degree_basis hvs hi, Nat.cast_withBot, WithBot.coe_lt_coe]