l3lab/ntp-mathlib huggingface dataset:
theorem multiset_sum_right (a : α) (h : ∀ b ∈ s, Commute a b) : Commute a s.sum := by
  induction s using Quotient.inductionOn
  

Proof state:
case h
α : Type u_1
inst✝ : NonUnitalNonAssocSemiring α
s : Multiset α
a : α
a✝ : List α
h : ∀ b ∈ ⟦a✝⟧, Commute a b
⊢ Commute a (sum ⟦a✝⟧)

Next tactic:
rw [quot_mk_to_coe, coe_sum]
theorem multiset_sum_right (a : α) (h : ∀ b ∈ s, Commute a b) : Commute a s.sum := by
  induction s using Quotient.inductionOn
  rw [quot_mk_to_coe, coe_sum]
  

Proof state:
case h
α : Type u_1
inst✝ : NonUnitalNonAssocSemiring α
s : Multiset α
a : α
a✝ : List α
h : ∀ b ∈ ⟦a✝⟧, Commute a b
⊢ Commute a (List.sum a✝)

Next tactic:
exact Commute.list_sum_right _ _ h
instance instCharP (p : ℕ) [h : CharP R p] : CharP R[X] p :=
  let ⟨h⟩ := h
  ⟨fun n => by 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
p : ℕ
h✝ : CharP R p
h : ∀ (x : ℕ), ↑x = 0 ↔ p ∣ x
n : ℕ
⊢ ↑n = 0 ↔ p ∣ n

Next tactic:
rw [← map_natCast C, ← C_0, C_inj, h]
theorem mem_degreeLE {n : WithBot ℕ} {f : R[X]} : f ∈ degreeLE R n ↔ degree f ≤ n := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : WithBot ℕ
f : R[X]
⊢ f ∈ degreeLE R n ↔ degree f ≤ n

Next tactic:
simp only [degreeLE, Submodule.mem_iInf, degree_le_iff_coeff_zero, LinearMap.mem_ker]
theorem mem_degreeLE {n : WithBot ℕ} {f : R[X]} : f ∈ degreeLE R n ↔ degree f ≤ n := by
  simp only [degreeLE, Submodule.mem_iInf, degree_le_iff_coeff_zero, LinearMap.mem_ker]; 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : WithBot ℕ
f : R[X]
⊢ (∀ (i : ℕ), ↑i > n → (lcoeff R i) f = 0) ↔ ∀ (m : ℕ), n < ↑m → coeff f m = 0

Next tactic:
rfl
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ degreeLE R ↑n = Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
apply le_antisymm
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · 

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ degreeLE R ↑n ≤ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
intro p hp
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : p ∈ degreeLE R ↑n
⊢ p ∈ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
replace hp := mem_degreeLE.1 hp
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p ≤ ↑n
⊢ p ∈ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p ≤ ↑n
⊢ ∑ n in support p, (monomial n) (coeff p n) ∈ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
refine' Submodule.sum_mem _ fun k hk => _
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p ≤ ↑n
k : ℕ
hk : k ∈ support p
⊢ (monomial k) (coeff p k) ∈ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p ≤ ↑n
k : ℕ
hk : k ∈ support p
this : k ≤ ↑n
⊢ (monomial k) (coeff p k) ∈ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
rw [← C_mul_X_pow_eq_monomial, C_mul']
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p ≤ ↑n
k : ℕ
hk : k ∈ support p
this : k ≤ ↑n
⊢ coeff p k • X ^ k ∈ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1)))

Next tactic:
refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <|
            Finset.mem_image.2 ⟨_, Finset.mem_range.2 (Nat.lt_succ_of_le this), rfl⟩)
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <|
            Finset.mem_image.2 ⟨_, Finset.mem_range.2 (Nat.lt_succ_of_le this), rfl⟩)
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ Submodule.span R ↑(image (fun n => X ^ n) (range (n + 1))) ≤ degreeLE R ↑n

Next tactic:
rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <|
            Finset.mem_image.2 ⟨_, Finset.mem_range.2 (Nat.lt_succ_of_le this), rfl⟩)
  rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ ↑(range (n + 1)) ⊆ (fun n => X ^ n) ⁻¹' ↑(degreeLE R ↑n)

