Experimente mit Prolog
Trace-Modus - Beispiel 1
Als erstes Beispiel betrachten wir noch einmal eine Welt, in der es um die Zusammenstellung von Mittagessen geht.
es_gibt_fleisch.
es_gibt_suppe.
es_gibt_pudding :- es_gibt_fleisch, es_gibt_kartoffeln.
es_gibt_eis :- es_gibt_pizza.
es_gibt_pudding :- es gibt pizza.
es_gibt_kartoffeln :- es_gibt_suppe.
Prolog stellt einen sog. Trace-Modus bereit, bei dem die Zwischenschritte bei der Auswertung einer Anfrage mitprotokolliert werden.
?- trace. Yes [trace] ?- es_gibt_pudding. Call: (6) es_gibt_pudding ? creep Call: (7) es_gibt_fleisch ? creep Exit: (7) es_gibt_fleisch ? creep Call: (7) es_gibt_kartoffeln ? creep Call: (8) es_gibt_suppe ? creep Exit: (8) es_gibt_suppe ? creep Exit: (7) es_gibt_kartoffeln ? creep Exit: (6) es_gibt_pudding ? creep Yes
Aufgabe 1
Gib für alle Call-Aufrufe an, welches Faktum / welche Regel angewandt (aufgerufen) wird.
Trace-Modus - Beispiel 2
Als zweites Beispiel betrachten wir einen Ausschnitt aus der Welt der griechischen Götter.
kind(hera, rhea).
kind(hebe, hera).
vorfahr(X, Y) :- kind(Y, X).
vorfahr(X, Y) :- kind(Y, Z), vorfahr(X, Z).
Die Auswertung der Anfrage vorfahr(V, hebe).
liefert im Trace-Modus die folgende Herleitung.
[trace] ?- vorfahr(V, hebe). Call: (7) vorfahr(_G286, hebe) ? creep Call: (8) kind(hebe, _G286) ? creep Exit: (8) kind(hebe, hera) ? creep Exit: (7) vorfahr(hera, hebe) ? creep V = hera ; Fail: (8) kind(hebe, _G286) ? creep Redo: (7) vorfahr(_G286, hebe) ? creep Call: (8) kind(hebe, _G341) ? creep Exit: (8) kind(hebe, hera) ? creep Call: (8) vorfahr(_G286, hera) ? creep Call: (9) kind(hera, _G286) ? creep Exit: (9) kind(hera, rhea) ? creep Exit: (8) vorfahr(rhea, hera) ? creep Exit: (7) vorfahr(rhea, hebe) ? creep V = rhea ; Fail: (9) kind(hera, _G286) ? creep Redo: (8) vorfahr(_G286, hera) ? creep Call: (9) kind(hera, _G341) ? creep Exit: (9) kind(hera, rhea) ? creep Call: (9) vorfahr(_G286, rhea) ? creep Call: (10) kind(rhea, _G286) ? creep Fail: (10) kind(rhea, _G286) ? creep Redo: (9) vorfahr(_G286, rhea) ? creep Call: (10) kind(rhea, _G341) ? creep Fail: (10) kind(rhea, _G341) ? creep Fail: (9) vorfahr(_G286, rhea) ? creep Fail: (9) kind(hera, _G341) ? creep Fail: (8) vorfahr(_G286, hera) ? creep Fail: (8) kind(hebe, _G341) ? creep Fail: (7) vorfahr(_G286, hebe) ? creep No
Aufgabe 2
(a) Vergleiche das von Prolog erzeugte Herleitungsprotokoll mit dem Herleitungsprotokoll des letzten Abschnitts.
?- vorfahr(V, hebe). benutze: vorfahr(X, Y) :- kind(Y, X). {X -> V; Y -> hebe} ?- kind(hebe, V). benutze: kind(hebe, hera). {V -> hera} ?- V = hera benutze: vorfahr(X, Y) :- kind(Y, Z), vorfahr(X, Z). {X -> V; Y -> hebe} ?- kind(hebe, Z), vorfahr(V, Z). benutze: kind(hebe, hera). {Z -> hera} ?- vorfahr(V, hera). benutze vorfahr(X, Y) :- kind(Y, X). {X -> V; Y -> hera} ?- kind(hera, V). benutze kind(hera, rhea). {V -> rhea} ?- V = rhea benutze vorfahr(X, Y) :- kind(Y, Z), vorfahr(X, Z). {X -> V; Y -> hera} ?- kind(hera, Z), vorfahr(V, Z). benutze kind(hera, rhea). {Z -> rhea} ?- vorfahr(V, rhea). benutze vorfahr(X, Y) :- kind(Y, X). {X -> V; Y -> rhea} ?- kind(rhea, V). keine Fortsetzung der Rückwärtsherleitung möglich! benutze vorfahr(X, Y) :- kind(Y, Z), vorfahr(X, Z). {X -> V; Y -> rhea} ?- kind(rhea, Z), vorfahr(V, Z). keine Fortsetzung der Rückwärtsherleitung möglich!
(b) Was bedeutet ein "Fail", was ein "Redo" im Prolog-Herleitungsprotokoll?
Aufgabe 3
...