Theorie der Programmierung SS 2017 Übungsblatt 5 Rev.16849 Abgabe der Lösungen: Tutorien zwischen 08.06. und 13.06. Präsenzaufgaben Church-Numerale Wir betrachten erneut die Church-Kodierung natürlicher Zahlen vom vorigen Übungsblatt: dne := λf a. f (f (f (. . . f a)))) | {z } n mit einheitlicher Kodierung one two three four zero = λf a . a succ n = λf a . f (n f a) = = = = succ succ succ succ zero one two three sowie den Operationen aus der Hausaufgabe, add und mult, mit der entsprechenden Semantik. Notation: Von nun an schreiben wir s + t und s ∗ t anstelle von add s t und mult s t und verwenden die βδ-Regeln dne + dme →∗βδ dn + me Übung 1 dne ∗ dme →∗βδ dnme. Subtraktion Das Dekrementieren von Church-Numeralen ist wesentlich komplizierter als die Addition, Multiplikation oder Exponentiation; angeblich benötigte Alonzo Church einige Jahre, um herauszubekommen, dass (und auf welche Weise) es möglich ist. Allerdings gab es zu dieser Zeit noch keine Computer, so dass Church auch kein Programmierer im klassischen Sinne war. pred n = fst (n (λp . pair (snd p) (succ (snd p))) (pair zero zero)) 1. Zeigen Sie, dass pred d2e →∗βδ d1e. 2. Erläutern Sie in eigenen Worten die Funktionsweise des durch pred implementierten Algorithmus. 3. Vervollständigen Sie die folgenden Funktionsdefinitionen: sub eq le lt n n n n m m m m = = = = ... ... ... ... // // // // n n n n −m == m ? ≤m? < m? Notation: Von nun an schreiben wir s − t, s == t, s ≤ t und s < t anstelle von sub s t , eq s t , le s t und lt s t . ThProg, SS 2017 Übung 2 Rekursive Definitionen In den meisten funktionalen Programmiersprachen sind rekursive Funktionsdefinitionen zulässig, das heißt, die definierte Funktion darf auf der rechten Seite einer solchen Funktionsdefinition vorkommen. Rekursive Funktionsdefinitionen entsprechen – wie in Übung 2, Blatt 4 – δReduktionen. 1. Wir betrachten die folgende rekursive Funktion: fact n = if n ≤ d1e then d1e else n ∗ (fact (n − d1e)) Zeigen Sie, dass fact d4e →∗βδ d24e. 2. Schreiben Sie eine rekursive Funktion odd dne, die true als Ergebnis liefert, wenn n ungerade ist, und false andernfalls. 3. Schreiben Sie eine rekursive Funktion halve, so dass: (d2e ∗ halve dne) + if odd dne then d1e else d0e →∗βδ dne. Übung 3 Typprüfung einfach getypter Terme Wir lesen Γ ` s : α wie folgt: “Dem λ-Term s lässt sich unter der Annahme, dass eventuellen freien Variablen von s die durch Γ gegebenen Typen zugeordnet sind, der Typ α zuweisen”. Zeigen Sie, dass die folgenden Aussagen zutreffen, indem Sie jeweils eine korrekte Typinferenz angeben. 1. x : int, add : int → int → int ` λy.add x (add x y) : int → int. 2. ` λx y . x : α → β → α, für alle Typen α und β. Hausaufgaben Übung 4 Wer braucht schon Rekursion? (7 Punkte) Rekursive Definitionen sind komfortabel, aber nicht notwendig: Bereits im reinen λ-Kalkül ist es möglich, Fixpunkt-Kombinatoren zu definieren (wie z.B. den Y-Kombinator). Es sei fix ein beliebiger Fixpunkt-Kombinator, d.h. es gelte fix f ↔∗βδ f (fix f). 1. Die folgende Definition entspricht der Funktion fact aus Übung 2; jedoch wurde die Rekursion durch einen Fixpunkt ersetzt: fact ’ = fix (λmyself n . if n ≤ d1e then d1e else n ∗ (myself (n − d1e))) Zeigen Sie, dass fact ’ d3e ↔∗βδ d6e 2. Schreiben Sie unter Verwendung von fix nun nicht-rekursive Versionen aller übrigen Definitionen aus Übung 2. 2 ThProg, SS 2017 Übung 5 Typprüfung einfach getypter Terme II (4 Punkte) Wir interpretieren Γ ` s : α wie in Übung 3. Zeigen Sie, dass die folgenden Aussagen zutreffen, indem Sie jeweils eine korrekte Typinferenz angeben. 1. length : string → int, name : person → string ` λx.length (name x) : person → int 2. ` λf x y . f y x : (int → char → string) → (char → int → string) 3. ` λf x y . f y x : (α → β → γ) → (β → α → γ), für alle Typen α, β und γ. Übung 6 Untypisierbare Terme (4 Punkte) Verwenden Sie das Inversionslemma um zu zeigen, dass: 1. 0 λx.xx : α, für jeden Typ α. 2. y : char 0 λx.yx : α, für jeden Typ α. Übung 7 η-Reduktion (5 Bonus-Punkte) Zusätzlich zur β-Reduktion, die das Einsetzen von Termen für gebundene Variablen in λ-Termen beschreibt, kann man noch die Ansicht vertreten, dass ein Term t dieselbe Funktion beschreibt wie der Term λx. tx, also eine Äquivalenz λx. tx =η t einführen (ähnlich wie bei α-Äquivalenz). Zugehörig ist eine Reduktionsregel λx. tx →η t. 1. Nach einem Theorem von Böhm gibt es für zwei in Bezug auf βη-Reduktion unterschiedliche Terme ohne freie Variablen ein n ∈ N und Terme u1 , . . . , un (ebenfalls ohne freie Variablen), sodass s u1 . . . un x y ↔∗βη x t u1 . . . un x y ↔∗βη y Finden Sie ein n sowie passende ui , i = 1 . . . n, um d0e und d1e auf diesem Wege zu unterscheiden. Hinweis: η-Reduktion könnte bei der Suche nach geeigneten Termen hilfreich sein. 2. Sei nun I = λx.x. Zeigen Sie, dass wir auch mit römischen Zahlen rechnen können: I + I ↔∗βη d2e. 3. Gegeben seien die λ-Terme (sogenannte Kombinatoren) B = λf gx.f (gx) und C = λf xy.f yx. Zeigen Sie, dass BCC ↔∗βη I. 3