2017-10-03 1 views
1

私はPrologで国の周辺を見つけようとしています。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. 

...しかし、私は取得しています出力は国境述語で2国間だけの長さである:私はこれをやってみました円周を取得するには

私のテスト:

?– 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は、これらの数字の合計となっていないのですか?

+0

なぜ「findall/3」ですか?なぜあなたは 'border(_、Country、X)'もチェックしないのですか? –

+0

私は、特定の国を混乱させている国々を探しています。 –

+0

すべての問題を解決したことを見つける、ありがとう! –

答えて

2

問題は、他の国のためにバインディング変数に関係してい

circumference(Country,C) :- aggregate(sum(Y),S^borders(Country,S,Y),C). 
1

...私は円周/ 2引数を入れ替えていますが、アイデアを得ます。 「

?- 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(X, borders(Country,_,X), Set). 
Country = angola, 
Set = [201] ; 
Country = angola, 
Set = [1376] ; 
Country = angola, 
Set = [2511] ; 
Country = angola, 
Set = [1110]. 

をしかし、あなたはその変数に名前を付けるならば、それは何が起こっているのか明確になる:最初はそれがクレイジーに見えますバインディングが受け取った価値には関心がない。

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

、存在量化がOtherCountryは様々な値を取るというの方法がある:setof/3との適切なソリューションは、グループ化のために重要ではありませ作るこれ、OtherCountryが存在量化することですあなたはグループ分けの目的でそれらに興味がありません。 findall/3が1つの結果しか生成しないシナリオがたくさんありますが、Goalパラメータの他の変数のいくつかに基づいて別々のグループを作成したい場合があります。findall/3がおそらくもっと簡単な解決策であってもこのテクニックについて知っておくと良いでしょう。この場合。詳細な説明はon this answerです。