Skip to content

Commit

Permalink
ENH: @migrate macro as shorthand for @migration then migrate.
Browse files Browse the repository at this point in the history
  • Loading branch information
epatters committed Nov 21, 2021
1 parent 370efe4 commit e4e57d0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 31 deletions.
1 change: 1 addition & 0 deletions src/categorical_algebra/CSetDataStructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ end
# StructACSet Operations
########################

Presentation(::Type{<:StructACSet{S}}) where S = Presentation(S)
Presentation(::StructACSet{S}) where S = Presentation(S)

# Accessors
Expand Down
43 changes: 30 additions & 13 deletions src/programs/DiagrammaticPrograms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ string diagram or wiring diagram. DSLs for constructing wiring diagrams are
provided by other submodules.
"""
module DiagrammaticPrograms
export @graph, @fincat, @finfunctor, @diagram, @migration
export @graph, @fincat, @finfunctor, @diagram, @migrate, @migration

using Base.Iterators: repeated
using MLStyle: @match
Expand All @@ -26,7 +26,9 @@ using ...Graphs.BasicGraphs: TheoryGraph
ename::Attr(E, Name)
end

""" Default graph type for [`@fincat`](@ref) macro and related macros.
""" Graph with uniquely named vertices and edges.
THe default graph type for the [`@fincat`](@ref) macro and related macros.
"""
@acset_type NamedGraph(TheoryNamedGraph, index=[:src,:tgt],
unique_index=[:vname,:ename]) <: AbstractGraph
Expand All @@ -41,9 +43,10 @@ end
@acset_type _MaybeNamedGraph(TheoryMaybeNamedGraph, index=[:src,:tgt],
unique_index=[:vname]) <: AbstractGraph

""" Default graph type for [`@graph`](@ref) macro.
""" Graph with named vertices and possibly named edges.
Vertex names are uniquely indexed and edge names are optional and unindexed.
The default graph type for the [`@graph`](@ref) macro. Vertex names are uniquely
indexed and edge names are optional and unindexed.
"""
const MaybeNamedGraph{Name} = _MaybeNamedGraph{Name,Union{Nothing,Name}}

Expand Down Expand Up @@ -300,14 +303,15 @@ diagram in ``C``, i.e., constructs a finitely presented indexing category ``J``
together with a functor ``F: J → C``. This method of simultaneous definition is
often more convenient than defining ``J`` and ``F`` separately.
For example, the following diagram specifies the paths of length two in a graph:
For example, the limit of the following diagram consists of the paths of length
two in a graph:
```julia
@diagram FinCat(TheoryGraph) begin
v::V
(e1, e2)::E
(t: e1 → v)::tgt
(s: e2 → v)::src
(e₁, e₂)::E
(t: e₁ → v)::tgt
(s: e₂ → v)::src
end
```
"""
Expand Down Expand Up @@ -373,7 +377,8 @@ end

""" A diagram without a codomain category.
Internal data type used by parser in [`@migration`](@ref) macro.
An intermediate data representation used internally by the parser for the
[`@migration`](@ref) macro.
"""
struct DiagramData{T,ObMap,HomMap,Shape<:FinCat}
ob_map::ObMap
Expand All @@ -392,7 +397,8 @@ Diagrams.shape(d::DiagramData) = d.shape

""" A diagram morphism without a domain or codomain.
Internal data type used by parser in [`@migration`](@ref) macro.
Like [`DiagramData`](@ref), an intermediate data representation used internally
by the parser for the [`@migration`](@ref) macro.
"""
struct DiagramHomData{T,ObMap,HomMap}
ob_map::ObMap
Expand All @@ -403,10 +409,21 @@ struct DiagramHomData{T,ObMap,HomMap}
end
end

