Skip to content

Commit

Permalink
Church-Zahlen / Lambda-Kalkuel
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinThoma committed Mar 7, 2014
1 parent 6fc7360 commit 575de5f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 31 deletions.
Binary file modified documents/Programmierparadigmen/Programmierparadigmen.pdf
Binary file not shown.
138 changes: 107 additions & 31 deletions documents/Programmierparadigmen/lambda.tex
Original file line number Diff line number Diff line change
@@ -1,87 +1,163 @@
%!TEX root = Programmierparadigmen.tex
\chapter{$\lambda$-Kalkül}
Der Lambda-Kalkül ist eine formale Sprache.
Der $\lambda$-Kalkül (gesprochen: Lambda-Kalkül) ist eine formale Sprache.
In diesem Kalkül gibt es drei Arten von Termen $T$:

\begin{itemize}
\item Variablen: $x$
\item Applikationen: $(T T)$
\item Lambda: $\lambda x. T$
\item Variablen: $x$
\item Applikationen: $(T S)$
\item Lambda-Abstraktion: $\lambda x. T$
\end{itemize}

Es ist zu beachten, dass Funktionsapplikation linksassoziativ ist. Es gilt also:
In der Lambda-Abstraktion nennt man den Teil vor dem Punkt die \textit{Parameter}
der $\lambda$-Funktion. Wenn etwas dannach kommt, auf die die Funktion angewendet
wird so heißt dieser Teil das \textit{Argument}:

\[(\lambda \underbrace{x}_{\mathclap{\text{Parameter}}}. x^2) \overbrace{5}^{\mathclap{\text{Argument}}} = 5^2\]

\begin{beispiel}[$\lambda$-Funktionen]
\begin{bspenum}
\item $\lambda x. x$ heißt Identität.
\item $(\lambda x. x^2)(\lambda y. y + 3) = \lambda y. (y+3)^2$
\item \label{bsp:lambda-3} $\begin{aligned}[t]
&(\lambda x.\Big (\lambda y.yx \Big ))~ab\\
\Rightarrow&(\lambda y.ya)b\\
\Rightarrow&ba
\end{aligned}$
\end{bspenum}

In \cref{bsp:lambda-3} sieht man, dass $\lambda$-Funktionen die Argumente
von Links nach rechts einziehen.
\end{beispiel}

Die Funktionsapplikation sei linksassoziativ. Es gilt also:

\[a~b~c~d = ((a~b)~c)~d\]

\begin{definition}[Freie Variable]
TODO
\begin{definition}[Gebundene Variable]\xindex{Variable!gebundene}%
Eine Variable heißt gebunden, wenn sie der Parameter einer $\lambda$-Funktion ist.
\end{definition}

\begin{definition}[Gebundene Variable]
Eine Variable heißt gebunden, wenn sie nicht frei ist.
\begin{definition}[Freie Variable]\xindex{Variable!freie}%
Eine Variable heißt \textit{frei}, wenn sie nicht gebunden ist.
\end{definition}

\begin{satz}
Der untypisierte $\lambda$-Kalkül ist Turing-Äquivalent.
\end{satz}

\section{Reduktionen}
\begin{definition}[$\alpha$-Äquivalenz]
Zwei Terme $T_1, T_2$ heißen $\alpha$-Äquivalent, wenn $T_1$ durch
konsistente Umbenennung in $T_2$ überführt werden kann.
Zwei Terme $T_1, T_2$ heißen $\alpha$-Äquivalent, wenn $T_1$ durch
konsistente Umbenennung in $T_2$ überführt werden kann.

Man schreibt dann: $T_1 \overset{\alpha}{=} T_2$.
Man schreibt dann: $T_1 \overset{\alpha}{=} T_2$.
\end{definition}

\begin{beispiel}[$\alpha$-Äquivalenz]
\begin{align*}
\lambda x.x &\overset{\alpha}{=} \lambda y. y\\
\lambda x. x x &\overset{\alpha}{=} \lambda y. y y\\
\lambda x. (\lambda y. z (\lambda x. z y) y) &\overset{\alpha}{=}
\lambda a. (\lambda x. z (\lambda c. z x) x)
\end{align*}
\begin{align*}
\lambda x.x &\overset{\alpha}{=} \lambda y. y\\
\lambda x. x x &\overset{\alpha}{=} \lambda y. y y\\
\lambda x. (\lambda y. z (\lambda x. z y) y) &\overset{\alpha}{=}
\lambda a. (\lambda x. z (\lambda c. z x) x)
\end{align*}
\end{beispiel}

\begin{definition}[$\beta$-Äquivalenz]
TODO
TODO
\end{definition}

\begin{beispiel}[$\beta$-Äquivalenz]
TODO
TODO
\end{beispiel}

\begin{definition}[$\eta$-Äquivalenz]
Zwei Terme $\lambda x. f~x$ und $f$ heißen $\eta$-Äquivalent, wenn
$x$ nicht freie Variable von $f$ ist.
Zwei Terme $\lambda x. f~x$ und $f$ heißen $\eta$-Äquivalent, wenn
$x$ nicht freie Variable von $f$ ist.
\end{definition}

