jpfairbanks / SemanticModels.jl

A julia package for representing and manipulating model semantics
MIT License
76 stars 16 forks source link

PetriNets and Wiring Diagrams #195

Open jpfairbanks opened 5 years ago

jpfairbanks commented 5 years ago

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.

jpfairbanks commented 5 years ago

@mehalter take a look at https://eprints.soton.ac.uk/261951/1/strong-conf.pdf

jpfairbanks commented 5 years ago

https://johncarlosbaez.wordpress.com/2017/07/30/a-compositional-framework-for-reaction-networks/

jpfairbanks commented 5 years ago

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
jpfairbanks commented 5 years ago

@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.

jpfairbanks commented 5 years ago

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
jpfairbanks commented 5 years ago

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))
    ))
)