File: Mathlib/Algebra/BigOperators/Finsupp.lean

full_name: Finsupp.prod
code: /-- `prod f g` is the product of `g a (f a)` over the support of `f`. -/
@[to_additive "`sum f g` is the sum of `g a (f a)` over the support of `f`. "]
def prod [Zero M] [CommMonoid N] (f : α →₀ M) (g : α → M → N) : N 
goal: N

full_name: Finsupp.sum
code: /-- `prod f g` is the product of `g a (f a)` over the support of `f`. -/
@[to_additive "`sum f g` is the sum of `g a (f a)` over the support of `f`. "]
def prod [Zero M] [CommMonoid N] (f : α →₀ M) (g : α → M → N) : N 
goal: N

full_name: Finsupp.prod_of_support_subset
code: @[to_additive]
theorem prod_of_support_subset (f : α →₀ M) {s : Finset α} (hs : f.support ⊆ s) (g : α → M → N)
    (h : ∀ i ∈ s, g i 0 = 1) : f.prod g = ∏ x ∈ s, g x (f x) 
goal: f.prod g = ∏ x ∈ s, g x (f x)

full_name: Finsupp.sum_of_support_subset
code: @[to_additive]
theorem prod_of_support_subset (f : α →₀ M) {s : Finset α} (hs : f.support ⊆ s) (g : α → M → N)
    (h : ∀ i ∈ s, g i 0 = 1) : f.prod g = ∏ x ∈ s, g x (f x) 
goal: f.sum g = ∑ x ∈ s, g x (f x)

full_name: Finsupp.sum_fintype
code: @[to_additive]
theorem prod_fintype [Fintype α] (f : α →₀ M) (g : α → M → N) (h : ∀ i, g i 0 = 1) :
    f.prod g = ∏ i, g i (f i) 
goal: f.sum g = ∑ i : α, g i (f i)

full_name: Finsupp.prod_fintype
code: @[to_additive]
theorem prod_fintype [Fintype α] (f : α →₀ M) (g : α → M → N) (h : ∀ i, g i 0 = 1) :
    f.prod g = ∏ i, g i (f i) 
goal: f.prod g = ∏ i : α, g i (f i)

full_name: Finsupp.prod_single_index
code: @[to_additive (attr := simp)]
theorem prod_single_index {a : α} {b : M} {h : α → M → N} (h_zero : h a 0 = 1) :
    (single a b).prod h = h a b 
goal: (Finsupp.single a b).prod h = h a b

full_name: Finsupp.sum_single_index
code: @[to_additive (attr := simp)]
theorem prod_single_index {a : α} {b : M} {h : α → M → N} (h_zero : h a 0 = 1) :
    (single a b).prod h = h a b 
goal: (Finsupp.single a b).sum h = h a b

full_name: Finsupp.sum_mapRange_index
code: @[to_additive]
theorem prod_mapRange_index {f : M → M'} {hf : f 0 = 0} {g : α →₀ M} {h : α → M' → N}
    (h0 : ∀ a, h a 0 = 1) : (mapRange f hf g).prod h = g.prod fun a b => h a (f b) 
goal: (Finsupp.mapRange f hf g).sum h = g.sum fun a b => h a (f b)

full_name: Finsupp.prod_mapRange_index
code: @[to_additive]
theorem prod_mapRange_index {f : M → M'} {hf : f 0 = 0} {g : α →₀ M} {h : α → M' → N}
    (h0 : ∀ a, h a 0 = 1) : (mapRange f hf g).prod h = g.prod fun a b => h a (f b) 
goal: (Finsupp.mapRange f hf g).prod h = g.prod fun a b => h a (f b)

full_name: Finsupp.prod_zero_index
code: @[to_additive (attr := simp)]
theorem prod_zero_index {h : α → M → N} : (0 : α →₀ M).prod h = 1 
goal: Finsupp.prod 0 h = 1

full_name: Finsupp.sum_zero_index
code: @[to_additive (attr := simp)]
theorem prod_zero_index {h : α → M → N} : (0 : α →₀ M).prod h = 1 
goal: Finsupp.sum 0 h = 0

full_name: Finsupp.prod_comm
code: @[to_additive]
theorem prod_comm (f : α →₀ M) (g : β →₀ M') (h : α → M → β → M' → N) :
    (f.prod fun x v => g.prod fun x' v' => h x v x' v') =
      g.prod fun x' v' => f.prod fun x v => h x v x' v' 
goal: (f.prod fun x v => g.prod fun x' v' => h x v x' v') = g.prod fun x' v' => f.prod fun x v => h x v x' v'

full_name: Finsupp.sum_comm
code: @[to_additive]
theorem prod_comm (f : α →₀ M) (g : β →₀ M') (h : α → M → β → M' → N) :
    (f.prod fun x v => g.prod fun x' v' => h x v x' v') =
      g.prod fun x' v' => f.prod fun x v => h x v x' v' 
goal: (f.sum fun x v => g.sum fun x' v' => h x v x' v') = g.sum fun x' v' => f.sum fun x v => h x v x' v'

full_name: Finsupp.sum_ite_eq
code: @[to_additive (attr := simp)]
theorem prod_ite_eq [DecidableEq α] (f : α →₀ M) (a : α) (b : α → M → N) :
    (f.prod fun x v => ite (a = x) (b x v) 1) = ite (a ∈ f.support) (b a (f a)) 1 
goal: (f.sum fun x v => if a = x then b x v else 0) = if a ∈ f.support then b a (f a) else 0

full_name: Finsupp.prod_ite_eq
code: @[to_additive (attr := simp)]
theorem prod_ite_eq [DecidableEq α] (f : α →₀ M) (a : α) (b : α → M → N) :
    (f.prod fun x v => ite (a = x) (b x v) 1) = ite (a ∈ f.support) (b a (f a)) 1 
goal: (f.prod fun x v => if a = x then b x v else 1) = if a ∈ f.support then b a (f a) else 1

