l3lab/ntp-mathlib huggingface dataset:
/-- Polarization identity for symmetric linear maps.
See `inner_map_polarization` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_polarization {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) (x y : E) :
    ⟪T x, y⟫ =
      (⟪T (x + y), x + y⟫ - ⟪T (x - y), x - y⟫ - I * ⟪T (x + (I : 𝕜) • y), x + (I : 𝕜) • y⟫ +
          I * ⟪T (x - (I : 𝕜) • y), x - (I : 𝕜) • y⟫) /
        4 := by
  rcases@I_mul_I_ax 𝕜 _ with (h | h)
  · simp_rw [h, zero_mul, sub_zero, add_zero, map_add, map_sub, inner_add_left,
      inner_add_right, inner_sub_left, inner_sub_right, hT x, ← inner_conj_symm x (T y)]
    suffices (re ⟪T y, x⟫ : 𝕜) = ⟪T y, x⟫ by
      rw [conj_eq_iff_re.mpr this]
      ring
    · rw [← re_add_im ⟪T y, x⟫]
      simp_rw [h, mul_zero, add_zero]
      norm_cast
  · 

Proof state:
case inr
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
x y : E
h : I * I = -1
⊢ inner (T x) y =
    (inner (T (x + y)) (x + y) - inner (T (x - y)) (x - y) - I * inner (T (x + I • y)) (x + I • y) +
        I * inner (T (x - I • y)) (x - I • y)) /
      4

Next tactic:
simp_rw [map_add, map_sub, inner_add_left, inner_add_right, inner_sub_left, inner_sub_right,
      LinearMap.map_smul, inner_smul_left, inner_smul_right, IsROrC.conj_I, mul_add, mul_sub,
      sub_sub, ← mul_assoc, mul_neg, h, neg_neg, one_mul, neg_one_mul]
/-- Polarization identity for symmetric linear maps.
See `inner_map_polarization` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_polarization {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) (x y : E) :
    ⟪T x, y⟫ =
      (⟪T (x + y), x + y⟫ - ⟪T (x - y), x - y⟫ - I * ⟪T (x + (I : 𝕜) • y), x + (I : 𝕜) • y⟫ +
          I * ⟪T (x - (I : 𝕜) • y), x - (I : 𝕜) • y⟫) /
        4 := by
  rcases@I_mul_I_ax 𝕜 _ with (h | h)
  · simp_rw [h, zero_mul, sub_zero, add_zero, map_add, map_sub, inner_add_left,
      inner_add_right, inner_sub_left, inner_sub_right, hT x, ← inner_conj_symm x (T y)]
    suffices (re ⟪T y, x⟫ : 𝕜) = ⟪T y, x⟫ by
      rw [conj_eq_iff_re.mpr this]
      ring
    · rw [← re_add_im ⟪T y, x⟫]
      simp_rw [h, mul_zero, add_zero]
      norm_cast
  · simp_rw [map_add, map_sub, inner_add_left, inner_add_right, inner_sub_left, inner_sub_right,
      LinearMap.map_smul, inner_smul_left, inner_smul_right, IsROrC.conj_I, mul_add, mul_sub,
      sub_sub, ← mul_assoc, mul_neg, h, neg_neg, one_mul, neg_one_mul]
    

Proof state:
case inr
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
x y : E
h : I * I = -1
⊢ inner (T x) y =
    (inner (T x) x + inner (T x) y + (inner (T y) x + inner (T y) y) -
          (inner (T x) x - (inner (T x) y + (inner (T y) x - inner (T y) y)) +
            (I * inner (T x) x + -inner (T x) y + (inner (T y) x + I * inner (T y) y))) +
        (I * inner (T x) x - (-inner (T x) y + (inner (T y) x - I * inner (T y) y)))) /
      4

Next tactic:
ring
/-- A symmetric linear map `T` is zero if and only if `⟪T x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) :
    (∀ x, ⟪T x, x⟫ = 0) ↔ T = 0 := by
  

Proof state:
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
⊢ (∀ (x : E), inner (T x) x = 0) ↔ T = 0

Next tactic:
simp_rw [LinearMap.ext_iff, zero_apply]
/-- A symmetric linear map `T` is zero if and only if `⟪T x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) :
    (∀ x, ⟪T x, x⟫ = 0) ↔ T = 0 := by
  simp_rw [LinearMap.ext_iff, zero_apply]
  

