• Keine Ergebnisse gefunden

Cut und Ablaufsteuerung

N/A
N/A
Protected

Academic year: 2022

Aktie "Cut und Ablaufsteuerung"

Copied!
33
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Cut und Ablaufsteuerung

Das Cut Goal mit Beispielen Negation als Failure

Probleme mit Cut und Negation

Das Cut Goal mit Beispielen Negation als Failure

Probleme mit Cut und Negation

(2)

Cut Einführung

Bislang war die Kontrolle der Abarbeitung nur durch die Ordnung der Klauseln beeinflussbar.

Der Cut: '!'

verhindert Backtracking

erhöht die Ausdruckskraft der Sprache mit der Negation als Failure

Zum Verhindern von Backtracking:

Automatisches Backtracking ist an sich sehr nützlich. Es nimmt die Last vom Programmierer Backtracking explizit zu implementieren.

Unkontrolliertes Backtracking kann allerdings in manchen Fällen zur Ineffizienz führen.

→ Manchmal muss Backtracking verhindert oder kontrolliert werden.

Bislang war die Kontrolle der Abarbeitung nur durch die Ordnung der Klauseln beeinflussbar.

Der Cut: '!'

verhindert Backtracking

erhöht die Ausdruckskraft der Sprache mit der Negation als Failure

Zum Verhindern von Backtracking:

Automatisches Backtracking ist an sich sehr nützlich. Es nimmt die Last vom Programmierer Backtracking explizit zu implementieren.

Unkontrolliertes Backtracking kann allerdings in manchen Fällen zur Ineffizienz führen.

→ Manchmal muss Backtracking verhindert oder kontrolliert werden.

(3)

Ein erstes Beispiel

Implementation einer Sprungfunktion.

Wenn X < 3 dann Y = 0 Wenn 3 ≤und X < 6 dann Y = 2 Wenn 6 ≤ X dann Y = 4

In Prolog als binäre Relation f(X,Y)

Implementation einer Sprungfunktion.

Wenn X < 3 dann Y = 0 Wenn 3 ≤und X < 6 dann Y = 2 Wenn 6 ≤ X dann Y = 4

In Prolog als binäre Relation f(X,Y)

3

6

2 4

(4)

Ein erstes Beispiel

Implementation einer Sprungfunktion.

f(X,0) :- X < 3. %Regel 1 f(X,2) :- 3=< X, X < 6. %Regel 2 f(X,4) :- 6 = < X. %Regel 3 Experiment 1: mit zwei Zielen

?- f(1,Y), 2<Y.

→ zunächst macht die erste Regel f(X,0), X =1, 1<3 und Y wird 0 erstes Ziel erfüllt, das zweite Ziel scheitert. 2 < 0 → fail

→ Prolog versucht nun Regel 2 und Regel 3.

Die drei Regeln der Relation f(X,Y) sind jedoch gegenseitig

exklusiv. Wenn eine schon erfüllt war macht es keinen Sinn, die anderen noch auszuprobieren!

Implementation einer Sprungfunktion.

f(X,0) :- X < 3. %Regel 1 f(X,2) :- 3=< X, X < 6. %Regel 2 f(X,4) :- 6 = < X. %Regel 3 Experiment 1: mit zwei Zielen

?- f(1,Y), 2<Y.

→ zunächst macht die erste Regel f(X,0), X =1, 1<3 und Y wird 0 erstes Ziel erfüllt, das zweite Ziel scheitert. 2 < 0 → fail

→ Prolog versucht nun Regel 2 und Regel 3.

Die drei Regeln der Relation f(X,Y) sind jedoch gegenseitig

exklusiv. Wenn eine schon erfüllt war macht es keinen Sinn, die anderen noch auszuprobieren!

(5)

Ein erstes Beispiel

Mit dem Cut kann dieses nutzlose Backtracking verhindert werden:

Er wird eingesetzt sobald einer der sich gegenseitig ausschließenden Fälle eintritt.

Implementation der Sprungfunktion mit Cut.

f(X,0) :- X < 3, !. %Regel 1 f(X,2) :- 3=< X, X < 6, !. %Regel 2 f(X,4) :- 6 = < X. %Regel 3

Prolog produziert dieselbe Abarbeitung wie vorher und mit dem Zweiten Ziel an 2<0, da Y mit 0 instantiert wurde. Nun wird

