AlgebraicJulia / AlgebraicJulia/Catlab.jl

Functor types

オープン
#194 コメント 5 件 リアクション 0 件 担当者 0 名 GitHub で見る
enhancement
主要言語
Julia
スター
724
フォーク
73
PR マージ指標
30日以内にマージされた PR はありません

説明

Why don't we create an abstract type Functor that has the API:

```julia
dom(F::Functor)::Theory
codom(F::Functor)::Theory
function (F::Functor)(x::Ob{:generator})
...
end
function (F::Functor)(f::Hom{:compose})
foldl(compose, map(x->F(x), f.args))
end
function (F::Functor)(f::Hom{:generator})
...
end
```

The idea being that the functor type creator just has to specify what happens on the generators of the theory and the term constructors. Then the `MonoidalFunctor <: AbstractFunctor` would have the following additional method definitions:

```julia
function (F::MonoidalFunctor)(x::Ob{:otimes})
foldl(otimes, map(F, x.args))
end
function (F::MonoidalFunctor)(f::Hom{:compose})
foldl(compose, map(F, f.args))
end
function (F::MonoidalFunctor)(f::Hom{:otimes})
foldl(otimes, map(F, f.args))
end
```

In this setting, in order to make a functor, you would just have to define a type `MyFunctor<:MonoidalFunctor` which supplies the action on the generators. We could supply a `PresentedMonoidalFunctor` which works like the current implementation by storing a dictionary mapping the generators to their images under the functor.

```julia
struct PresentedMonoidalFunctor{K,V} <: MonoidalFunctor
g::Dict{K,V}
end
function (F::PresentedMonoidalFunctor)(x::Ob{:generator})
F.g[x]
end
function (F::PresentedMonoidalFunctor)(f::Hom{:generator})
F.g[x]
end
```

I think we could simplify a lot of this code if we store the GATExprs with the
operation as a `Function` instead of a `Symbol`. The current implementation looks
like:

```julia
julia> X = Ob(FreeSymmetricMonoidalCategory, :X)
julia> dump(X)
Catlab.Theories.FreeSymmetricMonoidalCategory.Ob{:generator}
args: Array{Symbol}((1,))
1: Symbol X
type_args: Array{GATExpr}((0,))
```

Instead of storing `head(ex) == :otimes` we could store the function `otimes`, this would allow a single abstract functor type with the idea that the codomain category will support all the term constructors of the domain category so that you can implement arbitrary GAT functors:

```julia
function (F::Functor)(x)
foldl(head(x), map(F, x.args))
end

#you still need a base case for generators
Generator = Union{Ob{:generator}, Hom{:generator}}
function (F::Functor)(x::Generator)
F.g[x]
end
```

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。