Browse Source

Haskell / Prolog

Martin Thoma 11 years ago
parent
commit
2306a2af2e

+ 118 - 0
documents/Programmierparadigmen/Definitionen.tex

@@ -0,0 +1,118 @@
+%!TEX root = Programmierparadigmen.tex
+\markboth{Ergänzende Definitionen}{Ergänzende Definitionen}
+\chapter*{Ergänzende Definitionen}
+\addcontentsline{toc}{chapter}{Ergänzende Definitionen}
+
+\begin{definition}[Quantoren]\xindex{Quantor}%
+	\begin{defenum}
+		\item $\forall x \in X: p(x)$: Für alle Elemente $x$ aus der Menge $X$ gilt
+		die Aussage $p$.
+		\item $\exists x \in X: p(x)$: Es gibt mindestens ein Element $x$ aus der
+		Menge $X$, für das die Aussage $p$ gilt.
+		\item $\exists! x \in X: p(x)$: Es gibt genau ein Element $x$ in der
+		Menge $X$, sodass die Aussage $p$ gilt.
+	\end{defenum}
+\end{definition}
+
+\begin{definition}[Prädikatenlogik]\xindex{Prädikatenlogik}%
+	Eine Prädikatenlogik ist ein formales System, das Variablen und Quantoren
+	nutzt um Aussagen zu formulieren.
+\end{definition}
+
+\begin{definition}[Aussagenlogik]\xindex{Aussagenlogik}%
+	TODO
+\end{definition}
+
+\begin{definition}[Grammatik]\xindex{Grammatik}\xindex{Alphabet}\xindex{Nichtterminal}\xindex{Startsymbol}\xindex{Produktionsregel}\index{Ableitungsregel|see{Produktionsregel}}%
+	Eine (formale) \textbf{Grammatik} ist ein Tupel $(\Sigma, V, P, S)$ wobei gilt:
+	\begin{defenumprops}
+		\item $\Sigma$ ist eine endliche Menge und heißt \textbf{Alphabet},
+		\item $V$ ist eine endliche Menge mit $V \cap \Sigma = \emptyset$ und
+		      heißt \textbf{Menge der Nichtterminale},
+		\item $S \in V$ heißt das \textbf{Startsymbol}
+		\item $P = \Set{p: I \rightarrow r | I \in (V \cup \Sigma)^+, r \in (V \cup \Sigma)^*}$ ist eine endliche Menge aus \textbf{Produktionsregeln}
+	\end{defenumprops}
+\end{definition}
+
+Man schreibt:
+
+\begin{itemize}
+	\item $a \Rightarrow b$: Die Anwendung einer Produktionsregel auf $a$ ergibt $b$.
+	\item $a \Rightarrow^* b$: Die Anwendung mehrerer (oder keiner) Produktionsregeln auf
+	$a$ ergibt $b$.
+	\item $a \Rightarrow^+ b$: Die Anwendung mindestens einer Produktionsregel auf $a$
+	ergibt $b$.
+\end{itemize}
+
+\begin{beispiel}[Formale Grammatik]
+	Folgende Grammatik $G = (\Sigma, V, P, A)$ erzeugt alle korrekten Klammerausdrücke:
+
+	\begin{itemize}
+		\item $\Sigma = \Set{(, )}$
+		\item $V = \Set{\alpha}$
+		\item $s = \alpha$
+		\item $P = \Set{\alpha \rightarrow () | \alpha \alpha | (\alpha)}$
+	\end{itemize}
+\end{beispiel}
+
+\begin{definition}[Kontextfreie Grammatik]\xindex{Grammatik!Kontextfreie}%
+	Eine Grammatik $(\Sigma, V, P, S)$ heißt \textbf{kontextfrei}, wenn für 
+	jede Produktion $p: I \rightarrow r$ gilt: $I \in V$.
+\end{definition}
+
+\begin{definition}[Sprache]\xindex{Sprache}%
+	Sei $G = (\Sigma, V, P, S)$ eine Grammatik. Dann ist
+	\[L(G) := \Set{\omega \in \Sigma^* | S \Rightarrow^* \omega}\]
+	die Menge aller in der Grammatik ableitbaren Wörtern. $L(G)$ heißt Sprache 
+	der Grammatik $G$.
+\end{definition}
+
+\begin{definition}\xindex{Linksableitung}\xindex{Rechtsableitung}%
+    Sei $G = (\Sigma, V, P, S)$ eine Grammatik und $a \in (V \cup \Sigma)^+$.
+    \begin{defenum}
+        \item $\Rightarrow_L$ heißt \textbf{Linksableitung}, wenn die Produktion
+              auf das linkeste Nichtterminal angewendet wird.
+        \item $\Rightarrow_R$ heißt \textbf{Rechtsableitung}, wenn die Produktion
+              auf das rechteste Nichtterminal angewendet wird.
+    \end{defenum}
+\end{definition}
+
+\begin{beispiel}[Links- und Rechtsableitung]
+    Sie $G$ wie zuvor die Grammatik der korrekten Klammerausdrücke:
+
+    \begin{equation*}
+    \begin{aligned}[t]
+        \alpha &\Rightarrow_L \alpha \alpha\\
+               &\Rightarrow_L \alpha \alpha \alpha\\
+               &\Rightarrow_L () \alpha \alpha\\
+               &\Rightarrow_L () (\alpha) \alpha\\
+               &\Rightarrow_L () (()) \alpha\\
+               &\Rightarrow_L () (()) ()\\
+    \end{aligned}
+    \qquad\Longleftrightarrow\qquad
+    \begin{aligned}[t]
+        \alpha &\Rightarrow_R \alpha \alpha\\
+               &\Rightarrow_R \alpha \alpha \alpha\\
+               &\Rightarrow_R \alpha \alpha ()\\
+               &\Rightarrow_R \alpha (\alpha) ()\\
+               &\Rightarrow_R \alpha (()) ()\\
+               &\Rightarrow_R () (()) ()\\
+    \end{aligned}
+    \end{equation*}
+\end{beispiel}
+
+\begin{definition}[LL($k$)-Grammatik]\xindex{LL(k)-Grammatik}%
+    Sei $G = (\Sigma, V, P, S)$ eine kontextfreie Grammatik. $G$ heißt
+    LL($k$)-Grammatik für $k \in \mathbb{N}_{\geq 1}$, wenn jeder Ableitungsschritt durch
+    die linkesten $k$ Symbole der Eingabe bestimmt ist.\todo{Was ist die Eingabe einer Grammatik?}
+\end{definition}
+
+Ein LL-Parser ist ein Top-Down-Parser liest die Eingabe von Links nach rechts
+und versucht eine Linksableitung der Eingabe zu berechnen. Ein LL($k$)-Parser
+kann $k$ Token vorausschauen, wobei $k$ als \textit{Lookahead}\xindex{Lookahead}
+bezeichnet wird.
+
+\begin{satz}
+    Für linksrekursive, kontextfreie Grammatiken $G$ gilt:
+    \[\forall k \in \mathbb{N}: G \notin \SLL(k)\] 
+\end{satz}

