我有一个谓词,其目的是打印出面积最大的国家(边界最大=最大面积的国家)。这就是我的谓词的样子:
/* 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).
谁能告诉我这里做错了什么?我如何简单地将所有国家/地区放入列表中,然后遍历列表以找到具有最大边界的那个国家,而不是仅仅将它们一次又一次打印出来,因为我将它们放入列表中?提前谢谢。
答案 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
置于降序顺序中,我们只需从该列表的头部选择Country
和Region
, [_-Country-Region]
。