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).

然而问题是我并没有在一个列表中得到所有答案。我很可能错误地使用了 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-TeamA^

   ?- 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)).上面的示例查询与此版本产生相同的结果。

于 2016-05-15T18:04:05.163 回答