我正在尝试创建一个prolog函数(我知道它不是一个函数,但我不记得它的名字)给定一个列表和一个数字N返回一个列表,其中的元素重复至少N次。 / p>
xpto(['a','a','a','b','b','c'],Out,3) 应该返回Out = ['a']
xpto(['a','a','a','b','b','c'],Out,2) 应该返回Out = ['a','b']
等
我目前有:
xpto([], _, _).
xpto([H | L], O, Num) :-
count(H, [H | L], N),
N = Num,
xpto(L, [H | O], Num).
xpto([H | L], O, Num) :-
count(H, [H | L], N),
N \= Num,
xpto(L, O, Num).
其中in count(A,L,N)N是L在L中重复的次数,但是它不起作用。我很确定我的算法在纸上工作。
感谢任何帮助:)
答案 0 :(得分:3)
如果您的Prolog系统支持clpfd,您可以使用以下实现
xpto/3
。实现保留logical-purity!
让我们根据xpto/3
实施
list_counts/2
,元谓词
tfilter/3
和
maplist/3
和(#=<)/3
。 (#=<)/3
是约束(#=</2)
的具体化版本。
:- use_module(library(clpfd)).
:- use_module(library(lambda)).
xpto(Xs,Ys,N) :-
list_counts(Xs,Css0),
tfilter(N+\ (_-V)^(N #=< V),Css0,Css1),
maplist(\ (K-_)^K^true,Css1,Ys).
让我们运行您在问题中提供的查询:
?- xpto([a,a,a,b,b,c],Out,3). Out = [a]. % succeeds deterministically ?- xpto([a,a,a,b,b,c],Out,2). Out = [a,b]. % succeeds deterministically
由于此实施中使用的代码是单调,我们可以提出相当一般的查询,并且仍然可以获得逻辑上合理的答案:
?- xpto([a,a,a,b,b,c],Out,N).
Out = [], N in 4..sup ;
Out = [a], N = 3 ;
Out = [a,b], N = 2 ;
Out = [a,b,c], N in inf..1 .
如果第一个参数包含变量,那么答案是什么样的?
?- Xs = [_,_],xpto(Xs,Out,N).
Xs = [_A,_A], Out = [], N in 3..sup ;
Xs = [_A,_A], Out = [_A], N in inf..2 ;
Xs = [_A,_B], Out = [], N in 2..sup, dif(_A,_B) ;
Xs = [_A,_B], Out = [_A, _B], N in inf..1, dif(_A,_B) .
答案 1 :(得分:0)
改为考虑:
xpto(L, O, Num) :-
% check Num is indeed a valid number
number(Num), Num >= 0,
% build element occurrence list EO
elem_occ(L, EO),
% extract all occurrences which occur at least C times
findall(E, (member(E-Num0, EO), Num0 >= Num), O).
% computes occurrences O of elements E in a list as E-O
elem_occ([], []).
elem_occ([E|Es], [E-O|EOs]) :-
filter([E|Es], E, ML, NL),
length(ML, O),
elem_occ(NL, EOs).
% filters occurrences of E from the input list and returns the remainder
filter([], _, [], []).
filter([E|Es], E, [E|Ms], Ns) :-
!, filter(Es, E, Ms, Ns).
filter([E|Es], E0, Ms, [E|Ns]) :-
filter(Es, E0, Ms, Ns).
使用您的示例进行验证:
?- xpto(['a', 'a', 'a', 'b', 'b', 'c'], Out, 3).
Out = [a].
?- xpto(['a', 'a', 'a', 'b', 'b', 'c'], Out, 2).
Out = [a, b].
此解决方案可能适用于Prolog的大多数变体(SWI,GNU,SICStus,YAP)。