这些子句的问题在于 Prolog 不会将算术表达式内联计算为查询谓词的参数。
所以这个:
even(X) :- X>0, odd(X-1).
odd(X) :- X>1, even(X-1).
如果查询为even(2) 将导致:
2 > 0, % success
odd(2-1). % hmmm
然后odd(2-1)(真正的意思是odd('-'(2,1)))不会匹配odd(1),它会去odd(X)并给出:
2-1>1, % This will evaluate, but will fail because 1>1 is false
由于>/2 是一个评估比较,它会进行评估。但为时已晚,因为选择了错误的子句。所以你会失败。
您需要预先评估:
even(0).
even(X) :- X>0, X1 is X-1, odd(X1).
odd(1).
odd(X) :- X>1, X1 is X-1, even(X1).
Prolog 将计算 is/2 的第二个参数上的表达式,例如:
Y is (X+1)/2.
或者如果在比较运算符中进行数字比较。例如,以下将在比较之前评估表达式:
Y+7 < X*2
X/2 =:= Y mod 2
请注意,=/2 不计算表达式。它是一个 unification 运算符。所以:
X-2 = Y*2
会失败,因为它试图将'-'(X,2) 与'*'(Y,2) 统一起来。