Firstly, I would suggest to change (Team,A)
to a pair representation A-Team
with the A
being in front since this is the total score of the team and thus the key you want to use for sorting. Then you would like to prefix the variables that should not be in the list with a ^
in front of the query you want to aggregate. See the following example:
?- 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]
Since you asked, consider the following query with the pair ordering flipped to Team-A
for comparison reasons:
?- 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]
Now the resulting list is sorted with respect to the teamnames. So A-Team
is the opportune choice. You could then use the predicate lists:reverse/2 to reverse the order to a descending list and then define an auxilary predicate pair_second/2 that you can use with apply:maplist/3 to get rid of the leading scores in the pairs:
:- 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
If you query the predicate now you get the desired results:
?- teams(T).
T = [rangers,queenspark,peterhead,stirling,clyde]
Concerning your question in the comments: Yes, of course that is possible. You can write a predicate that describes a relation between a list of pairs and a list than only consists of the second element of the pairs. Let's call it pairlist_namelist/2:
pairlist_namelist([],[]).
pairlist_namelist([S-N|SNs],[N|Ns]) :-
pairlist_namelist(SNs,Ns).
Then you can define teams/1 like so:
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).
In this case, besides maplist/3, you don't need pair_second/2 either. Also you don't need to include :- use_module(library(apply)).
The example query above yields the same result with this version.