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 2015 Aufgabenblatt Nr. 4 Abgabe: Mittwoch 13. Mai 2015 vor! der Vorlesung Aufgabe 1 (24 Punkte) a) Berechnen (Rechenweg erforderlich!) Sie die Menge der freien Variablen FV (s) und der gebundenen Variablen GV (s) für den Ausdruck s := if (\x -> let x = \x -> (y x) in x) then (x y) else (let f x = (w x) in \x -> w) (jeweils 8 Punkte) b) Benennen Sie die gebundenen Variablen von s um, so dass die gebundenen Variablen (paarweise) verschieden sind (d.h. an jedem Binder wird eine neue Variable verwendet) und disjunkt von den freien Variablen sind. (8 Punkte) Aufgabe 2 (20 Punkte) Implementieren Sie die folgenden Funktionen in Haskell im Wesentlichen unter Verwendung von List Comprehensions, d.h. die entsprechende Implementierung sollte von der Form f xs = e sein, wobei e eine List Comprehension ist, die xs verwendet. Die Verwendung von Pattern Matching in Funktionsargumenten und den Listenfunktionen map, filter und concat ist dabei verboten! a) Eine Funktion f1, die eine Liste xs von Paaren (as, bs) erhält, wobei jeweils as und bs Listen von Zahlen sind. Die Funktion f1 erstellt daraus die Liste von Drei-Tupeln (a, b, a + b) für alle Elemente a aus as und b aus bs, wobei nur dann ein Tupel in der Ausgabe erscheint, wenn b durch a ohne Rest teilbar ist. Z.B. soll f1 [([2,3],[4,5,6]),([3,3,9],[6,6]),([30,10],[20,40])] als Ergebnis die Liste [(2,4,6),(2,6,8),(3,6,9),(3,6,9),(3,6,9),(3,6,9),(3,6,9),(10,20,30),(10,40,50)] liefern. (10 Punkte) b) Eine Funktion f2, die eine Liste xs von Listen von Zahlen erhält, und zunächst alle inneren Listen entfernt, die mehr als 4 Elemente enthalten und anschließend in den verbleibenden inneren Listen alle ungeraden Zahlen entfernt. Dabei ist die Ausgabe die entstehende Liste von Listen von Zahlen. Z.B. soll f2 [[1,2,3,4,5],[6,7,8,9],[10,11,12]] als Ergebnis die Liste [[6,8],[10,12]] erzeugen. (10 Punkte) 1 Aufgabe 3 (22 Punkte) Geben Sie jeweils List Comprehensions in Haskell an, welche die folgenden Listen erzeugen: a) Die unendliche Liste aller Zahlen n (n ∈ N), die durch 11, aber nicht durch 5 teilbar sind. (6 Punkte) b) Geben Sie eine List Comprehensions an, die die (endliche) Liste aller 3-Tupel (x, y, z) für alle x ∈ {’a’,’b’,’c’}, y ∈ {True, False} und z ∈ {1, 2, . . . , 1000} erzeugt, und zwar in der Reihenfolge, sodass stetig die Wahrheitswerte wechseln, danach die Buchstaben, und zuletzt die Zahlen erhöht werden, d.h. die Ausgabe beginnt mit: [(’a’,True,1),(’a’,False,1),(’b’,True,1),(’b’,False,1),(’c’,True,1),(’c’,False,1), (’a’,True,2),(’a’,False,2),(’b’,True,2),(’b’,False,2)... (8 Punkte) c) Die unendliche Liste xs aller Paar (a, b) mit a, b ∈ N, so dass die Paare in einer fairen Reihenfolge erzeugt werden. Fair bedeutet hierbei, dass (a,b) ‘elem‘ xs für jedes Paar von Zahlen (a,b) nach endlicher Zeit terminiert. (8 Punkte) Aufgabe 4 (34 Punkte) Ein Brief sei durch die folgen Attribute repräsentiert • • • • Abmessungen (Länge, Breite, Höhe) jeweils in mm Gewicht in Gramm Empfänger als Zeichenkette Absender als Zeichenkette In Haskell sei ein Brief dementsprechend durch den folgenden Datentyp Brief1 und die Typsynonyme Abmessungen, Gewicht, Empfaenger und Absender dargestellt: data Brief = Brief deriving(Eq,Show) type Abmessungen = type Gewicht = type Empfaenger = type Absender = Abmessungen Gewicht Empfaenger Absender (Int,Int,Int) Int String String Z.B. kann ein Brief der Größe DIN C6 mit einer Höhe von 3mm und einem Gewicht von 15 Gramm, der von der Präsidentin der Goethe-Universität an den Hessischen Ministerpräsidenten versendet wird, als beispiel = Brief (162,114,3) 15 "Hessischer Ministerpraesident" "Praesidentin der Goethe-Universitaet" dargestellt werden. 1 Die Zeile deriving(Eq,Show) führt dabei dazu, dass Objekte des entsprechenden Datentyps angezeigt und verglichen werden können. 2 a) Implementieren Sie Zugriffsfunktionen – getLaenge :: Brief -> Int – getBreite :: Brief -> Int – getHoehe :: Brief -> Int – getGewicht :: Brief -> Gewicht – getEmpfaenger :: Brief -> Empfaenger – getAbsender :: Brief -> Absender die für einen Brief dessen Länge, Breite, Höhe, Gewicht, Empfänger bzw. Absender extrahieren. (6 Punkte) b) Die Post2 unterscheidet Briefe in die Formate Standard, Kompakt, Groß und Maxi, wobei das anfallende Porto entsprechend ansteigt. Die Klassifzierung der Briefe erfolgt anhand der folgenden Tabelle: Format Standard Kompakt Groß Maxi Länge im Bereich 140 bis 235 mm 100 bis 235 mm 100 bis 353 mm 100 bis 353 mm Breite im Bereich 90 bis 125 mm 70 bis 125 mm 70 bis 353 mm 70 bis 353 mm Höhe bis zu 5 mm 10 mm 20 mm 20 mm Gewicht bis zu 20g 50g 500g 1000g Porto 0,62 EUR 0,85 EUR 1,45 EUR 2,40 EUR Die Briefklassen seien in Haskell durch den folgenden Datentyp Klasse repräsentiert: data Klasse = Standard | Kompakt | Gross | Maxi | Ungueltig deriving(Eq,Show) wobei der Wert Ungueltig ausdrückt, dass ein Brief keiner der Klassen zugeordnet werden kann. Implementieren Sie in Haskell eine Funktion klassifiziere :: Brief -> Klasse, die einen Brief als Eingabe erhält und diesen der kostengünstigsten Klasse zuordnet. (10 Punkte) c) Geben Sie die Definition eines Datentyps BriefMitFrankierung in Haskell an, welcher den Datentyp Brief um ein weiteres Attribut Frankierung (in Cent als Int-Wert) erweitert und implementieren Sie in Haskell eine Funktion konvertiere :: BriefMitFrankierung -> Brief, die einen BriefMitFrankierung in einen Brief (durch Weglassen der Frankierung) konvertiert. (8 Punkte) d) Ein Postsack sei durch eine Liste von Briefen mit Frankierung dargestellt: type Postsack = [BriefMitFrankierung] Implementieren Sie in Haskell eine Funktion pruefe :: Postsack -> (Postsack,Postsack), die einen Postsack als Eingabe erhält und ein Paar von Postsäcken liefert, wobei die erste Komponente alle korrekt frankierten Briefe und die zweite Komponete alle falsch frankierten Briefe enthält. Beachten Sie, dass es erlaubt ist (der Brief ist dann ebenfalls korrekt frankiert), wenn die Frankierung höher als das notwendige Porto ist. (10 Punkte) 2 Die hier verwendete Darstellung ist vereinfacht, tatsächlich gibt es weitere Anforderungen und Ausnahmen, die hier nicht berücksichtigt werden 3