Zulip Chat Archive
Stream: Is there code for X?
Topic: Surjective function from Type u to some `α :Type u`
Robert Maxton (Mar 22 2025 at 03:21):
"Clearly", I claim, there must exist some surjective function from all of Type u
to any specific α : Type u
. But I'm having a bear of a time coming up with a construction. I can make it work by importing Cardinal
, though even then it's less clean than I'd like:
import Mathlib.SetTheory.Cardinal.Arithmetic
lemma exists_surj {α : Type u} [Inhabited α] : ∃ (f : Type u → α), f.Surjective := by
suffices #{ f : Type u → α | f.Surjective } ≠ 0 by
simpa [mk_eq_zero_iff]
intro h
rw [mk_surjective_eq_zero_iff_lift] at h
contrapose! h
simp only [ne_eq, mk_ne_zero, not_false_eq_true, imp_self, and_true]
suffices IsEmpty {f : α → Type u // f.Surjective} by
erw [← mk_eq_zero_iff, mk_surjective_eq_zero_iff_lift] at this
simp at this; exact le_of_lt this
rw [isEmpty_iff]
rintro ⟨f, hf⟩
exact Function.not_surjective_Type f hf
... which I'm moderately okay with, since this is fundamentally a size argument: Type u is much bigger than any specific Type u, so of course there's a surjective function. But surely there's something cleaner than this? It feels just a step away from Cantor, but it's a step I don't quite see.
Robert Maxton (Mar 22 2025 at 03:23):
I suppose it boils down to: what's the cleanest way to show that for any two sets, there exists a surjective function in at least one direction?
Matt Diamond (Mar 22 2025 at 03:36):
I wonder if docs#Function.Embedding.total could help here (by proving an injection in the reverse direction and then getting the surjection from that)
Matt Diamond (Mar 22 2025 at 03:38):
it just says "for any two types, there must be an injection going from one of them to the other"
Matt Diamond (Mar 22 2025 at 03:40):
also it sounds like you want to prove it in a specific direction, so maybe that's not so helpful...
Matt Diamond (Mar 22 2025 at 04:07):
here's one approach:
import Mathlib.SetTheory.Cardinal.SchroederBernstein
lemma exists_surj {α : Type u} [Inhabited α] : ∃ (f : Type u → α), f.Surjective := by
have h : ¬Nonempty (Type u ↪ α) := by
have : ¬∃ (g : α → Type u), g.Surjective := by
intro ⟨g, hg⟩
exact Function.not_surjective_Type g hg
simpa [Function.exists_surjective_iff]
have ⟨g, hg⟩ := (Function.Embedding.total _ _).resolve_left h
use Function.invFun g, Function.invFun_surjective hg
Robert Maxton (Mar 22 2025 at 04:24):
Oh hey. Yes, that does clean up the lemma a bunch, thanks~
Mario Carneiro (Mar 22 2025 at 13:46):
But surely there's something cleaner than this? It feels just a step away from Cantor, but it's a step I don't quite see.
I think the core theorem you want here (which does not use cardinals) is docs#Function.not_surjective_Type, used in Matt's proof above.
Mario Carneiro (Mar 22 2025 at 13:47):
and indeed it is one step away from cantor - it's literally the following theorem :grinning_face_with_smiling_eyes:
Robert Maxton (Mar 22 2025 at 19:18):
Ha! Indeed it is. But also, see my original proof, which uses it as well -- but I don't see a way to get from "no surjective (α : Type u) → Type u
" to "yes surjective Type u → (α : Type u)
" without a cardinality argument.
Matt Diamond (Mar 22 2025 at 19:23):
right, which is why I suggested docs#Function.Embedding.total ... I guess the question is whether or not that lemma relies on a cardinality argument
Robert Maxton (Mar 22 2025 at 19:24):
... Huh. Apparently not, to my surprise; it's imported by Cardinal.Basic. Alright, neat, no further remarks! :p
Last updated: May 02 2025 at 03:31 UTC