第一次和Prolog一起玩,虽然我觉得我知道它基本上有什么好处,但我觉得很难完成任何事情。所以,我试图找到最容易的任务,甚至没有完成。
我认为这是因为我不知道prolog数据类型(数字)应该如何工作或者它们具有特殊的语法。
所以,我第一次尝试对偶数进行分类是:
even(0).
even(X) :- even(X-2).
结果:查询的堆栈溢出:even(2)。
所以我认为如果不是这样,那么也许就是:
even(0).
even(X+2) :- even(X).
偶数(2)的结果:错误。
所以我的简单问题是:如何在prolog中编写这样简单的东西?这一切都不起作用,因为我使用数字?
答案 0 :(得分:3)
为什么不以正常的方式去做:
is_even(X) :-
X /\ 0x1 =:= 0.
如果你想在没有约束参数的情况下在回溯时枚举非负偶数,那么这完全是另一回事。可能很容易说:
even(X) :-
between(0, infinite, X),
is_even(X).
您可以使用第二个定义:
?- even(X).
X = 0 ;
X = 2 ;
X = 4 ;
X = 6 . % and so on
is_even/1
和even/1
之间存在一些差异:
is_even/1
适用于任何整数,正数或负数is_even/1
将用于评估整数的表达式,例如X = 3, ..., is_even(X + 1)
。这是因为=:=
接受任何一方的算术表达式。even/1
使用between/3
,因此 X 的域名和错误条件与between/3
的第三个参数相同。even/1
不适用于负整数或算术表达式。但等等,还有更多!
显然,between(0, infinite, X)
除了SWI之外几乎不能在任何Prolog中做到。因此,相反,您可以使用另一个将枚举正整数的谓词(列表长度):
even_f(X) :-
length(_, X),
is_even(X).
(感谢@false)
答案 1 :(得分:0)
使用is/2
强制进行算术评估。就其本身而言,Prolog术语只是结构符号实体,X-2
是arity 2的复合术语,-(X,2)
:
3 ?- write_canonical( X-2 ).
-(_,2)
true.
但是is
用于算术表达式:
4 ?- Z is 5-2.
Z = 3.
因此,您的定义应为
even(X):- X=:=0 -> true
; X > 0 -> Y is X-2, even(Y).
这种定义的缺点是它不能以生成方式调用,如even(X)
,以便一个接一个地生成所有的平均值。
只检查给定的数字。为简单起见,它忽略了负数并且总是对它们失败。