2 Logikprogrammierung am Beispiel Prolog -...

25
2 Logikprogrammierung am Beispiel Prolog 2.1 Logikprogrammierung mit einfachen Daten 2.2 Variablenumbenennung 2.3 Syntax 2.4 Komplexe Daten 2.5 Der Cut 2.6 Negation als Fehlschlag 2.7 Literaturhinweise 2.8 ¨ Ubungsaufgaben 2 Logikprogrammierung am Beispiel Prolog 1

Transcript of 2 Logikprogrammierung am Beispiel Prolog -...

2 Logikprogrammierung am Beispiel Prolog

2.1 Logikprogrammierung mit einfachen Daten

2.2 Variablenumbenennung

2.3 Syntax

2.4 Komplexe Daten

2.5 Der Cut

2.6 Negation als Fehlschlag

2.7 Literaturhinweise

2.8 Ubungsaufgaben

2 Logikprogrammierung am Beispiel Prolog 1

2.1 Logikprogrammierung mit einfachen Daten

maennlich(paul). % Paul ist mannlichmaennlich(fritz). % Fritz ist mannlichmaennlich(steffen). % Steffen ist mannlich

weiblich(karin). % Karin ist weiblichweiblich(lisa). % Lisa ist weiblichweiblich(maria). % Maria ist weiblichweiblich(sina). % Sina ist weiblich

vater(steffen, paul). % Steffen ist der Vater von Paulvater(fritz, karin). % Fritz ist der Vater von Karinvater(steffen, lisa). % Steffen ist der Vater von Lisavater(paul, maria). % Paul ist der Vater von Maria

mutter(karin, maria). % Karin ist die Mutter von Mariamutter(sina, paul). % Sina ist die Mutter von Paul

tochter(Y, X) :−vater(X, Y), weiblich(Y).

2 Logikprogrammierung am Beispiel Prolog 2

2.1.7 Rekursiv definierte Pradikate - Motivation

I Eltern und weitere Vorfahren

elternteil(E, Kind) :− vater(E, Kind).elternteil(E, Kind) :− mutter(E, Kind).

vorfahre(Alt, Jung) :− elternteil(Alt, Jung). % Elternvorfahre(Alt, Jung) :− elternteil(Alt, X), % Großeltern

elternteil(X, Jung).vorfahre(Alt, Jung) :− elternteil(Alt, X), % Urgroßeltern

elternteil(X, Y),elternteil(Y, Jung).

. . .

2 Logikprogrammierung am Beispiel Prolog 3

Ein rekursiv definiertes Pradikat

I Eltern und weitere Vorfahren

elternteil(E, Kind) :− vater(E, Kind).elternteil(E, Kind) :− mutter(E, Kind).

vorfahre(Alt, Jung) :− elternteil(Alt, Jung).vorfahre(Alt, Jung) :− elternteil(Alt, X),

vorfahre(X, Jung).

I Die Reihenfolge der Teilziele ist wichtig !

vorfahre1(Alt, Jung) :− elternteil(Alt, Jung).vorfahre1(Alt, Jung) :− vorfahre1(X, Jung),

elternteil(Alt, X).

2 Logikprogrammierung am Beispiel Prolog 4

Variablenumbenennung

I Geltungsbereich einer Variablen:

vorfahre(Alt, Jung) :− elternteil(Alt, Jung).vorfahre(Alt, Jung) :− elternteil(Alt, X), vorfahre(X, Jung).

I Indizierung X i bzw. i.

2 Logikprogrammierung am Beispiel Prolog 5

2.3 Syntax: Terme, Konstantensymbole und Atome

I Terme sind

. Konstantensymbole,

. Variable oder

. zusammengesetzte Terme.

I Konstantensymbole sind

. Atome oder

. Zahlen.

I Atome sind

. Folgen von alphanumerischen Zeichen, die mit einem kleinen Buchstabenbeginnen (a, a12, steffen),

. eine Folge von Sonderzeichen ([ ]) oder

. eine Folge von Zeichen in einfachen Anfuhrungszeichen(′Schule ist doof′).