Backtracking versucht. Da der Cut für f(X,0) erreicht wurde, können keine Alternativen mehr innerhalb der rechten Regelseite erreicht werden und auch der Regelkopf ist nicht mehr Alternativen

zugänglich. Der Zustand bis zum Cut wird eingefrohren.

Mit dem Cut kann dieses nutzlose Backtracking verhindert werden:

Er wird eingesetzt sobald einer der sich gegenseitig ausschließenden Fälle eintritt.

Implementation der Sprungfunktion mit Cut.

f(X,0) :- X < 3, !. %Regel 1 f(X,2) :- 3=< X, X < 6, !. %Regel 2 f(X,4) :- 6 = < X. %Regel 3

Prolog produziert dieselbe Abarbeitung wie vorher und mit dem Zweiten Ziel an 2<0, da Y mit 0 instantiert wurde. Nun wird

Backtracking versucht. Da der Cut für f(X,0) erreicht wurde, können keine Alternativen mehr innerhalb der rechten Regelseite erreicht werden und auch der Regelkopf ist nicht mehr Alternativen

zugänglich. Der Zustand bis zum Cut wird eingefrohren.

(6)

Ein erstes Beispiel: Trace

Aufruftrace von ?- f(1,Y), 2<Y. ohne Cut

[trace] ?- f(1,Y),2<Y.

Call: (7) f(1, _G807) ? creep Call: (8) 1<3 ? creep

Exit: (8) 1<3 ? creep

Exit: (7) f(1, 0) ? creep %goal 1 erfüllt Call: (7) 2<0 ? creep

Fail: (7) 2<0 ? creep

Redo: (7) f(1, _G807) ? creep %Versuch goal 1 anders zu lösen Call: (8) 3=<1 ? creep

Fail: (8) 3=<1 ? creep

Redo: (7) f(1, _G807) ? creep %letzter Versuch Call: (8) 6=<1 ? creep

Fail: (8) 6=<1 ? creep

Fail: (7) f(1, _G807) ? creep false.

Aufruftrace von ?- f(1,Y), 2<Y. ohne Cut

[trace] ?- f(1,Y),2<Y.

Call: (7) f(1, _G807) ? creep Call: (8) 1<3 ? creep

Exit: (8) 1<3 ? creep

Exit: (7) f(1, 0) ? creep %goal 1 erfüllt Call: (7) 2<0 ? creep

Fail: (7) 2<0 ? creep

Redo: (7) f(1, _G807) ? creep %Versuch goal 1 anders zu lösen Call: (8) 3=<1 ? creep

Fail: (8) 3=<1 ? creep

Redo: (7) f(1, _G807) ? creep %letzter Versuch Call: (8) 6=<1 ? creep

Fail: (8) 6=<1 ? creep

Fail: (7) f(1, _G807) ? creep false.

(7)

Ein erstes Beispiel: Trace

Aufruftrace von ?- f(1,Y), 2<Y. mit Cut

?- f(1,Y),2<Y.

Call: (7) f(1, _G3205) ? creep Call: (8) 1<3 ? creep

Exit: (8) 1<3 ? creep %goal 1 erfüllt Exit: (7) f(1, 0) ? creep

Call: (7) 2<0 ? creep

Fail: (7) 2<0 ? creep %kein Backtracking false. %nach Scheitern

Aufruftrace von ?- f(1,Y), 2<Y. mit Cut

?- f(1,Y),2<Y.

Call: (7) f(1, _G3205) ? creep Call: (8) 1<3 ? creep

Exit: (8) 1<3 ? creep %goal 1 erfüllt Exit: (7) f(1, 0) ? creep

Call: (7) 2<0 ? creep

Fail: (7) 2<0 ? creep %kein Backtracking false. %nach Scheitern

(8)

Ein erstes Beispiel

Erstes Ergebnis:

Wir haben die Effizienz des Programms durch das Einfügen eines Cuts verbessert. Wenn wir die Cuts wieder entfernen bleibt das Resultat gleich = grüner Cut.

Die prozedurale Bedeutung des Programms bleibt gleich.

Dies ist nicht immer so.

Erstes Ergebnis:

Wir haben die Effizienz des Programms durch das Einfügen eines Cuts verbessert. Wenn wir die Cuts wieder entfernen bleibt das Resultat gleich = grüner Cut.

Die prozedurale Bedeutung des Programms bleibt gleich.

Dies ist nicht immer so.

(9)

Ein erstes Beispiel

Zweites Experiment:

