using AlgebraicPetri
using Catlab
using Catlab.Graphics
using Catlab.Graphics.Graphviz
using Catlab.Graphics.Graphviz: Html
using Catlab.WiringDiagrams
using Catlab.CategoricalAlgebra
using Catlab.Programs.RelationalPrograms
using GraphViz
using LabelledArrays
using OrdinaryDiffEq
using Plots
# Functions for graphing typed Petri nets
colors = ["#a08eae","#ffeec6", "#a8dcd9", "#ffeec6", "#a8dcd9"]
function def_trans(typed_petri::ACSetTransformation, colors; labels = true)
(p, t; pos = "") -> ("t$t", Attributes(
:label => labels ? Html(flatten(tname(p,t))) : "" ,
:shape=>"square",
:color=>colors[typed_petri[:T](t)],
:pos=>pos))
end
function def_trans(colors = colors; labels = true)
(p, t; pos = "") -> ("t$t", Attributes(
:label => labels ? "$(tname(p, t))" : "" ,
:shape=>"square",
:color=>colors[t],
:pos=>pos))
end
flatten(tname::Symbol) = "$tname"
function flatten(tname::Tuple)
names = split(replace(string(tname), "("=>"", ")"=>"", ":"=>""), ",")
for i in 1:length(names)
name = strip(names[i])
if name[1:2] == "id"
continue
end
return name
end
return "id"
end
def_states(p, s; pos="") = ("s$s", Attributes(
:label => sname(p,s) isa Tuple where T ? Html(replace(string(sname(p,s)), ":"=>"", "," => "", "("=>"", ")"=>"")) : "$(sname(p,s))",
:shape=>"circle",
:color=>"#6C9AC3",
:pos=>pos
))
Graph_typed(typed_petri::ACSetTransformation, colors = colors; labels = true) = Graph(dom(typed_petri),
make_trans = def_trans(typed_petri, colors; labels = labels),
make_states = def_states
)
### Define models
SIR = LabelledPetriNet([:S, :I, :R],
:β => ((:S, :I)=>(:I, :I)),
:γ => (:I=>:R),
:∅ => (:S => :S),
:∅ => (:I => :I),
:∅ => (:R => :R)
)
infectious_type = LabelledPetriNet([:Pop],
:interact=>((:Pop, :Pop)=>(:Pop, :Pop)),
:t_disease=>(:Pop=>:Pop),
:t_strata=>(:Pop=>:Pop)
)
## Pull out indexing from model
s, = parts(infectious_type, :S)
t_interact, t_disease, t_strata = parts(infectious_type, :T)
i_interact1, i_interact2, i_disease, i_strata = parts(infectious_type, :I)
o_interact1, o_interact2, o_disease, o_strata = parts(infectious_type, :O)
typed_SIR = ACSetTransformation(SIR, infectious_type,
S = [s, s, s],
T = [t_interact, t_disease, t_strata, t_strata, t_strata],
I = [i_interact1, i_interact2, i_disease, i_strata, i_strata, i_strata],
O = [o_interact1, o_interact2, o_disease, o_strata, o_strata, o_strata],
Name = name -> nothing # specify the mapping for the loose ACSet transform
)
Graph_typed(typed_SIR)
risk = LabelledPetriNet([:H, :L],
:∅ => (:H => :H),
:∅ => (:L => :L),
:interact => ((:H, :H) => (:H, :H)),
:interact => ((:L, :L) => (:L, :L)),
:interact => ((:H, :L) => (:H, :L)),
:interact => ((:L, :H) => (:L, :H)),
)
typed_risk = ACSetTransformation(risk, infectious_type,
S = [s, s],
T = [t_disease, t_disease, t_interact, t_interact, t_interact, t_interact],
I = [i_disease, i_disease, i_interact1, i_interact2, i_interact1, i_interact2, i_interact2, i_interact1, i_interact2, i_interact1],
O = [o_disease, o_disease, o_interact1, o_interact2, o_interact1, o_interact2, o_interact2, o_interact1, o_interact2, o_interact1],
Name = name -> nothing # specify the mapping for the loose ACSet transform
)
[i_disease, i_disease, i_interact1, i_interact2, i_interact1, i_interact2, i_interact2, i_interact1, i_interact2, i_interact1]
Graph_typed(typed_risk)
typed_stratify(typed_model1, typed_model2) =
compose(proj1(pullback(typed_model1, typed_model2)), typed_model1)
SIR_risk = typed_stratify(typed_SIR, typed_risk)