2
0
Fork 0
mirror of https://github.com/MartinThoma/LaTeX-examples.git synced 2025-04-25 06:18:05 +02:00

Abschnitt über Arithmetik in Prolog hinzugefügt; misc

This commit is contained in:
Martin Thoma 2014-03-23 19:28:44 +01:00
parent 82dd24d55b
commit 80e8df59d6
20 changed files with 194 additions and 27 deletions

View file

@ -77,8 +77,7 @@ In C gibt es keinen direkten Support für Booleans.
}
\end{table}
\section{Syntax}
\section{Präzedenzregeln}
\section{Präzedenzregeln}\xindex{Präzedenzregeln}%
\begin{tabbing}
\textbf{A} \=\enquote{[name] is a\dots}\\
\>\textbf{B.1} \=prenthesis {\color{red}$( )$}\\

View file

@ -184,4 +184,12 @@ Maschinencode oder Assembler zu erstellen. Dabei muss folgendes beachtet werden:
\item \textbf{Nachoptimierung}\todo{?}
\end{itemize}
\section{Literatur}
Ich kann das folgende Buch empfehlen:
\textit{Compiler - Prinzipien, Techniken und Werkzeuge}. Alfred V. Aho, Monica S. Lam,
Ravi Sethi und Jeffry D. Ullman. Pearson Verlag, 2. Auflage, 2008. ISBN 978-3-8273-7097-6.
Es ist mit über 1200 Seiten zwar etwas dick, aber dafür sehr einfach geschrieben.
\index{Compilerbau|)}

View file

@ -94,10 +94,12 @@ hat einen Speicherverbrauch von $\mathcal{O}(n)$. Durch einen
\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}
\item \texttt{null list} prüft, ob \texttt{list} leer ist.
\item \texttt{last [1,9,1,3]} gibt 3 zurück.
\item \texttt{length list} gibt die Anzahl der Elemente in \texttt{list} zurück.
\item \texttt{maximum [1,9,1,3]} gibt 9 zurück (analog: \texttt{minimum}).
\item \texttt{last [1,9,1,3]} gibt 3 zurück.
\item \texttt{null list} prüft, ob \texttt{list} leer ist.
\item \texttt{take 3 [1,2,3,4,5]} gibt \texttt{[1,2,3]} zurück.
\item \texttt{drop 3 [1,2,3,4,5]} gibt \texttt{[4,5]} zurück.
\item \texttt{reverse [1,9,1,3]} gibt \texttt{[3,1,9,1]} zurück.
\item \texttt{elem item list} gibt zurück, ob sich \texttt{item} in \texttt{list} befindet.
\end{itemize}
@ -105,7 +107,7 @@ hat einen Speicherverbrauch von $\mathcal{O}(n)$. Durch einen
\subsubsection{Beispiel in der interaktiven Konsole}
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/listenoperationen.sh}
\subsubsection{List-Comprehensions}\xindex{List-Comprehension}
\subsubsection{List-Comprehensions}\xindex{List-Comprehension}%
List-Comprehensions sind kurzschreibweisen für Listen, die sich an
der Mengenschreibweise in der Mathematik orientieren. So entspricht
die Menge
@ -116,6 +118,13 @@ die Menge
in etwa folgendem Haskell-Code:
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/list-comprehensions.sh}
\begin{beispiel}[List-Comprehension]
Das folgende Beispiel zeigt, wie man mit List-Comprehensions die unendliche
Liste aller pythagoreischen Tripels erstellen kann:
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/pythagorean-triples.hs}
\end{beispiel}
\subsection{Strings}
\begin{itemize}
\item Strings sind Listen von Zeichen:\\
@ -227,9 +236,9 @@ wird wie folgt erzeugt:
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=lauflaengencodierung.hs]{haskell}{scripts/haskell/lauflaengencodierung.hs}
\subsection{Intersections}\xindex{Intersections}%
\subsection{Intersections}\xindex{Intersections}\xindex{List-Comprehension}%
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=Intersect.hs]{haskell}{scripts/haskell/Intersect.hs}
\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}

View file