Next tactic:
intro k hk
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <|
            Finset.mem_image.2 ⟨_, Finset.mem_range.2 (Nat.lt_succ_of_le this), rfl⟩)
  rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
  intro k hk
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n k : ℕ
hk : k ∈ ↑(range (n + 1))
⊢ k ∈ (fun n => X ^ n) ⁻¹' ↑(degreeLE R ↑n)

Next tactic:
apply mem_degreeLE.2
theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLE R n = Submodule.span R ↑((Finset.range (n + 1)).image fun n => (X : R[X]) ^ n) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLE.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_le_coe.1 (Finset.sup_le_iff.1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <|
            Finset.mem_image.2 ⟨_, Finset.mem_range.2 (Nat.lt_succ_of_le this), rfl⟩)
  rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
  intro k hk
  apply mem_degreeLE.2
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n k : ℕ
hk : k ∈ ↑(range (n + 1))
⊢ degree ((fun n => X ^ n) k) ≤ ↑n

Next tactic:
exact
    (degree_X_pow_le _).trans (WithBot.coe_le_coe.2 <| Nat.le_of_lt_succ <| Finset.mem_range.1 hk)
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ f ∈ degreeLT R n ↔ degree f < ↑n

Next tactic:
rw [degreeLT, Submodule.mem_iInf]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ (∀ (i : ℕ), f ∈ ⨅ (_ : i ≥ n), LinearMap.ker (lcoeff R i)) ↔ degree f < ↑n

Next tactic:
conv_lhs => intro i; rw [Submodule.mem_iInf]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
| ∀ (i : ℕ), f ∈ ⨅ (_ : i ≥ n), LinearMap.ker (lcoeff R i)

Next tactic:
intro i; rw [Submodule.mem_iInf]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
| ∀ (i : ℕ), f ∈ ⨅ (_ : i ≥ n), LinearMap.ker (lcoeff R i)

Next tactic:
intro i
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; 

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
i : ℕ
| f ∈ ⨅ (_ : i ≥ n), LinearMap.ker (lcoeff R i)

Next tactic:
rw [Submodule.mem_iInf]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ (∀ i ≥ n, f ∈ LinearMap.ker (lcoeff R i)) ↔ degree f < ↑n

Next tactic:
rw [degree, Finset.max_eq_sup_coe]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ (∀ i ≥ n, f ∈ LinearMap.ker (lcoeff R i)) ↔ sup (support f) WithBot.some < ↑n

Next tactic:
rw [Finset.sup_lt_iff ?_]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ (∀ i ≥ n, f ∈ LinearMap.ker (lcoeff R i)) ↔ ∀ b ∈ support f, ↑b < ↑n
R : Type u S : Type u_1 inst✝ : Semiring R n : ℕ f : R[X] ⊢ ⊥ < ↑n

Next tactic:
rotate_left
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  rotate_left
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ ⊥ < ↑n
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ (∀ i ≥ n, f ∈ LinearMap.ker (lcoeff R i)) ↔ ∀ b ∈ support f, ↑b < ↑n

Next tactic:
apply WithBot.bot_lt_coe
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  rotate_left
  apply WithBot.bot_lt_coe
  

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
⊢ (∀ i ≥ n, f ∈ LinearMap.ker (lcoeff R i)) ↔ ∀ b ∈ support f, ↑b < ↑n

Next tactic:
conv_rhs =>
    simp only [mem_support_iff]
    intro b
    rw [Nat.cast_withBot, WithBot.coe_lt_coe, lt_iff_not_le, Ne, not_imp_not]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  rotate_left
  apply WithBot.bot_lt_coe
  conv_rhs =>
    

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
| ∀ b ∈ support f, ↑b < ↑n

Next tactic:
simp only [mem_support_iff]
    intro b
    rw [Nat.cast_withBot, WithBot.coe_lt_coe, lt_iff_not_le, Ne, not_imp_not]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  rotate_left
  apply WithBot.bot_lt_coe
  conv_rhs =>
    

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
| ∀ b ∈ support f, ↑b < ↑n

Next tactic:
simp only [mem_support_iff]
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  rotate_left
  apply WithBot.bot_lt_coe
  conv_rhs =>
    simp only [mem_support_iff]
    

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
| ∀ (b : ℕ), coeff f b ≠ 0 → ↑b < ↑n