?-f(7,Y).

Regel 1: fail 7 < 3, Cut nicht erreicht also Backtracking über den Regelkopf

Regel 2: fail, zwar gilt 3 ≤ X aber fail 7 < 6 Regel 3: 6 ≤ 7 erfolgreich.

Eine weitere Quelle der Inefzienz.

Wenn wir schon wissen: X < 3 fail, dann gilt natürlich 3 ≤ X

Wenn wir schon wissen: X < 6 fail, dann gilt natürlich 6 ≤ X

"if, elsif, else Konstruktion"

Zweites Experiment:

?-f(7,Y).

Regel 1: fail 7 < 3, Cut nicht erreicht also Backtracking über den Regelkopf

Regel 2: fail, zwar gilt 3 ≤ X aber fail 7 < 6 Regel 3: 6 ≤ 7 erfolgreich.

Eine weitere Quelle der Inefzienz.

Wenn wir schon wissen: X < 3 fail, dann gilt natürlich 3 ≤ X

Wenn wir schon wissen: X < 6 fail, dann gilt natürlich 6 ≤ X

"if, elsif, else Konstruktion"

(10)

Ein erstes Beispiel

f(X,0) :- X < 3, !. %Regel 1 f(X,2) :- X < 6, !. %Regel 2 f(X,4). %Regel 3

Diese Version ist effizienter als die beiden Ersten und produziert dieselben Resultate. Was aber wenn wir die Cuts entfernen.

?- f(1,Y).

f(X,0) :- X < 3, !. %Regel 1 f(X,2) :- X < 6, !. %Regel 2 f(X,4). %Regel 3

Diese Version ist effizienter als die beiden Ersten und produziert dieselben Resultate. Was aber wenn wir die Cuts entfernen.

?- f(1,Y).

(11)

Ein erstes Beispiel

f(X,0) :- X < 3. %Regel 1 ohne Cut f(X,2) :- X < 6. %Regel 2 ohne Cut f(X,4). %Regel 3

?- f(1,Y).

Y=0;

Y=2;

Y=4;no.

Nicht nur ist der prozedurale Ablauf verändert sondern auch das Resultat ist unterschiedlich.

f(X,0) :- X < 3. %Regel 1 ohne Cut f(X,2) :- X < 6. %Regel 2 ohne Cut f(X,4). %Regel 3

?- f(1,Y).

Y=0;

Y=2;

Y=4;no.

Nicht nur ist der prozedurale Ablauf verändert sondern auch das Resultat ist unterschiedlich.

(12)

Präzise Bedeutung des Cut

Das Parent-Goal sei das Goal das mit dem Kopf der Klausel

gematcht hatte, die den Cut enthält. Wenn der Cut vom Stack der Zielliste geholt wird, ist er sofort erfüllt. Das System wird auf alle Entscheidungen festgelegt, seit das Parent-Goal aufgerufen wurde und bis der Cut eingetreten ist. Alle Alternativen zwischen dem Parent-Goal und dem Cut können nicht aufgerufen werden.

Beispiel:

H:- B1,B2, ...., Bm,!,..., Bn.

Wurde von einem Parent-Goal G, das mit dem Regelkopf H matcht aufgerufen. Wenn der Cut erreicht wird, hat das System schon

Lösungen für B1,B2...Bm gefunden. Auch ist der Aufrufer G auf diese Klausel festgelegt. Versuche nun G mit irgendeinem anderen Klauselkopf zu matchen werden durch den Cut verhindert.

Das Parent-Goal sei das Goal das mit dem Kopf der Klausel

gematcht hatte, die den Cut enthält. Wenn der Cut vom Stack der Zielliste geholt wird, ist er sofort erfüllt. Das System wird auf alle Entscheidungen festgelegt, seit das Parent-Goal aufgerufen wurde und bis der Cut eingetreten ist. Alle Alternativen zwischen dem Parent-Goal und dem Cut können nicht aufgerufen werden.

Beispiel:

H:- B1,B2, ...., Bm,!,..., Bn.

Wurde von einem Parent-Goal G, das mit dem Regelkopf H matcht aufgerufen. Wenn der Cut erreicht wird, hat das System schon

Lösungen für B1,B2...Bm gefunden. Auch ist der Aufrufer G auf diese Klausel festgelegt. Versuche nun G mit irgendeinem anderen Klauselkopf zu matchen werden durch den Cut verhindert.

(13)

Weiteres formales Beispiel

