Fortgeschrittene Funktionale Programmierung
Sommersemester 2020
Typisierung
Prof. Dr. David Sabel
LFE Theoretische Informatik
Letzte ¨Anderung der Folien: 22. Juli 2020Die Folien basieren zum Teil auf Material von Dr. Steffen Jost, dem an dieser Stelle f¨ur die Verwendungserlaubnis herzlich gedankt sei.
Ziele des Kapitels
Warum typisieren?
Typisierungsverfahren f¨ ur Haskell bzw. KFPTS+seq f¨ ur parametrisch polymorphe Typen
Iteratives Typisierungsverfahren Milnersches Typisierungsverfahren
TCS
|07 Typisierung
|SoSe 2020 2/108 Motivation Typen Typisierungsverfahren
Ubersicht ¨
TCS
|07 Typisierung
|SoSe 2020 3/108 Motivation Typen Typisierungsverfahren
Motivation
Warum ist ein Typsystem sinnvoll?
F¨ ur ungetypte Programme k¨ onnen dynamische Typfehler auftreten Fehler zur Laufzeit sind Programmierfehler
Starkes und statisches Typsystem = ⇒ keine Typfehler zu Laufzeit Typen als Dokumentation
Typen bewirken besser strukturierte Programme Typen als Spezifikation in der Entwurfsphase
TCS
|07 Typisierung
|SoSe 2020 4/108 Motivation Typen Typisierungsverfahren
Motivation (2)
Minimalanforderungen:
Die Typisierung sollte zur Compilezeit entschieden werden.
Korrekt getypte Programme erzeugen keine Typfehler zur Laufzeit.
W¨ unschenswerte Eigenschaften:
Typsystem schr¨ ankt wenig oder gar nicht beim Programmieren ein Compiler kann selbst Typen berechnen = Typinferenz
TCS
|07 Typisierung
|SoSe 2020 5/108 Motivation Typen Typisierungsverfahren
Motivation (3)
Es gibt Typsysteme, die diese Eigenschaften nicht erf¨ ullen:
Z.B. Simply-typed Lambda-Calculus: Getypte Sprache ist nicht mehr Turing-m¨ achtig, da dieses Typsystem erzwingt, dass alle Programme terminieren
Erweiterungen in Haskells Typsystem:
Typisierung / Typinferenz ist unentscheidbar.
U.U. terminiert der Compiler nicht!.
Folge: mehr Vorsicht/Anforderungen an den Programmierer.
TCS
|07 Typisierung
|SoSe 2020 6/108 Motivation Typen Typisierungsverfahren
Naiver Ansatz
Naive Definition von
” korrekt getypt“:
Ein KFPTS+seq-Programm ist korrekt getypt, wenn es keine dynamischen Typfehler zur Laufzeit erzeugt.
Funktioniert nicht gut, denn
Die dynamische Typisierung in KFPTS+seq ist unentscheidbar!
Unentscheidbarkeit der dynamischen Typisierung
Sei tmEncode eine KFPTS+seq-Funktion, die sich wie eine universelle Turingmaschine verh¨ alt:
Eingabe: Turingmaschinenbeschreibung und Eingabe f¨ ur die TM Ausgabe: True, falls die Turingmaschine anh¨ alt
Beachte: tmEncode ist in KFPTS+seq definierbar und nicht dynamisch ungetypt (also
dynamisch getypt)
Unentscheidbarkeit der dynamischen Typisierung (2)
F¨ ur eine TM-Beschreibung b und Eingabe e sei s := if tmEncode b e
then case Bool Nil of {True → True; False → False}
else case Bool Nil of {True → True; False → False}
Es gilt:
s ist genau dann dynamisch ungetypt, wenn Turingmaschine b auf Eingabe e h¨ alt.
Daher: Wenn wir dynamische Typisierung entscheiden k¨ onnten, dann auch das Halteproblem Satz
Die dynamische Typisierung von KFPTS+seq-Programmen ist unentscheidbar.
TCS
|07 Typisierung
|SoSe 2020 9/108 Motivation Typen Typisierungsverfahren
Typen
Syntax von polymorphen Typen:
T ::= T V | T C T 1 . . . T n | T 1 → T 2
wobei T V Typvariable, T C Typkonstruktor Sprechweisen:
Ein Basistyp ist ein Typ der Form T C, wobei T C ein nullstelliger Typkonstruktor ist.
Ein Grundtyp (oder alternativ monomorpher Typ) ist ein Typ, der keine Typvariablen enth¨ alt.
Beispiele:
Int, Bool und Char sind Basistypen.
[Int] und Char -> Int sind keine Basistypen aber Grundtypen.
[a] und a -> a sind weder Basistypen noch Grundtypen.
TCS
|07 Typisierung
|SoSe 2020 10/108 Motivation Typen Typisierungsverfahren
Typen (2)
Wir verwenden f¨ ur polymorphe Typen die Schreibweise mit All-Quantoren:
Sei τ ein polymorpher Typ mit Vorkommen der Variablen α 1 , . . . , α n
Dann ist ∀α 1 , . . . , α n .τ der all-quantifizierte Typ f¨ ur τ .
Da Reihenfolge egal, verwenden wir auch ∀X .τ wobei X Menge von Typvariablen Sp¨ ater:
Allquantifizierte Typen d¨ urfen kopiert und umbenannt werden, Typen ohne Quantor d¨ urfen nicht umbenannt werden!
TCS
|07 Typisierung
|SoSe 2020 11/108 Motivation Typen Typisierungsverfahren
Typsubstitutionen
Eine Typsubstitution ist eine Abbildung einer endlichen Menge von Typvariablen auf Typen, Schreibweise: σ = {α 1 7→ τ 1 , . . . , α n 7→ τ n }.
Formal: Erweiterung auf Typen: σ E : Abbildung von Typen auf Typen
σ E (T V ) := σ(T V ), falls σ die Variable T V abbildet σ E (T V ) := T V, falls σ die Variable T V nicht abbildet σ E (T C T 1 . . . T n ) := T C σ E (T 1 ) . . . σ E (T n )
σ E (T 1 → T 2 ) := σ E (T 1 ) → σ E (T 2 )
Wir unterscheiden im folgenden nicht zwischen σ und der Erweiterung σ E !
TCS
|07 Typisierung
|SoSe 2020 12/108 Motivation Typen Typisierungsverfahren
Semantik eines polymorphen Typs
Grundtypen-Semantik f¨ ur polymorphe Typen:
sem(τ) := {σ(τ ) | σ(τ ) ist Grundtyp , σ ist Substitution}
Entspricht der Vorstellung von schematischen Typen:
Ein polymorpher Typ ist ein Schema f¨ ur eine Menge von Grundtypen
TCS
|07 Typisierung
|SoSe 2020 13/108 Motivation Typen Typisierungsverfahren
Typregeln
Bekannte Regel:
s :: T 1 → T 2 , t :: T 1
(s t) :: T 2
Problem: Man muss “richtige Instanz raten”, z.B.
map :: (a -> b) -> [a] -> [b]
not :: Bool -> Bool
Typisierung von map not: Vor Anwendung der Regel muss der Typ von map instanziiert werden mit
σ = {a 7→ Bool, b 7→ Bool}
Statt σ zu raten, kann man σ berechnen: Unifikation
TCS
|07 Typisierung
|SoSe 2020 14/108 Motivation Typen Typisierungsverfahren
Unifikationsproblem
Definition
Ein Unifikationsproblem auf Typen ist gegeben durch eine Menge E von Gleichungen der Form τ 1
= · τ 2 , wobei τ 1 und τ 2 polymorphe Typen sind.
Eine L¨ osung eines Unifikationsproblem E auf Typen ist eine Substitution σ (bezeichnet als Unifikator), so dass σ(τ 1 ) = σ(τ 2 ) f¨ ur alle Gleichungen τ 1
= · τ 2 des Problems.
Eine allgemeinste L¨ osung (allgemeinster Unifikator, mgu = most general unifier) von E ist ein Unifikator σ, so dass gilt: F¨ ur jeden anderen Unifikator ρ von E gibt es eine Substitution γ so dass ρ(x) = γ ◦ σ(x) f¨ ur alle x ∈ FV (E).
Unifikationsalgorithmus
Datenstruktur: E = Multimenge von Gleichungen
Multimenge ≡ Menge mit mehrfachem Vorkommen von Elementen
E ∪ E 0 sei die disjunkte Vereinigung von zwei Multimengen E [τ /α] ist definiert als {s[τ /α] = · t[τ /α] | (s = · t) ∈ E}.
Algorithmus: Wende Schlussregeln (s.u.) solange auf E an, bis Fail auftritt, oder
keine Regel mehr anwendbar ist
Unifikationsalgorithmus: Schlussregeln
Fail-Regeln:
Fail1
E ∪ {(T C 1 τ 1 . . . τ n ) = (T C · 2 τ 1 0 . . . τ m 0 )}
Fail wenn T C 1 6= T C 2 Fail2
E ∪ {(T C 1 τ 1 . . . τ n ) = (τ · 1 0 → τ 2 0 )}
Fail Fail3
E ∪ {(τ 1 0 → τ 2 0 ) = (T C · 1 τ 1 . . . τ n )}
Fail
TCS
|07 Typisierung
|SoSe 2020 17/108 Motivation Typen Typisierungsverfahren
Unifikationsalgorithmus: Schlussregeln (2)
Dekomposition:
Decompose1
E ∪ {T C τ 1 . . . τ n
= · T C τ 1 0 . . . τ n 0 }
E ∪ {τ 1 ·
= τ 1 0 , . . . , τ n ·
= τ n 0 }
Decompose2
E ∪ {τ 1 → τ 2
= · τ 1 0 → τ 2 0 }
E ∪ {τ 1 ·
= τ 1 0 , τ 2 ·
= τ 2 0 }
TCS
|07 Typisierung
|SoSe 2020 18/108 Motivation Typen Typisierungsverfahren
Unifikationsalgorithmus: Schlussregeln (3)
Orientierung, Elimination:
Orient
E ∪ {τ 1 = · α}
E ∪ {α = · τ 1 }
wenn τ 1 keine Typvariable und α Typvariable
Elim
E ∪ {α = · α}
E wobei α Typvariable
TCS
|07 Typisierung
|SoSe 2020 19/108 Motivation Typen Typisierungsverfahren
Unifikationsalgorithmus: Schlussregeln (4)
Einsetzung, Occurs-Check:
Solve
E ∪ {α = · τ } E[τ /α] ∪ {α = · τ}
wenn Typvariable α nicht in τ vorkommt, aber α kommt in E vor
OccursCheck
E ∪ {α = · τ } Fail
wenn τ 6= α und Typvariable α kommt in τ vor
TCS
|07 Typisierung
|SoSe 2020 20/108 Motivation Typen Typisierungsverfahren
Beispiele
Beispiel 1: {(a → b) = · Bool → Bool}:
Decompose2
{(a → b) = · Bool → Bool}
{a = · Bool, b = · Bool}
Beispiel 2: {[d] = · c, a → [a] = · Bool → c}:
{[d] = · c, a → [a] = · Bool → c}
Decompose2
{[d] = · c, a → [a] = · Bool → c}
{[d] = · c, a = · Bool, [a] = · c}
Orient Decompose2
{[d] = · c, a → [a] = · Bool → c}
{[d] = · c, a = · Bool, [a] = · c}
{[d] = · c, a = · Bool, c = [a]} ·
Solve Orient Decompose2
{[d] = · c, a → [a] = · Bool → c}
{[d] = · c, a = · Bool, [a] = · c}
{[d] = · c, a = · Bool, c = [a]} · {[d] = [a], a · = · Bool, c = [a]} ·
Solve Solve Orient Decompose2
{[d] = · c, a → [a] = · Bool → c}
{[d] = · c, a = · Bool, [a] = · c}
{[d] = · c, a = · Bool, c = [a]} · {[d] = [a], a · = · Bool, c = [a]} · {[d] = [Bool], a · = · Bool, c = [Bool]} ·
Decompose1 Solve Solve Orient Decompose2
{[d] = · c, a → [a] = · Bool → c}
{[d] = · c, a = · Bool, [a] = · c}
{[d] = · c, a = · Bool, c = [a]} · {[d] = [a], a · = · Bool, c = [a]} · {[d] = [Bool], a · = · Bool, c = [Bool]} ·
{d = · Bool, a = · Bool, c = [Bool]} · Der Unifikator ist {d 7→ Bool, a 7→ Bool, c 7→ [Bool]}.
TCS
|07 Typisierung
|SoSe 2020 21/108 Motivation Typen Typisierungsverfahren
Beispiele (2)
Beispiel 3: {a = [b], b · = [a]} ·
OccursCheck Solve
{a = [b], b · = [a]} · {a = [[a]], b · = [a]} ·
Fail Beispiel 4: {a → [b] = · a → c → d}
Fail2 Elim Decompose2
{a → [b] = · a → c → d}
{a = · a, [b] = · c → d}
{[b] = · c → d}
Fail
TCS
|07 Typisierung
|SoSe 2020 22/108 Motivation Typen Typisierungsverfahren
Eigenschaften des Unifikationsalgorithmus
Der Algorithmus endet mit Fail gdw. es keinen Unifikator f¨ ur die Eingabe gibt.
Der Algorithmus endet erfolgreich gdw. es einen Unifikator f¨ ur die Eingabe gibt. Das Gleichungssystem E ist dann von der Form
{α 1 = · τ 1 , . . . , α n
= · τ n },
wobei α i paarweise verschiedene Typvariablen sind und kein α i in irgendeinem τ j
vorkommt. Der Unifikator ist dann σ = {α 1 7→ τ 1 , . . . , α n 7→ τ n }.
Liefert der Algorithmus einen Unifikator, dann ist es ein allgemeinster Unifikator.
σ allgemeinst bedeutet: jede andere L¨ osung ist abgedeckt, d.h. kann durch weitere Einsetzung aus σ erzeugt werden.
Eigenschaften des Unifikationsalgorithmus (2)
Man braucht keine alternativen Regelanwendungen auszuprobieren! Der Algorithmus kann deterministisch implementiert werden.
Der Algorithmus terminiert f¨ ur jedes Unifikationsproblem auf Typen.
Ausgabe: Fail oder der allgemeinste Unifikator
Eigenschaften des Unifikationsalgorithmus (3)
Die Typen in der Resultat-Substitution k¨ onnen exponentiell groß werden.
Der Unifikationsalgorithmus kann aber so implementiert werden, dass er Zeit
O(n ∗ log n) ben¨ otigt. Man muss Sharing dazu beachten; Dazu eine andere Solve-Regel benutzen.
Die Typen in der Resultat-Substitution haben danach Darstellungsgr¨ oße O(n).
Das Unifikationsproblem (d.h. die Frage, ob eine Menge von Typgleichungen unifizierbar ist) ist P-complete. D.h. man kann im wesentlichen alle PTIME-Probleme als
Unifikationsproblem darstellen:
Interpretation ist: Unifikation ist nicht effizient parallelisierbar.
TCS
|07 Typisierung
|SoSe 2020 25/108 Motivation Typen Typisierungsverfahren
Typisierungsverfahren
Wir betrachten nun die
polymorphe Typisierung von KFPTSP+seq-Ausdr¨ ucken Wir verschieben zun¨ achst: Typisierung von Superkombinatoren
N¨ achster Schritt:
Wie m¨ ussen die Typisierungsregeln aussehen?
TCS
|07 Typisierung
|SoSe 2020 26/108 Motivation Typen Typisierungsverfahren
Anwendungsregel mit Unifikation
s :: τ 1 , t :: τ 2
(s t) :: σ(α) wenn σ allgemeinster Unifikator f¨ ur τ 1 ·
= τ 2 → α ist und α neue Typvariable ist.
Beispiel:
map :: (a → b) → [a] → [b], not :: Bool → Bool (map not) :: σ(α)
wenn σ allgemeinster Unifikator f¨ ur (a → b) → [a] → [b] = (Bool · → Bool) → α ist
und α neue Typvariable ist.
Unifikation ergibt {a 7→ Bool, b 7→ Bool, α 7→ [Bool] → [Bool]}
Daher: σ(α) = [Bool] → [Bool]
TCS
|07 Typisierung
|SoSe 2020 27/108 Motivation Typen Typisierungsverfahren
Typisierung mit Bindern
Wie typisiert man eine Abstraktion λx.s?
Typisiere den Rumpf s Sei s :: τ
Dann erh¨ alt λx.s einen Funktionstyp τ 1 → τ Was hat τ 1 mit τ zu tun?
τ 1 ist der Typ von x
Wenn x im Rumpf s vorkommt, brauchen wir τ 1 bei der Berechnung von τ !
TCS
|07 Typisierung
|SoSe 2020 28/108 Motivation Typen Typisierungsverfahren
Typisierung mit Bindern (2)
Informelle Regel f¨ ur die Abstraktion:
Typisierung von s unter der Annahme “x hat Typ τ 1 ” ergibt s :: τ λx.s :: τ 1 → τ
Woher erhalten wir τ 1 ?
Nehme allgemeinsten Typ an f¨ ur x, danach schr¨ anke durch die Berechnung von τ den Typ ein.
Beispiel:
λx.(x True)
Typisiere (x True) beginnend mit x :: α Typisierung muss liefern α = Bool → α 0
Typ der Abstraktion λx.(x True) :: (Bool → α 0 ) → α 0 .
TCS
|07 Typisierung
|SoSe 2020 29/108 Motivation Typen Typisierungsverfahren
Typisierung von Ausdr¨ ucken
Erweitertes Regelformat:
Γ ` s :: τ, E
Bedeutung:
Gegeben eine Menge Γ von Typ-Annahmen.
Dann kann f¨ ur den Ausdruck s der Typ τ und die Typgleichungen E hergeleitet werden.
In Γ kommen nur Typ-Annahmen f¨ ur Konstruktoren, Variablen, Superkombinatoren vor.
In E sammeln wir Gleichungen, sie werden erst sp¨ ater unifiziert.
TCS
|07 Typisierung
|SoSe 2020 30/108 Motivation Typen Typisierungsverfahren
Typisierung von Ausdr¨ ucken (2)
Herleitungsregeln schreiben wir in der Form
Voraussetzung(en) Konsequenz
Γ 1 ` s 1 :: τ 1 , E 1 . . . Γ k ` s k :: τ k , E K
Γ ` s :: τ, E
Typisierung von Ausdr¨ ucken (2)
Vereinfachung:
Konstruktoranwendungen (c s 1 . . . s n ) werden w¨ ahrend der Typisierung
wie geschachtelte Anwendungen (((c s 1 ) . . .) s n )) behandelt.
Typisierungsregeln f¨ ur KFPTS+seq Ausdr¨ ucke (1)
Axiom f¨ ur Variablen:
(AxV)
Γ ∪ {x :: τ } ` x :: τ, ∅
Axiom f¨ ur Konstruktoren:
(AxK)
Γ ∪ {c :: ∀α 1 . . . α n .τ } ` c :: τ[β 1 /α 1 , . . . , β n /α n ], ∅ wobei β i neue Typvariablen sind
Beachte: Jedesmal wird ein neu umbenannter Typ verwendet!
TCS
|07 Typisierung
|SoSe 2020 33/108 Motivation Typen Typisierungsverfahren
Typisierungsregeln f¨ ur KFPTS+seq Ausdr¨ ucke (2)
Axiom f¨ ur Superkombinatoren, deren Typ schon bekannt ist:
(AxSK)
Γ ∪ {SK :: ∀α 1 . . . α n .τ} ` SK :: τ [β 1 /α 1 , . . . , β n /α n ], ∅ wobei β i neue Typvariablen sind
Beachte: Jedesmal wird ein neu umbenannter Typ verwendet!
TCS
|07 Typisierung
|SoSe 2020 34/108 Motivation Typen Typisierungsverfahren
Typisierungsregeln f¨ ur KFPTS+seq Ausdr¨ ucke (3)
Regel f¨ ur Anwendungen:
(RApp)
Γ ` s :: τ 1 , E 1 und Γ ` t :: τ 2 , E 2
Γ ` (s t) :: α, E 1 ∪ E 2 ∪ {τ 1
= · τ 2 → α}
wobei α neue Typvariable
Regel f¨ ur seq:
(RSeq)
Γ ` s :: τ 1 , E 1 und Γ ` t :: τ 2 , E 2
Γ ` (seq s t) :: τ 2 , E 1 ∪ E 2
TCS
|07 Typisierung
|SoSe 2020 35/108 Motivation Typen Typisierungsverfahren
Typisierungsregeln f¨ ur KFPTS+seq Ausdr¨ ucke (4)
Regel f¨ ur Abstraktionen:
(RAbs)
Γ ∪ {x :: α} ` s :: τ, E Γ ` λx.s :: α → τ, E wobei α eine neue Typvariable
TCS
|07 Typisierung
|SoSe 2020 36/108 Motivation Typen Typisierungsverfahren
Typisierungsregeln f¨ ur KFPTS+seq Ausdr¨ ucke (5)
Typisierung eines case: Prinzipien
case T yp s of {
(c 1 x 1,1 . . . x 1,ar (c 1 ) ) → t 1 ; . . . ;
(c m x m,1 . . . x m,ar (c
m) ) → t m }
Die Pattern und der Ausdruck s haben gleichen Typ.
Der Typ muss auch zum Typindex am case passen
(Haskell hat keinen Typindex an case )
Die Ausdr¨ ucke t 1 , . . . , t n haben gleichen Typ,
und dieser Typ ist auch der Typ des ganzen case-Ausdrucks.
TCS
|07 Typisierung
|SoSe 2020 37/108 Motivation Typen Typisierungsverfahren
Typisierungsregeln f¨ ur KFPTS+seq Ausdr¨ ucke (6)
Regel f¨ ur case:
(RCase)
Γ ` s :: τ, E
f¨ ur alle i = 1, . . . , m: Γ ∪ {x i,1 :: α i,1 , . . . , x i,ar(c
i) :: α i,ar(c
i) } ` (c i x i,1 . . . x i,ar(ci) ) :: τ i , E i f¨ ur alle i = 1, . . . , m: Γ ∪ {x i,1 :: α i,1 , . . . , x i,ar(c
i) :: α i,ar(c
i) } ` t i :: τ i 0 , E i 0
Γ `
case T yp s of {
(c 1 x 1,1 . . . x 1,ar(c 1 ) ) → t 1 ; . . . ;
(c m x m,1 . . . x m,ar(c
m) ) → t m }
:: α, E 0
wobei E 0 = E ∪
m
S
i=1
E i ∪
m
S
i=1
E i 0 ∪
m
S
i=1
{τ = · τ i } ∪
m
S
i=1
{α = · τ i 0 } und α i,j , α neue Typvariablen sind
TCS
|07 Typisierung
|SoSe 2020 38/108 Motivation Typen Typisierungsverfahren
Instanz der Case-Regel f¨ ur Bool
(RCase)
Γ ` s :: τ, E Γ ` True :: τ 1 , E 1 Γ ` False :: τ 2 , E 2 Γ ` t 1 :: τ 1 0 , E 1 0 Γ ` t 2 :: τ 2 0 , E 0 2 Γ ` (case Bool s of {True → t 1 ; False → t 2 }) :: α, E 0
wobei E 0 = E ∪ E 1 ∪ E 2 ∪ E 0 1 ∪ E 2 0 ∪ {τ = · τ 1 , τ = · τ 2 } ∪ {α = · τ 1 0 , α = · τ 2 0 } und α i,j , α neue Typvariablen sind
Instanz der Case-Regel f¨ ur Listen
(RCase)
Γ ` s :: τ, E Γ ` Nil :: τ 1 , E 1
Γ ∪ {x 1 :: α 1 , x 2 :: α 2 } ` Cons x 1 x 2 :: τ 2 , E 2
Γ ` t 1 :: τ 1 0 , E 1 0
Γ ∪ {x 1 :: α 1 , x 2 :: α 2 } ` t 2 :: τ 2 0 , E 0 2
Γ ` (case List s of {Nil → t 1 ; (Cons x 1 x 2 ) → t 2 }) :: α, E 0 wobei E 0 = E ∪ E 1 ∪ E 2 ∪ E 1 0 ∪ E 2 0 ∪ {τ = · τ 1 , τ = · τ 2 } ∪ {α = · τ 1 0 , α = · τ 2 0 }
und α i,j , α neue Typvariablen sind
Typisierungsalgorithmus f¨ ur KFPTS+seq-Ausdr¨ ucke
Sei s ein geschlossener KFPTS+seq-Ausdruck, wobei die Typen f¨ ur alle in s benutzten Superkombinatoren und Konstruktoren bekannt sind. (d.h. diese Typen sind schon berechnet)
1
Starte mit Anfangsannahme Γ, die Typen f¨ ur die Konstruktoren und die Superkombinatoren enth¨ alt.
2
Leite Γ ` s :: τ, E mit den Typisierungsregeln her.
3
L¨ ose E mit Unifikation.
4
Wenn die Unifikation mit Fail endet, ist s nicht typisierbar;
Andernfalls: Sei σ ein allgemeinster Unifikator von E, dann gilt s :: σ(τ).
TCS
|07 Typisierung
|SoSe 2020 41/108 Motivation Typen Typisierungsverfahren
Optimierung
Zus¨ atzliche Regel, zum zwischendrin Unifizieren:
Typberechnung:
(RUnif)
Γ ` s :: τ, E Γ ` s :: σ(τ ), E σ
wobei E σ das gel¨ oste Gleichungssystem zu E ist und σ der ablesbare Unifikator ist
TCS
|07 Typisierung
|SoSe 2020 42/108 Motivation Typen Typisierungsverfahren
Wohlgetyptheit
Definition
Ein KFPTS+seq Ausdruck s ist wohl-getypt, wenn er sich mit obigem Verfahren typisieren l¨ asst.
(Typisierung von Superkombinatoren kommt noch)
TCS
|07 Typisierung
|SoSe 2020 43/108 Motivation Typen Typisierungsverfahren
Beispiele: Typisierung von (Cons True Nil)
Typisierung von Cons True Nil Starte mit:
Anfangsannahme: Γ 0 = {Cons :: ∀a.a → [a] → [a], Nil :: ∀a.[a], True :: Bool}
(RApp)
Γ 0 ` (Cons True) :: τ 1 , E 1 , Γ 0 ` Nil :: τ 2 , E 2
Γ 0 ` (Cons True Nil) :: α 4 , E 1 ∪ E 2 ∪ {τ 1
= · τ 2 → α 4 }
(RApp)
Γ 0 ` (Cons True) :: τ 1 , E 1 ,
(AxK)Γ 0 ` Nil :: [α 3 ], ∅ Γ 0 ` (Cons True Nil) :: α 4 , E 1 ∪ ∅ ∪ {τ 1
= [α · 3 ] → α 4 }
(RApp) (RApp)
Γ 0 ` Cons :: τ 3 , E 3 , Γ 0 ` True :: τ 4 , E 4
Γ 0 ` (Cons True) :: α 2 , {τ 3
= · τ 4 → α 2 } ∪ E 3 ∪ E 4 ,
(AxK)Γ 0 ` Nil :: [α 3 ], ∅
Γ 0 ` (Cons True Nil) :: α 4 , {τ 3
= · τ 4 → α 2 } ∪ E 3 ∪ E 4 ∪ {α 2
= [α · 3 ] → α 4 }
(RApp) (RApp)
(AxK)
Γ 0 ` Cons :: α 1 → [α 1 ] → [α 1 ], ∅ , Γ 0 ` True :: τ 4 , E 4
Γ 0 ` (Cons True) :: α 2 , {α 1 → [α 1 ] → [α 1 ] = · τ 4 → α 2 } ∪ E 4 ,
(AxK)Γ 0 ` Nil :: [α 3 ], ∅ Γ 0 ` (Cons True Nil) :: α 4 , {α 1 → [α 1 ] → [α 1 ] = · τ 4 → α 2 } ∪ E 4 ∪ {α 2
= [α · 3 ] → α 4 }
(RApp) (RApp) (AxK)
Γ 0 ` Cons :: α 1 → [α 1 ] → [α 1 ], ∅ ,
(AxK)Γ 0 ` True :: Bool, ∅
Γ 0 ` (Cons True) :: α 2 , {α 1 → [α 1 ] → [α 1 ] = · Bool → α 2 } ,
(AxK)Γ 0 ` Nil :: [α 3 ], ∅ Γ 0 ` (Cons True Nil) :: α 4 , {α 1 → [α 1 ] → [α 1 ] = · Bool → α 2 } ∪ {α 2
= [α · 3 ] → α 4 }
(RApp) (RApp) (AxK)
Γ 0 ` Cons :: α 1 → [α 1 ] → [α 1 ], ∅ ,
(AxK)Γ 0 ` True :: Bool, ∅
Γ 0 ` (Cons True) :: α 2 , {α 1 → [α 1 ] → [α 1 ] = · Bool → α 2 } ,
(AxK)Γ 0 ` Nil :: [α 3 ], ∅ Γ 0 ` (Cons True Nil) :: α 4 , {α 1 → [α 1 ] → [α 1 ] = · Bool → α 2 , α 2 ·
= [α 3 ] → α 4 } L¨ ose {α 1 → [α 1 ] → [α 1 ] =
·Bool → α 2 , α 2
= [α
·3 ] → α 4 } mit Unifikation
Ergibt: σ = {α 1 7→ Bool, α 2 7→ ([Bool] → [Bool]), α 3 7→ Bool, α 4 7→ [Bool]}
Daher (Cons True Nil) :: σ(α 4 ) = [Bool]
TCS
|07 Typisierung
|SoSe 2020 44/108 Motivation Typen Typisierungsverfahren
Beispiele: Typisierung von λx.x
Typisierung von λx.x
Starte mit: Anfangsannahme: Γ 0 = ∅
(RAbs)
Γ 0 ∪ {x :: α} ` x :: τ, E Γ 0 ` (λx.x) :: α → τ, E
(RAbs)(AxV)
Γ 0 ∪ {x :: α} ` x :: α, ∅ Γ 0 ` (λx.x) :: α → α, ∅
Nichts zu unifizieren, daher (λx.x) :: α → α
TCS
|07 Typisierung
|SoSe 2020 45/108 Motivation Typen Typisierungsverfahren
Beispiele: Typisierung von Ω
Typisierung von (λx.(x x)) (λy.(y y)) Starte mit: Anfangsannahme: Γ 0 = ∅
(RApp)
∅ ` (λx.(x x)) :: τ 1 , E 1 , ∅ ` (λy.(y y)) :: τ 2 , E 2
∅ ` (λx.(x x)) (λy.(y y)) :: α 1 , E 1 ∪ E 2 ∪ {τ 1
= · τ 2 → α 1 }
(RApp) (RAbs)
{x :: α 2 } ` (x x) :: τ 1 , E 1
∅ ` (λx.(x x)) :: α 2 → τ 1 , E 1 , ∅ ` (λy.(y y)) :: τ 2 , E 2
∅ ` (λx.(x x)) (λy.(y y)) :: α 1 , E 1 ∪ E 2 ∪ {τ 1 ·
= τ 2 → α 1 }
(RApp) (RAbs)
(RApp)
{x :: α 2 } ` x :: τ 3 , E 3 , {x :: α 2 } ` x :: τ 4 , E 4 , {x :: α 2 } ` (x x) :: α 3 , {τ 3
= · τ 4 → α 3 } ∪ E 3 ∪ E 4
∅ ` (λx.(x x)) :: α 2 → α 3 , {τ 3 ·
= τ 4 → α 3 } ∪ E 3 ∪ E 4 , ∅ ` (λy.(y y)) :: τ 2 , E 2
∅ ` (λx.(x x)) (λy.(y y)) :: α 1 , {τ 3
= · τ 4 → α 3 } ∪ E 3 ∪ E 4 ∪ E 2 ∪ {α 3
= · τ 2 → α 1 }
(RApp) (RAbs)
(RApp) (AxV)
{x :: α 2 } ` x :: α 2 , ∅ , {x :: α 2 } ` x :: τ 4 , E 4 , {x :: α 2 } ` (x x) :: α 3 , {α 2 ·
= τ 4 → α 3 } ∪ E 4
∅ ` (λx.(x x)) :: α 2 → α 3 , {α 2 ·
= τ 4 → α 3 } ∪ E 4 , ∅ ` (λy.(y y)) :: τ 2 , E 2
∅ ` (λx.(x x)) (λy.(y y)) :: α 1 , {α 2
= · τ 4 → α 3 } ∪ E 4 ∪ E 2 ∪ {α 3
= · τ 2 → α 1 }
(RApp) (RAbs) (RApp) (AxV)
{x :: α 2 } ` x :: α 2 , ∅ ,
(AxV){x :: α 2 } ` x :: α 2 , ∅ , {x :: α 2 } ` (x x) :: α 3 , {α 2 ·
= α 2 → α 3 }
∅ ` (λx.(x x)) :: α 2 → α 3 , {α 2
= · α 2 → α 3 } , ∅ ` (λy.(y y)) :: τ 2 , E 2
∅ ` (λx.(x x)) (λy.(y y)) :: α 1 , {α 2
= · α 2 → α 3 } ∪ E 2 ∪ {α 3
= · τ 2 → α 1 }
(RApp) (RAbs) (RApp) (AxV)
{x :: α 2 } ` x :: α 2 , ∅ ,
(AxV){x :: α 2 } ` x :: α 2 , ∅ , {x :: α 2 } ` (x x) :: α 3 , {α 2 ·
= α 2 → α 3 }
∅ ` (λx.(x x)) :: α 2 → α 3 , {α 2
= · α 2 → α 3 } ,
. . .
∅ ` (λy.(y y)) :: τ 2 , E 2
∅ ` (λx.(x x)) (λy.(y y)) :: α 1 , {α 2
= · α 2 → α 3 } ∪ E 2 ∪ {α 3
= · τ 2 → α 1 }
Man sieht schon:
Die Unifikation schl¨ agt fehl, wegen: α 2
= · α 2 → α 3
Daher: (λx.(x x)) (λy.(y y)) ist nicht typisierbar!
Beachte: (λx.(x x)) (λy.(y y)) ist nicht dynamisch ungetypt aber nicht wohl-getypt
TCS
|07 Typisierung
|SoSe 2020 46/108 Motivation Typen Typisierungsverfahren
Beispiele: Typisierung eines Ausdrucks mit SKs (1)
Annahme: map und length sind bereits typisierte Superkombinatoren.
Wir typisieren:
t := λxs.case List xs of {Nil → Nil; (Cons y ys) → map length ys}
Als Anfangsannahme benutzen wir:
Γ 0 = {map :: ∀a, b.(a → b) → [a] → [b], length :: ∀a.[a] → Int, Nil :: ∀a.[a]
Cons :: ∀a.a → [a] → [a]
}
Beispiele: Typisierung eines Ausdrucks mit SKs (2)
Herleitungsbaum:
(RAbs) (RCase) (AxV)
B 3
,(AxK)B 4
,(RApp) (RApp) (AxK)B 8
,(AxV)B 9 B 6
,(AxV)B 7
B 5
,(AxK)B 10
,(RApp) (RApp) (AxSK)B 14
,(AxSK)B 15 B 12
,(AxV)B 13 B 11
B 2 B 1
Beschriftungen:
B 1 = Γ 0 ` t :: α 1 → α 13 ,
{α 5 → [α 5 ] → [α 5 ] =
·α 3 → α 6 , α 6
=
·α 4 → α 7 , (α 8 → α 9 ) → [α 8 ] → [α 9 ] = ([α
·10 ] → Int) → α 11 , α 11
=
·α 4 → α 12 , α 1
= [α
·2 ], α 1 = α 7 , α 13
= [α
·14 ], α 13 = α 12 , } B 2 = Γ 0 ∪ {xs :: α 1 } `
case
Listxs of {Nil → Nil; (Cons y ys) → map length ys} :: α 13 , {α 5 → [α 5 ] → [α 5 ] =
·α 3 → α 6 , α 6
=
·α 4 → α 7 , (α 8 → α 9 ) → [α 8 ] → [α 9 ] = ([α
·10 ] → Int) → α 11 , α 11
=
·α 4 → α 12 , α 1
= [α
·2 ], α 1 = α 7 , α 13
= [α
·14 ], α 13 = α 12 , }
Beispiele: Typisierung eines Ausdrucks mit SKs (3)
Herleitungsbaum:
(RAbs) (RCase) (AxV)
B 3
,(AxK)B 4
,(RApp) (RApp) (AxK)B 8
,(AxV)B 9 B 6
,(AxV)B 7
B 5
,(AxK)B 10
,(RApp) (RApp) (AxSK)B 14
,(AxSK)B 15 B 12
,(AxV)B 13 B 11
B 2 B 1
Beschriftungen:
B 3 = Γ 0 ∪ {xs :: α 1 } ` xs :: α 1 , ∅ B 4 = Γ 0 ∪ {xs :: α 1 } ` Nil :: [α 2 ], ∅
B 5 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` (Cons y ys) :: α 7 , {α 5 → [α 5 ] → [α 5 ] =
·α 3 → α 6 , α 6
=
·α 4 → α 7 } B 6 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` (Cons y) :: α 6 ,
{α 5 → [α 5 ] → [α 5 ] =
·α 3 → α 6 } B 7 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` ys :: α 4 , ∅
B 8 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` Cons :: α 5 → [α 5 ] → [α 5 ], ∅ B 9 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` y :: α 3 , ∅
B 10 = Γ 0 ∪ {xs :: α 1 } ` Nil :: [α 14 ], ∅
TCS
|07 Typisierung
|SoSe 2020 49/108 Motivation Typen Typisierungsverfahren
Beispiele: Typisierung eines Ausdrucks mit SKs (4)
Herleitungsbaum:
(RAbs) (RCase) (AxV)
B 3
,(AxK)B 4
,(RApp) (RApp) (AxK)B 8
,(AxV)B 9 B 6
,(AxV)B 7
B 5
,(AxK)B 10
,(RApp) (RApp) (AxSK)B 14
,(AxSK)B 15 B 12
,(AxV)B 13 B 11
B 2 B 1
Beschriftungen:
B 11 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` (map length) ys :: α 12 , {(α 8 → α 9 ) → [α 8 ] → [α 9 ] = ([α
·10 ] → Int) → α 11 , α 11
=
·α 4 → α 12 } B 12 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` (map length) :: α 11 ,
{(α 8 → α 9 ) → [α 8 ] → [α 9 ] = ([α
·10 ] → Int) → α 11 } B 13 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` ys :: α 4 , ∅
B 14 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` map :: (α 8 → α 9 ) → [α 8 ] → [α 9 ], ∅ B 15 = Γ 0 ∪ {xs :: α 1 , y :: α 3 , ys :: α 4 } ` length :: [α 10 ] → Int, ∅
TCS
|07 Typisierung
|SoSe 2020 50/108 Motivation Typen Typisierungsverfahren
Beispiele: Typisierung eines Ausdrucks mit SKs (5)
Beschriftung unten:
B 1 = Γ 0 ` t :: α 1 → α 13 ,
{α 5 → [α 5 ] → [α 5 ] =
·α 3 → α 6 , α 6
=
·α 4 → α 7 , (α 8 → α 9 ) → [α 8 ] → [α 9 ] = ([α
·10 ] → Int) → α 11 , α 11
=
·α 4 → α 12 , α 1
= [α
·2 ], α 1 = α 7 , α 13
= [α
·14 ], α 13 = α 12 , }
L¨ ose mit Unifikation:
{α 5 → [α 5 ] → [α 5 ] =
·α 3 → α 6 , α 6
=
·α 4 → α 7 , (α 8 → α 9 ) → [α 8 ] → [α 9 ] = ([α
·10 ] → Int) → α 11 , α 11
=
·α 4 → α 12 , α 1
= [α
·2 ], α 1 = α 7 , α 13
= [α
·14 ], α 13 = α 12 }
Ergibt:
σ = {α 1 7→ [[α 10 ]], α 2 7→ [α 10 ], α 3 7→ [α 10 ], α 4 7→ [[α 10 ]], α 5 7→ [α 10 ], α 6 7→ [[α 10 ]] → [[α 10 ]], α 7 7→ [[α 10 ]], α 8 7→ [α 10 ], α 9 7→ Int, α 11 7→ [[α 10 ]] → [Int], α 12 7→ [Int], α 13 7→ [Int], α 14 7→ Int}
Damit erh¨ alt man t :: σ(α 1 → α 13 ) = [[α 10 ]] → [Int].
TCS
|07 Typisierung
|SoSe 2020 51/108 Motivation Typen Typisierungsverfahren
Bsp.: Typisierung von Lambda-geb. Variablen (1)
Die Funktion const ist definiert als const :: a -> b -> a
const x y = x
Typisierung von λx.const (x True) (x ’A’) Anfangsannahme:
Γ 0 = {const :: ∀a, b.a → b → a, True :: Bool, ’A’ :: Char}.
TCS
|07 Typisierung
|SoSe 2020 52/108 Motivation Typen Typisierungsverfahren
Bsp.: Typisierung von Lambda-geb. Variablen (2)
(RAbs) (RApp) (RApp) (AxSK)
Γ 1 ` const :: α 2 → α 3 → α 2 , ∅ ,
(RApp)(AxV)
Γ 1 ` x :: α 1 ,
(AxK)Γ 1 ` True :: Bool Γ 1 ` (x True) :: α 4 , E 1
Γ 1 ` const (x True) :: α 5 , E 2 ,
(RApp)(AxV)
Γ 1 ` x :: α 1 ,
(AxK)Γ 1 ` ’A’ :: Char Γ 1 ` (x ’A’) :: α 6 , E 3
Γ 1 ` const (x True) (x ’A’) :: α 7 , E 4
Γ 0 ` λx.const (x True) (x ’A’) :: α 1 → α 7 , E 4
wobei Γ 1 = Γ 0 ∪ {x :: α 1 } und:
E 1 = {α 1
=
·Bool → α 4 } E 2 = {α 1
=
·Bool → α 4 , α 2 → α 3 → α 2
=
·α 4 → α 5 } E 3 = {α 1
=
·Char → α 6 } E 4 = {α
1=
·Bool → α
4, α 2 → α 3 → α 2
=
·α 4 → α 5 , α
1=
·Char → α
6, α 5
=
·α 6 → α 7 } Die Unifikation schl¨ agt fehl, da Char 6= Bool
TCS
|07 Typisierung
|SoSe 2020 53/108 Motivation Typen Typisierungsverfahren
Bsp.: Typisierung von Lambda-geb. Variablen (3)
In Haskell:
Main> \x -> const (x True) (x 'A')
<interactive>:1:23:
Couldn't match expected type `Char' against inferred type `Bool' Expected type: Char -> b
Inferred type: Bool -> a
In the second argument of `const', namely `(x 'A')' In the expression: const (x True) (x 'A')
Beispiel verdeutlicht: Lambda-gebundene Variablen sind monomorph getypt!
Das gleiche gilt f¨ ur case-Pattern gebundene Variablen Daher spricht man auch von let-Polymorphismus, da nur let-gebundene Variablen polymorph sind.
KFPTS+seq hat kein let, aber Superkombinatoren, die wie (ein eingeschr¨ anktes rekursives) let wirken
TCS
|07 Typisierung
|SoSe 2020 54/108 Motivation Typen Typisierungsverfahren
Rekursive Superkombinatoren
Definition (direkt rekursiv, rekursiv, verschr¨ ankt rekursiv) Sei SK eine Menge von Superkombinatoren F¨ ur SK i , SK j ∈ SK sei
SK i SK j
gdw. SK j den Superkombinator SK i im Rumpf benutzt.
+ : transitiver Abschluss von ( ∗ : reflexiv-transitiver Abschluss) SK i ist direkt rekursiv wenn SK i SK i gilt.
SK i ist rekursiv wenn SK i + SK i gilt.
SK 1 , . . . , SK m sind verschr¨ ankt rekursiv, wenn SK i + SK j f¨ ur alle i, j ∈ {1, . . . , m}
Typisierung von nicht-rekursiven Superkombinatoren
Nicht-rekursive Superkombinatoren kann man wie Abstraktionen typisieren Notation: Γ ` T SK :: τ , bedeutet:
unter Annahme Γ kann man SK mit Typ τ typisieren Typisierungsregel f¨ ur (geschlossene) nicht-rekursive SK:
(RSK1)
Γ ∪ {x 1 :: α 1 , . . . , x n :: α n } ` s :: τ, E Γ ` T SK :: ∀X .σ(α 1 → . . . → α n → τ )
wenn σ L¨ osung von E,
SK x 1 . . . x n = s die Definition von SK und SK nicht rekursiv ist,
und X die Typvariablen in σ(α 1 → . . . → α n → τ )
Beispiel: Typisierung von (.)
(.) f g x = f (g x)
Γ 0 ist leer, da keine Konstruktoren oder SK vorkommen.
(RSK1) (RApp) (AxV)
Γ 1 ` f :: α 1 , ∅ ,
(RApp) (AxV)
Γ 1 ` g :: α 2 , ∅ ,
(AxV)Γ 1 ` x :: α 3 , ∅ Γ 1 ` (g x) :: α 5 , {α 2
= · α 3 → α 5 }
Γ 1 ` (f (g x)) :: α 4 , {α 2 = · α 3 → α 5 , α 1 = α 5 → α 4 }
∅ ` T (.) :: ∀X .σ(α 1 → α 2 → α 3 → α 4 ) wobei Γ 1 = {f :: α 1 , g :: α 2 , x :: α 3 }
Unifikation ergibt σ = {α 2 7→ α 3 → α 5 , α 1 7→ α 5 → α 4 }.
Daher: σ(α 1 → α 2 → α 3 → α 4 ) = (α 5 → α 4 ) → (α 3 → α 5 ) → α 3 → α 4
Jetzt kann man X = {α 3 , α 4 , α 5 } berechnen , und umbenennen:
(.) :: ∀a, b, c.(a → b) → (c → a) → c → b
TCS
|07 Typisierung
|SoSe 2020 57/108 Motivation Typen Typisierungsverfahren
Typisierung von rekursiven Superkombinatoren
Sei SK x 1 . . . x n = e
und SK kommt in e vor, d.h. SK ist rekursiv Warum kann man SK nicht ganz einfach typisieren?
Will man den Rumpf e typisieren, so muss man den Typ von SK kennen!
TCS
|07 Typisierung
|SoSe 2020 58/108 Motivation Typen Typisierungsverfahren
Idee des Iterativen Typisierungsverfahrens
Gebe SK zun¨ achst den allgemeinsten Typ
(d.h. eine Typvariable) und typisiere den Rumpf unter Benutzung dieses Typs Man erh¨ alt anschließend einen neuen Typ f¨ ur SK
Mache mit neuem Typ weiter Stoppe, wenn neuer Typ = alter Typ
Dann hat man eine konsistente Typannahme gefunden;
Vermutung: auch eine ausreichend allgemeine (allgemeinste?) Allgemeinster Typ: Typ T so dass sem(T ) = {alle Grundtypen}.
Das liefert der Typ α (bzw. quantifiziert ∀α.α)
TCS
|07 Typisierung
|SoSe 2020 59/108 Motivation Typen Typisierungsverfahren
Iteratives Typisierungsverfahren
Regel zur Berechnung neuer Annahmen:
(SKRek)
Γ ∪ {x 1 :: α 1 , . . . , x n :: α n } ` s :: τ, E Γ ` T SK :: σ(α 1 → . . . α n → τ)
wenn SK x 1 . . . x n = s die Definition von SK, σ L¨ osung von E Genau wie RSK1, aber in Γ muss es eine Annahme f¨ ur SK geben.
TCS
|07 Typisierung
|SoSe 2020 60/108 Motivation Typen Typisierungsverfahren
Iteratives Typisierungsverfahren: Vorarbeiten (1)
Wegen verschr¨ ankter Rekursion:
Abh¨ angigkeitsanalyse der Superkombinatoren
Berechnung der starken Zusammenhangskomponenten im Aufrufgraph Sei ' die ¨ Aquivalenzrelation passend zu ∗ , dann sind die starken Zusammenhangskomponenten gerade die ¨ Aquivalenzklassen zu '.
Jede ¨ Aquivalenzklasse wird gemeinsam typisiert
Typisierung der Gruppen entsprechend der ∗ -Ordnung modulo '.
TCS
|07 Typisierung
|SoSe 2020 61/108 Motivation Typen Typisierungsverfahren
Iteratives Typisierungsverfahren: Vorarbeiten (2)
Beispiel:
f x y = if x<=1 then y else f (x-y) (y + g x) g x = if x==0 then (f 1 x) + (h 2) else 10 h x = if x==1 then 0 else h (x-1)
k x y = if x==1 then y else k (x-1) (y+(f x y)) Der Aufrufgraph (nur bzgl. f,g,h,k ) ist
g
h
-- f
^^ ee
k
@@
%%
Die ¨ Aquivalenzklassen (mit Ordnung) sind {h} + {f, g} + {k}.
TCS
|07 Typisierung
|SoSe 2020 62/108 Motivation Typen Typisierungsverfahren
Iteratives Typisierungsverfahren: Der Algorithmus
Iterativer Typisierungsalgorithmus
Eingabe: Verschr¨ ankt rekursive Superkombinatoren SK 1 , . . . , SK m (kleinere SKs schon typisiert)
1
Anfangsannahme Γ enth¨ alt Typen der Konstruktoren und der bereits bekannten SKs
2
Γ 0 := Γ ∪ {SK 1 :: ∀α 1 .α 1 , . . . , SK m :: ∀α m .α m } und j = 0.
3
Verwende f¨ ur jeden Superkombinator SK i (mit i = 1, . . . , m) die Regel ( SKRek ) und Annahme Γ j , um SK i zu typisieren.
4
Wenn die m Typisierungen erfolgreich, d.h. f¨ ur alle i: Γ j ` T SK i :: τ i
Dann allquantifiziere: SK 1 :: ∀X 1 .τ 1 , . . . , SK m :: ∀X m .τ m Setze Γ j+1 := Γ ∪ {SK 1 :: ∀X 1 .τ 1 , . . . , SK m :: ∀X m .τ m }
5
Wenn Γ j 6= Γ j+1 , dann gehe mit j := j + 1 zu Schritt (3).
Anderenfalls, d.h. wenn Γ j = Γ j+1 , war Γ j konsistent.
Ausgabe: Allquantifizierte polymorphen Typen der SK i aus der konsistenten Annahme.
Sollte irgendwann ein Fail in der Unifikation auftreten, dann sind SK , . . . , SK nicht typisierbar.
Eigenschaften des Algorithmus
Die berechneten Typen pro Iterationsschritt sind eindeutig bis auf Umbenennung.
= ⇒ bei Terminierung liefert der Algorithmus eindeutige Typen.
Pro Iteration werden die neuen Typen spezieller (oder bleiben gleich).
D.h. Monotonie bzgl. der Grundtypensemantik: sem(T j ) ⊇ sem(T j+1 ) Bei Nichtterminierung gibt es keinen polymorphen Typ.
Grund: Monotonie und man hat mit gr¨ oßten Annahmen begonnen.
Das iterative Verfahren berechnet einen gr¨ oßten Fixpunkt (bzgl. der
Grundtypensemantik): Menge wird solange verkleinert, bis sie sich nicht mehr ¨ andert.
D.h. es wird der allgemeinste polymorphe Typ berechnet
Beispiele: length (1)
length xs = case List xs of{Nil → 0; (y : ys) → 1 + length ys}
Annahme:
Γ = {Nil :: ∀a.[a], (:) :: ∀a.a → [a] → [a], 0, 1 :: Int, (+) :: Int → Int → Int}
1.Iteration: Γ 0 = Γ ∪ {length :: ∀α.α}
(SKRek) (RCase)
(a) Γ
0∪ {xs :: α
1} ` xs :: τ
1, E
1(b) Γ
0∪ {xs :: α
1} ` Nil :: τ
2, E
2(c) Γ
0∪ {xs :: α
1, y :: α
4, ys :: α
5} ` (y : ys) :: τ
3, E
3(d) Γ
0∪ {xs :: α
1} ` 0 :: τ
4, E
4(e) Γ
0∪ {xs :: α
1, y :: α
4, ys :: α
5}} ` (1 + length ys) :: τ
5, E
5Γ
0∪ {xs :: α
1} ` (case
Listxs of{Nil → 0; (y : ys) → 1 + length xs}) :: α
3,
E
1∪E
2∪ E
3∪ E
4∪ E
5∪ {τ
1 ·= τ
2, τ
1 ·= τ
3, α
3 ·= τ
4, α
3 ·= τ
5} Γ
0`
Tlength :: σ(α
1→ α
3)
wobei σ L¨ osung von E 1 ∪ E 2 ∪ E 3 ∪ E 4 ∪ E 5 ∪ {τ 1 = · τ 2 , τ 1
= · τ 3 , α 3
= · τ 4 , α 3
= · τ 5 }
TCS
|07 Typisierung
|SoSe 2020 65/108 Motivation Typen Typisierungsverfahren
Beispiele: length (2)
(a): (AxV) Γ 0 ∪ {xs :: α 1 } ` xs :: α 1 , ∅ D.h τ 1 = α 1 und E 1 = ∅
(b): (AxK) Γ 0 ∪ {xs :: α 1 } ` Nil :: [α 6 ], ∅ D.h. τ 2 = [α 6 ] und E 2 = ∅
(c)
(RApp) (RApp) (AxK)
Γ
00` (:) :: α
9→ [α
9] → [α
9], ∅ , (AxV) Γ
00` y :: α
4,∅
Γ
00` ((:) y) :: α
8,{α
9→ [α
9] → [α
9] =
·α
4→ α
8} , (AxV) Γ
00` ys :: α
5,∅
Γ
00` (y : ys) :: α
7,{α
9→ [α
9] → [α
9] =
·α
4→ α
8, α
8=
·α
5→ α
7}
wobei Γ 0 = Γ 0 ∪ {xs :: α 1 , y :: α 4 , ys :: α 5 }
D.h. τ 3 = α 7 und E 3 = {α 9 → [α 9 ] → [α 9 ] = · α 4 → α 8 , α 8 ·
= α 5 → α 7 }
TCS
|07 Typisierung
|SoSe 2020 66/108 Motivation Typen Typisierungsverfahren
Beispiele: length (3)
(d) (AxK) Γ 0 ∪ {xs :: α 1 } ` 0 :: Int, ∅ D.h. τ 4 = Int und E 4 = ∅
(e)
(RApp) (RApp) (AxK)
Γ
00` (+) :: Int → Int → Int,∅ ,
(AxK)Γ
00` 1 :: Int,∅
Γ
00` ((+) 1) :: α
11,{Int → Int → Int =
·Int → α
11} ,
(RApp)(AxSK)
Γ
00` length :: α
13,∅ ,
(AxV)Γ
00` (ys) :: α
5, ∅ Γ
00` (length ys) :: α
12, {α
13=
·α
5→ α
12} Γ
00` (1 + length ys) :: α
10,{Int → Int → Int =
·Int → α
11, α
13=
·α
5→ α
12, α
11=
·α
12→ α
10}
wobei Γ 0 = Γ 0 ∪ {xs :: α 1 , y :: α 4 , ys :: α 5 } D.h. τ 5 = α 10 und
E 5 = {Int → Int → Int =
·Int → α 11 , α 13
=
·α 5 → α 12 , α 11
=
·α 12 → α 10 }
TCS
|07 Typisierung
|SoSe 2020 67/108 Motivation Typen Typisierungsverfahren
Beispiele: length (4)
Zusammengefasst: Γ 0 ` T length :: σ(α 1 → α 3 ) wobei σ L¨ osung von
{α 9 → [α 9 ] → [α 9 ] = · α 4 → α 8 , α 8
= · α 5 → α 7 , Int → Int → Int = · Int → α 11 , α 13
= · α 5 → α 12 , α 11
= · α 12 → α 10 , α 1 ·
= [α 6 ], α 1 ·
= α 7 , α 3 ·
= Int, α 3 ·
= α 10 } Die Unifikation ergibt als Unifikator
{α 1 7→ [α 9 ], α 3 7→ Int, α 4 7→ α 9 , α 5 7→ [α 9 ], α 6 7→ α 9 , α 7 7→ [α 9 ], α 8 7→ [α 9 ] → [α 9 ], α 10 7→ Int, α 11 7→ Int → Int, α 12 7→ Int, α 13 7→ [α 9 ] → Int}
daher σ(α 1 → α 3 ) = [α 9 ] → Int Γ 1 = Γ ∪ {length :: ∀α.[α] → Int}
Da Γ 0 6= Γ 1 muss man mit Γ 1 erneut iterieren.
2.Iteration: Ergibt den gleichen Typ, daher war Γ 1 konsistent.
TCS
|07 Typisierung
|SoSe 2020 68/108 Motivation Typen Typisierungsverfahren
Iteratives Verfahren ist allgemeiner als Haskell
Beispiel
g x = 1 : (g (g 'c'))
Γ = {1 :: Int, Cons :: ∀a.a → [a] → [a], ’c’ :: Char}
Γ 0 = Γ ∪ {g :: ∀α.α} (und Γ 0 0 = Γ 0 ∪ {x :: α 1 }):
(SKRek) (RApp) (RApp) (AxK)
Γ
00` Cons :: α
5→ [α
5] → [α
5], ∅ ,
(AxK)Γ
00` 1 :: Int, ∅ Γ
00` (Cons 1) :: α
3, α
5→ [α
5] → [α
5] =
·Int → α
3,
(RApp)(AxSK)
Γ
00` g :: α
6, ∅
(RApp),
(AxSK)
Γ
00` g :: α
8, ∅
(AxK), Γ
00` ’c’ :: Char,∅ , Γ
00` (g ’c’) :: α
7, {α
8 ·= Char → α
7} Γ
00` (g (g ’c’)) :: α
4, {α
8=
·Char → α
7, α
6=
·α
7→ α
4} Γ
00` Cons 1 (g (g ’c’)) :: α
2, {α
8·= Char → α
7, α
6 ·= α
7→ α
4, α
5→ [α
5] → [α
5] =
·Int → α
3, α
3 ·= α
4→ α
2} Γ
0`
Tg :: σ(α
1→ α
2) = α
1→ [Int]
wobei σ = {α
27→ [Int], α
37→ [Int] → [Int], α
47→ [Int], α
57→ Int, α
67→ α
7→ [Int], α
87→ Char → α
7} die L¨ osung von {α
8=
·Char → α
7, α
6=
·α
7→ α
4, α
5→ [α
5] → [α
5] =
·Int → α
3, α
3=
·α
4→ α
2} ist.
D.h. Γ 1 = Γ ∪ {g :: ∀α.α → [Int]}.
N¨ achste Iteration zeigt: Γ 1 ist konsistent.
TCS
|07 Typisierung
|SoSe 2020 69/108 Motivation Typen Typisierungsverfahren
Iteratives Verfahren ist allgemeiner als Haskell (2)
Beachte: F¨ ur die Funktion g kann Haskell keinen Typ herleiten:
Prelude> let g x = 1:(g(g 'c'))
<interactive>:1:13:
Couldn't match expected type `[t]' against inferred type `Char' Expected type: Char -> [t]
Inferred type: Char -> Char
In the second argument of `(:)', namely `(g (g 'c'))' In the expression: 1 : (g (g 'c'))
Aber: Haskell kann den Typ verifizieren, wenn man ihn angibt:
let g::a -> [Int]; g x = 1:(g(g 'c')) Prelude> :t g
g :: a -> [Int]
Grund: Wenn Typ vorhanden, f¨ uhrt Haskell keine Typinferenz durch, sondern verifiziert nur die Annahme. g wird im Rumpf wie bereits typisiert behandelt.
TCS
|07 Typisierung
|SoSe 2020 70/108 Motivation Typen Typisierungsverfahren
Bsp.: Mehrere Iterationen sind n¨ otig (1)
g x = x : (g (g 'c'))
Γ = {Cons :: ∀a.a → [a] → [a], ’c’ :: Char}.
Γ 0 = Γ ∪ {g :: ∀α.α}
(SKRek) (RApp) (RApp) (AxK)
Γ
00` Cons :: α
5→ [α
5] → [α
5], ∅ ,
(AxV)Γ
00` x :: α
1, ∅ Γ
00` (Cons x) :: α
3, α
5→ [α
5] → [α
5] =
·α
1→ α
3 (RApp),
(AxSK)
Γ
00` g :: α
6, ∅
(RApp),
(AxSK)
Γ
00` g :: α
8, ∅
(AxK), Γ
00` ’c’ :: Char, ∅ , Γ
00` (g ’c’) :: α
7, {α
8 ·= Char → α
7} Γ
00` (g (g ’c’)) :: α
4, {α
8=
·Char → α
7, α
6=
·α
7→ α
4} Γ
00` Cons x (g (g ’c’)) :: α
2, {α
8 ·= Char → α
7, α
6 ·= α
7→ α
4, α
5→ [α
5] → [α
5] =
·α
1→ α
3, α
3 ·= α
4→ α
2} Γ
0`
Tg :: σ(α
1→ α
2) = α
5→ [α
5]
wobei σ = {α
17→ α
5, α
27→ [α
5], α
37→ [α
5] → [α
5], α
47→ [α
5], α
67→ α
7→ [α
5], α
87→ Char → α
7} die L¨ osung von {α
8=
·Char → α
7, α
6=
·α
7→ α
4, α
5→ [α
5] → [α
5] =
·α
1→ α
3, α
3=
·α
4→ α
2} ist.
D.h. Γ 1 = Γ ∪ {g :: ∀α.α → [α]}.
Bsp.: Mehrere Iterationen sind n¨ otig (2)
Da Γ 0 6= Γ 1 muss eine weitere Iteration durchgef¨ uhrt werden.
Sei Γ 0 1 = Γ 1 ∪ {x :: α 1 }:
(SKRek) (RApp) (RApp) (AxK)
Γ01`Cons::α5→[α5]→[α5],∅(AxV), Γ01`x::α1,∅ Γ01`(Consx) ::α3, α5→[α5]→[α5]=·α1→α3 (RApp),
(AxSK)
Γ01`g::α6→[α6],∅(RApp),
(AxSK)
Γ01`g::α8→[α8],∅(AxK), Γ01`’c’::Char,∅, Γ01`(g ’c’) ::α7,{α8→[α8]=·Char→α7} Γ01`(g(g ’c’)) ::α4,{α8→[α8]=·Char→α7, α6→[α6]=·α7→α4} Γ01`Consx(g(g ’c’)) ::α2,{α8→[α8]=·Char→α7, α6→[α6]=·α7→α4α5→[α5]→[α5]=·α1→α3, α3·
=α4→α2}
Γ1`Tg::σ(α1→α2) =[Char]→[[Char]]
wobeiσ={α17→[Char], α27→[[Char]], α37→[[Char]]→[[Char]], α47→[[Char]], α57→[Char], α67→[Char], α77→[Char], α87→Char}
die L¨osung von{α8→[α8]=·Char→α7, α6→[α6]=·α7→α4, α5→[α5]→[α5]=·α1→α3, α3
=·α4→α2}ist.
Daher ist Γ 2 = Γ ∪ {g :: [Char] → [[Char]]}.
Bsp.: Mehrere Iterationen sind n¨ otig (3)
Da Γ 1 6= Γ 2 muss eine weitere Iteration durchgef¨ uhrt werden:
Sei Γ 0 2 = Γ 2 ∪ {x :: α 1 }:
(SKRek) (RApp) (RApp)
(AxK)
Γ02`Cons::α5→[α5]→[α5],∅(AxV), Γ02`x::α1,∅
Γ02`(Consx) ::α3, α5→[α5]→[α5]=α· 1→α3 ,
(RApp) (AxSK)
Γ02`g:: [Char]→[[Char]],∅,(RApp)
(AxSK)
Γ02`g:: [Char]→[[Char]],∅,(AxK)Γ02`’c’::Char,∅, Γ02`(g ’c’) ::α7,{[Char]→[[Char]]=Char· →α7} Γ02`(g(g ’c’)) ::α4,{[Char]→[[Char]]=Char· →α7,[Char]→[[Char]]=·α7→α4} Γ02`Consx(g(g ’c’)) ::α2,{[Char]→[[Char]]=·Char→α7,[Char]→[[Char]]=·α7→α4α5→[α5]→[α5]=α· 1→α3, α3=·α4→α2}
Γ2`Tg::σ(α1→α2) wobeiσdie L¨osung von
{[Char]→[[Char]]=Char· →α7,[Char]→[[Char]]=·α7→α4, α5→[α5]→[α5]=α· 1→α3, α3·
=α4→α2}ist.