Proof state:
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
⊢ (∀ (x : E), inner (T x) x = 0) ↔ ∀ (x : E), T x = 0

Next tactic:
refine' ⟨fun h x => _, fun h => by simp_rw [h, inner_zero_left, forall_const]⟩
/-- A symmetric linear map `T` is zero if and only if `⟪T x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) :
    (∀ x, ⟪T x, x⟫ = 0) ↔ T = 0 := by
  simp_rw [LinearMap.ext_iff, zero_apply]
  refine' ⟨fun h x => _, fun h => by 

Proof state:
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
h : ∀ (x : E), T x = 0
⊢ ∀ (x : E), inner (T x) x = 0

Next tactic:
simp_rw [h, inner_zero_left, forall_const]
/-- A symmetric linear map `T` is zero if and only if `⟪T x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) :
    (∀ x, ⟪T x, x⟫ = 0) ↔ T = 0 := by
  simp_rw [LinearMap.ext_iff, zero_apply]
  refine' ⟨fun h x => _, fun h => by simp_rw [h, inner_zero_left, forall_const]⟩
  

Proof state:
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
h : ∀ (x : E), inner (T x) x = 0
x : E
⊢ T x = 0

Next tactic:
rw [← @inner_self_eq_zero 𝕜, hT.inner_map_polarization]
/-- A symmetric linear map `T` is zero if and only if `⟪T x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) :
    (∀ x, ⟪T x, x⟫ = 0) ↔ T = 0 := by
  simp_rw [LinearMap.ext_iff, zero_apply]
  refine' ⟨fun h x => _, fun h => by simp_rw [h, inner_zero_left, forall_const]⟩
  rw [← @inner_self_eq_zero 𝕜, hT.inner_map_polarization]
  

Proof state:
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
h : ∀ (x : E), inner (T x) x = 0
x : E
⊢ (inner (T (x + T x)) (x + T x) - inner (T (x - T x)) (x - T x) - I * inner (T (x + I • T x)) (x + I • T x) +
        I * inner (T (x - I • T x)) (x - I • T x)) /
      4 =
    0

Next tactic:
simp_rw [h _]
/-- A symmetric linear map `T` is zero if and only if `⟪T x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) :
    (∀ x, ⟪T x, x⟫ = 0) ↔ T = 0 := by
  simp_rw [LinearMap.ext_iff, zero_apply]
  refine' ⟨fun h x => _, fun h => by simp_rw [h, inner_zero_left, forall_const]⟩
  rw [← @inner_self_eq_zero 𝕜, hT.inner_map_polarization]
  simp_rw [h _]
  

Proof state:
𝕜 : Type u_1
E : Type u_2
E' : Type u_3
F : Type u_4
G : Type u_5
inst✝⁸ : IsROrC 𝕜
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : InnerProductSpace 𝕜 E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : InnerProductSpace 𝕜 F
inst✝³ : NormedAddCommGroup G
inst✝² : InnerProductSpace 𝕜 G
inst✝¹ : NormedAddCommGroup E'
inst✝ : InnerProductSpace ℝ E'
T : E →ₗ[𝕜] E
hT : IsSymmetric T
h : ∀ (x : E), inner (T x) x = 0
x : E
⊢ (0 - 0 - I * 0 + I * 0) / 4 = 0

Next tactic:
ring
/-- The natural equivalence between lists and difference lists, using
`DList.ofList` and `DList.toList`. -/
def DList.listEquivDList : List α ≃ DList α := by
  

Proof state:
α : Type u_1
⊢ List α ≃ DList α

Next tactic:
refine'
      { toFun := DList.ofList
        invFun := DList.toList.. }
/-- The natural equivalence between lists and difference lists, using
`DList.ofList` and `DList.toList`. -/
def DList.listEquivDList : List α ≃ DList α := by
  refine'
      { toFun := DList.ofList
        invFun := DList.toList.. } <;>
    

Proof state:
case refine'_1
α : Type u_1
⊢ LeftInverse toList ofList