Programmfragment.

C:- P,Q,R,!,S,T,U.

C:- V.

A:- B,C,D.

Anfrage A.

?- A.

Sei B erfüllt, läuft die Abarbeitung der Zielliste auf C. Die erste

Regel matcht. Wenn der Cut erreicht wird sind alle Alternativen von P, Q und R abgeschnitten. Ebenso kann nicht etwa die zweite Regel mit C als Kopf von Anfrage A aus erreicht werden. Alternativen für S,T und U sind jedoch nach wie vor offen.

Programmfragment.

C:- P,Q,R,!,S,T,U.

C:- V.

A:- B,C,D.

Anfrage A.

?- A.

Sei B erfüllt, läuft die Abarbeitung der Zielliste auf C. Die erste

Regel matcht. Wenn der Cut erreicht wird sind alle Alternativen von P, Q und R abgeschnitten. Ebenso kann nicht etwa die zweite Regel mit C als Kopf von Anfrage A aus erreicht werden. Alternativen für S,T und U sind jedoch nach wie vor offen.

(14)

Weitere Beispiele zum Cut

Berechnung des Maximum max(X,Y,Max)

X ist das Maximum wenn es größer oder gleich Y ist. Y ist das Maximum wenn X kleiner Y ist.

max(X,Y,X) :- X >= Y.

max(X,Y,Y) :- X < Y.

Regeln sind gegenseitig ausschließend (Fallunterscheidung). Wenn die erste erfolgreich ist, wird die zweite scheitern. Wenn die erste gescheitert ist wird die zweite erfolgreich sein.

Wenn X größer oder gleich Y ist, ist X das Maximum, sonst Y.

Berechnung des Maximum max(X,Y,Max)

X ist das Maximum wenn es größer oder gleich Y ist. Y ist das Maximum wenn X kleiner Y ist.

max(X,Y,X) :- X >= Y.

max(X,Y,Y) :- X < Y.

Regeln sind gegenseitig ausschließend (Fallunterscheidung). Wenn die erste erfolgreich ist, wird die zweite scheitern. Wenn die erste gescheitert ist wird die zweite erfolgreich sein.

Wenn X größer oder gleich Y ist, ist X das Maximum, sonst Y.

(15)

Weitere Beispiele zum Cut

Alternative Formulierung mit Cut.

max(X,Y,X) :- X >= Y,!.

max(X,Y,Y).

Allerdings Vorsicht. Das Argument Max bei der Anfrage sollte unbelegt sein:

?- max(3,1,1).

yes. Warum? Regelkopf von max Regel 1 matcht nicht, also wird die Regel nicht aufgerufen, der Cut wird nicht erreicht, die zweite Regel kann noch feuern.

Reformulierung in eine Regel mit oder:

max(X,Y,Max) :- X >= Y,!, Max = X ; Max = Y.

?- max(3,1,1).no. Warum? Cut wird erreicht. Blockiert den oder Aufruf

Alternative Formulierung mit Cut.

max(X,Y,X) :- X >= Y,!.

max(X,Y,Y).

Allerdings Vorsicht. Das Argument Max bei der Anfrage sollte unbelegt sein:

?- max(3,1,1).

yes. Warum? Regelkopf von max Regel 1 matcht nicht, also wird die Regel nicht aufgerufen, der Cut wird nicht erreicht, die zweite Regel kann noch feuern.

Reformulierung in eine Regel mit oder:

max(X,Y,Max) :- X >= Y,!, Max = X ; Max = Y.

?- max(3,1,1).no. Warum? Cut wird erreicht. Blockiert den oder Aufruf

(16)

Weitere Beispiele zum Cut

Member Prädikat mit eindeutiger Lösung member(X,L).

Wurde benutzt um festzustellen, ob X in der Liste L enthalten ist.

member(X,[X|_]).

member(X,[_|L]):- member(X,L).

Das Prädikat ist nicht-deterministisch, wenn X mehrere male in der Liste auftaucht, können durch Backtracking unterschiedliche

Lösungen erreicht werden.

Jetzt soll member in ein Prädikat umgeschrieben werden, das immer nur das erste Auftreten findet.

Member Prädikat mit eindeutiger Lösung member(X,L).

Wurde benutzt um festzustellen, ob X in der Liste L enthalten ist.

member(X,[X|_]).

member(X,[_|L]):- member(X,L).

