l3lab/ntp-mathlib huggingface dataset:
theorem induction_on_monomial {M : MvPolynomial σ R → Prop} (h_C : ∀ a, M (C a))
    (h_X : ∀ p n, M p → M (p * X n)) : ∀ s a, M (monomial s a) := by
  intro s a
  apply @Finsupp.induction σ ℕ _ _ s
  · show M (monomial 0 a)
    exact h_C a
  · intro n e p _hpn _he ih
    have : ∀ e : ℕ, M (monomial p a * X n ^ e) := by
      intro e
      induction e with
      | zero => 

Proof state:
case zero
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e✝ : ℕ
n✝ m : σ
s✝ : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
M : MvPolynomial σ R → Prop
h_C : ∀ (a : R), M (C a)
h_X : ∀ (p : MvPolynomial σ R) (n : σ), M p → M (p * X n)
s : σ →₀ ℕ
a : R
n : σ
e : ℕ
p : σ →₀ ℕ
_hpn : n ∉ p.support
_he : e ≠ 0
ih : M ((monomial p) a)
⊢ M ((monomial p) a * X n ^ Nat.zero)

Next tactic:
simp [ih]
theorem induction_on_monomial {M : MvPolynomial σ R → Prop} (h_C : ∀ a, M (C a))
    (h_X : ∀ p n, M p → M (p * X n)) : ∀ s a, M (monomial s a) := by
  intro s a
  apply @Finsupp.induction σ ℕ _ _ s
  · show M (monomial 0 a)
    exact h_C a
  · intro n e p _hpn _he ih
    have : ∀ e : ℕ, M (monomial p a * X n ^ e) := by
      intro e
      induction e with
      | zero => simp [ih]
      

Proof state:
case succ
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e✝¹ : ℕ
n✝ m : σ
s✝ : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
M : MvPolynomial σ R → Prop
h_C : ∀ (a : R), M (C a)
h_X : ∀ (p : MvPolynomial σ R) (n : σ), M p → M (p * X n)
s : σ →₀ ℕ
a : R
n : σ
e✝ : ℕ
p : σ →₀ ℕ
_hpn : n ∉ p.support
_he : e✝ ≠ 0
ih : M ((monomial p) a)
e : ℕ
e_ih : M ((monomial p) a * X n ^ e)
⊢ M ((monomial p) a * X n ^ Nat.succ e)

