Если вы хотите генерировать натуральные числа, вы можете сделать это без использования разрезов или управляющей конструкции fail/0
. Например:
nat(Nat) :-
next_integer(0, Nat).
next_integer(I, I).
next_integer(I, K) :-
J is I + 1,
next_integer(J, K).
Пример вызова:
| ?- nat(Nat).
Nat = 0 ? ;
Nat = 1 ? ;
Nat = 2 ? ;
Nat = 3 ?
...
Но этот предикат не будет работать, если вместо этого вы захотите проверить , если термин является натуральным числом. Например, следующий вызов приведет к переполнению стека в большинстве систем Prolog (поскольку мы не можем сгенерировать отрицательное целое число путем увеличения от нуля):
| ?- nat(-3).
Если вы используете систему Prolog, предоставляющую CLP ( FD), вы можете использовать лучшее определение:
nat(Nat) :-
Nat #>= 0,
next_integer(0, Nat).
next_integer(I, I).
next_integer(I, K) :-
J is I + 1,
next_integer(J, K).
И затем использовать тот же предикат для генерации и тестирования. Например, используя SWI-Prolog и library(clpfd)
:
?- nat(Nat).
Nat = 0 ;
Nat = 1 ;
Nat = 2 ;
Nat = 3
...
?- nat(-3).
false.
Без использования библиотеки ограничений вам нужно написать что-то вроде:
nat(Nat) :-
( var(Nat) ->
next_integer(0, Nat)
; integer(Nat), Nat >= 0
).