Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Mathlib/Analysis/Real/Cardinality.lean
Original file line number Diff line number Diff line change
Expand Up @@ -268,23 +268,23 @@ lemma Real.Ioo_countable_iff {x y : ℝ} :
(Ioo x y).Countable ↔ y ≤ x := by
refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩
contrapose! h
rw [← Cardinal.le_aleph0_iff_set_countable, Cardinal.mk_Ioo_real h, not_le]
rw [← Cardinal.aleph0_lt_iff_set_uncountable, Cardinal.mk_Ioo_real h]
exact Cardinal.aleph0_lt_continuum

@[simp]
lemma Real.Ico_countable_iff {x y : ℝ} :
(Ico x y).Countable ↔ y ≤ x := by
refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩
contrapose! h
rw [← Cardinal.le_aleph0_iff_set_countable, Cardinal.mk_Ico_real h, not_le]
rw [← Cardinal.aleph0_lt_iff_set_uncountable, Cardinal.mk_Ico_real h]
exact Cardinal.aleph0_lt_continuum

@[simp]
lemma Real.Ioc_countable_iff {x y : ℝ} :
(Ioc x y).Countable ↔ y ≤ x := by
refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩
contrapose! h
rw [← Cardinal.le_aleph0_iff_set_countable, Cardinal.mk_Ioc_real h, not_le]
rw [← Cardinal.aleph0_lt_iff_set_uncountable, Cardinal.mk_Ioc_real h]
exact Cardinal.aleph0_lt_continuum

@[simp]
Expand All @@ -295,7 +295,7 @@ lemma Real.Icc_countable_iff {x y : ℝ} :
· simp [heq]
· simp [hlt]⟩
contrapose! h
rw [← Cardinal.le_aleph0_iff_set_countable, Cardinal.mk_Icc_real h, not_le]
rw [← Cardinal.aleph0_lt_iff_set_uncountable, Cardinal.mk_Icc_real h]
exact Cardinal.aleph0_lt_continuum

end Cardinal
73 changes: 73 additions & 0 deletions Mathlib/Data/Set/Countable.lean
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,76 @@ end Set

theorem Finset.countable_toSet (s : Finset α) : Set.Countable (↑s : Set α) :=
s.finite_toSet.countable

namespace Set

/-- A set is uncountable if it is not countable.

This is protected so that it does not conflict with global `Uncountable`. -/
protected def Uncountable (s : Set α) : Prop :=
¬s.Countable
Comment on lines +339 to +340
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question which arose in a discussion about the simp-question below is whether it is really sensible to add such a definition.

[...] we already have a nice phrasing as ¬s.Countable, I am not convinced it is useful, because it will force us to introduce quite a lot of API for a gain I don't really see.

and

[...] If the concept is really used a lot, and in particular makes it possible to have several lemmas expressed with dot notation, then we should definitely have it. If it's less used, it's less obvious we should have it. For Infinite, it's a natural assumption in many many lemmas so we should definitely have it. For Uncountable, I don't know. [...]

Is there some more motivation you could provide besides the analogy to Infinite?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides analogy, I find I need the result of "removing a countable set from an uncountable set is still countable" (Set.Uncountable.diff) and "any uncountable set is non-empty" (Set.Uncountable.nonempty) in #34246. If I represent this as ¬s.Countable, I can definitely use Set.Countable.of_diff for the former but the latter is not quite easy (grind may help I guess). These are exactly "several lemmas expressed with dot notation" in my feeling.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though I agree that "uncountable sets" do not occur in a lot of lemmas. In fact I would likely generalize #34246 to any regular cardinal so this PR may become unnecessary then.

Copy link
Copy Markdown
Collaborator Author

@staroperator staroperator Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing I'd like to point out is that besides ¬s.Countable, another way to write "a set is uncountable" is Uncountable s (where s is coerced to a type). They are of course equivalent via Set.countable_coe_iff and not_countable_iff, but I don't think there is one representation that is more canonical than another (while Set.Uncountable would definitely be the most canonical way to say it).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I have generalized #34246, so I don't need this PR now. Still, it doesn't harm to introduce such a shortcut.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm somewhat unsure as to why we even have an Uncountable predicate. I don't believe there's many useful theorems to be stated about it other than ℵ₁ ≤ #α? And considering you were able to generalize your use of it, I think that signals we don't need this either.

Copy link
Copy Markdown
Collaborator Author