Next tactic:
simp [Function.RightInverse, Function.LeftInverse, DList.toList_ofList, DList.ofList_toList]
/-- The natural equivalence between lists and difference lists, using
`DList.ofList` and `DList.toList`. -/
def DList.listEquivDList : List α ≃ DList α := by
  refine'
      { toFun := DList.ofList
        invFun := DList.toList.. } <;>
    

Proof state:
case refine'_2
α : Type u_1
⊢ Function.RightInverse toList ofList

Next tactic:
simp [Function.RightInverse, Function.LeftInverse, DList.toList_ofList, DList.ofList_toList]
protected theorem Finite.upperClosure [LocallyFiniteOrderTop α] (hs : s.Finite) :
    (upperClosure s : Set α).Finite := by
  

Proof state:
α : Type u_1
inst✝¹ : Preorder α
s : Set α
inst✝ : LocallyFiniteOrderTop α
hs : Set.Finite s
⊢ Set.Finite ↑(upperClosure s)

Next tactic:
rw [coe_upperClosure]
protected theorem Finite.upperClosure [LocallyFiniteOrderTop α] (hs : s.Finite) :
    (upperClosure s : Set α).Finite := by
  rw [coe_upperClosure]
  

Proof state:
α : Type u_1
inst✝¹ : Preorder α
s : Set α
inst✝ : LocallyFiniteOrderTop α
hs : Set.Finite s
⊢ Set.Finite (⋃ a ∈ s, Ici a)

Next tactic:
exact hs.biUnion fun _ _ => finite_Ici _
protected theorem Finite.lowerClosure [LocallyFiniteOrderBot α] (hs : s.Finite) :
    (lowerClosure s : Set α).Finite := by
  

Proof state:
α : Type u_1
inst✝¹ : Preorder α
s : Set α
inst✝ : LocallyFiniteOrderBot α
hs : Set.Finite s
⊢ Set.Finite ↑(lowerClosure s)

Next tactic:
rw [coe_lowerClosure]
protected theorem Finite.lowerClosure [LocallyFiniteOrderBot α] (hs : s.Finite) :
    (lowerClosure s : Set α).Finite := by
  rw [coe_lowerClosure]
  

Proof state:
α : Type u_1
inst✝¹ : Preorder α
s : Set α
inst✝ : LocallyFiniteOrderBot α
hs : Set.Finite s
⊢ Set.Finite (⋃ a ∈ s, Iic a)

Next tactic:
exact hs.biUnion fun _ _ => finite_Iic _
theorem degrees_def [DecidableEq σ] (p : MvPolynomial σ R) :
    p.degrees = p.support.sup fun s : σ →₀ ℕ => Finsupp.toMultiset s := 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
⊢ degrees p = Finset.sup (support p) fun s => toMultiset s

Next tactic:
rw [degrees]
theorem degrees_def [DecidableEq σ] (p : MvPolynomial σ R) :
    p.degrees = p.support.sup fun s : σ →₀ ℕ => Finsupp.toMultiset s := by rw [degrees]; 

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
⊢ (Finset.sup (support p) fun s => toMultiset s) = Finset.sup (support p) fun s => toMultiset s

Next tactic:
convert rfl
theorem degrees_monomial (s : σ →₀ ℕ) (a : R) : degrees (monomial s a) ≤ toMultiset s := 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
s : σ →₀ ℕ
a : R
⊢ degrees ((monomial s) a) ≤ toMultiset s

Next tactic:
classical
    refine' Finset.sup_le fun t h => _
    have := Finsupp.support_single_subset h
    rw [Finset.mem_singleton] at this
    rw [this]
theorem degrees_monomial (s : σ →₀ ℕ) (a : R) : degrees (monomial s a) ≤ toMultiset s := 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
s : σ →₀ ℕ
a : R
⊢ degrees ((monomial s) a) ≤ toMultiset s

Next tactic:
refine' Finset.sup_le fun t h => _
theorem degrees_monomial (s : σ →₀ ℕ) (a : R) : degrees (monomial s a) ≤ toMultiset s := by
  classical
    refine' Finset.sup_le fun t 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 : MvPolynomial σ R
s : σ →₀ ℕ
a : R
t : σ →₀ ℕ
h : t ∈ support ((monomial s) a)
⊢ toMultiset t ≤ toMultiset s

