l3lab/ntp-mathlib huggingface dataset:
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
⊢ i ∈ d₁.support ∨ i ∈ d₂.support

Next tactic:
simpa only [Finset.mem_union] using Finsupp.support_add hi
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · 

Proof state:
case intro.intro.intro.mk.inl
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₁.support
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
suffices coeff d₁ φ = 0 by simp [this]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by 

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₁.support
this : coeff d₁ φ = 0
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
simp [this]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    

Proof state:
case intro.intro.intro.mk.inl
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₁.support
⊢ coeff d₁ φ = 0

Next tactic:
rw [coeff, ← Finsupp.not_mem_support_iff]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    

Proof state:
case intro.intro.intro.mk.inl
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₁.support
⊢ d₁ ∉ φ.support

Next tactic:
intro
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    

Proof state:
case intro.intro.intro.mk.inl
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₁.support
a✝ : d₁ ∈ φ.support
⊢ False

Next tactic:
solve_by_elim
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    solve_by_elim
  · 

Proof state:
case intro.intro.intro.mk.inr
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₂.support
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
suffices coeff d₂ ψ = 0 by simp [this]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    solve_by_elim
  · suffices coeff d₂ ψ = 0 by 

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₂.support
this : coeff d₂ ψ = 0
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
simp [this]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    solve_by_elim
  · suffices coeff d₂ ψ = 0 by simp [this]
    

Proof state:
case intro.intro.intro.mk.inr
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₂.support
⊢ coeff d₂ ψ = 0

Next tactic:
rw [coeff, ← Finsupp.not_mem_support_iff]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    solve_by_elim
  · suffices coeff d₂ ψ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    

Proof state:
case intro.intro.intro.mk.inr
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₂.support
⊢ d₂ ∉ ψ.support

Next tactic:
intro
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  rw [mem_support_iff, coeff_mul] at hd
  contrapose! hd
  cases hd
  rw [Finset.sum_eq_zero]
  rintro ⟨d₁, d₂⟩ H
  rw [Finset.mem_antidiagonal] at H
  subst H
  obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi
  · suffices coeff d₁ φ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    solve_by_elim
  · suffices coeff d₂ ψ = 0 by simp [this]
    rw [coeff, ← Finsupp.not_mem_support_iff]
    intro
    

Proof state:
case intro.intro.intro.mk.inr
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
i : σ
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
hi : i ∈ ((d₁, d₂).1 + (d₁, d₂).2).support
H : i ∈ d₂.support
a✝ : d₂ ∈ ψ.support
⊢ False

Next tactic:
solve_by_elim
theorem vars_pow (φ : MvPolynomial σ R) (n : ℕ) : (φ ^ n).vars ⊆ φ.vars := by
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n✝ m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q φ : MvPolynomial σ R
n : ℕ
⊢ vars (φ ^ n) ⊆ vars φ

Next tactic:
classical
  induction' n with n ih
  · simp
  · rw [pow_succ]
    apply Finset.Subset.trans (vars_mul _ _)
    exact Finset.union_subset (Finset.Subset.refl _) ih
theorem vars_pow (φ : MvPolynomial σ R) (n : ℕ) : (φ ^ n).vars ⊆ φ.vars := by
  classical
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n✝ m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q φ : MvPolynomial σ R
n : ℕ
⊢ vars (φ ^ n) ⊆ vars φ

Next tactic:
induction' n with n ih
theorem vars_pow (φ : MvPolynomial σ R) (n : ℕ) : (φ ^ n).vars ⊆ φ.vars := by
  classical
  induction' n with n ih
  · 

Proof state:
case zero
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q φ : MvPolynomial σ R
⊢ vars (φ ^ Nat.zero) ⊆ vars φ

Next tactic:
simp
theorem vars_pow (φ : MvPolynomial σ R) (n : ℕ) : (φ ^ n).vars ⊆ φ.vars := by
  classical
  induction' n with n ih
  · simp
  · 

Proof state:
case succ
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n✝ m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q φ : MvPolynomial σ R
n : ℕ
ih : vars (φ ^ n) ⊆ vars φ
⊢ vars (φ ^ Nat.succ n) ⊆ vars φ

Next tactic:
rw [pow_succ]
theorem vars_pow (φ : MvPolynomial σ R) (n : ℕ) : (φ ^ n).vars ⊆ φ.vars := by
  classical
  induction' n with n ih
  · simp
  · rw [pow_succ]
    

Proof state:
case succ
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n✝ m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q φ : MvPolynomial σ R
n : ℕ
ih : vars (φ ^ n) ⊆ vars φ
⊢ vars (φ * φ ^ n) ⊆ vars φ

Next tactic:
apply Finset.Subset.trans (vars_mul _ _)
theorem vars_pow (φ : MvPolynomial σ R) (n : ℕ) : (φ ^ n).vars ⊆ φ.vars := by
  classical
  induction' n with n ih
  · simp
  · rw [pow_succ]
    apply Finset.Subset.trans (vars_mul _ _)
    

