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

...

X

Fehler melden

X

Suche