The simplex category has one object for each , and its morphisms are the monotone maps (). It is the Skeleton of , the category of finite nonempty linear orders and monotone maps: every finite nonempty linear order is isomorphic to exactly one , so the inclusion is an Equivalence of Categories (CTfS Exercise 4.3.4.4) — just as the category of the sets is equivalent to .
Sources: CTfS Exercise 4.1.1.8 (counting monotone maps), Exercise 4.3.4.4 (), Example 4.6.1.6 (simplicial sets), §4.6.3 ( full), Exercise 4.5.2.9 (iterated cones); §2.7.4.3 (simplicial complexes).
Counting morphisms
A monotone map is a non-decreasing sequence of values in — a multiset of size drawn from values — so
In CTfS Exercise 4.1.1.8: (pick a point), ( is terminal), , and .
Faces and degeneracies
Every monotone map factors uniquely as a surjection followed by an injection, and these are generated by
- coface maps , the injection that skips — including a face of an -simplex into an -simplex;
- codegeneracy maps , the surjection that hits twice — collapsing a simplex.
They satisfy the cosimplicial identities (e.g. for ), which give a presentation of .
Simplicial sets
A simplicial set is a Presheaf — a C-Set on the schema (Opposite Category). is the set of -simplices, and takes the -th face. Truncating at and forgetting degeneracies leaves the Graph schema : a simplicial set is a “higher-dimensional graph”. Unlike simplicial complexes, simplicial sets have “excellent formal properties” (CTfS Example 4.6.1.6): they form a Topos with all limits and colimits. The representable is the standard -simplex , and by the Yoneda Lemma its maps into are exactly . The nerve of a category has as -simplices the composable strings , and embeds fully faithfully in simplicial sets.
The objects appear elsewhere too: is the -fold iterated cone on the empty category (CTfS Exercise 4.5.2.9), and is the Walking Arrow.
Docs: Graphs
using Catlab
# monotone maps [m] → [n] between the linear orders {0<…<m}, {0<…<n} (CTfS Exercise 4.1.1.8)
monotone_maps(m, n) = [f for f in Iterators.product(fill(0:n, m + 1)...) if issorted(collect(f))]
length(monotone_maps(0, 3)), length(monotone_maps(3, 0)), length(monotone_maps(2, 3)) # (4, 1, 20)
binomial(3 + 2 + 1, 2 + 1) # 20 = C(m+n+1, m+1)
# coface d^i : [n-1] → [n] skips i; codegeneracy s^i : [n+1] → [n] repeats i
d(i) = j -> j < i ? j : j + 1
s(i) = j -> j <= i ? j : j - 1
all((d(2) ∘ d(0))(j) == (d(0) ∘ d(1))(j) for j in 0:1) # a cosimplicial identity: d²d⁰ = d⁰d¹
# the boundary of the 2-simplex as a symmetric graph (its 1-skeleton): an empty triangle
∂Δ2 = cycle_graph(SymmetricGraph, 3)
nv(∂Δ2), ne(∂Δ2) ÷ 2 # (3, 3)import Mathlib
open CategoryTheory
#check SimplexCategory -- objects [n], morphisms monotone maps Fin (m+1) →o Fin (n+1)
#check @SimplexCategory.δ -- coface maps
#check @SimplexCategory.σ -- codegeneracy maps
#check @SimplexCategory.δ_comp_δ -- a cosimplicial identity
#check SSet -- simplicial sets: SimplexCategoryᵒᵖ ⥤ Type
#check @nerve -- the nerve of a categoryimport Data.List (sort)
-- a morphism [m] → [n] as its list of values [f 0, …, f m] (non-decreasing)
monotone :: Int -> Int -> [[Int]]
monotone m n = filter (\f -> f == sort f) (sequence (replicate (m + 1) [0..n]))
compose :: [Int] -> [Int] -> [Int] -- (g . f) as lists: apply g's table to f's values
compose g f = map (g !!) f
-- map length [monotone 0 3, monotone 3 0, monotone 2 3] == [4, 1, 20]