0

試験勉強中に過去問で行き詰まりました。

質問は:

https://gyazo.com/ee2fcd88d67068e8cf7d478a98f486a0

findall/bagof/setof一連のソリューションを収集する必要があるため、使用する必要があると考えました。さらに、setofリストは降順で表示する必要があるため、適切と思われます。

これまでの私の解決策は次のとおりです。

teams(List) :- 
    setof((Team, A), 
    (Team^team(Team, _, Wins, Draws, _), A is Wins*3 + Draws*1), 
    List).

ただし、問題は、1 つのリストですべての回答が得られないことです。Team^ を間違って使用している可能性が非常に高いです。ポイントに関して順序付けられたタプルのリストを取得する方法についてのポインタを本当に感謝します。それが私に与える出力は次のとおりです。

X = [(queenspark,43)] ? ;
X = [(stirling,26)] ? ;
X = [(clyde,25)] ? ;
X = [(peterhead,35)] ? ;
X = [(rangers,63)] ? ;

また、どのような順番で並んでいるのかがよくわからないので、どのように並んでいるのかもわからなくなってしまいsetofます。

setof を使用してこの質問にアプローチする最良の方法は何ですか?

ありがとう。

4

1 に答える 1

2

まず、これはチームの合計スコアであり、並べ替えに使用するキーであるため、前(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)).。上記のクエリ例では、このバージョンで同じ結果が得られます。

于 2016-05-15T18:04:05.163 に答える