@ -69,23 +69,29 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
\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]\]
\[(\lambda x. t_1)\ t_2 \Rightarrow t_1 [x \mapsto t_2]\]
\end{definition}
\begin{beispiel}[$\beta$-Äquivalenz]
\begin{defenum}
\item $(\lambda x.x) y \overset{\beta}{\Rightarrow} x[x \mapsto y] = y$
\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)$
\item $(\lambda x.\ x)\ y \overset{\beta}{\Rightarrow} x[x \mapsto y] = y$
\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)$
\end{defenum}
\end{beispiel}
\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.
\begin{definition}[$\eta$-Äquivalenz\footnote{Folie 158}]\xindex{Reduktion!Eta ($\eta$)}\xindex{Äquivalenz!Eta ($\eta$)}%
Die Terme $\lambda x. f~x$ und $f$ heißen $\eta$-Äquivalent, wenn $x \notin FV(f)$ gilt.
Man schreibt: $\lambda x. f~x \overset{\eta}{=} f$.
\end{definition}
\begin{beispiel}[$\eta$-Äquivalenz]
TODO
\begin{beispiel}[$\eta$-Äquivalenz\footnote{Folie 158}]%
\begin{align*}
\lambda x.\ \lambda y.\ f\ z\ x\ y &\overset{\eta}{=} \lambda x.\ f\ z\ x\\
f\ z &\overset{\eta}{=} \lambda x.\ f\ z\ x\\
\lambda x.\ x &\overset{\eta}{=} \lambda x.\ (\lambda x.\ x)\ x\\
\lambda x.\ f\ x\ x &\overset{\eta}{\neq} f\ x
\end{align*}
\end{beispiel}
\index{Reduktion|)}
@ -366,3 +372,10 @@ und
\[\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}\]
\todo[inline]{Folie 208ff}
\section{Literatur}
\begin{itemize}
\item \url{http://c2.com/cgi/wiki?FreeVariable}
\item \url{http://www.lambda-bound.com/book/lambdacalc/node9.html}
\end{itemize}

View file

@ -15,7 +15,7 @@ gestartet.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Funktionen}
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size.c}\xindex{MPI\_Comm\_size}
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size.c}\xindex{MPI\_Comm\_size}%
Liefert die Größe des angegebenen Kommunikators; dh. die Anzahl der Prozesse in der Gruppe.
\textbf{Parameter}
@ -27,7 +27,7 @@ Liefert die Größe des angegebenen Kommunikators; dh. die Anzahl der Prozesse i
\textbf{Beispiel}
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size-example.c}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\rule{\textwidth}{0.4pt}\xindex{MPI\_Comm\_rank}
\rule{\textwidth}{0.4pt}\xindex{MPI\_Comm\_rank}%
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank.c}
Bestimmt den Rang des rufenden Prozesses innerhalb des Kommunikators.
@ -42,7 +42,7 @@ Der Rang wird von MPI zum Identifizieren eines Prozesses verwendet. Die Rangnumm
\textbf{Beispiel}
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank-example.c}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\rule{\textwidth}{0.4pt}\xindex{MPI\_Send}
\rule{\textwidth}{0.4pt}\xindex{MPI\_Send}%
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send.c}
Senden einer Nachricht an einen anderen Prozeß innerhalb eines Kommunikators. (Standard-Send)
@ -60,7 +60,7 @@ Ein Kommunikationsvorgang wird durch ein Tripel (Sender, Empfänger, tag) eindeu
\textbf{Beispiel}
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send-example.c}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\rule{\textwidth}{0.4pt}\xindex{MPI\_Recv}
\rule{\textwidth}{0.4pt}\xindex{MPI\_Recv}%
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive.c}
Empfangen einer Nachricht (blockierend)
@ -79,7 +79,7 @@ Empfangen einer Nachricht (blockierend)
\textbf{Beispiel}
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive-example.c}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\rule{\textwidth}{0.4pt}\xindex{MPI\_Reduce}
\rule{\textwidth}{0.4pt}\xindex{MPI\_Reduce}%
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce.c}
Führt eine globale Operation \textbf{op} aus; der Prozeß \enquote{root} erhält das Resultat.
@ -93,7 +93,7 @@ Führt eine globale Operation \textbf{op} aus; der Prozeß \enquote{root} erhäl
\item \textbf{comm}: Kommunikator (handle)
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\rule{\textwidth}{0.4pt}\xindex{MPI\_Bcast}
\rule{\textwidth}{0.4pt}\xindex{MPI\_Bcast}%
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-bcast.c}
Sendet eine Nachricht vom Prozess \texttt{root} an alle anderen Prozesse des
angegebenen Kommunikators.
@ -107,7 +107,7 @@ angegebenen Kommunikators.
\item \textbf{comm}: Kommunikator (handle)
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\rule{\textwidth}{0.4pt}\xindex{MPI\_Scatter}
\rule{\textwidth}{0.4pt}\xindex{MPI\_Scatter}%
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-scatter.c}
Verteilt Daten vom Prozess \texttt{root} unter alle anderen Prozesse in der Gruppe, so daß, soweit möglich, alle Prozesse gleich große Anteile erhalten.

