AlgebraicJulia / AlgebraicJulia/Catlab.jl

Issue with `parse_json_acset`

Abierto
#711 2 comentarios 0 reacciones 0 asignados Ver en GitHub
acsets bug wiring diagrams
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

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.