@@ -86,6 +86,74 @@ function array_variable_assignments(args...; argument_name = generated_argument_
8686 return assignments
8787end
8888
89+ """
90+ $(TYPEDSIGNATURES)
91+
92+ Check if the variable `var` is a delayed variable, where `iv` is the independent
93+ variable.
94+ """
95+ function isdelay (var, iv)
96+ iv === nothing && return false
97+ isvariable (var) || return false
98+ isparameter (var) && return false
99+ if iscall (var) && ! ModelingToolkit. isoperator (var, Symbolics. Operator)
100+ args = arguments (var)
101+ length (args) == 1 || return false
102+ isequal (args[1 ], iv) || return true
103+ end
104+ return false
105+ end
106+
107+ """
108+ The argument of generated functions corresponding to the history function.
109+ """
110+ const DDE_HISTORY_FUN = Sym {Symbolics.FnType{Tuple{Any, <:Real}, Vector{Real}}} (:___history___ )
111+
112+ """
113+ $(TYPEDSIGNATURES)
114+
115+ Turn delayed unknowns in `eqs` into calls to `DDE_HISTORY_FUNCTION`.
116+
117+ # Arguments
118+
119+ - `sys`: The system of DDEs.
120+ - `eqs`: The equations to convert.
121+
122+ # Keyword Arguments
123+
124+ - `param_arg`: The name of the variable containing the parameter object.
125+ """
126+ function delay_to_function (
127+ sys:: AbstractSystem , eqs = full_equations (sys); param_arg = MTKPARAMETERS_ARG)
128+ delay_to_function (eqs,
129+ get_iv (sys),
130+ Dict {Any, Int} (operation (s) => i for (i, s) in enumerate (unknowns (sys))),
131+ parameters (sys),
132+ DDE_HISTORY_FUN; param_arg)
133+ end
134+ function delay_to_function (eqs:: Vector , iv, sts, ps, h; param_arg = MTKPARAMETERS_ARG)
135+ delay_to_function .(eqs, (iv,), (sts,), (ps,), (h,); param_arg)
136+ end
137+ function delay_to_function (eq:: Equation , iv, sts, ps, h; param_arg = MTKPARAMETERS_ARG)
138+ delay_to_function (eq. lhs, iv, sts, ps, h; param_arg) ~ delay_to_function (
139+ eq. rhs, iv, sts, ps, h; param_arg)
140+ end
141+ function delay_to_function (expr, iv, sts, ps, h; param_arg = MTKPARAMETERS_ARG)
142+ if isdelay (expr, iv)
143+ v = operation (expr)
144+ time = arguments (expr)[1 ]
145+ idx = sts[v]
146+ return term (getindex, h (param_arg, time), idx, type = Real)
147+ elseif iscall (expr)
148+ return maketerm (typeof (expr),
149+ operation (expr),
150+ map (x -> delay_to_function (x, iv, sts, ps, h; param_arg), arguments (expr)),
151+ metadata (expr))
152+ else
153+ return expr
154+ end
155+ end
156+
89157"""
90158 $(TYPEDSIGNATURES)
91159
@@ -138,11 +206,11 @@ function build_function_wrapper(sys::AbstractSystem, expr, args...; p_start = 2,
138206 obs = filter (filter_observed, observed (sys))
139207 # turn delayed unknowns into calls to the history function
140208 if wrap_delays
141- history_arg = is_split (sys) ? MTKPARAMETERS_ARG : generated_argument_name (p_start)
209+ param_arg = is_split (sys) ? MTKPARAMETERS_ARG : generated_argument_name (p_start)
142210 obs = map (obs) do eq
143- delay_to_function (sys, eq; history_arg )
211+ delay_to_function (sys, eq; param_arg )
144212 end
145- expr = delay_to_function (sys, expr; history_arg )
213+ expr = delay_to_function (sys, expr; param_arg )
146214 # add extra argument
147215 args = (args[1 : (p_start - 1 )]. .. , DDE_HISTORY_FUN, args[p_start: end ]. .. )
148216 p_start += 1
0 commit comments