l3lab/ntp-mathlib huggingface dataset:
/-- The first `n` coefficients on `degreeLT n` form a linear equivalence with `Fin n → R`. -/
def degreeLTEquiv (R) [Semiring R] (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where
  toFun p n := (↑p : R[X]).coeff n
  invFun f :=
    ⟨∑ i : Fin n, monomial i (f i),
      (degreeLT R n).sum_mem fun i _ =>
        mem_degreeLT.mpr
          (lt_of_le_of_lt (degree_monomial_le i (f i)) (WithBot.coe_lt_coe.mpr i.is_lt))⟩
  map_add' p q := by
    ext
    dsimp
    rw [coeff_add]
  map_smul' x p := by
    ext
    dsimp
    rw [coeff_smul]
    rfl
  left_inv := by
    rintro ⟨p, hp⟩
    ext1
    simp only [Submodule.coe_mk]
    by_cases hp0 : p = 0
    · subst hp0
      simp only [coeff_zero, LinearMap.map_zero, Finset.sum_const_zero]
    rw [mem_degreeLT, degree_eq_natDegree hp0, Nat.cast_lt] at hp
    conv_rhs => rw [p.as_sum_range' n hp, ← Fin.sum_univ_eq_sum_range]
  right_inv f := by
    ext i
    simp only [finset_sum_coeff, Submodule.coe_mk]
    rw [Finset.sum_eq_single i, coeff_monomial, if_pos rfl]
    · 

Proof state:
case h.h₀
R✝ : Type u
S : Type u_1
inst✝¹ : Semiring R✝
R : Type ?u.20962
inst✝ : Semiring R
n : ℕ
f : Fin n → R
i : Fin n
⊢ ∀ b ∈ univ, b ≠ i → coeff ((monomial ↑b) (f b)) ↑i = 0

Next tactic:
rintro j - hji
/-- The first `n` coefficients on `degreeLT n` form a linear equivalence with `Fin n → R`. -/
def degreeLTEquiv (R) [Semiring R] (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where
  toFun p n := (↑p : R[X]).coeff n
  invFun f :=
    ⟨∑ i : Fin n, monomial i (f i),
      (degreeLT R n).sum_mem fun i _ =>
        mem_degreeLT.mpr
          (lt_of_le_of_lt (degree_monomial_le i (f i)) (WithBot.coe_lt_coe.mpr i.is_lt))⟩
  map_add' p q := by
    ext
    dsimp
    rw [coeff_add]
  map_smul' x p := by
    ext
    dsimp
    rw [coeff_smul]
    rfl
  left_inv := by
    rintro ⟨p, hp⟩
    ext1
    simp only [Submodule.coe_mk]
    by_cases hp0 : p = 0
    · subst hp0
      simp only [coeff_zero, LinearMap.map_zero, Finset.sum_const_zero]
    rw [mem_degreeLT, degree_eq_natDegree hp0, Nat.cast_lt] at hp
    conv_rhs => rw [p.as_sum_range' n hp, ← Fin.sum_univ_eq_sum_range]
  right_inv f := by
    ext i
    simp only [finset_sum_coeff, Submodule.coe_mk]
    rw [Finset.sum_eq_single i, coeff_monomial, if_pos rfl]
    · rintro j - hji
      

Proof state:
case h.h₀
R✝ : Type u
S : Type u_1
inst✝¹ : Semiring R✝
R : Type ?u.20962
inst✝ : Semiring R
n : ℕ
f : Fin n → R
i j : Fin n
hji : j ≠ i
⊢ coeff ((monomial ↑j) (f j)) ↑i = 0

Next tactic:
rw [coeff_monomial, if_neg]
/-- The first `n` coefficients on `degreeLT n` form a linear equivalence with `Fin n → R`. -/
def degreeLTEquiv (R) [Semiring R] (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where
  toFun p n := (↑p : R[X]).coeff n
  invFun f :=
    ⟨∑ i : Fin n, monomial i (f i),
      (degreeLT R n).sum_mem fun i _ =>
        mem_degreeLT.mpr
          (lt_of_le_of_lt (degree_monomial_le i (f i)) (WithBot.coe_lt_coe.mpr i.is_lt))⟩
  map_add' p q := by
    ext
    dsimp
    rw [coeff_add]
  map_smul' x p := by
    ext
    dsimp
    rw [coeff_smul]
    rfl
  left_inv := by
    rintro ⟨p, hp⟩
    ext1
    simp only [Submodule.coe_mk]
    by_cases hp0 : p = 0
    · subst hp0
      simp only [coeff_zero, LinearMap.map_zero, Finset.sum_const_zero]
    rw [mem_degreeLT, degree_eq_natDegree hp0, Nat.cast_lt] at hp
    conv_rhs => rw [p.as_sum_range' n hp, ← Fin.sum_univ_eq_sum_range]
  right_inv f := by
    ext i
    simp only [finset_sum_coeff, Submodule.coe_mk]
    rw [Finset.sum_eq_single i, coeff_monomial, if_pos rfl]
    · rintro j - hji
      rw [coeff_monomial, if_neg]
      

Proof state:
case h.h₀.hnc
R✝ : Type u
S : Type u_1
inst✝¹ : Semiring R✝
R : Type ?u.20962
inst✝ : Semiring R
n : ℕ
f : Fin n → R
i j : Fin n
hji : j ≠ i
⊢ ¬↑j = ↑i

Next tactic:
rwa [← Fin.ext_iff]
/-- The first `n` coefficients on `degreeLT n` form a linear equivalence with `Fin n → R`. -/
def degreeLTEquiv (R) [Semiring R] (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where
  toFun p n := (↑p : R[X]).coeff n
  invFun f :=
    ⟨∑ i : Fin n, monomial i (f i),
      (degreeLT R n).sum_mem fun i _ =>
        mem_degreeLT.mpr
          (lt_of_le_of_lt (degree_monomial_le i (f i)) (WithBot.coe_lt_coe.mpr i.is_lt))⟩
  map_add' p q := by
    ext
    dsimp
    rw [coeff_add]
  map_smul' x p := by
    ext
    dsimp
    rw [coeff_smul]
    rfl
  left_inv := by
    rintro ⟨p, hp⟩
    ext1
    simp only [Submodule.coe_mk]
    by_cases hp0 : p = 0
    · subst hp0
      simp only [coeff_zero, LinearMap.map_zero, Finset.sum_const_zero]
    rw [mem_degreeLT, degree_eq_natDegree hp0, Nat.cast_lt] at hp
    conv_rhs => rw [p.as_sum_range' n hp, ← Fin.sum_univ_eq_sum_range]
  right_inv f := by
    ext i
    simp only [finset_sum_coeff, Submodule.coe_mk]
    rw [Finset.sum_eq_single i, coeff_monomial, if_pos rfl]
    · rintro j - hji
      rw [coeff_monomial, if_neg]
      rwa [← Fin.ext_iff]
    · 

Proof state:
case h.h₁
R✝ : Type u
S : Type u_1
inst✝¹ : Semiring R✝
R : Type ?u.20962
inst✝ : Semiring R
n : ℕ
f : Fin n → R
i : Fin n
⊢ i ∉ univ → coeff ((monomial ↑i) (f i)) ↑i = 0

Next tactic:
intro h
/-- The first `n` coefficients on `degreeLT n` form a linear equivalence with `Fin n → R`. -/
def degreeLTEquiv (R) [Semiring R] (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where
  toFun p n := (↑p : R[X]).coeff n
  invFun f :=
    ⟨∑ i : Fin n, monomial i (f i),
      (degreeLT R n).sum_mem fun i _ =>
        mem_degreeLT.mpr
          (lt_of_le_of_lt (degree_monomial_le i (f i)) (WithBot.coe_lt_coe.mpr i.is_lt))⟩
  map_add' p q := by
    ext
    dsimp
    rw [coeff_add]
  map_smul' x p := by
    ext
    dsimp
    rw [coeff_smul]
    rfl
  left_inv := by
    rintro ⟨p, hp⟩
    ext1
    simp only [Submodule.coe_mk]
    by_cases hp0 : p = 0
    · subst hp0
      simp only [coeff_zero, LinearMap.map_zero, Finset.sum_const_zero]
    rw [mem_degreeLT, degree_eq_natDegree hp0, Nat.cast_lt] at hp
    conv_rhs => rw [p.as_sum_range' n hp, ← Fin.sum_univ_eq_sum_range]
  right_inv f := by
    ext i
    simp only [finset_sum_coeff, Submodule.coe_mk]
    rw [Finset.sum_eq_single i, coeff_monomial, if_pos rfl]
    · rintro j - hji
      rw [coeff_monomial, if_neg]
      rwa [← Fin.ext_iff]
    · intro h
      

Proof state:
case h.h₁
R✝ : Type u
S : Type u_1
inst✝¹ : Semiring R✝
R : Type ?u.20962
inst✝ : Semiring R
n : ℕ
f : Fin n → R
i : Fin n
h : i ∉ univ
⊢ coeff ((monomial ↑i) (f i)) ↑i = 0

Next tactic:
exact (h (Finset.mem_univ _)).elim
theorem degreeLTEquiv_eq_zero_iff_eq_zero {n : ℕ} {p : R[X]} (hp : p ∈ degreeLT R n) :
    degreeLTEquiv _ _ ⟨p, hp⟩ = 0 ↔ p = 0 := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
p : R[X]
hp : p ∈ degreeLT R n
⊢ (degreeLTEquiv R n) { val := p, property := hp } = 0 ↔ p = 0

Next tactic:
rw [LinearEquiv.map_eq_zero_iff, Submodule.mk_eq_zero]
theorem eval_eq_sum_degreeLTEquiv {n : ℕ} {p : R[X]} (hp : p ∈ degreeLT R n) (x : R) :
    p.eval x = ∑ i, degreeLTEquiv _ _ ⟨p, hp⟩ i * x ^ (i : ℕ) := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
p : R[X]
hp : p ∈ degreeLT R n
x : R
⊢ eval x p = ∑ i : Fin n, (degreeLTEquiv R n) { val := p, property := hp } i * x ^ ↑i

Next tactic:
simp_rw [eval_eq_sum]
theorem eval_eq_sum_degreeLTEquiv {n : ℕ} {p : R[X]} (hp : p ∈ degreeLT R n) (x : R) :
    p.eval x = ∑ i, degreeLTEquiv _ _ ⟨p, hp⟩ i * x ^ (i : ℕ) := by
  simp_rw [eval_eq_sum]
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
p : R[X]
hp : p ∈ degreeLT R n
x : R
⊢ (sum p fun e a => a * x ^ e) = ∑ i : Fin n, (degreeLTEquiv R n) { val := p, property := hp } i * x ^ ↑i

Next tactic:
exact (sum_fin _ (by simp_rw [zero_mul, forall_const]) (mem_degreeLT.mp hp)).symm
theorem eval_eq_sum_degreeLTEquiv {n : ℕ} {p : R[X]} (hp : p ∈ degreeLT R n) (x : R) :
    p.eval x = ∑ i, degreeLTEquiv _ _ ⟨p, hp⟩ i * x ^ (i : ℕ) := by
  simp_rw [eval_eq_sum]
  exact (sum_fin _ (by 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
p : R[X]
hp : p ∈ degreeLT R n
x : R
⊢ ∀ (i : ℕ), 0 * x ^ i = 0

Next tactic:
simp_rw [zero_mul, forall_const]
theorem degreeLT_succ_eq_degreeLE {n : ℕ} : degreeLT R (n + 1) = degreeLE R n := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
⊢ degreeLT R (n + 1) = degreeLE R ↑n

Next tactic:
ext x
theorem degreeLT_succ_eq_degreeLE {n : ℕ} : degreeLT R (n + 1) = degreeLE R n := by
  ext x
  

Proof state:
case h
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
x : R[X]
⊢ x ∈ degreeLT R (n + 1) ↔ x ∈ degreeLE R ↑n

Next tactic:
by_cases x_zero : x = 0
theorem degreeLT_succ_eq_degreeLE {n : ℕ} : degreeLT R (n + 1) = degreeLE R n := by
  ext x
  by_cases x_zero : x = 0
  · 

Proof state:
case pos
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
x : R[X]
x_zero : x = 0
⊢ x ∈ degreeLT R (n + 1) ↔ x ∈ degreeLE R ↑n

Next tactic:
simp_rw [x_zero, Submodule.zero_mem]
theorem degreeLT_succ_eq_degreeLE {n : ℕ} : degreeLT R (n + 1) = degreeLE R n := by
  ext x
  by_cases x_zero : x = 0
  · simp_rw [x_zero, Submodule.zero_mem]
  · 

Proof state:
case neg
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
x : R[X]
x_zero : ¬x = 0
⊢ x ∈ degreeLT R (n + 1) ↔ x ∈ degreeLE R ↑n

Next tactic:
rw [mem_degreeLT, mem_degreeLE, ← natDegree_lt_iff_degree_lt (by rwa [ne_eq]),
      ← natDegree_le_iff_degree_le, Nat.lt_succ]
theorem degreeLT_succ_eq_degreeLE {n : ℕ} : degreeLT R (n + 1) = degreeLE R n := by
  ext x
  by_cases x_zero : x = 0
  · simp_rw [x_zero, Submodule.zero_mem]
  · rw [mem_degreeLT, mem_degreeLE, ← natDegree_lt_iff_degree_lt (by 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
x : R[X]
x_zero : ¬x = 0
⊢ x ≠ 0

Next tactic:
rwa [ne_eq]
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
⊢ ∃ p' ∈ s, degree p ≤ degree p'

Next tactic:
by_contra! h
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
⊢ False

Next tactic:
by_cases hp_zero : p = 0
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · 

Proof state:
case pos
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
hp_zero : p = 0
⊢ False

Next tactic:
rw [hp_zero, degree_zero] at h
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    

Proof state:
case pos
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < ⊥
hp_zero : p = 0
⊢ False

Next tactic:
rcases hs with ⟨x,hx⟩
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    rcases hs with ⟨x,hx⟩
    

Proof state:
case pos.intro
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < ⊥
hp_zero : p = 0
x : R[X]
hx : x ∈ s
⊢ False

Next tactic:
exact not_lt_bot (h x hx)
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    rcases hs with ⟨x,hx⟩
    exact not_lt_bot (h x hx)
  · 

Proof state:
case neg
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
hp_zero : ¬p = 0
⊢ False

Next tactic:
have : p ∈ degreeLT R (natDegree p) := by
      refine (Submodule.span_le.mpr fun p' p'_mem => ?_) hp
      rw [SetLike.mem_coe, mem_degreeLT, Nat.cast_withBot]
      exact lt_of_lt_of_le (h p' p'_mem) degree_le_natDegree
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    rcases hs with ⟨x,hx⟩
    exact not_lt_bot (h x hx)
  · have : p ∈ degreeLT R (natDegree p) := by
      

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
hp_zero : ¬p = 0
⊢ p ∈ degreeLT R (natDegree p)

Next tactic:
refine (Submodule.span_le.mpr fun p' p'_mem => ?_) hp
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    rcases hs with ⟨x,hx⟩
    exact not_lt_bot (h x hx)
  · have : p ∈ degreeLT R (natDegree p) := by
      refine (Submodule.span_le.mpr fun p' p'_mem => ?_) hp
      

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
hp_zero : ¬p = 0
p' : R[X]
p'_mem : p' ∈ s
⊢ p' ∈ ↑(degreeLT R (natDegree p))

Next tactic:
rw [SetLike.mem_coe, mem_degreeLT, Nat.cast_withBot]
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    rcases hs with ⟨x,hx⟩
    exact not_lt_bot (h x hx)
  · have : p ∈ degreeLT R (natDegree p) := by
      refine (Submodule.span_le.mpr fun p' p'_mem => ?_) hp
      rw [SetLike.mem_coe, mem_degreeLT, Nat.cast_withBot]
      

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
hp_zero : ¬p = 0
p' : R[X]
p'_mem : p' ∈ s
⊢ degree p' < ↑(natDegree p)

Next tactic:
exact lt_of_lt_of_le (h p' p'_mem) degree_le_natDegree
/-- For every polynomial `p` in the span of a set `s : Set R[X]`, there exists a polynomial of
  `p' ∈ s` with higher degree. See also `Polynomial.exists_degree_le_of_mem_span_of_finite`. -/
theorem exists_degree_le_of_mem_span {s : Set R[X]} {p : R[X]}
    (hs : s.Nonempty) (hp : p ∈ Submodule.span R s) :
    ∃ p' ∈ s, degree p ≤ degree p' := by
  by_contra! h
  by_cases hp_zero : p = 0
  · rw [hp_zero, degree_zero] at h
    rcases hs with ⟨x,hx⟩
    exact not_lt_bot (h x hx)
  · have : p ∈ degreeLT R (natDegree p) := by
      refine (Submodule.span_le.mpr fun p' p'_mem => ?_) hp
      rw [SetLike.mem_coe, mem_degreeLT, Nat.cast_withBot]
      exact lt_of_lt_of_le (h p' p'_mem) degree_le_natDegree
    

Proof state:
case neg
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
p : R[X]
hs : Set.Nonempty s
hp : p ∈ Submodule.span R s
h : ∀ p' ∈ s, degree p' < degree p
hp_zero : ¬p = 0
this : p ∈ degreeLT R (natDegree p)
⊢ False

Next tactic:
rwa [mem_degreeLT, Nat.cast_withBot, degree_eq_natDegree hp_zero,
      Nat.cast_withBot, lt_self_iff_false] at this
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
⊢ ∃ p' ∈ s, ∀ p ∈ Submodule.span R s, degree p ≤ degree p'

Next tactic:
rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
  

Proof state:
case intro.intro
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
a : R[X]
has : a ∈ s
hmax : ∀ a' ∈ s, degree a ≤ degree a' → degree a = degree a'
⊢ ∃ p' ∈ s, ∀ p ∈ Submodule.span R s, degree p ≤ degree p'

Next tactic:
refine ⟨a, has, fun p hp => ?_⟩
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
  refine ⟨a, has, fun p hp => ?_⟩
  

Proof state:
case intro.intro
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
a : R[X]
has : a ∈ s
hmax : ∀ a' ∈ s, degree a ≤ degree a' → degree a = degree a'
p : R[X]
hp : p ∈ Submodule.span R s
⊢ degree p ≤ degree a

Next tactic:
rcases exists_degree_le_of_mem_span hs hp with ⟨p', hp'⟩
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
  refine ⟨a, has, fun p hp => ?_⟩
  rcases exists_degree_le_of_mem_span hs hp with ⟨p', hp'⟩
  

Proof state:
case intro.intro.intro
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
a : R[X]
has : a ∈ s
hmax : ∀ a' ∈ s, degree a ≤ degree a' → degree a = degree a'
p : R[X]
hp : p ∈ Submodule.span R s
p' : R[X]
hp' : p' ∈ s ∧ degree p ≤ degree p'
⊢ degree p ≤ degree a

Next tactic:
have p'max := hmax p' hp'.left
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
  refine ⟨a, has, fun p hp => ?_⟩
  rcases exists_degree_le_of_mem_span hs hp with ⟨p', hp'⟩
  have p'max := hmax p' hp'.left
  

Proof state:
case intro.intro.intro
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
a : R[X]
has : a ∈ s
hmax : ∀ a' ∈ s, degree a ≤ degree a' → degree a = degree a'
p : R[X]
hp : p ∈ Submodule.span R s
p' : R[X]
hp' : p' ∈ s ∧ degree p ≤ degree p'
p'max : degree a ≤ degree p' → degree a = degree p'
⊢ degree p ≤ degree a

Next tactic:
by_cases h : degree a ≤ degree p'
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
  refine ⟨a, has, fun p hp => ?_⟩
  rcases exists_degree_le_of_mem_span hs hp with ⟨p', hp'⟩
  have p'max := hmax p' hp'.left
  by_cases h : degree a ≤ degree p'
  · 

Proof state:
case pos
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
a : R[X]
has : a ∈ s
hmax : ∀ a' ∈ s, degree a ≤ degree a' → degree a = degree a'
p : R[X]
hp : p ∈ Submodule.span R s
p' : R[X]
hp' : p' ∈ s ∧ degree p ≤ degree p'
p'max : degree a ≤ degree p' → degree a = degree p'
h : degree a ≤ degree p'
⊢ degree p ≤ degree a

Next tactic:
rw [← p'max h] at hp'
/-- A stronger version of `Polynomial.exists_degree_le_of_mem_span` under the assumption that the
  set `s : R[X]` is finite. There exists a polynomial `p' ∈ s` whose degree dominates the degree of
  every element of `p ∈ span R s`-/
theorem exists_degree_le_of_mem_span_of_finite {s : Set R[X]} (s_fin : s.Finite) (hs : s.Nonempty) :
    ∃ p' ∈ s, ∀ (p : R[X]), p ∈ Submodule.span R s → degree p ≤ degree p' := by
  rcases Set.Finite.exists_maximal_wrt degree s s_fin hs with ⟨a, has, hmax⟩
  refine ⟨a, has, fun p hp => ?_⟩
  rcases exists_degree_le_of_mem_span hs hp with ⟨p', hp'⟩
  have p'max := hmax p' hp'.left
  by_cases h : degree a ≤ degree p'
  · rw [← p'max h] at hp'; 

Proof state:
case pos
R : Type u
S : Type u_1
inst✝ : Semiring R
s : Set R[X]
s_fin : Set.Finite s
hs : Set.Nonempty s
a : R[X]
has : a ∈ s
hmax : ∀ a' ∈ s, degree a ≤ degree a' → degree a = degree a'
p : R[X]
hp : p ∈ Submodule.span R s
p' : R[X]
hp' : p' ∈ s ∧ degree p ≤ degree a
p'max : degree a ≤ degree p' → degree a = degree p'
h : degree a ≤ degree p'
⊢ degree p ≤ degree a

Next tactic:
exact hp'.right