首先,我建議將(Team,A)
更改爲A-Team
的配對代表A-Team
,因爲這是團隊的總分,因此這是您要用於排序的關鍵。然後,您希望將不應包含在列表中的變量作爲要聚合的查詢前面的^
的前綴。請看下面的例子:
?- setof(A-Team, P^Wins^Draws^L^(team(Team, P, Wins, Draws, L), A is Wins*3 + Draws*1), List).
List = [25-clyde,26-stirling,35-peterhead,43-queenspark,63-rangers]
既然你這麼問,考慮下面的查詢與對排序翻轉Team-A
用於比較的原因:
?- setof(Team-A,P^Wins^Draws^L^(team(Team,P,Wins,Draws,L), A is Wins*3 + Draws*1),List).
List = [clyde-25,peterhead-35,queenspark-43,rangers-63,stirling-26]
現在結果列表關於teamnames排序。所以A-Team
是合適的選擇。然後,您可以使用謂詞列表:reverse/2將順序反轉爲降序列表,然後定義輔助句謂語pair_second/2,您可以在apply:maplist/3中使用以排除對中的前導分數:
:- use_module(library(lists)).
:- use_module(library(apply)).
% team(+Name, +Played, +Won, +Drawn, +Lost)
team(clyde,26,7,4,15).
team(peterhead,26,9,8,9).
team(queenspark,24,12,7,5).
team(rangers,26,19,6,1).
team(stirling,25,7,5,13).
pair_second(A-B,B). % 2nd argument is 2nd element of pair
teams(Results) :-
setof(A-Team,
P^Wins^Draws^L^(team(Team, P, Wins, Draws, L), A is Wins*3 + Draws*1),
List),
reverse(List,RList),
maplist(pair_second,RList,Results). % apply pair_second/2 to RList
如果你現在查詢謂詞你得到想要的結果:
?- teams(T).
T = [rangers,queenspark,peterhead,stirling,clyde]
關於在評論你的問題:是的,當然這是可能的。您可以編寫一個謂詞,該謂詞描述對的列表與列表之間的關係,而不僅僅包含對的第二個元素。讓我們把它pairlist_namelist/2:
pairlist_namelist([],[]).
pairlist_namelist([S-N|SNs],[N|Ns]) :-
pairlist_namelist(SNs,Ns).
然後你就可以定義團隊/ 1,像這樣:
teams(Results) :-
setof(A-Team,
P^Wins^Draws^L^(team(Team, P, Wins, Draws, L), A is Wins*3 + Draws*1),
List),
reverse(List,RList),
pairlist_namelist(RList,Results).
在這種情況下,除了MAPLIST/3,你不需要任何pair_second/2。此外,您不需要包含:- use_module(library(apply)).
上面的示例查詢與此版本的結果相同。
感謝您的支持!有沒有辦法做到這個問題,而不使用maplist?它不是真的出現在我們的講座幻燈片中(我們正在按照Learn Prolog Now),所以我不確定考試是否會被允許。我們絕對不能在考試中使用外部模塊,這是肯定的。 – user3186023
我從你的代碼中獲得靈感。非常感謝您使用「A-B」教給我的整潔技巧!不知道這是可能的,使排序更容易。再次感謝。 – user3186023
@ user3186023:我更新了我的答案以解決您的問題;-) – tas