l3lab/ntp-mathlib huggingface dataset:
theorem degrees_rename (f : σ → τ) (φ : MvPolynomial σ R) :
    (rename f φ).degrees ⊆ φ.degrees.map f := by
  classical
  intro i
  rw [mem_degrees, Multiset.mem_map]
  rintro ⟨d, hd, hi⟩
  obtain ⟨x, rfl, hx⟩ := coeff_rename_ne_zero _ _ _ hd
  simp only [Finsupp.mapDomain, Finsupp.mem_support_iff] at hi
  rw [sum_apply, Finsupp.sum] at hi
  contrapose! hi
  rw [Finset.sum_eq_zero]
  intro j hj
  simp only [exists_prop, mem_degrees] at hi
  specialize hi j ⟨x, hx, hj⟩
  

Proof state:
case intro.intro.intro.intro
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
f : σ → τ
φ : MvPolynomial σ R
i : τ
x : σ →₀ ℕ
hx : coeff x φ ≠ 0
hd : coeff (Finsupp.mapDomain f x) ((rename f) φ) ≠ 0
j : σ
hj : j ∈ x.support
hi : f j ≠ i
⊢ (fun₀ | f j => x j) i = 0

Next tactic:
rw [Finsupp.single_apply, if_neg hi]
theorem degrees_map_of_injective [CommSemiring S] (p : MvPolynomial σ R) {f : R →+* S}
    (hf : Injective f) : (map f p).degrees = p.degrees := 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✝ : CommSemiring S
p : MvPolynomial σ R
f : R →+* S
hf : Injective ⇑f
⊢ degrees ((map f) p) = degrees p

Next tactic:
simp only [degrees, MvPolynomial.support_map_of_injective _ hf]
theorem degrees_rename_of_injective {p : MvPolynomial σ R} {f : σ → τ} (h : Function.Injective f) :
    degrees (rename f p) = (degrees p).map f := 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 p : MvPolynomial σ R
f : σ → τ
h : Injective f
⊢ degrees ((rename f) p) = Multiset.map f (degrees p)

Next tactic:
classical
  simp only [degrees, Multiset.map_finset_sup p.support Finsupp.toMultiset f h,
    support_rename_of_injective h, Finset.sup_image]
  refine' Finset.sup_congr rfl fun x _ => _
  exact (Finsupp.toMultiset_map _ _).symm
theorem degrees_rename_of_injective {p : MvPolynomial σ R} {f : σ → τ} (h : Function.Injective f) :
    degrees (rename f p) = (degrees p).map f := 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 p : MvPolynomial σ R
f : σ → τ
h : Injective f
⊢ degrees ((rename f) p) = Multiset.map f (degrees p)

Next tactic:
simp only [degrees, Multiset.map_finset_sup p.support Finsupp.toMultiset f h,
    support_rename_of_injective h, Finset.sup_image]
theorem degrees_rename_of_injective {p : MvPolynomial σ R} {f : σ → τ} (h : Function.Injective f) :
    degrees (rename f p) = (degrees p).map f := by
  classical
  simp only [degrees, Multiset.map_finset_sup p.support Finsupp.toMultiset f h,
    support_rename_of_injective h, Finset.sup_image]
  

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 p : MvPolynomial σ R
f : σ → τ
h : Injective f
⊢ Finset.sup (support p) ((fun s => toMultiset s) ∘ Finsupp.mapDomain f) =
    Finset.sup (support p) (Multiset.map f ∘ ⇑toMultiset)

Next tactic:
refine' Finset.sup_congr rfl fun x _ => _
theorem degrees_rename_of_injective {p : MvPolynomial σ R} {f : σ → τ} (h : Function.Injective f) :
    degrees (rename f p) = (degrees p).map f := by
  classical
  simp only [degrees, Multiset.map_finset_sup p.support Finsupp.toMultiset f h,
    support_rename_of_injective h, Finset.sup_image]
  refine' Finset.sup_congr rfl fun x _ => _
  

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 p : MvPolynomial σ R
f : σ → τ
h : Injective f
x : σ →₀ ℕ
x✝ : x ∈ support p
⊢ ((fun s => toMultiset s) ∘ Finsupp.mapDomain f) x = (Multiset.map f ∘ ⇑toMultiset) x

Next tactic:
exact (Finsupp.toMultiset_map _ _).symm
theorem vars_def [DecidableEq σ] (p : MvPolynomial σ R) : p.vars = p.degrees.toFinset := 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 σ
p : MvPolynomial σ R
⊢ vars p = Multiset.toFinset (degrees p)

