File: Mathlib/Logic/Unique.lean

full_name: Unique.uniq
code: /-- `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. -/
@[ext]
structure Unique (α : Sort u) extends Inhabited α where
  /-- In a `Unique` type, every term is equal to the default element (from `Inhabited`). -/
  uniq : ∀ a : α, a = default
goal: a = default

full_name: Unique
code: /-- `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. -/
@[ext]
structure Unique (α : Sort u) extends Inhabited α where
  /-- In a `Unique` type, every term is equal to the default element (from `Inhabited`). -/
  uniq : ∀ a : α, a = default
goal: Sort (max 1 u)

full_name: unique_iff_exists_unique
code: theorem unique_iff_exists_unique (α : Sort u) : Nonempty (Unique α) ↔ ∃! _ : α, True 
goal: Nonempty (Unique α) ↔ ∃! x, True

full_name: unique_subtype_iff_exists_unique
code: theorem unique_subtype_iff_exists_unique {α} (p : α → Prop) :
    Nonempty (Unique (Subtype p)) ↔ ∃! a, p a 
goal: Nonempty (Unique (Subtype p)) ↔ ∃! a, p a

full_name: uniqueOfSubsingleton
code: /-- 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]. -/
abbrev uniqueOfSubsingleton {α : Sort*} [Subsingleton α] (a : α) : Unique α 
goal: Unique α

full_name: PUnit.unique
code: instance PUnit.unique : Unique PUnit.{u} 
goal: Unique PUnit.{u}

full_name: PUnit.default_eq_unit
code: @[simp, nolint simpNF]
theorem PUnit.default_eq_unit : (default : PUnit) = PUnit.unit 
goal: default = PUnit.unit

full_name: uniqueProp
code: /-- Every provable proposition is unique, as all proofs are equal. -/
def uniqueProp {p : Prop} (h : p) : Unique.{0} p 
goal: Unique p

full_name: instUniqueTrue
code: instance : Unique True 
goal: Unique True

full_name: Unique.instInhabited
code: instance (priority := 100) : Inhabited α 
goal: Inhabited α

full_name: Unique.eq_default
code: theorem eq_default (a : α) : a = default 
goal: a = default

full_name: Unique.default_eq
code: theorem default_eq (a : α) : default = a 
goal: default = a

full_name: Unique.instSubsingleton
code: instance (priority := 100) instSubsingleton : Subsingleton α 
goal: Subsingleton α

full_name: Unique.forall_iff
code: theorem forall_iff {p : α → Prop} : (∀ a, p a) ↔ p default 
goal: (∀ (a : α), p a) ↔ p default

full_name: Unique.exists_iff
code: theorem exists_iff {p : α → Prop} : Exists p ↔ p default 
goal: Exists p ↔ p default

full_name: Unique.subsingleton_unique'
code: @[ext]
protected theorem subsingleton_unique' : ∀ h₁ h₂ : Unique α, h₁ = h₂
  
goal: h₁ = h₂

full_name: Unique.subsingleton_unique
code: instance subsingleton_unique : Subsingleton (Unique α) 
goal: Subsingleton (Unique α)

full_name: Unique.mk'
code: /-- Construct `Unique` from `Inhabited` and `Subsingleton`. Making this an instance would create
a loop in the class inheritance graph. -/
abbrev mk' (α : Sort u) [h₁ : Inhabited α] [Subsingleton α] : Unique α 
goal: Unique α

full_name: unique_iff_subsingleton_and_nonempty
code: theorem unique_iff_subsingleton_and_nonempty (α : Sort u) :
    Nonempty (Unique α) ↔ Subsingleton α ∧ Nonempty α 
goal: Nonempty (Unique α) ↔ Subsingleton α ∧ Nonempty α

full_name: Pi.default_def
code: @[simp]
theorem Pi.default_def {β : α → Sort v} [∀ a, Inhabited (β a)] :
    @default (∀ a, β a) _ = fun a : α ↦ @default (β a) _ 
goal: default = fun a => default

full_name: Pi.default_apply
code: theorem Pi.default_apply {β : α → Sort v} [∀ a, Inhabited (β a)] (a : α) :
    @default (∀ a, β a) _ a = default 
goal: default a = default

