Skip to content

Commit dc414b7

Browse files
authored
Merge pull request #1193 from SciML/finish_dsl_src_update
Finish dsl src update (reorder functions)
2 parents 08f28a6 + c74a266 commit dc414b7

File tree

1 file changed

+104
-104
lines changed

1 file changed

+104
-104
lines changed

src/dsl.jl

Lines changed: 104 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ function make_reaction_system(ex::Expr, name)
285285
ps_declared = extract_syms(options, :parameters)
286286
vs_declared = extract_syms(options, :variables)
287287
tiv, sivs, ivs, ivsexpr = read_ivs_option(options)
288-
cmpexpr_init, cmps_declared = read_compound_option(options)
288+
cmpexpr_init, cmps_declared = read_compounds_option(options)
289289
diffsexpr, diffs_declared = read_differentials_option(options)
290290
syms_declared = collect(Iterators.flatten((cmps_declared, sps_declared, ps_declared,
291291
vs_declared, ivs, diffs_declared)))
@@ -303,7 +303,7 @@ function make_reaction_system(ex::Expr, name)
303303
ps_inferred = setdiff(ps_pre_inferred, vs_inferred, diffs_inferred)
304304
syms_inferred = union(sps_inferred, ps_inferred, vs_inferred, diffs_inferred)
305305
all_syms = union(syms_declared, syms_inferred)
306-
obsexpr, obs_eqs, obs_syms = read_observed_option(options, ivs,
306+
obsexpr, obs_eqs, obs_syms = read_observables_option(options, ivs,
307307
union(sps_declared, vs_declared), all_syms; requiredec)
308308

309309
# Read options not related to the declaration or inference of symbols.
@@ -508,6 +508,20 @@ end
508508

509509
### DSL Output Expression Builders ###
510510

511+
# Given the parameters that were extracted from the reactions, and the options dictionary,
512+
# creates the `@parameters ...` expression for the macro output.
513+
function get_psexpr(parameters_extracted, options)
514+
pexprs = if haskey(options, :parameters)
515+
options[:parameters]
516+
elseif isempty(parameters_extracted)
517+
:()
518+
else
519+
:(@parameters)
520+
end
521+
foreach(p -> push!(pexprs.args, p), parameters_extracted)
522+
pexprs
523+
end
524+
511525
# Given the extracted species (or variables) and the option dictionary, create the
512526
# `@species ...` (or `@variables ..`) expression which would declare these.
513527
# If `key = :variables`, does this for variables (and not species).
@@ -525,20 +539,6 @@ function get_usexpr(us_extracted, options, key = :species; ivs = (DEFAULT_IV_SYM
525539
usexpr
526540
end
527541

528-
# Given the parameters that were extracted from the reactions, and the options dictionary,
529-
# creates the `@parameters ...` expression for the macro output.
530-
function get_psexpr(parameters_extracted, options)
531-
pexprs = if haskey(options, :parameters)
532-
options[:parameters]
533-
elseif isempty(parameters_extracted)
534-
:()
535-
else
536-
:(@parameters)
537-
end
538-
foreach(p -> push!(pexprs.args, p), parameters_extracted)
539-
pexprs
540-
end
541-
542542
# From the system reactions (as `DSLReaction`s) and equations (as expressions),
543543
# creates the expression that evaluates to the reaction (+ equations) vector.
544544
function get_rxexprs(reactions, equations, all_syms)
@@ -614,24 +614,28 @@ end
614614

615615
### DSL Option Handling ###
616616

617-
# Returns the `default_reaction_metadata` output. Technically Catalyst's code could have been made
618-
# more generic to account for other default reaction metadata. Practically, this will likely
619-
# be the only relevant reaction metadata to have a default value via the DSL. If another becomes
620-
# relevant, the code can be rewritten to take this into account.
621-
# Checks if the `@default_noise_scaling` option is used. If so, use it as the default value of
622-
# the `default_noise_scaling` reaction metadata, otherwise, returns an empty vector.
623-
function read_default_noise_scaling_option(options)
624-
if haskey(options, :default_noise_scaling)
625-
(length(options[:default_noise_scaling].args) != 3) &&
626-
error("@default_noise_scaling should only have a single expression as its input, this appears not to be the case: \"$(options[:default_noise_scaling])\"")
627-
return :([:noise_scaling => $(options[:default_noise_scaling].args[3])])
617+
# Finds the time independent variable, and any potential spatial independent variables.
618+
# Returns these (individually and combined), as well as an expression for declaring them.
619+
function read_ivs_option(options)
620+
# Creates the independent variables expressions (depends on whether the `ivs` option was used).
621+
if haskey(options, :ivs)
622+
ivs = Tuple(extract_syms(options, :ivs))
623+
ivsexpr = copy(options[:ivs])
624+
ivsexpr.args[1] = Symbol("@", "independent_variables")
625+
else
626+
ivs = (DEFAULT_IV_SYM,)
627+
ivsexpr = :($(DEFAULT_IV_SYM) = default_t())
628628
end
629-
return :([])
629+
630+
# Extracts the independent variables symbols (time and spatial), and returns the output.
631+
tiv = ivs[1]
632+
sivs = (length(ivs) > 1) ? Expr(:vect, ivs[2:end]...) : nothing
633+
return tiv, sivs, ivs, ivsexpr
630634
end
631635

632636
# When compound species are declared using the "@compound begin ... end" option, get a list
633637
# of the compound species, and also the expression that creates them.
634-
function read_compound_option(options)
638+
function read_compounds_option(options)
635639
# If the compound option is used, retrieve a list of compound species and the option line
636640
# that creates them (used to declare them as compounds at the end). Due to some expression
637641
# handling, in the case of a single compound we must change to the `@compound` macro.
@@ -648,38 +652,30 @@ function read_compound_option(options)
648652
return cmpexpr_init, cmps_declared
649653
end
650654

651-
# Read the events (continuous or discrete) provided as options to the DSL. Returns an expression which evaluates to these.
652-
function read_events_option(options, event_type::Symbol)
653-
# Prepares the events, if required to, converts them to block form.
654-
if event_type [:continuous_events, :discrete_events]
655-
error("Trying to read an unsupported event type.")
656-
end
657-
events_input = haskey(options, event_type) ? get_block_option(options[event_type]) :
658-
striplines(:(begin end))
659-
events_input = option_block_form(events_input)
660-
661-
# Goes through the events, checks for errors, and adds them to the output vector.
662-
events_expr = :([])
663-
for arg in events_input.args
664-
# Formatting error checks.
665-
# NOTE: Maybe we should move these deeper into the system (rather than the DSL), throwing errors more generally?
666-
if (arg isa Expr) && (arg.head != :call) || (arg.args[1] != :(=>)) ||
667-
(length(arg.args) != 3)
668-
error("Events should be on form `condition => affect`, separated by a `=>`. This appears not to be the case for: $(arg).")
669-
end
670-
if (arg isa Expr) && (arg.args[2] isa Expr) && (arg.args[2].head != :vect) &&
671-
(event_type == :continuous_events)
672-
error("The condition part of continuous events (the left-hand side) must be a vector. This is not the case for: $(arg).")
673-
end
674-
if (arg isa Expr) && (arg.args[3] isa Expr) && (arg.args[3].head != :vect)
675-
error("The affect part of all events (the right-hand side) must be a vector. This is not the case for: $(arg).")
676-
end
655+
# Creates an expression declaring differentials. Here, `tiv` is the time independent variables,
656+
# which is used by the default differential (if it is used).
657+
function read_differentials_option(options)
658+
# Creates the differential expression.
659+
# If differentials were provided as options, this is used as the initial expression.
660+
# If the default differential (D(...)) was used in equations, this is added to the expression.
661+
diffsexpr = (haskey(options, :differentials) ?
662+
get_block_option(options[:differentials]) : striplines(:(begin end)))
663+
diffsexpr = option_block_form(diffsexpr)
677664

678-
# Adds the correctly formatted event to the event creation expression.
679-
push!(events_expr.args, arg)
665+
# Goes through all differentials, checking that they are correctly formatted. Adds their
666+
# symbol to the list of declared differential symbols.
667+
diffs_declared = Union{Symbol, Expr}[]
668+
for dexpr in diffsexpr.args
669+
(dexpr.head != :(=)) &&
670+
error("Differential declaration must have form like D = Differential(t), instead \"$(dexpr)\" was given.")
671+
(dexpr.args[1] isa Symbol) ||
672+
error("Differential left-hand side must be a single symbol, instead \"$(dexpr.args[1])\" was given.")
673+
in(dexpr.args[1], forbidden_symbols_error) &&
674+
error("A forbidden symbol ($(dexpr.args[1])) was used as a differential name.")
675+
push!(diffs_declared, dexpr.args[1])
680676
end
681677

682-
return events_expr
678+
return diffsexpr, diffs_declared
683679
end
684680

685681
# Reads the variables options. Outputs a list of the variables inferred from the equations,
@@ -740,36 +736,10 @@ function find_D_call(expr)
740736
end
741737
end
742738

743-
# Creates an expression declaring differentials. Here, `tiv` is the time independent variables,
744-
# which is used by the default differential (if it is used).
745-
function read_differentials_option(options)
746-
# Creates the differential expression.
747-
# If differentials were provided as options, this is used as the initial expression.
748-
# If the default differential (D(...)) was used in equations, this is added to the expression.
749-
diffsexpr = (haskey(options, :differentials) ?
750-
get_block_option(options[:differentials]) : striplines(:(begin end)))
751-
diffsexpr = option_block_form(diffsexpr)
752-
753-
# Goes through all differentials, checking that they are correctly formatted. Adds their
754-
# symbol to the list of declared differential symbols.
755-
diffs_declared = Union{Symbol, Expr}[]
756-
for dexpr in diffsexpr.args
757-
(dexpr.head != :(=)) &&
758-
error("Differential declaration must have form like D = Differential(t), instead \"$(dexpr)\" was given.")
759-
(dexpr.args[1] isa Symbol) ||
760-
error("Differential left-hand side must be a single symbol, instead \"$(dexpr.args[1])\" was given.")
761-
in(dexpr.args[1], forbidden_symbols_error) &&
762-
error("A forbidden symbol ($(dexpr.args[1])) was used as a differential name.")
763-
push!(diffs_declared, dexpr.args[1])
764-
end
765-
766-
return diffsexpr, diffs_declared
767-
end
768-
769739
# Reads the observables options. Outputs an expression for creating the observable variables,
770740
# a vector containing the observable equations, and a list of all observable symbols (this
771741
# list contains both those declared separately or inferred from the `@observables` option` input`).
772-
function read_observed_option(options, all_ivs, us_declared, all_syms; requiredec = false)
742+
function read_observables_option(options, all_ivs, us_declared, all_syms; requiredec = false)
773743
syms_unavailable = setdiff(all_syms, us_declared)
774744
if haskey(options, :observables)
775745
# Gets list of observable equations and prepares variable declaration expression.
@@ -849,32 +819,62 @@ function make_obs_eqs(observables_expr)
849819
return obs_eqs
850820
end
851821

822+
# Read the events (continuous or discrete) provided as options to the DSL. Returns an expression which evaluates to these.
823+
function read_events_option(options, event_type::Symbol)
824+
# Prepares the events, if required to, converts them to block form.
825+
if event_type [:continuous_events, :discrete_events]
826+
error("Trying to read an unsupported event type.")
827+
end
828+
events_input = haskey(options, event_type) ? get_block_option(options[event_type]) :
829+
striplines(:(begin end))
830+
events_input = option_block_form(events_input)
831+
832+
# Goes through the events, checks for errors, and adds them to the output vector.
833+
events_expr = :([])
834+
for arg in events_input.args
835+
# Formatting error checks.
836+
# NOTE: Maybe we should move these deeper into the system (rather than the DSL), throwing errors more generally?
837+
if (arg isa Expr) && (arg.head != :call) || (arg.args[1] != :(=>)) ||
838+
(length(arg.args) != 3)
839+
error("Events should be on form `condition => affect`, separated by a `=>`. This appears not to be the case for: $(arg).")
840+
end
841+
if (arg isa Expr) && (arg.args[2] isa Expr) && (arg.args[2].head != :vect) &&
842+
(event_type == :continuous_events)
843+
error("The condition part of continuous events (the left-hand side) must be a vector. This is not the case for: $(arg).")
844+
end
845+
if (arg isa Expr) && (arg.args[3] isa Expr) && (arg.args[3].head != :vect)
846+
error("The affect part of all events (the right-hand side) must be a vector. This is not the case for: $(arg).")
847+
end
848+
849+
# Adds the correctly formatted event to the event creation expression.
850+
push!(events_expr.args, arg)
851+
end
852+
853+
return events_expr
854+
end
855+
856+
# Returns the `default_reaction_metadata` output. Technically Catalyst's code could have been made
857+
# more generic to account for other default reaction metadata. Practically, this will likely
858+
# be the only relevant reaction metadata to have a default value via the DSL. If another becomes
859+
# relevant, the code can be rewritten to take this into account.
860+
# Checks if the `@default_noise_scaling` option is used. If so, use it as the default value of
861+
# the `default_noise_scaling` reaction metadata, otherwise, returns an empty vector.
862+
function read_default_noise_scaling_option(options)
863+
if haskey(options, :default_noise_scaling)
864+
(length(options[:default_noise_scaling].args) != 3) &&
865+
error("@default_noise_scaling should only have a single expression as its input, this appears not to be the case: \"$(options[:default_noise_scaling])\"")
866+
return :([:noise_scaling => $(options[:default_noise_scaling].args[3])])
867+
end
868+
return :([])
869+
end
870+
852871
# Reads the combinatorial ratelaw options, which determines if a combinatorial rate law should
853872
# be used or not. If not provided, use the default (true).
854873
function read_combinatoric_ratelaws_option(options)
855874
return haskey(options, :combinatoric_ratelaws) ?
856875
get_block_option(options[:combinatoric_ratelaws]) : true
857876
end
858877

859-
# Finds the time independent variable, and any potential spatial independent variables.
860-
# Returns these (individually and combined), as well as an expression for declaring them.
861-
function read_ivs_option(options)
862-
# Creates the independent variables expressions (depends on whether the `ivs` option was used).
863-
if haskey(options, :ivs)
864-
ivs = Tuple(extract_syms(options, :ivs))
865-
ivsexpr = copy(options[:ivs])
866-
ivsexpr.args[1] = Symbol("@", "independent_variables")
867-
else
868-
ivs = (DEFAULT_IV_SYM,)
869-
ivsexpr = :($(DEFAULT_IV_SYM) = default_t())
870-
end
871-
872-
# Extracts the independent variables symbols (time and spatial), and returns the output.
873-
tiv = ivs[1]
874-
sivs = (length(ivs) > 1) ? Expr(:vect, ivs[2:end]...) : nothing
875-
return tiv, sivs, ivs, ivsexpr
876-
end
877-
878878
### `@reaction` Macro & its Internals ###
879879

880880
"""

0 commit comments

Comments
 (0)