""" Define a data migration query.
""" Contravariantly migrate data from one acset to another.
"""
macro migrate(tgt_type, src_acset, body)
quote
let T = $(esc(tgt_type)), X = $(esc(src_acset))
migrate(T, X, parse_migration(Presentation(T), Presentation(X),
$(Meta.quot(body))))
end
end
end

""" Define a contravariant data migration.
This macro provides a DSL to specify a data migration query from a ``C``-set to
a ``D``-set for arbitrary schemas ``C`` and ``D``.
This macro provides a DSL to specify a contravariant data migration from
``C``-sets to ``D``-sets for given schemas ``C`` and ``D``.
"""
macro migration(src_schema, body)
:(parse_migration($(esc(src_schema)), $(Meta.quot(body))))
Expand Down
2 changes: 1 addition & 1 deletion src/theories/Schema.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function SchemaDescTypeType(s::SchemaDesc)
}
end

function Presentation(S::Type{T}) where T <: SchemaDescType
function Presentation(::Type{S}) where S <: SchemaDescType
pres = Presentation(FreeSchema)

obs = map(x -> Ob(FreeSchema, x), collect(ob(S)))
Expand Down
28 changes: 11 additions & 17 deletions test/categorical_algebra/DataMigrations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ using Test

using Catlab, Catlab.Theories, Catlab.Graphs, Catlab.CategoricalAlgebra
using Catlab.Programs.DiagrammaticPrograms
using Catlab.Graphs.BasicGraphs: TheoryGraph, TheoryReflexiveGraph,
TheorySymmetricGraph, TheorySymmetricReflexiveGraph, TheoryWeightedGraph
using Catlab.Graphs.BasicGraphs: TheoryGraph, TheoryWeightedGraph
using Catlab.Graphs.BipartiteGraphs: TheoryUndirectedBipartiteGraph

# Contravariant migration
Expand Down Expand Up @@ -129,7 +128,8 @@ migrate!(h, g, F)
@test sort!(collect(zip(h[:src], h[:tgt]))) == [(6,8), (7,9), (8,10)]

# Graph whose vertices are paths of length 2 and edges are paths of length 3.
F = @migration TheoryGraph TheoryGraph begin
g = path_graph(Graph, 6)
h = @migrate Graph g begin
V => @join begin
v::V
(e₁, e₂)::E
Expand All @@ -147,39 +147,36 @@ F = @migration TheoryGraph TheoryGraph begin
src => (v => v₁; e₁ => e₁; e₂ => e₂; t => t₁; s => s₁)
tgt => (v => v₂; e₁ => e₂; e₂ => e₃; t => t₂; s => s₂)
end
g = path_graph(Graph, 6)
h = migrate(Graph, g, F)
@test h == path_graph(Graph, 4)

# Gluing migration
#-----------------

# Free reflexive graph on a graph.
F = @migration TheoryReflexiveGraph TheoryGraph begin
g = cycle_graph(Graph, 5)
h = @migrate ReflexiveGraph g begin
V => V
E => @cases (v::V; e::E)
src => (e => src)
tgt => (e => tgt)
refl => v
end
g = cycle_graph(Graph, 5)
h = migrate(ReflexiveGraph, g, F)
@test h == cycle_graph(ReflexiveGraph, 5)

# Free symmetric graph on a graph.
F = @migration TheorySymmetricGraph TheoryGraph begin
g = star_graph(Graph, 5)
h = @migrate SymmetricGraph g begin
V => V
E => @cases (fwd::E; rev::E)
src => (fwd => src; rev => tgt)
tgt => (fwd => tgt; rev => src)
inv => (fwd => rev; rev => fwd)
end
g = star_graph(Graph, 5)
h = migrate(SymmetricGraph, g, F)
@test is_isomorphic(h, star_graph(SymmetricGraph, 5))

# Free symmetric reflexive graph on a reflexive graph.
F = @migration TheorySymmetricReflexiveGraph TheoryReflexiveGraph begin
g = star_graph(ReflexiveGraph, 5)
h = @migrate SymmetricReflexiveGraph g begin
V => V
E => @glue begin
(fwd, rev)::E
Expand All @@ -195,15 +192,14 @@ F = @migration TheorySymmetricReflexiveGraph TheoryReflexiveGraph begin
refl_fwd => refl_rev; refl_rev => refl_fwd
end
end
g = star_graph(ReflexiveGraph, 5)
h = migrate(SymmetricReflexiveGraph, g, F)
@test is_isomorphic(h, star_graph(SymmetricReflexiveGraph, 5))

# Gluc migration
#---------------

# Graph with edges that are paths of length <= 2.
F = @migration TheoryGraph TheoryGraph begin
g = path_graph(Graph, 4)
h = @migrate Graph g begin
V => V
E => @cases begin
v => V
Expand All @@ -218,8 +214,6 @@ F = @migration TheoryGraph TheoryGraph begin
src => (e => src; path => e₁src)
tgt => (e => tgt; path => e₂tgt)
end
g = path_graph(Graph, 4)
h = migrate(Graph, g, F)
h′ = @acset Graph begin
V = 4
E = 9
Expand Down

0 comments on commit e4e57d0

Please sign in to comment.