File: Mathlib/RingTheory/Binomial.lean

full_name: BinomialRing.factorial_nsmul_multichoose
code: /-- A binomial ring is a ring for which ascending Pochhammer evaluations are uniquely divisible by
suitable factorials. We define this notion as a mixin for additive commutative monoids with natural
number powers, but retain the ring name. We introduce `Ring.multichoose` as the uniquely defined
quotient. -/
class BinomialRing (R : Type*) [AddCommMonoid R] [Pow R ℕ] where
  /-- Scalar multiplication by positive integers is injective -/
  nsmul_right_injective (n : ℕ) (h : n ≠ 0) : Injective (n • · : R → R)
  /-- A multichoose function, giving the quotient of Pochhammer evaluations by factorials. -/
  multichoose : R → ℕ → R
  /-- The `n`th ascending Pochhammer polynomial evaluated at any element is divisible by `n!` -/
  factorial_nsmul_multichoose (r : R) (n : ℕ) :
    n.factorial • multichoose r n = (ascPochhammer ℕ n).smeval r
goal: n.factorial • BinomialRing.multichoose r n = (ascPochhammer ℕ n).smeval r

full_name: BinomialRing
code: /-- A binomial ring is a ring for which ascending Pochhammer evaluations are uniquely divisible by
suitable factorials. We define this notion as a mixin for additive commutative monoids with natural
number powers, but retain the ring name. We introduce `Ring.multichoose` as the uniquely defined
quotient. -/
class BinomialRing (R : Type*) [AddCommMonoid R] [Pow R ℕ] where
  /-- Scalar multiplication by positive integers is injective -/
  nsmul_right_injective (n : ℕ) (h : n ≠ 0) : Injective (n • · : R → R)
  /-- A multichoose function, giving the quotient of Pochhammer evaluations by factorials. -/
  multichoose : R → ℕ → R
  /-- The `n`th ascending Pochhammer polynomial evaluated at any element is divisible by `n!` -/
  factorial_nsmul_multichoose (r : R) (n : ℕ) :
    n.factorial • multichoose r n = (ascPochhammer ℕ n).smeval r
goal: Type u_1

full_name: BinomialRing.nsmul_right_injective
code: /-- A binomial ring is a ring for which ascending Pochhammer evaluations are uniquely divisible by
suitable factorials. We define this notion as a mixin for additive commutative monoids with natural
number powers, but retain the ring name. We introduce `Ring.multichoose` as the uniquely defined
quotient. -/
class BinomialRing (R : Type*) [AddCommMonoid R] [Pow R ℕ] where
  /-- Scalar multiplication by positive integers is injective -/
  nsmul_right_injective (n : ℕ) (h : n ≠ 0) : Injective (n • · : R → R)
  /-- A multichoose function, giving the quotient of Pochhammer evaluations by factorials. -/
  multichoose : R → ℕ → R
  /-- The `n`th ascending Pochhammer polynomial evaluated at any element is divisible by `n!` -/
  factorial_nsmul_multichoose (r : R) (n : ℕ) :
    n.factorial • multichoose r n = (ascPochhammer ℕ n).smeval r
goal: Function.Injective fun x => n • x

full_name: BinomialRing.multichoose
code: /-- A binomial ring is a ring for which ascending Pochhammer evaluations are uniquely divisible by
suitable factorials. We define this notion as a mixin for additive commutative monoids with natural
number powers, but retain the ring name. We introduce `Ring.multichoose` as the uniquely defined
quotient. -/
class BinomialRing (R : Type*) [AddCommMonoid R] [Pow R ℕ] where
  /-- Scalar multiplication by positive integers is injective -/
  nsmul_right_injective (n : ℕ) (h : n ≠ 0) : Injective (n • · : R → R)
  /-- A multichoose function, giving the quotient of Pochhammer evaluations by factorials. -/
  multichoose : R → ℕ → R
  /-- The `n`th ascending Pochhammer polynomial evaluated at any element is divisible by `n!` -/
  factorial_nsmul_multichoose (r : R) (n : ℕ) :
    n.factorial • multichoose r n = (ascPochhammer ℕ n).smeval r
