l3lab/ntp-mathlib huggingface dataset:
theorem degrees_sum {ι : Type*} [DecidableEq σ] (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∑ i in s, f i).degrees ≤ s.sup fun i => (f i).degrees := by
  classical
  refine' s.induction _ _
  · simp only [Finset.sum_empty, Finset.sup_empty, degrees_zero]
    exact le_rfl
  · intro i s his ih
    

Proof state:
case refine'_2
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
i : ι
s : Finset ι
his : i ∉ s
ih : degrees (∑ i in s, f i) ≤ Finset.sup s fun i => degrees (f i)
⊢ degrees (∑ i in insert i s, f i) ≤ Finset.sup (insert i s) fun i => degrees (f i)

Next tactic:
rw [Finset.sup_insert, Finset.sum_insert his]
theorem degrees_sum {ι : Type*} [DecidableEq σ] (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∑ i in s, f i).degrees ≤ s.sup fun i => (f i).degrees := by
  classical
  refine' s.induction _ _
  · simp only [Finset.sum_empty, Finset.sup_empty, degrees_zero]
    exact le_rfl
  · intro i s his ih
    rw [Finset.sup_insert, Finset.sum_insert his]
    

Proof state:
case refine'_2
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
i : ι
s : Finset ι
his : i ∉ s
ih : degrees (∑ i in s, f i) ≤ Finset.sup s fun i => degrees (f i)
⊢ degrees (f i + ∑ x in s, f x) ≤ degrees (f i) ⊔ Finset.sup s fun i => degrees (f i)

Next tactic:
exact le_trans (degrees_add _ _) (sup_le_sup_left ih _)
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.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✝ p q : MvPolynomial σ R
⊢ degrees (p * q) ≤ degrees p + degrees q

Next tactic:
classical
  refine' Finset.sup_le fun b hb => _
  have := support_mul p q hb
  simp only [Finset.mem_biUnion, Finset.mem_singleton] at this
  rcases this with ⟨a₁, h₁, a₂, h₂, rfl⟩
  rw [Finsupp.toMultiset_add]
  exact add_le_add (Finset.le_sup h₁) (Finset.le_sup h₂)
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.degrees := 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 q : MvPolynomial σ R
⊢ degrees (p * q) ≤ degrees p + degrees q

Next tactic:
refine' Finset.sup_le fun b hb => _
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.degrees := by
  classical
  refine' Finset.sup_le fun b hb => _
  

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 q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p * q)
⊢ toMultiset b ≤ degrees p + degrees q

Next tactic:
have := support_mul p q hb
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.degrees := by
  classical
  refine' Finset.sup_le fun b hb => _
  have := support_mul p q hb
  

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 q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p * q)
this : b ∈ Finset.biUnion (support p) fun a => Finset.biUnion (support q) fun b => {a + b}
⊢ toMultiset b ≤ degrees p + degrees q

Next tactic:
simp only [Finset.mem_biUnion, Finset.mem_singleton] at this
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.degrees := by
  classical
  refine' Finset.sup_le fun b hb => _
  have := support_mul p q hb
  simp only [Finset.mem_biUnion, Finset.mem_singleton] at this
  

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 q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p * q)
this : ∃ a ∈ support p, ∃ a_1 ∈ support q, b = a + a_1
⊢ toMultiset b ≤ degrees p + degrees q

Next tactic:
rcases this with ⟨a₁, h₁, a₂, h₂, rfl⟩
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.degrees := by
  classical
  refine' Finset.sup_le fun b hb => _
  have := support_mul p q hb
  simp only [Finset.mem_biUnion, Finset.mem_singleton] at this
  rcases this with ⟨a₁, h₁, a₂, h₂, rfl⟩
  

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✝ p q : MvPolynomial σ R
a₁ : σ →₀ ℕ
h₁ : a₁ ∈ support p
a₂ : σ →₀ ℕ
h₂ : a₂ ∈ support q
hb : a₁ + a₂ ∈ support (p * q)
⊢ toMultiset (a₁ + a₂) ≤ degrees p + degrees q

