wiedijk_100_theorems.partition
⟷
Archive.Wiedijk100Theorems.Partition
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)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -112,7 +112,7 @@ def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
theorem mem_cut {ι : Type _} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
f ∈ cut s n ↔ s.Sum f = n ∧ ∀ (i) (_ : i ∉ s), f i = 0 :=
by
- rw [cut, mem_filter, and_comm', and_congr_right]
+ rw [cut, mem_filter, and_comm, and_congr_right]
intro h
simp only [mem_map, exists_prop, Function.Embedding.coeFn_mk, mem_pi]
constructor
@@ -336,7 +336,7 @@ theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset
simp_rw [coeff_prod_range, coeff_indicator, prod_boole, sum_boole]
congr 1
refine' Finset.card_congr (fun p _ i => Multiset.count i p.parts • i) _ _ _
- · simp only [mem_filter, mem_cut, mem_univ, true_and_iff, exists_prop, and_assoc', and_imp,
+ · simp only [mem_filter, mem_cut, mem_univ, true_and_iff, exists_prop, and_assoc, and_imp,
smul_eq_zero, Function.Embedding.coeFn_mk, exists_imp]
rintro ⟨p, hp₁, hp₂⟩ hp₃ hp₄
dsimp only at *
@@ -360,7 +360,7 @@ theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₂.2 0 a))
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₁.2 0 a))
· rwa [Nat.nsmul_eq_mul, Nat.nsmul_eq_mul, mul_left_inj' i.succ_ne_zero] at h
- · simp only [mem_filter, mem_cut, mem_univ, exists_prop, true_and_iff, and_assoc']
+ · simp only [mem_filter, mem_cut, mem_univ, exists_prop, true_and_iff, and_assoc]
rintro f ⟨hf₁, hf₂, hf₃⟩
refine' ⟨⟨∑ i in s, Multiset.replicate (f i / i) i, _, _⟩, _, _, _⟩
· intro i hi
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -432,7 +432,7 @@ theorem odd_gf_prop [Field α] (n m : ℕ) (h : n < m * 2) :
rw [← partial_odd_gf_prop]
trace
"./././Mathport/Syntax/Translate/Tactic/Builtin.lean:73:14: unsupported tactic `congrm #[[expr card (filter (λ p, (_ : exprProp())) _)]]"
- apply ball_congr
+ apply forall₂_congr
intro i hi
have hin : i ≤ n := by
simpa [p.parts_sum] using Multiset.single_le_sum (fun _ _ => Nat.zero_le _) _ hi
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -3,8 +3,8 @@ Copyright (c) 2020 Bhavik Mehta, Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
-/
-import RingTheory.PowerSeries.Basic
-import Combinatorics.Partition
+import RingTheory.MvPowerSeries.Basic
+import Combinatorics.Enumerative.Partition
import Data.Nat.Parity
import Data.Finset.NatAntidiagonal
import Data.Fin.Tuple.NatAntidiagonal
@@ -108,7 +108,7 @@ def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
simpa [dif_pos hi] using congr_fun h i⟩)
#align theorems_100.cut Theorems100.cut
-/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (i «expr ∉ » s) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:642:2: warning: expanding binder collection (i «expr ∉ » s) -/
theorem mem_cut {ι : Type _} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
f ∈ cut s n ↔ s.Sum f = n ∧ ∀ (i) (_ : i ∉ s), f i = 0 :=
by
@@ -323,7 +323,7 @@ def mkOdd : ℕ ↪ ℕ :=
⟨fun i => 2 * i + 1, fun x y h => by linarith⟩
#align theorems_100.mk_odd Theorems100.mkOdd
-/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (i «expr ∉ » s) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:642:2: warning: expanding binder collection (i «expr ∉ » s) -/
-- The main workhorse of the partition theorem proof.
theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset ℕ) (hs : ∀ i ∈ s, 0 < i)
(c : ℕ → Set ℕ) (hc : ∀ (i) (_ : i ∉ s), 0 ∈ c i) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -160,7 +160,7 @@ theorem cut_empty_succ {ι : Type _} (n : ℕ) : cut (∅ : Finset ι) (n + 1) =
by
apply eq_empty_of_forall_not_mem
intro x hx
- rw [mem_cut, sum_empty] at hx
+ rw [mem_cut, sum_empty] at hx
cases hx.1
#align theorems_100.cut_empty_succ Theorems100.cut_empty_succ
@@ -221,7 +221,7 @@ theorem coeff_prod_range [CommSemiring α] {ι : Type _} (s : Finset ι) (f : ι
mul_sum]
apply sum_congr rfl _
intro x hx
- rw [mem_cut] at hx
+ rw [mem_cut] at hx
rw [hx.2 a hi, zero_add]
trace
"./././Mathport/Syntax/Translate/Tactic/Builtin.lean:73:14: unsupported tactic `congrm #[[expr «expr * »(_, _)]]"
@@ -303,7 +303,7 @@ theorem num_series' [Field α] (i : ℕ) :
rw [Nat.mul_sub_left_distrib, ← hp, ← a_left, mul_one, Nat.add_sub_cancel]
· rintro ⟨rfl, rfl⟩
cases p
- · rw [MulZeroClass.mul_zero] at hp ; cases hp
+ · rw [MulZeroClass.mul_zero] at hp; cases hp
rw [hp]
simp [Nat.succ_eq_add_one, mul_add]
· suffices
@@ -350,21 +350,21 @@ theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset
· exact fun i hi => ⟨_, hp₃ i, rfl⟩
· intro p₁ p₂ hp₁ hp₂ h
apply Nat.Partition.ext
- simp only [true_and_iff, mem_univ, mem_filter] at hp₁ hp₂
+ simp only [true_and_iff, mem_univ, mem_filter] at hp₁ hp₂
ext i
- rw [Function.funext_iff] at h
+ rw [Function.funext_iff] at h
specialize h i
cases i
· rw [Multiset.count_eq_zero_of_not_mem]
rw [Multiset.count_eq_zero_of_not_mem]
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₂.2 0 a))
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₁.2 0 a))
- · rwa [Nat.nsmul_eq_mul, Nat.nsmul_eq_mul, mul_left_inj' i.succ_ne_zero] at h
+ · rwa [Nat.nsmul_eq_mul, Nat.nsmul_eq_mul, mul_left_inj' i.succ_ne_zero] at h
· simp only [mem_filter, mem_cut, mem_univ, exists_prop, true_and_iff, and_assoc']
rintro f ⟨hf₁, hf₂, hf₃⟩
refine' ⟨⟨∑ i in s, Multiset.replicate (f i / i) i, _, _⟩, _, _, _⟩
· intro i hi
- simp only [exists_prop, mem_sum, mem_map, Function.Embedding.coeFn_mk] at hi
+ simp only [exists_prop, mem_sum, mem_map, Function.Embedding.coeFn_mk] at hi
rcases hi with ⟨t, ht, z⟩
apply hs
rwa [Multiset.eq_of_mem_replicate z]
@@ -380,7 +380,7 @@ theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset
rwa [← hw₂, Nat.mul_div_cancel _ (hs i h)]
· exact hc _ h
· intro i hi
- rw [mem_sum] at hi
+ rw [mem_sum] at hi
rcases hi with ⟨j, hj₁, hj₂⟩
rwa [Multiset.eq_of_mem_replicate hj₂]
· ext i
@@ -440,8 +440,8 @@ theorem odd_gf_prop [Field α] (n m : ℕ) (h : n < m * 2) :
constructor
· intro hi₂
have := Nat.mod_add_div i 2
- rw [Nat.not_even_iff] at hi₂
- rw [hi₂, add_comm] at this
+ rw [Nat.not_even_iff] at hi₂
+ rw [hi₂, add_comm] at this
refine' ⟨i / 2, _, this⟩
rw [Nat.div_lt_iff_lt_mul zero_lt_two]
exact lt_of_le_of_lt hin h
@@ -515,7 +515,7 @@ theorem same_gf [Field α] (m : ℕ) :
set π₁ : PowerSeries α := ∏ i in range m, (1 - X ^ (2 * i + 1))⁻¹ with hπ₁
set π₂ : PowerSeries α := ∏ i in range m, (1 - X ^ (m + i + 1)) with hπ₂
set π₃ : PowerSeries α := ∏ i in range m, (1 + X ^ (i + 1)) with hπ₃
- rw [← hπ₃] at ih
+ rw [← hπ₃] at ih
have h : constant_coeff α (1 - X ^ (2 * m + 1)) ≠ 0 :=
by
rw [RingHom.map_sub, RingHom.map_pow, constant_coeff_one, constant_coeff_X,
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,14 +3,14 @@ Copyright (c) 2020 Bhavik Mehta, Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
-/
-import Mathbin.RingTheory.PowerSeries.Basic
-import Mathbin.Combinatorics.Partition
-import Mathbin.Data.Nat.Parity
-import Mathbin.Data.Finset.NatAntidiagonal
-import Mathbin.Data.Fin.Tuple.NatAntidiagonal
-import Mathbin.Tactic.IntervalCases
-import Mathbin.Tactic.ApplyFun
-import Mathbin.Tactic.Congrm
+import RingTheory.PowerSeries.Basic
+import Combinatorics.Partition
+import Data.Nat.Parity
+import Data.Finset.NatAntidiagonal
+import Data.Fin.Tuple.NatAntidiagonal
+import Tactic.IntervalCases
+import Tactic.ApplyFun
+import Tactic.Congrm
#align_import wiedijk_100_theorems.partition from "leanprover-community/mathlib"@"08b081ea92d80e3a41f899eea36ef6d56e0f1db0"
@@ -108,7 +108,7 @@ def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
simpa [dif_pos hi] using congr_fun h i⟩)
#align theorems_100.cut Theorems100.cut
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (i «expr ∉ » s) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (i «expr ∉ » s) -/
theorem mem_cut {ι : Type _} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
f ∈ cut s n ↔ s.Sum f = n ∧ ∀ (i) (_ : i ∉ s), f i = 0 :=
by
@@ -323,7 +323,7 @@ def mkOdd : ℕ ↪ ℕ :=
⟨fun i => 2 * i + 1, fun x y h => by linarith⟩
#align theorems_100.mk_odd Theorems100.mkOdd
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (i «expr ∉ » s) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (i «expr ∉ » s) -/
-- The main workhorse of the partition theorem proof.
theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset ℕ) (hs : ∀ i ∈ s, 0 < i)
(c : ℕ → Set ℕ) (hc : ∀ (i) (_ : i ∉ s), 0 ∈ c i) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,11 +2,6 @@
Copyright (c) 2020 Bhavik Mehta, Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
-
-! This file was ported from Lean 3 source module wiedijk_100_theorems.partition
-! leanprover-community/mathlib commit 08b081ea92d80e3a41f899eea36ef6d56e0f1db0
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.RingTheory.PowerSeries.Basic
import Mathbin.Combinatorics.Partition
@@ -17,6 +12,8 @@ import Mathbin.Tactic.IntervalCases
import Mathbin.Tactic.ApplyFun
import Mathbin.Tactic.Congrm
+#align_import wiedijk_100_theorems.partition from "leanprover-community/mathlib"@"08b081ea92d80e3a41f899eea36ef6d56e0f1db0"
+
/-!
# Euler's Partition Theorem
@@ -111,7 +108,7 @@ def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
simpa [dif_pos hi] using congr_fun h i⟩)
#align theorems_100.cut Theorems100.cut
-/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (i «expr ∉ » s) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (i «expr ∉ » s) -/
theorem mem_cut {ι : Type _} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
f ∈ cut s n ↔ s.Sum f = n ∧ ∀ (i) (_ : i ∉ s), f i = 0 :=
by
@@ -326,7 +323,7 @@ def mkOdd : ℕ ↪ ℕ :=
⟨fun i => 2 * i + 1, fun x y h => by linarith⟩
#align theorems_100.mk_odd Theorems100.mkOdd
-/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (i «expr ∉ » s) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (i «expr ∉ » s) -/
-- The main workhorse of the partition theorem proof.
theorem partial_gf_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset ℕ) (hs : ∀ i ∈ s, 0 < i)
(c : ℕ → Set ℕ) (hc : ∀ (i) (_ : i ∉ s), 0 ∈ c i) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/bf2428c9486c407ca38b5b3fb10b87dad0bc99fa
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
! This file was ported from Lean 3 source module wiedijk_100_theorems.partition
-! leanprover-community/mathlib commit 5563b1b49e86e135e8c7b556da5ad2f5ff881cad
+! leanprover-community/mathlib commit 08b081ea92d80e3a41f899eea36ef6d56e0f1db0
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -20,6 +20,9 @@ import Mathbin.Tactic.Congrm
/-!
# Euler's Partition Theorem
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file proves Theorem 45 from the [100 Theorems List](https://www.cs.ru.nl/~freek/100/).
The theorem concerns the counting of integer partitions -- ways of
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -104,7 +104,7 @@ This should be thought of as a generalisation of `finset.nat.antidiagonal_tuple`
def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
Finset.filter (fun f => s.Sum f = n)
((s.pi fun _ => range (n + 1)).map
- ⟨fun f i => if h : i ∈ s then f i h else 0, fun f g h => by ext (i hi);
+ ⟨fun f i => if h : i ∈ s then f i h else 0, fun f g h => by ext i hi;
simpa [dif_pos hi] using congr_fun h i⟩)
#align theorems_100.cut Theorems100.cut
mathlib commit https://github.com/leanprover-community/mathlib/commit/893964fc28cefbcffc7cb784ed00a2895b4e65cf
@@ -3,8 +3,8 @@ Copyright (c) 2020 Bhavik Mehta, Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
-! This file was ported from Lean 3 source module «100-theorems-list».«45_partition»
-! leanprover-community/mathlib commit 328375597f2c0dd00522d9c2e5a33b6a6128feeb
+! This file was ported from Lean 3 source module wiedijk_100_theorems.partition
+! leanprover-community/mathlib commit 5563b1b49e86e135e8c7b556da5ad2f5ff881cad
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -215,7 +215,7 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
exact fun hi _ => ha.2 i hi
· conv_rhs => simp [← a.parts_sum]
rw [sum_multiset_count_of_subset _ s]
- simp only [smul_eq_mul]
+ · simp only [smul_eq_mul]
· intro i
simp only [Multiset.mem_toFinset, not_not, mem_filter]
apply ha.2
@@ -229,8 +229,8 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
by_cases hi : i = 0
· rw [hi]
rw [Multiset.count_eq_zero_of_not_mem]
- rw [Multiset.count_eq_zero_of_not_mem]
- intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₂.2 0 a))
+ · rw [Multiset.count_eq_zero_of_not_mem]
+ intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₂.2 0 a))
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₁.2 0 a))
· rw [← mul_left_inj' hi]
rw [Function.funext_iff] at h
bex
and ball
from lemma names (#11615)
Follow-up to #10816.
Remaining places containing such lemmas are
Option.bex_ne_none
and Option.ball_ne_none
: defined in Lean coreNat.decidableBallLT
and Nat.decidableBallLE
: defined in Lean corebef_def
is still used in a number of places and could be renamedBAll.imp_{left,right}
, BEx.imp_{left,right}
, BEx.intro
and BEx.elim
I only audited the first ~150 lemmas mentioning "ball"; too many lemmas named after Metric.ball/openBall/closedBall.
Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>
@@ -306,7 +306,7 @@ theorem oddGF_prop [Field α] (n m : ℕ) (h : n < m * 2) :
(Finset.card (Nat.Partition.odds n) : α) = coeff α n (partialOddGF m) := by
rw [← partialOddGF_prop, Nat.Partition.odds]
congr with p
- apply ball_congr
+ apply forall₂_congr
intro i hi
have hin : i ≤ n := by
simpa [p.parts_sum] using Multiset.single_le_sum (fun _ _ => Nat.zero_le _) _ hi
Move Catalan
, Composition
, DoubleCounting
, Partition
to a new folder Combinatorics.Enumerative
.
@@ -5,7 +5,7 @@ Authors: Bhavik Mehta, Aaron Anderson
-/
import Mathlib.RingTheory.PowerSeries.Inverse
import Mathlib.RingTheory.PowerSeries.Order
-import Mathlib.Combinatorics.Partition
+import Mathlib.Combinatorics.Enumerative.Partition
import Mathlib.Data.Nat.Parity
import Mathlib.Data.Finset.NatAntidiagonal
import Mathlib.Data.Fin.Tuple.NatAntidiagonal
@@ -203,8 +203,7 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
simp only [Multiset.mem_toFinset, not_not, mem_filter] }
refine' Finset.card_congr φ _ _ _
· intro a ha
- unfold_let
- simp only [not_forall, not_exists, not_and, exists_prop, mem_filter]
+ simp only [φ, not_forall, not_exists, not_and, exists_prop, mem_filter]
rw [mem_piAntidiagonal']
dsimp only [ne_eq, smul_eq_mul, id_eq, eq_mpr_eq_cast, le_eq_subset, Finsupp.coe_mk]
simp only [mem_univ, forall_true_left, not_and, not_forall, exists_prop,
This PR split the files devoted to power series (especially RingTheory/PowerSeries/Basic) into several ones:
RingTheory/MvPowerSeries/Basic - initial definitions (multivariate)
RingTheory/MvPowerSeries/Trunc - truncation
RingTheory/MvPowerSeries/Inverse - stuff pertaining to inverses
RingTheory/PowerSeries/Basic - initial definitions (univariate)
RingTheory/PowerSeries/Trunc - truncation
RingTheory/PowerSeries/Inverse - stuff pertaining to inverses
RingTheory/PowerSeries/Order - stuff pertaining to order
it remains to adjust the other files (PowerSeries/Derivative and PowerSeries/WellKnown)
Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr> Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: faenuccio <filippo.nuccio@univ-st-etienne.fr>
@@ -3,7 +3,8 @@ Copyright (c) 2020 Bhavik Mehta, Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
-/
-import Mathlib.RingTheory.PowerSeries.Basic
+import Mathlib.RingTheory.PowerSeries.Inverse
+import Mathlib.RingTheory.PowerSeries.Order
import Mathlib.Combinatorics.Partition
import Mathlib.Data.Nat.Parity
import Mathlib.Data.Finset.NatAntidiagonal
@@ -202,6 +202,7 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
simp only [Multiset.mem_toFinset, not_not, mem_filter] }
refine' Finset.card_congr φ _ _ _
· intro a ha
+ unfold_let
simp only [not_forall, not_exists, not_and, exists_prop, mem_filter]
rw [mem_piAntidiagonal']
dsimp only [ne_eq, smul_eq_mul, id_eq, eq_mpr_eq_cast, le_eq_subset, Finsupp.coe_mk]
@@ -224,7 +225,7 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
apply Nat.Partition.ext
simp only [true_and_iff, mem_univ, mem_filter] at hp₁ hp₂
ext i
- simp only [ne_eq, Multiset.mem_toFinset, not_not, smul_eq_mul, Finsupp.mk.injEq] at h
+ simp only [φ, ne_eq, Multiset.mem_toFinset, not_not, smul_eq_mul, Finsupp.mk.injEq] at h
by_cases hi : i = 0
· rw [hi]
rw [Multiset.count_eq_zero_of_not_mem]
@@ -234,7 +235,7 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
· rw [← mul_left_inj' hi]
rw [Function.funext_iff] at h
exact h.2 i
- · simp only [mem_filter, mem_piAntidiagonal, mem_univ, exists_prop, true_and_iff, and_assoc]
+ · simp only [φ, mem_filter, mem_piAntidiagonal, mem_univ, exists_prop, true_and_iff, and_assoc]
rintro f ⟨hf, hf₃, hf₄⟩
have hf' : f ∈ piAntidiagonal s n := mem_piAntidiagonal.mpr ⟨hf, hf₃⟩
simp only [mem_piAntidiagonal'] at hf'
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>
@@ -236,9 +236,9 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
exact h.2 i
· simp only [mem_filter, mem_piAntidiagonal, mem_univ, exists_prop, true_and_iff, and_assoc]
rintro f ⟨hf, hf₃, hf₄⟩
- suffices hf' : f ∈ piAntidiagonal s n
+ have hf' : f ∈ piAntidiagonal s n := mem_piAntidiagonal.mpr ⟨hf, hf₃⟩
simp only [mem_piAntidiagonal'] at hf'
- refine' ⟨⟨∑ i in s, Multiset.replicate (f i / i) i, _, _⟩, _, _, _⟩
+ refine ⟨⟨∑ i in s, Multiset.replicate (f i / i) i, ?_, ?_⟩, ?_, ?_, ?_⟩
· intro i hi
simp only [exists_prop, mem_sum, mem_map, Function.Embedding.coeFn_mk] at hi
rcases hi with ⟨t, ht, z⟩
@@ -271,7 +271,6 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
· apply symm
rw [← Finsupp.not_mem_support_iff]
exact not_mem_mono hf h
- · exact mem_piAntidiagonal.mpr ⟨hf, hf₃⟩
#align theorems_100.partial_gf_prop Theorems100.partialGF_prop
theorem partialOddGF_prop [Field α] (n m : ℕ) :
HasPiAntidiagonal
defined in PR #7904 to compute the coefficients of products of power series (in several or one variable) : MvPowerSeries.coeff_prod
and PowerSeries.coeff_prod
Archive/Partition.lean
accordinglyCo-author : Maria Ines de Frutos Fernandez
Based on work of Bhavik Mehta in Archive/Partition.lean
Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr> Co-authored-by: mariainesdff <mariaines.dff@gmail.com>
@@ -10,6 +10,7 @@ import Mathlib.Data.Finset.NatAntidiagonal
import Mathlib.Data.Fin.Tuple.NatAntidiagonal
import Mathlib.Tactic.IntervalCases
import Mathlib.Tactic.ApplyFun
+import Mathlib.Data.Finset.PiAntidiagonal
#align_import wiedijk_100_theorems.partition from "leanprover-community/mathlib"@"5563b1b49e86e135e8c7b556da5ad2f5ff881cad"
@@ -91,140 +92,10 @@ def partialDistinctGF (m : ℕ) [CommSemiring α] :=
∏ i in range m, (1 + (X : PowerSeries α) ^ (i + 1))
#align theorems_100.partial_distinct_gf Theorems100.partialDistinctGF
-/--
-Functions defined only on `s`, which sum to `n`. In other words, a partition of `n` indexed by `s`.
-Every function in here is finitely supported, and the support is a subset of `s`.
-This should be thought of as a generalisation of `Finset.Nat.antidiagonalTuple` where
-`antidiagonalTuple k n` is the same thing as `cut (s : Finset.univ (Fin k)) n`.
--/
-def cut {ι : Type*} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
- Finset.filter (fun f => s.sum f = n)
- ((s.pi fun _ => range (n + 1)).map
- ⟨fun f i => if h : i ∈ s then f i h else 0, fun f g h => by
- ext i hi; simpa [dif_pos hi] using congr_fun h i⟩)
-#align theorems_100.cut Theorems100.cut
-
-theorem mem_cut {ι : Type*} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
- f ∈ cut s n ↔ s.sum f = n ∧ ∀ i, i ∉ s → f i = 0 := by
- rw [cut, mem_filter, and_comm, and_congr_right]
- intro h
- simp only [mem_map, exists_prop, Function.Embedding.coeFn_mk, mem_pi]
- constructor
- · rintro ⟨_, _, rfl⟩ _ H
- simp [dif_neg H]
- · intro hf
- refine' ⟨fun i _ => f i, fun i hi => _, _⟩
- · rw [mem_range, Nat.lt_succ_iff, ← h]
- apply single_le_sum _ hi
- simp
- · ext x
- rw [dite_eq_ite, ite_eq_left_iff, eq_comm]
- exact hf x
-#align theorems_100.mem_cut Theorems100.mem_cut
-
-theorem cut_equiv_antidiag (n : ℕ) :
- Equiv.finsetCongr (Equiv.boolArrowEquivProd _) (cut univ n) = antidiagonal n := by
- ext ⟨x₁, x₂⟩
- simp_rw [Equiv.finsetCongr_apply, mem_map, Equiv.toEmbedding, Function.Embedding.coeFn_mk, ←
- Equiv.eq_symm_apply]
- simp [mem_cut, add_comm]
-#align theorems_100.cut_equiv_antidiag Theorems100.cut_equiv_antidiag
-
-theorem cut_univ_fin_eq_antidiagonalTuple (n : ℕ) (k : ℕ) :
- cut univ n = Nat.antidiagonalTuple k n := by ext; simp [Nat.mem_antidiagonalTuple, mem_cut]
-#align theorems_100.cut_univ_fin_eq_antidiagonal_tuple Theorems100.cut_univ_fin_eq_antidiagonalTuple
-
-/-- There is only one `cut` of 0. -/
-@[simp]
-theorem cut_zero {ι : Type*} (s : Finset ι) : cut s 0 = {0} := by
- -- In general it's nice to prove things using `mem_cut` but in this case it's easier to just
- -- use the definition.
- rw [cut, range_one, pi_const_singleton, map_singleton, Function.Embedding.coeFn_mk,
- filter_singleton, if_pos, singleton_inj]
- · ext; split_ifs <;> rfl
- rw [sum_eq_zero_iff]
- intro x hx
- apply dif_pos hx
-#align theorems_100.cut_zero Theorems100.cut_zero
-
-@[simp]
-theorem cut_empty_succ {ι : Type*} (n : ℕ) : cut (∅ : Finset ι) (n + 1) = ∅ := by
- apply eq_empty_of_forall_not_mem
- intro x hx
- rw [mem_cut, sum_empty] at hx
- cases hx.1
-#align theorems_100.cut_empty_succ Theorems100.cut_empty_succ
-
-theorem cut_insert {ι : Type*} (n : ℕ) (a : ι) (s : Finset ι) (h : a ∉ s) :
- cut (insert a s) n =
- (antidiagonal n).biUnion fun p : ℕ × ℕ =>
- (cut s p.snd).map
- ⟨fun f => f + fun t => if t = a then p.fst else 0, add_left_injective _⟩ := by
- ext f
- rw [mem_cut, mem_biUnion, sum_insert h]
- constructor
- · rintro ⟨rfl, h₁⟩
- simp only [exists_prop, Function.Embedding.coeFn_mk, mem_map, mem_antidiagonal, Prod.exists]
- refine' ⟨f a, s.sum f, rfl, fun i => if i = a then 0 else f i, _, _⟩
- · rw [mem_cut]
- refine' ⟨_, _⟩
- · rw [sum_ite]
- have : filter (fun x => x ≠ a) s = s := by
- apply filter_true_of_mem
- rintro i hi rfl
- apply h hi
- simp [this]
- · intro i hi
- rw [ite_eq_left_iff]
- intro hne
- apply h₁
- simp [not_or, hne, hi]
- · ext x
- obtain rfl | h := eq_or_ne x a
- · simp
- · simp [if_neg h]
- · simp only [mem_insert, Function.Embedding.coeFn_mk, mem_map, mem_antidiagonal, Prod.exists,
- exists_prop, mem_cut, not_or]
- rintro ⟨p, q, rfl, g, ⟨rfl, hg₂⟩, rfl⟩
- refine' ⟨_, _⟩
- · simp [sum_add_distrib, if_neg h, hg₂ _ h, add_comm]
- · rintro i ⟨h₁, h₂⟩
- simp [if_neg h₁, hg₂ _ h₂]
-#align theorems_100.cut_insert Theorems100.cut_insert
-
-theorem coeff_prod_range [CommSemiring α] {ι : Type*} (s : Finset ι) (f : ι → PowerSeries α)
- (n : ℕ) : coeff α n (∏ j in s, f j) = ∑ l in cut s n, ∏ i in s, coeff α (l i) (f i) := by
- revert n
- induction s using Finset.induction_on with
- | empty =>
- rintro ⟨_ | n⟩
- · simp
- simp [cut_empty_succ, if_neg (Nat.succ_ne_zero _)]
- | @insert a s hi ih =>
- intro n
- rw [cut_insert _ _ _ hi, prod_insert hi, coeff_mul, sum_biUnion]
- · congr with i
- simp only [sum_map, Pi.add_apply, Function.Embedding.coeFn_mk, prod_insert hi, if_pos rfl, ih,
- mul_sum]
- apply sum_congr rfl _
- intro x hx
- rw [mem_cut] at hx
- rw [hx.2 a hi, zero_add]
- congr 1
- apply prod_congr rfl
- intro k hk
- rw [if_neg, add_zero]
- exact ne_of_mem_of_not_mem hk hi
- · simp only [Set.PairwiseDisjoint, Set.Pairwise, Prod.forall, not_and, Ne.def,
- mem_antidiagonal, disjoint_left, mem_map, exists_prop, Function.Embedding.coeFn_mk,
- exists_imp, not_exists, Finset.mem_coe, Function.onFun, mem_cut, and_imp]
- rintro p₁ q₁ rfl p₂ q₂ h t x p hp _ hp3 q hq _ hq3
- have z := hp3.trans hq3.symm
- have := sum_congr (Eq.refl s) fun x _ => Function.funext_iff.1 z x
- obtain rfl : q₁ = q₂ := by simpa [sum_add_distrib, hp, hq, if_neg hi] using this
- obtain rfl : p₂ = p₁ := by simpa using h
- exact (t rfl).elim
-#align theorems_100.coeff_prod_range Theorems100.coeff_prod_range
+open Finset.HasAntidiagonal Finset
+
+universe u
+variable {ι : Type u}
/-- A convenience constructor for the power series whose coefficients indicate a subset. -/
def indicatorSeries (α : Type*) [Semiring α] (s : Set ℕ) : PowerSeries α :=
@@ -315,53 +186,74 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
((univ : Finset (Nat.Partition n)).filter fun p =>
(∀ j, p.parts.count j ∈ c j) ∧ ∀ j ∈ p.parts, j ∈ s) :
α) =
- (coeff α n) (∏ i : ℕ in s, indicatorSeries α ((· * i) '' c i)) := by
- simp_rw [coeff_prod_range, coeff_indicator, prod_boole, sum_boole]
- congr 1
- refine' Finset.card_congr (fun p _ i => Multiset.count i p.parts • i) _ _ _
- · simp only [mem_filter, mem_cut, mem_univ, true_and_iff, exists_prop, and_assoc, and_imp,
- smul_eq_zero, Function.Embedding.coeFn_mk, exists_imp]
- rintro ⟨p, hp₁, hp₂⟩ hp₃ hp₄
- dsimp only at *
- refine' ⟨_, _, _⟩
- · rw [← hp₂, ←
- sum_multiset_count_of_subset p s fun x hx => hp₄ _ (Multiset.mem_toFinset.mp hx)]
- · intro i hi
- left
- exact Multiset.count_eq_zero_of_not_mem (mt (hp₄ i) hi)
- · exact fun i _ => ⟨_, hp₃ i, rfl⟩
+ (coeff α n) (∏ i in s, indicatorSeries α ((· * i) '' c i)) := by
+ simp_rw [coeff_prod, coeff_indicator, prod_boole, sum_boole]
+ apply congr_arg
+ simp only [mem_univ, forall_true_left, not_and, not_forall, exists_prop,
+ Set.mem_image, not_exists]
+ set φ : (a : Nat.Partition n) →
+ a ∈ filter (fun p ↦ (∀ (j : ℕ), Multiset.count j p.parts ∈ c j) ∧ ∀ j ∈ p.parts, j ∈ s) univ →
+ ℕ →₀ ℕ := fun p _ => {
+ toFun := fun i => Multiset.count i p.parts • i
+ support := Finset.filter (fun i => i ≠ 0) p.parts.toFinset
+ mem_support_toFun := fun a => by
+ simp only [smul_eq_mul, ne_eq, mul_eq_zero, Multiset.count_eq_zero]
+ rw [not_or, not_not]
+ simp only [Multiset.mem_toFinset, not_not, mem_filter] }
+ refine' Finset.card_congr φ _ _ _
+ · intro a ha
+ simp only [not_forall, not_exists, not_and, exists_prop, mem_filter]
+ rw [mem_piAntidiagonal']
+ dsimp only [ne_eq, smul_eq_mul, id_eq, eq_mpr_eq_cast, le_eq_subset, Finsupp.coe_mk]
+ simp only [mem_univ, forall_true_left, not_and, not_forall, exists_prop,
+ mem_filter, true_and] at ha
+ constructor
+ constructor
+ · intro i
+ simp only [ne_eq, Multiset.mem_toFinset, not_not, mem_filter, and_imp]
+ exact fun hi _ => ha.2 i hi
+ · conv_rhs => simp [← a.parts_sum]
+ rw [sum_multiset_count_of_subset _ s]
+ simp only [smul_eq_mul]
+ · intro i
+ simp only [Multiset.mem_toFinset, not_not, mem_filter]
+ apply ha.2
+ · exact fun i _ => ⟨Multiset.count i a.parts, ha.1 i, rfl⟩
· dsimp only
intro p₁ p₂ hp₁ hp₂ h
apply Nat.Partition.ext
simp only [true_and_iff, mem_univ, mem_filter] at hp₁ hp₂
ext i
- rw [Function.funext_iff] at h
- specialize h i
- match i with
- | 0 =>
+ simp only [ne_eq, Multiset.mem_toFinset, not_not, smul_eq_mul, Finsupp.mk.injEq] at h
+ by_cases hi : i = 0
+ · rw [hi]
rw [Multiset.count_eq_zero_of_not_mem]
rw [Multiset.count_eq_zero_of_not_mem]
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₂.2 0 a))
intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₁.2 0 a))
- | .succ i =>
- rwa [Nat.nsmul_eq_mul, Nat.nsmul_eq_mul, mul_left_inj' i.succ_ne_zero] at h
- · simp only [mem_filter, mem_cut, mem_univ, exists_prop, true_and_iff, and_assoc]
- rintro f ⟨hf₁, hf₂, hf₃⟩
+ · rw [← mul_left_inj' hi]
+ rw [Function.funext_iff] at h
+ exact h.2 i
+ · simp only [mem_filter, mem_piAntidiagonal, mem_univ, exists_prop, true_and_iff, and_assoc]
+ rintro f ⟨hf, hf₃, hf₄⟩
+ suffices hf' : f ∈ piAntidiagonal s n
+ simp only [mem_piAntidiagonal'] at hf'
refine' ⟨⟨∑ i in s, Multiset.replicate (f i / i) i, _, _⟩, _, _, _⟩
· intro i hi
simp only [exists_prop, mem_sum, mem_map, Function.Embedding.coeFn_mk] at hi
rcases hi with ⟨t, ht, z⟩
apply hs
rwa [Multiset.eq_of_mem_replicate z]
- · simp_rw [Multiset.sum_sum, Multiset.sum_replicate, Nat.nsmul_eq_mul, ← hf₁]
+ · simp_rw [Multiset.sum_sum, Multiset.sum_replicate, Nat.nsmul_eq_mul]
+ rw [← hf'.2]
refine' sum_congr rfl fun i hi => Nat.div_mul_cancel _
- rcases hf₃ i hi with ⟨w, _, hw₂⟩
+ rcases hf₄ i hi with ⟨w, _, hw₂⟩
rw [← hw₂]
exact dvd_mul_left _ _
· intro i
simp_rw [Multiset.count_sum', Multiset.count_replicate, sum_ite_eq]
split_ifs with h
- · rcases hf₃ i h with ⟨w, hw₁, hw₂⟩
+ · rcases hf₄ i h with ⟨w, hw₁, hw₂⟩
rwa [← hw₂, Nat.mul_div_cancel _ (hs i h)]
· exact hc _ h
· intro i hi
@@ -370,11 +262,16 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ)
rwa [Multiset.eq_of_mem_replicate hj₂]
· ext i
simp_rw [Multiset.count_sum', Multiset.count_replicate, sum_ite_eq]
+ simp only [ne_eq, Multiset.mem_toFinset, not_not, smul_eq_mul, ite_mul,
+ zero_mul, Finsupp.coe_mk]
split_ifs with h
· apply Nat.div_mul_cancel
- rcases hf₃ i h with ⟨w, _, hw₂⟩
+ rcases hf₄ i h with ⟨w, _, hw₂⟩
apply Dvd.intro_left _ hw₂
- · rw [zero_smul, hf₂ i h]
+ · apply symm
+ rw [← Finsupp.not_mem_support_iff]
+ exact not_mem_mono hf h
+ · exact mem_piAntidiagonal.mpr ⟨hf, hf₃⟩
#align theorems_100.partial_gf_prop Theorems100.partialGF_prop
theorem partialOddGF_prop [Field α] (n m : ℕ) :
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
@@ -484,7 +484,7 @@ theorem same_gf [Field α] (m : ℕ) :
rw [← hπ₃] at ih
have h : constantCoeff α (1 - X ^ (2 * m + 1)) ≠ 0 := by
rw [RingHom.map_sub, RingHom.map_pow, constantCoeff_one, constantCoeff_X,
- zero_pow (2 * m).succ_pos, sub_zero]
+ zero_pow (2 * m).succ_ne_zero, sub_zero]
exact one_ne_zero
calc
(∏ i in range (m + 1), (1 - X ^ (2 * i + 1))⁻¹) *
@@ -384,19 +384,11 @@ theorem partialOddGF_prop [Field α] (n m : ℕ) :
α) =
coeff α n (partialOddGF m) := by
rw [partialOddGF]
- -- Porting note: `convert` timeouts. Please revert to `convert` when the performance of `convert`
- -- is improved.
- refine Eq.trans ?_
- (Eq.trans (partialGF_prop α n ((range m).map mkOdd) ?_ (fun _ => Set.univ) fun _ _ => trivial)
- (Eq.symm ?_))
+ convert partialGF_prop α n
+ ((range m).map mkOdd) _ (fun _ => Set.univ) (fun _ _ => trivial) using 2
· congr
simp only [true_and_iff, forall_const, Set.mem_univ]
- · intro i
- rw [mem_map]
- rintro ⟨a, -, rfl⟩
- exact Nat.succ_pos _
- · congr 1
- rw [Finset.prod_map]
+ · rw [Finset.prod_map]
simp_rw [num_series']
congr! 2 with x
ext k
@@ -406,6 +398,10 @@ theorem partialOddGF_prop [Field α] (n m : ℕ) :
apply mul_comm
rintro ⟨a_w, -, rfl⟩
apply Dvd.intro_left a_w rfl
+ · intro i
+ rw [mem_map]
+ rintro ⟨a, -, rfl⟩
+ exact Nat.succ_pos _
#align theorems_100.partial_odd_gf_prop Theorems100.partialOddGF_prop
/-- If m is big enough, the partial product's coefficient counts the number of odd partitions -/
@@ -438,23 +434,20 @@ theorem partialDistinctGF_prop [CommSemiring α] (n m : ℕ) :
α) =
coeff α n (partialDistinctGF m) := by
rw [partialDistinctGF]
- -- Porting note: `convert` timeouts. Please revert to `convert` when the performance of `convert`
- -- is improved.
- refine Eq.trans ?_
- (Eq.trans (partialGF_prop α n ((range m).map ⟨Nat.succ, Nat.succ_injective⟩) ?_
- (fun _ => {0, 1}) fun _ _ => Or.inl rfl) (Eq.symm ?_))
+ convert partialGF_prop α n
+ ((range m).map ⟨Nat.succ, Nat.succ_injective⟩) _ (fun _ => {0, 1}) (fun _ _ => Or.inl rfl)
+ using 2
· congr
congr! with p
rw [Multiset.nodup_iff_count_le_one]
congr! with i
rcases Multiset.count i p.parts with (_ | _ | ms) <;> simp
+ · simp_rw [Finset.prod_map, two_series]
+ congr with i
+ simp [Set.image_pair]
· simp only [mem_map, Function.Embedding.coeFn_mk]
rintro i ⟨_, _, rfl⟩
apply Nat.succ_pos
- · congr 1
- simp_rw [Finset.prod_map, two_series]
- congr with i
- simp [Set.image_pair]
#align theorems_100.partial_distinct_gf_prop Theorems100.partialDistinctGF_prop
/-- If m is big enough, the partial product's coefficient counts the number of distinct partitions
exact_mod_cast
tactic with mod_cast
elaborator where possible (#8404)
We still have the exact_mod_cast
tactic, used in a few places, which somehow (?) works a little bit harder to prevent the expected type influencing the elaboration of the term. I would like to get to the bottom of this, and it will be easier once the only usages of exact_mod_cast
are the ones that don't work using the term elaborator by itself.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -521,14 +521,14 @@ theorem same_coeffs [Field α] (m n : ℕ) (h : n ≤ m) :
rw [← same_gf, coeff_mul_prod_one_sub_of_lt_order]
rintro i -
rw [order_X_pow]
- exact_mod_cast Nat.lt_succ_of_le (le_add_right h)
+ exact mod_cast Nat.lt_succ_of_le (le_add_right h)
#align theorems_100.same_coeffs Theorems100.same_coeffs
theorem partition_theorem (n : ℕ) :
(Nat.Partition.odds n).card = (Nat.Partition.distincts n).card := by
-- We need the counts to live in some field (which contains ℕ), so let's just use ℚ
- suffices ((Nat.Partition.odds n).card : ℚ) = (Nat.Partition.distincts n).card by
- exact_mod_cast this
+ suffices ((Nat.Partition.odds n).card : ℚ) = (Nat.Partition.distincts n).card from
+ mod_cast this
rw [distinctGF_prop n (n + 1) (by linarith)]
rw [oddGF_prop n (n + 1) (by linarith)]
apply same_coeffs (n + 1) n n.le_succ
@@ -496,15 +496,15 @@ theorem same_gf [Field α] (m : ℕ) :
calc
(∏ i in range (m + 1), (1 - X ^ (2 * i + 1))⁻¹) *
∏ i in range (m + 1), (1 - X ^ (m + 1 + i + 1)) =
- π₁ * (1 - X ^ (2 * m + 1))⁻¹ * (π₀ * (1 - X ^ (m + 1 + m + 1))) :=
- by rw [prod_range_succ _ m, ← hπ₁, prod_range_succ _ m, ← hπ₀]
+ π₁ * (1 - X ^ (2 * m + 1))⁻¹ * (π₀ * (1 - X ^ (m + 1 + m + 1))) := by
+ rw [prod_range_succ _ m, ← hπ₁, prod_range_succ _ m, ← hπ₀]
_ = π₁ * (1 - X ^ (2 * m + 1))⁻¹ * (π₀ * ((1 + X ^ (m + 1)) * (1 - X ^ (m + 1)))) := by
rw [← sq_sub_sq, one_pow, add_assoc _ m 1, ← two_mul (m + 1), pow_mul']
_ = π₀ * (1 - X ^ (m + 1)) * (1 - X ^ (2 * m + 1))⁻¹ * (π₁ * (1 + X ^ (m + 1))) := by ring
_ =
(∏ i in range (m + 1), (1 - X ^ (m + 1 + i))) * (1 - X ^ (2 * m + 1))⁻¹ *
- (π₁ * (1 + X ^ (m + 1))) :=
- by rw [prod_range_succ', add_zero, hπ₀]; simp_rw [← add_assoc]
+ (π₁ * (1 + X ^ (m + 1))) := by
+ rw [prod_range_succ', add_zero, hπ₀]; simp_rw [← add_assoc]
_ = π₂ * (1 - X ^ (m + 1 + m)) * (1 - X ^ (2 * m + 1))⁻¹ * (π₁ * (1 + X ^ (m + 1))) := by
rw [add_right_comm, hπ₂, ← prod_range_succ]; simp_rw [add_right_comm]
_ = π₂ * (1 - X ^ (2 * m + 1)) * (1 - X ^ (2 * m + 1))⁻¹ * (π₁ * (1 + X ^ (m + 1))) := by
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>
@@ -123,7 +123,7 @@ theorem mem_cut {ι : Type*} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
#align theorems_100.mem_cut Theorems100.mem_cut
theorem cut_equiv_antidiag (n : ℕ) :
- Equiv.finsetCongr (Equiv.boolArrowEquivProd _) (cut univ n) = Nat.antidiagonal n := by
+ Equiv.finsetCongr (Equiv.boolArrowEquivProd _) (cut univ n) = antidiagonal n := by
ext ⟨x₁, x₂⟩
simp_rw [Equiv.finsetCongr_apply, mem_map, Equiv.toEmbedding, Function.Embedding.coeFn_mk, ←
Equiv.eq_symm_apply]
@@ -157,14 +157,14 @@ theorem cut_empty_succ {ι : Type*} (n : ℕ) : cut (∅ : Finset ι) (n + 1) =
theorem cut_insert {ι : Type*} (n : ℕ) (a : ι) (s : Finset ι) (h : a ∉ s) :
cut (insert a s) n =
- (Nat.antidiagonal n).biUnion fun p : ℕ × ℕ =>
+ (antidiagonal n).biUnion fun p : ℕ × ℕ =>
(cut s p.snd).map
⟨fun f => f + fun t => if t = a then p.fst else 0, add_left_injective _⟩ := by
ext f
rw [mem_cut, mem_biUnion, sum_insert h]
constructor
· rintro ⟨rfl, h₁⟩
- simp only [exists_prop, Function.Embedding.coeFn_mk, mem_map, Nat.mem_antidiagonal, Prod.exists]
+ simp only [exists_prop, Function.Embedding.coeFn_mk, mem_map, mem_antidiagonal, Prod.exists]
refine' ⟨f a, s.sum f, rfl, fun i => if i = a then 0 else f i, _, _⟩
· rw [mem_cut]
refine' ⟨_, _⟩
@@ -183,7 +183,7 @@ theorem cut_insert {ι : Type*} (n : ℕ) (a : ι) (s : Finset ι) (h : a ∉ s)
obtain rfl | h := eq_or_ne x a
· simp
· simp [if_neg h]
- · simp only [mem_insert, Function.Embedding.coeFn_mk, mem_map, Nat.mem_antidiagonal, Prod.exists,
+ · simp only [mem_insert, Function.Embedding.coeFn_mk, mem_map, mem_antidiagonal, Prod.exists,
exists_prop, mem_cut, not_or]
rintro ⟨p, q, rfl, g, ⟨rfl, hg₂⟩, rfl⟩
refine' ⟨_, _⟩
@@ -216,7 +216,7 @@ theorem coeff_prod_range [CommSemiring α] {ι : Type*} (s : Finset ι) (f : ι
rw [if_neg, add_zero]
exact ne_of_mem_of_not_mem hk hi
· simp only [Set.PairwiseDisjoint, Set.Pairwise, Prod.forall, not_and, Ne.def,
- Nat.mem_antidiagonal, disjoint_left, mem_map, exists_prop, Function.Embedding.coeFn_mk,
+ mem_antidiagonal, disjoint_left, mem_map, exists_prop, Function.Embedding.coeFn_mk,
exists_imp, not_exists, Finset.mem_coe, Function.onFun, mem_cut, and_imp]
rintro p₁ q₁ rfl p₂ q₂ h t x p hp _ hp3 q hq _ hq3
have z := hp3.trans hq3.symm
@@ -275,14 +275,14 @@ theorem num_series' [Field α] (i : ℕ) :
symm
split_ifs with h
· suffices
- ((Nat.antidiagonal n.succ).filter fun a : ℕ × ℕ => i + 1 ∣ a.fst ∧ a.snd = i + 1).card =
+ ((antidiagonal n.succ).filter fun a : ℕ × ℕ => i + 1 ∣ a.fst ∧ a.snd = i + 1).card =
1 by
simp only [Set.mem_setOf_eq]; convert congr_arg ((↑) : ℕ → α) this; norm_cast
rw [card_eq_one]
cases' h with p hp
refine' ⟨((i + 1) * (p - 1), i + 1), _⟩
ext ⟨a₁, a₂⟩
- simp only [mem_filter, Prod.mk.inj_iff, Nat.mem_antidiagonal, mem_singleton]
+ simp only [mem_filter, Prod.mk.inj_iff, mem_antidiagonal, mem_singleton]
constructor
· rintro ⟨a_left, ⟨a, rfl⟩, rfl⟩
refine' ⟨_, rfl⟩
@@ -292,12 +292,12 @@ theorem num_series' [Field α] (i : ℕ) :
| 0 => rw [mul_zero] at hp; cases hp
| p + 1 => rw [hp]; simp [mul_add]
· suffices
- (filter (fun a : ℕ × ℕ => i + 1 ∣ a.fst ∧ a.snd = i + 1) (Nat.antidiagonal n.succ)).card =
+ (filter (fun a : ℕ × ℕ => i + 1 ∣ a.fst ∧ a.snd = i + 1) (antidiagonal n.succ)).card =
0 by
simp only [Set.mem_setOf_eq]; convert congr_arg ((↑) : ℕ → α) this; norm_cast
rw [card_eq_zero]
apply eq_empty_of_forall_not_mem
- simp only [Prod.forall, mem_filter, not_and, Nat.mem_antidiagonal]
+ simp only [Prod.forall, mem_filter, not_and, mem_antidiagonal]
rintro _ h₁ h₂ ⟨a, rfl⟩ rfl
apply h
simp [← h₂]
cliqueFree_of_replaceVertex_cliqueFree
is still quite long.
@@ -60,7 +60,7 @@ namespace Theorems100
noncomputable section
-variable {α : Type _}
+variable {α : Type*}
open Finset
@@ -97,14 +97,14 @@ Every function in here is finitely supported, and the support is a subset of `s`
This should be thought of as a generalisation of `Finset.Nat.antidiagonalTuple` where
`antidiagonalTuple k n` is the same thing as `cut (s : Finset.univ (Fin k)) n`.
-/
-def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
+def cut {ι : Type*} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
Finset.filter (fun f => s.sum f = n)
((s.pi fun _ => range (n + 1)).map
⟨fun f i => if h : i ∈ s then f i h else 0, fun f g h => by
ext i hi; simpa [dif_pos hi] using congr_fun h i⟩)
#align theorems_100.cut Theorems100.cut
-theorem mem_cut {ι : Type _} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
+theorem mem_cut {ι : Type*} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
f ∈ cut s n ↔ s.sum f = n ∧ ∀ i, i ∉ s → f i = 0 := by
rw [cut, mem_filter, and_comm, and_congr_right]
intro h
@@ -136,7 +136,7 @@ theorem cut_univ_fin_eq_antidiagonalTuple (n : ℕ) (k : ℕ) :
/-- There is only one `cut` of 0. -/
@[simp]
-theorem cut_zero {ι : Type _} (s : Finset ι) : cut s 0 = {0} := by
+theorem cut_zero {ι : Type*} (s : Finset ι) : cut s 0 = {0} := by
-- In general it's nice to prove things using `mem_cut` but in this case it's easier to just
-- use the definition.
rw [cut, range_one, pi_const_singleton, map_singleton, Function.Embedding.coeFn_mk,
@@ -148,14 +148,14 @@ theorem cut_zero {ι : Type _} (s : Finset ι) : cut s 0 = {0} := by
#align theorems_100.cut_zero Theorems100.cut_zero
@[simp]
-theorem cut_empty_succ {ι : Type _} (n : ℕ) : cut (∅ : Finset ι) (n + 1) = ∅ := by
+theorem cut_empty_succ {ι : Type*} (n : ℕ) : cut (∅ : Finset ι) (n + 1) = ∅ := by
apply eq_empty_of_forall_not_mem
intro x hx
rw [mem_cut, sum_empty] at hx
cases hx.1
#align theorems_100.cut_empty_succ Theorems100.cut_empty_succ
-theorem cut_insert {ι : Type _} (n : ℕ) (a : ι) (s : Finset ι) (h : a ∉ s) :
+theorem cut_insert {ι : Type*} (n : ℕ) (a : ι) (s : Finset ι) (h : a ∉ s) :
cut (insert a s) n =
(Nat.antidiagonal n).biUnion fun p : ℕ × ℕ =>
(cut s p.snd).map
@@ -192,7 +192,7 @@ theorem cut_insert {ι : Type _} (n : ℕ) (a : ι) (s : Finset ι) (h : a ∉ s
simp [if_neg h₁, hg₂ _ h₂]
#align theorems_100.cut_insert Theorems100.cut_insert
-theorem coeff_prod_range [CommSemiring α] {ι : Type _} (s : Finset ι) (f : ι → PowerSeries α)
+theorem coeff_prod_range [CommSemiring α] {ι : Type*} (s : Finset ι) (f : ι → PowerSeries α)
(n : ℕ) : coeff α n (∏ j in s, f j) = ∑ l in cut s n, ∏ i in s, coeff α (l i) (f i) := by
revert n
induction s using Finset.induction_on with
@@ -227,7 +227,7 @@ theorem coeff_prod_range [CommSemiring α] {ι : Type _} (s : Finset ι) (f : ι
#align theorems_100.coeff_prod_range Theorems100.coeff_prod_range
/-- A convenience constructor for the power series whose coefficients indicate a subset. -/
-def indicatorSeries (α : Type _) [Semiring α] (s : Set ℕ) : PowerSeries α :=
+def indicatorSeries (α : Type*) [Semiring α] (s : Set ℕ) : PowerSeries α :=
PowerSeries.mk fun n => if n ∈ s then 1 else 0
#align theorems_100.indicator_series Theorems100.indicatorSeries
@@ -309,7 +309,7 @@ def mkOdd : ℕ ↪ ℕ :=
#align theorems_100.mk_odd Theorems100.mkOdd
-- The main workhorse of the partition theorem proof.
-theorem partialGF_prop (α : Type _) [CommSemiring α] (n : ℕ) (s : Finset ℕ) (hs : ∀ i ∈ s, 0 < i)
+theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ) (hs : ∀ i ∈ s, 0 < i)
(c : ℕ → Set ℕ) (hc : ∀ i, i ∉ s → 0 ∈ c i) :
(Finset.card
((univ : Finset (Nat.Partition n)).filter fun p =>
MulZeroClass.
in mul_zero
/zero_mul
(#6682)
Search&replace MulZeroClass.mul_zero
-> mul_zero
, MulZeroClass.zero_mul
-> zero_mul
.
These were introduced by Mathport, as the full name of mul_zero
is actually MulZeroClass.mul_zero
(it's exported with the short name).
@@ -289,7 +289,7 @@ theorem num_series' [Field α] (i : ℕ) :
rw [Nat.mul_sub_left_distrib, ← hp, ← a_left, mul_one, Nat.add_sub_cancel]
· rintro ⟨rfl, rfl⟩
match p with
- | 0 => rw [MulZeroClass.mul_zero] at hp; cases hp
+ | 0 => rw [mul_zero] at hp; cases hp
| p + 1 => rw [hp]; simp [mul_add]
· suffices
(filter (fun a : ℕ × ℕ => i + 1 ∣ a.fst ∧ a.snd = i + 1) (Nat.antidiagonal n.succ)).card =
@@ -2,11 +2,6 @@
Copyright (c) 2020 Bhavik Mehta, Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Bhavik Mehta, Aaron Anderson
-
-! This file was ported from Lean 3 source module wiedijk_100_theorems.partition
-! leanprover-community/mathlib commit 5563b1b49e86e135e8c7b556da5ad2f5ff881cad
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.RingTheory.PowerSeries.Basic
import Mathlib.Combinatorics.Partition
@@ -16,6 +11,8 @@ import Mathlib.Data.Fin.Tuple.NatAntidiagonal
import Mathlib.Tactic.IntervalCases
import Mathlib.Tactic.ApplyFun
+#align_import wiedijk_100_theorems.partition from "leanprover-community/mathlib"@"5563b1b49e86e135e8c7b556da5ad2f5ff881cad"
+
/-!
# Euler's Partition Theorem
This is the second half of the changes originally in #5699, removing all occurrences of ;
after a space and implementing a linter rule to enforce it.
In most cases this 2-character substring has a space after it, so the following command was run first:
find . -type f -name "*.lean" -exec sed -i -E 's/ ; /; /g' {} \;
The remaining cases were few enough in number that they were done manually.
@@ -292,7 +292,7 @@ theorem num_series' [Field α] (i : ℕ) :
rw [Nat.mul_sub_left_distrib, ← hp, ← a_left, mul_one, Nat.add_sub_cancel]
· rintro ⟨rfl, rfl⟩
match p with
- | 0 => rw [MulZeroClass.mul_zero] at hp ; cases hp
+ | 0 => rw [MulZeroClass.mul_zero] at hp; cases hp
| p + 1 => rw [hp]; simp [mul_add]
· suffices
(filter (fun a : ℕ × ℕ => i + 1 ∣ a.fst ∧ a.snd = i + 1) (Nat.antidiagonal n.succ)).card =
ext
(#5258)
Co-authored-by: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Co-authored-by: Joël Riou <joel.riou@universite-paris-saclay.fr> Co-authored-by: Riccardo Brasca <riccardo.brasca@gmail.com> Co-authored-by: Yury G. Kudryashov <urkud@urkud.name> Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com> Co-authored-by: Pol'tta / Miyahara Kō <pol_tta@outlook.jp> Co-authored-by: Jason Yuen <jason_yuen2007@hotmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Jireh Loreaux <loreaujy@gmail.com> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Co-authored-by: Jujian Zhang <jujian.zhang1998@outlook.com> Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>
@@ -104,7 +104,7 @@ def cut {ι : Type _} (s : Finset ι) (n : ℕ) : Finset (ι → ℕ) :=
Finset.filter (fun f => s.sum f = n)
((s.pi fun _ => range (n + 1)).map
⟨fun f i => if h : i ∈ s then f i h else 0, fun f g h => by
- ext (i hi); simpa [dif_pos hi] using congr_fun h i⟩)
+ ext i hi; simpa [dif_pos hi] using congr_fun h i⟩)
#align theorems_100.cut Theorems100.cut
theorem mem_cut {ι : Type _} (s : Finset ι) (n : ℕ) (f : ι → ℕ) :
The unported dependencies are