如何return找到最大的结果?
How to return the largest found result?
我有以下事实,描述了一场世界杯的数据库:
% host(X) <- X is the host country of World Cup
host('South Africa').
% federation (X,Y) <- X is the federation and Y is the numbers of countries in federation X
% qualified for World Cup.
federation('AFC',4).
federation('UEFA', 10).
federation('CAF', 5).
federation('CONMEBOL', 5).
% member_of(X,Y) <- Country Y is member of federation X
member_of('AFC','Australia').
member_of('UEFA', 'England').
member_of('CAF', 'South Africa').
member_of('CONMEBOL','Brazil').
% top(X) <- Country X is top of the World.
top('Brazil').
问题是,如何找到世界杯参赛国家数量最多的联盟?
我想我要做的是:
solution(X):-federation(X,Y), isMax(Y).
...但我还不知道如何实现。
您的问题可以改写为"Find the federation for which there are no other federation with more qualified countries"
该语句可以在序言中写成:
solution(X):-
federation(X,Y), % Find the federation for which
\+(( % there are no
federation(_, Z), % other federation with
Z > Y % more qualified countries
)).
library(aggregate) 提供适当的构造:
solution(X) :- aggregate(max(N,C), federation(C,N), max(_,X)).
?- solution(X).
X = 'UEFA'.
我在这里提供的是另一种变体,不会声称是迄今为止提供的最好的变体:
solution(X) :- setof(N-F, federation(F, N), L), reverse(L, [_-X|_]).
setof/3
将收集独特的 N-F
对,其中 F
是联合会名称,N
是该联合会中有资格参加世界杯的国家/地区数量.它们将按照 N-F
的自然顺序递增排列,即按数字 N
然后按 F
。 reverse
将最大的数字放在列表的第一位,而 [_-X|_]
只是从列表的头部选择数字。
附录
需要注意的是,如果数据包含多个最大结果,@gusbro 的方法将生成所有这些结果。但是,aggregate
方法不会。上面的 setof
/reverse
方法可以按数量级的降序提供所有内容,但如果只选择最大值,则需要一些额外的帮助:
pick_top([X-F|_], X, F).
pick_top([_|T], X, F) :-
pick_top(T, X, F).
solution(X) :-
setof(N-F, federation(F, N), L),
reverse(L, [C-Fed|T]),
pick_top([C-Fed|T], C, X).
这将生成所有顶级联盟:
federation('AFC',4).
federation('UEFA', 10).
federation('CAF', 5).
federation('CONMEBOL', 5).
federation('PDQ', 10).
| ?- solution(X).
X = 'UEFA' ? ;
X = 'PDQ' ? ;
no
使用 bagof
并避免 reverse
: 的替代解决方案
pick_top([X-F|T], Top) :-
pick_top(T, X, [F], Top).
pick_top([X-F|T], X, A, Top) :-
pick_top(T, X, [F|A], Top).
pick_top([Y-_|T], X, A, Top) :-
Y < X,
pick_top(T, X, A, Top).
pick_top([Y-F|T], X, _, Top) :-
Y > X,
pick_top(T, Y, [F], Top).
pick_top([], _, Top, Top).
solution(X) :-
bagof(N-F, federation(F, N), L),
pick_top(L, X).
生成最大值列表:
| ?- solution(X).
X = ['PDQ','UEFA'] ? a
no
我有以下事实,描述了一场世界杯的数据库:
% host(X) <- X is the host country of World Cup
host('South Africa').
% federation (X,Y) <- X is the federation and Y is the numbers of countries in federation X
% qualified for World Cup.
federation('AFC',4).
federation('UEFA', 10).
federation('CAF', 5).
federation('CONMEBOL', 5).
% member_of(X,Y) <- Country Y is member of federation X
member_of('AFC','Australia').
member_of('UEFA', 'England').
member_of('CAF', 'South Africa').
member_of('CONMEBOL','Brazil').
% top(X) <- Country X is top of the World.
top('Brazil').
问题是,如何找到世界杯参赛国家数量最多的联盟?
我想我要做的是:
solution(X):-federation(X,Y), isMax(Y).
...但我还不知道如何实现。
您的问题可以改写为"Find the federation for which there are no other federation with more qualified countries"
该语句可以在序言中写成:
solution(X):-
federation(X,Y), % Find the federation for which
\+(( % there are no
federation(_, Z), % other federation with
Z > Y % more qualified countries
)).
library(aggregate) 提供适当的构造:
solution(X) :- aggregate(max(N,C), federation(C,N), max(_,X)).
?- solution(X).
X = 'UEFA'.
我在这里提供的是另一种变体,不会声称是迄今为止提供的最好的变体:
solution(X) :- setof(N-F, federation(F, N), L), reverse(L, [_-X|_]).
setof/3
将收集独特的 N-F
对,其中 F
是联合会名称,N
是该联合会中有资格参加世界杯的国家/地区数量.它们将按照 N-F
的自然顺序递增排列,即按数字 N
然后按 F
。 reverse
将最大的数字放在列表的第一位,而 [_-X|_]
只是从列表的头部选择数字。
附录
需要注意的是,如果数据包含多个最大结果,@gusbro 的方法将生成所有这些结果。但是,aggregate
方法不会。上面的 setof
/reverse
方法可以按数量级的降序提供所有内容,但如果只选择最大值,则需要一些额外的帮助:
pick_top([X-F|_], X, F).
pick_top([_|T], X, F) :-
pick_top(T, X, F).
solution(X) :-
setof(N-F, federation(F, N), L),
reverse(L, [C-Fed|T]),
pick_top([C-Fed|T], C, X).
这将生成所有顶级联盟:
federation('AFC',4).
federation('UEFA', 10).
federation('CAF', 5).
federation('CONMEBOL', 5).
federation('PDQ', 10).
| ?- solution(X).
X = 'UEFA' ? ;
X = 'PDQ' ? ;
no
使用
bagof
并避免 reverse
: 的替代解决方案
pick_top([X-F|T], Top) :-
pick_top(T, X, [F], Top).
pick_top([X-F|T], X, A, Top) :-
pick_top(T, X, [F|A], Top).
pick_top([Y-_|T], X, A, Top) :-
Y < X,
pick_top(T, X, A, Top).
pick_top([Y-F|T], X, _, Top) :-
Y > X,
pick_top(T, Y, [F], Top).
pick_top([], _, Top, Top).
solution(X) :-
bagof(N-F, federation(F, N), L),
pick_top(L, X).
生成最大值列表:
| ?- solution(X).
X = ['PDQ','UEFA'] ? a
no