1998 Programmierkurs PROLOG Sommersemester...Programmierkurs PROLOG Sommersemester 1998 1.5...

Post on 13-Jul-2020

15 views 0 download

Transcript of 1998 Programmierkurs PROLOG Sommersemester...Programmierkurs PROLOG Sommersemester 1998 1.5...

Programmierkurs PROLOG Sommersemester

Programmierkurs PROLOG

Sommersemester

Thorsten Joachims (LS VIII)

Stephan Lehmke (LS I)

Programmierkurs PROLOG Sommersemester

1.1 Kursverlauf

1. Woche 14. 09. 98 – 18. 09. 98 Stephan Lehmke

2. Woche 21. 09. 98 – 25. 09. 98 Thorsten Joachims

8.15–11.45h Vorlesung HG I / HS 2

14.15–15.45h Globalubung HG I / HS 2

3. Woche: 28. 09. 98 – 02. 10. 98

8.15– 9.45h Vorlesung GB IV / HS 112

14.15–15.45h Individualubung

1 Einfuhrung 1-1

Pausen festlegen:

• 2×90min VL + 30min Pause, Ende 11.45h

• 4×45min VL mit je 15min Pause, Ende 12.00h

• 180min VL am Stuck, Ende 11.15h

1-1-1

Programmierkurs PROLOG Sommersemester

Erste Woche:

Mo Einfuhrung, Logische Grundlagen, Erste Schritte

Di Syntax, Ausfuhrungsmodell, Arithmetik, Rekursion

Mi Strukturen, Baume, Listen, Backtracking, der Cut,

Do Ein- und Ausgabe, Systempradikate, Modulsystem

Fr Datenstrukturen und Algorithmen

1 Einfuhrung 1-2

Programmierkurs PROLOG Sommersemester

Zweite Woche:

Mo Graphen, Suche, Werkzeuge (Debugger)

Di Constraint Logic Programming

Mi Metapradikate, Metaprogrammierung, Metainterpreter

Do Expertensysteme, Planen, Lernsysteme

Fr Definite Clause Grammars

1 Einfuhrung 1-3

Programmierkurs PROLOG Sommersemester

Dritte Woche:

Mo Programmierpraxis, fortgeschrittene Programmiertechnik

Di Programmierpraxis, fortgeschrittene Programmiertechnik

Mi Programmierpraxis, PROLOG & Softwaretechnik

Do Programmierpraxis, Einfuhrung in MERCURY

Fr Programmierpraxis, Einfuhrung in MERCURY

1 Einfuhrung 1-4

Programmierkurs PROLOG Sommersemester

1.2 Ubungen

• Accountvergabe nach der heutigen Vorlesung.

• Erste und zweite Woche Globalubung (keine Korrektur).

• Abgabe bitte per email:

prolog-betreuer@krypton

bis 12.00h!

• Organisation der Individualubung Anfang dritte Woche.

• Leistungsnachweis: Ubungsschein nach Prg. Projekt.

1 Einfuhrung 1-5

Programmierkurs PROLOG Sommersemester

1.3 Technisches

Pools: GB V / Raum 9–10

Rechner: blei, cadmium etc., accounts pkpro00–pkpro49.

Druckquota: 50 Seiten.

Installation: Bitte die Dateien ~pkpro00/.login und~pkpro00/.emacs kopieren.

Editor: emacs

PROLOG-System: eclipse

1 Einfuhrung 1-6

Programmierkurs PROLOG Sommersemester

1 Einfuhrung 1-7

Programmierkurs PROLOG Sommersemester

1.4 Materialien

Website unter

http://ls1-www.informatik.uni-dortmund.de/~lehmke/Prolog-Kurs/

Dort: Termine, Online-Doku, Folien, Ubungsblatter, Links, . . .

1 Einfuhrung 1-8

Programmierkurs PROLOG Sommersemester

1.5 Literatur

• W. F. Clocksin and C. S. Mellish

Programming in Prolog, 4th edition, Springer-Verlag 1994

• Leon Sterling and Ehud Shapiro

The Art of Prolog, 2nd edition, MIT Press 1994

• Richard A. O’Keefe

The Craft of Prolog, MIT Press 1990

• Ivan Bratko

PROLOG Programming for Artificial Intelligence2nd edition, Addison-Wesley 1990

1 Einfuhrung 1-9

Programmierkurs PROLOG Sommersemester

1.6 Logisches Programmieren

Grundlegende Idee:

Robert Kowalski

Algorithm = Logic + ControlComm. ACM 22, 1979, pp. 424–436.

Logik: Was ist das Problem?

Kontrolle: Wie wird das Problem gelost?

1 Einfuhrung 1-10

Programmierkurs PROLOG Sommersemester

What-Type-Language: Der Benutzer spezifiziert dasProblem abstrakt; das System berechnet die Losung.

How-Type-Language: Der Benutzer spezifiziert eine Folge vonOperationen, durch die das Problem gelost wird.

In Prolog:

• Abstrakte Beschreibung durch Fakten und Regeln.

• Das System stellt das Losungsverfahren zur Verfugung

logisch: Unifikation und Resolution.

technisch: Matching und Nichtdeterminismus (Backtr.).

1 Einfuhrung 1-11

Programmierkurs PROLOG Sommersemester

1.7 Geschichte

1965: Resolutionskalkul (J. A. Robinson)

1970–72 Erster Prolog-Interpreter

• R. Kowalski, Edinburgh (Theorie; Horn-Klauseln)

• A. Colmerauer, Marseille (Implementierung)

1975–79 Erster Prolog-Compiler (D. Warren).

1980 Borland’s Turbo Prolog.

1982 Beginn des japanischen 5th Generation Projekts.

1 Einfuhrung 1-12

Programmierkurs PROLOG Sommersemester

heute Viele Implementierungen, z. T. erheblich erweitert (z. B.um constraints).

Wir verwenden ECLiPSe.

1 Einfuhrung 1-13

Programmierkurs PROLOG Sommersemester

1.8 Anwendungen

• Kunstliche Intelligenz

• deduktive Datenbanken (Datalog)

• symbolische Mathematik

• constraint programming

• Konstruktion von Parsern, Interpretern und Compilern

• Konfigurationsaufgaben (z. B. NT-Netzwerkkonfiguration)

Allgemein:strukturorientierte Verarbeitung symbolischer Daten.

1 Einfuhrung 1-14

Programmierkurs PROLOG Sommersemester

1.9 Drei Perspektiven bzgl. Prolog

1. Programming in Logic.Zu ausdrucksschwach ; Theorembeweiser

2. Database Query Language.Zu ausdrucksstark ; Datalog

3. Effiziente strukturorientierte Programmiersprache.

1 Einfuhrung 1-15

Programmierkurs PROLOG Sommersemester

Gliederung

• Einleitung.

• Syntax und Semantik des Pradikatenkalkuls 1. Stufe.

• Der Modellbegriff. Semantisches Folgern.

• Formales Ableiten und Beweisen. Resolutionskalkul.

• Entscheidbarkeitsfragen.

• Logisches Programmieren. Horn-Klauseln.

2 Logische Grundlagen 2-1

Programmierkurs PROLOG Sommersemester

2.1 Einleitung

Zum Nachlesen und Vertiefen:

• H. Thiele (91–96), H. Wagner (96–99)Skriptum zur Stammvorlesung LSI

• U. Schoning

Logik fur InformatikerB·I Wissenschaftsverlag 87–95

2 Logische Grundlagen 2-2

Programmierkurs PROLOG Sommersemester

2.1.1 Elemente der mathematischen Logik

Syntax: Sprache logischer Ausdrucke.

Semantik: Interpretation logischer Ausdrucke — wann ist einAusdruck gultig, wann ungultig?

Modellbegriff: Was macht einen Ausdruck gultig?

Semantische Folgerung:

Was folgt aus einer Menge von Annahmen?

Formales Ableiten: Wie kann man die semantische Folgerungdurch regelbasiertes Schließen charakterisieren?

2 Logische Grundlagen 2-3

Programmierkurs PROLOG Sommersemester

2.2 Syntax der Pradikatenlogik 1. Stufe

PS Menge von Paaren Pradikatensymbol/Aritat (Stellenz.).

Beispiel Pradikatensymbol member mit Aritat 2:

member/2 ∈ PS .

FS Menge von Paaren Funktionssymbol/Aritat.

Beispiel Funktionssymbol div mit Aritat 2: div/2 ∈ FS.

(Spezialfall Aritat = 0: Individuenkonstante (Beisp. pi)).

2 Logische Grundlagen 2-4

Programmierkurs PROLOG Sommersemester

Definition 1 (Individuenvariablen und Terme)

1. Wir fixieren eine Menge VAR von Individuenvariablen.

2. Individuenvariablen und Individuenkonstanten sind Terme.

3. Gilt f/n ∈ FS mit n ≥ 1 und sind T1, . . . , Tn Terme, dann

ist f(T1, . . . , Tn) ein Term.

2 Logische Grundlagen 2-5

Programmierkurs PROLOG Sommersemester

Definition 2 (Ausdrucke)

1. Wenn p/0 ∈ PS, so ist p ein Ausdruck.

2. Gilt p/n ∈ PS mit n ≥ 1 und sind T1, . . . , Tn Terme, dann

ist p(T1, . . . , Tn) ein Ausdruck.

3. Sind A und B Ausdrucke, so auch ¬A, (A ∨B).

4. Ist V ∈ VAR und ist A ein Ausdruck, so auch ∀V A.

Die Menge aller Ausdrucke: AUSD.

Ausdrucke nach 1 und 2 heißen atomar.

2 Logische Grundlagen 2-6

Programmierkurs PROLOG Sommersemester

Zusatzliche Operatoren:

(A→B) =def (¬A ∨B)

(A ∧B) =def ¬(¬A ∨ ¬B)

(A↔ B) =def ((A→ B) ∧ (B → A))

∃V A =def ¬∀V ¬A

Klammersparung:

↔ trennt starker als →, ∨ und ∧→ trennt starker als ∨ und ∧∨ trennt starker als ∧

2 Logische Grundlagen 2-7

Programmierkurs PROLOG Sommersemester

Beispiel

PS = {p/2} , FS = ?

∀X p(X,X) p reflexiv(1)

∀X∀Y (p(X,Y)→ p(Y,X)) p symmetrisch(2)

∀X∀Y∀Z (p(X,Y) ∧ p(Y,Z)→ p(X,Z)) p transitiv(3)

(3) ohne Abkurzungen:

∀X ∀Y∀Z (¬¬(¬p(X,Y) ∨ ¬p(Y,Z)) ∨ p(X,Z))

2 Logische Grundlagen 2-8

Programmierkurs PROLOG Sommersemester

2.3 Interpretation der Terme und Ausdrucke

Definition 3 (Interpretation)

Ein Quintupel J = [PS,FS,∆,Φ,Π] heiße Interpretation

⇔ 1. ∆ ist eine nicht-leere Menge (Individuenbereich).

2. Φ ordnet jedem Paar f/n ∈ FS eine Abbildung

Φf/n : ∆n → ∆ zu; ist n = 0, so gilt: Φf/n ∈ ∆.

3. Π ordnet jedem Paar p/n ∈ PS eine Teilmenge

Πp/n ⊆ ∆n zu; ist n = 0, so gilt Πp/n j {?}.

2 Logische Grundlagen 2-9

Programmierkurs PROLOG Sommersemester

Definition 4 (Zustande; Interpretation der Terme)

1. σ heiße J-Zustand der Individuenvariablen aus VAR⇔ σ : VAR→ ∆

2. EL(T, J, σ) ordnet dem Term T das durch J im J-Zustand

σ festgelegte Individuum aus ∆ zu.

EL(V, J, σ) =def σ(V ), falls V ∈ VAR

EL(f, J, σ) =def Φf , falls f/0 ∈ FS

EL(f(T1, . . . , Tn), J, σ)=def Φf/n(EL(T1, J, σ), . . . ,EL(Tn, J, σ)),

falls f/n ∈ FS und n ≥ 1.

2 Logische Grundlagen 2-10

Programmierkurs PROLOG Sommersemester

σ 〈V := ξ〉 (W ) =def

σ(W ) , falls W 6= V

ξ , falls W = V.

2 Logische Grundlagen 2-11

Programmierkurs PROLOG Sommersemester

Definition 5 (Erfullungsdefinition)

σ, J |= p =def Πp = {?}σ, J |= q(T1, . . . , Tn)

=def [EL(T1, J, σ), . . . ,EL(Tn, J, σ)] ∈ Πq

σ, J |= ¬A =def Es gilt nicht, daß σ, J |= A

σ, J |= (A ∨B) =def σ, J |= A oder σ, J |= B

σ, J |= ∀V A =def Fur jedes ξ ∈ ∆ gilt: σ 〈V := ξ〉 , J |= A

2 Logische Grundlagen 2-12

Programmierkurs PROLOG Sommersemester

Definition 6

1. In J ist A allgemeingultig (kurz: J |= A oder J ag A)

=def Fur jeden J-Zustand σ gilt: σ, J |= A.

2. In J ist A erfullbar (kurz: J ef A)

=def es gibt einen J-Zustand σ mit σ, J |= A.

3. A ist (schlechthin) allgemeingultig

(kurz: |= A oder agA)

=def Fur jede Interpretation J gilt: J |= A.

4. A ist (schlechthin) erfullbar (kurz: efA)

=def es gibt eine Interpretation J, so daß J ef A.

2 Logische Grundlagen 2-13

Programmierkurs PROLOG Sommersemester

Beispiel A =def ∀X p(X,X)B =def ∀X∀Y (p(X,Y)→ p(Y,X))

C =def ∀X∀Y∀Z (p(X,Y) ∧ p(Y,Z)→ p(X,Z))

Dann gilt fur J = [PS,FS,∆,Φ,Π] mit

∆ = N×N

Πp ={

(n,m) n,m ∈ N und n,m haben die gleichen Teiler},

daß J |= A und J |= B und J |= C (Aquivalenzrelation).

Wahlen wir Πp ={

(n,m) n,m ∈ N und n 5 m}

, so gilt J |= A

und J |= C, aber nicht J |= B.

2 Logische Grundlagen 2-14

Programmierkurs PROLOG Sommersemester

Beispiel Fur jeden Ausdruck A gilt

|= A→A.

2 Logische Grundlagen 2-15

Programmierkurs PROLOG Sommersemester

Lemma 1

1. A ist allgemeingultig

genau dann, wenn ¬A nicht erfullbar ist.

2. A ist erfullbar

genau dann, wenn ¬A nicht allgemeingultig ist.

2 Logische Grundlagen 2-16

Programmierkurs PROLOG Sommersemester

Definition 7

A1 ist mit A2 semantisch aquivalent (A1 ≡ A2)

=def (A1 ↔ A2) ist allgemeingultig, d. h. |= (A1 ↔ A2).

Theorem 2 (Semantisches Ersetzbarkeitstheorem)

Sind A1, A2, A3 beliebige Ausdrucke und geht A4 aus A1 durch

Ersetzung von A2 durch A3 hervor, gilt schließlich

A2 ≡ A3,

so gilt auch A1 ≡ A4.

2 Logische Grundlagen 2-17

Programmierkurs PROLOG Sommersemester

Beispiel Es gilt fur Ausdrucke A,B,C

A ∨B ≡ B ∨A Kommutativitat

(A ∨B) ∨ C ≡ A ∨ (B ∨ C) Assoziativitat

A ∨ (A ∧B) ≡ A Absorption

A ∨ (B ∧ C) ≡ (A ∨B) ∧ (A ∨ C) Distributivitat

¬(A ∨B) ≡ ¬A ∧ ¬B De Morgansche Regel

¬¬A ≡ A Doppelte Negation

¬A→¬B ≡ B→A Kontraposition

¬∀xA ≡ ∃x¬A

Kommt x nicht frei in B vor, so ∀xA ∨B ≡ ∀x(A ∨B)

2 Logische Grundlagen 2-18

Programmierkurs PROLOG Sommersemester

Definition 8

1. A heiße pranexe Normalform

=def A ist quantorenfrei oder es gibt V1, . . . , Vn ∈ VAR,

Quantoren Q1, . . . , Qn ∈ {∀, ∃} und ein

quantorenfreies B, so daß A = Q1V1 . . . QnVnB.

Q1V1 . . . QnVn heißt Prafix von A.

2. A heiße universale Normalform

=def A ist pranexe Normalform; ist das Prafix von A nicht

leer, so kommen darin nur Allquantoren vor.

2 Logische Grundlagen 2-19

Programmierkurs PROLOG Sommersemester

Theorem 3

Zu jedem Ausdruck A ∈ AUSD kann eine pranexe Normalform

N konstruiert werden, so daß

A ≡ N.

Beweis

Anwenden des semantischen Ersetzbarkeitstheorems. 2

2 Logische Grundlagen 2-20

Programmierkurs PROLOG Sommersemester

2.4 Der Modellbegriff. Semantisches Folgern

Sei X eine Menge von Ausdrucken.

Definition 9 (Modell)

J heiße Modell von X (J |= X)

=def Fur jedes A ∈ X ist A in J allgemeingultig,

d. h. es gilt J |= A.

Menge aller Modelle von X: MOD(X).

2 Logische Grundlagen 2-21

Programmierkurs PROLOG Sommersemester

Theorem 4 (Endlichkeitssatz fur Modelle)

Gibt es zu jeder endlichen Teilmenge Xfin ⊆ Y ein Modell J,

d. h. mit J |= Xfin, dann gibt es auch fur die gesamte Menge Y

ein Modell, etwa J′, d. h. mit J′ |= Y .

2 Logische Grundlagen 2-22

Programmierkurs PROLOG Sommersemester

Definition 10 (Semantische Folgerung)

1. Aus X folgt (semantisch) A (kurz X |−|− A)

=def Fur jede Interpretation J gilt:

Wenn J Modell von X, so J Modell von A.

2. Cons(X) =def

{A A ∈ AUSD und X |−|− A

}.

2 Logische Grundlagen 2-23

Programmierkurs PROLOG Sommersemester

Beispiel

PS = {=/2}, FS = {+/2, 0/0}

A =def ∀X∀Y∀Z (X + Y) + Z = X + (Y + Z) (+ ist assoziativ)

B =def ∀X X + 0 = X (Neutrales Element)

C =def ∀X∃Y X + Y = 0 (Inverses)

D =def ∀X∀Y X + Y = Y + X (+ ist kommutativ)

G =def {A,B,C}

T ∈ Cons(G)⇔ T ist ein Satz der Gruppentheorie.

2 Logische Grundlagen 2-24