Next tactic:
rw [vars]
theorem vars_def [DecidableEq σ] (p : MvPolynomial σ R) : p.vars = p.degrees.toFinset := by
  rw [vars]
  

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 σ
p : MvPolynomial σ R
⊢ Multiset.toFinset (degrees p) = Multiset.toFinset (degrees p)

Next tactic:
convert rfl
@[simp]
theorem vars_0 : (0 : MvPolynomial σ R).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
⊢ vars 0 = ∅

Next tactic:
classical rw [vars_def, degrees_zero, Multiset.toFinset_zero]
@[simp]
theorem vars_0 : (0 : MvPolynomial σ R).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
⊢ vars 0 = ∅

Next tactic:
rw [vars_def, degrees_zero, Multiset.toFinset_zero]
@[simp]
theorem vars_monomial (h : r ≠ 0) : (monomial s r).vars = s.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
h : r ≠ 0
⊢ vars ((monomial s) r) = s.support

Next tactic:
classical rw [vars_def, degrees_monomial_eq _ _ h, Finsupp.toFinset_toMultiset]
@[simp]
theorem vars_monomial (h : r ≠ 0) : (monomial s r).vars = s.support := 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
h : r ≠ 0
⊢ vars ((monomial s) r) = s.support

Next tactic:
rw [vars_def, degrees_monomial_eq _ _ h, Finsupp.toFinset_toMultiset]
@[simp]
theorem vars_C : (C r : MvPolynomial σ R).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
⊢ vars (C r) = ∅

Next tactic:
classical rw [vars_def, degrees_C, Multiset.toFinset_zero]
@[simp]
theorem vars_C : (C r : MvPolynomial σ R).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
⊢ vars (C r) = ∅

Next tactic:
rw [vars_def, degrees_C, Multiset.toFinset_zero]
@[simp]
theorem vars_X [Nontrivial R] : (X n : MvPolynomial σ R).vars = {n} := 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✝ : Nontrivial R
⊢ vars (X n) = {n}

Next tactic:
rw [X, vars_monomial (one_ne_zero' R), Finsupp.support_single_ne_zero _ (one_ne_zero' ℕ)]
theorem mem_vars (i : σ) : i ∈ p.vars ↔ ∃ d ∈ p.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
i : σ
⊢ i ∈ vars p ↔ ∃ d ∈ support p, i ∈ d.support

Next tactic:
classical simp only [vars_def, Multiset.mem_toFinset, mem_degrees, mem_support_iff, exists_prop]
theorem mem_vars (i : σ) : i ∈ p.vars ↔ ∃ d ∈ p.support, i ∈ d.support := 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
i : σ
⊢ i ∈ vars p ↔ ∃ d ∈ support p, i ∈ d.support

Next tactic:
simp only [vars_def, Multiset.mem_toFinset, mem_degrees, mem_support_iff, exists_prop]
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∉ vars f
⊢ x v = 0

Next tactic:
classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  rw [degrees_def]
  rw [show f.support = insert x f.support from Eq.symm <| Finset.insert_eq_of_mem H]
  rw [Finset.sup_insert]
  simp only [Multiset.mem_union, Multiset.sup_eq_union]
  left
  rwa [← toFinset_toMultiset, Multiset.mem_toFinset] at h
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := 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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∉ vars f
⊢ x v = 0

Next tactic:
rw [vars_def, Multiset.mem_toFinset] at h
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∉ degrees f
⊢ x v = 0

Next tactic:
rw [← Finsupp.not_mem_support_iff]
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∉ degrees f
⊢ v ∉ x.support

Next tactic:
contrapose! h
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∈ x.support
⊢ v ∈ degrees f

Next tactic:
rw [degrees_def]
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  rw [degrees_def]
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∈ x.support
⊢ v ∈ Finset.sup (support f) fun s => toMultiset s

Next tactic:
rw [show f.support = insert x f.support from Eq.symm <| Finset.insert_eq_of_mem H]
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  rw [degrees_def]
  rw [show f.support = insert x f.support from Eq.symm <| Finset.insert_eq_of_mem H]
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∈ x.support
⊢ v ∈ Finset.sup (insert x (support f)) fun s => toMultiset s

Next tactic:
rw [Finset.sup_insert]
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  rw [degrees_def]
  rw [show f.support = insert x f.support from Eq.symm <| Finset.insert_eq_of_mem H]
  rw [Finset.sup_insert]
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∈ x.support
⊢ v ∈ toMultiset x ⊔ Finset.sup (support f) fun s => toMultiset s

