Kaynağa Gözat

Fixpunktkombinatoren; Haskell-Beispiele

Martin Thoma 11 yıl önce
ebeveyn
işleme
0174aa0cc6

+ 9 - 0
documents/Programmierparadigmen/Haskell.tex

@@ -209,6 +209,11 @@ sich das ganze sogar noch kürzer schreiben:
 \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-zip.hs]{haskell}{scripts/haskell/fibonacci-zip.hs}
 \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-pattern-matching.hs]{haskell}{scripts/haskell/fibonacci-pattern-matching.hs}
 
+Die unendliche Liste alle Fibonacci-Zahlen, also der Fibonacci-\textit{Stream}\xindex{Stream}
+wird wie folgt erzeugt:
+
+\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-stream.hs]{haskell}{scripts/haskell/fibonacci-stream.hs}
+
 \subsection{Polynome}\xindex{Polynome}\xindex{zipWith}\xindex{foldr}\xindex{tail}%
 \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=polynome.hs]{haskell}{scripts/haskell/polynome.hs}
 
@@ -222,6 +227,10 @@ sich das ganze sogar noch kürzer schreiben:
 
 \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=lauflaengencodierung.hs]{haskell}{scripts/haskell/lauflaengencodierung.hs}
 
+\subsection{Intersections}\xindex{Intersections}%
+
+\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=Intersect.hs]{haskell}{scripts/haskell/Intersect.hs}
+
 \subsection{Funktionen höherer Ordnung}\xindex{Folds}\xindex{foldl}\xindex{foldr}\label{bsp:foldl-und-foldr}
 \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=folds.hs]{haskell}{scripts/haskell/folds.hs}
 

+ 103 - 6
documents/Programmierparadigmen/Lambda.tex

@@ -46,12 +46,12 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
     Der untypisierte $\lambda$-Kalkül ist Turing-Äquivalent.
 \end{satz}
 
-\section{Reduktionen}\index{Reduktionen|(}
+\section{Reduktionen}\index{Reduktion|(}
 \begin{definition}[Redex]\xindex{Redex}%
     Eine $\lambda$-Term der Form $(\lambda x. t_1) t_2$ heißt Redex.
 \end{definition}
 
-\begin{definition}[$\alpha$-Äquivalenz]
+\begin{definition}[$\alpha$-Äquivalenz]\xindex{Reduktion!Alpha ($\alpha$)}\xindex{Äquivalenz!Alpha ($\alpha$)}%
     Zwei Terme $T_1, T_2$ heißen $\alpha$-Äquivalent, wenn $T_1$ durch 
     konsistente Umbenennung in $T_2$ überführt werden kann.
 
@@ -67,7 +67,7 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
     \end{align*}
 \end{beispiel}
 
-\begin{definition}[$\beta$-Äquivalenz]
+\begin{definition}[$\beta$-Äquivalenz]\xindex{Reduktion!Beta ($\beta$)}\xindex{Äquivalenz!Beta ($\beta$)}%
     Eine $\beta$-Reduktion ist die Funktionsanwendung auf einen Redex:
     \[(\lambda x. t_1) t_2 \Rightarrow t_1 [x \mapsto t_2]\]
 \end{definition}
@@ -79,7 +79,7 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
     \end{defenum}
 \end{beispiel}
 
-\begin{definition}[$\eta$-Äquivalenz]
+\begin{definition}[$\eta$-Äquivalenz]\xindex{Reduktion!Eta ($\eta$)}\xindex{Äquivalenz!Eta ($\eta$)}%
     Zwei Terme $\lambda x. f~x$ und $f$ heißen $\eta$-Äquivalent, wenn
     $x$ nicht freie Variable von $f$ ist.
 \end{definition}
@@ -87,7 +87,7 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
 \begin{beispiel}[$\eta$-Äquivalenz]
     TODO
 \end{beispiel}
-\index{Reduktionen|)}
+\index{Reduktion|)}
 
 \section{Auswertungsstrategien}
 \begin{definition}[Normalenreihenfolge]\xindex{Normalenreihenfolge}%
@@ -193,4 +193,101 @@ Auch die gewohnten Operationen lassen sich so darstellen.
 \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.
