PD Dr. David Sabel Institut für Informatik Fachbereich Informatik und Mathematik Johann Wolfgang Goethe-Universität Frankfurt am Main Einführung in die funktionale Programmierung Wintersemester 2015/2016 Aufgabenblatt Nr. 2 Abgabe: Montag 26. Oktober 2015 vor der Vorlesung Bitte senden Sie den zu Ihrer Lösung zugehörigen Quellcode auch per Email an [email protected]. Aufgabe 1 (30 Punkte) a) Werten Sie den Ausdruck (((λx1 .(λx2 .(x1 x2 ))) (λx3 .(λx4 .x3 ))) (λx5 .x5 )) in Normalordnung bis zur WHNF aus. (10 Punkte) b) Werten Sie den Ausdruck (((λx1 .(λx2 .(x1 (x2 x2 )))) (λx3 .x3 )) (λx4 .x4 )) in Anwendungsordnung bis zur WHNF aus. (10 Punkte) c) Werten Sie den Ausdruck ((λx1 .x1 ) (let x2 = (λx3 .x3 ) in x2 )) mit verzögerter Auswertung bis zur WHNF aus. Geben Sie für jeden call-by-need Reduktionsschritt die verwendete Reduktionsregel an. (10 Punkte) 1 Aufgabe 2 (20 Punkte) Ein Datentyp in Haskell zur Darstellung von Lambda-Ausdrücken ist data Expression = Variable String | Lambda String Expression | Application Expression Expression deriving(Show) Z.B. kann der Lambda Ausdruck λx.((λy.y) x) in der Repräsentation als Lambda "x" (Application (Lambda "y" (Variable "y")) (Variable "x")) dargestellt werden. Mithilfe von Pattern-Matching können Funktionen in Haskell implementiert werden, die Lambda-Ausdrücke testen oder manipulieren. Z.B. kann eine Funktion isWHNF implementiert werden, die prüft, ob ein Ausdruck eine WHNF ist: isWHNF (Lambda var body) = True isWHNF _ = False Die Tiefe depth(t) eines Lambda-Ausdrucks t sei definiert durch: depth(λx.s) = 1 + depth(s) depth((e1 e2 )) = max(depth(e1 ), depth(e2 )) depth(x) = 1, wenn x eine Variable ist Z.B. gilt depth(λx.((λy.y) x)) = 3 Ein Lambda-Ausdruck t ist eine Normalform, wenn er eine WHNF ist und keine β-Reduktion an beliebiger Position in t möglich ist (d.h. t = λx.t0 für irgendein x und t0 und t 6= C[(λx.s1 ) s2 ] für alle x, s1 , s2 ). Z.B. ist der Ausdruck λx.((λy.y) x) zwar eine WHNF, aber keine Normalform, da er den β-Redex (λy.y) x besitzt. Implementieren Sie in Haskell die folgenden Funktionen: a) depth :: Expression -> Integer, die für einen Lambda-Ausdruck dessen Tiefe berechnet. (10 Punkte) b) isNormalform :: Expression -> Bool, die für einen Lambda-Ausdruck prüft, ob dieser eine Normalform ist. (10 Punkte) 2