\begin{beispiel}[$\eta$-Äquivalenz]
TODO
TODO
\end{beispiel}

\section{Auswertungsstrategien}
\begin{definition}[Normalenreihenfolge]\xindex{Normalenreihenfolge}%
In der Normalenreihenfolge-Auswertungsstrategie wird der linkeste äußerste
Redex ausgewertet.
In der Normalenreihenfolge-Auswertungsstrategie wird der linkeste äußerste
Redex ausgewertet.
\end{definition}

\begin{definition}[Call-By-Name]\xindex{Call-By-Name}%
In der Call-By-Name Auswertungsreihenfolge wird der linkeste äußerste Redex
reduziert, der nicht von einem $\lambda$ umgeben ist.
In der Call-By-Name Auswertungsreihenfolge wird der linkeste äußerste Redex
reduziert, der nicht von einem $\lambda$ umgeben ist.
\end{definition}

Die Call-By-Name Auswertung wird in Funktionen verwendet.

\begin{definition}[Call-By-Value]\xindex{Call-By-Value}%
In der Call-By-Value Auswertung wird der linkeste Redex reduziert, der
nicht von einem $\lambda$ umgeben ist und dessen Argument ein Wert ist.
In der Call-By-Value Auswertung wird der linkeste Redex reduziert, der
nicht von einem $\lambda$ umgeben ist und dessen Argument ein Wert ist.
\end{definition}

Die Call-By-Value Auswertungsreihenfolge wird in C und Java verwendet.
Auch in Haskell werden arithmetische Ausdrücke in der Call-By-Name Auswertungsreihenfolge
reduziert.

\section{Church-Zahlen}
TODO
Im $\lambda$-Kalkül lässt sich jeder mathematische Ausdruck darstellen, also
insbesondere beispielsweise auch $\lambda x. x+3$. Aber \enquote{$3$} und
\enquote{$+$} ist hier noch nicht das $\lambda$-Kalkül.

Zuerst müssen wir uns also Gedanken machen, wie man natürliche Zahlen $n \in \mdn$
darstellt. Dafür dürfen wir nur Variablen und $\lambda$ verwenden. Eine Möglichkeit
das zu machen sind die sog. \textit{Church-Zahlen}.

Dabei ist die Idee, dass die Zahl angibt wie häufig eine Funktion $f$ auf eine
Variable $x$ angewendet wird. Also:
\begin{itemize}
\item $0 := \lambda f~x. x$
\item $1 := \lambda f~x. f x$
\item $2 := \lambda f~x. f (f x)$
\item $3 := \lambda f~x. f (f (f x))$
\end{itemize}

Auch die gewohnten Operationen lassen sich so darstellen.

\begin{beispiel}[Nachfolger-Operation]
\begin{align*}
\succ :&= \lambda n f z. f (n f x)\\
&= \lambda n. (\lambda f (\lambda x f (n f x)))
\end{align*}
Dabei ist $n$ die Zahl.

Will man diese Funktion anwenden, sieht das wie folgt aus:
\begin{align*}
\succ 1 &= (\lambda n f x. f(n f x)) 1\\
&= (\lambda n f x. f(n f x)) \underbrace{(\lambda f~x. f x)}_{n}\\
&= \lambda f x. f (\lambda f~x. f x) f x\\
&= \lambda f x. f (f x)\\
&= 2
\end{align*}
\end{beispiel}

\begin{beispiel}[Addition]
\begin{align*}
\text{+} : &= \lambda m n f x. m f (n f x)
\end{align*}
Dabei ist $m$ der erste Summand und $n$ der zweite Summand.
\end{beispiel}

\begin{beispiel}[Multiplikation]
%\[\text{\cdot} := \lambda m n.m(n f) \]
Dabei ist $m$ der erste Faktor und $n$ der zweite Faktor.
\end{beispiel}

\begin{beispiel}[Potenz]
%\[\text{\cdot} := \text{TODO}\]
Dabei ist $b$ die Basis und $e$ der Exponent.
\end{beispiel}

\section{Weiteres}

\begin{satz}[Satz von Curch-Rosser]
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.
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.
\end{satz}
2 changes: 2 additions & 0 deletions documents/Programmierparadigmen/shortcuts.sty
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
\DeclareMathOperator{\IWS}{IWS}
\DeclareMathOperator{\SLL}{SLL}
\DeclareMathOperator{\Bild}{Bild}
\let\succ\relax% Set equal to \relax so that LaTeX thinks it's not defined
\DeclareMathOperator{\succ}{succ}
\newcommand{\iu}{{i\mkern1mu}} % imaginary unit
%\DeclareMathOperator{\Re}{Re}
%\DeclareMathOperator{\Im}{Im}
Expand Down

0 comments on commit 575de5f

Please sign in to comment.