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

full_name: Commute.add_pow
code: /-- A version of the **binomial theorem** for commuting elements in noncommutative semirings. -/
theorem add_pow (h : Commute x y) (n : ℕ) :
    (x + y) ^ n = ∑ m ∈ range (n + 1), x ^ m * y ^ (n - m) * choose n m 
goal: (x + y) ^ n = ∑ m ∈ Finset.range (n + 1), x ^ m * y ^ (n - m) * ↑(n.choose m)

full_name: Commute.add_pow'
code: /-- A version of `Commute.add_pow` that avoids ℕ-subtraction by summing over the antidiagonal and
also with the binomial coefficient applied via scalar action of ℕ. -/
theorem add_pow' (h : Commute x y) (n : ℕ) :
    (x + y) ^ n = ∑ m ∈ antidiagonal n, choose n m.fst • (x ^ m.fst * y ^ m.snd) 
goal: (x + y) ^ n = ∑ m ∈ Finset.antidiagonal n, n.choose m.1 • (x ^ m.1 * y ^ m.2)

full_name: add_pow
code: /-- The **binomial theorem** -/
theorem add_pow [CommSemiring R] (x y : R) (n : ℕ) :
    (x + y) ^ n = ∑ m ∈ range (n + 1), x ^ m * y ^ (n - m) * choose n m 
goal: (x + y) ^ n = ∑ m ∈ Finset.range (n + 1), x ^ m * y ^ (n - m) * ↑(n.choose m)

full_name: Nat.sum_range_choose
code: /-- The sum of entries in a row of Pascal's triangle -/
theorem sum_range_choose (n : ℕ) : (∑ m ∈ range (n + 1), choose n m) = 2 ^ n 
goal: ∑ m ∈ Finset.range (n + 1), n.choose m = 2 ^ n

full_name: Nat.sum_range_choose_halfway
code: theorem sum_range_choose_halfway (m : Nat) : (∑ i ∈ range (m + 1), choose (2 * m + 1) i) = 4 ^ m 
goal: ∑ i ∈ Finset.range (m + 1), (2 * m + 1).choose i = 4 ^ m

full_name: Nat.choose_middle_le_pow
code: theorem choose_middle_le_pow (n : ℕ) : choose (2 * n + 1) n ≤ 4 ^ n 
goal: (2 * n + 1).choose n ≤ 4 ^ n

full_name: Nat.four_pow_le_two_mul_add_one_mul_central_binom
code: theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
    4 ^ n ≤ (2 * n + 1) * choose (2 * n) n 
goal: 4 ^ n ≤ (2 * n + 1) * (2 * n).choose n

full_name: Nat.sum_Icc_choose
code: /-- **Zhu Shijie's identity** aka hockey-stick identity. -/
theorem sum_Icc_choose (n k : ℕ) : ∑ m ∈ Icc k n, m.choose k = (n + 1).choose (k + 1) 
goal: ∑ m ∈ Finset.Icc k n, m.choose k = (n + 1).choose (k + 1)

