Passing new Parameters in symbolics and ModelingToolKit

I am trying to create a few different equations, pass them to a function that puts them together adding new parameters to the system and then returns the result to the user who will later pass them to other functions.
As an example

using ModelingToolkit
using Symbolics

function Homotopy(L, NL)

    #@variables q
    @parameters q

    H = (1-q) * L - q * NL

    return (H)
    #return(H,q)
end

@variables t x(..) L(..)

Dtt = Differential(t)^2

NL = Dtt(x(t)) + x(t) + x(t)^3
L = x(t)

H = Homotopy(L, NL)
#H, q = Homotopy(L, NL)

println(H)

substitute(H, Dict([q => 1]))

Whether I define q to be a variable or a parameter when I try to substitute a new value in for it I get a

ERROR: UndefVarError: q not defined.

If I return q from the function and put it into a variable I can then make the substitution, however this puts the job of managing these variables on the user of the function.

Getting this error makes sense form the prospective of never having defined it outside of the function Homotopy however is there a way around having to pass the variables back to the user in this way? Or is there a preferred way to do this in Julia?

I’m not entirely sure what the question is. This is just, if you define q in the local scope of a function then it’s not by default in the global scope. That’s just Julia’s standard scoping rules for variables. Symbolic variables obey the standard rules of Julia.

So what I am asking is this, suppose that I pass a pair of symbolic functions to the function Homotopy, and it returns the result back to me, I now need to preform some actions on it and then later return the function to another location where I can set q to some value.

My question is how do I do this without passing back any new terms that I create in the function, and how do I modify these values later if I don’t have the original terms that I defined?

So yes, you are right I am trying to use a variable outside of its scope, but the value of it is inside of H, and I am returning H. The question is how do I keep track of these terms and modify them when I am no longer in the scope of the function.

I think that I have solved at least part of my problem, what I have found is the Symbolics.getvariables() function. This gives me an array with the terms in it that are used in the equation.

This leaves me with the question of, is there somewhere that I can store the information telling me what terms have been used in what way, so that I know what terms in the array are used in what way in the equation.

My thought is that I need to use something like a mutable struct and put everything inside of it, and just pass it back and forth between functions. My other thought here is that the @named function seems to have some relevance to what I am doing, but I don’t really understand what it is doing, or how to best use it.

With ModelingToolkit you would normally create subsystems, and then use the hierarchical indexing to handle that kind of thing?