+ 7 - 3
documents/Programmierparadigmen/Haskell.tex

@@ -28,6 +28,8 @@ Speichere folgenden Quelltext als \texttt{hello-world.hs}:
 Kompiliere ihn mit \texttt{ghc -o hello hello-world.hs}. Es wird eine
 ausführbare Datei erzeugt.
 
+Alternativ kann es direkt mit \texttt{runghc hello-world.hs} ausgeführt werden.
+
 \section{Syntax}
 \subsection{Klammern und Funktionsdeklaration}
 Haskell verzichtet an vielen Stellen auf Klammern. So werden im
@@ -57,15 +59,16 @@ Zu lesen ist die Deklaration wie folgt:
         \end{itemize}
 \end{itemize}
 
-\todo[inline]{Gibt es Funktionsdeklarationen, die äquivalent? (bis auf wechsel des namens und der Reihenfolge)}
+\todo[inline]{Gibt es Funktionsdeklarationen, die bis auf Wechsel des Namens und der Reihenfolge äquivalent sind?}
 
 \subsection{if / else}
 Das folgende Beispiel definiert den Binomialkoeffizienten (vgl. \cref{bsp:binomialkoeffizient})
 
 \inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/binomialkoeffizient.hs}
-\inputminted[numbersep=5pt, tabsize=4]{bash}{scripts/haskell/compile-binom.sh}
 
