# Symbolics Equality

**URL:** https://discourse.julialang.org/t/symbolics-equality/102803
**Category:** General Usage
**Tags:** symbolics
**Created:** [August 14, 2023, 9:10pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803 "2023-08-14T21:10:31Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Allan\_Baker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/allan_baker/32/42645_2.png) [@Allan\_Baker](https://discourse.julialang.org/u/Allan_Baker)
#### Post date: [August 14, 2023, 9:10pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/1 "2023-08-14T21:10:31Z")

</div>

I’m trying to extend some modules to work with Symbolics by getting rid of Bool conditionals and divide by zero checks etc. I’m trying to add some unit tests and I want to test if two symbolic equations are equivalent.

When I try and extend Base.:(==) by checking if the components of a composite type structure are == symbolically (I even throw in some simplify calls wrapping the LHS and RHS of the equals) it complains about non-Boolean being used in a Boolean context.

What’s the trick to see if two equations are the same symbolically so that my test cases can mean something.

Best Regards,  
Allan

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [August 14, 2023, 9:18pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/2 "2023-08-14T21:18:31Z")

</div>

Use `isequal`.

---

<div class="post-metadata">

### Author: ![Gavin-Rockwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gavin-rockwood/32/219194_2.png) [@Gavin-Rockwood](https://discourse.julialang.org/u/Gavin-Rockwood)
#### Post date: [September 2, 2026, 1:55am UTC](https://discourse.julialang.org/t/symbolics-equality/102803/3 "2026-09-02T01:55:07Z")

</div>

Lol I know this is reviving a few years old thread, but I wanted to ask why this is still a thing with symbolics, as it generates a lot of comparability issues with other packages. Unless there is something within symbolics that utilizes == in a symbolic sense, this seems like a bad design choice?

For example, if I want to use symbolics with a package that runs `ishermitian` in a constructor, then it will just return an error. To fix this, it would require LinearAlgebra.jl, SparseArrays.jl and others to always be careful when doing any comparisons, and always use `isequal` instead of `==`.

---

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [September 2, 2026, 1:00pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/4 "2026-09-02T13:00:32Z")

</div>

Worth adding that `isequal` isn’t always the safe fallback either:

```julia
julia> using SymbolicUtils

julia> pkgversion(SymbolicUtils)
v"4.46.1"

julia> @syms U
(U,)

julia> (-U)^2
(U^2)

julia> isequal(U*U, U^2)
true

julia> isequal((-U)^2, U^2)
false

```

Those two print the same modulo a pair of parentheses, and `isequal` still says no. It’s a malformed single-argument `Mul` node - `simplify` on it throws a `BoundsError`, and `expand` normalises it away. Details in [SymbolicUtils.jl#1044](https://github.com/JuliaSymbolics/SymbolicUtils.jl/issues/1044).

My middle-school maths teacher passed away a few years ago. Small mercy: she never had to see the sign rule get an entry in a bug tracker. Though she did already ship the fix “expand it first” so `expand((-U)^2) == U^2` would have been a one-line answer from her, in red pen, with a note about tidying up my brackets. 😉

Edit: she was a [PEGC](https://fr.wikipedia.org/wiki/Professeur_d'enseignement_g%C3%A9n%C3%A9ral_de_coll%C3%A8ge).

---

<div class="post-metadata">

### Author: ![Gavin-Rockwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gavin-rockwood/32/219194_2.png) [@Gavin-Rockwood](https://discourse.julialang.org/u/Gavin-Rockwood)
#### Post date: [September 2, 2026, 2:36pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/5 "2026-09-02T14:36:08Z")

</div>

Not really. Isequal and == are both structural comparisons, you don’t want these to include an internal simplify / expand as it could make them really slow. Even then, for complicated expressions, they might still fail. They will always be not completely reliable, so it is better to do an explicit form manipulation before checking equality. The bigger issue here is that they way == is defined in symbolics makes this unreliable comparison impossible as most packages use == and not isequal, which generates a lot of incompatibility issues and makes it hard to fine new uses for Symbolics.jl.

Edit: there is a good argument for modifying how power works so that it can distribute to any negative signs within an Mul automatically on creation. But I think that’s separate from the compatibility issues the current setup introduces.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [September 4, 2026, 1:32pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/6 "2026-09-04T13:32:13Z")

</div>

> [@Gavin-Rockwood](#):
>
> Lol I know this is reviving a few years old thread, but I wanted to ask why this is still a thing with symbolics, as it generates a lot of comparability issues with other packages. Unless there is something within symbolics that utilizes == in a symbolic sense, this seems like a bad design choice?

This is standard Julia. It’s how the `==` and `isequal` docstring tell you to overload things. `==` does not generally return booleans, `isequal` does.

> [@Gavin-Rockwood](#):
>
> Unless there is something within symbolics that utilizes == in a symbolic sense

There’s a few thousand uses of this 😅, tracing standard numerical functions requires it for example.

---

<div class="post-metadata">

### Author: ![Gavin-Rockwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gavin-rockwood/32/219194_2.png) [@Gavin-Rockwood](https://discourse.julialang.org/u/Gavin-Rockwood)
#### Post date: [September 4, 2026, 5:35pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/7 "2026-09-04T17:35:06Z")

</div>

> [@ChrisRackauckas](#):
>
> This is standard Julia. It’s how the `==` and `isequal` docstring tell you to overload things. `==` does not generally return booleans, `isequal` does.

I’m a bit confused on this part, because the documentation states the output for `Base.:(==)` is `Bool` or `missing`. It says that type promotion should be done to facilitate this comparison, and `missing` is only returned in special cases. The current implementation in symbolics returns `Num`, which breaks with this convention. It’s this break with convention which makes compatibility with other packages in the julia ecosystem problematic, because if two symbolic expressions end up in a if a==b situation, it throws an error instead of returning a true/false, and most packages use this instead of `isequal`, because something like `isequal(0.0,-0.0)` returns false while `-0.0 == 0.0` returns true.

> [@ChrisRackauckas](#):
>
> There’s a few thousand uses of this 😅, tracing standard numerical functions requires it for example.

Let me phase this a bit better, are their routines in symbolics that are built around handling a the Num output of `x==b`? If not, then I don’t see any reason symbolics should break with the `Base.:(==)` convention outlined in the documentation.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [September 5, 2026, 7:52am UTC](https://discourse.julialang.org/t/symbolics-equality/102803/8 "2026-09-05T07:52:20Z")

</div>

> [@Gavin-Rockwood](#):
>
> Let me phase this a bit better, are their routines in symbolics that are built around handling a the Num output of `x==b`? If not, then I don’t see any reason symbolics should break with the `Base.:(==)` convention outlined in the documentation.

No, it’s because routines outside of Symbolics use `==` so we have to match that in order to trace.

---

<div class="post-metadata">

### Author: ![Gavin-Rockwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gavin-rockwood/32/219194_2.png) [@Gavin-Rockwood](https://discourse.julialang.org/u/Gavin-Rockwood)
#### Post date: [September 8, 2026, 7:28pm UTC](https://discourse.julialang.org/t/symbolics-equality/102803/9 "2026-09-08T19:28:07Z")

</div>

> [@ChrisRackauckas](#):
>
> No, it’s because routines outside of Symbolics use `==` so we have to match that in order to trace.

So, I’m still a bit confused on why that requires `Base.:(==)` to behave differently for `Num` instead of following outputs outlined in the documentation.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [September 12, 2026, 9:16am UTC](https://discourse.julialang.org/t/symbolics-equality/102803/10 "2026-09-12T09:16:21Z")

</div>

Because `Num` is a tracer, and if it doesn’t build a symbolic expression from it then it would not be able to continue through branches
