📚 The CoCalc Library - books, templates and other resources
License: OTHER
%!TEX root = Programmierparadigmen.tex1\chapter{Typinferenz}2\begin{definition}[Datentyp]\index{Typ|see{Datentyp}}\xindex{Datentyp}%3Ein \textit{Datentyp} oder kurz \textit{Typ} ist eine Menge von Werten, mit4denen eine Bedeutung verbunden ist.5\end{definition}67\begin{beispiel}[Datentypen]8\begin{itemize}9\item $\text{\texttt{bool}} = \Set{\text{True}, \text{False}}$10\item $\text{\texttt{char}} = \text{vgl. \cpageref{sec:ascii-tabelle}}$11\item $\text{\texttt{int}}_{\text{Haskell}} = [-2^{29}, 2^{29}-1] \cap \mathbb{N}$12\item $\text{\texttt{int}}_{\text{C90}} = [-2^{15}-1, 2^{15}-1] \cap \mathbb{N}$\footnote{siehe ISO/IEC 9899:TC2, Kapitel 7.10: Sizes of integer types <limits.h>}13\item \texttt{float} = siehe IEEE 75414\item Funktionstypen, z.~B. $\text{\texttt{int}} \rightarrow \text{\texttt{int}}$ oder15$\text{\texttt{char}} \rightarrow \text{\texttt{int}}$16\end{itemize}17\end{beispiel}1819\underline{Hinweis:} Typen sind unabhängig von ihrer Repräsentation. So kann ein20\texttt{bool} durch ein einzelnes Bit repräsentiert werden oder eine Bitfolge21zugrunde liegen.2223Auf Typen sind Operationen definiert. So kann man auf numerischen Typen eine24Addition (+), eine Subtraktion (-), eine Multiplikation (*) und eine Division (/)25definieren.\\26Ich schreibe hier bewusst \enquote{eine} Multiplikation und nicht \enquote{die}27Multiplikation, da es verschiedene Möglichkeiten gibt auf Gleitpunktzahlen28Multiplikationen zu definieren. So kann man beispielsweise die Assoziativität29unterschiedlich wählen.3031\begin{beispiel}[Multiplikation ist nicht assoziativ]32In Python 3 ist die Multiplikation linksassoziativ. Also:33\inputminted[numbersep=5pt, tabsize=4]{python}{scripts/python/multiplikation.py}34\end{beispiel}3536\begin{definition}[Typvariable]\xindex{Typvariable}%37Eine Typvariable repräsentiert einen Typen.38\end{definition}3940\underline{Hinweis:} Üblicherweise werden kleine griechische Buchstaben ($\alpha, \beta, \tau_1, \tau_2, \dots$) als Typvariablen gewählt.4142Genau wie Typen bestimmte Operationen haben, die auf ihnen definiert sind,43kann man sagen, dass Operationen bestimmte Typen, auf die diese Anwendbar sind. So ist44\[\alpha+\beta\]45für numerische $\alpha$ und $\beta$ wohldefiniert, auch wenn $\alpha$ und $\beta$ boolesch sind46oder beides Strings sind könnte das Sinn machen. Es macht jedoch z.~B. keinen Sinn,47wenn $\alpha$ ein String ist und $\beta$ boolesch.4849Die Menge aller Operationen, die auf die Variablen angewendet werden, nennt man50\textbf{Typkontext}\xindex{Typkontext}. Dieser wird üblicherweise mit $\Gamma$51bezeichnet. Der Typkontext weist freien Variablen $x$ ihren Typ $\Gamma(x)$ zu.5253Das Ableiten einer Typisierung für einen Ausdruck nennt man \textbf{Typinferenz}\xindex{Typinferenz}.54Man schreibt: $\vdash(\lambda x.2): \alpha \rightarrow \text{int}$.5556Bei solchen Ableitungen sind häufig viele Typen möglich. So kann der Ausdruck57\[\lambda x.\ 2\]58folgenderweise typisiert werden:59\begin{itemize}60\item $\vdash(\lambda x.\ 2): \text{bool} \rightarrow \text{int}$61\item $\vdash(\lambda x.\ 2): \text{int} \rightarrow \text{int}$62\item $\vdash(\lambda x.\ 2): \text{Char} \rightarrow \text{int}$63\item $\vdash(\lambda x.\ 2): \alpha \rightarrow \text{int}$64\end{itemize}6566In der letzten Typisierung stellt $\alpha$ einen beliebigen Typen dar.6768Wichtig ist, dass man sich von unten nach oben vorarbeitet.6970\begin{beispiel}[Typinferenz\footnotemark]71Typisieren Sie den Term72\[\lambda a.\ a\ \text{true}\]73unter Verwendung der Regeln \verb+Var+, \verb+Abs+ und \verb+App+.7475\[\ABS: \frac{\APP \frac{\VAR \frac{(a:\alpha_2)(a) = \alpha_4}{a: \alpha_2 \vdash a: \alpha_4} \;\;\;\;\;\; a: \alpha_2 \vdash \text{true}: \text{bool}}{a: \alpha_2 \vdash a\ \text{true}: \alpha_3}}{\vdash \lambda a.\ a\ \text{true}: \alpha_1}\]76\end{beispiel}77\footnotetext{Dieses Beispiel stammt aus der Klausur vom WS2013/2014}7879\section{Typsystem}80\begin{definition}[Typsystem $\Gamma \vdash t: T$\footnotemark]\label{def:typsystem-t1}\xindex{Typregel}\xindex{Typsystem}\xindex{APP@$\APP$}\xindex{ABS@$\ABS$}\xindex{VAR@$\VAR$}\xindex{CONST@$\CONST$}%81Ein Typsystem besteht aus einem Typkontext $\Gamma$ und folgenden Regeln:8283\begin{align*}84\CONST:&\frac{c \in \text{Const}}{\Gamma \vdash c: \tau_c}\\85&\\86\VAR: &\frac{\Gamma(x) = \tau}{\Gamma \vdash x: \tau}\\87&\\88\ABS: &\frac{\Gamma, x: \tau_1 \vdash t: \tau_2}{\Gamma \vdash \lambda x. t: \tau_1 \rightarrow \tau_2}\\89&\\90\APP: &\frac{\Gamma \vdash t_1: \tau_2 \rightarrow \tau\;\;\; \Gamma \vdash t_2: \tau_2}{\Gamma \vdash t_1 t_2: \tau} \\91\end{align*}9293wobei $t_1, t_2$ immer $\lambda$-Terme bezeichnet.94\end{definition}95\footnotetext{WS 2013 / 2014, Folie 192}969798Dabei ist der lange Strich kein Bruchstrich, sondern ein Symbol der Logik das als99\textbf{Schlussstrich}\xindex{Schlussstrich} bezeichnet wird. Dabei ist der100Zähler als Voraussetzung und der Nenner als Schlussfolgerung zu verstehen.101102\begin{definition}[Typsubstituition]\xindex{Typsubstituition}%103Eine \textit{Typsubstituition} ist eine endliche Abbildung von Typvariablen auf104Typen.105\end{definition}106107Für eine Menge von Typsubsitutionen wird überlicherweise $\sigma$ als Symbol108verwendet. Man schreibt also beispielsweise:109\[\sigma = [\alpha_1 \text{\pointer} \text{\texttt{bool}}, \alpha_2 \text{\pointer} \alpha_1 \rightarrow \alpha_1]\]110111\begin{definition}[Lösung eines Typkontextes]112Sei $t$ eine beliebige freie Variable, $\tau = \tau(t)$ ein beliebiger Typ113$\sigma$ eine Menge von Typsubstitutionen und $\Gamma$ ein Typkontext.114115$(\sigma, \tau)$ heißt eine Lösung für $(\Gamma, t)$, falls gilt:116\[\sigma \Gamma \vdash t : \tau\]117\end{definition}118119\begin{beispiel}[Typisierungsregel]\xindex{Typisierungsregel}%120Das Folgende nennt man eine Typisierungsregel:\footnote{Klausur WS 2010 / 2011}121\[\frac{\Gamma \vdash b: \text{\texttt{bool}}\;\;\; \Gamma \vdash x: \tau \;\;\; \Gamma \vdash y: \tau }{\Gamma \vdash \text{\textbf{if} b \textbf{then} x \textbf{else} y} : \tau}\]122\end{beispiel}123124\section{Constraint-Mengen}125Die Konstraint-Mengen ergeben sich direkt aus den Typisierungsregeln:126127\begin{align*}128\CONST:&\text{z.~B.} \CONST \frac{2 \in \text{Const}}{\Gamma \vdash 2 : \alpha_5} \text{ ergibt } \alpha_5 = \text{\texttt{int}}\\129&\\130\VAR: &\\131&\\132\ABS: &\frac{\alpha_2 \vdash \alpha_3}{\alpha_1} \text{ ergibt } \alpha_1 = \alpha_2 \rightarrow \alpha_3\\133&\\134\APP: &\frac{\vdash \alpha_2 \;\;\; \vdash \alpha_3}{\alpha_1} \text{ ergibt } \alpha_2 = \alpha_3 \rightarrow \alpha_1\\135\end{align*}136137\section{Let-Polymorphismus}\xindex{let-Polymorphismus}\footnote{WS 2013 / 2014, Folie 205ff}%138Das Programm $P = \text{let } f = \lambda x.\ 2 \text{ in } f\ (f\ \text{\texttt{true}})$139ist eine polymorphe Hilfsfunktion, da sie beliebige Werte auf 2 Abbildet.140Auch solche Ausdrücke sollen typisierbar sein.141142Die Kodierung143\[\text{let } x = t_1 \text{ in } t_2\]144ist bedeutungsgleich mit145\[(\lambda x.\ t_2) t_1\]146147Das Problem ist, dass148\[P = \lambda f. \ f (f\ \text{\texttt{true}})\ (\lambda x.\ 2)\]149so nicht typisierbar ist, da in150\[\ABS \frac{f: \tau_f \vdash f\ (f\ \text{\texttt{true}}): \dots}{\vdash \lambda f.\ f\ (f\ \text{\texttt{true}}): \dots}\]151müsste152\[\tau_f = \text{bool} \rightarrow \text{int}\]153und zugleich154\[\tau_f = \text{int} \rightarrow \text{int}\]155in den Typkontext eingetragen werden. Dies ist jedoch nicht möglich. Stattdessen156wird157\[\text{let} x = t_1 \text{ in } t_2\]158als neues Konstrukt im $\lambda$-Kalkül erlaubt.159160Der Term161\[\text{let } x = t_1 \text{ in } t_2\]162ist bedeutungsgleich zu163\[\lambda x.\ (t_2)\ t_1\]164165\begin{definition}[Typschema]\xindex{Typschema}%166Ein Typ der Gestalt $\forall \alpha_1.\ \forall \alpha_2.\ \dots\ \forall \alpha_n. \tau$167heißt \textbf{Typschema}. Es bindet freie Variablen $\alpha_1, \dots, \alpha_n$168in $\tau$.169\end{definition}170171\begin{beispiel}[Typschema]172Das Typschema $\forall \alpha.\ \alpha \rightarrow \alpha$ steht für unendlich173viele Typen und insbesondere für folgende:174\begin{bspenum}175\item int $\rightarrow$ int, bool $\rightarrow$ bool, \dots176\item (int $\rightarrow$ int) $\rightarrow$ (int $\rightarrow$ int), \dots177\item \dots178\end{bspenum}179\end{beispiel}180181\begin{definition}[Typschemainstanziierung]\xindex{Typschemainstanziierung}%182Sei $\tau_2$ ein Nicht-Schema-Typ. Dann heißt der Typ183\[\tau[\alpha \mapsto \tau_2]\]184eine \textbf{Instanziierung} vom Typschema $\forall \alpha.\ \tau$185und man schreibt:186\[(\forall \alpha.\ \tau) \succeq \tau [\alpha \mapsto \tau_2]\]187\end{definition}188189\begin{beispiel}[Typschemainstanziierung]190Folgendes sind Beispiele für Typschemainstanziierungen:191\begin{bspenum}192\item $\forall \alpha.\ \alpha \rightarrow \alpha \succeq \text{int} \rightarrow \text{int}$193\item $\forall \alpha.\ \alpha \rightarrow \alpha \succeq (\text{int} \rightarrow \text{int}) \rightarrow (\text{int} \rightarrow \text{int})$194\item $\text{int} \succeq \text{int}$195\end{bspenum}196197Folgendes sind keine Typschemainstanziierungen:198\begin{bspenum}199\item $\alpha \rightarrow \alpha \nsucceq \text{int} \rightarrow \text{int}$200\item $\alpha \nsucceq \text{bool}$201\item $\forall \alpha.\ \alpha \rightarrow \alpha \nsucceq \text{bool}$202\end{bspenum}203\end{beispiel}204205Zu Typschemata gibt es angepasste Regeln:\xindex{Typregel!mit Typabstraktionen}%206207\[\VAR \frac{\Gamma(x)= \tau' \;\;\; \tau' \succeq \tau}{\gamma \vdash x: \tau}\]208209und210211\[\ABS \frac{\Gamma, x: \tau_1 \vdash t: \tau_2 \;\;\; \tau_1 \text{ kein Typschema}}{\Gamma \vdash \lambda x. t: \tau_1 \rightarrow \tau_2}\]212213\todo[inline]{Folie 208ff}214215\section{Beispiele}216Im Folgenden wird die Typinferenz für einige $\lambda$-Funktionen durchgeführt.217218\subsection[$\lambda x.\ \lambda y.\ x\ y$]{$\lambda x.\ \lambda y.\ x\ y$\footnote{Lösung von Übungsblatt 6, WS 2013 / 2014}}219Gesucht ist ein Typ $\tau$, sodass sich $\vdash \lambda x.\ \lambda y.\ x\ y: \tau$220mit einem Ableitungsbaum nachweisen lässt. Es gibt mehrere solche $\tau$, aber221wir suchen das allgemeinste. Die Regeln unseres Typsystems (siehe \cpageref{def:typsystem-t1})222sind \textit{syntaxgerichtet}, d.~h. zu jedem $\lambda$-(Teil)-Term gibt es genau223eine passende Regel.224225Für $\lambda x.\ \lambda y.\ x\ y$ wissen wir also schon, dass jeder Ableitungsbaum\xindex{Ableitungsbaum}226von folgender Gestalt ist. Dabei sind $\alpha_i$ Platzhalter:227228\[\ABS \frac{\ABS\frac{\textstyle\APP \frac{\textstyle\VAR \frac{(x: \alpha_2, y: \alpha_4)\ (x) = \alpha_6}{x: \alpha_2, y: \alpha_4 \vdash x: \alpha_6}\ \ \VAR \frac{(x:\alpha_2, y: \alpha_4)\ (y) = \alpha_7}{x: \alpha_2, y: \alpha_4 \vdash y : \alpha_7}}{\textstyle x: \alpha_2, y: \alpha_4 \vdash x\ y: \alpha_5}}{x:\alpha_2 \vdash \lambda y.\ x\ y\ :\ \alpha_3}}{\vdash \lambda x.\ \lambda \ y.\ x\ y: \alpha_1}\]229230Das was wir haben wollen steht am Ende, also unter dem unterstem Schlussstrich.231Dann bedeutet die letzte Zeile232\[\vdash \lambda x.\ \lambda \ y.\ x\ y: \alpha_1\]233234Ohne (weitere) Voraussetzungen lässt sich sagen, dass der Term235\[\lambda x.\ \lambda \ y.\ x\ y\]236vom Typ $\alpha_1$ ist.237238Links der Schlussstriche steht jeweils die Regel, die wir anwenden. Also entweder239$\ABS$, $\VAR$, $\CONST$ oder $\APP$.240241Nun gehen wir eine Zeile höher:242243\[x:\alpha_2 \vdash \lambda y.\ x\ y\ :\ \alpha_3\]244245Diese Zeile ist so zu lesen: Mit der Voraussetzung, dass $x$ vom Typ $\alpha_2$246ist, lässt sich syntaktisch Folgern, dass der Term $\lambda y.\ x\ y$ vom247Typ $\alpha_3$ ist.248249\underline{Hinweis:} Alles was in Zeile $i$ dem $\vdash$ steht, steht auch in250jedem \enquote{Nenner} in Zeile $j < i$ vor jedem einzelnen $\vdash$.251252Folgende Typgleichungen $C$ lassen sich aus dem Ableitungsbaum ablesen:253254\begin{align*}255C &= \Set{\alpha_1 = \alpha_2 \rightarrow \alpha_3}\\256&\cup \Set{\alpha_3 = \alpha_4 \rightarrow \alpha_5}\\257&\cup \Set{\alpha_6 = \alpha_7 \rightarrow \alpha_5}\\258&\cup \Set{\alpha_6 = \alpha_2}\\259&\cup \Set{\alpha_7 = \alpha_4}260\end{align*}261262Diese Bedingungen (engl. \textit{Constraints})\xindex{Constraints} haben eine263allgemeinste Lösung mit einem allgemeinsten Unifikator $\sigma_C$:264265\begin{align*}266\sigma_C = [&\alpha_1 \Parr (\alpha_4 \rightarrow \alpha_5) \rightarrow \alpha_4 \rightarrow \alpha_5,\\267&\alpha_2 \Parr \alpha_4 \rightarrow \alpha_5,\\268&\alpha_3 \Parr \alpha_4 \rightarrow \alpha_5,\\269&\alpha_6 \Parr \alpha_4 \rightarrow \alpha_5,\\270&\alpha_7 \Parr \alpha_4]271\end{align*}272273\underline{Hinweis:} Es gilt $(\alpha_4 \rightarrow \alpha_5) \rightarrow \alpha_4 \rightarrow \alpha_5 = (\alpha_4 \rightarrow \alpha_5) \rightarrow (\alpha_4 \rightarrow \alpha_5)$274275Also gilt: Der allgemeinste Typ von $\lambda x.\ \lambda y.\ x\ y$ ist $\sigma_C (\alpha_1) = (\alpha_4 \rightarrow \alpha_5) \rightarrow \alpha_4 \rightarrow \alpha_5$.276277\subsection[Selbstapplikation]{Selbstapplikation\footnote{Lösung von Übungsblatt 6, WS 2013 / 2014}}\xindex{Selbstapplikation}278Im Folgenden wird eine Typinferenz für die Selbstapplikation, also279\[\lambda x.\ x\ x\]280durchgeführt.281282Zuerst erstellt man den Ableitungsbaum:283284\[\ABS\frac{\APP \frac{\VAR \frac{(x:\alpha_2)\ (x) = \alpha_5}{x:\alpha_2 \vdash x: \alpha_5} \;\;\; \VAR \frac{(x:\alpha_2)\ (x) = \alpha_4}{x:\alpha_2 \vdash x:\alpha_4}}{x: \alpha_2 \vdash x\ x\ :\ \alpha_3}}{\vdash \lambda x.\ x\ x: \alpha_1}\]285286Dies ergibt die Constraint-Menge287\begin{align}288C&= \Set{\alpha_1 = \alpha_2 \rightarrow \alpha_3} &\text{$\ABS$-Regel}\label{eq:bsp2.c1}\\289&\cup \Set{\alpha_5 = \alpha_4 \rightarrow \alpha_3} &\text{$\APP$-Regel}\label{eq:bsp2.c2}\\290&\cup \Set{\alpha_5 = \alpha_2} &\text{Linke $\VAR$-Regel}\label{eq:bsp2.c3}\\291&\cup \Set{\alpha_4 = \alpha_2} &\text{Rechte $\VAR$-Regel}\label{eq:bsp2.c4}292\end{align}293294Aus \cref{eq:bsp2.c3} und \cref{eq:bsp2.c4} folgt:295\[\alpha_2 = \alpha_4 = \alpha_5\]296297Also lässt sich \cref{eq:bsp2.c2} umformulieren:298\[\alpha_2 = \alpha_2 \rightarrow \alpha_3\]299300Offensichtlich ist diese Bedingung nicht erfüllbar. Daher ist ist die Selbstapplikation301nicht typisierbar. Dies würde im Unifikationsalgorithmus302(vgl. \cref{alg:klassischer-unifikationsalgorithmus})303durch den \textit{occur check} festgestellt werden.304305