goal: R → ℕ → R

full_name: Ring.nsmul_right_injective
code: theorem nsmul_right_injective (n : ℕ) (h : n ≠ 0) :
    Injective (n • · : R → R) 
goal: Function.Injective fun x => n • x

full_name: Ring.multichoose
code: /-- The multichoose function is the quotient of ascending Pochhammer evaluation by the corresponding
factorial. When applied to natural numbers, `multichoose k n` describes choosing a multiset of `n`
items from a type of size `k`, i.e., choosing with replacement. -/
def multichoose (r : R) (n : ℕ) : R 
goal: R

full_name: Ring.multichoose_eq_multichoose
code: @[simp]
theorem multichoose_eq_multichoose (r : R) (n : ℕ) :
    BinomialRing.multichoose r n = multichoose r n 
goal: BinomialRing.multichoose r n = Ring.multichoose r n

full_name: Ring.factorial_nsmul_multichoose_eq_ascPochhammer
code: theorem factorial_nsmul_multichoose_eq_ascPochhammer (r : R) (n : ℕ) :
    n.factorial • multichoose r n = (ascPochhammer ℕ n).smeval r 
goal: n.factorial • Ring.multichoose r n = (ascPochhammer ℕ n).smeval r

full_name: Ring.multichoose_zero_right'
code: @[simp]
theorem multichoose_zero_right' (r : R) : multichoose r 0 = r ^ 0 
goal: Ring.multichoose r 0 = r ^ 0

full_name: Ring.multichoose_zero_right
code: theorem multichoose_zero_right [MulOneClass R] [NatPowAssoc R]
    (r : R) : multichoose r 0 = 1 
goal: Ring.multichoose r 0 = 1

full_name: Ring.multichoose_one_right'
code: @[simp]
theorem multichoose_one_right' (r : R) : multichoose r 1 = r ^ 1 
goal: Ring.multichoose r 1 = r ^ 1

full_name: Ring.multichoose_one_right
code: theorem multichoose_one_right [MulOneClass R] [NatPowAssoc R] (r : R) : multichoose r 1 = r 
goal: Ring.multichoose r 1 = r

full_name: Ring.multichoose_zero_succ
code: @[simp]
theorem multichoose_zero_succ (k : ℕ) : multichoose (0 : R) (k + 1) = 0 
goal: Ring.multichoose 0 (k + 1) = 0

full_name: Ring.ascPochhammer_succ_succ
code: theorem ascPochhammer_succ_succ (r : R) (k : ℕ) :
    smeval (ascPochhammer ℕ (k + 1)) (r + 1) = Nat.factorial (k + 1) • multichoose (r + 1) k +
    smeval (ascPochhammer ℕ (k + 1)) r 
goal: (ascPochhammer ℕ (k + 1)).smeval (r + 1) =
  (k + 1).factorial • Ring.multichoose (r + 1) k + (ascPochhammer ℕ (k + 1)).smeval r

full_name: Ring.multichoose_succ_succ
code: theorem multichoose_succ_succ (r : R) (k : ℕ) :
    multichoose (r + 1) (k + 1) = multichoose r (k + 1) + multichoose (r + 1) k 
goal: Ring.multichoose (r + 1) (k + 1) = Ring.multichoose r (k + 1) + Ring.multichoose (r + 1) k

full_name: Ring.multichoose_one
code: @[simp]
theorem multichoose_one (k : ℕ) : multichoose (1 : R) k = 1 
goal: Ring.multichoose 1 k = 1

full_name: Ring.multichoose_two
code: theorem multichoose_two (k : ℕ) : multichoose (2 : R) k = k + 1 
goal: Ring.multichoose 2 k = ↑k + 1

full_name: Polynomial.ascPochhammer_smeval_cast
code: @[simp]
theorem ascPochhammer_smeval_cast (R : Type*) [Semiring R] {S : Type*} [NonAssocSemiring S]
    [Pow S ℕ] [Module R S] [IsScalarTower R S S] [NatPowAssoc S]
    (x : S) (n : ℕ) : (ascPochhammer R n).smeval x = (ascPochhammer ℕ n).smeval x 
