2017-10-03 1 views
1

Ich habe versucht, den Umfang eines Landes in Prolog zu finden.Prolog - Summe der Listenmitglieder

Ich habe die fertige Prädikat

borders(Country1, Country2, Length) 

und

setof(Item, Condition, Set) 

, die eine Liste aller Elemente in die Menge, die die Bedingung erfüllen gibt.

Um den Umfang erhalte ich versucht, dies zu tun:

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. 

... aber die Ausgabe erhalte ich nur die Länge zwischen den beiden Ländern in der Grenz Prädikat.

Mein Test:

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

Regeln:

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

Warum nicht C die Summe dieser Zahlen werden?

+0

Warum nicht 'findall/3'? Warum suchst du nicht auch nach 'border (_, Country, X)'? –

+0

Ich möchte die Länder finden, die ein spezifisches Land begrenzen, was mir nur unnötige Werte geben würde? –

+0

finden alle behoben das Problem, danke! –

Antwort

2

Ich tauschte Umfang/2 Argumente, aber Sie bekommen die Idee ...

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

Das Problem mit der Variable für das andere Land verbindlich zu tun hat. Zunächst sieht es verrückt:

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

Aber wenn Sie diese Variable nennen wird klar, was los ist:

?- 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]. 

Es kann nicht gruppieren sie zusammen, weil das andere Land unterscheidet, auch wenn Sie‘ nicht interessiert an dem Wert, den die Bindung erhalten hat. Die richtige Lösung mit setof/3 ist OtherCountry existenzquantifizierte zu machen, die für die Zwecke der Gruppierung es keine Rolle spielt:

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

In setof/3 und bagof/3, existentielle Quantifizierung ist eine Art zu sagen, dass Othercountry auf verschiedene Werte annehmen wird aber Sie sind nicht interessiert an ihnen für die Zwecke der Gruppierung. Es gibt viele Szenarien, in denen findall/3 nur ein einzelnes Ergebnis liefert, aber Sie möchten vielleicht separate Gruppierungen basierend auf einigen der anderen Variablen im Goal-Parameter haben. Ich denke, es ist gut über diese Technik zu wissen, obwohl findall/3 wahrscheinlich eine einfachere Lösung ist in diesem Fall. Weitere Diskussionen finden Sie unter on this answer.

Verwandte Themen