Пролог - это реляционный язык, а не функциональный язык. Таким образом, когда вы вызываете odd2(X-1)
, аргумент предиката X-1
не оценивается как выражение, но интерпретируется как составной термин :
?- functor(X-1, Name, Arity).
Name = (-),
Arity = 2.
Вы можете проверить, что произойдет, когда Prolog подтвердит запрос, используя функции системной трассировки:
?- trace.
true.
[trace] ?- even2(2).
Call: (8) even2(2) ? creep
Call: (9) 2>0 ? creep
Exit: (9) 2>0 ? creep
Call: (9) odd2(2-1) ? creep
Call: (10) 2-1>0 ? creep
Exit: (10) 2-1>0 ? creep
Call: (10) even2(2-1-1) ? creep
Call: (11) 2-1-1>0 ? creep
Fail: (11) 2-1-1>0 ? creep
Fail: (10) even2(2-1-1) ? creep
Fail: (9) odd2(2-1) ? creep
Fail: (8) even2(2) ? creep
false.
Обратите внимание, что выражение 2-1-1
оценивается как ноль, но, будучи составным термином, вызов even2(2-1-1)
не объединяется с вашим базовым регистром для предиката, even2(0)
:
?- even2(2-1-1) = even2(0).
false.
?- 2-1-1 = 0.
false.
Следовательно, Prolog пробует второе предложение, и вызов в конечном итоге не проходит проверку X>0
. Обратите внимание, что >/2
, будучи предикатом арифметического сравнения, он оценивает свои аргументы до фактического сравнения.