Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(data/countable): add
countable
typeclass (#15280)
Also add a few new operations on `equiv`s.
- Loading branch information
Showing
3 changed files
with
237 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/- | ||
Copyright (c) 2022 Yury Kudryashov. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Yury Kudryashov | ||
-/ | ||
import logic.equiv.nat | ||
import logic.equiv.fin | ||
import data.countable.defs | ||
|
||
/-! | ||
# Countable types | ||
In this file we provide basis instances of the `countable` typeclass defined elsewhere. | ||
-/ | ||
|
||
universes u v w | ||
|
||
open function | ||
|
||
instance : countable ℤ := countable.of_equiv ℕ equiv.int_equiv_nat.symm | ||
|
||
/-! | ||
### Definition in terms of `function.embedding` | ||
-/ | ||
|
||
section embedding | ||
|
||
variables {α : Sort u} {β : Sort v} | ||
|
||
lemma countable_iff_nonempty_embedding : countable α ↔ nonempty (α ↪ ℕ) := | ||
⟨λ ⟨⟨f, hf⟩⟩, ⟨⟨f, hf⟩⟩, λ ⟨f⟩, ⟨⟨f, f.2⟩⟩⟩ | ||
|
||
lemma nonempty_embedding_nat (α) [countable α] : nonempty (α ↪ ℕ) := | ||
countable_iff_nonempty_embedding.1 ‹_› | ||
|
||
protected lemma function.embedding.countable [countable β] (f : α ↪ β) : countable α := | ||
f.injective.countable | ||
|
||
end embedding | ||
|
||
/-! | ||
### Operations on `Type*`s | ||
-/ | ||
|
||
section type | ||
|
||
variables {α : Type u} {β : Type v} {π : α → Type w} | ||
|
||
instance [countable α] [countable β] : countable (α ⊕ β) := | ||
begin | ||
rcases exists_injective_nat α with ⟨f, hf⟩, | ||
rcases exists_injective_nat β with ⟨g, hg⟩, | ||
exact (equiv.nat_sum_nat_equiv_nat.injective.comp $ hf.sum_map hg).countable | ||
end | ||
|
||
instance [countable α] : countable (option α) := | ||
countable.of_equiv _ (equiv.option_equiv_sum_punit α).symm | ||
|
||
instance [countable α] [countable β] : countable (α × β) := | ||
begin | ||
rcases exists_injective_nat α with ⟨f, hf⟩, | ||
rcases exists_injective_nat β with ⟨g, hg⟩, | ||
exact (equiv.nat_prod_nat_equiv_nat.injective.comp $ hf.prod_map hg).countable | ||
end | ||
|
||
instance [countable α] [Π a, countable (π a)] : countable (sigma π) := | ||
begin | ||
rcases exists_injective_nat α with ⟨f, hf⟩, | ||
choose g hg using λ a, exists_injective_nat (π a), | ||
exact ((equiv.sigma_equiv_prod ℕ ℕ).injective.comp $ hf.sigma_map hg).countable | ||
end | ||
|
||
end type | ||
|
||
section sort | ||
|
||
variables {α : Sort u} {β : Sort v} {π : α → Sort w} | ||
|
||
/-! | ||
### Operations on and `Sort*`s | ||
-/ | ||
|
||
@[priority 500] | ||
instance set_coe.countable {α} [countable α] (s : set α) : countable s := subtype.countable | ||
|
||
instance [countable α] [countable β] : countable (psum α β) := | ||
countable.of_equiv (plift α ⊕ plift β) (equiv.plift.sum_psum equiv.plift) | ||
|
||
instance [countable α] [countable β] : countable (pprod α β) := | ||
countable.of_equiv (plift α × plift β) (equiv.plift.prod_pprod equiv.plift) | ||
|
||
instance [countable α] [Π a, countable (π a)] : countable (psigma π) := | ||
countable.of_equiv (Σ a : plift α, plift (π a.down)) (equiv.psigma_equiv_sigma_plift π).symm | ||
|
||
instance [finite α] [Π a, countable (π a)] : countable (Π a, π a) := | ||
begin | ||
haveI : ∀ n, countable (fin n → ℕ), | ||
{ intro n, induction n with n ihn, | ||
{ apply_instance }, | ||
{ exactI countable.of_equiv _ (equiv.pi_fin_succ _ _).symm } }, | ||
rcases finite.exists_equiv_fin α with ⟨n, ⟨e⟩⟩, | ||
have f := λ a, (nonempty_embedding_nat (π a)).some, | ||
exact ((embedding.Pi_congr_right f).trans (equiv.Pi_congr_left' _ e).to_embedding).countable | ||
end | ||
|
||
end sort |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/- | ||
Copyright (c) 2022 Yury Kudryashov. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Yury Kudryashov | ||
-/ | ||
import data.finite.defs | ||
|
||
/-! | ||
# Countable types | ||
In this file we define a typeclass saying that a given `Sort*` is countable. See also `encodable` | ||
for a version that singles out a specific encoding of elements of `α` by natural numbers. | ||
This file also provides a few instances of this typeclass. More instances can be found in other | ||
files. | ||
-/ | ||
|
||
open function | ||
universes u v | ||
variables {α : Sort u} {β : Sort v} | ||
|
||
/-! | ||
### Definition and basic properties | ||
-/ | ||
|
||
/-- A type `α` is countable if there exists an injective map `α → ℕ`. -/ | ||
@[mk_iff countable_iff_exists_injective] class countable (α : Sort u) : Prop := | ||
(exists_injective_nat [] : ∃ f : α → ℕ, injective f) | ||
|
||
instance : countable ℕ := ⟨⟨id, injective_id⟩⟩ | ||
|
||
export countable (exists_injective_nat) | ||
|
||
protected lemma function.injective.countable [countable β] {f : α → β} (hf : injective f) : | ||
countable α := | ||
let ⟨g, hg⟩ := exists_injective_nat β in ⟨⟨g ∘ f, hg.comp hf⟩⟩ | ||
|
||
protected lemma function.surjective.countable [countable α] {f : α → β} (hf : surjective f) : | ||
countable β := | ||
(injective_surj_inv hf).countable | ||
|
||
lemma exists_surjective_nat (α : Sort u) [nonempty α] [countable α] : ∃ f : ℕ → α, surjective f := | ||
let ⟨f, hf⟩ := exists_injective_nat α in ⟨inv_fun f, inv_fun_surjective hf⟩ | ||
|
||
lemma countable_iff_exists_surjective [nonempty α] : countable α ↔ ∃ f : ℕ → α, surjective f := | ||
⟨@exists_surjective_nat _ _, λ ⟨f, hf⟩, hf.countable⟩ | ||
|
||
lemma countable.of_equiv (α : Sort*) [countable α] (e : α ≃ β) : countable β := | ||
e.symm.injective.countable | ||
|
||
lemma equiv.countable_iff (e : α ≃ β) : countable α ↔ countable β := | ||
⟨λ h, @countable.of_equiv _ _ h e, λ h, @countable.of_equiv _ _ h e.symm⟩ | ||
|
||
instance {β : Type v} [countable β] : countable (ulift.{u} β) := | ||
countable.of_equiv _ equiv.ulift.symm | ||
|
||
/-! | ||
### Operations on `Sort*`s | ||
-/ | ||
|
||
instance [countable α] : countable (plift α) := equiv.plift.injective.countable | ||
|
||
@[priority 100] | ||
instance subsingleton.to_countable [subsingleton α] : countable α := | ||
⟨⟨λ _, 0, λ x y h, subsingleton.elim x y⟩⟩ | ||
|
||
@[priority 500] | ||
instance [countable α] {p : α → Prop} : countable {x // p x} := subtype.val_injective.countable | ||
|
||
instance {n : ℕ} : countable (fin n) := subtype.countable | ||
|
||
@[priority 100] | ||
instance finite.to_countable [finite α] : countable α := | ||
let ⟨n, ⟨e⟩⟩ := finite.exists_equiv_fin α in countable.of_equiv _ e.symm | ||
|
||
instance : countable punit.{u} := subsingleton.to_countable | ||
|
||
@[nolint instance_priority] | ||
instance Prop.countable (p : Prop) : countable p := subsingleton.to_countable | ||
|
||
instance bool.countable : countable bool := | ||
⟨⟨λ b, cond b 0 1, bool.injective_iff.2 nat.one_ne_zero⟩⟩ | ||
|
||
instance Prop.countable' : countable Prop := countable.of_equiv bool equiv.Prop_equiv_bool.symm | ||
|
||
@[priority 500] instance [countable α] {r : α → α → Prop} : countable (quot r) := | ||
(surjective_quot_mk r).countable | ||
|
||
@[priority 500] instance [countable α] {s : setoid α} : countable (quotient s) := quot.countable |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters