combinatorics.hindman
⟷
Mathlib.Combinatorics.Hindman
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)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -91,7 +91,7 @@ attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
Continuous (· * V) :=
TopologicalSpace.IsTopologicalBasis.continuous ultrafilterBasis_is_basis _ <|
- Set.forall_range_iff.mpr fun s => ultrafilter_isOpen_basic {m : M | ∀ᶠ m' in V, m * m' ∈ s}
+ Set.forall_mem_range.mpr fun s => ultrafilter_isOpen_basic {m : M | ∀ᶠ m' in V, m * m' ∈ s}
#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_left
#align ultrafilter.continuous_add_left Ultrafilter.continuous_add_left
-/
@@ -180,7 +180,7 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
so we can repeat the argument starting from `s₁`, obtaining `a₁`, `s₂`, etc. This gives the desired
infinite sequence. -/
have exists_elem : ∀ {s : Set M} (hs : s ∈ U), (s ∩ {m | ∀ᶠ m' in U, m * m' ∈ s}).Nonempty :=
- fun s hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rw [← U_idem] at hs ; exact hs)
+ fun s hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rw [← U_idem] at hs; exact hs)
let elem : { s // s ∈ U } → M := fun p => (exists_elem p.property).some
let succ : { s // s ∈ U } → { s // s ∈ U } := fun p =>
⟨p.val ∩ {m | elem p * m ∈ p.val},
@@ -262,7 +262,7 @@ theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
apply FP.cons
rcases le_iff_exists_add.mp (Nat.succ_le_of_lt ij) with ⟨d, hd⟩
have := FP.singleton (a.drop i).tail d
- rw [Stream'.tail_eq_drop, Stream'.get_drop, Stream'.get_drop] at this
+ rw [Stream'.tail_eq_drop, Stream'.get_drop, Stream'.get_drop] at this
convert this
rw [hd, add_comm, Nat.succ_add, Nat.add_succ]
#align hindman.FP.mul_two Hindman.FP.mul_two
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -145,7 +145,7 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
obtain ⟨U, hU, U_idem⟩ := exists_idempotent_in_compact_subsemigroup _ S _ _ _
· refine' ⟨U, U_idem, _⟩; convert set.mem_Inter.mp hU 0
· exact Ultrafilter.continuous_mul_left
- · apply IsCompact.nonempty_iInter_of_sequence_nonempty_compact_closed
+ · apply IsCompact.nonempty_iInter_of_sequence_nonempty_isCompact_isClosed
· intro n U hU
apply eventually.mono hU
rw [add_comm, ← Stream'.drop_drop, ← Stream'.tail_eq_drop]
mathlib commit https://github.com/leanprover-community/mathlib/commit/b1abe23ae96fef89ad30d9f4362c307f72a55010
@@ -262,7 +262,7 @@ theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
apply FP.cons
rcases le_iff_exists_add.mp (Nat.succ_le_of_lt ij) with ⟨d, hd⟩
have := FP.singleton (a.drop i).tail d
- rw [Stream'.tail_eq_drop, Stream'.nth_drop, Stream'.nth_drop] at this
+ rw [Stream'.tail_eq_drop, Stream'.get_drop, Stream'.get_drop] at this
convert this
rw [hd, add_comm, Nat.succ_add, Nat.add_succ]
#align hindman.FP.mul_two Hindman.FP.mul_two
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,9 +3,9 @@ Copyright (c) 2021 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
-/
-import Mathbin.Topology.StoneCech
-import Mathbin.Topology.Algebra.Semigroup
-import Mathbin.Data.Stream.Init
+import Topology.StoneCech
+import Topology.Algebra.Semigroup
+import Data.Stream.Init
#align_import combinatorics.hindman from "leanprover-community/mathlib"@"69c6a5a12d8a2b159f20933e60115a4f2de62b58"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,16 +2,13 @@
Copyright (c) 2021 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
-
-! This file was ported from Lean 3 source module combinatorics.hindman
-! leanprover-community/mathlib commit 69c6a5a12d8a2b159f20933e60115a4f2de62b58
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Topology.StoneCech
import Mathbin.Topology.Algebra.Semigroup
import Mathbin.Data.Stream.Init
+#align_import combinatorics.hindman from "leanprover-community/mathlib"@"69c6a5a12d8a2b159f20933e60115a4f2de62b58"
+
/-!
# Hindman's theorem on finite sums
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -88,6 +88,7 @@ def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) :=
attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
+#print Ultrafilter.continuous_mul_left /-
-- We don't prove `continuous_mul_right`, because in general it is false!
@[to_additive]
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
@@ -96,6 +97,7 @@ theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
Set.forall_range_iff.mpr fun s => ultrafilter_isOpen_basic {m : M | ∀ᶠ m' in V, m * m' ∈ s}
#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_left
#align ultrafilter.continuous_add_left Ultrafilter.continuous_add_left
+-/
namespace Hindman
@@ -121,6 +123,7 @@ inductive FP {M} [Semigroup M] : Stream' M → Set M
#align hindman.FS Hindman.FS
-/
+#print Hindman.FP.mul /-
/-- If `m` and `m'` are finite products in `M`, then so is `m * m'`, provided that `m'` is obtained
from a subsequence of `M` starting sufficiently late. -/
@[to_additive
@@ -134,7 +137,9 @@ theorem FP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ FP a) :
· cases' ih with n hn; use n + 1; intro m' hm'; rw [mul_assoc]; exact FP.cons _ _ (hn _ hm')
#align hindman.FP.mul Hindman.FP.mul
#align hindman.FS.add Hindman.FS.add
+-/
+#print Hindman.exists_idempotent_ultrafilter_le_FP /-
@[to_additive exists_idempotent_ultrafilter_le_FS]
theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
∃ U : Ultrafilter M, U * U = U ∧ ∀ᶠ m in U, m ∈ FP a :=
@@ -165,7 +170,9 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
simpa only [Stream'.drop_drop] using hm'
#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_FP
#align hindman.exists_idempotent_ultrafilter_le_FS Hindman.exists_idempotent_ultrafilter_le_FS
+-/
+#print Hindman.exists_FP_of_large /-
@[to_additive exists_FS_of_large]
theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U = U) (s₀ : Set M)
(sU : s₀ ∈ U) : ∃ a, FP a ⊆ s₀ :=
@@ -199,7 +206,9 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
rw [Stream'.corec_eq, Stream'.tail_cons]
#align hindman.exists_FP_of_large Hindman.exists_FP_of_large
#align hindman.exists_FS_of_large Hindman.exists_FS_of_large
+-/
+#print Hindman.FP_partition_regular /-
/-- The strong form of **Hindman's theorem**: in any finite cover of an FP-set, one the parts
contains an FP-set. -/
@[to_additive FS_partition_regular
@@ -211,7 +220,9 @@ theorem FP_partition_regular {M} [Semigroup M] (a : Stream' M) (s : Set (Set M))
⟨c, cs, exists_FP_of_large U idem c hc⟩
#align hindman.FP_partition_regular Hindman.FP_partition_regular
#align hindman.FS_partition_regular Hindman.FS_partition_regular
+-/
+#print Hindman.exists_FP_of_finite_cover /-
/-- The weak form of **Hindman's theorem**: in any finite cover of a nonempty semigroup, one of the
parts contains an FP-set. -/
@[to_additive exists_FS_of_finite_cover
@@ -224,6 +235,7 @@ theorem exists_FP_of_finite_cover {M} [Semigroup M] [Nonempty M] (s : Set (Set M
⟨c, c_s, exists_FP_of_large U hU c hc⟩
#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_cover
#align hindman.exists_FS_of_finite_cover Hindman.exists_FS_of_finite_cover
+-/
#print Hindman.FP_drop_subset_FP /-
@[to_additive FS_iter_tail_sub_FS]
@@ -244,6 +256,7 @@ theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get? i ∈
#align hindman.FS.singleton Hindman.FS.singleton
-/
+#print Hindman.FP.mul_two /-
@[to_additive]
theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
a.get? i * a.get? j ∈ FP a := by
@@ -257,6 +270,7 @@ theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
rw [hd, add_comm, Nat.succ_add, Nat.add_succ]
#align hindman.FP.mul_two Hindman.FP.mul_two
#align hindman.FS.add_two Hindman.FS.add_two
+-/
#print Hindman.FP.finset_prod /-
@[to_additive]
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -93,7 +93,7 @@ attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
Continuous (· * V) :=
TopologicalSpace.IsTopologicalBasis.continuous ultrafilterBasis_is_basis _ <|
- Set.forall_range_iff.mpr fun s => ultrafilter_isOpen_basic { m : M | ∀ᶠ m' in V, m * m' ∈ s }
+ Set.forall_range_iff.mpr fun s => ultrafilter_isOpen_basic {m : M | ∀ᶠ m' in V, m * m' ∈ s}
#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_left
#align ultrafilter.continuous_add_left Ultrafilter.continuous_add_left
@@ -139,7 +139,7 @@ theorem FP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ FP a) :
theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
∃ U : Ultrafilter M, U * U = U ∧ ∀ᶠ m in U, m ∈ FP a :=
by
- let S : Set (Ultrafilter M) := ⋂ n, { U | ∀ᶠ m in U, m ∈ FP (a.drop n) }
+ let S : Set (Ultrafilter M) := ⋂ n, {U | ∀ᶠ m in U, m ∈ FP (a.drop n)}
obtain ⟨U, hU, U_idem⟩ := exists_idempotent_in_compact_subsemigroup _ S _ _ _
· refine' ⟨U, U_idem, _⟩; convert set.mem_Inter.mp hU 0
· exact Ultrafilter.continuous_mul_left
@@ -175,11 +175,11 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
let `s₁` be the intersection `s₀ ∩ { m | a₀ * m ∈ s₀ }`. By choice of `a₀`, this is again `U`-large,
so we can repeat the argument starting from `s₁`, obtaining `a₁`, `s₂`, etc. This gives the desired
infinite sequence. -/
- have exists_elem : ∀ {s : Set M} (hs : s ∈ U), (s ∩ { m | ∀ᶠ m' in U, m * m' ∈ s }).Nonempty :=
+ have exists_elem : ∀ {s : Set M} (hs : s ∈ U), (s ∩ {m | ∀ᶠ m' in U, m * m' ∈ s}).Nonempty :=
fun s hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rw [← U_idem] at hs ; exact hs)
let elem : { s // s ∈ U } → M := fun p => (exists_elem p.property).some
let succ : { s // s ∈ U } → { s // s ∈ U } := fun p =>
- ⟨p.val ∩ { m | elem p * m ∈ p.val },
+ ⟨p.val ∩ {m | elem p * m ∈ p.val},
inter_mem p.2 <| show _ from Set.inter_subset_right _ _ (exists_elem p.2).some_mem⟩
use Stream'.corec elem succ (Subtype.mk s₀ sU)
suffices ∀ (a : Stream' M), ∀ m ∈ FP a, ∀ p, a = Stream'.corec elem succ p → m ∈ p.val by
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -176,7 +176,7 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
so we can repeat the argument starting from `s₁`, obtaining `a₁`, `s₂`, etc. This gives the desired
infinite sequence. -/
have exists_elem : ∀ {s : Set M} (hs : s ∈ U), (s ∩ { m | ∀ᶠ m' in U, m * m' ∈ s }).Nonempty :=
- fun s hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rw [← U_idem] at hs; exact hs)
+ fun s hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rw [← U_idem] at hs ; exact hs)
let elem : { s // s ∈ U } → M := fun p => (exists_elem p.property).some
let succ : { s // s ∈ U } → { s // s ∈ U } := fun p =>
⟨p.val ∩ { m | elem p * m ∈ p.val },
@@ -252,7 +252,7 @@ theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
apply FP.cons
rcases le_iff_exists_add.mp (Nat.succ_le_of_lt ij) with ⟨d, hd⟩
have := FP.singleton (a.drop i).tail d
- rw [Stream'.tail_eq_drop, Stream'.nth_drop, Stream'.nth_drop] at this
+ rw [Stream'.tail_eq_drop, Stream'.nth_drop, Stream'.nth_drop] at this
convert this
rw [hd, add_comm, Nat.succ_add, Nat.add_succ]
#align hindman.FP.mul_two Hindman.FP.mul_two
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -88,12 +88,6 @@ def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) :=
attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
-/- warning: ultrafilter.continuous_mul_left -> Ultrafilter.continuous_mul_left is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) _x V)
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) _x V)
-Case conversion may be inaccurate. Consider using '#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_leftₓ'. -/
-- We don't prove `continuous_mul_right`, because in general it is false!
@[to_additive]
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
@@ -127,12 +121,6 @@ inductive FP {M} [Semigroup M] : Stream' M → Set M
#align hindman.FS Hindman.FS
-/
-/- warning: hindman.FP.mul -> Hindman.FP.mul is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] {a : Stream'.{u1} M} {m : M}, (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) -> (Exists.{1} Nat (fun (n : Nat) => forall (m' : M), (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m' (Hindman.FP.{u1} M _inst_1 (Stream'.drop.{u1} M n a))) -> (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1)) m m') (Hindman.FP.{u1} M _inst_1 a))))
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] {a : Stream'.{u1} M} {m : M}, (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) -> (Exists.{1} Nat (fun (n : Nat) => forall (m' : M), (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m' (Hindman.FP.{u1} M _inst_1 (Stream'.drop.{u1} M n a))) -> (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toMul.{u1} M _inst_1)) m m') (Hindman.FP.{u1} M _inst_1 a))))
-Case conversion may be inaccurate. Consider using '#align hindman.FP.mul Hindman.FP.mulₓ'. -/
/-- If `m` and `m'` are finite products in `M`, then so is `m * m'`, provided that `m'` is obtained
from a subsequence of `M` starting sufficiently late. -/
@[to_additive
@@ -147,12 +135,6 @@ theorem FP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ FP a) :
#align hindman.FP.mul Hindman.FP.mul
#align hindman.FS.add Hindman.FS.add
-/- warning: hindman.exists_idempotent_ultrafilter_le_FP -> Hindman.exists_idempotent_ultrafilter_le_FP is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Ultrafilter.{u1} M) (Filter.{u1} M) (HasLiftT.mk.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (CoeTCₓ.coe.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (Ultrafilter.Filter.hasCoeT.{u1} M))) U)))
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) (Ultrafilter.toFilter.{u1} M U)))
-Case conversion may be inaccurate. Consider using '#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_FPₓ'. -/
@[to_additive exists_idempotent_ultrafilter_le_FS]
theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
∃ U : Ultrafilter M, U * U = U ∧ ∀ᶠ m in U, m ∈ FP a :=
@@ -184,12 +166,6 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_FP
#align hindman.exists_idempotent_ultrafilter_le_FS Hindman.exists_idempotent_ultrafilter_le_FS
-/- warning: hindman.exists_FP_of_large -> Hindman.exists_FP_of_large is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.Mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.hasMem.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.instMembershipSetUltrafilter.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
-Case conversion may be inaccurate. Consider using '#align hindman.exists_FP_of_large Hindman.exists_FP_of_largeₓ'. -/
@[to_additive exists_FS_of_large]
theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U = U) (s₀ : Set M)
(sU : s₀ ∈ U) : ∃ a, FP a ⊆ s₀ :=
@@ -224,12 +200,6 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
#align hindman.exists_FP_of_large Hindman.exists_FP_of_large
#align hindman.exists_FS_of_large Hindman.exists_FS_of_large
-/- warning: hindman.FP_partition_regular -> Hindman.FP_partition_regular is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
-Case conversion may be inaccurate. Consider using '#align hindman.FP_partition_regular Hindman.FP_partition_regularₓ'. -/
/-- The strong form of **Hindman's theorem**: in any finite cover of an FP-set, one the parts
contains an FP-set. -/
@[to_additive FS_partition_regular
@@ -242,12 +212,6 @@ theorem FP_partition_regular {M} [Semigroup M] (a : Stream' M) (s : Set (Set M))
#align hindman.FP_partition_regular Hindman.FP_partition_regular
#align hindman.FS_partition_regular Hindman.FS_partition_regular
-/- warning: hindman.exists_FP_of_finite_cover -> Hindman.exists_FP_of_finite_cover is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toHasTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.completeBooleanAlgebra.{u1} M)))))) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.instCompleteBooleanAlgebraSet.{u1} M)))))) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
-Case conversion may be inaccurate. Consider using '#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_coverₓ'. -/
/-- The weak form of **Hindman's theorem**: in any finite cover of a nonempty semigroup, one of the
parts contains an FP-set. -/
@[to_additive exists_FS_of_finite_cover
@@ -280,12 +244,6 @@ theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get? i ∈
#align hindman.FS.singleton Hindman.FS.singleton
-/
-/- warning: hindman.FP.mul_two -> Hindman.FP.mul_two is a dubious translation:
-lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (i : Nat) (j : Nat), (LT.lt.{0} Nat Nat.hasLt i j) -> (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1)) (Stream'.nth.{u1} M a i) (Stream'.nth.{u1} M a j)) (Hindman.FP.{u1} M _inst_1 a))
-but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (i : Nat) (j : Nat), (LT.lt.{0} Nat instLTNat i j) -> (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toMul.{u1} M _inst_1)) (Stream'.nth.{u1} M a i) (Stream'.nth.{u1} M a j)) (Hindman.FP.{u1} M _inst_1 a))
-Case conversion may be inaccurate. Consider using '#align hindman.FP.mul_two Hindman.FP.mul_twoₓ'. -/
@[to_additive]
theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
a.get? i * a.get? j ∈ FP a := by
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -142,15 +142,8 @@ theorem FP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ FP a) :
by
induction' hm with a a m hm ih a m hm ih
· exact ⟨1, fun m hm => FP.cons a m hm⟩
- · cases' ih with n hn
- use n + 1
- intro m' hm'
- exact FP.tail _ _ (hn _ hm')
- · cases' ih with n hn
- use n + 1
- intro m' hm'
- rw [mul_assoc]
- exact FP.cons _ _ (hn _ hm')
+ · cases' ih with n hn; use n + 1; intro m' hm'; exact FP.tail _ _ (hn _ hm')
+ · cases' ih with n hn; use n + 1; intro m' hm'; rw [mul_assoc]; exact FP.cons _ _ (hn _ hm')
#align hindman.FP.mul Hindman.FP.mul
#align hindman.FS.add Hindman.FS.add
@@ -166,19 +159,16 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
by
let S : Set (Ultrafilter M) := ⋂ n, { U | ∀ᶠ m in U, m ∈ FP (a.drop n) }
obtain ⟨U, hU, U_idem⟩ := exists_idempotent_in_compact_subsemigroup _ S _ _ _
- · refine' ⟨U, U_idem, _⟩
- convert set.mem_Inter.mp hU 0
+ · refine' ⟨U, U_idem, _⟩; convert set.mem_Inter.mp hU 0
· exact Ultrafilter.continuous_mul_left
· apply IsCompact.nonempty_iInter_of_sequence_nonempty_compact_closed
· intro n U hU
apply eventually.mono hU
rw [add_comm, ← Stream'.drop_drop, ← Stream'.tail_eq_drop]
exact FP.tail _
- · intro n
- exact ⟨pure _, mem_pure.mpr <| FP.head _⟩
+ · intro n; exact ⟨pure _, mem_pure.mpr <| FP.head _⟩
· exact (ultrafilter_isClosed_basic _).IsCompact
- · intro n
- apply ultrafilter_isClosed_basic
+ · intro n; apply ultrafilter_isClosed_basic
· exact IsClosed.isCompact (isClosed_iInter fun i => ultrafilter_isClosed_basic _)
· intro U hU V hV
rw [Set.mem_iInter] at *
@@ -210,20 +200,14 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
so we can repeat the argument starting from `s₁`, obtaining `a₁`, `s₂`, etc. This gives the desired
infinite sequence. -/
have exists_elem : ∀ {s : Set M} (hs : s ∈ U), (s ∩ { m | ∀ᶠ m' in U, m * m' ∈ s }).Nonempty :=
- fun s hs =>
- Ultrafilter.nonempty_of_mem
- (inter_mem hs <| by
- rw [← U_idem] at hs
- exact hs)
+ fun s hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rw [← U_idem] at hs; exact hs)
let elem : { s // s ∈ U } → M := fun p => (exists_elem p.property).some
let succ : { s // s ∈ U } → { s // s ∈ U } := fun p =>
⟨p.val ∩ { m | elem p * m ∈ p.val },
inter_mem p.2 <| show _ from Set.inter_subset_right _ _ (exists_elem p.2).some_mem⟩
use Stream'.corec elem succ (Subtype.mk s₀ sU)
- suffices ∀ (a : Stream' M), ∀ m ∈ FP a, ∀ p, a = Stream'.corec elem succ p → m ∈ p.val
- by
- intro m hm
- exact this _ m hm ⟨s₀, sU⟩ rfl
+ suffices ∀ (a : Stream' M), ∀ m ∈ FP a, ∀ p, a = Stream'.corec elem succ p → m ∈ p.val by
+ intro m hm; exact this _ m hm ⟨s₀, sU⟩ rfl
clear sU s₀
intro a m h
induction' h with b b n h ih b n h ih
@@ -290,12 +274,8 @@ theorem FP_drop_subset_FP {M} [Semigroup M] (a : Stream' M) (n : ℕ) : FP (a.dr
#print Hindman.FP.singleton /-
@[to_additive]
-theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get? i ∈ FP a :=
- by
- induction' i with i ih generalizing a
- · apply FP.head
- · apply FP.tail
- apply ih
+theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get? i ∈ FP a := by
+ induction' i with i ih generalizing a; · apply FP.head; · apply FP.tail; apply ih
#align hindman.FP.singleton Hindman.FP.singleton
#align hindman.FS.singleton Hindman.FS.singleton
-/
@@ -329,10 +309,8 @@ theorem FP.finset_prod {M} [CommMonoid M] (a : Stream' M) (s : Finset ℕ) (hs :
induction' s using Finset.strongInduction with s ih
rw [← Finset.mul_prod_erase _ _ (s.min'_mem hs), ← Stream'.head_drop]
cases' (s.erase (s.min' hs)).eq_empty_or_nonempty with h h
- · rw [h, Finset.prod_empty, mul_one]
- exact FP.head _
- · apply FP.cons
- rw [Stream'.tail_eq_drop, Stream'.drop_drop, add_comm]
+ · rw [h, Finset.prod_empty, mul_one]; exact FP.head _
+ · apply FP.cons; rw [Stream'.tail_eq_drop, Stream'.drop_drop, add_comm]
refine' Set.mem_of_subset_of_mem _ (ih _ (Finset.erase_ssubset <| s.min'_mem hs) h)
have : s.min' hs + 1 ≤ (s.erase (s.min' hs)).min' h :=
Nat.succ_le_of_lt (Finset.min'_lt_of_mem_erase_min' _ _ <| Finset.min'_mem _ _)
mathlib commit https://github.com/leanprover-community/mathlib/commit/e3fb84046afd187b710170887195d50bada934ee
@@ -169,7 +169,7 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
· refine' ⟨U, U_idem, _⟩
convert set.mem_Inter.mp hU 0
· exact Ultrafilter.continuous_mul_left
- · apply IsCompact.nonempty_interᵢ_of_sequence_nonempty_compact_closed
+ · apply IsCompact.nonempty_iInter_of_sequence_nonempty_compact_closed
· intro n U hU
apply eventually.mono hU
rw [add_comm, ← Stream'.drop_drop, ← Stream'.tail_eq_drop]
@@ -179,9 +179,9 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
· exact (ultrafilter_isClosed_basic _).IsCompact
· intro n
apply ultrafilter_isClosed_basic
- · exact IsClosed.isCompact (isClosed_interᵢ fun i => ultrafilter_isClosed_basic _)
+ · exact IsClosed.isCompact (isClosed_iInter fun i => ultrafilter_isClosed_basic _)
· intro U hU V hV
- rw [Set.mem_interᵢ] at *
+ rw [Set.mem_iInter] at *
intro n
rw [Set.mem_setOf_eq, Ultrafilter.eventually_mul]
apply eventually.mono (hU n)
@@ -242,9 +242,9 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
/- warning: hindman.FP_partition_regular -> Hindman.FP_partition_regular is a dubious translation:
lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
Case conversion may be inaccurate. Consider using '#align hindman.FP_partition_regular Hindman.FP_partition_regularₓ'. -/
/-- The strong form of **Hindman's theorem**: in any finite cover of an FP-set, one the parts
contains an FP-set. -/
@@ -253,16 +253,16 @@ contains an FP-set. -/
theorem FP_partition_regular {M} [Semigroup M] (a : Stream' M) (s : Set (Set M)) (sfin : s.Finite)
(scov : FP a ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ b : Stream' M, FP b ⊆ c :=
let ⟨U, idem, aU⟩ := exists_idempotent_ultrafilter_le_FP a
- let ⟨c, cs, hc⟩ := (Ultrafilter.finite_unionₛ_mem_iff sfin).mp (mem_of_superset aU scov)
+ let ⟨c, cs, hc⟩ := (Ultrafilter.finite_sUnion_mem_iff sfin).mp (mem_of_superset aU scov)
⟨c, cs, exists_FP_of_large U idem c hc⟩
#align hindman.FP_partition_regular Hindman.FP_partition_regular
#align hindman.FS_partition_regular Hindman.FS_partition_regular
/- warning: hindman.exists_FP_of_finite_cover -> Hindman.exists_FP_of_finite_cover is a dubious translation:
lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toHasTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.completeBooleanAlgebra.{u1} M)))))) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toHasTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.completeBooleanAlgebra.{u1} M)))))) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.instCompleteBooleanAlgebraSet.{u1} M)))))) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.instCompleteBooleanAlgebraSet.{u1} M)))))) (Set.sUnion.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
Case conversion may be inaccurate. Consider using '#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_coverₓ'. -/
/-- The weak form of **Hindman's theorem**: in any finite cover of a nonempty semigroup, one of the
parts contains an FP-set. -/
@@ -272,7 +272,7 @@ theorem exists_FP_of_finite_cover {M} [Semigroup M] [Nonempty M] (s : Set (Set M
(scov : ⊤ ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ a : Stream' M, FP a ⊆ c :=
let ⟨U, hU⟩ :=
exists_idempotent_of_compact_t2_of_continuous_mul_left (@Ultrafilter.continuous_mul_left M _)
- let ⟨c, c_s, hc⟩ := (Ultrafilter.finite_unionₛ_mem_iff sfin).mp (mem_of_superset univ_mem scov)
+ let ⟨c, c_s, hc⟩ := (Ultrafilter.finite_sUnion_mem_iff sfin).mp (mem_of_superset univ_mem scov)
⟨c, c_s, exists_FP_of_large U hU c hc⟩
#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_cover
#align hindman.exists_FS_of_finite_cover Hindman.exists_FS_of_finite_cover
mathlib commit https://github.com/leanprover-community/mathlib/commit/da3fc4a33ff6bc75f077f691dc94c217b8d41559
@@ -51,16 +51,16 @@ Ramsey theory, ultrafilter
open Filter
-#print Ultrafilter.hasMul /-
+#print Ultrafilter.mul /-
/-- Multiplication of ultrafilters given by `∀ᶠ m in U*V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m*m')`. -/
@[to_additive
"Addition of ultrafilters given by\n`∀ᶠ m in U+V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m+m')`."]
-def Ultrafilter.hasMul {M} [Mul M] : Mul (Ultrafilter M) where mul U V := (· * ·) <$> U <*> V
-#align ultrafilter.has_mul Ultrafilter.hasMul
-#align ultrafilter.has_add Ultrafilter.hasAdd
+def Ultrafilter.mul {M} [Mul M] : Mul (Ultrafilter M) where mul U V := (· * ·) <$> U <*> V
+#align ultrafilter.has_mul Ultrafilter.mul
+#align ultrafilter.has_add Ultrafilter.add
-/
-attribute [local instance] Ultrafilter.hasMul Ultrafilter.hasAdd
+attribute [local instance] Ultrafilter.mul Ultrafilter.add
#print Ultrafilter.eventually_mul /-
/- We could have taken this as the definition of `U * V`, but then we would have to prove that it
@@ -78,7 +78,7 @@ theorem Ultrafilter.eventually_mul {M} [Mul M] (U V : Ultrafilter M) (p : M →
@[to_additive
"Additive semigroup structure on `ultrafilter M` induced by an additive semigroup\nstructure on `M`."]
def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) :=
- { Ultrafilter.hasMul with
+ { Ultrafilter.mul with
mul_assoc := fun U V W =>
Ultrafilter.coe_inj.mp <|
Filter.ext' fun p => by simp only [Ultrafilter.eventually_mul, mul_assoc] }
@@ -90,9 +90,9 @@ attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
/- warning: ultrafilter.continuous_mul_left -> Ultrafilter.continuous_mul_left is a dubious translation:
lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) _x V)
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) _x V)
but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) _x V)
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) _x V)
Case conversion may be inaccurate. Consider using '#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_leftₓ'. -/
-- We don't prove `continuous_mul_right`, because in general it is false!
@[to_additive]
@@ -156,9 +156,9 @@ theorem FP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ FP a) :
/- warning: hindman.exists_idempotent_ultrafilter_le_FP -> Hindman.exists_idempotent_ultrafilter_le_FP is a dubious translation:
lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Ultrafilter.{u1} M) (Filter.{u1} M) (HasLiftT.mk.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (CoeTCₓ.coe.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (Ultrafilter.Filter.hasCoeT.{u1} M))) U)))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Ultrafilter.{u1} M) (Filter.{u1} M) (HasLiftT.mk.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (CoeTCₓ.coe.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (Ultrafilter.Filter.hasCoeT.{u1} M))) U)))
but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) (Ultrafilter.toFilter.{u1} M U)))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) (Ultrafilter.toFilter.{u1} M U)))
Case conversion may be inaccurate. Consider using '#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_FPₓ'. -/
@[to_additive exists_idempotent_ultrafilter_le_FS]
theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
@@ -196,9 +196,9 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
/- warning: hindman.exists_FP_of_large -> Hindman.exists_FP_of_large is a dubious translation:
lean 3 declaration is
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.Mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.hasMem.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.Mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.hasMem.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
but is expected to have type
- forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.instMembershipSetUltrafilter.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.mul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.instMembershipSetUltrafilter.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
Case conversion may be inaccurate. Consider using '#align hindman.exists_FP_of_large Hindman.exists_FP_of_largeₓ'. -/
@[to_additive exists_FS_of_large]
theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U = U) (s₀ : Set M)
mathlib commit https://github.com/leanprover-community/mathlib/commit/2196ab363eb097c008d4497125e0dde23fb36db2
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
! This file was ported from Lean 3 source module combinatorics.hindman
-! leanprover-community/mathlib commit 1e6b748c175e64dd033d7a1a1bfe3e9fe72011d3
+! leanprover-community/mathlib commit 69c6a5a12d8a2b159f20933e60115a4f2de62b58
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -15,6 +15,9 @@ import Mathbin.Data.Stream.Init
/-!
# Hindman's theorem on finite sums
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
We prove Hindman's theorem on finite sums, using idempotent ultrafilters.
Given an infinite sequence `a₀, a₁, a₂, …` of positive integers, the set `FS(a₀, …)` is the set
mathlib commit https://github.com/leanprover-community/mathlib/commit/ddec54a71a0dd025c05445d467f1a2b7d586a3ba
@@ -48,15 +48,18 @@ Ramsey theory, ultrafilter
open Filter
+#print Ultrafilter.hasMul /-
/-- Multiplication of ultrafilters given by `∀ᶠ m in U*V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m*m')`. -/
@[to_additive
"Addition of ultrafilters given by\n`∀ᶠ m in U+V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m+m')`."]
def Ultrafilter.hasMul {M} [Mul M] : Mul (Ultrafilter M) where mul U V := (· * ·) <$> U <*> V
#align ultrafilter.has_mul Ultrafilter.hasMul
#align ultrafilter.has_add Ultrafilter.hasAdd
+-/
attribute [local instance] Ultrafilter.hasMul Ultrafilter.hasAdd
+#print Ultrafilter.eventually_mul /-
/- We could have taken this as the definition of `U * V`, but then we would have to prove that it
defines an ultrafilter. -/
@[to_additive]
@@ -65,7 +68,9 @@ theorem Ultrafilter.eventually_mul {M} [Mul M] (U V : Ultrafilter M) (p : M →
Iff.rfl
#align ultrafilter.eventually_mul Ultrafilter.eventually_mul
#align ultrafilter.eventually_add Ultrafilter.eventually_add
+-/
+#print Ultrafilter.semigroup /-
/-- Semigroup structure on `ultrafilter M` induced by a semigroup structure on `M`. -/
@[to_additive
"Additive semigroup structure on `ultrafilter M` induced by an additive semigroup\nstructure on `M`."]
@@ -76,9 +81,16 @@ def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) :=
Filter.ext' fun p => by simp only [Ultrafilter.eventually_mul, mul_assoc] }
#align ultrafilter.semigroup Ultrafilter.semigroup
#align ultrafilter.add_semigroup Ultrafilter.addSemigroup
+-/
attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
+/- warning: ultrafilter.continuous_mul_left -> Ultrafilter.continuous_mul_left is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) _x V)
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (V : Ultrafilter.{u1} M), Continuous.{u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (Ultrafilter.topologicalSpace.{u1} M) (fun (_x : Ultrafilter.{u1} M) => HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) _x V)
+Case conversion may be inaccurate. Consider using '#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_leftₓ'. -/
-- We don't prove `continuous_mul_right`, because in general it is false!
@[to_additive]
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
@@ -90,30 +102,40 @@ theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
namespace Hindman
+#print Hindman.FS /-
/-- `FS a` is the set of finite sums in `a`, i.e. `m ∈ FS a` if `m` is the sum of a nonempty
subsequence of `a`. We give a direct inductive definition instead of talking about subsequences. -/
-inductive fS {M} [AddSemigroup M] : Stream' M → Set M
+inductive FS {M} [AddSemigroup M] : Stream' M → Set M
| head (a : Stream' M) : FS a a.headI
| tail (a : Stream' M) (m : M) (h : FS a.tail m) : FS a m
| cons (a : Stream' M) (m : M) (h : FS a.tail m) : FS a (a.headI + m)
-#align hindman.FS Hindman.fS
+#align hindman.FS Hindman.FS
+-/
+#print Hindman.FP /-
/-- `FP a` is the set of finite products in `a`, i.e. `m ∈ FP a` if `m` is the product of a nonempty
subsequence of `a`. We give a direct inductive definition instead of talking about subsequences. -/
@[to_additive FS]
-inductive fP {M} [Semigroup M] : Stream' M → Set M
+inductive FP {M} [Semigroup M] : Stream' M → Set M
| head (a : Stream' M) : FP a a.headI
| tail (a : Stream' M) (m : M) (h : FP a.tail m) : FP a m
| cons (a : Stream' M) (m : M) (h : FP a.tail m) : FP a (a.headI * m)
-#align hindman.FP Hindman.fP
-#align hindman.FS Hindman.fS
+#align hindman.FP Hindman.FP
+#align hindman.FS Hindman.FS
+-/
+/- warning: hindman.FP.mul -> Hindman.FP.mul is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] {a : Stream'.{u1} M} {m : M}, (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) -> (Exists.{1} Nat (fun (n : Nat) => forall (m' : M), (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m' (Hindman.FP.{u1} M _inst_1 (Stream'.drop.{u1} M n a))) -> (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1)) m m') (Hindman.FP.{u1} M _inst_1 a))))
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] {a : Stream'.{u1} M} {m : M}, (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) -> (Exists.{1} Nat (fun (n : Nat) => forall (m' : M), (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m' (Hindman.FP.{u1} M _inst_1 (Stream'.drop.{u1} M n a))) -> (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toMul.{u1} M _inst_1)) m m') (Hindman.FP.{u1} M _inst_1 a))))
+Case conversion may be inaccurate. Consider using '#align hindman.FP.mul Hindman.FP.mulₓ'. -/
/-- If `m` and `m'` are finite products in `M`, then so is `m * m'`, provided that `m'` is obtained
from a subsequence of `M` starting sufficiently late. -/
@[to_additive
"If `m` and `m'` are finite sums in `M`, then so is `m + m'`, provided that `m'`\nis obtained from a subsequence of `M` starting sufficiently late."]
-theorem fP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ fP a) :
- ∃ n, ∀ m' ∈ fP (a.drop n), m * m' ∈ fP a :=
+theorem FP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ FP a) :
+ ∃ n, ∀ m' ∈ FP (a.drop n), m * m' ∈ FP a :=
by
induction' hm with a a m hm ih a m hm ih
· exact ⟨1, fun m hm => FP.cons a m hm⟩
@@ -126,12 +148,18 @@ theorem fP.mul {M} [Semigroup M] {a : Stream' M} {m : M} (hm : m ∈ fP a) :
intro m' hm'
rw [mul_assoc]
exact FP.cons _ _ (hn _ hm')
-#align hindman.FP.mul Hindman.fP.mul
-#align hindman.FS.add Hindman.fS.add
-
+#align hindman.FP.mul Hindman.FP.mul
+#align hindman.FS.add Hindman.FS.add
+
+/- warning: hindman.exists_idempotent_ultrafilter_le_FP -> Hindman.exists_idempotent_ultrafilter_le_FP is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Ultrafilter.{u1} M) (Filter.{u1} M) (HasLiftT.mk.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (CoeTCₓ.coe.{succ u1, succ u1} (Ultrafilter.{u1} M) (Filter.{u1} M) (Ultrafilter.Filter.hasCoeT.{u1} M))) U)))
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M), Exists.{succ u1} (Ultrafilter.{u1} M) (fun (U : Ultrafilter.{u1} M) => And (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) (Filter.Eventually.{u1} M (fun (m : M) => Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) m (Hindman.FP.{u1} M _inst_1 a)) (Ultrafilter.toFilter.{u1} M U)))
+Case conversion may be inaccurate. Consider using '#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_FPₓ'. -/
@[to_additive exists_idempotent_ultrafilter_le_FS]
-theorem exists_idempotent_ultrafilter_le_fP {M} [Semigroup M] (a : Stream' M) :
- ∃ U : Ultrafilter M, U * U = U ∧ ∀ᶠ m in U, m ∈ fP a :=
+theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
+ ∃ U : Ultrafilter M, U * U = U ∧ ∀ᶠ m in U, m ∈ FP a :=
by
let S : Set (Ultrafilter M) := ⋂ n, { U | ∀ᶠ m in U, m ∈ FP (a.drop n) }
obtain ⟨U, hU, U_idem⟩ := exists_idempotent_in_compact_subsemigroup _ S _ _ _
@@ -160,12 +188,18 @@ theorem exists_idempotent_ultrafilter_le_fP {M} [Semigroup M] (a : Stream' M) :
intro m' hm'
apply hn
simpa only [Stream'.drop_drop] using hm'
-#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_fP
+#align hindman.exists_idempotent_ultrafilter_le_FP Hindman.exists_idempotent_ultrafilter_le_FP
#align hindman.exists_idempotent_ultrafilter_le_FS Hindman.exists_idempotent_ultrafilter_le_FS
+/- warning: hindman.exists_FP_of_large -> Hindman.exists_FP_of_large is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.Mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.hasMem.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (U : Ultrafilter.{u1} M), (Eq.{succ u1} (Ultrafilter.{u1} M) (HMul.hMul.{u1, u1, u1} (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.{u1} M) (instHMul.{u1} (Ultrafilter.{u1} M) (Ultrafilter.hasMul.{u1} M (Semigroup.toMul.{u1} M _inst_1))) U U) U) -> (forall (s₀ : Set.{u1} M), (Membership.mem.{u1, u1} (Set.{u1} M) (Ultrafilter.{u1} M) (Ultrafilter.instMembershipSetUltrafilter.{u1} M) s₀ U) -> (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) s₀)))
+Case conversion may be inaccurate. Consider using '#align hindman.exists_FP_of_large Hindman.exists_FP_of_largeₓ'. -/
@[to_additive exists_FS_of_large]
-theorem exists_fP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U = U) (s₀ : Set M)
- (sU : s₀ ∈ U) : ∃ a, fP a ⊆ s₀ :=
+theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U = U) (s₀ : Set M)
+ (sU : s₀ ∈ U) : ∃ a, FP a ⊆ s₀ :=
by
/- Informally: given a `U`-large set `s₀`, the set `s₀ ∩ { m | ∀ᶠ m' in U, m * m' ∈ s₀ }` is also
`U`-large (since `U` is idempotent). Thus in particular there is an `a₀` in this intersection. Now
@@ -200,56 +234,78 @@ theorem exists_fP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
have := Set.inter_subset_right _ _ (ih (succ p) _)
· simpa only using this
rw [Stream'.corec_eq, Stream'.tail_cons]
-#align hindman.exists_FP_of_large Hindman.exists_fP_of_large
+#align hindman.exists_FP_of_large Hindman.exists_FP_of_large
#align hindman.exists_FS_of_large Hindman.exists_FS_of_large
+/- warning: hindman.FP_partition_regular -> Hindman.FP_partition_regular is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (b : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 b) c))))
+Case conversion may be inaccurate. Consider using '#align hindman.FP_partition_regular Hindman.FP_partition_regularₓ'. -/
/-- The strong form of **Hindman's theorem**: in any finite cover of an FP-set, one the parts
contains an FP-set. -/
@[to_additive FS_partition_regular
"The strong form of **Hindman's theorem**: in any finite cover of\nan FS-set, one the parts contains an FS-set."]
-theorem fP_partition_regular {M} [Semigroup M] (a : Stream' M) (s : Set (Set M)) (sfin : s.Finite)
- (scov : fP a ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ b : Stream' M, fP b ⊆ c :=
- let ⟨U, idem, aU⟩ := exists_idempotent_ultrafilter_le_fP a
+theorem FP_partition_regular {M} [Semigroup M] (a : Stream' M) (s : Set (Set M)) (sfin : s.Finite)
+ (scov : FP a ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ b : Stream' M, FP b ⊆ c :=
+ let ⟨U, idem, aU⟩ := exists_idempotent_ultrafilter_le_FP a
let ⟨c, cs, hc⟩ := (Ultrafilter.finite_unionₛ_mem_iff sfin).mp (mem_of_superset aU scov)
- ⟨c, cs, exists_fP_of_large U idem c hc⟩
-#align hindman.FP_partition_regular Hindman.fP_partition_regular
+ ⟨c, cs, exists_FP_of_large U idem c hc⟩
+#align hindman.FP_partition_regular Hindman.FP_partition_regular
#align hindman.FS_partition_regular Hindman.FS_partition_regular
+/- warning: hindman.exists_FP_of_finite_cover -> Hindman.exists_FP_of_finite_cover is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toHasTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.completeBooleanAlgebra.{u1} M)))))) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => Exists.{0} (Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) (fun (H : Membership.Mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.hasMem.{u1} (Set.{u1} M)) c s) => Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.hasSubset.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] [_inst_2 : Nonempty.{succ u1} M] (s : Set.{u1} (Set.{u1} M)), (Set.Finite.{u1} (Set.{u1} M) s) -> (HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Top.top.{u1} (Set.{u1} M) (CompleteLattice.toTop.{u1} (Set.{u1} M) (Order.Coframe.toCompleteLattice.{u1} (Set.{u1} M) (CompleteDistribLattice.toCoframe.{u1} (Set.{u1} M) (CompleteBooleanAlgebra.toCompleteDistribLattice.{u1} (Set.{u1} M) (Set.instCompleteBooleanAlgebraSet.{u1} M)))))) (Set.unionₛ.{u1} M s)) -> (Exists.{succ u1} (Set.{u1} M) (fun (c : Set.{u1} M) => And (Membership.mem.{u1, u1} (Set.{u1} M) (Set.{u1} (Set.{u1} M)) (Set.instMembershipSet.{u1} (Set.{u1} M)) c s) (Exists.{succ u1} (Stream'.{u1} M) (fun (a : Stream'.{u1} M) => HasSubset.Subset.{u1} (Set.{u1} M) (Set.instHasSubsetSet.{u1} M) (Hindman.FP.{u1} M _inst_1 a) c))))
+Case conversion may be inaccurate. Consider using '#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_coverₓ'. -/
/-- The weak form of **Hindman's theorem**: in any finite cover of a nonempty semigroup, one of the
parts contains an FP-set. -/
@[to_additive exists_FS_of_finite_cover
"The weak form of **Hindman's theorem**: in any finite cover\nof a nonempty additive semigroup, one of the parts contains an FS-set."]
-theorem exists_fP_of_finite_cover {M} [Semigroup M] [Nonempty M] (s : Set (Set M)) (sfin : s.Finite)
- (scov : ⊤ ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ a : Stream' M, fP a ⊆ c :=
+theorem exists_FP_of_finite_cover {M} [Semigroup M] [Nonempty M] (s : Set (Set M)) (sfin : s.Finite)
+ (scov : ⊤ ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ a : Stream' M, FP a ⊆ c :=
let ⟨U, hU⟩ :=
exists_idempotent_of_compact_t2_of_continuous_mul_left (@Ultrafilter.continuous_mul_left M _)
let ⟨c, c_s, hc⟩ := (Ultrafilter.finite_unionₛ_mem_iff sfin).mp (mem_of_superset univ_mem scov)
- ⟨c, c_s, exists_fP_of_large U hU c hc⟩
-#align hindman.exists_FP_of_finite_cover Hindman.exists_fP_of_finite_cover
+ ⟨c, c_s, exists_FP_of_large U hU c hc⟩
+#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_cover
#align hindman.exists_FS_of_finite_cover Hindman.exists_FS_of_finite_cover
+#print Hindman.FP_drop_subset_FP /-
@[to_additive FS_iter_tail_sub_FS]
-theorem fP_drop_subset_fP {M} [Semigroup M] (a : Stream' M) (n : ℕ) : fP (a.drop n) ⊆ fP a :=
+theorem FP_drop_subset_FP {M} [Semigroup M] (a : Stream' M) (n : ℕ) : FP (a.drop n) ⊆ FP a :=
by
induction' n with n ih; · rfl
rw [Nat.succ_eq_one_add, ← Stream'.drop_drop]
exact trans (FP.tail _) ih
-#align hindman.FP_drop_subset_FP Hindman.fP_drop_subset_fP
+#align hindman.FP_drop_subset_FP Hindman.FP_drop_subset_FP
#align hindman.FS_iter_tail_sub_FS Hindman.FS_iter_tail_sub_FS
+-/
+#print Hindman.FP.singleton /-
@[to_additive]
-theorem fP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get? i ∈ fP a :=
+theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get? i ∈ FP a :=
by
induction' i with i ih generalizing a
· apply FP.head
· apply FP.tail
apply ih
-#align hindman.FP.singleton Hindman.fP.singleton
-#align hindman.FS.singleton Hindman.fS.singleton
+#align hindman.FP.singleton Hindman.FP.singleton
+#align hindman.FS.singleton Hindman.FS.singleton
+-/
+/- warning: hindman.FP.mul_two -> Hindman.FP.mul_two is a dubious translation:
+lean 3 declaration is
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (i : Nat) (j : Nat), (LT.lt.{0} Nat Nat.hasLt i j) -> (Membership.Mem.{u1, u1} M (Set.{u1} M) (Set.hasMem.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toHasMul.{u1} M _inst_1)) (Stream'.nth.{u1} M a i) (Stream'.nth.{u1} M a j)) (Hindman.FP.{u1} M _inst_1 a))
+but is expected to have type
+ forall {M : Type.{u1}} [_inst_1 : Semigroup.{u1} M] (a : Stream'.{u1} M) (i : Nat) (j : Nat), (LT.lt.{0} Nat instLTNat i j) -> (Membership.mem.{u1, u1} M (Set.{u1} M) (Set.instMembershipSet.{u1} M) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (Semigroup.toMul.{u1} M _inst_1)) (Stream'.nth.{u1} M a i) (Stream'.nth.{u1} M a j)) (Hindman.FP.{u1} M _inst_1 a))
+Case conversion may be inaccurate. Consider using '#align hindman.FP.mul_two Hindman.FP.mul_twoₓ'. -/
@[to_additive]
-theorem fP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
- a.get? i * a.get? j ∈ fP a := by
+theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
+ a.get? i * a.get? j ∈ FP a := by
refine' FP_drop_subset_FP _ i _
rw [← Stream'.head_drop]
apply FP.cons
@@ -258,12 +314,13 @@ theorem fP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
rw [Stream'.tail_eq_drop, Stream'.nth_drop, Stream'.nth_drop] at this
convert this
rw [hd, add_comm, Nat.succ_add, Nat.add_succ]
-#align hindman.FP.mul_two Hindman.fP.mul_two
-#align hindman.FS.add_two Hindman.fS.add_two
+#align hindman.FP.mul_two Hindman.FP.mul_two
+#align hindman.FS.add_two Hindman.FS.add_two
+#print Hindman.FP.finset_prod /-
@[to_additive]
-theorem fP.finset_prod {M} [CommMonoid M] (a : Stream' M) (s : Finset ℕ) (hs : s.Nonempty) :
- (s.Prod fun i => a.get? i) ∈ fP a :=
+theorem FP.finset_prod {M} [CommMonoid M] (a : Stream' M) (s : Finset ℕ) (hs : s.Nonempty) :
+ (s.Prod fun i => a.get? i) ∈ FP a :=
by
refine' FP_drop_subset_FP _ (s.min' hs) _
induction' s using Finset.strongInduction with s ih
@@ -279,8 +336,9 @@ theorem fP.finset_prod {M} [CommMonoid M] (a : Stream' M) (s : Finset ℕ) (hs :
cases' le_iff_exists_add.mp this with d hd
rw [hd, add_comm, ← Stream'.drop_drop]
apply FP_drop_subset_FP
-#align hindman.FP.finset_prod Hindman.fP.finset_prod
-#align hindman.FS.finset_sum Hindman.fS.finset_sum
+#align hindman.FP.finset_prod Hindman.FP.finset_prod
+#align hindman.FS.finset_sum Hindman.FS.finset_sum
+-/
end Hindman
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
filter_upwards
(#11208)
This is presumably not exhaustive, but covers about a hundred instances.
Style opinions (e.g., why a particular change is great/not a good idea) are very welcome; I'm still forming my own.
@@ -145,7 +145,7 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
· exact Ultrafilter.continuous_mul_left
· apply IsCompact.nonempty_iInter_of_sequence_nonempty_isCompact_isClosed
· intro n U hU
- apply Eventually.mono hU
+ filter_upwards [hU]
rw [add_comm, ← Stream'.drop_drop, ← Stream'.tail_eq_drop]
exact FP.tail _
· intro n
@@ -158,11 +158,9 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
rw [Set.mem_iInter] at *
intro n
rw [Set.mem_setOf_eq, Ultrafilter.eventually_mul]
- apply Eventually.mono (hU n)
- intro m hm
+ filter_upwards [hU n] with m hm
obtain ⟨n', hn⟩ := FP.mul hm
- apply Eventually.mono (hV (n' + n))
- intro m' hm'
+ filter_upwards [hV (n' + n)] with m' hm'
apply hn
simpa only [Stream'.drop_drop] using hm'
set_option linter.uppercaseLean3 false in
ball
and bex
from lemma names (#10816)
ball
for "bounded forall" and bex
for "bounded exists" are from experience very confusing abbreviations. This PR renames them to forall_mem
and exists_mem
in the few Set
lemma names that mention them.
Also deprecate ball_image_of_ball
, mem_image_elim
, mem_image_elim_on
since those lemmas are duplicates of the renamed lemmas (apart from argument order and implicitness, which I am also fixing by making the binder in the RHS of forall_mem_image
semi-implicit), have obscure names and are completely unused.
@@ -82,7 +82,7 @@ attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
@[to_additive]
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
Continuous (· * V) :=
- ultrafilterBasis_is_basis.continuous_iff.2 <| Set.forall_range_iff.mpr fun s ↦
+ ultrafilterBasis_is_basis.continuous_iff.2 <| Set.forall_mem_range.mpr fun s ↦
ultrafilter_isOpen_basic { m : M | ∀ᶠ m' in V, m * m' ∈ s }
#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_left
#align ultrafilter.continuous_add_left Ultrafilter.continuous_add_left
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -89,7 +89,7 @@ theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
namespace Hindman
--- porting note: mathport wants these names to be `fS`, `fP`, etc, but this does violence to
+-- Porting note: mathport wants these names to be `fS`, `fP`, etc, but this does violence to
-- mathematical naming conventions, as does `fs`, `fp`, so we just followed `mathlib` 3 here
/-- `FS a` is the set of finite sums in `a`, i.e. `m ∈ FS a` if `m` is the sum of a nonempty
slow / slower
porting notes (#11084)
Classifies by adding issue number #11083 to porting notes claiming anything semantically equivalent to:
attribute
because it caused extremely slow tactic
"@@ -71,7 +71,7 @@ def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) :=
{ Ultrafilter.mul with
mul_assoc := fun U V W =>
Ultrafilter.coe_inj.mp <|
- -- porting note: `simp` was slow to typecheck, replaced by `simp_rw`
+ -- porting note (#11083): `simp` was slow to typecheck, replaced by `simp_rw`
Filter.ext' fun p => by simp_rw [Ultrafilter.eventually_mul, mul_assoc] }
#align ultrafilter.semigroup Ultrafilter.semigroup
#align ultrafilter.add_semigroup Ultrafilter.addSemigroup
The iInter version of Cantor's intersection theorem is already present: IsCompact.nonempty_iInter_of_directed_nonempty_compact_closed
.
The proof of the added sInter version takes advantage of the iInter version.
Much of the addition due to conversation with Sebastien Gouezel on Zulip.
@@ -143,7 +143,7 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
refine' ⟨U, U_idem, _⟩
convert Set.mem_iInter.mp hU 0
· exact Ultrafilter.continuous_mul_left
- · apply IsCompact.nonempty_iInter_of_sequence_nonempty_compact_closed
+ · apply IsCompact.nonempty_iInter_of_sequence_nonempty_isCompact_isClosed
· intro n U hU
apply Eventually.mono hU
rw [add_comm, ← Stream'.drop_drop, ← Stream'.tail_eq_drop]
continuous_generateFrom
to an iff
(#9259)
Similarly, upgrade tendsto_nhds_generateFrom
, IsTopologicalBasis.continuous
, Topology.IsLower.continuous_of_Ici
, and Topology.IsUpper.continuous_iff_Iic
.
The old lemmas are now deprecated, and the new ones have _iff
in their names.
Once we remove the old lemmas, we can drop the _iff
suffixes.
@@ -82,8 +82,8 @@ attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup
@[to_additive]
theorem Ultrafilter.continuous_mul_left {M} [Semigroup M] (V : Ultrafilter M) :
Continuous (· * V) :=
- TopologicalSpace.IsTopologicalBasis.continuous ultrafilterBasis_is_basis _ <|
- Set.forall_range_iff.mpr fun s => ultrafilter_isOpen_basic { m : M | ∀ᶠ m' in V, m * m' ∈ s }
+ ultrafilterBasis_is_basis.continuous_iff.2 <| Set.forall_range_iff.mpr fun s ↦
+ ultrafilter_isOpen_basic { m : M | ∀ᶠ m' in V, m * m' ∈ s }
#align ultrafilter.continuous_mul_left Ultrafilter.continuous_mul_left
#align ultrafilter.continuous_add_left Ultrafilter.continuous_add_left
cases'
(#9171)
I literally went through and regex'd some uses of cases'
, replacing them with rcases
; this is meant to be a low effort PR as I hope that tools can do this in the future.
rcases
is an easier replacement than cases
, though with better tools we could in future do a second pass converting simple rcases
added here (and existing ones) to cases
.
@@ -286,7 +286,7 @@ theorem FP.finset_prod {M} [CommMonoid M] (a : Stream' M) (s : Finset ℕ) (hs :
refine' FP_drop_subset_FP _ (s.min' hs) _
induction' s using Finset.strongInduction with s ih
rw [← Finset.mul_prod_erase _ _ (s.min'_mem hs), ← Stream'.head_drop]
- cases' (s.erase (s.min' hs)).eq_empty_or_nonempty with h h
+ rcases (s.erase (s.min' hs)).eq_empty_or_nonempty with h | h
· rw [h, Finset.prod_empty, mul_one]
exact FP.head _
· apply FP.cons
Stream'.nth
to Stream'.get
(#7514)
Many of nth
(e.g. list.nth
, stream.seq.nth
) are renamed to get?
in Mathlib 4, but Stream'.nth
had been remained as it.
@@ -252,7 +252,7 @@ set_option linter.uppercaseLean3 false in
#align hindman.FS_iter_tail_sub_FS Hindman.FS_iter_tail_sub_FS
@[to_additive]
-theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.nth i ∈ FP a := by
+theorem FP.singleton {M} [Semigroup M] (a : Stream' M) (i : ℕ) : a.get i ∈ FP a := by
induction' i with i ih generalizing a
· apply FP.head
· apply FP.tail
@@ -264,7 +264,7 @@ set_option linter.uppercaseLean3 false in
@[to_additive]
theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
- a.nth i * a.nth j ∈ FP a := by
+ a.get i * a.get j ∈ FP a := by
refine' FP_drop_subset_FP _ i _
rw [← Stream'.head_drop]
apply FP.cons
@@ -272,7 +272,7 @@ theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
-- Porting note: need to fix breakage of Set notation
change _ ∈ FP _
have := FP.singleton (a.drop i).tail d
- rw [Stream'.tail_eq_drop, Stream'.nth_drop, Stream'.nth_drop] at this
+ rw [Stream'.tail_eq_drop, Stream'.get_drop, Stream'.get_drop] at this
convert this
rw [hd, add_comm, Nat.succ_add, Nat.add_succ]
set_option linter.uppercaseLean3 false in
@@ -282,7 +282,7 @@ set_option linter.uppercaseLean3 false in
@[to_additive]
theorem FP.finset_prod {M} [CommMonoid M] (a : Stream' M) (s : Finset ℕ) (hs : s.Nonempty) :
- (s.prod fun i => a.nth i) ∈ FP a := by
+ (s.prod fun i => a.get i) ∈ FP a := by
refine' FP_drop_subset_FP _ (s.min' hs) _
induction' s using Finset.strongInduction with s ih
rw [← Finset.mul_prod_erase _ _ (s.min'_mem hs), ← Stream'.head_drop]
@@ -2,16 +2,13 @@
Copyright (c) 2021 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
-
-! This file was ported from Lean 3 source module combinatorics.hindman
-! leanprover-community/mathlib commit dc6c365e751e34d100e80fe6e314c3c3e0fd2988
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Topology.StoneCech
import Mathlib.Topology.Algebra.Semigroup
import Mathlib.Data.Stream.Init
+#align_import combinatorics.hindman from "leanprover-community/mathlib"@"dc6c365e751e34d100e80fe6e314c3c3e0fd2988"
+
/-!
# Hindman's theorem on finite sums
sSup
/iSup
(#3938)
As discussed on Zulip
supₛ
→ sSup
infₛ
→ sInf
supᵢ
→ iSup
infᵢ
→ iInf
bsupₛ
→ bsSup
binfₛ
→ bsInf
bsupᵢ
→ biSup
binfᵢ
→ biInf
csupₛ
→ csSup
cinfₛ
→ csInf
csupᵢ
→ ciSup
cinfᵢ
→ ciInf
unionₛ
→ sUnion
interₛ
→ sInter
unionᵢ
→ iUnion
interᵢ
→ iInter
bunionₛ
→ bsUnion
binterₛ
→ bsInter
bunionᵢ
→ biUnion
binterᵢ
→ biInter
Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>
@@ -144,9 +144,9 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
have h := exists_idempotent_in_compact_subsemigroup ?_ S ?_ ?_ ?_
· rcases h with ⟨U, hU, U_idem⟩
refine' ⟨U, U_idem, _⟩
- convert Set.mem_interᵢ.mp hU 0
+ convert Set.mem_iInter.mp hU 0
· exact Ultrafilter.continuous_mul_left
- · apply IsCompact.nonempty_interᵢ_of_sequence_nonempty_compact_closed
+ · apply IsCompact.nonempty_iInter_of_sequence_nonempty_compact_closed
· intro n U hU
apply Eventually.mono hU
rw [add_comm, ← Stream'.drop_drop, ← Stream'.tail_eq_drop]
@@ -156,9 +156,9 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
· exact (ultrafilter_isClosed_basic _).isCompact
· intro n
apply ultrafilter_isClosed_basic
- · exact IsClosed.isCompact (isClosed_interᵢ fun i => ultrafilter_isClosed_basic _)
+ · exact IsClosed.isCompact (isClosed_iInter fun i => ultrafilter_isClosed_basic _)
· intro U hU V hV
- rw [Set.mem_interᵢ] at *
+ rw [Set.mem_iInter] at *
intro n
rw [Set.mem_setOf_eq, Ultrafilter.eventually_mul]
apply Eventually.mono (hU n)
@@ -220,7 +220,7 @@ contains an FP-set. -/
theorem FP_partition_regular {M} [Semigroup M] (a : Stream' M) (s : Set (Set M)) (sfin : s.Finite)
(scov : FP a ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ b : Stream' M, FP b ⊆ c :=
let ⟨U, idem, aU⟩ := exists_idempotent_ultrafilter_le_FP a
- let ⟨c, cs, hc⟩ := (Ultrafilter.finite_unionₛ_mem_iff sfin).mp (mem_of_superset aU scov)
+ let ⟨c, cs, hc⟩ := (Ultrafilter.finite_sUnion_mem_iff sfin).mp (mem_of_superset aU scov)
⟨c, cs, exists_FP_of_large U idem c hc⟩
set_option linter.uppercaseLean3 false in
#align hindman.FP_partition_regular Hindman.FP_partition_regular
@@ -236,7 +236,7 @@ theorem exists_FP_of_finite_cover {M} [Semigroup M] [Nonempty M] (s : Set (Set M
(scov : ⊤ ⊆ ⋃₀ s) : ∃ c ∈ s, ∃ a : Stream' M, FP a ⊆ c :=
let ⟨U, hU⟩ :=
exists_idempotent_of_compact_t2_of_continuous_mul_left (@Ultrafilter.continuous_mul_left M _)
- let ⟨c, c_s, hc⟩ := (Ultrafilter.finite_unionₛ_mem_iff sfin).mp (mem_of_superset univ_mem scov)
+ let ⟨c, c_s, hc⟩ := (Ultrafilter.finite_sUnion_mem_iff sfin).mp (mem_of_superset univ_mem scov)
⟨c, c_s, exists_FP_of_large U hU c hc⟩
set_option linter.uppercaseLean3 false in
#align hindman.exists_FP_of_finite_cover Hindman.exists_FP_of_finite_cover
@@ -50,12 +50,12 @@ open Filter
/-- Multiplication of ultrafilters given by `∀ᶠ m in U*V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m*m')`. -/
@[to_additive
- "Addition of ultrafilters given by\n`∀ᶠ m in U+V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m+m')`."]
-def Ultrafilter.hasMul {M} [Mul M] : Mul (Ultrafilter M) where mul U V := (· * ·) <$> U <*> V
-#align ultrafilter.has_mul Ultrafilter.hasMul
-#align ultrafilter.has_add Ultrafilter.hasAdd
+ "Addition of ultrafilters given by `∀ᶠ m in U+V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m+m')`."]
+def Ultrafilter.mul {M} [Mul M] : Mul (Ultrafilter M) where mul U V := (· * ·) <$> U <*> V
+#align ultrafilter.has_mul Ultrafilter.mul
+#align ultrafilter.has_add Ultrafilter.add
-attribute [local instance] Ultrafilter.hasMul Ultrafilter.hasAdd
+attribute [local instance] Ultrafilter.mul Ultrafilter.add
/- We could have taken this as the definition of `U * V`, but then we would have to prove that it
defines an ultrafilter. -/
@@ -66,16 +66,16 @@ theorem Ultrafilter.eventually_mul {M} [Mul M] (U V : Ultrafilter M) (p : M →
#align ultrafilter.eventually_mul Ultrafilter.eventually_mul
#align ultrafilter.eventually_add Ultrafilter.eventually_add
--- porting note: slow to typecheck
/-- Semigroup structure on `Ultrafilter M` induced by a semigroup structure on `M`. -/
@[to_additive
"Additive semigroup structure on `Ultrafilter M` induced by an additive semigroup
structure on `M`."]
def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) :=
- { Ultrafilter.hasMul with
+ { Ultrafilter.mul with
mul_assoc := fun U V W =>
Ultrafilter.coe_inj.mp <|
- Filter.ext' fun p => by simp only [Ultrafilter.eventually_mul, mul_assoc] }
+ -- porting note: `simp` was slow to typecheck, replaced by `simp_rw`
+ Filter.ext' fun p => by simp_rw [Ultrafilter.eventually_mul, mul_assoc] }
#align ultrafilter.semigroup Ultrafilter.semigroup
#align ultrafilter.add_semigroup Ultrafilter.addSemigroup
@@ -142,8 +142,8 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) :
∃ U : Ultrafilter M, U * U = U ∧ ∀ᶠ m in U, m ∈ FP a := by
let S : Set (Ultrafilter M) := ⋂ n, { U | ∀ᶠ m in U, m ∈ FP (a.drop n) }
have h := exists_idempotent_in_compact_subsemigroup ?_ S ?_ ?_ ?_
- rcases h with ⟨U, hU, U_idem⟩
- · refine' ⟨U, U_idem, _⟩
+ · rcases h with ⟨U, hU, U_idem⟩
+ refine' ⟨U, U_idem, _⟩
convert Set.mem_interᵢ.mp hU 0
· exact Ultrafilter.continuous_mul_left
· apply IsCompact.nonempty_interᵢ_of_sequence_nonempty_compact_closed
@@ -182,11 +182,7 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
`U`-large, so we can repeat the argument starting from `s₁`, obtaining `a₁`, `s₂`, etc.
This gives the desired infinite sequence. -/
have exists_elem : ∀ {s : Set M} (_hs : s ∈ U), (s ∩ { m | ∀ᶠ m' in U, m * m' ∈ s }).Nonempty :=
- fun {s} hs =>
- Ultrafilter.nonempty_of_mem
- (inter_mem hs <| by
- rw [← U_idem] at hs
- exact hs)
+ fun {s} hs => Ultrafilter.nonempty_of_mem (inter_mem hs <| by rwa [← U_idem] at hs)
let elem : { s // s ∈ U } → M := fun p => (exists_elem p.property).some
let succ : {s // s ∈ U} → {s // s ∈ U} := fun (p : {s // s ∈ U}) =>
⟨p.val ∩ {m : M | elem p * m ∈ p.val},
@@ -195,8 +191,7 @@ theorem exists_FP_of_large {M} [Semigroup M] (U : Ultrafilter M) (U_idem : U * U
p.val.inter_subset_right {m : M | ∀ᶠ (m' : M) in ↑U, m * m' ∈ p.val}
(exists_elem p.property).some_mem)⟩
use Stream'.corec elem succ (Subtype.mk s₀ sU)
- suffices ∀ (a : Stream' M), ∀ m ∈ FP a, ∀ p, a = Stream'.corec elem succ p → m ∈ p.val
- by
+ suffices ∀ (a : Stream' M), ∀ m ∈ FP a, ∀ p, a = Stream'.corec elem succ p → m ∈ p.val by
intro m hm
exact this _ m hm ⟨s₀, sU⟩ rfl
clear sU s₀
@@ -250,7 +245,8 @@ set_option linter.uppercaseLean3 false in
@[to_additive FS_iter_tail_sub_FS]
theorem FP_drop_subset_FP {M} [Semigroup M] (a : Stream' M) (n : ℕ) : FP (a.drop n) ⊆ FP a := by
- induction' n with n ih; · rfl
+ induction' n with n ih
+ · rfl
rw [Nat.succ_eq_one_add, ← Stream'.drop_drop]
exact _root_.trans (FP.tail _) ih
set_option linter.uppercaseLean3 false in
congr!
and convert
(#2606)
congr!
, convert
, and convert_to
to control parts of the congruence algorithm, in particular transparency settings when applying congruence lemmas.congr!
now applies congruence lemmas with reducible transparency by default. This prevents it from unfolding definitions when applying congruence lemmas. It also now tries both the LHS-biased and RHS-biased simp congruence lemmas, with a configuration option to set which it should try first.HEq
congruence lemma generator that gives each hypothesis access to the proofs of previous hypotheses. This means that if you have an equality ⊢ ⟨a, x⟩ = ⟨b, y⟩
of sigma types, congr!
turns this into goals ⊢ a = b
and ⊢ a = b → HEq x y
(note that congr!
will also auto-introduce a = b
for you in the second goal). This congruence lemma generator applies to more cases than the simp congruence lemma generator does.congr!
(and hence convert
) are more careful about applying lemmas that don't force definitions to unfold. There were a number of cases in mathlib where the implementation of congr
was being abused to unfold definitions.set_option trace.congr! true
you can see what congr!
sees when it is deciding on congruence lemmas.convert_to
to do using 1
when there is no using
clause, to match its documentation.Note that congr!
is more capable than congr
at finding a way to equate left-hand sides and right-hand sides, so you will frequently need to limit its depth with a using
clause. However, there is also a new heuristic to prevent considering unlikely-to-be-provable type equalities (controlled by the typeEqs
option), which can help limit the depth automatically.
There is also a predefined configuration that you can invoke with, for example, convert (config := .unfoldSameFun) h
, that causes it to behave more like congr
, including using default transparency when unfolding.
@@ -276,6 +276,8 @@ theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
rw [← Stream'.head_drop]
apply FP.cons
rcases le_iff_exists_add.mp (Nat.succ_le_of_lt ij) with ⟨d, hd⟩
+ -- Porting note: need to fix breakage of Set notation
+ change _ ∈ FP _
have := FP.singleton (a.drop i).tail d
rw [Stream'.tail_eq_drop, Stream'.nth_drop, Stream'.nth_drop] at this
convert this
The unported dependencies are