full_name: Finsupp.sum_ite_self_eq
code: theorem sum_ite_self_eq [DecidableEq α] {N : Type*} [AddCommMonoid N] (f : α →₀ N) (a : α) :
    (f.sum fun x v => ite (a = x) v 0) = f a 
goal: (f.sum fun x v => if a = x then v else 0) = f a

full_name: Finsupp.sum_ite_self_eq_aux
code: @[simp]
theorem sum_ite_self_eq_aux [DecidableEq α] {N : Type*} [AddCommMonoid N] (f : α →₀ N) (a : α) :
    (if a ∈ f.support then f a else 0) = f a 
goal: (if a ∈ f.support then f a else 0) = f a

full_name: Finsupp.prod_ite_eq'
code: /-- A restatement of `prod_ite_eq` with the equality test reversed. -/
@[to_additive (attr := simp) "A restatement of `sum_ite_eq` with the equality test reversed."]
theorem prod_ite_eq' [DecidableEq α] (f : α →₀ M) (a : α) (b : α → M → N) :
    (f.prod fun x v => ite (x = a) (b x v) 1) = ite (a ∈ f.support) (b a (f a)) 1 
goal: (f.prod fun x v => if x = a then b x v else 1) = if a ∈ f.support then b a (f a) else 1

full_name: Finsupp.sum_ite_eq'
code: /-- A restatement of `prod_ite_eq` with the equality test reversed. -/
@[to_additive (attr := simp) "A restatement of `sum_ite_eq` with the equality test reversed."]
theorem prod_ite_eq' [DecidableEq α] (f : α →₀ M) (a : α) (b : α → M → N) :
    (f.prod fun x v => ite (x = a) (b x v) 1) = ite (a ∈ f.support) (b a (f a)) 1 
goal: (f.sum fun x v => if x = a then b x v else 0) = if a ∈ f.support then b a (f a) else 0

full_name: Finsupp.sum_ite_self_eq'
code: theorem sum_ite_self_eq' [DecidableEq α] {N : Type*} [AddCommMonoid N] (f : α →₀ N) (a : α) :
    (f.sum fun x v => ite (x = a) v 0) = f a 
goal: (f.sum fun x v => if x = a then v else 0) = f a

full_name: Finsupp.prod_pow
code: @[simp]
theorem prod_pow [Fintype α] (f : α →₀ ℕ) (g : α → N) :
    (f.prod fun a b => g a ^ b) = ∏ a, g a ^ f a 
goal: (f.prod fun a b => g a ^ b) = ∏ a : α, g a ^ f a

