mathlib documentation

logic.unique

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 #

Main statements #

Implementation details #

The typeclass unique α is implemented as a type, rather than a Prop-valued predicate, for good definitional properties of the default term.

@[ext, class]
structure unique (α : Sort u) :
Sort (max 1 u)

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 of this typeclass
Instances of other typeclasses for unique
theorem unique.ext_iff {α : Sort u} (x y : unique α) :
theorem unique.ext {α : Sort u} (x y : unique α) (h : x.to_inhabited = y.to_inhabited) :
x = y
theorem unique_iff_exists_unique (α : Sort u) :
nonempty (unique α) ∃! (a : α), true
theorem unique_subtype_iff_exists_unique {α : Sort u_1} (p : α → Prop) :
nonempty (unique (subtype p)) ∃! (a : α), p a
@[reducible]
def unique_of_subsingleton {α : Sort u_1} [subsingleton α] (a : α) :

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
@[protected, instance]
Equations
@[simp]
theorem punit.default_eq_star  :
inhabited.default = punit.star
def unique_prop {p : Prop} (h : p) :

Every provable proposition is unique, as all proofs are equal.

Equations
@[protected, instance]
Equations
theorem fin.eq_zero (n : fin 1) :
n = 0
@[protected, instance]
def fin.inhabited {n : } :
Equations
@[protected, instance]
def inhabited_fin_one_add (n : ) :
inhabited (fin (1 + n))
Equations
@[simp]
@[protected, instance]
def fin.unique  :
Equations
@[protected, instance]
def unique.inhabited {α : Sort u} [unique α] :
Equations
theorem unique.eq_default {α : Sort u} [unique α] (a : α) :
theorem unique.default_eq {α : Sort u} [unique α] (a : α) :
@[protected, instance]
def unique.subsingleton {α : Sort u} [unique α] :
theorem unique.forall_iff {α : Sort u} [unique α] {p : α → Prop} :
(∀ (a : α), p a) p inhabited.default
theorem unique.exists_iff {α : Sort u} [unique α] {p : α → Prop} :
@[protected, ext]
theorem unique.subsingleton_unique' {α : Sort u} (h₁ h₂ : unique α) :
h₁ = h₂
@[protected, instance]
def unique.subsingleton_unique {α : Sort u} :
@[reducible]
def unique.mk' (α : Sort u) [h₁ : inhabited α] [subsingleton α] :

Construct unique from inhabited and subsingleton. Making this an instance would create a loop in the class inheritance graph.

Equations
@[simp]
theorem pi.default_def {α : Sort u} {β : α → Sort v} [Π (a : α), inhabited (β a)] :
theorem pi.default_apply {α : Sort u} {β : α → Sort v} [Π (a : α), inhabited (β a)] (a : α) :
@[protected, instance]
def pi.unique {α : Sort u} {β : α → Sort v} [Π (a : α), unique (β a)] :
unique (Π (a : α), β a)
Equations
@[protected, instance]
def pi.unique_of_is_empty {α : Sort u} [is_empty α] (β : α → Sort v) :
unique (Π (a : α), β a)

There is a unique function on an empty domain.

Equations
theorem eq_const_of_unique {α : Sort u} {β : Sort v} [unique α] (f : α → β) :
theorem heq_const_of_unique {α : Sort u} [unique α] {β : α → Sort v} (f : Π (a : α), β a) :
@[protected]
theorem function.injective.subsingleton {α : Sort u} {β : Sort v} {f : α → β} (hf : function.injective f) [subsingleton β] :

If the codomain of an injective function is a subsingleton, then the domain is a subsingleton as well.

@[protected]
theorem function.surjective.subsingleton {α : Sort u} {β : Sort v} {f : α → β} [subsingleton α] (hf : function.surjective f) :

If the domain of a surjective function is a subsingleton, then the codomain is a subsingleton as well.

@[protected]
def function.surjective.unique {α : Sort u} {β : Sort v} {f : α → β} (hf : function.surjective f) [unique α] :

If the domain of a surjective function is a singleton, then the codomain is a singleton as well.

Equations
@[protected]
def function.injective.unique {α : Sort u} {β : Sort v} {f : α → β} [inhabited α] [subsingleton β] (hf : function.injective f) :

If α is inhabited and admits an injective map to a subsingleton type, then α is unique.

Equations
def function.surjective.unique_of_surjective_const (α : Type u_1) {β : Type u_2} (b : β) (h : function.surjective (function.const α b)) :

If a constant function is surjective, then the codomain is a singleton.

Equations
theorem unique.bijective {A : Sort u_1} {B : Sort u_2} [unique A] [unique B] {f : A → B} :
theorem option.subsingleton_iff_is_empty {α : Type u_1} :

option α is a subsingleton if and only if α is empty.

@[protected, instance]
def option.unique {α : Type u_1} [is_empty α] :
Equations
@[protected, instance]
def unique.subtype_eq {α : Sort u} (y : α) :
unique {x // x = y}
Equations
@[protected, instance]
def unique.subtype_eq' {α : Sort u} (y : α) :
unique {x // y = x}
Equations