2011-05-11 38 views
0
**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). 

非常感謝......

+0

爲了澄清,謂詞** find/2 **應該返回所有(非空?)團隊子集(作爲第一個參數中的列表)以及所有這些團隊共有的相應球員列表。根據這些例子,如果玩家列表爲空(但您可能會滿足該要求),則看起來您不會返回「成功」。 – hardmath 2011-05-11 11:55:22

+0

我不明白?我寫了一個代碼,看看列表不是空的。但它仍然返回重複... – Palindrom 2011-05-11 12:58:58

+0

嗨,邁克爾...我很清楚,你*不*希望重複的結果。我的評論旨在澄清的是你想要的。你可能很清楚謂詞的意圖是什麼,但你的描述(「它將返回隊列表X,和隊員名單Y,沒有任何重複」)並不是它應該做什麼的規範。根據你的例子,讀者需要填寫空白,並且存在對規範曲解的空間。因此我的問題是:是否應該有一個結果(當然不是重複的),其中一小組小組產生空的球員列表? – hardmath 2011-05-11 14:38:39

回答

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). 

在這裏,我找到了一組首先團隊,並設法找到滿足條件的子集。

+0

非常感謝... – Palindrom 2011-05-11 14:35:15