まず、これはチームの合計スコアであり、並べ替えに使用するキーであるため、前(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
な選択も同様です。次に、述語 list:reverse/2 を使用して順序を逆にして降順リストにし、apply:maplist/3 で使用できる補助述語 pair_second/2 を定義して、ペアの先頭のスコアを取り除くことができます。
:- 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]
コメントでの質問について: はい、もちろん可能です。ペアのリストと、ペアの 2 番目の要素のみで構成されるリストとの間の関係を記述する述語を作成できます。それをpairlist_namelist/2としましょう:
pairlist_namelist([],[]).
pairlist_namelist([S-N|SNs],[N|Ns]) :-
pairlist_namelist(SNs,Ns).
次に、teams/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)).
。上記のクエリ例では、このバージョンで同じ結果が得られます。