3

不断收到Arguments are not sufficiently instantiated我写的乘法乘法规则的错误,如下所示。

mult(_, 0, 0).                                   %base case for multiplying by 0
mult(X, 1, X).                                   % another base case
mult(X, Y, Z) :-
   Y > 1,
   Y1 is Y - 1,
   mult(X, Y1, Z1),
   Z is X + Z1. 

我是 Prolog 的新手,即使是这样简单的问题也很挣扎。

任何关于书籍或在线教程的建议都会很棒。

我在 Ubuntu Linux 上的 SWI-Prolog 上运行它。

4

2 回答 2

4

在您mult/3对前两个参数的定义中必须知道。如果其中一个仍然是变量,则会发生实例化错误。例如。mult(2, X, 6)会产生一个实例化错误,虽然X = 3是一个正确的答案;事实上,唯一的答案。

您有几种选择:

、约束或元逻辑谓词。

这是后继算术的起点:

add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

另一种方法是对整数使用约束。YAP 和 SWI 有一个library(clpfd)可以以非常灵活的方式使用的方法:用于常规整数计算和更一般的约束。当然,乘法已经预定义:

?- A * B #= C。
A*B#=C。

?- A * B #= C, C = 6。
C = 6,
A in -6.. -1\/1..6,
A*B#=6,
B 在 -6.. -1\/1..6.

?- A * B #= C, C = 6, A = 2。
A = 2,
B = 3,
C = 6。

元逻辑谓词:我不推荐使用var/1, nonvar/1,ground/1来区分各种情况并以不同方式处理它们的选项。这很容易出错,以至于我很少看到使用它们的正确程序。事实上,即使是非常有名的教科书也包含严重的错误!

于 2012-03-20T12:29:33.010 回答
2

我想你把最后两个电话打反了。你不是说:

mult(X,Y,Z):- Y>1,Y1 is Y-1, Z1 is X+Z, mult(X,Y1,Z1).

编辑:没关系,再次查看代码并没有意义。我相信您的原始代码是正确的。

至于为什么会发生这个错误,我需要知道你是如何调用谓词的。你能举个例子输入吗?

调用谓词的正确方法是mult(+X, +Y, ?Z)

?- mult(5,0,X).
X = 0

?- mult(5,1,X).
X = 5

?- mult(5,5,X).
X = 25

?- mult(4,4,16).
yes

?- mult(3,3,10).
no

等等。在前两个参数中使用自由变量调用它会产生该错误,因为其中一个将用于 a 的右侧is或 的任一侧<,并且这些谓词期望基本术语成功。

于 2012-03-19T18:09:16.157 回答