2017-05-09 9 views
0

Ich bin sehr neu zu Prolog und mein Professor scheint vergessen zu haben, der Klasse ihren grundlegenden Gebrauch beizubringen. Er gab uns die Aufgabe Prädikate des Schreibens stmt und stmts, wobei das erste Prädikat suchen, wie:SWI-Prolog Prädikate

stmt([pass|X], X). 
stmt([declare,N|X], X) :- atom(N). 
stmt([use,N|X], X) :- atom(N). 

, die dann den Test-Code Anw ([Verwendung, x, etwas, sonst], [etwas, sonst]) .

Der zweite Teil sieht wie folgt aus:

definieren eine stmts Prädikats so dass {stmts(List1, List2)} belegbar ist, wenn (List1) beginnt mit Atomen, welche die (stmts) nicht terminale und dann mit den Atomen in List2 weiter entsprechen. Die folgende Abfrage sollte beispielsweise "true" ergeben: stmts([pass,use,x,more,stuff],[more,stuff]).

Ich verstehe nicht, wie genau das funktioniert. Jede Hilfe wäre willkommen.

Antwort

0

Es funktioniert, weil der Vereinigung Prozesses in Prolog und die Tatsache, dass eine Liste in Prolog ist eine verkettete Liste.

Zunächst kann es nützlich sein zu verstehen, dass eine Liste in einem CONS-way implementiert ist (der Begriff stammt von Lisp, wenn ich mich richtig erinnere). Das bedeutet, dass es einen Funktor gibt (hier verwenden wir einfach cons/2), so dass eine Liste, [use,x,something,else] wie cons(use,cons(x,cons(something,cons(else,nil)))) strukturiert ist (nil ist das Ende der Liste). Also in einer verketteten Liste.

Als nächstes, wenn Sie ein Prädikat in Prolog "Vereinigung aufrufen passiert. Es zielt darauf ab, die Argumente im Aufruf mit den Argumenten im Kopf der Klausel zu vereinheitlichen. Zum Beispiel, wenn der Kopf des Claus ist foo(bar(X,qux(Y))) und Sie rufen es mit foo(bar(3,Z)), dann als Ergebnis X = 3 und Z = qux(Y) mit X und Y werden "uninstantiated Variablen".

Wenn wir diese beiden kombinieren wir sehen, dass eine entzuckert Variante des Codes würde:

stmt(cons(pass,X), X). 
stmt(cons(declare,cons(N,X)), X) :- atom(N). 
stmt(cons(use,cons(N,X)), X) :- atom(N). 

So, jetzt, wenn wir stmt(cons(use,cons(x,cons(something,cons(else,nil)))),cons(something,cons(else,nil))). nennen Eine Einigung wird passieren. Erster Prolog Ziel mit der ersten Klausel zu vereinen:

stmt(cons(pass,X),   X) 
stmt(cons(use, cons(x,...),cons(something,cons(else,nil))) 

(ich eine Ellipse verwenden es einfach zu halten).

wird die Vereinigung zum Ziel, die ersten Argumente zu vereinen, wie:

cons(pass,X) ~ cons(use,cons(else,...)) 
X ~ cons(something,cons(else,nil)) 

Nun ist die Vereinigung wird schälen: die erste Vereinigung entfernen, und Vereinigung der Argumente injizieren, so:

pass ~ use 
X ~ cons(else,...) 
X ~ cons(something,cons(else,nil)) 

Jetzt in Prolog pass und use sind Konstanten (da diese mit einem Kleinbuchstaben beginnen).Außerdem sind alle Konstanten in Prolog verschiedene (außer wenn sie den gleichen "Namen" sozusagen haben). Also seit pass ~ use kann nicht vereinheitlichen. Die erste Klausel "scheitert".

In Prolog ein Rückzieher Mechanismus ist an Ort und Stelle: nach der ersten Klausel genannt - egal, ob das ein Erfolg oder ein Misserfolg war - Prolog wird den Anruf mit der zweiten Klausel, dritter Klausel usw. wiederholen.

Also jetzt wollen wir den Anruf vereinheitlichen. So, jetzt führen wir Vereinigung wie:

stmt(cons(declare,cons(N,X )),X) 
stmt(cons(use, cons(x,...)),cons(something,cons(else,nil))) 

, die wie in der Vereinigung zur Folge haben:

cons(declare,cons(N,X)) ~ cons(use,cons(x,...)) 
X ~ cons(something,cons(else,nil)) 

wieder wir schälen:

declare ~ use 
cons(N,X) ~ cons(x,...) 
X ~ cons(something,cons(else,nil)) 

und wieder, das ist eine fehlschlagen.

Unser letzter Versuch:

stmt(cons(use,cons(N,X)) ,X). 
stmt(cons(use,cons(x,...),cons(something,cons(else,nil))) 

, die ergibt:

cons(use,cons(N,X)) ~ cons(use,cons(x,...)) 
X ~ cons(something,cons(else,nil)) 

und dann ergibt sich:

use ~ use 
cons(N,X) ~ cons(x,...) 
X ~ cons(something,cons(else,nil)) 

die in Ergebnisse:

use ~ use 
N ~ x 
X ~ ... 
X ~ cons(something,cons(else,nil)) 

(die ... ist cons(something,cons(else,nil))). So jetzt hat Vereinigung erfolgreich, hurray. Aber wir sind noch nicht da. Jetzt ist der Kopf der dritten Klausel erfolgreich, was bedeutet, dass wir nun Aufrufe an die Stelle dieser Klausel ausführen müssen. So nennen wir:

atom(N). 

und seit N = x, es bedeutet, dass wir x nennen. Jetzt ist atom(x) ein eingebauter und erfolgreich (wir werden den Wiedervereinigungsprozess hier nicht wiederholen). Das bedeutet also, dass die dritte Klausel erfolgreich ist.

+0

Das erklärt den ersten Teil, können Sie mit dem zweiten Teil helfen? – Anton