Open jpfairbanks opened 5 years ago
@mehalter take a look at https://eprints.soton.ac.uk/261951/1/strong-conf.pdf
What should the return value of run! be? The network, the final marking, or some kind of return code like
struct ReturnCode
iterations::Int # number of iterations
changes::Int # number of state changes,
infite::Bool # a flag for infinite loop detected
end
@ewdavis, @rrwright, @cl4yton i think this is the new code for the PetriNet (AMIDOL flavor) based simulation of the SIR system.
function main(β, γ, μ)
@grounding begin
S => Noun(Susceptible, ontology=Snowmed)
I => Noun(Infectious, ontology=ICD9)
R => Noun(Recovered, ontology=ICD9)
λ₁ => Verb(infection)
λ₂ => Verb(recovery)
λ₃ => Verb(loss_of_immunity)
end
@reaction begin
λ₁, S + I -> 2I
λ₂, I -> R
λ₃, R -> S
end, λ₁, λ₂, λ₃
# β, 1S + 1I -> 0S + 2I
# γ, 0R + 1I -> 0I + 1R
# μ, 1R + 0S -> 1S + 0R
Δ = [
(S,I) -> (S-1, I+1),
(I,R) -> (I-1, R+1),
(R,S) -> (R-1, S+1),
]
ϕ = [
(S, I) -> x > 0 && I > 0,
(I) -> x > 0,
(R) -> x > 0,
]
Λ = [
λ₁(S,I) = begin n = +(S,I,R); β*S*I/n end,
λ₂(I) = begin γ*I end,
λ₃(R) = begin μ*R end
]
m = Petri.Model(g, Δ, ϕ, Λ)
d = convert(ODEProblem, m)
soln = solve(m) #discrete
soln = solve(d) #continuos
end
the @grounding
macro is some way to encode the ontological information about the model, we can use arbitrary trees in here to avoid having to specify it in some serialization format. We are going to just use ast = parsefile("main.jl"); dump(IOContext(stdout, :limit => true), ast)
as the output format for AMIDOL to consume, that way they basically get the S-expression version of the code directly without having to write a julia parser in scala.
The corresponding AST dumped without line numbers is
julia> MacroTools.postwalk(ast) do x
rmlines(x)
end |> x->dump(IOContext(stdout, :limit => true), x, maxdepth=100)
Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol function
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((4,))
1: Symbol main
2: Symbol β
3: Symbol γ
4: Symbol μ
2: Expr
head: Symbol block
args: Array{Any}((9,))
1: Expr
head: Symbol macrocall
args: Array{Any}((3,))
1: Symbol @grounding
2: Nothing nothing
3: Expr
head: Symbol block
args: Array{Any}((6,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol S
3: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol Noun
2: Symbol Susceptible
3: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol ontology
2: Symbol Snowmed
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol I
3: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol Noun
2: Symbol Infectious
3: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol ontology
2: Symbol ICD9
3: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol R
3: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol Noun
2: Symbol Recovered
3: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol ontology
2: Symbol ICD9
4: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol λ₁
3: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol Verb
2: Symbol infection
5: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol λ₂
3: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol Verb
2: Symbol recovery
6: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol λ₃
3: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol Verb
2: Symbol loss_of_immunity
2: Expr
head: Symbol macrocall
args: Array{Any}((3,))
1: Symbol @reaction
2: Nothing nothing
3: Expr
head: Symbol tuple
args: Array{Any}((4,))
1: Expr
head: Symbol block
args: Array{Any}((3,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol λ₁
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol +
2: Symbol S
3: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol *
2: Int64 2
3: Symbol I
2: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol λ₂
2: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Symbol R
3: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol λ₃
2: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Symbol R
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Symbol S
2: Symbol λ₁
3: Symbol λ₂
4: Symbol λ₃
3: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol Δ
2: Expr
head: Symbol vect
args: Array{Any}((3,))
1: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol S
2: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol -
2: Symbol S
3: Int64 1
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol +
2: Symbol I
3: Int64 1
2: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol I
2: Symbol R
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol -
2: Symbol I
3: Int64 1
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol +
2: Symbol R
3: Int64 1
3: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol R
2: Symbol S
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol -
2: Symbol R
3: Int64 1
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol +
2: Symbol S
3: Int64 1
4: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol ϕ
2: Expr
head: Symbol vect
args: Array{Any}((3,))
1: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Expr
head: Symbol tuple
args: Array{Any}((2,))
1: Symbol S
2: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol &&
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol >
2: Symbol x
3: Int64 0
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol >
2: Symbol I
3: Int64 0
2: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol >
2: Symbol x
3: Int64 0
3: Expr
head: Symbol ->
args: Array{Any}((2,))
1: Symbol R
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol >
2: Symbol x
3: Int64 0
5: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol Λ
2: Expr
head: Symbol vect
args: Array{Any}((3,))
1: Expr
head: Symbol =
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol λ₁
2: Symbol S
3: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((2,))
1: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol n
2: Expr
head: Symbol call
args: Array{Any}((4,))
1: Symbol +
2: Symbol S
3: Symbol I
4: Symbol R
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol /
2: Expr
head: Symbol call
args: Array{Any}((4,))
1: Symbol *
2: Symbol β
3: Symbol S
4: Symbol I
3: Symbol n
2: Expr
head: Symbol =
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol λ₂
2: Symbol I
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol *
2: Symbol γ
3: Symbol I
3: Expr
head: Symbol =
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol λ₃
2: Symbol R
2: Expr
head: Symbol block
args: Array{Any}((1,))
1: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol *
2: Symbol μ
3: Symbol R
6: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol m
2: Expr
head: Symbol call
args: Array{Any}((5,))
1: Expr
head: Symbol .
args: Array{Any}((2,))
1: Symbol Petri
2: QuoteNode
value: Symbol Model
2: Symbol g
3: Symbol Δ
4: Symbol ϕ
5: Symbol Λ
7: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol d
2: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol convert
2: Symbol ODEProblem
3: Symbol m
8: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol soln
2: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol solve
2: Symbol m
9: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol soln
2: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol solve
2: Symbol d
A more compact, and easier to parse version of the AST can be given by something about the parentheses is very appealing...
julia> MacroTools.postwalk(ast) do x
rmlines(x)
end |> x->Base.Meta.show_sexpr(stdout, x)
(:block,
(:function, (:call, :main, :β, :γ, :μ), (:block,
(:macrocall, Symbol("@grounding"), nothing, (:block,
(:call, :(=>), :S, (:call, :Noun, :Susceptible, (:kw, :ontology, :Snowmed))),
(:call, :(=>), :I, (:call, :Noun, :Infectious, (:kw, :ontology, :ICD9))),
(:call, :(=>), :R, (:call, :Noun, :Recovered, (:kw, :ontology, :ICD9))),
(:call, :(=>), :λ₁, (:call, :Verb, :infection)),
(:call, :(=>), :λ₂, (:call, :Verb, :recovery)),
(:call, :(=>), :λ₃, (:call, :Verb, :loss_of_immunity))
)),
(:macrocall, Symbol("@reaction"), nothing, (:tuple, (:block,
(:tuple, :λ₁, (:call, :+, :S, (:->, :I, (:block,
(:call, :*, 2, :I)
)))),
(:tuple, :λ₂, (:->, :I, (:block,
:R
))),
(:tuple, :λ₃, (:->, :R, (:block,
:S
)))
), :λ₁, :λ₂, :λ₃)),
(:(=), :Δ, (:vect, (:->, (:tuple, :S, :I), (:block,
(:tuple, (:call, :-, :S, 1), (:call, :+, :I, 1))
)), (:->, (:tuple, :I, :R), (:block,
(:tuple, (:call, :-, :I, 1), (:call, :+, :R, 1))
)), (:->, (:tuple, :R, :S), (:block,
(:tuple, (:call, :-, :R, 1), (:call, :+, :S, 1))
)))),
(:(=), :ϕ, (:vect, (:->, (:tuple, :S, :I), (:block,
(:&&, (:call, :>, :x, 0), (:call, :>, :I, 0))
)), (:->, :I, (:block,
(:call, :>, :x, 0)
)), (:->, :R, (:block,
(:call, :>, :x, 0)
)))),
(:(=), :Λ, (:vect, (:(=), (:call, :λ₁, :S, :I), (:block,
(:(=), :n, (:call, :+, :S, :I, :R)),
(:call, :/, (:call, :*, :β, :S, :I), :n)
)), (:(=), (:call, :λ₂, :I), (:block,
(:call, :*, :γ, :I)
)), (:(=), (:call, :λ₃, :R), (:block,
(:call, :*, :μ, :R)
)))),
(:(=), :m, (:call, (:., :Petri, (:quote, #QuoteNode
:Model
)), :g, :Δ, :ϕ, :Λ)),
(:(=), :d, (:call, :convert, :ODEProblem, :m)),
(:(=), :soln, (:call, :solve, :m)),
(:(=), :soln, (:call, :solve, :d))
))
)
The catlab branch has some code in
src/petri.jl
that implements petrinets as a modeling framework and then some code to convert them to wiring diagrams, I don't think that code is right, but I'm not sure how to fix it.We should be able to model a Petri Nets as a category P and represent each Petri Net as a functor from the category of P to Set like a P-Instance or something like that.