Das Prädikat ist nicht-deterministisch, wenn X mehrere male in der Liste auftaucht, können durch Backtracking unterschiedliche

Lösungen erreicht werden.

Jetzt soll member in ein Prädikat umgeschrieben werden, das immer nur das erste Auftreten findet.

(17)

Weitere Beispiele zum Cut

Einfach Backtracking verhindern.

member(X,[X|_]):- !.

member(X,[_|L]):- member(X,L).

?- member(X,[a,b,c]).

X=a;

no.

Einfach Backtracking verhindern.

member(X,[X|_]):- !.

member(X,[_|L]):- member(X,L).

?- member(X,[a,b,c]).

X=a;

no.

(18)

Weitere Beispiele zum Cut

Ein Element in eine Liste einfügen, ohne Dubletten. Füge X nur dann ein, wenn X nicht schon in der Liste ist.

add(X,L,L1).

Wenn X schon in L enthalten ist, dann ist L1 identisch mit L. Sonst ist L1 die Liste L in die X eingefügt wird.

→ Was ist die einfachste Möglichkeit in Prolog ein Element in eine Liste einzufügen: mach es zum Kopf der Liste.

Zur Konstruktion wird das member Prädikat und der Cut benutzt.

Ein Element in eine Liste einfügen, ohne Dubletten. Füge X nur dann ein, wenn X nicht schon in der Liste ist.

add(X,L,L1).

Wenn X schon in L enthalten ist, dann ist L1 identisch mit L. Sonst ist L1 die Liste L in die X eingefügt wird.

→ Was ist die einfachste Möglichkeit in Prolog ein Element in eine Liste einzufügen: mach es zum Kopf der Liste.

Zur Konstruktion wird das member Prädikat und der Cut benutzt.

(19)

Weitere Beispiele zum Cut

add(X,L,L):- member(X,L),!.

add(X,L,[X|L]).

Beispielaufrufe:

?- add(a,[b,c],L).

L=[a,b,c].

?- add(X,[b,c],L).

L=[b,c]

X=b.

?- add(a,[b,c,X],L).

L=[b,c,a]

X=a.

Wiederum soll add(X,L1,L2) mit L2 uninstantiert aufgerufen werden, sonst kann es zu unerwartetem Verhalten kommen.

add(a,[a],[a,a]) ist erfolgreich. Warum? Regelkopf der ersten Regel macht nicht. Zweite wird angewandt, member nie gerufen!

add(X,L,L):- member(X,L),!.

add(X,L,[X|L]).

Beispielaufrufe:

?- add(a,[b,c],L).

L=[a,b,c].

?- add(X,[b,c],L).

L=[b,c]

X=b.

?- add(a,[b,c,X],L).

L=[b,c,a]

X=a.

Wiederum soll add(X,L1,L2) mit L2 uninstantiert aufgerufen werden, sonst kann es zu unerwartetem Verhalten kommen.

add(a,[a],[a,a]) ist erfolgreich. Warum? Regelkopf der ersten Regel macht nicht. Zweite wird angewandt, member nie gerufen!

(20)

Weitere Beispiele zum Cut

Es ist nicht offensichtlich, wie man add ohne Duplikate unter Verzicht auf den Cut implementieren soll. Wenn der Cut einfach weggelassen wird, werden durch Backtracking auch Duplikate

eingefügt. Der Cut ist hier notwendig um die gewünschte Relation zu spezifizieren und nicht nur um die Effizienz zu verbessern.

Es ist nicht offensichtlich, wie man add ohne Duplikate unter Verzicht auf den Cut implementieren soll. Wenn der Cut einfach weggelassen wird, werden durch Backtracking auch Duplikate

eingefügt. Der Cut ist hier notwendig um die gewünschte Relation zu spezifizieren und nicht nur um die Effizienz zu verbessern.

(21)

Klassifikation in Kategorien

Beispieldatenbank mit Sportresultaten:

beat(tom,jim).

beat(ann,tom).

beat(pat,jim).

class Prädikat: class(Spieler,Kategorie).

winner: gewinnt immer

fighter: gewinnt mal, verliert mal looser: verliert immer

Versuch als if, elsif ...Regel zu formulieren → in Prolog mit Cut.

Beispieldatenbank mit Sportresultaten:

beat(tom,jim).

beat(ann,tom).

beat(pat,jim).

class Prädikat: class(Spieler,Kategorie).

winner: gewinnt immer

fighter: gewinnt mal, verliert mal looser: verliert immer

