From 2f6755950641b865c42a45d912888bc63e87bc8f Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 9 Jun 2025 13:41:19 +0530 Subject: [PATCH 1/5] fix: use `namespace_expr` in two-argument `unknowns` --- src/systems/abstractsystem.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/systems/abstractsystem.jl b/src/systems/abstractsystem.jl index 386dd2f2fd..ae42ac7ba6 100644 --- a/src/systems/abstractsystem.jl +++ b/src/systems/abstractsystem.jl @@ -1538,9 +1538,9 @@ function defaults_and_guesses(sys::AbstractSystem) merge(guesses(sys), defaults(sys)) end -unknowns(sys::Union{AbstractSystem, Nothing}, v) = renamespace(sys, v) +unknowns(sys::Union{AbstractSystem, Nothing}, v) = namespace_expr(v, sys) for vType in [Symbolics.Arr, Symbolics.Symbolic{<:AbstractArray}] - @eval unknowns(sys::AbstractSystem, v::$vType) = renamespace(sys, v) + @eval unknowns(sys::AbstractSystem, v::$vType) = namespace_expr(v, sys) @eval parameters(sys::AbstractSystem, v::$vType) = toparam(unknowns(sys, v)) end parameters(sys::Union{AbstractSystem, Nothing}, v) = toparam(unknowns(sys, v)) From 4801a9e4e4ec347ada9d2326f0d6ab48f807ae74 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 9 Jun 2025 13:41:31 +0530 Subject: [PATCH 2/5] fix: do not consider variables of variables as delayed --- src/systems/codegen_utils.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/systems/codegen_utils.jl b/src/systems/codegen_utils.jl index d6bcd06d07..dbbd7f85a8 100644 --- a/src/systems/codegen_utils.jl +++ b/src/systems/codegen_utils.jl @@ -123,7 +123,11 @@ function isdelay(var, iv) if iscall(var) && !ModelingToolkit.isoperator(var, Symbolics.Operator) args = arguments(var) length(args) == 1 || return false - isequal(args[1], iv) || return true + arg = args[1] + isequal(arg, iv) && return false + iscall(arg) || return true + issym(operation(arg)) && !iscalledparameter(arg) && return false + return true end return false end From 2ecbdb2dd6620a6a1785f47aa0afcf65e114f592 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 9 Jun 2025 13:41:41 +0530 Subject: [PATCH 3/5] test: test namespacing of variables of variables --- test/namespacing.jl | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/namespacing.jl b/test/namespacing.jl index 6a8a654ecf..4cc8ea7296 100644 --- a/test/namespacing.jl +++ b/test/namespacing.jl @@ -1,5 +1,6 @@ using ModelingToolkit -using ModelingToolkit: t_nounits as t, D_nounits as D, iscomplete, does_namespacing +using ModelingToolkit: t_nounits as t, D_nounits as D, iscomplete, does_namespacing, + renamespace @variables x(t) @parameters p @@ -24,3 +25,23 @@ nsys = toggle_namespacing(sys, false) @test_throws ["namespacing", "inner"] System( Equation[], t; systems = [nsys], name = :a) + +@testset "Variables of variables" begin + @variables x(t) y(x) + @named inner = System([D(x) ~ x, y ~ 2x + 1], t) + @test issetequal(unknowns(inner), [x, y]) + ss = mtkcompile(inner) + @test isequal(only(unknowns(ss)), x) + @test isequal(only(observed(ss)), y ~ 2x + 1) + + @named sys = System(Equation[], t; systems = [inner]) + xx, yy = let sys = inner + xx = renamespace(sys, x) + yy = only(@variables y(xx)) + xx, renamespace(sys, yy) + end + @test issetequal(unknowns(sys), [xx, yy]) + ss = mtkcompile(sys) + @test isequal(only(unknowns(ss)), xx) + @test isequal(only(observed(ss)), yy ~ 2xx + 1) +end From 18cc95179af8b9e1fef75fce65f5689299d21a65 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 9 Jun 2025 16:54:18 +0530 Subject: [PATCH 4/5] fix: handle `nothing` sys in `namespace_expr` --- src/systems/abstractsystem.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/systems/abstractsystem.jl b/src/systems/abstractsystem.jl index ae42ac7ba6..1d92416455 100644 --- a/src/systems/abstractsystem.jl +++ b/src/systems/abstractsystem.jl @@ -1169,7 +1169,9 @@ function is_array_of_symbolics(x) end function namespace_expr( - O, sys, n = nameof(sys); ivs = independent_variables(sys)) + O, sys, n = (sys === nothing ? nothing : nameof(sys)); + ivs = sys === nothing ? nothing : independent_variables(sys)) + sys === nothing && return O O = unwrap(O) # Exceptions for arrays of symbolic and Ref of a symbolic, the latter # of which shows up in broadcasts From 64829833fc6c502a7425a11e2d76ac6e91b087a2 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 9 Jun 2025 16:54:35 +0530 Subject: [PATCH 5/5] feat: `GlobalScope` variables in `@independent_variables` --- src/independent_variables.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/independent_variables.jl b/src/independent_variables.jl index 94d792a11e..d1f2ab4210 100644 --- a/src/independent_variables.jl +++ b/src/independent_variables.jl @@ -7,8 +7,12 @@ Define one or more independent variables. For example: @variables x(t) """ macro independent_variables(ts...) - :(@parameters $(ts...)) |> esc # TODO: treat independent variables separately from variables and parameters + Symbolics._parse_vars(:independent_variables, + Real, + ts, + toiv) |> esc end -toiv(s::Symbolic) = setmetadata(s, MTKVariableTypeCtx, PARAMETER) +toiv(s::Symbolic) = GlobalScope(setmetadata(s, MTKVariableTypeCtx, PARAMETER)) +toiv(s::Symbolics.Arr) = wrap(toiv(value(s))) toiv(s::Num) = Num(toiv(value(s)))