Skip to content
Draft
1 change: 1 addition & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -7008,6 +7008,7 @@ public import Mathlib.SetTheory.Cardinal.Arithmetic
public import Mathlib.SetTheory.Cardinal.Basic
public import Mathlib.SetTheory.Cardinal.Cofinality.Basic
public import Mathlib.SetTheory.Cardinal.Cofinality.Club
public import Mathlib.SetTheory.Cardinal.Cofinality.Filter
public import Mathlib.SetTheory.Cardinal.Cofinality.Ordinal
public import Mathlib.SetTheory.Cardinal.Continuum
public import Mathlib.SetTheory.Cardinal.CountableCover
Expand Down
31 changes: 31 additions & 0 deletions Mathlib/Algebra/Ring/BooleanRing.lean
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public import Mathlib.Algebra.Group.Idempotent
public import Mathlib.Algebra.Ring.Equiv
public import Mathlib.Algebra.Ring.PUnit
public import Mathlib.Order.Hom.BoundedLattice
public import Mathlib.RingTheory.Ideal.Quotient.Defs
public import Mathlib.Tactic.Abel
public import Mathlib.Tactic.Ring

Expand Down Expand Up @@ -105,6 +106,13 @@ instance (priority := 100) toCommRing : CommRing α :=
{ (inferInstance : BooleanRing α) with
mul_comm := fun a b => by rw [← add_eq_zero', mul_add_mul] }

instance (I : Ideal α) [I.IsTwoSided] : BooleanRing (α ⧸ I) where
isIdempotentElem x := by
apply Quotient.ind
intro x
change ⟦x * x⟧ = ⟦x⟧
rw [isIdempotentElem x]

end BooleanRing

instance : BooleanRing PUnit :=
Expand Down Expand Up @@ -149,6 +157,11 @@ theorem toBoolAlg_inj {a b : α} : toBoolAlg a = toBoolAlg b ↔ a = b :=
theorem ofBoolAlg_inj {a b : AsBoolAlg α} : ofBoolAlg a = ofBoolAlg b ↔ a = b :=
Iff.rfl

/-- A recursor for `AsBoolAlg`. Use as `induction x`. -/
@[elab_as_elim, induction_eliminator, cases_eliminator]
protected def AsBoolAlg.rec {β : AsBoolAlg α → Sort*} (ind : ∀ a, β (toBoolAlg a)) :
∀ a, β a := fun a ↦ ind (ofBoolAlg a)

instance [Inhabited α] : Inhabited (AsBoolAlg α) :=
‹Inhabited α›

Expand Down Expand Up @@ -367,6 +380,11 @@ theorem toBoolRing_inj {a b : α} : toBoolRing a = toBoolRing b ↔ a = b :=
theorem ofBoolRing_inj {a b : AsBoolRing α} : ofBoolRing a = ofBoolRing b ↔ a = b :=
Iff.rfl

/-- A recursor for `AsBoolRing`. Use as `induction x`. -/
@[elab_as_elim, induction_eliminator, cases_eliminator]
protected def AsBoolRing.rec {β : AsBoolRing α → Sort*} (ind : ∀ a, β (toBoolRing a)) :
∀ a, β a := fun a ↦ ind (ofBoolRing a)

instance [Inhabited α] : Inhabited (AsBoolRing α) :=
⟨default (α := α)⟩

Expand Down Expand Up @@ -471,6 +489,19 @@ theorem toBoolRing_inf (a b : α) : toBoolRing (a ⊓ b) = toBoolRing a * toBool
theorem toBoolRing_symmDiff (a b : α) : toBoolRing (a ∆ b) = toBoolRing a + toBoolRing b :=
rfl

@[simp]
theorem toBoolRing_compl (a : α) : toBoolRing aᶜ = 1 + toBoolRing a := by
rw [← top_symmDiff, toBoolRing_symmDiff, toBoolRing_top]

@[simp]
theorem toBoolRing_sup (a b : α) :
toBoolRing (a ⊔ b) = toBoolRing a + toBoolRing b + toBoolRing a * toBoolRing b := by
rw [← symmDiff_symmDiff_inf, toBoolRing_symmDiff, toBoolRing_symmDiff, toBoolRing_inf]

@[simp]
theorem toBoolRing_sdiff (a b : α) : toBoolRing (a \ b) = toBoolRing a * (1 + toBoolRing b) := by
simp [sdiff_eq]

/-- Turn a bounded lattice homomorphism from Boolean algebras `α` to `β` into a ring homomorphism
from `α` to `β` considered as Boolean rings. -/
@[simps]
Expand Down
5 changes: 5 additions & 0 deletions Mathlib/Order/Cofinal.lean
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ theorem IsCofinal.mono {s t : Set α} (h : s ⊆ t) (hs : IsCofinal s) : IsCofin
obtain ⟨b, hb, hb'⟩ := hs a
exact ⟨b, h hb, hb'⟩

theorem IsCofinal.nonempty [Nonempty α] {s : Set α} (h : IsCofinal s) : s.Nonempty := by
inhabit α
obtain ⟨x, hx, _⟩ := h default
exact ⟨x, hx⟩

end LE

section Preorder
Expand Down
171 changes: 149 additions & 22 deletions Mathlib/SetTheory/Cardinal/Cofinality/Club.lean
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ public import Mathlib.SetTheory.Cardinal.Cofinality.Basic
/-!
# Club sets

A subset of a well-ordered type `α` is called a club set when it is closed in the order topology and
cofinal. If `α` has no maximum, then an equivalent condition is that `α` is closed and unbounded;
hence the name.
A subset of a well-ordered type `α` is called a **club set** when it is closed in the order topology
and cofinal. If `α` has no maximum, then an equivalent condition is that `α` is closed and
unbounded; hence the name.

A **stationary set** is a set which intersects all club sets.

## Implementation notes

Expand All @@ -27,7 +29,9 @@ public section

universe u v

open Cardinal Order
open Cardinal Order Set

variable {α : Type v} {s t : Set α} {x : α} [LinearOrder α]

/-- A club set is closed under suprema and cofinal. -/
structure IsClub {α : Type*} [LinearOrder α] (s : Set α) where
Expand All @@ -40,8 +44,6 @@ structure IsClub {α : Type*} [LinearOrder α] (s : Set α) where

namespace IsClub

variable {α : Type v} {s t : Set α} {x : α} [LinearOrder α]

@[simp]
theorem of_isEmpty [IsEmpty α] {s : Set α} : IsClub s :=
⟨.of_isEmpty, .of_isEmpty⟩
Expand All @@ -50,6 +52,12 @@ theorem of_isEmpty [IsEmpty α] {s : Set α} : IsClub s :=
protected theorem univ : IsClub (α := α) .univ :=
⟨.univ, .univ⟩

protected theorem nonempty [Nonempty α] (hs : IsClub s) : s.Nonempty :=
hs.isCofinal.nonempty

theorem _root_.isClub_empty_iff : IsClub (α := α) ∅ ↔ IsEmpty α :=
⟨fun h ↦ isCofinal_empty_iff.1 h.isCofinal, fun _ ↦ .of_isEmpty⟩

protected theorem union (hs : IsClub s) (ht : IsClub t) : IsClub (s ∪ t) :=
⟨hs.dirSupClosed.union ht.dirSupClosed, hs.isCofinal.mono Set.subset_union_left⟩

Expand All @@ -63,12 +71,12 @@ theorem csSup_mem {α} [ConditionallyCompleteLinearOrder α] {s t : Set α}
theorem sInter_of_orderTop {s : Set (Set α)} [OrderTop α] (hs : ∀ x ∈ s, IsClub x) :
IsClub (⋂₀ s) := by
refine ⟨.sInter fun x hx ↦ (hs x hx).dirSupClosed, ?_⟩
rw [isCofinal_iff_top_mem, Set.mem_sInter]
rw [isCofinal_iff_top_mem, mem_sInter]
exact fun x hx ↦ (hs x hx).isCofinal.top_mem

theorem iInter_of_orderTop {ι : Type*} {f : ι → Set α} [OrderTop α] (hs : ∀ i, IsClub (f i)) :
IsClub (⋂ i, f i) := by
rw [← Set.sInter_range]
rw [← sInter_range]
exact .sInter_of_orderTop (by simpa)

theorem sInter_of_cof_le_one {s : Set (Set α)} (hα : cof α ≤ 1) (hs : ∀ x ∈ s, IsClub x) :
Expand All @@ -80,11 +88,10 @@ theorem sInter_of_cof_le_one {s : Set (Set α)} (hα : cof α ≤ 1) (hs : ∀ x

theorem iInter_of_cof_le_one {ι : Type*} {f : ι → Set α} (hα : cof α ≤ 1) (hs : ∀ i, IsClub (f i)) :
IsClub (⋂ i, f i) := by
rw [← Set.sInter_range]
rw [← sInter_range]
exact .sInter_of_cof_le_one hα (by simpa)

section WellFoundedLT

variable [WellFoundedLT α]

attribute [local instance]
Expand All @@ -102,7 +109,7 @@ protected theorem sInter {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : #s
refine .of_not_isCofinal fun hg ↦ (cof_le hg).not_gt (hα.trans_le' ?_)
simpa using mk_range_le_lift (f := g)
refine ⟨_, fun t ht ↦ ?_, le_csSup hg ⟨0, rfl⟩⟩
apply (hs t ht).isLUB_mem (t := .range fun n ↦ f ⟨t, ht⟩ (g n)) _ (Set.range_nonempty _)
apply (hs t ht).isLUB_mem (t := .range fun n ↦ f ⟨t, ht⟩ (g n)) _ (range_nonempty _)
· refine ⟨?_, fun b hb ↦ csSup_le' ?_⟩ <;> rintro _ ⟨n, rfl⟩
· apply (le_csSup (.of_not_isCofinal _) _).trans (le_csSup hg ⟨n + 1, rfl⟩)
· exact fun hg' ↦ (cof_le hg').not_gt (mk_range_le.trans_lt hsα)
Expand All @@ -113,28 +120,36 @@ protected theorem sInter {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : #s
protected theorem iInter {ι : Type u} {f : ι → Set α} (hα : cof α ≠ ℵ₀)
(hι : Cardinal.lift.{v} #ι < Cardinal.lift.{u} (cof α)) (hf : ∀ i, IsClub (f i)) :
IsClub (⋂ i, f i) := by
rw [← Set.sInter_range]
rw [← sInter_range]
refine IsClub.sInter hα ?_ (by simpa)
rw [← Cardinal.lift_lt]
exact mk_range_le_lift.trans_lt hι

protected theorem inter {s t : Set α} (hα : cof α ≠ ℵ₀) (hs : IsClub s) (ht : IsClub t) :
IsClub (s ∩ t) := by
rw [← Set.sInter_pair]
have H : ∀ x ∈ ({s, t} : Set _), IsClub x := by simpa [hs]
obtain hα | hα' := hα.lt_or_gt
· rw [cof_lt_aleph0_iff] at hα
exact .sInter_of_cof_le_one hα H
· exact .sInter hα (hα'.trans_le' <| by simp) H
theorem sInter_of_countable {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : s.Countable)
(hs : ∀ x ∈ s, IsClub x) : IsClub (⋂₀ s) := by
obtain hα | hα := hα.lt_or_gt
· apply IsClub.sInter_of_cof_le_one _ hs
rwa [← cof_lt_aleph0_iff]
· apply IsClub.sInter hα.ne' (hα.trans_le' _) hs
rwa [le_aleph0_iff_set_countable]

theorem iInter_of_countable {ι : Type*} {f : ι → Set α} [Countable ι] (hα : cof α ≠ ℵ₀)
(hf : ∀ i, IsClub (f i)) : IsClub (⋂ i, f i) := by
rw [← sInter_range]
apply IsClub.sInter_of_countable hα (countable_range f)
simpa

theorem _root_.Order.IsNormal.isClub_range {f : α → α} (hf : IsNormal f) : IsClub (.range f) :=
protected theorem inter (hα : cof α ≠ ℵ₀) (hs : IsClub s) (ht : IsClub t) : IsClub (s ∩ t) := by
simpa [hs, ht] using IsClub.sInter_of_countable (s := {s, t}) hα

theorem Order.IsNormal.isClub_range {f : α → α} (hf : IsNormal f) : IsClub (.range f) :=
⟨hf.dirSupClosed_range, fun x ↦ ⟨_, ⟨x, rfl⟩, hf.strictMono.le_apply⟩⟩

theorem _root_.Order.IsNormal.isClub_fixedPoints {f : α → α} (hα : cof α ≠ ℵ₀) (hf : IsNormal f) :
IsClub f.fixedPoints := by
cases isEmpty_or_nonempty α; · simp
refine ⟨fun s hs hs₀ _ a ha ↦ (hf.map_isLUB ha hs₀).unique ?_, fun a ↦ ?_⟩
· rwa [Set.image_congr hs, Set.image_id']
· rwa [image_congr hs, image_id']
· cases topOrderOrNoTopOrder α with
| inl => use ⊤; simpa using hf.strictMono.id_le ⊤
| inr h =>
Expand All @@ -147,3 +162,115 @@ theorem _root_.Order.IsNormal.isClub_fixedPoints {f : α → α} (hα : cof α

end WellFoundedLT
end IsClub

/-! ### Stationary sets -/

/-- A set is called stationary when it intersects all club sets. -/
@[expose]
def IsStationary (s : Set α) : Prop :=
∀ ⦃t⦄, IsClub t → (s ∩ t).Nonempty

theorem not_isStationary_iff : ¬ IsStationary s ↔ ∃ t, IsClub t ∧ Disjoint s t := by
simp [IsStationary, disjoint_iff, not_nonempty_iff_eq_empty]

@[gcongr]
theorem IsStationary.mono (hs : IsStationary s) (h : s ⊆ t) : IsStationary t :=
fun _u hu ↦ (hs hu).mono (inter_subset_inter_left _ h)

theorem IsStationary.nonempty (hs : IsStationary s) : s.Nonempty := by
simpa using hs .univ

theorem isStationary_univ_iff : IsStationary (.univ (α := α)) ↔ Nonempty α := by
simp [IsStationary, ← not_imp_not (b := IsClub _), not_nonempty_iff_eq_empty,
isClub_empty_iff]

@[simp]
protected theorem IsStationary.univ [Nonempty α] : IsStationary (.univ (α := α)) :=
isStationary_univ_iff.2 ‹_›

@[simp]
theorem not_isStationary_empty : ¬ IsStationary (∅ : Set α) := by
intro h
simpa using h .univ

@[simp]
theorem not_isStationary_of_isEmpty [IsEmpty α] : ¬ IsStationary s :=
s.eq_empty_of_isEmpty ▸ not_isStationary_empty

theorem IsStationary.of_not_isCofinal_compl (hs : ¬ IsCofinal sᶜ) : IsStationary s := by
intro t ht
obtain ⟨a, ha⟩ := not_isCofinal_iff.1 hs
obtain ⟨b, hb, hb'⟩ := ht.isCofinal a
refine ⟨b, ?_, hb⟩
contrapose! ha
exact ⟨b, ha, hb'⟩

theorem isStationary_sUnion_iff_of_cof_le_one {s : Set (Set α)} (hα : cof α ≤ 1) :
IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x where
mp h := by
contrapose! h
simp_rw [not_isStationary_iff] at h ⊢
choose f hf hxf using h
refine ⟨⋂ x : s, f _ x.2, ?_, ?_⟩
· apply IsClub.iInter_of_cof_le_one hα
simpa
· rw [disjoint_sUnion_left]
exact fun x hx ↦ (hxf _ hx).mono_right (iInter_subset _ ⟨x, hx⟩)
mpr := fun ⟨x, hxs, hx⟩ ↦ hx.mono (subset_sUnion_of_mem hxs)

theorem isStationary_iUnion_iff_of_cof_le_one {ι : Type u} {f : ι → Set α} (hα : cof α ≤ 1) :
IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := by
rw [← sUnion_range, isStationary_sUnion_iff_of_cof_le_one hα]
simp

theorem isStationary_sUnion_iff_of_orderTop [OrderTop α] {s : Set (Set α)} :
IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x :=
isStationary_sUnion_iff_of_cof_le_one (by simp)

theorem isStationary_iUnion_iff_of_orderTop [OrderTop α] {ι : Type u} {f : ι → Set α} :
IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) :=
isStationary_iUnion_iff_of_cof_le_one (by simp)

section WellFoundedLT
variable [WellFoundedLT α]

theorem IsClub.isStationary [Nonempty α] (hα : cof α ≠ ℵ₀) (hs : IsClub s) : IsStationary s :=
fun _ ht ↦ (hs.inter hα ht).nonempty

theorem isStationary_sUnion_iff {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : #s < cof α) :
IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x where
mp h := by
contrapose! h
simp_rw [not_isStationary_iff] at h ⊢
choose f hf hxf using h
refine ⟨⋂ x : s, f _ x.2, ?_, ?_⟩
· apply IsClub.iInter hα <;> simpa
· rw [disjoint_sUnion_left]
exact fun x hx ↦ (hxf _ hx).mono_right (iInter_subset _ ⟨x, hx⟩)
mpr := fun ⟨x, hxs, hx⟩ ↦ hx.mono (subset_sUnion_of_mem hxs)

theorem isStationary_iUnion_iff {ι : Type u} {f : ι → Set α} (hα : cof α ≠ ℵ₀)
(hι : lift.{v} #ι < lift.{u} (cof α)) : IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := by
rw [← sUnion_range, isStationary_sUnion_iff hα]
· simp
· rw [← Cardinal.lift_lt]
exact mk_range_le_lift.trans_lt hι

theorem isStationary_sUnion_iff_of_countable {s : Set (Set α)} (hα : cof α ≠ ℵ₀)
(hsα : s.Countable) : IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x := by
obtain hα | hα := hα.lt_or_gt
· apply isStationary_sUnion_iff_of_cof_le_one
rwa [← cof_lt_aleph0_iff]
· apply isStationary_sUnion_iff hα.ne' (hα.trans_le' _)
rwa [le_aleph0_iff_set_countable]

theorem isStationary_iUnion_iff_of_countable {ι : Type*} {f : ι → Set α} [Countable ι]
(hα : cof α ≠ ℵ₀) : IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := by
rw [← sUnion_range, isStationary_sUnion_iff_of_countable hα (countable_range f)]
simp

theorem isStationary_union_iff (hα : cof α ≠ ℵ₀) :
IsStationary (s ∪ t) ↔ IsStationary s ∨ IsStationary t := by
simpa using isStationary_sUnion_iff_of_countable (s := {s, t}) hα

end WellFoundedLT
Loading
Loading