View file

@ -16,6 +16,7 @@ Parallelverarbeitung kann auf mehreren Ebenen statt finden:
Besteht zwischen aufeinanderfolgenden Anweisungen keine Abhängigkeit,
so kann der Instruction Fetch-Teil einer zweiten Anweisung parallel zum
Decode-Teil einer ersten Anweisung geschehen. Das nennt man Pipelining\xindex{Pipelining}.
Man spricht hier auch von \textit{Instruction Level Parallelism} (ILP)\xindex{ILP}
\item \textbf{Datenebene}: Es kommt immer wieder vor, dass man in Schleifen
eine Operation für jedes Objekt eines Contaitainers (z.~B. einer Liste)
durchführen muss. Zwischen den Anweisungen verschiedener Schleifendurchläufe

View file

@ -339,7 +339,40 @@ Beispiel:
\[f(X_1, X_2, \dots, X_n) = f(g(X_0, X_0), g(X_1, X_1), \dots, g(X_{n-1}, X_{n-1}) )\]
Der \textit{Paterson-Wegman-Unifikationsalgorithmus}\xindex{Paterson-Wegman-Unifikationsalgorithmus} ist deutlich effizienter.
Er basiert auf dem \textit{Union-Find-Algorithmus}\xindex{Union-Find-Algorithmus}.
Er basiert auf dem \textit{Union-Find-Algorithmus}\xindex{Union-Find-Algorithmus}
und funktioniert wie folgt:
\begin{algorithm}[h]
\begin{algorithmic}
\Function{unify}{Knoten $p$, Knoten $q$}
\State $s \gets \Call{find}{p}$
\State $t \gets \Call{find}{q}$
\If{$s == t$ oder $s.\Call{getAtom}{} == t.\Call{getAtom}{}$}
\State \Return \texttt{True}
\EndIf
\If{$s,t$ Knoten für gleichen Funktor, mit Nachfolgern $s_1, \dots , s_n$ bzw. $t_1 , \dots , t_n$ }
\State $\Call{union}{s,t}$
\State $k \gets 1$
\State $b \gets $ \texttt{True}
\While{$k \leq n$ and $b$}
\State $b \gets \Call{unify}{s_k, t_k}$
\State $k \gets k + 1$
\EndWhile
\State \Return \texttt{True}
\EndIf
\If{$s$ oder $t$ ist Variablen-Knoten}
\State $\Call{union}{s,t}$
\State \Return \texttt{True}
\EndIf
\State \Return \texttt{False}
\EndFunction
\end{algorithmic}
\caption{Paterson-Wegeman Unifikationsalgorithmus}
\label{alg:paterson-wegeman-unifikationsalgorithmus}
\end{algorithm}
\footnotetext{\url{https://de.wikipedia.org/w/index.php?title=Unifikation\_(Logik)&oldid=116848554\#Beispiel}}

View file

@ -34,6 +34,58 @@ und $Y$ Farben sind und $X \neq Y$ gilt:
\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/simple-term.pl}
\subsection{Arithmetik}
Die Auswertung artihmetischer Ausdrücke muss in Prolog explizit durch \texttt{is}
durchgeführt werden:
\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/arithmetik.pl}
Dabei müssen alle Variablen, die im Term rechts von \texttt{is} vorkommen,
istanziiert sein:
\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/arithmetik-fail.pl}
Arithmetische Ausdrücke können mit \texttt{=:= , =\textbackslash= , < , <= , > , >=}
verglichen werden.
\begin{beispiel}[Arithmetik in Prolog\footnotemark]
\begin{bspenum}
\item \inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/even.pl}\xindex{even}
\item \inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/fibonacci2.pl}\xindex{fib}
\end{bspenum}
\end{beispiel}
\footnotetext{WS 2013 / 2014, Folie 237f}
\subsection{Listen}
Das Atom \texttt{[]} ist die leere Liste.
Mit der Syntax \texttt{[K|R]} wird eine Liste in den Listekopf \texttt{K} und
den Rest der Liste \texttt{R} gesplitet:
\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/liste-basic.pl}
Einen Test \texttt{member(X, Liste)}, der \texttt{True} zurückgibt wenn \texttt{X}
in \texttt{Liste} vorkommt, realisiert man wie folgt:
\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/liste-member.pl}\xindex{member}
Eine Regel \texttt{append(A, B, C)}, die die Listen \texttt{A} und \texttt{B}
zusammenfügt und als Liste \texttt{C} speichert, kann
wie folgt erstellt werden:
\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/liste-append.pl}
Die erste Regel besagt, dass das Hinzufügen der leeren Liste zu einer Liste
\texttt{L} immer noch die Liste \texttt{L} ist.
Die zweite Regel besagt: Wenn die Liste \texttt{R} und \texttt{L} die Liste \texttt{T}
ergeben, dann ergibt die Liste, deren Kopf \texttt{X} ist und deren Rumpf \texttt{R}
ist zusammen mit der Liste \texttt{L} die Liste mit dem Kopf \texttt{X} und dem
Rumpf \texttt{T}.
\xindex{split}Übergibt man \texttt{append(X,Y,[1,2,3,4,5])}, so werden durch Reerfüllung alle
Möglichkeiten durchgegangen, wie man die Liste \texttt{[1,2,3,4,5]} splitten kann.
\section{Beispiele}
\subsection{Humans}
Erstelle folgende Datei:

