Types with a unique term #
In this file we define a typeclass unique
,
which expresses that a type has a unique term.
In other words, a type that is inhabited
and a subsingleton
.
Main declaration #
unique
: a typeclass that expresses that a type has a unique term.
Main statements #
-
unique.mk'
: an inhabited subsingleton type isunique
. This can not be an instance because it would lead to loops in typeclass inference. -
function.surjective.unique
: if the domain of a surjective function isunique
, then its codomain isunique
as well. -
function.injective.subsingleton
: if the codomain of an injective function issubsingleton
, then its domain issubsingleton
as well. -
function.injective.unique
: if the codomain of an injective function issubsingleton
and its domain isinhabited
, then its domain isunique
.
Implementation details #
The typeclass unique α
is implemented as a type,
rather than a Prop
-valued predicate,
for good definitional properties of the default term.
unique α
expresses that α
is a type with a unique term default α
.
This is implemented as a type, rather than a Prop
-valued predicate,
for good definitional properties of the default term.
Instances
- punit.unique
- true.unique
- fin.unique
- pi.unique
- pi.unique_of_is_empty
- option.unique
- unique.subtype_eq
- unique.subtype_eq'
- equiv.perm_unique
- set.unique_singleton
- units.unique
- mul_opposite.unique
- mul_equiv.unique
- add_equiv.unique
- nat.unique_units
- nat.unique_add_units
- fin.order_iso_unique
- plift.unique
- ulift.unique
- submonoid.unique
- add_submonoid.unique
- ring_equiv.unique
- quiver.path.unique
- subgroup.has_bot.bot.unique
- add_subgroup.has_bot.bot.unique
- subgroup.unique
- add_subgroup.unique
- associates.unique
- associates.unique_units
- submodule.unique_bot
- finsupp.unique_of_right
- finsupp.unique_of_left
- linear_map.unique_of_left
- linear_map.unique_of_right
- submodule.unique
- submodule.unique'
- linear_equiv.unique
Given an explicit a : α
with [subsingleton α]
, we can construct
a [unique α]
instance. This is a def because the typeclass search cannot
arbitrarily invent the a : α
term. Nevertheless, these instances are all
equivalent by unique.subsingleton.unique
.
See note [reducible non-instances].
Equations
- unique_of_subsingleton a = {to_inhabited := {default := a}, uniq := _}
Equations
- punit.unique = {to_inhabited := {default := punit.star}, uniq := punit.unique._proof_1}
Every provable proposition is unique, as all proofs are equal.
Equations
- unique_prop h = {to_inhabited := {default := h}, uniq := _}
Equations
Equations
- fin.inhabited = {default := 0}
Equations
- fin.unique = {to_inhabited := {default := default (fin 1) fin.inhabited}, uniq := fin.eq_zero}
Equations
- unique.inhabited = _inst_1.to_inhabited
Construct unique
from inhabited
and subsingleton
. Making this an instance would create
a loop in the class inheritance graph.
Equations
- unique.mk' α = {to_inhabited := {default := default α h₁}, uniq := _}
There is a unique function on an empty domain.
Equations
- pi.unique_of_is_empty β = {to_inhabited := {default := is_empty_elim (λ (a : α), β a)}, uniq := _}
If the domain of a surjective function is a singleton, then the codomain is a singleton as well.
If the codomain of an injective function is a subsingleton, then the domain is a subsingleton as well.
If α
is inhabited and admits an injective map to a subsingleton type, then α
is unique
.
Equations
- hf.unique = unique.mk' α
option α
is a subsingleton
if and only if α
is empty.
Equations
Equations
- unique.subtype_eq y = {to_inhabited := {default := ⟨y, _⟩}, uniq := _}
Equations
- unique.subtype_eq' y = {to_inhabited := {default := ⟨y, _⟩}, uniq := _}