2 Logikprogrammierung am Beispiel Prolog 6

Syntax: Zahlen, Variable und zusammengesetzte Terme

I Zahlen sind

. ganze Zahlen (1, −2) oder

. reelle Zahlen (1.7, −3.14).

I Variable sind Folgen von alphanumerischen Zeichen, die mit einem großenBuchstaben oder mit beginnen (X, Y4w 13, G124).

I Zusammengesetzte Terme sind Zeichenreihen der Form f(t1, . . . , tn) undbestehen aus einem Funktor f/n und n ≥ 1 Termen t1, . . . , tn.

. Die Terme t1, . . . , tn werden auch Argumente genannt.

. Ein Funktor f/n ist definiert durch seinen Namen f und seine Stelligkeit n.

. Funktoren mit gleichen Namen aber verschiedenen Stelligkeiten werden alsverschieden betrachtet.

. f(a12, X, 1.7), f(a, f(1.3, [ ])).

2 Logikprogrammierung am Beispiel Prolog 7

Syntax: Prolog-Programme

I Ein Prolog-Programm ist eine Folge von Programmklauseln.

I Eine Programmklausel ist eine Zeichenreihe der Form

t :− t1, . . . , tn.

wobei t, t1, . . . , tn Atome oder zusammengesetzte Terme sind und n ≥ 0 ist.

. t heißt Kopf,

. t1, . . . , tn heißt Rumpf der Programmklausel.

. Wenn n = 0 ist, dann schreiben wir kurz t.Programmklauseln dieser Form heißen Fakten.

. Programmklauseln, fur die n > 0 gilt, heißen Regeln.

2 Logikprogrammierung am Beispiel Prolog 8

Syntax: Anfragen bzw. Ziele

I Eine Anfrage oder Ziel ist eine Zeichenreihe der Form

?− t1, . . . , tn.

wobei die t1, . . . , tn Atome oder zusammengesetzte Terme sind und n ≥ 0 ist.

. Die t1, . . . , tn heißen Teilziele.

. Wenn n = 0 ist, dann wollen wir von einer leeren Anfrage oder einem leerenZiel sprechen.

. Eine leere Anfrage ist immer erfullt.

2 Logikprogrammierung am Beispiel Prolog 9

2.4 Komplexe Daten

person(lisa, geb(3, 12, 1910)). % Lisa wurde am 3.12.1910 geborenperson(maria, geb(1, 10, 1990)). % Maria wurde am 1.10.1990 geborenperson(steffen, geb(4, 5, 1919)). % Steffen wurde am 4.5.1919 geboren

rentner(X) :− person(X, geb(T, M, J)), % Frauen werden mitweiblich(X), % 60 in den RuhestandJ < 1944. % versetzt,

rentner(X) :− person(X, geb(T, M, J)), % Manner erstmaennlich(X), % mit 65J < 1939.

2 Logikprogrammierung am Beispiel Prolog 10

2.4.1 Listen

I Sei [ ] ein Atom und ./2 ein Funktor.

. [ ] ist eine Liste.

. Wenn K ein Term und R eine Liste ist, dann ist .(K, R) eine Liste.

I [ ] wird haufig als leere Liste, K als Kopf und R als Rumpf bezeichnet.

I Abkurzungen:

. .(t1, .(t2, .(. . . (tn, t) . . .))) [t1, t2, . . . , tn|t].

. .(t1, .(t2., (. . . (tn, []) . . .))) [t1, t2, . . . , tn].

I liste([ ]). % [ ] ist eine Liste.liste([Kopf|Rest]) :− liste(Rest). % [Kopf|Rest] ist eine Liste,

% wenn Rest eine Liste ist.

2 Logikprogrammierung am Beispiel Prolog 11

2.4.2 Listenoperationen

I Das Pradikatszeichen member/2:

member(X, [X | ]).member(X, [ | Rest]) :− member(X, Rest).

I Das Pradikatszeichen append/3:

append([ ], L, L).append([Kopf|Rest], L, [Kopf|Rest1]) :− append(Rest, L, Rest1).

I Das Pradikatszeichen naive reverse/2:

