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

时间:2015-03-03 09:46:02

标签: prolog prolog-setof

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

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

谁能告诉我这里做错了什么?我如何简单地将所有国家/地区放入列表中,然后遍历列表以找到具有最大边界的那个国家,而不是仅仅将它们一次又一次打印出来,因为我将它们放入列表中?提前谢谢。

1 个答案:

答案 0 :(得分:1)

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匹配的第一个元素,如果Country,它将是第一个元素Region最初未经实例化。

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