I’m trying to use Symbolics.jl to simplify some expressions in the domain of quantum mechanics. The problem I’m facing is that I would like to simplify a partial expression that does not exactly reduce to a single type.

For example

using Symbolics
using SymbolicUtils
abstract type MyType end
@syms a::MyType b::Number
@acrule(*(~~a) + *(~b, ~~a) => *(1 + ~b, (~~a)...))
simplify(a + a*b)

brings up MethodError: no method matching *(::SymbolicUtils.BasicSymbolic{Number}, ::SymbolicUtils.BasicSymbolic{MyType}).

How could I simplify the expression as far as it can using the rules, even if all operations are not defined?

The issue is not with the rules so far, it’s with a*b

We only define the arithmetic methods for Symbolic{<:Number}, that’s why * is not defined for Symbolic{MyType}.

It should work if you make MyType a subtype of Number. It will have the default behavior that is suitable for numbers, you can of course overload specific methods if they behave differently.

As for applying the rules, you can use the Rewriters to compose the rules into something that does what you want (e.g. traverse the tree and apply the rule to each node, etc.) The docs for this are here SymbolicUtils.jl

Thanks for the insightful response, but the problem is that making MyType a subtype of Number makes it behave like a number (commute in multiplication etc.) which is the behaviour I want to avoid by making my own type.