σ, J |= T1 = T2 =def EL(T1, J, σ) = EL(T2, J, σ)

2-24-1

Programmierkurs PROLOG Sommersemester

Definition 11 (Generalisierte)

Seien X1, . . . , Xn die Variablen, die in A frei vorkommen.

Gen(A) =def ∀X1 . . .∀XnA.

Lemma 5

Sei A ∈ AUSD.

Cons(A) = Cons(Gen(A))

2 Logische Grundlagen 2-25

Programmierkurs PROLOG Sommersemester

2.5 Formales Ableiten und Beweisen.

Resolutionstheorie

2.5.1 Idee

Semantische Folgerung (zu aufwendig) soll durch SyntaktischesAbleiten (Berechnungen uber der Sprache AUSD) ersetztwerden.

2 Logische Grundlagen 2-26

Programmierkurs PROLOG Sommersemester

Logik: Eine Sprache AUSD zusammen mit einem(semantischen) Folgerungsoperator |−|−.

Kalkul: Eine Sprache AUSD zusammen mit einem(syntaktischen) Beweisbarkeitsoperator |−.

Rechtfertigung eines Kalkuls:

Korrektheit: X |− A =⇒ X |−|− A

”Alles, was beweisbar ist, folgt auch semantisch“.

Vollstandigkeit: X |−|− A =⇒ X |− A

”Alles, was folgt, ist auch beweisbar“.

2 Logische Grundlagen 2-27

Programmierkurs PROLOG Sommersemester

Um den Beweisoperator automatisieren zu konnen, wahlen wirden Resolutionskalkul.

Da dieser auf einer sehr einfachen Schlußregel beruht, mussenwir die Ausdrucke stark vereinfachen. ; Klauselform.

2 Logische Grundlagen 2-28

Programmierkurs PROLOG Sommersemester

2.5.2 Vorbereitung

Definition 12 (Termeinsetzung)

A[V /T

]=def Derjenige Ausdruck, der aus A dadurch entsteht, daß die

Individuenvariable V in A uberall, wo sie frei vorkommt,

simultan durch T ersetzt wird.

Gebundene Umbenennung: Eine Variable wird uberall imWirkungsbereich eines Quantors, durch den sie gebunden wird,durch eine andere ersetzt.

2 Logische Grundlagen 2-29

Programmierkurs PROLOG Sommersemester

Lemma 6 (Widerlegungssystem)

Fur jedes X j AUSD und jedes A ∈ AUSD gilt:

X |−|− A genau dann,

wenn X ∪ {¬Gen(A)} kein Modell hat.

2 Logische Grundlagen 2-30

Programmierkurs PROLOG Sommersemester

Definition 13

1. X und Y heißen semantisch aquivalent (X ≡ Y )

=def Fur jede Interpretation J und jeden J-Zustand σ gilt:

σ, J |= X g.d.w. σ, J |= Y.

2. X und Y heißen Modell-aquivalent(X ∼= Y )

=def MOD(X) = MOD(Y ).

3. X und Y heißen schwach Modell-aquivalent (X u Y )

=def MOD(X) 6= ? genau dann, wenn MOD(Y ) 6= ?.

2 Logische Grundlagen 2-31

Programmierkurs PROLOG Sommersemester

Theorem 7

Zu jedem X ⊆ AUSD kann ein Y ⊆ AUSD konstruiert werden,

so daß

1. Y allein aus pranexen Normalformen besteht und

2. X und Y semantisch aquivalent sind.

2 Logische Grundlagen 2-32

Programmierkurs PROLOG Sommersemester

2.5.3 Skolemisierung

A sei eine Aussage (Ausdruck ohne freie Variablen) der Form

A = ∀X1 . . .∀Xn∃Y B.

Wir wahlen ein neues Funktionssymbol f/n.Dann ist A schwach modell-aquivalent zu

∀X1 . . .∀XnB[Y /f(X1, . . . , Xn)

].

2 Logische Grundlagen 2-33

Programmierkurs PROLOG Sommersemester

Theorem 8 (Skolemisierungstheorem)

Zu jedem X ⊆ AUSD kann ein X ′ konstruiert werden, so daß

1. X ′ allein aus universalen Normalformen besteht und

2. X ′ schwach Modell-aquivalent mit X ist.

Folgerung 9

Zu jedem X ⊆ AUSD kann ein X ′ konstruiert werden, so daß

1. X ′ allein aus quantorenfreien Ausdrucken besteht und

2. X ′ schwach Modell-aquivalent mit X ist.

2 Logische Grundlagen 2-34

Programmierkurs PROLOG Sommersemester

2.5.4 Konjunktive Normalform

Definition 14

1. L heiße Literal

=def L ∈ AUSD und L ist ein atomarer oder ein negierter

atomarer Ausdruck.

2. Eine konjunktive Normalform ist eine Konjunktion aus

Alternativen, die ihrerseits aus Literalen bestehen.

2 Logische Grundlagen 2-35

Programmierkurs PROLOG Sommersemester

Lemma 10

Zu jeder Menge X ⊆ AUSD von quantorenfreien Ausdrucken

kann X ′ ⊆ AUSD konstruiert werden, so daß

1. alle Ausdrucke A′ ∈ X ′ konjunktive Normalformen sind

2. und X ′ semantisch aquivalent mit X ist.

Theorem 11

Zu jedem X ⊆ AUSD kann ein X ′ konstruiert werden, so daß

1. alle Ausdrucke aus X ′ Alternativen von Literalen sind und

2. X ′ schwach Modell-aquivalent mit X ist.

2 Logische Grundlagen 2-36

Beispiel

¬(∃X p(X,Y) ∨ ∀Z q(Z)) ≡ ∀X∃Z¬(p(X,Y) ∨ q(Z))∼= ∀Y∀X∃Z¬(p(X,Y) ∨ q(Z))

u ∀Y∀X¬(p(X,Y) ∨ q(g(Y,X)))∼= ¬(p(X,Y) ∨ q(g(Y,X)))≡ ¬p(X,Y) ∧ ¬q(g(Y,X))≡ {¬p(X,Y),¬q(g(Y,X))}

2-36-1

Programmierkurs PROLOG Sommersemester

2.5.5 Klausellogik

Menge von Alternativen von Literalen

=⇒ Menge von Mengen von Literalen

{¬p(X) ∨ p(f(X, Y)),¬q(Y) ∨ p(f(X, Y))}

=⇒{{¬p(X), p(f(X, Y))} , {¬q(Y), p(f(X, Y))}

}

2 Logische Grundlagen 2-37

Programmierkurs PROLOG Sommersemester

• Klausel: Menge von Literalen(Semantik wie bei Alternative).

• Sei X eine Menge von Alternativen von Literalen.

KLM(X): Die X zugeordnete Klauselmenge.

• 2 =def ?: Die leere Klausel (ist niemals erfullt).

2 Logische Grundlagen 2-38

Programmierkurs PROLOG Sommersemester

2.5.6 Grundresolution

Definition 15

T ist ein Grundterm =def T enthalt keine Individuenvariablen.

Menge aller Grundterme: GTERM.

2 Logische Grundlagen 2-39

Programmierkurs PROLOG Sommersemester

Definition 16 (Herbrand-Menge)

Sei A ein quantorenfreier Ausdruck, der genau die Variablen

V1, . . . , Vn enthalt.

H(A) =def

{A[V1, . . . , Vn/T1, . . . , Tn

]Ti ∈ GTERM

}H(X) =def

⋃A∈X

H(A)

2 Logische Grundlagen 2-40

Programmierkurs PROLOG Sommersemester

Grundresolution: Anwenden der Schlußregel

Aus K ′ ∪ {A}und K ′′ ∪ {¬A}

wird abgeleitet K ′ ∪K ′′

Grundresolutionsbeweis aus Grundklauselmenge KLM:

Sammeln aller Klauseln, die sich aus KLM und darausableitbaren Klauseln (induktive Definition) ableiten lassen.

2 Logische Grundlagen 2-41

Programmierkurs PROLOG Sommersemester

Definition 17

Sei KLM eine Menge von Grundklauseln.

KLM GR|−−− K=def K ∈ KLM oder

es gibt einen Grundresolutionsbeweis fur K aus KLM

Sei X eine Menge von Alternativen von Literalen.

Theorem 12

X hat kein Modell genau dann, wenn KLM(H(X)) GR|−−− 2.

2 Logische Grundlagen 2-42

Beispiel

KLM =�

{p(f(g(a)))} , {¬p(f(g(a))), q(f(g(a)))} , {¬q(f(g(a)))}

{p(f(g(a)))} {¬p(f(g(a))), q(f(g(a)))} {¬q(f(g(a)))}

{q(f(g(a)))}

2

2-42-1

Programmierkurs PROLOG Sommersemester

Definition 18 (Grundresolutionskalkul)

Sei X j AUSD, A ∈ AUSD und X ′ eine Menge von

Alternativen von Literalen, so daß

X ′ u X ∪ {¬A}.

Dann sei

X G|−− A =def KLM(H(X ′))

GR|−−− 2.

Theorem 13 (Korrektheit und Vollstandigkeit)

Sei X j AUSD und A ∈ AUSD. Dann gilt

X |−|− A g.d.w. X G|−− A.

2 Logische Grundlagen 2-43

Beispiel

KLM ={{p(U)} , {¬p(f(V)), q(U)} , {¬q(f(g(W)))}

}

2-43-1

Programmierkurs PROLOG Sommersemester

2.5.7 Pradikatenlogische Resolution

Idee (Robinson, 1965): Substitutionen nach Bedarf ausfuhren.Definition 19 (Substitution)

Eine Abbildung

sub : VAR→ TERM

nennen wir Substitution.

Sei Z ein Term oder Ausdruck.

Z sub: ersetze in Z alle Variablen V simultan durch sub(V ).

Notation sub =[V /T

]: sub(V ) = T , W 6= V ⇒ sub(W ) = W .

2 Logische Grundlagen 2-44

Programmierkurs PROLOG Sommersemester

sub1 ◦ sub2: Hintereinanderausfuhrung.

Sei M eine Menge von Termen oder Ausdrucken.(Anwendung M sub elementweise definiert)

Definition 20 (Unifikator)

1. sub heiße Unifikator fur M =def M sub ist einelementig.

2. sub heiße allgemeinster Unifikator fur M

=def sub ist Unifikator fur M und fur jeden Unifikator sub′

von M existiert sub′′, so daß

sub′ = sub ◦ sub′′ .

2 Logische Grundlagen 2-45

Programmierkurs PROLOG Sommersemester

Theorem 14 (Unifikationstheorem)

Hat die Menge M von Literalen einen Unifikator, so hat M

auch einen allgemeinsten Unifikator.

2 Logische Grundlagen 2-46

Programmierkurs PROLOG Sommersemester

Unifikationsalgorithmus

EINGABE: Eine nicht-leere endliche Menge M von Literalen.

sub := die identische Substitution.

WHILE card(M sub) > 1 DO

BEGIN Wahle L1, L2 ∈M subsowie die erste Stelle, wo sich L1 und L2 unterscheiden.

IF keines der Symbole an dieser Stelle ist eine VariableTHEN stop ”nicht unifizierbar“

2 Logische Grundlagen 2-47

Programmierkurs PROLOG Sommersemester

ELSE

BEGIN

Sei V die Variable und T der Term an dieser Stelle.

IF V kommt in T vorTHEN stop ”nicht unifizierbar“ELSE sub := sub ◦

[V /T

]END;

END;

Gib sub aus.

2 Logische Grundlagen 2-48

Beispiel

M1 ={{p(U)} , {p(f(V))}

}M2 =

{{p(U)} , {p(f(U))}

}

2-48-1

Programmierkurs PROLOG Sommersemester

Theorem 15

Der Unifikationsalgorithmus terminiert fur jedes M und

1. gibt”nicht unifizierbar“ aus

g.d.w. M nicht unifizierbar ist

2. gibt einen allgemeinsten Unifikator sub fur M aus

g.d.w. M unifizierbar ist

2 Logische Grundlagen 2-49

Programmierkurs PROLOG Sommersemester

Pradikatenlogische Resolutionsregel

Sei A ein atomarer Ausdruck. A =def ¬A und ¬A =def A.

Aus K ′ ∪ {L1, . . . , Ln}und K ′′ ∪ {L′1, . . . , L′m}

wird abgeleitet(K ′ ∪K ′′

)sub

wobei sub allg. Unifikator von{L1, . . . , Ln, L′1, . . . , L

′m

}ist.

Pradikatenlogischer Resolutionsbeweis aus Klauselmenge

KLM: Wie bei Grundresolution.

2 Logische Grundlagen 2-50

Programmierkurs PROLOG Sommersemester

Definition 21

Sei KLM eine Menge von Klauseln.

KLM PR|−−− K=def K ∈ KLM oder

ex. ein pradikatenlog. Resolutionsbeweis fur K aus KLM

Sei X eine Menge von Alternativen von Literalen.

Theorem 16

X hat kein Modell genau dann, wenn KLM(X) PR|−−− 2.

2 Logische Grundlagen 2-51

Beispiel

KLM ={{p(U)} , {¬p(f(V)), q(U)} , {¬q(f(g(W)))}

}

{p(U)} {¬p(f(V)), q(U)} {¬q(f(g(W)))}

sub =[U/f(V)

]{q(f(V))}

sub =[V/g(W)

]2

2-51-1

Programmierkurs PROLOG Sommersemester

Definition 22 (Pradikatenlogischer Resolutionskalkul)

Sei X j AUSD, A ∈ AUSD und X ′ eine Menge von

Alternativen von Literalen, so daß

X ′ u X ∪ {¬A}.

Dann sei

X |− A =def KLM(X ′)

PR|−−− 2.

Theorem 17 (Korrektheit und Vollstandigkeit)

Sei X j AUSD und A ∈ AUSD. Dann gilt

X |−|− A g.d.w. X |− A.

2 Logische Grundlagen 2-52

Programmierkurs PROLOG Sommersemester

2.6 Entscheidbarkeitsfragen

Theorem 18

Ist X rekursiv aufzahlbar, so ist auch Cons(X) rekursiv

aufzahlbar.

Theorem 19 (Unentscheidbarkeit; Satz von Church)

Gibt es mindestens ein nullstelliges Funktionssymbol, zwei

einstellige Funktionssymbole und ein zweistelliges

Pradikatensymbol, so ist fur die Sprache AUSD die

Allgemeingultigkeit unentscheidbar.

2 Logische Grundlagen 2-53

Programmierkurs PROLOG Sommersemester

2.7 Logisches Programmieren

Idee (Kowalski, 1970): Durch spezielle Klauselnotation undfestgelegte Resolutionsstrategie Logik zum Programmierennutzen.

2.7.1 Horn-Klauseln

Definition 23

Eine Klausel K heiße Horn-Klausel

=def K enthalt hochstens ein positives Literal.

2 Logische Grundlagen 2-54

Programmierkurs PROLOG Sommersemester

Was konnen Horn-Klauseln? Wir unterscheiden drei Falle:

Fakten (oder Tatsachenklauseln):

K besteht aus genau einem positiven Literal, z. B.

K = {gruen(gras)}

2 Logische Grundlagen 2-55

Programmierkurs PROLOG Sommersemester

Regeln (oder Prozedurklauseln):

K enthalt ein positives und mindestens ein negativesLiteral, z. B.

K = {¬mensch(X), sterblich(X)}≡ mensch(X)→ sterblich(X)

oder

K = {¬teilt(2,X),¬teilt(3,X), teilt(6,X)}≡ teilt(2,X) ∧ teilt(3,X)→ teilt(6,X)

2 Logische Grundlagen 2-56

Programmierkurs PROLOG Sommersemester

Anfragen (oder Zielklauseln):

K enthalt nur negative Literale, z. B.

K = {¬prim(X),¬gerade(X)} ≡ ¬ (prim(X) ∧ gerade(X))

Achtung:

∀X (¬prim(X) ∨ ¬gerade(X)) ≡ ¬∃X (prim(X) ∧ gerade(X))

2 Logische Grundlagen 2-57

Programmierkurs PROLOG Sommersemester

Beispiel SeiX =

{∀V (mensch(V)→ sterblich(V)) , mensch(sokrates)

}.

Dann gilt

X |−|− ∃V sterblich(V)

g.d.w. {¬mensch(V), sterblich(V)},{mensch(sokrates)},{¬sterblich(V)}

PR|−−− 2

2 Logische Grundlagen 2-58

Programmierkurs PROLOG Sommersemester

Was konnen Horn-Klauseln nicht?

Alternativen als Konklusion

elternteil(X,Y)→ vater(X,Y) ∨ mutter(X,Y)≡ {¬elternteil(X,Y), vater(X,Y), mutter(X,Y)}

Negationen

teil(X,Y) ∧ ¬teil(Y,X)→ echter teil(X,Y)

≡ {¬teil(X,Y), teil(Y,X), echter teil(X,Y)}

2 Logische Grundlagen 2-59

Programmierkurs PROLOG Sommersemester

2.7.2 Logik-Programme

Notation:

Fakten

Beispiel dargestellt als

{mensch(sokrates)} mensch(sokrates).

2 Logische Grundlagen 2-60

Programmierkurs PROLOG Sommersemester

Regeln

Beispiel

{¬teilt(2,X),¬teilt(3,X), teilt(6,X)}

dargestellt als

teilt(6,X)← teilt(2,X), teilt(3,X).

Ziele

Beispiel dargestellt als

{¬prim(X),¬gerade(X)} ?- prim(X), gerade(X).

2 Logische Grundlagen 2-61

Programmierkurs PROLOG Sommersemester

Definition 24 (Logik-Programm)

1. Eine Klausel K heiße definit (oder Programm-Klausel)

=def K enthalt genau ein positives Literal.

Das positive Literal heißt Kopf von K,

die Menge der negativen heißt Rumpf.

2. KLM heiße Logik-Programm

=def KLM ist eine Menge von definiten Klauseln.

2 Logische Grundlagen 2-62

Programmierkurs PROLOG Sommersemester

2.7.3 SLD-Resolution

”linear resolution with selection function for definite clauses“

Wir definieren eine Resolutionsstrategie SLD(P,Z), die fur einLogik-Programm P und eine Zielklausel Z bestimmt, ob sichaus P ∪ {Z} die leere Klausel ableiten laßt.

Wir nehmen an, daß sowohl P als auch Z geordnet sind.

Auf diese Weise wird das Ausfuhrungsmodell einesLogikprogramms eindeutig festgelegt.

2 Logische Grundlagen 2-63

Programmierkurs PROLOG Sommersemester

Festlegung: Resolvent von Z und ProgrammklauselK wird immer bzgl. der beiden ersten Literale gebildet.