Versuch als if, elsif ...Regel zu formulieren → in Prolog mit Cut.

(22)

Klassifikation in Kategorien

Versuch als if, elsif, else Regel zu formulieren → in Prolog mit Cut.

if X beats somebody and somebody else beats X then X is a fighter elsif X beats somebody X is a winner

elsif X is beaten by somebody X is a looser class(X,fighter) :- beat(X,_), beat(_,X),! . class(X,winner) :- beat(X,_),! .

class(X,looser) :- beat(_,X).

Cut schneidet Backtracking ab, wenn einer der if Zweige eingetreten ist.

Wiederum sollte beim Aufruf das zweite Argument nicht schon instanitiert sein.

?- class(tom, looser). yes. %warum?

Beachten Sie: der zweite Cut ist nicht prozedural notwendig, nur effizient.

Versuch als if, elsif, else Regel zu formulieren → in Prolog mit Cut.

if X beats somebody and somebody else beats X then X is a fighter elsif X beats somebody X is a winner

elsif X is beaten by somebody X is a looser class(X,fighter) :- beat(X,_), beat(_,X),! . class(X,winner) :- beat(X,_),! .

class(X,looser) :- beat(_,X).

Cut schneidet Backtracking ab, wenn einer der if Zweige eingetreten ist.

Wiederum sollte beim Aufruf das zweite Argument nicht schon instanitiert sein.

?- class(tom, looser). yes. %warum?

Beachten Sie: der zweite Cut ist nicht prozedural notwendig, nur effizient.

(23)

Negation als Failure

Mary mag alle Tiere außer Schlangen! Der erste Teil ist leicht!

Mary likes any X, if X is an animal.

likes(mary,X) :- animal(X).

Der zweite Teil:

Wenn X eine Schlange ist, dann soll likes nicht true ergeben.

Zusammen:

Wenn X eine Schlange ist, likes not true, elseif, wenn X ein Tier ist likes ist true.

Wir benutzen das spezielle goal fail, das nie erfolgreich ist und deshalb das aufrufende Ziel Parent-Goal zum Scheitern bringt.

Mary mag alle Tiere außer Schlangen! Der erste Teil ist leicht!

Mary likes any X, if X is an animal.

likes(mary,X) :- animal(X).

Der zweite Teil:

Wenn X eine Schlange ist, dann soll likes nicht true ergeben.

Zusammen:

Wenn X eine Schlange ist, likes not true, elseif, wenn X ein Tier ist likes ist true.

Wir benutzen das spezielle goal fail, das nie erfolgreich ist und deshalb das aufrufende Ziel Parent-Goal zum Scheitern bringt.

(24)

Negation as Failure

likes(mary,X) :- snake(X),!, fail.

likes(mary,X) :- animal(X).

Cut dient dazu, das fail einzufrieren.

Implementation von different(X,Y) im Sinne X,Y matchen nicht.

If X and Y match, different(X,Y) fail, else different succeed.

different(X,X) :- !, fail.

different(X,Y).

in einer Klausel:

different(X,Y) :- X=Y, !, fail ; true.

true ist ein Goal das immer erfolgreich ist.

likes(mary,X) :- snake(X),!, fail.

likes(mary,X) :- animal(X).

Cut dient dazu, das fail einzufrieren.

Implementation von different(X,Y) im Sinne X,Y matchen nicht.

If X and Y match, different(X,Y) fail, else different succeed.

different(X,X) :- !, fail.

different(X,Y).

in einer Klausel:

different(X,Y) :- X=Y, !, fail ; true.

true ist ein Goal das immer erfolgreich ist.

(25)

Unäres "not"

not(P) :- P,!,fail ;

true.

not(Goal) ist wahr wenn Goal nicht wahr ist. Wenn also Goal erfolgreich ist, ist not(Goal) nicht erfolgreich und umgekehrt.

Wir werden im Folgenden annehmen not(X) sei in der spezifizierten Weise implementiert und auch als Präfix-Operator nutzbar.

Also soll etwa

not snake(X) not(snake(X)) entsprechen.

not(P) :- P,!,fail ;

true.

not(Goal) ist wahr wenn Goal nicht wahr ist. Wenn also Goal erfolgreich ist, ist not(Goal) nicht erfolgreich und umgekehrt.

Wir werden im Folgenden annehmen not(X) sei in der spezifizierten Weise implementiert und auch als Präfix-Operator nutzbar.

