[英]GNU Prolog - searching a list of facts
我一定要放屁,但是我似乎找不到解决办法。
如果您有以下事实,例如:
%country(country, population, capital)
country(sweden, 8823, stockholm).
country(usa, 221000, washington).
country(france, 56000, paris).
country(denmark, 3400, copenhagen).
%city(city, country, population)
city(lund, sweden, 88).
city(new_york, usa, 5000).
city(paris, usa, 1).
city(copenhagen, denmark, 1200).
city(aarhus, denmark, 330).
city(odense, denmark, 120).
city(stockholm, sweden, 350).
city(washington, usa, 3400).
city(paris, france, 2000).
city(marseilles, france, 1000).
我想找到第二大人口稠密的城市,在这种情况下将是美国华盛顿州3400人。 您将如何做到这一点?
谢谢。
尝试以下尺寸:
second_largest_city(City) :-
findall(Size, city(_, _, Size), Sizes),
sort(Sizes, SortedSizes),
append(_, [Size2, _], SortedSizes),
city(City, _Country, Size2).
说明: findall/3
查找所有city/3
事实的大小,这些事实按sort/2
升序排序,其中删除了重复项 。 对append/3
模式的调用匹配将已排序列表SortedSizes
分为两部分; 一个任意大小( _
)和长度为2的余数( [Size2, _]
)的列表-这将变量Size2
绑定到city/3
事实中的第二大城市大小。 最后,所有具有此大小的城市都位于city/3
事实之中,并受输出约束。
注意:如果您的sort/2
内置内置程序没有删除重复项,那么通常这将无法正常工作,因为这有可能使city/3
事实的最大值大于一个等于仅返回最大值(最大) 。 这种使用append/3
来查找大小排序列表中倒数第二个元素的实现还假定sort/2
排序的数字按升序排列。
此外,最后要注意的是,如果少于两个city/3
事实,这将彻底失败-但这可能很好,因为该谓词寻求“第二大”城市,严格来说,除非有一个,实际上,数据库中至少有两个大小不同的城市。 如果这是一个问题,则可以为second_largest_city/1
写更多子句来处理这种情况。
@sharky的出色答案的简短版本:
second_largest_city(Second) :-
setof(Size/City, Country^city(City,Country,Size), Cities),
append(_, [_/Second, _], Cities).
setof
结合了findall
和sort
。 我们收集Size/City
对,以便它们自动按尺寸排序。 构造X^Goal
引入了一个存在量化的变量X
(如一阶逻辑中的x )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.