P1-WS04-MusterLoesung03.txt: Unterschied zwischen den Versionen

Aus Fachschaft_Informatik
Zur Navigation springen Zur Suche springen
fsrwiki_>1illig
K (antispam)
 
fsrwiki_>Oddmuse Import
K (link fix)
Zeile 2: Zeile 2:
Aufgabenblatt 3
Aufgabenblatt 3


P1 WiSe 04/05
P1 [[WiSe]] 04/05


Özgür Özcep
Özgür Özcep
Zeile 30: Zeile 30:
explizites Auflisten. Fakten können formal als Regeln (s.u.) ohne
explizites Auflisten. Fakten können formal als Regeln (s.u.) ohne


Körper/Rumpf verstanden werden.
Körper[[/Rumpf]] verstanden werden.




Zeile 62: Zeile 62:
Klausel ist als ein (komplexes) Ziel zu verstehen. Formal können
Klausel ist als ein (komplexes) Ziel zu verstehen. Formal können


Anfragen/Ziele als Regeln ohne Kopf verstanden werden.
Anfragen[[/Ziele]] als Regeln ohne Kopf verstanden werden.




Zeile 710: Zeile 710:
Für diese Aufgabe modifizieren wir zunächst die Datenbasis, so dass
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
wir nicht mit dem "[[Y2K]]-Problem" zu kämpfen haben: Bsp.: aus der


Datumsangabe '97.01.01' mache '1997.01.01'.
Datumsangabe '97.01.01' mache '1997.01.01'.
Zeile 716: Zeile 716:




% --- Datenbasis HAEUSER1_NEU.pl ----
% --- Datenbasis [[HAEUSER1_NEU]].pl ----




Zeile 792: Zeile 792:




neueigentuemer(Eig,ObjNr) :-  
neueigentuemer(Eig,[[ObjNr]]) :-  


bew(_,ObjNr,_,Eig,_,Datum),
bew(_,[[ObjNr]],_,Eig,_,Datum),


Datum @> '2001.12.31',
Datum @> '2001.12.31',


\+((bew(_,ObjNr,Eig,_,_,Datum2),Datum2 @>= Datum)).
\+((bew(_,[[ObjNr]],Eig,_,_,Datum2),Datum2 @>= Datum)).




Zeile 810: Zeile 810:




?- consult('HAEUSER1_NEU.PL').
?- consult('[[HAEUSER1_NEU]].PL').


% HAEUSER1_NEU.PL compiled 0.00 sec, 4,176 bytes
% [[HAEUSER1_NEU]].PL compiled 0.00 sec, 4,176 bytes




Zeile 820: Zeile 820:
% Liste zunächst die Neueigentümer auf
% Liste zunächst die Neueigentümer auf


?- neueigentuemer(Eig,ObjNr).
?- neueigentuemer(Eig,[[ObjNr]]).




Zeile 826: Zeile 826:
Eig = herder
Eig = herder


ObjNr = 7 ;
[[ObjNr]] = 7 ;




Zeile 832: Zeile 832:
Eig = schmidt
Eig = schmidt


ObjNr = 6 ;
[[ObjNr]] = 6 ;




Zeile 838: Zeile 838:
Eig = meier
Eig = meier


ObjNr = 5 ;
[[ObjNr]] = 5 ;




Zeile 844: Zeile 844:
Eig = hose
Eig = hose


ObjNr = 3 ;
[[ObjNr]] = 3 ;




Zeile 850: Zeile 850:
Eig = bund
Eig = bund


ObjNr = 1 ;
[[ObjNr]] = 1 ;




Zeile 856: Zeile 856:
Eig = schmidt
Eig = schmidt


ObjNr = 2 ;
[[ObjNr]] = 2 ;




Zeile 864: Zeile 864:
% Neueigentümer in der Gärtnerstrasse?
% Neueigentümer in der Gärtnerstrasse?


?- neueigentuemer(Eig,ObjNr),obj(ObjNr,_,gaertnerstr,_,_).
?- neueigentuemer(Eig,[[ObjNr]]),obj([[ObjNr]],_,gaertnerstr,_,_).




Zeile 870: Zeile 870:
Eig = herder
Eig = herder


ObjNr = 7 ;
[[ObjNr]] = 7 ;




Zeile 876: Zeile 876:
Eig = bund
Eig = bund


ObjNr = 1 ;
[[ObjNr]] = 1 ;





Version vom 5. November 2007, 06:49 Uhr

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.