Next tactic:
intro b
theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by
  rw [degreeLT, Submodule.mem_iInf]
  conv_lhs => intro i; rw [Submodule.mem_iInf]
  rw [degree, Finset.max_eq_sup_coe]
  rw [Finset.sup_lt_iff ?_]
  rotate_left
  apply WithBot.bot_lt_coe
  conv_rhs =>
    simp only [mem_support_iff]
    intro b
    

Proof state:
R : Type u
S : Type u_1
inst✝ : Semiring R
n : ℕ
f : R[X]
b : ℕ
| coeff f b ≠ 0 → ↑b < ↑n

Next tactic:
rw [Nat.cast_withBot, WithBot.coe_lt_coe, lt_iff_not_le, Ne, not_imp_not]
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  

Proof state:
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ degreeLT R n = Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
apply le_antisymm
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · 

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ degreeLT R n ≤ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
intro p hp
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : p ∈ degreeLT R n
⊢ p ∈ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
replace hp := mem_degreeLT.1 hp
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p < ↑n
⊢ p ∈ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p < ↑n
⊢ ∑ n in support p, (monomial n) (coeff p n) ∈ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
refine' Submodule.sum_mem _ fun k hk => _
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p < ↑n
k : ℕ
hk : k ∈ support p
⊢ (monomial k) (coeff p k) ∈ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p < ↑n
k : ℕ
hk : k ∈ support p
this : k < n
⊢ (monomial k) (coeff p k) ∈ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
rw [← C_mul_X_pow_eq_monomial, C_mul']
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
p : R[X]
hp : degree p < ↑n
k : ℕ
hk : k ∈ support p
this : k < n
⊢ coeff p k • X ^ k ∈ Submodule.span R ↑(image (fun n => X ^ n) (range n))

Next tactic:
refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <| Finset.mem_image.2 ⟨_, Finset.mem_range.2 this, rfl⟩)
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <| Finset.mem_image.2 ⟨_, Finset.mem_range.2 this, rfl⟩)
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ Submodule.span R ↑(image (fun n => X ^ n) (range n)) ≤ degreeLT R n

Next tactic:
rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <| Finset.mem_image.2 ⟨_, Finset.mem_range.2 this, rfl⟩)
  rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n : ℕ
⊢ ↑(range n) ⊆ (fun n => X ^ n) ⁻¹' ↑(degreeLT R n)

Next tactic:
intro k hk
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <| Finset.mem_image.2 ⟨_, Finset.mem_range.2 this, rfl⟩)
  rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
  intro k hk
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n k : ℕ
hk : k ∈ ↑(range n)
⊢ k ∈ (fun n => X ^ n) ⁻¹' ↑(degreeLT R n)

Next tactic:
apply mem_degreeLT.2
theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} :
    degreeLT R n = Submodule.span R ↑((Finset.range n).image fun n => X ^ n : Finset R[X]) := by
  apply le_antisymm
  · intro p hp
    replace hp := mem_degreeLT.1 hp
    rw [← Polynomial.sum_monomial_eq p, Polynomial.sum]
    refine' Submodule.sum_mem _ fun k hk => _
    have := WithBot.coe_lt_coe.1 ((Finset.sup_lt_iff <| WithBot.bot_lt_coe n).1 hp k hk)
    rw [← C_mul_X_pow_eq_monomial, C_mul']
    refine'
      Submodule.smul_mem _ _
        (Submodule.subset_span <|
          Finset.mem_coe.2 <| Finset.mem_image.2 ⟨_, Finset.mem_range.2 this, rfl⟩)
  rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff]
  intro k hk
  apply mem_degreeLT.2
  

Proof state:
case a
R : Type u
S : Type u_1
inst✝¹ : Semiring R
inst✝ : DecidableEq R
n k : ℕ
hk : k ∈ ↑(range n)
⊢ degree ((fun n => X ^ n) k) < ↑n

Next tactic:
exact lt_of_le_of_lt (degree_X_pow_le _) (WithBot.coe_lt_coe.2 <| Finset.mem_range.1 hk)
/-- 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
    

Proof state:
R✝ : Type u
S : Type u_1
inst✝¹ : Semiring R✝
R : Type ?u.20962
inst✝ : Semiring R
n : ℕ
p q : ↥(degreeLT R n)
⊢ (fun p n_1 => coeff ↑p ↑n_1) (p + q) = (fun p n_1 => coeff ↑p ↑n_1) p + (fun p n_1 => coeff ↑p ↑n_1) q

Next tactic:
ext