1-- Examples of small categories2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Category.Examples8import Product9import Set1011theorem IsPreorder.relation (A r : Set)12requires preorder : IsPreorder(A, r)13shows RelationBetween(r, A, A)14proof15obtain⟨relation, reflexive, transitive⟩:= preorder16exact relation1718theorem IsPreorder.reflexive (A r : Set)19requires preorder : IsPreorder(A, r)20shows ReflexiveOn(A, r)21proof22obtain⟨relation, reflexive, transitive⟩:= preorder23exact reflexive2425theorem IsPreorder.transitive (A r : Set)26requires preorder : IsPreorder(A, r)27shows TransitiveOn(A, r)28proof29obtain⟨relation, reflexive, transitive⟩:= preorder30exact transitive3132-- Every member of a relation on A is a related pair of members of A.33theorem RelationBetween.shape (A B r f : Set)34requires relation : RelationBetween(r, A, B)35requires fInR : f ∈ r36shows∃ x ∈ A, ∃ y ∈ B, f = (x, y) ∧ relates(r, x, y)37proof38unfold RelationBetween at relation39have bounded := relation with f, fInR40obtain⟨bound, x, hx, y, hy, shape⟩:= product.membership.forward with bounded41refine⟨x, hx, y, hy, shape, ?_⟩42unfold relates43 rwa ← shape4445-- A preorder (A, r) as a category: objects A, morphisms the related46-- pairs, composition by transitivity.47defgraph orderDom (A r : Set) (f ∈ r) : A := fst(f)48requires relation : RelationBetween(r, A, A)49proof50obtain⟨x, xInA, y, yInA, shape, related⟩:=51 RelationBetween.shape with relation, member52rw shape53rw fst.pair54exact xInA5556defgraph orderCod (A r : Set) (f ∈ r) : A := snd(f)57requires relation : RelationBetween(r, A, A)58proof59obtain⟨x, xInA, y, yInA, shape, related⟩:=60 RelationBetween.shape with relation, member61rw shape62rw snd.pair63exact yInA6465defgraph orderIdentity (A r : Set) (a ∈ A) : r := (a, a)66requires reflexive : ReflexiveOn(A, r)67proof68have related := reflexive with a, member69unfold relates at related70exact related7172theorem orderDom.pair (A r x y : Set)73requires relation : RelationBetween(r, A, A)74requires related : relates(r, x, y)75shows orderDom(A, r)((x, y)) = x76proof77unfold relates at related78have value := orderDom.value with relation, related79rw value80exact fst.pair at x, y8182theorem orderCod.pair (A r x y : Set)83requires relation : RelationBetween(r, A, A)84requires related : relates(r, x, y)85shows orderCod(A, r)((x, y)) = y86proof87unfold relates at related88have value := orderCod.value with relation, related89rw value90exact snd.pair at x, y9192theorem orderIdentity.pair (A r a : Set)93requires reflexive : ReflexiveOn(A, r)94requires aInA : a ∈ A95shows orderIdentity(A, r)(a) = (a, a)96proof97exact orderIdentity.value with reflexive, aInA9899defgraph orderComposition (A r : Set)100 (p ∈ composablePairsOf(r, orderDom(A, r), orderCod(A, r))) : r :=101 (orderDom(A, r)(snd(p)), orderCod(A, r)(fst(p)))102requires preorder : IsPreorder(A, r)103proof104have relation := IsPreorder.relation with preorder105have transitive := IsPreorder.transitive with preorder106obtain⟨bounded, g, gInR, f, fInR, shape, composable⟩:=107 composablePairsOf.membership.forward with member108obtain⟨y, yInA, z, zInA, gShape, gRelated⟩:=109 RelationBetween.shape with relation, gInR110obtain⟨x, xInA, w, wInA, fShape, fRelated⟩:=111 RelationBetween.shape with relation, fInR112have domG := orderDom.pair with relation, gRelated113have codF := orderCod.pair with relation, fRelated114have domF := orderDom.pair with relation, fRelated115have codG := orderCod.pair with relation, gRelated116have middle : y = w bycc117have related : relates(r, x, z)118rw← middle at fRelated119exact transitive with x, xInA, y, yInA, z, zInA, fRelated, gRelated120unfold relates at related121rw shape122rw [fst.pair, snd.pair, gShape, fShape, domF, codG]123exact related124125theorem orderComposition.pair (A r x y z : Set)126requires preorder : IsPreorder(A, r)127requires first : relates(r, x, y)128requires second : relates(r, y, z)129shows orderComposition(A, r)((y, z), (x, y)) = (x, z)130proof131have relation := IsPreorder.relation with preorder132have gInR : (y, z) ∈ r := second133have fInR : (x, y) ∈ r := first134have domG := orderDom.pair with relation, second135have codF := orderCod.pair with relation, first136have domF := orderDom.pair with relation, first137have codG := orderCod.pair with relation, second138have composable : orderDom(A, r)((y, z)) = orderCod(A, r)((x, y)) bycc139have pairIn := composablePairsOf.pair at r, orderDom(A, r), orderCod(A, r),140 (y, z), (x, y) with gInR, fInR, composable141have value := orderComposition.value with preorder, pairIn142have firstValue := fst.pair at (y, z), (x, y)143have secondValue := snd.pair at (y, z), (x, y)144unfold call2145cc146147def orderCategory (A r : Set) : Set:=148 Category.mk(A, r, orderDom(A, r), orderCod(A, r), orderIdentity(A, r),149 orderComposition(A, r))150151theorem orderCategory.category (A r : Set)152requires preorder : IsPreorder(A, r)153shows Category(orderCategory(A, r))154proof155have relation := IsPreorder.relation with preorder156have reflexive := IsPreorder.reflexive with preorder157have domFunction := orderDom.function with relation158have codFunction := orderCod.function with relation159have idFunction := orderIdentity.function with reflexive160have compFunction := orderComposition.function with preorder161unfold orderCategory162apply Category.intro with domFunction, codFunction, idFunction, compFunction163 . intros a aInA164have idValue := orderIdentity.pair with reflexive, aInA165have related := reflexive with a, aInA166have domValue := orderDom.pair with relation, related167have codValue := orderCod.pair with relation, related168rw idValue169refine⟨domValue, codValue⟩170 . intros g gInR f fInR composable171obtain⟨y, yInA, z, zInA, gShape, gRelated⟩:=172 RelationBetween.shape with relation, gInR173obtain⟨x, xInA, w, wInA, fShape, fRelated⟩:=174 RelationBetween.shape with relation, fInR175have domG := orderDom.pair with relation, gRelated176have codF := orderCod.pair with relation, fRelated177have domF := orderDom.pair with relation, fRelated178have codG := orderCod.pair with relation, gRelated179have middle : y = w bycc180rw← middle at fRelated181rw← middle at fShape182have composite := orderComposition.pair with preorder, fRelated, gRelated183have transitive := IsPreorder.transitive with preorder184have related := transitive with185 x, xInA, y, yInA, z, zInA, fRelated, gRelated186have domComposite := orderDom.pair with relation, related187have codComposite := orderCod.pair with relation, related188rw [gShape, fShape, composite]189refine⟨?_, ?_⟩190 . cc191 . cc192 . intros f fInR193obtain⟨x, xInA, y, yInA, fShape, fRelated⟩:=194 RelationBetween.shape with relation, fInR195have domF := orderDom.pair with relation, fRelated196have codF := orderCod.pair with relation, fRelated197have xRelated := reflexive with x, xInA198have yRelated := reflexive with y, yInA199have xIdentity := orderIdentity.pair with reflexive, xInA200have yIdentity := orderIdentity.pair with reflexive, yInA201have leftComposite := orderComposition.pair with202 preorder, fRelated, yRelated203have rightComposite := orderComposition.pair with204 preorder, xRelated, fRelated205rw fShape206rw [domF, codF, xIdentity, yIdentity]207refine⟨leftComposite, rightComposite⟩208 . intros h hInR g gInR f fInR outer inner209obtain⟨z, zInA, w, wInA, hShape, hRelated⟩:=210 RelationBetween.shape with relation, hInR211obtain⟨y, yInA, v, vInA, gShape, gRelated⟩:=212 RelationBetween.shape with relation, gInR213obtain⟨x, xInA, u, uInA, fShape, fRelated⟩:=214 RelationBetween.shape with relation, fInR215have domH := orderDom.pair with relation, hRelated216have codG := orderCod.pair with relation, gRelated217have domG := orderDom.pair with relation, gRelated218have codF := orderCod.pair with relation, fRelated219have outerMiddle : z = v bycc220have innerMiddle : y = u bycc221rw← outerMiddle at gRelated222rw← outerMiddle at gShape223rw← innerMiddle at fRelated224rw← innerMiddle at fShape225have transitive := IsPreorder.transitive with preorder226have hgRelated := transitive with227 y, yInA, z, zInA, w, wInA, gRelated, hRelated228have gfRelated := transitive with229 x, xInA, y, yInA, z, zInA, fRelated, gRelated230have hg := orderComposition.pair with preorder, gRelated, hRelated231have gf := orderComposition.pair with preorder, fRelated, gRelated232have leftComposite := orderComposition.pair with233 preorder, fRelated, hgRelated234have rightComposite := orderComposition.pair with235 preorder, gfRelated, hRelated236rw [hShape, gShape, fShape, hg, gf, leftComposite, rightComposite]237rfl238239-- The discrete category on a set: the identity relation is a preorder.240theorem identity.preorder (X : Set)241shows IsPreorder(X, identity(X))242proof243unfold IsPreorder244refine⟨identity.relation at X, ?_, ?_⟩245 . intros x xInX246exact identity.relates with xInX247 . intros x xInX y yInX z zInX first second248unfold relates at first249obtain⟨bound, a, aInX, shape⟩:= identity.membership.forward with first250obtain⟨xa, ya⟩:= orderedPair.injective with shape251have same : x = y bycc252rw same253exact second254255def discreteCategory (X : Set) : Set:= orderCategory(X, identity(X))256257theorem discreteCategory.category (X : Set)258shows Category(discreteCategory(X))259proof260have preorder := identity.preorder at X261unfold discreteCategory262exact orderCategory.category with preorder263264theorem discreteCategory.obj (X : Set)265shows obj(discreteCategory(X)) = X266proof267simp [discreteCategory, orderCategory, Category.mk.obj]268269theorem discreteCategory.mor (X : Set)270shows mor(discreteCategory(X)) = identity(X)271proof272simp [discreteCategory, orderCategory, Category.mk.mor]273274theorem discreteCategory.id (X : Set)275shows id(discreteCategory(X)) = orderIdentity(X, identity(X))276proof277simp [discreteCategory, orderCategory, Category.mk.id]278279theorem discreteCategory.morphism (X f : Set)280requires fInM : f ∈ mor(discreteCategory(X))281shows∃ x ∈ X, f = id(discreteCategory(X))(x)282proof283have preorder := identity.preorder at X284have reflexive := IsPreorder.reflexive with preorder285rw discreteCategory.mor at fInM286obtain⟨bound, x, xInX, shape⟩:= identity.membership.forward with fInM287have idValue := orderIdentity.pair with reflexive, xInX288refine⟨x, xInX, ?_⟩289rw [discreteCategory.id, idValue]290exact shape291292theorem discreteCategory.isomorphism (X f : Set)293requires fInM : f ∈ mor(discreteCategory(X))294shows Isomorphism(discreteCategory(X), f)295proof296have category := discreteCategory.category at X297have xInObjects : ∀ x ∈ X, x ∈ obj(discreteCategory(X))298intros x xInX299rw discreteCategory.obj300exact xInX301obtain⟨x, xInX, shape⟩:= discreteCategory.morphism with fInM302have xInO := xInObjects with x, xInX303rw shape304exact Isomorphism.id with category, xInO305306-- A monoid as a category with one object, the carrier itself.307theorem composablePairsOf.constant (A c : Set)308shows composablePairsOf(A, constantFunction(A, {A}, A),309 constantFunction(A, {A}, A)) = A × A310proof311have selfIn := singleton.self at A312ext p313constructor314 . intro member315obtain⟨bounded, rest⟩:= composablePairsOf.membership.forward with member316exact bounded317 . intro member318obtain⟨bound, g, gInA, f, fInA, shape⟩:= product.membership.forward with319 member320have gValue := constantFunction.apply with gInA, selfIn321have fValue := constantFunction.apply with fInA, selfIn322have composable : constantFunction(A, {A}, A)(g) =323 constantFunction(A, {A}, A)(f) bycc324rw shape325exact composablePairsOf.pair with gInA, fInA, composable326327def monoidCategory (A op unit : Set) : Set:=328 Category.mk({A}, A, constantFunction(A, {A}, A), constantFunction(A, {A}, A),329 constantFunction({A}, A, unit), op)330331theorem monoidCategory.category (A op unit : Set)332requires monoid : IsMonoid(A, op, unit)333shows Category(monoidCategory(A, op, unit))334proof335obtain⟨semigroup, identity⟩:= monoid336obtain⟨magma, associative⟩:= semigroup337obtain⟨unitInA, identityLaws⟩:= identity338unfold IsMagma at magma339have selfIn := singleton.self at A340have constant := constantFunction.function at A, {A}, A with selfIn341have identities := constantFunction.function at {A}, A, unit with unitInA342have pairs := composablePairsOf.constant at A, A343have operation : op : composablePairsOf(A, constantFunction(A, {A}, A),344 constantFunction(A, {A}, A)) → A345rw pairs346exact magma347have closed : ∀ g ∈ A, ∀ f ∈ A, op(g, f) ∈ A348intros g gInA f fInA349have pairIn := product.pair with gInA, fInA350unfold call2351exact FunctionBetween.apply_closed with magma, pairIn352unfold monoidCategory353apply Category.intro with constant, constant, identities, operation354 . intros a aInO355have aValue := singleton.membership.forward with aInO356have idValue := constantFunction.apply with aInO, unitInA357have domValue := constantFunction.apply with unitInA, selfIn358rw idValue359rw domValue360refine⟨?_, ?_⟩361 . symm362exact aValue363 . symm364exact aValue365 . intros g gInA f fInA composable366have gfInA := closed with g, gInA, f, fInA367have gValue := constantFunction.apply with gInA, selfIn368have fValue := constantFunction.apply with fInA, selfIn369have gfValue := constantFunction.apply with gfInA, selfIn370refine⟨?_, ?_⟩371 . cc372 . cc373 . intros f fInA374have fValue := constantFunction.apply with fInA, selfIn375have idValue := constantFunction.apply with selfIn, unitInA376obtain⟨leftUnit, rightUnit⟩:= identityLaws with f, fInA377rw fValue378rw idValue379refine⟨leftUnit, rightUnit⟩380 . intros h hInA g gInA f fInA outer inner381exact associative with h, hInA, g, gInA, f, fInA382