-\end{satz}
+\end{satz}
+
+\section{Fixpunktkombinator}
+\begin{definition}[Fixpunkt]\xindex{Fixpunkt}%
+    Sei $f: X \rightarrow Y$ eine Funktion mit $\emptyset \neq A = X \cap Y$ und
+    $a \in A$.
+
+    $a$ heißt \textbf{Fixpunkt} der Funktion $f$, wenn $f(a) = a$ gilt.
+\end{definition}
+
+\begin{beispiel}[Fixpunkt]
+    \begin{bspenum}
+        \item $f_1: \mdr \rightarrow \mdr; f(x) = x^2 \Rightarrow x_1 = 0$ ist 
+              Fixpunkt von $f$, da $f(0) = 0$. $x_2 = 1$ ist der einzige weitere
+              Fixpunkt dieser Funktion.
+        \item $f_2: \mdn \rightarrow \mdn$ hat ganz $\mdn$ als Fixpunkte, also
+              insbesondere unendlich viele Fixpunkte.
+        \item $f_3: \mdr \rightarrow \mdr; f(x) = x+1$ hat keinen einzigen Fixpunkt.
+        \item $f_4: \mdr[X] \rightarrow \mdr[X]; f(p) = p^2$ hat $p_1(x) = 0$ und
+              $p_2(x)=1$ als Fixpunkte.
+    \end{bspenum}
+\end{beispiel}
+
+\begin{definition}[Kombinator]\xindex{Kombinator}%
+    Ein Kombinator ist eine Abbildung ohne freie Variablen.
+\end{definition}
+
+\begin{beispiel}[Kombinatoren\footnotemark]%
+    \begin{bspenum}
+        \item $\lambda a.\ a$
+        \item $\lambda a.\ \lambda b.\ a$
+        \item $\lambda f.\ \lambda a.\ \lambda b. f\ b\ a$
+    \end{bspenum}
+\end{beispiel}
+\footnotetext{Quelle: \url{http://www.haskell.org/haskellwiki/Combinator}}
+
+\begin{definition}[Fixpunkt-Kombinator]\xindex{Fixpunkt-Kombinator}%
+    Sei $f$ ein Kombinator, der $f\ g = g\ (f\ g)$ erfüllt. Dann heißt $f$
+    \textbf{Fixpunktkombinator}.
+\end{definition}
+
+Insbesondere ist also $f \ g$ ein Fixpunkt von $g$.
+
+\begin{definition}[Y-Kombinator]\xindex{Y-Kombinator}%
+    Der Fixpunktkombinator
+    \[Y := \lambda f.\ (\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x))\]
+    heißt $Y$-Kombinator.
+\end{definition}
+
+\begin{behauptung}
+    Der $Y$-Kombinator ist ein Fixpunktkombinator.
+\end{behauptung}
+
+\begin{beweis}\footnote{Quelle: Vorlesung WS 2013/2014, Folie 175}\leavevmode
+
+    \textbf{Teil 1:} Offensichtlich ist $Y$ ein Kombinator.
+
+    \textbf{Teil 2:} z.~Z.: $Y f \Rightarrow^* f \ (Y \ f)$
+
+    \begin{align*}
+        Y\ f     &=\hphantom{^\beta f\ } (\lambda f.\ (\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x)))\ f\\
+                 &\Rightarrow^\beta\hphantom{f \ (\lambda f.\ }  (\lambda x. f\ (x\ x))\ (\lambda x.\ f\ (x\ x))\\
+                 &\Rightarrow^\beta  f \ (\hphantom{\lambda f.\ }(\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x)))\\
+                 &\Rightarrow^\beta  f \ (\lambda f.\ (\lambda x.\ f\ (x\ x))\ (\lambda x.\ f\ (x\ x))\ f)\\
+                 &=\hphantom{^\beta} f \ (Y \ f)
+    \end{align*}
+    $\qed$
+\end{beweis}
+
+\begin{definition}[Turingkombinator]\xindex{Turingkombinator}%
+    Der Fixpunktkombinator
+    \[\Theta := (\lambda x. \lambda y. y\ (x\ x\ y)) (\lambda x.\ \lambda y.\ y\ (x\ x\ y))\]
+    heißt \textbf{Turingkombinator}.
+\end{definition}
+
+\begin{behauptung}
+    Der Turing-Kombinator $\Theta$ ist ein Fixpunktkombinator.
+\end{behauptung}
+
+\begin{beweis}\footnote{Quelle: Übungsblatt 6, WS 2013/2014}
+
+    \textbf{Teil 1:} Offensichtlich ist $\Theta$ ein Kombinator.
+
+    \textbf{Teil 2:} z.~Z.: $\Theta f \Rightarrow^* f \ (\Theta \ f)$
+
+    Sei $\Theta_0 := (\lambda x.\ \lambda y.\ y\ (x\ x\ y))$. Dann gilt:
+    \begin{align*}
+        \Theta\ f &= ((\lambda x.\ \lambda y.\ y\ (x\ x\ y))\ \Theta_0)\ f\\
+                 &\Rightarrow^\beta (\lambda y. y\ (\Theta_0 \ \Theta_0 \ y))\ f\\
+                 &\Rightarrow^\beta f \ (\Theta_0 \Theta_0 f)\\
+                 &= f \ (\Theta \ f)
+    \end{align*}
+    $\qed$
+\end{beweis}
+
+
+
+Für den Turing-Operator gilt 

BIN
documents/Programmierparadigmen/Programmierparadigmen.pdf


+ 15 - 0
documents/Programmierparadigmen/scripts/haskell/Intersect.hs

@@ -0,0 +1,15 @@
+module Intersect where
+intersect :: (Ord t) => [t] -> [t] -> [t]
+intersect a [] = []
+intersect [] a = []
+intersect (x:xs) (y:ys)
+        | x == y = x : intersect xs ys
+        | x < y  = intersect xs (y:ys)
+        | y > y  = intersect (x:xs) ys
+
+intersectAll :: (Ord t) => [[t]] -> [t]
+intersectAll (l:ls) = (foldr intersect l) ls
+intersectAll []     = undefined
+
+multiples n = [n*k | k <- [1..]]
+commonMultiples a b c = intersectAll [ multiples n | n <- [a,b,c]]

+ 2 - 0
documents/Programmierparadigmen/scripts/haskell/fibonacci-stream.hs

@@ -0,0 +1,2 @@
+fibs :: [Integer]
+fibs = 0 : 1 : zipWith (+) fibs (tail fibs)