计入Prolog列表

时间:2011-05-11 02:12:51

标签: prolog

我正在尝试创建一个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中重复的​​次数,但是它不起作用。我很确定我的算法在纸上工作。

感谢任何帮助:)

2 个答案:

答案 0 :(得分:3)

如果您的Prolog系统支持,您可以使用以下实现 xpto/3。实现保留

让我们根据xpto/3实施 list_counts/2,元谓词 tfilter/3maplist/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)。