繁体   English   中英

GNU Prolog-搜索事实列表

[英]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结合了findallsort 我们收集Size/City对,以便它们自动按尺寸排序。 构造X^Goal引入了一个存在量化的变量X (如一阶逻辑中的x )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM