通过基于具有算术运算的谓词属性进行过滤,从其他谓词编写谓词

write a predicate from other predicates by filtering based on predicate attributes with arithmetic operations

我想根据 mondial 的现有谓词编写一个谓词。我感兴趣的谓词是 cc(Country) 表示 Country 是这样一个国家,即该国有一个城市,其人口至少占该国总人口的 75%。有些国家/地区的人口未知,因此该值为空。

给定谓词的示例:

% city(N,C,R,Pop) is a city by name N in country C in region R with
% population Pop
city('Aachen',germany,'Nordrhein Westfalen',247113).
city('Aalborg',denmark,'Nordjylland',113865).
city('Aarau',switzerland,'Aargau',null).
city('Aarhus',denmark,'Midtjylland',194345).
city('Abaetetuba',brazil,'Para',106753).
city('Abakaliki',nigeria,'Ebonyi',null).
city('Abakan',russia,'Rep. of Khakassiya',161000).
city('Abancay',peru,'Apurimac',null).
city('Aba',nigeria,'Abia',500183).
city('Abengourou',cote_divoire,'Moyen-Comoe',null).
city('Abeokuta',nigeria,'Ogun',352735).
city('Aberdeen',united_kingdom,'Grampian',219100).
city('Aberystwyth',united_kingdom,'Ceredigion',null).
city('Abha',saudi_arabia,'Aseer',null).
city('Abidjan',cote_divoire,'Lagunes',null).
city('Abilene',united_states,'Texas',106707).
city('Aboisso',cote_divoire,'Sud-Comoe',null).
city('Abu Dhabi',united_arab_emirates,'Abu Dhabi',363432).
city('Abuja',nigeria,'Abuja',107069).
city('Acapulco',mexico,'Guerrero',515374).
city('Acarigua',venezuela,'Portuguesa',116551).
city('Accra',ghana,'Greater Accra',867459).
city('Acheng',china,'Heilongjiang',197595).
city('Achinsk',russia,'Krasnoyarskiy kray',123000).
city('Adama/Nazret',ethiopia,'Oromia',127842).
city('Adamstown',pitcairn_islands,'Pitcairn Islands',null).
city('Adana',turkey,'Adana',1047300).
city('Adapazari',turkey,'Sakarya',186000).
city('ad Damir',sudan,'ash Shamaliyah',null).
city('Ad Dammam',saudi_arabia,'Ash Sharqiyah',744321).
city('Addis Ababa',ethiopia,'Addis Ababa',2084588).
city('Adelaide',australia,'South Australia',1050000).
city('Aden',yemen,'Yemen',550744).
city('Adiyaman',turkey,'Adiyaman',128000).
city('Ado-Ekiti',nigeria,'Ekiti',156122).

我完成这个任务的逻辑:

pop(Country,Pop) :-
    city(_,C,_,Pop),
    Country = C.

setof(P,pop(germany,P), poplist). %intend to create a list of population from a specific country
poplist([]).
poplist([_|T]) :- poplist(T).  %poplist should be the list with population from each city of germany

%I wanted to sum the entire list, so i get the total population of the germany
sum([], 0).
sum([H|T], N):-
    sum(T, X),
    N is X + H.

%once I get the total population I wanted to iteratively execute and check with the population for a specific city in the country is > 75% so to get the country listed in the output

cc(Country):-
%get the city for specific country
city(_, Country, _, Pop),
%calculate the percentage
Perc is div(Pop, sum(poplist, N)),
%see if percentage is over 75%
Perc >= 75.

看起来我的代码无法正常工作,它在创建 sum(poplist, N) 时甚至在 cc(Country) 谓词定义中都中断了。

我是序言的新手,在这里需要我们的帮助。我的算法或逻辑对我想要完成的任务有意义吗?我怎样才能得到想要的结果?

您的代码中存在多个问题:

这一行只是定义了一个新事实 - 仅此而已。

setof(P,pop(germany,P), poplist). %intend to create a list of population from a specific country

以类似的方式,你对 poplist 的定义对我来说没有意义:它只是说明空列表是一个 poplist,如果 T 是一个 poplist,则列表 [_|T] 是一个 poplist。

您对 sum 的定义似乎没问题,但是 SWI-Prolog 为此(sumlist)提供 built-in 谓词。

Perc is div(Pop, sum(poplist, N)),

看起来不对; sum 是谓词; poplist 是谓词。

此外,您的数据集中有“空”元素。请注意,null 只是 Prolog 中的另一个原子,您不能对包含 non-arithmetic 原子的列表求和。

这是我尚未测试的解决方案:

country(Country) :-
    city(_, Country, _, _).

has_big_city(Country) :-
    % exclude countries that have a city with unknown population
    forall(city(_, Country, _, P), dif(P, null)),
    % compute country population
    findall(P, city(_, Country, _, P), Ps),
    sumlist(Ps, Country_Population),
    % look for big city
    city(_, Country, _, City_Pop),
    Perc is City_Pop / Country_Population,
    Perc >= 0.75.


cc(Country) :-
    country(Country),
    has_big_city(Country).