Использованный вами предикат integer/1
равен true тогда его аргумент является целым числом.Поскольку термин truncate(sqrt(9))
является , а не целым числом, предикат удерживается не и, следовательно, не может для этого термина.
как минимум два способа получить то, что вы хотите:
Решение 1: Быстрый и неработающий
Вы можете использовать предикат (is)/2
для преобразования между различными представлениями чисел.В частности, обратите внимание на арифметические функции round
, truncate
и ceiling
.Например:
?- X is round(sqrt(9)).
X = 3.
Однако учтите, что использование чисел с плавающей запятой всегда весьма проблематично .Например:
?- X is sqrt(2^10000).
<b>ERROR: is/2: Arithmetic: evaluation error: `float_overflow'</b>
Существуют и другие проблемы, такие как ошибки округления и возможный недополнение.
Решение 2. Быстрое и общее
Из-за присущих плавающихчисла точек, я настоятельно рекомендую вместо этого использовать более общие механизмы .Например, некоторые системы Prolog поддерживают рациональные числа и целые числа с неограниченной точностью, тогда как числа с плавающей точкой всегда ограничены точностью станка.
Если вам нужно целое число квадратные корни, используйте, например, ограничение конечной области .С ограничениями достаточно указать, что содержит для целого числа X
, которое обозначает положительный квадратный корень:
?- X*X #= 9, X #>= 0.
X = 3.
Это также работает для больших целых чисел:
?- X*X #= <b>2^10000</b>, X #>= 0.
<b>X = 1412467032...(1496 digits omitted)</b>
См. clpfd для получения дополнительной информации.