Next tactic:
rw [Finsupp.toMultiset_add]
theorem degrees_mul (p q : MvPolynomial σ R) : (p * q).degrees ≤ p.degrees + q.degrees := by
  classical
  refine' Finset.sup_le fun b hb => _
  have := support_mul p q hb
  simp only [Finset.mem_biUnion, Finset.mem_singleton] at this
  rcases this with ⟨a₁, h₁, a₂, h₂, rfl⟩
  rw [Finsupp.toMultiset_add]
  

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✝ p q : MvPolynomial σ R
a₁ : σ →₀ ℕ
h₁ : a₁ ∈ support p
a₂ : σ →₀ ℕ
h₂ : a₂ ∈ support q
hb : a₁ + a₂ ∈ support (p * q)
⊢ toMultiset a₁ + toMultiset a₂ ≤ degrees p + degrees q

Next tactic:
exact add_le_add (Finset.le_sup h₁) (Finset.le_sup h₂)
theorem degrees_prod {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).degrees ≤ ∑ i in s, (f i).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
ι : Type u_3
s : Finset ι
f : ι → MvPolynomial σ R
⊢ degrees (∏ i in s, f i) ≤ ∑ i in s, degrees (f i)

Next tactic:
classical
  refine' s.induction _ _
  · simp only [Finset.prod_empty, Finset.sum_empty, degrees_one, le_refl]
  · intro i s his ih
    rw [Finset.prod_insert his, Finset.sum_insert his]
    exact le_trans (degrees_mul _ _) (add_le_add_left ih _)
theorem degrees_prod {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).degrees ≤ ∑ i in s, (f i).degrees := 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
s : Finset ι
f : ι → MvPolynomial σ R
⊢ degrees (∏ i in s, f i) ≤ ∑ i in s, degrees (f i)

Next tactic:
refine' s.induction _ _
theorem degrees_prod {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).degrees ≤ ∑ i in s, (f i).degrees := by
  classical
  refine' s.induction _ _
  · 

Proof state:
case refine'_1
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
s : Finset ι
f : ι → MvPolynomial σ R
⊢ degrees (∏ i in ∅, f i) ≤ ∑ i in ∅, degrees (f i)

Next tactic:
simp only [Finset.prod_empty, Finset.sum_empty, degrees_one, le_refl]
theorem degrees_prod {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).degrees ≤ ∑ i in s, (f i).degrees := by
  classical
  refine' s.induction _ _
  · simp only [Finset.prod_empty, Finset.sum_empty, degrees_one, le_refl]
  · 

Proof state:
case refine'_2
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
s : Finset ι
f : ι → MvPolynomial σ R
⊢ ∀ ⦃a : ι⦄ {s : Finset ι},
    a ∉ s →
      degrees (∏ i in s, f i) ≤ ∑ i in s, degrees (f i) →
        degrees (∏ i in insert a s, f i) ≤ ∑ i in insert a s, degrees (f i)

Next tactic:
intro i s his ih
theorem degrees_prod {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).degrees ≤ ∑ i in s, (f i).degrees := by
  classical
  refine' s.induction _ _
  · simp only [Finset.prod_empty, Finset.sum_empty, degrees_one, le_refl]
  · intro i s his ih
    

Proof state:
case refine'_2
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
s✝ : Finset ι
f : ι → MvPolynomial σ R
i : ι
s : Finset ι
his : i ∉ s
ih : degrees (∏ i in s, f i) ≤ ∑ i in s, degrees (f i)
⊢ degrees (∏ i in insert i s, f i) ≤ ∑ i in insert i s, degrees (f i)

Next tactic:
rw [Finset.prod_insert his, Finset.sum_insert his]
theorem degrees_prod {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∏ i in s, f i).degrees ≤ ∑ i in s, (f i).degrees := by
  classical
  refine' s.induction _ _
  · simp only [Finset.prod_empty, Finset.sum_empty, degrees_one, le_refl]
  · intro i s his ih
    rw [Finset.prod_insert his, Finset.sum_insert his]
    

Proof state:
case refine'_2
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
s✝ : Finset ι
f : ι → MvPolynomial σ R
i : ι
s : Finset ι
his : i ∉ s
ih : degrees (∏ i in s, f i) ≤ ∑ i in s, degrees (f i)
⊢ degrees (f i * ∏ x in s, f x) ≤ degrees (f i) + ∑ x in s, degrees (f x)

