-
-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Wip] Refactor "src/dsl.jl" file #985
base: master
Are you sure you want to change the base?
Conversation
3f92a31
to
b6ba044
Compare
src/dsl.jl
Outdated
variables = vcat(variables_declared, vars_extracted) | ||
|
||
# handle independent variables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of the organisations so that options are handled together (in two sets, some before and some after the reactions are considered, depending on whichever is possible for which option)
symvec = gensym() | ||
ex = quote | ||
$symvec = $ex | ||
expr = quote |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in some places we used ex and some expr, here I just made it uniform
isequivalent(rs_empty_1, rs_empty) | ||
rs_empty_2 == rs_empty | ||
rs_empty_3 == rs_empty | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WHen I remade how the macor inputs are handled at the top level (nothing, name, reactions, name + reactions) I wanted to add some tests that all of this works for all cases and both macros.
function escape_equation!(eqexpr::Expr, diffsyms) | ||
eqexpr.args[2] = recursive_escape_functions!(eqexpr.args[2], diffsyms) | ||
eqexpr.args[3] = recursive_escape_functions!(eqexpr.args[3], diffsyms) | ||
eqexpr | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved escape_equation!
up here since it is just a helper function to the function above and not involved in other stuff. Calls recursive_escape_functions!
on the lhs as well.
rn = @reaction_network begin | ||
@equations D(A) ~ f(A, t) | ||
@equations D(A) + g(A) ~ f(A, t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated because we now hanldes functions on both sides.
diffs_inferred = Union{Symbol, Expr}[] | ||
if add_default_diff && !any(diff_dec.args[1] == :D for diff_dec in diffsexpr.args) | ||
diffs_inferred = [:D] | ||
push!(diffsexpr.args, :(D = Differential($(tiv)))) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, if we use a default differential, diffsexpr
is updated directly in read_equations_options!
. Made more sense as I wanted to handle the @differnetials
option at the beginning (since this explicitly declares symbols). Previously this option was handled after @equations
.
src/dsl.jl
Outdated
spsexpr, spsvar = scalarize_macro(spsexpr_init, "specs") | ||
vsexpr, vsvar = scalarize_macro(vsexpr_init, "vars") | ||
cmpsexpr, cmpsvar = scalarize_macro(cmpexpr_init, "comps") | ||
rxsexprs = get_rxexprs(reactions, equations, union(diffs_declared, diffs_inferred)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trying to harmonise notation a bit across everything. exprs is the expression that generates the actually code, var is the generated variable we store stuff in. init on things that should not be evaluated. sps are species, vs variables, us unknowns, ps parameters, cmps compounds. Syms are lists of symbols (e.g. the symbols corresponding to observables). Not insisting we use this across the board, just explaining how I have changed things.
if rateex isa Symbol | ||
if !(rateex in forbidden_symbols_skip) && !(rateex in excluded_syms) | ||
push!(push_symbols, rateex) | ||
function add_syms_from_expr!(push_symbols::AbstractSet, expr::ExprValues, excluded_syms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rateex -> expr as this is not necessarily only the rate anymore.
end | ||
return compound_expr, compound_species | ||
return cmpexpr_init, cmps_declared |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shortened compound to cmp in line with other shortenings, and to avoid having to break certain lines into two lines in some places.
allunique(syms) || | ||
error("Reaction network independent variables, parameters, species, and variables must all have distinct names, but a duplicate has been detected. ") | ||
nothing | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now only used in one place, there implemented directly.
(length(expr.args) > 3) && | ||
error("An option input ($expr) is misformatted. Potentially, it has multiple inputs on a single lines, and these should be split across multiple lines using a `begin ... end` block.") | ||
return expr.args[3] | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Helper function for handling error checks across multiple options.
sexprs = get_sexpr([species], Dict{Symbol, Expr}()) | ||
pexprs = get_pexpr(parameters, Dict{Symbol, Expr}()) | ||
sexprs = get_usexpr([species], Dict{Symbol, Expr}()) | ||
pexprs = get_psexpr(parameters, Dict{Symbol, Expr}()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uses new names in the DSL file
# Tests error when disallowed name is used for variable. | ||
let | ||
@test_throws Exception @eval @reaction_network begin | ||
@variables π(t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new test
probODE = ODEProblem(rn, args...; kwargs...) # Using multiple dispatch the reaction network can be used as input to create ODE, SDE and Jump problems. | ||
probSDE = SDEProblem(rn, args...; kwargs...) | ||
probJump = JumpProblem(prob,aggregator::Direct,rn) | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first documentation of @reactio_network
, but now not even a docstring and just a weird remnant. remove.
probJump = JumpProblem(prob,aggregator::Direct,rn) | ||
""" | ||
|
||
### Constant Declarations ### |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not removed, now just line 1 and git got confused.
(sum(length, [reaction_lines, option_lines]) != length(ex.args)) && | ||
error("@reaction_network input contain $(length(ex.args) - sum(length.([reaction_lines,option_lines]))) malformed lines.") | ||
any(!in(option_keys), keys(options)) && | ||
error("The following unsupported options were used: $(filter(opt_in->!in(opt_in,option_keys), keys(options)))") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step one, read the macro input and check that it is correctly formatted.
if !allunique(syms_declared) | ||
nonunique_syms = [s for s in syms_declared if count(x -> x == s, syms_declared) > 1] | ||
error("The following symbols $(unique(nonunique_syms)) have explicitly been declared as multiple types of components (e.g. occur in at least two of the `@species`, `@parameters`, `@variables`, `@ivs`, `@compounds`, `@differentials`). This is not allowed.") | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step 2, read all options that explicitly declares symbols as stuff.
union(syms_declared, sps_inferred), tiv; requiredec) | ||
ps_inferred = setdiff(ps_pre_inferred, vs_inferred, diffs_inferred) | ||
syms_inferred = union(sps_inferred, ps_inferred, vs_inferred, diffs_inferred) | ||
all_syms = union(syms_declared, syms_inferred) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step 3, read the reactions, as well as the options from which we infer symbols.
continuous_events_expr = read_events_option(options, :continuous_events) | ||
discrete_events_expr = read_events_option(options, :discrete_events) | ||
default_reaction_metadata = read_default_noise_scaling_option(options) | ||
combinatoric_ratelaws = read_combinatoric_ratelaws_option(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step 4, read the other options.
spsexpr, spsvar = scalarize_macro(spsexpr_init, "specs") | ||
vsexpr, vsvar = scalarize_macro(vsexpr_init, "vars") | ||
cmpsexpr, cmpsvar = scalarize_macro(cmpexpr_init, "comps") | ||
rxsexprs = get_rxexprs(reactions, equations, all_syms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step 5, creates the various expressions to put in the macro.
end | ||
union!(excluded_syms, species) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
union!
replaces foreach(s -> push!(excluded_syms, s), species)
@test_throws Exception @eval @reaction_network begin | ||
@combinatoric_ratelaws false false | ||
d, 3X --> 0 | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checks that new error checks work (don't think the one above actually errored either, but it should)
Also does the "src/expression_utils.jl" file, as that primarily support the dsl file (the other relevant file is the chemistry one).
Primarily four types of changes:
@reaction_network
and@network_component
macros reuse minimal amount of code (where as previously it the second was basically ctrl+copied versions of the first.I also add some tests of all the various ways to create models via the DSL, mostly stuff that was not tested before.