File: Mathlib/Data/Nat/Choose/Multinomial.lean

full_name: Nat.multinomial
code: /-- The multinomial coefficient. Gives the number of strings consisting of symbols
from `s`, where `c ∈ s` appears with multiplicity `f c`.

Defined as `(∑ i ∈ s, f i)! / ∏ i ∈ s, (f i)!`.
-/
def multinomial : ℕ 
goal: ℕ

full_name: Nat.multinomial_pos
code: theorem multinomial_pos : 0 < multinomial s f 
goal: 0 < Nat.multinomial s f

full_name: Nat.multinomial_spec
code: theorem multinomial_spec : (∏ i ∈ s, (f i)!) * multinomial s f = (∑ i ∈ s, f i)! 
goal: (∏ i ∈ s, (f i)!) * Nat.multinomial s f = (∑ i ∈ s, f i)!

full_name: Nat.multinomial_empty
code: @[simp] lemma multinomial_empty : multinomial ∅ f = 1 
goal: Nat.multinomial ∅ f = 1

full_name: Nat.multinomial_cons
code: lemma multinomial_cons (ha : a ∉ s) (f : α → ℕ) :
    multinomial (s.cons a ha) f = (f a + ∑ i ∈ s, f i).choose (f a) * multinomial s f 
goal: Nat.multinomial (Finset.cons a s ha) f = (f a + ∑ i ∈ s, f i).choose (f a) * Nat.multinomial s f

full_name: Nat.multinomial_insert
code: lemma multinomial_insert [DecidableEq α] (ha : a ∉ s) (f : α → ℕ) :
    multinomial (insert a s) f = (f a + ∑ i ∈ s, f i).choose (f a) * multinomial s f 
goal: Nat.multinomial (insert a s) f = (f a + ∑ i ∈ s, f i).choose (f a) * Nat.multinomial s f

full_name: Nat.multinomial_singleton
code: @[simp] lemma multinomial_singleton (a : α) (f : α → ℕ) : multinomial {a} f = 1 
goal: Nat.multinomial {a} f = 1

full_name: Nat.multinomial_insert_one
code: @[simp]
theorem multinomial_insert_one [DecidableEq α] (h : a ∉ s) (h₁ : f a = 1) :
    multinomial (insert a s) f = (s.sum f).succ * multinomial s f 
goal: Nat.multinomial (insert a s) f = (s.sum f).succ * Nat.multinomial s f

full_name: Nat.multinomial_congr
code: theorem multinomial_congr {f g : α → ℕ} (h : ∀ a ∈ s, f a = g a) :
    multinomial s f = multinomial s g 
goal: Nat.multinomial s f = Nat.multinomial s g

full_name: Nat.binomial_eq
code: theorem binomial_eq [DecidableEq α] (h : a ≠ b) :
    multinomial {a, b} f = (f a + f b)! / ((f a)! * (f b)!) 
goal: Nat.multinomial {a, b} f = (f a + f b)! / ((f a)! * (f b)!)

full_name: Nat.binomial_eq_choose
code: theorem binomial_eq_choose [DecidableEq α] (h : a ≠ b) :
    multinomial {a, b} f = (f a + f b).choose (f a) 
goal: Nat.multinomial {a, b} f = (f a + f b).choose (f a)

full_name: Nat.binomial_spec
code: theorem binomial_spec [DecidableEq α] (hab : a ≠ b) :
    (f a)! * (f b)! * multinomial {a, b} f = (f a + f b)! 
goal: (f a)! * (f b)! * Nat.multinomial {a, b} f = (f a + f b)!

full_name: Nat.binomial_one
code: @[simp]
theorem binomial_one [DecidableEq α] (h : a ≠ b) (h₁ : f a = 1) :
    multinomial {a, b} f = (f b).succ 
goal: Nat.multinomial {a, b} f = (f b).succ

full_name: Nat.binomial_succ_succ
code: theorem binomial_succ_succ [DecidableEq α] (h : a ≠ b) :
    multinomial {a, b} (Function.update (Function.update f a (f a).succ) b (f b).succ) =
      multinomial {a, b} (Function.update f a (f a).succ) +
      multinomial {a, b} (Function.update f b (f b).succ) 
goal: Nat.multinomial {a, b} (Function.update (Function.update f a (f a).succ) b (f b).succ) =
  Nat.multinomial {a, b} (Function.update f a (f a).succ) + Nat.multinomial {a, b} (Function.update f b (f b).succ)

full_name: Nat.succ_mul_binomial
code: theorem succ_mul_binomial [DecidableEq α] (h : a ≠ b) :
    (f a + f b).succ * multinomial {a, b} f =
      (f a).succ * multinomial {a, b} (Function.update f a (f a).succ) 
goal: (f a + f b).succ * Nat.multinomial {a, b} f = (f a).succ * Nat.multinomial {a, b} (Function.update f a (f a).succ)

