combinatorics.hindmanMathlib.Combinatorics.Hindman

This file has been ported!

Changes since the initial port

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.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(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)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -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
Diff
@@ -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]
Diff
@@ -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
Diff
@@ -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"
 
Diff
@@ -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
 
Diff
@@ -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]
Diff
@@ -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
Diff
@@ -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
Diff
@@ -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
Diff
@@ -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 _ _)
Diff
@@ -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
Diff
@@ -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)
Diff
@@ -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
Diff
@@ -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
 

Changes in mathlib4

mathlib3
mathlib4
chore: golf using 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.

Diff
@@ -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
chore: Remove 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.

Diff
@@ -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
style: homogenise porting notes (#11145)

Homogenises porting notes via capitalisation and addition of whitespace.

It makes the following changes:

  • converts "--porting note" into "-- Porting note";
  • converts "porting note" into "Porting note".
Diff
@@ -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
chore: classify slow / slower porting notes (#11084)

Classifies by adding issue number #11083 to porting notes claiming anything semantically equivalent to:

  • "very slow; improve performance?"
  • "quite slow; improve performance?"
  • "`tactic" was slow"
  • "removed attribute because it caused extremely slow tactic"
  • "proof was rewritten, because it was too slow"
  • "doing this make things very slow"
  • "slower implementation"
Diff
@@ -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
feat(Mathlib.Topology.Compactness.Compact): add sInter version of Cantor's intersection theorem (#10956)

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.

Open in Gitpod

Diff
@@ -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]
feat(Topology/Order): upgrade 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.

Diff
@@ -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
 
chore: remove uses of 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.

Diff
@@ -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
style: rename 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.

Diff
@@ -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]
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -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
 
chore: Rename to sSup/iSup (#3938)

As discussed on Zulip

Renames

  • 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>

Diff
@@ -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
chore: tidy various files (#2950)
Diff
@@ -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
feat: improvements to congr! and convert (#2606)
  • There is now configuration for 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.
  • There is now a new 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.
  • With set_option trace.congr! true you can see what congr! sees when it is deciding on congruence lemmas.
  • There is also a bug fix in 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.

Diff
@@ -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
feat: Port/Combinatorics.Hindman (#2280)

port of combinatorics.hindman

Co-authored-by: Johan Commelin <johan@commelin.net>

Dependencies 8 + 308

309 files ported (97.5%)
134809 lines ported (96.4%)
Show graph

The unported dependencies are