HTWM Hochschule für Technik und Wirtschaft Mittweida Technikumsplatz 17 09648 Mittweida Semester: V Prof: Prof. Schulz Künstliche Intelligenz Einführung in die Programmiersprache Prolog Mitschrift von: Isabel MaineC Drost Semester: V Fachbereich: MPI Seminargruppe: if99wp1 Massaneier Str. 55 04736 Waldheim [email protected] http://www.isabel-drost.de Einführung in die Künstliche Intelligenz Semester V Erstellt von Isabel Maine C. Drost Seite 2 von 42 Einführung in die Künstliche Intelligenz Semester V 1. Einführung..........................................................................................................................5 Zielsetzungen:..................................................................................................................................... 5 Kontroversen:..................................................................................................................................... 5 Intelligenz: .......................................................................................................................................... 5 Themen: .............................................................................................................................................. 5 Symbolische KI – Konnektionistische KI ........................................................................................ 6 Symbolische KI: .............................................................................................................................................. 6 Konnektionistische KI: .................................................................................................................................... 6 Erfolge:................................................................................................................................................ 6 Arbeitshypothese:............................................................................................................................... 6 Logik: .................................................................................................................................................. 6 Logische Programmierung:............................................................................................................... 6 Resolutionsprinzip: ............................................................................................................................ 6 2. Grundbegriffe der logischen Programmierung....................................................................7 Refutationstheorem: .......................................................................................................................... 7 Resolutionsverfahren:........................................................................................................................ 7 Klausel: ............................................................................................................................................... 7 Resolutionsregel: ................................................................................................................................ 7 Satz von Robinson:............................................................................................................................. 7 Hornklauseln: ..................................................................................................................................... 8 Wie können die Ergebnisse aussehen: ............................................................................................................. 8 2 Auswahlkonflikte sind zu lösen:................................................................................................................... 8 Selektionsregeln: ............................................................................................................................................. 8 3. Logische Programmierung – Reines Prolog......................................................................9 3.1 Syntax und Terme ................................................................................................................... 9 Terme zerfallen in: .......................................................................................................................................... 9 3.2 Unifikation von Termen .............................................................................................................. 9 Vergleich arithmetischer Ausdrücke: ............................................................................................................ 10 Ablauf des Unifikationsalgorithmus.............................................................................................................. 10 3.3 Operatoren.................................................................................................................................. 10 3.4 Prädikatenlogische Formeln 1. Stufe........................................................................................ 11 Bestandteile: .................................................................................................................................................. 11 Interpretation: ................................................................................................................................................ 11 3.5 Herbrand – Universum: ............................................................................................................ 12 3.6 Hornklausel in der Prädikatenlogik:........................................................................................ 12 3.7 Semantik logischer Programme................................................................................................ 13 Deklarative Semantik .................................................................................................................................... 14 Prozedurale Semantik .................................................................................................................................... 14 Steuerung der Verarbeitung........................................................................................................................... 16 MetaProgrammierung.................................................................................................................................... 17 Negation als Fehlschlag – Negation by failure .............................................................................................. 17 Die Prozedur repeat ....................................................................................................................................... 18 Disjunktion (entspricht dem Oder) von zwei Anfragen:................................................................................ 18 Erstellt von Isabel Maine C. Drost Seite 3 von 42 Einführung in die Künstliche Intelligenz Semester V Bedingte Anfrage ......................................................................................................................18 ; if – then – else ............................................................................................................................................. 19 4. Standardprädikate................................................................................................................20 4.1. Die Ein und Ausgabe................................................................................................................. 20 3.1.1 Edinburgh – Modell....................................................................................................................... 20 4.1.2 Konventionelles Modell der Dateiarbeit............................................................................................... 21 4.1.3 Ein und Ausgabe von Termen .............................................................................................................. 21 4.1.3 zeichenweise Ein und Ausgabe ............................................................................................................ 21 4.2 Termverarbeitung...................................................................................................................... 22 4.3 Kanonische Termordnung: ....................................................................................................... 22 4.4 Analysieren von Termen: .......................................................................................................... 23 5. Manipulation der Wissenbasis:..........................................................................................23 5.1. Assert.......................................................................................................................................... 23 5.2. Retract........................................................................................................................................ 23 5.3. Abolish........................................................................................................................................ 24 5.4. Clause ......................................................................................................................................... 24 5.5. Anwendung zum Caching......................................................................................................... 24 5.6. Modifikation der Wiederholenfunktion zum Mitzählen, wie oft iteriert wurde:................ 24 6. Programmierstil ...................................................................................................................25 6.1. Effizienz...................................................................................................................................... 25 6.1.1. Effizienz in Prolog............................................................................................................................... 25 6.1.2 Drei Optimierungsverfahren vom Prologsystem .................................................................................. 25 7. Rekursion durch Iteration...................................................................................................27 7.1 Kopfgesteuerte Schleife ............................................................................................................. 27 7.2 Endgeprüfteschleife ................................................................................................................... 27 7.3. Akkumulation und Übergabe................................................................................................... 28 Differenzlisten ............................................................................................................................................... 28 8. Problemlösung durch Suche ...............................................................................................29 Problemlösen: ................................................................................................................................... 29 Vorgehensweise: ............................................................................................................................... 29 Grundlegende Suchalgorithmen ..................................................................................................... 30 Tiefensuche.................................................................................................................................................... 30 Breitensuche .................................................................................................................................................. 31 Tiefensuche mit beschränkter Suchtiefe:.................................................Fehler! Textmarke nicht definiert. Einfügung wegen Krankheit von Ronny ............................. Fehler! Textmarke nicht definiert. 9. Prolog als Regelinterpreter..................................................................................................33 Erstellt von Isabel Maine C. Drost Seite 4 von 42 Einführung in die Künstliche Intelligenz Semester V Sicstus – Key – ncxWDFQ2 1. Einführung TuringTest: Können Maschinen eigentlich denken. Man setze einen Frager an einen Rechner. Die Fragen werden von einem Menschen und von einer Maschine beantwortet, kann der Frager Maschine und Mensch nicht unterscheiden, kann die Maschine denken ;-) 1956 – Dartmouth Conference – Etablierung der neuen Disziplin Artificial Intelligence Anfangserfolge: • LogicTheorist • Checkers Program (DameSpiel) Grandiose Versprechungen, Erfolge erst nach Jahren (DeepBlue als Schachrechner in den 90ern) Zielsetzungen: • • • • Systeme mit menschlichem Denken treffen von Entscheidungen, Lösen von Problemen, Lernen Systeme mit rationalem Denken Studium von mentalen Fähigkeiten, durch die Nutzung von Rechnermodellen Systeme mit menschlichem Verhalten Rechner sollen Dinge tun, die derzeit nur Menschen tun können Systeme mit rationalem Verhalten Automatisierung von intelligentem Verhalten Kontroversen: • • Mensch versteht sich als intelligentes, denkendes Wesen diverse Zielstellungen Intelligenz: • • • • • Reflexion über sich selbst ist Gegenstand des Interesses des Menschen keine befriedigende Antwort daher auch keine Antwort auf die Frage: "Was ist künstliche Intelligenz" bis Mitte der 20er Jahre wurden Maschinen zu physischen Leistungen herangezogen (Dampfmaschinen, Webmaschinen...) Mit dem Erscheinen des Computers, wird es realistischer, an eine denkende Maschine zu denken. Themen: • • • • • • • • • • • • automatisches Problemlösen und Beweisen SpieleProgrammierung Suchen und Planen Verarbeitung der natürlichen Sprache Wissensrepräsentation und –verarbeitung (Kernstück, praktische Anwendung sind die folgenden Expertensysteme) Expertensysteme (Diagnosesysteme, Qualitätskontrolle) Schlußfolgerungen und Entscheiden bei Unsicherheiten Bild- und Mustererkennung Lernen Robotik Softwareagenten (Suchmaschinen ...) ... Erstellt von Isabel Maine C. Drost Seite 5 von 42 Einführung in die Künstliche Intelligenz Semester V Symbolische KI – Konnektionistische KI Symbolische KI: machinelle Inelligenz durch Symbol – Manipulation symbolische Wissensdarstellung Basis: Logik Konnektionistische KI: subsymbolische Wissenverarbeitung maschinelle Intelligenz durch Zusammenspiel vieler einzelner Bausteine (Neuronale Netze als Ansatz) Erfolge: • • • an eigenen Ansprüchen gemessen bescheiden unvoreingenommen betrachtet unbestreibar Beispiele: DeepBlue, graphische Benutzeroberflächen, Prototyping, Entwicklungsumgebungen, Objektorientierung ... Arbeitshypothese: Durch Manipulation von Symbolen sind Schlußfolgerungen möglich, auch wenn sich daraus keine Intelligenz ergibt. Logik: 0322 Aristoteles: 1854 Boole: 1879 Frege: 1930 Gödel: 1965 Robinson: 1973 Colmerauer: 1974 Kowalski: Logik, Gesetzmäßigkeiten des formalen Schlußfolgerns Laws of Thought – Boolsche Algebra Begriffsschrift – Prädikatenkalkül Vollständigkeitssatz, Unvollständigkeitssatz MachineOriented Logic PROLOG PredicateLogic as a Programming Language Logische Programmierung: Programmierung mit logischen Formeln – Hornklauseln Folgerung:-Bedingungen. (Regel) Fakt. ?-Anfrage. Resolutionsprinzip: Anfrage ?-A. wird durch Regel A:-B. auf Anfrage ?-B reduziert und mit Fakt B. bewiesen. Kowalski: Algorithm = Logic + Control. Erstellt von Isabel Maine C. Drost modus ponens: a:-b. b. a. Seite 6 von 42 Einführung in die Künstliche Intelligenz Semester V 2. Grundbegriffe der logischen Programmierung Refutationstheorem: Für eine Aussage P1..., Pn und S ist die Formel P11..., Pn->S genau dann allgemeingültig wenn die Formelmenge {P1,...Pn NOT S} unerfüllbar ist. (Man beweise, dass sich aus den P S ergeben muß, indem man beweist, dass das Gegenteil sich nicht aus den Aussagen ergibt) Resolutionsverfahren: Formelmenge wird systematisch ausgewertet mit dem Ziel, einen Widerspruch zu finden. (Kann ich mithilfe von noch zu erklärenden Mitteln eine Aussage x als auch ihr Gegenteil mit den Prämissen zu basteln, so ist ein Widerspruch in den Prämissen vorhanden.) Definition: Eine Aussagenvariable oder negierte Aussagenvariable heißen Literale. A und sein Gegenteil heißen komplementäre Literale. ¬A Klausel: Disjunktion (Oderverknüpfung) von Literalen. Beispiele: A||B, A||B|| !C, A, !A Disjunktion ohne Elemente ist die log. Konstante false und wird mit abgekürzt, entspricht der leeren Klausel. Resolutionsregel: Zwei Klauseln enthalten je ein Element eines komplementären Paares von Literalen, die Klausel aus allen Literalen beider Ausgangsklauseln ohne das komplementäre Paar heißt Resolvente. Elternklauseln: A || B1 || B2 || !A || C1 || C2 || = B1 || B2 || ... || Bn ... || Cm ... || Bn || C1 || C2 || ... || Cm Resolutionsregel ist korrekt A || B !A || C B || C (A || B) && (!A || B) (B || C) Aus A folgt B läßt sich ersetzen durch: !A||B Jede Aussagenlogische Formel kann in eine äquivalente Formel überführt werden, die nur &&, || und ! enthält und dann durch "ausmultiplizieren" äquivalent in die sog. konjunktive Normalform überführt werden: Konjunktion durch Disjunktionen: logisches X ... (A1 || ... || An) && (B1 || ... || Bn) && ... && (C1 || ... || Cn) (A, B und C sind dabei Literale) Jede Aussagenlogische Formel ist äquivalent zu einer Menge von Klauseln {K1, K2, ... Kn}. Satz von Robinson: Klauselmenge ist genau dann unerfüllbar, wenn in endlich vielen Resolutionsschritten die leere Klausel abgeleitet werden kann. Beispiel: R beweisen als Folgerung 1) (Q-> P || R) 2) (P-> R) 3) Q || R) Erstellt von Isabel Maine C. Drost 1) 2) 3) 4) (!Q || P || R) (!P || R) (Q || R) (!R) .......... Ziel ist einen Seite 7 von 42 Einführung in die Künstliche Intelligenz Semester V Widerspruch zu erzeugen Resolution (1 + 2) -> (5) (!Q || R) Resolution (5 + 3) -> (6) (R) Resolution (4 + 2)-> Widerspruch -> R ist Folgerung ovn 1, 2 und 3 Hornklauseln: HornKlauseln sind solche Klauseln mit höchstens einem unnegiertem Literal. S || !B1 ... || !Bn S:- B1, ... Bn. S wird geschrieben S. und ist ein Fakt. !B1 || ... || !Bn wird geschrieben: ?- B1, ... ,Bn und ist eine Anfrage leere Klausel S:- B1, ... Bn. S || !B1 || ... || !Bn S || !(B1 && ... && Bn) (B1 && ... && Bn) -> S Regel drückt aus: falls alle Bedingungen Bi wahr sind, so ist auch S wahr. Fakt sagt aus, dass die formulierte Relation wahr ist. !B1 && ... && !Bn !(B1&& ... && Bn) Das heißt, Anfrage ist Verallgemeinerung der Aussage, dass alle Bi wahr sind. Wenn aus einer Anfrage mithilfe von Fakten und Regeln die leere Klausel erzeugt werden kann, dann folgt daraus: !(B1&& ... && Bn) ist falsch und (B1&& ... && Bn) ist wahr. Mit den Hornklauseln entsteht mit den Resolutionsschritten ein sog. lineares Resolutionsverfahren: Eine Anfrage ist immer eine Elternklausel, eine Programmklausel (Regel oder Fakt) ist eine zweite Elternklausel. Anfrage hat nur negierten Literale, eine Programmklausel hat ein negiertes Literal. Bei der Resolution ergibt sich eine Anfrage – das negierte Literal in der Programmklausel, wenn vorhanden, fällt heraus. In brief: Resolutionsschritte mit einer Anfrage und einer passenden Programmklausel liefern neue Anfrage. Wie können die Ergebnisse aussehen: • • • Durch die Resolutionsschritte wird die leere Klausel erhalten, durch Resolution mit Fakten. Dann ist die Anfrage abgeleitet und bewiesen worden (Prolog sagt yes) Anfrage ist nicht leer, aber es gibt keine passende Programmklausel. Dann kann ich noch via Backtracking suchen, ob es noch Alternativen zu dem begangen Weg gibt. Verfahren bricht nicht ab. 2 Auswahlkonflikte sind zu lösen: ?- B1,..., Bn • • logischesProgramm mit Fakten und Regeln welches Literal soll durch Resolution verschwinden welchen Fakt oder welche mögliche Regel soll ich verwenden, um das Literal wegzubekommen Selektionsregeln: • • • in der Anfrage wird das am weitesten links stehende Teilziel ausgewählt zur Resolution geeignete Klauseln (Fakten oder Regeln) im Programm werden von oben nach unten gesucht. Bei Mißerfolg (Anfrage ohne passende Klausel), wird Backtracking zur vorhergehenden Anfrage durchgeführt und nach obigen Regeln weiter nach Alternativen gesucht Erstellt von Isabel Maine C. Drost Seite 8 von 42 Einführung in die Künstliche Intelligenz Semester V 3. Logische Programmierung – Reines Prolog 3.1 Syntax und Terme • • • Terme enthalten einen einheitlichen Datentyp der logischen Programmiersprache Großbuchstaben entsprechen Variablen Kleinbuchstaben entsprechen Fakten Terme zerfallen in: • • • • • • • • • • einfach Terme - Atome sind entweder Namen oder Bezeichner (müssen mit kleinem Buchstaben beginnen) oder quotierte Atome (beliebige Zeichenfolgen, die mit einfachen Quotes auskommentiert werden: 'Max', 'Max und Moritz') oder Symbole (spezielle Sonderzeichen und Folgen von Sonderzeichen, die für bestimmte Operationen vorbelegt sind. Kommata, ?- ; :- ; \= ; =:= ; =.. ; ...) - Zahlen (Ganze Zahlen bis in sehr hohe Bereiche und Gleitkommazahlen aus dem drunterliegendem CSystem) - Variablen (beginnen mit einem Großbuchstaben) Strukturen Variable sind mathematische oder logische Variable, keine Speicherplätze im Sinne der Informatik. Sie sind Platzhalter für einen im Moment noch unbekannten Term. Variable können zwei Zustände haben: ungebundene oder gebundene Variable. Ungebunden ist ein typischer Platzhalter für einen noch nicht bekannten Term. Ein Unterstrich steht für die anonyme Variable, auf deren Inhalt man nicht zugreifen kann. Jedes Vorkommen von ihr entspricht logisch einer anderen Variablen. Der Gültigkeitsbereich von Variablennamen ist jedesmal die Klausel (der Fakt, die Regel oder die Anfrage). Stukturen sind aufgebaut aus einem sog. Funktornamen (Strukturname), der verschiedene Argumente haben kann: Funktorname(_, _, _, _) Die Argumente sind beliebige Terme Funktornamen sind beliebige Atome Funktoren sind Funktorname zusammen mit der Anzahl der Argumente (die Stelligkeit): Funktor: Funktorname/ N nullstellige Struktoren sind Atome Kanonische Termordnung: @< Variable @< Gleitkommazahlen @< ganzen Zahlen @< Atomen @< Strukturen Variable nach Entstehen geordnet, Zahlen in arithmetischer Ordnung (<), die Atome in lexikographischer Ordnung anhand der ASCII-Tabelle, Stukturen werden nach Funktionsnamen, Stelligkeit und Argumenten geordnet. 3.2 Unifikation von Termen Substitution: {V <- T} Variable V wird durch den Term T ersetzt. Instanz eines Terms T1 ist ein Term T2, der aus T1 durch endlich viele Substitutionen entsteht. Beispiel: punkt(x,1) {x<-2} punkt(2,1) /*ist Instanz der ersten Beispielzeile*/ Bei f(x) darf x dabei aber nicht ersetzt werden durch f(x). Erstellt von Isabel Maine C. Drost Seite 9 von 42 Einführung in die Künstliche Intelligenz Semester V Substitutionen sind dann zulässig, wenn Variable nicht im zu substituierenden Term T vorkommt! Der Test hierfür nennt sich Occurs-Test. Dieser wird aber im PrologSystem nicht durchgeführt aus Rechenzeitgründen. {V1 <- V2} (V sind Variable) Effekt: Variablen verschmelzen zu einer gemeinsamen Variablen. Zwei Terme sind unifizierbar, wenn es eine gemeinsame Instanz gibt, d.h. wenn man solche Variablenbindungen finden kann, dass beide Terme syntaktisch identisch werden. punkt(X,1) punkt(2,Y) punkt(2,1) punkt(X, 1) punkt(2,3) punkt(x,1) punkt(x,y) sind unifizierbar: {x<-2, y<-1} ist der Unifikator sind nicht unifizierbar sind unifizierbar mit unendlich vielen Unifikatoren. Ein allgemeinster Unifikator gilt: {x<-y, z<-1}, dieser ist eindeutig bis auf Variablenumbenennungen Die Abfrage dazu: ?- Term1 = Term2. "=" ruft die Unifikation auf ?- Term1 = Term2. ist yes sofern unifizierbar ?- Term1 \= Term2. ist yes bei nichtunifizierbaren Termen, sonst no Term is Ausdruck X is 1+2*(3-2) Auswertung des Ausdrucks, Term wird mit Ergebnis unifiziert (z.B. 1+1 is 2.) X=3 Vergleich arithmetischer Ausdrücke: =:= Wertgleichheit =\= Wertungleichheit < Kleiner als <= > >= Ablauf des Unifikationsalgorithmus (vereinfachter Algorithmus von Herbrand) (1) zwei syntaktisch identische einfache Terme (einfache Terme: Atome, Variablen, Zahlen) sind ohne Substitution unifizierbar. (2) eine ungebundene Variable V und ein von ihr verschiedener Term T sind unifizierbar mit der Substitution {V<- T} (3) Zwei Struckturen sind unifizierbar, wenn Funktorname uns Stelligkeit gleich sind: f(arg11, arg12, ... arg1n) f(arg21, arg22, ... arg2n) und alle entsprechenden Paare von Argumenten sind unifizierbar. Zusätzlich müsste ein Occurscheck durchgeführt werden, nicht jedoch in Prolog eingesetzt. 3.3 Operatoren Funktornamen, Symbole mit spezieller Syntax +(1,2) +(1,x(2,3) ... 1+2 ... 1+2*3 Erstellt von Isabel Maine C. Drost Seite 10 von 42 Einführung in die Künstliche Intelligenz Semester V Infixoperatoren: zweistellige Operatoren zwischen Operanden Präfixoperatoren: einstellige Operatoren vor Operand (-3) Postfixoperatoren: einstellige Operatoren nach Operand (n!) Syntaxtransformation zwischen Standard- und Operatorsyntax leistet ein expressionhandler auf der Basis einer Operatorentabelle. Assoziativität: regelt Klammerung von Operatoren. ?- display(Term) zeigt den Standardsyntax an ?- op(Assoziativität,Prio, Funktornamen) op(xfx, 300, mag). ... anna mag otto anstelle von mag(anna, otto). Präzedenz (Priorität): regelt den Vorrang der Bindungstakte 1...1200 je kleiner die Priorität, umso stärker die Bindung Bsp: 1+(2*3) oder +(1, *(2,3)) Listen sind spezielle Terme: [ ] ... leere Liste [Kopf | Rest] for .(Kopf, Rest) ist Liste, falls Rest eine Liste ist. [X1,X2] = [X1| [X2 | [ ] ] ] = .(X1, .(X2, [ ])) Listenmuster: [X1, X2, ... , Xn | Var] .(X1, .(X2, ... , .(Xn | Var) ... )) Unifizierungsregeln für 2Listen: • gleiche Anzahl von Elementen • entsprechende Elementepaare sind unifizierbar Unifizierungsregel für 1 Liste und ein Listenmuster: • [a1, ... an] • [b1, ... bm | X] X ist leere Liste [ ], falls n=m ai = bi, i=1 ... m <= n X ist [am+1 ... an] für m<n 3.4 Prädikatenlogische Formeln 1. Stufe Bestandteile: • • • • • • Bezeichner für Individuen, einzelne Objekte, Dinge, Begriffe (Namen, Symbole) Individuenvariablen (Platzhalter für einzelne Dinge, Bezeichner mit Großbuchstaben am Anfang) Funktionen (Funktionsnamen, spielen nur die Rolle von Datenstrukturen) Prädikate (Prädikatennamen) Junktoren (not, and, or ...) Quantoren (Für alle gilt, exist) Interpretation: Zuordnung von Elementen zu einer Grundmenge G • Individuenbezeichner und unquantisierte Variable werden zu Elementen der Grundmenge zugeordnet • Funktionenbezeichner werden konkreten Abbildungen von je n Elementen der Grundmenge in Grundmenge zugeordnet: f: GxGxG ... xG -> G • Prädikatenbezeichner werden konkreten Prädikaten zugeordnet: pred: GxGx ... xG -> {true || false} Interpretation heißt Modell einer Formelmenge, wenn alle Formeln zu wahren Aussagen werden. Erstellt von Isabel Maine C. Drost Seite 11 von 42 Einführung in die Künstliche Intelligenz Semester V In logischen Programmiersprachen: ausgehend vom Problem (als Modell) finde ich: • Namen für Individuen • Namen für Datenstrukturen • Namen für Prädikate Formelmenge, für das die Ausgangsproblem ein Modell darstellt (falls fehlerfrei). 3.5 Herbrand – Universum: Definition: Grundterm heißt ein Term, der keine Variablen hat. Grundterme können sein: Funktionengrundterme, Prädikatengrundterme Das Herbranduniversum einer Formelmenge ist die Menge aller Funktionengrundterme aus den Namen/ Bezeichnern und Funktionsnamen, die in dieser Formelmenge vorkommen. Schalterbeispiel: schaltvorschrift( ein, hell, hell, hell). ... signal(hell). signal(dunkel). signal, schaltvorschrift ... Prädikatenname hell, dunkel ... Individuen Herbranduniversum: {ein, aus, hell, dunkel} Natürliche Zahlen: nat(0). nat(s(N)):- nat(N). (s ist hierbei ein Funktionsbezeichner) Herbranduniversum ist hier unendlich: {0, s(0), s(s(0)) ... } Satz von Herbrand: Klauselmenge ist genau dann unerfüllbar, wenn keine Herbrandinterpretation ein Modell ist. Eine Herbrandinterpretation: • Grundmenge ist Herbranduniversum • Konstanten und Funktionsnamen stellen sich selbst dar • Zuordnung der Prädikatennamen zu Prädikaten (Abbildungen in true und false) ist frei wählbar Variablen in der logischen Programmierung stehen für alle Terme des Herbrandunivserums. 3.6 Hornklausel in der Prädikatenlogik: prädikatenlogische Literale: • • Prädikatenterme und negierte Prädikatenterme Komplementarers Paar von Literalen sind zwei Literale A1 und !A2 wobei A1 und A2 unifizierbar sind. Hornklauseln: sind Terme mit speziellen Operatoren Fakten: Prädikatenterm . ... sagt aus, dass die formulierte Beziehung wahr ist für alle möglichen Variablenbin- dungen an Terme des Herbranduniversums. Beispiel: schaltvorschrift(ein, hell, S, S). Regeln: folgerung(...) :- bedigung1, bedingung2 ... ist Operatorschreibweise für: :- (folgerung(...), (bedinung1, bedingung2 ...) sagt aus, dass die auf der linken Seite beschriebene Folgerung stets wahr ist, wenn alle Bedingungen auf der rechten Seite zutreffen für alle möglichen Variablenbindungen. Fakten fassen wir bei Bedarf auf als "Regeln" Fakt:-true. (Symbol für TRUE ist true) logische Prozeduren: besteht aus allen Fakten und Regeln mit dem gleichen Prädikatennamen im Schlußfolgerungsterm. Erstellt von Isabel Maine C. Drost Seite 12 von 42 Einführung in die Künstliche Intelligenz Semester V log Prozedur { member(E,[E | _] ). member(E,[_ | E]). member(E,R). Anfragen: ?- Bed1, ... Bedn ist Operatorsyntax für den Term: ?- ((Bed1, ... Bedn)). Anfragenklausel aus negiertem Literal: ∀Variablen1 (!Bed1 || !Bed2 || ... || !Bedn) Variablen1 = alle Variablen in den Bedingungen ∀Variablen1 !(Bed1, Bed2, ... , Bedn) ¬∃ Variablen(Bed1, Bed2, ..., Bedn) d.h. Anfrage, Verneinung der Aussage: es gibt Variablenbindungen, so dass alle Bedingungen gleichzeitig wahr sind. Wenn aus Anfrage und Programm leere Klausel gefunden wird, Widerspruch erzeugt wurde, dann: Verneinung ist falsch, also (Bed1, ... , Bedn) wahr und zwar genau für die gefundene Variablenbindung. Bedeutung der Anfrage: "Gibt es Variablenbindungen, so dass alle foumulierten Bedinungen wahr werden?" (Implizite) Allquantisierung aller Variablen in den Klauseln hat zur Folge, dass jeder Variablenname nur lokal innerhalb einer Klausel gültig ist. Regelkopf :- Regelkörper ?- Ziele Folgerung :- Bedingungen 3.7 Semantik logischer Programme Resolution in Prädikatenlogik: zwei Elternklauseln: ( A1 || B1 || ... || Bn) (¬A2 || C1 || ... || Cm) wobei A1 und A2 unifizierbar sind (gleicher Prädikatenname und unifizierbare Argumentpaare) liefern Resolvente (B1' || ... || Bn' || C1' || ... || Cm') wobei die Bi' und Cj' aus Bi und Cj entstehen durch Anwendung des allgemeinsten Unifikators von A1 und A2. Resolution ist korrekt: wenn Elternklauseln bei einer Interpretation wahr sind, so ist auch Resolvente bei dierser Interpretation wahr. Resolution ist vollständig: Klauselmenge ist unerfüllbar genau dann, wenn in endlich vielen Resolutionsschritten die leere Klausel gefunden werden kann. Wie bei Aussagenlogik: Beschränkung auf Fakten, Regeln und Anfragen liefert ein lineares Resolutionsverfahren: eine Anfrage + passender Fakt bzw. eine passende Regel liefern eine neue Anfrage. Es sind mehrere Ausgänge möglich: • leere Klausel: Erfolg • Anfrage aber keine passenden Programmklauseln: Sackgasse, Backtracking • unendliches Verfahren Beispiel: mensch(turing). mensch(sokrates). grieche(sokrates). fehlbar(X):-mensch(X). ?- fehlbar(Y), grieche(Y). >Y=turing >Y=sokrates >leere Klausel: Erfolg Ergebnis: Y=sokrates Erstellt von Isabel Maine C. Drost Konstanten: turing, sokrates Variablen: X log. Prozeduren: mensch, grieche (bestehend aus Fakten) und fehlbar (Regel) Herbranduniversum: {turing, sokrates} > mensch(Y),grieche(Y) > mensch(turing), grieche(turing)=false (Sackgasse) >mensch(sokrates), grieche(sokrates)=true Seite 13 von 42 Einführung in die Künstliche Intelligenz Semester V Deklarative Semantik ... ist die Menge aller Prädikatengrundterme, die durch endlich viele Resolutionsschritte als Folgerung eines logischen Programms gefunden werden. Beispiel: alle PrädikatenGrundterme im Beispiel fehlbarer Grieche: mensch(sokrates), mensch(turing), fehlbar(sokrates), fehlbar(turing), grieche(sokrates) > deklarative Semantik Vorgehensweise zum Nachweis eines Ziels/ Bedingung als Element der deklarativen Semantik: 1) wenn ein unifizierbarer Fakt vorhanden ist, Ende mit Erfolg 2) wenn Regel vorhanden ist mit unifizierbarem Regelkopf, weise alle Bedingungen des Regelkörpers nach, wobei vorher die Variablensubstitutionen entsprechend der Unifikation angwandt worden 3) Anfrage aus mehreren Bedingungen wird gelöst durch Bearbeitung jedes einzelnen Ziels/ Bedingung Prozedurale Semantik • • beschreibt systematische Auswertung von Anfragen an logische Programme Folge der konkreten Verarbeitungsschritte die Anfrage an log. Programm auslöst, wird bestimmt durch PROLOG - Verarbeitungsstrategie: - Ziele von Anfragen/ Bedingungen in Regeln werden "von links nach rechts" ausgewertet - passende Fakten/ Regeln werden "von oben nach unten" verwendet - falls Ziel/ Bedinung nicht nachgewiesen werden kann, dann erfolgt Backtracking zum vorherigen Ziel und dort Suche nach weiteren Lösungen Definition: Ist die Folge der Verarbeitungsschritte, die eine Anfrage an ein logisches Programm auslöst. Pseudocode: Eingabedaten: eine Anfrage an ein log. Programm Ausgabedaten: Erfolg und eine Lösung oder Fehlschlag Algorithmus: begin {Prozedur} falls(Anfrage keine Ziele mehr hat)> dann beende mit Erfolg; sonst begin(Auswertung der Anfrage) nimm erstes Ziel von Anfrage als aktuelles Ziel nimm übrige Ziele von Anfrage als restl. Ziele solange (akutelles Ziel nicht Erfolg und Programm hat unbenutzte Klauseln) begin(Auswertung des akt. Zieles) nimm nächste unbenutzte Klausel in Prog. als aktuelleKlausel; nimm Kopf von aktuelleKlausel; unifiziere aktZiel mit Kopf und ermittle Unifikator falls (Unifikator existiert) begin (Auswertung einer neuen Anfrage) nimm Klauselkörper von aktuellKlausel; binde neueAnfrage aus Klauselkörper und reslZiele; wende Unifikator auf neueAnfrage an; rufe Auswertgsprozedur für neueAnfrage an Progr.; falls (neueAnfrage Erfolg hat) gib LösungvonneueAnfrage und Unifikator als Lösung zurück und beende mit Erfolg; ende(Auswertung der neuenAnfrage ende (Auswertung des aktuellenZiels) falls (aktuellesZiel nicht Erfolg hat) > dann beende mit Fehlschlag ende (Auswertung der Anfrage) ende(Prozedur) Prozedurale Semantik wirkt sich aus auf: • Reihenfolge der Lösungen • Effizienz der Auswertung Ideal: ProzeduraleSemantik = Deklarativer Semantik (mit effizienter prozeduraler Semantik) Erstellt von Isabel Maine C. Drost Seite 14 von 42 Einführung in die Künstliche Intelligenz Semester V Beispiel zu den Auswirkungen: Familienbeispiel ?-mutter (wer, Robert); 1. Variante: mutter(X,Y):elternteil(X,Y), weiblich(X). 1. Variante ist effizienter, da hier weniger Unifikationen ausgeführt werden müssen. (Es gibt nur eine Mutter von Robert, jedoch 50% weibliche Personen, die daraufhin auch noch auf die Eigenschaft Eltern geprüft werden. 2. Variante: mutter(X,Y):weiblich(X), elternteil(X,Y). Reihenfolge von Bedingungen in der Regel/ Zielen in Anfragen bestimmt sowohl die Reihenfolge der Lösungsfindung als auch Effizienz des Auswertens. Hinweis: möglichst Ziele mit wenigen Lösungsalternativen vor Zielen mit vielen Lösungsalternativen anordnen. SLD – Bäume: • enthält als Knoten alle Remutter(wer, robert) solventen, die bei der Auswertung einer Anfrage an ein logisches Programm elternteil(Wer,robert), entstehen können. weiblich(Wer) • Wurzelknoten ist Knoten mit der ursprünglichen Anelternteil(thomas, robert) elternteil(heike, robert) frage weiblich(thomas). Wer=heike • jede Kante repräsentiert einen Resolutionsschritt weiblich(heike). weiblich(thomas). unter Verwendung des ersten Ziels der Anfrage in diesem Knoten • Blätter (Knoten ohne ?-. %leere Anfrage, Erfolg Nachfolger) können zwei Situationen darstellen: - leere Anfrage entspricht Erfolg; Zurückverfolgung des Weges zur Wurzel erlaubt das Aufinden der konkreten Lösungsvariablenbindungen - nichtleere Anfrage: Mißerfolg, ab dem Backtracking ausgelöst wird • wenn der SLD-Baum so aufgebaut wird, dass die Kanten von links nach rechts der Reihenfolge der verwendeten Klauseln im Prog. darstellen, dann entspricht die Auswertungsprozedur einer "Tiefensuche" mit der Strategie "Links zuerst" Steuerprozedur: repeat. repeat:- repeat. hat beliebig oft Erfolg, solange man will. Ist ein nichtdeterministisches Prädikat. Beispiel: echo:repeat, read(X), write(X), fail. fail ... gelingt nie und löst Backtracking aus, read und write gelingen nur einmal somit kann ich unendlich mal das rausschreiben, was ich eingebe Ergebnis: Endlos – Echo – Schleife Erstellt von Isabel Maine C. Drost Seite 15 von 42 Einführung in die Künstliche Intelligenz Semester V Boxmodell für trace erstmalige Anfrage der Prozedur CALL FAIL Verlassen mit Erfolg r edu r oz P e sch l ogi EXIT REDO engültiges Scheitern des Aufrufes Rückkehr zur Prozedu durch Backtracking (weitere Ausführungen siehe Script) Steuerung der Verarbeitung • • Reihenfolge von Zielen und Bedingungen spielt eine Rolle Reihenfolge von Klauseln innerhalb einer log. Prozedur ist von Bedeutung ! (cut) – beschneidet den Suchbaum durch Vernichtung best. Alternativen bei der Auswertg eines Ziels. Ist ein völlig außerlogisches Programm, das nur prozedural erklärt werden kann. Begriff: Ziel einer Anfrage, das bei der Auswertung mit dem Kopf einer Regel unifiziert wird, deren Regelkörper einen "!" enthält, heißt "Elternteil des cut". Beispiel: ?- a,b. ... a:- c, !, d. Das a in der Anfrage hier ist Elternteil des cut. Wirkung des !: Es wirkt wie ein logisches True, wenn ich über den Callport in die Prozedur reinkomme und wie ein Fail für das Elternziel, wenn ich durch den REDO Port reinkomme: TRUE ur zed Pr o e i sch l og TRUE FAIL Cut als Bedingung einer Regel macht alle Resolutionsschritte seit Auswertung des Elternziels definitiv im Sinne von "ohne Alternative". Die Alternativen werden einfach vernichtet. Beispiel: − 1 fürX < −1 f ( x) = 0 für − 1 <= X <= 1 1 fürX > 1 f(x,-1) :- x<(-1),!. f(x,0) :- -1<=x<=1,!. f(x,1) :- x>1. Hier erfolgt der Cut zur Effizienzsteigerung. f(x,-1):- x<(-1),!. f(x,0) :- x=<1,!. f(x,1) . Weitere Effizienzsteigerung. Ist aber gefährlich z.B. bei: f(-5, Umgang mit dem Cut: Setze zwar Cuts, aber wenn Du das tust, lasse keine Bedingungen weg, um keine roten Cuts zu erzeugen. Allgemeines Muster für "sichere" cuts: falls A1, dann Z sonst falls A2, dann Z sonst falls A3, dann Z ... sonst Z. Erstellt von Isabel Maine C. Drost Alle AN werden hier als Wächter bezeichnet. Z:-A1,!, BN1. Z:-A2,!, BN2. Z:-AN,!. Z. Seite 16 von 42 Einführung in die Künstliche Intelligenz Semester V MetaProgrammierung Term: einheitliche Datenstruktur für Daten und Programme im Prolog ist es leicht Programme zu schreiben, die Programme verarbeiten Beispiel: call(Anfrage):- Anfrage. once(Anfrage):- Anfrage, !. once hat genau einmal Erfolg – wenn Anfrage Erfolg hat – und liefert dann die 1. Lösung. Hat die Anfrage keine Lösung, so hat auch once keine Lösung. Weitere Prozeduren: true. (ist genau einmal wahr) fail. oder false. Beispiel: ?-elternteil(X,Y), write(X),write(Y), nl, fail. Ergebnis: thomas, heike ... no alle_Eltern:write('alle Paare von Eltern und Kind'), nl, elternteil(X,Y), write(X – Y), nl, fail. alle_Eltern:- write('Das waren alle Paare'),nl. Das ist Beispiel zu "Generator-fail-Schleife" Generator, ... Backtracking, bis alle Lösungen von Generatro aufgezählt sind fail. Negation als Fehlschlag – Negation by failure \+ (oder not) \+ (Ziel):- Ziel, !, fail. \+ (_). \+ (Ziel) gelingt genau dann, wenn Ziel fehlschlägt. Beispiel: is_kinderlos(Person):- \+ elternteil(Person, _). Negierte Bedingung können keine Lösungen erzeugen. Negierte Bedingungen können nur testen. (is_kinderlos(Wer). geht nicht.) Sinnvoller Einsatz von \+: ..., Generator, ... , Test, ... Einsatz nur zum Testen generierter Lösungen: person(P):-maennlich(P). person(P):-weiblich(P). person(P), ist_kinderlos(P). Erstellt von Isabel Maine C. Drost Seite 17 von 42 Einführung in die Künstliche Intelligenz Semester V Die Prozedur repeat repeat. repeat:- repeat. hat beliebig oft Erfolg Einsatz Fall: endlosSchleife:repeat, ... fail. Endgeprüfte Schleife: repeat, ... read(T), write(T), abbruchtest,!. abbruchtest:write('nochmal(j/n?'), read(Ant), Ant=n. Disjunktion (entspricht dem Oder) von zwei Anfragen: ; (Ziel1;Ziel2) :- Ziel1. (Ziel1;Ziel2):- Ziel2. generiert erst alle Lösungen von Ziel1 und danch alle Lösungen von Ziel2. Die Bindung ist schwächer als von ",". (Ziel1,Ziel2, ZielI);(ZielI1, ...) Klammern entsprechen der impliziten Klammerung, um diese zu vermeiden, müßte man selber die Klammern korrekt setzen. ?- (weiblich(X) ; maennlich(X)), ist_kinderlos(X). Layout von Disjunktionen: [...] ( .......... ; ........... ), [...] ?- person(X):(weiblich(X) ;maennlich(X) ). Bedingte Anfrage (Wenn -> Dann):- Wenn,!,Dann. • erst wird Wenn ausgeführt, dann wird Dann ausgeführt. • erzeugt sämtliche Lösungen von dem Ziel Dann mit der ersten Lösung von Wenn • Geht das Wenn schon schief, dann hat die gesamte Struktur keinen Erfolg. Hat Wenn aber Erfolg, so wird mit seiner ersten Lösung Dann ausgeführt. Danach scheitert dann wieder das gesamte Konstrukt. • Wird vor allem dann verwendet, um einen evtl. schlechter zu interpretierenden ! einzusparen. Erstellt von Isabel Maine C. Drost Seite 18 von 42 Einführung in die Künstliche Intelligenz Semester V ; if – then – else (Wenn -> Dann; Sonst):- Wenn, !, Dann. (Wenn -> Dann; Sonst):- Sonst. Allgemein übliche Definition des Maximum: max(X,Y,Z):(X>Y -> Z=X ; Z=Y ). Erstellt von Isabel Maine C. Drost Seite 19 von 42 Einführung in die Künstliche Intelligenz Semester V 4. Standardprädikate "Systemfunktionen", built-in-predicats • teilweise in C realisiert, teilweise selbst schon in Prolog Handhabung Ein-/Ausgabe arithmetische Berechnungen Steuerung der Auswertung von Anfragen Manipulation von Termen und Programmen Standardprädikate erfordern im allg. bestimmte Aufrufmuster. Dafür gibt es drei Beschreibungszeichen: +: Eingabeargument beim Aufruf muß passender Term stehen -: Ausgabeargument muß ungebundene Variable sein ?: beliebiges Argument Verhaltensweise beim Backtracking: • deterministisch (nicht backtrackfähig) Aufruf hat maximal eine Lösung, somit höchstens einmal Erfolg. Beispiel für nichtdeterministisch: ?-member (X,[a,b,c]). -> kann a, b und c als Lösung haben. • nicht deterministisch Aufruf kann prinzipiell mehr als einmal Erfolg haben und Lösungsalternativen generieren. Beispiel für deterministisch: ?- fakultaet(5,X). -> 120 • Prozedurname/ Stelligkeit beschreibt die Prozeduren danach wird das Backtrackingverhalten angegeben, das Aufrufmuster permutation/2 nicht deterministisch/ permutation(+Liste1, ?Liste2). generiren und testen von Permutationen 4.1. Die Ein und Ausgabe • über Ströme geregelt 3.1.1 Edinburgh – Modell userinput useroutput • Es gibt immer aktuellen Ein- und aktuellen AusgaprologEingabedatein bestrom system • beim Systemstart sind user_input und user_output Ausgabedatein standardmäßig aktiviert • 6 Standardprädikate zum Umbiegen dieser aktuellen Ein- und Ausgabeströme: - tell/1 – tell(+Dateiname) – deterministisch – tell('output.dat'). falls Datei offen – fortsetzen des Schreibens in diese Datei falls Datei nicht offen – Datei neu anlegen und zum Schreiben öffnen (vorhandene Datei wird gelöscht) - telling/1 – mit wem wird gerade output veranstaltet – telling(?Datei) – deterministisch – testen oder ermitteln des aktuellen Ausgabestroms - told/0 – deterministisch – aktueller Ausgabestrom wird geschlossen und setzt zurück auf den useroutput Beispiel: ?- tell('programm.pl'), telling(X), listing, told. Bei der Rückkehr auf das nächste Kommando wird automatisch ein told ausgeführt. telling gibt noch an, wohin ich grade schreibe zur Absicherung, Prolog schreibt ja wirklich *staun* ;-) Erstellt von Isabel Maine C. Drost Seite 20 von 42 Einführung in die Künstliche Intelligenz Semester V • Eingabeumlenkung: - see/1 – see(+Daten) – deterministisch – lesen aus Datei, wenn die nicht existiert, gibbs ne Fehlermeldung - seeing/1 – seeing(?Datei) – deterministisch – aus welcher Datei werden grade Märchen erzählt - see/0 – determinstisch – setzt den Eingabestrom wieder zurück auf user_input 4.1.2 Konventionelles Modell der Dateiarbeit • mit expliziten Strömen ISO – Standard: - open/3, open/4 – öffnen von Dateien - close/1 – schließen von Dateien - current_stream/3 – feststellen der göffneten Dateien – nichtdeterministisch - current_input/1 – was für Inputströme hab ich offen - current_output/1 – was hab ich für offene Outputs - set_input/1 – entsprechend tell - set_output/1 – entspricht see 4.1.3 Ein und Ausgabe von Termen • write/1 – write(?Term) – deterministisch – wirkt wie ein logisches true – benutzt den aktuellen Ausgabestrom und schreibt dort den Term hin ?-tell('test'),write('hello'),told. schreibt hello in die Datei test. • read/1 – read(?Term) – deterministisch ?-read(Eingabe) - ergibt einen Leseprompt, an dem ich was eingeben und am Ende den Pkt eingeben darf. |:_....... .<ENTER> Eingabe = Term(den ich eingegeben habe) (ist das Resultat) yes • prompt( ?Old, +New). ?- prompt(_,'>>>'), read(X). >>>.... wird immer wieder zurückgeschalten beim Rückkehr auf die Hauptein- und ausgabeschleife. • write(+Datei, Term); read(+Datei, Term) – lesen und schreiben aus der jeweiligen Datei 4.1.3 zeichenweise Ein und Ausgabe • • • • put/1 – put(+ASCIICode) – deterministisch – put(65). (ergibt ein großes A) schreibt auf den aktuellen Ausgabestrom put/2 – put(+Datei, +Code) – deterministisch – schreibt das Zeichen in eine Datei get0/1 – get0(?Code) – ?-get0(X) ... |: ....<ENTER> X=erstes Zeichen der Eingabe – liest Zeichen vom aktuellen Eingabestrom, bringt jedes Zeichen, was ich eingebe get/1 – get(?Code) – ignoriert alle nichtdruckbaren Zeichen Außer beim user_input gilt grundsätzlich: Dateiende wird mit –1 angezeigt. • • • get und get0 gibt es auch zweistellig mit einer Datei als ersten und Code als zweitem Parameter. peek_char/1 – man gucke, was das nächste Zeichen im Eingabestrom ist, entferne es aber nicht von dort, wie get. nl – beginnt eine neue Zeile, analog nl(+Datei). Erstellt von Isabel Maine C. Drost Seite 21 von 42 Einführung in die Künstliche Intelligenz Semester V 4.2 Termverarbeitung • • • • • • • • • • • '='/2 '\='/2 '=='/2 '\=='/2 @< @=< @> @>= var(?Term) nonvar(?Term) integer(?Term) float(?Term) number(?Term) atom(?Term) • • • atomic(?Term) compound(?Term) ground(?Term) – ?Term1 = ?Term2 – ruft Termunifiktation auf – Term1 und Term2 sind nicht unifizierbar – Term1 und Term2 werden ohne Variablenbindg. syntaktisch verglichen. X==Y. – no – Term1 und Term2 sind nicht identisch – Vergleiche nach der kanonischen Termordnung – Testet, ob beim Aufruf, der Term eine unbebundene Variable ist – Erfolg, wenn Term eine gebundene Variable ist – Erfolg, wenn Term eine ganze Zahl ist – handelt es sich um eine Gleitkommazahl – Test auf eine Zahl – testet, ob es sich um ein Atom handelt (Bezeichner mit Kleinbuchstaben, Sonderzeichen, Symbole, quotierte ZK) – Test auf eine Konstante (Überbegriff zu Atom und Zahl) – Test auf eine Struktur – Test auf einen Grundterm (Term, der, keine ungebunden Variablen hat) KI - Akku halb leer ;) • • T1 = T2 ... Unifikation T1 == T2 ... Termidentität (\= ... ungleich) (\== ... nichtIdentität) Beispiel: Variante der memberRelation, die Variable ohne Bindung überprüft auf Mitgliedschaft in der Liste: is_member(X, [Kopf|_]) :- X==Kopf. is_member(X,[_|Rest]):- is_member(X, Rest). 4.3 Kanonische Termordnung: @< @=< @> @>= • • • • • • • • • var(T) ... Test, ob T eine ungebundene Variable ist nonvar(T) ... Test, ob T eine gebundene Variable ist integer(T) ... Test, ob T eine ganze Zahl ist float(T) ... Test, ob T eine Gleitkommazahl ist number(T) ... Test, ob T eine Zahl ist atom(T) ... Test, ob T ein Atom ist (Bezeichner mit Kleinbuchstaben, Zeichenfolgen in Hochkommas, Sonderzeichen/ Symbole) atomic(T) ... Test, ob T ein Atom oder eine Zahl ist (Test auf eine Konstante) compound(T) ... Test, ob T eine Struktur ist ground(T) ... Test, das T keine ungebundenen Variablen hat - Grundterm Beispiel: Variante der Summe: summe(S1, S2, Summe):number(S1), number(S2),!,Summe is S1 + S2. summe(S1, S2, Summe): number(S1), number(Summe),!, S2 is Summe - S1. Erstellt von Isabel Maine C. Drost Seite 22 von 42 Einführung in die Künstliche Intelligenz Semester V 4.4 Analysieren von Termen: arg/3 ... arg(+N, +Struktur, ?T) ... deterministisch - greift in der Struktur auf das N.te Argument zu arg(2, fun(1,b, C), b). -> yes arg(2, fun(1,b, C), X). -> X=b functor/3 ... functor(?Struktur, ?Atom, ?N) ... Zugriff auf den Namen oder die Stelligkeit einer Struktur functor(fun(a,X), Name, Zahl). -> Name=fun Zahl=2 functor(X, f, 3). -> X=f(_,_,_) Univ-Operator =.. ... wandelt Strukturen in Listen um und umgekehrt Struktur =.. Liste (mindestens eines muß gegeben sein) Beispiel: Prozedur, die für einen gegebene Funktion f aus einer Liste von Argumenten die Liste der Funktionswerte bildet: fktwertListe(_,[],[]) fktwertListe(Fkt, [X1, XR], [Y1, YR]):Ausdruck=..[Fkt, X1], Y1 is Ausdruck, fktwertListe(Fkt, XR, YR). fktwertListe(sin, [0, 0.5 ...], Y). -> Y=[0, ...] name/2 ... name(?Atom, ?Codeliste) ... wenigstens eines gegeben, Konvertiert Atom in Liste der ASCII-Codes und zurück name(anna, X). -> X=[97, 110, 110, 97]. 5. Manipulation der Wissenbasis: :- ... Prologdirektive, die in den Quelltext kommt und als Anfrage ausgeführt wird (ohne Reaktion auf der Kdozeile) Dynamische Prologprozeduren können zur Laufzeit von Auswertungen verändert werden. Deklaration: :-dynamic(ProzName/Stelligkeit). (Wird aufgerufen, bevor von dieser Prozedur die erste Klausel auftaucht!) 5.1. Assert Jetzt können zu dieser Prozedur Fakten und Regeln weggenommen oder hinzugefügt werden: asserta/1 ... asserta(+Klausel) ... fügt Klausel am Anfang der Prozedur ein Beispiel: asserta(a(1,2)). asserta( (a(1,X):-b(X)) ). assertz/1 ... synonym zu oben, fügt aber am Ende an. 5.2. Retract retract/1 ... nicht deteministisch ... Musterterm wird mit 1. unifizierbaren Klausel unifiziert, diese Klausel wird dann gelöscht retract(gefunden(X)). X=1, X=2, NO. bei: gefunden(1), gefunden(2) retract((proc(_,_):-_)), fail. ... löscht alle Klauseln von proc retract interpretiert Fakten bei Bedarf als Regel: Fakt:-true. Erstellt von Isabel Maine C. Drost Seite 23 von 42 Einführung in die Künstliche Intelligenz Semester V 5.3. Abolish abolish(+Prozname/Stelligkeit) ... löscht die Prozedur (z.B. aus der Liste der gerade geladenen Funktionen) dynamische Prozeduren können tlw. auch ohne Klauseln definiert sein, werden sie in dieser Situation aufgerufen, liefern sie als Ergebnis ein no zurück. 5.4. Clause clause/2 ... clause (+KopfMuster, ?Term) ... nichtdeterministisch liefert alle Klauseln, deren Kopf mit dem Kopfmuster unifizierbar ist clause(vorfahr(X,Y), Bed). -> X= ..., Y = ..., Bed=elternteil(X,Y); -> X= ..., Y = ..., Bed=elternteil(XZ, YZ) Backtracking über die in der logischen Struktur vorhandenen Fakten und Regeln. Zum Beispiel um Metaprologinterpreter zu schreiben - schreiben eines eigenen Tracers ... 5.5. Anwendung zum Caching Anwendung von assert/ retract: caching/ LemmaGeneration Beispiel Fibonaci: fib(1,1). fib(2,1). fib(N,F):N>2, N1 is N-1, N2 is N-2, fib(N1, F1), fib(N2, F2), F is F1 + F2. Besser: Jede Zahl einmal berechnen, dann merken. Uterscheidung zwischen bekannter und noch zu berechnender Zahl :-dynamic(bekann_fib/2). bekannt_fib(1,1). bekannt_fib(2,1). cache_fib(N,F):once( (bekannt_fib(N,F), ;berechne_fib(N,F), assertz(bekannt_fib(N,F)) )). berechne_fib(N,F):N>2, N1 is N-1, N2 is N-2, cache_fib(N1, F2), cache_fib(N2, F2), F is F1 + F2. Nachteil: Prozedur wird speicherplatztechnisch ziemlich weit aufgeblasen... Bei einem zweiten Aufruf wird die Zeit drastisch reduziert, da dann die abgefragte Zahl schon gecached ist. listing(bekannt_fib) zeigt alle bekannten Zahlen an! 5.6. Modifikation der Wiederholenfunktion zum Mitzählen, wie oft iteriert wurde: :-dynamic('$$$count'/1). '$$$count'(1). counter(N):retract('$$$count'(N)), N1 is N+1, assert('$$$count(N1)). Erstellt von Isabel Maine C. Drost Seite 24 von 42 Einführung in die Künstliche Intelligenz Semester V 6. Programmierstil • • • • • • logische Prozeduren sollen überschaubar bleiben: nicht zuviele Argumente, nicht zuviele Klauseln (es gibt eine Ausnahme: "Faktenbasen" in tabellarischer Struktur) pro Regel nicht zuviele Bedingungen wählen sprechender Bezeichner !, assert, retract nur defensiv einsetzen \+ nur zum Testen einsetzen, zum Generieren nicht möglich verwenden von Kommentaren 6.1. Effizienz • mehr Wissen führt zu besseren Lösungen Der Programmierung muß also einerseits das Problem analysieren können, andererseits aber auch die Prologmaschine kennen. 6.1.1. Effizienz in Prolog • • • • • • • • entspricht der Anzahl der Inferenzschritte Anordnung der Klauseln innerhalb einer Prozedur spielt eine Rolle (setze spezifischere vor allgemeinere Klauseln) Anordnung der Bedingungen in einer Regel muß beachtet (man setze Regeln vor, die weniger Lösungen produzieren) Cut wird genutzt zum Abschneiden von Teilen des SLD-Baumes, die aus inhaltlichen Gründen keine Lösungen beinhalten können Caching - Zwischenspeichern von Zwischenergebnissen Weiterhn ist es möglich, nach besseren Datenstrukturen zu finden. Z.B. verwenden von Listen (gut für dynamische Sachen) im Vergleich zu statischen Strukturen mit Funktor. finden von allgemeineren oder detaillierteren Lösungsansätzen Ausnutzen des besseren Verständnisses der Prologmaschine 6.1.2 Drei Optimierungsverfahren vom Prologsystem • Ausnutzen durch Einhaltung von bestimmten Stilregeln 6.1.2.1 Klauselindizierung nach dem ersten Argument • • • • Erstellen einer Tabelle, in der drin steht, wo ich Klauseln finde, die dieses Argument brauchen bewirkt eine Einschränkung auf die für eine Unifikation in Frage kommenden Klauseln auf diese erfolgt Zugriff in konstanter Zeit Folgerung: Nutze möglichst die Argumente als erstes Argument, bei denen Du möglichst viel vorgibst, also ein Inputargument! Allgemein sollten Inputargumente als erste vor die Outputargumente angeordnet werden. Konstanten oder Strukturen sollten möglichst im ersten Argument notiert werden. Listen gehören i.A. nur für dynamische Datenstruckturen verwendet. Für statische lieber Prologstrukturen verwenden. Daraus resultieren folgende Regeln: • Ordnen Sie in Prozeduren Eingabe-Argumente vor Ausgabe-Argumenten an. • Schreiben Sie Klauseln mit Konstanten oder Strukturen im 1. Argument. • Verwenden Sie strukturierte Terme für statische Datenstrukturen. • Benutzen Sie Listen für dynamische Datenstrukturen. Erstellt von Isabel Maine C. Drost Seite 25 von 42 Einführung in die Künstliche Intelligenz Semester V 6.1.2.2. Optimierung des letzten Aufrufs (Last Call Optimization) Wenn bei der Auswertung eines Ziels die letzte Bedingung einer Regel erreicht wird und keine weiteren Lösungsalternativen für dieses Ziel existieren, so wird vor dem Aufruf der letzten Bedingung der für die Verwaltung dieses Ziels benötigte lokale Arbeitsspeicher freigegeben. Auf diese Weise kann eine Auswertung in beliebige Rekursionstiefen absteigen, ohne daß allein dadurch der Arbeitsspeicher erschöpft wird. "restrekursive Prozeduren" schleife(Zustand) :transformiere(Zustand,Zustand1), schleife(Zustand1). Diese Schleife mit einem deterministischen Prädikat transformiere kann beliebig oft durchlaufen werden, sofern die Datenstrukturen in den Argumenten beschränkt bleiben. Nicht vorhandene Lösungsalternativen können z.B. daran erkannt werden, • daß Bedingungen mit deterministischen Standardprädikaten formuliert wurden, • daß ein cut alle Alternativen abgeschnitten hat, • daß die noch zur Unifikation in Frage kommende Klauselmenge leer ist. Daraus resultieren folgende Regeln: • • Prüfen Sie stets, ob die Optimierung des letzten Aufrufs genutzt werden kann. • Setzen Sie cuts an Stellen, an denen die Auswahl einer Lösung definitiv wird. • Versuchen Sie, rekursive Aufrufe als letzte Bedingungen anzuordnen und die vorhergehenden Ziele deterministisch zu machen deterministische Aufrufe werden erkannt an für Standardprädikate implizit bekannt in Frage kommende Klausel ist leer wenn ! alle vorhandenen Lösungsalternativen abgeschnitten hat 6.1.2.3 if then else • • wird auf bedingten Sprung transformiert, Voraussetzung: Bedingung besteht aus arithmetischen und TypenTests sowie Term-Vergleichen Folgerung: Nutzen Sie bedingte Anfragen zur Optimierung (und weniger als syntaktischen Zucker oder gar als Ersatz für imperative Programmkonstrukte). Beispiel: effizientes Umkehren einer Liste: naiv: umkehren([],[]). umkehren([K,R],UL):umkehren (R,UR), append(UR, [K],UL). Inferenzschritte bei einer Liste der Länge N: n+1 Schritte für Reduktion auf leere Liste => O(N²) umgekehrt_anhängen([],[]). umgekehrt_anhängen([K,R], Liste, Erg):umgekehrt_anhängen(R,[K|Liste], Erg). (macht n+1 Schritte) reverse(L, UL):umgekehrt_anhängen(L,[],UL). Erstellt von Isabel Maine C. Drost Seite 26 von 42 Einführung in die Künstliche Intelligenz Semester V 7. Rekursion durch Iteration 7.1 Kopfgesteuerte Schleife wiederhole_kopfgesteuert(Daten):fortsetzungsbedingung(Daten), verarbeite(Daten), !, wiederhole_kopfgesteuert(NeueDaten), wiederhole_kopfgesteuert(Daten). Beispiel: newton(A,X,G):abs(A-X*X) >= G, X1 is (X+A/X)/2, !, newton(A, X1, G). newton(A,X,G):write('Wurzel aus'),write(A),write(X),... . a, X0 =1 X n+1 = 0,5 * ( a + xx ) xn 2 Abbruchbei : X n − a < genau Aufruf: newton(2,1,0.00001). (Will ich die Lösung mit im Aufruf haben, muß ich ein Akkumulatorelement einfügen. 7.2 Endgeprüfteschleife wiederhole_fussgesteuert(Daten):verarbeite(Daten, NeueDaten), (abbruchbedingung(NeueDaten) -> ! ; wiederhole_fussgesteuert(NeueDaten) ). Beispiel: Antworte mit Ja oder Nein. antworte(Ant):write('Antworte j(a) oder n(ein):'), get(Char), ( (Char==106; Char==110) -> Ant=Char, ! ; write('falsche Taste, nochmal'),nl, antworte(Ant) ). Falls Schleifen unabhängig voneinander sind im Sinne, dass keine Daten weitergereicht werden müssen (z.B. die Hauptschleife eines Prologprogrammes), sind auch repeatkonstruktionen für Schleifen möglich. fussgesteuertes_repeat:repeat, beschaffeDaten(Daten), verarbeite (Daten, Ergebn), abbruchtest(Ergebnisses),!. generator-fail-schleifen:generiere(Daten), verarbeite(Daten, Ergebnis), fail. generator-fail-schleife. generator-test-schleife:Datenfilter generiere(Daten), verarbeite(Daten, Ergebnis), test(Ergebnis). Erstellt von Isabel Maine C. Drost Seite 27 von 42 Einführung in die Künstliche Intelligenz Semester V 7.3. Akkumulation und Übergabe akku_rekursion(Daten, Akku, Uebergabe):abbruchbedingung(Daten, Loesung), !. akku_rekusrion(Daten, Akku, Uebergabe):verarbeitung(Daten, Akku, NeueDaten, NeuerAkku), akku_rekursion(NeueDaten, NeuerAkku, Uebergabe). Differenzlisten In der Listenverarbeitung wird die Technik der Akkumulator-Übergabe oftmals mit Hilfe von Differenzlisten realisiert. Darunter versteht man Datenstrukturen der Form [X1,X2,...,XN|Rest]-Rest wobei Rest eine ungebundene Variable ist, die als Markierung für das Ende der dargestellten Folge X1,X2,...,XN von Elementen dient. Man stellt sich die Liste [X1,X2,...,XN] quasi als "Differenz" zweier Listen vor: X1, X2, X3, X4 ... XN [X1, X2, X3, X4 ... XN|Rest] – Rest hinten_einfügen(X, Q-[X|Rest], Q-R). ?- hinten_einfuegen(4,[1,2,3|R]-R,DL). X<4 Q<[1,2,3,R] R<[4|R] DL<Q-Rest Dl=[1,2,3| [4|Rest]]-Rest=[1,2,3,4|Rest]-Rest vorn_entnehmen(X,[X|Rest]-Rest,Q-Rest). vorn_entnehmen(E,[1,2,3,4|Rest]-Rest,DL). E<1, Q=[2,3,4|Rest], DL=[2,3,4|Rest]-Rest difflisten_anhaengen(Q-Q1, Q1-Rest, Q-Rest). difflisten_anhaengen([1,2,3|R1]-R1, [4,5|R2]-R2,DL). Q<[1,2,3|R1] R1<Q1 Q1<[4,5|R2] Rest<R2 DL<[1,2,3|[4,5|R2]]-R2=[1,2,3,4,5|R2]-R2 Erstellt von Isabel Maine C. Drost Q Q-Q1 Q1 Q1-Rest Rest Seite 28 von 42 Einführung in die Künstliche Intelligenz Semester V Diese Listenfunktionen sind nur zum Listenverarbeiten geeignet, nicht aber zum Generieren von Listen. Allerdings sind sie so beim Verarbeiten sehr effizient im Vergleich zu klassischen Listen. um_anhaengen([],Liste-Liste). um_anhaengen([k|R],Erg-Liste):um_anhaengen(R, ErgListe-[K|Liste]). - ... wird hier als Verbindungsoperator genutzt. Genauso könnte man auch plus oder mal verwenden. Die Operatoren werden bei Verwendung des is, Vergleichsoperationszeichen oder abs wirklich in ihrer Funktion als Operator verwendet. Ansonsten sind sie nur Namen für extra Strukturen mit einer extraSyntax dame(X,Y,AufD,AbD) Zustand(Damenliste, AbDiagonalenFrei) XFrei, YFrei, AufDiagonalenFrei, setzen( zustand ( N-1Damen, [ XN | XFreiRest ], YFrei, AufDFrei, AbDFrei ), zustand ( [ dame(XN, YN, AufDN, AbDN) | N-1Damen ], XFreiRest, YFreiRest, AufDFreiRest, AbFreiRest):select(YN, YFrei, YFreiRest), AufDN is YN-XN, select(AufDN,AufDFrei,AufDFreiRest), AbDN is YN+XN, select(AbDN, AbDFrei, AbDFreiRest). start(zustand([],[1,2,3,4,5,6,7,8], [1,2,3,4,5,6,7,8], [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]). ziel(zustand(Loes,[],[],_,_)). [0,1,2,3,4,5,6,7], loesung_finden(Zust,Zust):- ziel(Zust). loesung_finden(Zust,ZielZustand):setzen(Zustand, Zwischenzustand), loesung_finden(Zwischenzustand, ZielZustand). 8. Problemlösung durch Suche Problemlösen: • • • Welt mit Zuständen Aktionen, die Zustände transformieren Problem: Aktionsfolge finden von Startzustan in den Endzustand Vorgehensweise: 1) Modellieren sie die relevanten Zustandsgrößen (siehe auch Affe mit der Banane, oder 8-Damen Problem Beispiel). 2) Legen sie die möglichen Aktivitäten fest. Beispiel: Zustandsdarstellung für obiges Blockbild Stapel von Blöcken wird zur Liste, wobei der Kopf der Liste dem obersten Steinchen entspricht Stapel ... [b1, b2, b3 ... ] Variante: Blockwelt(S1, S2, S3) Erstellt von Isabel Maine C. Drost Seite 29 von 42 Einführung in die Künstliche Intelligenz Semester V Variante: [S1, S2, S3 ... ] Festlegung möglicher Aktivitäten in der Form von aktion(Blockwelt, Blockweltneu) von einem Stapel obersten Block entnehmen und oben auf anderen Stapel ablegen Beginn der Realisierung: aktion(Blockwelt, Blockweltneu):append(Vorn, [[Block| Stapelrest] | Hinten], Blockwelt), append(Zwischen,[Zielstapel| Ende], Hinten), append(Zwischen, [[Block|Zielstapel]|Ende], HintenNeu), append(Vorn, [StapelRest|HintenNeu], BlockweltNeu). aktionvonrechtsnachlinks(Blockwelt, Blockweltneu):append(Vorn, [[Block| Stapelrest] | Hinten], Blockwelt), append(Zwischen,[Zielstapel| Ende], Vorn), append(Zwischen, [[Block|Zielstapel]|Ende], HintenNeu), append(Vorn, [StapelRest|HintenNeu], BlockweltNeu). Startzustand: start([ [c, a, b], [ ], [ ] ]). ziel ([ [ ], [a, b, c], [ ] ]). %Block zum Entnehmen finden %Zielstapel finden %Block zum Entnehmen finden %Zielstapel finden Startzustand Grundlegende Suchalgorithmen Gegeben ist ein Graph Es gibt zwei Mengen von Knoten: OFFEN: bekannte Knoten, die noch nicht überprüft wurden ABGESCHLOSSEN: Knoten, die schon überprüft wurden Initialisierung: OFFEN ABGESCHLOSSEN <- {Start} <- {} k1 k2 k3 Ziele nach Ende der ersten Operation, sähen die Listen folgendermaßen aus: O={k1, k2, k3} A={Start} Iteration: Solange kein Zielknoten gefunden wurde: nimm einen AktuellenKnoten aus OFFEN falls dies Zielknoten, dann Ende der Iteration sonst: bestimme die Nachfolger, die nicht in OFFEN und in ABGESCHLOSSEN drin sind und füge sie in OFFEN ein und füge den aktuellen Knoten in ABGESCHLOSSEN ein Abgeschlossen existiert nur, um nicht wieder zu Knoten zurückzugelangen, wo ich schon war. Bei Baumgraphen brauche ich diese Liste nicht, da dort keine Zyklen existieren. Die Organisation von OFFEN definiert konkretes Suchverhalten. Voraussetzungen: • Datenstruktur für Zustände • start(...) ... sagt mir, wo das Suchen beginnt • Ziel ... kann auch eine Prozedur sein, die testet, ob die Zustände dem Ziel entsprechen • aktion(Ausgangszustand, Folgezustand, Akionsnamen):- Bedingungen. • Lösungsweg in Form: [Z0, A1, Z1, A2, Z2, A3, Z3 ... AN, ZN] Folge von Zustand0 – Aktion1 – Zustand1 – Aktion2 – ... – Zielzustand Tiefensuche /* s(WegZumZiel, OffeneWege, AbgWege)*/ ts([Ende|Rest] ,[[Ende|Rest]|_], _):- Ziel(Ende). ts(WegZumZiel, [[Zustand|Rest]|OffenRest], Abgeschlossen):%Zustand ... Zustand zu dem ich hingewaschelt bin %Rest ... Weg, auf dem ich zu dem Zustand gekommen bin findall([NachfolgeZustand, NachfolgeAktion, Zustand| Rest], (aktion(Zustand, Nachfolgezustand, NachfolgeAktion), \+member([NachfolgeZustand|_],[[Zust|Rest]OffenRest]), \+member([NachfolgeZustand|_], Abgeschlossen) ),NeueWege), %für Tiefensuche füge man die neuenWege vorn an den Offenrest an append(NeueWege, OffenRest, OffenNeu), !,s(WegZumZiel, OffenNeu, [[Zustand|Rest]|Abgeschlossen]). Erstellt von Isabel Maine C. Drost Seite 30 von 42 Einführung in die Künstliche Intelligenz Semester V Breitensuche bs([Ende|Rest] ,[[Ende|Rest]|_], _):- Ziel(Ende). bs(WegZumZiel, [[Zustand|Rest]|OffenRest], Abgeschlossen):%Zustand ... Zustand zu dem ich hingewaschelt bin %Rest ... Weg, auf dem ich zu dem Zustand gekommen bin findall([NachfolgeZustand, NachfolgeAktion, Zustand| Rest], (aktion(Zustand, Nachfolgezustand, NachfolgeAktion), \+member([NachfolgeZustand|_],[[Zust|Rest]OffenRest]), \+member([NachfolgeZustand|_], Abgeschlossen) ),NeueWege), %für Breitensuche füge ich die neuen Wege hinten an den noch offenen Rest an, %dann werden erst sämtliche unmittelbaren Nachfolger des aktuellen Knotens abgearbeitet %Menge Offen ist hier eine Queue, die von vorn nach hinten abgearbeitet wird %und bei der man sich hinten anstellt ;) append(OffenRest, NeueWege, OffenNeu), Tiefensuche mit beschränkter Suchtiefe: /* s(WegZumZiel, OffeneWege, AbgWege, MaximaleTiefe)*/ ts([Ende|Rest] ,[[Ende|Rest]|_], _,_):Ziel(Ende). ts(WegZumZiel, [[Zustand|Rest]|OffenRest], Abgeschlossen,MaxTiefe):%Zustand ... Zustand zu dem ich hingewaschelt bin %Rest ... Weg, auf dem ich zu dem Zustand gekommen bin length(Rest, Laenge2), %entspricht der doppelten Länge der gemachten Aktionen, da ich ja sowohl %Aktion als auch Weg aufhebe Laenge is Laenge2//2, Laenge < MaxTiefe, ->findall([NachfolgeZustand, NachfolgeAktion, Zustand| Rest], (aktion(Zustand, Nachfolgezustand, NachfolgeAktion), \+member([NachfolgeZustand|_],[[Zust|Rest]OffenRest]), \+member([NachfolgeZustand|_], Abgeschlossen) ),NeueWege) ; NeueWege=[] %habe ich die maximale Weglaenge überschritten, wird der Weg einfach leer %gemacht , %für Tiefensuche füge man die neuenWege vorn an den Offenrest an append(NeueWege, OffenRest, OffenNeu), !,s(WegZumZiel, OffenNeu, [[Zustand|Rest]|Abgeschlossen], MaxTiefe). !,s(WegZumZiel, OffenNeu, [[Zustand|Rest]|Abgeschlossen]). Erstellt von Isabel Maine C. Drost Seite 31 von 42 Einführung in die Künstliche Intelligenz Semester V Suche mit Zusatzinformationen - lokale Bewertungen - globale Bewertungen Heuristiken Menge aller offenen Wege können geordnet werden lokale Bewertungen Voraussetzungen: lh(Zustand,FolgeZustand,Bewertung) erweitern im allg. Verfahren die Datenstruktur für die Wege: Bewertung-[ZN,AN,ZN1,...,Z0] Wege /* keysort(PaarListe,SortPaarListe) */ [Schlüsselwert1-Term,Schlüsselwert2-Term,...] Tiefensuche mit lokaler Heuristik tslh([Ziel|RestWeg],Ziel,[_-[Ziel|RestWeg]|_],_). tslh(Loes,Ziel,[Bewertung-[Z|R]|OffRest],Abg):findall(NBew-[NZ,NA,Z|R], (aktion(Z,NZ,NA), \+member(_-[NZ|_],[Bewertung-[Z|R]|OffRest]), \+member(_-[NZ|_],Abg), lh(Z,NZ,Nbew)), NeueBewerteteWege), keysort(NeueBewerteteWege,NeueGeordWege), append(NeueGeordWege,OffRest,OffNeu), !, tslh(Loes,Ziel,OffNeu,[Bew-[Z|R]|Abg). analog: Breitensuche Suche mit globaler Bewertung Menge der offenen Wege wird als Ganzes in jedem Schritt neu geordnet Voraussetzung: gh(Zustand,Bewertung) "Abstandsschätzung zum Ziel" sgh([Ziel|Rest],Ziel,[_-[Ziel|Rest]|_],_). sgh(... findall(... (aktion(... \+... \+... gh(NZ,Nbew)), NeueBewWege), keysort(NeueBewWege,NeueGeordWege), merge(NeueGeordWege,OffRest,OffNeu), !, sgh(...). merge([],Liste,Liste):-!. merge(Liste,[],Liste):-!. merge([X|SRest1],[Y|SRest2],[X|SRest]):X @=< Y,!, merge(SRest1,[Y|SRest2],[Y|SRest). merge([X|SRest1],[Y|SRest2],[Y|SRest]):merge([X|Srest1],SRest2,SRest). Erstellt von Isabel Maine C. Drost Seite 32 von 42 Einführung in die Künstliche Intelligenz Semester V Suche nach kostenoptimierten Wegen Voraussetzung: - Aktionen verursachen Kosten: aktion(Zust,Nzust,NameAkt,AktKosten) - es gibt eine Schätzfunktion für die "Restkosten" von jedem Zustand zum Ziel h(Zust,Restkosten) f(Z)= g(Z)+h(Z) exakte Kosten von Start Restkosten nach Z (∑Aktionskosten) globale Heuristik für ein Suchverfahren A* (Nilssen) A*-Bedingung - alle Aktionskosten >=k0 > 0 - Restkostenschätzung h(Z) <= tatsächliche Kosten von Z nach Ziel erste gefundene Lösung ist kostenoptimal Wissensrepräsentation und Meta-Interpreter wissensbasierte Systeme Verarbeitung Inferenzmaschine Algorithmen Problemspezifikation auf formaler Ebene WAS WIE Wissensbasis Datenstrukturen Regelbasierte Wissensrepräsentation, regelbasierte Systeme (Frauen?) wenn Bedingung dann Folgerung wenn Situation dann Aktion Daten/FaktenBasis Regelbasis Regelinterpreter konkreter Zustand der Problemlösung allg. Problemlösungsbasis Regelinterpreter: steuert die Ausführung jeweils einer konkreten Regel in einem best. Zustand und übernimmt Konfliktlösung bei mehreren anwendbaren Regeln nach Strategie Regelbasierte Systeme Rückwärstverkettende Systeme Vorwärtsverkettende Systeme 9. Prolog als Regelinterpreter • • Rückwärtsverkettung zielgesteuerte Verarbeitung Vorwärtsverkettung datengetriebene Verarbeitung nachweis(Aussage):wenn Bedingungen dann Aussage, nachweis(Bedingungen). Erstellt von Isabel Maine C. Drost Datenbasis Regeln Regelinterpreter Seite 33 von 42 Einführung in die Künstliche Intelligenz Semester V Konfliktlösung: erste Regel wird genutzt /*Aussage zutreffend: stellt gültige Fakten dar*/ -> Prozedur zutreffend:-dynamic zutreffend/1. neue_folgerung(Aussage):wenn Bedingungen dann Aussage, \+ Aussage zutreffend, folgerbar(Bedingungen). folgerbar(A1 und A2):-!, folgerbar(A1), folgerbar(A2). folgerbar(A1 oder A2):-!, (folgerbar(A1) ;folgerbar(A2) ). folgerbar(A1):- A zutreffend. folgern:(neue_folgerung(A) ->write(A), write('trifft zu'), nl, assert(A zutreffend), folgern ;write('keine weiteren Folgerungen möglich'),nl). 9.1 Benutzerbefragung nach Fakten - Rückwärtsverkettung • • Ziel ist nich alle möglichen Fakten zu Beginn zu speichern, sondern bei Bedarf abzufragen Diesmal muß man sich nicht die Fakten merken, sondern das, wonach man fragen muß und kann. /*fragbar(Aussage, Fragetext)*/ fragbar(diele_nass, 'Ist die Diele nass?'). • diesmal muß ich mir nicht nur merken, was zutreffend ist, sondern auch das, was nicht zutreffend ist – sonst wird der Nutzer evtl. mehrmals nach demselben Fakt gefragt :-op(..., zutreffend). :-op(800,xf,unzutreffend). :-dynamic zutreffend/1, unzutreffend/1. beweis(A1 oder A2, Bew):- !, (beweis(A1, Bew) ;beweis(A2, Bew)). beweis(A1 und A2, Bew1 und Bew2):-!, beweis(A1, Bew1), beweis(A2, Bew2). beweis(A1,fakt(A)):A zutreffend,!. beweis(A,_):A unzutreffend, !, fail. beweis(A,fakt(A)):fragbar(A, Frage),!, write(Frage), write('j/n'), read(Ant), (Ant==j -> assert(A zutreffend) ; -> assert(A unzutreffend),fail ). beweis(Aussage, foglerung(A, Bedingungen, Beweis)):wenn Bedingung dann A, beweis(Bedingung, Beweis). Erstellt von Isabel Maine C. Drost Seite 34 von 42 Einführung in die Künstliche Intelligenz Semester V 9.2 Vorwärtsverkettung mit Beweiskonstruktion und Benutzerbefragung :-op(900, fx, wegen) :-dynamic wegen/2 folgern2:retractall(-wegen-), folgern_mitBeweis. folgern_mitBeweis:(neuefolgerung(A, Bew), -> write('gefolgert wurde'), write(A), nl, assert(A wegen Bew), folgern2 ;write('keine weiteren Folgerungen') ). /*weiter auf nächster Seite*/ neue_folgerung(A, folgerung(A, Bed, Bew)):wenn Bed dann A, \+A wegen _, folgerbar(Bed, Bew). folgerbar(A1 oder A2):- /*siehe oben*/ folgerbar(A1 und A2, Bew1 und Bew2):- /*siehe oben*/ folgerbar(A,B):A wegen B,!, B\=keinfakt. folgerbar(A, fakt(A)):fragbar(A, Frage), write(Frage),write('j/n'), read(Ant), (Ant==j -> assert(A wegen fakt(A)) ;assert (A wegen keinfakt), fail ). 9.3 warum – Fragen – warum wird nach einer bestimmten Information gefragt Erstellt von Isabel Maine C. Drost Seite 35 von 42 Einführung in die Künstliche Intelligenz Semester V /*beweis(Aussage, Bew, Fragespur)*/ beweis1(A, Bew):beweis(A, Bew, [frage(A)]). beweis(A1 oder A2, Bew, FS):- siehe oben beweis(A1 und A2, Bew1 und Bew2, FS):- siehe oben beweis(A, fakt(A), _):- A zutreffend,!. beweis(A, _, _):- A unzutreffend, !, fail. beweis(A, fakt(A), FS):frage(A,Fragetext), write(Fragetext), read(Ant), verarbeite(Ant, Fragetext, FS, Ant1), (Ant1==j -> assert(A zutreffend) ; assert(A unzutreffend),!,fail ). beweis(A, folgerung(A, Bed, Bew), FS):wenn Bed dann A, beweis(Bed, Bew, [wenn Bed dann A| FS]). verarbeite(j, _, _, j). verarbeite(n, _, _, n). verarbeite(warum, Fragetext, [wenn B dann Folg | RestFS], Ant1):write('Es wird untersucht: '), write(wenn B dann Folg), write('Deshalb die Frage: '), write(Fragetext), write('j/n'), read(Ant), verarbeite(Ant, Fragetext, RestFS, Ant1). verarbeite(warum, Fragetext, [frage(A)], Ant1):write(A), write(' war Deine Frage!'), write(Fragetext), read(Ant), verarbeite(Ant, Frage, [frage(A)], Ant1). Erstellt von Isabel Maine C. Drost Seite 36 von 42 Einführung in die Künstliche Intelligenz Semester V 9.4 Behandlung von unsicherem Wissen • • viele Ansätze/ Modelle zur Behandlung von unsicherem Wissen jedes konkrete mit Unsicherheit behaftete Problem benötigt seinen eigenen Ansatz der Behandlung 9.4.1 Theoretische Grundlagen • • • Wahrscheinlichkeitsrechnung/ Statistik Fuzzy-Logik ad-hoc-Modelle (bezogen auf eine bestimmte Sache, Verarbeitungsmodelle ohne theoretische Grundlage, die durch ihre Resultate gerechtfertigt werden; z.B. MYCIN – Modell) Beispiel für theoretisch – fundiertes Vorgehen: Anwendung bedingter Wahrscheinlichkeiten nach dem Satz von Bayes Diagnostik: { Ursache Ursache Ursache Ursache Ursache } und { Symptom Symptom Symptom Symptom }, Ursachen führen zu Symptomen, beobachtbar sind aber lediglich die Symptome. Frage: welche Symptome deuten auf welche Ursachen. einfacher Fall: eine Ursache und ein Symptom Voraussetzung: es wurden in der Vergangenheit n Beobachtungen gemacht. Ns ... Anzahl des Auftretens von S Nu ... Anzahl des Auftretens der Ursache U Ns/u ... wie oft traten Ursache und Symptom gemeinsam auf? N P( S / U ) = s / u Nu Bedingte Wahrscheinlichkeit dafür, dass S auftritt, falls U vorliegt. Uns interessiert aber gerade das Gegenteil P(U/S). P(U / S ) = N s / u N s ,u N u N P( S / U ) * P(U ) = = * * Ns Nu N Ns P(S ) Haben wir Datenmaterial darüber, wie oft das Symptom überhaupt beobachtet wurde, wie wahrscheinlich die Ursache auftritt und die Wahrscheinlichkeit dafür, dass das Symptom bei der entsprechenden Ursache auftritt – so können wir Rückschlüsse darauf ziehen, wie wahrscheinlich die Ursache schuld am Symptom ist... Voraussetzung P(U) ist näherungsweise bekannt, P(S) näherungsweise bekannt, P(S/U) näherungsweise bekannt Daraus kann man P(U/S) berechnen. Beispiel: Ursache ... Krankheit Bronchitis tritt mit einer Wahrscheinlichkeit von 5% auf, wenn ein Patient zu mir kommt Symptom ... Husten tritt mit einer Wahrscheinlichkeit mit einer Wahrscheinlichkeit von 20% auf Symptom Husten bei einer Bronchitis tritt bei 80% auf. Daraus läßt sich die Wahrscheinlichkeit berechnen, dass jemand Bronchitis hat, falls er hustet: P( Bronchitis / Husten) = 0.8 * 0.05 = 0 .2 0 .2 P(U) ist die Apriorie Wahrscheinlichkeit P(U/S) ist die Aposteriori Wahrscheinlichkeit • • • • • {S1 ... Sn} Menge aller beobachtbaren Symptome {U1 ... Un} Menge aller möglichen Ursachen, die sich wechselseitig ausschließen S1 ... Sn sind nur von U1 ... Un abhängig und die Symptome sind bei jeder Ursache voneinander unabhängig. hinreichend genaues statistisches Material über Vorkommen der Ursachen und Symptome sowie ihrer Abhängigkeiten hinreichend stabiles Problem Erstellt von Isabel Maine C. Drost Seite 37 von 42 Einführung in die Künstliche Intelligenz Semester V absolute Aposteriori Wahrscheinlichkeit. Interessant zur gegenseitigen Gewichtung der Ursachen sind die "relativen Aposteriori Wahrscheinlichkeiten" (siehe nächstes Feld) P(U i / S1 ∩ ... ∩ S m ) = P( S1 ∩ ... ∩ S m / U i ) * P(U i ) P( S1 ∩ ... ∩ S m ) = P( S1 / U i ) * ... * P( S m / U i ) * P (U i ) P( S1 ∩ ... ∩ S m ) P( S1 / U i ) * ... * P( S m / U i ) * P(U i ) P( S1 ∩ ... ∩ S m ) Prel (U i / S1 ...S m ) = m P( S1 / U j ) * ... * P ( S m / U j ) ( * P(U j )) ∑ P( S1 ∩ ... ∩ S m ) j =1 = P( S1 / U i ) * ... * P( S m / U i ) * P(U i ) ∑ m j =1 ( P( S1 / U j ) * ... * P( S m / U j ) * P(U j )) 9.4.2 Problemtypen für Wissensbasierte Systeme • • • Diagnostik (medizinisch oder technisch) Überwachungsaufgaben von Prozessen Interpretation von Daten }Klassifikationsaufgaben Konstruktive Aufgaben: • Konfiguration von technischen Systemen • Design • Planung Beispiele sind hier unsere Puzzleaufgaben Prognoseaufgaben • Vorhersagen über Prozeßentwicklungen • Simulation Erstellt von Isabel Maine C. Drost Seite 38 von 42 Einführung in die Künstliche Intelligenz Semester V Prüfungsvorbereitung: 1. Welche Resolvente liefert folgende Resolutionsregel: A || B !A || C B || C Nachweis, dass dies eine allgemeingültige Aussage ist, kann über eine Wertetabelle erfolgen A B C AvB !AvC 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 0 0 1 1 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 0 1 oder: Annahme: !(BvC) = !B ^ !C => Somit stünde unabhängig vom A in einer von beiden immer ein false ... 2. ist folgendes syntaktisch korrekt: ob_das_ein_Term_ist ... gültig WasIstDas ... gültig 3ter_Versuch ... ungültig steht(Dies, an, tafel(2)) ... gültig BvC 1 1 1 0 1 1 1 0 ... Atom ... Variable ... Datenstrucktur 3. Unifikation von Termen termin(Fach, datum(19,2,01)) = termin(prolog, Heute). yes Antwort: Fach=prolog; Heute=datum(...) • Funktor gleich, Argumentanzahl gleich, Terme unifizieren • Konstanten passen nur, wenn zwei gleiche aufeinandertreffen • Variablenbindungen kommen zustande, wenn eine Variable auf irgendwas anderes trifft • treffen zwei ungebundene Variablen aufeinander, bleiben sie zunächst ungebunden, werden aber zu einer einzigen, sind nur noch gemeinsam an einen Wert zu binden kennt(otto, Wen)=kennt(Person, freund(Person)). [hier, Kommt, 1, liste([X,Y])] = [Das, ist, nicht | Klar]. [hier, Kommt, 1, liste([X,Y])] = [Das, ist, Nicht | Klar]. Person=otto; Wen=freund(otto) Das=hier; Kommt=ist; 1!=nicht ... no Das=hier; Kommt=ist; Nicht=1;Klar=[liste([X,Y])] 4. Welche Arten von Hornklauseln haben wir in Prolog? Fakten, Regeln, Anfragen, leere Klausel Logische Prozeduren sind Sammlungen von Fakten und Regeln mit dem gleichen Kopfnamen/ Klauselkopf und der gleichen Stelligkeit. Fakt ... das, was aufgeschrieben wurde, soll wahr sein Regel ... soll wahr sein, falls die Bedingungen zutreffen Anfrage ... ich möchte wissen, ob das, was ich aufgeschrieben habe, zutrifft Variablen in Anfrage ... ich möchte wissen, für welche Werte treffen diese Aussagen zu Variablen in Fakten und Regeln ... Das, was ich da hinschreibe trifft für alle möglichen Variablenbindungen zu Erstellt von Isabel Maine C. Drost Seite 39 von 42 Einführung in die Künstliche Intelligenz Semester V 5. Wie ist die Prozdurale Semantik folgendes Programms? hat_hobby( anna, surfen). ella, kochen). ella, wandern). otto, surfen). otto, wandern). paul, kochen). haben_gesprächsthema(P1, P2):hat_hobby(P1, H),hat_hobby(P2, H), P1\=P2. Namen von Konstanten: siehe Herbranduniversum Namen von Datenstrukturen: keine Prozedurnamen/ Prädikatennamen: hat_hobby/ 2; haben_gesprächsthema/2 Herbranduniversum: anna, ella, otto, surfen, kochen, wandern, paul Deklarative Semantik: Schlußfolgerbar ohne Variablen mit einem Resolutionsschritt: hat_hobby/2 Schlußfolgerbar ohne Variablen mit mehreren Resolutionschritten: haben_gesprächsthema(anna, otto). haben_gesprächsthema(ella, paul). haben_gesprächsthema(ella, otto). haben_gesprächsthema(otto, anna). haben_gesprächsthema(paul, ella). haben_gesprächsthema(otto, ella). Reihenfolge der Abarbeitung ?-haben_gesprächsthema(otto, X). X=anna SLD: haben_gesprächsthema(otto, Wer) P1=otto P2=Wer hat_hobby(otto, H), hat_hobby(Wer, H), otto\ =Wer H=surfen hat_hobby(Wer, surfen) otto\ =Wer Wer=anna otto\ =anna ERFOLG Erstellt von Isabel Maine C. Drost Wer=otto H=wandern hat_hobby(Wer, wandern) otto\ =Wer Wer=ella Wer=otto otto\ =otto otto\ =ella otto\ =otto MIßERFOLG ERFOLG MIßERFOLG Seite 40 von 42 Einführung in die Künstliche Intelligenz Semester V 6. Interpretation einer Prozedur: vari(0,_,[ ]). vari(Anz, Grundmenge, [Erstes, Rest]):Anz>0, Anz1 is Anz-1, member(Erstes, Grundmenge), vari(Anz1, Grundmenge, Rest). Variation mit Wiederholung. Für Variation ohne Wiederholung: statt member und neuer variAufruf: select(Erstes, Grundmenge, RestGrundmenge), vari(Anz1, RestGrundmenge, Rest). Was bringt folgende Anfrage: var(N, [2,4], [1,2,3,4]). ... ERROR (da N ungebunden ist) 7. Programmiere ein member ohne Unifikation member_without_unification(X, Liste) m(X, [1,X, y]) ... yes m(X, [1,Y, z]) ... no Membergrundform: is_member(X, [Kopf|_]) :- X=Kopf. is_member(X,[_|Rest]):- is_member(X, Rest). neue Memberform ohne Unifikation: is_member(X, [Kopf|_]):-X==Kopf. is_member(X,[_|Rest]):- is_member(X, Rest). 8. Programmieren Sie die Binomialkoeffizienten n n = = 1 0 n n n − 1 n − 1 + = k k − 1 k koeff(N, 0, 1). koeff(N, N, 1). haben_gesprächsthema(otto, Wer) koeff(N, K, Koeff):N>0, k>0, P1=otto N1 is N-1, P2=Wer K1 is K-1, koeff(N1, K1,H), B1), hat_hobby(otto, koeff(N1, K, B2), hat_hobby(Wer, H), Koeff is B1 + B2. otto\ =Wer In effizienterer Form: siehe Fibonacchizahlen mit Zwischenspeichern oder mit Akkumulator – Übergabeschema H=surfen H=wandern :-dynamic(bekann_koeff/3). bekannt_koeff(N,0,0). bekannt_koeff(N,N,0). hat_hobby(Wer, surfen) hat_hobby(Wer, wandern) bekannt_koeff=(1,1,1). otto\ =Wer otto\ =Wer cache_bino(N, K, B):once((bekannt_koeff(N, K, B) Wer=anna Wer=ella Wer=otto ;berechne_koeff(N,Wer=otto K, B), assert(bekannt_koeff(N, K, B) otto\ ). =anna otto\ =otto otto\ =ella otto\ =otto berechne_bino(N, K, B):N1 isERFOLG N-1, K1 is K-1,MIßERFOLG ERFOLG MIßERFOLG cache_bino(N1, K1, B1), cache_bino(N1, K, B2), B is B1 +B2. Erstellt von Isabel Maine C. Drost Seite 41 von 42 Einführung in die Künstliche Intelligenz Semester V Für Akkumulator-Übergabe: n n * (n − 1) * ... * (n − k + 1) = 1 * 2 * ... * k k /*binkoeff(N, K, ,I, Akku, Überg)*/ bin(_, K, K, Akku, Akku). bin(N,K,I,Akku,Ueb):Akku1 is Akku * (N-I) / I+1, I1 is I+1, bin(N,K,I1,Akku1, Ueb). Aufruf: bin(17, 4, 0, 1, Resultat). Erstellt von Isabel Maine C. Drost Seite 42 von 42