2016-05-15 10 views
0

Ich habe auf eine vergangene Papierfrage stecken während des Studiums für meine Prüfungen.Prolog - mit Bagof

Die Frage ist:

https://gyazo.com/ee2fcd88d67068e8cf7d478a98f486a0

ich dache, ich habe findall/bagof/setof verwenden, weil ich eine Reihe von Lösungen sammeln muß. Darüber hinaus scheint setof angemessen, da die Liste in absteigender Reihenfolge dargestellt werden muss.

Meine Lösung ist so weit:

teams(List) :- 
    setof((Team, A), 
    (Team^team(Team, _, Wins, Draws, _), A is Wins*3 + Draws*1), 
    List). 

aber das Problem ist, ich nicht ganz die Antworten in einer Liste erhalten alle. Ich verwende sehr wahrscheinlich Team^falsch. Ich würde mich sehr über Hinweise freuen, wie ich eine Liste der geordneten Tupel in Bezug auf Punkte bekommen kann. Die Ausgabe, die es mir gibt, ist:

X = [(queenspark,43)] ? ; 
X = [(stirling,26)] ? ; 
X = [(clyde,25)] ? ; 
X = [(peterhead,35)] ? ; 
X = [(rangers,63)] ? ; 

Also, es ist nicht wirklich ersichtlich, welche Art von Ordnung, wenn überhaupt es in ist, so bin ich auch verloren, wie setof befiehlt.

Was ist der beste Weg, um diese Frage mit setof zu nähern?

Danke.

Antwort

3

Zuerst würde ich empfehlen, (Team,A) zu einer Paardarstellung A-Team zu ändern, wobei die A vorne liegt, da dies die Gesamtpunktzahl des Teams ist und somit der Schlüssel, den Sie zum Sortieren verwenden möchten. Dann möchten Sie die Variablen, die nicht in der Liste enthalten sein sollten, mit einem ^ vor der Abfrage, die Sie aggregieren möchten, voranstellen. Siehe das folgende Beispiel:

?- setof(A-Team, P^Wins^Draws^L^(team(Team, P, Wins, Draws, L), A is Wins*3 + Draws*1), List). 
List = [25-clyde,26-stirling,35-peterhead,43-queenspark,63-rangers] 

Da würden wir Sie bitten, die folgende Abfrage als mit dem Paar Ordnung zu Team-A aus Vergleichsgründen gekippt:

?- setof(Team-A,P^Wins^Draws^L^(team(Team,P,Wins,Draws,L), A is Wins*3 + Draws*1),List). 
List = [clyde-25,peterhead-35,queenspark-43,rangers-63,stirling-26] 

Nun ist die resultierende Liste wird in Bezug auf die Teamnamen sortiert. So ist A-Team die richtige Wahl. Sie können dann die Prädikatlisten verwenden: reverse/2, um die Reihenfolge in eine absteigende Liste umzukehren und dann ein Hilfsprädikat pair_second/2 zu definieren, das Sie mit apply verwenden können: maplist/3, um die führenden Punkte in den Paaren zu entfernen:

:- use_module(library(lists)). 
:- use_module(library(apply)). 

% team(+Name, +Played, +Won, +Drawn, +Lost) 
team(clyde,26,7,4,15). 
team(peterhead,26,9,8,9). 
team(queenspark,24,12,7,5). 
team(rangers,26,19,6,1). 
team(stirling,25,7,5,13). 

pair_second(A-B,B). % 2nd argument is 2nd element of pair 

teams(Results) :- 
    setof(A-Team, 
     P^Wins^Draws^L^(team(Team, P, Wins, Draws, L), A is Wins*3 + Draws*1), 
     List), 
    reverse(List,RList), 
    maplist(pair_second,RList,Results). % apply pair_second/2 to RList 

Wenn Sie das Prädikat jetzt abfragen Sie die gewünschten Ergebnisse erhalten:

?- teams(T). 
T = [rangers,queenspark,peterhead,stirling,clyde] 

in Bezug auf Ihre Frage in den Kommentaren: Ja, natürlich, die möglich ist. Sie können ein Prädikat schreiben, das eine Beziehung zwischen einer Liste von Paaren und einer Liste beschreibt, die nur aus dem zweiten Element der Paare besteht. Nennen wir es pairlist_namelist/2:

pairlist_namelist([],[]). 
pairlist_namelist([S-N|SNs],[N|Ns]) :- 
    pairlist_namelist(SNs,Ns). 

Dann können Sie Teams/1 wie so definieren:

teams(Results) :- 
    setof(A-Team, 
     P^Wins^Draws^L^(team(Team, P, Wins, Draws, L), A is Wins*3 + Draws*1), 
     List), 
    reverse(List,RList), 
    pairlist_namelist(RList,Results). 

In diesem Fall neben maplist/3, nicht wahr/2 entweder pair_second müssen. Sie müssen auch :- use_module(library(apply)). nicht einschließen Die obige Beispielabfrage führt das gleiche Ergebnis mit dieser Version.

+0

Danke dafür! Gibt es eine Möglichkeit, diese Frage ohne Maplist zu tun? Es ist nicht wirklich in unseren Vortragsfolien aufgetaucht (wir folgten jetzt Prolog lernen), also bin ich mir nicht sicher, ob es in der Prüfung erlaubt wäre. Wir können definitiv keine externen Module in der Prüfung verwenden, das ist sicher. – user3186023

+0

Ich habe es mit Inspiration von Ihrem Code arbeiten. Vielen Dank, dass Sie mir den schönen Trick mit "A-B" beigebracht haben! Wusste nicht, dass das möglich war, macht das Sortieren so viel einfacher. Danke noch einmal. – user3186023

+0

@ user3186023: Ich habe meine Antwort aktualisiert, um deine Frage zu beantworten ;-) – tas