1

我一直试图在 Prolog 中找到一个国家的周长。

我有完成的谓词

borders(Country1, Country2, Length)

setof(Item, Condition, Set) 

它给出了集合中满足条件的所有项目的列表。

为了得到周长,我尝试这样做:

circumference(C, Country) :-
    setof(X, borders(Country,_,X), Set),
    sum_list(Set,C).

sum_list([], 0).
sum_list([H|T], C) :-
   sum_list(T, Rest),
   C is H + Rest.

...但我得到的输出只是边界谓词中两国之间的长度。

我的测试:

?– circumference(C,angola).
C = 201 ;
C = 1376 ;
C = 2511 ;
C = 1110.

规则:

borders(angola,namibia,1376).
borders(angola,congo,201).
borders(angola,zambia,1110).
borders(angola,zaire,2511).

为什么不C成为这些数字的总和?

4

2 回答 2

2

我交换了圆周/2 参数,但你明白了......

circumference(Country,C) :- aggregate(sum(Y),S^borders(Country,S,Y),C).
于 2017-10-03T13:25:56.687 回答
1

问题与另一个国家的变量绑定有关。起初它看起来很疯狂:

?- setof(X, borders(Country,_,X), Set).
Country = angola,
Set = [201] ;
Country = angola,
Set = [1376] ;
Country = angola,
Set = [2511] ;
Country = angola,
Set = [1110].

但是,如果您命名该变量,就会清楚发生了什么:

?- setof(X, borders(Country,OtherCountry,X), Set).
Country = angola,
OtherCountry = congo,
Set = [201] ;
Country = angola,
OtherCountry = namibia,
Set = [1376] ;
Country = angola,
OtherCountry = zaire,
Set = [2511] ;
Country = angola,
OtherCountry = zambia,
Set = [1110].

它无法将它们组合在一起,因为其他国家/地区不同,即使您对绑定收到的价值不感兴趣。正确的解决方案setof/3是进行OtherCountry存在量化,这对于分组的目的无关紧要:

?- setof(X, OtherCountry^borders(Country,OtherCountry,X), Set).
Country = angola,
Set = [201, 1110, 1376, 2511].

setof/3bagof/3中,存在量化是一种说法,即 OtherCountry 将采用各种值,但出于分组的目的您对它们不感兴趣。有很多场景findall/3只会产生一个结果,但您可能希望根据 Goal 参数中的其他一些变量进行单独的分组,所以我认为了解这种技术是件好事,尽管findall/3这可能是一个更直接的解决方案案子。可以在这个答案上找到更多讨论。

于 2017-10-03T16:50:38.550 回答