给出如下的查询:
containsN(4,2,Z).
我应该得到:Z = [2,2,2,2]。
或
containsN(4,W,[3,3,3,3])
我应该得到:W = 3。
换句话说,对于第一个例子,我需要在绑定到Z的列表中有4个2的实例。
对于第二个例子,我需要将列表中的元素应用4次绑定到W。
到目前为止,我的尝试导致无限循环:
containsN(Y,W,Z) :- contains_helper(Y,W,Z).
contains_helper(0,_,_).
contains_helper(Y,W,[H|T]) :- W = H, Y0 is Y - 1, contains_helper(Y0,W,T).
我的想法是,我称之为辅助函数,以便我可以逐个检查Z的元素。当计数器达到0时,我知道列表为真,因为每次迭代H = W.但是,我得到一个无限循环。
答案 0 :(得分:2)
如果您希望谓词尽可能通用(我将其重命名为repeat/3
)
?- repeat(X, N, L).
N = 0, L = [] ;
N = 1, L = [X] ;
...
您可以使用length/2
的漂亮属性,如下所示:
% True when L is a list with N repeats of X
repeat(X, N, L) :-
length(L, N),
maplist(=(X), L).
在这里,length(L, N)
可以检查列表的长度,或者生成所需长度的列表,或者在回溯时生成增加长度的列表。
如果列表L的每个元素与变量X统一,maplist(=(X), L)
将成功。您可以将其写为:
foo([], _).
foo([X|Xs], X) :-
foo(Xs, X).
但我不认为这是必要的。