View file

@ -3,6 +3,19 @@
X10 ist eine objektorientierte Programmiersprache, die 2004 bei IBM entwickelt
wurde.
X10 nutzt das PGAS-Modell:
\begin{definition}[PGAS\footnotemark]\xindex{PGAS}%
PGAS (partitioned global address space) ist ein Programmiermodell für
Mehrprozessorsysteme und massiv parallele Rechner. Dabei wird der globale
Adressbereich des Arbeitsspeichers logisch unterteilt. Jeder Prozessor
bekommt jeweils einen dieser Adressbereiche als lokalen Speicher zugeteilt.
Trotzdem können alle Prozessoren auf jede Speicherzelle zugreifen, wobei auf
den lokalen Speicher mit wesentlich höherer Geschwindigkeit zugegriffen
werden kann als auf den von anderen Prozessoren.
\end{definition}
\footnotetext{\url{https://de.wikipedia.org/wiki/PGAS}}
\section{Erste Schritte}
Als erstes sollte man x10 von \url{http://x10-lang.org/x10-development/building-x10-from-source.html?id=248} herunterladen.

View file

@ -8,5 +8,7 @@ hIndex l = helper (reverse (sort l)) 0
| otherwise = acc
-- Alternativ
hindex1 = length . takeWhile id . zipWith (<=) [1..] . reverse . sort
hindex2 = length . takeWhile (\(i, n) -> n >= i) . zip [1..] . reverse . sort
hindex1 = length . takeWhile id .
zipWith (<=) [1..] . reverse . sort
hindex2 = length . takeWhile (\(i, n) -> n >= i) .
zip [1..] . reverse . sort

View file

@ -12,4 +12,5 @@ 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]]
commonMultiples a b c =
intersectAll [ multiples n | n <- [a,b,c]]

View file

@ -0,0 +1,6 @@
triples :: [(Integer, Integer, Integer)]
triples = [(x,y,z) | z <-[1..],
x <- [1..z],
y <- [1..z],
z^2 == x^2 + y^2
]

View file

@ -0,0 +1,10 @@
?- X is 3^2.
X = 9.
?- Y is X*X.
ERROR: is/2: Arguments are not sufficiently
instantiated
?- X is X+1.
ERROR: is/2: Arguments are not sufficiently
instantiated

View file

@ -0,0 +1,2 @@
?- X is 5-2*5.
X = -5.

View file

@ -0,0 +1,5 @@
even(0).
even(X) :- X>0, X1 is X-1, odd(X1).
odd(1).
odd(X) :- X>1, X1 is X-1, even(X1).

View file

@ -0,0 +1,6 @@
fib(0,0).
fib(1,1).
fib(X,Y) :- X>1,
X1 is X-1, X2 is X-2,
fib(X1,Y1), fib(X2,Y2),
Y is Y1+Y2.

View file

@ -0,0 +1,2 @@
append([],L,L).
append([X|R],L,[X|T]) :- append(R,L,T).

View file

@ -0,0 +1,3 @@
?- [X|Y] = [1,2,3,4,5].
X = 1,
Y = [2, 3, 4, 5].

View file

@ -0,0 +1,2 @@
member(X,[X|R]).
member(X,[Y|R]) :- member(X,R).