full_name: Finsupp.onFinset_prod
code: /-- If `g` maps a second argument of 0 to 1, then multiplying it over the
result of `onFinset` is the same as multiplying it over the original `Finset`. -/
@[to_additive
      "If `g` maps a second argument of 0 to 0, summing it over the
      result of `onFinset` is the same as summing it over the original `Finset`."]
theorem onFinset_prod {s : Finset α} {f : α → M} {g : α → M → N} (hf : ∀ a, f a ≠ 0 → a ∈ s)
    (hg : ∀ a, g a 0 = 1) : (onFinset s f hf).prod g = ∏ a ∈ s, g a (f a) 
goal: (Finsupp.onFinset s f hf).prod g = ∏ a ∈ s, g a (f a)

full_name: Finsupp.onFinset_sum
code: /-- If `g` maps a second argument of 0 to 1, then multiplying it over the
result of `onFinset` is the same as multiplying it over the original `Finset`. -/
@[to_additive
      "If `g` maps a second argument of 0 to 0, summing it over the
      result of `onFinset` is the same as summing it over the original `Finset`."]
theorem onFinset_prod {s : Finset α} {f : α → M} {g : α → M → N} (hf : ∀ a, f a ≠ 0 → a ∈ s)
    (hg : ∀ a, g a 0 = 1) : (onFinset s f hf).prod g = ∏ a ∈ s, g a (f a) 
goal: (Finsupp.onFinset s f hf).sum g = ∑ a ∈ s, g a (f a)

full_name: Finsupp.mul_prod_erase
code: /-- Taking a product over `f : α →₀ M` is the same as multiplying the value on a single element
`y ∈ f.support` by the product over `erase y f`. -/
@[to_additive
      " Taking a sum over `f : α →₀ M` is the same as adding the value on a
      single element `y ∈ f.support` to the sum over `erase y f`. "]
theorem mul_prod_erase (f : α →₀ M) (y : α) (g : α → M → N) (hyf : y ∈ f.support) :
    g y (f y) * (erase y f).prod g = f.prod g 
goal: g y (f y) * (Finsupp.erase y f).prod g = f.prod g

full_name: Finsupp.add_sum_erase
code: /-- Taking a product over `f : α →₀ M` is the same as multiplying the value on a single element
`y ∈ f.support` by the product over `erase y f`. -/
@[to_additive
      " Taking a sum over `f : α →₀ M` is the same as adding the value on a
      single element `y ∈ f.support` to the sum over `erase y f`. "]
theorem mul_prod_erase (f : α →₀ M) (y : α) (g : α → M → N) (hyf : y ∈ f.support) :
    g y (f y) * (erase y f).prod g = f.prod g 
goal: g y (f y) + (Finsupp.erase y f).sum g = f.sum g

full_name: Finsupp.add_sum_erase'
code: /-- Generalization of `Finsupp.mul_prod_erase`: if `g` maps a second argument of 0 to 1,
then its product over `f : α →₀ M` is the same as multiplying the value on any element
`y : α` by the product over `erase y f`. -/
@[to_additive
      " Generalization of `Finsupp.add_sum_erase`: if `g` maps a second argument of 0
      to 0, then its sum over `f : α →₀ M` is the same as adding the value on any element
      `y : α` to the sum over `erase y f`. "]
theorem mul_prod_erase' (f : α →₀ M) (y : α) (g : α → M → N) (hg : ∀ i : α, g i 0 = 1) :
    g y (f y) * (erase y f).prod g = f.prod g 
goal: g y (f y) + (Finsupp.erase y f).sum g = f.sum g

full_name: Finsupp.mul_prod_erase'
code: /-- Generalization of `Finsupp.mul_prod_erase`: if `g` maps a second argument of 0 to 1,
then its product over `f : α →₀ M` is the same as multiplying the value on any element
`y : α` by the product over `erase y f`. -/
@[to_additive
      " Generalization of `Finsupp.add_sum_erase`: if `g` maps a second argument of 0
      to 0, then its sum over `f : α →₀ M` is the same as adding the value on any element
      `y : α` to the sum over `erase y f`. "]
theorem mul_prod_erase' (f : α →₀ M) (y : α) (g : α → M → N) (hg : ∀ i : α, g i 0 = 1) :
    g y (f y) * (erase y f).prod g = f.prod g 
goal: g y (f y) * (Finsupp.erase y f).prod g = f.prod g

full_name: AddSubmonoidClass.finsupp_sum_mem
code: @[to_additive]
theorem _root_.SubmonoidClass.finsupp_prod_mem {S : Type*} [SetLike S N] [SubmonoidClass S N]
    (s : S) (f : α →₀ M) (g : α → M → N) (h : ∀ c, f c ≠ 0 → g c (f c) ∈ s) : f.prod g ∈ s 
goal: f.sum g ∈ s

full_name: SubmonoidClass.finsupp_prod_mem
code: @[to_additive]
theorem _root_.SubmonoidClass.finsupp_prod_mem {S : Type*} [SetLike S N] [SubmonoidClass S N]
    (s : S) (f : α →₀ M) (g : α → M → N) (h : ∀ c, f c ≠ 0 → g c (f c) ∈ s) : f.prod g ∈ s 
goal: f.prod g ∈ s

full_name: Finsupp.prod_congr
code: @[to_additive]
theorem prod_congr {f : α →₀ M} {g1 g2 : α → M → N} (h : ∀ x ∈ f.support, g1 x (f x) = g2 x (f x)) :
    f.prod g1 = f.prod g2 
goal: f.prod g1 = f.prod g2

full_name: Finsupp.sum_congr
code: @[to_additive]
theorem prod_congr {f : α →₀ M} {g1 g2 : α → M → N} (h : ∀ x ∈ f.support, g1 x (f x) = g2 x (f x)) :
    f.prod g1 = f.prod g2 
goal: f.sum g1 = f.sum g2

full_name: Finsupp.prod_eq_single
code: @[to_additive]
theorem prod_eq_single {f : α →₀ M} (a : α) {g : α → M → N}
    (h₀ : ∀ b, f b ≠ 0 → b ≠ a → g b (f b) = 1) (h₁ : f a = 0 → g a 0 = 1) :
    f.prod g = g a (f a) 
goal: f.prod g = g a (f a)

full_name: Finsupp.sum_eq_single
code: @[to_additive]
theorem prod_eq_single {f : α →₀ M} (a : α) {g : α → M → N}
    (h₀ : ∀ b, f b ≠ 0 → b ≠ a → g b (f b) = 1) (h₁ : f a = 0 → g a 0 = 1) :
    f.prod g = g a (f a) 
goal: f.sum g = g a (f a)

full_name: Finsupp.prod_eq_zero_iff
code: @[simp]
lemma prod_eq_zero_iff : f.prod g = 0 ↔ ∃ i ∈ f.support, g i (f i) = 0 
goal: f.prod g = 0 ↔ ∃ i ∈ f.support, g i (f i) = 0

full_name: Finsupp.prod_ne_zero_iff
code: lemma prod_ne_zero_iff : f.prod g ≠ 0 ↔ ∀ i ∈ f.support, g i (f i) ≠ 0 
goal: f.prod g ≠ 0 ↔ ∀ i ∈ f.support, g i (f i) ≠ 0

full_name: map_finsupp_prod
code: @[to_additive]
theorem map_finsupp_prod [Zero M] [CommMonoid N] [CommMonoid P] {H : Type*}
    [FunLike H N P] [MonoidHomClass H N P]
    (h : H) (f : α →₀ M) (g : α → M → N) : h (f.prod g) = f.prod fun a b => h (g a b) 
goal: h (f.prod g) = f.prod fun a b => h (g a b)

full_name: map_finsupp_sum
code: @[to_additive]
theorem map_finsupp_prod [Zero M] [CommMonoid N] [CommMonoid P] {H : Type*}
    [FunLike H N P] [MonoidHomClass H N P]
    (h : H) (f : α →₀ M) (g : α → M → N) : h (f.prod g) = f.prod fun a b => h (g a b) 
goal: h (f.sum g) = f.sum fun a b => h (g a b)

full_name: AddMonoidHom.coe_finsupp_sum
code: @[to_additive]
theorem MonoidHom.coe_finsupp_prod [Zero β] [Monoid N] [CommMonoid P] (f : α →₀ β)
    (g : α → β → N →* P) : ⇑(f.prod g) = f.prod fun i fi => ⇑(g i fi) 
goal: ⇑(f.sum g) = f.sum fun i fi => ⇑(g i fi)

full_name: MonoidHom.coe_finsupp_prod
code: @[to_additive]
theorem MonoidHom.coe_finsupp_prod [Zero β] [Monoid N] [CommMonoid P] (f : α →₀ β)
    (g : α → β → N →* P) : ⇑(f.prod g) = f.prod fun i fi => ⇑(g i fi) 
goal: ⇑(f.prod g) = f.prod fun i fi => ⇑(g i fi)

full_name: AddMonoidHom.finsupp_sum_apply
code: @[to_additive (attr := simp)]
theorem MonoidHom.finsupp_prod_apply [Zero β] [Monoid N] [CommMonoid P] (f : α →₀ β)
    (g : α → β → N →* P) (x : N) : f.prod g x = f.prod fun i fi => g i fi x 
goal: (f.sum g) x = f.sum fun i fi => (g i fi) x

full_name: MonoidHom.finsupp_prod_apply
code: @[to_additive (attr := simp)]
theorem MonoidHom.finsupp_prod_apply [Zero β] [Monoid N] [CommMonoid P] (f : α →₀ β)
    (g : α → β → N →* P) (x : N) : f.prod g x = f.prod fun i fi => g i fi x 
goal: (f.prod g) x = f.prod fun i fi => (g i fi) x

full_name: Finsupp.single_multiset_sum
code: theorem single_multiset_sum [AddCommMonoid M] (s : Multiset M) (a : α) :
    single a s.sum = (s.map (single a)).sum 
goal: Finsupp.single a s.sum = (Multiset.map (Finsupp.single a) s).sum

full_name: Finsupp.single_finset_sum
code: theorem single_finset_sum [AddCommMonoid M] (s : Finset ι) (f : ι → M) (a : α) :
    single a (∑ b ∈ s, f b) = ∑ b ∈ s, single a (f b) 
goal: Finsupp.single a (∑ b ∈ s, f b) = ∑ b ∈ s, Finsupp.single a (f b)

full_name: Finsupp.single_sum
code: theorem single_sum [Zero M] [AddCommMonoid N] (s : ι →₀ M) (f : ι → M → N) (a : α) :
    single a (s.sum f) = s.sum fun d c => single a (f d c) 
goal: Finsupp.single a (s.sum f) = s.sum fun d c => Finsupp.single a (f d c)

full_name: Finsupp.prod_neg_index
code: @[to_additive]
theorem prod_neg_index [AddGroup G] [CommMonoid M] {g : α →₀ G} {h : α → G → M}
    (h0 : ∀ a, h a 0 = 1) : (-g).prod h = g.prod fun a b => h a (-b) 
goal: (-g).prod h = g.prod fun a b => h a (-b)

full_name: Finsupp.sum_neg_index
code: @[to_additive]
theorem prod_neg_index [AddGroup G] [CommMonoid M] {g : α →₀ G} {h : α → G → M}
    (h0 : ∀ a, h a 0 = 1) : (-g).prod h = g.prod fun a b => h a (-b) 
goal: (-g).sum h = g.sum fun a b => h a (-b)

full_name: Finsupp.finset_sum_apply
code: theorem finset_sum_apply [AddCommMonoid N] (S : Finset ι) (f : ι → α →₀ N) (a : α) :
    (∑ i ∈ S, f i) a = ∑ i ∈ S, f i a 
goal: (∑ i ∈ S, f i) a = ∑ i ∈ S, (f i) a

full_name: Finsupp.sum_apply
code: @[simp]
theorem sum_apply [Zero M] [AddCommMonoid N] {f : α →₀ M} {g : α → M → β →₀ N} {a₂ : β} :
    (f.sum g) a₂ = f.sum fun a₁ b => g a₁ b a₂ 
goal: (f.sum g) a₂ = f.sum fun a₁ b => (g a₁ b) a₂

full_name: Finsupp.coe_finset_sum
code: theorem coe_finset_sum [AddCommMonoid N] (S : Finset ι) (f : ι → α →₀ N) :
    ⇑(∑ i ∈ S, f i) = ∑ i ∈ S, ⇑(f i) 
goal: ⇑(∑ i ∈ S, f i) = ∑ i ∈ S, ⇑(f i)

full_name: Finsupp.coe_sum
code: theorem coe_sum [Zero M] [AddCommMonoid N] (f : α →₀ M) (g : α → M → β →₀ N) :
    ⇑(f.sum g) = f.sum fun a₁ b => ⇑(g a₁ b) 
goal: ⇑(f.sum g) = f.sum fun a₁ b => ⇑(g a₁ b)

full_name: Finsupp.support_sum
code: theorem support_sum [DecidableEq β] [Zero M] [AddCommMonoid N] {f : α →₀ M} {g : α → M → β →₀ N} :
    (f.sum g).support ⊆ f.support.biUnion fun a => (g a (f a)).support 
goal: (f.sum g).support ⊆ f.support.biUnion fun a => (g a (f a)).support

full_name: Finsupp.support_finset_sum
code: theorem support_finset_sum [DecidableEq β] [AddCommMonoid M] {s : Finset α} {f : α → β →₀ M} :
    (Finset.sum s f).support ⊆ s.biUnion fun x => (f x).support 
goal: (s.sum f).support ⊆ s.biUnion fun x => (f x).support

full_name: Finsupp.sum_zero
code: @[simp]
theorem sum_zero [Zero M] [AddCommMonoid N] {f : α →₀ M} : (f.sum fun _ _ => (0 : N)) = 0 
goal: (f.sum fun x x => 0) = 0

full_name: Finsupp.sum_add
code: @[to_additive (attr := simp)]
theorem prod_mul [Zero M] [CommMonoid N] {f : α →₀ M} {h₁ h₂ : α → M → N} :
    (f.prod fun a b => h₁ a b * h₂ a b) = f.prod h₁ * f.prod h₂ 
goal: (f.sum fun a b => h₁ a b + h₂ a b) = f.sum h₁ + f.sum h₂

full_name: Finsupp.prod_mul
code: @[to_additive (attr := simp)]
theorem prod_mul [Zero M] [CommMonoid N] {f : α →₀ M} {h₁ h₂ : α → M → N} :
    (f.prod fun a b => h₁ a b * h₂ a b) = f.prod h₁ * f.prod h₂ 
goal: (f.prod fun a b => h₁ a b * h₂ a b) = f.prod h₁ * f.prod h₂

full_name: Finsupp.prod_inv
code: @[to_additive (attr := simp)]
theorem prod_inv [Zero M] [CommGroup G] {f : α →₀ M} {h : α → M → G} :
    (f.prod fun a b => (h a b)⁻¹) = (f.prod h)⁻¹ 
goal: (f.prod fun a b => (h a b)⁻¹) = (f.prod h)⁻¹

full_name: Finsupp.sum_neg
code: @[to_additive (attr := simp)]
theorem prod_inv [Zero M] [CommGroup G] {f : α →₀ M} {h : α → M → G} :
    (f.prod fun a b => (h a b)⁻¹) = (f.prod h)⁻¹ 
goal: (f.sum fun a b => -h a b) = -f.sum h

full_name: Finsupp.sum_sub
code: @[simp]
theorem sum_sub [Zero M] [AddCommGroup G] {f : α →₀ M} {h₁ h₂ : α → M → G} :
    (f.sum fun a b => h₁ a b - h₂ a b) = f.sum h₁ - f.sum h₂ 
goal: (f.sum fun a b => h₁ a b - h₂ a b) = f.sum h₁ - f.sum h₂

full_name: Finsupp.prod_add_index
code: /-- Taking the product under `h` is an additive-to-multiplicative homomorphism of finsupps,
if `h` is an additive-to-multiplicative homomorphism on the support.
This is a more general version of `Finsupp.prod_add_index'`; the latter has simpler hypotheses. -/
@[to_additive
      "Taking the product under `h` is an additive homomorphism of finsupps,  if `h` is an
      additive homomorphism on the support. This is a more general version of
      `Finsupp.sum_add_index'`; the latter has simpler hypotheses."]
theorem prod_add_index [DecidableEq α] [AddZeroClass M] [CommMonoid N] {f g : α →₀ M}
    {h : α → M → N} (h_zero : ∀ a ∈ f.support ∪ g.support, h a 0 = 1)
    (h_add : ∀ a ∈ f.support ∪ g.support, ∀ (b₁ b₂), h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (f + g).prod h = f.prod h * g.prod h 
goal: (f + g).prod h = f.prod h * g.prod h

full_name: Finsupp.sum_add_index
code: /-- Taking the product under `h` is an additive-to-multiplicative homomorphism of finsupps,
if `h` is an additive-to-multiplicative homomorphism on the support.
This is a more general version of `Finsupp.prod_add_index'`; the latter has simpler hypotheses. -/
@[to_additive
      "Taking the product under `h` is an additive homomorphism of finsupps,  if `h` is an
      additive homomorphism on the support. This is a more general version of
      `Finsupp.sum_add_index'`; the latter has simpler hypotheses."]
theorem prod_add_index [DecidableEq α] [AddZeroClass M] [CommMonoid N] {f g : α →₀ M}
    {h : α → M → N} (h_zero : ∀ a ∈ f.support ∪ g.support, h a 0 = 1)
    (h_add : ∀ a ∈ f.support ∪ g.support, ∀ (b₁ b₂), h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (f + g).prod h = f.prod h * g.prod h 
goal: (f + g).sum h = f.sum h + g.sum h

full_name: Finsupp.prod_add_index'
code: /-- Taking the product under `h` is an additive-to-multiplicative homomorphism of finsupps,
if `h` is an additive-to-multiplicative homomorphism.
This is a more specialized version of `Finsupp.prod_add_index` with simpler hypotheses. -/
@[to_additive
      "Taking the sum under `h` is an additive homomorphism of finsupps,if `h` is an additive
      homomorphism. This is a more specific version of `Finsupp.sum_add_index` with simpler
      hypotheses."]
theorem prod_add_index' [AddZeroClass M] [CommMonoid N] {f g : α →₀ M} {h : α → M → N}
    (h_zero : ∀ a, h a 0 = 1) (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (f + g).prod h = f.prod h * g.prod h 
goal: (f + g).prod h = f.prod h * g.prod h

full_name: Finsupp.sum_add_index'
code: /-- Taking the product under `h` is an additive-to-multiplicative homomorphism of finsupps,
if `h` is an additive-to-multiplicative homomorphism.
This is a more specialized version of `Finsupp.prod_add_index` with simpler hypotheses. -/
@[to_additive
      "Taking the sum under `h` is an additive homomorphism of finsupps,if `h` is an additive
      homomorphism. This is a more specific version of `Finsupp.sum_add_index` with simpler
      hypotheses."]
theorem prod_add_index' [AddZeroClass M] [CommMonoid N] {f g : α →₀ M} {h : α → M → N}
    (h_zero : ∀ a, h a 0 = 1) (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (f + g).prod h = f.prod h * g.prod h 
goal: (f + g).sum h = f.sum h + g.sum h

full_name: Finsupp.sum_hom_add_index
code: @[simp]
theorem sum_hom_add_index [AddZeroClass M] [AddCommMonoid N] {f g : α →₀ M} (h : α → M →+ N) :
    ((f + g).sum fun x => h x) = (f.sum fun x => h x) + g.sum fun x => h x 
goal: ((f + g).sum fun x => ⇑(h x)) = (f.sum fun x => ⇑(h x)) + g.sum fun x => ⇑(h x)

full_name: Finsupp.prod_hom_add_index
code: @[simp]
theorem prod_hom_add_index [AddZeroClass M] [CommMonoid N] {f g : α →₀ M}
    (h : α → Multiplicative M →* N) :
    ((f + g).prod fun a b => h a (Multiplicative.ofAdd b)) =
      (f.prod fun a b => h a (Multiplicative.ofAdd b)) *
        g.prod fun a b => h a (Multiplicative.ofAdd b) 
goal: ((f + g).prod fun a b => (h a) (Multiplicative.ofAdd b)) =
  (f.prod fun a b => (h a) (Multiplicative.ofAdd b)) * g.prod fun a b => (h a) (Multiplicative.ofAdd b)

full_name: Finsupp.liftAddHom
code: /-- The canonical isomorphism between families of additive monoid homomorphisms `α → (M →+ N)`
and monoid homomorphisms `(α →₀ M) →+ N`. -/
def liftAddHom [AddZeroClass M] [AddCommMonoid N] : (α → M →+ N) ≃+ ((α →₀ M) →+ N) 
goal: (α → M →+ N) ≃+ ((α →₀ M) →+ N)

full_name: Finsupp.liftAddHom_apply
code: @[simp]
theorem liftAddHom_apply [AddCommMonoid M] [AddCommMonoid N] (F : α → M →+ N) (f : α →₀ M) :
    (liftAddHom (α := α) (M := M) (N := N)) F f = f.sum fun x => F x 
goal: (Finsupp.liftAddHom F) f = f.sum fun x => ⇑(F x)

full_name: Finsupp.liftAddHom_symm_apply
code: @[simp]
theorem liftAddHom_symm_apply [AddCommMonoid M] [AddCommMonoid N] (F : (α →₀ M) →+ N) (x : α) :
    (liftAddHom (α := α) (M := M) (N := N)).symm F x = F.comp (singleAddHom x) 
goal: Finsupp.liftAddHom.symm F x = F.comp (Finsupp.singleAddHom x)

full_name: Finsupp.liftAddHom_symm_apply_apply
code: theorem liftAddHom_symm_apply_apply [AddCommMonoid M] [AddCommMonoid N] (F : (α →₀ M) →+ N) (x : α)
    (y : M) : (liftAddHom (α := α) (M := M) (N := N)).symm F x y = F (single x y) 
goal: (Finsupp.liftAddHom.symm F x) y = F (Finsupp.single x y)

full_name: Finsupp.liftAddHom_singleAddHom
code: @[simp]
theorem liftAddHom_singleAddHom [AddCommMonoid M] :
    (liftAddHom (α := α) (M := M) (N := α →₀ M)) (singleAddHom : α → M →+ α →₀ M) =
      AddMonoidHom.id _ 
goal: Finsupp.liftAddHom Finsupp.singleAddHom = AddMonoidHom.id (α →₀ M)

full_name: Finsupp.sum_single
code: @[simp]
theorem sum_single [AddCommMonoid M] (f : α →₀ M) : f.sum single = f 
goal: f.sum Finsupp.single = f

full_name: Finsupp.univ_sum_single
code: /-- The `Finsupp` version of `Finset.univ_sum_single` -/
@[simp]
theorem univ_sum_single [Fintype α] [AddCommMonoid M] (f : α →₀ M) :
    ∑ a : α, single a (f a) = f 
goal: ∑ a : α, Finsupp.single a (f a) = f

full_name: Finsupp.univ_sum_single_apply
code: @[simp]
theorem univ_sum_single_apply [AddCommMonoid M] [Fintype α] (i : α) (m : M) :
    ∑ j : α, single i m j = m 
goal: ∑ j : α, (Finsupp.single i m) j = m

full_name: Finsupp.univ_sum_single_apply'
code: @[simp]
theorem univ_sum_single_apply' [AddCommMonoid M] [Fintype α] (i : α) (m : M) :
    ∑ j : α, single j m i = m 
goal: ∑ j : α, (Finsupp.single j m) i = m

full_name: Finsupp.equivFunOnFinite_symm_eq_sum
code: theorem equivFunOnFinite_symm_eq_sum [Fintype α] [AddCommMonoid M] (f : α → M) :
    equivFunOnFinite.symm f = ∑ a, Finsupp.single a (f a) 
goal: Finsupp.equivFunOnFinite.symm f = ∑ a : α, Finsupp.single a (f a)

full_name: Finsupp.liftAddHom_apply_single
code: theorem liftAddHom_apply_single [AddCommMonoid M] [AddCommMonoid N] (f : α → M →+ N) (a : α)
    (b : M) : (liftAddHom (α := α) (M := M) (N := N)) f (single a b) = f a b 
goal: (Finsupp.liftAddHom f) (Finsupp.single a b) = (f a) b

full_name: Finsupp.liftAddHom_comp_single
code: @[simp]
theorem liftAddHom_comp_single [AddCommMonoid M] [AddCommMonoid N] (f : α → M →+ N) (a : α) :
    ((liftAddHom (α := α) (M := M) (N := N)) f).comp (singleAddHom a) = f a 
goal: (Finsupp.liftAddHom f).comp (Finsupp.singleAddHom a) = f a

full_name: Finsupp.comp_liftAddHom
code: theorem comp_liftAddHom [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P] (g : N →+ P)
    (f : α → M →+ N) :
    g.comp ((liftAddHom (α := α) (M := M) (N := N)) f) =
      (liftAddHom (α := α) (M := M) (N := P)) fun a => g.comp (f a) 
goal: g.comp (Finsupp.liftAddHom f) = Finsupp.liftAddHom fun a => g.comp (f a)

full_name: Finsupp.sum_sub_index
code: theorem sum_sub_index [AddCommGroup β] [AddCommGroup γ] {f g : α →₀ β} {h : α → β → γ}
    (h_sub : ∀ a b₁ b₂, h a (b₁ - b₂) = h a b₁ - h a b₂) : (f - g).sum h = f.sum h - g.sum h 
goal: (f - g).sum h = f.sum h - g.sum h

full_name: Finsupp.prod_embDomain
code: @[to_additive]
theorem prod_embDomain [Zero M] [CommMonoid N] {v : α →₀ M} {f : α ↪ β} {g : β → M → N} :
    (v.embDomain f).prod g = v.prod fun a b => g (f a) b 
goal: (Finsupp.embDomain f v).prod g = v.prod fun a b => g (f a) b

full_name: Finsupp.sum_embDomain
code: @[to_additive]
theorem prod_embDomain [Zero M] [CommMonoid N] {v : α →₀ M} {f : α ↪ β} {g : β → M → N} :
    (v.embDomain f).prod g = v.prod fun a b => g (f a) b 
goal: (Finsupp.embDomain f v).sum g = v.sum fun a b => g (f a) b

full_name: Finsupp.sum_finset_sum_index
code: @[to_additive]
theorem prod_finset_sum_index [AddCommMonoid M] [CommMonoid N] {s : Finset ι} {g : ι → α →₀ M}
    {h : α → M → N} (h_zero : ∀ a, h a 0 = 1) (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (∏ i ∈ s, (g i).prod h) = (∑ i ∈ s, g i).prod h 
goal: ∑ i ∈ s, (g i).sum h = (∑ i ∈ s, g i).sum h

full_name: Finsupp.prod_finset_sum_index
code: @[to_additive]
theorem prod_finset_sum_index [AddCommMonoid M] [CommMonoid N] {s : Finset ι} {g : ι → α →₀ M}
    {h : α → M → N} (h_zero : ∀ a, h a 0 = 1) (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (∏ i ∈ s, (g i).prod h) = (∑ i ∈ s, g i).prod h 
goal: ∏ i ∈ s, (g i).prod h = (∑ i ∈ s, g i).prod h

full_name: Finsupp.prod_sum_index
code: @[to_additive]
theorem prod_sum_index [AddCommMonoid M] [AddCommMonoid N] [CommMonoid P] {f : α →₀ M}
    {g : α → M → β →₀ N} {h : β → N → P} (h_zero : ∀ a, h a 0 = 1)
    (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (f.sum g).prod h = f.prod fun a b => (g a b).prod h 
goal: (f.sum g).prod h = f.prod fun a b => (g a b).prod h

full_name: Finsupp.sum_sum_index
code: @[to_additive]
theorem prod_sum_index [AddCommMonoid M] [AddCommMonoid N] [CommMonoid P] {f : α →₀ M}
    {g : α → M → β →₀ N} {h : β → N → P} (h_zero : ∀ a, h a 0 = 1)
    (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ * h a b₂) :
    (f.sum g).prod h = f.prod fun a b => (g a b).prod h 
goal: (f.sum g).sum h = f.sum fun a b => (g a b).sum h

full_name: Finsupp.multiset_sum_sum_index
code: theorem multiset_sum_sum_index [AddCommMonoid M] [AddCommMonoid N] (f : Multiset (α →₀ M))
    (h : α → M → N) (h₀ : ∀ a, h a 0 = 0)
    (h₁ : ∀ (a : α) (b₁ b₂ : M), h a (b₁ + b₂) = h a b₁ + h a b₂) :
    f.sum.sum h = (f.map fun g : α →₀ M => g.sum h).sum 
goal: f.sum.sum h = (Multiset.map (fun g => g.sum h) f).sum

full_name: Finsupp.support_sum_eq_biUnion
code: theorem support_sum_eq_biUnion {α : Type*} {ι : Type*} {M : Type*} [DecidableEq α]
    [AddCommMonoid M] {g : ι → α →₀ M} (s : Finset ι)
    (h : ∀ i₁ i₂, i₁ ≠ i₂ → Disjoint (g i₁).support (g i₂).support) :
    (∑ i ∈ s, g i).support = s.biUnion fun i => (g i).support 
goal: (∑ i ∈ s, g i).support = s.biUnion fun i => (g i).support

full_name: Finsupp.multiset_map_sum
code: theorem multiset_map_sum [Zero M] {f : α →₀ M} {m : β → γ} {h : α → M → Multiset β} :
    Multiset.map m (f.sum h) = f.sum fun a b => (h a b).map m 
goal: Multiset.map m (f.sum h) = f.sum fun a b => Multiset.map m (h a b)

full_name: Finsupp.multiset_sum_sum
code: theorem multiset_sum_sum [Zero M] [AddCommMonoid N] {f : α →₀ M} {h : α → M → Multiset N} :
    Multiset.sum (f.sum h) = f.sum fun a b => Multiset.sum (h a b) 
goal: (f.sum h).sum = f.sum fun a b => (h a b).sum

full_name: Finsupp.sum_add_index_of_disjoint
code: /-- For disjoint `f1` and `f2`, and function `g`, the product of the products of `g`
over `f1` and `f2` equals the product of `g` over `f1 + f2` -/
@[to_additive
      "For disjoint `f1` and `f2`, and function `g`, the sum of the sums of `g`
      over `f1` and `f2` equals the sum of `g` over `f1 + f2`"]
theorem prod_add_index_of_disjoint [AddCommMonoid M] {f1 f2 : α →₀ M}
    (hd : Disjoint f1.support f2.support) {β : Type*} [CommMonoid β] (g : α → M → β) :
    (f1 + f2).prod g = f1.prod g * f2.prod g 
goal: (f1 + f2).sum g = f1.sum g + f2.sum g

full_name: Finsupp.prod_add_index_of_disjoint
code: /-- For disjoint `f1` and `f2`, and function `g`, the product of the products of `g`
over `f1` and `f2` equals the product of `g` over `f1 + f2` -/
@[to_additive
      "For disjoint `f1` and `f2`, and function `g`, the sum of the sums of `g`
      over `f1` and `f2` equals the sum of `g` over `f1 + f2`"]
theorem prod_add_index_of_disjoint [AddCommMonoid M] {f1 f2 : α →₀ M}
    (hd : Disjoint f1.support f2.support) {β : Type*} [CommMonoid β] (g : α → M → β) :
    (f1 + f2).prod g = f1.prod g * f2.prod g 
goal: (f1 + f2).prod g = f1.prod g * f2.prod g

full_name: Finsupp.prod_dvd_prod_of_subset_of_dvd
code: theorem prod_dvd_prod_of_subset_of_dvd [AddCommMonoid M] [CommMonoid N] {f1 f2 : α →₀ M}
    {g1 g2 : α → M → N} (h1 : f1.support ⊆ f2.support)
    (h2 : ∀ a : α, a ∈ f1.support → g1 a (f1 a) ∣ g2 a (f2 a)) : f1.prod g1 ∣ f2.prod g2 
goal: f1.prod g1 ∣ f2.prod g2

full_name: Finsupp.indicator_eq_sum_attach_single
code: lemma indicator_eq_sum_attach_single [AddCommMonoid M] {s : Finset α} (f : ∀ a ∈ s, M) :
    indicator s f = ∑ x ∈ s.attach, single ↑x (f x x.2) 
goal: Finsupp.indicator s f = ∑ x ∈ s.attach, Finsupp.single (↑x) (f ↑x ⋯)

full_name: Finsupp.indicator_eq_sum_single
code: lemma indicator_eq_sum_single [AddCommMonoid M] (s : Finset α) (f : α → M) :
    indicator s (fun x _ ↦ f x) = ∑ x ∈ s, single x (f x) 
goal: (Finsupp.indicator s fun x x_1 => f x) = ∑ x ∈ s, Finsupp.single x (f x)

full_name: Finsupp.sum_indicator_index_eq_sum_attach
code: @[to_additive (attr := simp)]
lemma prod_indicator_index_eq_prod_attach [Zero M] [CommMonoid N]
    {s : Finset α} (f : ∀ a ∈ s, M) {h : α → M → N} (h_zero : ∀ a ∈ s, h a 0 = 1) :
    (indicator s f).prod h = ∏ x ∈ s.attach, h ↑x (f x x.2) 
goal: (Finsupp.indicator s f).sum h = ∑ x ∈ s.attach, h (↑x) (f ↑x ⋯)

full_name: Finsupp.prod_indicator_index_eq_prod_attach
code: @[to_additive (attr := simp)]
lemma prod_indicator_index_eq_prod_attach [Zero M] [CommMonoid N]
    {s : Finset α} (f : ∀ a ∈ s, M) {h : α → M → N} (h_zero : ∀ a ∈ s, h a 0 = 1) :
    (indicator s f).prod h = ∏ x ∈ s.attach, h ↑x (f x x.2) 
goal: (Finsupp.indicator s f).prod h = ∏ x ∈ s.attach, h (↑x) (f ↑x ⋯)

full_name: Finsupp.prod_indicator_index
code: @[to_additive (attr := simp)]
lemma prod_indicator_index [Zero M] [CommMonoid N]
    {s : Finset α} (f : α → M) {h : α → M → N} (h_zero : ∀ a ∈ s, h a 0 = 1) :
    (indicator s (fun x _ ↦ f x)).prod h = ∏ x ∈ s, h x (f x) 
goal: (Finsupp.indicator s fun x x_1 => f x).prod h = ∏ x ∈ s, h x (f x)

full_name: Finsupp.sum_indicator_index
code: @[to_additive (attr := simp)]
lemma prod_indicator_index [Zero M] [CommMonoid N]
    {s : Finset α} (f : α → M) {h : α → M → N} (h_zero : ∀ a ∈ s, h a 0 = 1) :
    (indicator s (fun x _ ↦ f x)).prod h = ∏ x ∈ s, h x (f x) 
goal: (Finsupp.indicator s fun x x_1 => f x).sum h = ∑ x ∈ s, h x (f x)

full_name: Finsupp.sum_cons
code: lemma sum_cons [AddCommMonoid M] (n : ℕ) (σ : Fin n →₀ M) (i : M) :
    (sum (cons i σ) fun _ e ↦ e) = i + sum σ (fun _ e ↦ e) 
goal: ((Finsupp.cons i σ).sum fun x e => e) = i + σ.sum fun x e => e

full_name: Finsupp.sum_cons'
code: lemma sum_cons' [AddCommMonoid M] [AddCommMonoid N] (n : ℕ) (σ : Fin n →₀ M) (i : M)
    (f : Fin (n+1) → M → N) (h : ∀ x, f x 0 = 0) :
    (sum (Finsupp.cons i σ) f) = f 0 i + sum σ (Fin.tail f) 
goal: (Finsupp.cons i σ).sum f = f 0 i + σ.sum (Fin.tail f)

full_name: Finsupp.prod_mul_eq_prod_mul_of_exists
code: @[to_additive]
lemma prod_mul_eq_prod_mul_of_exists [Zero M] [CommMonoid N]
    {f : α →₀ M} {g : α → M → N} {n₁ n₂ : N}
    (a : α) (ha : a ∈ f.support)
    (h : g a (f a) * n₁ = g a (f a) * n₂) :
    f.prod g * n₁ = f.prod g * n₂ 
goal: f.prod g * n₁ = f.prod g * n₂

full_name: Finsupp.sum_add_eq_sum_add_of_exists
code: @[to_additive]
lemma prod_mul_eq_prod_mul_of_exists [Zero M] [CommMonoid N]
    {f : α →₀ M} {g : α → M → N} {n₁ n₂ : N}
    (a : α) (ha : a ∈ f.support)
    (h : g a (f a) * n₁ = g a (f a) * n₂) :
    f.prod g * n₁ = f.prod g * n₂ 
goal: f.sum g + n₁ = f.sum g + n₂

full_name: Finset.sum_apply'
code: theorem Finset.sum_apply' : (∑ k ∈ s, f k) i = ∑ k ∈ s, f k i 
goal: (∑ k ∈ s, f k) i = ∑ k ∈ s, (f k) i

full_name: Finsupp.sum_apply'
code: theorem Finsupp.sum_apply' : g.sum k x = g.sum fun i b => k i b x 
goal: g.sum k x = g.sum fun i b => k i b x

full_name: Finsupp.sum_sum_index'
code: theorem Finsupp.sum_sum_index' : (∑ x ∈ s, f x).sum t = ∑ x ∈ s, (f x).sum t 
goal: (∑ x ∈ s, f x).sum t = ∑ x ∈ s, (f x).sum t

full_name: Finsupp.sum_mul
code: theorem Finsupp.sum_mul (b : S) (s : α →₀ R) {f : α → R → S} :
    s.sum f * b = s.sum fun a c => f a c * b 
goal: s.sum f * b = s.sum fun a c => f a c * b

full_name: Finsupp.mul_sum
code: theorem Finsupp.mul_sum (b : S) (s : α →₀ R) {f : α → R → S} :
    b * s.sum f = s.sum fun a c => b * f a c 
goal: b * s.sum f = s.sum fun a c => b * f a c

full_name: Nat.prod_pow_pos_of_zero_not_mem_support
code: /-- If `0 : ℕ` is not in the support of `f : ℕ →₀ ℕ` then `0 < ∏ x ∈ f.support, x ^ (f x)`. -/
theorem prod_pow_pos_of_zero_not_mem_support {f : ℕ →₀ ℕ} (nhf : 0 ∉ f.support) :
    0 < f.prod (· ^ ·) 
goal: 0 < f.prod fun x x_1 => x ^ x_1