如何在Prolog中实现查找指定大洲周长最大的内陆国?
查询指定大洲周长最大的内陆国
背景数据
% ------------------ % country(N,C,Ar,Pop), a country N with % capital C, area Ar and population Pop % ------------------ country( andorra , 'Andorra la Vella' , 450 , 72766 ) . country( angola , 'Luanda' , 1246700 , 10342899 ) . % ------------------ % continent(N,Pop), N is a continent with population Pop. % ------------------ continent('Europe',9562488). % ------------------ % geo_sea(N,C,P), the sea N is in country C in province P % ------------------ geo_sea( 'Andaman Sea' , india , 'Andaman and Nicobar Is.' ) . % ------------------ % encompasses(C,R,Fr), country C is encompassed % by region R to fraction Fr (percent) %------------------- encompasses( austria , 'Europe' ,100 ) . encompasses( afghanistan , 'Asia' ,100 ) . encompasses( antigua_and_barbuda , 'America' ,100 ) . encompasses( albania , 'Europe' ,100 ) .
原谓词问题
原谓词尝试查询指定大洲R中周长最大的内陆国C,但调用lll(C,'Europe')时会输出所有欧洲内陆国,而非仅周长最大的那个:
lll(C,R) :- country(C,_,_,_), continent(R,_), not(geo_sea(_,C,_)), encompasses(C,R,100), setof( Circumf, circumference(Circumf,C), Cs ), max_list(Cs,CirMax), circumference(CirMax,C) .
问题根源:每个国家对应的Cs列表仅包含自身的周长值,max_list直接返回该值,导致所有符合内陆国+所属大洲条件的国家都会被匹配输出。
修改方案
要实现需求,需要先收集所有符合条件的国家及其周长,再从中筛选出周长最大的国家,以下是两种可行的修改方式:
方式一:用setof收集候选对后取最大值
lll(C,R) :- % 收集所有符合条件的(周长,国家)元组,默认按周长升序排列 setof(Circumf-C, (country(C,_,_,_), continent(R,_), not(geo_sea(_,C,_)), encompasses(C,R,100), circumference(Circumf,C)), Pairs), % 取列表最后一个元素(升序排列下,最后一个为周长最大值对应的国家) last(Pairs, _-C).
逻辑说明:
setof会生成有序的候选元组列表,确保我们能直接定位到周长最大的条目- 如果存在多个国家周长同为最大值,该方案会返回所有符合条件的国家
方式二:用forall验证当前国家周长为最大值
lll(C,R) :- country(C,_,_,_), continent(R,_), not(geo_sea(_,C,_)), encompasses(C,R,100), circumference(CircumfC,C), % 验证当前国家的周长大于等于所有其他符合条件的国家 forall( (country(C2,_,_,_), not(geo_sea(_,C2,_)), encompasses(C2,R,100), C2 \= C, circumference(CircumfC2,C2)), CircumfC >= CircumfC2 ).
逻辑说明:
- 先匹配符合条件的国家
C并获取其周长 - 通过
forall遍历所有其他候选国家,确保C的周长是最大的
注意事项
- 需确保
circumference(Circumf, Country)谓词能正确返回每个国家的周长值 - 若存在多个国家周长同为最大值,两种方案都会返回所有这些国家(符合Prolog的多解特性)
内容的提问来源于stack exchange,提问作者EvilDoUsHarm
相关产品推荐
相关产品推荐

