Skip to content

Commit

Permalink
Merge pull request #532 from epatters/data-migration
Browse files Browse the repository at this point in the history
Data migration using conjunctive queries
  • Loading branch information
epatters committed Oct 28, 2021
2 parents e57d470 + 8a90889 commit 629c462
Show file tree
Hide file tree
Showing 21 changed files with 1,234 additions and 591 deletions.
13 changes: 8 additions & 5 deletions docs/src/apis/programs.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ There are two major macros for constructing wiring diagrams:
- [`@program`](@ref), for directed wiring diagrams
- [`@relation`](@ref), for undirected wiring diagrams

In addition, there is a family of macros for constructing category-theoretic
[diagrams](https://ncatlab.org/nlab/show/diagram):
In addition, there is a family of related macros for constructing
category-theoretic [diagrams](https://ncatlab.org/nlab/show/diagram):

- [`@graph`](@ref), for defining a graph
- [`@category`](@ref), for presenting a category as a graph plus path equations
- [`@diagram`](@ref), for defining a diagram in a given category
- [`@graph`](@ref), for constructing a graph
- [`@fincat`](@ref), for presenting a category as a graph together with path
equations
- [`@finfunctor`](@ref), for defining a functor between two finitely presented
categories
- [`@diagram`](@ref), for defining a diagram in a category

## API

Expand Down
125 changes: 83 additions & 42 deletions src/categorical_algebra/CSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ using Reexport
using Tables

@reexport using ...CSetDataStructures
using ...GAT, ..FreeDiagrams, ..Limits, ..Subobjects, ..Sets, ..FinSets
using ...GAT, ...Present
using ..FreeDiagrams, ..Limits, ..Subobjects, ..FinSets, ..FinCats
import ..Limits: limit, colimit, universal, pushout_complement,
can_pushout_complement
import ..Subobjects: Subobject, SubobjectBiHeytingAlgebra,
implies, , subtract, \, negate, ¬, non, ~
import ..Sets: TypeSet
import ..Sets: SetOb, SetFunction, TypeSet
import ..FinSets: FinSet, FinFunction, FinDomFunction, force, predicate
import ..FinCats: components, is_natural
import ..FinCats: FinDomFunctor, components, is_natural
using ...Theories: Category, SchemaDescType, CSetSchemaDescType,
attrtype, attrtype_num, attr, adom, acodom, acodom_nums, roottype
import ...Theories: dom, codom, compose, , id,
Expand All @@ -32,51 +33,95 @@ import ...Theories: dom, codom, compose, ⋅, id,
# Sets interop
##############

""" Create `FinSet` for part of attributed C-set.
""" Create `SetOb` for object or attribute type of attributed C-set.
For objects, the result is a `FinSet`; for attribute types, a `TypeSet`.
"""
FinSet(X::StructACSet, type::Symbol) = FinSet{Int,Int}(nparts(X, type))
@inline SetOb(X::StructACSet, type::Symbol)::SetOb = set_ob(X, Val{type})

@generated function set_ob(X::StructACSet{S,Ts},
::Type{Val{type}}) where {S,Ts,type}
if type ob(S)
:(FinSet(X, $(Meta.quot(type))))
elseif type attrtype(S)
T = Ts.parameters[attrtype_num(S, type)]
:(TypeSet{$T}())
else
throw(ArgumentError("$(repr(type)) not in $(ob(S)) or $(attrtype(S))"))
end
end

""" Create `FinFunction` for part or subpart of attributed C-set.
""" Create `FinSet` for object of attributed C-set.
"""
@inline FinSet(X::StructACSet, type::Symbol) = FinSets.FinSetInt(nparts(X, type))

The subpart must be of kind `Ob`. For indexed subparts, the index is included.
""" Create `TypeSet` for object or attribute type of attributed C-set.
"""
FinFunction(X::StructACSet, name::Symbol) = fin_function(X, Val{name})
@inline TypeSet(X::StructACSet, type::Symbol)::TypeSet = type_set(X, Val{type})

@generated function type_set(X::StructACSet{S,Ts},
::Type{Val{type}}) where {S,Ts,type}
T = if type ob(S)
Int
elseif type attrtype(S)
Ts.parameters[attrtype_num(S, type)]
else
throw(ArgumentError("$(repr(type)) not in $(ob(S)) or $(attrtype(S))"))
end
:(TypeSet{$T}())
end

@generated function fin_function(X::StructACSet{S,Ts,Idxed},
::Type{Val{name}}) where {Ts,S,Idxed,name}
if name ob(S)
quote
FinFunction(identity, FinSet(X, $(QuoteNode(name))))
end
""" Create `SetFunction` for morphism or attribute of attributed C-set.
For morphisms, the result is a `FinFunction`; for attributes, a
`FinDomFunction`.
"""
@inline SetFunction(X::StructACSet, name::Symbol)::SetFunction =
set_function(X, Val{name})

@generated function set_function(X::StructACSet{S,Ts,Idxed},
::Type{Val{name}}) where {S,Ts,Idxed,name}
if name ob(S) || name attrtype(S)
:(SetFunction(identity, SetOb(X, $(Meta.quot(name)))))
elseif name hom(S)
quote
FinFunction(subpart(X, $(QuoteNode(name))),
FinSet(X, $(QuoteNode(codom(S, name)))),
FinFunction(subpart(X, $(Meta.quot(name))),
FinSet(X, $(Meta.quot(codom(S, name)))),
index=$(Idxed[name] ? :(X.hom_indices.$name) : false))
end
elseif name attr(S)
:(FinDomFunction(X, $(Meta.quot(name))))
else
throw(ArgumentError("$(repr(name)) not in $(ob(S)) or $(hom(S))"))
throw(ArgumentError("$(repr(name)) does not belong to schema $S"))
end
end

""" Create `FinDomFunction` for part or subpart of attributed C-set.
""" Create `FinFunction` for morphism of attributed C-set.
Indices are included whenever they exist.
"""
@inline FinFunction(X::StructACSet, name::Symbol)::FinFunction =
set_function(X, Val{name})

""" Create `FinDomFunction` for morphism or attribute of attributed C-set.
The codomain is always of type `TypeSet`, regardless of whether the subpart is
of kind `Ob` or `AttrType`. For indexed subparts, the index is included.
Indices are included whenever they exist. Unlike the `FinFunction` constructor,
the codomain of the result is always of type `TypeSet`.
"""
FinDomFunction(X::StructACSet, name::Symbol) = fin_dom_function(X, Val{name})
@inline FinDomFunction(X::StructACSet, name::Symbol)::FinDomFunction =
fin_dom_function(X, Val{name})

@generated function fin_dom_function(X::StructACSet{S,Ts,Idxed},
::Type{Val{name}}) where {S,Ts,Idxed,name}
if name ob(S)
quote
n = nparts(X, $(QuoteNode(name)))
n = nparts(X, $(Meta.quot(name)))
FinDomFunction(1:n, FinSet(n), TypeSet{Int}())
end
elseif name hom(S) || name attr(S)
index_name = name hom(S) ? :hom_indices : :attr_indices
quote
FinDomFunction(subpart(X, $(QuoteNode(name))),
FinDomFunction(subpart(X, $(Meta.quot(name))),
index=$(Idxed[name] ? :(X.$index_name.$name) : false))
end
else
Expand All @@ -85,12 +130,13 @@ FinDomFunction(X::StructACSet, name::Symbol) = fin_dom_function(X, Val{name})
end
end

""" Create `TypeSet` for attribute type of attributed C-set.
"""
function TypeSet(X::ACS, type::Symbol) where {S, ACS <: StructACSet{S}}
i = attrtype_num(S, type)
TypeSet(ACS.parameters[i])
function FinDomFunctor(C::FinCats.FinCatPresentation, X::ACSet)
# TODO: Make struct `FinDomFunctorACSet` to avoid allocation.
ob_map = Dict(c => SetOb(X, nameof(c)) for c in ob_generators(C))
hom_map = Dict(f => SetFunction(X, nameof(f)) for f in hom_generators(C))
FinDomFunctor(ob_map, hom_map, C)
end
FinDomFunctor(pres::Presentation, X::ACSet) = FinDomFunctor(FinCat(pres), X)

# C-set transformations
#######################
Expand Down Expand Up @@ -747,18 +793,17 @@ unpack_diagram(comp::ComposableMorphisms{<:ACSet}; kw...) =

function unpack_diagram(diag::Union{FreeDiagram{ACS},BipartiteFreeDiagram{ACS}};
all::Bool=false) where {S, ACS <: StructACSet{S}}
fin_diagrams = (c => map(diag, Ob=X->FinSet(X,c), Hom=α->α[c])
for c in ob(S))
NamedTuple(all ?
flatten((fin_diagrams, (d => map(diag, Ob=X->TypeSet(X,d), Hom=α->α[d])
for d in attrtype(S)))) :
fin_diagrams)
names = all ? flatten((ob(S), attrtype(S))) : ob(S)
NamedTuple(c => map(diag, Ob=X->SetOb(X,c), Hom=α->α[c]) for c in names)
end

""" Vector of C-sets → named tuple of vectors of sets.
"""
function unpack_sets(Xs::AbstractVector{<:StructACSet{S}};
all::Bool=false) where S
# XXX: The explicit use of `FinSet` and `TypeSet` is needed here for the
# nullary case (empty vector) because the Julia compiler cannot infer the
# return type of the more general `SetOb`.
fin_sets = (c => map(X->FinSet(X,c), Xs) for c in ob(S))
NamedTuple(all ?
flatten((fin_sets, (d => map(X->TypeSet(X,d), Xs) for d in attrtype(S)))) :
Expand All @@ -769,10 +814,8 @@ end
"""
function unpack_components(αs::AbstractVector{<:ACSetTransformation{S}};
all::Bool=false) where S
fin_components = (c => map-> α[c], αs) for c in ob(S))
NamedTuple(all ?
flatten((fin_components, (d => map-> α[d], αs) for d in attrtype(S)))) :
fin_components)
names = all ? flatten((ob(S), attrtype(S))) : ob(S)
NamedTuple(c => map-> α[c], αs) for c in names)
end

