5. Übungsblatt - Universität Konstanz

Werbung
Konzepte der Programmierung
Programmierkurs 2
Sommer 2017
Universität Konstanz
Informatik & Informationswissenschaft
M. Grossniklaus, J. Fuchs, L. Wörteler
5. Übungsblatt
(Ausgabe: 22. Mai 2017 — Abgabe bis: 29. Mai 2017, 15:00 Uhr)
Aufgabe 1 (6 Punkte) Der naive Ansatz, eine rekursive Funktion im λ-Kalkül zu realisieren,
scheitert. Betrachten wir die Fakultätsfunktion:
(
1
für n = 0
n! :=
n · (n − 1)! für n ≥ 1
Eine erste Umsetzung in den λ-Kalkül würde wahrscheinlich zu folgendem Punkt führen:
λn. if (= n 0) 1 (× n (f (− n 1)))
Da es im λ-Kalkül (wie bisher definiert) nicht möglich ist, einen Teilausdruck so an eine Variable
zu binden, dass man ihn in sich selbst referenzieren kann, müsste man für die Metavariable f den
gesamten Ausdruck einsetzen, den wir gerade zu definieren versuchen. Dieser enthielte aber wieder
ein f, sodass durch wiederholtes Einsetzen ein unendlich großer λ-Ausdruck entstünde. Das ist
nicht zulässig.
Man kann aber dennoch eine endliche Repräsentation der rekursiv definierten Fakultätsfunktion
formulieren. Dazu bedient man sich des sogenannten Y-Kombinators (Kombinatoren sind Ausdrücke
im λ-Kalkül ohne freie Variablen)
Y = λx. (λy. x (y y)) (λy. x (y y))
und einer modifizierten, nicht-rekursiven Definition der Fakultät, in der wir die Funktion für den
rekursiven Aufruf g als zusätzliches Argument erwarten:
f = λg. λn. if (= n 0) 1 (× n (g (− n 1)))
Nun entspricht Y f der Fakultätsfunktion. Vollziehen Sie dies nach, indem Sie die wohlbekannte
Reduktion mit dem Argument 2 durchführen. Vereinfachen Sie also den Ausdruck
Yf 2
des λ-Kalküls! Sie können dabei wiederkehrende Teilausdrücke abkürzen.
Aufgabe 2 (2 Punkte) Schreiben Sie eine Funktion
middle :: [a] -> a
die das mittlere Element der übergebenen Liste zurückgibt (bei einer ungeraden Anzahl von
Elementen). Hat die Liste 2p Elemente für ein p ∈ N, so soll das p-te Element zurückgegeben
werden.
Beispiele: middle [1,2,3] _ 2, middle "test" _ ’e’
Aufgabe 3 (2 Punkte) Schreiben Sie eine Funktion, die überprüft ob alle Listenelemente gleich
sind:
allEqual :: [Integer] -> Bool
Beispiele: allEqual [42,42,42,42,42,42,42,42] _ True, allEqual [1,1,1,2,1] _ False
1
Aufgabe 4 (4 Punkte) Schreiben Sie eine Funktion
gaps :: Double -> [Double] -> [(Double, Double)]
so dass gaps delta xs die Paare aller aufeinander folgenden Zahlen in xs ausgibt, die weiter als
delta voneinander entfernt sind. Nehmen Sie dabei an dass delta immer größer oder gleich Null
ist.
Beispiel:
*Main> gaps 2.2 [1.2, 3.4, 12.5, 6.14, 8, 11]
[(3.4,12.5),(12.5,6.14),(8.0,11.0)]
Aufgabe 5 (5 Punkte) Schreiben Sie eine Funktion
insSort :: (a -> a -> Bool) -> [a] -> [a]
die ein Vergleichsprädikat lt :: a -> a -> Bool und eine Liste ` als Argument bekommt. Die
Ausgabe soll die bezüglich der durch lt definierten Ordnung mit Insertion Sort sortierte Liste `
sein. Dabei funktioniert Insertion Sort wie folgt: Die zu sortierenden Elemente werden der Reihe
nach in eine (dann bereits sortierte) Ergebnisliste eingefügt. Schreiben Sie also zunächst eine
Hilfsfunktion
insert :: (a -> a -> Bool) -> a -> [a] -> [a]
die dieses erledigt. Beispiel:
Main> insert (<) 3 [1,2,5,7,9]
[1,2,3,5,7,9]
Main> insSort (>) [7,9,1,2,1,5]
[9,7,5,2,1,1]
Aufgabe 6 (6 Punkte)
f, g, und h
Die folgenden neun Ausdrücke zeigen alle Möglichkeiten, drei Variablen
• mit Anwendung durch Juxtaposition,
• durch den Anwendungsoperator $, oder
• mit der Komposition . zu kombinieren.
Teilen Sie diese in Gruppen äquivalenter Ausdrücke ein.
f g
h
f g . h
f g $ h
-- 1
-- 2
-- 3
f . g
h
f . g . h
f . g $ h
-- 4
-- 5
-- 6
f $ g
h
f $ g . h
f $ g $ h
-- 7
-- 8
-- 9
Tipp: Entfernen Sie zunächst alle Vorkommen von . und $, indem Sie Klammern und ggf.
λ-Abstraktionen mit neuen Variablen einführen.
Herunterladen