naive reverse([ ], [ ]).naive reverse([Kopf|Rest], X) :− naive reverse(Rest, Y),

append(Y, [Kopf], X).

2 Logikprogrammierung am Beispiel Prolog 12

2.4.3 Operatoren

I Ziel: Wir wollen Operatoren auch infix oder postfix schreiben durfen;Operatoren sollen auch assoziativ sein durfen.

. +(2, 5) 2 + 5, +(3, +(5, 7)) 3 + 5 + 7

I Operatordeklaration::−op(500, yfx, +).

I Einstellige Operatoren: fx Prafix nicht assoziativfy Prafix rechtsassoziativxf Postfix nicht assoziativyf Postfix linksassoziativ

Zweistellige Operatoren: xfx Infix nicht assoziativyfx Infix linksassoziativxfy Infix rechtsassoziativ

I Prazedenzzahl: niedere Prazedenzzahl hohere Prioritat.

2 Logikprogrammierung am Beispiel Prolog 13

2.4.4 Arithmethik

I Ein Term ist grundinstantiiert, wenn in ihm keine Variablen mehr vorkommen.

I Der Operator is/2: X is 7 ∗ 8.

I Vergleichsoperatoren: 4 ∗ 12 =:= 100 − (60 − 8)

. Gleichheit =:= /2

. Ungleichheit =\= /2

. Kleiner < /2

. Großer > /2

. Kleiner oder gleich =< /2

. Großer oder gleich >= /2

2 Logikprogrammierung am Beispiel Prolog 14

Eine Klassenhierarchie der Prolog-Terme

Ganze Zahlen Gleitkommazahlen�

��

��

@@

@@@

Atome Zahlen�

��

��

@@

@@@

Konstantensymbole Zusammengesetzte Terme�

��

��

@@

@@@

Variablen Nicht–Variablen�

��

��

@@

@@@

Terme

2 Logikprogrammierung am Beispiel Prolog 15

2.4.5 Strukturpradikate

I Typbestimmung var(X) X ist eine Variable.nonvar(X) X ist keine Variable.atomic(X) X ist ein Konstantensymbol.atom(X) X ist ein Atom.number(X) X ist eine Zahl.integer(X) X ist eine ganze Zahl.float(X) X ist eine Gleitkommazahl.compound(X) X ist ein zusammengesetzter Term.

I Analyse und Synthese von Termen

. Das Systempradikatszeichen functor/3: Zugriff auf Funktor.

. Das Systempradikatszeichen arg/3: Zugriff auf Argumente.

. Der Systemoperator = .. /2: Terme ⇔ Listen.

2 Logikprogrammierung am Beispiel Prolog 16

2.4.6 Vergleich von Termen

I Der Systemoperator = = /2: Syntaktische Gleichheit.

I Der Systemoperator \= = /2: Syntaktische Ungleichheit.

2 Logikprogrammierung am Beispiel Prolog 17

2.4.7 Unifikation von Termen

I Ein Unifikationsproblem wird durch zwei Terme s und t beschrieben und ist dieFrage, ob es eine Ersetzung (oder Substitution) der in s und t vorkommendenVariablen gibt, so dass die entsprechenden Instanzen von s und t syntaktischidentisch sind.

I Gibt es eine solche Substitution, dann sind s und t unifizierbar.

I Der Systemoperator =/2: Unifikation.

I Unterschied =/2 und = = /2.

I Zeichenreihen der Form X = a werden Bindung genannt.

I Eine Menge von Bindungen ist eine Substitution.

I Eine leere Menge von Bindungen wird leere Substitution genannt.

I Fehlschlagende Unifikationsprobleme

. Verschiedene Funktoren: f(X, a) = g(Y, a).

. Verschiedene Stelligkeiten: f(X) = f(X, Y).

. Occurs Check Problem: X = f(X).

2 Logikprogrammierung am Beispiel Prolog 18

Ein Unifikationsalgorithmus ohne Occurs Check

unify(X, Y) :− var(X), X = Y.unify(X, Y) :− nonvar(X), var(Y), Y = X.unify(X, Y) :−

