Praktikum Funktionale Programmierung Teil 2: Typecheck und Transformation Dr. David Sabel Sommersemester 2015 Stand der Folien: SoSe 2015
Übersicht FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 2/34
Übersicht FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 2/34
Übersicht FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 2/34
Übersicht Bearbeitungszeit: 5 Wochen FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 2/34
Das Typsystem (ohne Typvariablen) Formalismen in den Typregeln: Sind von der Form: e :: τ = Ausdruck e hat den Typ τ Voraussetzung Konsequenz Γ ist eine Typumgebung: {x 1 :: τ 1,..., x n :: τ n } Γ S = Disjunkte Vereinigung von Γ und S Γ e :: τ: In der Typumgebung Γ kann man für e den Typ τ herleiten FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 3/34
Typregeln (ohne Typvariablen) Γ e :: τ Γ e 1 :: IO τ 1, Γ e 2 :: τ 1 IO τ 2 Γ return e :: IO τ Γ e 1 >>= e 2 :: IO τ 2 Γ e :: IO τ Γ forkio e :: IO τ Γ e 1 :: MVar τ, Γ e 2 :: τ Γ putmvar e 1 e 2 :: IO () Γ e :: MVar τ Γ takemvar e :: IO τ Γ e :: τ Γ newmvar e :: IO (MVar τ) i : Γ e i :: τ i und c :: τ 1... τ n τ n+1 Γ (c e 1... e ar(c) ) :: τ n+1 Γ e 1 :: τ 1 τ 2, Γ e 2 :: τ 1 Γ (e 1 e 2 ) :: τ 2 Γ {x :: τ 1 } e :: τ 2 Γ (λx e) :: τ 1 τ 2 FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 4/34
Typregeln (ohne Typvariablen) Γ {x :: τ} x :: τ Γ e 1 :: τ 1, Γ e 2 :: τ 2 τ 1 = τ 3 τ 4 oder τ 1 = T Γ (seq e 1 e 2 ) :: τ 2 Γ e :: T, i : Γ {x 1,i :: τ 1,i,... x ni,i :: τ ni,i} (c i x 1,i... x ni,i) :: T, i : Γ {x 1,i :: τ 1,i,... x ni,i :: τ ni,i} e i :: τ 2 Γ (case T e of (c 1 x 1,1... x n1,1 e 1 )... (c m x 1,m... x nm,m e m )) :: τ 2 i : Γ {x 1 :: τ 1,... x n :: τ n } e i :: τ i, Γ {x 1 :: τ 1,... x n :: τ n } e :: τ Γ (letrec x 1 = e 1,... x n = e n in e) :: τ FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 5/34
Algorithmus dazu Baue den Typherleitungsbaum von unten nach oben auf. Z.B. aber auch x :: Bool x :: Bool λx x :: Bool Bool x :: ListBool x :: ListBool λx x :: ListBool ListBool FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 6/34
Größeres Beispiel {x :: Bool, y :: Bool} y :: Bool {x :: Bool} (λy x) :: Bool Bool True :: Bool (λx λy x) :: Bool Bool Bool True :: Bool ((λx λy x) True) :: Bool Bool ((λx λy x) True False) :: Bool False :: Bool False :: Bool FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 7/34
Problem bei diesem Typsystem Man muss manchmal den richtigen Typ raten Z.B. {x :: τ 1 } e :: τ 2 λx x :: τ 1 τ 2 Welchen Typ nimmt man für τ 1? Ausweg: Typvariablen benutzen und Typgleichungen E {x :: α} e :: τ 2, E λx x :: τ 1 τ 2, E In den Gleichungen E werden die Anforderungen an die Variablen gesammelt FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 8/34
Beispiel: Anwendungsregel Vorher: Γ e 1 :: τ 1 τ 2, Γ e 2 :: τ 1 Γ (e 1 e 2 ) :: τ 2 Jetzt: Γ e 1 :: τ 1, E 1 und Γ e 2 :: τ 2, E 2 Γ (e 1 e 2 ) :: α, E 1 E 2 {τ 1. = τ2 α} Γ e : τ, E e kann unter Typumgebung mit dem Typ τ typisiert werden, wobei die Gleichungen aus E noch gelöst werden müssen FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 9/34
Typisierungsregeln mit Gleichungen Γ e :: τ, E Γ return e :: IO τ, E Γ e 1 :: τ 1, E 1 und Γ e 2 :: τ 2, E 2 Γ e 1 >>= e 2 :: IO α 2, E 1 E 2 {τ 1. = IO α, τ2. = α IO α2 } Γ e :: τ, E Γ forkio e :: τ, E {τ. = IO α} Γ e :: τ, E Γ takemvar e :: IO α, E {τ. = MVar α} Γ e 1 :: τ 1, E 1 und Γ e 2 :: τ 2, E 2 Γ putmvar e 1 e 2 :: IO (), E 1 E 2 {τ 1. = MVar τ2 } FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 10/34
Typisierungsregeln mit Gleichungen (2) Γ e :: τ, E Γ newmvar e :: IO (MVar τ), E Γ (c e 1... e ar(c) ) :: τ n+1, i i : Γ e i :: τ i, E i E i {Typ(c). = τ 1... τ n τ n+1 } Γ e 1 :: τ 1, E 1 und Γ e 2 :: τ 2, E 2 Γ (e 1 e 2 ) :: α, E 1 E 2 {τ 1. = τ2 α} Γ {x :: α} e :: τ, E Γ (λx e) :: α τ, E Γ {x :: τ} x :: τ, FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 11/34
Typisierungsregeln mit Gleichungen (3) Γ e 1 :: τ 1, E 1 Γ e 2 :: τ 2, E 2 τ 1. = τ3 τ 4 oder τ 1. = T Γ (seq e 1 e 2 ) :: τ 2, E 1 E 2 Γ e :: τ, E i : Γ {x 1,i :: α 1,i,... x ni,i :: α ni,i} (c i x 1,i... x ni,i) :: τ i, E i i : Γ {x 1,i :: α 1,i,... x ni,i :: α ni,i} e i :: τ i, E i case e of(c 1 x 1,1... x n1,1 e 1 ) Γ... :: α, (c m x 1,m... x nm,m e m ) E (E i E i {α =. τ i} {τ =. τ i }) i i : Γ {x 1 :: α 1,... x n :: α n } e i :: τ i, E i Γ {x 1 :: α 1,... x n :: α n } e :: τ, E Γ (letrec x 1 = e 1,... x n = e n in e) :: τ, E i E i i {α i. = τi } FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 12/34
Beispiel {x :: α 2, y :: α 3 } x :: α 2, {x :: α 2 } λy x :: α 3 α 2, (λx λy x) :: α 2 α 3 α 2,, True :: Bool,. ((λx λy x) True) :: α 1, {α 2 α 3 α 2 = Bool α1 }, False :: Bool,. ((λx λy x) True False) :: α 0, {α 2 α 3 α 2 = Bool α1, α 1 = Bool α 0 } FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 13/34
Beispiel {x :: α 2, y :: α 3 } x :: α 2, {x :: α 2 } λy x :: α 3 α 2, (λx λy x) :: α 2 α 3 α 2,, True :: Bool,. ((λx λy x) True) :: α 1, {α 2 α 3 α 2 = Bool α1 }, False :: Bool,. ((λx λy x) True False) :: α 0, {α 2 α 3 α 2 = Bool α1, α 1 = Bool α 0 } Löse: {α 2 α 3 α 2. = Bool α1, α 1 = Bool α 0 } Durch Hinschauen: α 2 α 3 α 0 α 1 = Bool = Bool = Bool = Bool Bool FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 13/34
Regel zur Typherleitung Γ e :: τ, E Typherleitung Γ e :: σ(τ) wenn σ Lösung von E Für das Beispiel:.. ((λx λy x) True False) :: α 0, {α 2 α 3 α 2 = Bool α1, α 1 = Bool α0 } ((λx λy x) True False) :: Bool FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 14/34
Gleichungen lösen: Unifikation Unifikation: Verfahren um Gleichungen zu lösen Datenstrukturen: E g = Menge der gelösten Gleichungen E u = Menge der ungelösten Gleichungen Start: E g =, E u enthält alle Gleichungen Ende: Fail oder E u = Regeln: nächste Folie Notation: E[τ/a] ersetze a durch τ in allen Untertermen der Gleichungen in E FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 15/34
Unifikationsregeln (1) α ist Typvariable, T, T 1, T 2 sind Typkonstruktoren Elim E g, {α. = α} E u E g, E u Solve E g, {α =. τ} E u E g [τ/α] {α =., falls α nicht in τ vorkommt. τ}, E u [τ/α] Occ.Check E g, {α. = τ} E u fail., falls α in τ vorkommt und τ = α Orient E g, {τ. = α} E u E g, {α. = τ} E u, wenn τ keine Typvariable ist Decomp.T E g, {T. = T } E u E g, E u FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 16/34
Unifikationsregeln (2) α ist Typvariable, T, T 1, T 2 sind Typkonstruktoren FailT E. g, {T 1 = τ} Eu, falls τ = T 2 und T 1 T 2, τ = IO τ, fail τ = MVar τ oder τ = τ 1 τ 2 Decomp.IO E. g, {IO τ 1 = IO τ2 } E u. E g, {τ 1 = τ2 } E u. = τ 2} E u FailMVar E g, {MVar τ 1 fail, falls τ 2 = T, τ 2 = MVar τ oder τ 2 = τ 1 τ 2 FailIO E g, {IO τ 1 fail Decomp.MVar E. g, {MVar τ 1 = MVar τ2 } E u. E g, {τ 1 = τ2 } E u. = τ 2} E u, falls τ 2 = T, τ 2 = IO τ oder τ 2 = τ 1 τ 2 FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 17/34
Unifikationsregeln (3) α ist Typvariable, T, T 1, T 2 sind Typkonstruktoren Decomp.Fn E. g, {τ 1 τ 2 = τ 1 τ 2} E u. E g, {τ 1 = τ. 1, τ 2 = τ 2 } E u FailFn E. g, {τ 1 τ 2 = τ} Eu, falls τ = T, τ = IO τ fail oder τ = MVar τ FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 18/34
Beispiel E g =, E u = {b c =. c a, b =. d MVar Bool, c =. Bool MVar d, e =. a Bool} E g =, E u = {b =. c, c =. a, b =. d MVar Bool, c =. Bool MVar d, e =. a Bool} E g = {b =. c}, E u = {c =. a, c =. d MVar Bool, c =. Bool MVar d, e =. a Bool} E g = {b =. a, c =. a}, E u = {a =. d MVar Bool, a =. Bool MVar d, e =. a Bool} E g = {b =. d MVar Bool, c =. d MVar Bool, a =. d MVar Bool}, E u = {d MVar Bool =. Bool MVar d, e =. (d MVar Bool) Bool} E g = {b =. d MVar Bool, c =. d MVar Bool, a =. d MVar Bool}, E u = {d =. Bool, MVar Bool =. MVar d, e =. (d MVar Bool) Bool} E g = {b =. Bool MVar Bool, c =. Bool MVar Bool, a =. Bool MVar Bool, d =. Bool}, E u = {MVar Bool =. MVar Bool, e =. (Bool MVar Bool) Bool} E g = {b =. Bool MVar Bool, c =. Bool MVar Bool, a =. Bool MVar Bool, d =. Bool}, E u = {Bool =. Bool, e =. (Bool MVar Bool) Bool} E g = {b =. Bool MVar Bool, c =. Bool MVar Bool, a =. Bool MVar Bool, d =. Bool}, E u = {e =. (Bool MVar Bool) Bool} E g = {b =. Bool MVar Bool, c =. Bool MVar Bool, a =. Bool MVar Bool, d =. Bool, e =. (Bool MVar Bool) Bool}, E u = FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 19/34
Beispiel (Forts.) E g = E u = {b =. Bool MVar Bool, c =. Bool MVar Bool, a =. Bool MVar Bool, d =. Bool, e =. (Bool MVar Bool) Bool}, Die Substitution (genannt: der Unifikator) lässt sich nun ablesen als {b Bool MVar Bool, c Bool MVar Bool, a Bool MVar Bool, d Bool, e (Bool MVar Bool) Bool}, FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 20/34
Aufgabe > type TypeEquation tname = (Type tname, Type tname) Implementieren: unify :: [TypeEquation ConsName] -> Either String [TypeEquation ConsName] Liefert: Hilfreich: Right loesung, wobei loesung die gelösten Gleichungen oder Left fehler, wobei fehler eine Fehlermeldung Variante von unify, die als Eingaben die gelösten und die ungelösten Gleichungen erhält. Funktion, die die Substitution E[τ/α] auf Typgleichungen durchführt. Funktion, die testet, ob eine Typvariable α in einem Typ τ vorkommt. FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 21/34
Implementierung des Typchecks Markiere alle Unterterme mit ihrem Typ: Verwende dafür den Label-Konstruktor Beispiel: Lam ((1,13),"x") (Var ((1,18),"x")) wir markiert: Label (TVar "t1" :->: TVar "t1") (Lam ((1,13),"x") (Label (TVar "t1") (Var ((1,18),"x")))) FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 22/34
Implementierung des Typchecks (2) Algorithmus: Wende die Typisierungsregeln rekursiv über die Termstruktur an Gleichungen dabei aufsammeln Am Ende unifizieren seq-test danach FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 23/34
Typen der Datenkonstruktoren Vorgegeben: > type TypeOfCons = [(String, Type ConsName)] Abbildung von Konstruktornamen auf den Typ des Konstruktors Hilfsfunktionen: mktypeofconslist :: [TDef ConsName ConsName] -> TypeOfCons erstellt aus der TDef-Liste die TypeOfCons-Liste gettypeofcons :: TypeOfCons -> String -> Maybe (Type ConsName) schaut den Typ eines Konstruktors in der TypeOfCons-Liste nach. Kann für Typ(c) verwendet werden. FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 24/34
Aufgabe Typ für Γ: type TypeEnvironment = [(String,Type ConsName)] Implementieren: > typecheck :: > TypeOfCons -- Liste der Konstruktortypen > -> [String] -- frische Namen > -> TypeEnvironment -- Gamma > -> (Expr () ConsName VarName) -- Ausdruck > -> ([String], -- verbleibende Namen > [TypeEquation ConsName], -- Gleichungen E > Expr (Type ConsName) ConsName VarName) -- Ausdruck mit Typmarkierungen Eingaben Die TypeOfCons-Liste Eine Liste von Strings, die als neue Namen dienen. Der Ausdruck Ausgabe ist 3-Tupel verbleibende neuen Namen Den Gleichungen E Mit Typen markierter Ausdruck Dran denken: Fehler, falls freie Variable entdeckt wird FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 25/34
Aufgabe Implementieren: tcheck :: ParseTree () ConsName VarName -> Expr (Type ConsName) ConsName VarName 1 typecheck für den Ausdruck 2 Unifikation 3 Unifikator anwenden 4 seq-ausdrücke prüfen FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 26/34
Aufgabe Γ e :: τ, E Γ, e :: σ(τ), E σ, wenn σ Lösung von E typecheck anpassen, so dass nach jeder Regelanwendung unifziert wird, bessere Fehlermeldungen. FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 27/34
Distinct Variable Convention Ausdruck erfüllt die DVC, wenn alle Variablen verschiedene Namen haben (λx x) (λx x) erfüllt die DVC nicht, (λx x) (λy y) schon In DVC überführen: Ausdruck mit frischen Variablen umbenennen Algorithmus in etwa: benenneum(λx e, σ) = λy.(benenneum(e, σ {x y}) benenneum(x, σ) = σ(x)... FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 28/34
Aufgabe Implementieren: > renameandclean :: > Expr (Type ConsName) ConsName VarName -- typis. Ausdrucl > -> [String] -- frische Namen > -> (Expr () String String, [String]) -- (Ausdruck, restl. Namen) Umbenennen Positionsmarkierungen für Variablen und Konstruktornamen wegwerfen ConsName String VarName String Typinformation wegwerfen: Label Typ Ausdruck Ausdruck FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 29/34
Maschinenausdrücke - MExpr Abstrakte Maschinen erfordern leicht vereinfachte Syntax Argumente von Anwendungen, Konstruktoranwendungen, etc. dürfen nur Variablen sein e, e i Expr M ::= x me (λx e) (e x) (c x 1... x ar(c) ) (seq e 1 x) (case T e of {((c T,1 x 1... x ar(ct,1 )) e T,1 );... ((c T, T x 1... x ar(ct, T )) e T, T ))} (letrec x 1 = e 1 ;... ; x n = e n in e) wobei n 1 me MExpr M ::= (return x) (x 1 >>= x 2 ) (forkio x) (takemvar x) (newmvar x) (putmvar x 1 x 2 ) FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 30/34
Übersetzung (1) (e 1 e 2) = letrec x = e 2 in ( e 1 x), wobei x eine neue Variable ist. (c e 1... e n) = letrec x 1 = e 1,..., x n = e n in (c x 1... x n), wobei x 1,..., x n neue Variablen sind. seq e 1 e 2 = letrec x = e 2 in (seq e 2 x), wobei x eine neue Variable ist. return e = letrec x = e in return x, wobei x eine neue Variable ist. e 1 >>= e 2 = letrec x 1 = e 1, x 2 = e 2 in x 1 >>= x 2, wobei x 1, x 2 neue Variablen sind. forkio e = letrec x = e in forkio x, wobei x eine neue Variable ist. takemvar e = letrec x = e in takemvar x, wobei x eine neue Variable ist. newmvar e = letrec x = e in newmvar x, wobei x eine neue Variable ist. putmvar e 1 e 2 = letrec x 1 = e 1, x 2 = e 2 in putmvar x 1 x 2, wobei x 1, x 2 neue Variablen sind. FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 31/34
Übersetzung (2) Für alle anderen Konstrukte wird homomorph über die Termstruktur gezogen: x = x λx e = λx e letrec x 1 = e 1,..., x n = e n in e = letrec x 1 = e 1,..., x n = e n in e case T e of {pat 1 e 1;... ; pat T e T } = case T e of {pat 1 e 1 ;... ; pat T e T } FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 32/34
Datentypen > data MExpr cname v = > VarM v > LamM v (MExpr cname v) > AppM (MExpr cname v) v > SeqM (MExpr cname v) v > ConsM (Either MAction cname) [v] > CaseM (MExpr cname v) [MCAlt cname v] > LetrecM [MBinding cname v] (MExpr cname v) > deriving(eq,show) > data MCAlt cname v = > CAltM cname [v] (MExpr cname v) > deriving(eq,show) > data MBinding cname v = > v := (MExpr cname v) > deriving(eq,show) FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 33/34
Aufgaben Implementieren: > normalize :: > [String] -- neue Namen > -> Expr () String String -- Ausdruck > -> ([String], MExpr String String) -- (Namen, Maschinenausdruck) Implementieren: > tomachineexpr :: String -> MExpr String String Lexen, Parsen, Typecheck, Umbenennen und in MExpr überführen. FP-PR Teil 2: Typecheck und Transformation Sommersemester 2015 D. Sabel 34/34