Lambda.tex 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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{Reduktionen|(}
  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]
  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]
  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]
  66. Zwei Terme $\lambda x. f~x$ und $f$ heißen $\eta$-Äquivalent, wenn
  67. $x$ nicht freie Variable von $f$ ist.
  68. \end{definition}
  69. \begin{beispiel}[$\eta$-Äquivalenz]
  70. TODO
  71. \end{beispiel}
  72. \index{Reduktionen|)}
  73. \section{Auswertungsstrategien}
  74. \begin{definition}[Normalenreihenfolge]\xindex{Normalenreihenfolge}%
  75. In der Normalenreihenfolge-Auswertungsstrategie wird der linkeste äußerste
  76. Redex ausgewertet.
  77. \end{definition}
  78. \begin{definition}[Call-By-Name]\xindex{Call-By-Name}%
  79. In der Call-By-Name Auswertungsreihenfolge wird der linkeste äußerste Redex
  80. reduziert, der nicht von einem $\lambda$ umgeben ist.
  81. \end{definition}
  82. Die Call-By-Name Auswertung wird in Funktionen verwendet.
  83. Haskell verwendet die Call-By-Name Auswertungsreihenfolge zusammen mit \enquote{sharing}. Dies nennt man Lazy Evaluation.
  84. \todo[inline]{Was ist sharing?}
  85. \begin{definition}[Call-By-Value]\xindex{Call-By-Value}%
  86. In der Call-By-Value Auswertung wird der linkeste Redex reduziert, der
  87. nicht von einem $\lambda$ umgeben ist und dessen Argument ein Wert ist.
  88. \end{definition}
  89. Die Call-By-Value Auswertungsreihenfolge wird in C und Java verwendet.
  90. Auch in Haskell werden arithmetische Ausdrücke in der Call-By-Name Auswertungsreihenfolge reduziert.
  91. \section{Church-Zahlen}
  92. Im $\lambda$-Kalkül lässt sich jeder mathematische Ausdruck darstellen, also
  93. insbesondere beispielsweise auch $\lambda x. x+3$. Aber \enquote{$3$} und
  94. \enquote{$+$} ist hier noch nicht das $\lambda$-Kalkül.
  95. Zuerst müssen wir uns also Gedanken machen, wie man natürliche Zahlen $n \in \mdn$
  96. darstellt. Dafür dürfen wir nur Variablen und $\lambda$ verwenden. Eine Möglichkeit
  97. das zu machen sind die sog. \textit{Church-Zahlen}.
  98. Dabei ist die Idee, dass die Zahl angibt wie häufig eine Funktion $f$ auf eine
  99. Variable $z$ angewendet wird. Also:
  100. \begin{itemize}
  101. \item $0 := \lambda f~z. z$
  102. \item $1 := \lambda f~z. f z$
  103. \item $2 := \lambda f~z. f (f z)$
  104. \item $3 := \lambda f~z. f (f (f z))$
  105. \end{itemize}
  106. Auch die gewohnten Operationen lassen sich so darstellen.
  107. \begin{beispiel}[Nachfolger-Operation]
  108. \begin{align*}
  109. \succ :&= \lambda n f z. f (n f z)\\
  110. &= \lambda n. (\lambda f (\lambda z f (n f z)))
  111. \end{align*}
  112. Dabei ist $n$ die Zahl.
  113. Will man diese Funktion anwenden, sieht das wie folgt aus:
  114. \begin{align*}
  115. \succ 1&= (\lambda n f z. f(n f z)) 1\\
  116. &= (\lambda n f z. f(n f z)) \underbrace{(\lambda f~z. f z)}_{n}\\
  117. &= \lambda f z. f (\lambda f~z. f z) f z\\
  118. &= \lambda f z. f (f z)\\
  119. &= 2
  120. \end{align*}
  121. \end{beispiel}
  122. \begin{beispiel}[Vorgänger-Operation]
  123. \begin{align*}
  124. \pair&:= \lambda a. \lambda b. \lambda f. f a b\\
  125. \fst &:= \lambda p. p (\lambda a. \lambda b. a)\\
  126. \snd &:= \lambda p. p (\lambda a. \lambda b. b)\\
  127. \nxt &:= \lambda p. \pair (\snd p)~(\succ (\snd p))\\
  128. \pred&:= \lambda n. \fst (n \nxt (\pair c_0 c_0))
  129. \end{align*}
  130. \end{beispiel}
  131. \begin{beispiel}[Addition]
  132. \begin{align*}
  133. \text{plus} &:= \lambda m n f z. m f (n f z)
  134. \end{align*}
  135. Dabei ist $m$ der erste Summand und $n$ der zweite Summand.
  136. \end{beispiel}
  137. \begin{beispiel}[Multiplikation]
  138. \begin{align*}
  139. \text{times} :&= \lambda m n f. m~s~(n~f~z)\\
  140. &\overset{\eta}{=} \lambda m n f z. n (m s) z
  141. \end{align*}
  142. Dabei ist $m$ der erste Faktor und $n$ der zweite Faktor.
  143. \end{beispiel}
  144. \begin{beispiel}[Potenz]
  145. \begin{align*}
  146. \text{exp} :&= \lambda b e. eb\\
  147. &\overset{\eta}{=} \lambda b e f z. e b f z
  148. \end{align*}
  149. Dabei ist $b$ die Basis und $e$ der Exponent.
  150. \end{beispiel}
  151. \section{Church-Booleans}
  152. \begin{definition}[Church-Booleans]\xindex{Church-Booleans}%
  153. \texttt{True} wird zu $c_{\text{true}} := \lambda t. \lambda f. t$.\\
  154. \texttt{False} wird zu $c_{\text{false}} := \lambda t. \lambda f. f$.
  155. \end{definition}
  156. \section{Weiteres}
  157. \begin{satz}[Satz von Curch-Rosser]
  158. 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.
  159. \end{satz}