📚 The CoCalc Library - books, templates and other resources
License: OTHER
%!TEX root = Programmierparadigmen.tex1\chapter{Prolog}2\index{Prolog|(}34Prolog ist eine Programmiersprache, die das logische Programmierparadigma5befolgt.67Eine interaktive Prolog-Sitzung startet man mit \texttt{swipl}.89In Prolog definiert man Terme.10\section{Erste Schritte}11\subsection{Hello World}12Speichere folgenden Quelltext als \texttt{hello-world.pl}:13\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=hello-world.hs]{prolog}{scripts/prolog/hello-world.pl}1415Kompiliere ihn mit \texttt{gplc hello-world.pl}. Es wird eine16ausführbare Datei erzeugt.1718\section{Syntax}19In Prolog gibt es Prädikate, die Werte haben. Prädikate werden immer klein geschrieben.20So kann das Prädikat \texttt{farbe} mit den Werten \texttt{rot}, \texttt{gruen},21\texttt{blau}, \texttt{gelb} - welche auch immer klein geschrieben werden - wie22folgt definiert werden:2324\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/praedikat-farbe.pl}2526\begin{itemize}27\item Terme werden durch \texttt{,} mit einem logischem \textbf{und} verknüpft.28\item Ungleichheit wird durch \texttt{\=} ausgedrückt.29\end{itemize}3031So ist folgendes Prädikat \texttt{nachbar(X, Y)} genau dann wahr, wenn $X$32und $Y$ Farben sind und $X \neq Y$ gilt:3334\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/simple-term.pl}3536\subsection{Kommentare}\xindex{Kommentare (Prolog)}37Prolog kennt zwei Kommentar-Typen:3839\begin{itemize}40\item Zeilen-Kommentare, die mit \verb+%+ beginnen41\item Block-Kommentare, diem durch \verb+/* ... */+ markiert werden.42\end{itemize}4344\subsection{= und ==}\xindex{= (Prolog)}\xindex{== (Prolog)}45In Prolog entspricht \texttt{=} dem Prädikat \texttt{=/2}. Das Prädikat \texttt{<a> = <b>} wird46erfüllt, wenn die beiden Terme \texttt{<a>} und \texttt{<b>} unifiziert werden47können.4849Das Prädikat \texttt{<a> == <b>} ist im Gegensatz dazu jedoch nur erfüllt, wenn50die beiden Terme bereits identisch sind.5152\begin{beispiel}[= und ==]53\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/equal.pl}54\end{beispiel}5556Weitere Informationen: \url{http://stackoverflow.com/a/8220315/562769}5758\subsection{! (Cut)}\xindex{"! (Cut, Prolog)}%59Das \texttt{!} wird in Prolog als \textit{cut} bezeichnet. Ein Cut verhindert60Backtracking nach dem cut.6162Die Klauseln eines Prädikates werden von Prolog von links nach rechts evaluiert.63Prolog bindet einen Wert an eine Variable in der linkesten Klausel. Wenn diese64Klausel als \texttt{true} ausgewertet wird, dann versucht Prolog die nächste65Klausel auszuwerten. Falls nicht, wird eine neuer Wert an die momentan66betrachtete Klausel gebunden.6768Da Klauseln über logische UND verbunden sind, führt eine nicht erfüllbare69Klausel dazu, dass das gesamte Prädikat als \texttt{false} evaluiert wird.7071Der cut ist ein Gate: Sind die Klauseln vor dem cut ein mal wahr, werden die72Werte festgelegt.7374\subsection{Arithmetik}75Die Auswertung artihmetischer Ausdrücke muss in Prolog explizit durch \texttt{is}76durchgeführt werden:7778\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/arithmetik.pl}7980Dabei müssen alle Variablen, die im Term rechts von \texttt{is} vorkommen,81istanziiert sein:8283\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/arithmetik-fail.pl}8485Arithmetische Ausdrücke können mit \texttt{=:= , =\textbackslash= , < , <= , > , >=}86verglichen werden.8788\begin{beispiel}[Arithmetik in Prolog\footnotemark]89\begin{bspenum}90\item \inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/even.pl}\xindex{even (Prolog)@\texttt{even} (Prolog)}91\item \inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/fibonacci2.pl}\xindex{Prolog!Fibonacci}92\end{bspenum}93\end{beispiel}94\footnotetext{WS 2013 / 2014, Folie 237f}9596\subsection{Listen}97Das Atom \texttt{[]} ist die leere Liste.9899Mit der Syntax \texttt{[K|R]} wird eine Liste in den Listekopf \texttt{K} und100den Rest der Liste \texttt{R} gesplitet:101102\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/liste-basic.pl}103104Einen Test \texttt{member(X, Liste)}, der \texttt{True} zurückgibt wenn \texttt{X}105in \texttt{Liste} vorkommt, realisiert man wie folgt:106107\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/liste-member.pl}\xindex{member}108109Eine Regel \texttt{append(A, B, C)}, die die Listen \texttt{A} und \texttt{B}110zusammenfügt und als Liste \texttt{C} speichert, kann111wie folgt erstellt werden:112113\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/liste-append.pl}114115Die erste Regel besagt, dass das Hinzufügen der leeren Liste zu einer Liste116\texttt{L} immer noch die Liste \texttt{L} ist.117118Die zweite Regel besagt: Wenn die Liste \texttt{R} und \texttt{L} die Liste \texttt{T}119ergeben, dann ergibt die Liste, deren Kopf \texttt{X} ist und deren Rumpf \texttt{R}120ist zusammen mit der Liste \texttt{L} die Liste mit dem Kopf \texttt{X} und dem121Rumpf \texttt{T}.122123\xindex{split}Übergibt man \texttt{append(X,Y,[1,2,3,4,5])}, so werden durch Reerfüllung alle124Möglichkeiten durchgegangen, wie man die Liste \texttt{[1,2,3,4,5]} splitten kann.125126Die Länge einer Liste \texttt{L} kann durch folgendes Prädikat ermittelt werden:\xindex{length(?List, ?Int)@\texttt{length(?List, ?Int)}}%127128\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/list-length.pl}129130\underline{Hinweis}: Da es das Prädikat \texttt{length(?List, ?Int)} bereits gibt,131musste dieses Prädikat \texttt{lengthof} genannt werden.132133Weitere nützliche Standard-Listenprädikate sind:\xindex{sort(+List, -Sorted)@\texttt{sort(+List, -Sorted)}}134\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/standard-list-predicates.pl}135136\underline{Hinweis}: \texttt{sort} entfernt Duplikate, \texttt{msort} hingegen nicht.137138Eine Liste kann mit \texttt{rev/2}\xindex{rev/2@\texttt{rev/2}} umgedreht werden:139\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/reverse-list.pl}140141\subsection{Bäume}142Bäume können in Prolog wie folgt erstellt werden:143144\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/binary-tree-example.pl}145146\begin{figure}[htp]147\centering148\input{figures/binary-tree.tex}149\caption{Binärbaum \texttt{T2}}150\label{fig:binary-tree-t2}151\end{figure}152153Dabei ist154\begin{itemize}155\item \texttt{T0} der einzelne Knoten \texttt{a},156\item \texttt{T1} der Baum, der \texttt{a} als Wurzel und \texttt{b} und157\texttt{c} als Kinder hat,158\item \texttt{T2} ist in \cref{fig:binary-tree-t2} dargestellt und159\item \texttt{T3} ist der leere Baum.160\end{itemize}161162Die folgenden Prädikate stammen von \url{https://sites.google.com/site/prologsite/prolog-problems/4}:163164\subsection{Binärbaum-Check}165Das folgende Prädikate \texttt{istree/1} überprüft, ob es sich bei dem Parameter166um einen Binärbaum handelt:167168\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/istree.pl}169170\subsection{Balancierte Binärbaumkonstruktion}171Das folgende Prädikate \texttt{cbal\_tree(n, T)} erstellt einen balancierten172Binärbaum mit \texttt{n} Knoten in \texttt{T}:173174\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/balancedtreeconstruction.pl}175176\section{Beispiele}177\subsection{Humans}178Erstelle folgende Datei:179\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=human.pro]{prolog}{scripts/prolog/human.pro}180181Kompiliere diese mit182\inputminted[numbersep=5pt, tabsize=4]{bash}{scripts/prolog/human.sh}183184Dabei wird eine \texttt{a.out} Datei erzeugt, die man wie folgt185nutzen kann:186\inputminted[numbersep=5pt, tabsize=4]{bash}{scripts/prolog/human-2.sh}187188\subsection{Splits}189\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=splits.pl]{prolog}{scripts/prolog/splits.pl}190191Dieses skript soll man \texttt{swipl -f test.pl} aufrufen. Dann erhält man:192193\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/splits.sh}194195\subsection{Delete}\xindex{remove}\xindex{delete}%196\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/delete.pl}197198% \subsection{Zebrarätsel}199% Folgendes Rätsel wurde von \url{https://de.wikipedia.org/w/index.php?title=Zebrar%C3%A4tsel&oldid=126585006}200% entnommen:201202% \begin{enumerate}203% \item Es gibt fünf Häuser.204% \item Der Engländer wohnt im roten Haus.205% \item Der Spanier hat einen Hund.206% \item Kaffee wird im grünen Haus getrunken.207% \item Der Ukrainer trinkt Tee.208% \item Das grüne Haus ist direkt rechts vom weißen Haus.209% \item Der Raucher von Altem-Gold-Zigaretten hält Schnecken als Haustiere.210% \item Die Zigaretten der Marke Kools werden im gelben Haus geraucht.211% \item Milch wird im mittleren Haus getrunken.212% \item Der Norweger wohnt im ersten Haus.213% \item Der Mann, der Chesterfields raucht, wohnt neben dem Mann mit dem Fuchs.214% \item Die Marke Kools wird geraucht im Haus neben dem Haus mit dem Pferd.215% \item Der Lucky-Strike-Raucher trinkt am liebsten Orangensaft.216% \item Der Japaner raucht Zigaretten der Marke Parliaments.217% \item Der Norweger wohnt neben dem blauen Haus.218% \end{enumerate}219220% Wer trinkt Wasser? Wem gehört das Zebra?221222% \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=zebraraetsel.pro]{prolog}{scripts/prolog/zebraraetsel.pro}223224% TODO: Zebrarätzel hinzufügen225226\subsection{Zahlen generieren}227Folgendes Skript generiert durch reerfüllung die Zahlen $1, \dots, 10$:228229\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/zahlen-bis-10.pl}230231\subsection{Reguläre ausdrücke}232Folgendes Beispiel stammt aus der Programmierparadigmenklausur vom WS 2013/2014233bei Prof. Dr. Snelting:234235\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/regex.pl}236237\subsection{Coffeetime 01: Two Bases}238239\inputminted[numbersep=5pt, tabsize=4]{prolog}{scripts/prolog/01-two-bases.prolog}240241\section{Weitere Informationen}242\begin{itemize}243\item \href{http://wiki.ubuntuusers.de/Prolog}{\path{wiki.ubuntuusers.de/Prolog}}: Hinweise zur Installation von Prolog unter Ubuntu244\item \url{http://www.swi-prolog.org/}245\end{itemize}246\index{Prolog|)}247248249