Serializing Stock and Flow Models
using StockFlow
using Catlab
using Catlab.CategoricalAlgebra
using JSON3
import StockFlow: StockAndFlowpUntyped, vectorify, state_dict, add_stocks!, add_flow!, add_links!
In order to serialize our models to JSON, we need to encode our functions as strings instead of julia functions. You can always recover the original model with Base.Meta.parse
and eval
.
StockAndFlowSymbolic = StockAndFlowpUntyped{Symbol,String}
# This is our constructor specialized to String formulas.
NewStockAndFlowSymbolic(s,f) = begin
d = StockAndFlowSymbolic()
s = vectorify(s)
add_stocks!(d,length(s),sname=s)
s_idx = state_dict(s)
f = vectorify(f)
for (i, ((fattr,uds),ls)) in enumerate(f)
fn = first(fattr)
ff = last(fattr)
sui = s_idx[first(uds)]
sdi = s_idx[last(uds)]
ls = vectorify(ls)
add_flow!(d,sui,sdi,fname=fn,ϕf=ff)
add_links!(d,map(x->s_idx[x],ls),repeat([i], length(ls)), length(ls))
end
d
end
NewStockAndFlowSymbolic (generic function with 1 method)
Examples
Our first example model is SIR.
# define functions ϕ of flows in the SIR model
fNewIncidence = "p.cβ*u.S*u.I/p.N"
fNewRecovery = "u.I/p.tr"
# StockAndFlowp(stocks,
# (flow=>function, upstream=>downstream) => stocks linked)
sir = NewStockAndFlowSymbolic((:S, :I, :R),
((:NewIncidence=>fNewIncidence, :S=>:I)=>(:S,:I),
(:NewRecovery=>fNewRecovery, :I=>:R)=>:I))
StockFlow.StockAndFlowpUntyped{Symbol, String} {Flow:2, Stock:3, Link:3, Name:0, FuncFlow:0}
Flow | u | d | fname | ϕf |
---|---|---|---|---|
1 | 1 | 2 | NewIncidence | p.cβ*u.S*u.I/p.N |
2 | 2 | 3 | NewRecovery | u.I/p.tr |
Stock | sname |
---|---|
1 | S |
2 | I |
3 | R |
Link | s | t |
---|---|---|
1 | 1 | 1 |
2 | 2 | 1 |
3 | 2 | 2 |
@example JSON JSON3.pretty(generatejsonacset(sir))
We can include some of the premade models, which are found in the `PremadeModels` module. They are all full-bore Stock and Flows.
@example JSON m = StockFlow.PremadeModels.seir_model
@example JSON JSON3.pretty(generatejsonacset(m))
## Schemas
The restricted class of primitive models.
@example JSON JSON3.pretty(generatejsonacset_schema(TheoryStockAndFlowp))
And for the generic schema
@example JSON JSON3.pretty(generatejsonacset_schema(TheoryStockAndFlow)) ```