Next tactic:
have := Finsupp.support_single_subset h
theorem degrees_monomial (s : σ →₀ ℕ) (a : R) : degrees (monomial s a) ≤ toMultiset s := by
  classical
    refine' Finset.sup_le fun t h => _
    have := Finsupp.support_single_subset 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 : MvPolynomial σ R
s : σ →₀ ℕ
a : R
t : σ →₀ ℕ
h : t ∈ support ((monomial s) a)
this : t ∈ {s}
⊢ toMultiset t ≤ toMultiset s

Next tactic:
rw [Finset.mem_singleton] at this
theorem degrees_monomial (s : σ →₀ ℕ) (a : R) : degrees (monomial s a) ≤ toMultiset s := by
  classical
    refine' Finset.sup_le fun t h => _
    have := Finsupp.support_single_subset h
    rw [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 : MvPolynomial σ R
s : σ →₀ ℕ
a : R
t : σ →₀ ℕ
h : t ∈ support ((monomial s) a)
this : t = s
⊢ toMultiset t ≤ toMultiset s

Next tactic:
rw [this]
theorem degrees_monomial_eq (s : σ →₀ ℕ) (a : R) (ha : a ≠ 0) :
    degrees (monomial s a) = toMultiset s := 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
s : σ →₀ ℕ
a : R
ha : a ≠ 0
⊢ degrees ((monomial s) a) = toMultiset s

Next tactic:
classical
    refine' le_antisymm (degrees_monomial s a) <| Finset.le_sup <| _
    rw [support_monomial, if_neg ha, Finset.mem_singleton]
theorem degrees_monomial_eq (s : σ →₀ ℕ) (a : R) (ha : a ≠ 0) :
    degrees (monomial s a) = toMultiset s := 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
s : σ →₀ ℕ
a : R
ha : a ≠ 0
⊢ degrees ((monomial s) a) = toMultiset s

Next tactic:
refine' le_antisymm (degrees_monomial s a) <| Finset.le_sup <| _
theorem degrees_monomial_eq (s : σ →₀ ℕ) (a : R) (ha : a ≠ 0) :
    degrees (monomial s a) = toMultiset s := by
  classical
    refine' le_antisymm (degrees_monomial s a) <| Finset.le_sup <| _
    

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
s : σ →₀ ℕ
a : R
ha : a ≠ 0
⊢ s ∈ support ((monomial s) a)

Next tactic:
rw [support_monomial, if_neg ha, Finset.mem_singleton]
@[simp]
theorem degrees_zero : degrees (0 : MvPolynomial σ R) = 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
⊢ degrees 0 = 0

Next tactic:
rw [← C_0]
@[simp]
theorem degrees_zero : degrees (0 : MvPolynomial σ R) = 0 := by
  rw [← C_0]
  

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
⊢ degrees (C 0) = 0

Next tactic:
exact degrees_C 0
theorem degrees_add [DecidableEq σ] (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✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
⊢ degrees (p + q) ≤ degrees p ⊔ degrees q

Next tactic:
classical
  simp_rw [degrees_def]
  refine' Finset.sup_le fun b hb => _
  have := Finsupp.support_add hb; rw [Finset.mem_union] at this
  cases' this with h h
  · exact le_sup_of_le_left (Finset.le_sup h)
  · exact le_sup_of_le_right (Finset.le_sup h)
theorem degrees_add [DecidableEq σ] (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✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
⊢ degrees (p + q) ≤ degrees p ⊔ degrees q

Next tactic:
simp_rw [degrees_def]
theorem degrees_add [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).degrees ≤ p.degrees ⊔ q.degrees := by
  classical
  simp_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✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
⊢ (Finset.sup (support (p + q)) fun s => toMultiset s) ≤
    (Finset.sup (support p) fun s => toMultiset s) ⊔ Finset.sup (support q) fun s => toMultiset s

Next tactic:
refine' Finset.sup_le fun b hb => _
theorem degrees_add [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).degrees ≤ p.degrees ⊔ q.degrees := by
  classical
  simp_rw [degrees_def]
  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✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p + q)
⊢ toMultiset b ≤ (Finset.sup (support p) fun s => toMultiset s) ⊔ Finset.sup (support q) fun s => toMultiset s

Next tactic:
have := Finsupp.support_add hb
theorem degrees_add [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).degrees ≤ p.degrees ⊔ q.degrees := by
  classical
  simp_rw [degrees_def]
  refine' Finset.sup_le fun b hb => _
  have := Finsupp.support_add 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✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p + q)
this : b ∈ p.support ∪ q.support
⊢ toMultiset b ≤ (Finset.sup (support p) fun s => toMultiset s) ⊔ Finset.sup (support q) fun s => toMultiset s

Next tactic:
rw [Finset.mem_union] at this
theorem degrees_add [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).degrees ≤ p.degrees ⊔ q.degrees := by
  classical
  simp_rw [degrees_def]
  refine' Finset.sup_le fun b hb => _
  have := Finsupp.support_add hb; rw [Finset.mem_union] 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✝ : MvPolynomial σ R
inst✝ : DecidableEq σ
p q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p + q)
this : b ∈ p.support ∨ b ∈ q.support
⊢ toMultiset b ≤ (Finset.sup (support p) fun s => toMultiset s) ⊔ Finset.sup (support q) fun s => toMultiset s