full_name: Int.alternating_sum_range_choose
code: theorem Int.alternating_sum_range_choose {n : ℕ} :
    (∑ m ∈ range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = if n = 0 then 1 else 0 
goal: ∑ m ∈ Finset.range (n + 1), (-1) ^ m * ↑(n.choose m) = if n = 0 then 1 else 0

full_name: Int.alternating_sum_range_choose_of_ne
code: theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
    (∑ m ∈ range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = 0 
goal: ∑ m ∈ Finset.range (n + 1), (-1) ^ m * ↑(n.choose m) = 0

full_name: Finset.sum_powerset_apply_card
code: theorem sum_powerset_apply_card {α β : Type*} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
    ∑ m ∈ x.powerset, f m.card = ∑ m ∈ range (x.card + 1), x.card.choose m • f m 
goal: ∑ m ∈ x.powerset, f m.card = ∑ m ∈ Finset.range (x.card + 1), x.card.choose m • f m

full_name: Finset.sum_powerset_neg_one_pow_card
code: theorem sum_powerset_neg_one_pow_card {α : Type*} [DecidableEq α] {x : Finset α} :
    (∑ m ∈ x.powerset, (-1 : ℤ) ^ m.card) = if x = ∅ then 1 else 0 
goal: ∑ m ∈ x.powerset, (-1) ^ m.card = if x = ∅ then 1 else 0

full_name: Finset.sum_powerset_neg_one_pow_card_of_nonempty
code: theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type*} {x : Finset α} (h0 : x.Nonempty) :
    (∑ m ∈ x.powerset, (-1 : ℤ) ^ m.card) = 0 
goal: ∑ m ∈ x.powerset, (-1) ^ m.card = 0

full_name: Finset.prod_pow_choose_succ
code: @[to_additive sum_choose_succ_nsmul]
theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
    (∏ i ∈ range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i) =
      (∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i) *
        ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i 
goal: ∏ i ∈ Finset.range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i =
  (∏ i ∈ Finset.range (n + 1), f i (n + 1 - i) ^ n.choose i) *
    ∏ i ∈ Finset.range (n + 1), f (i + 1) (n - i) ^ n.choose i

full_name: Finset.sum_choose_succ_nsmul
code: @[to_additive sum_choose_succ_nsmul]
theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
    (∏ i ∈ range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i) =
      (∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i) *
        ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i 
goal: ∑ i ∈ Finset.range (n + 2), (n + 1).choose i • f i (n + 1 - i) =
  ∑ i ∈ Finset.range (n + 1), n.choose i • f i (n + 1 - i) + ∑ i ∈ Finset.range (n + 1), n.choose i • f (i + 1) (n - i)

full_name: Finset.prod_antidiagonal_pow_choose_succ
code: @[to_additive sum_antidiagonal_choose_succ_nsmul]
theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
    (∏ ij ∈ antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
      (∏ ij ∈ antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
        ∏ ij ∈ antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2 
goal: ∏ ij ∈ Finset.antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1 =
  (∏ ij ∈ Finset.antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
    ∏ ij ∈ Finset.antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2

full_name: Finset.sum_antidiagonal_choose_succ_nsmul
code: @[to_additive sum_antidiagonal_choose_succ_nsmul]
theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
    (∏ ij ∈ antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
      (∏ ij ∈ antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
        ∏ ij ∈ antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2 
goal: ∑ ij ∈ Finset.antidiagonal (n + 1), (n + 1).choose ij.1 • f ij.1 ij.2 =
  ∑ ij ∈ Finset.antidiagonal n, n.choose ij.1 • f ij.1 (ij.2 + 1) +
    ∑ ij ∈ Finset.antidiagonal n, n.choose ij.2 • f (ij.1 + 1) ij.2

full_name: Finset.sum_choose_succ_mul
code: /-- The sum of `(n+1).choose i * f i (n+1-i)` can be split into two sums at rank `n`,
respectively of `n.choose i * f i (n+1-i)` and `n.choose i * f (i+1) (n-i)`. -/
theorem sum_choose_succ_mul (f : ℕ → ℕ → R) (n : ℕ) :
    (∑ i ∈ range (n + 2), ((n + 1).choose i : R) * f i (n + 1 - i)) =
      (∑ i ∈ range (n + 1), (n.choose i : R) * f i (n + 1 - i)) +
        ∑ i ∈ range (n + 1), (n.choose i : R) * f (i + 1) (n - i) 
goal: ∑ i ∈ Finset.range (n + 2), ↑((n + 1).choose i) * f i (n + 1 - i) =
  ∑ i ∈ Finset.range (n + 1), ↑(n.choose i) * f i (n + 1 - i) +
    ∑ i ∈ Finset.range (n + 1), ↑(n.choose i) * f (i + 1) (n - i)

full_name: Finset.sum_antidiagonal_choose_succ_mul
code: /-- The sum along the antidiagonal of `(n+1).choose i * f i j` can be split into two sums along the
antidiagonal at rank `n`, respectively of `n.choose i * f i (j+1)` and `n.choose j * f (i+1) j`. -/
theorem sum_antidiagonal_choose_succ_mul (f : ℕ → ℕ → R) (n : ℕ) :
    (∑ ij ∈ antidiagonal (n + 1), ((n + 1).choose ij.1 : R) * f ij.1 ij.2) =
      (∑ ij ∈ antidiagonal n, (n.choose ij.1 : R) * f ij.1 (ij.2 + 1)) +
        ∑ ij ∈ antidiagonal n, (n.choose ij.2 : R) * f (ij.1 + 1) ij.2 
goal: ∑ ij ∈ Finset.antidiagonal (n + 1), ↑((n + 1).choose ij.1) * f ij.1 ij.2 =
  ∑ ij ∈ Finset.antidiagonal n, ↑(n.choose ij.1) * f ij.1 (ij.2 + 1) +
    ∑ ij ∈ Finset.antidiagonal n, ↑(n.choose ij.2) * f (ij.1 + 1) ij.2

full_name: Finset.sum_antidiagonal_choose_add
code: theorem sum_antidiagonal_choose_add (d n : ℕ) :
    (Finset.sum (antidiagonal n) fun ij => (d + ij.2).choose d) =
    (d + n).choose d + (d + n).choose (succ d) 
goal: ∑ ij ∈ Finset.antidiagonal n, (d + ij.2).choose d = (d + n).choose d + (d + n).choose d.succ