The integer/1 predicate you used is true if its argument is an integer. Since the term truncate(sqrt(9)) not an integer, the predicate does not execute and does not fail for this term.
There are at least two ways to get what you want:
Solution 1: Fast and Broken
You can use the predicate (is)/2 to convert between different representations of a number. In particular, check the arithmetic functions round , truncate and ceiling . For example:
? - X is round (sqrt (9)).
X = 3.
However, note that using floating point numbers is always very problematic. For example:
? - X is sqrt (2 ^ 10000).
ERROR: is / 2: Arithmetic: evaluation error: `float_overflow '
There are other problems, such as rounding errors and possible under-implementation.
Solution 2: Quick and General
Due to the inherent flaws of floating point numbers, I strongly recommend that you use more general mechanisms instead. For example, several Prolog systems support rational numbers and integers with unlimited precision, while floats are always limited by machine accuracy.
If you need integer square roots, use, for example, destination domain restrictions . With restrictions, it suffices to indicate what holds for an integer X , which denotes a positive square root:
? - X * X # = 9, X #> = 0.
X = 3.
This also works for large integers:
? - X * X # = 2 ^ 10000 , X #> = 0.
X = 1412467032 ... (1496 digits omitted)
See clpfd for more information.