Next tactic:
| succ e e_ih => simp [ih, pow_succ', (mul_assoc _ _ _).symm, h_X, e_ih]
theorem induction_on_monomial {M : MvPolynomial σ R → Prop} (h_C : ∀ a, M (C a))
    (h_X : ∀ p n, M p → M (p * X n)) : ∀ s a, M (monomial s a) := by
  intro s a
  apply @Finsupp.induction σ ℕ _ _ s
  · show M (monomial 0 a)
    exact h_C a
  · intro n e p _hpn _he ih
    have : ∀ e : ℕ, M (monomial p a * X n ^ e) := by
      intro e
      induction e with
      | zero => simp [ih]
      | succ e e_ih => 

Proof state:
case succ
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e✝¹ : ℕ
n✝ m : σ
s✝ : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
M : MvPolynomial σ R → Prop
h_C : ∀ (a : R), M (C a)
h_X : ∀ (p : MvPolynomial σ R) (n : σ), M p → M (p * X n)
s : σ →₀ ℕ
a : R
n : σ
e✝ : ℕ
p : σ →₀ ℕ
_hpn : n ∉ p.support
_he : e✝ ≠ 0
ih : M ((monomial p) a)
e : ℕ
e_ih : M ((monomial p) a * X n ^ e)
⊢ M ((monomial p) a * X n ^ Nat.succ e)

Next tactic:
simp [ih, pow_succ', (mul_assoc _ _ _).symm, h_X, e_ih]
theorem induction_on_monomial {M : MvPolynomial σ R → Prop} (h_C : ∀ a, M (C a))
    (h_X : ∀ p n, M p → M (p * X n)) : ∀ s a, M (monomial s a) := by
  intro s a
  apply @Finsupp.induction σ ℕ _ _ s
  · show M (monomial 0 a)
    exact h_C a
  · intro n e p _hpn _he ih
    have : ∀ e : ℕ, M (monomial p a * X n ^ e) := by
      intro e
      induction e with
      | zero => simp [ih]
      | succ e e_ih => simp [ih, pow_succ', (mul_assoc _ _ _).symm, h_X, e_ih]
    

Proof state:
case ha
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a✝ a' a₁ a₂ : R
e✝ : ℕ
n✝ m : σ
s✝ : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
M : MvPolynomial σ R → Prop
h_C : ∀ (a : R), M (C a)
h_X : ∀ (p : MvPolynomial σ R) (n : σ), M p → M (p * X n)
s : σ →₀ ℕ
a : R
n : σ
e : ℕ
p : σ →₀ ℕ
_hpn : n ∉ p.support
_he : e ≠ 0
ih : M ((monomial p) a)
this : ∀ (e : ℕ), M ((monomial p) a * X n ^ e)
⊢ M ((monomial ((fun₀ | n => e) + p)) a)

Next tactic:
simp [add_comm, monomial_add_single, this]
/-- Analog of `Polynomial.induction_on'`.
To prove something about mv_polynomials,
it suffices to show the condition is closed under taking sums,
and it holds for monomials. -/
@[elab_as_elim]
theorem induction_on' {P : MvPolynomial σ R → Prop} (p : MvPolynomial σ R)
    (h1 : ∀ (u : σ →₀ ℕ) (a : R), P (monomial u a))
    (h2 : ∀ p q : MvPolynomial σ R, P p → P q → P (p + q)) : P p :=
  Finsupp.induction p
    (suffices P (monomial 0 0) by 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
P : MvPolynomial σ R → Prop
p : MvPolynomial σ R
h1 : ∀ (u : σ →₀ ℕ) (a : R), P ((monomial u) a)
h2 : ∀ (p q : MvPolynomial σ R), P p → P q → P (p + q)
this : P ((monomial 0) 0)
⊢ P 0

Next tactic:
rwa [monomial_zero] at this
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
⊢ f = g

Next tactic:
refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
  -- porting note: this has high priority, but Lean still chooses `RingHom.ext`, why?
  -- probably because of the type synonym
  · 

Proof state:
case refine_1
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
⊢ RingHom.comp f singleZeroRingHom = RingHom.comp g singleZeroRingHom

Next tactic:
ext x
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
  -- porting note: this has high priority, but Lean still chooses `RingHom.ext`, why?
  -- probably because of the type synonym
  · ext x
    

Proof state:
case refine_1.a
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
x : R
⊢ (RingHom.comp f singleZeroRingHom) x = (RingHom.comp g singleZeroRingHom) x

Next tactic:
exact hC _
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
  -- porting note: this has high priority, but Lean still chooses `RingHom.ext`, why?
  -- probably because of the type synonym
  · ext x
    exact hC _
  · 

Proof state:
case refine_2
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
⊢ MonoidHom.comp (↑f) (of R (σ →₀ ℕ)) = MonoidHom.comp (↑g) (of R (σ →₀ ℕ))

Next tactic:
apply Finsupp.mulHom_ext'
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
  -- porting note: this has high priority, but Lean still chooses `RingHom.ext`, why?
  -- probably because of the type synonym
  · ext x
    exact hC _
  · apply Finsupp.mulHom_ext'; 

Proof state:
case refine_2.H
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
⊢ ∀ (x : σ),
    MonoidHom.comp (MonoidHom.comp (↑f) (of R (σ →₀ ℕ))) (AddMonoidHom.toMultiplicative (singleAddHom x)) =
      MonoidHom.comp (MonoidHom.comp (↑g) (of R (σ →₀ ℕ))) (AddMonoidHom.toMultiplicative (singleAddHom x))

Next tactic:
intros x
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
  -- porting note: this has high priority, but Lean still chooses `RingHom.ext`, why?
  -- probably because of the type synonym
  · ext x
    exact hC _
  · apply Finsupp.mulHom_ext'; intros x
    -- porting note: `Finsupp.mulHom_ext'` needs to have increased priority
    

Proof state:
case refine_2.H
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
x : σ
⊢ MonoidHom.comp (MonoidHom.comp (↑f) (of R (σ →₀ ℕ))) (AddMonoidHom.toMultiplicative (singleAddHom x)) =
    MonoidHom.comp (MonoidHom.comp (↑g) (of R (σ →₀ ℕ))) (AddMonoidHom.toMultiplicative (singleAddHom x))

Next tactic:
apply MonoidHom.ext_mnat
theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A}
    (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by
  refine AddMonoidAlgebra.ringHom_ext' ?_ ?_
  -- porting note: this has high priority, but Lean still chooses `RingHom.ext`, why?
  -- probably because of the type synonym
  · ext x
    exact hC _
  · apply Finsupp.mulHom_ext'; intros x
    -- porting note: `Finsupp.mulHom_ext'` needs to have increased priority
    apply MonoidHom.ext_mnat
    

Proof state:
case refine_2.H.h
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
A : Type u_2
inst✝ : Semiring A
f g : MvPolynomial σ R →+* A
hC : ∀ (r : R), f (C r) = g (C r)
hX : ∀ (i : σ), f (X i) = g (X i)
x : σ
⊢ (MonoidHom.comp (MonoidHom.comp (↑f) (of R (σ →₀ ℕ))) (AddMonoidHom.toMultiplicative (singleAddHom x)))
      (Multiplicative.ofAdd 1) =
    (MonoidHom.comp (MonoidHom.comp (↑g) (of R (σ →₀ ℕ))) (AddMonoidHom.toMultiplicative (singleAddHom x)))
      (Multiplicative.ofAdd 1)

Next tactic:
exact hX _
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
⊢ Algebra.adjoin R (range X) = ⊤

Next tactic:
set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
⊢ S = ⊤

Next tactic:
refine' top_unique fun p hp => _
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p : MvPolynomial σ R
hp : p ∈ ⊤
⊢ p ∈ S

Next tactic:
clear hp
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p : MvPolynomial σ R
⊢ p ∈ S

Next tactic:
induction p using MvPolynomial.induction_on
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  

Proof state:
case h_C
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
a✝ : R
⊢ C a✝ ∈ S
case h_add
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p✝ q✝ : MvPolynomial σ R
a✝¹ : p✝ ∈ S
a✝ : q✝ ∈ S
⊢ p✝ + q✝ ∈ S
case h_X
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p✝ : MvPolynomial σ R
n✝ : σ
a✝ : p✝ ∈ S
⊢ p✝ * X n✝ ∈ S

Next tactic:
case h_C => exact S.algebraMap_mem _
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
a✝ : R
⊢ C a✝ ∈ S

Next tactic:
case h_C => exact S.algebraMap_mem _
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
a✝ : R
⊢ C a✝ ∈ S

Next tactic:
exact S.algebraMap_mem _
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => exact S.algebraMap_mem _
  

Proof state:
case h_add
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p✝ q✝ : MvPolynomial σ R
a✝¹ : p✝ ∈ S
a✝ : q✝ ∈ S
⊢ p✝ + q✝ ∈ S
case h_X
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p✝ : MvPolynomial σ R
n✝ : σ
a✝ : p✝ ∈ S
⊢ p✝ * X n✝ ∈ S

Next tactic:
case h_add p q hp hq => exact S.add_mem hp hq
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => exact S.algebraMap_mem _
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q✝ : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p q : MvPolynomial σ R
hp : p ∈ S
hq : q ∈ S
⊢ p + q ∈ S

Next tactic:
case h_add p q hp hq => exact S.add_mem hp hq
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => exact S.algebraMap_mem _
  case h_add p q hp hq => 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q✝ : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p q : MvPolynomial σ R
hp : p ∈ S
hq : q ∈ S
⊢ p + q ∈ S

Next tactic:
exact S.add_mem hp hq
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => exact S.algebraMap_mem _
  case h_add p q hp hq => exact S.add_mem hp hq
  

Proof state:
case h_X
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p✝ : MvPolynomial σ R
n✝ : σ
a✝ : p✝ ∈ S
⊢ p✝ * X n✝ ∈ S

Next tactic:
case h_X p i hp => exact S.mul_mem hp (Algebra.subset_adjoin <| mem_range_self _)
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => exact S.algebraMap_mem _
  case h_add p q hp hq => exact S.add_mem hp hq
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p : MvPolynomial σ R
i : σ
hp : p ∈ S
⊢ p * X i ∈ S

Next tactic:
case h_X p i hp => exact S.mul_mem hp (Algebra.subset_adjoin <| mem_range_self _)
@[simp]
theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) = ⊤ := by
  set S := Algebra.adjoin R (range (X : σ → MvPolynomial σ R))
  refine' top_unique fun p hp => _; clear hp
  induction p using MvPolynomial.induction_on
  case h_C => exact S.algebraMap_mem _
  case h_add p q hp hq => exact S.add_mem hp hq
  case h_X p i hp => 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q : MvPolynomial σ R
S : Subalgebra R (MvPolynomial σ R) := Algebra.adjoin R (range X)
p : MvPolynomial σ R
i : σ
hp : p ∈ S
⊢ p * X i ∈ S

Next tactic:
exact S.mul_mem hp (Algebra.subset_adjoin <| mem_range_self _)
theorem support_monomial [h : Decidable (a = 0)] :
    (monomial s a).support = if a = 0 then ∅ else {s} := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
h : Decidable (a = 0)
⊢ support ((monomial s) a) = if a = 0 then ∅ else {s}

Next tactic:
rw [← Subsingleton.elim (Classical.decEq R a 0) h]
theorem support_monomial [h : Decidable (a = 0)] :
    (monomial s a).support = if a = 0 then ∅ else {s} := by
  rw [← Subsingleton.elim (Classical.decEq R a 0) h]
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p q : MvPolynomial σ R
h : Decidable (a = 0)
⊢ support ((monomial s) a) = if a = 0 then ∅ else {s}

Next tactic:
rfl
theorem support_X [Nontrivial R] : (X n : MvPolynomial σ R).support = {Finsupp.single n 1} := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
inst✝ : Nontrivial R
⊢ support (X n) = {fun₀ | n => 1}

Next tactic:
classical rw [X, support_monomial, if_neg]; exact one_ne_zero
theorem support_X [Nontrivial R] : (X n : MvPolynomial σ R).support = {Finsupp.single n 1} := by
  classical 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
inst✝ : Nontrivial R
⊢ support (X n) = {fun₀ | n => 1}

Next tactic:
rw [X, support_monomial, if_neg]
theorem support_X [Nontrivial R] : (X n : MvPolynomial σ R).support = {Finsupp.single n 1} := by
  classical rw [X, support_monomial, if_neg]; 

Proof state:
case hnc
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
inst✝ : Nontrivial R
⊢ ¬1 = 0

Next tactic:
exact one_ne_zero
theorem support_X_pow [Nontrivial R] (s : σ) (n : ℕ) :
    (X s ^ n : MvPolynomial σ R).support = {Finsupp.single s n} := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n✝ m : σ
s✝ : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
inst✝ : Nontrivial R
s : σ
n : ℕ
⊢ support (X s ^ n) = {fun₀ | s => n}

Next tactic:
classical
    rw [X_pow_eq_monomial, support_monomial, if_neg (one_ne_zero' R)]
theorem support_X_pow [Nontrivial R] (s : σ) (n : ℕ) :
    (X s ^ n : MvPolynomial σ R).support = {Finsupp.single s n} := by
  classical
    

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n✝ m : σ
s✝ : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p q : MvPolynomial σ R
inst✝ : Nontrivial R
s : σ
n : ℕ
⊢ support (X s ^ n) = {fun₀ | s => n}

Next tactic:
rw [X_pow_eq_monomial, support_monomial, if_neg (one_ne_zero' R)]
@[simp]
theorem mem_support_iff {p : MvPolynomial σ R} {m : σ →₀ ℕ} : m ∈ p.support ↔ p.coeff m ≠ 0 := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m✝ : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q p : MvPolynomial σ R
m : σ →₀ ℕ
⊢ m ∈ support p ↔ coeff m p ≠ 0

Next tactic:
simp [support, coeff]
theorem not_mem_support_iff {p : MvPolynomial σ R} {m : σ →₀ ℕ} : m ∉ p.support ↔ p.coeff m = 0 :=
  by 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m✝ : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S₁
p✝ q p : MvPolynomial σ R
m : σ →₀ ℕ
⊢ m ∉ support p ↔ coeff m p = 0

Next tactic:
simp
theorem sum_def {A} [AddCommMonoid A] {p : MvPolynomial σ R} {b : (σ →₀ ℕ) → R → A} :
    p.sum b = ∑ m in p.support, b m (p.coeff m) := by 

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p✝ q : MvPolynomial σ R
A : Type u_2
inst✝ : AddCommMonoid A
p : MvPolynomial σ R
b : (σ →₀ ℕ) → R → A
⊢ sum p b = ∑ m in support p, b m (coeff m p)

Next tactic:
simp [support, Finsupp.sum, coeff]
theorem support_mul [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p * q).support ⊆ p.support.biUnion fun a => q.support.biUnion fun b => {a + b} := by
  

Proof state:
R : Type u
S₁ : Type v
S₂ : Type w
S₃ : Type x
σ : Type u_1
a a' a₁ a₂ : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S₁
p✝ q✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
⊢ support (p * q) ⊆ Finset.biUnion (support p) fun a => Finset.biUnion (support q) fun b => {a + b}

Next tactic:
convert AddMonoidAlgebra.support_mul p q