nonvar(X), nonvar(Y),X = .. [F | L1], Y = .. [F | L2],unify list(L1, L2).

unify list([ ], [ ]).unify list([X1 | L1], [X2 | L2]) :− unify(X1, X2), unify list(L1, L2).

2 Logikprogrammierung am Beispiel Prolog 19

Ein Unifikationsalgorithmus mit Occurs Check

unify with occurs check(X, Y) :− var(X), var(Y), X = Y.unify with occurs check(X, Y) :−

var(X), nonvar(Y), not occurs in(X, Y), X = Y.unify with occurs check(X, Y) :−

nonvar(X), var(Y), not occurs in(Y, X), Y = X.unify with occurs check(X, Y) :−

nonvar(X), nonvar(Y), X = .. [F | L1], Y = .. [F | L2],unify list with occurs check(L1, L2).

unify list with occurs check([ ], [ ]).unify list with occurs check([X1 | L1], [X2 | L2]) :−

unify with occurs check(X1, X2), unify list with occurs check(L1, L2).

not occurs in(X, Y) :− var(Y), X \= = Y.not occurs in(X, Y) :− nonvar(Y), Y = .. [F | L], not occurs in list(X, L).

not occurs in list(X, [ ]).not occurs in list(X, [Kopf | Rest]) :−

not occurs in(X, Kopf), not occurs in list(X, Rest).

2 Logikprogrammierung am Beispiel Prolog 20

2.5 Der Cut

I Das Systempradikatszeichen !/0, genannt Cut.

max1(X, Y, X) :− X >= Y.max1(X, Y, Y) :− X < Y.

max2(X, Y, X) :− X >= Y, !.max2(X, Y, Y) :− X < Y, !.

max3(X, Y, X) :− X >= Y, !.max3(X, Y, Y).

max4(X, Y, X) :− X >= Y.max4(X, Y, Y).

max5(X, Y, Z) :− X >= Y, !, Z = X.max5(X, Y, Y).

2 Logikprogrammierung am Beispiel Prolog 21

Das Abschneiden von Asten in einem Ableitungsbaum

e f

?− 7 >= 5 ?− 5 < 7�

��

��

@@

@@@

{X = 7, Y = 5, Z = 7} {X = 7, Y = 5, Z = 5}��

?− max1(7, 5, Z).

2 Logikprogrammierung am Beispiel Prolog 22

Rote und grune Cuts

I Grune Cuts: schneiden keine Losungen ab.

I Rote Cuts: schneiden Losungen ab.

I Setzen Sie einen Cut sobald Sie wissen, dass dies die richtige Programmklauselist – nicht spater, aber auch nicht fruher.

I Verzogern Sie Ausgabe-Unifikationen bis nach dem Cut.

2 Logikprogrammierung am Beispiel Prolog 23

Die Familiendatenbank

maennlich(paul). % Paul ist mannlichmaennlich(fritz). % Fritz ist mannlichmaennlich(steffen). % Steffen ist mannlich

weiblich(karin). % Karin ist weiblichweiblich(lisa). % Lisa ist weiblichweiblich(maria). % Maria ist weiblichweiblich(sina). % Sina ist weiblich

vater(steffen, paul). % Steffen ist der Vater von Paulvater(fritz, karin). % Fritz ist der Vater von Karinvater(steffen, lisa). % Steffen ist der Vater von Lisavater(paul, maria). % Paul ist der Vater von Maria

mutter(karin, maria). % Karin ist die Mutter von Mariamutter(sina, paul). % Sina ist die Mutter von Paul

2 Logikprogrammierung am Beispiel Prolog 24

2.6 Negation als Fehlschlag

I Wie konnen wir in Prolog testen, dass die 1 in der Liste [2,3,4] nicht vorkommt?

I Der Systemoperator \+ /1.

I Das Systempradikatszeichen fail/0.

I Implementation von \+:

\+ X :− X, !, fail.\+ X.

I Negation als Fehlschlag ist keine klassische Negation.

cross(X) :− \+ train(X).

2 Logikprogrammierung am Beispiel Prolog 25