Open Roger-luo opened 5 years ago
here is a toy implementation if anyone would like to play with it:
using Simplify, MacroTools
struct SymReal <: Real
term::Term
end
SymReal(name::Symbol) = SymReal(Variable(name))
function Base.show(io::IO, x::SymReal)
t = x.term
ex = MacroTools.postwalk(Simplify._show_term, get(t))
macro_call = Expr(:macrocall, Symbol("@term"), nothing, ex)
repr = sprint(show, macro_call)[9:end-1]
print(io, repr)
end
_term(x) = x
_term(x::SymReal) = x.term
function track(f, xs...)
xs = map(_term, xs)
t = track_term(f, xs...)
return SymReal(t)
end
@generated function track_term(f, xs...)
quote
convert(Term, Expr(:call, f, xs...))
end
end
Base.promote_rule(::Type{SymReal}, ::Type{T}) where {T <: Real} = SymReal
Base.convert(::Type{SymReal}, x::Real) = SymReal(@term(x))
Base.convert(::Type{SymReal}, x::SymReal) = x
Base.:(*)(x::SymReal, y::SymReal) = track(*, x, y)
x = SymReal(:x)
y = SymReal(:y)
ex = 2x * y * 2
normalize(ex.term)
Yes, this is a good suggestion. I have some ideas for a next gen interface as I rewrite Symbolics.jl from scratch, but those aren't really ready to make public.
currently symbols are all defined as subtype of
Number
, which my cause things not work with builtin complex number. After I played a few ideas with my own toy engine: https://github.com/Roger-luo/Sym.jlI think a proper solution might be to have different types defined as subtype of
Real
,Number
and evenAbstractMatrix
. This will make symbolic objects go through most of the functions defined in many packages, so a lot things should "just work".Moreover, the domain can always be inferred by Julia's own type inference in this way. So to be more specific what I'm suggesting is to separate the engine with higher abstraction of the symbols, e.g
Variable
,Term
,Expression
etc.maybe we could just use
Rewrite.jl
orSimplify
as the engine in the future, and provide this wrapper here, it would look likeand we could just forward the functions calls to
Term
, e.gin this way the Real/Complex domain of result type can be inferred by Julia's own type inference from these primitives (imagine if there is a more complicated user defined function)
XRef: https://github.com/JuliaDiffEq/ModelingToolkit.jl/issues/175