Prolog,从一组列表中找到最大值

Prolog, finding largest value from a setOf list

我有一个谓词,目的是打印出面积最大的国家(边界最大的国家 = 面积最大的国家)。这就是我的谓词的样子:

/* If I write get_country(X, 'Europe'). then all the countries in Europe 
that isn't bordering a sea gets printed out. 
However as you can see I am creating a list 
with all of the countries and then I want to
take the largest country from all of these 
and print that one out. But instead 
all of the countries gets printed out 
with their length, ex: X = hungary ; 359 (length) ...  */
get_country(Country, Region):-
    encompasses(Country,Region,_),
    not(geo_sea(_,Country,_)),
    setof(Length, country_circumference(Country,Length), Cs),
    largest(Cs, X),
    write(X).

该谓词中使用的谓词如下:

country_circumference(Country, X):-
    setof(Length, get_border_length(Country, Length), Cs),
    sum(Cs, X).

largest([X],X).
largest([X|Xs],R) :-
    largest(Xs,Y),
    R is max(X,Y).

谁能告诉我我做错了什么?我如何简单地将我所有的国家都放入列表中,然后遍历列表以找到边界最大的国家,而不是在将它们放入列表时将它们一个接一个地打印出来?提前致谢。

Prolog 定义了术语的自然顺序。比如下面是true:

foo(3, z) @< foo(10, x)
bar(2, 9) @< foo(3, 1)

请注意 术语比较 运算符 @< 数字比较 < 的使用。谓词 setof/3 将进行术语比较。

如果您想找到边界最长的国家/地区,那么您可以利用术语比较并收集 setof/3 中包含您要作为排序依据的项目的类似术语来实现第一个参数。在这种情况下,我们首先需要圆周。此外,如果我正确理解您的 get_country 谓词的预期含义,您需要在 setof/3:

get_country(Country, Region):-
    setof(L-C-R, X^Y^Z^( encompasses(C, R, X),
                         \+ geo_sea(Y, C, Z),
                         country_circumference(C, L) ), Cs),
    reverse(Cs, HighToLowAreas),
    member(_-Country-Region, HighToLowAreas), !.

谓词子句末尾的 member/2 将查找列表 HighToLowAreas 中第一个与 _-Country-Region 匹配的元素,如果 CountryRegion 最初是未实例化的。

需要存在量词 X^Y^Z^ 才能将它们排除在查询中的选择器之外。使用 _ 不会在 setof/3 的上下文中执行此操作。在这里,我们使用术语形式 -(-(X,Y),Z),因为它写起来很方便,X-Y-Z。但您也可以在这里使用 foo(X, Y, Z)reverse/2 将列表 Cs 置于 降序 顺序,我们只需从其头部取出 CountryRegion列出 [_-Country-Region].