full_name: Pi.unique
code: instance Pi.unique {β : α → Sort v} [∀ a, Unique (β a)] : Unique (∀ a, β a) 
goal: Unique ((a : α) → β a)

full_name: Pi.uniqueOfIsEmpty
code: /-- There is a unique function on an empty domain. -/
instance Pi.uniqueOfIsEmpty [IsEmpty α] (β : α → Sort v) : Unique (∀ a, β a) 
goal: Unique ((a : α) → β a)

full_name: eq_const_of_subsingleton
code: theorem eq_const_of_subsingleton {β : Sort*} [Subsingleton α] (f : α → β) (a : α) :
    f = Function.const α (f a) 
goal: f = Function.const α (f a)

full_name: eq_const_of_unique
code: theorem eq_const_of_unique {β : Sort*} [Unique α] (f : α → β) : f = Function.const α (f default) 
goal: f = Function.const α (f default)

full_name: heq_const_of_unique
code: theorem heq_const_of_unique [Unique α] {β : α → Sort v} (f : ∀ a, β a) :
    HEq f (Function.const α (f default)) 
goal: HEq f (Function.const α (f default))

full_name: Function.Injective.subsingleton
code: /-- If the codomain of an injective function is a subsingleton, then the domain
is a subsingleton as well. -/
protected theorem Injective.subsingleton (hf : Injective f) [Subsingleton β] : Subsingleton α 
goal: Subsingleton α

full_name: Function.Surjective.subsingleton
code: /-- If the domain of a surjective function is a subsingleton, then the codomain is a subsingleton as
well. -/
protected theorem Surjective.subsingleton [Subsingleton α] (hf : Surjective f) : Subsingleton β 
goal: Subsingleton β

full_name: Function.Surjective.unique
code: /-- If the domain of a surjective function is a singleton,
then the codomain is a singleton as well. -/
protected def Surjective.unique {α : Sort u} (f : α → β) (hf : Surjective f) [Unique.{u} α] :
    Unique β 
goal: Unique β

full_name: Function.Injective.unique
code: /-- If `α` is inhabited and admits an injective map to a subsingleton type, then `α` is `Unique`. -/
protected def Injective.unique [Inhabited α] [Subsingleton β] (hf : Injective f) : Unique α 
goal: Unique α

full_name: Function.Surjective.uniqueOfSurjectiveConst
code: /-- If a constant function is surjective, then the codomain is a singleton. -/
def Surjective.uniqueOfSurjectiveConst (α : Type*) {β : Type*} (b : β)
    (h : Function.Surjective (Function.const α b)) : Unique β 
goal: Unique β

full_name: uniqueElim
code: /-- Given one value over a unique, we get a dependent function. -/
def uniqueElim [Unique ι] (x : α (default : ι)) (i : ι) : α i 
goal: α i

full_name: uniqueElim_default
code: @[simp]
theorem uniqueElim_default {_ : Unique ι} (x : α (default : ι)) : uniqueElim x (default : ι) = x 
goal: ∀ {x : Unique ι} (x_1 : α default), uniqueElim x_1 default = x_1

full_name: uniqueElim_const
code: @[simp]
theorem uniqueElim_const {β : Sort*} {_ : Unique ι} (x : β) (i : ι) :
    uniqueElim (α := fun _ ↦ β) x i = x 
goal: ∀ {x : Unique ι} (x_1 : β) (i : ι), uniqueElim x_1 i = x_1

full_name: Unique.bijective
code: theorem Unique.bijective {A B} [Unique A] [Unique B] {f : A → B} : Function.Bijective f 
goal: Function.Bijective f

full_name: Option.subsingleton_iff_isEmpty
code: /-- `Option α` is a `Subsingleton` if and only if `α` is empty. -/
theorem subsingleton_iff_isEmpty {α : Type u} : Subsingleton (Option α) ↔ IsEmpty α 
goal: Subsingleton (Option α) ↔ IsEmpty α

full_name: Option.instUniqueOfIsEmpty
code: instance {α} [IsEmpty α] : Unique (Option α) 
goal: Unique (Option α)

full_name: Unique.subtypeEq
code: instance Unique.subtypeEq (y : α) : Unique { x // x = y } 
goal: Unique { x // x = y }

full_name: Unique.subtypeEq'
code: instance Unique.subtypeEq' (y : α) : Unique { x // y = x } 
goal: Unique { x // y = x }