Also soll etwa

not snake(X) not(snake(X)) entsprechen.

(26)

Unäres "not"

Vorhergehende Beispiele:

likes(marry, X) :- animal(X), not snake(X).

different(X,Y) :- not(X=Y).

Sportklassifikation:

class(X,fighter) :- beat(X,_),beat(_,X).

class(X,winner) :- beat(X,_), not beat(_,X).

class(X,looser) :- beat(_,X), not beat(X,_).

Überlegen Sie, ob diese Implementation so effizient ist, wie die ursprüngliche. Wie verhält sich diese Implementation mit unsinnig instantiertem zweiten Argument?

Vorhergehende Beispiele:

likes(marry, X) :- animal(X), not snake(X).

different(X,Y) :- not(X=Y).

Sportklassifikation:

class(X,fighter) :- beat(X,_),beat(_,X).

class(X,winner) :- beat(X,_), not beat(_,X).

class(X,looser) :- beat(_,X), not beat(X,_).

Überlegen Sie, ob diese Implementation so effizient ist, wie die ursprüngliche. Wie verhält sich diese Implementation mit unsinnig instantiertem zweiten Argument?

(27)

Probleme mit Cut und Negation

Vorteile des Cut:

(1) Verbessern der Effizienz von Programmen.

Unsinnige Alternativen können blockiert werden.

(2) Gegenseitig exklusive Regeln können implementiert werden.

Nachteile des Cut:

Der Preis ist der Verlust von Korrespondenz zwischen deklarativer und prozeduraler Bedeutung des Programms. Ohne Cut können die Klauseln umorganisiert werden und dies betrifft nur die Effizienz oder Terminierung. Mit Cut kann Umorganisation zu

unterschiedlichen Resultaten führen.

Vorteile des Cut:

(1) Verbessern der Effizienz von Programmen.

Unsinnige Alternativen können blockiert werden.

(2) Gegenseitig exklusive Regeln können implementiert werden.

Nachteile des Cut:

Der Preis ist der Verlust von Korrespondenz zwischen deklarativer und prozeduraler Bedeutung des Programms. Ohne Cut können die Klauseln umorganisiert werden und dies betrifft nur die Effizienz oder Terminierung. Mit Cut kann Umorganisation zu

unterschiedlichen Resultaten führen.

(28)

Probleme mit Cut und Negation

p :- a,b.

p:- c.

deklarative Bedeutung:

p <=> (a&b)Vc p :- a,!,b.

p:- c.

deklarative Bedeutung:

p <=> (a&b)V(¬a&c) tauschen Klauseln

p:- c.

p :- a,!,b.

deklarative Bedeutung:

p <=> cV(a&b)

p :- a,b.

p:- c.

deklarative Bedeutung:

p <=> (a&b)Vc p :- a,!,b.

p:- c.

deklarative Bedeutung:

p <=> (a&b)V(¬a&c) tauschen Klauseln

p:- c.

p :- a,!,b.

deklarative Bedeutung:

p <=> cV(a&b)

(29)

Probleme mit der Negation

not human (mary).

Oft mit yes beantwortet, nämlich immer dann, wenn keine Aussagen über mary in der Datenbank sind! "Closed world assumption"

Alles was existiert steht im Programm oder kann daraus abgeleitet werden.

not human (mary).

Oft mit yes beantwortet, nämlich immer dann, wenn keine Aussagen über mary in der Datenbank sind! "Closed world assumption"

Alles was existiert steht im Programm oder kann daraus abgeleitet werden.

(30)

Probleme mit der Negation

Restaurant-Beispiel

guter_standard(jeanluis).

teuer(jeanluis).

guter_standard(francesco).

empfehlenswert(Restaurant) :- not teuer(Restaurant).

?- guter_standard(X), empfehlenswert(X).

X = francesco.

?- empfehlenswert(X),guter_standard(X).

no.

Im zweiten Fall ist X unbelegt, wenn das not Goal abgearbeitet wird.

Restaurant-Beispiel

guter_standard(jeanluis).

teuer(jeanluis).

guter_standard(francesco).

empfehlenswert(Restaurant) :- not teuer(Restaurant).

?- guter_standard(X), empfehlenswert(X).

X = francesco.

?- empfehlenswert(X),guter_standard(X).

no.

Im zweiten Fall ist X unbelegt, wenn das not Goal abgearbeitet wird.

(31)

Probleme mit der Negation

