在考试期间,我一直被困在过去的纸质问题上。
问题是:
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处理此问题的最佳方法是什么?
感谢。
答案 0 :(得分: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
是合适的选择。然后,您可以使用谓词列表:reverse / 2将顺序反转为降序列表,然后定义辅助谓词pair_second / 2,您可以使用apply:maplist / 3来消除成对中的主要分数:< / p>
:- 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).
然后你可以像这样定义团队/ 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)).
上面的示例查询会产生与此版本相同的结果。