230 lines
8.6 KiB
TeX
230 lines
8.6 KiB
TeX
%! Author = tdpeuter
|
|
%! Date = 27/03/2025
|
|
|
|
\documentclass[11pt,a4paper]{article}
|
|
|
|
\usepackage{amsmath}
|
|
\usepackage[dutch]{babel} % Nederlands taal
|
|
\usepackage{enumitem} % Aanpasbare lijsten
|
|
\usepackage[margin=1in]{geometry} % Sane marges
|
|
\usepackage{hyperref} % Hyperlinks
|
|
\usepackage{multicol} % Meerdere kolommen
|
|
|
|
\title{Ghent Prolog}
|
|
\author{Tibo De Peuter}
|
|
\date{\today}
|
|
|
|
% Document
|
|
\begin{document}
|
|
\maketitle
|
|
|
|
\section{Inleiding}\label{sec:inleiding}
|
|
|
|
% Uitvoeren van testen ref appendix
|
|
|
|
\section{Architectuur}\label{sec:architectuur}
|
|
|
|
% Overzicht van programma-loop
|
|
|
|
\begin{enumerate}
|
|
\item Lexing and parsing
|
|
\item Preprocessor
|
|
\item Programma en Repl
|
|
\end{enumerate}
|
|
|
|
% Parser maakt gebruik van welk Grammar???
|
|
|
|
% Preprocessor om parser eenvoudig te houden (eventueel later eigen implementatie
|
|
|
|
% Interfaces: satisfiable, resolvent
|
|
|
|
\subsection{Unificatie}\label{subsec:unificatie}
|
|
|
|
Zoals beschreven in Artificial Intelligence a Modern Approach. Algoritme is geïnspireerd door
|
|
|
|
\section{Implementatie}\label{sec:implementatie}
|
|
|
|
% Kotlin, libraries
|
|
Ghent Prolog werd geschreven in Kotlin, en gebruikt verder twee bibliotheken: \href{https://github.com/h0tk3y/better-parse}{\texttt{better-parse}}, een parser combinator library voor het parsen van een gedefinieerde grammatica, en \href{}{}, voor het gebruik van command-line argumenten.
|
|
% TODO Add link
|
|
|
|
% Data representatie: klassen, satisfiable, resolvent
|
|
|
|
%% Evaluatie strategie
|
|
|
|
% Overzicht van geïmplementeerde predicaten in appendix.
|
|
|
|
% Belangrijkste delen zijn Clause.satisfy
|
|
|
|
\section{Resultaat}\label{sec:resultaat}
|
|
|
|
% Code wordt lelijk en overzichtelijk. Door de geneste datatypes veel boilerplate.
|
|
|
|
\subsection{Afwijkingen van SWI-Prolog}\label{subsec:afwijkingen}
|
|
|
|
% Occurs check
|
|
|
|
% SLD Resolutie
|
|
In tegenstelling tot ISO Prolog en SWI-Prolog, maak ik geen gebruik van SLD-resolutie.
|
|
% TODO Bronnen voor SLD-resolutie
|
|
% TODO Bronnen voor ISO-Prolog maakt gebruik van SLD resolutie
|
|
% TODO Bronnen voor SWIPL maakt gebruik van SLD resolutie
|
|
|
|
\section{Toekomstig werk}\label{sec:toekomstig-werk}
|
|
|
|
% Stack gebruiken
|
|
|
|
\section{Conclusie}\label{sec:conclusie}
|
|
|
|
\appendix
|
|
\newpage
|
|
|
|
\section{Aanvullende opmerkingen}\label{sec:aanvullende-opmerkingen}
|
|
|
|
\subsection{Operator precedentie en associativiteit}\label{subsec:operator-precedence}
|
|
|
|
Mijn implementatie ondersteunt operator precedentie en associativiteit.
|
|
Deze functionaliteit bevindt zich in de parser, omdat de argumenten van een operator steeds rechtstreeks als parameters in de constructor van de klasse worden meegegeven.
|
|
|
|
Operator precedentie en associativiteit werd geïmplementeerd volgens de \href{https://www.swi-prolog.org/pldoc/man?section=operators}{SWI-Prolog documentatie}.
|
|
|
|
\subsection{Test driven development}\label{subsec:ttd}
|
|
|
|
Doorheen de ontwikkeling van grote delen van mijn implementatie heb ik gebruik gemaakt van Test Driven Development, onder andere met behulp van \href{https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-t-o-d-o.html}{Kotlin \texttt{TODO}}.
|
|
|
|
\subsection{Onafgewerkte Lexer en Parser implementatie}\label{subsec:lexer-parser}
|
|
|
|
Bij de start van het project was ik begonnen met het schrijven van mijn eigen lexer en parser. Uit gebruik omdat het eenvoudiger was om de parser library
|
|
% TODO reference sectie over de parser
|
|
te gebruiken.
|
|
|
|
De implementatie was gebaseerd op \href{https://craftinginterpreters.com/contents.html}{Crafting Interpreters, Robert Nystrom} en \href{https://www.youtube.com/playlist?list=PLGNbPb3dQJ_5FTPfFIg28UxuMpu7k0eT4}{Building a Parser from scratch, Dmitry Soshnikov}.
|
|
|
|
De voorlopige implementatie van de lexer en parser kunnen hier teruggevonden worden.
|
|
% TODO Link naar commit met voorlopige implementatie
|
|
|
|
\section{Uitvoeren en testen}\label{sec:uitvoeren-en-testen}
|
|
|
|
Om Ghent Prolog op een Windows, Linux of MacOS uit te voeren is het voldoende om Java te installeren en Ghent Prolog op te roepen met `./src/gpl`. De nodige stappen, waaronder het bouwen van een JAR, worden dan automatisch uitgevoerd.
|
|
|
|
De ingediende JAR kan ook handmatig opgeroepen worden met \texttt{java -jar ./build/gpl.jar}.
|
|
|
|
Er word ook een Docker omgeving voorzien waarin Ghent Prolog opgeroepen kan worden met \texttt{gpl}.
|
|
|
|
Het programma ondersteunt de volgende vlaggen:
|
|
|
|
% TODO gpl --help
|
|
|
|
\subsection{Testen}\label{subsection:testen}
|
|
|
|
De testen kunnen uitgevoerd worden door de meeste IDE's.
|
|
|
|
Alternatief kunnen de testen uitgevoerd worden met \texttt{./gradlew test}. Resultaten worden naar \texttt{stdout} geschreven of kunnen bekeken worden met
|
|
% TODO HTML rapporten.
|
|
|
|
\section{Overzicht van geïmplementeerde predicaten}\label{sec:predicaten}
|
|
|
|
\begin{multicols}{2}
|
|
\begin{itemize}[label={}]
|
|
\item \textbf{Analysing and Constructing Terms}
|
|
\begin{itemize}
|
|
\item \texttt{functor/3}
|
|
\item \texttt{arg/3}
|
|
\item \texttt{=..}
|
|
\item \texttt{numbervars/1}
|
|
\item \texttt{numbervars/3}
|
|
\end{itemize}
|
|
\item \textbf{Arithmetic}
|
|
\begin{itemize}
|
|
\item \texttt{between/3}
|
|
\item \texttt{succ/2}
|
|
\item \texttt{plus/3}
|
|
\item \texttt{=\textbackslash=/2}
|
|
\item \texttt{=:=/2}
|
|
\item \texttt{is/2}
|
|
\item \texttt{-/1}
|
|
\item \texttt{+/1}
|
|
\item \texttt{+/2}
|
|
\item \texttt{*/2}
|
|
\item \texttt{//2}
|
|
\item \texttt{inf/0}
|
|
\end{itemize}
|
|
\item \textbf{Comparison and Unification of Terms}
|
|
\begin{itemize}
|
|
\item \texttt{=/2}
|
|
\item \texttt{\textbackslash=/2}
|
|
\item \texttt{==/2}
|
|
\item \texttt{\textbackslash==/2}
|
|
\end{itemize}
|
|
\item \textbf{Control Predicates}
|
|
\begin{itemize}
|
|
\item \texttt{fail/0}
|
|
\item \texttt{false/0}
|
|
\item \texttt{true/0}
|
|
\item \texttt{!/0}
|
|
\item \texttt{,/2}
|
|
\item \texttt{;/2}
|
|
\item \texttt{|/2}
|
|
\item \texttt{\textbackslash+/1}
|
|
\end{itemize}
|
|
\item \textbf{Database}
|
|
\begin{itemize}
|
|
\item \texttt{retract/1}
|
|
\item \texttt{retractall/1}
|
|
\item \texttt{asserta/1}
|
|
\item \texttt{assertz/1}
|
|
\item \texttt{assert/1}
|
|
\end{itemize}
|
|
\item \textbf{Declaring predicate properties}
|
|
\begin{itemize}
|
|
\item \texttt{dynamic/1}
|
|
\end{itemize}
|
|
\item \textbf{Delimited continuations}
|
|
\begin{itemize}
|
|
\item \texttt{reset/3}
|
|
\item \texttt{shift/1}
|
|
\end{itemize}
|
|
\item \textbf{Examining the program}
|
|
\begin{itemize}
|
|
\item \texttt{clause/2}
|
|
\end{itemize}
|
|
\item \textbf{Forall}
|
|
\begin{itemize}
|
|
\item \texttt{forall/2}
|
|
\end{itemize}
|
|
\item \textbf{Loading Prolog source files}
|
|
\begin{itemize}
|
|
\item \texttt{consult/1}
|
|
\item \texttt{initialization/1}
|
|
\end{itemize}
|
|
\item \textbf{Meta-Call Predicates}
|
|
\begin{itemize}
|
|
\item \texttt{call/1}
|
|
\item \texttt{once/1}
|
|
\item \texttt{ignore/1}
|
|
\end{itemize}
|
|
\item \textbf{Primitive character I/O}
|
|
\begin{itemize}
|
|
\item \texttt{nl/0}
|
|
\end{itemize}
|
|
\item \textbf{Term reading and writing}
|
|
\begin{itemize}
|
|
\item \texttt{write/1}
|
|
\item \texttt{writeln/1}
|
|
\item \texttt{read/1}
|
|
\end{itemize}
|
|
\item \textbf{Verify Type of a Term}
|
|
\begin{itemize}
|
|
\item \texttt{var/1}
|
|
\item \texttt{nonvar/1}
|
|
\item \texttt{atom/1}
|
|
\item \texttt{compound/1}
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{multicols}
|
|
|
|
\section{Dankwoord}\label{sec:dankwoord}
|
|
|
|
Bedankt aan LogicalCaptain om steeds nuttige informatie en voorbeelden te geven bij SWI-Prolog documentatie die iets minder duidelijk is. Uw nota's waren verhelderend en zorgden voor een beter begrip van en voor de nuances van SWI-Prolog.
|
|
|
|
\end{document}
|