Das Problem mit nicht instantierten negierten Zielen rührt von der unglücklichen Quantifikation von Variablen im Konzept Negation als Failure her:

?-expensive(X). Existentiell quantifiziert. Existiert in der Datenbank X, so dass expensive(X) wahr ist → jeanlouis.

?-not expensive(X). Nicht so interpretiert: es existiert ein X, so dass not expensive(X) → francesco sondern, universale Quantifikation durch Negation als failure:

not( exists X such that expensive(X))

also all-quantifiziert, for all X: not expensive(X).

Das Problem mit nicht instantierten negierten Zielen rührt von der unglücklichen Quantifikation von Variablen im Konzept Negation als Failure her:

?-expensive(X). Existentiell quantifiziert. Existiert in der Datenbank X, so dass expensive(X) wahr ist → jeanlouis.

?-not expensive(X). Nicht so interpretiert: es existiert ein X, so dass not expensive(X) → francesco sondern, universale Quantifikation durch Negation als failure:

not( exists X such that expensive(X))

also all-quantifiziert, for all X: not expensive(X).

(32)

Schleifen mit true und fail

Mit den eingebauten Prädikaten true und fail lassen sich Schleifen simulieren.

p(X) :-

q(X,Y), fail.

p(X).

Da fail nicht beweisbar ist, muß durch Backtracking jede Lösung Y von q(X,Y) gesucht werden.

Schließlich wird nach der letzten Alternative die zweite Regel p(X) erreicht, wodurch die Schleife beendet wird.

Andere Schreibweise mit true:

p(X) :- ( q(X,Y) , fail; true).

Mit den eingebauten Prädikaten true und fail lassen sich Schleifen simulieren.

p(X) :-

q(X,Y), fail.

p(X).

Da fail nicht beweisbar ist, muß durch Backtracking jede Lösung Y von q(X,Y) gesucht werden.

Schließlich wird nach der letzten Alternative die zweite Regel p(X) erreicht, wodurch die Schleife beendet wird.

Andere Schreibweise mit true:

p(X) :- ( q(X,Y) , fail; true).

(33)

Hausaufgabe

(1) Arbeiten Sie im Leiss Skript Seite 27 – 38 durch. Versuchen Sie alle Beispiele zu verstehen.

(2) Implementieren Sie die Programme aus der Vorlesung und im Leiss Skript in SWI Prolog, lassen Sie Beispielaufrufe im Tracer laufen.

(1) Arbeiten Sie im Leiss Skript Seite 27 – 38 durch. Versuchen Sie alle Beispiele zu verstehen.

(2) Implementieren Sie die Programme aus der Vorlesung und im Leiss Skript in SWI Prolog, lassen Sie Beispielaufrufe im Tracer laufen.

Referenzen

ÄHNLICHE DOKUMENTE

Es ist grundsätzlich möglich, dass sich die Kantone und Gemeinden in Zukunft in ab- gelegenen Regionen im ambulanten Bereich stärker im Infrastrukturbereich engagieren, wenn

HAART ist 2011 sehr effektiv, erreicht aber bei Patienten mit Plasma-HIV- RNA unter 50 Kopien pro Milliliter keine Heilung, da es bei Therapieunter- bruch zum Rebound kommt, bei 80

Noch keine Studien Auch beim neuen Flash Glucose Monitoring be- findet sich der Sensor im Unterhaut- fettgewebe, allerdings wurde hier ein Algorithmus in das System einge- baut,

Es orientiert regelmässig die kantonale Arbeitsmarktkommission KAMKO, die aus Vertreterinnen und Vertretern der Sozialpartner sowie aus Behördenmitgliedern

Unter der Leitung des Chefs Telematik, Oblt Karl Mayer, wurde das zuvor in Ausbildungsblöcken Gelernte im Raum Studenland in zwei Übungen praktisch umgesetzt... Surbtal und Rheintal

Aber auch die Steuerpolitik kann und muß einen Beitrag für höhere Netto-Reallöhne leisten und so zusätzliche Nachfrageimpulse auslösen, die zu mehr Wirtschaftswachstum und zu

I Hitting sets over all cut landmarks yield a perfect heuristic for delete-free planning tasks. I The LM-cut heuristic is an admissible heuristic based on

Die Ablösung des Bundes-Angestellten- tarifvertrags (BAT) für den öffentlichen Dienst mit seinen Veränderungen (dadurch und durch die Vielzahl der notwendig ge-