Proof state:
case succ
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n✝ m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q φ : MvPolynomial σ R
n : ℕ
ih : vars (φ ^ n) ⊆ vars φ
⊢ vars φ ∪ vars (φ ^ n) ⊆ vars φ

Next tactic:
exact Finset.union_subset (Finset.Subset.refl _) ih
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s✝ : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
s : Finset ι
f : ι → MvPolynomial σ R
⊢ vars (∏ i in s, f i) ⊆ Finset.biUnion s fun i => vars (f i)

Next tactic:
classical
  induction s using Finset.induction_on with
  | empty => simp
  | insert hs hsub =>
    simp only [hs, Finset.biUnion_insert, Finset.prod_insert, not_false_iff]
    apply Finset.Subset.trans (vars_mul _ _)
    exact Finset.union_subset_union (Finset.Subset.refl _) hsub
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s✝ : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
s : Finset ι
f : ι → MvPolynomial σ R
⊢ vars (∏ i in s, f i) ⊆ Finset.biUnion s fun i => vars (f i)

Next tactic:
induction s using Finset.induction_on with
  | empty => simp
  | insert hs hsub =>
    simp only [hs, Finset.biUnion_insert, Finset.prod_insert, not_false_iff]
    apply Finset.Subset.trans (vars_mul _ _)
    exact Finset.union_subset_union (Finset.Subset.refl _) hsub
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  induction s using Finset.induction_on with
  

Proof state:
case empty
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
f : ι → MvPolynomial σ R
⊢ vars (∏ i in ∅, f i) ⊆ Finset.biUnion ∅ fun i => vars (f i)

Next tactic:
| empty => simp
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  induction s using Finset.induction_on with
  | empty => 

Proof state:
case empty
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
f : ι → MvPolynomial σ R
⊢ vars (∏ i in ∅, f i) ⊆ Finset.biUnion ∅ fun i => vars (f i)

Next tactic:
simp
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  induction s using Finset.induction_on with
  | empty => simp
  

Proof state:
case insert
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
f : ι → MvPolynomial σ R
a✝ : ι
s✝ : Finset ι
hs : a✝ ∉ s✝
hsub : vars (∏ i in s✝, f i) ⊆ Finset.biUnion s✝ fun i => vars (f i)
⊢ vars (∏ i in insert a✝ s✝, f i) ⊆ Finset.biUnion (insert a✝ s✝) fun i => vars (f i)

Next tactic:
| insert hs hsub =>
    simp only [hs, Finset.biUnion_insert, Finset.prod_insert, not_false_iff]
    apply Finset.Subset.trans (vars_mul _ _)
    exact Finset.union_subset_union (Finset.Subset.refl _) hsub
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  induction s using Finset.induction_on with
  | empty => simp
  | insert hs hsub =>
    

Proof state:
case insert
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
f : ι → MvPolynomial σ R
a✝ : ι
s✝ : Finset ι
hs : a✝ ∉ s✝
hsub : vars (∏ i in s✝, f i) ⊆ Finset.biUnion s✝ fun i => vars (f i)
⊢ vars (∏ i in insert a✝ s✝, f i) ⊆ Finset.biUnion (insert a✝ s✝) fun i => vars (f i)

Next tactic:
simp only [hs, Finset.biUnion_insert, Finset.prod_insert, not_false_iff]
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  induction s using Finset.induction_on with
  | empty => simp
  | insert hs hsub =>
    simp only [hs, Finset.biUnion_insert, Finset.prod_insert, not_false_iff]
    

Proof state:
case insert
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
f : ι → MvPolynomial σ R
a✝ : ι
s✝ : Finset ι
hs : a✝ ∉ s✝
hsub : vars (∏ i in s✝, f i) ⊆ Finset.biUnion s✝ fun i => vars (f i)
⊢ vars (f a✝ * ∏ i in s✝, f i) ⊆ vars (f a✝) ∪ Finset.biUnion s✝ fun i => vars (f i)

Next tactic:
apply Finset.Subset.trans (vars_mul _ _)
/-- The variables of the product of a family of polynomials
are a subset of the union of the sets of variables of each polynomial.
-/
theorem vars_prod {ι : Type*} [DecidableEq σ] {s : Finset ι} (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).vars ⊆ s.biUnion fun i => (f i).vars := by
  classical
  induction s using Finset.induction_on with
  | empty => simp
  | insert hs hsub =>
    simp only [hs, Finset.biUnion_insert, Finset.prod_insert, not_false_iff]
    apply Finset.Subset.trans (vars_mul _ _)
    

Proof state:
case insert
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
inst✝ : DecidableEq σ
f : ι → MvPolynomial σ R
a✝ : ι
s✝ : Finset ι
hs : a✝ ∉ s✝
hsub : vars (∏ i in s✝, f i) ⊆ Finset.biUnion s✝ fun i => vars (f i)
⊢ vars (f a✝) ∪ vars (∏ i in s✝, f i) ⊆ vars (f a✝) ∪ Finset.biUnion s✝ fun i => vars (f i)