Next tactic:
simp only [Multiset.mem_union, Multiset.sup_eq_union]
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  rw [degrees_def]
  rw [show f.support = insert x f.support from Eq.symm <| Finset.insert_eq_of_mem H]
  rw [Finset.sup_insert]
  simp only [Multiset.mem_union, Multiset.sup_eq_union]
  

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 f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∈ x.support
⊢ v ∈ toMultiset x ∨ v ∈ Finset.sup (support f) fun s => toMultiset s

Next tactic:
left
theorem mem_support_not_mem_vars_zero {f : MvPolynomial σ R} {x : σ →₀ ℕ} (H : x ∈ f.support)
    {v : σ} (h : v ∉ vars f) : x v = 0 := by
  classical
  rw [vars_def, Multiset.mem_toFinset] at h
  rw [← Finsupp.not_mem_support_iff]
  contrapose! h
  rw [degrees_def]
  rw [show f.support = insert x f.support from Eq.symm <| Finset.insert_eq_of_mem H]
  rw [Finset.sup_insert]
  simp only [Multiset.mem_union, Multiset.sup_eq_union]
  left
  

Proof state:
case h
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p q f : MvPolynomial σ R
x : σ →₀ ℕ
H : x ∈ support f
v : σ
h : v ∈ x.support
⊢ v ∈ toMultiset x

Next tactic:
rwa [← toFinset_toMultiset, Multiset.mem_toFinset] at h
theorem vars_add_subset [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).vars ⊆ p.vars ∪ q.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
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
⊢ vars (p + q) ⊆ vars p ∪ vars q

Next tactic:
intro x hx
theorem vars_add_subset [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).vars ⊆ p.vars ∪ q.vars := by
  intro x hx
  

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 σ
p q : MvPolynomial σ R
x : σ
hx : x ∈ vars (p + q)
⊢ x ∈ vars p ∪ vars q

Next tactic:
simp only [vars_def, Finset.mem_union, Multiset.mem_toFinset] at hx ⊢
theorem vars_add_subset [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).vars ⊆ p.vars ∪ q.vars := by
  intro x hx
  simp only [vars_def, Finset.mem_union, Multiset.mem_toFinset] at hx ⊢
  

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 σ
p q : MvPolynomial σ R
x : σ
hx : x ∈ degrees (p + q)
⊢ x ∈ degrees p ∨ x ∈ degrees q

Next tactic:
simpa using Multiset.mem_of_le (degrees_add _ _) hx
theorem vars_add_of_disjoint [DecidableEq σ] (h : Disjoint p.vars q.vars) :
    (p + q).vars = p.vars ∪ q.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
inst✝ : DecidableEq σ
h : Disjoint (vars p) (vars q)
⊢ vars (p + q) = vars p ∪ vars q

Next tactic:
apply Finset.Subset.antisymm (vars_add_subset p q)
theorem vars_add_of_disjoint [DecidableEq σ] (h : Disjoint p.vars q.vars) :
    (p + q).vars = p.vars ∪ q.vars := by
  apply Finset.Subset.antisymm (vars_add_subset p q)
  

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 σ
h : Disjoint (vars p) (vars q)
⊢ vars p ∪ vars q ⊆ vars (p + q)

Next tactic:
intro x hx
theorem vars_add_of_disjoint [DecidableEq σ] (h : Disjoint p.vars q.vars) :
    (p + q).vars = p.vars ∪ q.vars := by
  apply Finset.Subset.antisymm (vars_add_subset p q)
  intro x hx
  

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 σ
h : Disjoint (vars p) (vars q)
x : σ
hx : x ∈ vars p ∪ vars q
⊢ x ∈ vars (p + q)

Next tactic:
simp only [vars_def, Multiset.disjoint_toFinset] at h hx ⊢
theorem vars_add_of_disjoint [DecidableEq σ] (h : Disjoint p.vars q.vars) :
    (p + q).vars = p.vars ∪ q.vars := by
  apply Finset.Subset.antisymm (vars_add_subset p q)
  intro x hx
  simp only [vars_def, Multiset.disjoint_toFinset] at h hx ⊢
  

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 σ
x : σ
h : Multiset.Disjoint (degrees p) (degrees q)
hx : x ∈ Multiset.toFinset (degrees p) ∪ Multiset.toFinset (degrees q)
⊢ x ∈ Multiset.toFinset (degrees (p + q))