goal: (ascPochhammer R n).smeval x = (ascPochhammer ℕ n).smeval x

full_name: Polynomial.ascPochhammer_smeval_eq_eval
code: theorem ascPochhammer_smeval_eq_eval [Semiring R] (r : R) (n : ℕ) :
    (ascPochhammer ℕ n).smeval r = (ascPochhammer R n).eval r 
goal: (ascPochhammer ℕ n).smeval r = Polynomial.eval r (ascPochhammer R n)

full_name: Polynomial.descPochhammer_smeval_eq_ascPochhammer
code: theorem descPochhammer_smeval_eq_ascPochhammer (r : R) (n : ℕ) :
    (descPochhammer ℤ n).smeval r = (ascPochhammer ℕ n).smeval (r - n + 1) 
goal: (descPochhammer ℤ n).smeval r = (ascPochhammer ℕ n).smeval (r - ↑n + 1)

full_name: Polynomial.descPochhammer_smeval_eq_descFactorial
code: theorem descPochhammer_smeval_eq_descFactorial (n k : ℕ) :
    (descPochhammer ℤ k).smeval (n : R) = n.descFactorial k 
goal: (descPochhammer ℤ k).smeval ↑n = ↑(n.descFactorial k)

full_name: Polynomial.ascPochhammer_smeval_neg_eq_descPochhammer
code: theorem ascPochhammer_smeval_neg_eq_descPochhammer (r : R) (k : ℕ) :
    (ascPochhammer ℕ k).smeval (-r) = (-1)^k * (descPochhammer ℤ k).smeval r 
goal: (ascPochhammer ℕ k).smeval (-r) = (-1) ^ k * (descPochhammer ℤ k).smeval r

full_name: Nat.instBinomialRing
code: instance Nat.instBinomialRing : BinomialRing ℕ 
goal: BinomialRing ℕ

full_name: Int.multichoose
code: /-- The multichoose function for integers. -/
def Int.multichoose (n : ℤ) (k : ℕ) : ℤ 
goal: ℤ

full_name: Int.instBinomialRing
code: instance Int.instBinomialRing : BinomialRing ℤ 
goal: BinomialRing ℤ

full_name: instBinomialRingOfModuleNNRat
code: noncomputable instance {R : Type*} [AddCommMonoid R] [Module ℚ≥0 R] [Pow R ℕ] : BinomialRing R 
goal: BinomialRing R

full_name: Ring.smeval_ascPochhammer_self_neg
code: @[simp]
theorem smeval_ascPochhammer_self_neg : ∀ n : ℕ,
    smeval (ascPochhammer ℕ n) (-n : ℤ) = (-1)^n * n.factorial
  
goal: (ascPochhammer ℕ n).smeval (-↑n) = (-1) ^ n * ↑n.factorial

full_name: Ring.smeval_ascPochhammer_succ_neg
code: @[simp]
theorem smeval_ascPochhammer_succ_neg (n : ℕ) :
    smeval (ascPochhammer ℕ (n + 1)) (-n : ℤ) = 0 
goal: (ascPochhammer ℕ (n + 1)).smeval (-↑n) = 0

full_name: Ring.smeval_ascPochhammer_neg_add
code: theorem smeval_ascPochhammer_neg_add (n : ℕ) : ∀ k : ℕ,
    smeval (ascPochhammer ℕ (n + k + 1)) (-n : ℤ) = 0
  
goal: (ascPochhammer ℕ (n + k + 1)).smeval (-↑n) = 0

full_name: Ring.smeval_ascPochhammer_neg_of_lt
code: @[simp]
theorem smeval_ascPochhammer_neg_of_lt {n k : ℕ} (h : n < k) :
    smeval (ascPochhammer ℕ k) (-n : ℤ) = 0 
goal: (ascPochhammer ℕ k).smeval (-↑n) = 0

