Browse Source

Merge pull request #372 from AlgebraicJulia/serialization

JSON serialization and deserialization of ACSets
master
Evan Patterson 1 week ago
committed by GitHub
parent
commit
ec4767600e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 3 deletions
  1. +49
    -1
      src/categorical_algebra/CSets.jl
  2. +13
    -2
      test/categorical_algebra/CSets.jl

+ 49
- 1
src/categorical_algebra/CSets.jl View File

@ -2,11 +2,12 @@
"""
module CSets
export ACSetTransformation, CSetTransformation, components, force, is_natural,
migrate!
migrate!, generate_json_acset, parse_json_acset, read_json_acset, write_json_acset
using Compat: isnothing
using AutoHashEquals
using JSON
using Reexport
using StaticArrays: SVector
@ -353,4 +354,51 @@ function (::Type{T})(X::ACSet, FOb::AbstractDict,
migrate!(Y, X, FOb, FHom)
end
""" Serialize an ACSet object to a JSON string
"""
function generate_json_acset(x::T) where T <: AbstractACSet
JSON.json(x.tables)
end
""" Deserialize a dictionary from a parsed JSON string to an object of the given ACSet type
"""
function parse_json_acset(type::Type{T}, input::Dict) where T <: AbstractACSet
out = type()
for (k,v) input
add_parts!(out, Symbol(k), length(v))
end
for l values(input)
for (i, j) enumerate(l)
for (k,v) j
vtype = eltype(out[Symbol(k)])
if !(typeof(v) <: vtype)
v = vtype(v)
end
set_subpart!(out, i, Symbol(k), v)
end
end
end
out
end
""" Deserialize a JSON string to an object of the given ACSet type
"""
function parse_json_acset(type::Type{T}, input::String) where T <: AbstractACSet
parse_json_acset(type, JSON.parse(input))
end
""" Read a JSON file to an object of the given ACSet type
"""
function read_json_acset(type::Type{T}, input::String) where T <: AbstractACSet
parse_json_acset(type, open(f->read(f, String), input))
end
""" Serialize an ACSet object to a JSON file
"""
function write_json_acset(x::T, fname::AbstractString) where T <: AbstractACSet
open(string(fname), "w") do f
write(f, generate_json_acset(x))
end
end
end

+ 13
- 2
test/categorical_algebra/CSets.jl View File

@ -5,6 +5,14 @@ using Catlab, Catlab.Theories, Catlab.Graphs, Catlab.CategoricalAlgebra,
Catlab.CategoricalAlgebra.FinSets
using Catlab.Graphs.BasicGraphs: TheoryGraph
function roundtrip_json_acset(x::T) where T <: AbstractACSet
mktempdir() do dir
path = joinpath(dir, "acset.json")
write_json_acset(x, path)
read_json_acset(T, path)
end
end
# FinSets interop
#################
@ -17,6 +25,7 @@ f = FinFunction(g, :src)
@test codom(f) == FinSet(6)
@test collect(f) == 2:4
@test is_indexed(f)
@test roundtrip_json_acset(g) == g
f = FinDomFunction(g, :E)
@test collect(f) == 1:3
@ -31,6 +40,7 @@ add_edges!(g, 1:2, 2:3, weight=[0.5, 1.5])
f = FinDomFunction(g, :weight)
@test codom(f) == TypeSet(Float64)
@test collect(f) == [0.5, 1.5]
@test roundtrip_json_acset(g) == g
# C-set morphisms
#################
@ -248,6 +258,7 @@ add_edge!(h, 1, 1, elabel=:f)
coprod = ob(coproduct(g, h))
@test subpart(coprod, :vlabel) == [:u, :v, :u]
@test subpart(coprod, :elabel) == [:e, :f]
@test roundtrip_json_acset(g) == g
# Pushout of labeled graph.
g0 = LabeledGraph{Symbol}()
@ -280,7 +291,7 @@ h = Graph(3)
add_parts!(h, :E, 3, src = [1,2,3], tgt = [2,3,1])
# Identity data migration.
@test h == Graph(h, Dict(:V => :V, :E => :E),
@test h == Graph(h, Dict(:V => :V, :E => :E),
Dict(:src => :src, :tgt => :tgt))
# Migrate DDS → Graph.
@ -314,6 +325,6 @@ add_parts!(wg, :E, 4, src=[1,2,3,4], tgt=[2,3,4,1], weight=[101, 102, 103, 100])
@test wg == WeightedGraph{Int}(ldds,
Dict(:V => :X, :E => :X),
Dict(:src => id(X), :tgt => :Φ, :weight => [:Φ, :label]))
@test roundtrip_json_acset(ldds) == ldds
end

Loading…
Cancel
Save