Skip to content

Commit

Permalink
ENH: Data structure for discrete categories.
Browse files Browse the repository at this point in the history
A trivial, yet useful, special case.
  • Loading branch information
epatters committed Oct 19, 2021
1 parent 716157c commit 14cec53
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
18 changes: 4 additions & 14 deletions src/categorical_algebra/Categories.jl
Expand Up @@ -40,21 +40,13 @@ The basic operations available in any category are: [`dom`](@ref),
"""
abstract type Cat{Ob,Hom} end

""" Look up object in category.
```julia
ob(C::Cat{Ob,Hom}, x)::Ob where {Ob,Hom}
```
""" Coerce or look up object in category.
"""
function ob end

""" Look up morphism in category.
ob(::Cat, x) = x

```julia
hom(C::Cat{Ob,Hom}, f)::Hom where {Ob,Hom}
```
""" Coerce or look up morphism in category.
"""
function hom end
hom(::Cat, f) = f

""" Domain of morphism in category.
"""
Expand Down Expand Up @@ -89,8 +81,6 @@ Ob(::TypeCat{T}) where T = TypeSet{T}()
# FIXME: This isn't practical because types are often too tight.
#ob(::TypeCat{Ob,Hom}, x) where {Ob,Hom} = convert(Ob, x)
#hom(::TypeCat{Ob,Hom}, f) where {Ob,Hom} = convert(Hom, f)
ob(::TypeCat, x) = x
hom(::TypeCat, f) = f

# Functors
##########
Expand Down
23 changes: 23 additions & 0 deletions src/categorical_algebra/FinCats.jl
Expand Up @@ -59,6 +59,29 @@ is_free(C::FinCat) = isempty(equations(C))

Ob(C::FinCat{Int}) = FinSet(length(ob_generators(C)))

# Discrete categories
#####################

""" Discrete category on a finite set.
The only morphisms in a discrete category are the identities, which in this
implementation are identified with the objects.
"""
@auto_hash_equals struct DiscreteCat{Ob,S<:FinSet{<:Any,Ob}} <: FinCat{Ob,Ob}
set::S
end

FinCat(s::FinSet) = DiscreteCat(s)

ob_generators(C::DiscreteCat) = C.set
hom_generators(C::DiscreteCat) = ()

dom(C::DiscreteCat{T}, f) where T = f::T
codom(C::DiscreteCat{T}, f) where T = f::T
id(C::DiscreteCat{T}, x) where T = x::T
compose(C::DiscreteCat{T}, f, g) where T = (f::T == g::T) ? f :
error("Nontrivial composite in discrete category: $f != $g")

# Categories on graphs
######################

Expand Down
14 changes: 12 additions & 2 deletions test/categorical_algebra/FinCats.jl
Expand Up @@ -4,6 +4,16 @@ using Test
using Catlab, Catlab.Theories, Catlab.CategoricalAlgebra, Catlab.Graphs
using Catlab.Graphs.BasicGraphs: TheoryGraph

# Discrete categories
#####################

C = FinCat(FinSet(3))
@test C isa FinCat{Int,Int}
@test collect(ob_generators(C)) == 1:3
@test isempty(hom_generators(C))
@test (dom(C, 1), codom(C, 1)) == (1, 1)
@test (id(C, 2), compose(C, 2, 2)) == (2, 2)

# Categories on graphs
######################

Expand Down Expand Up @@ -143,14 +153,14 @@ G = FinDomFunctor(TheoryGraph, g)
@test ασ == FinTransformation(F, G, V=FinFunction([1,2,2]), E=FinFunction([2,4]))

# Pullback data migration by pre-whiskering.
ιV = FinFunctor([:V], [], FinCat(Graph(1)), FinCat(TheoryGraph))
ιV = FinFunctor([:V], [], FinCat(FinSet(1)), FinCat(TheoryGraph))
αV = ιV * α
@test ob_map(dom(αV), 1) == ob_map(F, :V)
@test ob_map(codom(αV), 1) == ob_map(G, :V)
@test component(αV, 1) == component(α, :V)

# Post-whiskering and horizontal composition.
ιE = FinFunctor([:E], [], FinCat(Graph(1)), FinCat(TheoryGraph))
ιE = FinFunctor([:E], [], FinCat(FinSet(1)), FinCat(TheoryGraph))
ϕ = FinTransformation([:src], ιE, ιV)
@test is_natural(ϕ)
@test component*F, 1) == hom_map(F, :src)
Expand Down

0 comments on commit 14cec53

Please sign in to comment.