If you don't mind using an external SMT solver, you can use the SBV package:
Prelude Data.SBV> allSat $ \x -> 2*x^3-19*x^2+15*x+72 .== (0::SReal)
Solution #1:
s0 = 3.0 :: Real
Solution #2:
s0 = 8.0 :: Real
Solution #3:
s0 = -1.5 :: Real
Found 3 different solutions.
You are guaranteed that the roots will be precise, i.e., no rounding error will happen. The Real
type corresponds to infinitely precise algebraic reals. If the result cannot be printed in a finite form, it'll be written as the root of a simple equation and will be expanded to the current print precision:
Prelude Data.SBV> allSat $ \x -> x^2-2 .== (0::SReal)
Solution #1:
s0 = root(1, x^2 = 2) = -1.414213562373095... :: Real
Solution #2:
s0 = root(2, x^2 = 2) = 1.414213562373095... :: Real
Found 2 different solutions.
The number of digits can be arbitrarily long and is configurable:
Prelude Data.SBV> allSatWith z3{printRealPrec=20} $ \x -> x^2-2 .== (0::SReal)
Solution #1:
s0 = root(1, x^2 = 2) = -1.4142135623730950488... :: Real
Solution #2:
s0 = root(2, x^2 = 2) = 1.4142135623730950488... :: Real
Found 2 different solutions.
Note that SMT solvers will only get you real-roots; no complex solutions will be found:
Prelude Data.SBV> allSat $ \x -> x^2+1 .== (0::SReal)
No solutions found.
If only some roots are real, those will be found:
Prelude Data.SBV> allSat $ \x -> x^3+2*x-1 .== (0::SReal)
Solution #1:
s0 = root(1, x^3+2x = 1) = 0.4533976515164037... :: Real
This is the only solution.
PS. To make this all work, do not forget to first install Z3 on your machine. You can get a recent copy from https://github.com/Z3Prover/z3/releases