Lambda.tex 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. %!TEX root = Programmierparadigmen.tex
  2. \chapter{$\lambda$-Kalkül}
  3. Der $\lambda$-Kalkül (gesprochen: Lambda-Kalkül) ist eine formale Sprache.
  4. In diesem Kalkül gibt es drei Arten von Termen $T$:
  5. \begin{itemize}
  6. \item Variablen: $x$
  7. \item Applikationen: $(T S)$
  8. \item Lambda-Abstraktion: $\lambda x. T$
  9. \end{itemize}
  10. In der Lambda-Abstraktion nennt man den Teil vor dem Punkt die \textit{Parameter}
  11. der $\lambda$-Funktion. Wenn etwas dannach kommt, auf die die Funktion angewendet
  12. wird so heißt dieser Teil das \textit{Argument}:
  13. \[(\lambda \underbrace{x}_{\mathclap{\text{Parameter}}}. x^2) \overbrace{5}^{\mathclap{\text{Argument}}} = 5^2\]
  14. \begin{beispiel}[$\lambda$-Funktionen]
  15. \begin{bspenum}
  16. \item $\lambda x. x$ heißt Identität.
  17. \item $(\lambda x. x^2)(\lambda y. y + 3) = \lambda y. (y+3)^2$
  18. \item \label{bsp:lambda-3} $\begin{aligned}[t]
  19. &(\lambda x.\Big (\lambda y.yx \Big ))~ab\\
  20. \Rightarrow&(\lambda y.ya)b\\
  21. \Rightarrow&ba
  22. \end{aligned}$
  23. \end{bspenum}
  24. In \cref{bsp:lambda-3} sieht man, dass $\lambda$-Funktionen die Argumente
  25. von Links nach rechts einziehen.
  26. \end{beispiel}
  27. Die Funktionsapplikation sei linksassoziativ. Es gilt also:
  28. \[a~b~c~d = ((a~b)~c)~d\]
  29. \begin{definition}[Gebundene Variable]\xindex{Variable!gebundene}%
  30. Eine Variable heißt gebunden, wenn sie der Parameter einer $\lambda$-Funktion ist.
  31. \end{definition}
  32. \begin{definition}[Freie Variable]\xindex{Variable!freie}%
  33. Eine Variable heißt \textit{frei}, wenn sie nicht gebunden ist.
  34. \end{definition}
  35. \begin{satz}
  36. Der untypisierte $\lambda$-Kalkül ist Turing-Äquivalent.
  37. \end{satz}
  38. \section{Reduktionen}\index{Reduktion|(}
  39. \begin{definition}[Redex]\xindex{Redex}%
  40. Eine $\lambda$-Term der Form $(\lambda x. t_1) t_2$ heißt Redex.
  41. \end{definition}
  42. \begin{definition}[$\alpha$-Äquivalenz]\xindex{Reduktion!Alpha ($\alpha$)}\xindex{Äquivalenz!Alpha ($\alpha$)}%
  43. Zwei Terme $T_1, T_2$ heißen $\alpha$-Äquivalent, wenn $T_1$ durch
  44. konsistente Umbenennung in $T_2$ überführt werden kann.
  45. Man schreibt dann: $T_1 \overset{\alpha}{=} T_2$.
  46. \end{definition}
  47. \begin{beispiel}[$\alpha$-Äquivalenz]
  48. \begin{align*}
  49. \lambda x.x &\overset{\alpha}{=} \lambda y. y\\
  50. \lambda x. x x &\overset{\alpha}{=} \lambda y. y y\\
  51. \lambda x. (\lambda y. z (\lambda x. z y) y) &\overset{\alpha}{=}
  52. \lambda a. (\lambda x. z (\lambda c. z x) x)
  53. \end{align*}
  54. \end{beispiel}
  55. \begin{definition}[$\beta$-Äquivalenz]\xindex{Reduktion!Beta ($\beta$)}\xindex{Äquivalenz!Beta ($\beta$)}%
  56. Eine $\beta$-Reduktion ist die Funktionsanwendung auf einen Redex:
  57. \[(\lambda x. t_1)\ t_2 \Rightarrow t_1 [x \mapsto t_2]\]
  58. \end{definition}
  59. \begin{beispiel}[$\beta$-Äquivalenz]
  60. \begin{defenum}
  61. \item $(\lambda x.\ x)\ y \overset{\beta}{\Rightarrow} x[x \mapsto y] = y$
  62. \item $(\lambda x.\ x\ (\lambda x.\ x)) (y\ z) \overset{\beta}{\Rightarrow} (x\ (\lambda x.\ x))[x \mapsto y\ z] (y\ z) (\lambda x.\ x)$
  63. \end{defenum}
  64. \end{beispiel}
  65. \begin{definition}[$\eta$-Äquivalenz\footnote{Folie 158}]\xindex{Reduktion!Eta ($\eta$)}\xindex{Äquivalenz!Eta ($\eta$)}%
  66. Die Terme $\lambda x. f~x$ und $f$ heißen $\eta$-Äquivalent, wenn $x \notin FV(f)$ gilt.
  67. Man schreibt: $\lambda x. f~x \overset{\eta}{=} f$.
  68. \end{definition}
  69. \begin{beispiel}[$\eta$-Äquivalenz\footnote{Folie 158}]%
  70. \begin{align*}
  71. \lambda x.\ \lambda y.\ f\ z\ x\ y &\overset{\eta}{=} \lambda x.\ f\ z\ x\\
  72. f\ z &\overset{\eta}{=} \lambda x.\ f\ z\ x\\
  73. \lambda x.\ x &\overset{\eta}{=} \lambda x.\ (\lambda x.\ x)\ x\\
  74. \lambda x.\ f\ x\ x &\overset{\eta}{\neq} f\ x
  75. \end{align*}
  76. \end{beispiel}
  77. \index{Reduktion|)}
  78. \section{Auswertungsstrategien}
  79. \begin{definition}[Normalenreihenfolge]\xindex{Normalenreihenfolge}%
  80. In der Normalenreihenfolge-Auswertungsstrategie wird der linkeste äußerste
  81. Redex ausgewertet.
  82. \end{definition}
  83. \begin{definition}[Call-By-Name]\xindex{Call-By-Name}%
  84. In der Call-By-Name Auswertungsreihenfolge wird der linkeste äußerste Redex
  85. reduziert, der nicht von einem $\lambda$ umgeben ist.
  86. \end{definition}
  87. Die Call-By-Name Auswertung wird in Funktionen verwendet.
  88. Haskell verwendet die Call-By-Name Auswertungsreihenfolge zusammen mit \enquote{sharing}. Dies nennt man \textit{Lazy Evaluation}. Ein spezialfall der Lazy-Evaluation ist die sog. \textit{Kurzschlussauswertung}.\xindex{Kurzschlussauswertung}\xindex{Short-circuit evaluation}
  89. Das bezeichnet die Lazy-Evaluation von booleschen Ausdrücken.
  90. \todo[inline]{Was ist sharing?}
  91. \begin{definition}[Call-By-Value]\xindex{Call-By-Value}%
  92. In der Call-By-Value Auswertung wird der linkeste Redex reduziert, der
  93. nicht von einem $\lambda$ umgeben ist und dessen Argument ein Wert ist.
  94. \end{definition}
  95. Die Call-By-Value Auswertungsreihenfolge wird in C und Java verwendet.
  96. Auch in Haskell werden arithmetische Ausdrücke in der Call-By-Name Auswertungsreihenfolge reduziert.
  97. \section{Church-Zahlen}
  98. Im $\lambda$-Kalkül lässt sich jeder mathematische Ausdruck darstellen, also
  99. insbesondere beispielsweise auch $\lambda x. x+3$. Aber \enquote{$3$} und
  100. \enquote{$+$} ist hier noch nicht das $\lambda$-Kalkül.
  101. Zuerst müssen wir uns also Gedanken machen, wie man natürliche Zahlen $n \in \mdn$
  102. darstellt. Dafür dürfen wir nur Variablen und $\lambda$ verwenden. Eine Möglichkeit
  103. das zu machen sind die sog. \textit{Church-Zahlen}.
  104. Dabei ist die Idee, dass die Zahl angibt wie häufig eine Funktion $f$ auf eine
  105. Variable $z$ angewendet wird. Also:
  106. \begin{itemize}
  107. \item $0 := \lambda f~z. z$
  108. \item $1 := \lambda f~z. f z$
  109. \item $2 := \lambda f~z. f (f z)$
  110. \item $3 := \lambda f~z. f (f (f z))$
  111. \end{itemize}
  112. Auch die gewohnten Operationen lassen sich so darstellen.
  113. \begin{beispiel}[Nachfolger-Operation]
  114. \begin{align*}
  115. \succ :&= \lambda n f z. f (n f z)\\
  116. &= \lambda n. (\lambda f (\lambda z f (n f z)))
  117. \end{align*}
  118. Dabei ist $n$ die Zahl.
  119. Will man diese Funktion anwenden, sieht das wie folgt aus:
  120. \begin{align*}
  121. \succ 1&= (\lambda n f z. f(n f z)) 1\\
  122. &= (\lambda n f z. f(n f z)) \underbrace{(\lambda f~z. f z)}_{n}\\
  123. &= \lambda f z. f (\lambda f~z. f z) f z\\
  124. &= \lambda f z. f (f z)\\
  125. &= 2
  126. \end{align*}
  127. \end{beispiel}
  128. \begin{beispiel}[Vorgänger-Operation]
  129. \begin{align*}
  130. \pair&:= \lambda a. \lambda b. \lambda f. f a b\\
  131. \fst &:= \lambda p. p (\lambda a. \lambda b. a)\\
  132. \snd &:= \lambda p. p (\lambda a. \lambda b. b)\\
  133. \nxt &:= \lambda p. \pair (\snd p)~(\succ (\snd p))\\
  134. \pred&:= \lambda n. \fst (n \nxt (\pair c_0 c_0))
  135. \end{align*}
  136. \end{beispiel}
  137. \begin{beispiel}[Addition]
  138. \begin{align*}
  139. \text{plus} &:= \lambda m n f z. m f (n f z)
  140. \end{align*}
  141. Dabei ist $m$ der erste Summand und $n$ der zweite Summand.
  142. \end{beispiel}
  143. \begin{beispiel}[Multiplikation]
  144. \begin{align*}
  145. \text{times} :&= \lambda m n f. m~s~(n~f~z)\\
  146. &\overset{\eta}{=} \lambda m n f z. n (m s) z
  147. \end{align*}
  148. Dabei ist $m$ der erste Faktor und $n$ der zweite Faktor.
  149. \end{beispiel}
  150. \begin{beispiel}[Potenz]
  151. \begin{align*}
  152. \text{exp} :&= \lambda b e. eb\\
  153. &\overset{\eta}{=} \lambda b e f z. e b f z
  154. \end{align*}
  155. Dabei ist $b$ die Basis und $e$ der Exponent.
  156. \end{beispiel}
  157. \section{Church-Booleans}
  158. \begin{definition}[Church-Booleans]\xindex{Church-Booleans}%
  159. \texttt{True} wird zu $c_{\text{true}} := \lambda t. \lambda f. t$.\\
  160. \texttt{False} wird zu $c_{\text{false}} := \lambda t. \lambda f. f$.
  161. \end{definition}
  162. Hiermit lässt sich beispielsweise die Funktion \texttt{is\_zero} definieren, die
  163. \texttt{True} zurückgibt, wenn eine Zahl $0$ repräsentiert und sonst \texttt{False}
  164. zurückgibt:
  165. \[ \text{\texttt{is\_zero}} = \lambda n.\ n\ (\lambda x.\ c_{\text{False}})\ c_{\text{True}}\]
  166. \section{Weiteres}
  167. \begin{satz}[Satz von Curch-Rosser]
  168. Wenn zwei unterschiedliche Terme $a$ und $b$ äquivalent sind, d.h. mit Reduktionsschritten beliebiger Richtung ineinander transformiert werden können, dann gibt es einen weiteren Term $c$, zu dem sowohl $a$ als auch $b$ reduziert werden können.
  169. \end{satz}
  170. \section{Fixpunktkombinator}
  171. \begin{definition}[Fixpunkt]\xindex{Fixpunkt}%
  172. Sei $f: X \rightarrow Y$ eine Funktion mit $\emptyset \neq A = X \cap Y$ und
  173. $a \in A$.
  174. $a$ heißt \textbf{Fixpunkt} der Funktion $f$, wenn $f(a) = a$ gilt.
  175. \end{definition}
  176. \begin{beispiel}[Fixpunkt]
  177. \begin{bspenum}
  178. \item $f_1: \mdr \rightarrow \mdr; f(x) = x^2 \Rightarrow x_1 = 0$ ist
  179. Fixpunkt von $f$, da $f(0) = 0$. $x_2 = 1$ ist der einzige weitere
  180. Fixpunkt dieser Funktion.
  181. \item $f_2: \mdn \rightarrow \mdn$ hat ganz $\mdn$ als Fixpunkte, also
  182. insbesondere unendlich viele Fixpunkte.
  183. \item $f_3: \mdr \rightarrow \mdr; f(x) = x+1$ hat keinen einzigen Fixpunkt.
  184. \item $f_4: \mdr[X] \rightarrow \mdr[X]; f(p) = p^2$ hat $p_1(x) = 0$ und
  185. $p_2(x)=1$ als Fixpunkte.
  186. \end{bspenum}
  187. \end{beispiel}
  188. \begin{definition}[Kombinator]\xindex{Kombinator}%
  189. Ein Kombinator ist eine Abbildung ohne freie Variablen.
  190. \end{definition}
  191. \begin{beispiel}[Kombinatoren\footnotemark]%
  192. \begin{bspenum}
  193. \item $\lambda a.\ a$
  194. \item $\lambda a.\ \lambda b.\ a$
  195. \item $\lambda f.\ \lambda a.\ \lambda b. f\ b\ a$
  196. \end{bspenum}
  197. \end{beispiel}
  198. \footnotetext{Quelle: \url{http://www.haskell.org/haskellwiki/Combinator}}
  199. \begin{definition}[Fixpunkt-Kombinator]\xindex{Fixpunkt-Kombinator}%
  200. Sei $f$ ein Kombinator, der $f\ g = g\ (f\ g)$ erfüllt. Dann heißt $f$
  201. \textbf{Fixpunktkombinator}.
  202. \end{definition}
  203. Insbesondere ist also $f \ g$ ein Fixpunkt von $g$.
  204. \begin{definition}[Y-Kombinator]\xindex{Y-Kombinator}%
  205. Der Fixpunktkombinator
  206. \[Y := \lambda f.\ (\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x))\]
  207. heißt $Y$-Kombinator.
  208. \end{definition}
  209. \begin{behauptung}
  210. Der $Y$-Kombinator ist ein Fixpunktkombinator.
  211. \end{behauptung}
  212. \begin{beweis}\footnote{Quelle: Vorlesung WS 2013/2014, Folie 175}\leavevmode
  213. \textbf{Teil 1:} Offensichtlich ist $Y$ ein Kombinator.
  214. \textbf{Teil 2:} z.~Z.: $Y f \Rightarrow^* f \ (Y \ f)$
  215. \begin{align*}
  216. Y\ f &=\hphantom{^\beta f\ } (\lambda f.\ (\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x)))\ f\\
  217. &\Rightarrow^\beta\hphantom{f \ (\lambda f.\ } (\lambda x. f\ (x\ x))\ (\lambda x.\ f\ (x\ x))\\
  218. &\Rightarrow^\beta f \ (\hphantom{\lambda f.\ }(\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x)))\\
  219. &\Rightarrow^\beta f \ (\lambda f.\ (\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x))\ f)\\
  220. &=\hphantom{^\beta} f \ (Y \ f)
  221. \end{align*}
  222. $\qed$
  223. \end{beweis}
  224. \begin{definition}[Turingkombinator]\xindex{Turingkombinator}%
  225. Der Fixpunktkombinator
  226. \[\Theta := (\lambda x. \lambda y. y\ (x\ x\ y)) (\lambda x.\ \lambda y.\ y\ (x\ x\ y))\]
  227. heißt \textbf{Turingkombinator}.
  228. \end{definition}
  229. \begin{behauptung}
  230. Der Turing-Kombinator $\Theta$ ist ein Fixpunktkombinator.
  231. \end{behauptung}
  232. \begin{beweis}\footnote{Quelle: Übungsblatt 6, WS 2013/2014}
  233. \textbf{Teil 1:} Offensichtlich ist $\Theta$ ein Kombinator.
  234. \textbf{Teil 2:} z.~Z.: $\Theta f \Rightarrow^* f \ (\Theta \ f)$
  235. Sei $\Theta_0 := (\lambda x.\ \lambda y.\ y\ (x\ x\ y))$. Dann gilt:
  236. \begin{align*}
  237. \Theta\ f &= ((\lambda x.\ \lambda y.\ y\ (x\ x\ y))\ \Theta_0)\ f\\
  238. &\Rightarrow^\beta (\lambda y. y\ (\Theta_0 \ \Theta_0 \ y))\ f\\
  239. &\Rightarrow^\beta f \ (\Theta_0 \Theta_0 f)\\
  240. &= f \ (\Theta \ f)
  241. \end{align*}
  242. $\qed$
  243. \end{beweis}
  244. \section{Let-Polymorphismus}\xindex{let-Polymorphismus}\footnote{WS 2013 / 2014, Folie 205ff}%
  245. Das Programm $P = \text{let } f = \lambda x.\ 2 \text{ in } f\ (f\ \text{\texttt{true}})$
  246. ist eine polymorphe Hilfsfunktion, da sie beliebige Werte auf 2 Abbildet.
  247. Auch solche Ausdrücke sollen typisierbar sein.
  248. Die Kodierung
  249. \[\text{let} x = t_1 \text{ in } t_2\]
  250. ist bedeutungsgleich mit
  251. \[(\lambda x.\ t_2) t_1\]
  252. Das Problem ist, dass
  253. \[P = \lambda f. \ f (f\ \text{\texttt{true}})\ (\lambda x.\ 2)\]
  254. so nicht typisierbar ist, da in
  255. \[\ABS \frac{f: \tau_f \vdash f\ (f\ \text{\texttt{true}}): \dots}{\vdash \lambda f.\ f\ (f\ \text{\texttt{true}}): \dots}\]
  256. müsste
  257. \[\tau_f = \text{bool} \rightarrow \text{int}\]
  258. und zugleich
  259. \[\tau_f = \text{int} \rightarrow \text{int}\]
  260. in den Typkontext eingetragen werden. Dies ist jedoch nicht möglich. Stattdessen
  261. wird
  262. \[\text{let} x = t_1 \text{ in } t_2\]
  263. als neues Konstrukt im $\lambda$-Kalkül erlaubt.
  264. \begin{definition}[Typschema]\xindex{Typschema}%
  265. Ein Typ der Gestalt $\forall \alpha_1.\ \forall \alpha_2.\ \dots\ \forall \alpha_n. \tau$
  266. heißt \textbf{Typschema}. Es bindet freie Variablen $\alpha_1, \dots, \alpha_n$
  267. in $\tau$.
  268. \end{definition}
  269. \begin{beispiel}[Typschema]
  270. Das Typschema $\forall \alpha.\ \alpha \rightarrow \alpha$ steht für unendlich
  271. viele Typen und insbesondere für folgende:
  272. \begin{bspenum}
  273. \item int $\rightarrow$ int, bool $\rightarrow$ bool, \dots
  274. \item (int $\rightarrow$ int) $\rightarrow$ (int $\rightarrow$ int), \dots
  275. \item \dots
  276. \end{bspenum}
  277. \end{beispiel}
  278. \begin{definition}[Typschemainstanziierung]\xindex{Typschemainstanziierung}%
  279. Sei $\tau_2$ ein Nicht-Schema-Typ. Dann heißt der Typ
  280. \[\tau[\alpha \mapsto \tau_2]\]
  281. eine \textbf{Instanziierung} vom Typschema $\forall \alpha.\ \tau$
  282. und man schreibt:
  283. \[(\forall \alpha.\ \tau) \succeq \tau [\alpha \mapsto \tau_2]\]
  284. \end{definition}
  285. \begin{beispiel}[Typschemainstanziierung]
  286. Folgendes sind Beispiele für Typschemainstanziierungen:
  287. \begin{bspenum}
  288. \item $\forall \alpha.\ \alpha \rightarrow \alpha \succeq \text{int} \rightarrow \text{int}$
  289. \item $\forall \alpha.\ \alpha \rightarrow \alpha \succeq (\text{int} \rightarrow \text{int}) \rightarrow (\text{int} \rightarrow \text{int})$
  290. \item $\text{int} \succeq \text{int}$
  291. \end{bspenum}
  292. Folgendes sind keine Typschemainstanziierungen:
  293. \begin{bspenum}
  294. \item $\alpha \rightarrow \alpha \nsucceq \text{int} \rightarrow \text{int}$
  295. \item $\alpha \nsucceq \text{bool}$
  296. \item $\forall \alpha.\ \alpha \rightarrow \alpha \nsucceq \text{bool}$
  297. \end{bspenum}
  298. \end{beispiel}
  299. Zu Typschemata gibt es angepasste Regeln:
  300. \[\VAR \frac{\Gamma(x)= \tau' \;\;\; \tau' \succeq \tau}{\gamma \vdash x: \tau}\]
  301. und
  302. \[\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}\]
  303. \todo[inline]{Folie 208ff}
  304. \section{Literatur}
  305. \begin{itemize}
  306. \item \url{http://c2.com/cgi/wiki?FreeVariable}
  307. \item \url{http://www.lambda-bound.com/book/lambdacalc/node9.html}
  308. \end{itemize}