Next tactic:
cases' this with h h
theorem degrees_add [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).degrees ≤ p.degrees ⊔ q.degrees := by
  classical
  simp_rw [degrees_def]
  refine' Finset.sup_le fun b hb => _
  have := Finsupp.support_add hb; rw [Finset.mem_union] at this
  cases' this with h h
  · 

Proof state:
case 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 σ
p q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p + q)
h : b ∈ p.support
⊢ toMultiset b ≤ (Finset.sup (support p) fun s => toMultiset s) ⊔ Finset.sup (support q) fun s => toMultiset s

Next tactic:
exact le_sup_of_le_left (Finset.le_sup h)
theorem degrees_add [DecidableEq σ] (p q : MvPolynomial σ R) :
    (p + q).degrees ≤ p.degrees ⊔ q.degrees := by
  classical
  simp_rw [degrees_def]
  refine' Finset.sup_le fun b hb => _
  have := Finsupp.support_add hb; rw [Finset.mem_union] at this
  cases' this with h h
  · exact le_sup_of_le_left (Finset.le_sup h)
  · 

Proof state:
case 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 σ
p q : MvPolynomial σ R
b : σ →₀ ℕ
hb : b ∈ support (p + q)
h : b ∈ q.support
⊢ toMultiset b ≤ (Finset.sup (support p) fun s => toMultiset s) ⊔ Finset.sup (support q) fun s => toMultiset s

Next tactic:
exact le_sup_of_le_right (Finset.le_sup h)
theorem degrees_sum {ι : Type*} [DecidableEq σ] (s : Finset ι) (f : ι → MvPolynomial σ R) :
    (∑ i in s, f i).degrees ≤ s.sup fun i => (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
inst✝ : DecidableEq σ
s : Finset ι
f : ι → MvPolynomial σ R
⊢ degrees (∑ i in s, f i) ≤ Finset.sup s fun i => degrees (f i)

Next tactic:
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]
    exact le_trans (degrees_add _ _) (sup_le_sup_left ih _)
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
  

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
⊢ degrees (∑ i in s, f i) ≤ Finset.sup s fun i => degrees (f i)

Next tactic:
refine' s.induction _ _
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 _ _
  · 

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
inst✝ : DecidableEq σ
s : Finset ι
f : ι → MvPolynomial σ R
⊢ degrees (∑ i in ∅, f i) ≤ Finset.sup ∅ fun i => degrees (f i)

Next tactic:
simp only [Finset.sum_empty, Finset.sup_empty, degrees_zero]
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]
    

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
inst✝ : DecidableEq σ
s : Finset ι
f : ι → MvPolynomial σ R
⊢ 0 ≤ ⊥

Next tactic:
exact le_rfl
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
  · 

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
⊢ ∀ ⦃a : ι⦄ {s : Finset ι},
    a ∉ s →
      (degrees (∑ i in s, f i) ≤ Finset.sup s fun i => degrees (f i)) →
        degrees (∑ i in insert a s, f i) ≤ Finset.sup (insert a s) fun i => degrees (f i)

Next tactic:
intro i s his ih