AlgebraicJulia / AlgebraicJulia/Catlab.jl
Issue with `parse_json_acset`
- Lenguaje dominante
- Julia
- Estrellas
- 724
- Forks
- 73
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
While trying to write a serialized directed wiring diagram ACSet out to file and then read it back in, I encountered an issue with `parse_json_acset`. `write_json_acset` and `generate_json_acset` work (in this case), but `read_json_acset` does not because `parse_json_acset` errors. I have included a script demonstrating the issue and a proposed fixed below. Note that the problematic calls to `read_json_acset` and `parse_json_acset` have been commented out at lines 36 and 59, respectively, to enable the script to run through entirely.
```
using Catlab, Catlab.Theories
using Catlab.CategoricalAlgebra
using Catlab.WiringDiagrams
using Catlab.Programs
using Catlab.Programs.RelationalPrograms
import Catlab.WiringDiagrams.DirectedWiringDiagrams: WiringDiagramACSet
# Form OfficeSpace presentation of FreeBiproductCategory
@present OfficeSpace(FreeBiproductCategory) begin
(LatePeter,CubiclePeter,LookLikeWorkingPeter,UncoveredTPSReport,HassledPeter,Milton,StaplerStatus,Lumbergh,BuildingOnFire)::Ob
UseSideDoorSoLumberghDoesntSee::Hom(LatePeter,CubiclePeter)
SpaceOutForAnHour::Hom(CubiclePeter,LookLikeWorkingPeter)
Do15MinActualWork::Hom(LookLikeWorkingPeter,CubiclePeter)
FileTPSReport::Hom(CubiclePeter⊗UncoveredTPSReport,HassledPeter)
TakeStapler::Hom(Milton⊗Lumbergh,BuildingOnFire)
end
# Form case_of_modays wiring diagram of OfficeSpace
case_of_mondays = @program OfficeSpace (lp::LatePeter,m::Milton,tps::UncoveredTPSReport,l::Lumbergh) begin #
cp = UseSideDoorSoLumberghDoesntSee(lp)
llwp = SpaceOutForAnHour(cp)
cp = Do15MinActualWork(llwp)
hassled_status = FileTPSReport(cp,tps)
building_status = TakeStapler(m,l)
return hassled_status, building_status
end
# Round trip of write/read json of wiring diagram acset errors in read_json_acset
function roundtrip_json_acset(x::T) where T <: ACSet
mktempdir() do dir
path = joinpath(dir, "acset.json")
write_json_acset(x, path)
read_json_acset(T, path)
end
end
# rt_json_acset = roundtrip_json_acset(case_of_mondays.diagram)
#=
ERROR: MethodError: no method matching DataType(::String)
Stacktrace:
[1] parse_json_acset(#unused#::Type{WiringDiagramACSet{Any, Any, Any, DataType}}, input::Dict{String, Any})
@ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/hMLnj/src/categorical_algebra/CSets.jl:1199
[2] read_json_acset(#unused#::Type{WiringDiagramACSet{Any, Any, Any, DataType}}, fname::String)
@ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/hMLnj/src/categorical_algebra/CSets.jl:1216
[3] #29
@ ./REPL[67]:5 [inlined]
[4] mktempdir(fn::var"#29#30"{WiringDiagramACSet{Any, Any, Any, DataType}, WiringDiagramACSet{Any, Any, Any, DataType}}, parent::String; prefix::String)
@ Base.Filesystem ./file.jl:764
[5] mktempdir (repeats 2 times)
@ ./file.jl:760 [inlined]
[6] roundtrip_json_acset(x::WiringDiagramACSet{Any, Any, Any, DataType})
@ Main ./REPL[67]:2
[7] top-level scope
@ REPL[69]:1
=#
# Round trip of generate/parse json of acset errors in parse_json_acset
json_from_wd_acset = generate_json_acset(case_of_mondays.diagram)
# rt_wd_acset = parse_json_acset(WiringDiagramACSet{Any,Any,Any,Any},json_from_wd_acset)
#=
ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
iterate(::Union{LinRange, StepRangeLen}) at range.jl:872
iterate(::Union{LinRange, StepRangeLen}, ::Integer) at range.jl:872
iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at dict.jl:712
...
Stacktrace:
[1] indexed_iterate(I::Symbol, i::Int64)
@ Base ./tuple.jl:91
[2] parse_json_acset(#unused#::Type{WiringDiagramACSet{Any, Any, Any, DataType}}, input::OrderedCollections.OrderedDict{Symbol, Vector})
@ Catlab.CategoricalAlgebra.CSets ~/.julia/packages/Catlab/hMLnj/src/categorical_algebra/CSets.jl:1196
[3] top-level scope
@ REPL[66]:1
=#
#**********
# HOWEVER *
#**********
# Modifying the parse_json_acset function from CSets.jl as follows works
function new_parse_json_acset(::Type{T}, input::AbstractDict) where T <: ACSet
out = T()
for (k,v) ∈ input
add_parts!(out, Symbol(k), length(v))
end
for l ∈ values(input)
for (i, j) ∈ enumerate(l)
for k ∈ keys(j) # (k,v) = j #
v = j[k]
vtype = eltype(out[Symbol(k)])
if !(v isa vtype)
v = vtype(v)
end
set_subpart!(out, i, Symbol(k), v)
end
end
end
out
end
rt_wd_acset = new_parse_json_acset(WiringDiagramACSet{Any,Any,Any,DataType},json_from_wd_acset)
println("Check Roundtrip WD ACSet Equals Original WD ACSet")
println(rt_wd_acset == case_of_mondays.diagram)
println("")
rt_wd = WiringDiagram{ThBiproductCategory,Any,Any,Any}(rt_wd_acset,nothing)
println("Check Roundtrip WD Equals Original WD")
println(rt_wd == case_of_mondays)
println("")
# This check is actually for comparison with a separate issue that has been avoided here
println("Check Types of Roundtrip WD ACSet and Original WD ACSet")
print("Orig: ")
println(typeof(case_of_mondays.diagram))
print("RT: ")
println(typeof(rt_wd_acset))
print("Equality of types: ")
println(typeof(rt_wd_acset) == typeof(case_of_mondays.diagram))
```
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.