首先,我建议更改为与在前面(Team,A)
的配对表示,因为这是团队的总分,因此是您要用于排序的键。然后,您想在要聚合的查询前面为不应该出现在列表中的变量添加前缀。请参见以下示例:A-Team
A
^
?- 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]
现在,结果列表根据团队名称进行排序。恰如其分的选择也是如此A-Team
。然后,您可以使用谓词 lists: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).
然后你可以像这样定义team/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)).
上面的示例查询与此版本产生相同的结果。