简体   繁体   English

GNU Prolog-搜索事实列表

[英]GNU Prolog - searching a list of facts

I must be having a brain fart or something, but i just can't seem to find a solution to this. 我一定要放屁,但是我似乎找不到解决办法。

If you have a list facts such as: 如果您有以下事实,例如:

%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).

I want to find the second largest populated city, which in this case would be washington, usa with 3400 people. 我想找到第二大人口稠密的城市,在这种情况下将是美国华盛顿州3400人。 How would you be able to do this? 您将如何做到这一点?

Thanks. 谢谢。

Try this out for size: 尝试以下尺寸:

second_largest_city(City) :-
    findall(Size, city(_, _, Size), Sizes),
    sort(Sizes, SortedSizes),
    append(_, [Size2, _], SortedSizes),
    city(City, _Country, Size2).

Explanation: The findall/3 finds the sizes of all city/3 facts, which are sorted into ascending order by sort/2 with duplicates removed . 说明: findall/3查找所有city/3事实的大小,这些事实按sort/2 升序排序,其中删除重复项 The call to append/3 pattern matches to partition the sorted list SortedSizes into two parts; append/3模式的调用匹配将已排序列表SortedSizes分为两部分; a list of any size ( _ ) and a remainder of length two ( [Size2, _] ) - this binds the variable Size2 to the second-largest city size from city/3 facts. 一个任意大小( _ )和长度为2的余数( [Size2, _] )的列表-这将变量Size2绑定到city/3事实中的第二大城市大小。 Lastly, all cities with this size are located amongst city/3 facts, and are bound on the output. 最后,所有具有此大小的城市都位于city/3事实之中,并受输出约束。

Note: This won't work properly in general if your built-in for sort/2 doesn't remove duplicates, because this leaves open the possibility that city/3 facts with more than one equal maximum will return the maximum (largest) only. 注意:如果您的sort/2内置内置程序没有删除重复项,那么通常这将无法正常工作,因为这有可能使city/3事实的最大值大于一个等于仅返回最大值(最大) 。 This implementation using append/3 to seek the second-last element of the sorted list of sizes also assumes sort/2 sorted numbers into ascending order. 这种使用append/3来查找大小排序列表中倒数第二个元素的实现还假定sort/2排序的数字按升序排列。

Also, lastly, note that this will fail outright if there are less than two city/3 facts -- but this is probably fine, given that the predicate seeks the 'second largest' city, and strictly speaking there wouldn't be one unless there are indeed at least two cities in the DB with different sizes. 此外,最后要注意的是,如果少于两个city/3事实,这将彻底失败-但这可能很好,因为该谓词寻求“第二大”城市,严格来说,除非有一个,实际上,数据库中至少有两个大小不同的城市。 If this is an issue, you can just write more clauses for second_largest_city/1 to handle such a case. 如果这是一个问题,则可以为second_largest_city/1写更多子句来处理这种情况。

Slightly shorter version of @sharky's excellent answer: @sharky的出色答案的简短版本:

second_largest_city(Second) :-
    setof(Size/City, Country^city(City,Country,Size), Cities),
    append(_, [_/Second, _], Cities).

setof combines findall and sort . setof结合了findallsort We collect Size/City pairs so they are sorted on size automatically. 我们收集Size/City对,以便它们自动按尺寸排序。 The construct X^Goal introduces an existentially quantified variable X (like ∃ x in first-order logic). 构造X^Goal引入了一个存在量化的变量X (如一阶逻辑中的x )。

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

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