Die ‘restlichen’ Literale von K werden vorne an Z angehangt.

RECURSIVE FUNCTION SLD(P,Z).

EINGABE: Logikprogramm P , Zielklausel Z.

IF Z ist leerTHEN RETURN true

ELSE

BEGIN

L := Erstes Literal in Z.

2 Logische Grundlagen 2-64

Programmierkurs PROLOG Sommersemester

LOOP

K := nachste Klausel in P , deren Kopf mit L unifizierb.

IF ein K konnte gefunden werdenTHEN

BEGIN

Z ′ := Resolvent von K und Z.IF SLD(P,Z ′) THEN RETURN true

END;

ELSE RETURN false

ENDLOOP

END

2 Logische Grundlagen 2-65

Beispiel

P = sterblich(V)← mensch(V).mensch(sokrates).

Z = ?- sterblich(V).

1. Aufruf von SLD

L := ¬sterblich(V)K := sterblich(V)← mensch(V).

Z ′ := ?- mensch(V).

2-65-1

2. Aufruf von SLD

L := ¬mensch(V)K := mensch(sokrates).

Z ′ := 2.

3. Aufruf von SLD ; Ruckgabe true.

2-65-2

Programmierkurs PROLOG Sommersemester

2.7.4 Antworterzeugung

Problem: SLD(P,Z) gibt nur true oder false zuruck.

Fur Variablen in der Anfrage hatten wir aber gern eineerfullende Belegung.

Losung: Fur jede in Z vorkommente Variable V fugen wir Zein Literal ¬antw("V ",V ) hinzu, das bei der SLD-Resolutionignoriert wird. Die erfullende Belegung wird automatischwahrend der Resolution fur V substituiert. Am Ende werdendie Antwortliterale aus Z geeignet ausgegeben.

2 Logische Grundlagen 2-66

Beispiel

P = sterblich(V)← mensch(V).mensch(sokrates).

Z = ?- sterblich(V), antw("V",V).

1. Aufruf von SLD

L := ¬sterblich(V)K := sterblich(V)← mensch(V).

Z ′ := ?- mensch(V), antw("V",V).

2-66-1

2. Aufruf von SLD

L := ¬mensch(V)K := mensch(sokrates).

Z ′ := ?- antw("V",sokrates).

3. Aufruf von SLD ; Ruckgabe ”V = sokrates“.

2-66-2

Programmierkurs PROLOG Sommersemester

2.7.5 Abwandlungen der Resolutionsstrategie

Alle Beweise: SLD stoppt, sobald ein Beweis erzeugt wurde.

Was, wenn wir alle erfullenden Belegungen erzeugen wollen?

; Backtracking

2 Logische Grundlagen 2-67

Programmierkurs PROLOG Sommersemester

RECURSIVE FUNCTION SLD(P,Z).

EINGABE: Logikprogramm P , Zielklausel Z.

IF Z besteht allein aus AntwortliteralenTHEN Gib Antworten in Z aus.ELSE

BEGIN

L := Erstes Literal in Z.

2 Logische Grundlagen 2-68

Programmierkurs PROLOG Sommersemester

LOOP

K := nachste Klausel in P , deren Kopf mit L unifizierb.

IF ein K konnte gefunden werdenTHEN

BEGIN

Z ′ := Resolvent von K und Z.SLD(P,Z ′)

END;

ELSE STOP ”no“

ENDLOOP

END

2 Logische Grundlagen 2-69

Programmierkurs PROLOG Sommersemester

Tiefen- vs. Breitensuche

SLD ist nicht vollstandig fur die Klasse der Hornklauseln.

Problem: Moglichkeit von Endlosschleifen.

Losung: Breitensuche— Literale aus K werden hinten an L angehangt.

Vollstandig fur die Klasse der Hornklauseln, aber mehrRechenaufwand; als Programmiersprache ungeeignet.

2 Logische Grundlagen 2-70

Beispiel

P = (1) p(V)← p(V).(2) p(ende).

Z = ?- p(V).

2-70-1

Programmierkurs PROLOG Sommersemester

2.8 Zusammenfassung und Beispiel

Wir wollen folgende Situation formalisieren:

”Der Dorfbarbier rasiert alle, die sich nicht selbst rasieren.“

Frage: Wer rasiert den Dorfbarbier?

Wir wollen zeigen: Die Situation ist widerspruchlich, d. h. einsolcher Dorfbarbier kann nicht existieren.

2 Logische Grundlagen 2-71

Programmierkurs PROLOG Sommersemester

2.8.1 Formalisierung

1. ”Der Dorfbarbier rasiert alle, die sich nicht selbst rasieren.“

∀B(ba(B)→∀P (¬ra(P,P)↔ ra(B,P))

)2. ”Es gibt keinen Dorfbarbier.“

¬∃B ba(B)

2 Logische Grundlagen 2-72

Programmierkurs PROLOG Sommersemester

2.8.2 Anwendung des Widerlegungssystems

{∀B(ba(B)→∀P (¬ra(P,P)↔ ra(B,P))

)} |−|− ¬∃B ba(B)

g.d.w.

{∀B(ba(B)→∀P (¬ra(P,P)↔ ra(B,P))

), ∃B ba(B)}

hat kein Modell.

2 Logische Grundlagen 2-73

Programmierkurs PROLOG Sommersemester

2.8.3 Umwandlung in Klauselform

{∀B(ba(B)→∀P (¬ra(P,P)↔ ra(B,P))

), ∃B ba(B)}

(⇒ pranexe Normalform)

≡ {∀B∀P(ba(B)→ (¬ra(P,P)↔ ra(B,P))

), ∃B ba(B)}

(⇒ Skolemisierung)

≡{(

ba(B)→ (¬ra(P,P)↔ ra(B,P))), ba(klaus)

}

2 Logische Grundlagen 2-74

Programmierkurs PROLOG Sommersemester

(⇒ konjunktive Normalform)

(ba(B)→ (¬ra(P,P)→ ra(B,P)) ∧ (¬ra(P,P)← ra(B,P))

),

ba(klaus)

(¬ba(B) ∨ (ra(P,P) ∨ ra(B,P)) ∧ (¬ra(P,P) ∨ ¬ra(B,P))

),

ba(klaus)

(¬ba(B) ∨ ra(P,P) ∨ ra(B,P))

∧ (¬ba(B) ∨ ¬ra(P,P) ∨ ¬ra(B,P)) ,

ba(klaus)

2 Logische Grundlagen 2-75

Programmierkurs PROLOG Sommersemester

¬ba(B) ∨ ra(P,P) ∨ ra(B,P),¬ba(B) ∨ ¬ra(P,P) ∨ ¬ra(B,P),ba(klaus)

(⇒ Klauselform)

{¬ba(B), ra(P,P), ra(B,P)},{¬ba(B),¬ra(P,P),¬ra(B,P)},{ba(klaus)}

2 Logische Grundlagen 2-76

Programmierkurs PROLOG Sommersemester

2.8.4 Anwendung der Resolution

{¬ba(B), ra(P,P), ra(B,P)} {ba(klaus)} {¬ba(B),¬ra(P,P),¬ra(B,P)}

sub =

h

B/klaus

i

{ra(P,P), ra(klaus,P)} {¬ra(P,P),¬ra(klaus,P)}

sub =h

P/klaus

i2

2 Logische Grundlagen 2-77

Programmierkurs PROLOG Sommersemester

2.9 Das Wichtigste in Kurze

1. Semantik: Ein Ziel zu beweisen, bedeutet zu beweisen,daß es aus dem Programm folgt.

2. Programmklauseln sind allquantifiziert,Zielklauseln existenzquantifiziert.

3. p, q bedeutet ”p und q“.

4. Die Negation kommt nicht mehr vor.

2 Logische Grundlagen 2-78

Programmierkurs PROLOG Sommersemester

5. Der Geltungsbereich einer Variablenist die Klausel, in der sie vorkommt.

6. Die Resolutionsstrategie verwendet Tiefensuche.

7. Ziel und Programmklauselkopf werden unifiziert.

2 Logische Grundlagen 2-79

Programmierkurs PROLOG Sommersemester

Programmieren in PROLOG umfaßt

1. Deklarieren von Fakten

2. Definieren von Regeln

}Programm

3. Stellen von Anfragen.

3 Erste Schritte 3-1

Programmierkurs PROLOG Sommersemester

3.1 Fakten

Schreibweise:

mag(klaus, sabine).

Pradikat Konstante Argumente

Pradikate und Konstanten beginnen mit einemKleinbuchstaben.

Fakten deklarieren Eigenschaften vonoder Relationen zwischen Objekten.

3 Erste Schritte 3-2

Programmierkurs PROLOG Sommersemester

Beispiel

wertvoll(gold).

weiblich(heike).

vater(klaus,heike).

bruder von(lukas,heike).

Die Bedeutung von Pradikaten und ihren Argumenten muß zuAnfang festgelegt und dann konsequent durchgehalten werden.

3 Erste Schritte 3-3

Programmierkurs PROLOG Sommersemester

Beispiel Zweistellige Pradikate werden infix verstanden:

bruder von(lukas,heike) ; lukas bruder von heike.

Die Gesamtheit aller Fakten (und Regeln) nennen wirDatenbasis oder logisches Programm.

3 Erste Schritte 3-4

Programmierkurs PROLOG Sommersemester

3.2 Anfragen (oder Ziele)

Schreibweise:

?- wertvoll(gold).

Anfragen bewirken eine Suche in der Datenbasis(Beweis des Ziels aus dem logischen Programm).

3 Erste Schritte 3-5

Programmierkurs PROLOG Sommersemester

Beispiel

weiblich(heike). maennlich(klaus).

vater(klaus,heike). bruder von(lukas,heike).

?- maennlich(klaus).

yes.

?- bruder von(lukas,heike).

yes.

?- maennlich(lukas).

no (more) solution.

3 Erste Schritte 3-6

Programmierkurs PROLOG Sommersemester

Anfragen sind nicht Teil des Programms, sondernwerden vom Benutzer an das System gestellt und von diesembeantwortet.

3.3 Variablen

Variablen beginnen mit einem Großbuchstaben oder einemUnterstrich.

?- maennlich(Mann).

Variablen konnen mit einem Wert instantiiert werden.

3 Erste Schritte 3-7

Programmierkurs PROLOG Sommersemester

3.3.1 Anfragen mit Variablen

Beim Versuch, ein Ziel zu beweisen, wird das Ziel mitvorhandenen Fakten gematcht (unifiziert).

Beim matching durfen Variablen beliebig instantiiert werden,alles nicht-variable muß exakt ubereinstimmen.

In Anfragen sind Variablen existenzquantifiziert.

Antworten auf eine Anfrage sind erfullende Belegungensamtlicher Variablen.

3 Erste Schritte 3-8

Programmierkurs PROLOG Sommersemester

Beispiel

maennlich(thomas). maennlich(klaus).

weiblich(heike). weiblich(ingrid).

?- maennlich(Mann).

Mann = thomas More? (;)

Mann = klaus

yes.

3 Erste Schritte 3-9

Programmierkurs PROLOG Sommersemester

3.3.2 Variablen in Fakten

Auch Fakten durfen Variablen enthalten. Eine solche Variablematcht alles, was in einem Ziel an dieser Argumentstelle steht.

Eine mehrfach vorkommende Variable muß an allen Stellen mitdem gleichen Wert instantiiert werden.

In Fakten sind Variablen allquantifiziert.

3 Erste Schritte 3-10

Programmierkurs PROLOG Sommersemester

Beispiel

teilt(1,X).

teilt(X,X).

?- teilt(X,2).

X = 1 More? (;)

X = 2

yes.

3 Erste Schritte 3-11

Programmierkurs PROLOG Sommersemester

3.4 Suchstrategie

Fur jedes Ziel wird die Datenbasis von vorn nach dem erstenFakt durchsucht, das das Ziel matcht (Variablen matchen alles).

Die Fundstelle wird markiert (choice point), die Variablen imZiel (oder Fakt) werden instantiiert.

Es wird eine Antwort ausgegeben.

Wird eine weitere Losung angefordert, wird die Instantiierungzuruckgenommen und ab der markierten Stelle weitergesucht(Wiedererfullung, REDO).

3 Erste Schritte 3-12

Programmierkurs PROLOG Sommersemester

3.5 Konjunktionen

?- mag(klaus, X), mag(heike, X).

”,“ wird als und gelesen.

Der Gultigkeitsbereich von Variablen ist die gesamteKonjunktion ; X steht fur ”alles, was Klaus und Heike mogen“.

3 Erste Schritte 3-13

Programmierkurs PROLOG Sommersemester

Erweiterte Suchstrategie

Variableninstantiierungen bleiben so lange fest, bis siezuruckgenommen werden.

Ist fur eine gegebene Variableninstantiierung ein Teilziel nichterfullbar, so schlagt dieses fehl (fail), und es wird versucht, dasvorherige Teilziel (choice point) wiederzuerfullen (REDO).

; Backtracking

Dabei werden evtl. Instantiierungen zuruckgenommen.

3 Erste Schritte 3-14

Beispiel

?- mag(klaus, X) , mag(heike, X).

kino

mag(klaus, kino).mag(klaus, tanzen).mag(heike, tanzen).mag(heike, fussball).

[X/kino

]

3-14-1

Programmierkurs PROLOG Sommersemester

3.6 Regeln

bruder(X,Y) :- maennlich(X),

eltern(X,E1,E2), eltern(Y,E1,E2).

”:-“ wird als wenn gelesen.

Der Teil vor dem :- heißt Kopf,der Teil hinter dem :- heißt Rumpf der Regel.

Der Gultigkeitsbereich von Variablen ist die gesamte Regel.

Die Gesamtheit aller Fakten und Regeln fur ein Pradikatnennen wir die Klauseln fur dieses Pradikat.

3 Erste Schritte 3-15

Programmierkurs PROLOG Sommersemester

Erweiterte Suchstrategie

Bei der Suche werden nicht nur Fakten, sondern auchRegelkopfe berucksichtigt.

Um eine Regel zu erfullen, mussen zuerst samtliche Ziele ausdem Rumpf erfullt werden — Variableninstantiierung beachten!

3 Erste Schritte 3-16

?- bruder(X,heike) .

bruder(X,Y) :- maennlich(X),eltern(X,E1,E2),eltern(Y,E1,E2).

eltern(lukas,klaus,ingrid).eltern(heike,klaus,ingrid).weiblich(ingrid).weiblich(heike).maennlich(klaus).maennlich(lukas).

3-16-1

?- bruder(X,heike) ,

• maennlich(X) ,•eltern(X,E1,E2),•eltern(Y,E1,E2).

klaus

heike

bruder(X,Y) :- maennlich(X),eltern(X,E1,E2),eltern(Y,E1,E2).

eltern(lukas,klaus,ingrid).eltern(heike,klaus,ingrid).weiblich(ingrid).weiblich(heike).maennlich(klaus).maennlich(lukas).

[Y/heike

]

[X/klaus

]

3-16-2

Programmierkurs PROLOG Sommersemester

3.7 Erste Schritte mit ECLiPSe

Programmstart

pkpro00@blei(/home/pkpro/pkpro00/Beispiele){36}: eclipse

