说我需要一个谓词代表(?List ,?Times ,?TList ),如果 List 在 TList 中重复 Times 次(例如,rep([a,c],2,[a,c,a,c])
)。只要实例化了两个参数,它就应该工作。这是一个有点工作的版本:
rep(_,0,[]).
rep(List,1,List).
rep(List,Times,TList) :- integer(Times), Times>1,
succ(RemTimes,Times), append(List,RemList,TList),
rep(List,RemTimes,RemList).
rep(List,Times,TList) :- var(Times),
append(List,RemList,TList),
rep(List,RemTimes,RemList), !,
succ(RemTimes,Times).
两个问题:
答案 0 :(得分:1)
您使用SWI-Prolog,因此您可以这样做:
:- use_module(library(lambda)).
rep(Lst, N, R) :-
( numlist(1,N, NL)
-> foldl(\_X^Y^Z^append(Y, Lst, Z), NL, [], R)
; R = []).
要解决CapelliC的评论,不报告对代表的X绑定(X,2,[a,b,a,b]) 你必须写
foldl(Lst +\_X^Y^Z^append(Y, Lst, Z), NL, [], R)
[编辑]谢谢@false!有趣的是
rep(Lst, N, R) :-
( nonvar(N)
-> length(NL, N),
foldl(Lst +\_^Y^append(Y, Lst), NL, [], R)
; foldl(Lst +\_^Y^append(Y, Lst), NL, [], R),
length(NL, N)),
!.
但不幸的是,它与rep([a,b],N,[a,c,a,c])循环!
答案 1 :(得分:0)
一个简单(但可能效率低下)的策略是扫描第二个列表并每次检查第一个列表是否是剩余部分的子列表。
要进行检查,您可以使用SWI-Prolog的prefix/2
运算符。
sublist_count(L, R, Times) :-
sublist_count(L, R, 0, Times).
sublist_count(L, [], Times, Times).
sublist_count(L, [R | Tail], Times, End) :-
prefix(L, [R | Tail]), !,
NewTimes is Times + 1,
sublist_count(L, Tail, NewTimes, End).
sublist_count(L, [R | Tail], Times, End) :-
sublist_count(L, Tail, Times, End).
答案 2 :(得分:0)
我不知道一个专门的内置。这是一个使用length / 2
的生成能力的程序rep(List, Times, TList) :-
( var(Times) ; Times > 0 ), % after joel76' comment...
( var(List) ; is_list(List) ), % after false' comment...
( var(TList) ; is_list(TList) ), % idem...
length(List, LA), LA > 0,
length(TList, LT), LT > 0,
Times is LT / LA,
findall(List, between(1, Times, _), [List|Ls]),
append([List|Ls], TList), !.
当任何列表空闲时,最终剪切避免循环。
答案 3 :(得分:0)
以下是否有意义。 (我没有处理Times
未定义的情况。)
rep(List, Times, TList) :-
length(List, ListLen),
PrefixLen is ListLen * Times,
open_list(List, OpenList, OpenList),
length(TList, PrefixLen),
append(TList, _, OpenList).
其中open_list/3
定义为:
open_list([], X, X).
open_list([H | T1], [H | T2], X) :-
open_list(T1, T2, X).
我们的想法是创建一个无限列表,然后关闭所需的前缀。
用法示例:
?- rep([a, c], 2, TList).
TList = [a, c, a, c].
?- rep(List, 2, TList).
List = TList, TList = [] ;
List = [_G886],
TList = [_G886, _G886] ;
List = [_G886, _G889],
TList = [_G886, _G889, _G886, _G889] ;