所以我的问题是这样的,我有一个谓词repete_el(El,N,L),其中El是一个元素,N是重复的次数,L是包含该元素重复N次的列表。
我的问题是,它没有重复该元素,而是给出了 false,我不明白为什么。
示例:
我的输出:
?- repete_el(a,3,L).
false
正确输出:
?- repete_el(a,3,L).
L = [a,a,a].
节目:
repete_el(El,0,[]) :- !.
repete_el(El,N,L) :- repete_el(El,N,L,[],N).
repete_el(El,N,L,L2) :- length(L2,C),
C =< N,
append(L2,[N],NL),
repete_el(El,N,L,NL).
顺便说一下,我只能迭代地执行此操作。
您可以使用标准
findall/3
谓词和事实上的标准 between/3
谓词。例如:
| ?- findall(a, between(1,5,_), List).
List = [a, a, a, a, a]
yes
这不起作用的原因是因为在您调用
repete_el/4
时,L2
是一个自由变量,因此 length(L2, C)
将开始构建各种具有长度的列表。然后,您对列表 NL
进行递归调用,并额外添加一个元素,并且您要求该列表再次具有长度 C
(应再次小于 N
)。但最终 C
将大于 N
,因此谓词将失败。
你可以写这样的谓词:
repete_el(_, 0, []). %% (1)
repete_el(X, N, [X|T]) :- %% (2)
N > 0,
N1 is N-1,
repete_el(X, N1, T).
我们在此说:
(1) 重复元素
次的列表是空列表;和 (2) 重复0
,X
次且N
大于N
的列表是以0
开头,以重复X
,X
的列表结束次。N-1
我喜欢将
maplist/2
与 =/2
结合使用来实现此目的。例如,
| ?- length(L, 3), maplist(=(a), L).
L = [a,a,a]
yes
| ?- length(L, 9), maplist(=(abc), L).
L = [abc,abc,abc,abc,abc,abc,abc,abc,abc]
yes
| ?-