full_name: Ring.smeval_ascPochhammer_nat_cast
code: theorem smeval_ascPochhammer_nat_cast [NatPowAssoc R] (n k : ℕ) :
    smeval (ascPochhammer ℕ k) (n : R) = smeval (ascPochhammer ℕ k) n 
goal: (ascPochhammer ℕ k).smeval ↑n = ↑((ascPochhammer ℕ k).smeval n)

full_name: Ring.multichoose_neg_self
code: theorem multichoose_neg_self (n : ℕ) : multichoose (-n : ℤ) n = (-1)^n 
goal: Ring.multichoose (-↑n) n = (-1) ^ n

full_name: Ring.multichoose_neg_succ
code: @[simp]
theorem multichoose_neg_succ (n : ℕ) : multichoose (-n : ℤ) (n + 1) = 0 
goal: Ring.multichoose (-↑n) (n + 1) = 0

full_name: Ring.multichoose_neg_add
code: theorem multichoose_neg_add (n k : ℕ) : multichoose (-n : ℤ) (n + k + 1) = 0 
goal: Ring.multichoose (-↑n) (n + k + 1) = 0

full_name: Ring.multichoose_neg_of_lt
code: @[simp]
theorem multichoose_neg_of_lt (n k : ℕ) (h : n < k) : multichoose (-n : ℤ) k = 0 
goal: Ring.multichoose (-↑n) k = 0

full_name: Ring.multichoose_succ_neg_natCast
code: theorem multichoose_succ_neg_natCast [NatPowAssoc R] (n : ℕ) :
    multichoose (-n : R) (n + 1) = 0 
goal: Ring.multichoose (-↑n) (n + 1) = 0

full_name: Ring.smeval_ascPochhammer_int_ofNat
code: theorem smeval_ascPochhammer_int_ofNat [NatPowAssoc R] (r : R) : ∀ n : ℕ,
    smeval (ascPochhammer ℤ n) r = smeval (ascPochhammer ℕ n) r
  
goal: (ascPochhammer ℤ n).smeval r = (ascPochhammer ℕ n).smeval r

full_name: Ring.choose
code: /-- The binomial coefficient `choose r n` generalizes the natural number `choose` function,
  interpreted in terms of choosing without replacement. -/
def choose [AddCommGroupWithOne R] [Pow R ℕ] [BinomialRing R] (r : R) (n : ℕ) : R 
goal: R

full_name: Ring.descPochhammer_eq_factorial_smul_choose
code: theorem descPochhammer_eq_factorial_smul_choose [NatPowAssoc R] (r : R) (n : ℕ) :
    (descPochhammer ℤ n).smeval r = n.factorial • choose r n 
goal: (descPochhammer ℤ n).smeval r = n.factorial • Ring.choose r n

full_name: Ring.choose_natCast
code: theorem choose_natCast [NatPowAssoc R] (n k : ℕ) : choose (n : R) k = Nat.choose n k 
goal: Ring.choose (↑n) k = ↑(n.choose k)

full_name: Ring.choose_zero_right'
code: @[simp]
theorem choose_zero_right' (r : R) : choose r 0 = (r + 1) ^ 0 
goal: Ring.choose r 0 = (r + 1) ^ 0

full_name: Ring.choose_zero_right
code: theorem choose_zero_right [NatPowAssoc R] (r : R) : choose r 0 = 1 
goal: Ring.choose r 0 = 1

full_name: Ring.choose_zero_succ
code: @[simp]
theorem choose_zero_succ (R) [NonAssocRing R] [Pow R ℕ] [NatPowAssoc R] [BinomialRing R]
    (n : ℕ) : choose (0 : R) (n + 1) = 0 
goal: Ring.choose 0 (n + 1) = 0

full_name: Ring.choose_zero_pos
code: theorem choose_zero_pos (R) [NonAssocRing R] [Pow R ℕ] [NatPowAssoc R] [BinomialRing R]
    {k : ℕ} (h_pos: 0 < k) : choose (0 : R) k = 0 
goal: Ring.choose 0 k = 0