full_name: Nat.multinomial_univ_two
code: theorem multinomial_univ_two (a b : ℕ) :
    multinomial Finset.univ ![a, b] = (a + b)! / (a ! * b !) 
goal: Nat.multinomial Finset.univ ![a, b] = (a + b)! / (a ! * b !)

full_name: Nat.multinomial_univ_three
code: theorem multinomial_univ_three (a b c : ℕ) :
    multinomial Finset.univ ![a, b, c] = (a + b + c)! / (a ! * b ! * c !) 
goal: Nat.multinomial Finset.univ ![a, b, c] = (a + b + c)! / (a ! * b ! * c !)

full_name: Finsupp.multinomial
code: /-- Alternative multinomial definition based on a finsupp, using the support
  for the big operations
-/
def multinomial (f : α →₀ ℕ) : ℕ 
goal: ℕ

full_name: Finsupp.multinomial_eq
code: theorem multinomial_eq (f : α →₀ ℕ) : f.multinomial = Nat.multinomial f.support f 
goal: f.multinomial = Nat.multinomial f.support ⇑f

full_name: Finsupp.multinomial_update
code: theorem multinomial_update (a : α) (f : α →₀ ℕ) :
    f.multinomial = (f.sum fun _ => id).choose (f a) * (f.update a 0).multinomial 
goal: f.multinomial = (f.sum fun x => id).choose (f a) * (f.update a 0).multinomial

full_name: Multiset.multinomial
code: /-- Alternative definition of multinomial based on `Multiset` delegating to the
  finsupp definition
-/
def multinomial [DecidableEq α] (m : Multiset α) : ℕ 
goal: ℕ

full_name: Multiset.multinomial_filter_ne
code: theorem multinomial_filter_ne [DecidableEq α] (a : α) (m : Multiset α) :
    m.multinomial = m.card.choose (m.count a) * (m.filter (a ≠ ·)).multinomial 
goal: m.multinomial = (Multiset.card m).choose (Multiset.count a m) * (Multiset.filter (fun x => a ≠ x) m).multinomial

full_name: Multiset.multinomial_zero
code: @[simp]
theorem multinomial_zero [DecidableEq α] : multinomial (0 : Multiset α) = 1 
goal: Multiset.multinomial 0 = 1

full_name: Finset.sum_pow_eq_sum_piAntidiag_of_commute
code: /-- The **multinomial theorem**. -/
lemma sum_pow_eq_sum_piAntidiag_of_commute (s : Finset α) (f : α → R)
    (hc : (s : Set α).Pairwise fun i j ↦ Commute (f i) (f j)) (n : ℕ) :
    (∑ i in s, f i) ^ n = ∑ k in piAntidiag s n, multinomial s k *
      s.noncommProd (fun i ↦ f i ^ k i) (hc.mono' fun i j h ↦ h.pow_pow ..) 
goal: (∑ i ∈ s, f i) ^ n = ∑ k ∈ s.piAntidiag n, ↑(Nat.multinomial s k) * s.noncommProd (fun i => f i ^ k i) ⋯

full_name: Finset.sum_pow_of_commute
code: /-- The **multinomial theorem**. -/
theorem sum_pow_of_commute [Semiring R] (x : α → R) (s : Finset α)
    (hc : (s : Set α).Pairwise fun i j => Commute (x i) (x j)) :
    ∀ n,
      s.sum x ^ n =
        ∑ k : s.sym n,
          k.1.1.multinomial *
            (k.1.1.map <| x).noncommProd
              (Multiset.map_set_pairwise <| hc.mono <| mem_sym_iff.1 k.2) 
goal: s.sum x ^ n = ∑ k : { x // x ∈ s.sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯

full_name: Finset.sum_pow_eq_sum_piAntidiag
code: lemma sum_pow_eq_sum_piAntidiag (s : Finset α) (f : α → R) (n : ℕ) :
    (∑ i in s, f i) ^ n = ∑ k in piAntidiag s n, multinomial s k * ∏ i in s, f i ^ k i 
goal: (∑ i ∈ s, f i) ^ n = ∑ k ∈ s.piAntidiag n, ↑(Nat.multinomial s k) * ∏ i ∈ s, f i ^ k i

full_name: Finset.sum_pow
code: theorem sum_pow [CommSemiring R] (x : α → R) (n : ℕ) :
    s.sum x ^ n = ∑ k ∈ s.sym n, k.val.multinomial * (k.val.map x).prod 
goal: s.sum x ^ n = ∑ k ∈ s.sym n, ↑(↑k).multinomial * (Multiset.map x ↑k).prod

full_name: Sym.multinomial_coe_fill_of_not_mem
code: theorem multinomial_coe_fill_of_not_mem {m : Fin (n + 1)} {s : Sym α (n - m)} {x : α} (hx : x ∉ s) :
    (fill x m s : Multiset α).multinomial = n.choose m * (s : Multiset α).multinomial 
goal: (↑(Sym.fill x m s)).multinomial = n.choose ↑m * (↑s).multinomial