# TypeError when using Symbolics.jl with Polynomials.jl

**URL:** <https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842>\
**Category:** New to Julia\
**Tags:** symbolic\
**Created:** [March 24, 2021, 3:40am UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842 "2021-03-24T03:40:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbu](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jbu](https://discourse.julialang.org/u/jbu)\
**Post date:** [March 24, 2021, 3:40am UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842/1 "2021-03-24T03:40:17Z")

</div>

I’m new to the Symbolics.jl package, and I’m currently trying to use it in combination with other packages. However I keep getting the error `ERROR: TypeError: non-boolean (Num) used in boolean context` when I try to use symbolic variables with a couple other packages.

For example, I’ve tried with the Polynomials.jl package: (Full stacktrace at the bottom of this post for visual clarity.)

```julia
julia> using Polynomials, Symbolics

julia> @variables x
(x,)

julia> Polynomial([x, 1, 2])
Polynomial(Error showing value of type Polynomial{Num}:
ERROR: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
...

```

I’ve also tried with the ControlSystems.jl package (creating a transfer function), and I get the same error:

```julia
julia> using ControlSystems, Symbolics

julia> @variables x
(x,)

julia> tf([1],[x,1])
TransferFunction{Continuous, ControlSystems.SisoRational{Num}}
Error showing value of type TransferFunction{Continuous, ControlSystems.SisoRational{Num}}:
ERROR: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
...

```

Would someone be willing to explain what the cause of this issue might be?

**Julia version Info:**

```julia
julia> versioninfo()
Julia Version 1.6.0-rc3
Commit 23267f0d46 (2021-03-16 17:04 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)

```

**Package versions:**

- Symbolics.jl:

```julia
(practice1) pkg> st --manifest Symbolics
      Status `~/code3/julia/AI/practice1/Manifest.toml`
  [0c5d862f] Symbolics v0.1.9

```

- Polynomials.jl:

```julia
(practice1) pkg> st --manifest Polynomials
      Status `~/code3/julia/AI/practice1/Manifest.toml`
  [f27b6e38] Polynomials v1.2.0

```

- ControlSystems.jl:

```julia
(practice1) pkg> st --manifest ControlSystems
      Status `~/code3/julia/AI/practice1/Manifest.toml`
  [a6e380b2] ControlSystems v0.9.2

```

**Stacktraces:**

- For the Polynomial.jl example:

```julia
julia> using Polynomials, Symbolics                                                                                                                                                                        
                                                                                                                                                                                                           
julia> @variables x
(x,)

julia> Polynomial([x, 1, 2])
Polynomial(Error showing value of type Polynomial{Num}:
ERROR: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
  [1] printsign(io::IOContext{Base.TTY}, pj::Num, first::Bool, mimetype::MIME{Symbol("text/plain")})
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/show.jl:168
  [2] showterm(io::IOContext{Base.TTY}, #unused#::Type{Polynomial{Num}}, pj::Num, var::Symbol, j::Int64, first::Bool, mimetype::MIME{Symbol("text/plain")})
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/polynomials/standard-basis.jl:9
  [3] printpoly(io::IOContext{Base.TTY}, p::Polynomial{Num}, mimetype::MIME{Symbol("text/plain")}; descending_powers::Bool, offset::Int64, var::Symbol, compact::Bool, mulsymbol::String)
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/show.jl:145
  [4] printpoly
    @ ~/.julia/packages/Polynomials/OvhiS/src/show.jl:138 [inlined]
  [5] show(io::IOContext{Base.TTY}, mimetype::MIME{Symbol("text/plain")}, p::Polynomial{Num})
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/show.jl:56
  [6] (::REPL.var"#38#39"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:220
  [7] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:462
  [8] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:213
  [9] display(d::REPL.REPLDisplay, x::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:225
 [10] display(x::Any)
    @ Base.Multimedia ./multimedia.jl:328
 [11] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
 [12] invokelatest
    @ ./essentials.jl:706 [inlined]
 [13] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:247
 [14] (::REPL.var"#40#41"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:231
 [15] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:462
 [16] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:229
 [17] (::REPL.var"#do_respond#61"{Bool, Bool, REPL.var"#72#82"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:798
 [18] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
 [19] invokelatest
    @ ./essentials.jl:706 [inlined]
 [20] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
    @ REPL.LineEdit /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/LineEdit.jl:2441
 [21] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:1126
 [22] (::REPL.var"#44#49"{REPL.LineEditREPL, REPL.REPLBackendRef})()
    @ REPL ./task.jl:406

```

- For the ControlSystems.jl example:

```julia
julia> using ControlSystems, Symbolics                                                                                                                                                                     
                                                                                                                                                                                                           
julia> @variables x                                                                                                                                                                                        
(x,)                                                                                                                                                                                                       
                                                                                                                                                                                                           
julia> tf([1],[x,1])                                                                                                                                                                                       
TransferFunction{Continuous, ControlSystems.SisoRational{Num}}                                                                                                                                             
Error showing value of type TransferFunction{Continuous, ControlSystems.SisoRational{Num}}:                                                                                                                
ERROR: TypeError: non-boolean (Num) used in boolean context                                                                                                                                                
Stacktrace:
  [1] printsign(io::IOContext{IOBuffer}, pj::Num, first::Bool, mimetype::MIME{Symbol("text/plain")})                                                                                                       
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/show.jl:168
  [2] showterm(io::IOContext{IOBuffer}, #unused#::Type{Polynomial{Num}}, pj::Num, var::Symbol, j::Int64, first::Bool, mimetype::MIME{Symbol("text/plain")})
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/polynomials/standard-basis.jl:9
  [3] printpoly(io::IOBuffer, p::Polynomial{Num}, mimetype::MIME{Symbol("text/plain")}; descending_powers::Bool, offset::Int64, var::Symbol, compact::Bool, mulsymbol::String)
    @ Polynomials ~/.julia/packages/Polynomials/OvhiS/src/show.jl:145
  [4] #90 (repeats 2 times)
    @ ~/.julia/packages/ControlSystems/D98Nv/src/utilities.jl:57 [inlined]
  [5] sprint(f::Function, args::Polynomial{Num}; context::Nothing, sizehint::Int64)
    @ Base ./strings/io.jl:105
  [6] sprint
    @ ./strings/io.jl:101 [inlined]
  [7] print_siso(io::IOContext{Base.TTY}, f::ControlSystems.SisoRational{Num}, var::Symbol)
    @ ControlSystems ~/.julia/packages/ControlSystems/D98Nv/src/types/SisoTfTypes/SisoRational.jl:48
  [8] show(io::IOContext{Base.TTY}, G::TransferFunction{Continuous, ControlSystems.SisoRational{Num}})
    @ ControlSystems ~/.julia/packages/ControlSystems/D98Nv/src/types/TransferFunction.jl:174
  [9] show(io::IOContext{Base.TTY}, #unused#::MIME{Symbol("text/plain")}, x::TransferFunction{Continuous, ControlSystems.SisoRational{Num}})
    @ Base.Multimedia ./multimedia.jl:47
 [10] (::REPL.var"#38#39"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:220
 [11] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:462
 [12] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:213
 [13] display(d::REPL.REPLDisplay, x::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:225
 [14] display(x::Any)
    @ Base.Multimedia ./multimedia.jl:328
 [15] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
 [16] invokelatest
    @ ./essentials.jl:706 [inlined]
 [17] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:247
 [18] (::REPL.var"#40#41"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:231
 [19] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:462
 [20] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:229
 [21] (::REPL.var"#do_respond#61"{Bool, Bool, REPL.var"#72#82"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:798
 [22] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
 [23] invokelatest
    @ ./essentials.jl:706 [inlined]
 [24] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
    @ REPL.LineEdit /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/LineEdit.jl:2441
 [25] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
    @ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:1126
 [26] (::REPL.var"#44#49"{REPL.LineEditREPL, REPL.REPLBackendRef})()
    @ REPL ./task.jl:406

```

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [March 24, 2021, 4:18am UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842/2 "2021-03-24T04:18:59Z")

</div>

For the Polynomials case, the issue arises because `Num <: Real`., and so `Polynomials.hasneg(Num) = true`. This in turn means that `isneg(x::Num) = x < zero(Num)`, which is expected to be a `Bool`, but actually gets turned into another `Num` that encodes the comparison. All of this logic happens while trying to pretty print the `Polynomial`. It is possible that only the printing is broken by this type of issue, but I haven’t checked.

This is a tricky problem. On the one hand, it seems like code ought to be able to assume that logical comparisons of subtypes of `Real` will yield a `Bool`, but on the other hand, the value of `x` is unknown, so `Symbolics` can’t truthfully make the comparison until a value for `x` is specified.

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [March 24, 2021, 11:43am UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842/3 "2021-03-24T11:43:05Z")

</div>

[Edit, sorry, I see adamsic beat me to much of this…]

For `Polynomials.jl` the issue is the use of conditional formatting based on the values of a coefficient. E.g. [https://github.com/JuliaMath/Polynomials.jl/blob/master/src/polynomials/standard-basis.jl#L5](https://github.com/JuliaMath/Polynomials.jl/blob/master/src/polynomials/standard-basis.jl#L5)

There we check if the coefficient is zero, which for a symbolic value is not a Boolean, rather a symbolic expression. For that particular one, we could write `x === zero(x)`, perhaps a pattern that would also work for other number types.

In `SymPy`, that is essentially how `iszero` is defined. `SymPy` has two different ways to test for zeroness: sympy has `Eq(x,0)` and for julia use there is `iszero(x)`. The latter intended to be used generically, the former for symbolic treatment.

---

<div class="post-metadata">

**Author:** ![jbu](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jbu](https://discourse.julialang.org/u/jbu)\
**Post date:** [March 24, 2021, 4:46pm UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842/4 "2021-03-24T16:46:02Z")

</div>

Thanks for those great explanations. It looks like the error for the ControlSystems.jl might stem from the Polynomials.jl package as well. I’ll post this as an issue on Github.

Just speculating, but for printing purposes I wonder if it would be helpful (or possible) to distinguish between the sign of the unevaluated variable and the sign of the evaluated variable. For example, the unevaluated term -x could be considered “negative” for printing purposes, even though evaluating -x at any negative value of x results in a positive number.

---

<div class="post-metadata">

**Author:** ![jbu](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jbu](https://discourse.julialang.org/u/jbu)\
**Post date:** [March 24, 2021, 4:59pm UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842/5 "2021-03-24T16:59:06Z")

</div>

As an update, I’m able to put Symbolic variables in Polynomials if all output is suppressed. For example, the following works just fine:

```julia
julia> using Polynomials, Symbolics

julia> @variables x y
(x, y)

julia> z = Polynomial([x, y, 1]); # Note the semicolon

julia> z[0]
x

julia> z[1]
y

```

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [March 24, 2021, 7:48pm UTC](https://discourse.julialang.org/t/typeerror-when-using-symbolics-jl-with-polynomials-jl/57842/6 "2021-03-24T19:48:26Z")

</div>

This is addressed here: [https://github.com/JuliaMath/Polynomials.jl/pull/321](https://github.com/JuliaMath/Polynomials.jl/pull/321)

After this is merged, you might still wish to add a method to `Base.show_unquoted`, as mentioned in `?Polynomials.printcoefficient`:

```julia
julia> @variables a b c
Poly(a, b, c)

julia> Polynomial([c,b,a])
Polynomial(c + b*x + a*x^2)

julia> Polynomial([c,b,a]) + Polynomial([a,b,c])
Polynomial(a + c + 2b*x + a + c*x^2)

julia> function Base.show_unquoted(io::IO, pj::Num, indent::Int, prec::Int)
              if Base.operator_precedence(:+) <= prec
                   print(io, "(")
                   show(io, pj)
                   print(io, ")")
               else
                   show(io, pj)
               end
           end

julia> Polynomial([c,b,a]) + Polynomial([a,b,c])
Polynomial((a + c) + (2b)*x + (a + c)*x^2)

```