-\todo[inline]{Guards}
+Das könnte man auch mit sog. Guards machen:\xindex{Guard}
+
+\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/binomialkoeffizient-guard.hs}
 
 \subsection{Rekursion}
 Die Fakultätsfunktion wurde wie folgt implementiert:
@@ -86,6 +89,7 @@ hat einen Speicherverbrauch von $\mathcal{O}(n)$. Durch einen
     \item \texttt{[1,2,3]} erzeugt eine Liste mit den Elementen $1, 2, 3$
     \item \texttt{:} wird \textbf{cons}\xindex{cons} genannt und ist
           der Listenkonstruktor.
+    \item \texttt{list !! i} gibt das $i$-te Element von \texttt{list} zurück.
     \item \texttt{head list} gibt den Kopf von \texttt{list} zurück,
           \texttt{tail list} den Rest:
           \inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/list-basic.sh}

BIN
documents/Programmierparadigmen/Programmierparadigmen.pdf


+ 2 - 0
documents/Programmierparadigmen/Programmierparadigmen.tex

@@ -105,6 +105,8 @@
 \clearpage
 \input{Abkuerzungen}
 \clearpage
+\input{Definitionen} 
+\clearpage
 \input{Symbolverzeichnis} 
 \clearpage
 \addcontentsline{toc}{chapter}{Stichwortverzeichnis}

+ 11 - 4
documents/Programmierparadigmen/Programmiersprachen.tex

@@ -1,3 +1,4 @@
+%!TEX root = Programmierparadigmen.tex
 \chapter{Programmiersprachen}
 Im folgenden werden einige Begriffe definiert anhand derer
 Programmiersprachen unterschieden werden können.
@@ -73,7 +74,7 @@ Wichtige Vorteile von funktionalen Programmiersprachen sind:
 \end{itemize}
 
 \begin{definition}[Logisches Paradigma]\xindex{Programmierung!logische}
-    In der logischen Programmierung baut man Unifikation.\todo{genauer!}
+    In der logischen Programmierung baut auf der Unifikation auf.\todo{genauer!}
 \end{definition}
 
 \section{Typisierung}
@@ -99,12 +100,18 @@ obwohl es Programmiersprachen gibt, die beides unterstützen.
 C und Java werden kompiliert, Python und TCL interpretiert.
 
 \section{Dies und das}
-\begin{definition}[Seiteneffekt]\xindex{Seiteneffekt}\xindex{Nebeneffekt}\xindex{Wirkung}
+\begin{definition}[Seiteneffekt]\xindex{Seiteneffekt}\index{Nebeneffekt|see{Seiteneffekt}}\index{Wirkung|see{Seiteneffekt}}%
     Seiteneffekte sind Veränderungen des Zustandes.\todo{Das geht besser}
 \end{definition}
 
 Manchmal werden Seiteneffekte auch als Nebeneffekt oder Wirkung bezeichnet.
 
-\begin{definition}[Unifikation]\xindex{Unifikation}
-    \todo[inline]{Was ist das?}
+\begin{definition}[Unifikation]\xindex{Unifikation}%
+    Die Unifikation ist eine Operation in der Logik und dient zur Vereinfachung
+    prädikatenlogischer Ausdrücke.
+    \todo[inline]{Das ist keine formale Definition!}
 \end{definition}
+
+\begin{beispiel}[Unifikation]
+    
+\end{beispiel}

+ 8 - 0
documents/Programmierparadigmen/Prolog.tex

