1

刚开始用 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).
4

2 回答 2

2

这些不是内存地址。这些是自由变量。您看到的是它们在您选择的 prolog 系统中的内部名称。然后,正如@chac 指出的那样(+1 顺便说一句),第三个子句没有任何意义!也许您可以尝试告诉我们您的意思,以便我们了解如何正确执行此操作。

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

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

在这里,在你的duple1/3谓词中,我们告诉 prolog 结果列表的长度LN,然后我们告诉它每个元素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.

这在我们的第一个谓词中之前有效!

希望这会有所帮助。

于 2012-03-28T20:06:33.813 回答
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].
于 2012-03-28T19:43:41.503 回答