刚开始用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).
答案 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).
但请注意,因为我们使用>/2
,is
和-/2
,即算术,我们会阻止prolog以多种方式使用此谓词,例如:
?- duple1(X, Y, [xyz, xyz]).
X = 2,
Y = xyz.
这在我们的第一个谓语中起作用了!
希望这有一些帮助。