Skip to content

Commit

Permalink
Read and Write JSON ACSetTransformations
Browse files Browse the repository at this point in the history
  • Loading branch information
lukem12345 committed Oct 31, 2023
1 parent 5e24202 commit 8ff21ea
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 73 deletions.
118 changes: 48 additions & 70 deletions src/categorical_algebra/JSONCSetTransformations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
"""
module JSONCSetTransformations
export generate_json_fin_function, parse_json_fin_function,
read_json_fin_function, write_json_fin_function#=,
read_json_fin_function, write_json_fin_function,
generate_json_acset_transformation, parse_json_acset_transformation,
read_json_acset_transformation, write_json_acset_transformation=#
read_json_acset_transformation, write_json_acset_transformation

import JSON
using DataStructures: OrderedDict
#import Pkg
#import Tables

using ..FinSets, ..CSets
# TODO: Some of these `using`s might not be necessary.
using ACSets.ACSetInterface, ACSets.Schemas, ACSets.DenseACSets
using ACSets.DenseACSets: attr_type
using ACSets.ColumnImplementations: AttrVar

# ACSetTransformation serialization
#####################
Expand Down Expand Up @@ -65,72 +59,56 @@ function generate_json_acset_transformation(X::ACSetTransformation)
:dom => (generate_json_acset dom)(X),
:codom => (generate_json_acset codom)(X),
:components => OrderedDict{Symbol,Any}(
Iterators.map((keys components)(X), (values components)(X)) do (k,v)
k => k (attrtypes acset_schema dom)(X) ?
"foo" :
generate_json_fin_function(k)
Iterators.map((keys components)(X), (values components)(X)) do k,v
k , k (attrtypes acset_schema dom)(X) ?
# TODO: Support VarFunctions that are not empty.
"TODO: VarFunctions are current not supported." :
generate_json_fin_function(v)
end))
end

""" Serialize an ACSetTransformation object to a JSON file.
#attr_to_json(var::AttrVar) = (_var = var.val,)
#attr_to_json(val) = val
#
#""" Parse JSON-able object or JSON string representing an ACSet.
#
#Inverse to [`generate_json_acset`](@ref).
#"""
#parse_json_acset_transformation(cons, input::AbstractDict) =
# parse_json_acset!(cons(), input)
#parse_json_acset_transformation(cons, input::AbstractString) =
# parse_json_acset_transformation(cons, JSON.parse(input))
#parse_json_acset_transformation(acs::ACSet, input::AbstractDict) =
# parse_json_acset_transformation(constructor(acs), input)
#
## TODO
#function parse_json_acset_transformation!(out::ACSetTransformation, input::AbstractDict)
# schema = acset_schema(out)
# parts = Iterators.map(input) do (type, rows)
# Symbol(type) => add_parts!(out, Symbol(type), length(rows))
# end |> Dict
# for rows ∈ values(input)
# for (rownum, row) ∈ enumerate(rows)
# for (k, v) ∈ pairs(row)
# k = Symbol(k)
# if k == :_id
# # For now, IDs are assumed to coincide with row number.
# @assert rownum == v
# continue
# end
# if k ∈ attrs(schema; just_names=true)
# vtype = attr_type(out, k)
# v = v isa AbstractDict && haskey(v, "_var") ?
# AttrVar(v["_var"]) : vtype(v)
# end
# set_subpart!(out, parts[dom(schema, k)][rownum], k, v)
# end
# end
# end
# out
#end
#
#""" Deserialize an ACSetTransformation object from a JSON file.
#
#Inverse to [`write_json_acset_transformation`](@ref).
#"""
#function read_json_acset_transformation(ty, fname::AbstractString)
# parse_json_acset_transformation(ty, JSON.parsefile(fname))
#end
#
#""" Serialize an ACSetTransformation object to a JSON file.
#
#Inverse to [`read_json_acset_transformation`](@ref).
#"""
#function write_json_acset_transformation(x::ACSetTransformation, fname::AbstractString)
# open(fname, "w") do f
# write(f, JSON.json(generate_json_acset_transformation(x)))
# end
#end
Inverse to [`read_json_acset_transformation`](@ref).
"""
function write_json_acset_transformation(x::ACSetTransformation, fname::AbstractString)
open(fname, "w") do f
write(f, JSON.json(generate_json_acset_transformation(x)))
end
end

""" Parse JSON-able object or JSON string representing an ACSetTransformation.
Inverse to [`generate_json_acset_transformation`](@ref).
"""
parse_json_acset_transformation(cons, input::AbstractString) =
parse_json_acset_transformation(cons, JSON.parse(input))
parse_json_acset_transformation(acs::ACSet, input::AbstractDict) =
parse_json_acset_transformation(constructor(acs), input)

function parse_json_acset_transformation(cons, input::AbstractDict)
domain = parse_json_acset(cons(), input["dom"])
codomain = parse_json_acset(cons(), input["codom"])
hom_keys = filter(keys(input["components"])) do k
Symbol(k) (attrtypes acset_schema)(domain)
end
# TODO: Support VarFunctions that are not empty.
ACSetTransformation(
NamedTuple{Tuple(Symbol.(hom_keys))}(
Iterators.map(hom_keys) do k
parse_json_fin_function(input["components"][k])
end),
domain,
codomain)
end

""" Deserialize an ACSetTransformation object from a JSON file.
Inverse to [`write_json_acset_transformation`](@ref).
"""
function read_json_acset_transformation(ty, fname::AbstractString)
parse_json_acset_transformation(ty, JSON.parsefile(fname))
end

end # module

6 changes: 3 additions & 3 deletions test/categorical_algebra/JSONCSetTransformations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ end
# ACSetTransformation serialization
###################################

function roundtrip_json_acset_transformation(x::T) where T <: ACSetTransformation
function roundtrip_json_acset_transformation(x, t)
mktempdir() do dir
path = joinpath(dir, "acset_transformation.json")
write_json_acset_transformation(x, path)
read_json_acset_transformation(T, path)
read_json_acset_transformation(t, path)
end
end

g = path_graph(WeightedGraph{Float64}, 2, E=(weight=2,))
h = path_graph(WeightedGraph{Float64}, 4, E=(weight=[1,2,3],))
α = ACSetTransformation((V=[2,3], E=[2]), g, h)
@test_broken roundtrip_json_acset_transformation(g) == g
@test roundtrip_json_acset_transformation(α, WeightedGraph{Float64}) == α

0 comments on commit 8ff21ea

Please sign in to comment.