""" Named tuple of vectors of FinFunctions → vector of C-set transformations.
Expand All @@ -786,10 +829,8 @@ end
""" C-set → named tuple of sets.
"""
function sets(X::StructACSet{S}; all::Bool=false) where S
fin_sets = (c => FinSet(X,c) for c in ob(S))
NamedTuple(all ?
flatten((fin_sets, (d => TypeSet(X,d) for d in attrtype(S)))) :
fin_sets)
names = all ? flatten((ob(S), attrtype(S))) : ob(S)
NamedTuple(c => SetOb(X,c) for c in names)
end

""" Compute pushout complement of attributed C-sets, if possible.
Expand Down
14 changes: 7 additions & 7 deletions src/categorical_algebra/CategoricalAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,38 @@ module CategoricalAlgebra

using Reexport

include("Categories.jl")
include("FinCats.jl")
include("FreeDiagrams.jl")
include("Limits.jl")
include("Subobjects.jl")
include("Sets.jl")
include("FinSets.jl")
include("Matrices.jl")
include("FinRelations.jl")
include("Categories.jl")
include("FinCats.jl")
include("CSets.jl")
include("GraphCategories.jl")
include("Diagrams.jl")
include("CommutativeDiagrams.jl")
include("CatElements.jl")
include("DataMigration.jl")
include("DataMigrations.jl")
include("StructuredCospans.jl")
include("DPO.jl")

