data.nat.choose.sum
⟷
Mathlib.Data.Nat.Choose.Sum
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -7,7 +7,7 @@ import Data.Nat.Choose.Basic
import Mathbin.Tactic.Linarith.Default
import Algebra.BigOperators.Ring
import Algebra.BigOperators.Intervals
-import Algebra.BigOperators.Order
+import Algebra.Order.BigOperators.Group.Finset
import Algebra.BigOperators.NatAntidiagonal
#align_import data.nat.choose.sum from "leanprover-community/mathlib"@"3e32bc908f617039c74c06ea9a897e30c30803c2"
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -55,20 +55,21 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
dsimp [t]
rw [choose_succ_succ, Nat.cast_add, mul_add]
congr 1
- · rw [pow_succ x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
+ · rw [pow_succ' x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
· rw [← mul_assoc y, ← mul_assoc y, (h.symm.pow_right i.succ).Eq]
by_cases h_eq : i = n
· rw [h_eq, choose_succ_self, Nat.cast_zero, MulZeroClass.mul_zero, MulZeroClass.mul_zero]
· rw [succ_sub (lt_of_le_of_ne h_le h_eq)]
- rw [pow_succ y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
+ rw [pow_succ' y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
induction' n with n ih
· rw [pow_zero, sum_range_succ, range_zero, sum_empty, zero_add]
dsimp [t]; rw [pow_zero, pow_zero, choose_self, Nat.cast_one, mul_one, mul_one]
· rw [sum_range_succ', h_first]
rw [sum_congr rfl (h_middle n), sum_add_distrib, add_assoc]
- rw [pow_succ (x + y), ih, add_mul, mul_sum, mul_sum]
+ rw [pow_succ' (x + y), ih, add_mul, mul_sum, mul_sum]
congr 1
- rw [sum_range_succ', sum_range_succ, h_first, h_last, MulZeroClass.mul_zero, add_zero, pow_succ]
+ rw [sum_range_succ', sum_range_succ, h_first, h_last, MulZeroClass.mul_zero, add_zero,
+ pow_succ']
#align commute.add_pow Commute.add_pow
-/
@@ -127,7 +128,7 @@ theorem sum_range_choose_halfway (m : Nat) : ∑ i in range (m + 1), choose (2 *
· linarith
_ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := (sum_range_add_sum_Ico _ (by linarith))
_ = 2 ^ (2 * m + 1) := (sum_range_choose (2 * m + 1))
- _ = 2 * 4 ^ m := by rw [pow_succ, pow_mul]; rfl
+ _ = 2 * 4 ^ m := by rw [pow_succ', pow_mul]; rfl
#align nat.sum_range_choose_halfway Nat.sum_range_choose_halfway
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -160,7 +160,7 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
by
cases n; · simp
have h := add_pow (-1 : ℤ) 1 n.succ
- simp only [one_pow, mul_one, add_left_neg] at h
+ simp only [one_pow, mul_one, add_left_neg] at h
rw [← h, zero_pow (Nat.succ_pos n), if_neg (Nat.succ_ne_zero n)]
#align int.alternating_sum_range_choose Int.alternating_sum_range_choose
-/
@@ -182,7 +182,7 @@ theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ →
· refine' (sum_fiberwise_of_maps_to _ _).symm
intro y hy
rw [mem_range, Nat.lt_succ_iff]
- rw [mem_powerset] at hy
+ rw [mem_powerset] at hy
exact card_le_of_subset hy
· refine' sum_congr rfl fun y hy => _
rw [← card_powerset_len, ← sum_const]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -202,7 +202,11 @@ theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset
#print Finset.sum_powerset_neg_one_pow_card_of_nonempty /-
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
- ∑ m in x.powerset, (-1 : ℤ) ^ m.card = 0 := by classical
+ ∑ m in x.powerset, (-1 : ℤ) ^ m.card = 0 := by
+ classical
+ rw [sum_powerset_neg_one_pow_card, if_neg]
+ rw [← Ne.def, ← nonempty_iff_ne_empty]
+ apply h0
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -202,11 +202,7 @@ theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset
#print Finset.sum_powerset_neg_one_pow_card_of_nonempty /-
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
- ∑ m in x.powerset, (-1 : ℤ) ^ m.card = 0 := by
- classical
- rw [sum_powerset_neg_one_pow_card, if_neg]
- rw [← Ne.def, ← nonempty_iff_ne_empty]
- apply h0
+ ∑ m in x.powerset, (-1 : ℤ) ^ m.card = 0 := by classical
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,12 +3,12 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Patrick Stevens
-/
-import Mathbin.Data.Nat.Choose.Basic
+import Data.Nat.Choose.Basic
import Mathbin.Tactic.Linarith.Default
-import Mathbin.Algebra.BigOperators.Ring
-import Mathbin.Algebra.BigOperators.Intervals
-import Mathbin.Algebra.BigOperators.Order
-import Mathbin.Algebra.BigOperators.NatAntidiagonal
+import Algebra.BigOperators.Ring
+import Algebra.BigOperators.Intervals
+import Algebra.BigOperators.Order
+import Algebra.BigOperators.NatAntidiagonal
#align_import data.nat.choose.sum from "leanprover-community/mathlib"@"3e32bc908f617039c74c06ea9a897e30c30803c2"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,11 +2,6 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Patrick Stevens
-
-! This file was ported from Lean 3 source module data.nat.choose.sum
-! leanprover-community/mathlib commit 3e32bc908f617039c74c06ea9a897e30c30803c2
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Data.Nat.Choose.Basic
import Mathbin.Tactic.Linarith.Default
@@ -15,6 +10,8 @@ import Mathbin.Algebra.BigOperators.Intervals
import Mathbin.Algebra.BigOperators.Order
import Mathbin.Algebra.BigOperators.NatAntidiagonal
+#align_import data.nat.choose.sum from "leanprover-community/mathlib"@"3e32bc908f617039c74c06ea9a897e30c30803c2"
+
/-!
# Sums of binomial coefficients
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -40,8 +40,7 @@ namespace Commute
variable [Semiring R] {x y : R} (h : Commute x y) (n : ℕ)
-include h
-
+#print Commute.add_pow /-
/-- A version of the **binomial theorem** for commuting elements in noncommutative semirings. -/
theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * choose n m :=
by
@@ -74,7 +73,9 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
congr 1
rw [sum_range_succ', sum_range_succ, h_first, h_last, MulZeroClass.mul_zero, add_zero, pow_succ]
#align commute.add_pow Commute.add_pow
+-/
+#print Commute.add_pow' /-
/-- 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' :
@@ -82,14 +83,17 @@ theorem add_pow' :
simp_rw [Finset.Nat.sum_antidiagonal_eq_sum_range_succ fun m p => choose n m • (x ^ m * y ^ p),
_root_.nsmul_eq_mul, cast_comm, h.add_pow]
#align commute.add_pow' Commute.add_pow'
+-/
end Commute
+#print add_pow /-
/-- The **binomial theorem** -/
theorem add_pow [CommSemiring R] (x y : R) (n : ℕ) :
(x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * choose n m :=
(Commute.all x y).add_pow n
#align add_pow add_pow
+-/
namespace Nat
@@ -153,6 +157,7 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
end Nat
+#print Int.alternating_sum_range_choose /-
theorem Int.alternating_sum_range_choose {n : ℕ} :
∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ) = if n = 0 then 1 else 0 :=
by
@@ -161,14 +166,18 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
simp only [one_pow, mul_one, add_left_neg] at h
rw [← h, zero_pow (Nat.succ_pos n), if_neg (Nat.succ_ne_zero n)]
#align int.alternating_sum_range_choose Int.alternating_sum_range_choose
+-/
+#print Int.alternating_sum_range_choose_of_ne /-
theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ) = 0 := by
rw [Int.alternating_sum_range_choose, if_neg h0]
#align int.alternating_sum_range_choose_of_ne Int.alternating_sum_range_choose_of_ne
+-/
namespace Finset
+#print Finset.sum_powerset_apply_card /-
theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
∑ m in x.powerset, f m.card = ∑ m in range (x.card + 1), x.card.choose m • f m :=
by
@@ -183,14 +192,18 @@ theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ →
refine' sum_congr powerset_len_eq_filter.symm fun z hz => _
rw [(mem_powerset_len.1 hz).2]
#align finset.sum_powerset_apply_card Finset.sum_powerset_apply_card
+-/
+#print Finset.sum_powerset_neg_one_pow_card /-
theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset α} :
∑ m in x.powerset, (-1 : ℤ) ^ m.card = if x = ∅ then 1 else 0 :=
by
rw [sum_powerset_apply_card]
simp only [nsmul_eq_mul', ← card_eq_zero, Int.alternating_sum_range_choose]
#align finset.sum_powerset_neg_one_pow_card Finset.sum_powerset_neg_one_pow_card
+-/
+#print Finset.sum_powerset_neg_one_pow_card_of_nonempty /-
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
∑ m in x.powerset, (-1 : ℤ) ^ m.card = 0 := by
classical
@@ -198,6 +211,7 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α}
rw [← Ne.def, ← nonempty_iff_ne_empty]
apply h0
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
+-/
end Finset
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -95,25 +95,25 @@ namespace Nat
#print Nat.sum_range_choose /-
/-- The sum of entries in a row of Pascal's triangle -/
-theorem sum_range_choose (n : ℕ) : (∑ m in range (n + 1), choose n m) = 2 ^ n := by
+theorem sum_range_choose (n : ℕ) : ∑ m in range (n + 1), choose n m = 2 ^ n := by
simpa using (add_pow 1 1 n).symm
#align nat.sum_range_choose Nat.sum_range_choose
-/
#print Nat.sum_range_choose_halfway /-
-theorem sum_range_choose_halfway (m : Nat) : (∑ i in range (m + 1), choose (2 * m + 1) i) = 4 ^ m :=
+theorem sum_range_choose_halfway (m : Nat) : ∑ i in range (m + 1), choose (2 * m + 1) i = 4 ^ m :=
have :
- (∑ i in range (m + 1), choose (2 * m + 1) (2 * m + 1 - i)) =
+ ∑ i in range (m + 1), choose (2 * m + 1) (2 * m + 1 - i) =
∑ i in range (m + 1), choose (2 * m + 1) i :=
sum_congr rfl fun i hi => choose_symm <| by linarith [mem_range.1 hi]
mul_right_injective₀ two_ne_zero <|
calc
- (2 * ∑ i in range (m + 1), choose (2 * m + 1) i) =
- (∑ i in range (m + 1), choose (2 * m + 1) i) +
+ 2 * ∑ i in range (m + 1), choose (2 * m + 1) i =
+ ∑ i in range (m + 1), choose (2 * m + 1) i +
∑ i in range (m + 1), choose (2 * m + 1) (2 * m + 1 - i) :=
by rw [two_mul, this]
_ =
- (∑ i in range (m + 1), choose (2 * m + 1) i) +
+ ∑ i in range (m + 1), choose (2 * m + 1) i +
∑ i in Ico (m + 1) (2 * m + 2), choose (2 * m + 1) i :=
by
rw [range_eq_Ico, sum_Ico_reflect]
@@ -154,7 +154,7 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
end Nat
theorem Int.alternating_sum_range_choose {n : ℕ} :
- (∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = if n = 0 then 1 else 0 :=
+ ∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ) = if n = 0 then 1 else 0 :=
by
cases n; · simp
have h := add_pow (-1 : ℤ) 1 n.succ
@@ -163,14 +163,14 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
#align int.alternating_sum_range_choose Int.alternating_sum_range_choose
theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
- (∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = 0 := by
+ ∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ) = 0 := by
rw [Int.alternating_sum_range_choose, if_neg h0]
#align int.alternating_sum_range_choose_of_ne Int.alternating_sum_range_choose_of_ne
namespace Finset
theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
- (∑ m in x.powerset, f m.card) = ∑ m in range (x.card + 1), x.card.choose m • f m :=
+ ∑ m in x.powerset, f m.card = ∑ m in range (x.card + 1), x.card.choose m • f m :=
by
trans ∑ m in range (x.card + 1), ∑ j in x.powerset.filter fun z => z.card = m, f j.card
· refine' (sum_fiberwise_of_maps_to _ _).symm
@@ -185,14 +185,14 @@ theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ →
#align finset.sum_powerset_apply_card Finset.sum_powerset_apply_card
theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset α} :
- (∑ m in x.powerset, (-1 : ℤ) ^ m.card) = if x = ∅ then 1 else 0 :=
+ ∑ m in x.powerset, (-1 : ℤ) ^ m.card = if x = ∅ then 1 else 0 :=
by
rw [sum_powerset_apply_card]
simp only [nsmul_eq_mul', ← card_eq_zero, Int.alternating_sum_range_choose]
#align finset.sum_powerset_neg_one_pow_card Finset.sum_powerset_neg_one_pow_card
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
- (∑ m in x.powerset, (-1 : ℤ) ^ m.card) = 0 := by
+ ∑ m in x.powerset, (-1 : ℤ) ^ m.card = 0 := by
classical
rw [sum_powerset_neg_one_pow_card, if_neg]
rw [← Ne.def, ← nonempty_iff_ne_empty]
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -127,7 +127,6 @@ theorem sum_range_choose_halfway (m : Nat) : (∑ i in range (m + 1), choose (2
_ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := (sum_range_add_sum_Ico _ (by linarith))
_ = 2 ^ (2 * m + 1) := (sum_range_choose (2 * m + 1))
_ = 2 * 4 ^ m := by rw [pow_succ, pow_mul]; rfl
-
#align nat.sum_range_choose_halfway Nat.sum_range_choose_halfway
-/
@@ -149,7 +148,6 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
_ ≤ ∑ m in range (2 * n + 1), choose (2 * n) (2 * n / 2) :=
(sum_le_sum fun i hi => choose_le_middle i (2 * n))
_ = (2 * n + 1) * choose (2 * n) n := by simp
-
#align nat.four_pow_le_two_mul_add_one_mul_central_binom Nat.four_pow_le_two_mul_add_one_mul_central_binom
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -196,9 +196,9 @@ theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
(∑ m in x.powerset, (-1 : ℤ) ^ m.card) = 0 := by
classical
- rw [sum_powerset_neg_one_pow_card, if_neg]
- rw [← Ne.def, ← nonempty_iff_ne_empty]
- apply h0
+ rw [sum_powerset_neg_one_pow_card, if_neg]
+ rw [← Ne.def, ← nonempty_iff_ne_empty]
+ apply h0
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
end Finset
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -160,7 +160,7 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
by
cases n; · simp
have h := add_pow (-1 : ℤ) 1 n.succ
- simp only [one_pow, mul_one, add_left_neg] at h
+ simp only [one_pow, mul_one, add_left_neg] at h
rw [← h, zero_pow (Nat.succ_pos n), if_neg (Nat.succ_ne_zero n)]
#align int.alternating_sum_range_choose Int.alternating_sum_range_choose
@@ -178,7 +178,7 @@ theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ →
· refine' (sum_fiberwise_of_maps_to _ _).symm
intro y hy
rw [mem_range, Nat.lt_succ_iff]
- rw [mem_powerset] at hy
+ rw [mem_powerset] at hy
exact card_le_of_subset hy
· refine' sum_congr rfl fun y hy => _
rw [← card_powerset_len, ← sum_const]
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -32,7 +32,7 @@ open Nat
open Finset
-open BigOperators
+open scoped BigOperators
variable {R : Type _}
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -42,12 +42,6 @@ variable [Semiring R] {x y : R} (h : Commute x y) (n : ℕ)
include h
-/- warning: commute.add_pow -> Commute.add_pow is a dubious translation:
-lean 3 declaration is
- forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R} {y : R}, (Commute.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) x y) -> (forall (n : Nat), Eq.{succ u1} R (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) x y) n) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x m) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) y (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) n m))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat R (HasLiftT.mk.{1, succ u1} Nat R (CoeTCₓ.coe.{1, succ u1} Nat R (Nat.castCoe.{u1} R (AddMonoidWithOne.toNatCast.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) (Nat.choose n m)))))
-but is expected to have type
- forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R} {y : R}, (Commute.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) x y) -> (forall (n : Nat), Eq.{succ u1} R (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) x y) n) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x m) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) y (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) n m))) (Nat.cast.{u1} R (Semiring.toNatCast.{u1} R _inst_1) (Nat.choose n m)))))
-Case conversion may be inaccurate. Consider using '#align commute.add_pow Commute.add_powₓ'. -/
/-- A version of the **binomial theorem** for commuting elements in noncommutative semirings. -/
theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * choose n m :=
by
@@ -81,12 +75,6 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
rw [sum_range_succ', sum_range_succ, h_first, h_last, MulZeroClass.mul_zero, add_zero, pow_succ]
#align commute.add_pow Commute.add_pow
-/- warning: commute.add_pow' -> Commute.add_pow' is a dubious translation:
-lean 3 declaration is
- forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R} {y : R}, (Commute.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) x y) -> (forall (n : Nat), Eq.{succ u1} R (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) x y) n) (Finset.sum.{u1, 0} R (Prod.{0, 0} Nat Nat) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.Nat.antidiagonal n) (fun (m : Prod.{0, 0} Nat Nat) => SMul.smul.{0, u1} Nat R (AddMonoid.SMul.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Nat.choose n (Prod.fst.{0, 0} Nat Nat m)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x (Prod.fst.{0, 0} Nat Nat m)) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) y (Prod.snd.{0, 0} Nat Nat m))))))
-but is expected to have type
- forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R} {y : R}, (Commute.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) x y) -> (forall (n : Nat), Eq.{succ u1} R (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) x y) n) (Finset.sum.{u1, 0} R (Prod.{0, 0} Nat Nat) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.Nat.antidiagonal n) (fun (m : Prod.{0, 0} Nat Nat) => HSMul.hSMul.{0, u1, u1} Nat R R (instHSMul.{0, u1} Nat R (AddMonoid.SMul.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (Nat.choose n (Prod.fst.{0, 0} Nat Nat m)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x (Prod.fst.{0, 0} Nat Nat m)) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) y (Prod.snd.{0, 0} Nat Nat m))))))
-Case conversion may be inaccurate. Consider using '#align commute.add_pow' Commute.add_pow'ₓ'. -/
/-- 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' :
@@ -97,12 +85,6 @@ theorem add_pow' :
end Commute
-/- warning: add_pow -> add_pow is a dubious translation:
-lean 3 declaration is
- forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (x : R) (y : R) (n : Nat), Eq.{succ u1} R (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))) x y) n) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) x m) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) y (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) n m))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat R (HasLiftT.mk.{1, succ u1} Nat R (CoeTCₓ.coe.{1, succ u1} Nat R (Nat.castCoe.{u1} R (AddMonoidWithOne.toNatCast.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))))) (Nat.choose n m))))
-but is expected to have type
- forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (x : R) (y : R) (n : Nat), Eq.{succ u1} R (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))) x y) n) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) x m) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) y (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) n m))) (Nat.cast.{u1} R (Semiring.toNatCast.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Nat.choose n m))))
-Case conversion may be inaccurate. Consider using '#align add_pow add_powₓ'. -/
/-- The **binomial theorem** -/
theorem add_pow [CommSemiring R] (x y : R) (n : ℕ) :
(x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * choose n m :=
@@ -173,12 +155,6 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
end Nat
-/- warning: int.alternating_sum_range_choose -> Int.alternating_sum_range_choose is a dubious translation:
-lean 3 declaration is
- forall {n : Nat}, Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.addCommMonoid (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.hasMul) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.monoid)) (Neg.neg.{0} Int Int.hasNeg (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne)))) m) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Int (HasLiftT.mk.{1, 1} Nat Int (CoeTCₓ.coe.{1, 1} Nat Int (coeBase.{1, 1} Nat Int Int.hasCoe))) (Nat.choose n m)))) (ite.{1} Int (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (Nat.decidableEq n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne))) (OfNat.ofNat.{0} Int 0 (OfNat.mk.{0} Int 0 (Zero.zero.{0} Int Int.hasZero))))
-but is expected to have type
- forall {n : Nat}, Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.instAddCommMonoidInt (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.instMulInt) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.instMonoidInt)) (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) m) (Nat.cast.{0} Int instNatCastInt (Nat.choose n m)))) (ite.{1} Int (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (instDecidableEqNat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (OfNat.ofNat.{0} Int 1 (instOfNatInt 1)) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
-Case conversion may be inaccurate. Consider using '#align int.alternating_sum_range_choose Int.alternating_sum_range_chooseₓ'. -/
theorem Int.alternating_sum_range_choose {n : ℕ} :
(∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = if n = 0 then 1 else 0 :=
by
@@ -188,12 +164,6 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
rw [← h, zero_pow (Nat.succ_pos n), if_neg (Nat.succ_ne_zero n)]
#align int.alternating_sum_range_choose Int.alternating_sum_range_choose
-/- warning: int.alternating_sum_range_choose_of_ne -> Int.alternating_sum_range_choose_of_ne is a dubious translation:
-lean 3 declaration is
- forall {n : Nat}, (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) -> (Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.addCommMonoid (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.hasMul) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.monoid)) (Neg.neg.{0} Int Int.hasNeg (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne)))) m) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Int (HasLiftT.mk.{1, 1} Nat Int (CoeTCₓ.coe.{1, 1} Nat Int (coeBase.{1, 1} Nat Int Int.hasCoe))) (Nat.choose n m)))) (OfNat.ofNat.{0} Int 0 (OfNat.mk.{0} Int 0 (Zero.zero.{0} Int Int.hasZero))))
-but is expected to have type
- forall {n : Nat}, (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) -> (Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.instAddCommMonoidInt (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.instMulInt) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.instMonoidInt)) (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) m) (Nat.cast.{0} Int instNatCastInt (Nat.choose n m)))) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
-Case conversion may be inaccurate. Consider using '#align int.alternating_sum_range_choose_of_ne Int.alternating_sum_range_choose_of_neₓ'. -/
theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
(∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = 0 := by
rw [Int.alternating_sum_range_choose, if_neg h0]
@@ -201,12 +171,6 @@ theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
namespace Finset
-/- warning: finset.sum_powerset_apply_card -> Finset.sum_powerset_apply_card is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : AddCommMonoid.{u1} α] (f : Nat -> α) {x : Finset.{u2} β}, Eq.{succ u1} α (Finset.sum.{u1, u2} α (Finset.{u2} β) _inst_1 (Finset.powerset.{u2} β x) (fun (m : Finset.{u2} β) => f (Finset.card.{u2} β m))) (Finset.sum.{u1, 0} α Nat _inst_1 (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Finset.card.{u2} β x) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => SMul.smul.{0, u1} Nat α (AddMonoid.SMul.{u1} α (AddCommMonoid.toAddMonoid.{u1} α _inst_1)) (Nat.choose (Finset.card.{u2} β x) m) (f m)))
-but is expected to have type
- forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : AddCommMonoid.{u2} α] (f : Nat -> α) {x : Finset.{u1} β}, Eq.{succ u2} α (Finset.sum.{u2, u1} α (Finset.{u1} β) _inst_1 (Finset.powerset.{u1} β x) (fun (m : Finset.{u1} β) => f (Finset.card.{u1} β m))) (Finset.sum.{u2, 0} α Nat _inst_1 (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Finset.card.{u1} β x) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HSMul.hSMul.{0, u2, u2} Nat α α (instHSMul.{0, u2} Nat α (AddMonoid.SMul.{u2} α (AddCommMonoid.toAddMonoid.{u2} α _inst_1))) (Nat.choose (Finset.card.{u1} β x) m) (f m)))
-Case conversion may be inaccurate. Consider using '#align finset.sum_powerset_apply_card Finset.sum_powerset_apply_cardₓ'. -/
theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
(∑ m in x.powerset, f m.card) = ∑ m in range (x.card + 1), x.card.choose m • f m :=
by
@@ -222,12 +186,6 @@ theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ →
rw [(mem_powerset_len.1 hz).2]
#align finset.sum_powerset_apply_card Finset.sum_powerset_apply_card
-/- warning: finset.sum_powerset_neg_one_pow_card -> Finset.sum_powerset_neg_one_pow_card is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {x : Finset.{u1} α}, Eq.{1} Int (Finset.sum.{0, u1} Int (Finset.{u1} α) Int.addCommMonoid (Finset.powerset.{u1} α x) (fun (m : Finset.{u1} α) => HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.monoid)) (Neg.neg.{0} Int Int.hasNeg (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne)))) (Finset.card.{u1} α m))) (ite.{1} Int (Eq.{succ u1} (Finset.{u1} α) x (EmptyCollection.emptyCollection.{u1} (Finset.{u1} α) (Finset.hasEmptyc.{u1} α))) (Finset.decidableEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b) x (EmptyCollection.emptyCollection.{u1} (Finset.{u1} α) (Finset.hasEmptyc.{u1} α))) (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne))) (OfNat.ofNat.{0} Int 0 (OfNat.mk.{0} Int 0 (Zero.zero.{0} Int Int.hasZero))))
-but is expected to have type
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {x : Finset.{u1} α}, Eq.{1} Int (Finset.sum.{0, u1} Int (Finset.{u1} α) Int.instAddCommMonoidInt (Finset.powerset.{u1} α x) (fun (m : Finset.{u1} α) => HPow.hPow.{0, 0, 0} Int Nat Int Int.instHPowIntNat (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) (Finset.card.{u1} α m))) (ite.{1} Int (Eq.{succ u1} (Finset.{u1} α) x (EmptyCollection.emptyCollection.{u1} (Finset.{u1} α) (Finset.instEmptyCollectionFinset.{u1} α))) (Finset.decidableEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b) x (EmptyCollection.emptyCollection.{u1} (Finset.{u1} α) (Finset.instEmptyCollectionFinset.{u1} α))) (OfNat.ofNat.{0} Int 1 (instOfNatInt 1)) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
-Case conversion may be inaccurate. Consider using '#align finset.sum_powerset_neg_one_pow_card Finset.sum_powerset_neg_one_pow_cardₓ'. -/
theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset α} :
(∑ m in x.powerset, (-1 : ℤ) ^ m.card) = if x = ∅ then 1 else 0 :=
by
@@ -235,12 +193,6 @@ theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset
simp only [nsmul_eq_mul', ← card_eq_zero, Int.alternating_sum_range_choose]
#align finset.sum_powerset_neg_one_pow_card Finset.sum_powerset_neg_one_pow_card
-/- warning: finset.sum_powerset_neg_one_pow_card_of_nonempty -> Finset.sum_powerset_neg_one_pow_card_of_nonempty is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {x : Finset.{u1} α}, (Finset.Nonempty.{u1} α x) -> (Eq.{1} Int (Finset.sum.{0, u1} Int (Finset.{u1} α) Int.addCommMonoid (Finset.powerset.{u1} α x) (fun (m : Finset.{u1} α) => HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.monoid)) (Neg.neg.{0} Int Int.hasNeg (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne)))) (Finset.card.{u1} α m))) (OfNat.ofNat.{0} Int 0 (OfNat.mk.{0} Int 0 (Zero.zero.{0} Int Int.hasZero))))
-but is expected to have type
- forall {α : Type.{u1}} {x : Finset.{u1} α}, (Finset.Nonempty.{u1} α x) -> (Eq.{1} Int (Finset.sum.{0, u1} Int (Finset.{u1} α) Int.instAddCommMonoidInt (Finset.powerset.{u1} α x) (fun (m : Finset.{u1} α) => HPow.hPow.{0, 0, 0} Int Nat Int Int.instHPowIntNat (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) (Finset.card.{u1} α m))) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
-Case conversion may be inaccurate. Consider using '#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonemptyₓ'. -/
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
(∑ m in x.powerset, (-1 : ℤ) ^ m.card) = 0 := by
classical
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -53,13 +53,9 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
by
let t : ℕ → ℕ → R := fun n m => x ^ m * y ^ (n - m) * choose n m
change (x + y) ^ n = ∑ m in range (n + 1), t n m
- have h_first : ∀ n, t n 0 = y ^ n := fun n =>
- by
- dsimp [t]
+ have h_first : ∀ n, t n 0 = y ^ n := fun n => by dsimp [t];
rw [choose_zero_right, pow_zero, Nat.cast_one, mul_one, one_mul]
- have h_last : ∀ n, t n n.succ = 0 := fun n =>
- by
- dsimp [t]
+ have h_last : ∀ n, t n n.succ = 0 := fun n => by dsimp [t];
rw [choose_succ_self, Nat.cast_zero, MulZeroClass.mul_zero]
have h_middle :
∀ n i : ℕ, i ∈ range n.succ → (t n.succ ∘ Nat.succ) i = x * t n i + y * t n i.succ :=
@@ -77,8 +73,7 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
rw [pow_succ y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
induction' n with n ih
· rw [pow_zero, sum_range_succ, range_zero, sum_empty, zero_add]
- dsimp [t]
- rw [pow_zero, pow_zero, choose_self, Nat.cast_one, mul_one, mul_one]
+ dsimp [t]; rw [pow_zero, pow_zero, choose_self, Nat.cast_one, mul_one, mul_one]
· rw [sum_range_succ', h_first]
rw [sum_congr rfl (h_middle n), sum_add_distrib, add_assoc]
rw [pow_succ (x + y), ih, add_mul, mul_sum, mul_sum]
@@ -149,9 +144,7 @@ theorem sum_range_choose_halfway (m : Nat) : (∑ i in range (m + 1), choose (2
· linarith
_ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := (sum_range_add_sum_Ico _ (by linarith))
_ = 2 ^ (2 * m + 1) := (sum_range_choose (2 * m + 1))
- _ = 2 * 4 ^ m := by
- rw [pow_succ, pow_mul]
- rfl
+ _ = 2 * 4 ^ m := by rw [pow_succ, pow_mul]; rfl
#align nat.sum_range_choose_halfway Nat.sum_range_choose_halfway
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/da3fc4a33ff6bc75f077f691dc94c217b8d41559
@@ -184,7 +184,7 @@ end Nat
lean 3 declaration is
forall {n : Nat}, Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.addCommMonoid (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.hasMul) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.monoid)) (Neg.neg.{0} Int Int.hasNeg (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne)))) m) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Int (HasLiftT.mk.{1, 1} Nat Int (CoeTCₓ.coe.{1, 1} Nat Int (coeBase.{1, 1} Nat Int Int.hasCoe))) (Nat.choose n m)))) (ite.{1} Int (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (Nat.decidableEq n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne))) (OfNat.ofNat.{0} Int 0 (OfNat.mk.{0} Int 0 (Zero.zero.{0} Int Int.hasZero))))
but is expected to have type
- forall {n : Nat}, Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.instAddCommMonoidInt (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.instMulInt) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.instMonoidInt)) (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) m) (Nat.cast.{0} Int Int.instNatCastInt (Nat.choose n m)))) (ite.{1} Int (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (instDecidableEqNat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (OfNat.ofNat.{0} Int 1 (instOfNatInt 1)) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
+ forall {n : Nat}, Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.instAddCommMonoidInt (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.instMulInt) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.instMonoidInt)) (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) m) (Nat.cast.{0} Int instNatCastInt (Nat.choose n m)))) (ite.{1} Int (Eq.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (instDecidableEqNat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (OfNat.ofNat.{0} Int 1 (instOfNatInt 1)) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
Case conversion may be inaccurate. Consider using '#align int.alternating_sum_range_choose Int.alternating_sum_range_chooseₓ'. -/
theorem Int.alternating_sum_range_choose {n : ℕ} :
(∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = if n = 0 then 1 else 0 :=
@@ -199,7 +199,7 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
lean 3 declaration is
forall {n : Nat}, (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) -> (Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.addCommMonoid (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.hasMul) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.monoid)) (Neg.neg.{0} Int Int.hasNeg (OfNat.ofNat.{0} Int 1 (OfNat.mk.{0} Int 1 (One.one.{0} Int Int.hasOne)))) m) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Int (HasLiftT.mk.{1, 1} Nat Int (CoeTCₓ.coe.{1, 1} Nat Int (coeBase.{1, 1} Nat Int Int.hasCoe))) (Nat.choose n m)))) (OfNat.ofNat.{0} Int 0 (OfNat.mk.{0} Int 0 (Zero.zero.{0} Int Int.hasZero))))
but is expected to have type
- forall {n : Nat}, (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) -> (Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.instAddCommMonoidInt (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.instMulInt) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.instMonoidInt)) (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) m) (Nat.cast.{0} Int Int.instNatCastInt (Nat.choose n m)))) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
+ forall {n : Nat}, (Ne.{1} Nat n (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) -> (Eq.{1} Int (Finset.sum.{0, 0} Int Nat Int.instAddCommMonoidInt (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (m : Nat) => HMul.hMul.{0, 0, 0} Int Int Int (instHMul.{0} Int Int.instMulInt) (HPow.hPow.{0, 0, 0} Int Nat Int (instHPow.{0, 0} Int Nat (Monoid.Pow.{0} Int Int.instMonoidInt)) (Neg.neg.{0} Int Int.instNegInt (OfNat.ofNat.{0} Int 1 (instOfNatInt 1))) m) (Nat.cast.{0} Int instNatCastInt (Nat.choose n m)))) (OfNat.ofNat.{0} Int 0 (instOfNatInt 0)))
Case conversion may be inaccurate. Consider using '#align int.alternating_sum_range_choose_of_ne Int.alternating_sum_range_choose_of_neₓ'. -/
theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
(∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = 0 := by
mathlib commit https://github.com/leanprover-community/mathlib/commit/3180fab693e2cee3bff62675571264cb8778b212
@@ -60,7 +60,7 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
have h_last : ∀ n, t n n.succ = 0 := fun n =>
by
dsimp [t]
- rw [choose_succ_self, Nat.cast_zero, mul_zero]
+ rw [choose_succ_self, Nat.cast_zero, MulZeroClass.mul_zero]
have h_middle :
∀ n i : ℕ, i ∈ range n.succ → (t n.succ ∘ Nat.succ) i = x * t n i + y * t n i.succ :=
by
@@ -72,7 +72,7 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
· rw [pow_succ x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
· rw [← mul_assoc y, ← mul_assoc y, (h.symm.pow_right i.succ).Eq]
by_cases h_eq : i = n
- · rw [h_eq, choose_succ_self, Nat.cast_zero, mul_zero, mul_zero]
+ · rw [h_eq, choose_succ_self, Nat.cast_zero, MulZeroClass.mul_zero, MulZeroClass.mul_zero]
· rw [succ_sub (lt_of_le_of_ne h_le h_eq)]
rw [pow_succ y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
induction' n with n ih
@@ -83,7 +83,7 @@ theorem add_pow : (x + y) ^ n = ∑ m in range (n + 1), x ^ m * y ^ (n - m) * ch
rw [sum_congr rfl (h_middle n), sum_add_distrib, add_assoc]
rw [pow_succ (x + y), ih, add_mul, mul_sum, mul_sum]
congr 1
- rw [sum_range_succ', sum_range_succ, h_first, h_last, mul_zero, add_zero, pow_succ]
+ rw [sum_range_succ', sum_range_succ, h_first, h_last, MulZeroClass.mul_zero, add_zero, pow_succ]
#align commute.add_pow Commute.add_pow
/- warning: commute.add_pow' -> Commute.add_pow' is a dubious translation:
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -147,8 +147,8 @@ theorem sum_range_choose_halfway (m : Nat) : (∑ i in range (m + 1), choose (2
rw [tsub_eq_iff_eq_add_of_le A]
ring
· linarith
- _ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := sum_range_add_sum_Ico _ (by linarith)
- _ = 2 ^ (2 * m + 1) := sum_range_choose (2 * m + 1)
+ _ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := (sum_range_add_sum_Ico _ (by linarith))
+ _ = 2 ^ (2 * m + 1) := (sum_range_choose (2 * m + 1))
_ = 2 * 4 ^ m := by
rw [pow_succ, pow_mul]
rfl
@@ -172,7 +172,7 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
4 ^ n = (1 + 1) ^ (2 * n) := by norm_num [pow_mul]
_ = ∑ m in range (2 * n + 1), choose (2 * n) m := by simp [add_pow]
_ ≤ ∑ m in range (2 * n + 1), choose (2 * n) (2 * n / 2) :=
- sum_le_sum fun i hi => choose_le_middle i (2 * n)
+ (sum_le_sum fun i hi => choose_le_middle i (2 * n))
_ = (2 * n + 1) * choose (2 * n) n := by simp
#align nat.four_pow_le_two_mul_add_one_mul_central_binom Nat.four_pow_le_two_mul_add_one_mul_central_binom
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
These are changes from #11997, the latest adaptation PR for nightly-2024-04-07, which can be made directly on master.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>
@@ -183,7 +183,7 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type*} {x : Finset α} (
(∑ m in x.powerset, (-1 : ℤ) ^ m.card) = 0 := by
classical
rw [sum_powerset_neg_one_pow_card, if_neg]
- rw [← Ne.def, ← nonempty_iff_ne_empty]
+ rw [← Ne, ← nonempty_iff_ne_empty]
apply h0
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
Take the content of
Algebra.BigOperators.List.Basic
Algebra.BigOperators.List.Lemmas
Algebra.BigOperators.Multiset.Basic
Algebra.BigOperators.Multiset.Lemmas
Algebra.BigOperators.Multiset.Order
Algebra.BigOperators.Order
and sort it into six files:
Algebra.Order.BigOperators.Group.List
. I credit Yakov for https://github.com/leanprover-community/mathlib/pull/8543.Algebra.Order.BigOperators.Group.Multiset
. Copyright inherited from Algebra.BigOperators.Multiset.Order
.Algebra.Order.BigOperators.Group.Finset
. Copyright inherited from Algebra.BigOperators.Order
.Algebra.Order.BigOperators.Ring.List
. I credit Stuart for https://github.com/leanprover-community/mathlib/pull/10184.Algebra.Order.BigOperators.Ring.Multiset
. I credit Ruben for https://github.com/leanprover-community/mathlib/pull/8787.Algebra.Order.BigOperators.Ring.Finset
. I credit Floris for https://github.com/leanprover-community/mathlib/pull/1294.Here are the design decisions at play:
Data.Nat.Order.Basic
in a few List
files.Algebra.Order.BigOperators
instead of Algebra.BigOperators.Order
because algebraic order theory is more of a theory than big operators algebra. Another reason is that algebraic order theory is the only way to mix pure order and pure algebra, while there are more ways to mix pure finiteness and pure algebra than just big operators.Algebra.Order.BigOperators.Group
should be additivisable (except a few Nat
- or Int
-specific lemmas). In contrast, things under Algebra.Order.BigOperators.Ring
are more prone to having heavy imports.List
vs Multiset
vs Finset
. This is not strictly necessary, and can be relaxed in cases where there aren't that many lemmas to be had. As an example, I could split out the AbsoluteValue
lemmas from Algebra.Order.BigOperators.Ring.Finset
to a file Algebra.Order.BigOperators.Ring.AbsoluteValue
and it could stay this way until too many lemmas are in this file (or a split is needed for import reasons), in which case we would need files Algebra.Order.BigOperators.Ring.AbsoluteValue.Finset
, Algebra.Order.BigOperators.Ring.AbsoluteValue.Multiset
, etc...Finsupp
big operator and finprod
/finsum
order lemmas also belong in Algebra.Order.BigOperators
. I haven't done so in this PR because the diff is big enough like that.@@ -3,13 +3,13 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Patrick Stevens
-/
-import Mathlib.Data.Nat.Choose.Basic
-import Mathlib.Tactic.Ring
-import Mathlib.Tactic.Linarith
-import Mathlib.Algebra.BigOperators.Ring
import Mathlib.Algebra.BigOperators.Intervals
-import Mathlib.Algebra.BigOperators.Order
import Mathlib.Algebra.BigOperators.NatAntidiagonal
+import Mathlib.Algebra.BigOperators.Ring
+import Mathlib.Algebra.Order.BigOperators.Group.Finset
+import Mathlib.Data.Nat.Choose.Basic
+import Mathlib.Tactic.Linarith
+import Mathlib.Tactic.Ring
#align_import data.nat.choose.sum from "leanprover-community/mathlib"@"4c19a16e4b705bf135cf9a80ac18fcc99c438514"
We change the following field in the definition of an additive commutative monoid:
nsmul_succ : ∀ (n : ℕ) (x : G),
- AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+ AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x
where the latter is more natural
We adjust the definitions of ^
in monoids, groups, etc.
Originally there was a warning comment about why this natural order was preferred
use
x * npowRec n x
and notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
is blocked, to avoid deep recursion issues.
but it seems to no longer apply.
Remarks on the PR :
pow_succ
and pow_succ'
have switched their meanings.Ideal.IsPrime.mul_mem_pow
which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul
.@@ -52,21 +52,21 @@ theorem add_pow (h : Commute x y) (n : ℕ) :
dsimp only [t]
rw [Function.comp_apply, choose_succ_succ, Nat.cast_add, mul_add]
congr 1
- · rw [pow_succ x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
+ · rw [pow_succ' x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
· rw [← mul_assoc y, ← mul_assoc y, (h.symm.pow_right i.succ).eq]
by_cases h_eq : i = n
· rw [h_eq, choose_succ_self, Nat.cast_zero, mul_zero, mul_zero]
· rw [succ_sub (lt_of_le_of_ne h_le h_eq)]
- rw [pow_succ y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
+ rw [pow_succ' y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
induction' n with n ih
· rw [_root_.pow_zero, sum_range_succ, range_zero, sum_empty, zero_add]
dsimp only [t]
rw [_root_.pow_zero, _root_.pow_zero, choose_self, Nat.cast_one, mul_one, mul_one]
· rw [sum_range_succ', h_first]
erw [sum_congr rfl (h_middle n), sum_add_distrib, add_assoc]
- rw [pow_succ (x + y), ih, add_mul, mul_sum, mul_sum]
+ rw [pow_succ' (x + y), ih, add_mul, mul_sum, mul_sum]
congr 1
- rw [sum_range_succ', sum_range_succ, h_first, h_last, mul_zero, add_zero, _root_.pow_succ]
+ rw [sum_range_succ', sum_range_succ, h_first, h_last, mul_zero, add_zero, _root_.pow_succ']
#align commute.add_pow Commute.add_pow
/-- A version of `Commute.add_pow` that avoids ℕ-subtraction by summing over the antidiagonal and
@@ -189,7 +189,7 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type*} {x : Finset α} (
variable {M R : Type*} [CommMonoid M] [NonAssocSemiring R]
--- Porting note: new lemma
+-- Porting note (#10756): new lemma
@[to_additive sum_choose_succ_nsmul]
theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
(∏ i in range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i) =
@@ -202,7 +202,7 @@ theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M)
rw [prod_range_succ']
simpa [Nat.choose_succ_succ, pow_add, prod_mul_distrib, A, mul_assoc] using mul_comm _ _
--- Porting note: new lemma
+-- Porting note (#10756): new lemma
@[to_additive sum_antidiagonal_choose_succ_nsmul]
theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
(∏ ij in antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0
branch as we update to intermediate nightlies.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>
@@ -114,7 +114,7 @@ theorem sum_range_choose_halfway (m : Nat) : (∑ i in range (m + 1), choose (2
· omega }
_ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := sum_range_add_sum_Ico _ (by omega)
_ = 2 ^ (2 * m + 1) := sum_range_choose (2 * m + 1)
- _ = 2 * 4 ^ m := by rw [pow_succ, pow_mul, mul_comm]; rfl
+ _ = 2 * 4 ^ m := by rw [Nat.pow_succ, pow_mul, mul_comm]; rfl
#align nat.sum_range_choose_halfway Nat.sum_range_choose_halfway
theorem choose_middle_le_pow (n : ℕ) : choose (2 * n + 1) n ≤ 4 ^ n := by
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -189,7 +189,7 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type*} {x : Finset α} (
variable {M R : Type*} [CommMonoid M] [NonAssocSemiring R]
--- porting note: new lemma
+-- Porting note: new lemma
@[to_additive sum_choose_succ_nsmul]
theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
(∏ i in range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i) =
@@ -202,7 +202,7 @@ theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M)
rw [prod_range_succ']
simpa [Nat.choose_succ_succ, pow_add, prod_mul_distrib, A, mul_assoc] using mul_comm _ _
--- porting note: new lemma
+-- Porting note: new lemma
@[to_additive sum_antidiagonal_choose_succ_nsmul]
theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
(∏ ij in antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
@@ -216,7 +216,7 @@ theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ
· refine prod_congr rfl fun i hi ↦ ?_
rw [Nat.choose_symm (this _ hi)]
--- porting note: moved from `Mathlib.Analysis.Calculus.ContDiff`
+-- Porting note: moved from `Mathlib.Analysis.Calculus.ContDiff`
/-- 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 ran tryAtEachStep on all files under Mathlib
to find all locations where omega
succeeds. For each that was a linarith
without an only
, I tried replacing it with omega
, and I verified that elaboration time got smaller. (In almost all cases, there was a noticeable speedup.) I also replaced some slow aesop
s along the way.
@@ -106,20 +106,20 @@ theorem sum_range_choose_halfway (m : Nat) : (∑ i in range (m + 1), choose (2
∑ i in Ico (m + 1) (2 * m + 2), choose (2 * m + 1) i := by
{ rw [range_eq_Ico, sum_Ico_reflect]
· congr
- have A : m + 1 ≤ 2 * m + 1 := by linarith
+ have A : m + 1 ≤ 2 * m + 1 := by omega
rw [add_comm, add_tsub_assoc_of_le A, ← add_comm]
congr
rw [tsub_eq_iff_eq_add_of_le A]
ring
- · linarith }
- _ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := sum_range_add_sum_Ico _ (by linarith)
+ · omega }
+ _ = ∑ i in range (2 * m + 2), choose (2 * m + 1) i := sum_range_add_sum_Ico _ (by omega)
_ = 2 ^ (2 * m + 1) := sum_range_choose (2 * m + 1)
_ = 2 * 4 ^ m := by rw [pow_succ, pow_mul, mul_comm]; rfl
#align nat.sum_range_choose_halfway Nat.sum_range_choose_halfway
theorem choose_middle_le_pow (n : ℕ) : choose (2 * n + 1) n ≤ 4 ^ n := by
have t : choose (2 * n + 1) n ≤ ∑ i in range (n + 1), choose (2 * n + 1) i :=
- single_le_sum (fun x _ ↦ by linarith) (self_mem_range_succ n)
+ single_le_sum (fun x _ ↦ by omega) (self_mem_range_succ n)
simpa [sum_range_choose_halfway n] using t
#align nat.choose_middle_le_pow Nat.choose_middle_le_pow
@@ -136,9 +136,9 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
theorem sum_Icc_choose (n k : ℕ) : ∑ m in Icc k n, m.choose k = (n + 1).choose (k + 1) := by
cases' le_or_gt k n with h h
· induction' n, h using le_induction with n _ ih; · simp
- rw [← Ico_insert_right (by linarith), sum_insert (by simp),
+ rw [← Ico_insert_right (by omega), sum_insert (by simp),
show Ico k (n + 1) = Icc k n by rfl, ih, choose_succ_succ' (n + 1)]
- · rw [choose_eq_zero_of_lt (by linarith), Icc_eq_empty_of_lt h, sum_empty]
+ · rw [choose_eq_zero_of_lt (by omega), Icc_eq_empty_of_lt h, sum_empty]
end Nat
@@ -41,15 +41,15 @@ theorem add_pow (h : Commute x y) (n : ℕ) :
let t : ℕ → ℕ → R := fun n m ↦ x ^ m * y ^ (n - m) * choose n m
change (x + y) ^ n = ∑ m in range (n + 1), t n m
have h_first : ∀ n, t n 0 = y ^ n := fun n ↦ by
- simp only [choose_zero_right, _root_.pow_zero, Nat.cast_one, mul_one, one_mul, tsub_zero]
+ simp only [t, choose_zero_right, _root_.pow_zero, Nat.cast_one, mul_one, one_mul, tsub_zero]
have h_last : ∀ n, t n n.succ = 0 := fun n ↦ by
- simp only [ge_iff_le, choose_succ_self, cast_zero, mul_zero]
+ simp only [t, ge_iff_le, choose_succ_self, cast_zero, mul_zero]
have h_middle :
∀ n i : ℕ, i ∈ range n.succ → (t n.succ ∘ Nat.succ) i =
x * t n i + y * t n i.succ := by
intro n i h_mem
have h_le : i ≤ n := Nat.le_of_lt_succ (mem_range.mp h_mem)
- dsimp only
+ dsimp only [t]
rw [Function.comp_apply, choose_succ_succ, Nat.cast_add, mul_add]
congr 1
· rw [pow_succ x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
@@ -60,7 +60,7 @@ theorem add_pow (h : Commute x y) (n : ℕ) :
rw [pow_succ y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
induction' n with n ih
· rw [_root_.pow_zero, sum_range_succ, range_zero, sum_empty, zero_add]
- dsimp only
+ dsimp only [t]
rw [_root_.pow_zero, _root_.pow_zero, choose_self, Nat.cast_one, mul_one, mul_one]
· rw [sum_range_succ', h_first]
erw [sum_congr rfl (h_middle n), sum_add_distrib, add_assoc]
have
, replace
and suffices
(#10640)
No changes to tactic file, it's just boring fixes throughout the library.
This follows on from #6964.
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -196,8 +196,8 @@ theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M)
(∏ i in range (n + 1), f i (n + 1 - i) ^ n.choose i) *
∏ i in range (n + 1), f (i + 1) (n - i) ^ n.choose i := by
have A : (∏ i in range (n + 1), f (i + 1) (n - i) ^ (n.choose (i + 1))) * f 0 (n + 1) =
- ∏ i in range (n + 1), f i (n + 1 - i) ^ (n.choose i)
- · rw [prod_range_succ, prod_range_succ']
+ ∏ i in range (n + 1), f i (n + 1 - i) ^ (n.choose i) := by
+ rw [prod_range_succ, prod_range_succ']
simp
rw [prod_range_succ']
simpa [Nat.choose_succ_succ, pow_add, prod_mul_distrib, A, mul_assoc] using mul_comm _ _
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
@@ -127,7 +127,7 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
4 ^ n ≤ (2 * n + 1) * choose (2 * n) n :=
calc
4 ^ n = (1 + 1) ^ (2 * n) := by norm_num [pow_mul]
- _ = ∑ m in range (2 * n + 1), choose (2 * n) m := by simp [add_pow]
+ _ = ∑ m in range (2 * n + 1), choose (2 * n) m := by set_option simprocs false in simp [add_pow]
_ ≤ ∑ m in range (2 * n + 1), choose (2 * n) (2 * n / 2) := by gcongr; apply choose_le_middle
_ = (2 * n + 1) * choose (2 * n) n := by simp
#align nat.four_pow_le_two_mul_add_one_mul_central_binom Nat.four_pow_le_two_mul_add_one_mul_central_binom
f ^ n
(#9617)
This involves moving lemmas from Algebra.GroupPower.Ring
to Algebra.GroupWithZero.Basic
and changing some 0 < n
assumptions to n ≠ 0
.
From LeanAPAP
@@ -149,7 +149,7 @@ theorem Int.alternating_sum_range_choose {n : ℕ} :
| succ n =>
have h := add_pow (-1 : ℤ) 1 n.succ
simp only [one_pow, mul_one, add_left_neg] at h
- rw [← h, zero_pow (Nat.succ_pos n), if_neg (Nat.succ_ne_zero n)]
+ rw [← h, zero_pow n.succ_ne_zero, if_neg (Nat.succ_ne_zero n)]
#align int.alternating_sum_range_choose Int.alternating_sum_range_choose
theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
@@ -132,6 +132,14 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
_ = (2 * n + 1) * choose (2 * n) n := by simp
#align nat.four_pow_le_two_mul_add_one_mul_central_binom Nat.four_pow_le_two_mul_add_one_mul_central_binom
+/-- **Zhu Shijie's identity** aka hockey-stick identity. -/
+theorem sum_Icc_choose (n k : ℕ) : ∑ m in Icc k n, m.choose k = (n + 1).choose (k + 1) := by
+ cases' le_or_gt k n with h h
+ · induction' n, h using le_induction with n _ ih; · simp
+ rw [← Ico_insert_right (by linarith), sum_insert (by simp),
+ show Ico k (n + 1) = Icc k n by rfl, ih, choose_succ_succ' (n + 1)]
+ · rw [choose_eq_zero_of_lt (by linarith), Icc_eq_empty_of_lt h, sum_empty]
+
end Nat
theorem Int.alternating_sum_range_choose {n : ℕ} :
cases x with | ...
instead of cases x; case => ...
(#9321)
This converts usages of the pattern
cases h
case inl h' => ...
case inr h' => ...
which derive from mathported code, to the "structured cases
" syntax:
cases h with
| inl h' => ...
| inr h' => ...
The case where the subgoals are handled with ·
instead of case
is more contentious (and much more numerous) so I left those alone. This pattern also appears with cases'
, induction
, induction'
, and rcases
. Furthermore, there is a similar transformation for by_cases
:
by_cases h : cond
case pos => ...
case neg => ...
is replaced by:
if h : cond then
...
else
...
Co-authored-by: Mario Carneiro <di.gama@gmail.com>
@@ -136,8 +136,9 @@ end Nat
theorem Int.alternating_sum_range_choose {n : ℕ} :
(∑ m in range (n + 1), ((-1) ^ m * ↑(choose n m) : ℤ)) = if n = 0 then 1 else 0 := by
- cases n; · simp
- case succ n =>
+ cases n with
+ | zero => simp
+ | succ n =>
have h := add_pow (-1 : ℤ) 1 n.succ
simp only [one_pow, mul_one, add_left_neg] at h
rw [← h, zero_pow (Nat.succ_pos n), if_neg (Nat.succ_ne_zero n)]
Finset
lemma names (#8894)
Change a few lemma names that have historically bothered me.
Finset.card_le_of_subset
→ Finset.card_le_card
Multiset.card_le_of_le
→ Multiset.card_le_card
Multiset.card_lt_of_lt
→ Multiset.card_lt_card
Set.ncard_le_of_subset
→ Set.ncard_le_ncard
Finset.image_filter
→ Finset.filter_image
CompleteLattice.finset_sup_compact_of_compact
→ CompleteLattice.isCompactElement_finset_sup
@@ -157,7 +157,7 @@ theorem sum_powerset_apply_card {α β : Type*} [AddCommMonoid α] (f : ℕ →
intro y hy
rw [mem_range, Nat.lt_succ_iff]
rw [mem_powerset] at hy
- exact card_le_of_subset hy
+ exact card_le_card hy
· refine' sum_congr rfl fun y _ ↦ _
rw [← card_powersetCard, ← sum_const]
refine' sum_congr powersetCard_eq_filter.symm fun z hz ↦ _
Finset.Nat.antidiagonal
(#7486)
We define a type class Finset.HasAntidiagonal A
which contains a function
antidiagonal : A → Finset (A × A)
such that antidiagonal n
is the Finset of all pairs adding to n
, as witnessed by mem_antidiagonal
.
When A
is a canonically ordered add monoid with locally finite order
this typeclass can be instantiated with Finset.antidiagonalOfLocallyFinite
.
This applies in particular when A
is ℕ
, more generally or σ →₀ ℕ
,
or even ι →₀ A
under the additional assumption OrderedSub A
that make it a canonically ordered add monoid.
(In fact, we would just need an AddMonoid
with a compatible order,
finite Iic
, such that if a + b = n
, then a, b ≤ n
,
and any finiteness condition would be OK.)
For computational reasons it is better to manually provide instances for ℕ
and σ →₀ ℕ
, to avoid quadratic runtime performance.
These instances are provided as Finset.Nat.instHasAntidiagonal
and Finsupp.instHasAntidiagonal
.
This is why Finset.antidiagonalOfLocallyFinite
is an abbrev
and not an instance
.
This definition does not exactly match with that of Multiset.antidiagonal
defined in Mathlib.Data.Multiset.Antidiagonal
, because of the multiplicities.
Indeed, by counting multiplicities, Multiset α
is equivalent to α →₀ ℕ
,
but Finset.antidiagonal
and Multiset.antidiagonal
will return different objects.
For example, for s : Multiset ℕ := {0,0,0}
, Multiset.antidiagonal s
has 8 elements
but Finset.antidiagonal s
has only 4.
def s : Multiset ℕ := {0, 0, 0}
#eval (Finset.antidiagonal s).card -- 4
#eval Multiset.card (Multiset.antidiagonal s) -- 8
HasMulAntidiagonal
(for monoids).
For PNat
, we will recover the set of divisors of a strictly positive integer.This closes #7917
Co-authored by: María Inés de Frutos-Fernández <mariaines.dff@gmail.com> and Eric Wieser <efw27@cam.ac.uk>
Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr> Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -72,7 +72,7 @@ theorem add_pow (h : Commute x y) (n : ℕ) :
/-- 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 in Nat.antidiagonal n, choose n m.fst • (x ^ m.fst * y ^ m.snd) := by
+ (x + y) ^ n = ∑ m in antidiagonal n, choose n m.fst • (x ^ m.fst * y ^ m.snd) := by
simp_rw [Finset.Nat.sum_antidiagonal_eq_sum_range_succ fun m p ↦ choose n m • (x ^ m * y ^ p),
_root_.nsmul_eq_mul, cast_comm, h.add_pow]
#align commute.add_pow' Commute.add_pow'
@@ -196,9 +196,9 @@ theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M)
-- porting note: new lemma
@[to_additive sum_antidiagonal_choose_succ_nsmul]
theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
- (∏ ij in Nat.antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
- (∏ ij in Nat.antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
- ∏ ij in Nat.antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2 := by
+ (∏ ij in antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
+ (∏ ij in antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
+ ∏ ij in antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2 := by
simp only [Nat.prod_antidiagonal_eq_prod_range_succ_mk, prod_pow_choose_succ]
have : ∀ i ∈ range (n + 1), i ≤ n := fun i hi ↦ by simpa [Nat.lt_succ_iff] using hi
congr 1
@@ -220,9 +220,9 @@ theorem sum_choose_succ_mul (f : ℕ → ℕ → R) (n : ℕ) :
/-- 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 in Nat.antidiagonal (n + 1), ((n + 1).choose ij.1 : R) * f ij.1 ij.2) =
- (∑ ij in Nat.antidiagonal n, (n.choose ij.1 : R) * f ij.1 (ij.2 + 1)) +
- ∑ ij in Nat.antidiagonal n, (n.choose ij.2 : R) * f (ij.1 + 1) ij.2 := by
+ (∑ ij in antidiagonal (n + 1), ((n + 1).choose ij.1 : R) * f ij.1 ij.2) =
+ (∑ ij in antidiagonal n, (n.choose ij.1 : R) * f ij.1 (ij.2 + 1)) +
+ ∑ ij in antidiagonal n, (n.choose ij.2 : R) * f (ij.1 + 1) ij.2 := by
simpa only [nsmul_eq_mul] using sum_antidiagonal_choose_succ_nsmul f n
#align finset.sum_antidiagonal_choose_succ_mul Finset.sum_antidiagonal_choose_succ_mul
@@ -159,9 +159,9 @@ theorem sum_powerset_apply_card {α β : Type*} [AddCommMonoid α] (f : ℕ →
rw [mem_powerset] at hy
exact card_le_of_subset hy
· refine' sum_congr rfl fun y _ ↦ _
- rw [← card_powersetLen, ← sum_const]
- refine' sum_congr powersetLen_eq_filter.symm fun z hz ↦ _
- rw [(mem_powersetLen.1 hz).2]
+ rw [← card_powersetCard, ← sum_const]
+ refine' sum_congr powersetCard_eq_filter.symm fun z hz ↦ _
+ rw [(mem_powersetCard.1 hz).2]
#align finset.sum_powerset_apply_card Finset.sum_powerset_apply_card
theorem sum_powerset_neg_one_pow_card {α : Type*} [DecidableEq α] {x : Finset α} :
I appreciate that this is "going backwards" in the sense of requiring more explicit imports of tactics (and making it more likely that users writing new files will need to import tactics rather than finding them already available).
However it's useful for me while I'm intensively working on refactoring and upstreaming tactics if I can minimise the dependencies between tactics. I'm very much aware that in the long run we don't want users to have to manage imports of tactics, and I am definitely going to tidy this all up again once I'm finished with this project!
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Patrick Stevens
-/
import Mathlib.Data.Nat.Choose.Basic
+import Mathlib.Tactic.Ring
import Mathlib.Tactic.Linarith
import Mathlib.Algebra.BigOperators.Ring
import Mathlib.Algebra.BigOperators.Intervals
norm_num
was passing the wrong syntax node to elabSimpArgs
when elaborating, which essentially had the effect of ignoring all arguments it was passed, i.e. norm_num [add_comm]
would not try to commute addition in the simp step.
The fix itself is very simple (though not obvious to debug!), probably using TSyntax more would help avoid such issues in future.
Due to this bug many norm_num [blah]
became rw [blah]; norm_num
or similar, sometimes with porting notes, sometimes not, we fix these porting notes and other regressions during the port also.
Interestingly cancel_denoms
uses norm_num [<- mul_assoc]
internally, so cancel_denoms
also got stronger with this change.
@@ -125,7 +125,7 @@ theorem choose_middle_le_pow (n : ℕ) : choose (2 * n + 1) n ≤ 4 ^ n := by
theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
4 ^ n ≤ (2 * n + 1) * choose (2 * n) n :=
calc
- 4 ^ n = (1 + 1) ^ (2 * n) := by simp only [pow_mul, one_add_one_eq_two]; rfl
+ 4 ^ n = (1 + 1) ^ (2 * n) := by norm_num [pow_mul]
_ = ∑ m in range (2 * n + 1), choose (2 * n) m := by simp [add_pow]
_ ≤ ∑ m in range (2 * n + 1), choose (2 * n) (2 * n / 2) := by gcongr; apply choose_le_middle
_ = (2 * n + 1) * choose (2 * n) n := by simp
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -28,7 +28,7 @@ open Finset
open BigOperators
-variable {R : Type _}
+variable {R : Type*}
namespace Commute
@@ -149,7 +149,7 @@ theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
namespace Finset
-theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
+theorem sum_powerset_apply_card {α β : Type*} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
∑ m in x.powerset, f m.card = ∑ m in range (x.card + 1), x.card.choose m • f m := by
trans ∑ m in range (x.card + 1), ∑ j in x.powerset.filter fun z ↦ z.card = m, f j.card
· refine' (sum_fiberwise_of_maps_to _ _).symm
@@ -163,13 +163,13 @@ theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ →
rw [(mem_powersetLen.1 hz).2]
#align finset.sum_powerset_apply_card Finset.sum_powerset_apply_card
-theorem sum_powerset_neg_one_pow_card {α : Type _} [DecidableEq α] {x : Finset α} :
+theorem sum_powerset_neg_one_pow_card {α : Type*} [DecidableEq α] {x : Finset α} :
(∑ m in x.powerset, (-1 : ℤ) ^ m.card) = if x = ∅ then 1 else 0 := by
rw [sum_powerset_apply_card]
simp only [nsmul_eq_mul', ← card_eq_zero, Int.alternating_sum_range_choose]
#align finset.sum_powerset_neg_one_pow_card Finset.sum_powerset_neg_one_pow_card
-theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α} (h0 : x.Nonempty) :
+theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type*} {x : Finset α} (h0 : x.Nonempty) :
(∑ m in x.powerset, (-1 : ℤ) ^ m.card) = 0 := by
classical
rw [sum_powerset_neg_one_pow_card, if_neg]
@@ -177,11 +177,11 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α}
apply h0
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
-variable {M R : Type _} [CommMonoid M] [NonAssocSemiring R]
+variable {M R : Type*} [CommMonoid M] [NonAssocSemiring R]
-- porting note: new lemma
@[to_additive sum_choose_succ_nsmul]
-theorem prod_pow_choose_succ {M : Type _} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
+theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
(∏ i in range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i) =
(∏ i in range (n + 1), f i (n + 1 - i) ^ n.choose i) *
∏ i in range (n + 1), f (i + 1) (n - i) ^ n.choose i := by
@@ -194,7 +194,7 @@ theorem prod_pow_choose_succ {M : Type _} [CommMonoid M] (f : ℕ → ℕ → M)
-- porting note: new lemma
@[to_additive sum_antidiagonal_choose_succ_nsmul]
-theorem prod_antidiagonal_pow_choose_succ {M : Type _} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
+theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
(∏ ij in Nat.antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
(∏ ij in Nat.antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
∏ ij in Nat.antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2 := by
@@ -2,11 +2,6 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Patrick Stevens
-
-! This file was ported from Lean 3 source module data.nat.choose.sum
-! leanprover-community/mathlib commit 4c19a16e4b705bf135cf9a80ac18fcc99c438514
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Data.Nat.Choose.Basic
import Mathlib.Tactic.Linarith
@@ -15,6 +10,8 @@ import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Algebra.BigOperators.Order
import Mathlib.Algebra.BigOperators.NatAntidiagonal
+#align_import data.nat.choose.sum from "leanprover-community/mathlib"@"4c19a16e4b705bf135cf9a80ac18fcc99c438514"
+
/-!
# Sums of binomial coefficients
∑'
precedence (#5615)
∑
, ∏
and variants).([^a-zA-Zα-ωΑ-Ω'𝓝ℳ₀𝕂ₛ)]) \(([∑∏][^()∑∏]*,[^()∑∏:]*)\) ([⊂⊆=<≤])
replaced by $1 $2 $3
@@ -153,7 +153,7 @@ theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) :
namespace Finset
theorem sum_powerset_apply_card {α β : Type _} [AddCommMonoid α] (f : ℕ → α) {x : Finset β} :
- (∑ m in x.powerset, f m.card) = ∑ m in range (x.card + 1), x.card.choose m • f m := by
+ ∑ m in x.powerset, f m.card = ∑ m in range (x.card + 1), x.card.choose m • f m := by
trans ∑ m in range (x.card + 1), ∑ j in x.powerset.filter fun z ↦ z.card = m, f j.card
· refine' (sum_fiberwise_of_maps_to _ _).symm
intro y hy
@@ -130,8 +130,7 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
calc
4 ^ n = (1 + 1) ^ (2 * n) := by simp only [pow_mul, one_add_one_eq_two]; rfl
_ = ∑ m in range (2 * n + 1), choose (2 * n) m := by simp [add_pow]
- _ ≤ ∑ m in range (2 * n + 1), choose (2 * n) (2 * n / 2) :=
- sum_le_sum fun i _ ↦ choose_le_middle i (2 * n)
+ _ ≤ ∑ m in range (2 * n + 1), choose (2 * n) (2 * n / 2) := by gcongr; apply choose_le_middle
_ = (2 * n + 1) * choose (2 * n) n := by simp
#align nat.four_pow_le_two_mul_add_one_mul_central_binom Nat.four_pow_le_two_mul_add_one_mul_central_binom
These lemmas are in the analysis.calculus.cont_diff
file with a
porting comment saying to move them to Data.Nat.Choose.Sum
. I moved
them, golfed, and added multiplicative versions.
@@ -181,4 +181,52 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type _} {x : Finset α}
apply h0
#align finset.sum_powerset_neg_one_pow_card_of_nonempty Finset.sum_powerset_neg_one_pow_card_of_nonempty
+variable {M R : Type _} [CommMonoid M] [NonAssocSemiring R]
+
+-- porting note: new lemma
+@[to_additive sum_choose_succ_nsmul]
+theorem prod_pow_choose_succ {M : Type _} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
+ (∏ i in range (n + 2), f i (n + 1 - i) ^ (n + 1).choose i) =
+ (∏ i in range (n + 1), f i (n + 1 - i) ^ n.choose i) *
+ ∏ i in range (n + 1), f (i + 1) (n - i) ^ n.choose i := by
+ have A : (∏ i in range (n + 1), f (i + 1) (n - i) ^ (n.choose (i + 1))) * f 0 (n + 1) =
+ ∏ i in range (n + 1), f i (n + 1 - i) ^ (n.choose i)
+ · rw [prod_range_succ, prod_range_succ']
+ simp
+ rw [prod_range_succ']
+ simpa [Nat.choose_succ_succ, pow_add, prod_mul_distrib, A, mul_assoc] using mul_comm _ _
+
+-- porting note: new lemma
+@[to_additive sum_antidiagonal_choose_succ_nsmul]
+theorem prod_antidiagonal_pow_choose_succ {M : Type _} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
+ (∏ ij in Nat.antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1) =
+ (∏ ij in Nat.antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
+ ∏ ij in Nat.antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2 := by
+ simp only [Nat.prod_antidiagonal_eq_prod_range_succ_mk, prod_pow_choose_succ]
+ have : ∀ i ∈ range (n + 1), i ≤ n := fun i hi ↦ by simpa [Nat.lt_succ_iff] using hi
+ congr 1
+ · refine prod_congr rfl fun i hi ↦ ?_
+ rw [tsub_add_eq_add_tsub (this _ hi)]
+ · refine prod_congr rfl fun i hi ↦ ?_
+ rw [Nat.choose_symm (this _ hi)]
+
+-- porting note: moved from `Mathlib.Analysis.Calculus.ContDiff`
+/-- 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 in range (n + 2), ((n + 1).choose i : R) * f i (n + 1 - i)) =
+ (∑ i in range (n + 1), (n.choose i : R) * f i (n + 1 - i)) +
+ ∑ i in range (n + 1), (n.choose i : R) * f (i + 1) (n - i) := by
+ simpa only [nsmul_eq_mul] using sum_choose_succ_nsmul f n
+#align finset.sum_choose_succ_mul Finset.sum_choose_succ_mul
+
+/-- 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 in Nat.antidiagonal (n + 1), ((n + 1).choose ij.1 : R) * f ij.1 ij.2) =
+ (∑ ij in Nat.antidiagonal n, (n.choose ij.1 : R) * f ij.1 (ij.2 + 1)) +
+ ∑ ij in Nat.antidiagonal n, (n.choose ij.2 : R) * f (ij.1 + 1) ij.2 := by
+ simpa only [nsmul_eq_mul] using sum_antidiagonal_choose_succ_nsmul f n
+#align finset.sum_antidiagonal_choose_succ_mul Finset.sum_antidiagonal_choose_succ_mul
+
end Finset
The unported dependencies are