diff --git a/src/complex.jl b/src/complex.jl index dc0ab983a..b221fa30f 100644 --- a/src/complex.jl +++ b/src/complex.jl @@ -81,3 +81,20 @@ Base.iszero(x::Complex{<:Num}) = iszero(real(x)) && iszero(imag(x)) Base.isone(x::Complex{<:Num}) = isone(real(x)) && iszero(imag(x)) _iszero(x::Complex{<:Num}) = _iszero(unwrap(x)) _isone(x::Complex{<:Num}) = _isone(unwrap(x)) + +function SymbolicIndexingInterface.hasname(x::ComplexTerm) + a = arguments(unwrap(x.im))[1] + b = arguments(unwrap(x.re))[1] + return isequal(a, b) && hasname(a) +end + +function _getname(x::ComplexTerm, val) + a = arguments(unwrap(x.im))[1] + b = arguments(unwrap(x.re))[1] + if isequal(a, b) + return _getname(a, val) + end + if val == _fail + throw(ArgumentError("Variable $x doesn't have a name.")) + end +end diff --git a/src/variable.jl b/src/variable.jl index 4ba3e571b..489a072de 100644 --- a/src/variable.jl +++ b/src/variable.jl @@ -503,13 +503,18 @@ function SymbolicIndexingInterface.symbolic_type(::Type{T}) where {S <: Abstract ArraySymbolic() end -SymbolicIndexingInterface.hasname(x::Union{Num,Arr}) = hasname(unwrap(x)) +SymbolicIndexingInterface.hasname(x::Union{Num,Arr,Complex{Num}}) = hasname(unwrap(x)) function SymbolicIndexingInterface.hasname(x::Symbolic) issym(x) || !iscall(x) || iscall(x) && (issym(operation(x)) || operation(x) == getindex) end -SymbolicIndexingInterface.getname(x, val=_fail) = _getname(unwrap(x), val) +# This is type piracy, but changing it breaks precompilation for MTK because it relies on this falling back to +# `_getname` which calls `nameof` which returns the name of the system, when `x::AbstractSystem`. +# FIXME: In a breaking release +function SymbolicIndexingInterface.getname(x, val = _fail) + _getname(unwrap(x), val) +end function SymbolicIndexingInterface.symbolic_evaluate(ex::Union{Num, Arr, Symbolic, Equation, Inequality}, d::Dict; kwargs...) val = fixpoint_sub(ex, d; kwargs...) diff --git a/test/complex.jl b/test/complex.jl index 1b4b7646f..d293e91ec 100644 --- a/test/complex.jl +++ b/test/complex.jl @@ -1,6 +1,7 @@ using Symbolics, Test using SymbolicUtils: metadata using Symbolics: unwrap +using SymbolicIndexingInterface: getname, hasname @variables a b::Real z::Complex (Z::Complex)[1:10] @@ -37,3 +38,15 @@ end z2 = 1.0 + z*im @test isnothing(metadata(unwrap(z1.re))) end + +@testset "getname" begin + @variables t a b x::Complex y(t)::Complex z(a, b)::Complex + @test hasname(x) + @test getname(x) == :x + @test hasname(y) + @test getname(y) == :y + @test hasname(z) + @test getname(z) == :z + @test !hasname(2x) + @test !hasname(x + y) +end