Ausrufezeichen im Prolog
Angesichts der folgenden Fakten und Prädikaten:
sound(time1).
sound(time2).
sun(time3).
relax(X):-sound(X),!,sun(X).
relax(_):-sun(_).
Beim ausführen relax(S).
würde ich erwarten, dass man S=time1
aufgrund der !
sagt (korrigiert mich wenn ich falsch Liege), dass wenn die " X " zufrieden ist , dann halt das backtracking.
Hier ist die trace:
3 ?- trace.
true.
[trace] 3 ?- relax(S).
Call: (6) relax(_G1831) ? creep
Call: (7) sound(_G1831) ? creep
Exit: (7) sound(time1) ? creep
Call: (7) sun(time1) ? creep
Fail: (7) sun(time1) ? creep
Fail: (6) relax(_G1831) ? creep
false.
Also warum Prolog prüft auch sun(time1)
, obwohl, dass es traf die Ausrufezeichen, nachdem er zufrieden durch sound(X)
(weil sound(time1)
ist eine Tatsache).
Das hat nichts zu tun mit funktionaler Programmierung und ist nicht geeignet für die Programmier-Sprachen-tag... keine tags hinzufügen, nur weil Sie Lust dazu haben.
InformationsquelleAutor ron | 2013-02-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
!
Zeichen verhindert, dass die Rückverfolgung der Klauseln auf der rechten Seite zu der linken Seite, es ist wie ein ein-Wege-Tor, so dass es nicht backtrack über den Schnitt.Wenn
sound(time1)
true ist, wird die nächste Ziffersun(time1)
bewertet werden, und nur dann prolog wird feststellen, dasssun(time1)
istfalse
(durch durchsuchen der knowledge base, es hat nicht wirklich wissen, dass es eine Tatsache).Dann, weil der Schnitt, der prolog nicht versuchen, Werte
time2
undtime3
in der ersten Klausel.Mehr über cut:
Prolog wertet die Klauseln eines Prädikats von Links nach rechts. Es bindet einen Wert an eine variable in die am weitesten Links stehende Ziffer. Wenn die Klausel ist
true
ist, verschiebt es auf den nächsten. Wenn esfalse
, prolog versucht andere Werte als gut.Wenn eine der Klauseln nicht erfüllt werden kann, indem ein beliebiger Wert sein, es wäre
false
, und so wird das gesamte Prädikat (weil die Klauseln verbunden sind, die durch UND).Funktioniert das ganze wie eine Tiefe-ersten traversal des Baums, wo die Klauseln sind die Knoten und die Kanten repräsentieren die verschiedenen Werte der Variablen. Wenn die überquerung findet sich eine Klausel, die
false
, würde es wieder in seinen vorhergehenden Satz und versuchen Sie einen anderen Wert.Hier kommt der Schnitt. Wenn Sie einen Schnitt (
!
) zwischen zwei Klauseln, würde es bedeuten, dass, wenn die Klausel nach ein Schnitt wirdfalse
, zu versuchen, neue Werte werden NUR eingeschaltet werden, WENN die Bewertung läuft NACH dem Schnitt. Es bedeutet, dass die Werte der Variablen vor dem schneiden sind gesperrt, und Sie können nicht geändert werden, wenn die Bewertung kreuzt den Schnitt.relax(X):-sound(X),!,sun(X).
undrelax(X):-sound(X),sun(X),!.
? prolog würde versuchen nur die aktuellen 'X' und wird dann nicht ... ?Natürlich gibt es einen Unterschied zwischen den beiden, das ist die Lage des Schnittes. Die erste version könnte Ihnen die Antwort mehrmals, wenn
sun(X)
gelöst werden kann, mehr als einmal, z.B. wenn Sie hinzufügensun(time1).
undsun(X) :- sound(X).
zu Ihren Prädikaten und dann Fragen, fürrelax(S)
. Die zweite version wird immer nur eine (oder keine) Antwort. Sie sind richtig, obwohl es nicht einen Unterschied machen für Sie Ihre aktuellen Prädikate.das ist der seltsame Teil : warum ist prolog-check über die
!
imrelax(X):-sound(X),!,sun(X).
? Wenn prolog gefunden, dassrelax(time1)
ist eine Tatsache , nicht die!
sagen, es nicht zu prüfen, nichts anderes , und außerdem nicht zu prüfen, auchsun(time1)
?Sie missverstanden, was der Schnitt bewirkt. Es hört nicht auf Bewertung, es bedeutet nur, dass alle Wahl Punkte angesammelt, bis
!
werden verworfen. Wennsound(X)
erreicht ist, möglich soulutions sindtime1
undtime2
. Der prolog-interpreter wählt das erste (time1
) und erstellt eine Wahl Punkt kann es ansetzen, wenn der rest der Klausel scheitert, so kann es neu bewerten, mittime2
. Die!
tut nichts, außer du diese Wahl zeigen. Prolog nun wertet Sie den rest des Prädikats, kann aber nicht ansetzen, bevor die!
und test mittime2
mehr.Prolog kann check über einen Schnitt (von Links nach rechts), aber nicht zurück über einen Schnitt (rechts nach Links) - das ist der Grund, warum ein Schnitt ist wie ein ein-Weg-Tor.
InformationsquelleAutor 0605002
Um dies zu verdeutlichen noch mehr, wenn jemand immer noch Kämpfe, wie Ausrufezeichen-operator funktioniert (wie ich), hier ist ein Beispiel:
Für dieses bestimmte Beispiel, wenn Sie Fragen Prolog für
?-relax(S).
diese Ergebnisse in false. Wir können beschreiben, Prolog funktioniert dies so:mit der S)) in unserem Beispiel).
X und S sind jetzt gebunden.
befriedigt sound(X).
vorhanden ist.
In der opposition wie ich schon sagte im 4. ohne ! Betreiber es Ergebnisse in Erfolg.
Fühlen Sie sich frei, mich zu korrigieren, wenn ich falsch bin, irgendwann.
InformationsquelleAutor Smarty77
Wird es trotzdem versuchen, um zu befriedigen den rest der Regel, es will einfach nicht backtrace vor dem Ausrufezeichen. Das ist, wenn
sun(X)
schlägt fehl, es wird nicht backtrace und versuchen, eine übereinstimmung mit einem verschiedenen Objektsound(X)
, aber nicht überein, dass die Regel völlig.InformationsquelleAutor Junuxx