Next tactic:
rw [degrees_add_of_disjoint h, Multiset.toFinset_union]
theorem vars_add_of_disjoint [DecidableEq σ] (h : Disjoint p.vars q.vars) :
    (p + q).vars = p.vars ∪ q.vars := by
  apply Finset.Subset.antisymm (vars_add_subset p q)
  intro x hx
  simp only [vars_def, Multiset.disjoint_toFinset] at h hx ⊢
  rw [degrees_add_of_disjoint h, Multiset.toFinset_union]
  

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 σ
x : σ
h : Multiset.Disjoint (degrees p) (degrees q)
hx : x ∈ Multiset.toFinset (degrees p) ∪ Multiset.toFinset (degrees q)
⊢ x ∈ Multiset.toFinset (degrees p) ∪ Multiset.toFinset (degrees q)

Next tactic:
exact hx
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.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
inst✝ : DecidableEq σ
φ ψ : MvPolynomial σ R
⊢ vars (φ * ψ) ⊆ vars φ ∪ vars ψ

Next tactic:
intro i
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  

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 : σ
⊢ i ∈ vars (φ * ψ) → i ∈ vars φ ∪ vars ψ

Next tactic:
simp only [mem_vars, Finset.mem_union]
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  

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 : σ
⊢ (∃ d ∈ support (φ * ψ), i ∈ d.support) → (∃ d ∈ support φ, i ∈ d.support) ∨ ∃ d ∈ support ψ, i ∈ d.support

Next tactic:
rintro ⟨d, hd, hi⟩
theorem vars_mul [DecidableEq σ] (φ ψ : MvPolynomial σ R) : (φ * ψ).vars ⊆ φ.vars ∪ ψ.vars := by
  intro i
  simp only [mem_vars, Finset.mem_union]
  rintro ⟨d, hd, hi⟩
  

Proof state:
case intro.intro
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 : σ
d : σ →₀ ℕ
hd : d ∈ support (φ * ψ)
hi : i ∈ d.support
⊢ (∃ d ∈ support φ, i ∈ d.support) ∨ ∃ d ∈ support ψ, i ∈ d.support

Next tactic:
rw [mem_support_iff, coeff_mul] at hd
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
  

Proof state:
case intro.intro
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 : σ
d : σ →₀ ℕ
hd : ∑ x in Finset.antidiagonal d, coeff x.1 φ * coeff x.2 ψ ≠ 0
hi : i ∈ d.support
⊢ (∃ d ∈ support φ, i ∈ d.support) ∨ ∃ d ∈ support ψ, i ∈ d.support

Next tactic:
contrapose! hd
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
  

Proof state:
case intro.intro
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 : σ
d : σ →₀ ℕ
hi : i ∈ d.support
hd : (∀ d ∈ support φ, i ∉ d.support) ∧ ∀ d ∈ support ψ, i ∉ d.support
⊢ ∑ x in Finset.antidiagonal d, coeff x.1 φ * coeff x.2 ψ = 0

Next tactic:
cases hd
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
  

Proof state:
case intro.intro.intro
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 : σ
d : σ →₀ ℕ
hi : i ∈ d.support
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
⊢ ∑ x in Finset.antidiagonal d, coeff x.1 φ * coeff x.2 ψ = 0

Next tactic:
rw [Finset.sum_eq_zero]
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]
  

Proof state:
case intro.intro.intro
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 : σ
d : σ →₀ ℕ
hi : i ∈ d.support
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
⊢ ∀ x ∈ Finset.antidiagonal d, coeff x.1 φ * coeff x.2 ψ = 0

Next tactic:
rintro ⟨d₁, d₂⟩ H
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
  

Proof state:
case intro.intro.intro.mk
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 : σ
d : σ →₀ ℕ
hi : i ∈ d.support
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
H : (d₁, d₂) ∈ Finset.antidiagonal d
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
rw [Finset.mem_antidiagonal] at H
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
  

Proof state:
case intro.intro.intro.mk
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 : σ
d : σ →₀ ℕ
hi : i ∈ d.support
left✝ : ∀ d ∈ support φ, i ∉ d.support
right✝ : ∀ d ∈ support ψ, i ∉ d.support
d₁ d₂ : σ →₀ ℕ
H : (d₁, d₂).1 + (d₁, d₂).2 = d
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
subst H
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
  

Proof state:
case intro.intro.intro.mk
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
⊢ coeff (d₁, d₂).1 φ * coeff (d₁, d₂).2 ψ = 0

Next tactic:
obtain H | H : i ∈ d₁.support ∨ i ∈ d₂.support := by
    simpa only [Finset.mem_union] using Finsupp.support_add hi