Prof. Dr. Manfred Schmidt-Schauß Künstliche Intelligenz/Softwaretechnologie Fachbereich Informatik und Mathematik/ Institut für Informatik Johann Wolfgang Goethe-Universität Frankfurt am Main Einführung in die funktionale Programmierung Wintersemester 2009/2010 Aufgabenblatt Nr. 3 Abgabe: Dienstag 3. November 2009 vor! der Vorlesung Bitte senden Sie den zu Ihrer Lösung zugehörigen dokumentierten Quellcode auch per Email an [email protected]! Aufgabe 1 (20 Punkte) Implementieren Sie in Haskell eine Funktion zentriert :: Int -> String -> String, die eine Zeilenbreite (als Anzahl von Zeichen) sowie einen Text als String erwartet und diesen entsprechend der Zeilenbreite zentriert setzt. Falls Zeilen länger als die Zeilenbreite sind, soll ein Fehler generiert werden (hierfür gibt es die vordefinierte Funktion error :: String -> a). Ein Beispiel für Ein- und Ausgabe ist im folgenden abgebildet: Habe nun, ach! Philosophie, Juristerei und Medizin, Und leider auch Theologie Durchaus studiert, mit heißem Bemühn. Da steh ich nun, ich armer Tor! Und bin so klug als wie zuvor; Heiße Magister, heiße Doktor gar Und ziehe schon an die zehen Jahr Herauf, herab und quer und krumm Meine Schüler an der Nase herumUnd sehe, daß wir nichts wissen können! Das will mir schier das Herz verbrennen. Habe nun, ach! Philosophie, Juristerei und Medizin, Und leider auch Theologie Durchaus studiert, mit heißem Bemühn. Da steh ich nun, ich armer Tor! Und bin so klug als wie zuvor; Heiße Magister, heiße Doktor gar Und ziehe schon an die zehen Jahr Herauf, herab und quer und krumm Meine Schüler an der Nase herumUnd sehe, daß wir nichts wissen können! Das will mir schier das Herz verbrennen. Eingabe txt Ausgabe des Aufrufs zentriert 55 txt 1 Aufgabe 2 (30 Punkte) Eine Implementierung1 von KFPT-Ausdrücken mithilfe von Haskell-Datentypen könnte wie folgt aussehen, wobei wir annehmen, es gäbe nur die Typen Bool und List data Exp = Variable Variablenname | Konstruktor Konstruktorname [Exp] | Applikation Exp Exp | Lambda Variablenname Exp | Case Typname Exp [Alternative] deriving(Show) ------ data Alternative = Alt Pattern Exp deriving(Show) -- Alt ::= Pat -> E E E E E E ::= ::= ::= ::= ::= V c E_1 ... E_ar(c) (E_1 E_2) \V -> E case_Typ E of Alts data Pattern = Pat Konstruktorname [Variablenname] -- Pat ::= c V_1 ... V_ar(c) deriving(Show) type Variablenname = String type Konstruktorname = String type Typname = String typen konstruktoren "Bool" konstruktoren "List" stelligkeit "Cons" stelligkeit _ = = = = = ["Bool", "List"] ["True", "False"] ["Cons", "Nil"] 2 0 -- True, False, Nil alle 0 a) Definieren Sie eine Funktion istWHNF :: Exp -> Bool, die prüft, ob das Argument eine WHNF ist. (4 Punkte) b) Implementieren Sie Funktionen tryBeta :: Exp -> Maybe Exp und tryCase :: Exp -> Maybe Exp, die falls möglich eine unmittelbare β- bzw. case-Reduktion durchführen (und dann Just e, liefern, wenn e das Ergebnis der Reduktion ist) und ansonsten Nothing liefern. (14 Punkte) c) Implementieren Sie eine Funktion tryOneStepNO :: Exp -> Maybe Exp, die falls möglich eine Ein-Schritt-Normalordnungsreduktion durchführt und ansonsten Nothing liefert. (8 Punkte) d) Implementieren Sie eine Funktion reduziereBisZurWHNF :: Exp -> Exp, die einen Ausdruck so oft mit Normalordnungsreduktionen reduziert bis eine WHNF erreicht ist. (4 Punkte) Kommentieren und testen Sie sämtliche implementierten Funktionalitäten! 1 Der Quelltext ist auch auf der Webseite zur Veranstaltung abrufbar. Zusätzlich sind dort Hilfsfunktionen und Beispiele zu finden 2