1998 programmierkurs prolog sommersemester...programmierkurs prolog sommersemester 1998 1.5...
TRANSCRIPT
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