Praktikum BKSPP: [2ex] Blatt 4

Werbung
Praktikum BKSPP:
Blatt 4
Dr. David Sabel
SoSe 2012
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Interpreter allgemein
Lexikalische
Analyse
Syntaktische
Analyse
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
Semantische
Analyse
Ausführung /
Auswertung
2/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Interpreter allgemein
Lexikalische
Analyse
Syntaktische
Analyse
Semantische
Analyse
Ausführung /
Auswertung
Lexikalische Analyse: überführt Quelltext in Tokenstrom.
(Entfernen von Zeilenkommentaren, Leerzeichen, Umbrüchen, etc.)
Token: Syntaktische Einheit, z.B. 1000 nicht 1,0,0,0
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
2/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Interpreter allgemein
Lexikalische
Analyse
Syntaktische
Analyse
Semantische
Analyse
Ausführung /
Auswertung
Lexikalische Analyse: überführt Quelltext in Tokenstrom.
(Entfernen von Zeilenkommentaren, Leerzeichen, Umbrüchen, etc.)
Token: Syntaktische Einheit, z.B. 1000 nicht 1,0,0,0
Syntaktische Analyse: Prüft, ob Tokenstrom syntaktisch korrektes
Programm (anhand e. kontextfreien Grammatik)
Eingabe: Tokenstrom; Ausgabe: Syntaxbaum
Programmierung von Hand aufwändig, deshalb Parsergeneratoren
(für Haskell Happy)
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
2/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Interpreter allgemein
Lexikalische
Analyse
Syntaktische
Analyse
Semantische
Analyse
Ausführung /
Auswertung
Lexikalische Analyse: überführt Quelltext in Tokenstrom.
(Entfernen von Zeilenkommentaren, Leerzeichen, Umbrüchen, etc.)
Token: Syntaktische Einheit, z.B. 1000 nicht 1,0,0,0
Syntaktische Analyse: Prüft, ob Tokenstrom syntaktisch korrektes
Programm (anhand e. kontextfreien Grammatik)
Eingabe: Tokenstrom; Ausgabe: Syntaxbaum
Programmierung von Hand aufwändig, deshalb Parsergeneratoren
(für Haskell Happy)
Semantische Analyse: Entdeckt Fehler, die nicht rein syntaktisch
sind, z.B. ob alle Variablen deklariert sind, aber auch Typcheck
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
2/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabenblatt
Implementiere Interpreter für den Lambda-Kalkül
1
Lexikalische Analyse: Kommentare und Leerzeichen entfernen,
Tokenstrom erzeugen
2
Syntaktische Analyse: Parser mit Happy generieren
3
Semantische Analyse: Typcheck bzgl. simple types
4
Ausführung: Call-by-name Auswertung implementieren
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
3/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Der Lambda-Kalkül
Syntax
e, ei ∈ E := x
Variable
| λx.e
Abstraktion
| (e1 @ e2 ) Anwendung / Applikation
λx.e: durch λx wird x im Rumpf e gebunden.
Abstraktion sind anonyme Funktionen,
z.B. id(x) = x entspricht λx.x.
Argumente können Funktionen sein,
z.B. id(id) entspricht (λx.x) @ (λx.x)
Ziel des Lexers und Parsers
Überführe Lambda-Ausdrück in Haskell-interne Datenstruktur.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
4/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Lexikalische Analyse
Im Gegensatz zur formalen Syntax:
\ statt λ im Quelltext
Zeilenkommentare beginnend mit -- erlaubt
Beliebige Leerzeichen, Zeilenumbrüche erlaubt
Zusätzliche Klammerung erlaubt
Variablennamen beginnen mit mit einem Buchstaben danach
Buchstaben und Zahlen
Variablen sind durch Leerzeichen getrennt: "xy" ist ein Token,
aber "x y" sind zwei Token.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
5/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Lexikalische Analyse
Tokentyp
data Token = TokBackSl
| TokDot
| TokBopen
| TokBclose
| TokApp
| TokVar
deriving(Eq,Show)
TokPos
TokPos
TokPos
TokPos
TokPos
TokPos String
-------
’\’
’.’
’(’
’)’
’@’
Variablen
Token speichern die Position im Quelltext:
type TokPos = (Int,Int) -- (Zeile,Spalte)
Aufgabe
Implementiere Funktion lexInput :: String -> [Token]
Hilfreich:
lexInput’ String -> Int -> Int -> Token
lexInput’ eingabe zeile spalte = ...
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
6/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Syntaktische Analyse
Datentyp für die interne Darstellung von Ausdrücken des
Lambda-Kalküls:
data Expr
= Lambda VarName Expr
| App Expr Expr
| Var VarName
deriving(Eq)
type VarName = String
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
7/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Syntaktische Analyse
Datentyp für die interne Darstellung von Ausdrücken des
Lambda-Kalküls:
data Expr
= Lambda VarName Expr
| App Expr Expr
| Var VarName
deriving(Eq)
type VarName = String
Parser
Happy-Überblick im Anhang
Beispiel in example.y
Parser (Parser.hs) erstellen: happy Parser.ly.
Anschließend testen.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
7/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Parser (2)
Festlegungen, die der Parser beachten muss:
Der Rumpf einer Abstraktion reicht so weit wie möglich
λx.e1 @ e2 ist vollgeklammert λx.(e1 @ e2 )) und nicht
((λx.e1 ) @ e2 ).
Die Anwendung @ ist links-assoziativ
e1 @ e2 @ e3 ist vollgeklammert ((e1 @ e2 ) @ e3 ) und nicht
(e1 @ (e2 @ e3 ))
Im Happy-Skript kann man Assoziativitäten und Prioritäten
fest legen!
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
8/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufbau eines Happy-Skripts (1)
Beispiel: Arithmetische Ausdrücke
Tokentyp
data Token = TokenInt Int | TokenPlus | TokenMinus | TokenTimes
| TokenDiv
| TokenOB
| TokenCB
Typ des Syntaxbaums (Ausgabe des Parsers)
data Expr
= Plus Expr Expr | Minus Expr Expr | Times Expr Expr
| Div Expr Expr | NumberInt
Parserspezifikation: Dateiendung .y (oder .ly)
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
9/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufbau eines Happy-Skripts (2)
1. Teil: Modulkopf (Haskell-Code) in geschweiften Klammern Z.B.
{
module Calc where
import Char
}
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
10/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufbau eines Happy-Skripts (3)
2. Teil: Matchlist und Direktiven
Z.B.
%name calculator
%tokentype { Token }
%token
int
’+’
’-’
’*’
’/’
’(’
’)’
%left ’+’ ’-’
%left ’*’ ’/’
{
{
{
{
{
{
{
TokenInt $$
TokenPlus
TokenMinus
TokenTimes
TokenDiv
TokenOB
TokenCB
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
-----
Name des Parsers
Zuordnung des Tokentyps
Zurordnung Terminal in
der Grammatik zu Token
}
}
}
}
}
}
}
-- left=linksassoziativ
-- Reihenfolge gibt Prioritaet an
-- niedrigste Prioritaet zuerst
11/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufbau eines Happy-Skripts (4)
3. Teil: Grammatik
Eingeleitet mit %%
Typ des Syntaxbaums angeben
Aktion in geschweiften Klammern hinter der Produktion
Expr :: { Expr }
Expr : Expr ’+’ Expr
| Expr ’-’ Expr
| Expr ’*’ Expr
| Expr ’/’ Expr
| ’(’ Expr ’)’
| int
{
{
{
{
{
{
Plus $1 $3
Minus $1 $3
Times $1 $3
Div $1 $3
$2
Number $1
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
}
}
}
}
}
}
12/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufbau eines Happy-Skripts (5)
4. Teil: Haskell-Code in geschweiften Klammern,
sollte zumindest happyError definieren.
{
happyError :: [Token] -> a
happyError _ = error "parse error!"
data Token = TokenInt Int | TokenPlus | TokenMinus | TokenTimes
| TokenDiv
| TokenOB
| TokenCB
data Expr
= Plus Expr Expr | Minus Expr Expr | Times Expr Expr
| Div Expr Expr | Number Int
lexer :: String -> [Token]
lexer [] = []
lexer (’+’:cs) = TokenPlus : lexer cs
lexer (’-’:cs) = TokenMinus : lexer cs
lexer (’*’:cs) = TokenTimes : lexer cs
lexer (’/’:cs) = TokenDiv : lexer cs
lexer (’(’:cs) = TokenOB : lexer cs
lexer (’)’:cs) = TokenCB : lexer cs
lexer (c:cs)
| isSpace c = lexer cs
| isDigit c = lexNum (c:cs)
| otherwise = error ("error, can’t lex symbol " ++ show "c")
lexNum cs = TokenInt (read num) : lexer rest
where (num,rest) = span isDigit cs
}
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
13/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabe
Parser für den Lambda-Kalkül mit Happy erzeugen
Parser sollte keine Shift-Reduce- oder
Reduce-Reduce-Konflikte haben
Pioritäten und Assoziativitäten verwenden!
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
14/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Semantische Analyse
Überspringen wir zunächst erstmal zur Auswertung
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
15/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Vorbereitung zur Auswertung
Bevor wir Auswerten können, brauchen wir
α-Umbenennung, um umbenannte Kopien von Ausdrücken zu
erstellen
Substitution: e1 [e2 /x] = ersetze alle x in e1 durch frische
Kopien von e2
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
16/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Vorbereitung zur Auswertung: α-Umbenennung
Freie und gebundene Variablen:
FV (x)
= x
FV (λx.e)
= FV (e) \ {x}
FV (e1 @ e2 ) = FV (e1 ) ∪ FV (e2 )
GV (x)
= ∅
GV (λx.e)
= GV (e) ∪ {x}
GV (e1 @ e2 ) = GV (e1 ) ∪ GV (e2 )
Substitution: e1 [e2 /x]: Ersetze x durch e2 in e1
x[e/x]
y[e/x]
(λy.e1 )[e2 /x]
(e1 @ e2 )[e3 /x]
=
=
=
=
e
y, falls x 6= y
λy.(e1 [e2 /x])
(e1 [e3 /x] @ e2 [e3 /x])
Kontexte: Ausdruck mit Loch [·] an einer Stelle
C ∈ C = [·] | λx.C | (C @ e) | (e @ C),
Einsetzung C[e] ist der Ausdruck der entsteht, nachdem e an die
Stelle des Lochs in C eingesetzt wurde
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
17/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Vorbereitung zur Auswertung: α-Umbenennung
α-Umbenennungsschritt:
α
C[λx.e] −
→ C[λy.e[y/x]] falls y 6∈ GV (λx.e) ∪ FV (λx.e)
Die reflexiv-transitive Hülle solcher α-Umbenennungen heißt
α-Äquivalenz.
α-äquivalente Ausdrücke werden als gleich angesehen, z.B.
λx.x =α λy.y
Ausdruck erfüllt DVC gdw. alle gebundenen Variablen haben
unterschiedliche Namen und Namen gebundener Variablen stets
verschieden sind von Namen freier Variablen.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
18/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabe: Umbenennung
Im Modul Util, die Funktion
renameExpr :: [VarName] -> Expr -> (Expr,[VarName])
erhält: Liste von frischen Variablennamen und Ausdruck
liefert: Umbenannten Ausdruck + restliche Variablen
Tipps: Man muss sich die Umbenennung am Binder merken
renameExpr’ (n:namen) λx.e merkliste =
renameExpr’ namen e (x,n):merkliste
renameExpr’ (n:namen) x+ merkliste =
case lookup x merkliste of
Just y -> y
Nothing -> x
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
19/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabe: Substitution
Im Modul Util eine Funktion
substitute :: [VarName] -> VarName -> Expr -> Expr -> (Expr,[VarName])
erhält: frische Namen, eine Variable x und zwei Ausdrücke
e1 , e2
liefert: e2 [e1 /x] (wobei jedes e1 vorher umbenannt wird) und
verbleibende Namen
Zum Umbenennen renameExpr verwenden.
Beispiel:
substitute ["a","b","c",...]z (λx.λy.x) (λw.(z @ z))
ergibt
(λw.(z[λx.λy.x/z] @ z[λx.λy.x/z]))
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
20/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabe: Substitution
Im Modul Util eine Funktion
substitute :: [VarName] -> VarName -> Expr -> Expr -> (Expr,[VarName])
erhält: frische Namen, eine Variable x und zwei Ausdrücke
e1 , e2
liefert: e2 [e1 /x] (wobei jedes e1 vorher umbenannt wird) und
verbleibende Namen
Zum Umbenennen renameExpr verwenden.
Beispiel:
substitute ["a","b","c",...]z (λx.λy.x) (λw.(z @ z))
ergibt
(λw.(z[λa.λb.a/z] @ z[λx.λy.x/z]))
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
20/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabe: Substitution
Im Modul Util eine Funktion
substitute :: [VarName] -> VarName -> Expr -> Expr -> (Expr,[VarName])
erhält: frische Namen, eine Variable x und zwei Ausdrücke
e1 , e2
liefert: e2 [e1 /x] (wobei jedes e1 vorher umbenannt wird) und
verbleibende Namen
Zum Umbenennen renameExpr verwenden.
Beispiel:
substitute ["a","b","c",...]z (λx.λy.x) (λw.(z @ z))
ergibt
(λw.(z[λa.λb.a/z] @ z[λc.λd.c/z]))
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
20/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Aufgabe: Substitution
Im Modul Util eine Funktion
substitute :: [VarName] -> VarName -> Expr -> Expr -> (Expr,[VarName])
erhält: frische Namen, eine Variable x und zwei Ausdrücke
e1 , e2
liefert: e2 [e1 /x] (wobei jedes e1 vorher umbenannt wird) und
verbleibende Namen
Zum Umbenennen renameExpr verwenden.
Beispiel:
substitute ["a","b","c",...]z (λx.λy.x) (λw.(z @ z))
ergibt
(λw.((λa.λb.a) @ (λc.λd.c)))
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
20/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Operationale Semantik
Operationale Semantik legt fest, wie man ein Programm
ausführt.
In imperativen Sprachen: Wie verändert jeder Befehl den
Zustand
Im Lambda-Kalkül: Auswerten statt ausführen
Wesentliche Regel: Auswertung der Funktionsanwendung auf
Argumente:
(β)
(λx.e1 ) @ e2 → e1 [e2 /x]
β
Beispiel: (λx.λy.x) @ (λz.z) −
→ λy.λz.z
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
21/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Reduktionsstrategien
Anwendung der (β)-Reduktion auf Top-Level nicht immer möglich:
((λx.x) @ (λy.y)) @ ((λx0 .x0 ) @ (λy 0 .y 0 ))
Wo reduzieren? Verschiedene Möglichkeiten:
((λx.x) @ (λy.y)) @ ((λx0 .x0 ) @ (λy 0 .y 0 ))
t
$
(λy.y) @ ((λx0 .x0 ) @ (λy 0 .y 0 ))
w
((λx0 .x0 ) @ (λy 0 .y 0 ))
(λy 0 .y 0 )
(((λx.x) @ (λy.y)) @ (λy 0 .y 0 ))
&
(λy.y) @ (λy 0 .y 0 )
(λy 0 .y 0 )
((λy.y) @ (λy 0 .y 0 ))
(λy 0 .y 0 )
Reduktionsstrategie legt (eindeutig) fest, wo reduziert wird.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
22/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Call-by-Name Reduktion
sucht immer den am weitesten oben und am weitesten links
stehenden Redex
Formale Definition mit (call-by-name) Reduktionskontexten
R ::= [·] | (R @ Expr)
β
name
Wenn e1 −
→ e2 , dann ist R[e1 ] −−−→ R[e2 ] eine call-by-name
Reduktion
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
23/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Call-by-Name Reduktion
Leicht implementierbares Verfahren:
Zustand: (Ausdruck, Stack) wobei Stack enthält Ausdrücke.
Regeln auf dem Zustand:
(push) ((e1 @ e2 ), S) → (e1 , e2 : S)
(take) (λx.e1 ), e2 : S) → (e1 [e2 /x], S)
Wende Regeln solange an wie es geht.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
24/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Beispiel
(push)
−−−−→
(push)
−−−−→
(take)
−−−−→
(take)
−−−−→
(push)
−−−−→
(take)
−−−−→
Ausdruck
(((λx.λy.x) @ ((λw.w) @ (λz.z))) @ (λu.u))
Stack
[]
((λx.λy.x) @ ((λw.w) @ (λz.z)))
[λu.u]
λx.λy.x
[((λw.w) @ (λz.z)), λu.u]
λy.((λw.w) @ (λz.z))
[λu.u]
((λw.w) @ (λz.z))
[]
λw.w
[λz.z]
λz.z
[]
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
25/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Ergebnisse
Drei Möglichkeiten
(λx.e, []), dann erfolgreich zu einer Abstraktion reduziert
(x, S), dann freie Variable gefunden, nicht erfolgreich, aber
stoppe
→ω , hält nicht
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
26/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Call-by-Name Reduktion: Aufgabe
Im Modul Evaluator eine Funktion
evaluate :: [VarName] -> Expr -> Expr
erhält frische Namen und Ausdruck
liefert Ergebnis (Abstraktion)
Fehlermeldung bei freier Variable
oder hält nicht an
Implementierung mit Stack (Stack kann durch Liste [Expr]
darsgestellt werden)
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
27/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Semantische Analyse: Einfaches Typsystem
Syntax für einfache Typen:
τ, τi ∈ Typ ::= 0 | τ1 → τ2
Γ: Typumgebung, d.h. Abbildung von Variablen auf Typen
Γ ` e : τ bedeutet: Unter der Typumgebung Γ ist der Typ τ
für den Ausdruck e herleitbar.
Typherleitungsregeln:
Anwendungsregel:
Abstraktionsregel:
Axiom für Variablen:
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
Γ ` e1 : τ1 → τ2 und Γ ` e2 : τ1
Γ ` (e1 @ e2 ) : τ2
Γ ∪ {x 7→ τ1 } ` e : τ2
Γ ` (λx.e) : τ1 → τ2
Γ ∪ {x 7→ τ } ` x : τ
28/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Beispiel
{x 7→ (0 → 0)} ` x : (0 → 0)
{y 7→ 0} ` y : 0
und
∅ ` λx.x : (0 → 0) → (0 → 0)
∅ ` λy.y : 0 → 0
∅ ` (λx.x) @ (λy.y) : 0 → 0
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
29/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Beispiel
{x 7→ (0 → 0)} ` x : (0 → 0)
{y 7→ 0} ` y : 0
und
∅ ` λx.x : (0 → 0) → (0 → 0)
∅ ` λy.y : 0 → 0
∅ ` (λx.x) @ (λy.y) : 0 → 0
Aber hier nur richtig geraten!
Regel für Abstraktion ist nicht richtig algorithmisch:
Man muss den Typ schon kennen, damit man richtig rechnet.
Deswegen: Algorithmischeres Verfahren
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
29/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Erweitertes Verfahren
Erweiterung um Variablen α:
τ, τi ::= 0 | τ1 → τ2 | α
Und um Typgleichungen E:
Menge von Gleichungen der Form τ1 =? τ2
Γ ` e : τ, E bedeutet
Unter der Typannahme Γ ist e typisierbar mit σ(τ ), wenn σ
die Lösung der Gleichungen in E ist
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
30/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Typregeln mit Gleichungen
Anwendungsregel:
Γ ` e1 : τ1 , E1 und Γ ` e2 : τ2 , E2
α neu
Γ ` (e1 @ e2 ) : α, {τ1 =? τ2 → α} ∪ E1 ∪ E2
Abstraktionsregel:
Axiom für Variablen:
Γ ∪ {x : α} ` e : τ, E
Γ ` (λx.e) : α → τ, E
Γ ∪ {x 7→ τ } ` x : τ, ∅
Leiten jedoch noch keinen Typ her, sondern Typ + Gleichungssystem
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
31/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Typregeln mit Gleichungen
Anwendungsregel:
Γ ` e1 : τ1 , E1 und Γ ` e2 : τ2 , E2
α neu
Γ ` (e1 @ e2 ) : α, {τ1 =? τ2 → α} ∪ E1 ∪ E2
Γ ∪ {x : α} ` e : τ, E
Γ ` (λx.e) : α → τ, E
Abstraktionsregel:
Axiom für Variablen:
Γ ∪ {x 7→ τ } ` x : τ, ∅
Leiten jedoch noch keinen Typ her, sondern Typ + Gleichungssystem
Typherleitung
∅ ` e : τ, E und γ ist Lösung von E
∅ ` e : ρ(γ(τ ))
für jede Grundsubstitution ρ
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
31/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Typregeln mit Gleichungen
Anwendungsregel:
Γ ` e1 : τ1 , E1 und Γ ` e2 : τ2 , E2
α neu
Γ ` (e1 @ e2 ) : α, {τ1 =? τ2 → α} ∪ E1 ∪ E2
Γ ∪ {x : α} ` e : τ, E
Γ ` (λx.e) : α → τ, E
Abstraktionsregel:
Axiom für Variablen:
Γ ∪ {x 7→ τ } ` x : τ, ∅
Leiten jedoch noch keinen Typ her, sondern Typ + Gleichungssystem
Typherleitung
∅ ` e : τ, E und γ ist Lösung von E
∅ ` e : ρ(γ(τ ))
für jede Grundsubstitution ρ
Grundsubstitution uninteressant, d.h. wir berechnen nur γ(τ )
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
31/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Unifikationsalgorithmus
Eingabe: Gleichungssystem E
Gesucht: Lösung für E, d.h. Abbildung von Typvariablen auf
Typen, so dass alle Gleichung links und rechts gleich sind
Datenstruktur: (G, E), G: Gelöste Gleichungen, E Ungelöste
Gleichungen
Löschregel
Dekomposition
Gelöst
(G, E ∪ {τ =? τ }) → (G, E), wobei τ eine Typvariable oder τ = 0
(G, E ∪ {τ1 → τ2 =? τ3 → τ4 }) → (G, E ∪ {τ1 =? τ3 , τ2 =? τ4 )
(G, E ∪ {α =τ }) → (G[τ /α] ∪ {α =τ }, E[τ /α])
wobei α Typvariable und α kommt nicht in τ vor
Occurs Check
Fail
Fail
Orientierung
(G, E ∪ {α =? τ }) → Fail, falls α in τ vorkommt
(G, E ∪ {τ1 → τ2 =? 0}) → Fail
(G, E ∪ {0 =? τ1 → τ2 }) → Fail
(G, E ∪ {τ =? α}) → (G, E ∪ {α =? τ })
wobei α Typvariable, τ keine Typvariable
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
32/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Beispiel
{x : α1 } ` x : α1 , ∅ und {y : α2 } ` y : α2 , ∅
∅ ` λx.x : α1 → α1 , ∅
∅ ` λy.y : α2 → α2 , ∅
∅ ` (λx.x) @ (λy.y) : α3 , {α1 → α1 =? (α2 → α2 ) → α3 }
Löse {α1 → α1 =? (α2 → α2 ) → α3 }:
G
α1 = ? α3
α1 = ? α2 → α2
α3 = ? α2 → α2
E
α1
α1
α1
α3
→ α1 =? (α2 → α2 ) → α3
= ? α2 → α2
= ? α3
= ? α2 → α2
nächste verwendete Regel
(Dekomposition)
(Gelöst)
(Gelöst)
Ergibt: γ = {α1 7→ α2 → α2 , α3 7→ α2 → α2 } und:
γ(α3 ) = α2 → α2
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
33/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Weiteres Beispiel
und
{x 7→ α1 } ` x : α1 , ∅
{x 7→ α1 } ` x : α1 , ∅
{x 7→ α1 } ` (x @ x) : α2 , {α1 =? α2 → α1 }
∅ ` λx.(x @ x) : α1 → α2 , {α1 =? α2 → α1 }
Unifikation
G
E
α1 = ? α2 → α1
nächste verwendete Regel
(Occurs Check)
Fail
D.h. λx.(x x) ist nicht typisierbar.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
34/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Implementierung
Darstellung der Typen in Haskell:
data Type = Unit
| Type :-> Type
| TVar TypVarName
deriving (Eq)
-- 0
-- t1 -> t2
-- Typvariable
type TypVarName = String
type Umgebung = [(TypVarName, Type)]
type Gleichung = (Type,Type)
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
35/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Implementierung Unifikation
Im Modul TypeCheck eine Funktion
unify :: [Gleichung] -> [Gleichung] -> Maybe [Gleichung]
wobei unify G und E erwartet und entweder fehlschlägt
(Nothing) oder das gelöste Gleichungssystem liefert.
Hilfsfunktion für die Ersetzung F [τ /α] vom Typ
ersetze :: TypVarName -> Type -> [Gleichung] -> [Gleichung]
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
36/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Implementierung Typcheck
Im Modul TypeCheck:
tcheck :: [TypVarName]
-> Umgebung
-> Expr
-> (Type,[Gleichung],[TypVarName])
erhält: frische Namen für Typvariablen, Typumgebung,
Ausdruck
liefert: Typ, Gleichungen, restliche Namen
Typregeln von unten nach oben rekursiv Programmieren.
Hauptfunktion runTCheck :: Expr -> Type ist schon
vorgegeben
Ruft tcheck und unify auf
Wendet Substitution an
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
37/38
Einleitung Syntax: Lexen und Parsen Auswertung Typisierung
Letzte Aufgabe: Interpreter
Konsolenprogramm, das
Lext und parst
Typcheck durchführt
Ausdruck auswertet
Option einfügen, so dass Typcheck ausgelassen wird.
Praktikum BKSPP: Blatt 4 – SoSe 2012 – D. Sabel
38/38
Herunterladen