@@ -69,44 +69,68 @@ function independent_variable_symbols(sc::SymbolCache)
6969end
7070is_observed (sc:: SymbolCache , sym) = false
7171is_observed (:: SymbolCache , :: Expr ) = true
72+ is_observed (:: SymbolCache , :: AbstractArray{Expr} ) = true
73+ is_observed (:: SymbolCache , :: Tuple{Vararg{Expr}} ) = true
74+
75+ struct ExpressionSearcher
76+ declared:: Set{Symbol}
77+ fnbody:: Expr
78+ end
79+
80+ ExpressionSearcher () = ExpressionSearcher (Set {Symbol} (), Expr (:block ))
81+
82+ function (exs:: ExpressionSearcher )(sys, expr:: Expr )
83+ for arg in expr. args
84+ exs (sys, arg)
85+ end
86+ exs (sys, expr. head)
87+ return nothing
88+ end
89+
90+ function (exs:: ExpressionSearcher )(sys, sym:: Symbol )
91+ sym in exs. declared && return
92+ if is_variable (sys, sym)
93+ idx = variable_index (sys, sym)
94+ push! (exs. fnbody. args, :($ sym = u[$ idx]))
95+ elseif is_parameter (sys, sym)
96+ idx = parameter_index (sys, sym)
97+ push! (exs. fnbody. args, :($ sym = p[$ idx]))
98+ elseif is_independent_variable (sys, sym)
99+ push! (exs. fnbody. args, :($ sym = t))
100+ end
101+ push! (exs. declared, sym)
102+ return nothing
103+ end
104+
105+ (:: ExpressionSearcher )(sys, sym) = nothing
106+
72107function observed (sc:: SymbolCache , expr:: Expr )
73108 let cache = Dict {Expr, Function} ()
74109 return get! (cache, expr) do
75- fnbody = Expr (:block )
76- declared = Set {Symbol} ()
77- MacroTools. postwalk (expr) do sym
78- sym isa Symbol || return
79- sym in declared && return
80- if sc. variables != = nothing &&
81- (idx = findfirst (isequal (sym), sc. variables)) != = nothing
82- push! (fnbody. args, :($ sym = u[$ idx]))
83- push! (declared, sym)
84- elseif sc. parameters != = nothing &&
85- (idx = findfirst (isequal (sym), sc. parameters)) != = nothing
86- push! (fnbody. args, :($ sym = p[$ idx]))
87- push! (declared, sym)
88- elseif sym === sc. independent_variables ||
89- sc. independent_variables isa Vector &&
90- sym == only (sc. independent_variables)
91- push! (fnbody. args, :($ sym = t))
92- push! (declared, sym)
93- end
94- end
110+ exs = ExpressionSearcher ()
111+ exs (sc, expr)
95112 fnexpr = if is_time_dependent (sc)
96113 :(function (u, p, t)
97- $ fnbody
114+ $ (exs . fnbody)
98115 return $ expr
99116 end )
100117 else
101118 :(function (u, p)
102- $ fnbody
119+ $ (exs . fnbody)
103120 return $ expr
104121 end )
105122 end
106123 return RuntimeGeneratedFunctions. @RuntimeGeneratedFunction (fnexpr)
107124 end
108125 end
109126end
127+ function observed (sc:: SymbolCache , exprs:: AbstractArray{Expr} )
128+ return observed (sc, :(reshape ([$ (exprs... )], $ (size (exprs)))))
129+ end
130+ function observed (sc:: SymbolCache , exprs:: Tuple{Vararg{Expr}} )
131+ return observed (sc, :(($ (exprs... ),)))
132+ end
133+
110134function is_time_dependent (sc:: SymbolCache )
111135 sc. independent_variables === nothing && return false
112136 if symbolic_type (sc. independent_variables) == NotSymbolic ()
0 commit comments