Next tactic:
exact le_trans (degrees_mul _ _) (add_le_add_left ih _)
theorem degrees_pow (p : MvPolynomial σ R) : ∀ n : ℕ, (p ^ n).degrees ≤ n • p.degrees
  | 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 p : MvPolynomial σ R
⊢ degrees (p ^ 0) ≤ 0 • degrees p

Next tactic:
rw [pow_zero, degrees_one]
theorem degrees_pow (p : MvPolynomial σ R) : ∀ n : ℕ, (p ^ n).degrees ≤ n • p.degrees
  | 0 => by rw [pow_zero, degrees_one]; 

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
⊢ 0 ≤ 0 • degrees p

Next tactic:
exact Multiset.zero_le _
theorem degrees_pow (p : MvPolynomial σ R) : ∀ n : ℕ, (p ^ n).degrees ≤ n • p.degrees
  | 0 => by rw [pow_zero, degrees_one]; exact Multiset.zero_le _
  | n + 1 => 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
n : ℕ
⊢ degrees (p ^ (n + 1)) ≤ (n + 1) • degrees p

Next tactic:
rw [pow_succ, add_smul, add_comm, one_smul]
theorem degrees_pow (p : MvPolynomial σ R) : ∀ n : ℕ, (p ^ n).degrees ≤ n • p.degrees
  | 0 => by rw [pow_zero, degrees_one]; exact Multiset.zero_le _
  | n + 1 => by
    rw [pow_succ, add_smul, add_comm, one_smul]
    

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
n : ℕ
⊢ degrees (p * p ^ n) ≤ degrees p + n • degrees p

Next tactic:
exact le_trans (degrees_mul _ _) (add_le_add_left (degrees_pow _ n) _)
theorem mem_degrees {p : MvPolynomial σ R} {i : σ} :
    i ∈ p.degrees ↔ ∃ d, p.coeff d ≠ 0 ∧ 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 p : MvPolynomial σ R
i : σ
⊢ i ∈ degrees p ↔ ∃ d, coeff d p ≠ 0 ∧ i ∈ d.support

Next tactic:
classical
  simp only [degrees_def, Multiset.mem_sup, ← mem_support_iff, Finsupp.mem_toMultiset, exists_prop]
theorem mem_degrees {p : MvPolynomial σ R} {i : σ} :
    i ∈ p.degrees ↔ ∃ d, p.coeff d ≠ 0 ∧ 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 p : MvPolynomial σ R
i : σ
⊢ i ∈ degrees p ↔ ∃ d, coeff d p ≠ 0 ∧ i ∈ d.support

Next tactic:
simp only [degrees_def, Multiset.mem_sup, ← mem_support_iff, Finsupp.mem_toMultiset, exists_prop]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).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✝ p q : MvPolynomial σ R
h : Multiset.Disjoint (degrees p) (degrees q)
⊢ degrees p ≤ degrees (p + q)

Next tactic:
classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    rw [mem_support_iff, coeff_add]
    suffices q.coeff d = 0 by rwa [this, add_zero, coeff, ← Finsupp.mem_support_iff]
    rw [← Finsupp.support_eq_empty, ← Ne.def, ← Finset.nonempty_iff_ne_empty] at h0
    obtain ⟨j, hj⟩ := h0
    contrapose! h
    rw [mem_support_iff] at hd
    refine' ⟨j, _, j, _, rfl⟩
    all_goals rw [mem_degrees]; refine' ⟨d, _, hj⟩; assumption
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := 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 q : MvPolynomial σ R
h : Multiset.Disjoint (degrees p) (degrees q)
⊢ degrees p ≤ degrees (p + q)

Next tactic:
apply Finset.sup_le
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  

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✝ p q : MvPolynomial σ R
h : Multiset.Disjoint (degrees p) (degrees q)
⊢ ∀ b ∈ support p, toMultiset b ≤ degrees (p + q)

Next tactic:
intro d hd
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  

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✝ p q : MvPolynomial σ R
h : Multiset.Disjoint (degrees p) (degrees q)
d : σ →₀ ℕ
hd : d ∈ support p
⊢ toMultiset d ≤ degrees (p + q)

Next tactic:
rw [Multiset.disjoint_iff_ne] at h
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  

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✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
⊢ toMultiset d ≤ degrees (p + q)