ECLiPSe Constraint Logic Programming System [sepia mps standal

Version 3.6.1, Copyright ECRC GmbH and ICL/IC-Parc, Wed Aug 20

[eclipse 1]:

ECLiPSe wartet auf Anfragen.

3 Erste Schritte 3-17

Programmierkurs PROLOG Sommersemester

Hilfe

[eclipse 1]: help.

After the prompt [<module>]: ECLiPSe waits for a goal.

To type in clauses, call [user] or compile(user), and then

enter the clauses ended by ^D (EOF).

Call help(Pred/Arity) or help(Pred) or help(String)

to get help on a specific built-in predicate.

yes.

3 Erste Schritte 3-18

Programmierkurs PROLOG Sommersemester

[eclipse 5]: help(help).

----

help

Prints general help information on the current output.

----

help(+PredSpec)

Prints help information on the specified built-ins in PredS

current output.

----

helpdb

Print a list of all relations to the standard output.

----

helpdrel(+RelationName)

3 Erste Schritte 3-19

Programmierkurs PROLOG Sommersemester

Print some info on RelationName to the standard output.

----

helpkb

Print a list of all relations to the standard output.

----

helprel(+RelationName)

Print some info on RelationName to the standard output.

----

Call help(Name/Arity) for detailed help.

yes.

3 Erste Schritte 3-20

Programmierkurs PROLOG Sommersemester

Fakten und Regeln eingeben

[eclipse 19]: [user].

maennlich(karl).

weiblich(helga).

vater(X,Y) :- eltern(Y,X,_).

user compiled traceable 144 bytes in 0.00 seconds

yes.

Beenden mit C-d.

3 Erste Schritte 3-21

Programmierkurs PROLOG Sommersemester

Ein Programm laden

[eclipse 21]: [verwandtschaft].

verwandtschaft.pl compiled traceable 680 bytes in 0.00 seconds

yes.

3 Erste Schritte 3-22

Programmierkurs PROLOG Sommersemester

Anfragen stellen

[eclipse 22]: bruder(X,Y).

X = lukas

Y = lukas More? (;)

X = lukas

Y = heike More? (;)

no (more) solution.

Eine weitere Losung wird mit ; angefordert.

3 Erste Schritte 3-23

Programmierkurs PROLOG Sommersemester

ECLiPSe beenden

[eclipse 1]: halt.

bye

3 Erste Schritte 3-24

Programmierkurs PROLOG Sommersemester

ECLiPSe von emacs aus starten

3 Erste Schritte 3-25

Programmierkurs PROLOG Sommersemester

3.8 Das Wichtigste in Kurze

1. Fakten und Regeln werden in Programmdateien mit derEndung .pl gespeichert.

2. Diese werden geladen und dann Anfragen gestellt.

3. Um ein Ziel zu beweisen, wird ein matchendes Faktum odereine Regel mit matchendem Kopf gesucht.

4. Beim matching werden Variablen passend instantiiert.

5. Bei einem passenden Fakt ist ein Ziel sofort erfullt, beieiner Regel mussen zuerst noch die Ziele aus dem Rumpferfullt werden.

3 Erste Schritte 3-26

Programmierkurs PROLOG Sommersemester

6. Stehen fur die Erfullung eines Ziels mehrere Alternativenzur Verfugung, so wird ein choice point erzeugt.

7. Schlagt die Erfullung eines Ziels fehl, so wird am zuletzterzeugten choice point die nachste Alternative ausprobiert(Backtracking).

3 Erste Schritte 3-27

Programmierkurs PROLOG Sommersemester

4.1 Terme

PROLOG-Programme sind aus Termen aufgebaut. Wirunterscheiden drei Typen.

4.1.1 Konstanten

Zwei Arten von Konstanten:

Atome dienen als Bezeichner.

Beginnen normalerweise mit einem Kleinbuchstaben undenthalten Buchstaben, Ziffern oder .

4 Syntax 4-1

Programmierkurs PROLOG Sommersemester

Beispiele:

bruder heike helmut Kohl nummer5

Man kann beliebige Zeichenfolgen verwenden, wenn mandiese in Hochkommata einschließt:

’KeineVariable’ ’12’ ’rechts-links’

Auch beliebige Folgen der folgenden Zeichen sind Atome:

= + - * / \ ~ ^ < > : . ? @ # $ &

Beispiele:

= $$$ >= ==> ?- \-/

4 Syntax 4-2

Programmierkurs PROLOG Sommersemester

Zahlen Verschiedene Darstellungen sind zulassig:

1. Ganze Zahlen:

0 1 999 123456789 -17

2. Rationale Zahlen:

12 3(

= 123

)1 10

(= 1

10

)3. Fließkommazahlen:

1.2 -15.0 1.3e5 -17.7e-5.

4 Syntax 4-3

Programmierkurs PROLOG Sommersemester

4.1.2 Variablen

Beginnen mit einem Großbuchstaben oder und enthaltenBuchstaben, Ziffern oder .

X L Mensch V 23 intern

4 Syntax 4-4

Programmierkurs PROLOG Sommersemester

Sonderfall : anonyme Variable. Mehrere anonyme Variablen ineiner Klausel durfen verschieden instantiiert werden!

maennlich(X) :- eltern( ,X, ).

?- eltern(X, , ).

X = lukas More? (;)

X = heike

yes.

4 Syntax 4-5

Programmierkurs PROLOG Sommersemester

4.1.3 Strukturen

f(T1, . . . , Tn).

Funktor Term Argumente Aritat

Der Funktor ist ein Atom, die Argumente beliebige Terme(rekursive Definition).

Einen Funktor zusammen mit seiner Aritat schreiben wir f/n.Verschiedenstellige Funktoren gelten als verschieden!

4 Syntax 4-6

Programmierkurs PROLOG Sommersemester

f(a).

f(1,2).

?- f(X).

X = a

yes.

?- f(X,Y).

X = 1

Y = 2

yes.

4 Syntax 4-7

Programmierkurs PROLOG Sommersemester

Strukturen konnen beliebig verschachtelt werden:

besitzt(lukas,buch).

besitzt(lukas,buch(momo,ende)).

besitzt(lukas,buch(momo,autor(ende,michael))).

4 Syntax 4-8

Programmierkurs PROLOG Sommersemester

4.2 Operatoren

Ein- und zweistellige Funktoren konnen als Operatorendeklariert werden.

Dies ergibt eine bequemere Schreibweise fur Terme.

Achtung: Operatoren bewirken keine Berechnung, sondernlediglich eine andere Schreibweise fur Terme.

2+3 und 3+2 sind verschiedene Terme!

4 Syntax 4-9

Programmierkurs PROLOG Sommersemester

4.2.1 Position

Einstellige Operatoren konnen Prafix- oder Postfixoperatorensein. Beispiel:

-X ; -(X) X! ; !(X)

Zweistellige Operatoren sind immer Infixoperatoren.

X+1 ; +(X,1) X >= Y ; >=(X,Y)

4 Syntax 4-10

Programmierkurs PROLOG Sommersemester

4.2.2 Vorrang

Welcher Operator der außerste ist, ist durch dieVorrangregelung festgelegt.

4 * Y + X ; +(*(4,Y),X) X + 4 * Y ; +(X,*(4,Y))

4.2.3 Assoziativitat

Wie wird bei mehrfach aufeinanderfolgenden gleichenOperatoren geklammert?

4 + Y + X ; +(+(4,Y),X) X ^ 4 ^ Y ; ^(X,^(4,Y))

4 Syntax 4-11

Programmierkurs PROLOG Sommersemester

4.2.4 Operatoren definieren

Um einen neuen Operator zu deklarieren, muß man Position,Vorrang und Assoziativitat festlegen.

Der Vorrang wird durch eine Rangstufe festgelegt. Diese kannzwischen 1 und 1200 liegen (1 bindet am starksten).

4 Syntax 4-12

Programmierkurs PROLOG Sommersemester

Position und Assoziativitat werden durch eine Deklarationfestgelegt. Beispiel

xfy

Dies bezeichnet einen zweistelligen infix-Operator. x bedeutet,in dem Term an dieser Stelle durfen nur Operatoren mit echtkleinerer Rangstufe vorkommen. y bedeutet, in dem Term andieser Stelle durfen Operatoren mit kleinerer oder gleicherRangstufe vorkommen. ; dieser Operator ist rechtsassoziativ.

4 Syntax 4-13

Programmierkurs PROLOG Sommersemester

Alle Assoziativitatsklassen:

Klasse Position Assoziativitat Beispiel

fy prefix iterierbar not

fx prefix nicht iterierbar -

yf postfix iterierbar !

xf postfix nicht iterierbar

xfx infix nicht iterierbar :-

yfx infix linksassoziativ +

xfy infix rechtsassoziativ ^

4 Syntax 4-14

Programmierkurs PROLOG Sommersemester

Operatordefinition:

:- op(500,yfx,+).

im Programmtext (wird sofort ausgefuhrt) oder mit?- op(500,yfx,+). als Anfrage.

4 Syntax 4-15

Programmierkurs PROLOG Sommersemester

Beispiele:

:- op(1200, xfx, :-).

:- op(1200, fx, :-).

:- op(1000, xfy, ’,’).

:- op(700, xfx, =).

:- op(500, yfx, +).

:- op(500, yfx, -).

:- op(500, fx, -).

:- op(400, yfx, *).

:- op(200, xfy, ^).

4 Syntax 4-16

Programmierkurs PROLOG Sommersemester

4.3 Matching und Termvergleich

4.3.1 Matching von Termen

Wird bei der Suche nach einer fur ein Ziel passenden Klauselgebraucht.

4 Syntax 4-17

Programmierkurs PROLOG Sommersemester

Seien T1, T2 Terme.

Rekursive Definition fur ”matche T1 und T2“:

1. T1 uninstantiierte Variable V ; instantiiere V mit T2.

2. T2 uninstantiierte Variable W ; instantiiere W mit T1.

T1, T2 uninstantiierte Variablen V,W; identifiziere V und W .

3. Sind T1, T2 (instantiiert zu) Konstanten, so matchen T1, T2

genau dann, wenn sie identisch sind.

4. (Rekursion:) Sind T1, T2 Strukturen, so matche erst dieFunktoren und dann die Argumente (Stelle fur Stelle).

4 Syntax 4-18

Programmierkurs PROLOG Sommersemester

Ausgabe: ”Fehlschlag“ oder Terme T ′1, T′2, die (nach

Variableneinsetzung) identisch sind.

Achtung! Kein occur check,also sind ‘unendliche’ Terme moglich!

4 Syntax 4-19

Beispiel Matche mag(kuno,kino) mit X.

Matche lukas mit lukas.

Matche wasser mit seife.

Matche 1001 mit 1002.

Matche 1+2 mit 2+1.

Matche mag(kuno,kino) mit mag(X,kino).

Matche a(b,C,d(e,F,g(h,i,J)))mit a(B,c,d(E,f,g(H,i,j))).

Matche X + Y * 5 mit A * 7 + B.

Matche a(X, f(X), f(Y,Y)) mit a(g(A), B, f(h(B),C)).

4-19-1

Programmierkurs PROLOG Sommersemester

[eclipse 6]: a(X,f(X),f(Y,Y)) = a(g(A),B,f(h(B),C)),

write(a(X,f(X),f(Y,Y))),nl,write(a(g(A),B,f(h(B),C))).

a(g(A), f(g(A)), f(h(f(g(A))), h(f(g(A)))))

a(g(A), f(g(A)), f(h(f(g(A))), h(f(g(A)))))

X = g(A)

Y = h(f(g(A)))

A = A

B = f(g(A))

C = h(f(g(A)))

yes.

4 Syntax 4-20

Programmierkurs PROLOG Sommersemester

[eclipse 3]: X = f(X).

X = f(f(f(f(f(f(f(f(f(f(f(...)))))))))))

yes.

4 Syntax 4-21

Programmierkurs PROLOG Sommersemester

4.3.2 Vergleich von Termen

T1 = T2.

T1 und T2 matchen. Das Pradikat = konnte definiert sein als

X = X.

Schlagt T1 = T2 fehl, werden keine Variablen instantiiert.

T1 \= T2.

T1 und T2 matchen nicht.

Durch \= werden keine Variablen instantiiert.

4 Syntax 4-22

Programmierkurs PROLOG Sommersemester

T1 == T2.

T1 und T2 sind identisch.

Durch == werden keine Variablen instantiiert.

Beim Test == werden Variablen als verschieden gewertet, wennsie nicht bereits vorher identifiziert wurden.

== ist nicht mit der logischen Sichtweise auf Prolog vereinbar.

4 Syntax 4-23

Programmierkurs PROLOG Sommersemester

?- X == Y.

no (more) solution.

?- X == X.

X = X

yes.

?- f(X) == f(Y).

no (more) solution.

4 Syntax 4-24

Programmierkurs PROLOG Sommersemester

?- X = Y, f(X) == f(Y).

X = Y

Y = Y

yes.

T1 \== T2.

T1 und T2 sind nicht identisch.

Durch \== werden keine Variablen instantiiert.

4 Syntax 4-25

Programmierkurs PROLOG Sommersemester

T1 @< T2.

T1 @> T2.

T1 @=< T2.

T1 @>= T2.

Vergleich gemaß der Standardordnung fur (endliche) Terme.

Durch diese Tests werden keine Variablen instantiiert.

X -9 1 fie foe X = Y foe(0,2) fie(1,1,1)

sind der Standardordnung gemaß geordnet.

4 Syntax 4-26

Programmierkurs PROLOG Sommersemester

@<, @>, @=<, @>= sind syntaktische, keine arithmetischenOperatoren:

?- 1+3 @> 2+1.

no (more) solution.

compare(Op,T1,T2).

Op ist das Ergebnis der Vergleichs der Terme T1, T2 gemaß derStandardordnung. Mogliche Werte: <, >, =.

4 Syntax 4-27

Programmierkurs PROLOG Sommersemester

?- compare(Op,X,Y).

Op = >

X = X

Y = Y

yes.

?- compare(=,X,Y).

no (more) solution.

4 Syntax 4-28

Programmierkurs PROLOG Sommersemester

X = Y, compare(Op,X,Y).

Op = =

X = Y

Y = Y

yes.

4 Syntax 4-29

Programmierkurs PROLOG Sommersemester

X=f(A), Y=f(A), compare(Op,X,Y).

Op = =

X = f(A)

Y = f(A)

yes.

compare(Op,1+2,2+1).

Op = <

yes.

4 Syntax 4-30

Programmierkurs PROLOG Sommersemester

4.4 Programme

Ein Prolog-Programm ist eine Folge von Termen, jeweils gefolgtvon einem .

Kommentare werden mit % abgetrennt und reichen bis zumEnde der Zeile oder werden in /* . . . */ eingeschlossen.

Beispiel

% eltern(Kind,Vater,Mutter) setzt Kinder

% mit ihren Eltern in Relation.

eltern(/*Kind*/ lukas, /*Vater*/ klaus, /*Mutter*/ ingrid).

eltern(heike,klaus,ingrid).

4 Syntax 4-31

Programmierkurs PROLOG Sommersemester

4.5 Das Wichtigste in Kurze

1. Prologprogramme sind aus Termen aufgebaut.

2. Terme sind Konstanten (Atome, Zahlen), Variablen oderStrukturen, in denen Terme als Argumente eines Funktorsauftreten.

3. Erklart man einen ein- oder zweistelligen Funktor zumOperator, darf man ihn in Termen prefix, postfix oder infixverwenden.

4 Syntax 4-32

Programmierkurs PROLOG Sommersemester

4. Mit T1 = T2 wird festgestellt, ob T1 und T2 matchen.

5. Mit T1 == T2 wird festgestellt, ob T1 und T2 identisch sind.

6. Kommentare werden mit % abgetrennt oder in /* . . . */

eingeschlossen.

4 Syntax 4-33

Programmierkurs PROLOG Sommersemester

Gegeben ein Programm P und eine Folge Z von Zielen.

1. Wahle das nachste Ziel L (ist Z leer ; Antwort).

2. Wahle die nachste Klausel K im Programm, deren Kopfmit L matcht.

3. Wenn es noch eine weitere Klausel gibt, die in Fragekommt, erzeuge einen choice point.

4. Instantiiere Variablen, so daß der Kopf von K und L

matchen.

5. Hange den Rumpf von K vorn an Z an.

6. Beginne von vorn.

5 Ausfuhrungsmodell 5-1

Programmierkurs PROLOG Sommersemester

7. Schlagt die Suche fehl oder wird eine weitere Losungangefordert (redo), fahre am letzten choice point fort(Backtracking).

5 Ausfuhrungsmodell 5-2

Programmierkurs PROLOG Sommersemester

5.1 First Argument Indexing

Wann kommt eine Klausel ”in Frage“?

; betrachte den Funktor des ersten Arguments.

eltern(lukas, klaus, ingrid).

eltern(heike,klaus,ingrid).

?- eltern(lukas,V,M).

V = klaus

M = ingrid

yes.

5 Ausfuhrungsmodell 5-3

Programmierkurs PROLOG Sommersemester

eltern(sohn(lukas), vater(klaus), mutter(ingrid)).

eltern(sohn(klaus), vater(gustav), mutter(gertrud)).

?- eltern(sohn(lukas),V,M).

V = vater(klaus)

M = mutter(ingrid) More? (;)

no (more) solution.

5 Ausfuhrungsmodell 5-4

Programmierkurs PROLOG Sommersemester

eltern(lukas, klaus, ingrid).

eltern(klaus, gustav, gertrud).

?- eltern(K,V,ingrid).

S = lukas

V = klaus More? (;)

no (more) solution.

5 Ausfuhrungsmodell 5-5

Programmierkurs PROLOG Sommersemester

5.2 (nicht-)Determinismus

Ein Pradikat heißt deterministisch, wenn nach Erzeugen derersten Losung keine choice points zuruckbleiben.

5 Ausfuhrungsmodell 5-6

Programmierkurs PROLOG Sommersemester

Beispiel

t_min_1(T1,T2,T1) :- T1 @=< T2.

t_min_1(T1,T2,T2) :- T1 @> T2.

t_min_2(T1,T2,T3) :-

compare(Op,T1,T2),

t_min_next(Op,T1,T2,T3).

t_min_next(<,T1,_,T1).

t_min_next(=,T1,_,T1).

t_min_next(>,_,T2,T2).

5 Ausfuhrungsmodell 5-7

Programmierkurs PROLOG Sommersemester

?- t min 1(a,b,X).

X = a More? (;)

no (more) solution.

?- t min 2(a,b,X).

X = a

yes.

5 Ausfuhrungsmodell 5-8

Programmierkurs PROLOG Sommersemester

(nicht-)Determinismus kann vom mode abhangen, in dem einPradikat aufgerufen wird.

Jedes Argument hat einen argument mode:

+ Enthalt keine uninstantiierte Variable.

++ Grundterm

- Uninstantiierte Variable

Der mode eines Pradikats setzt sich aus den argument modeszusammen.

5 Ausfuhrungsmodell 5-9

Programmierkurs PROLOG Sommersemester

Man kann den mode eines Pradikats deklarieren (ist imHandbuch angegeben), dann gibt es noch die zusatzlicheDeklaration ? (egal).

Bis jetzt haben wir nur Pradikate kennengelernt, bei denen alleargument modes als ? deklariert sind.

Beispiel mutter(-,+) ist deterministisch, mutter(+,-) nicht.

5 Ausfuhrungsmodell 5-10

Programmierkurs PROLOG Sommersemester

5.3 Das Box-Modell

Erlaubt, die Ausfuhrung eines Pradikats zu verfolgen (trace).

Erzeuge fur jeden Aufruf eines Pradikats (Prozedur) eine Box.

Klauselnzu Z

CALL Z

FAIL

EXIT sub

REDO

5 Ausfuhrungsmodell 5-11

Programmierkurs PROLOG Sommersemester

Kontrollfluß betritt/verlaßt die Box uber Ports:

CALL Z Erster Aufruf mit Ziel Z.; Klauseln zu Z per first argument indexing.

EXIT sub Erfolgreich beendet ; Ruckgabe substitution.

Laßt evtl. choice points zuruck.

FAIL (endgultiger) Fehlschlag.; REDO des vorhergehenden Ziels.

REDO Bewirkt Sprung zum nachsten choice point (oder FAIL).

5 Ausfuhrungsmodell 5-12

Beispiel

weiblich(heike).

eltern(K,M,V) :- mutter(K,M), vater(K,V).

mutter(uwe,anke).mutter(thomas,anke).mutter(heike,anke).

vater(uwe,karl).vater(heike,holger).vater(thomas,holger).

5-12-1

?- weiblich(heike), eltern(heike,M,V), eltern(G,M,V).

5-12-2

Programmierkurs PROLOG Sommersemester

5.4 last call optimisation

Wenn zum Zeitpunkt des Aufrufs des letzten Teilziels einerKlausel keine choice points ubrig sind, wird dieses in der Boxder aufrufenden Klausel ausgefuhrt.

5 Ausfuhrungsmodell 5-13

Programmierkurs PROLOG Sommersemester

5.5 Das Wichtigste in Kurze

1. Um ein Ziel zu erfullen, wird nach passenden Klauselngesucht.

2. Ob eine Klausel paßt, wird mit first argument indexingermittelt.

3. Gibt es mehrere passende Klauseln, wird ein choice pointerzeugt.

4. Fuhrt die Ausfuhrung eines Pradikats nicht zur Erzeugungvon choice points, nennt man dieses deterministisch.

5 Ausfuhrungsmodell 5-14

Programmierkurs PROLOG Sommersemester

Problem: Mit den Vergleichsoperatoren in 4.3.2 kannman Zahlen vergleichen. Arithmetische Ausdrucke wie z. B. 1+2konnen nicht gemaß des von ihnen reprasentierten Zahlenwertsverglichen werden.

6 Arithmetik 6-1

Programmierkurs PROLOG Sommersemester

6.1 Arithmetische Ausdrucke

Induktive Definition: Ein arithmetischer Ausdruck ist

• eine Zahl oder

• eine Struktur, deren Funktor ein arithmetischer Operatorund deren Argumente arithmetische Ausdrucke sind oder

• eine Variable, die mit einen arithmetischen Ausdruckinstantiiert ist.

6 Arithmetik 6-2

Programmierkurs PROLOG Sommersemester

6.2 Arithmetische OperatorenBeispiele:Ausdruck steht fur

-A NegationA1 + A2 SummeA1 - A2 DifferenzA1 * A2 ProduktA1 / A2 DivisionA1 ^ A2 ExponenzierungA1 // A2 Integer-Anteil der Division (nur wenn A1, A2 ganz)A1 mod A2 Modulo (A1 und A2 mussen ganz sein)abs(A) Absolutwert

6 Arithmetik 6-3

Programmierkurs PROLOG Sommersemester

6.3 Auswertung eines arithmetischen Ausdrucks

is(?,+) X is Ausd

Ausd wird gemaß den Regeln der Arithmetik ausgewertet; dasErgebnis (Zahl) wird mit X gematcht.

6 Arithmetik 6-4

Programmierkurs PROLOG Sommersemester

6.4 Vergleich arithmetischer Ausdrucke

Argumente werden ausgewertet und die Ergebnisse verglichen.

Vergleich Relation

A1 =:= A2 Gleich

A1 =\= A2 Ungleich

A1 < A2 Kleiner

A1 > A2 Großer

A1 >= A2 Großer oder Gleich

A1 =< A2 Kleiner oder Gleich

6 Arithmetik 6-5

Programmierkurs PROLOG Sommersemester

6.5 Das Wichtigste in Kurze

1. Ein arithmetischer Ausdruck darf keine uninstantiiertenVariablen enthalten.

2. is(?,+) wertet einen arithmetischen Ausdruck aus undmatcht das Ergebnis mit einer Variablen.

3. =:=, =\=, <, >, >=, =< werten zwei arithmetische Ausdruckeaus und vergleichen die Ergebnisse.

6 Arithmetik 6-6

Programmierkurs PROLOG Sommersemester

Beispiel gcd(+I,+J,?G) berechnet den großten gemeinsamenTeiler von I und J und matcht das Ergebnis mit G.

IB: Ist J = 0, so soll G = I gelten.

gcd(I,0,I).

IS: Ist J > 0, berechne gcd(J, I mod J, G).

gcd(I,J,Gcd) :-

J > 0, K is I mod J, gcd(J,K,Gcd) .

Dank last call optimization ist gcd iterativ ! IH

7 Rekursion 7-1

Beispiel ?- gcd(16,12,G).

7-1-1

Programmierkurs PROLOG Sommersemester

Beispiel fact(+N,?F) berechnet die Fakultat dernaturlichen Zahl N und matcht das Ergebnis mit F.

IB: Ist N = 0, so soll F = 1 gelten.

fact(0,1).

IS: Ist N > 0, berechne fact(N-1, F’);es soll F is N * F’ gelten.

fact(N,F) :-

N > 0, N1 is N - 1, fact(N1,F1), F is N*F1.

fact ist nicht iterativ!

7 Rekursion 7-2

Beispiel ?- fact(5,F).

7-2-1

Programmierkurs PROLOG Sommersemester

7.1 Von Rekursion zu Iteration: AkkumulatorenBeispiel Hilfspradikat fact(+I,+N,+A,-F):

I wird von 0 bis N hochgezahlt und dabei A = I! akkumuliert.

• Um fact(N,F) zu beweisen, beweise fact(0,N,1,F).

fact(N,F) :- fact(0,N,1,F).

• Ist I = N, soll F = A gelten.

fact(N,N,F,F).

• Ist I < N, berechne fact(I+1,N,A*(I+1),F).

fact(I,N,A,F) :- I < N, I1 is I + 1,

A1 is A*I1, fact(I1,N,A1,F).

7 Rekursion 7-3

Programmierkurs PROLOG Sommersemester

Beispiel Hilfspradikat fact(+N,+A,-F):

N wird heruntergezahlt und dabei A = N ∗ (N− 1) ∗ . . .akkumuliert.

• Um fact(N,F) zu beweisen, beweise fact(N,1,F).

fact(N,F) :- fact(N,1,F).

• Ist N = 0, soll F = A gelten.

fact(0,F,F).

• Ist N > 0, berechne fact(N-1,A*N,F).

fact(N,A,F) :- N > 0, N1 is N -1, A1 is A*N,

fact(N1,A1,F).

7 Rekursion 7-4

Programmierkurs PROLOG Sommersemester

Beispiel between(+I,+J,?K) ist erfullt,wenn K zwischen I und K liegt (incl.).

• Wenn I ≤ J gilt, ist K = I eine Losung.

between(I,J,I) :- I =< J.

• Wenn I < J gilt, ist auch K mit between(I+1,J,K) eineLosung.

between(I,J,K) :-

I < J, I1 is I+1, between(I1,J,K)

7 Rekursion 7-5

Programmierkurs PROLOG Sommersemester

[eclipse 11]: between(4,7,N).

N = 4 More? (;)

N = 5 More? (;)

N = 6 More? (;)

N = 7 More? (;)

no (more) solution.

7 Rekursion 7-6

Programmierkurs PROLOG Sommersemester

7.2 Arithmetik ‘logisch’: Successor-Arithmetik

Eine rekursive Datenstruktur fur naturliche Zahlen

nat(?N) soll fur jede naturliche Zahl erfullt sein.

nat(0).

nat(s(N)) :- nat(N).

7 Rekursion 7-7

Programmierkurs PROLOG Sommersemester

Beispiel

[eclipse 8]: nat(X).

X = 0 More? (;)

X = s(0) More? (;)

X = s(s(0)) More? (;)

X = s(s(s(0))) More? (;)

X = s(s(s(s(0)))) More? (;)

7 Rekursion 7-8

Programmierkurs PROLOG Sommersemester

Vergleich

leq(?N1,?N2) soll erfullt sein, wenn N1 ≤ N2 gilt.

leq(0,N) :- nat(N). (minimales Element)

leq(s(N1),s(N2)) :- leq(N1,N2).

7 Rekursion 7-9

Programmierkurs PROLOG Sommersemester

Beispiel

[eclipse 16]: leq(N1,N2).

N1 = 0

N2 = 0 More? (;)

N1 = 0

N2 = s(0) More? (;)

N1 = 0

N2 = s(s(0)) More? (;)

7 Rekursion 7-10

Programmierkurs PROLOG Sommersemester

Addition

splus(?N1,?N2,?S) soll erfullt sein, wenn N1 + N2 = S.

splus(0,N,N) :- nat(N). (neutrales Element)

splus(s(N1),N2,s(S)) :- splus(N1,N2,S).

7 Rekursion 7-11

Programmierkurs PROLOG Sommersemester

Beispiel

[eclipse 12]: splus(X,Y,Z).

X = 0

Y = 0

Z = 0 More? (;)

X = 0

Y = s(0)

Z = s(0) More? (;)

7 Rekursion 7-12

Programmierkurs PROLOG Sommersemester

[eclipse 13]: splus(X,0,Z).

X = 0

Z = 0 More? (;)

X = s(0)

Z = s(0) More? (;)

X = s(s(0))

Z = s(s(0)) More? (;)

7 Rekursion 7-13

Programmierkurs PROLOG Sommersemester

Euklidischer Algorithmus

less(0,s(N)) :- nat(N).

less(s(N1),s(N2)) :- less(N1,N2).

smod(N1,N2,N1) :- less(N1,N2).

smod(N1,N2,N3) :- splus(N11,N2,N1), smod(N11,N2,N3).

sgcd(N,0,N) :- less(0,N).

sgcd(N1,N2,G) :- less(0,N2), smod(N1,N2,N3), sgcd(N2,N3,G

7 Rekursion 7-14

Programmierkurs PROLOG Sommersemester

Beispiel

[eclipse 9]: sgcd(s(s(s(s(s(s(s(s(s(0))))))))),

s(s(s(s(s(s(0)))))),

N).

N = s(s(s(0))) More? (;)

no (more) solution.

7 Rekursion 7-15

Programmierkurs PROLOG Sommersemester

[eclipse 14]: sgcd(N,s(s(s(s(s(s(0)))))),s(s(s(0)))).

N = s(s(s(0))) More? (;)

N = s(s(s(s(s(s(s(s(s(0))))))))) More? (;)

N = s(s(s(s(s(s(s(s(s(s(s(...))))))))))) More? (;)

7 Rekursion 7-16

Programmierkurs PROLOG Sommersemester

7.3 Das Wichtigste in Kurze

1. Ein rekursives Pradikat besitzt eine Regel, die einen Aufrufdesselben Pradikats als Teilziel enthalt.

2. Ein rekursives Pradikat ist immer induktiv aufgebaut:

• Die Induktionsbasis (Abbruchbedingung der Rekursion)ist ein ausreichend einfacher Fall, daß das Ziel ohnerekursiven Aufruf bewiesen werden kann.

• Im Induktionsschritt wird auf die Induktionshypothese(rekursiver Aufruf) zuruckgegriffen.

7 Rekursion 7-17

Programmierkurs PROLOG Sommersemester

3. Ein rekursives Pradikat kann einen iterativen Prozeßdefinieren, wenn alle rekursiven Aufrufe am Ende der jwlg.Regel stehen und zum Zeitpunkt des rekursiven Aufrufskeine choice points zuruckbleiben (last call optimization).

7 Rekursion 7-18

Programmierkurs PROLOG Sommersemester

Jede Struktur kann als Baum aufgefaßt werden.

buch(momo,autor(ende,michael))

buch

momo autor

ende michael

8 Strukturen, Baume 8-1

Programmierkurs PROLOG Sommersemester

Identische Variablen in Strukturen fuhren zu identischenKnoten.

f(X,g(X,a))

f

g

a

8 Strukturen, Baume 8-2

Programmierkurs PROLOG Sommersemester

8.1 Implizit definierte Baume

fahrzeit(hbf,6min).

fahrzeit(bochum,12min).

fahrzeit(essen,20min).

fahrzeit(duesseldorf,40min).

fahrzeit(koeln,70min).

8 Strukturen, Baume 8-3

Programmierkurs PROLOG Sommersemester

Man erhalt eine Baumstruktur durch Verwenden rekursivdefinierter Strukturen.

Gewunschte Baumdarstellung:

fahrzeit(essen,20min, , ).

fahrzeit(duesseldorf,40min, , ). fahrzeit(hbf,6min, , ).

fahrzeit(bochum,12min, , ). fahrzeit(koeln,70min, , ).

8 Strukturen, Baume 8-4

Programmierkurs PROLOG Sommersemester

Als Term:

fahrzeit(essen,20min,

fahrzeit(duesseldorf,40min,

fahrzeit(bochum,12min,_,_),

_

),

fahrzeit(hbf,6min,

_,

fahrzeit(koeln,70min,_,_)

)

).

8 Strukturen, Baume 8-5

Programmierkurs PROLOG Sommersemester

Implementierung der Baumsuche:

:- op(1,xf,min).

suche(Stadt,fahrzeit(Stadt,Zeit,_,_),Zeit).

suche(Stadt,fahrzeit(StadtZuGross,_,Links,_),Zeit) :-

Stadt @< StadtZuGross,

suche(Stadt,Links,Zeit).

suche(Stadt,fahrzeit(StadtZuKlein,_,_,Rechts),Zeit) :-

Stadt @> StadtZuKlein,

suche(Stadt,Rechts,Zeit).

8 Strukturen, Baume 8-6

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 48]: suche(essen,B,20min),

suche(duesseldorf,B,40min),

suche(bochum,B,12min),

suche(hbf,B,6min),

suche(koeln,B,70min).

8 Strukturen, Baume 8-7

Programmierkurs PROLOG Sommersemester

B = fahrzeit(essen, 20 min,

fahrzeit(duesseldorf, 40 min,

fahrzeit(bochum, 12 min, _126, _127

_119

),

fahrzeit(hbf, 6 min,

_132,

fahrzeit(koeln, 70 min, _138, _139)

)

)

More? (;) ;

8 Strukturen, Baume 8-8

Programmierkurs PROLOG Sommersemester

B = fahrzeit(essen, 20 min,

fahrzeit(duesseldorf, 40 min,

fahrzeit(bochum, 12 min, _126, _127

_119

),

fahrzeit(hbf, 6 min, _132,

fahrzeit(StadtZuKlein, _136,

_137,

fahrzeit(koeln, 70 min, _

)

)

)

8 Strukturen, Baume 8-9

Programmierkurs PROLOG Sommersemester

Alternative:

suche(Stadt,fahrzeit(Stadt,Zeit,_,_),Zeit).

suche(Stadt,fahrzeit(StadtZuGross,_,Links,_),Zeit) :-

nonvar(StadtZuGross),

Stadt @< StadtZuGross,

suche(Stadt,Links,Zeit).

suche(Stadt,fahrzeit(StadtZuKlein,_,_,Rechts),Zeit) :-

nonvar(StadtZuKlein),

Stadt @> StadtZuKlein,

suche(Stadt,Rechts,Zeit).

8 Strukturen, Baume 8-10

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 58]: suche(essen,B,20min),

suche(duesseldorf,B,40min),

suche(bochum,B,12min),

suche(hbf,B,6min),

suche(koeln,B,70min).

8 Strukturen, Baume 8-11

Programmierkurs PROLOG Sommersemester

B = fahrzeit(essen, 20 min,

fahrzeit(duesseldorf, 40 min,

fahrzeit(bochum, 12 min, _126, _127

_119),

fahrzeit(hbf, 6 min,

_132,

fahrzeit(koeln, 70 min, _138, _139)

)

)

More? (;) ;

no (more) solution.

8 Strukturen, Baume 8-12

Programmierkurs PROLOG Sommersemester

8.2 Explizit definierte Baume

bintree(void).

bintree(tree(Element,Left,Right)) :-

bintree(Left), bintree(Right).

Der Baum

a

b c

wird reprasentiert als

tree(a,tree(b,void,void),tree(c,void,void)).

8 Strukturen, Baume 8-13

Programmierkurs PROLOG Sommersemester

8.2.1 Suche in Baumen

bt_member(X,tree(X,_,_)).

bt_member(X,tree(_,Left,_)) :- bt_member(X,Left).

bt_member(X,tree(_,_,Right)) :- bt_member(X,Right).

8 Strukturen, Baume 8-14

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 54]: bt_member(a,T), bt_member(b,T),

bt_member(c,T), bintree(T).

T = tree(a,

tree(b,

tree(c, void, void),

void),

void)

More? (;) ;

8 Strukturen, Baume 8-15

Programmierkurs PROLOG Sommersemester

T = tree(a,

tree(b,

tree(c, void, void),

void),

tree(_107, void, void)

)

More? (;)

8 Strukturen, Baume 8-16

Programmierkurs PROLOG Sommersemester

Suche mit Schlusseln:

bt_search(X,tree(X,_,_)).

bt_search(K-D,tree(KLarge-_,Left,_)) :-

K @< KLarge,

bt_search(K-D,Left).

bt_search(K-D,tree(KSmall-_,_,Right)) :-

K @> KSmall,

bt_search(K-D,Right).

8 Strukturen, Baume 8-17

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 62]:

bt_search(essen-fahrzeit(essen,20min),T),

bt_search(duesseldorf-fahrzeit(duesseldorf,40min),T),

bt_search(bochum-fahrzeit(bochum,12min),T),

bt_search(hbf-fahrzeit(hbf,6min),T),

bt_search(koeln-fahrzeit(koeln,70min),T),

bintree(T).

8 Strukturen, Baume 8-18

Programmierkurs PROLOG Sommersemester

T = tree(essen - fahrzeit(essen, 20 min),

tree(duesseldorf - fahrzeit(duesseldorf, 40 min),

tree(bochum - fahrzeit(bochum, 12 min), void, vo

void

),

tree(hbf - fahrzeit(hbf, 6 min),

void,

tree(koeln - fahrzeit(koeln, 70 min), void, void

)

)

More? (;) ;

8 Strukturen, Baume 8-19

Programmierkurs PROLOG Sommersemester

T = tree(essen - fahrzeit(essen, 20 min),

tree(duesseldorf - fahrzeit(duesseldorf, 40 min),

tree(bochum - fahrzeit(bochum, 12 min), void, vo

void

),

tree(hbf - fahrzeit(hbf, 6 min),

void,

tree(koeln - fahrzeit(koeln, 70 min),

void,

tree(_171, void, void)

)

)

)

8 Strukturen, Baume 8-20

Programmierkurs PROLOG Sommersemester

8.2.2 Baume durchlaufen

Beispiel

bt_subst(_,_,void,void).

bt_subst(X,Y,tree(Elem,L,R),tree(SElem,SL,SR)) :-

repl(X,Y,Elem,SElem),

bt_subst(X,Y,L,SL),

bt_subst(X,Y,R,SR).

repl(X,Y,X,Y).

repl(X,_,Z,Z) :- X \= Z.

8 Strukturen, Baume 8-21

Programmierkurs PROLOG Sommersemester

[eclipse 81]: bt_subst(c,zeh,

tree(a,tree(b,void,void),tree(c,void,void)),T).

T = tree(a, tree(b, void, void), tree(zeh, void, void))

More? (;) ;

no (more) solution.

8 Strukturen, Baume 8-22

Programmierkurs PROLOG Sommersemester

Beispiel

bt_count(void,0).

bt_count(tree(_,L,R),N) :-

bt_count(L,NL),

bt_count(R,NR),

N is NL + NR + 1.

ist nicht iterativ!

8 Strukturen, Baume 8-23

Programmierkurs PROLOG Sommersemester

‘Iterativere’ Losung mit Akkumulator:

bt_count_it(T,N) :- bt_count(T,0,N).

bt_count(void,N,N).

bt_count(tree(_,L,R),A,N) :-

NA is A+1,

bt_count(L,NA,NL),

bt_count(R,NL,N).

8 Strukturen, Baume 8-24

Programmierkurs PROLOG Sommersemester

8.2.3 Partielle Strukturen

Eine Struktur, die freie Variablen enthalt, nennen wir partielleStruktur.

Die Variablen konnen jederzeit instantiiert werden; Flexibilitat beim Aufbau der Struktur.

Uninstantiierte Variablen konnen dupliziert werden; ‘merken’ von Lochern.

Beispiel

T = lochb(tree(a,tree(b, ,Loch),tree(c, , )),Loch),

Loch = tree(d, , ).

8 Strukturen, Baume 8-25

Programmierkurs PROLOG Sommersemester

8.3 Das Wichtigste in Kurze

1. Jede Struktur kann als Baum aufgefaßt werden.

2. Die Datenstruktur Baum kann implizit durch Verwendeneiner rekursiven Datenstruktur implementiert werden.

3. Man kann die Baumstruktur explizit machen durchVerwendung einer Struktur

tree(Knoten,LinkerTeilbaum,RechterTeilbaum)

4. Akkumulatoren konnen auch beim Baumdurchlaufengenutzt werden, um uberflussige Rekursion zu vermeiden.

8 Strukturen, Baume 8-26

Programmierkurs PROLOG Sommersemester

5. Partielle Strukturen konnen als Strukturen mit Lochernaufgefaßt werden, wobei man die Locher explizitreprasentieren kann.

8 Strukturen, Baume 8-27

Programmierkurs PROLOG Sommersemester

Induktive Definition: eine Liste ist

IB: die leere Liste [] oder

IS: eine Struktur .(K,L), wobei K (Kopf der Liste) einbeliebiger Term und L (Rumpf der Liste) wieder eine Listeist.

Baumnotation:

K L

9 Listen 9-1

Programmierkurs PROLOG Sommersemester

Alternative Notation:

.(K,L) [K|L]

.(T1,.(T2,.(T3,[]))) [T1,T2,T3]

9 Listen 9-2

Programmierkurs PROLOG Sommersemester

Baumdarstellung fur [T1,T2,T3]:

T1

T2

T3 []

Alternativ:

· · · []

T1 T2 T3

9 Listen 9-3

Programmierkurs PROLOG Sommersemester

Listen konnen verschachtelt werden:

[a,V1,b,[X,Y]]

· · · · []

a V1 b · · []

X Y

9 Listen 9-4

Programmierkurs PROLOG Sommersemester

Beispiel

p([1,2,3]).

p([1,2,3,[4,5,6]]).

[eclipse 16]: p([X|Y]).

X = 1

Y = [2, 3] More? (;)

X = 1

Y = [2, 3, [4, 5, 6]]

yes.

9 Listen 9-5

Programmierkurs PROLOG Sommersemester

[eclipse 17]: p([_,_,_,[_|X]]).

X = [5, 6]

yes.

9 Listen 9-6

Programmierkurs PROLOG Sommersemester

9.1 Suche nach Listenelementen

member(X, [X|_]).

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

Test:

[eclipse 20]: member(X,[1,2,3]).

X = 1 More? (;)

X = 2 More? (;)

X = 3 More? (;)

no (more) solution.

9 Listen 9-7

Programmierkurs PROLOG Sommersemester

9.2 Abbildungen auf Listen

map([], []).

map([K|R], [MK|MR]) :- m(K, MK), map(R,MR).

[eclipse 23]: [user].

m(X,Y) :- Y is X * 2.

user compiled traceable 104 bytes in 0.00 seconds

yes.

[eclipse 26]: map([1,2,3,4],L).

L = [2, 4, 6, 8]

yes.

9 Listen 9-8

Programmierkurs PROLOG Sommersemester

[eclipse 28]: [user].

m([],[]).

m([_|R],R).

user compiled traceable 196 bytes in 0.00 seconds

yes.

[eclipse 30]: map([[1,2,3],[4,5,6],[7,8,9]],L).

L = [[2, 3], [5, 6], [8, 9]]

yes.

[eclipse 31]: map(L,[[1,2,3],[4,5,6],[7,8,9]]).

L = [[_96, 1, 2, 3], [_102, 4, 5, 6], [_108, 7, 8, 9]]

yes.

9 Listen 9-9

Programmierkurs PROLOG Sommersemester

9.3 Listen aneinanderhangen

append([],L,L).

append([K|R1], L2, [K|R3]) :- append(R1,L2,R3).

9 Listen 9-10

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 33]: append(X,Y,[1,2,3]).

X = []

Y = [1, 2, 3] More? (;)

X = [1]

Y = [2, 3] More? (;)

X = [1, 2]

Y = [3] More? (;)

9 Listen 9-11

Programmierkurs PROLOG Sommersemester

X = [1, 2, 3]

Y = []

yes.

9 Listen 9-12

Programmierkurs PROLOG Sommersemester

Beispiel

bt_leaves(void,[]).

bt_leaves(tree(L,void,void),[L]).

bt_leaves(tree(_,Left,Right),L) :-

Left \= void,

bt_leaves(Left,L1), bt_leaves(Right,L2),

append(L1,L2,L).

bt_leaves(tree(_,Left,Right),L) :-

Right \= void,

bt_leaves(Left,L1), bt_leaves(Right,L2),

append(L1,L2,L).

9 Listen 9-13

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 80]: bt_leaves(tree(a,tree(b,void,void),

tree(c,void,void)

),

L).

L = [b, c] More? (;)

9 Listen 9-14

Programmierkurs PROLOG Sommersemester

9.4 Listenverarbeitung mit Akkumulatoren

9.4.1 Lange einer Liste

len1([],0).

len1([K|R], N) :- len1(R,N1), N is N1 + 1.

ist rekursiv,

len2(L,N) :- len_acc(L,0,N).

len_acc([],A,A).

len_acc([K|R],A,N) :- A1 is A + 1, len_acc(R, A1, N).

ist iterativ!

9 Listen 9-15

Programmierkurs PROLOG Sommersemester

9.4.2 Eine Liste umkehren

‘Naive’ Version:

nreverse([], []).

nreverse([X|Xs], Zs) :-

reverse(Xs,Ys),

append(Ys,[X],Zs).

9 Listen 9-16

Programmierkurs PROLOG Sommersemester

Mit Akkumulator:

areverse(Xs,Ys) :-

reverse_acc(Xs, [], Ys).

reverse_acc([],Ys,Ys).

reverse_acc([X|Xs],A,Ys) :-

reverse_acc(Xs,[X|A],Ys).

9 Listen 9-17

Programmierkurs PROLOG Sommersemester

9.5 Listen mit ‘Lochern’: Differenzlisten

Eine Differenzliste ist eine partielle Liste die ein ‘Loch’ amEnde hat, zusammen mit dem Loch.

Beispiel [a,b,c|X]-X, reprasentiert als Baum:

A

B

C X

- X

9 Listen 9-18

Programmierkurs PROLOG Sommersemester

In einer Differenzliste FL - D ist FL ein ‘Versprechen’ fur dievollstandige Liste und D der Anteil, der zur vollen Liste nochfehlt.

Der eigentliche Inhalt, der durch D=[] erhalten wird, ist alsotatsachlich in gewissem Sinne die Differenz zwischen FL und D.

Aneinanderhangen von Differenzlisten:

dl_append(A-M, M-R, A-R).

9 Listen 9-19

Programmierkurs PROLOG Sommersemester

Beispiel

quicksort(L,S) :- quicksort_acc(L,[],S).

quicksort_acc([],S,S).

quicksort_acc([K|R],A,S) :-

split(K,R,L1,L2),

quicksort_acc(L1,[K|Loch],S),

quicksort_acc(L2,A,Loch).

split(M, [K|R1], [K|R2], L) :- K @=< M, split(M,R1,R2,L)

split(M, [K|R1], L, [K|R2]) :- K @> M, split(M,R1,L,R2).

split(_, [], [], []).

9 Listen 9-20

Programmierkurs PROLOG Sommersemester

Test:

[eclipse 96]: quicksort([5,3,a,7,2,z,b],X).

X = [2, 3, 5, 7, a, b, z] More? (;) ;

9 Listen 9-21

Programmierkurs PROLOG Sommersemester

9.6 Das Wichtigste in Kurze

1. Eine Liste ist eine spezielle Struktur mit Funktor ..

2. Schreibweise [K|R] (statt .(K,R)) fur eine Liste mit KopfK und Rumpf R.

3. Operationen auf Listen sind rekursiv: Behandle zuerst denKopf, dann (rekursiver Aufruf) den Rumpf.

9 Listen 9-22

Programmierkurs PROLOG Sommersemester

4. Akkumulatoren konnen bei der Listenverarbeitung dieEffizienz verbessern.

5. Eine Differenzliste ist eine partielle Struktur, die anstellemit der leeren Liste mit einem Loch (uninstantiierteVariable) abgeschlossen wird, das explizit reprasentiertwird. Durch Instantiieren mit dem Loch kann an die Listeetwas hinten angehangt werden.

9 Listen 9-23

Programmierkurs PROLOG Sommersemester

!

Das Ziel ! ist immer erfullbar und bewirkt einen Nebeneffekt:Alle choice points, die in der aktuellen Box noch existieren,

• sowohl choice points innerhalb der Boxen von Teilzielen

• als auch der choice point, der auf alternative Klauseln zumaktuellen Ziel zeigt,

werden geloscht.

Im Box-Modell: der FAIL-Port des ! (der vorher mit demREDO-Port des vorhergehenden Teilziels verbunden war), wirddirekt mit dem FAIL-Port der aktuellen Box verbunden.

10 Backtracking, der Cut 10-1

Programmierkurs PROLOG Sommersemester

Der Cut bewirkt, daß das aktuelle Pradikat sich aufalle bisher getroffenen Entscheidungen festlegt.

10.1 Graue Cuts

Ein grauer Cut entfernt choice points, die nicht zu neuenLosungen fuhren.

Ein grauer Cut verandert nicht die logische Semantik einesProgramms, sondern verhindert nur, daß beim Beweis ‘sinnlose’Teilziele verfolgt werden.

10 Backtracking, der Cut 10-2

Programmierkurs PROLOG Sommersemester

10.1.1 Blaue Cuts

Machen ein Pradikat deterministisch, daß es eigentlich seinsollte, es aber nicht ist, weil dies vom Compiler nicht erkanntwird.

10.2 Rote Cuts

Schneiden Losungen ab.

Konnen eingesetzt werden, um unerwunschte Losungen zuverhindern.

10 Backtracking, der Cut 10-3

Programmierkurs PROLOG Sommersemester

10.3 Anwendungen des Cut

10.3.1 Cut/Fail

Dient, um Ausnahmen zu kennzeichnen.

10 Backtracking, der Cut 10-4

Programmierkurs PROLOG Sommersemester

11.1 Streams

In Prolog:

see(+File). Macht die Datei File zum aktuellenEingabestream. File muß ein atomsein. Sonderfall user: standard in.

seeing(?File). Matcht File mit dem aktuellenEingabestream (ohne ihn zu andern).

seen. Setzt den aktuellen Eingabestreamzuruck zu user.

11 Ein- und Ausgabe 11-1

Programmierkurs PROLOG Sommersemester

tell(+File). Macht die Datei File zum aktuellenAusgabestream. File muß ein atomsein. Sonderfall user: standard out.

telling(?File). Matcht File mit dem aktuellenAusgabestream (ohne ihn zu andern).

told. Setzt den aktuellen Ausgabestreamzuruck zu user.

11 Ein- und Ausgabe 11-2

Programmierkurs PROLOG Sommersemester

Achtung ‘Verschachteln’ von see/seen nicht moglich, alsoimmer mit seeing den aktuellen Stream merken.

In ECLiPSe Nur im Kompatibilitatsmodus. Sonst mit open

(Erzeugen eines ”physical stream“), set stream (fursee/tell), get stream (fur seeing/telling), close (furseen/told).

11 Ein- und Ausgabe 11-3

Programmierkurs PROLOG Sommersemester

11.2 Ein- / Ausgabe von ASCII-Zeichen

get(?Ascii). Matcht Ascii mit dem Charactercode(Integer) des nachsten Zeichens, dasvom aktuellen Eingabestream gelesenwird.

put(+Ascii). Schreibt das Zeichen mit demCharactercode Ascii auf denaktuellen Ausgabestream.

nl. Schreibt ein Zeilenendekennzeichen auf denaktuellen Ausgabestream.

11 Ein- und Ausgabe 11-4

Programmierkurs PROLOG Sommersemester

11.3 Ein- / Ausgabe von Termen

read(?T). Liest einen vollstandigen Term(abgeschlossen mit .) vom aktuellenEingabestream und matcht ihn mit T.

write(?T). Schreibt den Term T (ohne abschließenden .,unter Beachtung der Operatordefinitionen)auf den aktuellen Ausgabestream.

display(?T). Wie write, ohne Operatoren.

11 Ein- und Ausgabe 11-5

Programmierkurs PROLOG Sommersemester

12.1 Programmkontrolle

fail

Schlagt immer fehl.

Beispiel Wenn wir Pradikate mit Nebeneffekten einsetzen(z. B. I/O), konnen wir alle Losungen eines Zielsfolgendermaßen abarbeiten (failure-driven loop):

alle_Loesungen :-

(

ziel(X),

verarbeite(X),

12 Systempradikate 12-1

Programmierkurs PROLOG Sommersemester

fail

;

true

).

;

”Oder“. Werden Ziele mit ; verknupft (bindet schwacher als ,),so wird erst versucht, die linke Seite des ; zu beweisen. Schlagtdies fehl, so wird versucht, die rechte Seite des ; zu beweisen.

Beispiel

elternteil(X, Y) :-

12 Systempradikate 12-2

Programmierkurs PROLOG Sommersemester

(

vater(X, Y)

;

mutter(X, Y)

).

12.2 Manipulation und Aufruf von Termen

name(?A,?L). Matcht L mit der Liste von ASCII-Codes,die den Zeichen entsprechen, die das Atom A

bilden.

12 Systempradikate 12-3

Programmierkurs PROLOG Sommersemester

functor(?T,?F,?A). Matcht T mit einer Struktur, die denFunktor F und die Aritat A hat.

arg(+N,+T,?Arg). Matcht das N-te Argument vonStruktur T mit Arg.

=..(?Term,?Liste). Matcht Term mit dem Term, dessenFunktor der Kopf von Liste ist unddessen Argumente die restlichenListenelemente bilden.

call(+Goal). Ruft den Term Goal als Ziel auf.

12 Systempradikate 12-4

Programmierkurs PROLOG Sommersemester

Beispiel

mapfunc([], [], _).

mapfunc([K|R], [MK|MR], F) :-

functor(Ziel,F,2),

arg(1,Ziel,K),

arg(2,Ziel,MK),

call(Ziel),

mapfunc(R,MR,F).

12 Systempradikate 12-5

Programmierkurs PROLOG Sommersemester

[eclipse 30]: mapfunc([1,2,3,4],L,-).

L = [-1, -2, -3, -4]

yes.

Alternativ:

mapfunc([], [], _).

mapfunc([K|R], [MK|MR], F) :-

Ziel =.. [F,K,MK],

call(Ziel),

mapfunc(R,MR,F).

12 Systempradikate 12-6

Programmierkurs PROLOG Sommersemester

Achtung! call ist ‘undurchdringlich’ fur den cut.

12.3 Compiliert vs. Interpretiert

:- dynamic(pred/n). Erklart das n-stellige Pradikatpred als dynamisch. Dieses wirdinterpretiert und darf manipuliertwerden.

12 Systempradikate 12-7

Programmierkurs PROLOG Sommersemester

12.4 Inspektion der Datenbasis

clause(+Clause). Matcht Clause mit einer dynamischenKlausel, falls dies moglich ist.

listing. Listet alle dynamischen Pradikate auf.

listing(+Pred). Listet alle Klauseln zum dynamischenPradikat Pred. Pred darf furpradikatname oder furpradikatname/aritat stehen.

12 Systempradikate 12-8

Programmierkurs PROLOG Sommersemester

12.5 Alle Antworten

findall(?T,+Z,?L). Matcht L mit einer Liste aller Instanzenvon Term T, fur die Ziel Z erfullt ist.Deterministisch!

bagof(?T,+Z,?L). Instantiiert zunachst alle Variablen inZiel Z, die nicht in T vorkommen, so daßZ erfullbar ist, und matcht L mit einerListe aller Instanzen von Term T, fur dieZ erfullt ist. Evtl. nichtdeterministisch.

setof(?T,+Z,?L). Wie bagof, aber mit anschließendemsort (entfernt Duplikate).

12 Systempradikate 12-9

Programmierkurs PROLOG Sommersemester

Beispiel

stdpl(lukas,montag,lina).

stdpl(lukas,dienstag,et).

stdpl(lukas,freitag,rs).

stdpl(heike,montag,lsi).

stdpl(heike,mittwoch,tdl).

stdpl(heike,freitag,ki).

12 Systempradikate 12-10

Programmierkurs PROLOG Sommersemester

[eclipse 13]: findall(Tag-Fach,stdpl(P,Tag,Fach),L).

P = P

Tag = Tag

Fach = Fach

L = [montag - lina, dienstag - et, freitag - rs,

montag - lsi, mittwoch - tdl, freitag - ki]

yes.

12 Systempradikate 12-11

Programmierkurs PROLOG Sommersemester

[eclipse 14]: bagof(Tag-Fach,stdpl(P,Tag,Fach),L).

P = heike

Tag = Tag

Fach = Fach

L = [montag - lsi, mittwoch - tdl, freitag - ki] More?

P = lukas

Tag = Tag

Fach = Fach

L = [montag - lina, dienstag - et, freitag - rs]

yes.

12 Systempradikate 12-12

Programmierkurs PROLOG Sommersemester

[eclipse 15]: findall(Fach,stdpl(P,Tag,Fach),L).

P = P

Tag = Tag

Fach = Fach

L = [lina, et, rs, lsi, tdl, ki]

yes.

[eclipse 16]: bagof(Fach,stdpl(P,Tag,Fach),L).

P = heike

Tag = freitag

12 Systempradikate 12-13

Programmierkurs PROLOG Sommersemester

Fach = Fach

L = [ki] More? (;)

P = heike

Tag = mittwoch

Fach = Fach

L = [tdl] More? (;)

P = heike

Tag = montag

Fach = Fach

L = [lsi] More? (;)

12 Systempradikate 12-14

Programmierkurs PROLOG Sommersemester

P = lukas

Tag = dienstag

Fach = Fach

L = [et] More? (;)

P = lukas

Tag = freitag

Fach = Fach

L = [rs] More? (;)

P = lukas

12 Systempradikate 12-15

Programmierkurs PROLOG Sommersemester

Tag = montag

Fach = Fach

L = [lina]

yes.

[eclipse 18]: bagof(Fach,Tag^stdpl(P,Tag,Fach),L).

P = heike

Tag = Tag

Fach = Fach

L = [lsi, tdl, ki] More? (;)

P = lukas

12 Systempradikate 12-16

Programmierkurs PROLOG Sommersemester

Tag = Tag

Fach = Fach

L = [lina, et, rs]

yes.

12 Systempradikate 12-17

Programmierkurs PROLOG Sommersemester

12.6 Manipulation der Datenbasis

assert(+Clause). Fugt die Klausel Clause derDatenbasis hinzu.

asserta(+Clause). Fugt die Klausel Clause amAnfang der Datenbasis hinzu.

assertz(+Clause). Fugt die Klausel Clause amEnde der Datenbasis hinzu.

12 Systempradikate 12-18

Programmierkurs PROLOG Sommersemester

retract(+Clause). Entfernt die erste Klausel, dieClause matcht, aus derDatenbasis.

retractall(+Clause). Entfernt alle Klauseln, dieClause matchen, aus derDatenbasis.

Das Pradikat, das definiert oder geloscht wird, muß alsdynamisch deklariert sein.

Beispiel [eclipse 1]: assert(ich(bin(froh))).

yes.

12 Systempradikate 12-19

Programmierkurs PROLOG Sommersemester

[eclipse 2]: ich(bin(X)).

X = froh

yes.

[eclipse 3]: assert(ich(bin(X)) :- emotion(positiv,X)).

X = X

yes.

[eclipse 4]: assert(emotion(positiv,gluecklich)).

yes.

[eclipse 5]: assert(emotion(positiv,happy)).

12 Systempradikate 12-20

Programmierkurs PROLOG Sommersemester

yes.

[eclipse 6]: ich(bin(X)).

X = froh More? (;)

X = gluecklich More? (;)

X = happy

yes.

12 Systempradikate 12-21

Programmierkurs PROLOG Sommersemester

abolish(+Pred). Entfernt das Pradikat Predvollstandig aus der Datenbasis.Pred darf fur pradikatnameoder fur pradikatname/aritatstehen.

Das Pradikat kann statisch oder dynamisch sein.

12 Systempradikate 12-22

Programmierkurs PROLOG Sommersemester

:- module interface(+Name). Deklariert alles folgende (bisFileende oder module body) zInterfaceteil von Modul Name

:- module body(+Name). Deklariert alles folgende zumRumpf von Modul Name.

In Prolog: :- module(+Name).

use module(+Name). Macht das Interface von ModulName verfugbar.

13 Modulsystem 13-1

Programmierkurs PROLOG Sommersemester

Wir kennen bereits:

• Listen

• Baume

• Record-Strukturen

14.1 Strings

In Prolog normalerweise reprasentiert durch Listen vonZeichencodes (integer-Werte).

Beispiel

14 Datenstrukturen und Algorithmen 14-1

Programmierkurs PROLOG Sommersemester

?- "Hallo" = X.

X = [72, 97, 108, 108, 111]

yes.

?- display(‘Hallo‘).

.(72, .(97, .(108, .(108, .(111, [])))))

yes.

In ECLiPSe sind Strings ein eigener Typ von Konstante.

Beispiel

[eclipse 6]: "Hallo" = X.

X = "Hallo"

14 Datenstrukturen und Algorithmen 14-2

Programmierkurs PROLOG Sommersemester

yes.

[eclipse 7]: display("Hallo").

Hallo

yes.

Listennotation wird erreicht durch:

:- set_chtab(0’‘,list_quote).

[eclipse 5]: ‘Hallo‘ = X.

X = [72, 97, 108, 108, 111]

yes.

14 Datenstrukturen und Algorithmen 14-3

Programmierkurs PROLOG Sommersemester

[eclipse 10]: type_of("Hallo",X).

X = string

yes.

[eclipse 11]: type_of(‘Hallo‘,X).

X = compound

yes.

" kann nicht umdefiniert werden.

14 Datenstrukturen und Algorithmen 14-4

Programmierkurs PROLOG Sommersemester

14.2 Arrays

In Prolog schwer zu reprasentieren.

In ECLiPSe realisierbar mitfunctor(?Term,?Functor,?Arity) und arg(+N,+Term,?Arg)

(Aritat unbegrenzt).

Erzeugung eines ‘Arrays’ mit 1000 Elementen:

functor(Array,array,1000).

‘Zuweisung’ (nur einmal moglich) oder Auslesen eines Wertesan Element 537 des Arrays:

arg(537,Array,Wert).

14 Datenstrukturen und Algorithmen 14-5

Programmierkurs PROLOG Sommersemester

Uberschreiben von Element 647 mit einem neuen Wert(Vorsicht Seiteneffekt!):

setarg(647,Array,Wert).

14.3 Konstruktion von Datenstrukturen

Durch Instantiieren von Variablen besteht in Prolog dieMoglichkeit, Datenstrukturen top-down oder bottom-up oder ineiner Mischung beider Paradigmen zu erzeugen.

Beispiel

append([],L,L).

14 Datenstrukturen und Algorithmen 14-6

Programmierkurs PROLOG Sommersemester

append([K|R1], L2, [K|R3]) :- append(R1,L2,R3).

append erzeugt die Ergebnisliste top-down (von Kopf zuRumpf).

Beispiel listtoset(+List)?Set soll aus List top-down eineListe Set erzeugen, die jedes Element, das in List vorkommt,genau einmal enthalt (keine Duplikate).

listtoset([X|Xs],Ys) :-

member(X,Xs),

!,

listtoset(Xs,Ys).

14 Datenstrukturen und Algorithmen 14-7

Programmierkurs PROLOG Sommersemester

listtoset([X|Xs],[X|Ys]) :-

listtoset(Xs,Ys).

listtoset([],[]).

[eclipse 33]: listtoset([1,2,3,3,5,1,2,4,3,4],L).

L = [5, 1, 2, 3, 4]

yes.

Alternative mit Akkumulator:

listtoset_acc(Xs,Ys) :- listtoset_acc(Xs,[],Ys).

14 Datenstrukturen und Algorithmen 14-8

Programmierkurs PROLOG Sommersemester

listtoset_acc([X|Xs],A,Ys) :-

member(X,A),

!,

listtoset_acc(Xs,A,Ys).

listtoset_acc([X|Xs],A,Ys) :-

listtoset_acc(Xs,[X|A],Ys).

listtoset_acc([],Ys,Ys).

[eclipse 35]: listtoset_acc([1,2,3,3,5,1,2,4,3,4],L).

L = [4, 5, 3, 2, 1]

yes.

14 Datenstrukturen und Algorithmen 14-9

Programmierkurs PROLOG Sommersemester

Besser fur Mengen:

[eclipse 36]: sort([1,2,3,3,5,1,2,4,3,4],L).

L = [1, 2, 3, 4, 5]

yes.

oder Reprasentation durch Baume.

14 Datenstrukturen und Algorithmen 14-10

Programmierkurs PROLOG Sommersemester

15.1 Ports

Das Verfolgen des Programmablaufs mit dem Debugger bestehtim Verfolgen der Durchgange durch die einzelnen Ports imerweiterten Box-Modell:

CALL Aufruf eines Pradikats.

Es wird das aktuelle Teilziel (Variableninstantiierung vordem Aufruf) angezeigt.

15 Der Debugger 15-1

Programmierkurs PROLOG Sommersemester

EXIT Erfolgreiches Ende eines Pradikataufrufs.

Das erfolgreich beendete Teilziel wird mit der erfullendenVariablenbelegung angezeigt.

∗EXIT: nichtdeterministisches EXIT: REDO moglich.

FAIL Fehlschlag eines Teilziels.

Das nicht erfullbare Teilziel wird angezeigt.

NEXT Sprung zur nachsten Klausel in der aktuellen Boxaufgrund eines Fehlschlags in der vorhergehenden Klausel.

Es wird dasselbe wie beim zugehorigen CALL angezeigt.

15 Der Debugger 15-2

Programmierkurs PROLOG Sommersemester

REDO Wiedererfullung eines Pradikats.

Es wird das wiederzuerfullende Teilziel mit derVariableninstantiierung es letzten choice point angezeigt.

UNIFY Unifikation eines Klauselkopfes mit dem aktuellenTeilziel.

Das Ergebnis der Unifikation wird angezeigt.

Dieser Port existiert nicht bei Fakten.

LEAVE Spezialport fur block/3 und exit block/1.

15 Der Debugger 15-3

Programmierkurs PROLOG Sommersemester

CUT Entfernung eines choice point durch den !.

Es wird das nun nicht mehr wiedererfullbare Teilzielangezeigt.

TRY Erzeugung eines choice point.

Das wiedererfullbare Teilziel wird angezeigt.

DELAY Die Ausfuhrung des Pradikats wird aufgehalten(suspend). Kann nur bei coroutining auftreten.

RESUME Ein aufgehaltenes Pradikat wird ausgefuhrt (nachDELAY). Handhabung wie CALL.

15 Der Debugger 15-4

Programmierkurs PROLOG Sommersemester

15.2 Leashing

Wahrend des Verfolgens der Ausfuhrung werden die Portsindividuell behandelt. Dies ist abhangig vom leash level:

stop Es wird eine Statuszeile angezeigt, angehalten, derdebugger prompt gezeigt und auf eine Eingabe gewartet.

print Es wird eine Statuszeile angezeigt und sofortweitergemacht.

notrace Der Port wird nicht verfolgt.

15 Der Debugger 15-5

Programmierkurs PROLOG Sommersemester

set leash(+Port,+Level). Legt den leash level fur einenPort fest.

15 Der Debugger 15-6

Programmierkurs PROLOG Sommersemester

15.3 Debug mode

creep Debugger ist aktiviert.

Bei jedem Durchgang durch einen Port wird dessen leashlevel entsprechend gehandelt.

leap Debugger ist aktiviert.

Das Programm lauft normal bis zur Unterbrechung durchC-c, einen Fehler oder einen spy point.

15 Der Debugger 15-7

Programmierkurs PROLOG Sommersemester

15.4 Aufruf des Debuggers, Spypoints

debug. Schaltet den Debugger in leap mode.

trace. Schaltet den Debugger in creep mode.

nodebug. Schaltet den Debugger aus.

notrace. Schaltet den Debugger aus.

15 Der Debugger 15-8

Programmierkurs PROLOG Sommersemester

spy(+Pred). Setzt einen spy point fur Pradikat Pred.Pred darf fur pradikatname oder furpradikatname/aritat stehen.

Wird im leap mode ein Pradikat erreicht, das mit einem spypoint belegt ist, so schaltet der Debugger automatisch in creepmode.

Beispiel [eclipse 2]: trace.

yes.

Debugger switched on - creep mode

15 Der Debugger 15-9

Programmierkurs PROLOG Sommersemester

[eclipse 4]: set_leash(unify,stop).

yes.

[eclipse 6]: set_leash(next,stop).

yes.

[eclipse 12]: set_leash(try,print).

yes.

15 Der Debugger 15-10

Programmierkurs PROLOG Sommersemester

[eclipse 13]: listtoset([1,2,1],X).

(1) 0 CALL listtoset([1, 2, 1], X) (dbg)?- creep

(1) 0 TRY listtoset([1, 2, 1], X)

(1) 0 UNIFY listtoset([1, 2, 1], X) (dbg)?- creep

(2) 1 CALL member(1, [2, 1]) (dbg)?- creep

(2) 1 TRY member(1, [2, 1])

(2) 1 NEXT member(1, [2, 1]) (dbg)?- creep

(2) 1 UNIFY member(1, [2, 1]) (dbg)?- creep

(3) 2 CALL member(1, [1]) (dbg)?- creep

(3) 2 TRY member(1, [1])

(3) 2 *EXIT member(1, [1]) (dbg)?- creep

(2) 1 *EXIT member(1, [2, 1]) (dbg)?- creep

15 Der Debugger 15-11

Programmierkurs PROLOG Sommersemester

(4) 1 CALL ! (dbg)?- creep

(3) 2 CUT member(1, [1])

(1) 0 CUT listtoset([1, 2, 1], X)

(4) 1 EXIT ! (dbg)?- creep

(5) 1 CALL listtoset([2, 1], X) (dbg)?- creep

(5) 1 TRY listtoset([2, 1], X)

(5) 1 UNIFY listtoset([2, 1], X) (dbg)?- creep

(6) 2 CALL member(2, [1]) (dbg)?- creep

(6) 2 TRY member(2, [1])

(6) 2 NEXT member(2, [1]) (dbg)?- creep

(6) 2 UNIFY member(2, [1]) (dbg)?- creep

(7) 3 CALL member(2, []) (dbg)?- creep

15 Der Debugger 15-12

Programmierkurs PROLOG Sommersemester

(7) 3 FAIL member(2, []) (dbg)?- creep

(6) 2 FAIL member(2, [1]) (dbg)?- creep

(5) 1 NEXT listtoset([2, 1], X) (dbg)?- creep

(5) 1 UNIFY listtoset([2, 1], [2|Ys]) (dbg)?- creep

(8) 2 CALL listtoset([1], Ys) (dbg)?- creep

(8) 2 TRY listtoset([1], Ys)

(8) 2 UNIFY listtoset([1], Ys) (dbg)?- creep

(9) 3 CALL member(1, []) (dbg)?- creep

(9) 3 FAIL member(1, []) (dbg)?- creep

(8) 2 NEXT listtoset([1], Ys) (dbg)?- creep

(8) 2 UNIFY listtoset([1], [1|Ys]) (dbg)?- creep

(10) 3 CALL listtoset([], Ys) (dbg)?- creep

15 Der Debugger 15-13

Programmierkurs PROLOG Sommersemester

(10) 3 EXIT listtoset([], []) (dbg)?- creep

(8) 2 EXIT listtoset([1], [1]) (dbg)?- creep

(5) 1 EXIT listtoset([2, 1], [2, 1]) (dbg)?- creep

(1) 0 EXIT listtoset([1, 2, 1], [2, 1]) (dbg)?- cree

X = [2, 1]

yes.

[eclipse 15]: debug.

yes.

Debugger switched on - leap mode

15 Der Debugger 15-14

Programmierkurs PROLOG Sommersemester

[eclipse 16]: spy(member).

spypoint added to member / 2.

yes.

[eclipse 17]: listtoset([1,2,1],X).

+(2) 1 CALL member(1, [2, 1]) (dbg)?- creep

15 Der Debugger 15-15

Programmierkurs PROLOG Sommersemester

16.1 Flags

Direktive Werte fur Flag

:- set flag(debug compile,Flag). on, off

Sollen Debug-Informationen eincompiliert werden?

Direktive Werte fur Flag

:- set flag(occur check,Flag). on, off

Occur-Check bei der Unifikation?

16 Der Compiler 16-1

Programmierkurs PROLOG Sommersemester

Direktive Werte fur Flag

:- set flag(dfid compile,Flag). on, off

Iterative deepening moglich?

Direktive Werte fur Flag

:- set flag(float precision,Flag). single, double

16 Der Compiler 16-2

Programmierkurs PROLOG Sommersemester

Direktive

:- set flag(variable names,Flag).

Werte fur Flag

check singletons, on, off

Variablennamen merken?

16 Der Compiler 16-3

Programmierkurs PROLOG Sommersemester

16.2 Aufruf

compile(+F). Compiliere Datei F in die akt.Datenbasis.

compile(+F,+M). Compiliere Datei F in Modul M.

ensure loaded(+F). Compiliere F, falls notig.

make. Compiliere alle geanderten Dateienneu.

lib(+File). Lade Library File.

16 Der Compiler 16-4

Programmierkurs PROLOG Sommersemester

16.3 Mode Declarations

:- mode pred(+,?). Lege den mode von pred fest.

16 Der Compiler 16-5

Programmierkurs PROLOG Sommersemester

16.4 Stand-alone Programme

In ECLiPSe (bei uns) keine Erzeugung ausfuhrbarer Dateienmoglich.

Nutzung von ECLiPSe als Runtimesystem fur einstand-alone-Programm mit Kommandozeilen-Optionen.

eclipse -b boot Compiliere sofort die Datei boot.

eclipse -e goal Fuhre als erstes das Ziel goal aus.

Bei Kombination von -b und -e wird erst boot compiliert unddann goal ausgefuhrt.

16 Der Compiler 16-6

Programmierkurs PROLOG Sommersemester

Beispiel

:- use_module(listen).

16 Der Compiler 16-7

Programmierkurs PROLOG Sommersemester

interface(L) :-

nl,

write("Die aktuelle Liste ist: "),

writeln(L),

nl,

writeln("n - Neue Liste eingeben"),

writeln("l - Laenge bestimmen"),

writeln("r - Liste umdrehen"),

writeln("d - Duplikate entfernen"),

writeln("q - Ende"),

get_char(C),

execute(C,L).

16 Der Compiler 16-8

Programmierkurs PROLOG Sommersemester

execute("n",_) :-

!,

write("Neue Liste? "),

read(L),

interface(L).

execute("l",L) :-

!,

len2(L,N),

write("Laenge: "),

writeln(N),

interface(L).

16 Der Compiler 16-9

Programmierkurs PROLOG Sommersemester

execute("r",L) :-

!,

areverse(L,R),

interface(R).

execute("d",L) :-

!,

listtoset(L,S),

interface(S).

execute("q",_).

16 Der Compiler 16-10

Programmierkurs PROLOG Sommersemester

execute(_,L) :- % Kein erlaubtes Kommando

get_char(C),

execute(C,L).

eclipse -b userinterface -e "interface([])."

listen.pl compiled traceable 4872 bytes in 0.05 seconds

userinterface.pl compiled traceable 1496 bytes in 0.07 se

Die aktuelle Liste ist: []

16 Der Compiler 16-11

Programmierkurs PROLOG Sommersemester

n - Neue Liste eingeben

l - Laenge bestimmen

r - Liste umdrehen

d - Duplikate entfernen

q - Ende

n

Neue Liste? [1,2,3].

Die aktuelle Liste ist: [1, 2, 3]

n - Neue Liste eingeben

l - Laenge bestimmen

16 Der Compiler 16-12

Programmierkurs PROLOG Sommersemester

r - Liste umdrehen

d - Duplikate entfernen

q - Ende

l

Laenge: 3

Die aktuelle Liste ist: [1, 2, 3]

n - Neue Liste eingeben

l - Laenge bestimmen

r - Liste umdrehen

d - Duplikate entfernen

16 Der Compiler 16-13

Programmierkurs PROLOG Sommersemester

q - Ende

r

Die aktuelle Liste ist: [3, 2, 1]

n - Neue Liste eingeben

l - Laenge bestimmen

r - Liste umdrehen

d - Duplikate entfernen

q - Ende

n

Neue Liste? [1,2,3,2,1].

16 Der Compiler 16-14

Programmierkurs PROLOG Sommersemester

Die aktuelle Liste ist: [1, 2, 3, 2, 1]

n - Neue Liste eingeben

l - Laenge bestimmen

r - Liste umdrehen

d - Duplikate entfernen

q - Ende

d

Die aktuelle Liste ist: [3, 2, 1]

16 Der Compiler 16-15

Programmierkurs PROLOG Sommersemester

n - Neue Liste eingeben

l - Laenge bestimmen

r - Liste umdrehen

d - Duplikate entfernen

q - Ende

q

pkpro00@neon(/home/pkpro/pkpro00/Beispiele){8}:

16 Der Compiler 16-16

Programmierkurs PROLOG Sommersemester

17.1 ProTcXl

Interface Prolog — Tcl/Tk und Xlib

Tcl Skriptsprache fur die Oberflachenprogrammierung

Tk Sprache zur Konstruktion von Widgets(Oberflachenelementen).

Xlib X11 Oberflachenbibliothek

17 Oberflachenprogrammierung 17-1

Programmierkurs PROLOG Sommersemester

17.2 Aufruf

Library laden:

:- lib(tk).

Hauptfenster offnen:

tk(+Optionen).

Optionen legen das Aussehen des Fensters fest (z. B.geometry). Im einfachsten Fall: [].

17 Oberflachenprogrammierung 17-2

Programmierkurs PROLOG Sommersemester

17.3 Erzeugung von Widgets

tcl(’TCL code’).

[eclipse 5]: tcl ’button .b -text "Hi" -command exit; pac

yes.

17 Oberflachenprogrammierung 17-3

Programmierkurs PROLOG Sommersemester

18.1 Programm-Layout

18.1.1 Aufteilen des Programms in Module

Module sollten thematisch zusammengehorige Pradikatesammeln.

Durch das Modul-Interface konnen interne Pradikate verstecktwerden.

18 Entwurf von Prolog-Programmen 18-1

Programmierkurs PROLOG Sommersemester

Beispiel

/* Hier beginnt das Interface fuer listtoset.

*/

:- module_interface(listtoset).

/* Direktiven, die in diesem und allen importierenden

* Modulen wirksam sind.

*/

:- op(200,xfx,-*->).

:- op(200,xfx,=*=>).

18 Entwurf von Prolog-Programmen 18-2

Programmierkurs PROLOG Sommersemester

/* Praedikate, die in dieses und alle importierenden

* Module importiert werden sollen.

*/

:- import member/2 from listen.

/* Praedikate, die in importierende Module exportiert

* werden sollen.

*/

:- export ’-*->’/2, ’=*=>’/2.

18 Entwurf von Prolog-Programmen 18-3

Programmierkurs PROLOG Sommersemester

/* Ende des Interface; jetzt kommt der body.

*/

:- begin_module(listtoset).

/* Alle Direktiven, Deklarationen und Imports, die hier

* stehen, sind nur in DIESEM Modul sichtbar.

*/

18 Entwurf von Prolog-Programmen 18-4

Programmierkurs PROLOG Sommersemester

[X|Xs] -*-> Ys :-

member(X,Xs),

!,

Xs -*-> Ys.

[X|Xs] -*-> [X|Ys] :-

Xs -*-> Ys.

[] -*-> [].

18 Entwurf von Prolog-Programmen 18-5

Programmierkurs PROLOG Sommersemester

Xs =*=> Ys :- listtoset_acc(Xs,[],Ys).

listtoset_acc([X|Xs],A,Ys) :-

member(X,A),

!,

listtoset_acc(Xs,A,Ys).

listtoset_acc([X|Xs],A,Ys) :-

listtoset_acc(Xs,[X|A],Ys).

listtoset_acc([],Ys,Ys).

[eclipse 49]: use_module(listtoset).

yes.

18 Entwurf von Prolog-Programmen 18-6

Programmierkurs PROLOG Sommersemester

[eclipse 54]: [1,2,3,2,1] -*-> L.

L = [3, 2, 1]

yes.

[eclipse 55]: [1,2,3,2,1] =*=> L.

L = [3, 2, 1]

yes.

[eclipse 56]: listtoset_acc([1,2,3,2,1],[],Ys).

calling an undefined procedure listtoset_acc([1, 2, 3, 2

18 Entwurf von Prolog-Programmen 18-7

Programmierkurs PROLOG Sommersemester

18.1.2 Aufteilen eines Moduls in Pradikate

• In Prolog sollten die Pradikate so klein sein wie moglich,aber eine logische Bedeutung haben.

• Beim Entwurf auf die Schnittstellen (Argumente) achten!

• Zu jedem Pradikat gehort ein Kommentar, in dem

1. die logische Bedeutung des Pradikats,

2. die Reihenfolge, Bedeutung und Typen der Argumente,

3. die zulassigen modes

erlautert werden.

18 Entwurf von Prolog-Programmen 18-8

Programmierkurs PROLOG Sommersemester

18.1.3 Implementieren eines Pradikats durch Klauseln

• Klauseln eines Pradikats mussen zusammen stehen(Prozedur).

• Klauseln sollten lesbar sein. Dazu sollten

– nicht mehr Teilziele in einer Zeile stehen als unbedingtnotig (am besten genau eins),

– , und ; auf keinen Fall in einer Zeile zusammen stehen,

– ; am Anfang einer ansonsten leeren Zeile stehen.

18 Entwurf von Prolog-Programmen 18-9

Programmierkurs PROLOG Sommersemester

• Cuts sollten durch Kommentare (blau/grun/rot) erlautertwerden.

• Man prufe, ob sich ; durch Verwendung vonHilfspradikaten vermeiden lassen (nur, wenn diese einelogische Bedeutung haben).

18 Entwurf von Prolog-Programmen 18-10

Programmierkurs PROLOG Sommersemester

18.2 Vermeiden von Fehlern

18.2.1 Eyeball debugging

Haufige Fehler, die zu silent failure fuhren konnen.:

• Tippfehler in Funktoren,

• falsche Aritat,

• falsche Klammerung bei Operatoren,

• Variablen(un)instantiierungen und sharing,

• bei Fallunterscheidungen: sich uberschneidende / fehlendeFalle.

18 Entwurf von Prolog-Programmen 18-11

Programmierkurs PROLOG Sommersemester

18.2.2 Steadfastness

Ein Pradikat heißt steadfast, wenn es in allen vorgesehenenModes wie gewunscht funktioniert.

18 Entwurf von Prolog-Programmen 18-12

Programmierkurs PROLOG Sommersemester

Beispiel max(+N1,+N2,?M).

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

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

[eclipse 12]: max1(2,1,X).

X = 2 More? (;) ;

no (more) solution.

18 Entwurf von Prolog-Programmen 18-13

Programmierkurs PROLOG Sommersemester

max2(X,Y,X) :- X >= Y, !. % Blauer CUT

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

[eclipse 14]: max2(2,1,X).

X = 2

yes.

max3(X,Y,X) :- X >= Y, !. % ROTER CUT

max3(_,Y,Y).

[eclipse 19]: max3(10,0,0).

yes.

18 Entwurf von Prolog-Programmen 18-14

Programmierkurs PROLOG Sommersemester

Wichtig: Ein ! muß genau dort stehen, wo absolut sicher ist,daß die richtige Klausel ausgewahlt wurde.

Beispiel

max4(X,Y,Z) :- X >= Y, !, Z is X. % ROTER CUT

max4(_,Y,Y).

[eclipse 21]: max4(10,0,0).

no (more) solution.

18 Entwurf von Prolog-Programmen 18-15

Programmierkurs PROLOG Sommersemester

Daumenregel: Matching von Ausgabevariablen hinter den !

verschieben.

18 Entwurf von Prolog-Programmen 18-16

Programmierkurs PROLOG Sommersemester

Beispiel flatten(+L,?FL).

flatten1(L,FL) :- flatten1(L,FL,[]).

flatten1([],L,L).

flatten1([K|R],L0,L) :-

flatten1(K,L0,L1),

flatten1(R,L1,L).

flatten1(O,[O|L],L) :-

O \= [],

O \= [_|_].

18 Entwurf von Prolog-Programmen 18-17

Programmierkurs PROLOG Sommersemester

[eclipse 35]: flatten1([[1,2],[[3],4]],L).

L = [1, 2, 3, 4] More? (;) ;

no (more) solution.

18 Entwurf von Prolog-Programmen 18-18

Programmierkurs PROLOG Sommersemester

flatten2(L,FL) :- flatten2(L,FL,[]).

flatten2([],L,L) :- !. % Blauer CUT

flatten2([K|R],L0,L) :- !, % Blauer CUT

flatten2(K,L0,L1),

flatten2(R,L1,L).

flatten2(O,[O|L],L) :-

O \= [],

O \= [_|_].

18 Entwurf von Prolog-Programmen 18-19

Programmierkurs PROLOG Sommersemester

[eclipse 37]: flatten2([[1,2],[[3],4]],L).

L = [1, 2, 3, 4]

yes.

18 Entwurf von Prolog-Programmen 18-20

Programmierkurs PROLOG Sommersemester

flatten3(L,FL) :- flatten3(L,FL,[]).

flatten3([],L,L) :- !. % ROTER CUT

flatten3([K|R],L0,L) :- !, % ROTER CUT

flatten3(K,L0,L1),

flatten3(R,L1,L).

flatten3(O,[O|L],L)

/* :-

* O \= [],

* O \= [_|_]

*/

.

18 Entwurf von Prolog-Programmen 18-21

Programmierkurs PROLOG Sommersemester

[eclipse 40]: flatten3([],X).

X = []

yes.

[eclipse 42]: X = [_], flatten3([],X).

X = [[]]

yes.

18 Entwurf von Prolog-Programmen 18-22

Programmierkurs PROLOG Sommersemester

flatten4(L,FL) :- flatten4(L,FL,[]).

flatten4([],L0,L) :- !, % ROTER CUT

L0 = L. % Matching NACH dem CUT

flatten4([K|R],L0,L) :- !, % ROTER CUT

flatten4(K,L0,L1),

flatten4(R,L1,L).

flatten4(O,[O|L],L)

/* :-

* O \= [],

* O \= [_|_]

*/

.

18 Entwurf von Prolog-Programmen 18-23

Programmierkurs PROLOG Sommersemester

[eclipse 45]: flatten4([],X).

X = []

yes.

[eclipse 46]: X = [_], flatten4([],X).

no (more) solution.

18 Entwurf von Prolog-Programmen 18-24

Programmierkurs PROLOG Sommersemester

• Rein deklarative Programmiersprache.

• Keine Nebeneffekte:

– kein CUT,

– I/O-Pradikate manipulieren state of the world.

• Kombination von logischem und funktionalemProgrammieren.

• Deklarationen fur

– Typen,

– Modes,

– Determinismus.

19 Einfuhrung in MERCURY 19-1

Programmierkurs PROLOG Sommersemester

• Compiler pruft die Korrektheit der Deklarationen undoptimiert das Programm.

19.1 Syntax

Im Prinzip wie bei ECLiPSe, mit zusatzlichen Deklarationen(s.u.) und folgenden Erganzungen.

19 Einfuhrung in MERCURY 19-2

Programmierkurs PROLOG Sommersemester

19.1.1 Klauseln

Klauseln, deren Kopf den Funktor = hat, heißenFunktionsklauseln.

Funktionsfakt:

Kopf = Ergebnis.

Funktionsregel:

Kopf = Ergebnis :- Rumpf.

kopf ist eine Struktur, deren Funktor die Funktion festlegt.

Die Argumente von kopf sind Datenterme.

19 Einfuhrung in MERCURY 19-3

Programmierkurs PROLOG Sommersemester

19.1.2 Datenterme

Datenterme sind Terme, in denen auch Funktionsaufrufevorkommen durfen.

Funktionsaufruf:

?- P = preis(aepfel,kg,dm,

1.0 + jahreszeitanpassung(september,dm)

).

P = preis(aepfel, kg, dm, 1.90000000000000).

19 Einfuhrung in MERCURY 19-4

Programmierkurs PROLOG Sommersemester

Definieren und Anwenden einer Funktion perlambda-Ausdruck:

?- N = apply(func(M) = jahreszeitanpassung(M,dm),

september

).

N = 0.900000000000000

19 Einfuhrung in MERCURY 19-5

Programmierkurs PROLOG Sommersemester

19.2 Module

Ein Mercury-Programm besteht aus einer Folge von Modulen.

Beispiel

:- module queue.

:- interface.

% Declare an abstract data type.

:- type queue(T).

19 Einfuhrung in MERCURY 19-6

Programmierkurs PROLOG Sommersemester

% Declare some predicates which operate on the abstract d

:- pred empty_queue(queue(T)).

:- mode empty_queue(out) is det.

:- mode empty_queue(in) is semidet.

:- pred put(queue(T), T, queue(T)).

:- mode put(in, in, out) is det.

:- pred get(queue(T), T, queue(T)).

:- mode get(in, out, out) is semidet.

19 Einfuhrung in MERCURY 19-7

Programmierkurs PROLOG Sommersemester

:- implementation.

% Queues are implemented as lists. We need the ‘list’ mod

% for the declaration of the type list(T), with its const

% ’[]’/0 % and ’.’/2, and for the declaration of the pred

% list__append/3.

:- import_module list.

% Define the queue ADT.

:- type queue(T) == list(T).

19 Einfuhrung in MERCURY 19-8

Programmierkurs PROLOG Sommersemester

% Declare the exported predicates.

empty_queue([]).

put(Queue0, Elem, Queue) :-

list__append(Queue0, [Elem], Queue).

get([Elem | Queue], Elem, Queue).

:- end_module queue.

19 Einfuhrung in MERCURY 19-9

Programmierkurs PROLOG Sommersemester

• Zugriff auf Objekte aus importierten Modulen:

Modulname Objektname

• Ein Modul im Programm muß ein zweistelliges Pradikatmain(io state::di, io state::uo) exportieren, dasbei Ausfuhren des Programms aufgerufen wird.

19 Einfuhrung in MERCURY 19-10

Programmierkurs PROLOG Sommersemester

19.3 Typen

Jedem Term wird ein Typ zugeordnet.

Primitive Typen: char, int, float, string.

Pradikattypen: pred, pred(T), pred(T1,T2), . . .

Funktionstypen: (func) = T, func(T1) = T2, . . .

Der universale Typ: univ.

Der state of the world Typ: io state

19 Einfuhrung in MERCURY 19-11

Programmierkurs PROLOG Sommersemester

19.3.1 Typen deklarieren

:- type monat ---> januar; februar; maerz; april;

mai; juni; juli; august; september;

oktober; november; dezember.

:- type kaufbar ---> aepfel.

:- type gewichtseinheit ---> kg.

:- type waehrung ---> dm.

19 Einfuhrung in MERCURY 19-12

Programmierkurs PROLOG Sommersemester

:- type preisprogewicht

---> preis(kaufbar,

gewichtseinheit,

waehrung,

float

).

:- type employee

---> employee(string, % name

int, % age

string % department

).

19 Einfuhrung in MERCURY 19-13

Programmierkurs PROLOG Sommersemester

:- type tree

---> empty

; leaf(int)

; branch(tree, tree).

:- type list(T)

---> []

; [T | list(T)].

:- type pair(T1, T2)

---> T1 - T2.

19 Einfuhrung in MERCURY 19-14

Programmierkurs PROLOG Sommersemester

Ein Typ ohne Typvariablen heißt monomorph, mitTypvariablen polymorph.

19.3.2 Aquivalenztypen

:- type money == int.

:- type assoc_list(KeyType, ValueType)

== list(pair(KeyType, ValueType)).

19 Einfuhrung in MERCURY 19-15

Programmierkurs PROLOG Sommersemester

19.3.3 Abstrakte Typen (fur Modulinterfaces)

:- type queue(T).

Funktoren werden nach Name, Aritat und Typ unterschieden.

19 Einfuhrung in MERCURY 19-16

Programmierkurs PROLOG Sommersemester

19.3.4 Typdeklarationen fur Pradikate und Funktionen

:- func jahreszeitanpassung(monat, waehrung) = float.

:- pred member(T, list(T)).

:- func length(list(T)) = int.

:- func sum(list(int)) = int.

:- func map(list(T1), func(T1) = T2) = list(T2).

Der Compiler pruft die Korrektheit von Typdeklarationen.

19 Einfuhrung in MERCURY 19-17

Programmierkurs PROLOG Sommersemester

19.4 Modes

Die einfachsten Modes:

in Grundterm.

out Eine freie Variable wird gebunden.

19 Einfuhrung in MERCURY 19-18

Programmierkurs PROLOG Sommersemester

Modedeklarationen:

:- pred append(list(T), list(T), list(T)).

:- mode append(in, in, out).

:- mode append(out, out, in).

:- pred empty_queue(queue(T)).

:- mode empty_queue(out) is det.

:- mode empty_queue(in) is semidet.

Auch Funktionen konnen verschiedene Modes annehmen.

19 Einfuhrung in MERCURY 19-19

Programmierkurs PROLOG Sommersemester

Hat ein Pradikat oder eine Funktion nur einen Mode, so kannman Mode- und Typdeklaration kombinieren.

:- func length(list(T)::in) = (int::out).

:- func jahreszeitanpassung(monat::in, waehrung::in)

= (float::out).

Der Compiler pruft die Korrektheit von Modedeklarationen.

19 Einfuhrung in MERCURY 19-20

Programmierkurs PROLOG Sommersemester

19.5 Determinismus

Jedem mode eines Pradikats oder einer Funktion wird eineDeterminismuskategorie zugeordnet.

det Hat genau eine Losung.

semidet Hat hochstens eine Losung.

multi Hat mindestens eine Losung.

nondet Kann fehlschlagen, eine oder mehrere Losungen haben.

failure Hat keine Losung.

erroneous Erzeugt in jedem Fall einen Laufzeitfehler.

19 Einfuhrung in MERCURY 19-21

Programmierkurs PROLOG Sommersemester

Maximale Anzahl von Losungen

Kann Fehlschlagen? 0 1 > 1

nein erroneous det multi

ja failure semidet nondet

Die Determinismusdeklaration wird an die Modedeklarationangehangt.

:- func jahreszeitanpassung(monat::in, waehrung::in)

= (float::out)

is det.

19 Einfuhrung in MERCURY 19-22

Programmierkurs PROLOG Sommersemester

:- pred append(list(T), list(T), list(T)).

:- mode append(in, in, out) is det.

:- mode append(out, out, in) is multi.

:- mode append(in, in, in) is semidet.

:- pred loop(int::in) is erroneous.

loop(X) :- loop(X).

:- pred p is det.

p.

19 Einfuhrung in MERCURY 19-23

Programmierkurs PROLOG Sommersemester

:- pred q is failure.

q :- fail.

Der Compiler pruft die Korrektheit vonDeterminismusdeklarationen.

19 Einfuhrung in MERCURY 19-24