Grundlagen der Programmierung 2 Aufgabenblatt Nr. 2 Aufgabe 1

Werbung
Prof. Dr. Manfred Schmidt-Schauß
Künstliche Intelligenz/Softwaretechnologie
Fachbereich Informatik und Mathematik/ Institut für Informatik
Goethe-Universität Frankfurt am Main
Grundlagen der Programmierung 2
Sommersemester 2014
Aufgabenblatt Nr. 2
Abgabe: Mittwoch 30. April 2014 vor! der Vorlesung
Aufgabe 1 (35 Punkte)
In dieser Aufgabe betrachten wir Eltern-Kind-Beziehungen. Diese seien in Haskell durch
die drei Funktionen elternBekannt :: String -> Bool, vater :: String -> String und
mutter :: String -> String modelliert, wobei:
• elternBekannt gibt für eine Person an, ob dessen Vater und Mutter bekannt sind.
• vater bzw. mutter berechnet den Vater bzw. die Mutter eines Kindes, sofern diese(r)
bekannt ist (und gibt sonst einen Fehler aus).
Die drei Funktionen seien bereits im Quellcode definiert. Z.B. könnte der Stammbaum
Axel
Berta
Claudia
Detlef
m
m
Carl
Bruno
m
Anna
Bert
Albert
Birgit
Clemens
m
Clara
Dirk
Dominik
m
Adele
Bastian
m
Curt
Diana
durch die folgende Haskell-Implementierung repräsentiert werden (das Beispiel finden Sie zum
Download als Haskell-Quellcode auf der Webseite zur PRG-2):
elternBekannt
elternBekannt
elternBekannt
elternBekannt
elternBekannt
elternBekannt
elternBekannt
elternBekannt
"Axel"
"Anna"
"Albert"
"Adele"
"Berta"
"Claudia"
"Curt"
_
=
=
=
=
=
=
=
=
False
False
False
False
False
False
False
True
mutter "Bruno"
= "Anna"
mutter "Bert"
= "Anna"
mutter "Birgit" = "Anna"
mutter "Bastian" = "Adele"
mutter "Carl"
= "Berta"
mutter "Clemens" = "Berta"
mutter "Clara"
= "Birgit"
mutter "Detlef" = "Claudia"
mutter "Dirk"
= "Claudia"
mutter "Dominik" = "Clara"
mutter "Diana"
= "Clara"
mutter _
=
error "Mutter unbekannt"
vater "Bruno"
= "Axel"
vater "Bert"
= "Axel"
vater "Birgit" = "Axel"
vater "Bastian" = "Albert"
vater "Carl"
= "Bruno"
vater "Clemens" = "Bruno"
vater "Clara"
= "Bastian"
vater "Detlef" = "Carl"
vater "Dirk"
= "Carl"
vater "Dominik" = "Curt"
vater "Diana"
= "Curt"
vater _
=
error "Vater unbekannt"
In den Teilaufgaben müssen Sie Funktionen definieren. Diese dürfen vater, mutter und
elternBekannt aufrufen, aber müssen für jede Implementierung dieser Funktionen funktionieren, d.h. nicht ausschließlich für obiges Beispiel!.
1
Implementieren Sie in Haskell
a) eine Funktion mindestensEineGrossmutterBekannt :: String -> Bool, die für eine
Person prüft, ob der Name mindestens einer Großmutter bekannt ist, und in diesem Fall
True und ansonsten False als Ausgabe liefert.
(5 Punkte)
b) eine Funktion istVorfahre :: String -> String -> Bool, die zwei Personen P1 und
P2 als Eingaben erhält und True liefert, wenn P1 ein Vorfahre von P2 ist, und in allen
anderen Fällen (P1 ist kein Vorfahre von P2 oder es ist unbekannt) den Wert False liefert.
(10 Punkte)
c) eine Funktion sindGeschwister :: String -> String -> Bool, die für zwei Personen
P1 und P2 überprüft, ob diese Geschwister sind, d.h. ob P1 und P2 sowohl den gleichen
Vater als auch die gleiche Mutter haben.
(5 Punkte)
d) eine Funktion istCousinOderCousine :: String -> String -> Bool, die zwei Personen P1 und P2 erwartet und True liefert, wenn P1 ein Cousin oder eine Cousine von P2 ist,
und in allen anderen Fällen False liefert. P1 ist Cousin oder Cousine von P2 , wenn P2 ein
Kind eines Onkels oder einer Tante von P1 ist, oder anders formuliert, wenn ein Elternteil
von P1 und ein Elternteil von P2 Geschwister sind.
(8 Punkte)
e) eine Funktion sindVerwandt :: String -> String -> Bool, die die zwei Personen P1
und P2 erwartet und True liefert, wenn P1 und P2 verwandt sind, d.h. P1 und P2 haben einen gemeinsamen Vorfahren. Sie können hier annehmen, dass jeder mit sich selbst
verwandt ist.
(7 Punkte)
Einige Beispielaufrufe der Funktionen (für obiges Beispiel sind):
*> mindestensEineGrossMutterBekannt "Bruno"
False
*> mindestensEineGrossMutterBekannt "Dirk"
True
*> mindestensEineGrossMutterBekannt "Clemens"
True
*> mindestensEineGrossMutterBekannt "Curt"
False
*> istVorfahre "Axel" "Dirk"
True
*> istVorfahre "Axel" "Curt"
False
*> istVorfahre "Dirk" "Axel"
False
*> sindGeschwister "Dirk" "Axel"
False
*> sindGeschwister "Carl" "Clemens"
True
*> sindGeschwister "Bruno" "Birgit"
True
*> istCousinOderCousine "Carl" "Clara"
True
*> istCousinOderCousine "Detlef" "Diana"
False
*> istCousinOderCousine "Detlef" "Dirk"
False
*> istCousinOderCousine "Clemens" "Clara"
True
*> sindVerwandt "Dirk" "Curt"
False
*> sindVerwandt "Clemens" "Clara"
True
*> sindVerwandt "Bert" "Dirk"
True
*> sindVerwandt "Dirk" "Bert"
True
2
Aufgabe 2 (15 Punkte)
Die Funktionen g1 bis g6 seien in Haskell definiert als:
g1
g2
g3
g4
g5
g6
x
x
x
x
x
x y
=
=
=
=
=
=
(g2 (x+10)) * (g3 (x-10))
if x > 100 then 20 else 40
if x <= 0 then 1 else g3 (g4 x)
if x == 0 then g3 (x-1) else g6 (x-2) 2
if (g2 (g2 x)) == 20 then g5 (x-20) else 10
if y == 0 then g2 x else g3 (y-10)
a) Für welche Funktionen gi, gj (1 ≤ i, j ≤ 6) gilt:
Die Funktion gi referenziert Funktion gj direkt?
(3 Punkte)
b) Für welche Funktionen gi, gj (1 ≤ i, j ≤ 6) gilt:
Die Funktion gi referenziert die Funktion gj?
(6 Punkte)
c) Welche der Funktionen gi mit 1 ≤ i ≤ 6 sind direkt rekursiv?
(2 Punkte)
d) Welche der Funktionen gi mit 1 ≤ i ≤ 6 sind rekursiv?
(2 Punkte)
e) Welche Paare (gi, gj) mit 1 ≤ i < j ≤ 6 sind verschränkt rekursiv?
(2 Punkte)
Aufgabe 3 (40 Punkte)
Die Funktion fun sei definert als
fun x y = if y <= 3 then x else x*(fun (x-1) (y-2))
definiert. Geben Sie für alle Teilaufgaben jeweils sämtliche Reduktionsschritte sowie die jeweils
verwendete Regel als Buchstabe D, A oder I an (D = Definitionseinsetzung, A=Arithmetische
Auswertung, I=if-Auswertung).
a) Werten Sie fun (fun 3 (2+2)) (10-8) in normaler Reihenfolge aus.
(12 Punkte)
b) Werten Sie fun (fun (2*5) (3+1)) (2-1) in applikativer Reihenfolge aus.
(12 Punkte)
c) Werten Sie den Ausdruck fun (2*20) (5-1) in verzögerter Reihenfolge aus. (16 Punkte)
Aufgabe 4 (10 Punkte)
Die Funktionen g1, g2, g3, g4 und g5 seien in Haskell definiert als:
g1
g2
g3
g4
g5
a
a
a
a
a
b
b
b
b
b
c
c
c
c
c
=
=
=
=
=
if a > b then g1 (a+2) (b-1) c else b
if c == 0 then 1 else a + b + g2 (a-1) (b-1) (c-2)
if c > 0 then (g3 2 a c) + (g3 (a-b) (b+1) (a-c)) else a+b-(2*c)
if c <= 0 then b*a else (g4 (a+c) (b-2) (c-3)) + 10
if b < 0 then True
else (g5 6 (b-2) (c*2)) + (g5 (g5 (a-2) (b-4) (c-6)) (4*b) (c-2))
Vervollständigen Sie die folgende Tabelle:
. . . ist iterativ
. . . ist endrekursiv
. . . ist linear rekursiv
. . . ist Baum-rekursiv
. . . ist geschachtelt Baum-rekursiv
g1
ja /
ja /
ja /
ja /
ja /
g2
ja /
ja /
ja /
ja /
ja /
nein
nein
nein
nein
nein
3
nein
nein
nein
nein
nein
g3
ja /
ja /
ja /
ja /
ja /
nein
nein
nein
nein
nein
g4
ja /
ja /
ja /
ja /
ja /
nein
nein
nein
nein
nein
g5
ja /
ja /
ja /
ja /
ja /
nein
nein
nein
nein
nein
Herunterladen