Next tactic:
rw [Multiset.le_iff_count]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  

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✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
⊢ ∀ (a : σ), Multiset.count a (toMultiset d) ≤ Multiset.count a (degrees (p + q))

Next tactic:
intro i
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro 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✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
⊢ Multiset.count i (toMultiset d) ≤ Multiset.count i (degrees (p + q))

Next tactic:
rw [degrees, Multiset.count_finset_sup]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  

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✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
⊢ Multiset.count i (toMultiset d) ≤ Finset.sup (support (p + q)) fun a => Multiset.count i (toMultiset a)

Next tactic:
simp only [Finsupp.count_toMultiset]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  

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✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
⊢ d i ≤ Finset.sup (support (p + q)) fun a => a i

Next tactic:
by_cases h0 : d = 0
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : d = 0
⊢ d i ≤ Finset.sup (support (p + q)) fun a => a i

Next tactic:
simp only [h0, zero_le, Finsupp.zero_apply]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · 

Proof state:
case neg
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : ¬d = 0
⊢ d i ≤ Finset.sup (support (p + q)) fun a => a i

Next tactic:
refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    

Proof state:
case neg
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : ¬d = 0
⊢ d ∈ support (p + q)

Next tactic:
rw [mem_support_iff, coeff_add]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    rw [mem_support_iff, coeff_add]
    

Proof state:
case neg
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : ¬d = 0
⊢ coeff d p + coeff d q ≠ 0

Next tactic:
suffices q.coeff d = 0 by rwa [this, add_zero, coeff, ← Finsupp.mem_support_iff]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    rw [mem_support_iff, coeff_add]
    suffices q.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✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : ¬d = 0
this : coeff d q = 0
⊢ coeff d p + coeff d q ≠ 0

Next tactic:
rwa [this, add_zero, coeff, ← Finsupp.mem_support_iff]
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    rw [mem_support_iff, coeff_add]
    suffices q.coeff d = 0 by rwa [this, add_zero, coeff, ← Finsupp.mem_support_iff]
    

Proof state:
case neg
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : ¬d = 0
⊢ coeff d q = 0

Next tactic:
rw [← Finsupp.support_eq_empty, ← Ne.def, ← Finset.nonempty_iff_ne_empty] at h0
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    rw [mem_support_iff, coeff_add]
    suffices q.coeff d = 0 by rwa [this, add_zero, coeff, ← Finsupp.mem_support_iff]
    rw [← Finsupp.support_eq_empty, ← Ne.def, ← Finset.nonempty_iff_ne_empty] at h0
    

Proof state:
case neg
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i : σ
h0 : Finset.Nonempty d.support
⊢ coeff d q = 0

Next tactic:
obtain ⟨j, hj⟩ := h0
theorem le_degrees_add {p q : MvPolynomial σ R} (h : p.degrees.Disjoint q.degrees) :
    p.degrees ≤ (p + q).degrees := by
  classical
  apply Finset.sup_le
  intro d hd
  rw [Multiset.disjoint_iff_ne] at h
  rw [Multiset.le_iff_count]
  intro i
  rw [degrees, Multiset.count_finset_sup]
  simp only [Finsupp.count_toMultiset]
  by_cases h0 : d = 0
  · simp only [h0, zero_le, Finsupp.zero_apply]
  · refine' @Finset.le_sup _ _ _ _ (p + q).support (fun a => a i) d _
    rw [mem_support_iff, coeff_add]
    suffices q.coeff d = 0 by rwa [this, add_zero, coeff, ← Finsupp.mem_support_iff]
    rw [← Finsupp.support_eq_empty, ← Ne.def, ← Finset.nonempty_iff_ne_empty] at h0
    obtain ⟨j, hj⟩ := h0
    

Proof state:
case neg.intro
R : Type u
S : Type v
σ : Type u_1
τ : Type u_2
r : R
e : ℕ
n m : σ
s : σ →₀ ℕ
inst✝ : CommSemiring R
p✝ q✝ p q : MvPolynomial σ R
h : ∀ a ∈ degrees p, ∀ b ∈ degrees q, a ≠ b
d : σ →₀ ℕ
hd : d ∈ support p
i j : σ
hj : j ∈ d.support
⊢ coeff d q = 0

Next tactic:
contrapose! h