full_name: Ring.choose_zero_ite
code: theorem choose_zero_ite (R) [NonAssocRing R] [Pow R ℕ] [NatPowAssoc R] [BinomialRing R]
    (k : ℕ) : choose (0 : R) k = if k = 0 then 1 else 0 
goal: Ring.choose 0 k = if k = 0 then 1 else 0

full_name: Ring.choose_one_right'
code: @[simp]
theorem choose_one_right' (r : R) : choose r 1 = r ^ 1 
goal: Ring.choose r 1 = r ^ 1

full_name: Ring.choose_one_right
code: theorem choose_one_right [NatPowAssoc R] (r : R) : choose r 1 = r 
goal: Ring.choose r 1 = r

full_name: Ring.descPochhammer_succ_succ_smeval
code: theorem descPochhammer_succ_succ_smeval {R} [NonAssocRing R] [Pow R ℕ] [NatPowAssoc R]
    (r : R) (k : ℕ) : smeval (descPochhammer ℤ (k + 1)) (r + 1) =
    (k + 1) • smeval (descPochhammer ℤ k) r + smeval (descPochhammer ℤ (k + 1)) r 
goal: (descPochhammer ℤ (k + 1)).smeval (r + 1) =
  (k + 1) • (descPochhammer ℤ k).smeval r + (descPochhammer ℤ (k + 1)).smeval r

full_name: Ring.choose_succ_succ
code: theorem choose_succ_succ [NatPowAssoc R] (r : R) (k : ℕ) :
    choose (r + 1) (k + 1) = choose r k + choose r (k + 1) 
goal: Ring.choose (r + 1) (k + 1) = Ring.choose r k + Ring.choose r (k + 1)

full_name: Ring.choose_eq_nat_choose
code: theorem choose_eq_nat_choose [NatPowAssoc R] (n k : ℕ) : choose (n : R) k = Nat.choose n k 
goal: Ring.choose (↑n) k = ↑(n.choose k)

full_name: Ring.choose_smul_choose
code: theorem choose_smul_choose [NatPowAssoc R] (r : R) (n k : ℕ) (hkn : k ≤ n) :
    (Nat.choose n k) • choose r n = choose r k * choose (r - k) (n - k) 
goal: n.choose k • Ring.choose r n = Ring.choose r k * Ring.choose (r - ↑k) (n - k)

full_name: Ring.choose_add_smul_choose
code: theorem choose_add_smul_choose [NatPowAssoc R] (r : R) (n k : ℕ) :
    (Nat.choose (n + k) k) • choose (r + k) (n + k) = choose (r + k) k * choose r n 
goal: (n + k).choose k • Ring.choose (r + ↑k) (n + k) = Ring.choose (r + ↑k) k * Ring.choose r n

full_name: Ring.descPochhammer_smeval_add
code: /-- Pochhammer version of Chu-Vandermonde identity -/
theorem descPochhammer_smeval_add [Ring R] {r s : R} (k : ℕ) (h: Commute r s) :
    (descPochhammer ℤ k).smeval (r + s) = ∑ ij ∈ antidiagonal k,
    Nat.choose k ij.1 * ((descPochhammer ℤ ij.1).smeval r * (descPochhammer ℤ ij.2).smeval s) 
goal: (descPochhammer ℤ k).smeval (r + s) =
  ∑ ij ∈ Finset.antidiagonal k, ↑(k.choose ij.1) * ((descPochhammer ℤ ij.1).smeval r * (descPochhammer ℤ ij.2).smeval s)

full_name: Ring.add_choose_eq
code: /-- The Chu-Vandermonde identity for binomial rings -/
theorem add_choose_eq [Ring R] [BinomialRing R] {r s : R} (k : ℕ) (h : Commute r s) :
    choose (r + s) k =
      ∑ ij ∈ antidiagonal k, choose r ij.1 * choose s ij.2 
goal: Ring.choose (r + s) k = ∑ ij ∈ Finset.antidiagonal k, Ring.choose r ij.1 * Ring.choose s ij.2