P1-WS04-MusterLoesung03.txt
Version vom 16. Juli 2010, 15:02 Uhr von 134.100.48.183 (Diskussion)
Diese Seite ist veraltet.
Genannte Informationen sind vermutlich nicht mehr gültig und werden bald angepasst oder gelöscht
Genannte Informationen sind vermutlich nicht mehr gültig und werden bald angepasst oder gelöscht
Aufgabenblatt 3 P1 [[WiSe]] 04/05 Özgür Özcep Aufgabe 1 (Grundbegriffe) ------------------------ Fakten: elementare Klauseln, die genau eine Grundstruktur enthalten. Fakten dienen der Simulation relationaler DB's in Prolog. Fakten sind die Elemente von Prädikaten der Logikprogrammierung. Mit ihnen wird extensionales Wissen spezifiziert, d.h. mit Fakten definiert man Eigenschaften eines Objektes bzw. Beziehungen zwischen Objekten durch explizites Auflisten. Fakten können formal als Regeln (s.u.) ohne Körper[[/Rumpf]] verstanden werden. Regel: Komplexe Klausel der Form A :- B, die aus einem Kopf und einem Körper besteht. Regeln führen eine deduktive Komponente in relationale Datenbanken ein: Ist das im Körper ausgedrückte Wissen bereits erschlossen worden, so darf auf das im Kopf ausgedrückte Wissen geschlossen werden. Unter einen anderen Perspektive formuliert: Um das im Kopf ausgedrückte Ziel zu erfüllen muss das im Rumpf ausgedrückte Ziel erfüllen. Regeln ermöglichen kompaktes Hinzufügen von intensionalem Wissen. Anfrage oder Ziel: am Systemprompt eingegebene (elementare) Klausel. Sie stellt eine Aufforderung dar, das in ihr angegebene Wissen auf Konsistenz mit der Datenbasis zu überprüfen. Auch der Körper einer Klausel ist als ein (komplexes) Ziel zu verstehen. Formal können Anfragen[[/Ziele]] als Regeln ohne Kopf verstanden werden. Aufgabe 2 (komplexe Anfragen) ----------------------------- a) ?- mutter_von(X,Y),mutter_von(X,Z). X ist Mutter von Y und X ist Mutter von Z, d.h. Y und Z haben dieselbe Mutter und sind damit (Halb-)Geschwister; oder Y und Z bezeichnen dieselbe Person. (Dieser Fall wird im folgenden ausgeklammert.) ?- mutter_von(A,X),mutter_von(A,B),mutter_von(B,Y), mutter_von(B,Z). (1) A ist Mutter von X und (2) A ist Mutter B und (3) B ist Mutter von Y und (4) B ist Mutter von Z Bildlich: A / \ X B / \ Y Z Wie in a) folgt aus (1),(2): (5) X und B sind (Halb-)Geschwister und aus (3) und (4): (6) Y und Z sind Halbgeschwister Ausserdem gilt: (7) X ist Onkel oder Tante von Y und Z (8) A ist Grossmutter von Y und Z. ?-vater_von(B,X),vater_von(C,Y),vater_von(C,Z),vater_von(A,B),vater_von(A,C). (1) B ist Vater von X (2) C ist Vater von Y (3) C ist Vater von Z (4) A ist Vater von B (5) A ist Vater von C. Bildlich: A / \ B C | / \ X Y Z Aus der obigen Darstellung ergeben sich folgende Verwandschaftsverhältnisse: (6) B und C sind (Halb-)Geschwister (7) Y und Z sind (Halb-)Geschwister (8) X, Y und Z sind Enkelkinder von A; genauer: A ist Grossvater von X und Y und Z (9) X ist Cousin von Y und Z et vice versa (10) B ist Onkel von Y und Z. (11) C ist Onkel von X. b) % mutter_von( Mutter , Kind ). % 'Mutter' und 'Kind' sind Argumentpositionen (Platzhalter, Variablen), % so dass 'Mutter' die Mutter von 'Kind' ist. :- dynamic mutter_von/2. % ermöglicht dynamische Veränderung mutter_von( marie , hans ). mutter_von( marie , helga ). mutter_von( julia , otto ). mutter_von( barbara , klaus ). mutter_von( barbara , andrea ). mutter_von( charlotte , barbara ). mutter_von( charlotte , magdalena ). mutter_von( helga , jana ). mutter_von( helga , frida ). mutter_von( frida , johannes ). % vater_von( Vater , Kind ). % 'Vater' und 'Kind' sind Argumentpositionen (Platzhalter, Variablen), % so da"s 'Vater' der Vater von 'Kind' ist. :- dynamic vater_von/2. % ermöglicht dynamische Veränderung vater_von( otto , hans ). vater_von( otto , helga ). vater_von( gerd , otto ). vater_von( johannes , klaus ). vater_von( johannes , andrea). vater_von( walter , barbara ). vater_von( walter , magdalena ). vater_von( ebbe , frida ). vater_von( kaj , jana ). vater_von( jan , johannes ). % und nun brauchen wir noch das Geschlecht % (zur Definition des Onkelprädikats): weiblich(julia). weiblich(marie). weiblich(helga). weiblich(frida). weiblich(jana). weiblich(charlotte). weiblich(magdalena). weiblich(barbara). weiblich(andrea). maennlich(gerd). maennlich(otto). maennlich(hans). maennlich(ebbe). maennlich(kaj). maennlich(jan). maennlich(walter). maennlich(johannes). maennlich(klaus). % elternteil_von( Elternteil, Person ): % 'Elternteil' und 'Person' sind Argumentpositionen, so dass % 'Elterntei' ein Elternteil von 'Person' ist. elternteil_von(E,P) :- vater_von(E,P). elternteil_von(E,P) :- mutter_von(E,P). % grossvater_von( Grossvater , Enkelkind ) % 'Grossvater' und 'Enkelkind' sind Argumentpositionen, so dass % 'Grossvater' ein Grossvater von 'Enkelkind' ist. grossvater_von(Grossvater , Person) :- vater_von(Grossvater,Z), elternteil_von(Z,Person). % onkel_von % Hier ist das Prädikatsschema uneindeutig: % Die intendierte Bedeutung "Onkel" wird durch den zweiten % Argumentsnamen 'Urenkel' gestört. Wir korrigieren das zu: % onkel_von(Onkel, Person) % 'Onkel' und 'Person' sind Argumentpositionen, so dass % 'Onkel' ein Onkel von 'Person' ist. % Ausserdem wird der Onkelbegriff so weit gefasst, dass auch Stiefonkel % unter das Prädikat onkel_von fallen. onkel_von(Onkel,Person) :- maennlich(Onkel), elternteil_von(X,Onkel), elternteil_von(X,Geschwister), Onkel \= Geschwister, % Das Geschwister sollte % nicht der Onkel selbst sein elternteil_von(Geschwister,Person). % ---- Beispielanfragen ---- Yes ?- grossvater_von(otto,X). % Wer sind die Enkelkinder von otto? X = jana ; X = frida ; No ?- grossvater_von(walter,Enkel). % Die Enkelkinder von walter? Enkel = klaus ; Enkel = andrea ; No ?- grossvater_von(X,jana). % Wer sind die Grossväter von jana? X = otto ; No % Über den anderen Grossvater gibt es keine Auskunft in der DB ?- onkel_von(Onkel,Person). % Wer ist der Onkel von Wem? Onkel = hans Person = jana ; Onkel = hans Person = frida ; Onkel = hans Person = jana ; Onkel = hans Person = frida ; No % die redundante Information rührt von der Tatsache her, % dass Prolog einmal die Vaterlinie % und zum anderen die Mutterlinie testet. ?- halt. Aufgabe 3 (komplexe Anfragen II) -------------------------------- a) Yes ?- consult('HAEUSER1.pl'). % HAEUSER1.pl compiled 0.00 sec, 1,320 bytes Yes ?- listing. % Foreign: rl_read_init_file/1 bew(1, 1, mueller, meier, 450000, '97.01.01'). bew(2, 3, schulze, schneider, 560000, '88.12.13'). bew(3, 3, schneider, mueller, 615000, '96.12.01'). bew(4, 5, bund, piepenbrink, 3500000, '91.06.01'). % Foreign: rl_add_history/1 obj(1, efh, gaertnerstr, 15, 1965). obj(2, efh, bahnhofsstr, 27, 1943). obj(3, efh, bahnhofsstr, 29, 1955). obj(4, mfh, bahnhofsstr, 28, 1991). obj(5, bahnhof, bahnhofsstr, 30, 1901). obj(6, kaufhaus, bahnhofsstr, 26, 1997). obj(7, efh, gaertnerstr, 17, 1982). Yes % i.) In welchen Strassen gibt es Einfamilienhäuser ?- obj(_,efh,Strassenname,_,_). Strassenname = gaertnerstr ; Strassenname = bahnhofsstr ; Strassenname = bahnhofsstr ; Strassenname = gaertnerstr ; No % i.') Dieselbe Anfrage mit dem findall-Prädikat ?- findall(Strassenname,obj(_,efh,Strassenname,_,_),L). Strassenname = _G159 L = [gaertnerstr, bahnhofsstr, bahnhofsstr, gaertnerstr] ; No % ii.) Welche Häuser sind in den letzten Zehn Jahren gebaut worden? ?- obj(Objektnummer,_,_,_,X), X > 1993, X < 2005. Objektnummer = 6 X = 1997 ; No % ii'.) ?- findall(haus(Objektnummer,Strassenname,Hausnummer),(obj(Objektnummer,_,Strassenname,Hausnummer,X),X > 1993, X < 2005),L). Objektnummer = _G157 Strassenname = _G158 Hausnummer = _G159 X = _G165 L = [haus(6, bahnhofsstr, 26)] ; No % iii.) Auf welchen Grundstücken stehen keine Einfamilienhäuser? ?- obj(_,Objekttyp,Strassenname,Hausnummer,_),Objekttyp \= efh. Objekttyp = mfh Strassenname = bahnhofsstr Hausnummer = 28 ; Objekttyp = bahnhof Strassenname = bahnhofsstr Hausnummer = 30 ; Objekttyp = kaufhaus Strassenname = bahnhofsstr Hausnummer = 26 ; No % iii'.) ?- findall(grundstueck(Strassenname,Hausnummer),(obj(_,Objekttyp,Strassenname,Hausnummer,_),Objekttyp \=efh),L). Strassenname = _G157 Hausnummer = _G158 Objekttyp = _G161 L = [grundstueck(bahnhofsstr, 28), grundstueck(bahnhofsstr, 30), grundstueck(bahnhofsstr, 26)] ; No % iv.) Welches Haus wurde mit Gewinn weiterverkauft? % Ausgespart wurden Ketten und Zyklen ?- bew(_,Objektnummer,_,Name,Betrag1,Datum1), bew(_,Objektnummer,Name,_,Betrag2,Datum2),Betrag2 > Betrag1,Datum2 @> Datum1, obj(Objektnummer,_,Strassenname,Hausnummer,_). Objektnummer = 3 Name = schneider Betrag1 = 560000 Datum1 = '88.12.13' Betrag2 = 615000 Datum2 = '96.12.01' Strassenname = bahnhofsstr Hausnummer = 29 ; No No b) Durch Verwendung der anonymen Variablen '_' kann die Ausgabe unterdrückt werden. Auch kann eine Regel verwendet werden, um Variablen innerhalb der Regel zu verstecken. c) Für diese Aufgabe modifizieren wir zunächst die Datenbasis, so dass wir nicht mit dem "[[Y2K]]-Problem" zu kämpfen haben: Bsp.: aus der Datumsangabe '97.01.01' mache '1997.01.01'. % --- Datenbasis [[HAEUSER1_NEU]].pl ---- % obj(Objektnummer, Objekttyp, Strassenname, Hausnummer, Baujahr). obj(1,efh,gaertnerstr,15,1965). obj(2,efh,bahnhofsstr,27,1943). obj(3,efh,bahnhofsstr,29,1955). obj(4,mfh,bahnhofsstr,28,1991). obj(5,bahnhof,bahnhofsstr,30,1901). obj(6,kaufhaus,bahnhofsstr,26,1997). obj(7,efh,gaertnerstr,17,1982). % Modifiziert: 'Verkaufsdatum'! Bsp.: '97.01.01' --> '1997.01.01' % bew(Vorgangsnr, Objektnr, Verkaeufer, Kaeufer, Preis, Verkaufsdatum) :- dynamic bew/6. bew(1,1,mueller,meier,450000,'1997.01.01'). bew(2,3,schulze,schneider,560000,'1988.12.13'). bew(3,3,schneider,mueller,615000,'1996.12.01'). bew(4,5,bund,piepenbrink,3500000,'1991.06.01'). % Neu eingefügt bew(5,7,schiller,goethe,560000,'2002.12.13'). bew(6,7,goethe,herder,615000,'2002.12.14'). bew(8,5,piepenbrink,schmidt,50000,'2002.12.23'). bew(9,6,jonas,schmidt,500000,'2002.12.23'). bew(10,5,schmidt,meier,350000,'2003.04.12'). bew(11,3,schneider,schmidt,210000,'2003.01.02'). bew(12,1,meier,schmidt,400000,'2003.04.12'). bew(13,3,schmidt,hose,360000,'2003.02.30'). bew(14,1,schmidt,bund,580000,'2003.07.08'). bew(15,2,schneider,meier,210000,'2003.01.02'). bew(16,2,meier,schmidt,400000,'2003.08.06'). % neueigentuemer(Eigentuemer,Objektnummer). % Eigentuemer hat Objekt mit Objektnummer nach 31.12.2001 % erworben und nicht weiterverkauft neueigentuemer(Eig,[[ObjNr]]) :- bew(_,[[ObjNr]],_,Eig,_,Datum), Datum @> '2001.12.31', \+((bew(_,[[ObjNr]],Eig,_,_,Datum2),Datum2 @>= Datum)). % ---- Protokoll ----- ?- consult('[[HAEUSER1_NEU]].PL'). % [[HAEUSER1_NEU]].PL compiled 0.00 sec, 4,176 bytes Yes % Liste zunächst die Neueigentümer auf ?- neueigentuemer(Eig,[[ObjNr]]). Eig = herder [[ObjNr]] = 7 ; Eig = schmidt [[ObjNr]] = 6 ; Eig = meier [[ObjNr]] = 5 ; Eig = hose [[ObjNr]] = 3 ; Eig = bund [[ObjNr]] = 1 ; Eig = schmidt [[ObjNr]] = 2 ; No % Neueigentümer in der Gärtnerstrasse? ?- neueigentuemer(Eig,[[ObjNr]]),obj([[ObjNr]],_,gaertnerstr,_,_). Eig = herder [[ObjNr]] = 7 ; Eig = bund [[ObjNr]] = 1 ; No % Neueigentümer mit benachbarten Immobilien? ?- neueigentuemer(Eig,Obj1), neueigentuemer(Eig,Obj2), Obj1 \= Obj2, obj(Obj1,_,Strasse,Num1,_), obj(Obj2,_,Strasse,Num2,_), ((Num1 =:=Num2-2); (Num2 =:=Num1-2)). No % Keine vorhanden. % Füge einen solchen Eigentümer ein: ?- assert(bew(17,1,bund,herder,580000,'2004.07.08')). Yes ?- neueigentuemer(Eig,Obj1), neueigentuemer(Eig,Obj2), Obj1 \= Obj2, obj(Obj1,_,Strasse,Num1,_), obj(Obj2,_,Strasse,Num2,_), ((Num1 =:=Num2-2); (Num2 =:=Num1-2)). Eig = herder Obj1 = 7 Obj2 = 1 Strasse = gaertnerstr Num1 = 17 Num2 = 15 Yes ?- halt.