Documentation

Mathlib.Algebra.BigOperators.Group.Finset.Defs

Big operators #

In this file we define products and sums indexed by finite sets (specifically, Finset).

Notation #

We introduce the following notation.

Let s be a Finset ι, and f : ι → β a function.

Implementation Notes #

The first arguments in all definitions and lemmas is the codomain of the function of the big operator. This is necessary for the heuristic in @[to_additive]. See the documentation of to_additive.attr for more information.

def Finset.prod {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιM) :
M

∏ 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.

Instances For
    def Finset.sum {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιM) :
    M

    ∑ 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.

    Instances For
      @[simp]
      theorem Finset.prod_mk {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Multiset ι) (hs : s.Nodup) (f : ιM) :
      { val := s, nodup := hs }.prod f = (Multiset.map f s).prod
      @[simp]
      theorem Finset.sum_mk {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Multiset ι) (hs : s.Nodup) (f : ιM) :
      { val := s, nodup := hs }.sum f = (Multiset.map f s).sum
      @[simp]
      theorem Finset.prod_val {M : Type u_3} [CommMonoid M] (s : Finset M) :
      s.val.prod = s.prod id
      @[simp]
      theorem Finset.sum_val {M : Type u_3} [AddCommMonoid M] (s : Finset M) :
      s.val.sum = s.sum id
      def LibraryNote.operator_precedence_of_big_operators :
      Batteries.Util.LibraryNote

      There is no established mathematical convention for the operator precedence of big operators like and . We will have to make a choice.

      Online discussions, such as https://math.stackexchange.com/q/185538/30839 seem to suggest that and should have the same precedence, and that this should be somewhere between * and +. The latter have precedence levels 70 and 65 respectively, and we therefore choose the level 67.

      In practice, this means that parentheses should be placed as follows:

      ∑ k ∈ K, (a k + b k) = ∑ k ∈ K, a k + ∑ k ∈ K, b k →
        ∏ k ∈ K, a k * b k = (∏ k ∈ K, a k) * (∏ k ∈ K, b k)
      

      (Example taken from page 490 of Knuth's Concrete Mathematics.)

      Instances For
        def BigOperators.bigOpBinder :
        Lean.ParserDescr

        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.

        Instances For

          A BigOperator binder in parentheses

          Instances For

            A list of parenthesized binders

            Instances For
              def BigOperators.bigOpBinders :
              Lean.ParserDescr

              A single (unparenthesized) binder, or a list of parenthesized binders

              Instances For
                def BigOperators.processBigOpBinder (processed : Array (Lean.Term × Lean.Term)) (binder : Lean.TSyntax `BigOperators.bigOpBinder) :
                Lean.MacroM (Array (Lean.Term × Lean.Term))

                Collects additional binder/Finset pairs for the given bigOpBinder.

                Note: this is not extensible at the moment, unlike the usual bigOpBinder expansions.

                Instances For
                  def BigOperators.processBigOpBinders (binders : Lean.TSyntax `BigOperators.bigOpBinders) :
                  Lean.MacroM (Array (Lean.Term × Lean.Term))

                  Collects the binder/Finset pairs for the given bigOpBinders.

                  Instances For
                    def BigOperators.bigOpBindersPattern (processed : Array (Lean.Term × Lean.Term)) :
                    Lean.MacroM Lean.Term

                    Collects the binderIdents into a ⟨...⟩ expression.

                    Instances For
                      def BigOperators.bigOpBindersProd (processed : Array (Lean.Term × Lean.Term)) :
                      Lean.MacroM Lean.Term

                      Collects the terms into a product of sets.

                      Instances For
                        def BigOperators.bigsum :
                        Lean.ParserDescr
                        • ∑ 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 with h : p x, f x h is notation for Finset.sum s fun x ↦ if h : p x then f x h else 0.
                        • ∑ (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" (ident ":")? term)? "," term

                        Instances For
                          def BigOperators.bigprod :
                          Lean.ParserDescr
                          • ∏ 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 with h : p x, f x h is notation for Finset.prod s fun x ↦ if h : p x then f x h else 1.
                          • ∏ (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" (ident ":")? term)? "," term

                          Instances For
                            def BigOperators.delabFinsetProd :
                            Lean.PrettyPrinter.Delaborator.Delab

                            Delaborator for Finset.prod. The pp.funBinderTypes option controls whether to show the domain type when the product is over Finset.univ.

                            Instances For
                              def BigOperators.delabFinsetSum :
                              Lean.PrettyPrinter.Delaborator.Delab

                              Delaborator for Finset.sum. The pp.funBinderTypes option controls whether to show the domain type when the sum is over Finset.univ.

                              Instances For
                                theorem Finset.prod_eq_multiset_prod {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιM) :
                                xs, f x = (Multiset.map f s.val).prod
                                theorem Finset.sum_eq_multiset_sum {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιM) :
                                xs, f x = (Multiset.map f s.val).sum
                                @[simp]
                                theorem Finset.prod_map_val {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιM) :
                                (Multiset.map f s.val).prod = as, f a
                                @[simp]
                                theorem Finset.sum_map_val {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιM) :
                                (Multiset.map f s.val).sum = as, f a
                                @[simp]
                                theorem Finset.sum_multiset_singleton {ι : Type u_1} (s : Finset ι) :
                                as, {a} = s.val
                                @[simp]
                                theorem map_prod {ι : Type u_1} {M : Type u_3} {N : Type u_4} [CommMonoid M] [CommMonoid N] {G : Type u_7} [FunLike G M N] [MonoidHomClass G M N] (g : G) (f : ιM) (s : Finset ι) :
                                g (∏ xs, f x) = xs, g (f x)
                                @[simp]
                                theorem map_sum {ι : Type u_1} {M : Type u_3} {N : Type u_4} [AddCommMonoid M] [AddCommMonoid N] {G : Type u_7} [FunLike G M N] [AddMonoidHomClass G M N] (g : G) (f : ιM) (s : Finset ι) :
                                g (∑ xs, f x) = xs, g (f x)
                                @[simp]
                                theorem Finset.prod_empty {ι : Type u_1} {M : Type u_3} {f : ιM} [CommMonoid M] :
                                x, f x = 1
                                @[simp]
                                theorem Finset.sum_empty {ι : Type u_1} {M : Type u_3} {f : ιM} [AddCommMonoid M] :
                                x, f x = 0
                                theorem Finset.prod_empty' {ι : Type u_1} {M : Type u_3} [CommMonoid M] :
                                .prod = fun (x : ιM) => 1

                                Variant of prod_empty not applied to a function.

                                theorem Finset.sum_empty' {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] :
                                .sum = fun (x : ιM) => 0
                                theorem Finset.prod_of_isEmpty {ι : Type u_1} {M : Type u_3} {f : ιM} [CommMonoid M] [IsEmpty ι] (s : Finset ι) :
                                is, f i = 1
                                theorem Finset.sum_of_isEmpty {ι : Type u_1} {M : Type u_3} {f : ιM} [AddCommMonoid M] [IsEmpty ι] (s : Finset ι) :
                                is, f i = 0
                                @[simp]
                                theorem Finset.prod_const_one {ι : Type u_1} {M : Type u_3} {s : Finset ι} [CommMonoid M] :
                                _xs, 1 = 1
                                @[simp]
                                theorem Finset.sum_const_zero {ι : Type u_1} {M : Type u_3} {s : Finset ι} [AddCommMonoid M] :
                                _xs, 0 = 0
                                @[simp]
                                theorem Finset.prod_map {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] (s : Finset ι) (e : ι κ) (f : κM) :
                                xmap e s, f x = xs, f (e x)
                                @[simp]
                                theorem Finset.sum_map {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (e : ι κ) (f : κM) :
                                xmap e s, f x = xs, f (e x)
                                theorem Finset.prod_map' {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] (s : Finset ι) (e : ι κ) :
                                (map e s).prod = fun (f : κM) => xs, f (e x)

                                Variant of prod_map not applied to a function.

                                theorem Finset.sum_map' {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (e : ι κ) :
                                (map e s).sum = fun (f : κM) => xs, f (e x)
                                @[simp]
                                theorem Finset.prod_map_toList {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιM) :
                                (List.map f s.toList).prod = s.prod f
                                @[simp]
                                theorem Finset.sum_map_toList {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιM) :
                                (List.map f s.toList).sum = s.sum f
                                @[simp]
                                theorem Finset.prod_toList {M : Type u_7} [CommMonoid M] (s : Finset M) :
                                s.toList.prod = xs, x
                                @[simp]
                                theorem Finset.sum_toList {M : Type u_7} [AddCommMonoid M] (s : Finset M) :
                                s.toList.sum = xs, x
                                theorem Equiv.Perm.prod_comp {ι : Type u_1} {M : Type u_3} [CommMonoid M] (σ : Perm ι) (s : Finset ι) (f : ιM) (hs : {a : ι | σ a a} s) :
                                xs, f (σ x) = xs, f x
                                theorem Equiv.Perm.sum_comp {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (σ : Perm ι) (s : Finset ι) (f : ιM) (hs : {a : ι | σ a a} s) :
                                xs, f (σ x) = xs, f x
                                theorem Equiv.Perm.prod_comp' {ι : Type u_1} {M : Type u_3} [CommMonoid M] (σ : Perm ι) (s : Finset ι) (f : ιιM) (hs : {a : ι | σ a a} s) :
                                xs, f (σ x) x = xs, f x ((Equiv.symm σ) x)
                                theorem Equiv.Perm.sum_comp' {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (σ : Perm ι) (s : Finset ι) (f : ιιM) (hs : {a : ι | σ a a} s) :
                                xs, f (σ x) x = xs, f x ((Equiv.symm σ) x)
                                theorem Finset.prod_bij {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : (a : ι) → a sκ) (hi : ∀ (a : ι) (ha : a s), i a ha t) (i_inj : ∀ (a₁ : ι) (ha₁ : a₁ s) (a₂ : ι) (ha₂ : a₂ s), i a₁ ha₁ = i a₂ ha₂a₁ = a₂) (i_surj : bt, ∃ (a : ι) (ha : a s), i a ha = b) (h : ∀ (a : ι) (ha : a s), f a = g (i a ha)) :
                                xs, f x = xt, g x

                                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.

                                theorem Finset.sum_bij {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : (a : ι) → a sκ) (hi : ∀ (a : ι) (ha : a s), i a ha t) (i_inj : ∀ (a₁ : ι) (ha₁ : a₁ s) (a₂ : ι) (ha₂ : a₂ s), i a₁ ha₁ = i a₂ ha₂a₁ = a₂) (i_surj : bt, ∃ (a : ι) (ha : a s), i a ha = b) (h : ∀ (a : ι) (ha : a s), f a = g (i a ha)) :
                                xs, f x = xt, g x

                                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 Finset.prod_bij' {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : (a : ι) → a sκ) (j : (a : κ) → a tι) (hi : ∀ (a : ι) (ha : a s), i a ha t) (hj : ∀ (a : κ) (ha : a t), j a ha s) (left_inv : ∀ (a : ι) (ha : a s), j (i a ha) = a) (right_inv : ∀ (a : κ) (ha : a t), i (j a ha) = a) (h : ∀ (a : ι) (ha : a s), f a = g (i a ha)) :
                                xs, f x = xt, g x

                                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.

                                theorem Finset.sum_bij' {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : (a : ι) → a sκ) (j : (a : κ) → a tι) (hi : ∀ (a : ι) (ha : a s), i a ha t) (hj : ∀ (a : κ) (ha : a t), j a ha s) (left_neg : ∀ (a : ι) (ha : a s), j (i a ha) = a) (right_neg : ∀ (a : κ) (ha : a t), i (j a ha) = a) (h : ∀ (a : ι) (ha : a s), f a = g (i a ha)) :
                                xs, f x = xt, g x

                                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 Finset.prod_nbij {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : ικ) (hi : as, i a t) (i_inj : Set.InjOn i s) (i_surj : Set.SurjOn i s t) (h : as, f a = g (i a)) :
                                xs, f x = xt, g x

                                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.

                                theorem Finset.sum_nbij {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : ικ) (hi : as, i a t) (i_inj : Set.InjOn i s) (i_surj : Set.SurjOn i s t) (h : as, f a = g (i a)) :
                                xs, f x = xt, g x

                                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.

                                theorem Finset.prod_nbij' {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : ικ) (j : κι) (hi : as, i a t) (hj : at, j a s) (left_inv : as, j (i a) = a) (right_inv : at, i (j a) = a) (h : as, f a = g (i a)) :
                                xs, f x = xt, g x

                                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.

                                theorem Finset.sum_nbij' {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (i : ικ) (j : κι) (hi : as, i a t) (hj : at, j a s) (left_neg : as, j (i a) = a) (right_neg : at, i (j a) = a) (h : as, f a = g (i a)) :
                                xs, f x = xt, g x

                                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.

                                theorem Finset.prod_equiv {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (e : ι κ) (hst : ∀ (i : ι), i s e i t) (hfg : is, f i = g (e i)) :
                                is, f i = it, g i

                                Specialization of Finset.prod_nbij' that automatically fills in most arguments.

                                See Fintype.prod_equiv for the version where s and t are univ.

                                theorem Finset.sum_equiv {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (e : ι κ) (hst : ∀ (i : ι), i s e i t) (hfg : is, f i = g (e i)) :
                                is, f i = it, g i

                                Specialization of Finset.sum_nbij' that automatically fills in most arguments.

                                See Fintype.sum_equiv for the version where s and t are univ.

                                theorem Finset.prod_bijective {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [CommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (e : ικ) (he : Function.Bijective e) (hst : ∀ (i : ι), i s e i t) (hfg : is, f i = g (e i)) :
                                is, f i = it, g i

                                Specialization of Finset.prod_bij that automatically fills in most arguments.

                                See Fintype.prod_bijective for the version where s and t are univ.

                                theorem Finset.sum_bijective {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [AddCommMonoid M] {s : Finset ι} {t : Finset κ} {f : ιM} {g : κM} (e : ικ) (he : Function.Bijective e) (hst : ∀ (i : ι), i s e i t) (hfg : is, f i = g (e i)) :
                                is, f i = it, g i

                                Specialization of Finset.sum_bij that automatically fills in most arguments.

                                See Fintype.sum_bijective for the version where s and t are univ.

                                theorem Finset.prod_hom_rel {ι : Type u_1} {M : Type u_3} {N : Type u_4} [CommMonoid M] [CommMonoid N] {r : MNProp} {f : ιM} {g : ιN} {s : Finset ι} (h₁ : r 1 1) (h₂ : ∀ (a : ι) (b : M) (c : N), r b cr (f a * b) (g a * c)) :
                                r (∏ xs, f x) (∏ xs, g x)
                                theorem Finset.sum_hom_rel {ι : Type u_1} {M : Type u_3} {N : Type u_4} [AddCommMonoid M] [AddCommMonoid N] {r : MNProp} {f : ιM} {g : ιN} {s : Finset ι} (h₁ : r 0 0) (h₂ : ∀ (a : ι) (b : M) (c : N), r b cr (f a + b) (g a + c)) :
                                r (∑ xs, f x) (∑ xs, g x)
                                theorem Finset.prod_coe_sort_eq_attach {ι : Type u_1} {M : Type u_3} (s : Finset ι) [CommMonoid M] (f : sM) :
                                i : s, f i = is.attach, f i
                                theorem Finset.sum_coe_sort_eq_attach {ι : Type u_1} {M : Type u_3} (s : Finset ι) [AddCommMonoid M] (f : sM) :
                                i : s, f i = is.attach, f i
                                theorem Finset.prod_ite_index {ι : Type u_1} {M : Type u_3} [CommMonoid M] (p : Prop) [Decidable p] (s t : Finset ι) (f : ιM) :
                                xif p then s else t, f x = if p then xs, f x else xt, f x
                                theorem Finset.sum_ite_index {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (p : Prop) [Decidable p] (s t : Finset ι) (f : ιM) :
                                xif p then s else t, f x = if p then xs, f x else xt, f x
                                @[simp]
                                theorem Finset.prod_ite_irrel {ι : Type u_1} {M : Type u_3} [CommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f g : ιM) :
                                (∏ xs, if p then f x else g x) = if p then xs, f x else xs, g x
                                @[simp]
                                theorem Finset.sum_ite_irrel {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f g : ιM) :
                                (∑ xs, if p then f x else g x) = if p then xs, f x else xs, g x
                                @[simp]
                                theorem Finset.prod_dite_irrel {ι : Type u_1} {M : Type u_3} [CommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f : pιM) (g : ¬pιM) :
                                (∏ xs, if h : p then f h x else g h x) = if h : p then xs, f h x else xs, g h x
                                @[simp]
                                theorem Finset.sum_dite_irrel {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f : pιM) (g : ¬pιM) :
                                (∑ xs, if h : p then f h x else g h x) = if h : p then xs, f h x else xs, g h x
                                theorem Finset.ite_prod_one {ι : Type u_1} {M : Type u_3} [CommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f : ιM) :
                                (if p then xs, f x else 1) = xs, if p then f x else 1
                                theorem Finset.ite_sum_zero {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f : ιM) :
                                (if p then xs, f x else 0) = xs, if p then f x else 0
                                theorem Finset.ite_one_prod {ι : Type u_1} {M : Type u_3} [CommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f : ιM) :
                                (if p then 1 else xs, f x) = xs, if p then 1 else f x
                                theorem Finset.ite_zero_sum {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (p : Prop) [Decidable p] (s : Finset ι) (f : ιM) :
                                (if p then 0 else xs, f x) = xs, if p then 0 else f x
                                theorem Finset.nonempty_of_prod_ne_one {ι : Type u_1} {M : Type u_3} {s : Finset ι} {f : ιM} [CommMonoid M] (h : xs, f x 1) :
                                theorem Finset.nonempty_of_sum_ne_zero {ι : Type u_1} {M : Type u_3} {s : Finset ι} {f : ιM} [AddCommMonoid M] (h : xs, f x 0) :
                                theorem Finset.prod_range_zero {M : Type u_3} [CommMonoid M] (f : M) :
                                krange 0, f k = 1
                                theorem Finset.sum_range_zero {M : Type u_3} [AddCommMonoid M] (f : M) :
                                krange 0, f k = 0
                                theorem Finset.sum_filter_count_eq_countP {ι : Type u_1} [DecidableEq ι] (p : ιProp) [DecidablePred p] (l : List ι) :
                                xl.toFinset with p x, List.count x l = List.countP (fun (b : ι) => decide (p b)) l
                                theorem Finset.prod_mem_multiset {ι : Type u_1} {M : Type u_3} [CommMonoid M] [DecidableEq ι] (m : Multiset ι) (f : { x : ι // x m }M) (g : ιM) (hfg : ∀ (x : { x : ι // x m }), f x = g x) :
                                x : { x : ι // x m }, f x = xm.toFinset, g x
                                theorem Finset.sum_mem_multiset {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] [DecidableEq ι] (m : Multiset ι) (f : { x : ι // x m }M) (g : ιM) (hfg : ∀ (x : { x : ι // x m }), f x = g x) :
                                x : { x : ι // x m }, f x = xm.toFinset, g x
                                theorem Finset.prod_induction {ι : Type u_1} {s : Finset ι} {M : Type u_7} [CommMonoid M] (f : ιM) (p : MProp) (hom : ∀ (a b : M), p ap bp (a * b)) (unit : p 1) (base : xs, p (f x)) :
                                p (∏ xs, f x)

                                To prove a property of a product, it suffices to prove that the property is multiplicative and holds on factors.

                                theorem Finset.sum_induction {ι : Type u_1} {s : Finset ι} {M : Type u_7} [AddCommMonoid M] (f : ιM) (p : MProp) (hom : ∀ (a b : M), p ap bp (a + b)) (addUnit : p 0) (base : xs, p (f x)) :
                                p (∑ xs, f x)

                                To prove a property of a sum, it suffices to prove that the property is additive and holds on summands.

                                theorem Finset.prod_induction_nonempty {ι : Type u_1} {s : Finset ι} {M : Type u_7} [CommMonoid M] (f : ιM) (p : MProp) (hom : ∀ (a b : M), p ap bp (a * b)) (nonempty : s.Nonempty) (base : xs, p (f x)) :
                                p (∏ xs, f x)

                                To prove a property of a product, it suffices to prove that the property is multiplicative and holds on factors.

                                theorem Finset.sum_induction_nonempty {ι : Type u_1} {s : Finset ι} {M : Type u_7} [AddCommMonoid M] (f : ιM) (p : MProp) (hom : ∀ (a b : M), p ap bp (a + b)) (nonempty : s.Nonempty) (base : xs, p (f x)) :
                                p (∑ xs, f x)

                                To prove a property of a sum, it suffices to prove that the property is additive and holds on summands.

                                theorem Finset.prod_pow {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (n : ) (f : ιM) :
                                xs, f x ^ n = (∏ xs, f x) ^ n
                                theorem Finset.sum_nsmul {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (n : ) (f : ιM) :
                                xs, n f x = n xs, f x
                                theorem Finset.prod_dvd_prod_of_subset {ι : Type u_7} {M : Type u_8} [CommMonoid M] (s t : Finset ι) (f : ιM) (h : s t) :
                                is, f i it, f i
                                @[simp]
                                theorem Finset.op_sum {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιM) :
                                MulOpposite.op (∑ xs, f x) = xs, MulOpposite.op (f x)

                                Moving to the opposite additive commutative monoid commutes with summing.

                                @[simp]
                                theorem Finset.unop_sum {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιMᵐᵒᵖ) :
                                MulOpposite.unop (∑ xs, f x) = xs, MulOpposite.unop (f x)
                                @[simp]
                                theorem Finset.op_prod {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιM) :
                                AddOpposite.op (∏ is, f i) = is, AddOpposite.op (f i)
                                @[simp]
                                theorem Finset.unop_prod {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιMᵐᵒᵖ) :
                                AddOpposite.unop (∏ is, f i) = is, AddOpposite.unop (f i)
                                @[simp]
                                theorem Finset.prod_inv_distrib {ι : Type u_1} {G : Type u_5} {s : Finset ι} [DivisionCommMonoid G] (f : ιG) :
                                xs, (f x)⁻¹ = (∏ xs, f x)⁻¹
                                @[simp]
                                theorem Finset.sum_neg_distrib {ι : Type u_1} {G : Type u_5} {s : Finset ι} [SubtractionCommMonoid G] (f : ιG) :
                                xs, -f x = -xs, f x
                                @[simp]
                                theorem Finset.prod_div_distrib {ι : Type u_1} {G : Type u_5} {s : Finset ι} [DivisionCommMonoid G] (f g : ιG) :
                                xs, f x / g x = (∏ xs, f x) / xs, g x
                                @[simp]
                                theorem Finset.sum_sub_distrib {ι : Type u_1} {G : Type u_5} {s : Finset ι} [SubtractionCommMonoid G] (f g : ιG) :
                                xs, (f x - g x) = xs, f x - xs, g x
                                theorem Finset.prod_zpow {ι : Type u_1} {G : Type u_5} [DivisionCommMonoid G] (f : ιG) (s : Finset ι) (n : ) :
                                as, f a ^ n = (∏ as, f a) ^ n
                                theorem Finset.sum_zsmul {ι : Type u_1} {G : Type u_5} [SubtractionCommMonoid G] (f : ιG) (s : Finset ι) (n : ) :
                                as, n f a = n as, f a
                                theorem Finset.sum_nat_mod {ι : Type u_1} (s : Finset ι) (n : ) (f : ι) :
                                (∑ is, f i) % n = (∑ is, f i % n) % n
                                theorem Finset.prod_nat_mod {ι : Type u_1} (s : Finset ι) (n : ) (f : ι) :
                                (∏ is, f i) % n = (∏ is, f i % n) % n
                                theorem Finset.sum_int_mod {ι : Type u_1} (s : Finset ι) (n : ) (f : ι) :
                                (∑ is, f i) % n = (∑ is, f i % n) % n
                                theorem Finset.prod_int_mod {ι : Type u_1} (s : Finset ι) (n : ) (f : ι) :
                                (∏ is, f i) % n = (∏ is, f i % n) % n
                                theorem Fintype.prod_bijective {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [CommMonoid M] (e : ικ) (he : Function.Bijective e) (f : ιM) (g : κM) (h : ∀ (x : ι), f x = g (e x)) :
                                x : ι, f x = x : κ, g x

                                Fintype.prod_bijective is a variant of Finset.prod_bij that accepts Function.Bijective.

                                See Function.Bijective.prod_comp for a version without h.

                                theorem Fintype.sum_bijective {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [AddCommMonoid M] (e : ικ) (he : Function.Bijective e) (f : ιM) (g : κM) (h : ∀ (x : ι), f x = g (e x)) :
                                x : ι, f x = x : κ, g x

                                Fintype.sum_bijective is a variant of Finset.sum_bij that accepts Function.Bijective.

                                See Function.Bijective.sum_comp for a version without h.

                                theorem Function.Bijective.finset_prod {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [CommMonoid M] (e : ικ) (he : Bijective e) (f : ιM) (g : κM) (h : ∀ (x : ι), f x = g (e x)) :
                                x : ι, f x = x : κ, g x

                                Alias of Fintype.prod_bijective.


                                Fintype.prod_bijective is a variant of Finset.prod_bij that accepts Function.Bijective.

                                See Function.Bijective.prod_comp for a version without h.

                                theorem Function.Bijective.finset_sum {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [AddCommMonoid M] (e : ικ) (he : Bijective e) (f : ιM) (g : κM) (h : ∀ (x : ι), f x = g (e x)) :
                                x : ι, f x = x : κ, g x
                                theorem Fintype.prod_equiv {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [CommMonoid M] (e : ι κ) (f : ιM) (g : κM) (h : ∀ (x : ι), f x = g (e x)) :
                                x : ι, f x = x : κ, g x

                                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.

                                theorem Fintype.sum_equiv {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [AddCommMonoid M] (e : ι κ) (f : ιM) (g : κM) (h : ∀ (x : ι), f x = g (e x)) :
                                x : ι, f x = x : κ, g x

                                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.

                                theorem Function.Bijective.prod_comp {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [CommMonoid M] {e : ικ} (he : Bijective e) (g : κM) :
                                i : ι, g (e i) = i : κ, g i
                                theorem Function.Bijective.sum_comp {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [AddCommMonoid M] {e : ικ} (he : Bijective e) (g : κM) :
                                i : ι, g (e i) = i : κ, g i
                                theorem Equiv.prod_comp {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [CommMonoid M] (e : ι κ) (g : κM) :
                                i : ι, g (e i) = i : κ, g i
                                theorem Equiv.sum_comp {ι : Type u_1} {κ : Type u_2} {M : Type u_3} [Fintype ι] [Fintype κ] [AddCommMonoid M] (e : ι κ) (g : κM) :
                                i : ι, g (e i) = i : κ, g i
                                theorem Fintype.prod_empty {ι : Type u_1} {M : Type u_3} [Fintype ι] [CommMonoid M] [IsEmpty ι] (f : ιM) :
                                x : ι, f x = 1
                                theorem Fintype.sum_empty {ι : Type u_1} {M : Type u_3} [Fintype ι] [AddCommMonoid M] [IsEmpty ι] (f : ιM) :
                                x : ι, f x = 0
                                @[simp]
                                theorem Finset.prod_attach_univ {ι : Type u_1} {M : Type u_3} [CommMonoid M] [Fintype ι] (f : univM) :
                                iuniv.attach, f i = i : ι, f i,
                                @[simp]
                                theorem Finset.sum_attach_univ {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] [Fintype ι] (f : univM) :
                                iuniv.attach, f i = i : ι, f i,
                                theorem Finset.prod_erase_attach {ι : Type u_1} {M : Type u_3} [CommMonoid M] [DecidableEq ι] {s : Finset ι} (f : ιM) (i : s) :
                                js.attach.erase i, f j = js.erase i, f j
                                theorem Finset.sum_erase_attach {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] [DecidableEq ι] {s : Finset ι} (f : ιM) (i : s) :
                                js.attach.erase i, f j = js.erase i, f j
                                @[simp]
                                theorem Multiset.card_sum {ι : Type u_1} {α : Type u_6} (s : Finset ι) (f : ιMultiset α) :
                                (∑ is, f i).card = is, (f i).card
                                theorem Multiset.disjoint_list_sum_left {α : Type u_6} {a : Multiset α} {l : List (Multiset α)} :
                                Disjoint l.sum a bl, Disjoint b a
                                theorem Multiset.disjoint_list_sum_right {α : Type u_6} {a : Multiset α} {l : List (Multiset α)} :
                                Disjoint a l.sum bl, Disjoint a b
                                theorem Multiset.disjoint_sum_left {α : Type u_6} {a : Multiset α} {i : Multiset (Multiset α)} :
                                Disjoint i.sum a bi, Disjoint b a
                                theorem Multiset.disjoint_sum_right {α : Type u_6} {a : Multiset α} {i : Multiset (Multiset α)} :
                                Disjoint a i.sum bi, Disjoint a b
                                theorem Multiset.disjoint_finset_sum_left {ι : Type u_1} {α : Type u_6} {i : Finset ι} {f : ιMultiset α} {a : Multiset α} :
                                Disjoint (i.sum f) a bi, Disjoint (f b) a
                                theorem Multiset.disjoint_finset_sum_right {ι : Type u_1} {α : Type u_6} {i : Finset ι} {f : ιMultiset α} {a : Multiset α} :
                                Disjoint a (i.sum f) bi, Disjoint a (f b)
                                theorem Multiset.count_sum' {ι : Type u_1} {α : Type u_6} [DecidableEq α] {s : Finset ι} {a : α} {f : ιMultiset α} :
                                count a (∑ xs, f x) = xs, count a (f x)
                                theorem Multiset.toFinset_prod_dvd_prod {M : Type u_3} [DecidableEq M] [CommMonoid M] (S : Multiset M) :
                                S.toFinset.prod id S.prod
                                @[simp]
                                theorem Units.coe_prod {M : Type u_3} {α : Type u_6} [CommMonoid M] (f : αMˣ) (s : Finset α) :
                                (∏ is, f i) = is, (f i)

                                Additive, Multiplicative #

                                @[simp]
                                theorem ofMul_list_prod {M : Type u_3} [Monoid M] (s : List M) :
                                Additive.ofMul s.prod = (List.map (⇑Additive.ofMul) s).sum
                                @[simp]
                                theorem toMul_list_sum {M : Type u_3} [Monoid M] (s : List (Additive M)) :
                                Additive.toMul s.sum = (List.map (⇑Additive.toMul) s).prod
                                @[simp]
                                theorem ofAdd_list_prod {M : Type u_3} [AddMonoid M] (s : List M) :
                                Multiplicative.ofAdd s.sum = (List.map (⇑Multiplicative.ofAdd) s).prod
                                @[simp]
                                theorem toAdd_list_sum {M : Type u_3} [AddMonoid M] (s : List (Multiplicative M)) :
                                Multiplicative.toAdd s.prod = (List.map (⇑Multiplicative.toAdd) s).sum
                                @[simp]
                                theorem ofMul_prod {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιM) :
                                Additive.ofMul (∏ is, f i) = is, Additive.ofMul (f i)
                                @[simp]
                                theorem toMul_sum {ι : Type u_1} {M : Type u_3} [CommMonoid M] (s : Finset ι) (f : ιAdditive M) :
                                Additive.toMul (∑ is, f i) = is, Additive.toMul (f i)
                                @[simp]
                                theorem ofAdd_sum {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιM) :
                                Multiplicative.ofAdd (∑ is, f i) = is, Multiplicative.ofAdd (f i)
                                @[simp]
                                theorem toAdd_prod {ι : Type u_1} {M : Type u_3} [AddCommMonoid M] (s : Finset ι) (f : ιMultiplicative M) :
                                Multiplicative.toAdd (∏ is, f i) = is, Multiplicative.toAdd (f i)