l3lab/ntp-mathlib huggingface dataset:
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      

Proof state:
case empty.succ
α : Type u_1
inst✝¹ : DecidableEq α
s : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
hc : Set.Pairwise ↑∅ fun i j => Commute (x i) (x j)
n : ℕ
⊢ 0 =
    ∑ k : { x // x ∈ Finset.sym ∅ (succ n) },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      

Proof state:
case empty.succ
α : Type u_1
inst✝¹ : DecidableEq α
s : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
hc : Set.Pairwise ↑∅ fun i j => Commute (x i) (x j)
n : ℕ
this : IsEmpty { x // x ∈ Finset.sym ∅ (succ n) }
⊢ 0 =
    ∑ k : { x // x ∈ Finset.sym ∅ (succ n) },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
apply (Fintype.sum_empty _).symm
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
ih :
  ∀ (hc : Set.Pairwise ↑s fun i j => Commute (x i) (x j)) (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
⊢ ∀ (n : ℕ),
    Finset.sum (insert a s) x ^ n =
      ∑ k : { x // x ∈ Finset.sym (insert a s) n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
intro n
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; 

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
ih :
  ∀ (hc : Set.Pairwise ↑s fun i j => Commute (x i) (x j)) (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
⊢ Finset.sum (insert a s) x ^ n =
    ∑ k : { x // x ∈ Finset.sym (insert a s) n },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
specialize ih (hc.mono <| s.subset_insert a)
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
⊢ Finset.sum (insert a s) x ^ n =
    ∑ k : { x // x ∈ Finset.sym (insert a s) n },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]; 

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
⊢ ∑ i : Fin (n + 1), x a ^ ↑i * (∑ i in s, x i) ^ (n - ↑i) * ↑(Nat.choose n ↑i) =
    ∑ k : { x // x ∈ Finset.sym (insert a s) n },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
⊢ ∀ i ∈ s, Commute (x a) (x i)

Next tactic:
swap
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]; swap
  · 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
⊢ ∀ i ∈ s, Commute (x a) (x i)

Next tactic:
exact fun _ hb => hc (mem_insert_self a s) (mem_insert_of_mem hb)
      (ne_of_mem_of_not_mem hb ha).symm
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]; swap
  · exact fun _ hb => hc (mem_insert_self a s) (mem_insert_of_mem hb)
      (ne_of_mem_of_not_mem hb ha).symm
  · 

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
⊢ ∑ i : Fin (n + 1), x a ^ ↑i * (∑ i in s, x i) ^ (n - ↑i) * ↑(Nat.choose n ↑i) =
    ∑ k : { x // x ∈ Finset.sym (insert a s) n },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
simp_rw [ih, mul_sum, sum_mul, sum_sigma', univ_sigma_univ]
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]; swap
  · exact fun _ hb => hc (mem_insert_self a s) (mem_insert_of_mem hb)
      (ne_of_mem_of_not_mem hb ha).symm
  · simp_rw [ih, mul_sum, sum_mul, sum_sigma', univ_sigma_univ]
    

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
⊢ ∑ x_1 : (i : Fin (n + 1)) × { x // x ∈ Finset.sym s (n - ↑i) },
      x a ^ ↑x_1.fst *
          (↑(Multiset.multinomial ↑↑x_1.snd) *
            Multiset.noncommProd (Multiset.map x ↑↑x_1.snd)
              (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑x_1.snd} Commute)) *
        ↑(Nat.choose n ↑x_1.fst) =
    ∑ k : { x // x ∈ Finset.sym (insert a s) n },
      ↑(Multiset.multinomial ↑↑k) *
        Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)

Next tactic:
refine' (Fintype.sum_equiv (symInsertEquiv ha) _ _ fun m => _).symm
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]; swap
  · exact fun _ hb => hc (mem_insert_self a s) (mem_insert_of_mem hb)
      (ne_of_mem_of_not_mem hb ha).symm
  · simp_rw [ih, mul_sum, sum_mul, sum_sigma', univ_sigma_univ]
    refine' (Fintype.sum_equiv (symInsertEquiv ha) _ _ fun m => _).symm
    

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
m : { x // x ∈ Finset.sym (insert a s) n }
⊢ ↑(Multiset.multinomial ↑↑m) *
      Multiset.noncommProd (Multiset.map x ↑↑m) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑m} Commute) =
    x a ^ ↑((symInsertEquiv ha) m).fst *
        (↑(Multiset.multinomial ↑↑((symInsertEquiv ha) m).snd) *
          Multiset.noncommProd (Multiset.map x ↑↑((symInsertEquiv ha) m).snd)
            (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑((symInsertEquiv ha) m).snd} Commute)) *
      ↑(Nat.choose n ↑((symInsertEquiv ha) m).fst)

Next tactic:
rw [m.1.1.multinomial_filter_ne a]
/-- The multinomial theorem

  Proof is by induction on the number of summands.
-/
theorem sum_pow_of_commute [Semiring R] (x : α → R)
    (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) := by
  induction' s using Finset.induction with a s ha ih
  · rw [sum_empty]
    rintro (_ | n)
      -- Porting note : Lean cannot infer this instance by itself
    · haveI : Subsingleton (Sym α 0) := Unique.instSubsingleton
      rw [_root_.pow_zero, Fintype.sum_subsingleton]
      swap
        -- Porting note : Lean cannot infer this instance by itself
      · have : Zero (Sym α 0) := Sym.instZeroSym
        exact ⟨0, by simp [eq_iff_true_of_subsingleton]⟩
      convert (@one_mul R _ _).symm
      dsimp only
      convert @Nat.cast_one R _
    · rw [_root_.pow_succ, zero_mul]
      -- Porting note : Lean cannot infer this instance by itself
      haveI : IsEmpty (Finset.sym (∅ : Finset α) (succ n)) := Finset.instIsEmpty
      apply (Fintype.sum_empty _).symm
  intro n; specialize ih (hc.mono <| s.subset_insert a)
  rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]; swap
  · exact fun _ hb => hc (mem_insert_self a s) (mem_insert_of_mem hb)
      (ne_of_mem_of_not_mem hb ha).symm
  · simp_rw [ih, mul_sum, sum_mul, sum_sigma', univ_sigma_univ]
    refine' (Fintype.sum_equiv (symInsertEquiv ha) _ _ fun m => _).symm
    rw [m.1.1.multinomial_filter_ne a]
    

Proof state:
case insert
α : Type u_1
inst✝¹ : DecidableEq α
s✝ : Finset α
R : Type u_2
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : Set.Pairwise ↑(insert a s) fun i j => Commute (x i) (x j)
n : ℕ
ih :
  ∀ (n : ℕ),
    Finset.sum s x ^ n =
      ∑ k : { x // x ∈ Finset.sym s n },
        ↑(Multiset.multinomial ↑↑k) *
          Multiset.noncommProd (Multiset.map x ↑↑k) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑k} Commute)
m : { x // x ∈ Finset.sym (insert a s) n }
⊢ ↑(Nat.choose (Multiset.card ↑↑m) (Multiset.count a ↑↑m) *
          Multiset.multinomial (Multiset.filter (fun x => a ≠ x) ↑↑m)) *
      Multiset.noncommProd (Multiset.map x ↑↑m) (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑m} Commute) =
    x a ^ ↑((symInsertEquiv ha) m).fst *
        (↑(Multiset.multinomial ↑↑((symInsertEquiv ha) m).snd) *
          Multiset.noncommProd (Multiset.map x ↑↑((symInsertEquiv ha) m).snd)
            (_ : Set.Pairwise {b | b ∈ Multiset.map x ↑↑((symInsertEquiv ha) m).snd} Commute)) *
      ↑(Nat.choose n ↑((symInsertEquiv ha) m).fst)

Next tactic:
conv in m.1.1.map _ => rw [← m.1.1.filter_add_not (a = ·), Multiset.map_add]