Ergänzungen zur Theoretischen Informatik Vorlesung 5 – 10.05.2013 Themen Prädikatenlogik erster Stufe, Formeln, Aussagen, Struktur, Modell, Überblick Unentscheidbarkeit, Herbrand–Universum und –Expansion, Endlichkeitssatz, Algorithmus von Gilmore, Prolog 1 Prolog Prolog ist eine Logikbasierte Programmiersprache. Als Berechnungsmodell wird die Prädikatenlogik herangezogen, um Probleme zu beschreiben, und dann automatisiert Lösungen dafür zu finden. Da die Prädikatenlogik bekanntermaßen unentscheidbar ist, muss man sich dabei allerdings etwas beschränken; im Falle von Prolog auf Hornformeln. Diese Einschränkung ist zum Beispiel auch dafür verantwortlich, dass es keinen echten NegationsOperator gibt – dennoch kann man viele Probleme elegant Lösen. 1.1 Installation Es gibt verschiedene Implementierungen der Sprache Prolog. Für unsere Zwecke gut geeignet ist SWI-Prolog, alle folgenden Beispiele beziehen sich darauf. Auf den Poolrechnern ist es leider nicht installiert, aber auf dem Server marvin. Die Interpreter Konsole swipl lässt sich auf ssh -X username@marvin öffnen. Die -X Option aktiviert das Tunneln von graphischen Fensterinhalten – gehen Sie bitte sparsam mit Fenstern um. Unter Ubuntu installiere apt-get install swi-prolog-x. Für andere Linuxe muss man es evtl. selbst kompilieren, bei Arch Linux aus dem AUR als swi-prolog. Nach erfolgreicher Installation startet der Befehl swipl den interaktiven Interpreter, in dem die folgenden Beispiele ausgeführt werden. Windows-Nutzer finden dort: http://www.swi-prolog.org/download/stable einen Installer. Das Programm swipl-win.exe sollte ebenfalls einen interaktiven Interpreter öffnen. Die Hilfe-Funktion lässt sich mittels Eingabe von apropos(Suchbegriff). verwenden. 1.2 Erste Abfragen Dem interaktiven Interpreter können nun Fragen gestellt werden, die dieser zu Beweisen versucht. Als sog. Zielklauseln wird direkt die Matrix einer Skolemform eingegeben. Daher sind Variablen (Großbuchstaben) All–quantifiziert. Möchte man Konstanten des Universums in einer Eingabe spezifizieren sind Kleinbuchstaben zu verwenden (z.B. eva, green oder null). 1 Ergänzungen zur Theoretischen Informatik Vorlesung 5 – 10.05.2013 Für die Eingabe von Zielklauseln steht schon eine gewisse Auswahl an vordefinierten Prädikaten mit fester Interpetation zu verfügung (z.B. über Zahlen). Man kann den Interpreter als Taschenrechner verwenden: ?− X i s 6 ∗ 7 . Als Ausgabe erhält man eine Unifikation, der All-quantifizierten Variablen X unter der die Abfrage wahr wird. Das liegt daran, dass der Interpreter bei der Eingabe von ∀X(falsch ⇐= Is(X, 6 ∗ 7) durch Resolution unter Verwendung der Unifikation X = 42 die leere Klausel herleiten kann. Nun eine etwas komplexere Abfrage: Gibt es Zahlen 5 ≤ X ≤ 50, 10 ≤ Y ≤ 50, deren Summe kleiner als 20 ist? Kommata zwischen Zielklauseln sind ein logisches und. ?− between ( 5 , 5 0 , X) , between ( 1 0 , 5 0 , Y) , Z i s X + Y, Z < 2 0 . Wieder erhält man als Antwort eine mögliche Kombination von Werten. Nun gibt es aber mehrere Lösungen – weitere erhält man mit ;. ?− between ( 5 , 5 0 , X) , between ( 1 0 , 5 0 , Y) , Z i s X + Y, Z < 1 2 . Für diese Abfrage findet Prolog keine passende Unifikation, und antwortet false.. Dies heißt aber noch nicht, das die Abfrage nachweislich falsch war! (Vgl. Nur ein Semi–Entscheidungsverfahren) In diesem Falle ist sie es aber. 1.3 Erste Programme Für komplexere Probleme muss man Prolog neue Aussagen, aus denen gefolgert werden kann, in die Wissensdatenbank eingeben. ?− c o n s u l t ( u s e r ) . | : g g t (A, 0 , A ) . | : g g t (A, B, X) :− between ( 1 , i n f , B) , C i s A mod B, g g t (B, C, X ) . consult(user). wechselt in einen anderen Eingabemodus, in dem Informationen für die Wissensdatenbank angenommen werden – In diesem Beispiel die, das der ggT einer Zahl und 0 die Zahl selbst ist, und das eine Zahl X der ggT vom A und B ist, wenn B eine positve Zahl ist und X der ggT von A und A mod B ist. (Dies ergibt den euklidischen Algorithmus bei Verwendung der Resolution). Nachdem man die Eingabe mit Ctrl-D beendet hat, werden die Klauseln kompiliert und stehen für Abfragen zur Verfügung. Nicht nur das Berechnen des ggT (ggt(123456789,987654321, X).), sondern auch das finden von Zahlen mit einem bestimmten ggT (ggt(35, X, 7).) ist möglich. 2 Ergänzungen zur Theoretischen Informatik 1.3.1 Vorlesung 5 – 10.05.2013 Klauselform Die Prolog-Klauseln erinnern nur entfernt an prädikatenlogische Klauseln: es tauchen beispielsweise keine Quantoren auf. Dies ist der Tatsache geschuldet, das Prolog die Eingabe von Hornklauseln erzwingt, in dem eine geeignete Normalform gewählt wird. Diese ist hier die Matrix der Skolemform einer Hornklausel. Das obige ggT-Beispiel würde also in etwas ausführlicherer Notation etwa so aussehen: ∀A ∀B ∀X ∀C between(1, ∞, B) ∧ C = A mod B ∧ ggT (B, C, X) ⇒ ggT (A, B, X) 1.3.2 Universum und Strukturen In welchem Universum sucht Prolog eigentlich nach der ¨ Lösung¨ ? Um das herauszufinden, verlassen wir kurz die vordefinierten Prädikate, und verwenden nur selbst definierte Logik. Wir definieren ein Zahlensystem ähnlich N und eine <-Relation. Dazu benutzen wir die selbst definierte Successor -Funktion s(...), die je die nächsthöhere Zahl liefern soll. zahl ( null ) . z a h l ( s (X) ) :− z a h l (X ) . k l e i n e r ( n u l l , X) :− z a h l (X ) . k l e i n e r ( s (X) , s (Y) ) :− k l e i n e r (X, Y ) . % % % % % N u l l i s t e i n e Zahl . F a l l s X Zahl , dann auch X+1 N u l l i s t <= j e d e r Zahl . Falls X < Y , dann auch X+1 < Y+1. Nun ist nicht einmal klar, wie unsere Zahlen ausschauen. Aber wir können ja ein paar Zahlen ausgeben lassen: ?- zahl(X). (und ein paar mal ;). Prolog verwendet also das Herbrand–Universum. Denn falls es eine Struktur geben sollte, die Modell ist, so ist diese dort auf jeden Fall zu finden – und es sind keinerlei weitere Informationen über Konstanten und Funktionen nötig. Das für eine Struktur nötige Universum und die Interpretation der Funktionen sind damit also schon bekannt, offen bleibt noch, welche Bedeutungen den Prädikten zugeordnet wurden. Tatsächlich ist das aber gar nicht bekannt; Prolog stellt mit Resolution fest, ob eine Aussage erfüllbar ist, ohne die bedeutung der Prädikte zu kennen. Die Bedeutung ergibt sich aus den Beziehungen zueinander, die als Klauseln angegeben wurden. Wenn Prolog durch Resolution zu einer Lösung gekommen ist, werden die dazu verwendeten Unifikationen ausgegeben. Durch Anwenden der Unifikationen auf die Klauseln erhält man die Teilmenge der Herbrand-Expansion, bei der Prolog die Unerfüllbarkeit festgestellt hat, und so die Wahrheit der Abfrage beweisen konnte. Man kann beobachten, wie Prolog verschiedene Elemente der Herbrand-Expansion testet, indem man mit gtrace. den grafischen Debugger aktiviert und dann eine Abfrage (z. B. kleiner(X, s(s(null))), kleiner(s(null), X).) durchführt. 3 Ergänzungen zur Theoretischen Informatik 1.4 Vorlesung 5 – 10.05.2013 Was kann man damit tun? Zum Abschluss ein richtiges Prolog-Programm, das Sudokus löst. Es verwendet eine Library für Constraint Logic Programming over Finite Domains – diese enthält einige vordefinierte Prädikate, mit denen Prolog sehr effektiv arbeiten kann (Denn ohne diese ist es einfach, in Prolog korrekte Programme zu schreiben, die sehr langsam sind.) Ansonsten ändert sich nichts am Prinzip der Programmierung. sudoku ( Rows ) :− l e n g t h ( Rows , 9 ) , m a p l i s t ( l e n g t h ( 9 ) , Rows ) , append ( Rows , Vs ) , Vs i n s 1 . . 9 , m a p l i s t ( a l l d i s t i n c t , Rows ) , t r a n s p o s e ( Rows , Columns ) , m a p l i s t ( a l l d i s t i n c t , Columns ) , Rows = [ A, B, C, D, E , F ,G, H, I ] , b l o c k s (A, B, C) , b l o c k s (D, E , F ) , b l o c k s (G, H, I ) , m a p l i s t ( w r i t e l n , Rows ) . l e n g t h (L , Ls ) :− l e n g t h ( Ls , L ) . blocks ( [ ] , [ ] , [ ] ) . b l o c k s ( [ A, B, C| Bs1 ] , [ D, E , F | Bs2 ] , [G, H, I | Bs3 ] ) :− a l l d i s t i n c t ( [ A, B, C, D, E , F ,G, H, I ] ) , b l o c k s ( Bs1 , Bs2 , Bs3 ) . Der komplette Code kann von der Veranstaltungswebseite heruntergeladen und mit consult(’sudoku.prolog’). geladen werden. Das Programm verwendet Listen von Variablen, über die rekursive Aussagen gemacht werden können. Anders als bisher wird das Ergebnis mit dem Prädikat writeln ausgeben, die unbenannten Variablen können dann alle mit _ bezeichnet werden, dadurch werden ihre Unifikationen nicht ausgegeben. Die Datei enthält auch ein Prädikat, das ein Sudoku definiert und die Lösung ausgibt, es kann mit test. ausgeführt werden. Aufgaben 1. Suchen Sie ein Sudoku online und lößen Sie es mit diesem Programm. 2. Verwenden Sie die Hilfe von swipl um die Funktionsweise des Sudoku–Prädikates nachzuvollziehen. Kommentieren Sie jede Zeile. 3. Schreiben Sie ein eigenes Prädikat welches das folgende 4 × 4–Sudoku lößt. 2 3 4 2 4 2 4. Erkennen Sie eine besondere Form in den Zeilen der Lösung? 4