-- Mathlib/Data/Nat/Choose/Multinomial.lean
theorem sum_pow_of_commute (x : α → R) (s : Finset α)
    (hc : (s : Set α).Pairwise (Commute on x)) :
    ∀ 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)

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

Tactic:
simp_rw [← mul_assoc, Nat.cast_comm]

Result:
case insert.e_a
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : (↑(insert a s)).Pairwise (Commute on x)
n : ℕ
ih : ∀ (n : ℕ), s.sum x ^ n = ∑ k : { x // x ∈ s.sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯
m : { x // x ∈ (insert a s).sym n }
⊢ x a ^ Multiset.count a ↑↑m * ↑(Multiset.filter (fun x => a ≠ x) ↑↑m).multinomial *
      (Multiset.map x (Multiset.filter (fun a_1 => ¬a = a_1) ↑↑m)).noncommProd ⋯ =
    x a ^ ↑((symInsertEquiv ha) m).fst * ↑(↑↑((symInsertEquiv ha) m).snd).multinomial *
      (Multiset.map x ↑↑((symInsertEquiv ha) m).snd).noncommProd ⋯

Proof state:
case empty.succ
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
hc : (↑∅).Pairwise (Commute on x)
n : ℕ
⊢ 0 ^ (n + 1) = ∑ k : { x // x ∈ ∅.sym (n + 1) }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯

Tactic:
rw [_root_.pow_succ, mul_zero]

Result:
case empty.succ
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
hc : (↑∅).Pairwise (Commute on x)
n : ℕ
⊢ 0 = ∑ k : { x // x ∈ ∅.sym (n + 1) }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯

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

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

Tactic:
swap

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

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

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

Tactic:
rw [sum_insert ha, (Commute.sum_right s _ _ _).add_pow, sum_range]

Result:
case insert
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : (↑(insert a s)).Pairwise (Commute on x)
n : ℕ
ih : ∀ (n : ℕ), s.sum x ^ n = ∑ k : { x // x ∈ s.sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯
⊢ ∑ i : Fin (n + 1), x a ^ ↑i * (∑ i ∈ s, x i) ^ (n - ↑i) * ↑(n.choose ↑i) =
    ∑ k : { x // x ∈ (insert a s).sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯

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

Proof state:
case h.e'_2.h.e'_3
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
hc : (↑∅).Pairwise (Commute on x)
this : Subsingleton (Sym α 0)
⊢ (↑↑(let_fun this_1 := Sym.instZeroSym;
          ⟨0, ⋯⟩)).multinomial =
    1

Tactic:
simp

Result:
no goals

Proof state:
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
hc : (↑∅).Pairwise (Commute on x)
this✝ : Subsingleton (Sym α 0)
this : Zero (Sym α 0)
⊢ 0 ∈ ∅.sym 0

Tactic:
simp [eq_iff_true_of_subsingleton]

Result:
no goals

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

Tactic:
refine (Fintype.sum_equiv (symInsertEquiv ha) _ _ fun m => ?_).symm

Result:
case insert
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : (↑(insert a s)).Pairwise (Commute on x)
n : ℕ
ih : ∀ (n : ℕ), s.sum x ^ n = ∑ k : { x // x ∈ s.sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯
m : { x // x ∈ (insert a s).sym n }
⊢ ↑(↑↑m).multinomial * (Multiset.map x ↑↑m).noncommProd ⋯ =
    x a ^ ↑((symInsertEquiv ha) m).fst *
        (↑(↑↑((symInsertEquiv ha) m).snd).multinomial * (Multiset.map x ↑↑((symInsertEquiv ha) m).snd).noncommProd ⋯) *
      ↑(n.choose ↑((symInsertEquiv ha) m).fst)

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

Tactic:
specialize ih (hc.mono <| s.subset_insert a)

Result:
case insert
α : Type u_1
R : Type u_2
inst✝¹ : DecidableEq α
inst✝ : Semiring R
x : α → R
a : α
s : Finset α
ha : a ∉ s
hc : (↑(insert a s)).Pairwise (Commute on x)
n : ℕ
ih : ∀ (n : ℕ), s.sum x ^ n = ∑ k : { x // x ∈ s.sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯
⊢ (insert a s).sum x ^ n =
    ∑ k : { x // x ∈ (insert a s).sym n }, ↑(↑↑k).multinomial * (Multiset.map x ↑↑k).noncommProd ⋯