当你查询even(0)时,如你所见,它成功了。但是您也看到它提示您获取更多结果,因为它留下了choicepoint,这是逻辑中 Prolog 决定它可以返回并探索可能成功查询的其他替代方案的地方。返回选择点并尝试找到更多解决方案后,它没有找到更多解决方案,因此它返回“错误”,因为它没有找到更多解决方案。所以它确实只找到了一个解决方案,但是选择点导致回溯,之后它没有找到其他解决方案。您的其他成功查询也是如此。
您会注意到,如果您进行更一般的查询,它会给出错误(示例取自 GNU Prolog):
| ?- even(N).
N = 0 ? ;
uncaught exception: error(instantiation_error,(>)/2)
| ?-
这是因为您正在使用需要实例化变量的特定算术表达式运算符。这些是关系运算符,例如 (>)/2 和 is/2 运算符。您可以使用专为整数推理而设计的 CLP(FD) 运算符使解决方案更具相关性:
even(0).
even(N) :-
N #> 0,
N1 #= N-1,
odd(N1).
odd(N) :-
N #> 0,
N1 #= N-1,
even(N1).
然后你得到一个更通用的解决方案,它更完整,更有用:
| ?- even(N).
N = 0 ? ;
N = 2 ? ;
N = 4 ? ;
N = 6 ? ;
...
| ?- odd(N).
N = 1 ? ;
N = 3 ? ;
N = 5 ? ;
N = 7 ?
...
如果您知道最多有一个答案,或者您只关心第一个可能的答案,您可以使用
once/1(此处的示例取自 SWI Prolog):
2 ?- even(2).
true ;
false.
3 ?- once(even(2)).
true.
4 ?- even(N).
N = 0 ;
N = 2 ;
N = 4 ;
...
5 ?- once(even(N)).
N = 0.
6 ?-
正如预期的那样,once(even(N)) 在找到第一个解决方案后终止。