1

Ich lerne Prolog an der Universität und stolpere über etwas seltsam während der Home-Übungen. Ich schrieb folgende Prolog-Klauseln, die einen Teil eines viel größeren Programms sind:Mitglied in Kombination mit Rekursion

edges(X,Edges):- 
    findall(Edge,(highway(X,Y,Edge);highway(Y,X,Edge)),Edges). 

edgesList([],_). 
edgesList([node(X)|InL],OutL):- 
    member((node(X),Edges),OutL), 
    edges(X,Edges), 
    edgesList(InL,OutL). 

, die Verwendung folgender Sachverhalt:

highway(1,2,yellow). 
highway(2,3,blue). 
highway(1,3,yellow). 

Sie können Autobahn als Tatsache sehen, dass zwei Knoten in den ersten beiden Argumente beschreibt und eine Kante in der dritten. Alle Fakten zusammen bilden ein zusammenhängendes Diagramm.

Mit der Klausel Kantenlisten möchte ich die Kanten pro Knoten z.B.

Result = [(node(1),[yellow,yellow]),(node(2),[blue,yellow]),(node(3),[blue,yellow])] 

Aber wenn ich meine Abfrage schreiben:

edgesList([node(1),node(2),node(3)],List). 

ich folgendes Ergebnis:

List = [(node(1),[yellow, yellow]), (node(2),[blue, yellow]), (node(3),[blue, yellow])|_G610] 

Aus irgendeinem Grunde Prolog wird das Heck der Ergebnis-Liste nicht vereinen mit die leere Liste, trotz der Tatsache, dass das Mitglied-Prädikat richtig verwendet wird, nehme ich an. Es ist etwas, das ein paar Mal jetzt in verschiedenem excercises passiert und es wäre gut, zu wissen, was ich falsch gemacht habe ...

+0

Im Wesentlichen gibt es eine unendliche Anzahl von Listen für die 'Element ((Knoten (X), Kanten), OutL)' 'ist wahr, wenn OutL' eine Variable ist. Bei einer Prolog-Eingabeaufforderung sehen Sie, was passiert, wenn Sie 'member (a, L) .' und drücken Sie'; '(siehe nächste Antwort) nach jedem Ergebnis. Außerdem ist Ihr Basisfall 'kantenListe ([], _).' Falsch. '_' bedeutet nicht * nichts *, aber es bedeutet * alles *, da '_' eine anonyme Variable ist. Wie sieht die Kantenliste für '[]' aus? Sicherlich ist es nicht '_' (irgendetwas). – lurker

Antwort

1

Das Problem in der Klausel ist:

edgesList([],_). 

denn am Ende wird es füllen die Liste mit einem uninstantiierten Tail (| _G610).

Eine Lösung ist:

edges(X,Edges):- 
    findall(Edge,(highway(X,Y,Edge);highway(Y,X,Edge)),Edges). 

edgesList([],[]). 
edgesList([node(X)|InL],[(node(X),Edges)|T]):- 
    edges(X,Edges), 
    edgesList(InL,T). 
+0

Also kann ich Mitglied in diesem Fall überhaupt nicht verwenden? Warum kann ich Member nicht mit einem Basisfall mit zwei leeren Listen kombinieren? – Programmer1994

+0

Ich glaube nicht, dass das Problem darin besteht, member im Allgemeinen zu verwenden, aber wenn Sie member und base-case die zwei leeren Listen verwenden, dann denken Sie, dass es gut funktioniert und wenn es um den Basisfall geht, übergeben Sie die OutL-Liste und fordern leer zu sein, was nicht sein kann, das wird nicht funktionieren. – coder

+0

Nun, immer noch nicht verstehen, "wann Mitglied zu verwenden, und wann nur den Kopf anhängen" quit wel, aber Ihre Antwort hat gut funktioniert, danke! :) – Programmer1994