File: Mathlib/Algebra/BigOperators/Group/Finset.lean

full_name: Finset.prod
code: /-- `∏ x ∈ s, f x` is the product of `f x` as `x` ranges over the elements of the finite set `s`.

When the index type is a `Fintype`, the notation `∏ x, f x`, is a shorthand for
`∏ x ∈ Finset.univ, f x`. -/
@[to_additive "`∑ x ∈ s, f x` is the sum of `f x` as `x` ranges over the elements
of the finite set `s`.

When the index type is a `Fintype`, the notation `∑ x, f x`, is a shorthand for
`∑ x ∈ Finset.univ, f x`."]
protected def prod [CommMonoid β] (s : Finset α) (f : α → β) : β 
goal: β

full_name: Finset.sum
code: /-- `∏ x ∈ s, f x` is the product of `f x` as `x` ranges over the elements of the finite set `s`.

When the index type is a `Fintype`, the notation `∏ x, f x`, is a shorthand for
`∏ x ∈ Finset.univ, f x`. -/
@[to_additive "`∑ x ∈ s, f x` is the sum of `f x` as `x` ranges over the elements
of the finite set `s`.

When the index type is a `Fintype`, the notation `∑ x, f x`, is a shorthand for
`∑ x ∈ Finset.univ, f x`."]
protected def prod [CommMonoid β] (s : Finset α) (f : α → β) : β 
goal: β

full_name: Finset.sum_mk
code: @[to_additive (attr := simp)]
theorem prod_mk [CommMonoid β] (s : Multiset α) (hs : s.Nodup) (f : α → β) :
    (⟨s, hs⟩ : Finset α).prod f = (s.map f).prod 
goal: { val := s, nodup := hs }.sum f = (Multiset.map f s).sum

full_name: Finset.prod_mk
code: @[to_additive (attr := simp)]
theorem prod_mk [CommMonoid β] (s : Multiset α) (hs : s.Nodup) (f : α → β) :
    (⟨s, hs⟩ : Finset α).prod f = (s.map f).prod 
goal: { val := s, nodup := hs }.prod f = (Multiset.map f s).prod

full_name: Finset.prod_val
code: @[to_additive (attr := simp)]
theorem prod_val [CommMonoid α] (s : Finset α) : s.1.prod = s.prod id 
goal: s.val.prod = s.prod id

full_name: Finset.sum_val
code: @[to_additive (attr := simp)]
theorem prod_val [CommMonoid α] (s : Finset α) : s.1.prod = s.prod id 
goal: s.val.sum = s.sum id

full_name: BigOperators.bigOpBinder
code: /-- A `bigOpBinder` is like an `extBinder` and has the form `x`, `x : ty`, or `x pred`
where `pred` is a `binderPred` like `< 2`.
Unlike `extBinder`, `x` is a term. -/
syntax bigOpBinder := term:max ((" : " term) <|> binderPred)?
goal: Lean.ParserDescr

full_name: BigOperators.bigOpBinderParenthesized
code: /-- A BigOperator binder in parentheses -/
syntax bigOpBinderParenthesized := " (" bigOpBinder ")"
goal: Lean.ParserDescr

full_name: BigOperators.bigOpBinderCollection
code: /-- A list of parenthesized binders -/
syntax bigOpBinderCollection := bigOpBinderParenthesized+
goal: Lean.ParserDescr

full_name: BigOperators.bigOpBinders
code: /-- A single (unparenthesized) binder, or a list of parenthesized binders -/
syntax bigOpBinders := bigOpBinderCollection <|> (ppSpace bigOpBinder)
goal: Lean.ParserDescr

full_name: BigOperators.processBigOpBinder
code: /-- Collects additional binder/Finset pairs for the given `bigOpBinder`.
Note: this is not extensible at the moment, unlike the usual `bigOpBinder` expansions. -/
def processBigOpBinder (processed : (Array (Term × Term)))
    (binder : TSyntax ``bigOpBinder) : MacroM (Array (Term × Term)) 
goal: Lean.MacroM (Array (Lean.Term × Lean.Term))

full_name: BigOperators.processBigOpBinders
code: /-- Collects the binder/Finset pairs for the given `bigOpBinders`. -/
def processBigOpBinders (binders : TSyntax ``bigOpBinders) :
    MacroM (Array (Term × Term)) 
goal: Lean.MacroM (Array (Lean.Term × Lean.Term))

full_name: BigOperators.bigOpBindersPattern
code: /-- Collect the binderIdents into a `⟨...⟩` expression. -/
def bigOpBindersPattern (processed : (Array (Term × Term))) :
    MacroM Term 
goal: Lean.MacroM Lean.Term

full_name: BigOperators.bigOpBindersProd
code: /-- Collect the terms into a product of sets. -/
def bigOpBindersProd (processed : (Array (Term × Term))) :
    MacroM Term 
goal: Lean.MacroM Lean.Term

full_name: BigOperators.bigsum
code: /--
- `∑ x, f x` is notation for `Finset.sum Finset.univ f`. It is the sum of `f x`,
  where `x` ranges over the finite domain of `f`.
- `∑ x ∈ s, f x` is notation for `Finset.sum s f`. It is the sum of `f x`,
  where `x` ranges over the finite set `s` (either a `Finset` or a `Set` with a `Fintype` instance).
- `∑ x ∈ s with p x, f x` is notation for `Finset.sum (Finset.filter p s) f`.
- `∑ (x ∈ s) (y ∈ t), f x y` is notation for `Finset.sum (s ×ˢ t) (fun ⟨x, y⟩ ↦ f x y)`.

These support destructuring, for example `∑ ⟨x, y⟩ ∈ s ×ˢ t, f x y`.

Notation: `"∑" bigOpBinders* ("with" term)? "," term` -/
syntax (name := bigsum) "∑ " bigOpBinders ("with " term)? ", " term:67 : term
goal: Lean.ParserDescr

full_name: BigOperators.bigprod
code: /--
- `∏ x, f x` is notation for `Finset.prod Finset.univ f`. It is the product of `f x`,
  where `x` ranges over the finite domain of `f`.
- `∏ x ∈ s, f x` is notation for `Finset.prod s f`. It is the product of `f x`,
  where `x` ranges over the finite set `s` (either a `Finset` or a `Set` with a `Fintype` instance).
- `∏ x ∈ s with p x, f x` is notation for `Finset.prod (Finset.filter p s) f`.
- `∏ (x ∈ s) (y ∈ t), f x y` is notation for `Finset.prod (s ×ˢ t) (fun ⟨x, y⟩ ↦ f x y)`.

These support destructuring, for example `∏ ⟨x, y⟩ ∈ s ×ˢ t, f x y`.

Notation: `"∏" bigOpBinders* ("with" term)? "," term` -/
syntax (name := bigprod) "∏ " bigOpBinders ("with " term)? ", " term:67 : term
goal: Lean.ParserDescr

full_name: BigOperators._aux_Mathlib_Algebra_BigOperators_Group_Finset___macroRules_BigOperators_bigsum_1
code: macro_rules (kind := bigsum)
  | `(∑ $bs:bigOpBinders $[with $p?]?, $v) => do
    let processed ← processBigOpBinders bs
    let x ← bigOpBindersPattern processed
    let s ← bigOpBindersProd processed
    match p? with
    | some p => `(Finset.sum (Finset.filter (fun $x ↦ $p) $s) (fun $x ↦ $v))
    | none => `(Finset.sum $s (fun $x ↦ $v))
goal: Lean.Macro

full_name: BigOperators._aux_Mathlib_Algebra_BigOperators_Group_Finset___macroRules_BigOperators_bigprod_1
code: macro_rules (kind := bigprod)
  | `(∏ $bs:bigOpBinders $[with $p?]?, $v) => do
    let processed ← processBigOpBinders bs
    let x ← bigOpBindersPattern processed
    let s ← bigOpBindersProd processed
    match p? with
    | some p => `(Finset.prod (Finset.filter (fun $x ↦ $p) $s) (fun $x ↦ $v))
    | none => `(Finset.prod $s (fun $x ↦ $v))
goal: Lean.Macro

full_name: BigOperators.bigsumin
code: /-- (Deprecated, use `∑ x ∈ s, f x`)
`∑ x in s, f x` is notation for `Finset.sum s f`. It is the sum of `f x`,
where `x` ranges over the finite set `s`. -/
syntax (name := bigsumin) "∑ " extBinder " in " term ", " term:67 : term
goal: Lean.ParserDescr

full_name: BigOperators._aux_Mathlib_Algebra_BigOperators_Group_Finset___macroRules_BigOperators_bigsumin_1
code: macro_rules (kind := bigsumin)
  | `(∑ $x:ident in $s, $r) => `(∑ $x:ident ∈ $s, $r)
  | `(∑ $x:ident : $t in $s, $r) => `(∑ $x:ident ∈ ($s : Finset $t), $r)
goal: Lean.Macro

full_name: BigOperators.bigprodin
code: /-- (Deprecated, use `∏ x ∈ s, f x`)
`∏ x in s, f x` is notation for `Finset.prod s f`. It is the product of `f x`,
where `x` ranges over the finite set `s`. -/
syntax (name := bigprodin) "∏ " extBinder " in " term ", " term:67 : term
goal: Lean.ParserDescr

full_name: BigOperators._aux_Mathlib_Algebra_BigOperators_Group_Finset___macroRules_BigOperators_bigprodin_1
code: macro_rules (kind := bigprodin)
  | `(∏ $x:ident in $s, $r) => `(∏ $x:ident ∈ $s, $r)
  | `(∏ $x:ident : $t in $s, $r) => `(∏ $x:ident ∈ ($s : Finset $t), $r)
goal: Lean.Macro

full_name: BigOperators.delabFinsetProd
code: /-- Delaborator for `Finset.prod`. The `pp.piBinderTypes` option controls whether
to show the domain type when the product is over `Finset.univ`. -/
@[delab app.Finset.prod] def delabFinsetProd : Delab 
goal: Lean.PrettyPrinter.Delaborator.Delab

full_name: BigOperators.delabFinsetSum
code: /-- Delaborator for `Finset.sum`. The `pp.piBinderTypes` option controls whether
to show the domain type when the sum is over `Finset.univ`. -/
@[delab app.Finset.sum] def delabFinsetSum : Delab 
goal: Lean.PrettyPrinter.Delaborator.Delab

full_name: Finset.sum_eq_multiset_sum
code: @[to_additive]
theorem prod_eq_multiset_prod [CommMonoid β] (s : Finset α) (f : α → β) :
    ∏ x ∈ s, f x = (s.1.map f).prod 
goal: ∑ x ∈ s, f x = (Multiset.map f s.val).sum

full_name: Finset.prod_eq_multiset_prod
code: @[to_additive]
theorem prod_eq_multiset_prod [CommMonoid β] (s : Finset α) (f : α → β) :
    ∏ x ∈ s, f x = (s.1.map f).prod 
goal: ∏ x ∈ s, f x = (Multiset.map f s.val).prod

full_name: Finset.prod_map_val
code: @[to_additive (attr := simp)]
lemma prod_map_val [CommMonoid β] (s : Finset α) (f : α → β) : (s.1.map f).prod = ∏ a ∈ s, f a 
goal: (Multiset.map f s.val).prod = ∏ a ∈ s, f a

full_name: Finset.sum_map_val
code: @[to_additive (attr := simp)]
lemma prod_map_val [CommMonoid β] (s : Finset α) (f : α → β) : (s.1.map f).prod = ∏ a ∈ s, f a 
goal: (Multiset.map f s.val).sum = ∑ a ∈ s, f a

full_name: Finset.sum_eq_fold
code: @[to_additive]
theorem prod_eq_fold [CommMonoid β] (s : Finset α) (f : α → β) :
    ∏ x ∈ s, f x = s.fold ((· * ·) : β → β → β) 1 f 
goal: ∑ x ∈ s, f x = Finset.fold (fun x x_1 => x + x_1) 0 f s

full_name: Finset.prod_eq_fold
code: @[to_additive]
theorem prod_eq_fold [CommMonoid β] (s : Finset α) (f : α → β) :
    ∏ x ∈ s, f x = s.fold ((· * ·) : β → β → β) 1 f 
goal: ∏ x ∈ s, f x = Finset.fold (fun x x_1 => x * x_1) 1 f s

full_name: Finset.sum_multiset_singleton
code: @[simp]
theorem sum_multiset_singleton (s : Finset α) : (s.sum fun x => {x}) = s.val 
goal: ∑ x ∈ s, {x} = s.val

full_name: map_prod
code: @[to_additive (attr := simp)]
theorem map_prod [CommMonoid β] [CommMonoid γ] {G : Type*} [FunLike G β γ] [MonoidHomClass G β γ]
    (g : G) (f : α → β) (s : Finset α) : g (∏ x ∈ s, f x) = ∏ x ∈ s, g (f x) 
goal: g (∏ x ∈ s, f x) = ∏ x ∈ s, g (f x)

full_name: map_sum
code: @[to_additive (attr := simp)]
theorem map_prod [CommMonoid β] [CommMonoid γ] {G : Type*} [FunLike G β γ] [MonoidHomClass G β γ]
    (g : G) (f : α → β) (s : Finset α) : g (∏ x ∈ s, f x) = ∏ x ∈ s, g (f x) 
goal: g (∑ x ∈ s, f x) = ∑ x ∈ s, g (f x)

full_name: AddMonoidHom.coe_finset_sum
code: @[to_additive]
theorem MonoidHom.coe_finset_prod [MulOneClass β] [CommMonoid γ] (f : α → β →* γ) (s : Finset α) :
    ⇑(∏ x ∈ s, f x) = ∏ x ∈ s, ⇑(f x) 
goal: ⇑(∑ x ∈ s, f x) = ∑ x ∈ s, ⇑(f x)

full_name: MonoidHom.coe_finset_prod
code: @[to_additive]
theorem MonoidHom.coe_finset_prod [MulOneClass β] [CommMonoid γ] (f : α → β →* γ) (s : Finset α) :
    ⇑(∏ x ∈ s, f x) = ∏ x ∈ s, ⇑(f x) 
goal: ⇑(∏ x ∈ s, f x) = ∏ x ∈ s, ⇑(f x)

full_name: AddMonoidHom.finset_sum_apply
code: /-- See also `Finset.prod_apply`, with the same conclusion but with the weaker hypothesis
`f : α → β → γ` -/
@[to_additive (attr := simp)
  "See also `Finset.sum_apply`, with the same conclusion but with the weaker hypothesis
  `f : α → β → γ`"]
theorem MonoidHom.finset_prod_apply [MulOneClass β] [CommMonoid γ] (f : α → β →* γ) (s : Finset α)
    (b : β) : (∏ x ∈ s, f x) b = ∏ x ∈ s, f x b 
goal: (∑ x ∈ s, f x) b = ∑ x ∈ s, (f x) b

full_name: MonoidHom.finset_prod_apply
code: /-- See also `Finset.prod_apply`, with the same conclusion but with the weaker hypothesis
`f : α → β → γ` -/
@[to_additive (attr := simp)
  "See also `Finset.sum_apply`, with the same conclusion but with the weaker hypothesis
  `f : α → β → γ`"]
theorem MonoidHom.finset_prod_apply [MulOneClass β] [CommMonoid γ] (f : α → β →* γ) (s : Finset α)
    (b : β) : (∏ x ∈ s, f x) b = ∏ x ∈ s, f x b 
goal: (∏ x ∈ s, f x) b = ∏ x ∈ s, (f x) b

full_name: Finset.sum_empty
code: @[to_additive (attr := simp)]
theorem prod_empty : ∏ x ∈ ∅, f x = 1 
goal: ∑ x ∈ ∅, f x = 0

full_name: Finset.prod_empty
code: @[to_additive (attr := simp)]
theorem prod_empty : ∏ x ∈ ∅, f x = 1 
goal: ∏ x ∈ ∅, f x = 1

full_name: Finset.prod_of_isEmpty
code: @[to_additive]
theorem prod_of_isEmpty [IsEmpty α] (s : Finset α) : ∏ i ∈ s, f i = 1 
goal: ∏ i ∈ s, f i = 1

full_name: Finset.sum_of_isEmpty
code: @[to_additive]
theorem prod_of_isEmpty [IsEmpty α] (s : Finset α) : ∏ i ∈ s, f i = 1 
goal: ∑ i ∈ s, f i = 0

full_name: Finset.prod_cons
code: @[to_additive (attr := simp)]
theorem prod_cons (h : a ∉ s) : ∏ x ∈ cons a s h, f x = f a * ∏ x ∈ s, f x 
goal: ∏ x ∈ Finset.cons a s h, f x = f a * ∏ x ∈ s, f x

full_name: Finset.sum_cons
code: @[to_additive (attr := simp)]
theorem prod_cons (h : a ∉ s) : ∏ x ∈ cons a s h, f x = f a * ∏ x ∈ s, f x 
goal: ∑ x ∈ Finset.cons a s h, f x = f a + ∑ x ∈ s, f x

full_name: Finset.prod_insert
code: @[to_additive (attr := simp)]
theorem prod_insert [DecidableEq α] : a ∉ s → ∏ x ∈ insert a s, f x = f a * ∏ x ∈ s, f x 
goal: a ∉ s → ∏ x ∈ insert a s, f x = f a * ∏ x ∈ s, f x

full_name: Finset.sum_insert
code: @[to_additive (attr := simp)]
theorem prod_insert [DecidableEq α] : a ∉ s → ∏ x ∈ insert a s, f x = f a * ∏ x ∈ s, f x 
goal: a ∉ s → ∑ x ∈ insert a s, f x = f a + ∑ x ∈ s, f x

full_name: Finset.sum_insert_of_eq_zero_if_not_mem
code: /-- The product of `f` over `insert a s` is the same as
the product over `s`, as long as `a` is in `s` or `f a = 1`. -/
@[to_additive (attr := simp) "The sum of `f` over `insert a s` is the same as
the sum over `s`, as long as `a` is in `s` or `f a = 0`."]
theorem prod_insert_of_eq_one_if_not_mem [DecidableEq α] (h : a ∉ s → f a = 1) :
    ∏ x ∈ insert a s, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ insert a s, f x = ∑ x ∈ s, f x

full_name: Finset.prod_insert_of_eq_one_if_not_mem
code: /-- The product of `f` over `insert a s` is the same as
the product over `s`, as long as `a` is in `s` or `f a = 1`. -/
@[to_additive (attr := simp) "The sum of `f` over `insert a s` is the same as
the sum over `s`, as long as `a` is in `s` or `f a = 0`."]
theorem prod_insert_of_eq_one_if_not_mem [DecidableEq α] (h : a ∉ s → f a = 1) :
    ∏ x ∈ insert a s, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ insert a s, f x = ∏ x ∈ s, f x

full_name: Finset.prod_insert_one
code: /-- The product of `f` over `insert a s` is the same as
the product over `s`, as long as `f a = 1`. -/
@[to_additive (attr := simp) "The sum of `f` over `insert a s` is the same as
the sum over `s`, as long as `f a = 0`."]
theorem prod_insert_one [DecidableEq α] (h : f a = 1) : ∏ x ∈ insert a s, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ insert a s, f x = ∏ x ∈ s, f x

full_name: Finset.sum_insert_zero
code: /-- The product of `f` over `insert a s` is the same as
the product over `s`, as long as `f a = 1`. -/
@[to_additive (attr := simp) "The sum of `f` over `insert a s` is the same as
the sum over `s`, as long as `f a = 0`."]
theorem prod_insert_one [DecidableEq α] (h : f a = 1) : ∏ x ∈ insert a s, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ insert a s, f x = ∑ x ∈ s, f x

full_name: Finset.prod_insert_div
code: @[to_additive]
theorem prod_insert_div {M : Type*} [CommGroup M] [DecidableEq α] (ha : a ∉ s) {f : α → M} :
    (∏ x ∈ insert a s, f x) / f a = ∏ x ∈ s, f x 
goal: (∏ x ∈ insert a s, f x) / f a = ∏ x ∈ s, f x

full_name: Finset.sum_insert_sub
code: @[to_additive]
theorem prod_insert_div {M : Type*} [CommGroup M] [DecidableEq α] (ha : a ∉ s) {f : α → M} :
    (∏ x ∈ insert a s, f x) / f a = ∏ x ∈ s, f x 
goal: ∑ x ∈ insert a s, f x - f a = ∑ x ∈ s, f x

full_name: Finset.sum_singleton
code: @[to_additive (attr := simp)]
theorem prod_singleton (f : α → β) (a : α) : ∏ x ∈ singleton a, f x = f a 
goal: ∑ x ∈ {a}, f x = f a

full_name: Finset.prod_singleton
code: @[to_additive (attr := simp)]
theorem prod_singleton (f : α → β) (a : α) : ∏ x ∈ singleton a, f x = f a 
goal: ∏ x ∈ {a}, f x = f a

full_name: Finset.sum_pair
code: @[to_additive]
theorem prod_pair [DecidableEq α] {a b : α} (h : a ≠ b) :
    (∏ x ∈ ({a, b} : Finset α), f x) = f a * f b 
goal: ∑ x ∈ {a, b}, f x = f a + f b

full_name: Finset.prod_pair
code: @[to_additive]
theorem prod_pair [DecidableEq α] {a b : α} (h : a ≠ b) :
    (∏ x ∈ ({a, b} : Finset α), f x) = f a * f b 
goal: ∏ x ∈ {a, b}, f x = f a * f b

full_name: Finset.prod_const_one
code: @[to_additive (attr := simp)]
theorem prod_const_one : (∏ _x ∈ s, (1 : β)) = 1 
goal: ∏ _x ∈ s, 1 = 1

full_name: Finset.sum_const_zero
code: @[to_additive (attr := simp)]
theorem prod_const_one : (∏ _x ∈ s, (1 : β)) = 1 
goal: ∑ _x ∈ s, 0 = 0

full_name: Finset.prod_image
code: @[to_additive (attr := simp)]
theorem prod_image [DecidableEq α] {s : Finset γ} {g : γ → α} :
    (∀ x ∈ s, ∀ y ∈ s, g x = g y → x = y) → ∏ x ∈ s.image g, f x = ∏ x ∈ s, f (g x) 
goal: (∀ x ∈ s, ∀ y ∈ s, g x = g y → x = y) → ∏ x ∈ Finset.image g s, f x = ∏ x ∈ s, f (g x)

full_name: Finset.sum_image
code: @[to_additive (attr := simp)]
theorem prod_image [DecidableEq α] {s : Finset γ} {g : γ → α} :
    (∀ x ∈ s, ∀ y ∈ s, g x = g y → x = y) → ∏ x ∈ s.image g, f x = ∏ x ∈ s, f (g x) 
goal: (∀ x ∈ s, ∀ y ∈ s, g x = g y → x = y) → ∑ x ∈ Finset.image g s, f x = ∑ x ∈ s, f (g x)

full_name: Finset.sum_map
code: @[to_additive (attr := simp)]
theorem prod_map (s : Finset α) (e : α ↪ γ) (f : γ → β) :
    ∏ x ∈ s.map e, f x = ∏ x ∈ s, f (e x) 
goal: ∑ x ∈ Finset.map e s, f x = ∑ x ∈ s, f (e x)

full_name: Finset.prod_map
code: @[to_additive (attr := simp)]
theorem prod_map (s : Finset α) (e : α ↪ γ) (f : γ → β) :
    ∏ x ∈ s.map e, f x = ∏ x ∈ s, f (e x) 
goal: ∏ x ∈ Finset.map e s, f x = ∏ x ∈ s, f (e x)

full_name: Finset.prod_attach
code: @[to_additive]
lemma prod_attach (s : Finset α) (f : α → β) : ∏ x ∈ s.attach, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ s.attach, f ↑x = ∏ x ∈ s, f x

full_name: Finset.sum_attach
code: @[to_additive]
lemma prod_attach (s : Finset α) (f : α → β) : ∏ x ∈ s.attach, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ s.attach, f ↑x = ∑ x ∈ s, f x

full_name: Finset.sum_congr
code: @[to_additive (attr := congr)]
theorem prod_congr (h : s₁ = s₂) : (∀ x ∈ s₂, f x = g x) → s₁.prod f = s₂.prod g 
goal: (∀ x ∈ s₂, f x = g x) → s₁.sum f = s₂.sum g

full_name: Finset.prod_congr
code: @[to_additive (attr := congr)]
theorem prod_congr (h : s₁ = s₂) : (∀ x ∈ s₂, f x = g x) → s₁.prod f = s₂.prod g 
goal: (∀ x ∈ s₂, f x = g x) → s₁.prod f = s₂.prod g

full_name: Finset.prod_eq_one
code: @[to_additive]
theorem prod_eq_one {f : α → β} {s : Finset α} (h : ∀ x ∈ s, f x = 1) : ∏ x ∈ s, f x = 1 
goal: ∏ x ∈ s, f x = 1

full_name: Finset.sum_eq_zero
code: @[to_additive]
theorem prod_eq_one {f : α → β} {s : Finset α} (h : ∀ x ∈ s, f x = 1) : ∏ x ∈ s, f x = 1 
goal: ∑ x ∈ s, f x = 0

full_name: Finset.prod_disjUnion
code: @[to_additive]
theorem prod_disjUnion (h) :
    ∏ x ∈ s₁.disjUnion s₂ h, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x 
goal: ∏ x ∈ s₁.disjUnion s₂ h, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x

full_name: Finset.sum_disjUnion
code: @[to_additive]
theorem prod_disjUnion (h) :
    ∏ x ∈ s₁.disjUnion s₂ h, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x 
goal: ∑ x ∈ s₁.disjUnion s₂ h, f x = ∑ x ∈ s₁, f x + ∑ x ∈ s₂, f x

full_name: Finset.prod_disjiUnion
code: @[to_additive]
theorem prod_disjiUnion (s : Finset ι) (t : ι → Finset α) (h) :
    ∏ x ∈ s.disjiUnion t h, f x = ∏ i ∈ s, ∏ x ∈ t i, f x 
goal: ∏ x ∈ s.disjiUnion t h, f x = ∏ i ∈ s, ∏ x ∈ t i, f x

full_name: Finset.sum_disjiUnion
code: @[to_additive]
theorem prod_disjiUnion (s : Finset ι) (t : ι → Finset α) (h) :
    ∏ x ∈ s.disjiUnion t h, f x = ∏ i ∈ s, ∏ x ∈ t i, f x 
goal: ∑ x ∈ s.disjiUnion t h, f x = ∑ i ∈ s, ∑ x ∈ t i, f x

full_name: Finset.sum_union_inter
code: @[to_additive]
theorem prod_union_inter [DecidableEq α] :
    (∏ x ∈ s₁ ∪ s₂, f x) * ∏ x ∈ s₁ ∩ s₂, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x 
goal: ∑ x ∈ s₁ ∪ s₂, f x + ∑ x ∈ s₁ ∩ s₂, f x = ∑ x ∈ s₁, f x + ∑ x ∈ s₂, f x

full_name: Finset.prod_union_inter
code: @[to_additive]
theorem prod_union_inter [DecidableEq α] :
    (∏ x ∈ s₁ ∪ s₂, f x) * ∏ x ∈ s₁ ∩ s₂, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x 
goal: (∏ x ∈ s₁ ∪ s₂, f x) * ∏ x ∈ s₁ ∩ s₂, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x

full_name: Finset.sum_union
code: @[to_additive]
theorem prod_union [DecidableEq α] (h : Disjoint s₁ s₂) :
    ∏ x ∈ s₁ ∪ s₂, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x 
goal: ∑ x ∈ s₁ ∪ s₂, f x = ∑ x ∈ s₁, f x + ∑ x ∈ s₂, f x

full_name: Finset.prod_union
code: @[to_additive]
theorem prod_union [DecidableEq α] (h : Disjoint s₁ s₂) :
    ∏ x ∈ s₁ ∪ s₂, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x 
goal: ∏ x ∈ s₁ ∪ s₂, f x = (∏ x ∈ s₁, f x) * ∏ x ∈ s₂, f x

full_name: Finset.prod_filter_mul_prod_filter_not
code: @[to_additive]
theorem prod_filter_mul_prod_filter_not
    (s : Finset α) (p : α → Prop) [DecidablePred p] [∀ x, Decidable (¬p x)] (f : α → β) :
    (∏ x ∈ s.filter p, f x) * ∏ x ∈ s.filter fun x => ¬p x, f x = ∏ x ∈ s, f x 
goal: (∏ x ∈ Finset.filter p s, f x) * ∏ x ∈ Finset.filter (fun x => ¬p x) s, f x = ∏ x ∈ s, f x

full_name: Finset.sum_filter_add_sum_filter_not
code: @[to_additive]
theorem prod_filter_mul_prod_filter_not
    (s : Finset α) (p : α → Prop) [DecidablePred p] [∀ x, Decidable (¬p x)] (f : α → β) :
    (∏ x ∈ s.filter p, f x) * ∏ x ∈ s.filter fun x => ¬p x, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ Finset.filter p s, f x + ∑ x ∈ Finset.filter (fun x => ¬p x) s, f x = ∑ x ∈ s, f x

full_name: Finset.sum_to_list
code: @[to_additive (attr := simp)]
theorem prod_to_list (s : Finset α) (f : α → β) : (s.toList.map f).prod = s.prod f 
goal: (List.map f s.toList).sum = s.sum f

full_name: Finset.prod_to_list
code: @[to_additive (attr := simp)]
theorem prod_to_list (s : Finset α) (f : α → β) : (s.toList.map f).prod = s.prod f 
goal: (List.map f s.toList).prod = s.prod f

full_name: Equiv.Perm.prod_comp
code: @[to_additive]
theorem _root_.Equiv.Perm.prod_comp (σ : Equiv.Perm α) (s : Finset α) (f : α → β)
    (hs : { a | σ a ≠ a } ⊆ s) : (∏ x ∈ s, f (σ x)) = ∏ x ∈ s, f x 
goal: ∏ x ∈ s, f (σ x) = ∏ x ∈ s, f x

full_name: Equiv.Perm.sum_comp
code: @[to_additive]
theorem _root_.Equiv.Perm.prod_comp (σ : Equiv.Perm α) (s : Finset α) (f : α → β)
    (hs : { a | σ a ≠ a } ⊆ s) : (∏ x ∈ s, f (σ x)) = ∏ x ∈ s, f x 
goal: ∑ x ∈ s, f (σ x) = ∑ x ∈ s, f x

full_name: Equiv.Perm.sum_comp'
code: @[to_additive]
theorem _root_.Equiv.Perm.prod_comp' (σ : Equiv.Perm α) (s : Finset α) (f : α → α → β)
    (hs : { a | σ a ≠ a } ⊆ s) : (∏ x ∈ s, f (σ x) x) = ∏ x ∈ s, f x (σ.symm x) 
goal: ∑ x ∈ s, f (σ x) x = ∑ x ∈ s, f x ((Equiv.symm σ) x)

full_name: Equiv.Perm.prod_comp'
code: @[to_additive]
theorem _root_.Equiv.Perm.prod_comp' (σ : Equiv.Perm α) (s : Finset α) (f : α → α → β)
    (hs : { a | σ a ≠ a } ⊆ s) : (∏ x ∈ s, f (σ x) x) = ∏ x ∈ s, f x (σ.symm x) 
goal: ∏ x ∈ s, f (σ x) x = ∏ x ∈ s, f x ((Equiv.symm σ) x)

full_name: Finset.sum_powerset_insert
code: /-- A product over all subsets of `s ∪ {x}` is obtained by multiplying the product over all subsets
of `s`, and over all subsets of `s` to which one adds `x`. -/
@[to_additive "A sum over all subsets of `s ∪ {x}` is obtained by summing the sum over all subsets
of `s`, and over all subsets of `s` to which one adds `x`."]
lemma prod_powerset_insert [DecidableEq α] (ha : a ∉ s) (f : Finset α → β) :
    ∏ t ∈ (insert a s).powerset, f t =
      (∏ t ∈ s.powerset, f t) * ∏ t ∈ s.powerset, f (insert a t) 
goal: ∑ t ∈ (insert a s).powerset, f t = ∑ t ∈ s.powerset, f t + ∑ t ∈ s.powerset, f (insert a t)

full_name: Finset.prod_powerset_insert
code: /-- A product over all subsets of `s ∪ {x}` is obtained by multiplying the product over all subsets
of `s`, and over all subsets of `s` to which one adds `x`. -/
@[to_additive "A sum over all subsets of `s ∪ {x}` is obtained by summing the sum over all subsets
of `s`, and over all subsets of `s` to which one adds `x`."]
lemma prod_powerset_insert [DecidableEq α] (ha : a ∉ s) (f : Finset α → β) :
    ∏ t ∈ (insert a s).powerset, f t =
      (∏ t ∈ s.powerset, f t) * ∏ t ∈ s.powerset, f (insert a t) 
goal: ∏ t ∈ (insert a s).powerset, f t = (∏ t ∈ s.powerset, f t) * ∏ t ∈ s.powerset, f (insert a t)

full_name: Finset.sum_powerset_cons
code: /-- A product over all subsets of `s ∪ {x}` is obtained by multiplying the product over all subsets
of `s`, and over all subsets of `s` to which one adds `x`. -/
@[to_additive "A sum over all subsets of `s ∪ {x}` is obtained by summing the sum over all subsets
of `s`, and over all subsets of `s` to which one adds `x`."]
lemma prod_powerset_cons (ha : a ∉ s) (f : Finset α → β) :
    ∏ t ∈ (s.cons a ha).powerset, f t = (∏ t ∈ s.powerset, f t) *
      ∏ t ∈ s.powerset.attach, f (cons a t $ not_mem_mono (mem_powerset.1 t.2) ha) 
goal: ∑ t ∈ (Finset.cons a s ha).powerset, f t = ∑ t ∈ s.powerset, f t + ∑ t ∈ s.powerset.attach, f (Finset.cons a ↑t ⋯)

full_name: Finset.prod_powerset_cons
code: /-- A product over all subsets of `s ∪ {x}` is obtained by multiplying the product over all subsets
of `s`, and over all subsets of `s` to which one adds `x`. -/
@[to_additive "A sum over all subsets of `s ∪ {x}` is obtained by summing the sum over all subsets
of `s`, and over all subsets of `s` to which one adds `x`."]
lemma prod_powerset_cons (ha : a ∉ s) (f : Finset α → β) :
    ∏ t ∈ (s.cons a ha).powerset, f t = (∏ t ∈ s.powerset, f t) *
      ∏ t ∈ s.powerset.attach, f (cons a t $ not_mem_mono (mem_powerset.1 t.2) ha) 
goal: ∏ t ∈ (Finset.cons a s ha).powerset, f t = (∏ t ∈ s.powerset, f t) * ∏ t ∈ s.powerset.attach, f (Finset.cons a ↑t ⋯)

full_name: Finset.sum_powerset
code: /-- A product over `powerset s` is equal to the double product over sets of subsets of `s` with
`card s = k`, for `k = 1, ..., card s`. -/
@[to_additive "A sum over `powerset s` is equal to the double sum over sets of subsets of `s` with
  `card s = k`, for `k = 1, ..., card s`"]
lemma prod_powerset (s : Finset α) (f : Finset α → β) :
    ∏ t ∈ powerset s, f t = ∏ j ∈ range (card s + 1), ∏ t ∈ powersetCard j s, f t 
goal: ∑ t ∈ s.powerset, f t = ∑ j ∈ Finset.range (s.card + 1), ∑ t ∈ Finset.powersetCard j s, f t

full_name: Finset.prod_powerset
code: /-- A product over `powerset s` is equal to the double product over sets of subsets of `s` with
`card s = k`, for `k = 1, ..., card s`. -/
@[to_additive "A sum over `powerset s` is equal to the double sum over sets of subsets of `s` with
  `card s = k`, for `k = 1, ..., card s`"]
lemma prod_powerset (s : Finset α) (f : Finset α → β) :
    ∏ t ∈ powerset s, f t = ∏ j ∈ range (card s + 1), ∏ t ∈ powersetCard j s, f t 
goal: ∏ t ∈ s.powerset, f t = ∏ j ∈ Finset.range (s.card + 1), ∏ t ∈ Finset.powersetCard j s, f t

full_name: IsCompl.sum_add_sum
code: @[to_additive]
theorem IsCompl.prod_mul_prod {s t : Finset α} (h : IsCompl s t) (f : α → β) :
    (∏ i ∈ s, f i) * ∏ i ∈ t, f i = ∏ i, f i 
goal: ∑ i ∈ s, f i + ∑ i ∈ t, f i = ∑ i : α, f i

full_name: IsCompl.prod_mul_prod
code: @[to_additive]
theorem IsCompl.prod_mul_prod {s t : Finset α} (h : IsCompl s t) (f : α → β) :
    (∏ i ∈ s, f i) * ∏ i ∈ t, f i = ∏ i, f i 
goal: (∏ i ∈ s, f i) * ∏ i ∈ t, f i = ∏ i : α, f i

full_name: Finset.prod_mul_prod_compl
code: /-- Multiplying the products of a function over `s` and over `sᶜ` gives the whole product.
For a version expressed with subtypes, see `Fintype.prod_subtype_mul_prod_subtype`. -/
@[to_additive "Adding the sums of a function over `s` and over `sᶜ` gives the whole sum.
For a version expressed with subtypes, see `Fintype.sum_subtype_add_sum_subtype`. "]
theorem prod_mul_prod_compl [Fintype α] [DecidableEq α] (s : Finset α) (f : α → β) :
    (∏ i ∈ s, f i) * ∏ i ∈ sᶜ, f i = ∏ i, f i 
goal: (∏ i ∈ s, f i) * ∏ i ∈ sᶜ, f i = ∏ i : α, f i

full_name: Finset.sum_add_sum_compl
code: /-- Multiplying the products of a function over `s` and over `sᶜ` gives the whole product.
For a version expressed with subtypes, see `Fintype.prod_subtype_mul_prod_subtype`. -/
@[to_additive "Adding the sums of a function over `s` and over `sᶜ` gives the whole sum.
For a version expressed with subtypes, see `Fintype.sum_subtype_add_sum_subtype`. "]
theorem prod_mul_prod_compl [Fintype α] [DecidableEq α] (s : Finset α) (f : α → β) :
    (∏ i ∈ s, f i) * ∏ i ∈ sᶜ, f i = ∏ i, f i 
goal: ∑ i ∈ s, f i + ∑ i ∈ sᶜ, f i = ∑ i : α, f i

full_name: Finset.sum_compl_add_sum
code: @[to_additive]
theorem prod_compl_mul_prod [Fintype α] [DecidableEq α] (s : Finset α) (f : α → β) :
    (∏ i ∈ sᶜ, f i) * ∏ i ∈ s, f i = ∏ i, f i 
goal: ∑ i ∈ sᶜ, f i + ∑ i ∈ s, f i = ∑ i : α, f i

full_name: Finset.prod_compl_mul_prod
code: @[to_additive]
theorem prod_compl_mul_prod [Fintype α] [DecidableEq α] (s : Finset α) (f : α → β) :
    (∏ i ∈ sᶜ, f i) * ∏ i ∈ s, f i = ∏ i, f i 
goal: (∏ i ∈ sᶜ, f i) * ∏ i ∈ s, f i = ∏ i : α, f i

full_name: Finset.sum_sdiff
code: @[to_additive]
theorem prod_sdiff [DecidableEq α] (h : s₁ ⊆ s₂) :
    (∏ x ∈ s₂ \ s₁, f x) * ∏ x ∈ s₁, f x = ∏ x ∈ s₂, f x 
goal: ∑ x ∈ s₂ \ s₁, f x + ∑ x ∈ s₁, f x = ∑ x ∈ s₂, f x

full_name: Finset.prod_sdiff
code: @[to_additive]
theorem prod_sdiff [DecidableEq α] (h : s₁ ⊆ s₂) :
    (∏ x ∈ s₂ \ s₁, f x) * ∏ x ∈ s₁, f x = ∏ x ∈ s₂, f x 
goal: (∏ x ∈ s₂ \ s₁, f x) * ∏ x ∈ s₁, f x = ∏ x ∈ s₂, f x

full_name: Finset.prod_subset_one_on_sdiff
code: @[to_additive]
theorem prod_subset_one_on_sdiff [DecidableEq α] (h : s₁ ⊆ s₂) (hg : ∀ x ∈ s₂ \ s₁, g x = 1)
    (hfg : ∀ x ∈ s₁, f x = g x) : ∏ i ∈ s₁, f i = ∏ i ∈ s₂, g i 
goal: ∏ i ∈ s₁, f i = ∏ i ∈ s₂, g i

full_name: Finset.sum_subset_zero_on_sdiff
code: @[to_additive]
theorem prod_subset_one_on_sdiff [DecidableEq α] (h : s₁ ⊆ s₂) (hg : ∀ x ∈ s₂ \ s₁, g x = 1)
    (hfg : ∀ x ∈ s₁, f x = g x) : ∏ i ∈ s₁, f i = ∏ i ∈ s₂, g i 
goal: ∑ i ∈ s₁, f i = ∑ i ∈ s₂, g i

full_name: Finset.sum_subset
code: @[to_additive]
theorem prod_subset (h : s₁ ⊆ s₂) (hf : ∀ x ∈ s₂, x ∉ s₁ → f x = 1) :
    ∏ x ∈ s₁, f x = ∏ x ∈ s₂, f x 
goal: ∑ x ∈ s₁, f x = ∑ x ∈ s₂, f x

full_name: Finset.prod_subset
code: @[to_additive]
theorem prod_subset (h : s₁ ⊆ s₂) (hf : ∀ x ∈ s₂, x ∉ s₁ → f x = 1) :
    ∏ x ∈ s₁, f x = ∏ x ∈ s₂, f x 
goal: ∏ x ∈ s₁, f x = ∏ x ∈ s₂, f x

full_name: Finset.sum_disj_sum
code: @[to_additive (attr := simp)]
theorem prod_disj_sum (s : Finset α) (t : Finset γ) (f : α ⊕ γ → β) :
    ∏ x ∈ s.disjSum t, f x = (∏ x ∈ s, f (Sum.inl x)) * ∏ x ∈ t, f (Sum.inr x) 
goal: ∑ x ∈ s.disjSum t, f x = ∑ x ∈ s, f (Sum.inl x) + ∑ x ∈ t, f (Sum.inr x)

full_name: Finset.prod_disj_sum
code: @[to_additive (attr := simp)]
theorem prod_disj_sum (s : Finset α) (t : Finset γ) (f : α ⊕ γ → β) :
    ∏ x ∈ s.disjSum t, f x = (∏ x ∈ s, f (Sum.inl x)) * ∏ x ∈ t, f (Sum.inr x) 
goal: ∏ x ∈ s.disjSum t, f x = (∏ x ∈ s, f (Sum.inl x)) * ∏ x ∈ t, f (Sum.inr x)

full_name: Finset.prod_sum_elim
code: @[to_additive]
theorem prod_sum_elim (s : Finset α) (t : Finset γ) (f : α → β) (g : γ → β) :
    ∏ x ∈ s.disjSum t, Sum.elim f g x = (∏ x ∈ s, f x) * ∏ x ∈ t, g x 
goal: ∏ x ∈ s.disjSum t, Sum.elim f g x = (∏ x ∈ s, f x) * ∏ x ∈ t, g x

full_name: Finset.sum_sum_elim
code: @[to_additive]
theorem prod_sum_elim (s : Finset α) (t : Finset γ) (f : α → β) (g : γ → β) :
    ∏ x ∈ s.disjSum t, Sum.elim f g x = (∏ x ∈ s, f x) * ∏ x ∈ t, g x 
goal: ∑ x ∈ s.disjSum t, Sum.elim f g x = ∑ x ∈ s, f x + ∑ x ∈ t, g x

full_name: Finset.sum_biUnion
code: @[to_additive]
theorem prod_biUnion [DecidableEq α] {s : Finset γ} {t : γ → Finset α}
    (hs : Set.PairwiseDisjoint (↑s) t) : ∏ x ∈ s.biUnion t, f x = ∏ x ∈ s, ∏ i ∈ t x, f i 
goal: ∑ x ∈ s.biUnion t, f x = ∑ x ∈ s, ∑ i ∈ t x, f i

full_name: Finset.prod_biUnion
code: @[to_additive]
theorem prod_biUnion [DecidableEq α] {s : Finset γ} {t : γ → Finset α}
    (hs : Set.PairwiseDisjoint (↑s) t) : ∏ x ∈ s.biUnion t, f x = ∏ x ∈ s, ∏ i ∈ t x, f i 
goal: ∏ x ∈ s.biUnion t, f x = ∏ x ∈ s, ∏ i ∈ t x, f i

full_name: Finset.prod_sigma
code: /-- Product over a sigma type equals the product of fiberwise products. For rewriting
in the reverse direction, use `Finset.prod_sigma'`.  -/
@[to_additive "Sum over a sigma type equals the sum of fiberwise sums. For rewriting
in the reverse direction, use `Finset.sum_sigma'`"]
theorem prod_sigma {σ : α → Type*} (s : Finset α) (t : ∀ a, Finset (σ a)) (f : Sigma σ → β) :
    ∏ x ∈ s.sigma t, f x = ∏ a ∈ s, ∏ s ∈ t a, f ⟨a, s⟩ 
goal: ∏ x ∈ s.sigma t, f x = ∏ a ∈ s, ∏ s ∈ t a, f ⟨a, s⟩

full_name: Finset.sum_sigma
code: /-- Product over a sigma type equals the product of fiberwise products. For rewriting
in the reverse direction, use `Finset.prod_sigma'`.  -/
@[to_additive "Sum over a sigma type equals the sum of fiberwise sums. For rewriting
in the reverse direction, use `Finset.sum_sigma'`"]
theorem prod_sigma {σ : α → Type*} (s : Finset α) (t : ∀ a, Finset (σ a)) (f : Sigma σ → β) :
    ∏ x ∈ s.sigma t, f x = ∏ a ∈ s, ∏ s ∈ t a, f ⟨a, s⟩ 
goal: ∑ x ∈ s.sigma t, f x = ∑ a ∈ s, ∑ s ∈ t a, f ⟨a, s⟩

full_name: Finset.prod_sigma'
code: @[to_additive]
theorem prod_sigma' {σ : α → Type*} (s : Finset α) (t : ∀ a, Finset (σ a)) (f : ∀ a, σ a → β) :
    (∏ a ∈ s, ∏ s ∈ t a, f a s) = ∏ x ∈ s.sigma t, f x.1 x.2 
goal: ∏ a ∈ s, ∏ s ∈ t a, f a s = ∏ x ∈ s.sigma t, f x.fst x.snd

full_name: Finset.sum_sigma'
code: @[to_additive]
theorem prod_sigma' {σ : α → Type*} (s : Finset α) (t : ∀ a, Finset (σ a)) (f : ∀ a, σ a → β) :
    (∏ a ∈ s, ∏ s ∈ t a, f a s) = ∏ x ∈ s.sigma t, f x.1 x.2 
goal: ∑ a ∈ s, ∑ s ∈ t a, f a s = ∑ x ∈ s.sigma t, f x.fst x.snd

full_name: Finset.prod_bij
code: /-- Reorder a product.

The difference with `Finset.prod_bij'` is that the bijection is specified as a surjective injection,
rather than by an inverse function.

The difference with `Finset.prod_nbij` is that the bijection is allowed to use membership of the
domain of the product, rather than being a non-dependent function. -/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_bij'` is that the bijection is specified as a surjective injection,
rather than by an inverse function.

The difference with `Finset.sum_nbij` is that the bijection is allowed to use membership of the
domain of the sum, rather than being a non-dependent function."]
theorem prod_bij (i : ∀ a ∈ s, κ) (hi : ∀ a ha, i a ha ∈ t)
    (i_inj : ∀ a₁ ha₁ a₂ ha₂, i a₁ ha₁ = i a₂ ha₂ → a₁ = a₂)
    (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) (h : ∀ a ha, f a = g (i a ha)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∏ x ∈ s, f x = ∏ x ∈ t, g x

full_name: Finset.sum_bij
code: /-- Reorder a product.

The difference with `Finset.prod_bij'` is that the bijection is specified as a surjective injection,
rather than by an inverse function.

The difference with `Finset.prod_nbij` is that the bijection is allowed to use membership of the
domain of the product, rather than being a non-dependent function. -/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_bij'` is that the bijection is specified as a surjective injection,
rather than by an inverse function.

The difference with `Finset.sum_nbij` is that the bijection is allowed to use membership of the
domain of the sum, rather than being a non-dependent function."]
theorem prod_bij (i : ∀ a ∈ s, κ) (hi : ∀ a ha, i a ha ∈ t)
    (i_inj : ∀ a₁ ha₁ a₂ ha₂, i a₁ ha₁ = i a₂ ha₂ → a₁ = a₂)
    (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) (h : ∀ a ha, f a = g (i a ha)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∑ x ∈ s, f x = ∑ x ∈ t, g x

full_name: Finset.prod_bij'
code: /-- Reorder a product.

The difference with `Finset.prod_bij` is that the bijection is specified with an inverse, rather
than as a surjective injection.

The difference with `Finset.prod_nbij'` is that the bijection and its inverse are allowed to use
membership of the domains of the products, rather than being non-dependent functions. -/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_bij` is that the bijection is specified with an inverse, rather than
as a surjective injection.

The difference with `Finset.sum_nbij'` is that the bijection and its inverse are allowed to use
membership of the domains of the sums, rather than being non-dependent functions."]
theorem prod_bij' (i : ∀ a ∈ s, κ) (j : ∀ a ∈ t, ι) (hi : ∀ a ha, i a ha ∈ t)
    (hj : ∀ a ha, j a ha ∈ s) (left_inv : ∀ a ha, j (i a ha) (hi a ha) = a)
    (right_inv : ∀ a ha, i (j a ha) (hj a ha) = a) (h : ∀ a ha, f a = g (i a ha)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∏ x ∈ s, f x = ∏ x ∈ t, g x

full_name: Finset.sum_bij'
code: /-- Reorder a product.

The difference with `Finset.prod_bij` is that the bijection is specified with an inverse, rather
than as a surjective injection.

The difference with `Finset.prod_nbij'` is that the bijection and its inverse are allowed to use
membership of the domains of the products, rather than being non-dependent functions. -/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_bij` is that the bijection is specified with an inverse, rather than
as a surjective injection.

The difference with `Finset.sum_nbij'` is that the bijection and its inverse are allowed to use
membership of the domains of the sums, rather than being non-dependent functions."]
theorem prod_bij' (i : ∀ a ∈ s, κ) (j : ∀ a ∈ t, ι) (hi : ∀ a ha, i a ha ∈ t)
    (hj : ∀ a ha, j a ha ∈ s) (left_inv : ∀ a ha, j (i a ha) (hi a ha) = a)
    (right_inv : ∀ a ha, i (j a ha) (hj a ha) = a) (h : ∀ a ha, f a = g (i a ha)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∑ x ∈ s, f x = ∑ x ∈ t, g x

full_name: Finset.sum_nbij
code: /-- Reorder a product.

The difference with `Finset.prod_nbij'` is that the bijection is specified as a surjective
injection, rather than by an inverse function.

The difference with `Finset.prod_bij` is that the bijection is a non-dependent function, rather than
being allowed to use membership of the domain of the product. -/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_nbij'` is that the bijection is specified as a surjective injection,
rather than by an inverse function.

The difference with `Finset.sum_bij` is that the bijection is a non-dependent function, rather than
being allowed to use membership of the domain of the sum."]
lemma prod_nbij (i : ι → κ) (hi : ∀ a ∈ s, i a ∈ t) (i_inj : (s : Set ι).InjOn i)
    (i_surj : (s : Set ι).SurjOn i t) (h : ∀ a ∈ s, f a = g (i a)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∑ x ∈ s, f x = ∑ x ∈ t, g x

full_name: Finset.prod_nbij
code: /-- Reorder a product.

The difference with `Finset.prod_nbij'` is that the bijection is specified as a surjective
injection, rather than by an inverse function.

The difference with `Finset.prod_bij` is that the bijection is a non-dependent function, rather than
being allowed to use membership of the domain of the product. -/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_nbij'` is that the bijection is specified as a surjective injection,
rather than by an inverse function.

The difference with `Finset.sum_bij` is that the bijection is a non-dependent function, rather than
being allowed to use membership of the domain of the sum."]
lemma prod_nbij (i : ι → κ) (hi : ∀ a ∈ s, i a ∈ t) (i_inj : (s : Set ι).InjOn i)
    (i_surj : (s : Set ι).SurjOn i t) (h : ∀ a ∈ s, f a = g (i a)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∏ x ∈ s, f x = ∏ x ∈ t, g x

full_name: Finset.sum_nbij'
code: /-- Reorder a product.

The difference with `Finset.prod_nbij` is that the bijection is specified with an inverse, rather
than as a surjective injection.

The difference with `Finset.prod_bij'` is that the bijection and its inverse are non-dependent
functions, rather than being allowed to use membership of the domains of the products.

The difference with `Finset.prod_equiv` is that bijectivity is only required to hold on the domains
of the products, rather than on the entire types.
-/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_nbij` is that the bijection is specified with an inverse, rather
than as a surjective injection.

The difference with `Finset.sum_bij'` is that the bijection and its inverse are non-dependent
functions, rather than being allowed to use membership of the domains of the sums.

The difference with `Finset.sum_equiv` is that bijectivity is only required to hold on the domains
of the sums, rather than on the entire types."]
lemma prod_nbij' (i : ι → κ) (j : κ → ι) (hi : ∀ a ∈ s, i a ∈ t) (hj : ∀ a ∈ t, j a ∈ s)
    (left_inv : ∀ a ∈ s, j (i a) = a) (right_inv : ∀ a ∈ t, i (j a) = a)
    (h : ∀ a ∈ s, f a = g (i a)) : ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∑ x ∈ s, f x = ∑ x ∈ t, g x

full_name: Finset.prod_nbij'
code: /-- Reorder a product.

The difference with `Finset.prod_nbij` is that the bijection is specified with an inverse, rather
than as a surjective injection.

The difference with `Finset.prod_bij'` is that the bijection and its inverse are non-dependent
functions, rather than being allowed to use membership of the domains of the products.

The difference with `Finset.prod_equiv` is that bijectivity is only required to hold on the domains
of the products, rather than on the entire types.
-/
@[to_additive "Reorder a sum.

The difference with `Finset.sum_nbij` is that the bijection is specified with an inverse, rather
than as a surjective injection.

The difference with `Finset.sum_bij'` is that the bijection and its inverse are non-dependent
functions, rather than being allowed to use membership of the domains of the sums.

The difference with `Finset.sum_equiv` is that bijectivity is only required to hold on the domains
of the sums, rather than on the entire types."]
lemma prod_nbij' (i : ι → κ) (j : κ → ι) (hi : ∀ a ∈ s, i a ∈ t) (hj : ∀ a ∈ t, j a ∈ s)
    (left_inv : ∀ a ∈ s, j (i a) = a) (right_inv : ∀ a ∈ t, i (j a) = a)
    (h : ∀ a ∈ s, f a = g (i a)) : ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∏ x ∈ s, f x = ∏ x ∈ t, g x

full_name: Finset.prod_equiv
code: /-- Specialization of `Finset.prod_nbij'` that automatically fills in most arguments.

See `Fintype.prod_equiv` for the version where `s` and `t` are `univ`. -/
@[to_additive "`Specialization of `Finset.sum_nbij'` that automatically fills in most arguments.

See `Fintype.sum_equiv` for the version where `s` and `t` are `univ`."]
lemma prod_equiv (e : ι ≃ κ) (hst : ∀ i, i ∈ s ↔ e i ∈ t) (hfg : ∀ i ∈ s, f i = g (e i)) :
    ∏ i ∈ s, f i = ∏ i ∈ t, g i 
goal: ∏ i ∈ s, f i = ∏ i ∈ t, g i

full_name: Finset.sum_equiv
code: /-- Specialization of `Finset.prod_nbij'` that automatically fills in most arguments.

See `Fintype.prod_equiv` for the version where `s` and `t` are `univ`. -/
@[to_additive "`Specialization of `Finset.sum_nbij'` that automatically fills in most arguments.

See `Fintype.sum_equiv` for the version where `s` and `t` are `univ`."]
lemma prod_equiv (e : ι ≃ κ) (hst : ∀ i, i ∈ s ↔ e i ∈ t) (hfg : ∀ i ∈ s, f i = g (e i)) :
    ∏ i ∈ s, f i = ∏ i ∈ t, g i 
goal: ∑ i ∈ s, f i = ∑ i ∈ t, g i

full_name: Finset.sum_bijective
code: /-- Specialization of `Finset.prod_bij` that automatically fills in most arguments.

See `Fintype.prod_bijective` for the version where `s` and `t` are `univ`. -/
@[to_additive "`Specialization of `Finset.sum_bij` that automatically fills in most arguments.

See `Fintype.sum_bijective` for the version where `s` and `t` are `univ`."]
lemma prod_bijective (e : ι → κ) (he : e.Bijective) (hst : ∀ i, i ∈ s ↔ e i ∈ t)
    (hfg : ∀ i ∈ s, f i = g (e i)) :
    ∏ i ∈ s, f i = ∏ i ∈ t, g i 
goal: ∑ i ∈ s, f i = ∑ i ∈ t, g i

full_name: Finset.prod_bijective
code: /-- Specialization of `Finset.prod_bij` that automatically fills in most arguments.

See `Fintype.prod_bijective` for the version where `s` and `t` are `univ`. -/
@[to_additive "`Specialization of `Finset.sum_bij` that automatically fills in most arguments.

See `Fintype.sum_bijective` for the version where `s` and `t` are `univ`."]
lemma prod_bijective (e : ι → κ) (he : e.Bijective) (hst : ∀ i, i ∈ s ↔ e i ∈ t)
    (hfg : ∀ i ∈ s, f i = g (e i)) :
    ∏ i ∈ s, f i = ∏ i ∈ t, g i 
goal: ∏ i ∈ s, f i = ∏ i ∈ t, g i

full_name: Finset.prod_of_injOn
code: @[to_additive]
lemma prod_of_injOn (e : ι → κ) (he : Set.InjOn e s) (hest : Set.MapsTo e s t)
    (h' : ∀ i ∈ t, i ∉ e '' s → g i = 1) (h : ∀ i ∈ s, f i = g (e i))  :
    ∏ i ∈ s, f i = ∏ j ∈ t, g j 
goal: ∏ i ∈ s, f i = ∏ j ∈ t, g j

full_name: Finset.sum_of_injOn
code: @[to_additive]
lemma prod_of_injOn (e : ι → κ) (he : Set.InjOn e s) (hest : Set.MapsTo e s t)
    (h' : ∀ i ∈ t, i ∉ e '' s → g i = 1) (h : ∀ i ∈ s, f i = g (e i))  :
    ∏ i ∈ s, f i = ∏ j ∈ t, g j 
goal: ∑ i ∈ s, f i = ∑ j ∈ t, g j

full_name: Finset.prod_fiberwise_eq_prod_filter
code: @[to_additive]
lemma prod_fiberwise_eq_prod_filter (s : Finset ι) (t : Finset κ) (g : ι → κ) (f : ι → α) :
    ∏ j ∈ t, ∏ i ∈ s.filter fun i ↦ g i = j, f i = ∏ i ∈ s.filter fun i ↦ g i ∈ t, f i 
goal: ∏ j ∈ t, ∏ i ∈ Finset.filter (fun i => g i = j) s, f i = ∏ i ∈ Finset.filter (fun i => g i ∈ t) s, f i

full_name: Finset.sum_fiberwise_eq_sum_filter
code: @[to_additive]
lemma prod_fiberwise_eq_prod_filter (s : Finset ι) (t : Finset κ) (g : ι → κ) (f : ι → α) :
    ∏ j ∈ t, ∏ i ∈ s.filter fun i ↦ g i = j, f i = ∏ i ∈ s.filter fun i ↦ g i ∈ t, f i 
goal: ∑ j ∈ t, ∑ i ∈ Finset.filter (fun i => g i = j) s, f i = ∑ i ∈ Finset.filter (fun i => g i ∈ t) s, f i

full_name: Finset.prod_fiberwise_eq_prod_filter'
code: @[to_additive]
lemma prod_fiberwise_eq_prod_filter' (s : Finset ι) (t : Finset κ) (g : ι → κ) (f : κ → α) :
    ∏ j ∈ t, ∏ _i ∈ s.filter fun i ↦ g i = j, f j = ∏ i ∈ s.filter fun i ↦ g i ∈ t, f (g i) 
goal: ∏ j ∈ t, ∏ _i ∈ Finset.filter (fun i => g i = j) s, f j = ∏ i ∈ Finset.filter (fun i => g i ∈ t) s, f (g i)

full_name: Finset.sum_fiberwise_eq_sum_filter'
code: @[to_additive]
lemma prod_fiberwise_eq_prod_filter' (s : Finset ι) (t : Finset κ) (g : ι → κ) (f : κ → α) :
    ∏ j ∈ t, ∏ _i ∈ s.filter fun i ↦ g i = j, f j = ∏ i ∈ s.filter fun i ↦ g i ∈ t, f (g i) 
goal: ∑ j ∈ t, ∑ _i ∈ Finset.filter (fun i => g i = j) s, f j = ∑ i ∈ Finset.filter (fun i => g i ∈ t) s, f (g i)

full_name: Finset.prod_fiberwise_of_maps_to
code: @[to_additive]
lemma prod_fiberwise_of_maps_to {g : ι → κ} (h : ∀ i ∈ s, g i ∈ t) (f : ι → α) :
    ∏ j ∈ t, ∏ i ∈ s.filter fun i ↦ g i = j, f i = ∏ i ∈ s, f i 
goal: ∏ j ∈ t, ∏ i ∈ Finset.filter (fun i => g i = j) s, f i = ∏ i ∈ s, f i

full_name: Finset.sum_fiberwise_of_maps_to
code: @[to_additive]
lemma prod_fiberwise_of_maps_to {g : ι → κ} (h : ∀ i ∈ s, g i ∈ t) (f : ι → α) :
    ∏ j ∈ t, ∏ i ∈ s.filter fun i ↦ g i = j, f i = ∏ i ∈ s, f i 
goal: ∑ j ∈ t, ∑ i ∈ Finset.filter (fun i => g i = j) s, f i = ∑ i ∈ s, f i

full_name: Finset.sum_fiberwise_of_maps_to'
code: @[to_additive]
lemma prod_fiberwise_of_maps_to' {g : ι → κ} (h : ∀ i ∈ s, g i ∈ t) (f : κ → α) :
    ∏ j ∈ t, ∏ _i ∈ s.filter fun i ↦ g i = j, f j = ∏ i ∈ s, f (g i) 
goal: ∑ j ∈ t, ∑ _i ∈ Finset.filter (fun i => g i = j) s, f j = ∑ i ∈ s, f (g i)

full_name: Finset.prod_fiberwise_of_maps_to'
code: @[to_additive]
lemma prod_fiberwise_of_maps_to' {g : ι → κ} (h : ∀ i ∈ s, g i ∈ t) (f : κ → α) :
    ∏ j ∈ t, ∏ _i ∈ s.filter fun i ↦ g i = j, f j = ∏ i ∈ s, f (g i) 
goal: ∏ j ∈ t, ∏ _i ∈ Finset.filter (fun i => g i = j) s, f j = ∏ i ∈ s, f (g i)

full_name: Finset.sum_fiberwise
code: @[to_additive]
lemma prod_fiberwise (s : Finset ι) (g : ι → κ) (f : ι → α) :
    ∏ j, ∏ i ∈ s.filter fun i ↦ g i = j, f i = ∏ i ∈ s, f i 
goal: ∑ j : κ, ∑ i ∈ Finset.filter (fun i => g i = j) s, f i = ∑ i ∈ s, f i

full_name: Finset.prod_fiberwise
code: @[to_additive]
lemma prod_fiberwise (s : Finset ι) (g : ι → κ) (f : ι → α) :
    ∏ j, ∏ i ∈ s.filter fun i ↦ g i = j, f i = ∏ i ∈ s, f i 
goal: ∏ j : κ, ∏ i ∈ Finset.filter (fun i => g i = j) s, f i = ∏ i ∈ s, f i

full_name: Finset.prod_fiberwise'
code: @[to_additive]
lemma prod_fiberwise' (s : Finset ι) (g : ι → κ) (f : κ → α) :
    ∏ j, ∏ _i ∈ s.filter fun i ↦ g i = j, f j = ∏ i ∈ s, f (g i) 
goal: ∏ j : κ, ∏ _i ∈ Finset.filter (fun i => g i = j) s, f j = ∏ i ∈ s, f (g i)

full_name: Finset.sum_fiberwise'
code: @[to_additive]
lemma prod_fiberwise' (s : Finset ι) (g : ι → κ) (f : κ → α) :
    ∏ j, ∏ _i ∈ s.filter fun i ↦ g i = j, f j = ∏ i ∈ s, f (g i) 
goal: ∑ j : κ, ∑ _i ∈ Finset.filter (fun i => g i = j) s, f j = ∑ i ∈ s, f (g i)

full_name: Finset.sum_univ_pi
code: /-- Taking a product over `univ.pi t` is the same as taking the product over `Fintype.piFinset t`.
`univ.pi t` and `Fintype.piFinset t` are essentially the same `Finset`, but differ
in the type of their element, `univ.pi t` is a `Finset (Π a ∈ univ, t a)` and
`Fintype.piFinset t` is a `Finset (Π a, t a)`. -/
@[to_additive "Taking a sum over `univ.pi t` is the same as taking the sum over
`Fintype.piFinset t`. `univ.pi t` and `Fintype.piFinset t` are essentially the same `Finset`,
but differ in the type of their element, `univ.pi t` is a `Finset (Π a ∈ univ, t a)` and
`Fintype.piFinset t` is a `Finset (Π a, t a)`."]
lemma prod_univ_pi [DecidableEq ι] [Fintype ι] {κ : ι → Type*} (t : ∀ i, Finset (κ i))
    (f : (∀ i ∈ (univ : Finset ι), κ i) → β) :
    ∏ x ∈ univ.pi t, f x = ∏ x ∈ Fintype.piFinset t, f fun a _ ↦ x a 
goal: ∑ x ∈ Finset.univ.pi t, f x = ∑ x ∈ Fintype.piFinset t, f fun a x_1 => x a

full_name: Finset.prod_univ_pi
code: /-- Taking a product over `univ.pi t` is the same as taking the product over `Fintype.piFinset t`.
`univ.pi t` and `Fintype.piFinset t` are essentially the same `Finset`, but differ
in the type of their element, `univ.pi t` is a `Finset (Π a ∈ univ, t a)` and
`Fintype.piFinset t` is a `Finset (Π a, t a)`. -/
@[to_additive "Taking a sum over `univ.pi t` is the same as taking the sum over
`Fintype.piFinset t`. `univ.pi t` and `Fintype.piFinset t` are essentially the same `Finset`,
but differ in the type of their element, `univ.pi t` is a `Finset (Π a ∈ univ, t a)` and
`Fintype.piFinset t` is a `Finset (Π a, t a)`."]
lemma prod_univ_pi [DecidableEq ι] [Fintype ι] {κ : ι → Type*} (t : ∀ i, Finset (κ i))
    (f : (∀ i ∈ (univ : Finset ι), κ i) → β) :
    ∏ x ∈ univ.pi t, f x = ∏ x ∈ Fintype.piFinset t, f fun a _ ↦ x a 
goal: ∏ x ∈ Finset.univ.pi t, f x = ∏ x ∈ Fintype.piFinset t, f fun a x_1 => x a

full_name: Finset.prod_diag
code: @[to_additive (attr := simp)]
lemma prod_diag [DecidableEq α] (s : Finset α) (f : α × α → β) :
    ∏ i ∈ s.diag, f i = ∏ i ∈ s, f (i, i) 
goal: ∏ i ∈ s.diag, f i = ∏ i ∈ s, f (i, i)

full_name: Finset.sum_diag
code: @[to_additive (attr := simp)]
lemma prod_diag [DecidableEq α] (s : Finset α) (f : α × α → β) :
    ∏ i ∈ s.diag, f i = ∏ i ∈ s, f (i, i) 
goal: ∑ i ∈ s.diag, f i = ∑ i ∈ s, f (i, i)

full_name: Finset.prod_finset_product
code: @[to_additive]
theorem prod_finset_product (r : Finset (γ × α)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : γ × α, p ∈ r ↔ p.1 ∈ s ∧ p.2 ∈ t p.1) {f : γ × α → β} :
    ∏ p ∈ r, f p = ∏ c ∈ s, ∏ a ∈ t c, f (c, a) 
goal: ∏ p ∈ r, f p = ∏ c ∈ s, ∏ a ∈ t c, f (c, a)

full_name: Finset.sum_finset_product
code: @[to_additive]
theorem prod_finset_product (r : Finset (γ × α)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : γ × α, p ∈ r ↔ p.1 ∈ s ∧ p.2 ∈ t p.1) {f : γ × α → β} :
    ∏ p ∈ r, f p = ∏ c ∈ s, ∏ a ∈ t c, f (c, a) 
goal: ∑ p ∈ r, f p = ∑ c ∈ s, ∑ a ∈ t c, f (c, a)

full_name: Finset.sum_finset_product'
code: @[to_additive]
theorem prod_finset_product' (r : Finset (γ × α)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : γ × α, p ∈ r ↔ p.1 ∈ s ∧ p.2 ∈ t p.1) {f : γ → α → β} :
    ∏ p ∈ r, f p.1 p.2 = ∏ c ∈ s, ∏ a ∈ t c, f c a 
goal: ∑ p ∈ r, f p.1 p.2 = ∑ c ∈ s, ∑ a ∈ t c, f c a

full_name: Finset.prod_finset_product'
code: @[to_additive]
theorem prod_finset_product' (r : Finset (γ × α)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : γ × α, p ∈ r ↔ p.1 ∈ s ∧ p.2 ∈ t p.1) {f : γ → α → β} :
    ∏ p ∈ r, f p.1 p.2 = ∏ c ∈ s, ∏ a ∈ t c, f c a 
goal: ∏ p ∈ r, f p.1 p.2 = ∏ c ∈ s, ∏ a ∈ t c, f c a

full_name: Finset.sum_finset_product_right
code: @[to_additive]
theorem prod_finset_product_right (r : Finset (α × γ)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : α × γ, p ∈ r ↔ p.2 ∈ s ∧ p.1 ∈ t p.2) {f : α × γ → β} :
    ∏ p ∈ r, f p = ∏ c ∈ s, ∏ a ∈ t c, f (a, c) 
goal: ∑ p ∈ r, f p = ∑ c ∈ s, ∑ a ∈ t c, f (a, c)

full_name: Finset.prod_finset_product_right
code: @[to_additive]
theorem prod_finset_product_right (r : Finset (α × γ)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : α × γ, p ∈ r ↔ p.2 ∈ s ∧ p.1 ∈ t p.2) {f : α × γ → β} :
    ∏ p ∈ r, f p = ∏ c ∈ s, ∏ a ∈ t c, f (a, c) 
goal: ∏ p ∈ r, f p = ∏ c ∈ s, ∏ a ∈ t c, f (a, c)

full_name: Finset.sum_finset_product_right'
code: @[to_additive]
theorem prod_finset_product_right' (r : Finset (α × γ)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : α × γ, p ∈ r ↔ p.2 ∈ s ∧ p.1 ∈ t p.2) {f : α → γ → β} :
    ∏ p ∈ r, f p.1 p.2 = ∏ c ∈ s, ∏ a ∈ t c, f a c 
goal: ∑ p ∈ r, f p.1 p.2 = ∑ c ∈ s, ∑ a ∈ t c, f a c

full_name: Finset.prod_finset_product_right'
code: @[to_additive]
theorem prod_finset_product_right' (r : Finset (α × γ)) (s : Finset γ) (t : γ → Finset α)
    (h : ∀ p : α × γ, p ∈ r ↔ p.2 ∈ s ∧ p.1 ∈ t p.2) {f : α → γ → β} :
    ∏ p ∈ r, f p.1 p.2 = ∏ c ∈ s, ∏ a ∈ t c, f a c 
goal: ∏ p ∈ r, f p.1 p.2 = ∏ c ∈ s, ∏ a ∈ t c, f a c

full_name: Finset.sum_image'
code: @[to_additive]
theorem prod_image' [DecidableEq α] {s : Finset γ} {g : γ → α} (h : γ → β)
    (eq : ∀ c ∈ s, f (g c) = ∏ x ∈ s.filter fun c' => g c' = g c, h x) :
    ∏ x ∈ s.image g, f x = ∏ x ∈ s, h x 
goal: ∑ x ∈ Finset.image g s, f x = ∑ x ∈ s, h x

full_name: Finset.prod_image'
code: @[to_additive]
theorem prod_image' [DecidableEq α] {s : Finset γ} {g : γ → α} (h : γ → β)
    (eq : ∀ c ∈ s, f (g c) = ∏ x ∈ s.filter fun c' => g c' = g c, h x) :
    ∏ x ∈ s.image g, f x = ∏ x ∈ s, h x 
goal: ∏ x ∈ Finset.image g s, f x = ∏ x ∈ s, h x

full_name: Finset.sum_add_distrib
code: @[to_additive]
theorem prod_mul_distrib : ∏ x ∈ s, f x * g x = (∏ x ∈ s, f x) * ∏ x ∈ s, g x 
goal: ∑ x ∈ s, (f x + g x) = ∑ x ∈ s, f x + ∑ x ∈ s, g x

full_name: Finset.prod_mul_distrib
code: @[to_additive]
theorem prod_mul_distrib : ∏ x ∈ s, f x * g x = (∏ x ∈ s, f x) * ∏ x ∈ s, g x 
goal: ∏ x ∈ s, f x * g x = (∏ x ∈ s, f x) * ∏ x ∈ s, g x

full_name: Finset.sum_add_sum_comm
code: @[to_additive]
lemma prod_mul_prod_comm (f g h i : α → β) :
    (∏ a ∈ s, f a * g a) * ∏ a ∈ s, h a * i a = (∏ a ∈ s, f a * h a) * ∏ a ∈ s, g a * i a 
goal: ∑ a ∈ s, (f a + g a) + ∑ a ∈ s, (h a + i a) = ∑ a ∈ s, (f a + h a) + ∑ a ∈ s, (g a + i a)

full_name: Finset.prod_mul_prod_comm
code: @[to_additive]
lemma prod_mul_prod_comm (f g h i : α → β) :
    (∏ a ∈ s, f a * g a) * ∏ a ∈ s, h a * i a = (∏ a ∈ s, f a * h a) * ∏ a ∈ s, g a * i a 
goal: (∏ a ∈ s, f a * g a) * ∏ a ∈ s, h a * i a = (∏ a ∈ s, f a * h a) * ∏ a ∈ s, g a * i a

full_name: Finset.prod_product
code: @[to_additive]
theorem prod_product {s : Finset γ} {t : Finset α} {f : γ × α → β} :
    ∏ x ∈ s ×ˢ t, f x = ∏ x ∈ s, ∏ y ∈ t, f (x, y) 
goal: ∏ x ∈ s ×ˢ t, f x = ∏ x ∈ s, ∏ y ∈ t, f (x, y)

full_name: Finset.sum_product
code: @[to_additive]
theorem prod_product {s : Finset γ} {t : Finset α} {f : γ × α → β} :
    ∏ x ∈ s ×ˢ t, f x = ∏ x ∈ s, ∏ y ∈ t, f (x, y) 
goal: ∑ x ∈ s ×ˢ t, f x = ∑ x ∈ s, ∑ y ∈ t, f (x, y)

full_name: Finset.prod_product'
code: /-- An uncurried version of `Finset.prod_product`. -/
@[to_additive "An uncurried version of `Finset.sum_product`"]
theorem prod_product' {s : Finset γ} {t : Finset α} {f : γ → α → β} :
    ∏ x ∈ s ×ˢ t, f x.1 x.2 = ∏ x ∈ s, ∏ y ∈ t, f x y 
goal: ∏ x ∈ s ×ˢ t, f x.1 x.2 = ∏ x ∈ s, ∏ y ∈ t, f x y

full_name: Finset.sum_product'
code: /-- An uncurried version of `Finset.prod_product`. -/
@[to_additive "An uncurried version of `Finset.sum_product`"]
theorem prod_product' {s : Finset γ} {t : Finset α} {f : γ → α → β} :
    ∏ x ∈ s ×ˢ t, f x.1 x.2 = ∏ x ∈ s, ∏ y ∈ t, f x y 
goal: ∑ x ∈ s ×ˢ t, f x.1 x.2 = ∑ x ∈ s, ∑ y ∈ t, f x y

full_name: Finset.sum_product_right
code: @[to_additive]
theorem prod_product_right {s : Finset γ} {t : Finset α} {f : γ × α → β} :
    ∏ x ∈ s ×ˢ t, f x = ∏ y ∈ t, ∏ x ∈ s, f (x, y) 
goal: ∑ x ∈ s ×ˢ t, f x = ∑ y ∈ t, ∑ x ∈ s, f (x, y)

full_name: Finset.prod_product_right
code: @[to_additive]
theorem prod_product_right {s : Finset γ} {t : Finset α} {f : γ × α → β} :
    ∏ x ∈ s ×ˢ t, f x = ∏ y ∈ t, ∏ x ∈ s, f (x, y) 
goal: ∏ x ∈ s ×ˢ t, f x = ∏ y ∈ t, ∏ x ∈ s, f (x, y)

full_name: Finset.sum_product_right'
code: /-- An uncurried version of `Finset.prod_product_right`. -/
@[to_additive "An uncurried version of `Finset.sum_product_right`"]
theorem prod_product_right' {s : Finset γ} {t : Finset α} {f : γ → α → β} :
    ∏ x ∈ s ×ˢ t, f x.1 x.2 = ∏ y ∈ t, ∏ x ∈ s, f x y 
goal: ∑ x ∈ s ×ˢ t, f x.1 x.2 = ∑ y ∈ t, ∑ x ∈ s, f x y

full_name: Finset.prod_product_right'
code: /-- An uncurried version of `Finset.prod_product_right`. -/
@[to_additive "An uncurried version of `Finset.sum_product_right`"]
theorem prod_product_right' {s : Finset γ} {t : Finset α} {f : γ → α → β} :
    ∏ x ∈ s ×ˢ t, f x.1 x.2 = ∏ y ∈ t, ∏ x ∈ s, f x y 
goal: ∏ x ∈ s ×ˢ t, f x.1 x.2 = ∏ y ∈ t, ∏ x ∈ s, f x y

full_name: Finset.prod_comm'
code: /-- Generalization of `Finset.prod_comm` to the case when the inner `Finset`s depend on the outer
variable. -/
@[to_additive "Generalization of `Finset.sum_comm` to the case when the inner `Finset`s depend on
the outer variable."]
theorem prod_comm' {s : Finset γ} {t : γ → Finset α} {t' : Finset α} {s' : α → Finset γ}
    (h : ∀ x y, x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t') {f : γ → α → β} :
    (∏ x ∈ s, ∏ y ∈ t x, f x y) = ∏ y ∈ t', ∏ x ∈ s' y, f x y 
goal: ∏ x ∈ s, ∏ y ∈ t x, f x y = ∏ y ∈ t', ∏ x ∈ s' y, f x y

full_name: Finset.sum_comm'
code: /-- Generalization of `Finset.prod_comm` to the case when the inner `Finset`s depend on the outer
variable. -/
@[to_additive "Generalization of `Finset.sum_comm` to the case when the inner `Finset`s depend on
the outer variable."]
theorem prod_comm' {s : Finset γ} {t : γ → Finset α} {t' : Finset α} {s' : α → Finset γ}
    (h : ∀ x y, x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t') {f : γ → α → β} :
    (∏ x ∈ s, ∏ y ∈ t x, f x y) = ∏ y ∈ t', ∏ x ∈ s' y, f x y 
goal: ∑ x ∈ s, ∑ y ∈ t x, f x y = ∑ y ∈ t', ∑ x ∈ s' y, f x y

full_name: Finset.sum_comm
code: @[to_additive]
theorem prod_comm {s : Finset γ} {t : Finset α} {f : γ → α → β} :
    (∏ x ∈ s, ∏ y ∈ t, f x y) = ∏ y ∈ t, ∏ x ∈ s, f x y 
goal: ∑ x ∈ s, ∑ y ∈ t, f x y = ∑ y ∈ t, ∑ x ∈ s, f x y

full_name: Finset.prod_comm
code: @[to_additive]
theorem prod_comm {s : Finset γ} {t : Finset α} {f : γ → α → β} :
    (∏ x ∈ s, ∏ y ∈ t, f x y) = ∏ y ∈ t, ∏ x ∈ s, f x y 
goal: ∏ x ∈ s, ∏ y ∈ t, f x y = ∏ y ∈ t, ∏ x ∈ s, f x y

full_name: Finset.sum_hom_rel
code: @[to_additive]
theorem prod_hom_rel [CommMonoid γ] {r : β → γ → Prop} {f : α → β} {g : α → γ} {s : Finset α}
    (h₁ : r 1 1) (h₂ : ∀ a b c, r b c → r (f a * b) (g a * c)) :
    r (∏ x ∈ s, f x) (∏ x ∈ s, g x) 
goal: r (∑ x ∈ s, f x) (∑ x ∈ s, g x)

full_name: Finset.prod_hom_rel
code: @[to_additive]
theorem prod_hom_rel [CommMonoid γ] {r : β → γ → Prop} {f : α → β} {g : α → γ} {s : Finset α}
    (h₁ : r 1 1) (h₂ : ∀ a b c, r b c → r (f a * b) (g a * c)) :
    r (∏ x ∈ s, f x) (∏ x ∈ s, g x) 
goal: r (∏ x ∈ s, f x) (∏ x ∈ s, g x)

full_name: Finset.prod_filter_of_ne
code: @[to_additive]
theorem prod_filter_of_ne {p : α → Prop} [DecidablePred p] (hp : ∀ x ∈ s, f x ≠ 1 → p x) :
    ∏ x ∈ s.filter p, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ Finset.filter p s, f x = ∏ x ∈ s, f x

full_name: Finset.sum_filter_of_ne
code: @[to_additive]
theorem prod_filter_of_ne {p : α → Prop} [DecidablePred p] (hp : ∀ x ∈ s, f x ≠ 1 → p x) :
    ∏ x ∈ s.filter p, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ Finset.filter p s, f x = ∑ x ∈ s, f x

full_name: Finset.prod_filter_ne_one
code: @[to_additive]
theorem prod_filter_ne_one (s : Finset α) [∀ x, Decidable (f x ≠ 1)] :
    ∏ x ∈ s.filter fun x => f x ≠ 1, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ Finset.filter (fun x => f x ≠ 1) s, f x = ∏ x ∈ s, f x

full_name: Finset.sum_filter_ne_zero
code: @[to_additive]
theorem prod_filter_ne_one (s : Finset α) [∀ x, Decidable (f x ≠ 1)] :
    ∏ x ∈ s.filter fun x => f x ≠ 1, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ Finset.filter (fun x => f x ≠ 0) s, f x = ∑ x ∈ s, f x

full_name: Finset.sum_filter
code: @[to_additive]
theorem prod_filter (p : α → Prop) [DecidablePred p] (f : α → β) :
    ∏ a ∈ s.filter p, f a = ∏ a ∈ s, if p a then f a else 1 
goal: ∑ a ∈ Finset.filter p s, f a = ∑ a ∈ s, if p a then f a else 0

full_name: Finset.prod_filter
code: @[to_additive]
theorem prod_filter (p : α → Prop) [DecidablePred p] (f : α → β) :
    ∏ a ∈ s.filter p, f a = ∏ a ∈ s, if p a then f a else 1 
goal: ∏ a ∈ Finset.filter p s, f a = ∏ a ∈ s, if p a then f a else 1

full_name: Finset.sum_eq_single_of_mem
code: @[to_additive]
theorem prod_eq_single_of_mem {s : Finset α} {f : α → β} (a : α) (h : a ∈ s)
    (h₀ : ∀ b ∈ s, b ≠ a → f b = 1) : ∏ x ∈ s, f x = f a 
goal: ∑ x ∈ s, f x = f a

full_name: Finset.prod_eq_single_of_mem
code: @[to_additive]
theorem prod_eq_single_of_mem {s : Finset α} {f : α → β} (a : α) (h : a ∈ s)
    (h₀ : ∀ b ∈ s, b ≠ a → f b = 1) : ∏ x ∈ s, f x = f a 
goal: ∏ x ∈ s, f x = f a

full_name: Finset.sum_eq_single
code: @[to_additive]
theorem prod_eq_single {s : Finset α} {f : α → β} (a : α) (h₀ : ∀ b ∈ s, b ≠ a → f b = 1)
    (h₁ : a ∉ s → f a = 1) : ∏ x ∈ s, f x = f a 
goal: ∑ x ∈ s, f x = f a

full_name: Finset.prod_eq_single
code: @[to_additive]
theorem prod_eq_single {s : Finset α} {f : α → β} (a : α) (h₀ : ∀ b ∈ s, b ≠ a → f b = 1)
    (h₁ : a ∉ s → f a = 1) : ∏ x ∈ s, f x = f a 
goal: ∏ x ∈ s, f x = f a

full_name: Finset.prod_union_eq_left
code: @[to_additive]
lemma prod_union_eq_left [DecidableEq α] (hs : ∀ a ∈ s₂, a ∉ s₁ → f a = 1) :
    ∏ a ∈ s₁ ∪ s₂, f a = ∏ a ∈ s₁, f a 
goal: ∏ a ∈ s₁ ∪ s₂, f a = ∏ a ∈ s₁, f a

full_name: Finset.sum_union_eq_left
code: @[to_additive]
lemma prod_union_eq_left [DecidableEq α] (hs : ∀ a ∈ s₂, a ∉ s₁ → f a = 1) :
    ∏ a ∈ s₁ ∪ s₂, f a = ∏ a ∈ s₁, f a 
goal: ∑ a ∈ s₁ ∪ s₂, f a = ∑ a ∈ s₁, f a

full_name: Finset.prod_union_eq_right
code: @[to_additive]
lemma prod_union_eq_right [DecidableEq α] (hs : ∀ a ∈ s₁, a ∉ s₂ → f a = 1) :
    ∏ a ∈ s₁ ∪ s₂, f a = ∏ a ∈ s₂, f a 
goal: ∏ a ∈ s₁ ∪ s₂, f a = ∏ a ∈ s₂, f a

full_name: Finset.sum_union_eq_right
code: @[to_additive]
lemma prod_union_eq_right [DecidableEq α] (hs : ∀ a ∈ s₁, a ∉ s₂ → f a = 1) :
    ∏ a ∈ s₁ ∪ s₂, f a = ∏ a ∈ s₂, f a 
goal: ∑ a ∈ s₁ ∪ s₂, f a = ∑ a ∈ s₂, f a

full_name: Finset.sum_eq_add_of_mem
code: @[to_additive]
theorem prod_eq_mul_of_mem {s : Finset α} {f : α → β} (a b : α) (ha : a ∈ s) (hb : b ∈ s)
    (hn : a ≠ b) (h₀ : ∀ c ∈ s, c ≠ a ∧ c ≠ b → f c = 1) : ∏ x ∈ s, f x = f a * f b 
goal: ∑ x ∈ s, f x = f a + f b

full_name: Finset.prod_eq_mul_of_mem
code: @[to_additive]
theorem prod_eq_mul_of_mem {s : Finset α} {f : α → β} (a b : α) (ha : a ∈ s) (hb : b ∈ s)
    (hn : a ≠ b) (h₀ : ∀ c ∈ s, c ≠ a ∧ c ≠ b → f c = 1) : ∏ x ∈ s, f x = f a * f b 
goal: ∏ x ∈ s, f x = f a * f b

full_name: Finset.prod_eq_mul
code: @[to_additive]
theorem prod_eq_mul {s : Finset α} {f : α → β} (a b : α) (hn : a ≠ b)
    (h₀ : ∀ c ∈ s, c ≠ a ∧ c ≠ b → f c = 1) (ha : a ∉ s → f a = 1) (hb : b ∉ s → f b = 1) :
    ∏ x ∈ s, f x = f a * f b 
goal: ∏ x ∈ s, f x = f a * f b

full_name: Finset.sum_eq_add
code: @[to_additive]
theorem prod_eq_mul {s : Finset α} {f : α → β} (a b : α) (hn : a ≠ b)
    (h₀ : ∀ c ∈ s, c ≠ a ∧ c ≠ b → f c = 1) (ha : a ∉ s → f a = 1) (hb : b ∉ s → f b = 1) :
    ∏ x ∈ s, f x = f a * f b 
goal: ∑ x ∈ s, f x = f a + f b

full_name: Finset.sum_subtype_eq_sum_filter
code: /-- A product over `s.subtype p` equals one over `s.filter p`. -/
@[to_additive (attr := simp, nolint simpNF)
  "A sum over `s.subtype p` equals one over `s.filter p`."]
theorem prod_subtype_eq_prod_filter (f : α → β) {p : α → Prop} [DecidablePred p] :
    ∏ x ∈ s.subtype p, f x = ∏ x ∈ s.filter p, f x 
goal: ∑ x ∈ Finset.subtype p s, f ↑x = ∑ x ∈ Finset.filter p s, f x

full_name: Finset.prod_subtype_eq_prod_filter
code: /-- A product over `s.subtype p` equals one over `s.filter p`. -/
@[to_additive (attr := simp, nolint simpNF)
  "A sum over `s.subtype p` equals one over `s.filter p`."]
theorem prod_subtype_eq_prod_filter (f : α → β) {p : α → Prop} [DecidablePred p] :
    ∏ x ∈ s.subtype p, f x = ∏ x ∈ s.filter p, f x 
goal: ∏ x ∈ Finset.subtype p s, f ↑x = ∏ x ∈ Finset.filter p s, f x

full_name: Finset.sum_subtype_of_mem
code: /-- If all elements of a `Finset` satisfy the predicate `p`, a product
over `s.subtype p` equals that product over `s`. -/
@[to_additive "If all elements of a `Finset` satisfy the predicate `p`, a sum
over `s.subtype p` equals that sum over `s`."]
theorem prod_subtype_of_mem (f : α → β) {p : α → Prop} [DecidablePred p] (h : ∀ x ∈ s, p x) :
    ∏ x ∈ s.subtype p, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ Finset.subtype p s, f ↑x = ∑ x ∈ s, f x

full_name: Finset.prod_subtype_of_mem
code: /-- If all elements of a `Finset` satisfy the predicate `p`, a product
over `s.subtype p` equals that product over `s`. -/
@[to_additive "If all elements of a `Finset` satisfy the predicate `p`, a sum
over `s.subtype p` equals that sum over `s`."]
theorem prod_subtype_of_mem (f : α → β) {p : α → Prop} [DecidablePred p] (h : ∀ x ∈ s, p x) :
    ∏ x ∈ s.subtype p, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ Finset.subtype p s, f ↑x = ∏ x ∈ s, f x

full_name: Finset.sum_subtype_map_embedding
code: /-- A product of a function over a `Finset` in a subtype equals a
product in the main type of a function that agrees with the first
function on that `Finset`. -/
@[to_additive "A sum of a function over a `Finset` in a subtype equals a
sum in the main type of a function that agrees with the first
function on that `Finset`."]
theorem prod_subtype_map_embedding {p : α → Prop} {s : Finset { x // p x }} {f : { x // p x } → β}
    {g : α → β} (h : ∀ x : { x // p x }, x ∈ s → g x = f x) :
    (∏ x ∈ s.map (Function.Embedding.subtype _), g x) = ∏ x ∈ s, f x 
goal: ∑ x ∈ Finset.map (Function.Embedding.subtype fun x => p x) s, g x = ∑ x ∈ s, f x

full_name: Finset.prod_subtype_map_embedding
code: /-- A product of a function over a `Finset` in a subtype equals a
product in the main type of a function that agrees with the first
function on that `Finset`. -/
@[to_additive "A sum of a function over a `Finset` in a subtype equals a
sum in the main type of a function that agrees with the first
function on that `Finset`."]
theorem prod_subtype_map_embedding {p : α → Prop} {s : Finset { x // p x }} {f : { x // p x } → β}
    {g : α → β} (h : ∀ x : { x // p x }, x ∈ s → g x = f x) :
    (∏ x ∈ s.map (Function.Embedding.subtype _), g x) = ∏ x ∈ s, f x 
goal: ∏ x ∈ Finset.map (Function.Embedding.subtype fun x => p x) s, g x = ∏ x ∈ s, f x

full_name: Finset.prod_coe_sort_eq_attach
code: @[to_additive]
theorem prod_coe_sort_eq_attach (f : s → β) : ∏ i : s, f i = ∏ i ∈ s.attach, f i 
goal: ∏ i : { x // x ∈ s }, f i = ∏ i ∈ s.attach, f i

full_name: Finset.sum_coe_sort_eq_attach
code: @[to_additive]
theorem prod_coe_sort_eq_attach (f : s → β) : ∏ i : s, f i = ∏ i ∈ s.attach, f i 
goal: ∑ i : { x // x ∈ s }, f i = ∑ i ∈ s.attach, f i

full_name: Finset.sum_coe_sort
code: @[to_additive]
theorem prod_coe_sort : ∏ i : s, f i = ∏ i ∈ s, f i 
goal: ∑ i : { x // x ∈ s }, f ↑i = ∑ i ∈ s, f i

full_name: Finset.prod_coe_sort
code: @[to_additive]
theorem prod_coe_sort : ∏ i : s, f i = ∏ i ∈ s, f i 
goal: ∏ i : { x // x ∈ s }, f ↑i = ∏ i ∈ s, f i

full_name: Finset.sum_finset_coe
code: @[to_additive]
theorem prod_finset_coe (f : α → β) (s : Finset α) : (∏ i : (s : Set α), f i) = ∏ i ∈ s, f i 
goal: ∑ i : ↑↑s, f ↑i = ∑ i ∈ s, f i

full_name: Finset.prod_finset_coe
code: @[to_additive]
theorem prod_finset_coe (f : α → β) (s : Finset α) : (∏ i : (s : Set α), f i) = ∏ i ∈ s, f i 
goal: ∏ i : ↑↑s, f ↑i = ∏ i ∈ s, f i

full_name: Finset.prod_subtype
code: @[to_additive]
theorem prod_subtype {p : α → Prop} {F : Fintype (Subtype p)} (s : Finset α) (h : ∀ x, x ∈ s ↔ p x)
    (f : α → β) : ∏ a ∈ s, f a = ∏ a : Subtype p, f a 
goal: ∏ a ∈ s, f a = ∏ a : Subtype p, f ↑a

full_name: Finset.sum_subtype
code: @[to_additive]
theorem prod_subtype {p : α → Prop} {F : Fintype (Subtype p)} (s : Finset α) (h : ∀ x, x ∈ s ↔ p x)
    (f : α → β) : ∏ a ∈ s, f a = ∏ a : Subtype p, f a 
goal: ∑ a ∈ s, f a = ∑ a : Subtype p, f ↑a

full_name: Finset.sum_preimage'
code: @[to_additive]
lemma prod_preimage' (f : ι → κ) [DecidablePred (· ∈ Set.range f)] (s : Finset κ) (hf) (g : κ → β) :
    ∏ x ∈ s.preimage f hf, g (f x) = ∏ x ∈ s.filter (· ∈ Set.range f), g x 
goal: ∑ x ∈ s.preimage f hf, g (f x) = ∑ x ∈ Finset.filter (fun x => x ∈ Set.range f) s, g x

full_name: Finset.prod_preimage'
code: @[to_additive]
lemma prod_preimage' (f : ι → κ) [DecidablePred (· ∈ Set.range f)] (s : Finset κ) (hf) (g : κ → β) :
    ∏ x ∈ s.preimage f hf, g (f x) = ∏ x ∈ s.filter (· ∈ Set.range f), g x 
goal: ∏ x ∈ s.preimage f hf, g (f x) = ∏ x ∈ Finset.filter (fun x => x ∈ Set.range f) s, g x

full_name: Finset.sum_preimage
code: @[to_additive]
lemma prod_preimage (f : ι → κ) (s : Finset κ) (hf) (g : κ → β)
    (hg : ∀ x ∈ s, x ∉ Set.range f → g x = 1) :
    ∏ x ∈ s.preimage f hf, g (f x) = ∏ x ∈ s, g x 
goal: ∑ x ∈ s.preimage f hf, g (f x) = ∑ x ∈ s, g x

full_name: Finset.prod_preimage
code: @[to_additive]
lemma prod_preimage (f : ι → κ) (s : Finset κ) (hf) (g : κ → β)
    (hg : ∀ x ∈ s, x ∉ Set.range f → g x = 1) :
    ∏ x ∈ s.preimage f hf, g (f x) = ∏ x ∈ s, g x 
goal: ∏ x ∈ s.preimage f hf, g (f x) = ∏ x ∈ s, g x

full_name: Finset.prod_preimage_of_bij
code: @[to_additive]
lemma prod_preimage_of_bij (f : ι → κ) (s : Finset κ) (hf : Set.BijOn f (f ⁻¹' ↑s) ↑s) (g : κ → β) :
    ∏ x ∈ s.preimage f hf.injOn, g (f x) = ∏ x ∈ s, g x 
goal: ∏ x ∈ s.preimage f ⋯, g (f x) = ∏ x ∈ s, g x

full_name: Finset.sum_preimage_of_bij
code: @[to_additive]
lemma prod_preimage_of_bij (f : ι → κ) (s : Finset κ) (hf : Set.BijOn f (f ⁻¹' ↑s) ↑s) (g : κ → β) :
    ∏ x ∈ s.preimage f hf.injOn, g (f x) = ∏ x ∈ s, g x 
goal: ∑ x ∈ s.preimage f ⋯, g (f x) = ∑ x ∈ s, g x

full_name: Finset.sum_set_coe
code: @[to_additive]
theorem prod_set_coe (s : Set α) [Fintype s] : (∏ i : s, f i) = ∏ i ∈ s.toFinset, f i 
goal: ∑ i : ↑s, f ↑i = ∑ i ∈ s.toFinset, f i

full_name: Finset.prod_set_coe
code: @[to_additive]
theorem prod_set_coe (s : Set α) [Fintype s] : (∏ i : s, f i) = ∏ i ∈ s.toFinset, f i 
goal: ∏ i : ↑s, f ↑i = ∏ i ∈ s.toFinset, f i

full_name: Finset.sum_congr_set
code: /-- The product of a function `g` defined only on a set `s` is equal to
the product of a function `f` defined everywhere,
as long as `f` and `g` agree on `s`, and `f = 1` off `s`. -/
@[to_additive "The sum of a function `g` defined only on a set `s` is equal to
the sum of a function `f` defined everywhere,
as long as `f` and `g` agree on `s`, and `f = 0` off `s`."]
theorem prod_congr_set {α : Type*} [CommMonoid α] {β : Type*} [Fintype β] (s : Set β)
    [DecidablePred (· ∈ s)] (f : β → α) (g : s → α) (w : ∀ (x : β) (h : x ∈ s), f x = g ⟨x, h⟩)
    (w' : ∀ x : β, x ∉ s → f x = 1) : Finset.univ.prod f = Finset.univ.prod g 
goal: Finset.univ.sum f = Finset.univ.sum g

full_name: Finset.prod_congr_set
code: /-- The product of a function `g` defined only on a set `s` is equal to
the product of a function `f` defined everywhere,
as long as `f` and `g` agree on `s`, and `f = 1` off `s`. -/
@[to_additive "The sum of a function `g` defined only on a set `s` is equal to
the sum of a function `f` defined everywhere,
as long as `f` and `g` agree on `s`, and `f = 0` off `s`."]
theorem prod_congr_set {α : Type*} [CommMonoid α] {β : Type*} [Fintype β] (s : Set β)
    [DecidablePred (· ∈ s)] (f : β → α) (g : s → α) (w : ∀ (x : β) (h : x ∈ s), f x = g ⟨x, h⟩)
    (w' : ∀ x : β, x ∉ s → f x = 1) : Finset.univ.prod f = Finset.univ.prod g 
goal: Finset.univ.prod f = Finset.univ.prod g

full_name: Finset.prod_apply_dite
code: @[to_additive]
theorem prod_apply_dite {s : Finset α} {p : α → Prop} {hp : DecidablePred p}
    [DecidablePred fun x => ¬p x] (f : ∀ x : α, p x → γ) (g : ∀ x : α, ¬p x → γ) (h : γ → β) :
    (∏ x ∈ s, h (if hx : p x then f x hx else g x hx)) =
      (∏ x ∈ (s.filter p).attach, h (f x.1 <| by simpa using (mem_filter.mp x.2).2)) *
        ∏ x ∈ (s.filter fun x => ¬p x).attach, h (g x.1 <| by simpa using (mem_filter.mp x.2).2) 
goal: ∏ x ∈ s, h (if hx : p x then f x hx else g x hx) =
  (∏ x ∈ (Finset.filter p s).attach, h (f ↑x ⋯)) * ∏ x ∈ (Finset.filter (fun x => ¬p x) s).attach, h (g ↑x ⋯)

full_name: Finset.sum_apply_dite
code: @[to_additive]
theorem prod_apply_dite {s : Finset α} {p : α → Prop} {hp : DecidablePred p}
    [DecidablePred fun x => ¬p x] (f : ∀ x : α, p x → γ) (g : ∀ x : α, ¬p x → γ) (h : γ → β) :
    (∏ x ∈ s, h (if hx : p x then f x hx else g x hx)) =
      (∏ x ∈ (s.filter p).attach, h (f x.1 <| by simpa using (mem_filter.mp x.2).2)) *
        ∏ x ∈ (s.filter fun x => ¬p x).attach, h (g x.1 <| by simpa using (mem_filter.mp x.2).2) 
goal: ∑ x ∈ s, h (if hx : p x then f x hx else g x hx) =
  ∑ x ∈ (Finset.filter p s).attach, h (f ↑x ⋯) + ∑ x ∈ (Finset.filter (fun x => ¬p x) s).attach, h (g ↑x ⋯)

full_name: Finset.prod_apply_ite
code: @[to_additive]
theorem prod_apply_ite {s : Finset α} {p : α → Prop} {_hp : DecidablePred p} (f g : α → γ)
    (h : γ → β) :
    (∏ x ∈ s, h (if p x then f x else g x)) =
      (∏ x ∈ s.filter p, h (f x)) * ∏ x ∈ s.filter fun x => ¬p x, h (g x) 
goal: ∏ x ∈ s, h (if p x then f x else g x) =
  (∏ x ∈ Finset.filter p s, h (f x)) * ∏ x ∈ Finset.filter (fun x => ¬p x) s, h (g x)

full_name: Finset.sum_apply_ite
code: @[to_additive]
theorem prod_apply_ite {s : Finset α} {p : α → Prop} {_hp : DecidablePred p} (f g : α → γ)
    (h : γ → β) :
    (∏ x ∈ s, h (if p x then f x else g x)) =
      (∏ x ∈ s.filter p, h (f x)) * ∏ x ∈ s.filter fun x => ¬p x, h (g x) 
goal: ∑ x ∈ s, h (if p x then f x else g x) =
  ∑ x ∈ Finset.filter p s, h (f x) + ∑ x ∈ Finset.filter (fun x => ¬p x) s, h (g x)

full_name: Finset.prod_dite
code: @[to_additive]
theorem prod_dite {s : Finset α} {p : α → Prop} {hp : DecidablePred p} (f : ∀ x : α, p x → β)
    (g : ∀ x : α, ¬p x → β) :
    ∏ x ∈ s, (if hx : p x then f x hx else g x hx) =
      (∏ x ∈ (s.filter p).attach, f x.1 (by simpa using (mem_filter.mp x.2).2)) *
        ∏ x ∈ (s.filter fun x => ¬p x).attach, g x.1 (by simpa using (mem_filter.mp x.2).2) 
goal: (∏ x ∈ s, if hx : p x then f x hx else g x hx) =
  (∏ x ∈ (Finset.filter p s).attach, f ↑x ⋯) * ∏ x ∈ (Finset.filter (fun x => ¬p x) s).attach, g ↑x ⋯

full_name: Finset.sum_dite
code: @[to_additive]
theorem prod_dite {s : Finset α} {p : α → Prop} {hp : DecidablePred p} (f : ∀ x : α, p x → β)
    (g : ∀ x : α, ¬p x → β) :
    ∏ x ∈ s, (if hx : p x then f x hx else g x hx) =
      (∏ x ∈ (s.filter p).attach, f x.1 (by simpa using (mem_filter.mp x.2).2)) *
        ∏ x ∈ (s.filter fun x => ¬p x).attach, g x.1 (by simpa using (mem_filter.mp x.2).2) 
goal: (∑ x ∈ s, if hx : p x then f x hx else g x hx) =
  ∑ x ∈ (Finset.filter p s).attach, f ↑x ⋯ + ∑ x ∈ (Finset.filter (fun x => ¬p x) s).attach, g ↑x ⋯

full_name: Finset.sum_ite
code: @[to_additive]
theorem prod_ite {s : Finset α} {p : α → Prop} {hp : DecidablePred p} (f g : α → β) :
    ∏ x ∈ s, (if p x then f x else g x) =
      (∏ x ∈ s.filter p, f x) * ∏ x ∈ s.filter fun x => ¬p x, g x 
goal: (∑ x ∈ s, if p x then f x else g x) = ∑ x ∈ Finset.filter p s, f x + ∑ x ∈ Finset.filter (fun x => ¬p x) s, g x

full_name: Finset.prod_ite
code: @[to_additive]
theorem prod_ite {s : Finset α} {p : α → Prop} {hp : DecidablePred p} (f g : α → β) :
    ∏ x ∈ s, (if p x then f x else g x) =
      (∏ x ∈ s.filter p, f x) * ∏ x ∈ s.filter fun x => ¬p x, g x 
goal: (∏ x ∈ s, if p x then f x else g x) = (∏ x ∈ Finset.filter p s, f x) * ∏ x ∈ Finset.filter (fun x => ¬p x) s, g x

full_name: Finset.sum_dite_of_false
code: @[to_additive]
lemma prod_dite_of_false {p : α → Prop} {_ : DecidablePred p} (h : ∀ i ∈ s, ¬ p i)
    (f : ∀ i, p i → β) (g : ∀ i, ¬ p i → β) :
    ∏ i ∈ s, (if hi : p i then f i hi else g i hi) = ∏ i : s, g i.1 (h _ i.2) 
goal: ∀ {x : DecidablePred p} (h : ∀ i ∈ s, ¬p i) (f : (i : α) → p i → β) (g : (i : α) → ¬p i → β),
  (∑ i ∈ s, if hi : p i then f i hi else g i hi) = ∑ i : { x // x ∈ s }, g ↑i ⋯

full_name: Finset.prod_dite_of_false
code: @[to_additive]
lemma prod_dite_of_false {p : α → Prop} {_ : DecidablePred p} (h : ∀ i ∈ s, ¬ p i)
    (f : ∀ i, p i → β) (g : ∀ i, ¬ p i → β) :
    ∏ i ∈ s, (if hi : p i then f i hi else g i hi) = ∏ i : s, g i.1 (h _ i.2) 
goal: ∀ {x : DecidablePred p} (h : ∀ i ∈ s, ¬p i) (f : (i : α) → p i → β) (g : (i : α) → ¬p i → β),
  (∏ i ∈ s, if hi : p i then f i hi else g i hi) = ∏ i : { x // x ∈ s }, g ↑i ⋯

full_name: Finset.prod_ite_of_false
code: @[to_additive]
lemma prod_ite_of_false {p : α → Prop} {_ : DecidablePred p} (h : ∀ x ∈ s, ¬p x) (f g : α → β) :
    ∏ x ∈ s, (if p x then f x else g x) = ∏ x ∈ s, g x 
goal: ∀ {x : DecidablePred p}, (∀ x ∈ s, ¬p x) → ∀ (f g : α → β), (∏ x_1 ∈ s, if p x_1 then f x_1 else g x_1) = ∏ x ∈ s, g x

full_name: Finset.sum_ite_of_false
code: @[to_additive]
lemma prod_ite_of_false {p : α → Prop} {_ : DecidablePred p} (h : ∀ x ∈ s, ¬p x) (f g : α → β) :
    ∏ x ∈ s, (if p x then f x else g x) = ∏ x ∈ s, g x 
goal: ∀ {x : DecidablePred p}, (∀ x ∈ s, ¬p x) → ∀ (f g : α → β), (∑ x_1 ∈ s, if p x_1 then f x_1 else g x_1) = ∑ x ∈ s, g x

full_name: Finset.sum_dite_of_true
code: @[to_additive]
lemma prod_dite_of_true {p : α → Prop} {_ : DecidablePred p} (h : ∀ i ∈ s, p i) (f : ∀ i, p i → β)
    (g : ∀ i, ¬ p i → β) :
    ∏ i ∈ s, (if hi : p i then f i hi else g i hi) = ∏ i : s, f i.1 (h _ i.2) 
goal: ∀ {x : DecidablePred p} (h : ∀ i ∈ s, p i) (f : (i : α) → p i → β) (g : (i : α) → ¬p i → β),
  (∑ i ∈ s, if hi : p i then f i hi else g i hi) = ∑ i : { x // x ∈ s }, f ↑i ⋯

full_name: Finset.prod_dite_of_true
code: @[to_additive]
lemma prod_dite_of_true {p : α → Prop} {_ : DecidablePred p} (h : ∀ i ∈ s, p i) (f : ∀ i, p i → β)
    (g : ∀ i, ¬ p i → β) :
    ∏ i ∈ s, (if hi : p i then f i hi else g i hi) = ∏ i : s, f i.1 (h _ i.2) 
goal: ∀ {x : DecidablePred p} (h : ∀ i ∈ s, p i) (f : (i : α) → p i → β) (g : (i : α) → ¬p i → β),
  (∏ i ∈ s, if hi : p i then f i hi else g i hi) = ∏ i : { x // x ∈ s }, f ↑i ⋯

full_name: Finset.prod_ite_of_true
code: @[to_additive]
lemma prod_ite_of_true {p : α → Prop} {_ : DecidablePred p} (h : ∀ x ∈ s, p x) (f g : α → β) :
    ∏ x ∈ s, (if p x then f x else g x) = ∏ x ∈ s, f x 
goal: ∀ {x : DecidablePred p}, (∀ x ∈ s, p x) → ∀ (f g : α → β), (∏ x_1 ∈ s, if p x_1 then f x_1 else g x_1) = ∏ x ∈ s, f x

full_name: Finset.sum_ite_of_true
code: @[to_additive]
lemma prod_ite_of_true {p : α → Prop} {_ : DecidablePred p} (h : ∀ x ∈ s, p x) (f g : α → β) :
    ∏ x ∈ s, (if p x then f x else g x) = ∏ x ∈ s, f x 
goal: ∀ {x : DecidablePred p}, (∀ x ∈ s, p x) → ∀ (f g : α → β), (∑ x_1 ∈ s, if p x_1 then f x_1 else g x_1) = ∑ x ∈ s, f x

full_name: Finset.prod_apply_ite_of_false
code: @[to_additive]
theorem prod_apply_ite_of_false {p : α → Prop} {hp : DecidablePred p} (f g : α → γ) (k : γ → β)
    (h : ∀ x ∈ s, ¬p x) : (∏ x ∈ s, k (if p x then f x else g x)) = ∏ x ∈ s, k (g x) 
goal: ∏ x ∈ s, k (if p x then f x else g x) = ∏ x ∈ s, k (g x)

full_name: Finset.sum_apply_ite_of_false
code: @[to_additive]
theorem prod_apply_ite_of_false {p : α → Prop} {hp : DecidablePred p} (f g : α → γ) (k : γ → β)
    (h : ∀ x ∈ s, ¬p x) : (∏ x ∈ s, k (if p x then f x else g x)) = ∏ x ∈ s, k (g x) 
goal: ∑ x ∈ s, k (if p x then f x else g x) = ∑ x ∈ s, k (g x)

full_name: Finset.prod_apply_ite_of_true
code: @[to_additive]
theorem prod_apply_ite_of_true {p : α → Prop} {hp : DecidablePred p} (f g : α → γ) (k : γ → β)
    (h : ∀ x ∈ s, p x) : (∏ x ∈ s, k (if p x then f x else g x)) = ∏ x ∈ s, k (f x) 
goal: ∏ x ∈ s, k (if p x then f x else g x) = ∏ x ∈ s, k (f x)

full_name: Finset.sum_apply_ite_of_true
code: @[to_additive]
theorem prod_apply_ite_of_true {p : α → Prop} {hp : DecidablePred p} (f g : α → γ) (k : γ → β)
    (h : ∀ x ∈ s, p x) : (∏ x ∈ s, k (if p x then f x else g x)) = ∏ x ∈ s, k (f x) 
goal: ∑ x ∈ s, k (if p x then f x else g x) = ∑ x ∈ s, k (f x)

full_name: Finset.prod_extend_by_one
code: @[to_additive]
theorem prod_extend_by_one [DecidableEq α] (s : Finset α) (f : α → β) :
    ∏ i ∈ s, (if i ∈ s then f i else 1) = ∏ i ∈ s, f i 
goal: (∏ i ∈ s, if i ∈ s then f i else 1) = ∏ i ∈ s, f i

full_name: Finset.sum_extend_by_zero
code: @[to_additive]
theorem prod_extend_by_one [DecidableEq α] (s : Finset α) (f : α → β) :
    ∏ i ∈ s, (if i ∈ s then f i else 1) = ∏ i ∈ s, f i 
goal: (∑ i ∈ s, if i ∈ s then f i else 0) = ∑ i ∈ s, f i

full_name: Finset.prod_ite_mem
code: @[to_additive (attr := simp)]
theorem prod_ite_mem [DecidableEq α] (s t : Finset α) (f : α → β) :
    ∏ i ∈ s, (if i ∈ t then f i else 1) = ∏ i ∈ s ∩ t, f i 
goal: (∏ i ∈ s, if i ∈ t then f i else 1) = ∏ i ∈ s ∩ t, f i

full_name: Finset.sum_ite_mem
code: @[to_additive (attr := simp)]
theorem prod_ite_mem [DecidableEq α] (s t : Finset α) (f : α → β) :
    ∏ i ∈ s, (if i ∈ t then f i else 1) = ∏ i ∈ s ∩ t, f i 
goal: (∑ i ∈ s, if i ∈ t then f i else 0) = ∑ i ∈ s ∩ t, f i

full_name: Finset.prod_dite_eq
code: @[to_additive (attr := simp)]
theorem prod_dite_eq [DecidableEq α] (s : Finset α) (a : α) (b : ∀ x : α, a = x → β) :
    ∏ x ∈ s, (if h : a = x then b x h else 1) = ite (a ∈ s) (b a rfl) 1 
goal: (∏ x ∈ s, if h : a = x then b x h else 1) = if a ∈ s then b a ⋯ else 1

full_name: Finset.sum_dite_eq
code: @[to_additive (attr := simp)]
theorem prod_dite_eq [DecidableEq α] (s : Finset α) (a : α) (b : ∀ x : α, a = x → β) :
    ∏ x ∈ s, (if h : a = x then b x h else 1) = ite (a ∈ s) (b a rfl) 1 
goal: (∑ x ∈ s, if h : a = x then b x h else 0) = if a ∈ s then b a ⋯ else 0

full_name: Finset.sum_dite_eq'
code: @[to_additive (attr := simp)]
theorem prod_dite_eq' [DecidableEq α] (s : Finset α) (a : α) (b : ∀ x : α, x = a → β) :
    ∏ x ∈ s, (if h : x = a then b x h else 1) = ite (a ∈ s) (b a rfl) 1 
goal: (∑ x ∈ s, if h : x = a then b x h else 0) = if a ∈ s then b a ⋯ else 0

full_name: Finset.prod_dite_eq'
code: @[to_additive (attr := simp)]
theorem prod_dite_eq' [DecidableEq α] (s : Finset α) (a : α) (b : ∀ x : α, x = a → β) :
    ∏ x ∈ s, (if h : x = a then b x h else 1) = ite (a ∈ s) (b a rfl) 1 
goal: (∏ x ∈ s, if h : x = a then b x h else 1) = if a ∈ s then b a ⋯ else 1

full_name: Finset.prod_ite_eq
code: @[to_additive (attr := simp)]
theorem prod_ite_eq [DecidableEq α] (s : Finset α) (a : α) (b : α → β) :
    (∏ x ∈ s, ite (a = x) (b x) 1) = ite (a ∈ s) (b a) 1 
goal: (∏ x ∈ s, if a = x then b x else 1) = if a ∈ s then b a else 1

full_name: Finset.sum_ite_eq
code: @[to_additive (attr := simp)]
theorem prod_ite_eq [DecidableEq α] (s : Finset α) (a : α) (b : α → β) :
    (∏ x ∈ s, ite (a = x) (b x) 1) = ite (a ∈ s) (b a) 1 
goal: (∑ x ∈ s, if a = x then b x else 0) = if a ∈ s then b a else 0

full_name: Finset.sum_ite_eq'
code: /-- A product taken over a conditional whose condition is an equality test on the index and whose
alternative is `1` has value either the term at that index or `1`.

The difference with `Finset.prod_ite_eq` is that the arguments to `Eq` are swapped. -/
@[to_additive (attr := simp) "A sum taken over a conditional whose condition is an equality
test on the index and whose alternative is `0` has value either the term at that index or `0`.

The difference with `Finset.sum_ite_eq` is that the arguments to `Eq` are swapped."]
theorem prod_ite_eq' [DecidableEq α] (s : Finset α) (a : α) (b : α → β) :
    (∏ x ∈ s, ite (x = a) (b x) 1) = ite (a ∈ s) (b a) 1 
goal: (∑ x ∈ s, if x = a then b x else 0) = if a ∈ s then b a else 0

full_name: Finset.prod_ite_eq'
code: /-- A product taken over a conditional whose condition is an equality test on the index and whose
alternative is `1` has value either the term at that index or `1`.

The difference with `Finset.prod_ite_eq` is that the arguments to `Eq` are swapped. -/
@[to_additive (attr := simp) "A sum taken over a conditional whose condition is an equality
test on the index and whose alternative is `0` has value either the term at that index or `0`.

The difference with `Finset.sum_ite_eq` is that the arguments to `Eq` are swapped."]
theorem prod_ite_eq' [DecidableEq α] (s : Finset α) (a : α) (b : α → β) :
    (∏ x ∈ s, ite (x = a) (b x) 1) = ite (a ∈ s) (b a) 1 
goal: (∏ x ∈ s, if x = a then b x else 1) = if a ∈ s then b a else 1

full_name: Finset.sum_ite_index
code: @[to_additive]
theorem prod_ite_index (p : Prop) [Decidable p] (s t : Finset α) (f : α → β) :
    ∏ x ∈ if p then s else t, f x = if p then ∏ x ∈ s, f x else ∏ x ∈ t, f x 
goal: ∑ x ∈ if p then s else t, f x = if p then ∑ x ∈ s, f x else ∑ x ∈ t, f x

full_name: Finset.prod_ite_index
code: @[to_additive]
theorem prod_ite_index (p : Prop) [Decidable p] (s t : Finset α) (f : α → β) :
    ∏ x ∈ if p then s else t, f x = if p then ∏ x ∈ s, f x else ∏ x ∈ t, f x 
goal: ∏ x ∈ if p then s else t, f x = if p then ∏ x ∈ s, f x else ∏ x ∈ t, f x

full_name: Finset.sum_ite_irrel
code: @[to_additive (attr := simp)]
theorem prod_ite_irrel (p : Prop) [Decidable p] (s : Finset α) (f g : α → β) :
    ∏ x ∈ s, (if p then f x else g x) = if p then ∏ x ∈ s, f x else ∏ x ∈ s, g x 
goal: (∑ x ∈ s, if p then f x else g x) = if p then ∑ x ∈ s, f x else ∑ x ∈ s, g x

full_name: Finset.prod_ite_irrel
code: @[to_additive (attr := simp)]
theorem prod_ite_irrel (p : Prop) [Decidable p] (s : Finset α) (f g : α → β) :
    ∏ x ∈ s, (if p then f x else g x) = if p then ∏ x ∈ s, f x else ∏ x ∈ s, g x 
goal: (∏ x ∈ s, if p then f x else g x) = if p then ∏ x ∈ s, f x else ∏ x ∈ s, g x

full_name: Finset.sum_dite_irrel
code: @[to_additive (attr := simp)]
theorem prod_dite_irrel (p : Prop) [Decidable p] (s : Finset α) (f : p → α → β) (g : ¬p → α → β) :
    ∏ x ∈ s, (if h : p then f h x else g h x) =
      if h : p then ∏ x ∈ s, f h x else ∏ x ∈ s, g h x 
goal: (∑ x ∈ s, if h : p then f h x else g h x) = if h : p then ∑ x ∈ s, f h x else ∑ x ∈ s, g h x

full_name: Finset.prod_dite_irrel
code: @[to_additive (attr := simp)]
theorem prod_dite_irrel (p : Prop) [Decidable p] (s : Finset α) (f : p → α → β) (g : ¬p → α → β) :
    ∏ x ∈ s, (if h : p then f h x else g h x) =
      if h : p then ∏ x ∈ s, f h x else ∏ x ∈ s, g h x 
goal: (∏ x ∈ s, if h : p then f h x else g h x) = if h : p then ∏ x ∈ s, f h x else ∏ x ∈ s, g h x

full_name: Finset.sum_pi_single'
code: @[to_additive (attr := simp)]
theorem prod_pi_mulSingle' [DecidableEq α] (a : α) (x : β) (s : Finset α) :
    ∏ a' ∈ s, Pi.mulSingle a x a' = if a ∈ s then x else 1 
goal: ∑ a' ∈ s, Pi.single a x a' = if a ∈ s then x else 0

full_name: Finset.prod_pi_mulSingle'
code: @[to_additive (attr := simp)]
theorem prod_pi_mulSingle' [DecidableEq α] (a : α) (x : β) (s : Finset α) :
    ∏ a' ∈ s, Pi.mulSingle a x a' = if a ∈ s then x else 1 
goal: ∏ a' ∈ s, Pi.mulSingle a x a' = if a ∈ s then x else 1

full_name: Finset.sum_pi_single
code: @[to_additive (attr := simp)]
theorem prod_pi_mulSingle {β : α → Type*} [DecidableEq α] [∀ a, CommMonoid (β a)] (a : α)
    (f : ∀ a, β a) (s : Finset α) :
    (∏ a' ∈ s, Pi.mulSingle a' (f a') a) = if a ∈ s then f a else 1 
goal: ∑ a' ∈ s, Pi.single a' (f a') a = if a ∈ s then f a else 0

full_name: Finset.prod_pi_mulSingle
code: @[to_additive (attr := simp)]
theorem prod_pi_mulSingle {β : α → Type*} [DecidableEq α] [∀ a, CommMonoid (β a)] (a : α)
    (f : ∀ a, β a) (s : Finset α) :
    (∏ a' ∈ s, Pi.mulSingle a' (f a') a) = if a ∈ s then f a else 1 
goal: ∏ a' ∈ s, Pi.mulSingle a' (f a') a = if a ∈ s then f a else 1

full_name: Finset.mulSupport_prod
code: @[to_additive]
lemma mulSupport_prod (s : Finset ι) (f : ι → α → β) :
    mulSupport (fun x ↦ ∏ i ∈ s, f i x) ⊆ ⋃ i ∈ s, mulSupport (f i) 
goal: (Function.mulSupport fun x => ∏ i ∈ s, f i x) ⊆ ⋃ i ∈ s, Function.mulSupport (f i)

full_name: Finset.support_sum
code: @[to_additive]
lemma mulSupport_prod (s : Finset ι) (f : ι → α → β) :
    mulSupport (fun x ↦ ∏ i ∈ s, f i x) ⊆ ⋃ i ∈ s, mulSupport (f i) 
goal: (Function.support fun x => ∑ i ∈ s, f i x) ⊆ ⋃ i ∈ s, Function.support (f i)

full_name: Finset.prod_mulIndicator_subset_of_eq_one
code: /-- Consider a product of `g i (f i)` over a finset.  Suppose `g` is a function such as
`n ↦ (· ^ n)`, which maps a second argument of `1` to `1`. Then if `f` is replaced by the
corresponding multiplicative indicator function, the finset may be replaced by a possibly larger
finset without changing the value of the product. -/
@[to_additive "Consider a sum of `g i (f i)` over a finset.  Suppose `g` is a function such as
`n ↦ (n • ·)`, which maps a second argument of `0` to `0` (or a weighted sum of `f i * h i` or
`f i • h i`, where `f` gives the weights that are multiplied by some other function `h`). Then if
`f` is replaced by the corresponding indicator function, the finset may be replaced by a possibly
larger finset without changing the value of the sum."]
lemma prod_mulIndicator_subset_of_eq_one [One α] (f : ι → α) (g : ι → α → β) {s t : Finset ι}
    (h : s ⊆ t) (hg : ∀ a, g a 1 = 1) :
    ∏ i ∈ t, g i (mulIndicator ↑s f i) = ∏ i ∈ s, g i (f i) 
goal: ∏ i ∈ t, g i ((↑s).mulIndicator f i) = ∏ i ∈ s, g i (f i)

full_name: Finset.sum_indicator_subset_of_eq_zero
code: /-- Consider a product of `g i (f i)` over a finset.  Suppose `g` is a function such as
`n ↦ (· ^ n)`, which maps a second argument of `1` to `1`. Then if `f` is replaced by the
corresponding multiplicative indicator function, the finset may be replaced by a possibly larger
finset without changing the value of the product. -/
@[to_additive "Consider a sum of `g i (f i)` over a finset.  Suppose `g` is a function such as
`n ↦ (n • ·)`, which maps a second argument of `0` to `0` (or a weighted sum of `f i * h i` or
`f i • h i`, where `f` gives the weights that are multiplied by some other function `h`). Then if
`f` is replaced by the corresponding indicator function, the finset may be replaced by a possibly
larger finset without changing the value of the sum."]
lemma prod_mulIndicator_subset_of_eq_one [One α] (f : ι → α) (g : ι → α → β) {s t : Finset ι}
    (h : s ⊆ t) (hg : ∀ a, g a 1 = 1) :
    ∏ i ∈ t, g i (mulIndicator ↑s f i) = ∏ i ∈ s, g i (f i) 
goal: ∑ i ∈ t, g i ((↑s).indicator f i) = ∑ i ∈ s, g i (f i)

full_name: Finset.prod_mulIndicator_subset
code: /-- Taking the product of an indicator function over a possibly larger finset is the same as
taking the original function over the original finset. -/
@[to_additive "Summing an indicator function over a possibly larger `Finset` is the same as summing
  the original function over the original finset."]
lemma prod_mulIndicator_subset (f : ι → β) {s t : Finset ι} (h : s ⊆ t) :
    ∏ i ∈ t, mulIndicator (↑s) f i = ∏ i ∈ s, f i 
goal: ∏ i ∈ t, (↑s).mulIndicator f i = ∏ i ∈ s, f i

full_name: Finset.sum_indicator_subset
code: /-- Taking the product of an indicator function over a possibly larger finset is the same as
taking the original function over the original finset. -/
@[to_additive "Summing an indicator function over a possibly larger `Finset` is the same as summing
  the original function over the original finset."]
lemma prod_mulIndicator_subset (f : ι → β) {s t : Finset ι} (h : s ⊆ t) :
    ∏ i ∈ t, mulIndicator (↑s) f i = ∏ i ∈ s, f i 
goal: ∑ i ∈ t, (↑s).indicator f i = ∑ i ∈ s, f i

full_name: Finset.sum_indicator_eq_sum_filter
code: @[to_additive]
lemma prod_mulIndicator_eq_prod_filter (s : Finset ι) (f : ι → κ → β) (t : ι → Set κ) (g : ι → κ)
    [DecidablePred fun i ↦ g i ∈ t i] :
    ∏ i ∈ s, mulIndicator (t i) (f i) (g i) = ∏ i ∈ s.filter fun i ↦ g i ∈ t i, f i (g i) 
goal: ∑ i ∈ s, (t i).indicator (f i) (g i) = ∑ i ∈ Finset.filter (fun i => g i ∈ t i) s, f i (g i)

full_name: Finset.prod_mulIndicator_eq_prod_filter
code: @[to_additive]
lemma prod_mulIndicator_eq_prod_filter (s : Finset ι) (f : ι → κ → β) (t : ι → Set κ) (g : ι → κ)
    [DecidablePred fun i ↦ g i ∈ t i] :
    ∏ i ∈ s, mulIndicator (t i) (f i) (g i) = ∏ i ∈ s.filter fun i ↦ g i ∈ t i, f i (g i) 
goal: ∏ i ∈ s, (t i).mulIndicator (f i) (g i) = ∏ i ∈ Finset.filter (fun i => g i ∈ t i) s, f i (g i)

full_name: Finset.sum_indicator_eq_sum_inter
code: @[to_additive]
lemma prod_mulIndicator_eq_prod_inter [DecidableEq ι] (s t : Finset ι) (f : ι → β) :
    ∏ i ∈ s, (t : Set ι).mulIndicator f i = ∏ i ∈ s ∩ t, f i 
goal: ∑ i ∈ s, (↑t).indicator f i = ∑ i ∈ s ∩ t, f i

full_name: Finset.prod_mulIndicator_eq_prod_inter
code: @[to_additive]
lemma prod_mulIndicator_eq_prod_inter [DecidableEq ι] (s t : Finset ι) (f : ι → β) :
    ∏ i ∈ s, (t : Set ι).mulIndicator f i = ∏ i ∈ s ∩ t, f i 
goal: ∏ i ∈ s, (↑t).mulIndicator f i = ∏ i ∈ s ∩ t, f i

full_name: Finset.mulIndicator_prod
code: @[to_additive]
lemma mulIndicator_prod (s : Finset ι) (t : Set κ) (f : ι → κ → β) :
    mulIndicator t (∏ i ∈ s, f i) = ∏ i ∈ s, mulIndicator t (f i) 
goal: t.mulIndicator (∏ i ∈ s, f i) = ∏ i ∈ s, t.mulIndicator (f i)

full_name: Finset.indicator_sum
code: @[to_additive]
lemma mulIndicator_prod (s : Finset ι) (t : Set κ) (f : ι → κ → β) :
    mulIndicator t (∏ i ∈ s, f i) = ∏ i ∈ s, mulIndicator t (f i) 
goal: t.indicator (∑ i ∈ s, f i) = ∑ i ∈ s, t.indicator (f i)

full_name: Finset.mulIndicator_biUnion
code: @[to_additive]
lemma mulIndicator_biUnion (s : Finset ι) (t : ι → Set κ) {f : κ → β} :
    ((s : Set ι).PairwiseDisjoint t) →
      mulIndicator (⋃ i ∈ s, t i) f = fun a ↦ ∏ i ∈ s, mulIndicator (t i) f a 
goal: (↑s).PairwiseDisjoint t → (⋃ i ∈ s, t i).mulIndicator f = fun a => ∏ i ∈ s, (t i).mulIndicator f a

full_name: Finset.indicator_biUnion
code: @[to_additive]
lemma mulIndicator_biUnion (s : Finset ι) (t : ι → Set κ) {f : κ → β} :
    ((s : Set ι).PairwiseDisjoint t) →
      mulIndicator (⋃ i ∈ s, t i) f = fun a ↦ ∏ i ∈ s, mulIndicator (t i) f a 
goal: (↑s).PairwiseDisjoint t → (⋃ i ∈ s, t i).indicator f = fun a => ∑ i ∈ s, (t i).indicator f a

full_name: Finset.mulIndicator_biUnion_apply
code: @[to_additive]
lemma mulIndicator_biUnion_apply (s : Finset ι) (t : ι → Set κ) {f : κ → β}
    (h : (s : Set ι).PairwiseDisjoint t) (x : κ) :
    mulIndicator (⋃ i ∈ s, t i) f x = ∏ i ∈ s, mulIndicator (t i) f x 
goal: (⋃ i ∈ s, t i).mulIndicator f x = ∏ i ∈ s, (t i).mulIndicator f x

full_name: Finset.indicator_biUnion_apply
code: @[to_additive]
lemma mulIndicator_biUnion_apply (s : Finset ι) (t : ι → Set κ) {f : κ → β}
    (h : (s : Set ι).PairwiseDisjoint t) (x : κ) :
    mulIndicator (⋃ i ∈ s, t i) f x = ∏ i ∈ s, mulIndicator (t i) f x 
goal: (⋃ i ∈ s, t i).indicator f x = ∑ i ∈ s, (t i).indicator f x

full_name: Finset.sum_bij_ne_zero
code: @[to_additive]
theorem prod_bij_ne_one {s : Finset α} {t : Finset γ} {f : α → β} {g : γ → β}
    (i : ∀ a ∈ s, f a ≠ 1 → γ) (hi : ∀ a h₁ h₂, i a h₁ h₂ ∈ t)
    (i_inj : ∀ a₁ h₁₁ h₁₂ a₂ h₂₁ h₂₂, i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂)
    (i_surj : ∀ b ∈ t, g b ≠ 1 → ∃ a h₁ h₂, i a h₁ h₂ = b) (h : ∀ a h₁ h₂, f a = g (i a h₁ h₂)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∑ x ∈ s, f x = ∑ x ∈ t, g x

full_name: Finset.prod_bij_ne_one
code: @[to_additive]
theorem prod_bij_ne_one {s : Finset α} {t : Finset γ} {f : α → β} {g : γ → β}
    (i : ∀ a ∈ s, f a ≠ 1 → γ) (hi : ∀ a h₁ h₂, i a h₁ h₂ ∈ t)
    (i_inj : ∀ a₁ h₁₁ h₁₂ a₂ h₂₁ h₂₂, i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂)
    (i_surj : ∀ b ∈ t, g b ≠ 1 → ∃ a h₁ h₂, i a h₁ h₂ = b) (h : ∀ a h₁ h₂, f a = g (i a h₁ h₂)) :
    ∏ x ∈ s, f x = ∏ x ∈ t, g x 
goal: ∏ x ∈ s, f x = ∏ x ∈ t, g x

full_name: Finset.nonempty_of_prod_ne_one
code: @[to_additive]
theorem nonempty_of_prod_ne_one (h : ∏ x ∈ s, f x ≠ 1) : s.Nonempty 
goal: s.Nonempty

full_name: Finset.nonempty_of_sum_ne_zero
code: @[to_additive]
theorem nonempty_of_prod_ne_one (h : ∏ x ∈ s, f x ≠ 1) : s.Nonempty 
goal: s.Nonempty

full_name: Finset.exists_ne_one_of_prod_ne_one
code: @[to_additive]
theorem exists_ne_one_of_prod_ne_one (h : ∏ x ∈ s, f x ≠ 1) : ∃ a ∈ s, f a ≠ 1 
goal: ∃ a ∈ s, f a ≠ 1

full_name: Finset.exists_ne_zero_of_sum_ne_zero
code: @[to_additive]
theorem exists_ne_one_of_prod_ne_one (h : ∏ x ∈ s, f x ≠ 1) : ∃ a ∈ s, f a ≠ 1 
goal: ∃ a ∈ s, f a ≠ 0

full_name: Finset.sum_range_succ_comm
code: @[to_additive]
theorem prod_range_succ_comm (f : ℕ → β) (n : ℕ) :
    (∏ x ∈ range (n + 1), f x) = f n * ∏ x ∈ range n, f x 
goal: ∑ x ∈ Finset.range (n + 1), f x = f n + ∑ x ∈ Finset.range n, f x

full_name: Finset.prod_range_succ_comm
code: @[to_additive]
theorem prod_range_succ_comm (f : ℕ → β) (n : ℕ) :
    (∏ x ∈ range (n + 1), f x) = f n * ∏ x ∈ range n, f x 
goal: ∏ x ∈ Finset.range (n + 1), f x = f n * ∏ x ∈ Finset.range n, f x

full_name: Finset.prod_range_succ
code: @[to_additive]
theorem prod_range_succ (f : ℕ → β) (n : ℕ) :
    (∏ x ∈ range (n + 1), f x) = (∏ x ∈ range n, f x) * f n 
goal: ∏ x ∈ Finset.range (n + 1), f x = (∏ x ∈ Finset.range n, f x) * f n

full_name: Finset.sum_range_succ
code: @[to_additive]
theorem prod_range_succ (f : ℕ → β) (n : ℕ) :
    (∏ x ∈ range (n + 1), f x) = (∏ x ∈ range n, f x) * f n 
goal: ∑ x ∈ Finset.range (n + 1), f x = ∑ x ∈ Finset.range n, f x + f n

full_name: Finset.prod_range_succ'
code: @[to_additive]
theorem prod_range_succ' (f : ℕ → β) :
    ∀ n : ℕ, (∏ k ∈ range (n + 1), f k) = (∏ k ∈ range n, f (k + 1)) * f 0
  
goal: ∏ k ∈ Finset.range (n + 1), f k = (∏ k ∈ Finset.range n, f (k + 1)) * f 0

full_name: Finset.sum_range_succ'
code: @[to_additive]
theorem prod_range_succ' (f : ℕ → β) :
    ∀ n : ℕ, (∏ k ∈ range (n + 1), f k) = (∏ k ∈ range n, f (k + 1)) * f 0
  
goal: ∑ k ∈ Finset.range (n + 1), f k = ∑ k ∈ Finset.range n, f (k + 1) + f 0

full_name: Finset.eventually_constant_prod
code: @[to_additive]
theorem eventually_constant_prod {u : ℕ → β} {N : ℕ} (hu : ∀ n ≥ N, u n = 1) {n : ℕ} (hn : N ≤ n) :
    (∏ k ∈ range n, u k) = ∏ k ∈ range N, u k 
goal: ∏ k ∈ Finset.range n, u k = ∏ k ∈ Finset.range N, u k

full_name: Finset.eventually_constant_sum
code: @[to_additive]
theorem eventually_constant_prod {u : ℕ → β} {N : ℕ} (hu : ∀ n ≥ N, u n = 1) {n : ℕ} (hn : N ≤ n) :
    (∏ k ∈ range n, u k) = ∏ k ∈ range N, u k 
goal: ∑ k ∈ Finset.range n, u k = ∑ k ∈ Finset.range N, u k

full_name: Finset.sum_range_add
code: @[to_additive]
theorem prod_range_add (f : ℕ → β) (n m : ℕ) :
    (∏ x ∈ range (n + m), f x) = (∏ x ∈ range n, f x) * ∏ x ∈ range m, f (n + x) 
goal: ∑ x ∈ Finset.range (n + m), f x = ∑ x ∈ Finset.range n, f x + ∑ x ∈ Finset.range m, f (n + x)

full_name: Finset.prod_range_add
code: @[to_additive]
theorem prod_range_add (f : ℕ → β) (n m : ℕ) :
    (∏ x ∈ range (n + m), f x) = (∏ x ∈ range n, f x) * ∏ x ∈ range m, f (n + x) 
goal: ∏ x ∈ Finset.range (n + m), f x = (∏ x ∈ Finset.range n, f x) * ∏ x ∈ Finset.range m, f (n + x)

full_name: Finset.sum_range_add_sub_sum_range
code: @[to_additive]
theorem prod_range_add_div_prod_range {α : Type*} [CommGroup α] (f : ℕ → α) (n m : ℕ) :
    (∏ k ∈ range (n + m), f k) / ∏ k ∈ range n, f k = ∏ k ∈ Finset.range m, f (n + k) 
goal: ∑ k ∈ Finset.range (n + m), f k - ∑ k ∈ Finset.range n, f k = ∑ k ∈ Finset.range m, f (n + k)

full_name: Finset.prod_range_add_div_prod_range
code: @[to_additive]
theorem prod_range_add_div_prod_range {α : Type*} [CommGroup α] (f : ℕ → α) (n m : ℕ) :
    (∏ k ∈ range (n + m), f k) / ∏ k ∈ range n, f k = ∏ k ∈ Finset.range m, f (n + k) 
goal: (∏ k ∈ Finset.range (n + m), f k) / ∏ k ∈ Finset.range n, f k = ∏ k ∈ Finset.range m, f (n + k)

full_name: Finset.sum_range_zero
code: @[to_additive]
theorem prod_range_zero (f : ℕ → β) : ∏ k ∈ range 0, f k = 1 
goal: ∑ k ∈ Finset.range 0, f k = 0

full_name: Finset.prod_range_zero
code: @[to_additive]
theorem prod_range_zero (f : ℕ → β) : ∏ k ∈ range 0, f k = 1 
goal: ∏ k ∈ Finset.range 0, f k = 1

full_name: Finset.sum_range_one
code: @[to_additive sum_range_one]
theorem prod_range_one (f : ℕ → β) : ∏ k ∈ range 1, f k = f 0 
goal: ∑ k ∈ Finset.range 1, f k = f 0

full_name: Finset.prod_range_one
code: @[to_additive sum_range_one]
theorem prod_range_one (f : ℕ → β) : ∏ k ∈ range 1, f k = f 0 
goal: ∏ k ∈ Finset.range 1, f k = f 0

full_name: Finset.prod_list_map_count
code: @[to_additive]
theorem prod_list_map_count [DecidableEq α] (l : List α) {M : Type*} [CommMonoid M] (f : α → M) :
    (l.map f).prod = ∏ m ∈ l.toFinset, f m ^ l.count m 
goal: (List.map f l).prod = ∏ m ∈ l.toFinset, f m ^ List.count m l

full_name: Finset.sum_list_map_count
code: @[to_additive]
theorem prod_list_map_count [DecidableEq α] (l : List α) {M : Type*} [CommMonoid M] (f : α → M) :
    (l.map f).prod = ∏ m ∈ l.toFinset, f m ^ l.count m 
goal: (List.map f l).sum = ∑ m ∈ l.toFinset, List.count m l • f m

full_name: Finset.sum_list_count
code: @[to_additive]
theorem prod_list_count [DecidableEq α] [CommMonoid α] (s : List α) :
    s.prod = ∏ m ∈ s.toFinset, m ^ s.count m 
goal: s.sum = ∑ m ∈ s.toFinset, List.count m s • m

full_name: Finset.prod_list_count
code: @[to_additive]
theorem prod_list_count [DecidableEq α] [CommMonoid α] (s : List α) :
    s.prod = ∏ m ∈ s.toFinset, m ^ s.count m 
goal: s.prod = ∏ m ∈ s.toFinset, m ^ List.count m s

full_name: Finset.prod_list_count_of_subset
code: @[to_additive]
theorem prod_list_count_of_subset [DecidableEq α] [CommMonoid α] (m : List α) (s : Finset α)
    (hs : m.toFinset ⊆ s) : m.prod = ∏ i ∈ s, i ^ m.count i 
goal: m.prod = ∏ i ∈ s, i ^ List.count i m

full_name: Finset.sum_list_count_of_subset
code: @[to_additive]
theorem prod_list_count_of_subset [DecidableEq α] [CommMonoid α] (m : List α) (s : Finset α)
    (hs : m.toFinset ⊆ s) : m.prod = ∏ i ∈ s, i ^ m.count i 
goal: m.sum = ∑ i ∈ s, List.count i m • i

full_name: Finset.sum_filter_count_eq_countP
code: theorem sum_filter_count_eq_countP [DecidableEq α] (p : α → Prop) [DecidablePred p] (l : List α) :
    ∑ x ∈ l.toFinset.filter p, l.count x = l.countP p 
goal: ∑ x ∈ Finset.filter p l.toFinset, List.count x l = List.countP (fun b => decide (p b)) l

full_name: Finset.prod_multiset_map_count
code: @[to_additive]
theorem prod_multiset_map_count [DecidableEq α] (s : Multiset α) {M : Type*} [CommMonoid M]
    (f : α → M) : (s.map f).prod = ∏ m ∈ s.toFinset, f m ^ s.count m 
goal: (Multiset.map f s).prod = ∏ m ∈ s.toFinset, f m ^ Multiset.count m s

full_name: Finset.sum_multiset_map_count
code: @[to_additive]
theorem prod_multiset_map_count [DecidableEq α] (s : Multiset α) {M : Type*} [CommMonoid M]
    (f : α → M) : (s.map f).prod = ∏ m ∈ s.toFinset, f m ^ s.count m 
goal: (Multiset.map f s).sum = ∑ m ∈ s.toFinset, Multiset.count m s • f m

full_name: Finset.prod_multiset_count
code: @[to_additive]
theorem prod_multiset_count [DecidableEq α] [CommMonoid α] (s : Multiset α) :
    s.prod = ∏ m ∈ s.toFinset, m ^ s.count m 
goal: s.prod = ∏ m ∈ s.toFinset, m ^ Multiset.count m s

full_name: Finset.sum_multiset_count
code: @[to_additive]
theorem prod_multiset_count [DecidableEq α] [CommMonoid α] (s : Multiset α) :
    s.prod = ∏ m ∈ s.toFinset, m ^ s.count m 
goal: s.sum = ∑ m ∈ s.toFinset, Multiset.count m s • m

full_name: Finset.sum_multiset_count_of_subset
code: @[to_additive]
theorem prod_multiset_count_of_subset [DecidableEq α] [CommMonoid α] (m : Multiset α) (s : Finset α)
    (hs : m.toFinset ⊆ s) : m.prod = ∏ i ∈ s, i ^ m.count i 
goal: m.sum = ∑ i ∈ s, Multiset.count i m • i

full_name: Finset.prod_multiset_count_of_subset
code: @[to_additive]
theorem prod_multiset_count_of_subset [DecidableEq α] [CommMonoid α] (m : Multiset α) (s : Finset α)
    (hs : m.toFinset ⊆ s) : m.prod = ∏ i ∈ s, i ^ m.count i 
goal: m.prod = ∏ i ∈ s, i ^ Multiset.count i m

full_name: Finset.prod_mem_multiset
code: @[to_additive]
theorem prod_mem_multiset [DecidableEq α] (m : Multiset α) (f : { x // x ∈ m } → β) (g : α → β)
    (hfg : ∀ x, f x = g x) : ∏ x : { x // x ∈ m }, f x = ∏ x ∈ m.toFinset, g x 
goal: ∏ x : { x // x ∈ m }, f x = ∏ x ∈ m.toFinset, g x

full_name: Finset.sum_mem_multiset
code: @[to_additive]
theorem prod_mem_multiset [DecidableEq α] (m : Multiset α) (f : { x // x ∈ m } → β) (g : α → β)
    (hfg : ∀ x, f x = g x) : ∏ x : { x // x ∈ m }, f x = ∏ x ∈ m.toFinset, g x 
goal: ∑ x : { x // x ∈ m }, f x = ∑ x ∈ m.toFinset, g x

full_name: Finset.prod_induction
code: /-- To prove a property of a product, it suffices to prove that
the property is multiplicative and holds on factors. -/
@[to_additive "To prove a property of a sum, it suffices to prove that
the property is additive and holds on summands."]
theorem prod_induction {M : Type*} [CommMonoid M] (f : α → M) (p : M → Prop)
    (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ s, p <| f x) :
    p <| ∏ x ∈ s, f x 
goal: p (∏ x ∈ s, f x)

full_name: Finset.sum_induction
code: /-- To prove a property of a product, it suffices to prove that
the property is multiplicative and holds on factors. -/
@[to_additive "To prove a property of a sum, it suffices to prove that
the property is additive and holds on summands."]
theorem prod_induction {M : Type*} [CommMonoid M] (f : α → M) (p : M → Prop)
    (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ s, p <| f x) :
    p <| ∏ x ∈ s, f x 
goal: p (∑ x ∈ s, f x)

full_name: Finset.sum_induction_nonempty
code: /-- To prove a property of a product, it suffices to prove that
the property is multiplicative and holds on factors. -/
@[to_additive "To prove a property of a sum, it suffices to prove that
the property is additive and holds on summands."]
theorem prod_induction_nonempty {M : Type*} [CommMonoid M] (f : α → M) (p : M → Prop)
    (hom : ∀ a b, p a → p b → p (a * b)) (nonempty : s.Nonempty) (base : ∀ x ∈ s, p <| f x) :
    p <| ∏ x ∈ s, f x 
goal: p (∑ x ∈ s, f x)

full_name: Finset.prod_induction_nonempty
code: /-- To prove a property of a product, it suffices to prove that
the property is multiplicative and holds on factors. -/
@[to_additive "To prove a property of a sum, it suffices to prove that
the property is additive and holds on summands."]
theorem prod_induction_nonempty {M : Type*} [CommMonoid M] (f : α → M) (p : M → Prop)
    (hom : ∀ a b, p a → p b → p (a * b)) (nonempty : s.Nonempty) (base : ∀ x ∈ s, p <| f x) :
    p <| ∏ x ∈ s, f x 
goal: p (∏ x ∈ s, f x)

full_name: Finset.prod_range_induction
code: /-- For any product along `{0, ..., n - 1}` of a commutative-monoid-valued function, we can verify
that it's equal to a different function just by checking ratios of adjacent terms.

This is a multiplicative discrete analogue of the fundamental theorem of calculus. -/
@[to_additive "For any sum along `{0, ..., n - 1}` of a commutative-monoid-valued function, we can
verify that it's equal to a different function just by checking differences of adjacent terms.

This is a discrete analogue of the fundamental theorem of calculus."]
theorem prod_range_induction (f s : ℕ → β) (base : s 0 = 1)
    (step : ∀ n, s (n + 1) = s n * f n) (n : ℕ) :
    ∏ k ∈ Finset.range n, f k = s n 
goal: ∏ k ∈ Finset.range n, f k = s n

full_name: Finset.sum_range_induction
code: /-- For any product along `{0, ..., n - 1}` of a commutative-monoid-valued function, we can verify
that it's equal to a different function just by checking ratios of adjacent terms.

This is a multiplicative discrete analogue of the fundamental theorem of calculus. -/
@[to_additive "For any sum along `{0, ..., n - 1}` of a commutative-monoid-valued function, we can
verify that it's equal to a different function just by checking differences of adjacent terms.

This is a discrete analogue of the fundamental theorem of calculus."]
theorem prod_range_induction (f s : ℕ → β) (base : s 0 = 1)
    (step : ∀ n, s (n + 1) = s n * f n) (n : ℕ) :
    ∏ k ∈ Finset.range n, f k = s n 
goal: ∑ k ∈ Finset.range n, f k = s n

full_name: Finset.prod_range_div
code: /-- A telescoping product along `{0, ..., n - 1}` of a commutative group valued function reduces to
the ratio of the last and first factors. -/
@[to_additive "A telescoping sum along `{0, ..., n - 1}` of an additive commutative group valued
function reduces to the difference of the last and first terms."]
theorem prod_range_div {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    (∏ i ∈ range n, f (i + 1) / f i) = f n / f 0 
goal: ∏ i ∈ Finset.range n, f (i + 1) / f i = f n / f 0

full_name: Finset.sum_range_sub
code: /-- A telescoping product along `{0, ..., n - 1}` of a commutative group valued function reduces to
the ratio of the last and first factors. -/
@[to_additive "A telescoping sum along `{0, ..., n - 1}` of an additive commutative group valued
function reduces to the difference of the last and first terms."]
theorem prod_range_div {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    (∏ i ∈ range n, f (i + 1) / f i) = f n / f 0 
goal: ∑ i ∈ Finset.range n, (f (i + 1) - f i) = f n - f 0

full_name: Finset.sum_range_sub'
code: @[to_additive]
theorem prod_range_div' {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    (∏ i ∈ range n, f i / f (i + 1)) = f 0 / f n 
goal: ∑ i ∈ Finset.range n, (f i - f (i + 1)) = f 0 - f n

full_name: Finset.prod_range_div'
code: @[to_additive]
theorem prod_range_div' {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    (∏ i ∈ range n, f i / f (i + 1)) = f 0 / f n 
goal: ∏ i ∈ Finset.range n, f i / f (i + 1) = f 0 / f n

full_name: Finset.eq_prod_range_div
code: @[to_additive]
theorem eq_prod_range_div {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    f n = f 0 * ∏ i ∈ range n, f (i + 1) / f i 
goal: f n = f 0 * ∏ i ∈ Finset.range n, f (i + 1) / f i

full_name: Finset.eq_sum_range_sub
code: @[to_additive]
theorem eq_prod_range_div {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    f n = f 0 * ∏ i ∈ range n, f (i + 1) / f i 
goal: f n = f 0 + ∑ i ∈ Finset.range n, (f (i + 1) - f i)

full_name: Finset.eq_sum_range_sub'
code: @[to_additive]
theorem eq_prod_range_div' {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    f n = ∏ i ∈ range (n + 1), if i = 0 then f 0 else f i / f (i - 1) 
goal: f n = ∑ i ∈ Finset.range (n + 1), if i = 0 then f 0 else f i - f (i - 1)

full_name: Finset.eq_prod_range_div'
code: @[to_additive]
theorem eq_prod_range_div' {M : Type*} [CommGroup M] (f : ℕ → M) (n : ℕ) :
    f n = ∏ i ∈ range (n + 1), if i = 0 then f 0 else f i / f (i - 1) 
goal: f n = ∏ i ∈ Finset.range (n + 1), if i = 0 then f 0 else f i / f (i - 1)

full_name: Finset.sum_range_tsub
code: /-- A telescoping sum along `{0, ..., n-1}` of an `ℕ`-valued function
reduces to the difference of the last and first terms
when the function we are summing is monotone.
-/
theorem sum_range_tsub [CanonicallyOrderedAddCommMonoid α] [Sub α] [OrderedSub α]
    [ContravariantClass α α (· + ·) (· ≤ ·)] {f : ℕ → α} (h : Monotone f) (n : ℕ) :
    ∑ i ∈ range n, (f (i + 1) - f i) = f n - f 0 
goal: ∑ i ∈ Finset.range n, (f (i + 1) - f i) = f n - f 0

full_name: Finset.prod_const
code: @[to_additive (attr := simp)]
theorem prod_const (b : β) : ∏ _x ∈ s, b = b ^ s.card 
goal: ∏ _x ∈ s, b = b ^ s.card

full_name: Finset.sum_const
code: @[to_additive (attr := simp)]
theorem prod_const (b : β) : ∏ _x ∈ s, b = b ^ s.card 
goal: ∑ _x ∈ s, b = s.card • b

full_name: Finset.sum_eq_card_nsmul
code: @[to_additive sum_eq_card_nsmul]
theorem prod_eq_pow_card {b : β} (hf : ∀ a ∈ s, f a = b) : ∏ a ∈ s, f a = b ^ s.card 
goal: ∑ a ∈ s, f a = s.card • b

full_name: Finset.prod_eq_pow_card
code: @[to_additive sum_eq_card_nsmul]
theorem prod_eq_pow_card {b : β} (hf : ∀ a ∈ s, f a = b) : ∏ a ∈ s, f a = b ^ s.card 
goal: ∏ a ∈ s, f a = b ^ s.card

full_name: Finset.card_nsmul_add_sum
code: @[to_additive card_nsmul_add_sum]
theorem pow_card_mul_prod {b : β} : b ^ s.card * ∏ a ∈ s, f a = ∏ a ∈ s, b * f a 
goal: s.card • b + ∑ a ∈ s, f a = ∑ a ∈ s, (b + f a)

full_name: Finset.pow_card_mul_prod
code: @[to_additive card_nsmul_add_sum]
theorem pow_card_mul_prod {b : β} : b ^ s.card * ∏ a ∈ s, f a = ∏ a ∈ s, b * f a 
goal: b ^ s.card * ∏ a ∈ s, f a = ∏ a ∈ s, b * f a

full_name: Finset.prod_mul_pow_card
code: @[to_additive sum_add_card_nsmul]
theorem prod_mul_pow_card {b : β} : (∏ a ∈ s, f a) * b ^ s.card = ∏ a ∈ s, f a * b 
goal: (∏ a ∈ s, f a) * b ^ s.card = ∏ a ∈ s, f a * b

full_name: Finset.sum_add_card_nsmul
code: @[to_additive sum_add_card_nsmul]
theorem prod_mul_pow_card {b : β} : (∏ a ∈ s, f a) * b ^ s.card = ∏ a ∈ s, f a * b 
goal: ∑ a ∈ s, f a + s.card • b = ∑ a ∈ s, (f a + b)

full_name: Finset.pow_eq_prod_const
code: @[to_additive]
theorem pow_eq_prod_const (b : β) : ∀ n, b ^ n = ∏ _k ∈ range n, b 
goal: b ^ n = ∏ _k ∈ Finset.range n, b

full_name: Finset.nsmul_eq_sum_const
code: @[to_additive]
theorem pow_eq_prod_const (b : β) : ∀ n, b ^ n = ∏ _k ∈ range n, b 
goal: n • b = ∑ _k ∈ Finset.range n, b

full_name: Finset.sum_nsmul
code: @[to_additive]
theorem prod_pow (s : Finset α) (n : ℕ) (f : α → β) : ∏ x ∈ s, f x ^ n = (∏ x ∈ s, f x) ^ n 
goal: ∑ x ∈ s, n • f x = n • ∑ x ∈ s, f x

full_name: Finset.prod_pow
code: @[to_additive]
theorem prod_pow (s : Finset α) (n : ℕ) (f : α → β) : ∏ x ∈ s, f x ^ n = (∏ x ∈ s, f x) ^ n 
goal: ∏ x ∈ s, f x ^ n = (∏ x ∈ s, f x) ^ n

full_name: Finset.prod_pow_eq_pow_sum
code: @[to_additive sum_nsmul_assoc]
lemma prod_pow_eq_pow_sum  (s : Finset ι) (f : ι → ℕ) (a : β) :
    ∏ i ∈ s, a ^ f i = a ^ ∑ i ∈ s, f i 
goal: ∏ i ∈ s, a ^ f i = a ^ ∑ i ∈ s, f i

full_name: Finset.sum_nsmul_assoc
code: @[to_additive sum_nsmul_assoc]
lemma prod_pow_eq_pow_sum  (s : Finset ι) (f : ι → ℕ) (a : β) :
    ∏ i ∈ s, a ^ f i = a ^ ∑ i ∈ s, f i 
goal: ∑ i ∈ s, f i • a = (∑ i ∈ s, f i) • a

full_name: Finset.sum_powersetCard
code: /-- A product over `Finset.powersetCard` which only depends on the size of the sets is constant. -/
@[to_additive
"A sum over `Finset.powersetCard` which only depends on the size of the sets is constant."]
lemma prod_powersetCard (n : ℕ) (s : Finset α) (f : ℕ → β) :
    ∏ t ∈ powersetCard n s, f t.card = f n ^ s.card.choose n 
goal: ∑ t ∈ Finset.powersetCard n s, f t.card = s.card.choose n • f n

full_name: Finset.prod_powersetCard
code: /-- A product over `Finset.powersetCard` which only depends on the size of the sets is constant. -/
@[to_additive
"A sum over `Finset.powersetCard` which only depends on the size of the sets is constant."]
lemma prod_powersetCard (n : ℕ) (s : Finset α) (f : ℕ → β) :
    ∏ t ∈ powersetCard n s, f t.card = f n ^ s.card.choose n 
goal: ∏ t ∈ Finset.powersetCard n s, f t.card = f n ^ s.card.choose n

full_name: Finset.sum_flip
code: @[to_additive]
theorem prod_flip {n : ℕ} (f : ℕ → β) :
    (∏ r ∈ range (n + 1), f (n - r)) = ∏ k ∈ range (n + 1), f k 
goal: ∑ r ∈ Finset.range (n + 1), f (n - r) = ∑ k ∈ Finset.range (n + 1), f k

full_name: Finset.prod_flip
code: @[to_additive]
theorem prod_flip {n : ℕ} (f : ℕ → β) :
    (∏ r ∈ range (n + 1), f (n - r)) = ∏ k ∈ range (n + 1), f k 
goal: ∏ r ∈ Finset.range (n + 1), f (n - r) = ∏ k ∈ Finset.range (n + 1), f k

full_name: Finset.sum_involution
code: @[to_additive]
theorem prod_involution {s : Finset α} {f : α → β} :
    ∀ (g : ∀ a ∈ s, α) (_ : ∀ a ha, f a * f (g a ha) = 1) (_ : ∀ a ha, f a ≠ 1 → g a ha ≠ a)
      (g_mem : ∀ a ha, g a ha ∈ s) (_ : ∀ a ha, g (g a ha) (g_mem a ha) = a),
      ∏ x ∈ s, f x = 1 
goal: (∀ (a : α) (ha : a ∈ s), f a + f (g a ha) = 0) →
  (∀ (a : α) (ha : a ∈ s), f a ≠ 0 → g a ha ≠ a) →
    ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s), (∀ (a : α) (ha : a ∈ s), g (g a ha) ⋯ = a) → ∑ x ∈ s, f x = 0

full_name: Finset.prod_involution
code: @[to_additive]
theorem prod_involution {s : Finset α} {f : α → β} :
    ∀ (g : ∀ a ∈ s, α) (_ : ∀ a ha, f a * f (g a ha) = 1) (_ : ∀ a ha, f a ≠ 1 → g a ha ≠ a)
      (g_mem : ∀ a ha, g a ha ∈ s) (_ : ∀ a ha, g (g a ha) (g_mem a ha) = a),
      ∏ x ∈ s, f x = 1 
goal: (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
  (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
    ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s), (∀ (a : α) (ha : a ∈ s), g (g a ha) ⋯ = a) → ∏ x ∈ s, f x = 1

full_name: Finset.prod_comp
code: /-- The product of the composition of functions `f` and `g`, is the product over `b ∈ s.image g` of
`f b` to the power of the cardinality of the fibre of `b`. See also `Finset.prod_image`. -/
@[to_additive "The sum of the composition of functions `f` and `g`, is the sum over `b ∈ s.image g`
of `f b` times of the cardinality of the fibre of `b`. See also `Finset.sum_image`."]
theorem prod_comp [DecidableEq γ] (f : γ → β) (g : α → γ) :
    ∏ a ∈ s, f (g a) = ∏ b ∈ s.image g, f b ^ (s.filter fun a => g a = b).card 
goal: ∏ a ∈ s, f (g a) = ∏ b ∈ Finset.image g s, f b ^ (Finset.filter (fun a => g a = b) s).card

full_name: Finset.sum_comp
code: /-- The product of the composition of functions `f` and `g`, is the product over `b ∈ s.image g` of
`f b` to the power of the cardinality of the fibre of `b`. See also `Finset.prod_image`. -/
@[to_additive "The sum of the composition of functions `f` and `g`, is the sum over `b ∈ s.image g`
of `f b` times of the cardinality of the fibre of `b`. See also `Finset.sum_image`."]
theorem prod_comp [DecidableEq γ] (f : γ → β) (g : α → γ) :
    ∏ a ∈ s, f (g a) = ∏ b ∈ s.image g, f b ^ (s.filter fun a => g a = b).card 
goal: ∑ a ∈ s, f (g a) = ∑ b ∈ Finset.image g s, (Finset.filter (fun a => g a = b) s).card • f b

full_name: Finset.prod_piecewise
code: @[to_additive]
theorem prod_piecewise [DecidableEq α] (s t : Finset α) (f g : α → β) :
    (∏ x ∈ s, (t.piecewise f g) x) = (∏ x ∈ s ∩ t, f x) * ∏ x ∈ s \ t, g x 
goal: ∏ x ∈ s, t.piecewise f g x = (∏ x ∈ s ∩ t, f x) * ∏ x ∈ s \ t, g x

full_name: Finset.sum_piecewise
code: @[to_additive]
theorem prod_piecewise [DecidableEq α] (s t : Finset α) (f g : α → β) :
    (∏ x ∈ s, (t.piecewise f g) x) = (∏ x ∈ s ∩ t, f x) * ∏ x ∈ s \ t, g x 
goal: ∑ x ∈ s, t.piecewise f g x = ∑ x ∈ s ∩ t, f x + ∑ x ∈ s \ t, g x

full_name: Finset.sum_inter_add_sum_diff
code: @[to_additive]
theorem prod_inter_mul_prod_diff [DecidableEq α] (s t : Finset α) (f : α → β) :
    (∏ x ∈ s ∩ t, f x) * ∏ x ∈ s \ t, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ s ∩ t, f x + ∑ x ∈ s \ t, f x = ∑ x ∈ s, f x

full_name: Finset.prod_inter_mul_prod_diff
code: @[to_additive]
theorem prod_inter_mul_prod_diff [DecidableEq α] (s t : Finset α) (f : α → β) :
    (∏ x ∈ s ∩ t, f x) * ∏ x ∈ s \ t, f x = ∏ x ∈ s, f x 
goal: (∏ x ∈ s ∩ t, f x) * ∏ x ∈ s \ t, f x = ∏ x ∈ s, f x

full_name: Finset.prod_eq_mul_prod_diff_singleton
code: @[to_additive]
theorem prod_eq_mul_prod_diff_singleton [DecidableEq α] {s : Finset α} {i : α} (h : i ∈ s)
    (f : α → β) : ∏ x ∈ s, f x = f i * ∏ x ∈ s \ {i}, f x 
goal: ∏ x ∈ s, f x = f i * ∏ x ∈ s \ {i}, f x

full_name: Finset.sum_eq_add_sum_diff_singleton
code: @[to_additive]
theorem prod_eq_mul_prod_diff_singleton [DecidableEq α] {s : Finset α} {i : α} (h : i ∈ s)
    (f : α → β) : ∏ x ∈ s, f x = f i * ∏ x ∈ s \ {i}, f x 
goal: ∑ x ∈ s, f x = f i + ∑ x ∈ s \ {i}, f x

full_name: Finset.sum_eq_sum_diff_singleton_add
code: @[to_additive]
theorem prod_eq_prod_diff_singleton_mul [DecidableEq α] {s : Finset α} {i : α} (h : i ∈ s)
    (f : α → β) : ∏ x ∈ s, f x = (∏ x ∈ s \ {i}, f x) * f i 
goal: ∑ x ∈ s, f x = ∑ x ∈ s \ {i}, f x + f i

full_name: Finset.prod_eq_prod_diff_singleton_mul
code: @[to_additive]
theorem prod_eq_prod_diff_singleton_mul [DecidableEq α] {s : Finset α} {i : α} (h : i ∈ s)
    (f : α → β) : ∏ x ∈ s, f x = (∏ x ∈ s \ {i}, f x) * f i 
goal: ∏ x ∈ s, f x = (∏ x ∈ s \ {i}, f x) * f i

full_name: Fintype.prod_eq_mul_prod_compl
code: @[to_additive]
theorem _root_.Fintype.prod_eq_mul_prod_compl [DecidableEq α] [Fintype α] (a : α) (f : α → β) :
    ∏ i, f i = f a * ∏ i ∈ {a}ᶜ, f i 
goal: ∏ i : α, f i = f a * ∏ i ∈ {a}ᶜ, f i

full_name: Fintype.sum_eq_add_sum_compl
code: @[to_additive]
theorem _root_.Fintype.prod_eq_mul_prod_compl [DecidableEq α] [Fintype α] (a : α) (f : α → β) :
    ∏ i, f i = f a * ∏ i ∈ {a}ᶜ, f i 
goal: ∑ i : α, f i = f a + ∑ i ∈ {a}ᶜ, f i

full_name: Fintype.prod_eq_prod_compl_mul
code: @[to_additive]
theorem _root_.Fintype.prod_eq_prod_compl_mul [DecidableEq α] [Fintype α] (a : α) (f : α → β) :
    ∏ i, f i = (∏ i ∈ {a}ᶜ, f i) * f a 
goal: ∏ i : α, f i = (∏ i ∈ {a}ᶜ, f i) * f a

full_name: Fintype.sum_eq_sum_compl_add
code: @[to_additive]
theorem _root_.Fintype.prod_eq_prod_compl_mul [DecidableEq α] [Fintype α] (a : α) (f : α → β) :
    ∏ i, f i = (∏ i ∈ {a}ᶜ, f i) * f a 
goal: ∑ i : α, f i = ∑ i ∈ {a}ᶜ, f i + f a

full_name: Finset.dvd_prod_of_mem
code: theorem dvd_prod_of_mem (f : α → β) {a : α} {s : Finset α} (ha : a ∈ s) : f a ∣ ∏ i ∈ s, f i 
goal: f a ∣ ∏ i ∈ s, f i

full_name: Finset.sum_partition
code: /-- A product can be partitioned into a product of products, each equivalent under a setoid. -/
@[to_additive "A sum can be partitioned into a sum of sums, each equivalent under a setoid."]
theorem prod_partition (R : Setoid α) [DecidableRel R.r] :
    ∏ x ∈ s, f x = ∏ xbar ∈ s.image Quotient.mk'', ∏ y ∈ s.filter (⟦·⟧ = xbar), f y 
goal: ∑ x ∈ s, f x = ∑ xbar ∈ Finset.image Quotient.mk'' s, ∑ y ∈ Finset.filter (fun x => ⟦x⟧ = xbar) s, f y

full_name: Finset.prod_partition
code: /-- A product can be partitioned into a product of products, each equivalent under a setoid. -/
@[to_additive "A sum can be partitioned into a sum of sums, each equivalent under a setoid."]
theorem prod_partition (R : Setoid α) [DecidableRel R.r] :
    ∏ x ∈ s, f x = ∏ xbar ∈ s.image Quotient.mk'', ∏ y ∈ s.filter (⟦·⟧ = xbar), f y 
goal: ∏ x ∈ s, f x = ∏ xbar ∈ Finset.image Quotient.mk'' s, ∏ y ∈ Finset.filter (fun x => ⟦x⟧ = xbar) s, f y

full_name: Finset.sum_cancels_of_partition_cancels
code: /-- If we can partition a product into subsets that cancel out, then the whole product cancels. -/
@[to_additive "If we can partition a sum into subsets that cancel out, then the whole sum cancels."]
theorem prod_cancels_of_partition_cancels (R : Setoid α) [DecidableRel R.r]
    (h : ∀ x ∈ s, ∏ a ∈ s.filter fun y => y ≈ x, f a = 1) : ∏ x ∈ s, f x = 1 
goal: ∑ x ∈ s, f x = 0

full_name: Finset.prod_cancels_of_partition_cancels
code: /-- If we can partition a product into subsets that cancel out, then the whole product cancels. -/
@[to_additive "If we can partition a sum into subsets that cancel out, then the whole sum cancels."]
theorem prod_cancels_of_partition_cancels (R : Setoid α) [DecidableRel R.r]
    (h : ∀ x ∈ s, ∏ a ∈ s.filter fun y => y ≈ x, f a = 1) : ∏ x ∈ s, f x = 1 
goal: ∏ x ∈ s, f x = 1

full_name: Finset.sum_update_of_not_mem
code: @[to_additive]
theorem prod_update_of_not_mem [DecidableEq α] {s : Finset α} {i : α} (h : i ∉ s) (f : α → β)
    (b : β) : ∏ x ∈ s, Function.update f i b x = ∏ x ∈ s, f x 
goal: ∑ x ∈ s, Function.update f i b x = ∑ x ∈ s, f x

full_name: Finset.prod_update_of_not_mem
code: @[to_additive]
theorem prod_update_of_not_mem [DecidableEq α] {s : Finset α} {i : α} (h : i ∉ s) (f : α → β)
    (b : β) : ∏ x ∈ s, Function.update f i b x = ∏ x ∈ s, f x 
goal: ∏ x ∈ s, Function.update f i b x = ∏ x ∈ s, f x

full_name: Finset.sum_update_of_mem
code: @[to_additive]
theorem prod_update_of_mem [DecidableEq α] {s : Finset α} {i : α} (h : i ∈ s) (f : α → β) (b : β) :
    ∏ x ∈ s, Function.update f i b x = b * ∏ x ∈ s \ singleton i, f x 
goal: ∑ x ∈ s, Function.update f i b x = b + ∑ x ∈ s \ {i}, f x

full_name: Finset.prod_update_of_mem
code: @[to_additive]
theorem prod_update_of_mem [DecidableEq α] {s : Finset α} {i : α} (h : i ∈ s) (f : α → β) (b : β) :
    ∏ x ∈ s, Function.update f i b x = b * ∏ x ∈ s \ singleton i, f x 
goal: ∏ x ∈ s, Function.update f i b x = b * ∏ x ∈ s \ {i}, f x

full_name: Finset.eq_of_card_le_one_of_prod_eq
code: /-- If a product of a `Finset` of size at most 1 has a given value, so
do the terms in that product. -/
@[to_additive eq_of_card_le_one_of_sum_eq "If a sum of a `Finset` of size at most 1 has a given
value, so do the terms in that sum."]
theorem eq_of_card_le_one_of_prod_eq {s : Finset α} (hc : s.card ≤ 1) {f : α → β} {b : β}
    (h : ∏ x ∈ s, f x = b) : ∀ x ∈ s, f x = b 
goal: x ∈ s → f x = b

full_name: Finset.eq_of_card_le_one_of_sum_eq
code: /-- If a product of a `Finset` of size at most 1 has a given value, so
do the terms in that product. -/
@[to_additive eq_of_card_le_one_of_sum_eq "If a sum of a `Finset` of size at most 1 has a given
value, so do the terms in that sum."]
theorem eq_of_card_le_one_of_prod_eq {s : Finset α} (hc : s.card ≤ 1) {f : α → β} {b : β}
    (h : ∏ x ∈ s, f x = b) : ∀ x ∈ s, f x = b 
goal: x ∈ s → f x = b

full_name: Finset.mul_prod_erase
code: /-- Taking a product over `s : Finset α` is the same as multiplying the value on a single element
`f a` by the product of `s.erase a`.

See `Multiset.prod_map_erase` for the `Multiset` version. -/
@[to_additive "Taking a sum over `s : Finset α` is the same as adding the value on a single element
`f a` to the sum over `s.erase a`.

See `Multiset.sum_map_erase` for the `Multiset` version."]
theorem mul_prod_erase [DecidableEq α] (s : Finset α) (f : α → β) {a : α} (h : a ∈ s) :
    (f a * ∏ x ∈ s.erase a, f x) = ∏ x ∈ s, f x 
goal: f a * ∏ x ∈ s.erase a, f x = ∏ x ∈ s, f x

full_name: Finset.add_sum_erase
code: /-- Taking a product over `s : Finset α` is the same as multiplying the value on a single element
`f a` by the product of `s.erase a`.

See `Multiset.prod_map_erase` for the `Multiset` version. -/
@[to_additive "Taking a sum over `s : Finset α` is the same as adding the value on a single element
`f a` to the sum over `s.erase a`.

See `Multiset.sum_map_erase` for the `Multiset` version."]
theorem mul_prod_erase [DecidableEq α] (s : Finset α) (f : α → β) {a : α} (h : a ∈ s) :
    (f a * ∏ x ∈ s.erase a, f x) = ∏ x ∈ s, f x 
goal: f a + ∑ x ∈ s.erase a, f x = ∑ x ∈ s, f x

full_name: Finset.prod_erase_mul
code: /-- A variant of `Finset.mul_prod_erase` with the multiplication swapped. -/
@[to_additive "A variant of `Finset.add_sum_erase` with the addition swapped."]
theorem prod_erase_mul [DecidableEq α] (s : Finset α) (f : α → β) {a : α} (h : a ∈ s) :
    (∏ x ∈ s.erase a, f x) * f a = ∏ x ∈ s, f x 
goal: (∏ x ∈ s.erase a, f x) * f a = ∏ x ∈ s, f x

full_name: Finset.sum_erase_add
code: /-- A variant of `Finset.mul_prod_erase` with the multiplication swapped. -/
@[to_additive "A variant of `Finset.add_sum_erase` with the addition swapped."]
theorem prod_erase_mul [DecidableEq α] (s : Finset α) (f : α → β) {a : α} (h : a ∈ s) :
    (∏ x ∈ s.erase a, f x) * f a = ∏ x ∈ s, f x 
goal: ∑ x ∈ s.erase a, f x + f a = ∑ x ∈ s, f x

full_name: Finset.sum_erase
code: /-- If a function applied at a point is 1, a product is unchanged by
removing that point, if present, from a `Finset`. -/
@[to_additive "If a function applied at a point is 0, a sum is unchanged by
removing that point, if present, from a `Finset`."]
theorem prod_erase [DecidableEq α] (s : Finset α) {f : α → β} {a : α} (h : f a = 1) :
    ∏ x ∈ s.erase a, f x = ∏ x ∈ s, f x 
goal: ∑ x ∈ s.erase a, f x = ∑ x ∈ s, f x

full_name: Finset.prod_erase
code: /-- If a function applied at a point is 1, a product is unchanged by
removing that point, if present, from a `Finset`. -/
@[to_additive "If a function applied at a point is 0, a sum is unchanged by
removing that point, if present, from a `Finset`."]
theorem prod_erase [DecidableEq α] (s : Finset α) {f : α → β} {a : α} (h : f a = 1) :
    ∏ x ∈ s.erase a, f x = ∏ x ∈ s, f x 
goal: ∏ x ∈ s.erase a, f x = ∏ x ∈ s, f x

full_name: Finset.sum_ite_zero
code: /-- See also `Finset.prod_boole`. -/
@[to_additive "See also `Finset.sum_boole`."]
theorem prod_ite_one (s : Finset α) (p : α → Prop) [DecidablePred p]
    (h : ∀ i ∈ s, ∀ j ∈ s, p i → p j → i = j) (a : β) :
    ∏ i ∈ s, ite (p i) a 1 = ite (∃ i ∈ s, p i) a 1 
goal: (∑ i ∈ s, if p i then a else 0) = if ∃ i ∈ s, p i then a else 0

full_name: Finset.prod_ite_one
code: /-- See also `Finset.prod_boole`. -/
@[to_additive "See also `Finset.sum_boole`."]
theorem prod_ite_one (s : Finset α) (p : α → Prop) [DecidablePred p]
    (h : ∀ i ∈ s, ∀ j ∈ s, p i → p j → i = j) (a : β) :
    ∏ i ∈ s, ite (p i) a 1 = ite (∃ i ∈ s, p i) a 1 
goal: (∏ i ∈ s, if p i then a else 1) = if ∃ i ∈ s, p i then a else 1

full_name: Finset.prod_erase_lt_of_one_lt
code: @[to_additive]
theorem prod_erase_lt_of_one_lt {γ : Type*} [DecidableEq α] [OrderedCommMonoid γ]
    [CovariantClass γ γ (· * ·) (· < ·)] {s : Finset α} {d : α} (hd : d ∈ s) {f : α → γ}
    (hdf : 1 < f d) : ∏ m ∈ s.erase d, f m < ∏ m ∈ s, f m 
goal: ∏ m ∈ s.erase d, f m < ∏ m ∈ s, f m

full_name: Finset.sum_erase_lt_of_pos
code: @[to_additive]
theorem prod_erase_lt_of_one_lt {γ : Type*} [DecidableEq α] [OrderedCommMonoid γ]
    [CovariantClass γ γ (· * ·) (· < ·)] {s : Finset α} {d : α} (hd : d ∈ s) {f : α → γ}
    (hdf : 1 < f d) : ∏ m ∈ s.erase d, f m < ∏ m ∈ s, f m 
goal: ∑ m ∈ s.erase d, f m < ∑ m ∈ s, f m

full_name: Finset.eq_zero_of_sum_eq_zero
code: /-- If a product is 1 and the function is 1 except possibly at one
point, it is 1 everywhere on the `Finset`. -/
@[to_additive "If a sum is 0 and the function is 0 except possibly at one
point, it is 0 everywhere on the `Finset`."]
theorem eq_one_of_prod_eq_one {s : Finset α} {f : α → β} {a : α} (hp : ∏ x ∈ s, f x = 1)
    (h1 : ∀ x ∈ s, x ≠ a → f x = 1) : ∀ x ∈ s, f x = 1 
goal: x ∈ s → f x = 0

full_name: Finset.eq_one_of_prod_eq_one
code: /-- If a product is 1 and the function is 1 except possibly at one
point, it is 1 everywhere on the `Finset`. -/
@[to_additive "If a sum is 0 and the function is 0 except possibly at one
point, it is 0 everywhere on the `Finset`."]
theorem eq_one_of_prod_eq_one {s : Finset α} {f : α → β} {a : α} (hp : ∏ x ∈ s, f x = 1)
    (h1 : ∀ x ∈ s, x ≠ a → f x = 1) : ∀ x ∈ s, f x = 1 
goal: x ∈ s → f x = 1

full_name: Finset.sum_boole_nsmul
code: @[to_additive sum_boole_nsmul]
theorem prod_pow_boole [DecidableEq α] (s : Finset α) (f : α → β) (a : α) :
    (∏ x ∈ s, f x ^ ite (a = x) 1 0) = ite (a ∈ s) (f a) 1 
goal: ∑ x ∈ s, (if a = x then 1 else 0) • f x = if a ∈ s then f a else 0

full_name: Finset.prod_pow_boole
code: @[to_additive sum_boole_nsmul]
theorem prod_pow_boole [DecidableEq α] (s : Finset α) (f : α → β) (a : α) :
    (∏ x ∈ s, f x ^ ite (a = x) 1 0) = ite (a ∈ s) (f a) 1 
goal: (∏ x ∈ s, f x ^ if a = x then 1 else 0) = if a ∈ s then f a else 1

full_name: Finset.prod_dvd_prod_of_dvd
code: theorem prod_dvd_prod_of_dvd {S : Finset α} (g1 g2 : α → β) (h : ∀ a ∈ S, g1 a ∣ g2 a) :
    S.prod g1 ∣ S.prod g2 
goal: S.prod g1 ∣ S.prod g2

full_name: Finset.prod_dvd_prod_of_subset
code: theorem prod_dvd_prod_of_subset {ι M : Type*} [CommMonoid M] (s t : Finset ι) (f : ι → M)
    (h : s ⊆ t) : (∏ i ∈ s, f i) ∣ ∏ i ∈ t, f i 
goal: ∏ i ∈ s, f i ∣ ∏ i ∈ t, f i

full_name: Finset.prod_mul_eq_prod_mul_of_exists
code: @[to_additive]
lemma prod_mul_eq_prod_mul_of_exists {s : Finset α} {f : α → β} {b₁ b₂ : β}
    (a : α) (ha : a ∈ s) (h : f a * b₁ = f a * b₂) :
    (∏ a ∈ s, f a) * b₁ = (∏ a ∈ s, f a) * b₂ 
goal: (∏ a ∈ s, f a) * b₁ = (∏ a ∈ s, f a) * b₂

full_name: Finset.sum_add_eq_sum_add_of_exists
code: @[to_additive]
lemma prod_mul_eq_prod_mul_of_exists {s : Finset α} {f : α → β} {b₁ b₂ : β}
    (a : α) (ha : a ∈ s) (h : f a * b₁ = f a * b₂) :
    (∏ a ∈ s, f a) * b₁ = (∏ a ∈ s, f a) * b₂ 
goal: ∑ a ∈ s, f a + b₁ = ∑ a ∈ s, f a + b₂

full_name: Finset.even_sum
code: @[to_additive]
lemma isSquare_prod {s : Finset ι} [CommMonoid α] (f : ι → α)
    (h : ∀ c ∈ s, IsSquare (f c)) : IsSquare (∏ i ∈ s, f i) 
goal: Even (∑ i ∈ s, f i)

full_name: Finset.isSquare_prod
code: @[to_additive]
lemma isSquare_prod {s : Finset ι} [CommMonoid α] (f : ι → α)
    (h : ∀ c ∈ s, IsSquare (f c)) : IsSquare (∏ i ∈ s, f i) 
goal: IsSquare (∏ i ∈ s, f i)

full_name: Finset.prod_sdiff_eq_prod_sdiff_iff
code: @[to_additive]
lemma prod_sdiff_eq_prod_sdiff_iff :
    ∏ i ∈ s \ t, f i = ∏ i ∈ t \ s, f i ↔ ∏ i ∈ s, f i = ∏ i ∈ t, f i 
goal: ∏ i ∈ s \ t, f i = ∏ i ∈ t \ s, f i ↔ ∏ i ∈ s, f i = ∏ i ∈ t, f i

full_name: Finset.sum_sdiff_eq_sum_sdiff_iff
code: @[to_additive]
lemma prod_sdiff_eq_prod_sdiff_iff :
    ∏ i ∈ s \ t, f i = ∏ i ∈ t \ s, f i ↔ ∏ i ∈ s, f i = ∏ i ∈ t, f i 
goal: ∑ i ∈ s \ t, f i = ∑ i ∈ t \ s, f i ↔ ∑ i ∈ s, f i = ∑ i ∈ t, f i

full_name: Finset.sum_sdiff_ne_sum_sdiff_iff
code: @[to_additive]
lemma prod_sdiff_ne_prod_sdiff_iff :
    ∏ i ∈ s \ t, f i ≠ ∏ i ∈ t \ s, f i ↔ ∏ i ∈ s, f i ≠ ∏ i ∈ t, f i 
goal: ∑ i ∈ s \ t, f i ≠ ∑ i ∈ t \ s, f i ↔ ∑ i ∈ s, f i ≠ ∑ i ∈ t, f i

full_name: Finset.prod_sdiff_ne_prod_sdiff_iff
code: @[to_additive]
lemma prod_sdiff_ne_prod_sdiff_iff :
    ∏ i ∈ s \ t, f i ≠ ∏ i ∈ t \ s, f i ↔ ∏ i ∈ s, f i ≠ ∏ i ∈ t, f i 
goal: ∏ i ∈ s \ t, f i ≠ ∏ i ∈ t \ s, f i ↔ ∏ i ∈ s, f i ≠ ∏ i ∈ t, f i

full_name: Finset.card_eq_sum_ones
code: theorem card_eq_sum_ones (s : Finset α) : s.card = ∑ x ∈ s, 1 
goal: s.card = ∑ x ∈ s, 1

full_name: Finset.sum_const_nat
code: theorem sum_const_nat {m : ℕ} {f : α → ℕ} (h₁ : ∀ x ∈ s, f x = m) :
    ∑ x ∈ s, f x = card s * m 
goal: ∑ x ∈ s, f x = s.card * m

full_name: Finset.sum_card_fiberwise_eq_card_filter
code: lemma sum_card_fiberwise_eq_card_filter {κ : Type*} [DecidableEq κ] (s : Finset ι) (t : Finset κ)
    (g : ι → κ) : ∑ j ∈ t, (s.filter fun i ↦ g i = j).card = (s.filter fun i ↦ g i ∈ t).card 
goal: ∑ j ∈ t, (Finset.filter (fun i => g i = j) s).card = (Finset.filter (fun i => g i ∈ t) s).card

full_name: Finset.card_filter
code: lemma card_filter (p) [DecidablePred p] (s : Finset α) :
    (filter p s).card = ∑ a ∈ s, ite (p a) 1 0 
goal: (Finset.filter p s).card = ∑ a ∈ s, if p a then 1 else 0

full_name: Finset.op_sum
code: /-- Moving to the opposite additive commutative monoid commutes with summing. -/
@[simp]
theorem op_sum [AddCommMonoid β] {s : Finset α} (f : α → β) :
    op (∑ x ∈ s, f x) = ∑ x ∈ s, op (f x) 
goal: MulOpposite.op (∑ x ∈ s, f x) = ∑ x ∈ s, MulOpposite.op (f x)

full_name: Finset.unop_sum
code: @[simp]
theorem unop_sum [AddCommMonoid β] {s : Finset α} (f : α → βᵐᵒᵖ) :
    unop (∑ x ∈ s, f x) = ∑ x ∈ s, unop (f x) 
goal: MulOpposite.unop (∑ x ∈ s, f x) = ∑ x ∈ s, MulOpposite.unop (f x)

full_name: Finset.prod_inv_distrib
code: @[to_additive (attr := simp)]
theorem prod_inv_distrib : (∏ x ∈ s, (f x)⁻¹) = (∏ x ∈ s, f x)⁻¹ 
goal: ∏ x ∈ s, (f x)⁻¹ = (∏ x ∈ s, f x)⁻¹

full_name: Finset.sum_neg_distrib
code: @[to_additive (attr := simp)]
theorem prod_inv_distrib : (∏ x ∈ s, (f x)⁻¹) = (∏ x ∈ s, f x)⁻¹ 
goal: ∑ x ∈ s, -f x = -∑ x ∈ s, f x

full_name: Finset.sum_sub_distrib
code: @[to_additive (attr := simp)]
theorem prod_div_distrib : ∏ x ∈ s, f x / g x = (∏ x ∈ s, f x) / ∏ x ∈ s, g x 
goal: ∑ x ∈ s, (f x - g x) = ∑ x ∈ s, f x - ∑ x ∈ s, g x

full_name: Finset.prod_div_distrib
code: @[to_additive (attr := simp)]
theorem prod_div_distrib : ∏ x ∈ s, f x / g x = (∏ x ∈ s, f x) / ∏ x ∈ s, g x 
goal: ∏ x ∈ s, f x / g x = (∏ x ∈ s, f x) / ∏ x ∈ s, g x

full_name: Finset.sum_zsmul
code: @[to_additive]
theorem prod_zpow (f : α → β) (s : Finset α) (n : ℤ) : ∏ a ∈ s, f a ^ n = (∏ a ∈ s, f a) ^ n 
goal: ∑ a ∈ s, n • f a = n • ∑ a ∈ s, f a

full_name: Finset.prod_zpow
code: @[to_additive]
theorem prod_zpow (f : α → β) (s : Finset α) (n : ℤ) : ∏ a ∈ s, f a ^ n = (∏ a ∈ s, f a) ^ n 
goal: ∏ a ∈ s, f a ^ n = (∏ a ∈ s, f a) ^ n

full_name: Finset.prod_sdiff_eq_div
code: @[to_additive (attr := simp)]
theorem prod_sdiff_eq_div (h : s₁ ⊆ s₂) :
    ∏ x ∈ s₂ \ s₁, f x = (∏ x ∈ s₂, f x) / ∏ x ∈ s₁, f x 
goal: ∏ x ∈ s₂ \ s₁, f x = (∏ x ∈ s₂, f x) / ∏ x ∈ s₁, f x

full_name: Finset.sum_sdiff_eq_sub
code: @[to_additive (attr := simp)]
theorem prod_sdiff_eq_div (h : s₁ ⊆ s₂) :
    ∏ x ∈ s₂ \ s₁, f x = (∏ x ∈ s₂, f x) / ∏ x ∈ s₁, f x 
goal: ∑ x ∈ s₂ \ s₁, f x = ∑ x ∈ s₂, f x - ∑ x ∈ s₁, f x

full_name: Finset.prod_sdiff_div_prod_sdiff
code: @[to_additive]
theorem prod_sdiff_div_prod_sdiff :
    (∏ x ∈ s₂ \ s₁, f x) / ∏ x ∈ s₁ \ s₂, f x = (∏ x ∈ s₂, f x) / ∏ x ∈ s₁, f x 
goal: (∏ x ∈ s₂ \ s₁, f x) / ∏ x ∈ s₁ \ s₂, f x = (∏ x ∈ s₂, f x) / ∏ x ∈ s₁, f x

full_name: Finset.sum_sdiff_sub_sum_sdiff
code: @[to_additive]
theorem prod_sdiff_div_prod_sdiff :
    (∏ x ∈ s₂ \ s₁, f x) / ∏ x ∈ s₁ \ s₂, f x = (∏ x ∈ s₂, f x) / ∏ x ∈ s₁, f x 
goal: ∑ x ∈ s₂ \ s₁, f x - ∑ x ∈ s₁ \ s₂, f x = ∑ x ∈ s₂, f x - ∑ x ∈ s₁, f x

full_name: Finset.prod_erase_eq_div
code: @[to_additive (attr := simp)]
theorem prod_erase_eq_div {a : α} (h : a ∈ s) :
    ∏ x ∈ s.erase a, f x = (∏ x ∈ s, f x) / f a 
goal: ∏ x ∈ s.erase a, f x = (∏ x ∈ s, f x) / f a

full_name: Finset.sum_erase_eq_sub
code: @[to_additive (attr := simp)]
theorem prod_erase_eq_div {a : α} (h : a ∈ s) :
    ∏ x ∈ s.erase a, f x = (∏ x ∈ s, f x) / f a 
goal: ∑ x ∈ s.erase a, f x = ∑ x ∈ s, f x - f a

full_name: Finset.card_sigma
code: @[simp]
theorem card_sigma {σ : α → Type*} (s : Finset α) (t : ∀ a, Finset (σ a)) :
    card (s.sigma t) = ∑ a ∈ s, card (t a) 
goal: (s.sigma t).card = ∑ a ∈ s, (t a).card

full_name: Finset.card_disjiUnion
code: @[simp]
theorem card_disjiUnion (s : Finset α) (t : α → Finset β) (h) :
    (s.disjiUnion t h).card = s.sum fun i => (t i).card 
goal: (s.disjiUnion t h).card = ∑ i ∈ s, (t i).card

full_name: Finset.card_biUnion
code: theorem card_biUnion [DecidableEq β] {s : Finset α} {t : α → Finset β}
    (h : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → Disjoint (t x) (t y)) :
    (s.biUnion t).card = ∑ u ∈ s, card (t u) 
goal: (s.biUnion t).card = ∑ u ∈ s, (t u).card

full_name: Finset.card_biUnion_le
code: theorem card_biUnion_le [DecidableEq β] {s : Finset α} {t : α → Finset β} :
    (s.biUnion t).card ≤ ∑ a ∈ s, (t a).card 
goal: (s.biUnion t).card ≤ ∑ a ∈ s, (t a).card

full_name: Finset.card_eq_sum_card_fiberwise
code: theorem card_eq_sum_card_fiberwise [DecidableEq β] {f : α → β} {s : Finset α} {t : Finset β}
    (H : ∀ x ∈ s, f x ∈ t) : s.card = ∑ a ∈ t, (s.filter fun x => f x = a).card 
goal: s.card = ∑ a ∈ t, (Finset.filter (fun x => f x = a) s).card

full_name: Finset.card_eq_sum_card_image
code: theorem card_eq_sum_card_image [DecidableEq β] (f : α → β) (s : Finset α) :
    s.card = ∑ a ∈ s.image f, (s.filter fun x => f x = a).card 
goal: s.card = ∑ a ∈ Finset.image f s, (Finset.filter (fun x => f x = a) s).card

full_name: Finset.mem_sum
code: theorem mem_sum {f : α → Multiset β} (s : Finset α) (b : β) :
    (b ∈ ∑ x ∈ s, f x) ↔ ∃ a ∈ s, b ∈ f a 
goal: b ∈ ∑ x ∈ s, f x ↔ ∃ a ∈ s, b ∈ f a

full_name: Finset.sum_unique_nonempty
code: @[to_additive]
theorem prod_unique_nonempty {α β : Type*} [CommMonoid β] [Unique α] (s : Finset α) (f : α → β)
    (h : s.Nonempty) : ∏ x ∈ s, f x = f default 
goal: ∑ x ∈ s, f x = f default

full_name: Finset.prod_unique_nonempty
code: @[to_additive]
theorem prod_unique_nonempty {α β : Type*} [CommMonoid β] [Unique α] (s : Finset α) (f : α → β)
    (h : s.Nonempty) : ∏ x ∈ s, f x = f default 
goal: ∏ x ∈ s, f x = f default

full_name: Finset.sum_nat_mod
code: theorem sum_nat_mod (s : Finset α) (n : ℕ) (f : α → ℕ) :
    (∑ i ∈ s, f i) % n = (∑ i ∈ s, f i % n) % n 
goal: (∑ i ∈ s, f i) % n = (∑ i ∈ s, f i % n) % n

full_name: Finset.prod_nat_mod
code: theorem prod_nat_mod (s : Finset α) (n : ℕ) (f : α → ℕ) :
    (∏ i ∈ s, f i) % n = (∏ i ∈ s, f i % n) % n 
goal: (∏ i ∈ s, f i) % n = (∏ i ∈ s, f i % n) % n

full_name: Finset.sum_int_mod
code: theorem sum_int_mod (s : Finset α) (n : ℤ) (f : α → ℤ) :
    (∑ i ∈ s, f i) % n = (∑ i ∈ s, f i % n) % n 
goal: (∑ i ∈ s, f i) % n = (∑ i ∈ s, f i % n) % n

full_name: Finset.prod_int_mod
code: theorem prod_int_mod (s : Finset α) (n : ℤ) (f : α → ℤ) :
    (∏ i ∈ s, f i) % n = (∏ i ∈ s, f i % n) % n 
goal: (∏ i ∈ s, f i) % n = (∏ i ∈ s, f i % n) % n

full_name: Fintype.prod_bijective
code: /-- `Fintype.prod_bijective` is a variant of `Finset.prod_bij` that accepts `Function.Bijective`.

See `Function.Bijective.prod_comp` for a version without `h`. -/
@[to_additive "`Fintype.sum_bijective` is a variant of `Finset.sum_bij` that accepts
`Function.Bijective`.

See `Function.Bijective.sum_comp` for a version without `h`. "]
lemma prod_bijective (e : ι → κ) (he : e.Bijective) (f : ι → α) (g : κ → α)
    (h : ∀ x, f x = g (e x)) : ∏ x, f x = ∏ x, g x 
goal: ∏ x : ι, f x = ∏ x : κ, g x

full_name: Fintype.sum_bijective
code: /-- `Fintype.prod_bijective` is a variant of `Finset.prod_bij` that accepts `Function.Bijective`.

See `Function.Bijective.prod_comp` for a version without `h`. -/
@[to_additive "`Fintype.sum_bijective` is a variant of `Finset.sum_bij` that accepts
`Function.Bijective`.

See `Function.Bijective.sum_comp` for a version without `h`. "]
lemma prod_bijective (e : ι → κ) (he : e.Bijective) (f : ι → α) (g : κ → α)
    (h : ∀ x, f x = g (e x)) : ∏ x, f x = ∏ x, g x 
goal: ∑ x : ι, f x = ∑ x : κ, g x

full_name: Fintype.sum_equiv
code: /-- `Fintype.prod_equiv` is a specialization of `Finset.prod_bij` that
automatically fills in most arguments.

See `Equiv.prod_comp` for a version without `h`.
-/
@[to_additive "`Fintype.sum_equiv` is a specialization of `Finset.sum_bij` that
automatically fills in most arguments.

See `Equiv.sum_comp` for a version without `h`."]
lemma prod_equiv (e : ι ≃ κ) (f : ι → α) (g : κ → α) (h : ∀ x, f x = g (e x)) :
    ∏ x, f x = ∏ x, g x 
goal: ∑ x : ι, f x = ∑ x : κ, g x

full_name: Fintype.prod_equiv
code: /-- `Fintype.prod_equiv` is a specialization of `Finset.prod_bij` that
automatically fills in most arguments.

See `Equiv.prod_comp` for a version without `h`.
-/
@[to_additive "`Fintype.sum_equiv` is a specialization of `Finset.sum_bij` that
automatically fills in most arguments.

See `Equiv.sum_comp` for a version without `h`."]
lemma prod_equiv (e : ι ≃ κ) (f : ι → α) (g : κ → α) (h : ∀ x, f x = g (e x)) :
    ∏ x, f x = ∏ x, g x 
goal: ∏ x : ι, f x = ∏ x : κ, g x

full_name: Function.Bijective.prod_comp
code: @[to_additive]
lemma _root_.Function.Bijective.prod_comp {e : ι → κ} (he : e.Bijective) (g : κ → α) :
    ∏ i, g (e i) = ∏ i, g i 
goal: ∏ i : ι, g (e i) = ∏ i : κ, g i

full_name: Function.Bijective.sum_comp
code: @[to_additive]
lemma _root_.Function.Bijective.prod_comp {e : ι → κ} (he : e.Bijective) (g : κ → α) :
    ∏ i, g (e i) = ∏ i, g i 
goal: ∑ i : ι, g (e i) = ∑ i : κ, g i

full_name: Equiv.sum_comp
code: @[to_additive]
lemma _root_.Equiv.prod_comp (e : ι ≃ κ) (g : κ → α) : ∏ i, g (e i) = ∏ i, g i 
goal: ∑ i : ι, g (e i) = ∑ i : κ, g i

full_name: Equiv.prod_comp
code: @[to_additive]
lemma _root_.Equiv.prod_comp (e : ι ≃ κ) (g : κ → α) : ∏ i, g (e i) = ∏ i, g i 
goal: ∏ i : ι, g (e i) = ∏ i : κ, g i

full_name: Fintype.prod_of_injective
code: @[to_additive]
lemma prod_of_injective (e : ι → κ) (he : Injective e) (f : ι → α) (g : κ → α)
    (h' : ∀ i ∉ Set.range e, g i = 1) (h : ∀ i, f i = g (e i)) : ∏ i, f i = ∏ j, g j 
goal: ∏ i : ι, f i = ∏ j : κ, g j

full_name: Fintype.sum_of_injective
code: @[to_additive]
lemma prod_of_injective (e : ι → κ) (he : Injective e) (f : ι → α) (g : κ → α)
    (h' : ∀ i ∉ Set.range e, g i = 1) (h : ∀ i, f i = g (e i)) : ∏ i, f i = ∏ j, g j 
goal: ∑ i : ι, f i = ∑ j : κ, g j

full_name: Fintype.sum_fiberwise
code: @[to_additive]
lemma prod_fiberwise [DecidableEq κ] (g : ι → κ) (f : ι → α) :
    ∏ j, ∏ i : {i // g i = j}, f i = ∏ i, f i 
goal: ∑ j : κ, ∑ i : { i // g i = j }, f ↑i = ∑ i : ι, f i

full_name: Fintype.prod_fiberwise
code: @[to_additive]
lemma prod_fiberwise [DecidableEq κ] (g : ι → κ) (f : ι → α) :
    ∏ j, ∏ i : {i // g i = j}, f i = ∏ i, f i 
goal: ∏ j : κ, ∏ i : { i // g i = j }, f ↑i = ∏ i : ι, f i

full_name: Fintype.sum_fiberwise'
code: @[to_additive]
lemma prod_fiberwise' [DecidableEq κ] (g : ι → κ) (f : κ → α) :
    ∏ j, ∏ _i : {i // g i = j}, f j = ∏ i, f (g i) 
goal: ∑ j : κ, ∑ _i : { i // g i = j }, f j = ∑ i : ι, f (g i)

full_name: Fintype.prod_fiberwise'
code: @[to_additive]
lemma prod_fiberwise' [DecidableEq κ] (g : ι → κ) (f : κ → α) :
    ∏ j, ∏ _i : {i // g i = j}, f j = ∏ i, f (g i) 
goal: ∏ j : κ, ∏ _i : { i // g i = j }, f j = ∏ i : ι, f (g i)

full_name: Fintype.prod_unique
code: @[to_additive]
theorem prod_unique {α β : Type*} [CommMonoid β] [Unique α] [Fintype α] (f : α → β) :
    ∏ x : α, f x = f default 
goal: ∏ x : α, f x = f default

full_name: Fintype.sum_unique
code: @[to_additive]
theorem prod_unique {α β : Type*} [CommMonoid β] [Unique α] [Fintype α] (f : α → β) :
    ∏ x : α, f x = f default 
goal: ∑ x : α, f x = f default

full_name: Fintype.prod_empty
code: @[to_additive]
theorem prod_empty {α β : Type*} [CommMonoid β] [IsEmpty α] [Fintype α] (f : α → β) :
    ∏ x : α, f x = 1 
goal: ∏ x : α, f x = 1

full_name: Fintype.sum_empty
code: @[to_additive]
theorem prod_empty {α β : Type*} [CommMonoid β] [IsEmpty α] [Fintype α] (f : α → β) :
    ∏ x : α, f x = 1 
goal: ∑ x : α, f x = 0

full_name: Fintype.sum_subsingleton
code: @[to_additive]
theorem prod_subsingleton {α β : Type*} [CommMonoid β] [Subsingleton α] [Fintype α] (f : α → β)
    (a : α) : ∏ x : α, f x = f a 
goal: ∑ x : α, f x = f a

full_name: Fintype.prod_subsingleton
code: @[to_additive]
theorem prod_subsingleton {α β : Type*} [CommMonoid β] [Subsingleton α] [Fintype α] (f : α → β)
    (a : α) : ∏ x : α, f x = f a 
goal: ∏ x : α, f x = f a

full_name: Fintype.prod_subtype_mul_prod_subtype
code: @[to_additive]
theorem prod_subtype_mul_prod_subtype {α β : Type*} [Fintype α] [CommMonoid β] (p : α → Prop)
    (f : α → β) [DecidablePred p] :
    (∏ i : { x // p x }, f i) * ∏ i : { x // ¬p x }, f i = ∏ i, f i 
goal: (∏ i : { x // p x }, f ↑i) * ∏ i : { x // ¬p x }, f ↑i = ∏ i : α, f i

full_name: Fintype.sum_subtype_add_sum_subtype
code: @[to_additive]
theorem prod_subtype_mul_prod_subtype {α β : Type*} [Fintype α] [CommMonoid β] (p : α → Prop)
    (f : α → β) [DecidablePred p] :
    (∏ i : { x // p x }, f i) * ∏ i : { x // ¬p x }, f i = ∏ i, f i 
goal: ∑ i : { x // p x }, f ↑i + ∑ i : { x // ¬p x }, f ↑i = ∑ i : α, f i

full_name: Fintype.prod_subset
code: @[to_additive] lemma prod_subset {s : Finset ι} {f : ι → α} (h : ∀ i, f i ≠ 1 → i ∈ s) :
    ∏ i ∈ s, f i = ∏ i, f i 
goal: ∏ i ∈ s, f i = ∏ i : ι, f i

full_name: Fintype.sum_subset
code: @[to_additive] lemma prod_subset {s : Finset ι} {f : ι → α} (h : ∀ i, f i ≠ 1 → i ∈ s) :
    ∏ i ∈ s, f i = ∏ i, f i 
goal: ∑ i ∈ s, f i = ∑ i : ι, f i

full_name: Fintype.prod_ite_eq_ite_exists
code: @[to_additive]
lemma prod_ite_eq_ite_exists (p : ι → Prop) [DecidablePred p] (h : ∀ i j, p i → p j → i = j)
    (a : α) : ∏ i, ite (p i) a 1 = ite (∃ i, p i) a 1 
goal: (∏ i : ι, if p i then a else 1) = if ∃ i, p i then a else 1

full_name: Fintype.sum_ite_eq_ite_exists
code: @[to_additive]
lemma prod_ite_eq_ite_exists (p : ι → Prop) [DecidablePred p] (h : ∀ i j, p i → p j → i = j)
    (a : α) : ∏ i, ite (p i) a 1 = ite (∃ i, p i) a 1 
goal: (∑ i : ι, if p i then a else 0) = if ∃ i, p i then a else 0

full_name: Fintype.sum_dite_eq
code: /-- See also `Finset.prod_dite_eq`. -/
@[to_additive "See also `Finset.sum_dite_eq`."] lemma prod_dite_eq (i : ι) (f : ∀ j, i = j → α) :
    ∏ j, (if h : i = j then f j h else 1) = f i rfl 
goal: (∑ j : ι, if h : i = j then f j h else 0) = f i ⋯

full_name: Fintype.prod_dite_eq
code: /-- See also `Finset.prod_dite_eq`. -/
@[to_additive "See also `Finset.sum_dite_eq`."] lemma prod_dite_eq (i : ι) (f : ∀ j, i = j → α) :
    ∏ j, (if h : i = j then f j h else 1) = f i rfl 
goal: (∏ j : ι, if h : i = j then f j h else 1) = f i ⋯

full_name: Fintype.sum_dite_eq'
code: /-- See also `Finset.prod_dite_eq'`. -/
@[to_additive "See also `Finset.sum_dite_eq'`."] lemma prod_dite_eq' (i : ι) (f : ∀ j, j = i → α) :
    ∏ j, (if h : j = i then f j h else 1) = f i rfl 
goal: (∑ j : ι, if h : j = i then f j h else 0) = f i ⋯

full_name: Fintype.prod_dite_eq'
code: /-- See also `Finset.prod_dite_eq'`. -/
@[to_additive "See also `Finset.sum_dite_eq'`."] lemma prod_dite_eq' (i : ι) (f : ∀ j, j = i → α) :
    ∏ j, (if h : j = i then f j h else 1) = f i rfl 
goal: (∏ j : ι, if h : j = i then f j h else 1) = f i ⋯

full_name: Fintype.prod_ite_eq
code: /-- See also `Finset.prod_ite_eq`. -/
@[to_additive "See also `Finset.sum_ite_eq`."]
lemma prod_ite_eq (i : ι) (f : ι → α) : ∏ j, (if i = j then f j else 1) = f i 
goal: (∏ j : ι, if i = j then f j else 1) = f i

full_name: Fintype.sum_ite_eq
code: /-- See also `Finset.prod_ite_eq`. -/
@[to_additive "See also `Finset.sum_ite_eq`."]
lemma prod_ite_eq (i : ι) (f : ι → α) : ∏ j, (if i = j then f j else 1) = f i 
goal: (∑ j : ι, if i = j then f j else 0) = f i

full_name: Fintype.prod_ite_eq'
code: /-- See also `Finset.prod_ite_eq'`. -/
@[to_additive "See also `Finset.sum_ite_eq'`."]
lemma prod_ite_eq' (i : ι) (f : ι → α) : ∏ j, (if j = i then f j else 1) = f i 
goal: (∏ j : ι, if j = i then f j else 1) = f i

full_name: Fintype.sum_ite_eq'
code: /-- See also `Finset.prod_ite_eq'`. -/
@[to_additive "See also `Finset.sum_ite_eq'`."]
lemma prod_ite_eq' (i : ι) (f : ι → α) : ∏ j, (if j = i then f j else 1) = f i 
goal: (∑ j : ι, if j = i then f j else 0) = f i

full_name: Fintype.prod_pi_mulSingle
code: /-- See also `Finset.prod_pi_mulSingle`. -/
@[to_additive "See also `Finset.sum_pi_single`."]
lemma prod_pi_mulSingle {α : ι → Type*} [∀ i, CommMonoid (α i)] (i : ι) (f : ∀ i, α i) :
    ∏ j, Pi.mulSingle j (f j) i = f i 
goal: ∏ j : ι, Pi.mulSingle j (f j) i = f i

full_name: Fintype.sum_pi_single
code: /-- See also `Finset.prod_pi_mulSingle`. -/
@[to_additive "See also `Finset.sum_pi_single`."]
lemma prod_pi_mulSingle {α : ι → Type*} [∀ i, CommMonoid (α i)] (i : ι) (f : ∀ i, α i) :
    ∏ j, Pi.mulSingle j (f j) i = f i 
goal: ∑ j : ι, Pi.single j (f j) i = f i

full_name: Fintype.sum_pi_single'
code: /-- See also `Finset.prod_pi_mulSingle'`. -/
@[to_additive "See also `Finset.sum_pi_single'`."]
lemma prod_pi_mulSingle' (i : ι) (a : α) : ∏ j, Pi.mulSingle i a j = a 
goal: ∑ j : ι, Pi.single i a j = a

full_name: Fintype.prod_pi_mulSingle'
code: /-- See also `Finset.prod_pi_mulSingle'`. -/
@[to_additive "See also `Finset.sum_pi_single'`."]
lemma prod_pi_mulSingle' (i : ι) (a : α) : ∏ j, Pi.mulSingle i a j = a 
goal: ∏ j : ι, Pi.mulSingle i a j = a

full_name: Finset.prod_attach_univ
code: @[to_additive (attr := simp)]
lemma prod_attach_univ [Fintype ι] (f : {i // i ∈ @univ ι _} → α) :
    ∏ i ∈ univ.attach, f i = ∏ i, f ⟨i, mem_univ _⟩ 
goal: ∏ i ∈ Finset.univ.attach, f i = ∏ i : ι, f ⟨i, ⋯⟩

full_name: Finset.sum_attach_univ
code: @[to_additive (attr := simp)]
lemma prod_attach_univ [Fintype ι] (f : {i // i ∈ @univ ι _} → α) :
    ∏ i ∈ univ.attach, f i = ∏ i, f ⟨i, mem_univ _⟩ 
goal: ∑ i ∈ Finset.univ.attach, f i = ∑ i : ι, f ⟨i, ⋯⟩

full_name: Finset.prod_erase_attach
code: @[to_additive]
theorem prod_erase_attach [DecidableEq ι] {s : Finset ι} (f : ι → α) (i : ↑s) :
    ∏ j ∈ s.attach.erase i, f ↑j = ∏ j ∈ s.erase ↑i, f j 
goal: ∏ j ∈ s.attach.erase i, f ↑j = ∏ j ∈ s.erase ↑i, f j

full_name: Finset.sum_erase_attach
code: @[to_additive]
theorem prod_erase_attach [DecidableEq ι] {s : Finset ι} (f : ι → α) (i : ↑s) :
    ∏ j ∈ s.attach.erase i, f ↑j = ∏ j ∈ s.erase ↑i, f j 
goal: ∑ j ∈ s.attach.erase i, f ↑j = ∑ j ∈ s.erase ↑i, f j

full_name: List.sum_toFinset
code: @[to_additive]
theorem prod_toFinset {M : Type*} [DecidableEq α] [CommMonoid M] (f : α → M) :
    ∀ {l : List α} (_hl : l.Nodup), l.toFinset.prod f = (l.map f).prod
  
goal: l.toFinset.sum f = (List.map f l).sum

full_name: List.prod_toFinset
code: @[to_additive]
theorem prod_toFinset {M : Type*} [DecidableEq α] [CommMonoid M] (f : α → M) :
    ∀ {l : List α} (_hl : l.Nodup), l.toFinset.prod f = (l.map f).prod
  
goal: l.toFinset.prod f = (List.map f l).prod

full_name: List.sum_toFinset_count_eq_length
code: @[simp]
theorem sum_toFinset_count_eq_length [DecidableEq α] (l : List α) :
    ∑ a in l.toFinset, l.count a = l.length 
goal: ∑ a ∈ l.toFinset, List.count a l = l.length

full_name: Multiset.disjoint_list_sum_left
code: theorem disjoint_list_sum_left {a : Multiset α} {l : List (Multiset α)} :
    Multiset.Disjoint l.sum a ↔ ∀ b ∈ l, Multiset.Disjoint b a 
goal: l.sum.Disjoint a ↔ ∀ b ∈ l, b.Disjoint a

full_name: Multiset.disjoint_list_sum_right
code: theorem disjoint_list_sum_right {a : Multiset α} {l : List (Multiset α)} :
    Multiset.Disjoint a l.sum ↔ ∀ b ∈ l, Multiset.Disjoint a b 
goal: a.Disjoint l.sum ↔ ∀ b ∈ l, a.Disjoint b

full_name: Multiset.disjoint_sum_left
code: theorem disjoint_sum_left {a : Multiset α} {i : Multiset (Multiset α)} :
    Multiset.Disjoint i.sum a ↔ ∀ b ∈ i, Multiset.Disjoint b a 
goal: i.sum.Disjoint a ↔ ∀ b ∈ i, b.Disjoint a

full_name: Multiset.disjoint_sum_right
code: theorem disjoint_sum_right {a : Multiset α} {i : Multiset (Multiset α)} :
    Multiset.Disjoint a i.sum ↔ ∀ b ∈ i, Multiset.Disjoint a b 
goal: a.Disjoint i.sum ↔ ∀ b ∈ i, a.Disjoint b

full_name: Multiset.disjoint_finset_sum_left
code: theorem disjoint_finset_sum_left {β : Type*} {i : Finset β} {f : β → Multiset α} {a : Multiset α} :
    Multiset.Disjoint (i.sum f) a ↔ ∀ b ∈ i, Multiset.Disjoint (f b) a 
goal: (i.sum f).Disjoint a ↔ ∀ b ∈ i, (f b).Disjoint a

full_name: Multiset.disjoint_finset_sum_right
code: theorem disjoint_finset_sum_right {β : Type*} {i : Finset β} {f : β → Multiset α}
    {a : Multiset α} : Multiset.Disjoint a (i.sum f) ↔ ∀ b ∈ i, Multiset.Disjoint a (f b) 
goal: a.Disjoint (i.sum f) ↔ ∀ b ∈ i, a.Disjoint (f b)

full_name: Multiset.mem_sum
code: @[simp]
lemma mem_sum {s : Finset ι} {m : ι → Multiset α} : a ∈ ∑ i ∈ s, m i ↔ ∃ i ∈ s, a ∈ m i 
goal: a ∈ ∑ i ∈ s, m i ↔ ∃ i ∈ s, a ∈ m i

full_name: Multiset.toFinset_sum_count_eq
code: theorem toFinset_sum_count_eq (s : Multiset α) : ∑ a in s.toFinset, s.count a = card s 
goal: ∑ a ∈ s.toFinset, Multiset.count a s = Multiset.card s

full_name: Multiset.sum_count_eq_card
code: @[simp] lemma sum_count_eq_card {s : Finset α} {m : Multiset α} (hms : ∀ a ∈ m, a ∈ s) :
    ∑ a ∈ s, m.count a = card m 
goal: ∑ a ∈ s, Multiset.count a m = Multiset.card m

full_name: Multiset.sum_count_eq
code: @[deprecated sum_count_eq_card (since := "2024-07-21")]
theorem sum_count_eq [Fintype α] (s : Multiset α) : ∑ a, s.count a = Multiset.card s 
goal: ∑ a : α, Multiset.count a s = Multiset.card s

full_name: Multiset.count_sum'
code: theorem count_sum' {s : Finset β} {a : α} {f : β → Multiset α} :
    count a (∑ x ∈ s, f x) = ∑ x ∈ s, count a (f x) 
goal: Multiset.count a (∑ x ∈ s, f x) = ∑ x ∈ s, Multiset.count a (f x)

full_name: Multiset.toFinset_sum_count_nsmul_eq
code: @[simp]
theorem toFinset_sum_count_nsmul_eq (s : Multiset α) :
    ∑ a ∈ s.toFinset, s.count a • {a} = s 
goal: ∑ a ∈ s.toFinset, Multiset.count a s • {a} = s

full_name: Multiset.exists_smul_of_dvd_count
code: theorem exists_smul_of_dvd_count (s : Multiset α) {k : ℕ}
    (h : ∀ a : α, a ∈ s → k ∣ Multiset.count a s) : ∃ u : Multiset α, s = k • u 
goal: ∃ u, s = k • u

full_name: Multiset.toFinset_prod_dvd_prod
code: theorem toFinset_prod_dvd_prod [CommMonoid α] (S : Multiset α) : S.toFinset.prod id ∣ S.prod 
goal: S.toFinset.prod id ∣ S.prod

full_name: Multiset.prod_sum
code: @[to_additive]
theorem prod_sum {α : Type*} {ι : Type*} [CommMonoid α] (f : ι → Multiset α) (s : Finset ι) :
    (∑ x ∈ s, f x).prod = ∏ x ∈ s, (f x).prod 
goal: (∑ x ∈ s, f x).prod = ∏ x ∈ s, (f x).prod

full_name: Multiset.sum_sum
code: @[to_additive]
theorem prod_sum {α : Type*} {ι : Type*} [CommMonoid α] (f : ι → Multiset α) (s : Finset ι) :
    (∑ x ∈ s, f x).prod = ∏ x ∈ s, (f x).prod 
goal: (∑ x ∈ s, f x).sum = ∑ x ∈ s, (f x).sum

full_name: Units.coe_prod
code: @[simp, norm_cast]
theorem Units.coe_prod {M : Type*} [CommMonoid M] (f : α → Mˣ) (s : Finset α) :
    (↑(∏ i ∈ s, f i) : M) = ∏ i ∈ s, (f i : M) 
goal: ↑(∏ i ∈ s, f i) = ∏ i ∈ s, ↑(f i)

full_name: nat_abs_sum_le
code: theorem nat_abs_sum_le {ι : Type*} (s : Finset ι) (f : ι → ℤ) :
    (∑ i ∈ s, f i).natAbs ≤ ∑ i ∈ s, (f i).natAbs 
goal: (∑ i ∈ s, f i).natAbs ≤ ∑ i ∈ s, (f i).natAbs

full_name: ofMul_list_prod
code: @[simp]
theorem ofMul_list_prod (s : List α) : ofMul s.prod = (s.map ofMul).sum 
goal: Additive.ofMul s.prod = (List.map (⇑Additive.ofMul) s).sum

full_name: toMul_list_sum
code: @[simp]
theorem toMul_list_sum (s : List (Additive α)) : toMul s.sum = (s.map toMul).prod 
goal: Additive.toMul s.sum = (List.map (⇑Additive.toMul) s).prod

full_name: ofAdd_list_prod
code: @[simp]
theorem ofAdd_list_prod (s : List α) : ofAdd s.sum = (s.map ofAdd).prod 
goal: Multiplicative.ofAdd s.sum = (List.map (⇑Multiplicative.ofAdd) s).prod

full_name: toAdd_list_sum
code: @[simp]
theorem toAdd_list_sum (s : List (Multiplicative α)) : toAdd s.prod = (s.map toAdd).sum 
goal: Multiplicative.toAdd s.prod = (List.map (⇑Multiplicative.toAdd) s).sum

full_name: ofMul_multiset_prod
code: @[simp]
theorem ofMul_multiset_prod (s : Multiset α) : ofMul s.prod = (s.map ofMul).sum 
goal: Additive.ofMul s.prod = (Multiset.map (⇑Additive.ofMul) s).sum

full_name: toMul_multiset_sum
code: @[simp]
theorem toMul_multiset_sum (s : Multiset (Additive α)) : toMul s.sum = (s.map toMul).prod 
goal: Additive.toMul s.sum = (Multiset.map (⇑Additive.toMul) s).prod

full_name: ofMul_prod
code: @[simp]
theorem ofMul_prod (s : Finset ι) (f : ι → α) : ofMul (∏ i ∈ s, f i) = ∑ i ∈ s, ofMul (f i) 
goal: Additive.ofMul (∏ i ∈ s, f i) = ∑ i ∈ s, Additive.ofMul (f i)

full_name: toMul_sum
code: @[simp]
theorem toMul_sum (s : Finset ι) (f : ι → Additive α) :
    toMul (∑ i ∈ s, f i) = ∏ i ∈ s, toMul (f i) 
goal: Additive.toMul (∑ i ∈ s, f i) = ∏ i ∈ s, Additive.toMul (f i)

full_name: ofAdd_multiset_prod
code: @[simp]
theorem ofAdd_multiset_prod (s : Multiset α) : ofAdd s.sum = (s.map ofAdd).prod 
goal: Multiplicative.ofAdd s.sum = (Multiset.map (⇑Multiplicative.ofAdd) s).prod

full_name: toAdd_multiset_sum
code: @[simp]
theorem toAdd_multiset_sum (s : Multiset (Multiplicative α)) :
    toAdd s.prod = (s.map toAdd).sum 
goal: Multiplicative.toAdd s.prod = (Multiset.map (⇑Multiplicative.toAdd) s).sum

full_name: ofAdd_sum
code: @[simp]
theorem ofAdd_sum (s : Finset ι) (f : ι → α) : ofAdd (∑ i ∈ s, f i) = ∏ i ∈ s, ofAdd (f i) 
goal: Multiplicative.ofAdd (∑ i ∈ s, f i) = ∏ i ∈ s, Multiplicative.ofAdd (f i)

full_name: toAdd_prod
code: @[simp]
theorem toAdd_prod (s : Finset ι) (f : ι → Multiplicative α) :
    toAdd (∏ i ∈ s, f i) = ∑ i ∈ s, toAdd (f i) 
goal: Multiplicative.toAdd (∏ i ∈ s, f i) = ∑ i ∈ s, Multiplicative.toAdd (f i)

full_name: Finset.sum_sym2_filter_not_isDiag
code: theorem Finset.sum_sym2_filter_not_isDiag {ι α} [LinearOrder ι] [AddCommMonoid α]
    (s : Finset ι) (p : Sym2 ι → α) :
    ∑ i in s.sym2.filter (¬ ·.IsDiag), p i =
      ∑ i in s.offDiag.filter (fun i => i.1 < i.2), p s(i.1, i.2) 
goal: ∑ i ∈ Finset.filter (fun x => ¬x.IsDiag) s.sym2, p i = ∑ i ∈ Finset.filter (fun i => i.1 < i.2) s.offDiag, p s(i.1, i.2)