@@ -7,6 +7,14 @@ befolgt.
 Eine interaktive Prolog-Sitzung startet man mit \texttt{swipl}.
 
 In Prolog definiert man Terme.
+\section{Erste Schritte}
+\subsection{Hello World}
+Speichere folgenden Quelltext als \texttt{hello-world.pl}:
+\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=hello-world.hs]{prolog}{scripts/prolog/hello-world.hs}
+
+Kompiliere ihn mit \texttt{gplc hello-world.pl}. Es wird eine
+ausführbare Datei erzeugt.
+
 \section{Syntax}
 \section{Beispiele}
 \subsection{Humans}

+ 8 - 0
documents/Programmierparadigmen/programmierparadigmen.sublime-project

@@ -0,0 +1,8 @@
+{
+	"folders":
+	[
+		{
+			"path": "/home/moose/Downloads/LaTeX-examples/documents/Programmierparadigmen"
+		}
+	]
+}

+ 5 - 0
documents/Programmierparadigmen/scripts/haskell/binomialkoeffizient-guard.hs

@@ -0,0 +1,5 @@
+binom :: (Eq a, Num a, Num a1) => a -> a -> a1
+binom n k
+    | (k==0) || (k==n) = 1
+    | otherwise        = binom (n-1) (k-1) 
+                         + binom (n-1) k

+ 2 - 0
documents/Programmierparadigmen/scripts/prolog/hello-world.pl

@@ -0,0 +1,2 @@
+:- initialization(main).
+main :- write('Hello World!'), nl, halt.

+ 5 - 17
documents/Programmierparadigmen/shortcuts.sty

@@ -64,28 +64,12 @@
 \def\mdn{\ensuremath{\mathbb{N}}}
 \def\mdh{\ensuremath{\mathbb{H}}}
 \def\gdw{\ensuremath{\Leftrightarrow}}
-
-\def\atlas{\ensuremath{\mathcal{A}}}
-\DeclareMathOperator{\rang}{rg}
-
-\def\GL{\ensuremath{\mathrm{GL}}}
-\def\SL{\ensuremath{\mathrm{SL}}}
-\def\PSL{\ensuremath{\mathrm{PSL}}}
 \newcommand\mapsfrom{\mathrel{\reflectbox{\ensuremath{\mapsto}}}}
 \newcommand\dcup{\mathbin{\dot{\cup}}}
 \newcommand{\id}{\textnormal{id}}
-\DeclareMathOperator{\Deck}{Deck}
-\DeclareMathOperator{\Fix}{Fix}
-\DeclareMathOperator{\Iso}{Iso}
-\DeclareMathOperator{\grad}{grad}
-\DeclareMathOperator{\Perm}{Perm}
-\DeclareMathOperator{\Sym}{Sym}
-\DeclareMathOperator{\Homoo}{\textnormal{Homöo}}
-\DeclareMathOperator{\Diffeo}{Diffeo}
 \DeclareMathOperator{\conv}{conv}
 \DeclareMathOperator{\IWS}{IWS}
-\DeclareMathOperator{\DV}{DV}
-\DeclareMathOperator{\Rg}{Rg}
+\DeclareMathOperator{\SLL}{SLL}
 \DeclareMathOperator{\Bild}{Bild}
 \newcommand{\iu}{{i\mkern1mu}} % imaginary unit
 %\DeclareMathOperator{\Re}{Re}
@@ -116,6 +100,10 @@
 \setlist[defenum]{label=\alph*),ref=\textup{\thedefinition.\alph*}}
 \crefalias{defenumi}{definition}
 
+\newlist{defenumprops}{enumerate}{1}
+\setlist[defenumprops]{label=(\roman*),ref=\textup{\thedefinition.\roman*}}
+\crefalias{defenumpropsi}{definition}
+
 \newlist{bemenum}{enumerate}{1}
 \setlist[bemenum]{label=\alph*),ref=\textup{\thebemerkung.\alph*}}
 \crefalias{bemenumi}{bemerkung}