【问题标题】:write a predicate from other predicates by filtering based on predicate attributes with arithmetic operations通过基于算术运算的谓词属性进行过滤,从其他谓词中编写一个谓词
【发布时间】:2020-10-07 20:35:30
【问题描述】:

我想从 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) 谓词定义中都中断了。

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

【问题讨论】:

    标签: prolog predicate logic-programming


    【解决方案1】:

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

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

    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)。

    线

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

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

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

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

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

    【讨论】:

    • 感谢您对我的代码和方向的建议。解决方案似乎可以运行,但我可以看到 2 个问题,一个是输出中有重复的国家,第二个是“当除数变为零时它会抛出并停止执行”。我不确定为什么是第二个问题。因为它直到最后才执行
    • 可以通过添加:- table country/1来解决第一个问题。对于第二个问题,我目前看不到这将如何出现。您能否提供导致此错误的数据库片段?
    • 我能够通过排除人口为“0”的国家来解决第二个问题,并且效果很好。我想这些重复是因为它正在针对该国的每个城市进行迭代。有没有一种方法可以通过删除重复项来控制。使用回溯?
    • 我在那个数据库中看到有一个人口为 0 的条目。 ഀ?- 城市(X,A,Y,0)。 X = '普利茅斯',A = 蒙特塞拉特,Y = '蒙特塞拉特'
    • 谢谢 tphilipp,现在一切正常。与我的逻辑和代码相比,您的解决方案教会了我如何高效地编码。
    猜你喜欢
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多