@reexport using .Categories
@reexport using .FinCats
@reexport using .FreeDiagrams
@reexport using .Limits
@reexport using .Subobjects

@reexport using .Sets
@reexport using .FinSets
@reexport using .Categories
@reexport using .FinCats
@reexport using .CSets
@reexport using .CatElements

@reexport using .Diagrams
@reexport using .CommutativeDiagrams
@reexport using .CatElements
@reexport using .DataMigration
@reexport using .DataMigrations
@reexport using .StructuredCospans
@reexport using .DPO

Expand Down
25 changes: 8 additions & 17 deletions src/categorical_algebra/Categories.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ instances are supported through the wrapper type [`TypeCat`](@ref). Finitely
presented categories are provided by another module, [`FinCats`](@ref).
"""
module Categories
export Cat, TypeCat, Ob, Functor, Transformation,
dom, codom, compose, id, ob, hom, is_hom_equal,
ob_map, hom_map, dom_ob, codom_ob, component
export Cat, TypeCat, Functor, Transformation, dom, codom, compose, id,
ob, hom, is_hom_equal, ob_map, hom_map, dom_ob, codom_ob, component

using AutoHashEquals

using ...GAT, ..Sets
import ...Theories: Category2, Ob, ob, hom, dom, codom, compose, , , id,
using ...GAT
import ...Theories: Category2, ob, hom, dom, codom, compose, , , id,
composeH, *

# Categories
Expand Down Expand Up @@ -85,8 +84,6 @@ struct TypeCat{Ob,Hom} <: Cat{Ob,Hom} end

TypeCat(Ob::Type, Hom::Type) = TypeCat{Ob,Hom}()

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)
Expand All @@ -107,26 +104,20 @@ abstract type Functor{Dom<:Cat,Codom<:Cat} end

""" Evaluate functor on object.
"""
function ob_map end
@inline ob_map(F::Functor, x) = do_ob_map(F, x)

""" Evaluate functor on morphism.
"""
function hom_map end

""" Forgetful functor Ob: Cat → Set.
Sends a category to its set of objects and a functor to its object map.
"""
function Ob end
@inline hom_map(F::Functor, f) = do_hom_map(F, f)

@auto_hash_equals struct IdentityFunctor{Dom<:Cat} <: Functor{Dom,Dom}
dom::Dom
end

codom(F::IdentityFunctor) = F.dom

ob_map(F::IdentityFunctor, x) = ob(F.dom, x)
hom_map(F::IdentityFunctor, f) = hom(F.dom, f)
do_ob_map(F::IdentityFunctor, x) = ob(F.dom, x)
do_hom_map(F::IdentityFunctor, f) = hom(F.dom, f)

# Instances
#----------
Expand Down
Loading

0 comments on commit 629c462

Please sign in to comment.