@staroperator staroperator Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm somewhat unsure as to why we even have an Uncountable predicate. I don't believe there's many useful theorems to be stated about it other than ℵ₁ ≤ #α? And considering you were able to generalize your use of it, I think that signals we don't need this either.

I guess Uncountable exists because it's a typeclass. That's useful because instance synthesis automates proof that some complicate type is actually uncountable.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's only three dozen theorems about uncountable, and most are just boilerplate conversions. I don't think anyone would miss this typeclass if it were gone.


@[simp, push]
theorem not_countable_iff_uncountable {s : Set α} : ¬s.Countable ↔ s.Uncountable := .rfl

@[simp, push]
theorem not_uncountable_iff_countable {s : Set α} : ¬s.Uncountable ↔ s.Countable :=
not_not

alias ⟨_, Countable.not_uncountable⟩ := not_uncountable_iff_countable

@[simp] lemma Uncountable.not_countable {s : Set α} (hs : s.Uncountable) : ¬ s.Countable := hs

attribute [simp] Countable.not_uncountable

theorem uncountable_coe_iff {s : Set α} : Uncountable s ↔ s.Uncountable :=
not_countable_iff.symm.trans countable_coe_iff.not

alias ⟨_root_.Uncountable.to_set, Uncountable.to_subtype⟩ := uncountable_coe_iff

theorem uncountable_univ_iff : (@univ α).Uncountable ↔ Uncountable α := by
rw [Set.Uncountable, countable_univ_iff, not_countable_iff]

theorem uncountable_univ [h : Uncountable α] : (@univ α).Uncountable :=
uncountable_univ_iff.2 h

protected lemma Uncountable.mono {s t : Set α} (h : s ⊆ t) : s.Uncountable → t.Uncountable :=
mt (·.mono h)

theorem uncountable_of_countable_compl [Uncountable α] {s : Set α} (hs : sᶜ.Countable) :
s.Uncountable := fun h =>
Set.uncountable_univ (α := α) (by simpa using hs.union h)

theorem Countable.uncountable_compl [Uncountable α] {s : Set α} (hs : s.Countable) :
sᶜ.Uncountable := fun h =>
Set.uncountable_univ (α := α) (by simpa using hs.union h)

theorem Uncountable.diff {s t : Set α} (hs : s.Uncountable) (ht : t.Countable) :
(s \ t).Uncountable := fun h =>
hs <| h.of_diff ht

@[simp]
theorem uncountable_union {s t : Set α} : (s ∪ t).Uncountable ↔ s.Uncountable ∨ t.Uncountable := by
simp only [Set.Uncountable, countable_union, not_and_or]

theorem Uncountable.of_image (f : α → β) {s : Set α} (hs : (f '' s).Uncountable) : s.Uncountable :=
mt (Countable.image · f) hs

theorem Uncountable.image {s : Set α} {f : α → β} (hs : s.Uncountable) (hi : InjOn f s) :
(f '' s).Uncountable :=
mt (countable_of_injective_of_countable_image hi) hs

theorem Uncountable.range [Uncountable α] {f : α → β} (hi : Injective f) :
(range f).Uncountable := by
simpa using uncountable_univ.image (hi.injOn (s := Set.univ))

theorem Uncountable.infinite {s : Set α} (hs : s.Uncountable) : s.Infinite :=
mt Finite.countable hs

theorem Uncountable.nonempty {s : Set α} (hs : s.Uncountable) : s.Nonempty :=
hs.infinite.nonempty

theorem Uncountable.nontrivial {s : Set α} (hs : s.Uncountable) : s.Nontrivial :=
hs.infinite.nontrivial

end Set
5 changes: 5 additions & 0 deletions Mathlib/SetTheory/Cardinal/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,11 @@ theorem aleph0_lt_mk_iff : ℵ₀ < #α ↔ Uncountable α := by
theorem aleph0_lt_mk [Uncountable α] : ℵ₀ < #α :=
aleph0_lt_mk_iff.mpr ‹_›

theorem aleph0_lt_iff_set_uncountable {s : Set α} : ℵ₀ < #s ↔ s.Uncountable :=
aleph0_lt_mk_iff.trans uncountable_coe_iff

alias ⟨_, _root_.Set.Uncountable.aleph0_lt⟩ := aleph0_lt_iff_set_uncountable

instance canLiftCardinalNat : CanLift Cardinal ℕ (↑) fun x => x < ℵ₀ :=
⟨fun _ hx =>
let ⟨n, hn⟩ := lt_aleph0.mp hx
Expand Down
Loading