prolog函数返回内存位置而不是值

时间:2012-03-28 19:26:58

标签: prolog prolog-toplevel

刚开始用prolog编程,我遇到了一些问题。我所拥有的函数应该取值X并将其复制N次到M.我的函数返回N个内存位置的列表。这是代码,任何想法?

duple(N,_,M):- length(M,Q), N is Q.
duple(N,X,M):- append(X,M,Q), duple(N,X,Q).

2 个答案:

答案 0 :(得分:2)

我想你以这种方式调用你的谓词:

?- duple(3,xyz,L).

你得到了

L = [_G289, _G292, _G295] ;
ERROR: Out of global stack

如果您尝试

?- length(X,Y).
X = [],
Y = 0 ;
X = [_G299],
Y = 1 ;
X = [_G299, _G302],
Y = 2 ;
X = [_G299, _G302, _G305],
Y = 3 ;
X = [_G299, _G302, _G305, _G308],
Y = 4 .
...

你可以看到发生了什么:

您的查询将匹配指定的*M*,显示M个未实例化变量(内存位置)的列表,然后继续回溯并生成更长的列表,直到有堆栈空间。你的第二条规则永远不会解雇(我并不真正理解它的目的)。

以这种方式编写生成器更容易:

duple(N,X,M) :- findall(X,between(1,N,_),M).

试验:

?- duple(3,xyz,L).
L = [xyz, xyz, xyz].

答案 1 :(得分:2)

那些不是记忆地址。那些是自由变量。你看到的是你选择的prolog系统中的内部名称。然后,正如@chac指出的那样(+1顺便说一句),第三个条款并没有真正有意义!也许你可以试着告诉我们你的意思,这样我们就能明白如何正确地做到这一点。

我将为您提供两个谓词实现,以尝试向您显示正确的Prolog语法:

duple1(N, X, L) :-
    length(L, N),
    maplist(=(X), L).

在这里,在您的duple1/3谓词中,我们告诉prolog结果列表L的长度是N,然后我们告诉它L的每个元素应与X统一以保留谓词。

另一个要做的是通过递归“手动”构建结果列表:

duple2(0, _X, []).
duple2(N, X, [X|L]) :-
    N > 0,
    NewN is N - 1,
    duple1(NewN, X, L).

但请注意,因为我们使用>/2is-/2,即算术,我们会阻止prolog以多种方式使用此谓词,例如:

?- duple1(X, Y, [xyz, xyz]).
X = 2,
Y = xyz.

这在我们的第一个谓语中起作用了!

希望这有一些帮助。