From 9fc50d50b52558c38389528c46308a6fc52b4932 Mon Sep 17 00:00:00 2001 From: vyudu Date: Thu, 14 Nov 2024 17:23:31 -0500 Subject: [PATCH 01/16] init --- src/dsl.jl | 16 +++++++++++----- test/dsl/dsl_options.jl | 5 +++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/dsl.jl b/src/dsl.jl index 91a2fa3851..4dae35b0b6 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -286,6 +286,11 @@ end ### DSL Internal Master Function ### # Function for creating a ReactionSystem structure (used by the @reaction_network macro). +# What should no_infer do? We currently infer in: +# equations +# observables +# differentials +# make it so that we no longer do so. function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Handle interpolation of variables @@ -308,6 +313,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) compound_expr, compound_species = read_compound_options(options) continuous_events_expr = read_events_option(options, :continuous_events) discrete_events_expr = read_events_option(options, :discrete_events) + noinfer = haskey(options, :no_infer) # Parses reactions, species, and parameters. reactions = get_reactions(reaction_lines) @@ -317,7 +323,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Reads equations. vars_extracted, add_default_diff, equations = read_equations_options( - options, variables_declared) + options, variables_declared; noinfer = noinfer) variables = vcat(variables_declared, vars_extracted) # Handle independent variables @@ -341,13 +347,13 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Reads observables. observed_vars, observed_eqs, obs_syms = read_observed_options( - options, [species_declared; variables], all_ivs) + options, [species_declared; variables], all_ivs; noinfer = noinfer) # Collect species and parameters, including ones inferred from the reactions. declared_syms = Set(Iterators.flatten((parameters_declared, species_declared, variables))) species_extracted, parameters_extracted = extract_species_and_parameters!( - reactions, declared_syms) + reactions, declared_syms; noinfer = noinfer) species = vcat(species_declared, species_extracted) parameters = vcat(parameters_declared, parameters_extracted) @@ -682,7 +688,7 @@ end # `vars_extracted`: A vector with extracted variables (lhs in pure differential equations only). # `dtexpr`: If a differential equation is defined, the default derivative (D ~ Differential(t)) must be defined. # `equations`: a vector with the equations provided. -function read_equations_options(options, variables_declared) +function read_equations_options(options, variables_declared; noinfer = false) # Prepares the equations. First, extracts equations from provided option (converting to block form if required). # Next, uses MTK's `parse_equations!` function to split input into a vector with the equations. eqs_input = haskey(options, :equations) ? options[:equations].args[3] : :(begin end) @@ -752,7 +758,7 @@ function create_differential_expr(options, add_default_diff, used_syms, tiv) end # Reads the observables options. Outputs an expression ofr creating the observable variables, and a vector of observable equations. -function read_observed_options(options, species_n_vars_declared, ivs_sorted) +function read_observed_options(options, species_n_vars_declared, ivs_sorted; noinfer = false) if haskey(options, :observables) # Gets list of observable equations and prepares variable declaration expression. # (`options[:observables]` includes `@observables`, `.args[3]` removes this part) diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index 8174598fd4..3dbeabd6d4 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1022,3 +1022,8 @@ let @parameters v n @test isequal(Catalyst.expand_registered_functions(equations(rn4)[1]), D(A) ~ v*(A^n)) end + +### test that @no_infer properly throws errors when undeclared variables are written + +let +end From bd30f6528dd3c3e0f0fb8f29218553c153630352 Mon Sep 17 00:00:00 2001 From: vyudu Date: Thu, 14 Nov 2024 18:29:19 -0500 Subject: [PATCH 02/16] init no_option --- src/dsl.jl | 17 ++++++++--- test/dsl/dsl_options.jl | 62 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/dsl.jl b/src/dsl.jl index 4dae35b0b6..d6e5fffa49 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -71,7 +71,7 @@ const pure_rate_arrows = Set{Symbol}([:(=>), :(<=), :⇐, :⟽, :⇒, :⟾, :⇔ # Declares the keys used for various options. const option_keys = (:species, :parameters, :variables, :ivs, :compounds, :observables, :default_noise_scaling, :differentials, :equations, - :continuous_events, :discrete_events, :combinatoric_ratelaws) + :continuous_events, :discrete_events, :combinatoric_ratelaws, :no_infer) ### `@species` Macro ### @@ -517,11 +517,12 @@ end # Function looping through all reactions, to find undeclared symbols (species or # parameters), and assign them to the right category. -function extract_species_and_parameters!(reactions, excluded_syms) +function extract_species_and_parameters!(reactions, excluded_syms; noinfer = noinfer) species = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(species, reactant.reactant, excluded_syms) + (!isempty(species) && noinfer) && error("Unrecognized variables $(species) detected in reaction $(reaction). Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") end end @@ -529,8 +530,10 @@ function extract_species_and_parameters!(reactions, excluded_syms) parameters = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions add_syms_from_expr!(parameters, reaction.rate, excluded_syms) + (!isempty(parameters) && noinfer) && error("Unrecognized parameter $(parameters) detected in reaction $(reaction.rate). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms) + (!isempty(parameters) && noinfer) && error("Unrecognized parameter $(parameters) detected in reactant $(reactant). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") end end @@ -717,9 +720,12 @@ function read_equations_options(options, variables_declared; noinfer = false) diff_var = lhs.args[2] if in(diff_var, forbidden_symbols_error) error("A forbidden symbol ($(diff_var)) was used as an variable in this differential equation: $eq") + elseif (!in(diff_var, variables_declared)) && noinfer + error("Unrecognized symbol $(diff_var) was used as a variable in this differential equation. Since the @no_infer flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.") + else + add_default_diff = true + in(diff_var, variables_declared) || push!(vars_extracted, diff_var) end - add_default_diff = true - in(diff_var, variables_declared) || push!(vars_extracted, diff_var) end end @@ -769,6 +775,9 @@ function read_observed_options(options, species_n_vars_declared, ivs_sorted; noi for (idx, obs_eq) in enumerate(observed_eqs.args) # Extract the observable, checks errors, and continues the loop if the observable has been declared. obs_name, ivs, defaults, metadata = find_varinfo_in_declaration(obs_eq.args[2]) + if (noinfer && !in(obs_name, species_n_vars_declared)) + error("An undeclared variable ($obs_name) was declared as an observable. Since the flag @no_infer is set, all variables must be declared with the @species, @parameters, or @variables macros.") + end isempty(ivs) || error("An observable ($obs_name) was given independent variable(s). These should not be given, as they are inferred automatically.") isnothing(defaults) || diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index 3dbeabd6d4..a7de64a17c 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1026,4 +1026,66 @@ end ### test that @no_infer properly throws errors when undeclared variables are written let + @test_throws LoadError rn = @reaction_network begin + @no_infer + (k, k1), A <--> B + end + + @test_nowarn rn = @reaction_network begin + @no_infer + @species A(t) B(t) + @parameters k + k, A --> B + end + + @test_throws LoadError rn = @reaction_network begin + @no_infer + @species A(t) B(t) + @parameters k + k*n, A --> B + end + + @test_nowarn rn = @reaction_network begin + @no_infer + @parameters n k + @species A(t) B(t) + k*n, A --> B + end + + @test_throws LoadError rn = @reaction_network begin + @no_infer + @species A(t) B(t) + k, n*A --> B + end + + @test_nowarn rn = @reaction_network begin + @no_infer + @parameters n + @species A(t) B(t) + k, n*A --> B + end + + @test_throws LoadError rn = @reaction_network begin + @no_infer + @equations D(V) ~ V^2 + end + + @test_nowarn rn = @reaction_network begin + @no_infer + @variables V(t) + @equations D(V) ~ V^2 + end + + @test_throws LoadError rn = @reaction_network begin + @no_infer + @variables X1(t) + @observables X2 ~ X1 + end + + @test_nowarn rn = @reaction_network begin + @no_infer + @variables X1(t) X2(t) + @observables X2 ~ X1 + end end + From 56b4363cc819d14c6fae7df900d4535656b840f8 Mon Sep 17 00:00:00 2001 From: vyudu Date: Fri, 15 Nov 2024 15:24:22 -0500 Subject: [PATCH 03/16] test fix --- test/dsl/dsl_options.jl | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index a7de64a17c..90aaed278e 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1026,63 +1026,64 @@ end ### test that @no_infer properly throws errors when undeclared variables are written let - @test_throws LoadError rn = @reaction_network begin + # Test error when species are inferred + @test_throws LoadError @eval rn = @reaction_network begin @no_infer - (k, k1), A <--> B + @parameters k + k, A --> B end - - @test_nowarn rn = @reaction_network begin + @test_nowarn @eval rn = @reaction_network begin @no_infer @species A(t) B(t) @parameters k k, A --> B end - @test_throws LoadError rn = @reaction_network begin + # Test error when a parameter in rate is inferred + @test_throws LoadError @eval rn = @reaction_network begin @no_infer @species A(t) B(t) @parameters k k*n, A --> B end - - @test_nowarn rn = @reaction_network begin + @test_nowarn @eval rn = @reaction_network begin @no_infer @parameters n k @species A(t) B(t) k*n, A --> B end - @test_throws LoadError rn = @reaction_network begin + # Test error when a parameter in stoichiometry is inferred + @test_throws LoadError @eval rn = @reaction_network begin @no_infer @species A(t) B(t) k, n*A --> B end - - @test_nowarn rn = @reaction_network begin + @test_nowarn @eval rn = @reaction_network begin @no_infer @parameters n @species A(t) B(t) k, n*A --> B end - @test_throws LoadError rn = @reaction_network begin + # Test error when a variable in an equation is inferred + @test_throws LoadError @eval rn = @reaction_network begin @no_infer @equations D(V) ~ V^2 end - - @test_nowarn rn = @reaction_network begin + @test_nowarn @eval rn = @reaction_network begin @no_infer @variables V(t) @equations D(V) ~ V^2 end - @test_throws LoadError rn = @reaction_network begin + # Test error when a variable in an observable is inferred + @test_throws LoadError @eval rn = @reaction_network begin @no_infer @variables X1(t) @observables X2 ~ X1 end - - @test_nowarn rn = @reaction_network begin + @test_nowarn @eval rn = @reaction_network begin @no_infer @variables X1(t) X2(t) @observables X2 ~ X1 From 4b26cc4972436c936631c3ef60e50e5fdea08c24 Mon Sep 17 00:00:00 2001 From: vyudu Date: Fri, 15 Nov 2024 15:42:37 -0500 Subject: [PATCH 04/16] up --- src/dsl.jl | 6 +++--- test/dsl/dsl_options.jl | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dsl.jl b/src/dsl.jl index d6e5fffa49..78b0a570de 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -522,7 +522,7 @@ function extract_species_and_parameters!(reactions, excluded_syms; noinfer = noi for reaction in reactions for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(species, reactant.reactant, excluded_syms) - (!isempty(species) && noinfer) && error("Unrecognized variables $(species) detected in reaction $(reaction). Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") + (!isempty(species) && noinfer) && error("Unrecognized variables $(species[1]) detected in reaction reaction expression. Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") end end @@ -530,10 +530,10 @@ function extract_species_and_parameters!(reactions, excluded_syms; noinfer = noi parameters = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions add_syms_from_expr!(parameters, reaction.rate, excluded_syms) - (!isempty(parameters) && noinfer) && error("Unrecognized parameter $(parameters) detected in reaction $(reaction.rate). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") + (!isempty(parameters) && noinfer) && error("Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms) - (!isempty(parameters) && noinfer) && error("Unrecognized parameter $(parameters) detected in reactant $(reactant). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") + (!isempty(parameters) && noinfer) && error("Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") end end diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index 90aaed278e..892d844cc0 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1056,12 +1056,13 @@ let # Test error when a parameter in stoichiometry is inferred @test_throws LoadError @eval rn = @reaction_network begin @no_infer + @parameters k @species A(t) B(t) k, n*A --> B end @test_nowarn @eval rn = @reaction_network begin @no_infer - @parameters n + @parameters k n @species A(t) B(t) k, n*A --> B end From 13d236ecba87be701e173691ed6c8b6b89ca30bb Mon Sep 17 00:00:00 2001 From: vyudu Date: Fri, 15 Nov 2024 15:45:56 -0500 Subject: [PATCH 05/16] up --- src/dsl.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dsl.jl b/src/dsl.jl index 78b0a570de..ff97abd746 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -517,12 +517,12 @@ end # Function looping through all reactions, to find undeclared symbols (species or # parameters), and assign them to the right category. -function extract_species_and_parameters!(reactions, excluded_syms; noinfer = noinfer) +function extract_species_and_parameters!(reactions, excluded_syms; noinfer = false) species = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(species, reactant.reactant, excluded_syms) - (!isempty(species) && noinfer) && error("Unrecognized variables $(species[1]) detected in reaction reaction expression. Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") + (!isempty(species) && noinfer) && error("Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") end end From e2b423e6c9a589f50b7941cd925c15eb57f76a2b Mon Sep 17 00:00:00 2001 From: Vincent Du <54586336+vyudu@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:18:36 -0500 Subject: [PATCH 06/16] Update src/dsl.jl Co-authored-by: Sam Isaacson --- src/dsl.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/dsl.jl b/src/dsl.jl index ff97abd746..0b2535930e 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -286,11 +286,6 @@ end ### DSL Internal Master Function ### # Function for creating a ReactionSystem structure (used by the @reaction_network macro). -# What should no_infer do? We currently infer in: -# equations -# observables -# differentials -# make it so that we no longer do so. function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Handle interpolation of variables From 71fd89f73a5969070638342131b63a8bc5084870 Mon Sep 17 00:00:00 2001 From: Vincent Du <54586336+vyudu@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:18:44 -0500 Subject: [PATCH 07/16] Update src/dsl.jl Co-authored-by: Sam Isaacson --- src/dsl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsl.jl b/src/dsl.jl index 0b2535930e..9e76f01138 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -318,7 +318,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Reads equations. vars_extracted, add_default_diff, equations = read_equations_options( - options, variables_declared; noinfer = noinfer) + options, variables_declared; noinfer) variables = vcat(variables_declared, vars_extracted) # Handle independent variables From 3e5b66920c11612a445d8e63760613802bd16dda Mon Sep 17 00:00:00 2001 From: Vincent Du <54586336+vyudu@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:18:50 -0500 Subject: [PATCH 08/16] Update src/dsl.jl Co-authored-by: Sam Isaacson --- src/dsl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsl.jl b/src/dsl.jl index 9e76f01138..a8d6de3f79 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -342,7 +342,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Reads observables. observed_vars, observed_eqs, obs_syms = read_observed_options( - options, [species_declared; variables], all_ivs; noinfer = noinfer) + options, [species_declared; variables], all_ivs; noinfer) # Collect species and parameters, including ones inferred from the reactions. declared_syms = Set(Iterators.flatten((parameters_declared, species_declared, From 56baddebfdd126725640868ac240f0c503b50819 Mon Sep 17 00:00:00 2001 From: Vincent Du <54586336+vyudu@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:18:56 -0500 Subject: [PATCH 09/16] Update src/dsl.jl Co-authored-by: Sam Isaacson --- src/dsl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsl.jl b/src/dsl.jl index a8d6de3f79..0e3b4ee59c 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -348,7 +348,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) declared_syms = Set(Iterators.flatten((parameters_declared, species_declared, variables))) species_extracted, parameters_extracted = extract_species_and_parameters!( - reactions, declared_syms; noinfer = noinfer) + reactions, declared_syms) species = vcat(species_declared, species_extracted) parameters = vcat(parameters_declared, parameters_extracted) From 4d02ba26048bb77f095c869270bc0340cfae015a Mon Sep 17 00:00:00 2001 From: Vincent Du <54586336+vyudu@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:19:05 -0500 Subject: [PATCH 10/16] Update src/dsl.jl Co-authored-by: Sam Isaacson --- src/dsl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsl.jl b/src/dsl.jl index 0e3b4ee59c..f7dc40d468 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -716,7 +716,7 @@ function read_equations_options(options, variables_declared; noinfer = false) if in(diff_var, forbidden_symbols_error) error("A forbidden symbol ($(diff_var)) was used as an variable in this differential equation: $eq") elseif (!in(diff_var, variables_declared)) && noinfer - error("Unrecognized symbol $(diff_var) was used as a variable in this differential equation. Since the @no_infer flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.") + error("Unrecognized symbol $(diff_var) was used as a variable in an equation. Since the @no_infer flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.") else add_default_diff = true in(diff_var, variables_declared) || push!(vars_extracted, diff_var) From 64dab974edf43f99d94f1bb68be0f97296d6f133 Mon Sep 17 00:00:00 2001 From: vyudu Date: Sat, 16 Nov 2024 11:06:13 -0500 Subject: [PATCH 11/16] rename + error --- src/dsl.jl | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/dsl.jl b/src/dsl.jl index f7dc40d468..17bb53a6b3 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -71,7 +71,7 @@ const pure_rate_arrows = Set{Symbol}([:(=>), :(<=), :⇐, :⟽, :⇒, :⟾, :⇔ # Declares the keys used for various options. const option_keys = (:species, :parameters, :variables, :ivs, :compounds, :observables, :default_noise_scaling, :differentials, :equations, - :continuous_events, :discrete_events, :combinatoric_ratelaws, :no_infer) + :continuous_events, :discrete_events, :combinatoric_ratelaws, :require_declaration) ### `@species` Macro ### @@ -230,6 +230,9 @@ struct ReactionStruct end end +#function Base.show(io::IO, rx::ReactionStruct) # +#end + # Recursive function that loops through the reaction line and finds the reactants and their # stoichiometry. Recursion makes it able to handle weird cases like 2(X+Y+3(Z+XY)). function recursive_find_reactants!(ex::ExprValues, mult::ExprValues, @@ -283,6 +286,12 @@ function extract_metadata(metadata_line::Expr) return metadata end + + +struct UndeclaredSymbolicError <: Exception + msg::String +end + ### DSL Internal Master Function ### # Function for creating a ReactionSystem structure (used by the @reaction_network macro). @@ -308,7 +317,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) compound_expr, compound_species = read_compound_options(options) continuous_events_expr = read_events_option(options, :continuous_events) discrete_events_expr = read_events_option(options, :discrete_events) - noinfer = haskey(options, :no_infer) + requiredec = haskey(options, :require_declaration) # Parses reactions, species, and parameters. reactions = get_reactions(reaction_lines) @@ -318,7 +327,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Reads equations. vars_extracted, add_default_diff, equations = read_equations_options( - options, variables_declared; noinfer) + options, variables_declared; requiredec) variables = vcat(variables_declared, vars_extracted) # Handle independent variables @@ -342,13 +351,13 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem))) # Reads observables. observed_vars, observed_eqs, obs_syms = read_observed_options( - options, [species_declared; variables], all_ivs; noinfer) + options, [species_declared; variables], all_ivs; requiredec) # Collect species and parameters, including ones inferred from the reactions. declared_syms = Set(Iterators.flatten((parameters_declared, species_declared, variables))) species_extracted, parameters_extracted = extract_species_and_parameters!( - reactions, declared_syms) + reactions, declared_syms; requiredec) species = vcat(species_declared, species_extracted) parameters = vcat(parameters_declared, parameters_extracted) @@ -512,12 +521,12 @@ end # Function looping through all reactions, to find undeclared symbols (species or # parameters), and assign them to the right category. -function extract_species_and_parameters!(reactions, excluded_syms; noinfer = false) +function extract_species_and_parameters!(reactions, excluded_syms; requiredec = false) species = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(species, reactant.reactant, excluded_syms) - (!isempty(species) && noinfer) && error("Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") + (!isempty(species) && requiredec) && error("Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") end end @@ -525,10 +534,10 @@ function extract_species_and_parameters!(reactions, excluded_syms; noinfer = fal parameters = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions add_syms_from_expr!(parameters, reaction.rate, excluded_syms) - (!isempty(parameters) && noinfer) && error("Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") + (!isempty(parameters) && requiredec) && error("Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms) - (!isempty(parameters) && noinfer) && error("Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") + (!isempty(parameters) && requiredec) && error("Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") end end @@ -686,7 +695,7 @@ end # `vars_extracted`: A vector with extracted variables (lhs in pure differential equations only). # `dtexpr`: If a differential equation is defined, the default derivative (D ~ Differential(t)) must be defined. # `equations`: a vector with the equations provided. -function read_equations_options(options, variables_declared; noinfer = false) +function read_equations_options(options, variables_declared; requiredec = false) # Prepares the equations. First, extracts equations from provided option (converting to block form if required). # Next, uses MTK's `parse_equations!` function to split input into a vector with the equations. eqs_input = haskey(options, :equations) ? options[:equations].args[3] : :(begin end) @@ -715,7 +724,7 @@ function read_equations_options(options, variables_declared; noinfer = false) diff_var = lhs.args[2] if in(diff_var, forbidden_symbols_error) error("A forbidden symbol ($(diff_var)) was used as an variable in this differential equation: $eq") - elseif (!in(diff_var, variables_declared)) && noinfer + elseif (!in(diff_var, variables_declared)) && requiredec error("Unrecognized symbol $(diff_var) was used as a variable in an equation. Since the @no_infer flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.") else add_default_diff = true @@ -759,7 +768,7 @@ function create_differential_expr(options, add_default_diff, used_syms, tiv) end # Reads the observables options. Outputs an expression ofr creating the observable variables, and a vector of observable equations. -function read_observed_options(options, species_n_vars_declared, ivs_sorted; noinfer = false) +function read_observed_options(options, species_n_vars_declared, ivs_sorted; requiredec = false) if haskey(options, :observables) # Gets list of observable equations and prepares variable declaration expression. # (`options[:observables]` includes `@observables`, `.args[3]` removes this part) @@ -770,7 +779,7 @@ function read_observed_options(options, species_n_vars_declared, ivs_sorted; noi for (idx, obs_eq) in enumerate(observed_eqs.args) # Extract the observable, checks errors, and continues the loop if the observable has been declared. obs_name, ivs, defaults, metadata = find_varinfo_in_declaration(obs_eq.args[2]) - if (noinfer && !in(obs_name, species_n_vars_declared)) + if (requiredec && !in(obs_name, species_n_vars_declared)) error("An undeclared variable ($obs_name) was declared as an observable. Since the flag @no_infer is set, all variables must be declared with the @species, @parameters, or @variables macros.") end isempty(ivs) || From 3aa68ad01d5e63b3ef7ad6c1d5233fb25ce2d6f8 Mon Sep 17 00:00:00 2001 From: vyudu Date: Sat, 16 Nov 2024 11:58:53 -0500 Subject: [PATCH 12/16] fixes --- src/Catalyst.jl | 2 +- src/dsl.jl | 20 +++++++++++++++----- test/dsl/dsl_options.jl | 40 ++++++++++++++++++++-------------------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/Catalyst.jl b/src/Catalyst.jl index 047747da71..499493c362 100644 --- a/src/Catalyst.jl +++ b/src/Catalyst.jl @@ -122,7 +122,7 @@ export symmap_to_varmap # reaction_network macro include("expression_utils.jl") include("dsl.jl") -export @reaction_network, @network_component, @reaction, @species +export @reaction_network, @network_component, @reaction, @species, UndeclaredSymbolicError # Network analysis functionality. include("network_analysis.jl") diff --git a/src/dsl.jl b/src/dsl.jl index 17bb53a6b3..6248a4442f 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -292,6 +292,11 @@ struct UndeclaredSymbolicError <: Exception msg::String end +function Base.showerror(io::IO, err::UndeclaredSymbolicError) + print(io, "UndeclaredSymbolicError: ") + print(io, err.msg) +end + ### DSL Internal Master Function ### # Function for creating a ReactionSystem structure (used by the @reaction_network macro). @@ -526,7 +531,8 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec = for reaction in reactions for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(species, reactant.reactant, excluded_syms) - (!isempty(species) && requiredec) && error("Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @no_infer is declared, all species must be explicitly declared with the @species macro.") + (!isempty(species) && requiredec) && throw(UndeclaredSymbolicError( + "Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @require_declaration is declared, all species must be explicitly declared with the @species macro.")) end end @@ -534,10 +540,12 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec = parameters = OrderedSet{Union{Symbol, Expr}}() for reaction in reactions add_syms_from_expr!(parameters, reaction.rate, excluded_syms) - (!isempty(parameters) && requiredec) && error("Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") + (!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError( + "Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms) - (!isempty(parameters) && requiredec) && error("Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @no_infer is declared, all parameters must be explicitly declared with the @parameters macro.") + (!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError( + "Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) end end @@ -725,7 +733,8 @@ function read_equations_options(options, variables_declared; requiredec = false) if in(diff_var, forbidden_symbols_error) error("A forbidden symbol ($(diff_var)) was used as an variable in this differential equation: $eq") elseif (!in(diff_var, variables_declared)) && requiredec - error("Unrecognized symbol $(diff_var) was used as a variable in an equation. Since the @no_infer flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.") + throw(UndeclaredSymbolicError( + "Unrecognized symbol $(diff_var) was used as a variable in an equation. Since the @require_declaration flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.")) else add_default_diff = true in(diff_var, variables_declared) || push!(vars_extracted, diff_var) @@ -780,7 +789,8 @@ function read_observed_options(options, species_n_vars_declared, ivs_sorted; req # Extract the observable, checks errors, and continues the loop if the observable has been declared. obs_name, ivs, defaults, metadata = find_varinfo_in_declaration(obs_eq.args[2]) if (requiredec && !in(obs_name, species_n_vars_declared)) - error("An undeclared variable ($obs_name) was declared as an observable. Since the flag @no_infer is set, all variables must be declared with the @species, @parameters, or @variables macros.") + throw(UndeclaredSymbolicError( + "An undeclared variable ($obs_name) was declared as an observable. Since the flag @require_declaration is set, all variables must be declared with the @species, @parameters, or @variables macros.")) end isempty(ivs) || error("An observable ($obs_name) was given independent variable(s). These should not be given, as they are inferred automatically.") diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index 892d844cc0..36d3afff38 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1027,65 +1027,65 @@ end let # Test error when species are inferred - @test_throws LoadError @eval rn = @reaction_network begin - @no_infer + @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @require_declaration @parameters k k, A --> B end - @test_nowarn @eval rn = @reaction_network begin - @no_infer + @test_nowarn @macroexpand rn = @reaction_network begin + @require_declaration @species A(t) B(t) @parameters k k, A --> B end # Test error when a parameter in rate is inferred - @test_throws LoadError @eval rn = @reaction_network begin - @no_infer + @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @require_declaration @species A(t) B(t) @parameters k k*n, A --> B end - @test_nowarn @eval rn = @reaction_network begin - @no_infer + @test_nowarn @macroexpand rn = @reaction_network begin + @require_declaration @parameters n k @species A(t) B(t) k*n, A --> B end # Test error when a parameter in stoichiometry is inferred - @test_throws LoadError @eval rn = @reaction_network begin - @no_infer + @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @require_declaration @parameters k @species A(t) B(t) k, n*A --> B end - @test_nowarn @eval rn = @reaction_network begin - @no_infer + @test_nowarn @macroexpand rn = @reaction_network begin + @require_declaration @parameters k n @species A(t) B(t) k, n*A --> B end # Test error when a variable in an equation is inferred - @test_throws LoadError @eval rn = @reaction_network begin - @no_infer + @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @require_declaration @equations D(V) ~ V^2 end - @test_nowarn @eval rn = @reaction_network begin - @no_infer + @test_nowarn @macroexpand rn = @reaction_network begin + @require_declaration @variables V(t) @equations D(V) ~ V^2 end # Test error when a variable in an observable is inferred - @test_throws LoadError @eval rn = @reaction_network begin - @no_infer + @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @require_declaration @variables X1(t) @observables X2 ~ X1 end - @test_nowarn @eval rn = @reaction_network begin - @no_infer + @test_nowarn @macroexpand rn = @reaction_network begin + @require_declaration @variables X1(t) X2(t) @observables X2 ~ X1 end From 54ea053f8f2cab5477a8fa61ef0079f4f9a4c1d0 Mon Sep 17 00:00:00 2001 From: vyudu Date: Mon, 18 Nov 2024 18:42:01 -0500 Subject: [PATCH 13/16] add reaction/equation printing --- src/Catalyst.jl | 3 ++- src/dsl.jl | 30 ++++++++++++++---------------- test/dsl/dsl_options.jl | 1 + 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Catalyst.jl b/src/Catalyst.jl index 499493c362..04bb436b48 100644 --- a/src/Catalyst.jl +++ b/src/Catalyst.jl @@ -122,7 +122,8 @@ export symmap_to_varmap # reaction_network macro include("expression_utils.jl") include("dsl.jl") -export @reaction_network, @network_component, @reaction, @species, UndeclaredSymbolicError +export @reaction_network, @network_component, @reaction, @species + # Network analysis functionality. include("network_analysis.jl") diff --git a/src/dsl.jl b/src/dsl.jl index 6248a4442f..22a6fbc3f0 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -220,19 +220,17 @@ struct ReactionStruct products::Vector{ReactantStruct} rate::ExprValues metadata::Expr + rxexpr::Expr function ReactionStruct(sub_line::ExprValues, prod_line::ExprValues, rate::ExprValues, - metadata_line::ExprValues) + metadata_line::ExprValues, rx_line::Expr) sub = recursive_find_reactants!(sub_line, 1, Vector{ReactantStruct}(undef, 0)) prod = recursive_find_reactants!(prod_line, 1, Vector{ReactantStruct}(undef, 0)) metadata = extract_metadata(metadata_line) - new(sub, prod, rate, metadata) + new(sub, prod, rate, metadata, rx_line) end end -#function Base.show(io::IO, rx::ReactionStruct) # -#end - # Recursive function that loops through the reaction line and finds the reactants and their # stoichiometry. Recursion makes it able to handle weird cases like 2(X+Y+3(Z+XY)). function recursive_find_reactants!(ex::ExprValues, mult::ExprValues, @@ -440,15 +438,15 @@ function get_reactions(exprs::Vector{Expr}, reactions = Vector{ReactionStruct}(u error("Error: Must provide a tuple of reaction rates when declaring a bi-directional reaction.") end push_reactions!(reactions, reaction.args[2], reaction.args[3], - rate.args[1], metadata.args[1], arrow) + rate.args[1], metadata.args[1], arrow, line) push_reactions!(reactions, reaction.args[3], reaction.args[2], - rate.args[2], metadata.args[2], arrow) + rate.args[2], metadata.args[2], arrow, line) elseif in(arrow, fwd_arrows) push_reactions!(reactions, reaction.args[2], reaction.args[3], - rate, metadata, arrow) + rate, metadata, arrow, line) elseif in(arrow, bwd_arrows) push_reactions!(reactions, reaction.args[3], reaction.args[2], - rate, metadata, arrow) + rate, metadata, arrow, line) else throw("Malformed reaction, invalid arrow type used in: $(MacroTools.striplines(line))") end @@ -482,7 +480,7 @@ end # Takes a reaction line and creates reaction(s) from it and pushes those to the reaction array. # Used to create multiple reactions from, for instance, `k, (X,Y) --> 0`. function push_reactions!(reactions::Vector{ReactionStruct}, sub_line::ExprValues, - prod_line::ExprValues, rate::ExprValues, metadata::ExprValues, arrow::Symbol) + prod_line::ExprValues, rate::ExprValues, metadata::ExprValues, arrow::Symbol, line::Expr) # The rates, substrates, products, and metadata may be in a tupple form (e.g. `k, (X,Y) --> 0`). # This finds the length of these tuples (or 1 if not in tuple forms). Errors if lengs inconsistent. lengs = (tup_leng(sub_line), tup_leng(prod_line), tup_leng(rate), tup_leng(metadata)) @@ -505,7 +503,7 @@ function push_reactions!(reactions::Vector{ReactionStruct}, sub_line::ExprValues push!(reactions, ReactionStruct(get_tup_arg(sub_line, i), - get_tup_arg(prod_line, i), get_tup_arg(rate, i), metadata_i)) + get_tup_arg(prod_line, i), get_tup_arg(rate, i), metadata_i, line)) end end @@ -532,7 +530,7 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec = for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(species, reactant.reactant, excluded_syms) (!isempty(species) && requiredec) && throw(UndeclaredSymbolicError( - "Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @require_declaration is declared, all species must be explicitly declared with the @species macro.")) + "Unrecognized variables $(join(species, ", ")) detected in reaction expression: \"$(string(reaction.rxexpr))\". Since the flag @require_declaration is declared, all species must be explicitly declared with the @species macro.")) end end @@ -541,11 +539,11 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec = for reaction in reactions add_syms_from_expr!(parameters, reaction.rate, excluded_syms) (!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError( - "Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) + "Unrecognized parameter $(join(parameters, ", ")) detected in rate expression: $(reaction.rate) for the following reaction expression: \"$(string(reaction.rxexpr))\". Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms) (!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError( - "Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) + "Unrecognized parameters $(join(parameters, ", ")) detected in the stoichiometry for reactant $(reactant.reactant) in the following reaction expression: \"$(string(reaction.rxpexpr))\". Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) end end @@ -734,7 +732,7 @@ function read_equations_options(options, variables_declared; requiredec = false) error("A forbidden symbol ($(diff_var)) was used as an variable in this differential equation: $eq") elseif (!in(diff_var, variables_declared)) && requiredec throw(UndeclaredSymbolicError( - "Unrecognized symbol $(diff_var) was used as a variable in an equation. Since the @require_declaration flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.")) + "Unrecognized symbol $(diff_var) was used as a variable in an equation: \"$eq\". Since the @require_declaration flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters.")) else add_default_diff = true in(diff_var, variables_declared) || push!(vars_extracted, diff_var) @@ -790,7 +788,7 @@ function read_observed_options(options, species_n_vars_declared, ivs_sorted; req obs_name, ivs, defaults, metadata = find_varinfo_in_declaration(obs_eq.args[2]) if (requiredec && !in(obs_name, species_n_vars_declared)) throw(UndeclaredSymbolicError( - "An undeclared variable ($obs_name) was declared as an observable. Since the flag @require_declaration is set, all variables must be declared with the @species, @parameters, or @variables macros.")) + "An undeclared variable ($obs_name) was declared as an observable in the following observable equation: \"$obs_eq\". Since the flag @require_declaration is set, all variables must be declared with the @species, @parameters, or @variables macros.")) end isempty(ivs) || error("An observable ($obs_name) was given independent variable(s). These should not be given, as they are inferred automatically.") diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index 36d3afff38..14d9432fa5 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1025,6 +1025,7 @@ end ### test that @no_infer properly throws errors when undeclared variables are written +import Catalyst: UndeclaredSymbolicError let # Test error when species are inferred @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin From 81d4a10671b7030e5f715f76b603245905769fd5 Mon Sep 17 00:00:00 2001 From: vyudu Date: Mon, 18 Nov 2024 18:43:13 -0500 Subject: [PATCH 14/16] fix --- src/Catalyst.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Catalyst.jl b/src/Catalyst.jl index 04bb436b48..047747da71 100644 --- a/src/Catalyst.jl +++ b/src/Catalyst.jl @@ -124,7 +124,6 @@ include("expression_utils.jl") include("dsl.jl") export @reaction_network, @network_component, @reaction, @species - # Network analysis functionality. include("network_analysis.jl") export reactioncomplexmap, reactioncomplexes, incidencemat From fbf7a295a98e8f46d4fd018f5889fedfe4b86163 Mon Sep 17 00:00:00 2001 From: vyudu Date: Mon, 18 Nov 2024 18:51:58 -0500 Subject: [PATCH 15/16] typo --- src/dsl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsl.jl b/src/dsl.jl index 22a6fbc3f0..f17c17522c 100644 --- a/src/dsl.jl +++ b/src/dsl.jl @@ -543,7 +543,7 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec = for reactant in Iterators.flatten((reaction.substrates, reaction.products)) add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms) (!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError( - "Unrecognized parameters $(join(parameters, ", ")) detected in the stoichiometry for reactant $(reactant.reactant) in the following reaction expression: \"$(string(reaction.rxpexpr))\". Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) + "Unrecognized parameters $(join(parameters, ", ")) detected in the stoichiometry for reactant $(reactant.reactant) in the following reaction expression: \"$(string(reaction.rxexpr))\". Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro.")) end end From c7108148a8baa7ea804a0599ac29d64f288e4b30 Mon Sep 17 00:00:00 2001 From: vyudu Date: Wed, 20 Nov 2024 10:26:58 -0500 Subject: [PATCH 16/16] remove rn --- test/dsl/dsl_options.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/dsl/dsl_options.jl b/test/dsl/dsl_options.jl index 14d9432fa5..872ba4f0b2 100644 --- a/test/dsl/dsl_options.jl +++ b/test/dsl/dsl_options.jl @@ -1028,12 +1028,12 @@ end import Catalyst: UndeclaredSymbolicError let # Test error when species are inferred - @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @test_throws UndeclaredSymbolicError @macroexpand @reaction_network begin @require_declaration @parameters k k, A --> B end - @test_nowarn @macroexpand rn = @reaction_network begin + @test_nowarn @macroexpand @reaction_network begin @require_declaration @species A(t) B(t) @parameters k @@ -1041,13 +1041,13 @@ let end # Test error when a parameter in rate is inferred - @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @test_throws UndeclaredSymbolicError @macroexpand @reaction_network begin @require_declaration @species A(t) B(t) @parameters k k*n, A --> B end - @test_nowarn @macroexpand rn = @reaction_network begin + @test_nowarn @macroexpand @reaction_network begin @require_declaration @parameters n k @species A(t) B(t) @@ -1055,13 +1055,13 @@ let end # Test error when a parameter in stoichiometry is inferred - @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @test_throws UndeclaredSymbolicError @macroexpand @reaction_network begin @require_declaration @parameters k @species A(t) B(t) k, n*A --> B end - @test_nowarn @macroexpand rn = @reaction_network begin + @test_nowarn @macroexpand @reaction_network begin @require_declaration @parameters k n @species A(t) B(t) @@ -1069,23 +1069,23 @@ let end # Test error when a variable in an equation is inferred - @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @test_throws UndeclaredSymbolicError @macroexpand @reaction_network begin @require_declaration @equations D(V) ~ V^2 end - @test_nowarn @macroexpand rn = @reaction_network begin + @test_nowarn @macroexpand @reaction_network begin @require_declaration @variables V(t) @equations D(V) ~ V^2 end # Test error when a variable in an observable is inferred - @test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin + @test_throws UndeclaredSymbolicError @macroexpand @reaction_network begin @require_declaration @variables X1(t) @observables X2 ~ X1 end - @test_nowarn @macroexpand rn = @reaction_network begin + @test_nowarn @macroexpand @reaction_network begin @require_declaration @variables X1(t) X2(t) @observables X2 ~ X1