Prolog中的乘法代码不起作用

时间:2014-03-17 11:56:58

标签: prolog

这是我在Prolog中创建乘法运算符的尝试。

times1(X,Y,Z) :- Z=X*Y.

但它不起作用,我不知道为什么。谁能认出这个问题?

times1(0,Y,0):-!.
times1(X,0,0):-!.
times1(X,Y,Z):- X<0,Y<0,!, times1(-X,-Y,Z).
times1(X,Y,Z):- X>0,!,times1(X-1,Y,Z1),Z is Z1+Y.
times1(X,Y,Z):- X<0,Y>0,times1(Y,X,Z).

第二次尝试:

times1(0,ֹ_,0):-!. 
times1(_,0,0):-!.  
times1(X,Y,Z):- X<0,Y=\=0,X1 is -X, times1(X1,Y,Z1), Z is -Z1.
times1(X,Y,Z):- X>0,Y=\=0, X2 is X-1, times1(X2,Y,Z1),Z is Z1+Y.

仍然不起作用......

1 个答案:

答案 0 :(得分:3)

在你的第一个解决方案中:

times1(X,Y,Z) :- Z=X*Y.

问题在于使用统一而不是表达评估。使用is/2进行表达式评估:

times1(X,Y,Z) :- Z is X*Y.

在第二个解决方案中:

times1(0,Y,0):-!.
times1(X,0,0):-!.
times1(X,Y,Z):- X<0,Y<0,!, times1(-X,-Y,Z).
times1(X,Y,Z):- X>0,!,times1(X-1,Y,Z1),Z is Z1+Y.
times1(X,Y,Z):- X<0,Y>0,times1(Y,X,Z).

在表达式times1(X-1,Y,Z1)中,Prolog在将其用作递归调用的参数之前不会评估X-1。您需要明确地执行此操作:X1 is X-1, times1(X1,Y,Z1)

此外,你不需要这么多削减。例如,由于您已经检查了其他谓词子句中X的{​​{1}}和Y条件,因此基本情况可能只是:

0

您无需同时检查times1(0, _, 0). % 0 times anything is 0 times1(_, 0, 0). % Anything times 0 is 0 X为否定因为Y,如果X*Y为否定,则可能只有Y个无论X的符号如何,Y值都会加在一起。然后,在否定Y得到结果之后,你仍然需要否定最终的总和(以补偿否定的X):

X

除了times1(X, Y, Z) :- X < 0, Y =\= 0, times1(-X, Y, Z1), Z is -Z1. times1(X, Y, Z) :- X > 0, Y =\= 0, X1 is X-1, times1(X1, Y, Z1), Z is Z1+Y. Y < 0案例已合并为Y > 0之外,这几乎与您所拥有的一样,我对{{1}进行了额外检查在Y =\= 0案例中避免削减,最后Y =\= 0补偿否定X > 0

请注意,Z is -Z1无需先执行X即可运行,因为当times1(-X,Y,Z1)传递给X1 is -X时,-X首先评估times1或{{ 1}}将评估times1的表达式,因此X < 0将根据需要进行评估。虽然首先做X > 0并且不做出假设仍然可能更安全。所以第一个条款将成为:

X

测试:

-

X1 is -Xtimes1(X, Y, Z) :- X < 0, Y =\= 0, X1 is -X, times1(X1, Y, Z1), Z is -Z1. 相乘会显示两个解决方案,因为它匹配两个案例。如果需要,可以使用原始解决方案中的方法消除切割,或者可以调整谓词逻辑,以便强制执行非重叠的情况。