创建列表不包括Prolog中的重复项

时间:2011-05-11 08:23:10

标签: list prolog duplicate-removal

**FACTS**
player(milan,[seedorf,zambrotta,gattuso]).
player(inter,[seedorf,ronaldo,zambrotta]).
player(realmadrid,[seedorf,zidane,ronaldo]).

我想创建一个谓词:

find (TEAM, PLAYERS)

如果我的目标是找到(X,Y),它将返回球队列表,X和球员名单,Y,没有任何重复......如下所示:

X=[milan], Y=[seedorf,zambrotta,gattuso];
X=[inter], Y=[seedorf,ronaldo,zambrotta];
X=[realmadrid], Y=[seedorf,zidane,ronaldo]; 
X=[milan,inter] Y=[seedorf,zambrotta];
X=[milan,realmadri] Y=[seedorf]; 
...
X=[milan,inter,realmadrid] Y=[seedorf];
... 

我尝试这样做,但它给出了“错误:超出本地堆栈”, 如果我不使用remove_dups谓词, 团队名单“X”会有重复,程序也无法停止...... 继续像X = [米兰,米兰,米兰,米兰,国际米兰] ....我怎样才能纠正这个代码。 ?:

find([X], Y) :- player(X1, Y),remove_dups(X1,X).
find([X|Xs], Y) :- player(X1, Y0),find(Xs, Y3), intersection(Y0, Y3, Y),remove_dups(X1,X).

remove_dups([],[]).
remove_dups([First|Rest],NewRest):-member(First, Rest),remove_dups(Rest, NewRest).
remove_dups([First|Rest],[First|NewRest]):-not(member(First, Rest)),remove_dups(Rest, NewRest).

非常感谢...

1 个答案:

答案 0 :(得分:1)

Xs列表上进行模式匹配时,它总是放入milan的相同值,因此存在大量重复。您可以通过首先确保Xs列表中没有重复并找到相应的玩家来避免它:

subset([], []).
subset(Xs, [_|Ys]) :- subset(Xs, Ys).
subset([X|Xs], [X|Ys]) :- subset(Xs, Ys).

allteams(Ts) :- findall(T, player(T, _), Ts).
teams(T) :- allteams(Ts), subset(T, Ts).

find1([T], L) :- player(T, L).
find1([T|Ts], L) :- player(T, L0), find1(Ts, L1), intersection(L0, L1, L).

find(X, Y) :- teams(X), find1(X, Y).

在这里,我首先找到一组所有团队,并尝试找到满足条件的子集。