What is an ordered pair, really?
In set theory an ordered pair is often defined as (Kuratowski, 1921). Norbert Wiener had proposed a different definition in 1914, and one could invent many more. No working mathematician cares which is used. What matters is one property: from a pair you can recover its first and second entries, and any two entries make exactly one pair.
The same happens across mathematics. The integers can be built from pairs of natural numbers, the rationals from pairs of integers, the real numbers from Dedekind cuts or from Cauchy sequences. The constructions differ; the objects behave identically. A universal property says precisely what behaviour we care about, in terms of maps to or from the object — and then proves that this behaviour determines the object up to a unique isomorphism. You met the first example in products by maps; this lesson develops the idea across categories.
The best solution to a problem
A universal property usually describes the most efficient solution to some problem, measured against all other solutions.
- Problem: an object with a map to and a map to . Best solution: the product — every other solution (with , ) maps to it in exactly one compatible way.
- Problem: a monoid containing the letters of an alphabet . Best solution: the monoid of words in — it satisfies no equations except those forced by the monoid axioms, so it maps to every other solution in exactly one compatible way.
- Problem: a map out of a set that makes equivalent elements equal. Best solution: the quotient , through which every other solution factors uniquely.
"Exactly one" packs two demands: existence (there is a compatible map) and uniqueness (there is only one). The second is easy to forget and is what makes the theory work.
Definitions
Definition— product
Let be objects of a category . A product of and is an object with morphisms and (the projections) such that for every object and every pair , there is exactly one with and . We write .
Reversing all arrows gives a coproduct: an object with , such that every pair , factors as , for exactly one . In the coproduct is the disjoint union.
Definition— initial and terminal objects
An object is initial if for every object there is exactly one morphism , and terminal if for every there is exactly one morphism .
In the empty set is initial and every one-element set is terminal; in the trivial group is both; in the ring is initial (there is exactly one ring homomorphism , determined by ).
The general shape covering free objects, quotients and many others is the following, where is a functor (often a forgetful functor).
Definition— universal arrow
A universal arrow from an object of to a functor is an object of together with a morphism of such that for every object of and every morphism there is exactly one morphism of with .
Definition— free monoid
Let be the forgetful functor. A free monoid on a set is a universal arrow from to : a monoid with a function such that every function into a monoid factors as for exactly one monoid homomorphism .
Note
A universal arrow is the same as an initial object of the category whose objects are pairs with , and whose morphisms are the with . (This is a comma category, written .) Products are likewise terminal objects of a category of "cones" over and . So every universal property in this lesson says that some object is initial or terminal in a suitable category.
Examples
Example— Products
- In : the cartesian product with the coordinate projections; .
- In : the direct product with coordinatewise multiplication.
- In : with the product topology (generated by the sets with open).
- In : ; in this category it is also the coproduct.
- In a poset regarded as a category, a product of and is an element such that every has : the greatest lower bound (meet) . In the subsets of a set it is ; for the positive integers ordered by divisibility it is ; in the poset of propositions ordered by entailment it is " and ".
- Products need not exist. In the poset with two incomparable elements (and nothing else), and have no lower bound at all, hence no product. In the category of fields the product of and does not exist (Theorem 5).
Example— Quotients
If is an equivalence relation on a set , the quotient set of equivalence classes comes with , . For a normal subgroup of a group , the quotient group comes with the homomorphism . Both are universal among maps that "kill" the relation (Theorem 3). For instance is universal among homomorphisms out of that vanish on — the Remainder families trail explores these classes.
Example— Free objects
- Free monoid: words in under concatenation (Theorem 4). On one letter it is .
- Free group: reduced words in the letters and their formal inverses (no or adjacent), multiplied by concatenating and cancelling. Every map from to a group extends uniquely to a homomorphism. That the reduced words form a group needs a careful argument (associativity is the subtle point); see Aluffi, Algebra: Chapter 0, §II.5. On one letter it is .
- Free vector space: , with basis . "Every function extends uniquely to a linear map " is exactly what it means for to be a basis. So a basis is a universal property.
Example— Field of fractions
with the inclusion is universal among injective ring homomorphisms from into fields: if is injective and is a field, there is exactly one ring homomorphism extending it, namely . The same holds for every integral domain and its field of fractions ; for example the field of rational functions .
Example— Tensor products
For vector spaces over , a tensor product is a vector space with a bilinear map such that every bilinear map equals for exactly one linear map . The universal property turns bilinear algebra into linear algebra. Constructions exist (a quotient of the free vector space on ; or, in finite dimensions, a space with basis ), but almost every proof about tensor products uses only the universal property. This is the textbook case of a construction "best defined by its universal property".
Uniqueness, existence and non-existence
Theorem— Theorem 1 (uniqueness up to unique isomorphism)
Let and be universal arrows from to . Then there is exactly one morphism with , and it is an isomorphism.
Proof
Existence and uniqueness of . Apply the universal property of to : there is exactly one with . Likewise there is exactly one with .
. Both and are morphisms that carry to :
By the uniqueness clause of the universal property of , applied to , they are equal. By symmetry .
∎
The same argument, word for word, shows that two initial objects are isomorphic by a unique isomorphism, that two products of and are isomorphic by a unique isomorphism commuting with the projections, and so on. This is why we may say the product, the free monoid, the quotient: any two choices are identified in exactly one sensible way. Notice where uniqueness was used — without it, need not be the identity.
Theorem— Theorem 2 (products exist in Set, Grp and Top)
The cartesian product, the direct product of groups and the product of spaces with the product topology satisfy the universal property of the product.
Proof
In . Given , the map satisfies , . If also does, then is a pair with first entry and second entry , so .
In . The same is the only candidate, since a homomorphism is in particular a function. It is a homomorphism: , because multiplication in is coordinatewise. The projections are homomorphisms for the same reason.
In . Again is the only candidate. It is continuous: for open and , is open, and these sets generate the topology. The projections are continuous since .
∎
The product topology is not an arbitrary choice: it is the coarsest topology making both projections continuous, and that is exactly what the universal property demands. (For infinite products, the "box topology" generated by all products of open sets is finer, and it fails the universal property — see the topologist's viewpoint below.)
Theorem— Theorem 3 (the universal property of quotients)
(a) Let be an equivalence relation on . If satisfies , there is exactly one with . (b) Let be a normal subgroup of . If is a homomorphism with , there is exactly one homomorphism with .
Proof
(a) Define . This is well defined: if then , so . Clearly . If also , then for every class, since every class is for some ( is surjective).
(b) The cosets of are the classes of the relation , and gives whenever . So (a) gives a unique function . It is a homomorphism: .
∎
Theorem— Corollary (first isomorphism theorem)
If is a surjective homomorphism, then is an isomorphism.
Proof
By Theorem 3(b) with we get with . It is surjective because is. It is injective: if then , so and , the identity of ; a homomorphism with trivial kernel is injective. A bijective homomorphism is an isomorphism of groups.
∎
Theorem— Theorem 4 (the free monoid is the monoid of words)
Let be the set of finite words in with concatenation and the empty word , and the one-letter word. For every function into a monoid there is exactly one monoid homomorphism with for all , namely
Proof
Existence. The formula sends to and one-letter words to ; and because the product of the values of the letters of is the product for followed by the product for (associativity in lets us regroup).
Uniqueness. Let be a homomorphism with . We show by induction on the length of . For : , since homomorphisms preserve the unit. For with : .
∎
With Theorem 1, Theorem 4 says: any free monoid on is isomorphic to , by a unique isomorphism fixing the letters. For example via .
Theorem— Theorem 5 (a universal property that nothing satisfies)
In the category of fields (with ring homomorphisms), and have no product.
Proof
A product would in particular be a field with ring homomorphisms and . A ring homomorphism out of a field is injective (its kernel is an ideal not containing , and the only such ideal of a field is ). Since in , injectivity gives in ; since in , also in . Then in , which is impossible in a field. So no field even has maps to both, let alone a universal one.
∎
So a universal property is a specification. Theorem 1 says at most one object (up to unique isomorphism) meets it; whether any object does is a separate question, answered by a construction — or, as here, by a proof that none exists.
Theorem— Theorem 6 (Q is the field of fractions of Z)
Let be a field and an injective ring homomorphism. There is exactly one ring homomorphism with for all .
Proof
Uniqueness. If extends and , then is an inverse of , and inverses are unique; so is forced. (This is the argument that showed is an epimorphism of rings in the lesson on categories.)
Existence. Define ; here because is injective. It is well defined: if then , so and . Checking that it preserves sums and products is routine algebra with fractions.
∎
Universal properties in Lean and Mathlib
We package the definition of a universal arrow as a Lean structure, with lift f the unique factorisation, fac its existence and uniq its uniqueness (Mathlib composes diagrammatically: unit ≫ U.map g is our ):
/-- A **universal arrow** from an object `X` of `C` to a functor `U : D ⥤ C`: an object `obj`
of `D` with a morphism `unit : X ⟶ U(obj)` such that every morphism `f : X ⟶ U(E)` factors as
`U(g) ∘ unit` for exactly one `g : obj ⟶ E`. Here `lift f` is that `g`, `fac` says it works and
`uniq` says it is the only one. (Free monoids: `X` a set, `U` the forgetful functor from monoids
to sets, `obj` the free monoid, `unit` the inclusion of one-letter words.) -/
structure UniversalArrow {C : Type u} [Category.{v} C] {D : Type u₂} [Category.{v₂} D]
(X : C) (U : D ⥤ C) where
/-- The universal object. -/
obj : D
/-- The universal morphism `X ⟶ U(obj)`. -/
unit : X ⟶ U.obj obj
/-- The factorisation of a morphism `X ⟶ U(E)` through `unit`. -/
lift : {E : D} → (X ⟶ U.obj E) → (obj ⟶ E)
/-- Existence: `U(lift f) ∘ unit = f`. -/
fac : ∀ {E : D} (f : X ⟶ U.obj E), unit ≫ U.map (lift f) = f
/-- Uniqueness: any `g` with `U(g) ∘ unit = f` is `lift f`. -/
uniq : ∀ {E : D} (f : X ⟶ U.obj E) (g : obj ⟶ E), unit ≫ U.map g = f → g = lift fTheorem 1 then follows the human proof exactly. First, the uniqueness clause as a cancellation principle, and the fact that the factorisation of itself is the identity:
/-- **Maps out of a universal object are determined by what they do to the unit.** If
`U(g) ∘ unit = U(g') ∘ unit` then `g = g'`: both are the unique factorisation of the same
morphism. This is the "uniqueness clause" doing its work. -/
theorem hom_ext (A : UniversalArrow X U) {E : D} {g g' : A.obj ⟶ E}
(h : A.unit ≫ U.map g = A.unit ≫ U.map g') : g = g' :=
(A.uniq _ g h).trans (A.uniq _ g' rfl).symm/-- The factorisation of `unit` itself is the identity: `lift unit = id`, because `id` also
factors `unit` (`U(id) ∘ unit = unit`) and factorisations are unique. -/
theorem lift_unit (A : UniversalArrow X U) : A.lift A.unit = 𝟙 A.obj :=
(A.uniq A.unit (𝟙 A.obj) (by rw [U.map_id, Category.comp_id])).symmThen the comparison isomorphism, its compatibility with the structure maps, and its uniqueness:
/-- **Two universal arrows have isomorphic objects.** The comparison maps are `A.lift B.unit`
and `B.lift A.unit`; each composite factors the unit through itself, so by `hom_ext` (the
uniqueness clause) it is the identity. This is the proof of the lesson, verbatim. -/
def iso (A B : UniversalArrow X U) : A.obj ≅ B.obj where
hom := A.lift B.unit
inv := B.lift A.unit
hom_inv_id := by
apply A.hom_ext
rw [U.map_comp, ← Category.assoc, A.fac, B.fac, U.map_id, Category.comp_id]
inv_hom_id := by
apply B.hom_ext
rw [U.map_comp, ← Category.assoc, B.fac, A.fac, U.map_id, Category.comp_id]/-- The isomorphism `iso A B` is **compatible with the structure maps**: it carries `A.unit` to
`B.unit`, i.e. `U(φ) ∘ A.unit = B.unit`. -/
theorem iso_compatible (A B : UniversalArrow X U) : A.unit ≫ U.map (A.iso B).hom = B.unit :=
A.fac B.unit/-- **…and it is the only compatible isomorphism** (indeed the only compatible morphism): any
`φ : A.obj ⟶ B.obj` with `U(φ) ∘ A.unit = B.unit` equals `(iso A B).hom`. So an object with a
universal property is unique *up to a unique isomorphism compatible with the structure maps*. -/
theorem iso_unique (A B : UniversalArrow X U) (φ : A.obj ⟶ B.obj)
(hφ : A.unit ≫ U.map φ = B.unit) : φ = (A.iso B).hom :=
A.uniq B.unit φ hφOur structure connects to Mathlib's general machinery through the Note above: a universal arrow is an initial object of the comma category, which Mathlib calls StructuredArrow X U, and Mathlib proves that initial objects are unique up to unique isomorphism:
/-- **A universal arrow is an initial object.** Objects of Mathlib's comma category
`StructuredArrow X U` are pairs `(E, f : X ⟶ U(E))`, and morphisms `(E, f) ⟶ (E', f')` are maps
`g : E ⟶ E'` with `U(g) ∘ f = f'`. The universal arrow `(obj, unit)` has exactly one morphism to
every other object — `lift` gives one (`fac`), and `uniq` says there are no others — so it is
initial. This connects our structure to Mathlib's library of initial objects and limits. -/
def isInitial (A : UniversalArrow X U) : Limits.IsInitial (StructuredArrow.mk A.unit) :=
Limits.IsInitial.ofUniqueHom
(fun E => StructuredArrow.homMk (A.lift E.hom) (A.fac E.hom))
(fun E m => by
ext
exact A.uniq E.hom m.right (StructuredArrow.w m))/-- Mathlib's form of the same principle: **initial objects are unique up to unique
isomorphism.** A universal arrow from `X` to `U` is exactly an initial object of the comma
category `StructuredArrow X U`, so this covers every universal property of the lesson. This
applies `IsInitial.uniqueUpToIso` and `IsInitial.hom_ext`. -/
theorem initial_unique_library {C : Type u} [Category.{v} C] {I J : C}
(hI : Limits.IsInitial I) (hJ : Limits.IsInitial J) :
Nonempty (I ≅ J) ∧ ∀ φ ψ : I ⟶ J, φ = ψ :=
⟨⟨hI.uniqueUpToIso hJ⟩, fun φ ψ => hI.hom_ext φ ψ⟩Products (Theorem 2). For spaces, Mathlib's lemma says precisely that a map into a product is continuous iff its components are:
/-- **The product of sets.** For maps `f : X → A` and `g : X → B` there is exactly one
`h : X → A × B` with `π₁ ∘ h = f` and `π₂ ∘ h = g`, namely `h(x) = (f(x), g(x))`. Uniqueness: a
point of `A × B` is determined by its two coordinates. -/
theorem prod_universal {X A B : Type u} (f : X → A) (g : X → B) :
∃! h : X → A × B, Prod.fst ∘ h = f ∧ Prod.snd ∘ h = g := by
refine ⟨fun x => (f x, g x), ⟨rfl, rfl⟩, ?_⟩
rintro h ⟨h₁, h₂⟩
funext x
exact Prod.ext (congrFun h₁ x) (congrFun h₂ x)/-- **The product of groups.** For homomorphisms `f : G → H` and `g : G → K` there is exactly
one homomorphism `h : G → H × K` with `π₁ ∘ h = f` and `π₂ ∘ h = g`. The map is the same as for
sets (`x ↦ (f x, g x)`, Mathlib's `MonoidHom.prod`); the new point is that it is a homomorphism
because the operation on `H × K` is defined coordinatewise. -/
theorem group_prod_universal {G H K : Type u} [Group G] [Group H] [Group K] (f : G →* H)
(g : G →* K) :
∃! h : G →* H × K, (MonoidHom.fst H K).comp h = f ∧ (MonoidHom.snd H K).comp h = g := by
refine ⟨f.prod g, ⟨MonoidHom.fst_comp_prod f g, MonoidHom.snd_comp_prod f g⟩, ?_⟩
rintro h ⟨h₁, h₂⟩
ext x
· exact DFunLike.congr_fun h₁ x
· exact DFunLike.congr_fun h₂ x/-- **The product of spaces.** With the product topology, a map into `Y × Z` is continuous
exactly when both coordinates are: the product topology is the coarsest topology making the
projections continuous, which is precisely what makes `X × Y` the product in **Top**. This
applies `continuous_prodMk`. -/
theorem continuous_prod_library {X Y Z : Type u} [TopologicalSpace X] [TopologicalSpace Y]
[TopologicalSpace Z] (f : X → Y) (g : X → Z) :
Continuous (fun x => (f x, g x)) ↔ Continuous f ∧ Continuous g :=
continuous_prodMkQuotients (Theorem 3). Lean has quotient types built in; Quotient.lift is the existence half of the universal property, and Quotient.ind (every class is the class of some element) gives uniqueness:
/-- **The quotient set.** If `f : X → Y` is constant on equivalence classes (`a ~ b` implies
`f a = f b`), there is exactly one `g : X/~ → Y` with `g ∘ q = f`, where `q : X → X/~` sends an
element to its class. Existence is `Quotient.lift`: define `g [a] = f a`, well defined by the
hypothesis. Uniqueness: every class is `[a]` for some `a` (`Quotient.ind`). -/
theorem quotient_universal {X Y : Type u} (s : Setoid X) (f : X → Y)
(hf : ∀ a b, s a b → f a = f b) :
∃! g : Quotient s → Y, g ∘ Quotient.mk s = f := by
refine ⟨Quotient.lift f hf, rfl, ?_⟩
intro g hg
funext c
induction c using Quotient.ind with
| _ a => exact congrFun hg a/-- **The quotient group.** If `N` is a normal subgroup of `G` and `f : G → H` is a homomorphism
killing `N` (`N ⊆ ker f`), there is exactly one homomorphism `g : G/N → H` with `g ∘ q = f`.
This applies `QuotientGroup.lift`, `QuotientGroup.lift_mk` and `QuotientGroup.monoidHom_ext`. -/
theorem quotient_group_library {G H : Type u} [Group G] [Group H] (N : Subgroup G) [N.Normal]
(f : G →* H) (hN : N ≤ f.ker) :
∃! g : G ⧸ N →* H, g.comp (QuotientGroup.mk' N) = f :=
⟨QuotientGroup.lift N f hN, MonoidHom.ext fun x => QuotientGroup.lift_mk N hN x,
fun _ hg => QuotientGroup.monoidHom_ext N (hg.trans
(MonoidHom.ext fun x => (QuotientGroup.lift_mk N hN x).symm))⟩The free monoid (Theorem 4), with words as Lean lists; the uniqueness proof is the induction on the length of a word. Mathlib's FreeMonoid is a type of lists with its own universal property:
/-- Evaluate a word `[s₁, s₂, …, sₖ]` in a monoid `M`, given a value `f(s)` for each letter:
the product `f(s₁) · f(s₂) ⋯ f(sₖ)` (the empty word gives `1`). -/
def evalWord {S M : Type u} [Monoid M] (f : S → M) (w : List S) : M :=
(w.map f).prod/-- `evalWord f` is a **monoid homomorphism** from words under concatenation: it sends the empty
word to `1` and `v ++ w` to the product of the values. -/
theorem evalWord_append {S M : Type u} [Monoid M] (f : S → M) (v w : List S) :
evalWord f [] = 1 ∧ evalWord f (v ++ w) = evalWord f v * evalWord f w := by
constructor
· rfl
· simp [evalWord, List.map_append, List.prod_append]/-- **Uniqueness in the universal property of the free monoid.** Any map `h` from words to a
monoid that preserves `1` and concatenation and agrees with `f` on one-letter words is
`evalWord f`. Proof by induction on the word: `s :: w` is the concatenation `[s] ++ w`, so
`h(s :: w) = h[s] · h(w) = f(s) · evalWord f w = evalWord f (s :: w)`. -/
theorem free_monoid_unique {S M : Type u} [Monoid M] (f : S → M) (h : List S → M)
(h_nil : h [] = 1) (h_append : ∀ v w, h (v ++ w) = h v * h w) (h_single : ∀ s, h [s] = f s) :
h = evalWord f := by
funext w
induction w with
| nil => exact h_nil
| cons s w ih =>
calc h (s :: w) = h ([s] ++ w) := rfl
_ = h [s] * h w := h_append [s] w
_ = f s * evalWord f w := by rw [h_single, ih]
_ = evalWord f (s :: w) := by simp [evalWord]/-- Mathlib's `FreeMonoid S` (words in `S`, with concatenation) and its universal property:
for every map `f : S → M` into a monoid there is exactly one monoid homomorphism
`FreeMonoid S → M` sending each letter `of s` to `f s`. This applies `FreeMonoid.lift`,
`FreeMonoid.lift_eval_of` and `FreeMonoid.hom_eq`. -/
theorem free_monoid_library {S M : Type u} [Monoid M] (f : S → M) :
∃! g : FreeMonoid S →* M, ∀ s, g (FreeMonoid.of s) = f s :=
⟨FreeMonoid.lift f, FreeMonoid.lift_eval_of f, fun _ hg =>
FreeMonoid.hom_eq fun s => (hg s).trans (FreeMonoid.lift_eval_of f s).symm⟩Fields: the universal property of (Theorem 6, for fields of characteristic zero, which is the same as being injective), and the non-existence of a product of and (Theorem 5), where ZMod p is :
/-- **`ℚ` is the field of fractions of `ℤ`.** For every field `K` of characteristic zero (so that
`ℤ → K` is injective) there is exactly one ring homomorphism `ℚ → K` extending `ℤ → K`. This
applies `Rat.castHom` (existence) and `RingHom.ext_rat` (uniqueness); the general construction
for any integral domain is Mathlib's `IsFractionRing.lift`. -/
theorem rat_universal_library (K : Type u) [Field K] [CharZero K] :
∃! φ : ℚ →+* K, φ.comp (Int.castRingHom ℚ) = Int.castRingHom K :=
⟨Rat.castHom K, RingHom.ext_int _ _, fun φ _ => RingHom.ext_rat φ (Rat.castHom K)⟩/-- **`𝔽₂` and `𝔽₃` have no product in the category of fields.** A product would be a field `K`
with homomorphisms `K → 𝔽₂` and `K → 𝔽₃`. But a ring homomorphism out of a field is injective;
`2 ↦ 0` in `𝔽₂` forces `2 = 0` in `K`, and `3 ↦ 0` in `𝔽₃` forces `3 = 0` in `K`; then
`1 = 3 - 2 = 0` in `K`, which no field allows. So no such `K` exists at all — the universal
property *characterises* products but does not *construct* them. -/
theorem no_field_maps_to_f2_f3 (K : Type u) [Field K] (f : K →+* ZMod 2) (g : K →+* ZMod 3) :
False := by
have h2 : (2 : K) = 0 := by
apply f.injective
rw [map_ofNat, map_zero]
decide
have h3 : (3 : K) = 0 := by
apply g.injective
rw [map_ofNat, map_zero]
decide
have h1 : (1 : K) = 0 := by
calc (1 : K) = 3 - 2 := by norm_num
_ = 0 := by rw [h2, h3, sub_zero]
exact one_ne_zero h1Not formalised here: the free group (Mathlib has FreeGroup with FreeGroup.lift), the tensor product (Mathlib's TensorProduct.lift), and the existence half of the general field-of-fractions construction (Mathlib's IsFractionRing.lift).
Existence and uniqueness, counted
For finite sets the universal property of the product can be checked by counting. The first experiment confirms that maps correspond exactly to pairs of maps, then tests three candidate "products": for each pair it counts the maps with and . A genuine product gives the count every time; a count of is a failure of existence, a count above a failure of uniqueness.
"""The universal property of the product, checked on finite sets.
For finite sets X, A, B, maps X -> A x B correspond exactly to pairs of maps
(X -> A, X -> B). We check this bijection exhaustively for small sizes. Then
we test three candidate "products" P with maps p : P -> A and q : P -> B by
counting, for every pair (f, g) of maps from a test set X, how many maps
u : X -> P satisfy p . u = f and q . u = g. A product needs exactly one every
time. The numbers model k = a*|B| + b passes; a set with a spare coordinate
fails uniqueness; the disjoint union fails existence whatever maps we choose
(it has 5 elements but there are 6 pairs to hit), and with the maps chosen
here it also fails uniqueness. Exhaustive and exact for these small sets.
"""
from itertools import product
def maps(domain, codomain):
"""All functions domain -> codomain, as dicts."""
domain, codomain = list(domain), list(codomain)
return [dict(zip(domain, values))
for values in product(codomain, repeat=len(domain))]
def pairing(f, g):
"""The map x -> (f(x), g(x)) into the product."""
return {x: (f[x], g[x]) for x in f}
def factorisations(xs, P, p, q, f, g):
"""Number of u : X -> P with p(u(x)) = f(x) and q(u(x)) = g(x) for all x."""
count = 1
for x in xs:
count *= sum(1 for z in P if p(z) == f[x] and q(z) == g[x])
return count
def candidates(A, B):
"""Three candidate products: (name, P, p, q)."""
nb = len(B)
numbers = list(range(len(A) * nb))
spare = list(product(A, B, [0, 1]))
union = [("A", a) for a in A] + [("B", b) for b in B]
return [
("numbers k = a*|B| + b", numbers,
lambda k: A[k // nb], lambda k: B[k % nb]),
("A x B x {0, 1}", spare, lambda z: z[0], lambda z: z[1]),
("disjoint union A + B", union,
lambda z: z[1] if z[0] == "A" else A[0],
lambda z: z[1] if z[0] == "B" else B[0]),
]
def factorisation_counts(X, A, B, P, p, q):
"""The set of factorisation counts over all pairs (f, g)."""
return {factorisations(X, P, p, q, f, g)
for f in maps(X, A) for g in maps(X, B)}
def main():
print("1. Maps X -> A x B versus pairs of maps (X -> A, X -> B)")
for nx, na, nb in [(1, 2, 3), (2, 2, 2), (2, 3, 2), (3, 2, 2)]:
X, A, B = range(nx), range(na), range(nb)
n_pairs = len(maps(X, A)) * len(maps(X, B))
images = {tuple(sorted(pairing(f, g).items()))
for f in maps(X, A) for g in maps(X, B)}
total = len(maps(X, list(product(A, B))))
ok = n_pairs == len(images) == total
print(f" |X|={nx} |A|={na} |B|={nb}: {n_pairs:>3} pairs, "
f"{total:>3} maps, pairing is a bijection: {ok}")
print()
print("2. Factorisations through candidate products, |A| = 2, |B| = 3")
A, B = ["a0", "a1"], ["b0", "b1", "b2"]
for nx in (1, 2):
X = range(nx)
print(f" test set X with {nx} element(s):")
for name, P, p, q in candidates(A, B):
counts = sorted(factorisation_counts(X, A, B, P, p, q))
verdict = "product" if counts == [1] else "not a product"
print(f" {name:<22} counts {str(counts):<13} {verdict}")
print()
print("Epistemic status: exhaustive and exact for these small sets. Part 1")
print("illustrates |A x B|^|X| = |A|^|X| |B|^|X|; part 2 shows how")
print("existence (count >= 1) and uniqueness (count <= 1) can each fail.")
print("The lesson proves the universal property for all sets.")
if __name__ == "__main__":
main()The second experiment takes the free monoid on two letters and the unique homomorphism to integer matrices sending and . Different words turn out to give different matrices, and a subtraction algorithm — Euclid's algorithm in disguise — reads the word back off the matrix. Homomorphisms to or , by contrast, forget almost everything.
"""The free monoid on {L, R}, evaluated in three monoids.
The universal property of the free monoid says: choosing a value for each
letter in a monoid M determines exactly one monoid homomorphism from words
to M, namely "multiply the values of the letters". We take M to be the 2x2
integer matrices with L = [[1,0],[1,1]] and R = [[1,1],[0,1]], check the
homomorphism property, and find that different words give different
matrices; a subtraction algorithm (Euclid's algorithm in disguise) reads the
word back off the matrix, which is why this homomorphism is injective. Other
choices of target, (N, +) and (Z, +), give homomorphisms that are far from
injective. Finally each word gives a fraction, listing positive rationals as
in the Stern-Brocot tree. Exact, exhaustive for words of bounded length.
"""
from fractions import Fraction
from itertools import product
IDENTITY = ((1, 0), (0, 1))
GENERATORS = {"L": ((1, 0), (1, 1)), "R": ((1, 1), (0, 1))}
def matmul(x, y):
"""Product of 2x2 matrices given as nested tuples."""
return tuple(
tuple(sum(x[i][k] * y[k][j] for k in range(2)) for j in range(2))
for i in range(2)
)
def evaluate(word, values, op, unit):
"""The unique homomorphism from words: multiply the letters' values."""
result = unit
for letter in word:
result = op(result, values[letter])
return result
def words(max_length, alphabet="LR"):
"""All words of length 0..max_length, shortest first."""
out = []
for n in range(max_length + 1):
out.extend("".join(w) for w in product(alphabet, repeat=n))
return out
def decode(m):
"""Recover the word of a matrix in the monoid generated by L and R.
If the top row dominates the bottom row the word starts with R
(strip it: subtract the bottom row from the top), otherwise with L.
Returns None if m is not reached by any word.
"""
word = []
(a, b), (c, d) = m
if min(a, b, c, d) < 0:
return None
# Each step subtracts a non-zero row of non-negative entries, so the
# entries stay non-negative and their sum strictly decreases: it stops.
while ((a, b), (c, d)) != IDENTITY:
if a >= c and b >= d and (c, d) != (0, 0):
word.append("R")
a, b = a - c, b - d
elif c >= a and d >= b and (a, b) != (0, 0):
word.append("L")
c, d = c - a, d - b
else:
return None
return "".join(word)
def fraction_of(m):
"""The Stern-Brocot fraction (a + b) / (c + d) of a matrix."""
(a, b), (c, d) = m
return Fraction(a + b, c + d)
def main():
def mat(w):
return evaluate(w, GENERATORS, matmul, IDENTITY)
short = words(4)
hom = all(mat(v + w) == matmul(mat(v), mat(w)) for v in short for w in short)
print("Target 1: 2x2 matrices, L = [[1,0],[1,1]], R = [[1,1],[0,1]]")
print(f" eval(vw) = eval(v) eval(w) for all {len(short)}^2 pairs of words"
f" of length <= 4: {hom}")
long = words(10)
images = {mat(w) for w in long}
print(f" {len(long)} words of length <= 10 give {len(images)} distinct"
" matrices")
back = all(decode(mat(w)) == w for w in long)
print(f" decoding by subtraction recovers every one of these words: {back}")
print(f" LR = {mat('LR')} but RL = {mat('RL')}")
print()
length = {"L": 1, "R": 1}
signed = {"L": 1, "R": -1}
plus = (lambda x, y: x + y)
for name, values in [("(N, +), L, R -> 1", length),
("(Z, +), L -> 1, R -> -1", signed)]:
image = {evaluate(w, values, plus, 0) for w in long}
print(f"Target: {name:<24} {len(long)} words -> {len(image)} values")
print()
fracs = [fraction_of(mat(w)) for w in words(3)]
print(f"Stern-Brocot: the {len(fracs)} words of length <= 3 give"
f" {len(set(fracs))} distinct")
print("fractions (a + b)/(c + d), where [[a, b], [c, d]] is the matrix:")
print(" " + " ".join(str(f) for f in sorted(set(fracs))))
print()
print("Epistemic status: exact and exhaustive for words of length at most")
print("10. That no two words share a matrix for all lengths is a theorem")
print("(the decoding always works, by the argument of Euclid's algorithm);")
print("this run is evidence for it, not a proof.")
if __name__ == "__main__":
main()Both experiments are exhaustive for bounded sizes. They illustrate the theorems; they do not prove them. (That the homomorphism is injective for words of every length is a theorem: the decoding step always succeeds because exactly one of the two rows of a matrix of non-negative integers with determinant , other than the identity, dominates the other.)
Explore: maps into a product, maps out of a quotient
Choose maps and between small finite sets, then try to build a map that is compatible with the projections. You will find that each choice of is forced: its first coordinate must be and its second . That is existence and uniqueness, one element at a time.
The product, by its maps
Choose maps f : Z → A and g : Z → B. Then try to build a map h : Z → A × B that projects back to f and g.
f : Z → A
g : Z → B
⟨f, g⟩ : Z → A × B
p ↦ (red, 2) q ↦ (blue, 2) r ↦ (red, 3)
Your turn: choose h(p), h(q), h(r) by clicking cells.
| A × B | 1 | 2 | 3 |
|---|---|---|---|
| red | |||
| blue |
The quotient that makes a torus. Gluing opposite sides of a square is a quotient: points on opposite edges are declared equivalent. By the universal property of the quotient (topology), a continuous function on the torus is exactly a continuous function on the square taking equal values at glued points. Walk the flatlander off one edge and watch it re-enter through the partner edge; the tiling view shows the same functions as doubly periodic functions on the plane.
A quotient of the square
Opposite sides are identified; maps out of the torus are maps out of the square that respect the gluing.
Keys: ↑ forward, ↓ back, ← and → turn, Space walks or stops. You can also drag it.
- Orientable
- Yes
- Euler characteristic
- χ = 0
Gluing turns the 4 corners into V = 1, the 4 sides into E = 2 and the square into F = 1: V − E + F = 1 − 2 + 1 = 0
Same way round as at the start.
Sides crossed so far: 0
Opposite sides are glued with arrows pointing the same way. Walk off the right side and you come back on the left, the same way round. However it walks, the flatlander is never mirrored: the torus is orientable.
Copies of the square tile the plane, and the trail runs on smoothly from copy to copy. This plane is the universal cover of the torus.
Exercises
1. Universal properties
Warm-upHumanLet , and . How many functions are there? (Use the universal property: such a function is the same as a pair of functions , .)
2. Universal properties
Warm-upHumanThe free monoid on a one-element set is isomorphic to which monoid?
3. Universal properties
CoreHumanLet be the unique monoid homomorphism from the free monoid on to with and . What is ?
4. Universal properties
CoreHumanLet be non-empty sets and , with and . Which part of the universal property of the product does fail?
5. Universal properties
CoreHumanIn the proof that two universal arrows and are isomorphic, we know . What exactly lets us conclude ?
6. Universal properties
CoreHumanRegard the positive integers ordered by divisibility ( when ) as a category. Which statements are true? Choose all that apply.
7. Universal properties
CoreFormalIn the Lean structure UniversalArrow X U, with fields obj, unit : X ⟶ U.obj obj and lift, which field states the uniqueness clause? (Recall unit ≫ U.map g means .)
8. Universal properties
StretchComputationalAn equivalence relation on a finite set is given by its list of classes, e.g. [{0, 3}, {1, 4}, {2, 5}], and a function by a dict. Write descend(f, classes) that returns the induced function on classes — a dict from each class (as a frozenset) to a value, with — or None if is not constant on some class (so that no with exists).
Common misconceptions
Misconception
"A universal property constructs the object." It only characterises it: if an object with the property exists, it is unique up to unique isomorphism. Existence needs a separate construction, and can fail — the fields and have no product, and two incomparable elements of a poset may have no meet.
Misconception
"The uniqueness clause is a technicality." Without it the theory collapses. The set with the obvious projections receives a compatible map from every — but never just one, and it is not isomorphic to . The proof of Theorem 1 uses uniqueness at the decisive step.
Misconception
"The product is one particular set." built from Kuratowski pairs, and the set with suitable projections, are both products of finite sets and . Neither is "the real one"; they are identified by a unique compatible bijection, and every statement made using only the universal property holds for both.
Misconception
"Unique up to isomorphism is the same as unique up to unique isomorphism." The extra word matters. Any two groups of order are isomorphic, but by four different isomorphisms; there is no canonical choice. Two products of and are related by exactly one isomorphism commuting with the projections, so identifying them never involves a choice.
Many ways of seeing
Topology— Topologies forced by universal properties: products and gluing
The product topology is the unique topology on making it the product in : a map is continuous iff every component is. For infinite products the box topology (generated by all products of open sets) is too fine to satisfy this: the diagonal map , , has continuous components, but the preimage of the box-open set is , which is not open. The universal property picks the right answer.
Dually, the quotient topology on is the one making universal: a map out of is continuous iff its composite with is. Gluing opposite sides of a square gives a torus, and the universal property says that continuous maps out of the torus are the same as continuous maps out of the square that agree on glued points — equivalently, continuous functions on that are periodic in both directions (quotient topologies are developed in point-set topology). The universal cover of a space, met with the fundamental group, is another object named for a universal property.
Number theory— gcd, lcm and the Chinese remainder theorem
In the positive integers ordered by divisibility, the product of and is (the largest common divisor, in the sense that every common divisor divides it) and the coproduct is . In rings, the Chinese remainder theorem says that for coprime the ring , with the reduction maps to and , is a product of and : the map given by the universal property of the product ring is injective (if and then ) and so bijective by counting. See divisibility and gcd. The rationals are the field of fractions of , and the -adic integers are the limit of , a universal property of the kind studied in limits and colimits.
Algebra— Presentations: free objects modulo relations
Combining two universal properties gives presentations. The group is the quotient of the free group by the smallest normal subgroup containing the words in . Its universal property: homomorphisms correspond exactly to functions under which every relation in becomes true in . For example, homomorphisms from the dihedral group to are pairs of elements of with . The same pattern defines polynomial rings ( is the free commutative -algebra on ) and quotient rings , and lets one construct as .
Computation— fold, reduce and MapReduce
The universal property of the free monoid is the fold (or reduce) of functional programming: given a value f(s) for each letter and a monoid , there is exactly one way to evaluate every list compatibly with concatenation. Because the result is a monoid homomorphism, a long list can be cut into pieces, each piece reduced on a different machine, and the partial results combined with — this is the algebra behind parallel "map-reduce" computations, and it works only because the operation is associative. Product types (pairs, records) and sum types (tagged unions) in programming languages are products and coproducts in a category of types.
Logic— And, or, and the quantifiers
In the preorder of propositions ordered by entailment, the product of and is (it entails both, and anything entailing both entails it), the coproduct is , the terminal object is "true" and the initial object is "false". The rules of natural deduction for — from infer and infer ; from and infer — are exactly the projections and the pairing of the universal property. F. William Lawvere (1969) showed that the quantifiers and are also characterised by universal properties (as adjoints to substitution) — see first-order logic and categorical logic.
Wonder Trails
History and global context
- Many universal constructions are old. The Chinese remainder theorem appears in the Sunzi Suanjing (China, around the 3rd to 5th century), and Indian mathematicians from Āryabhaṭa (499) onwards solved such systems with the kuṭṭaka method. Fractions of integers are ancient; the abstract field of fractions of an integral domain belongs to the algebra of the late 19th and early 20th centuries (Dedekind, Steinitz).
- Walther von Dyck (1882) studied groups given by generators and relations; Jakob Nielsen (1921) and Otto Schreier (1927) developed the theory of free groups. Hassler Whitney defined the tensor product of abelian groups in 1938.
- Kazimierz Kuratowski gave his definition of the ordered pair in 1921, refining Norbert Wiener's of 1914.
- Pierre Samuel, in "On universal mappings and free topological groups" (1948), formulated universal mapping problems in general, and the Bourbaki group made them a standard tool. Daniel Kan's adjoint functors (1958) showed that universal arrows for every object assemble into a functor, and Saunders Mac Lane's Categories for the Working Mathematician (1971) made universal properties the organising principle of category theory.
Further reading
- Tom Leinster, Basic Category Theory (2014), chapter 0 (an introduction through universal properties) and chapter 5 (limits).
- Emily Riehl, Category Theory in Context (2016), chapter 2.
- Paolo Aluffi, Algebra: Chapter 0 (2009) — an algebra textbook built on universal properties from the start.
- Saunders Mac Lane and Garrett Birkhoff, Algebra (1967; 3rd ed. 1988).