Next tactic:
exact Finset.union_subset_union (Finset.Subset.refl _) hsub
theorem vars_C_mul (a : A) (ha : a ≠ 0) (φ : MvPolynomial σ A) :
    (C a * φ : MvPolynomial σ A).vars = φ.vars := by
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
p q : MvPolynomial σ R
A : Type u_3
inst✝¹ : CommRing A
inst✝ : IsDomain A
a : A
ha : a ≠ 0
φ : MvPolynomial σ A
⊢ vars (C a * φ) = vars φ

Next tactic:
ext1 i
theorem vars_C_mul (a : A) (ha : a ≠ 0) (φ : MvPolynomial σ A) :
    (C a * φ : MvPolynomial σ A).vars = φ.vars := by
  ext1 i
  

Proof state:
case a
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
p q : MvPolynomial σ R
A : Type u_3
inst✝¹ : CommRing A
inst✝ : IsDomain A
a : A
ha : a ≠ 0
φ : MvPolynomial σ A
i : σ
⊢ i ∈ vars (C a * φ) ↔ i ∈ vars φ

Next tactic:
simp only [mem_vars, exists_prop, mem_support_iff]
theorem vars_C_mul (a : A) (ha : a ≠ 0) (φ : MvPolynomial σ A) :
    (C a * φ : MvPolynomial σ A).vars = φ.vars := by
  ext1 i
  simp only [mem_vars, exists_prop, mem_support_iff]
  

Proof state:
case a
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
p q : MvPolynomial σ R
A : Type u_3
inst✝¹ : CommRing A
inst✝ : IsDomain A
a : A
ha : a ≠ 0
φ : MvPolynomial σ A
i : σ
⊢ (∃ d, coeff d (C a * φ) ≠ 0 ∧ i ∈ d.support) ↔ ∃ d, coeff d φ ≠ 0 ∧ i ∈ d.support

Next tactic:
apply exists_congr
theorem vars_C_mul (a : A) (ha : a ≠ 0) (φ : MvPolynomial σ A) :
    (C a * φ : MvPolynomial σ A).vars = φ.vars := by
  ext1 i
  simp only [mem_vars, exists_prop, mem_support_iff]
  apply exists_congr
  

Proof state:
case a.h
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
p q : MvPolynomial σ R
A : Type u_3
inst✝¹ : CommRing A
inst✝ : IsDomain A
a : A
ha : a ≠ 0
φ : MvPolynomial σ A
i : σ
⊢ ∀ (a_1 : σ →₀ ℕ), coeff a_1 (C a * φ) ≠ 0 ∧ i ∈ a_1.support ↔ coeff a_1 φ ≠ 0 ∧ i ∈ a_1.support

Next tactic:
intro d
theorem vars_C_mul (a : A) (ha : a ≠ 0) (φ : MvPolynomial σ A) :
    (C a * φ : MvPolynomial σ A).vars = φ.vars := by
  ext1 i
  simp only [mem_vars, exists_prop, mem_support_iff]
  apply exists_congr
  intro d
  

Proof state:
case a.h
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
p q : MvPolynomial σ R
A : Type u_3
inst✝¹ : CommRing A
inst✝ : IsDomain A
a : A
ha : a ≠ 0
φ : MvPolynomial σ A
i : σ
d : σ →₀ ℕ
⊢ coeff d (C a * φ) ≠ 0 ∧ i ∈ d.support ↔ coeff d φ ≠ 0 ∧ i ∈ d.support

Next tactic:
apply and_congr _ Iff.rfl
theorem vars_C_mul (a : A) (ha : a ≠ 0) (φ : MvPolynomial σ A) :
    (C a * φ : MvPolynomial σ A).vars = φ.vars := by
  ext1 i
  simp only [mem_vars, exists_prop, mem_support_iff]
  apply exists_congr
  intro d
  apply and_congr _ Iff.rfl
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝² : CommSemiring R
p q : MvPolynomial σ R
A : Type u_3
inst✝¹ : CommRing A
inst✝ : IsDomain A
a : A
ha : a ≠ 0
φ : MvPolynomial σ A
i : σ
d : σ →₀ ℕ
⊢ coeff d (C a * φ) ≠ 0 ↔ coeff d φ ≠ 0

Next tactic:
rw [coeff_C_mul, mul_ne_zero_iff, eq_true ha, true_and_iff]
theorem vars_sum_subset [DecidableEq σ] :
    (∑ i in t, φ i).vars ⊆ Finset.biUnion t fun i => (φ i).vars := by
  

Proof state:
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝¹ : CommSemiring R
p q : MvPolynomial σ R
ι : Type u_3
t : Finset ι
φ : ι → MvPolynomial σ R
inst✝ : DecidableEq σ
⊢ vars (∑ i in t, φ i) ⊆ Finset.biUnion t fun i => vars (φ i)

Next tactic:
classical
  induction t using Finset.induction_on with
  | empty => simp
  | insert has hsum =>
    rw [Finset.biUnion_insert, Finset.sum_insert has]
    refine'
      Finset.Subset.trans (vars_add_subset _ _) (Finset.union_subset_union (Finset.Subset.refl _) _)
    assumption