P1-WS04-MusterLoesung03.txt

Aus Fachschaft_Informatik
Zur Navigation springen Zur Suche springen
Knut Briefmarke 2008.jpg
Diese Seite ist veraltet.
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.