Compare commits

..

No commits in common. "2c6dfb77a0d7eb4ffa14b7381910ba25fc603b60" and "130ff622c9882fc14959fbcc1db13c29c13ecad8" have entirely different histories.

8 changed files with 67 additions and 366 deletions

Binary file not shown.

View file

@ -0,0 +1,11 @@
@book{russell2016,
author = {Russell, Stuart and Norvig, Peter},
title = {{Artificial Intelligence A Modern Approach, Global Edition}},
abstract = {{For one or two-semester, undergraduate or graduate-level courses in Artificial Intelligence. The long-anticipated revision of this best-selling text offers the most comprehensive, up-to-date introduction to the theory and practice of artificial intelligence. }},
pages = {1152},
publisher = {Pearson Deutschland},
year = {2016},
isbn = {9781292153964},
doi = {},
url = {https://elibrary.pearson.de/book/99.150005/9781292153971}
}

View file

@ -1,65 +0,0 @@
@book{boizumault-1993,
author = {given-i=P, given=Patrice, family=Boizumault},
date = {1993-12-31},
doi = {10.1515/9781400863440},
publisher = {Princeton University Press},
title = {The Implementation of Prolog},
url = {https://doi.org/10.1515/9781400863440},
}
@book{toman-2008,
author = {Toman, David},
booktitle = {{Computational Logic}},
title = {Chapter 9. SLD-Resolution And Logic Programming (PROLOG)},
pages = {410--475},
publisher = {University of Waterloo},
year = {2008},
url = {https://cs.uwaterloo.ca/~david/cl/}
}
@book{deransart-1996,
author = {given-i=P, given=Pierre, family=Deransart and given-i=A, given=AbdelAli, family=Ed-Dbali and given-i=L, given=Laurent, family=Cervoni},
date = {1996-01-01},
doi = {10.1007/978-3-642-61411-8},
title = {Prolog: The Standard},
url = {https://doi.org/10.1007/978-3-642-61411-8},
}
@misc{enwiki:1274527056,
author = "{Wikipedia contributors}",
title = "Comparison of Prolog implementations --- {Wikipedia}{,} The Free Encyclopedia",
year = "2025",
howpublished = "\url{https://en.wikipedia.org/w/index.php?title=Comparison_of_Prolog_implementations&oldid=1274527056}",
note = "[Online; accessed 12-May-2025]"
}
@article{iso1995iec,
title={IEC 13211-1: 1995: Information Technology—Programming Languages—Prolog—Part 1: General Core},
author={ISO, ISO and ISO, IEC},
journal={ISO: Geneva, Switzerland},
pages={1--199},
year={1995}
}
@book{russell2016,
author = {Russell, Stuart and Norvig, Peter},
booktitle = {{Artificial Intelligence A Modern Approach, Global Edition}},
title = {Chapter 9. Inference in First-Order Logic},
abstract = {{For one or two-semester, undergraduate or graduate-level courses in Artificial Intelligence.
The long-anticipated revision of this best-selling text offers the most comprehensive, up-to-date introduction to the theory and practice of artificial intelligence.
}},
pages = {325--345},
publisher = {Pearson Deutschland},
year = {2016},
isbn = {9781292153964},
doi = {},
url = {https://elibrary.pearson.de/book/99.150005/9781292153971}
}
@software{unknown-author-2025,
date = {2025-04-25},
title = {SWI-Prolog},
type = {software},
url = {https://www.swi-prolog.org/},
version = {9.3.24},
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

View file

@ -5,332 +5,129 @@
\usepackage{amsmath} \usepackage{amsmath}
\usepackage[dutch]{babel} % Nederlands taal \usepackage[dutch]{babel} % Nederlands taal
\usepackage[style=apa]{biblatex} % Bronnen
\usepackage{enumitem} % Aanpasbare lijsten \usepackage{enumitem} % Aanpasbare lijsten
\usepackage{float} % Figures \usepackage[margin=1in]{geometry} % Sane marges
\usepackage[margin=2cm]{geometry} % Sane marges
\usepackage{graphicx} % Figures
\usepackage{hyperref} % Hyperlinks
\usepackage{minted} % Syntax highlighting
\usepackage{multicol} % Meerdere kolommen \usepackage{multicol} % Meerdere kolommen
\usepackage{url} % Beter geformatteerde URLs
\addbibresource{bibliography.bib}
\title{Ghent Prolog} \title{Ghent Prolog}
\author{Tibo De Peuter} \author{Tibo De Peuter}
\date{\today} \date{\today}
% Document
\begin{document} \begin{document}
\maketitle \maketitle
\abstract{ \section{Inleiding}\label{sec:inleiding}
% KERN: Wat is Ghent Prolog?
Ghent Prolog is een command-line Prolog interpreter geschreven in Kotlin.
Het biedt een subset van de functionaliteit van SWI-Prolog, waaronder database operaties en meta abstracties.
Hoewel het programma nog niet als equivalent van SWI-Prolog kan worden beschouwd, is Ghent Prolog een nuttig leerproject.
}
% Uitvoeren van testen ref appendix
\section{Overzicht}\label{sec:overzicht} \section{Architectuur}\label{sec:architectuur}
% KERN: Insteek % Overzicht van programma-loop
Ghent Prolog is een proof of concept van een Prolog interpreter, als alternatief voor SWI-Prolog.
Het volgt grotendeels ~\cite[de ISO Prolog standaard]{iso1995iec}, maar is niet volledig compatibel.
% KERN: Programmeertaal, libraries, etc.
Ghent Prolog werd geschreven in Kotlin en maakt gebruik van zowel object-gerichte als functionele concepten.
Er werden twee bibliotheken gebruikt:
\href{https://github.com/h0tk3y/better-parse}{\texttt{better-parse}}, voor het parsen van een gegeven grammatica, en
\href{https://github.com/xenomachina/kotlin-argparser}{\texttt{kotlin-argparser}}, voor het gebruik van command-line argumenten.
% KERN: Hoe ziet Ghent Prolog er abstract uit?
De verschillende fases van een interpreter (lexing, parsing, evaluatie, etc.) zijn in Ghent Prolog zo goed mogelijk gescheiden.
Op die manier blijft de implementatie modulair en uitbreidbaar.
De volgende secties concentreren zich op de evaluatie-fase van de interpreter.
Voor meer informatie over de lexing en parsing, zie sectie~\ref{sec:lexing-parsing-preprocessing}.
\section{Programma en REPL}\label{sec:programma-repl}
% KERN: Methode
Ghent Prolog's evaluatiemethode kan gezien worden als een vorm van \textit{backward chaining} (\cite{russell2016}), maar komt niet exact overeen met de definitie.
% KERN: Datastructuur
Ghent Prolog maakt gebruik van functie-oproepen en streams om een backtracking mechanisme te implementeren.
Bijzondere logica met betrekking tot \textit{choicepoints} en foutenafhandeling maakt gebruik van de Kotlin \mintinline{kotlin}{Result} klasse.
Om de resultaten van unificatie en evaluatie \textit{lazy} te verwerken, wordt er gebruik gemaakt van Kotlin \mintinline{kotlin}{Sequence}'s (\textit{lazy streams}).
Meer specifiek wordt er gebruik gemaakt van de volgende types:
\begin{minted}{kotlin}
typealias Substitutions = Map<Term, Term>
typealias Answer = Result<Substitutions>
typealias Answers = Sequence<Answer>
\end{minted}
Een lege \mintinline{kotlin}{Sequence} betekent dat er geen oplossingen zijn gevonden.
Een \mintinline{kotlin}{Result.success} met \mintinline{kotlin}{Substitutions} representeert een oplossing met de resulterende substituties (die leeg kan zijn).
Een \texttt{Result.failure} betekent een fout of bijzondere logica die afgehandeld moet worden.
Er werden twee interfaces gedefinieerd:
\begin{minted}{kotlin}
interface Resolvent {
fun solve(goal: Goal, substitutions: Substitutions): Answers
}
interface Satisfiable {
fun satisfy(substitutions: Substitutions): Answers
}
\end{minted}
Klassen die \mintinline{kotlin}{Resolvent} implementeren kunnen een \textit{goal} oplossen, bijvoorbeeld een database of een regel (\textit{rule}).
Klassen die \mintinline{kotlin}{Satisfiable} implementeren kunnen worden geëvalueerd, bijvoorbeeld operatoren.
De verschillende Prolog termen werden voorgesteld als klassen op basis van
\href{https://www.swi-prolog.org/pldoc/man?section=glossary}{SWI-Prolog's Glossary of Terms},
met bijkomende inspiratie uit~\cite{deransart-1996}.
\section{Evaluatiestrategie}\label{sec:evaluatiestrategie}
% KERN: Evaluatiestrategie
Ghent Prolog maakt gebruik van een depth-first zoekstrategie.
Op het moment dat de databank een goal gevraagd wordt (\textit{query}), worden de volgende stappen doorlopen:
\begin{enumerate} \begin{enumerate}
\item De databank geeft de goal beurtelings door aan de overeenkomende clauses, aan de hand van \mintinline{kotlin}{solve}. \item Lexing and parsing
\item Voor elke clause wordt de goal met de head geünificeerd, wat nieuwe substituties kan introduceren. \item Preprocessor
\item De body van de clause wordt geëvalueerd (\mintinline{kotlin}{Body.satisfy}), die zo de nieuwe goal wordt. \item Programma en Repl
Deze procedure wordt herhaald totdat de goal \mintinline{prolog}{true} of \mintinline{prolog}{false} is.
\item Het programma zal backtracken naar de functie die de laatste stap uitvoerde, en de pas geïntroduceerde substituties omhoog doorgeven.
Daar wordt de juiste logica uitgevoerd, of het resultaat wordt verder doorgegeven aan de volgende stap.
\end{enumerate} \end{enumerate}
Doorheen dit proces kunnen variabelen hernoemd worden aan de hand van \mintinline{prolog}{numbervars/1}. % Parser maakt gebruik van welk Grammar???
Een schematisch overzicht van dit proces is te zien in figuur~\ref{fig:renaming}.
% TODO Verklarende figuur met substitutie toevoegen % Preprocessor om parser eenvoudig te houden (eventueel later eigen implementatie
% Overzicht van geïmplementeerde predicaten in appendix. % Interfaces: satisfiable, resolvent
Operator-specifieke logica bevindt zich in de klassen van de operatoren zelf.
\begin{figure}[H]
\centering
\includegraphics[width=0.4\textwidth]{renaming}
\caption{Voorbeeld van een substitutie met variable renaming.}\label{fig:renaming}
\end{figure}
In de volgende subsecties worden de belangrijkste onderdelen van de evaluatiestrategie in meer detail besproken.
\subsection{Unificatie}\label{subsec:unificatie} \subsection{Unificatie}\label{subsec:unificatie}
Het unificatie-algoritme is gebaseerd op Robinsons Unificatie-algoritme, zoals beschreven door~\cite{boizumault-1993}, met inspiratie van~\cite{russell2016}. Zoals beschreven in Artificial Intelligence a Modern Approach. Algoritme is geïnspireerd door
Merk op dat er gebruik gemaakt wordt van de \textit{occurs check}.
\subsection{Cut}\label{subsec:cut} \section{Implementatie}\label{sec:implementatie}
De cut operator geeft altijd een \mintinline{kotlin}{Result.failure(AppliedCut)} terug wanneer \mintinline{kotlin}{satisfy} wordt opgeroepen. % Kotlin, libraries
Deze uitzondering moet dan afgehandeld worden door de aanroepende functie, wat meestal resulteert in het teruggeven van de eerstvolgende oplossing en het onderbreken van de logica.
\subsection{Meta abstracties}\label{subsec:meta-abstractions} % Data representatie: klassen, satisfiable, resolvent
% KERN: Wat wordt ondersteund? %% Evaluatie strategie
Ghent Prolog ondersteunt meta abstracts zoals \mintinline{prolog}{functor/3}, \mintinline{prolog}{arg/3}, \mintinline{prolog}{=../2} en \mintinline{prolog}{clause/2}.
Daarnaast werden ook de operatoren \mintinline{prolog}{reset/3} en \mintinline{prolog}{shift/1} ingebouwd.
Die laten toe om \textit{delimited continuations} te gebruiken.
% KERN: Hoe wordt dat ondersteund? % Overzicht van geïmplementeerde predicaten in appendix.
De ingebouwde ondersteuning van delimited continuations maakt opnieuw gebruik vaan een uitzondering.
Deze keer heet die \mintinline{kotlin}{Result.failure(AppliedShift)}, die de nieuwe substituties, doorgespeeld term (\textit{ball}) en de nieuwe \textit{continuatie}.
Net zoals bij de cut operator, moet deze uitzondering afgehandeld worden door de aanroepende functie.
In dit geval zal de \mintinline{kotlin}{AppliedShift} steeds doorgespeeld worden, totdat de \mintlinline{kotlin}{Reset} de uitzondering opvangt.
Daarna gaat het programma verder met de nieuwe substituties en continuatie.
% Belangrijkste delen zijn Clause.satisfy
\section{Resultaat}\label{sec:resultaat} \section{Resultaat}\label{sec:resultaat}
De implementatie van Ghent Prolog ondersteunt de gevraagde functionaliteit, waaronder database operaties en meta abstracties. % Code wordt lelijk en overzichtelijk. Door de geneste datatypes veel boilerplate.
De architecturele verschillen met SWI-Prolog zijn echter groot, wat zowel positieve als negatieve gevolgen heeft.
% KERN: Uitbreidbaarheid \subsection{Afwijkingen van SWI-Prolog}\label{subsec:afwijkingen}
\textbf{De architectuur van Ghent Prolog is modulair en uitbreidbaar.}
Eens de evaluatiestrategie en datastructuren zijn gedefinieerd, is het eenvoudig om extra ingebouwde operatoren toe te voegen.
Een volledig overzicht van de geïmplementeerde predicaten, waaronder extra's en uitbreidingen, kan teruggevonden worden in sectie~\ref{sec:predicaten}.
% KERN: Nesting probleem % Occurs check
\textbf{Code wordt snel onoverzichtelijk} door het gebruik van \mintinline{kotlin}{Sequence} en \mintinline{kotlin}{Result}.
Belangrijke logica zit genest in onduidelijke boilerplate.
De code in~\ref{lst:nesting} komt bijvoorbeeld in de meeste termen voor, weliswaar in verschillende vorm.
\begin{listing}[H]
\begin{minted}{kotlin}
/* Function entry logic */
unifyLazy(a, b, subs).forEach { firstResult ->
firstResult.map { firstSubs ->
/* First stage logic, e.g. preparing the body etc. */
c.satsify(firstSubs).forEach { secondResult ->
secondResult.fold(
onSuccess = { secondSubs ->
/* End result logic */
yield(Result.success(firstSubs + secondSubs))
},
onFailure = { failure ->
when (failure) {
is AppliedCut -> /* Cut logic */
is AppliedShift -> /* Shift logic */
} } ) } } }
\end{minted}
\caption{Voorbeeld van geneste boilerplate code}\label{lst:nesting}
\end{listing}
% KERN: Overerving zorgt voor boilerplate
\textbf{De implementatie bevat boilerplate code} door het gebruik van overerving en interfaces in de klassenrepresentatie van termen.
Deze methode wordt gebruikt om de onderlinge relaties tussen de verschillende termen te beschrijven.
Hoewel nuttig voor de representatie van de AST en generieke functies, moeten de meeste klassen de \mintinline{kotlin}{satsify} en \mintinline{kotlin}{solve} methoden overschrijven.
Dit zorgt voor boilerplate code en verspreidt de logica over verschillende klassen.
Daarnaast kan het leiden tot verlies van type-informatie wanneer generieke functies en type-specifieke functies worden gemengd.
\subsection{Functionele afwijkingen van SWI-Prolog}\label{subsec:afwijkingen}
% TODO Maak appendix?
% KERN: Functionele afwijkingen
De huidige versie van Ghent Prolog heeft functionele afwijkingen van SWI-Prolog:
\begin{itemize}
\item Door het gebruik van de \textit{occurs check} is het niet mogelijk om een oplossing te vinden voor recursieve unificatie.
Voor \mintinline{prolog}{?- X = f(X).} vindt SWI-Prolog de oplossing \mintinline{prolog}{X = f(f(X))}, maar Ghent Prolog geeft \texttt{false} terug.
\item Ghent Prolog maakt geen gebruik van SLD-resolutie, in tegenstelling tot ISO Prolog en SWI-Prolog (\cite{toman-2008}).
\item In de REPL wordt er niet meteen teruggekeerd naar de prompt als een query maar één oplossing heeft.
Dit is een artifact om oplossingen die de database aanpassen, bijvoorbeeld \mintinline{prolog}{retract/1}, pas uit te voeren wanneer de gebruiker dat expliciet vraagt.
Het gebruik van een iterator en \mintinline{kotlin}{it.hasNext()} zou al de volgende oplossing genereren.
Verder wordt ook de puntkomma (\texttt{;}) pas herkend na een newline.
\item Voorlopig is het niet mogelijk om ingebouwde operatoren te overschrijven met \mintinline{prolog}{assert/1} of \mintinline{prolog}{retract/1}.
Dit is een gevolg van het gebruik van de preprocessor.
\end{itemize}
% 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} \section{Toekomstig werk}\label{sec:toekomstig-werk}
% KERN: Wat moet volgende keer anders? % Stack gebruiken
Bij de ontwikkeling van een variant van Ghent Prolog, wordt er best aandacht besteed aan de volgende zaken:
\begin{itemize}
\item Het gebruik van een stack voor choicepoints en andere informatie om het gebruik van exceptions weg te werken en eenvoudiger choicepoints te kunnen manipuleren.
Zo kan bijvoorbeeld de cut operator transparanter \textit{committen} tot de huidige oplossing door in één stap de juiste choicepoints te verwijderen, zonder dat elke operator een \texttt{AppliedCut} moet afhandelen.
\item Het gebruik van een visitor-patroon in plaats van overerving, om boilerplate te verminderen, zoals aangegeven in sectie~\ref{sec:resultaat}.
\end{itemize}
\section{Conclusie}\label{sec:conclusie} \section{Conclusie}\label{sec:conclusie}
% KERN: Niet equivalent.
Ghent Prolog is duidelijk een proof of concept project.
Het kan nog lang niet als equivalent van SWI-Prolog beschouwd worden.
% KERN: Wat heb ik eruit gehaald?
Het implementeren ervan en het onderzoeken van de (voorlopig) ingebouwde functionaliteit biedt echter een goed inzicht in de werking van Prolog.
Het geeft een beter begrip van de ingebouwde operatoren en hoe die interageren.
Persoonlijk vond ik de moeilijkste stap het opzetten van de evaluatie-strategie.
Daarna ging het toevoegen van extra operatoren en functionaliteit vrij vlot.
Ik ben ondertussen bezig met het zoeken van een manier om een bronbestand te schrijven waarmee de som van de getallen in een interval berekend wordt, aan de hand van \mintinline{prolog}{read/1}, \mintinline{prolog}{between/3} en delimited continuations.
\printbibliography
\appendix \appendix
\newpage \newpage
\section{Lexing, parsing en preprocessing}\label{sec:lexing-parsing-preprocessing}
% KERN: Overzicht
Traditioneel zijn de lexer en parser aparte componenten.
Om tijd te besparen werd echter voor het lexen en parsen van Prolog broncode en REPL-invoer gebruik gemaakt van de \texttt{better-parse} bibliotheek.
Een gecompartimentaliseerde, onafgewerkt variant wordt besproken in sectie~\ref{subsec:onafgewerkte-lexer-parser}.
% KERN: Grammatica
De parser maakt gebruik van een vereenvoudigde Prolog grammatica, gebaseerd op
\href{https://github.com/antlr/grammars-v4/blob/master/prolog/prolog.g4}{de ANTLR Prolog grammatica},
\href{https://sicstus.sics.se/sicstus/docs/3.7.1/html/sicstus_45.html#SEC370}{SICStus Prolog Full Prolog Syntax} en
\href{https://github.com/simonkrenger/ch.bfh.bti7064.w2013.PrologParser/blob/2c06e5a221c1cc51ba766304250749a7f0caed8c/doc/prolog-bnf-grammar.txt}{simonkrenger/PrologParser's BNF}.
De uiteindelijk gebruikte grammatica kan teruggevonden worden in de \texttt{parser/grammars}.
% KERN: Simpliciteit en preprocessor
Omdat de lexer en parser niet op maat gemaakt zijn, worden ze bewust zo eenvoudig mogelijk gehouden.
Hun verantwoordelijkheid is het omzetten van inputtekst naar een basis Abstract Syntax Tree (AST), die enkel uit generieke Prolog termen bestaat.
Merk op dat de parser ook verantwoordelijk is voor operator precedentie en associativiteit, zoals besproken wordt in sectie~\ref{subsec:operator-precedence}.
Daarna worden de termen in de AST door de preprocessor omgezet naar specifieke klassen die de ingebouwde operatoren voorstellen.
Termen worden herkend aan de hand van hun functor en ariteit.
Na de preprocessor is de AST klaar om gebruikt te worden door de evaluatie-fase.
\subsection{Onafgewerkte Lexer en Parser implementatie}\label{subsec:onafgewerkte-lexer-parser}
% KERN: Introductie vorige implementatie
Origineel werden de lexer en parser op maat gemaakt, zonder het gebruik van een parser library.
De lexer en parser waren 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 parser was een recursive descent parser.
De voorlopige implementatie kan nog steeds teruggevonden worden op commit
\href{https://github.com/Logisch-Programmeren/project2425-tdpeuter/tree/d5632e92173abf443251d2445de31f03b696b1d0/src}{d5632e9}.
\section{Aanvullende opmerkingen}\label{sec:aanvullende-opmerkingen} \section{Aanvullende opmerkingen}\label{sec:aanvullende-opmerkingen}
\subsection{Operator precedentie en associativiteit}\label{subsec:operator-precedence} \subsection{Operator precedence en associativiteit}\label{subsec:operator-precedence}
Ghent Prolog ondersteunt operator precedentie en associativiteit. Mijn implementatie heeft volledig ondersteuning voor operator precendentie 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. % TODO Link naar prolog tabel
Operator precedentie en associativiteit werd geïmplementeerd volgens de~\href{https://www.swi-prolog.org/pldoc/man?section=operators}{SWI-Prolog documentatie}.
\subsection{Database bewerkingen}\label{subsec:database}
Ghent Prolog laat toe om tijdens de programma-uitvoering database bestanden te laden met behulp van de \mintinline{prolog}{consult/1} predicaat.
De ingeladen predicaten worden als \mintinline{prolog}{static} gemarkeerd, maar kunnen \mintinline{prolog}{dynamic} worden met behulp van het \mintinline{prolog}{dynamic/1} predicaat.
Dit is analoog aan SWI-Prolog.
\subsection{Test driven development}\label{subsec:ttd} \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}}. Doorheen de ontwikkeling van grote delen van mijn implementatie heb ik gebruik gemaakt van Test Driven Development door eerst een klasse te definiëren met Kotlin TODO() implementaties, vervolgens testen te schrijven die falen en pas daarna mijn functies te implementeren todat de testen slagen.
\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
% TODO Crafting interpreters
% TODO Dmitri 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} \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 \texttt{./src/gpl}. 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 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}. De ingediende JAR kan ook handmatig opgeroepen worden met \texttt{java -jar ./build/gpl.jar}.
\subsection{Testen}\label{subsec:testen} 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. De testen kunnen uitgevoerd worden door de meeste IDE's.
Alternatief kunnen de testen uitgevoerd worden met \texttt{./gradlew test}. 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} \section{Overzicht van geïmplementeerde predicaten}\label{sec:predicaten}
Deze sectie geeft een overzicht van de geïmplementeerde predicaten in Ghent Prolog, gesorteerd volgens de categorieën die in
\href{https://www.swi-prolog.org/pldoc/man?section=builtin}{de SWI-Prolog documentatie}
gebruikt worden.
\begin{multicols}{2} \begin{multicols}{2}
\begin{itemize}[label={}] \begin{itemize}[label={}]
\item \textbf{Analysing and Constructing Terms} \item \textbf{Analysing and Constructing Terms}
\begin{itemize} \begin{itemize}
\item \texttt{functor/3} \item \texttt{functor/3}
\item \texttt{arg/3} \item \texttt{arg/3}
\item \texttt{=../2} \item \texttt{=..}
\item \texttt{numbervars/1} \item \texttt{numbervars/1}
\item \texttt{numbervars/3} \item \texttt{numbervars/3}
\end{itemize} \end{itemize}
@ -423,34 +220,8 @@
\end{itemize} \end{itemize}
\end{multicols} \end{multicols}
\section{Bestaande Prolog implementaties}\label{sec:prolog-implementaties}
Tijdens mijn onderzoek naar Prolog implementaties, kwam ik verschillende bestaande Prolog implementaties tegen die niet vermeld worden in~\cite{enwiki:1274527056}.
Daarom zou ik durven stellen dat er geen gebrek is aan Prolog implementaties, maar dat er een gebrek is aan \emph{goede} Prolog implementaties.
Vaak zijn deze implementaties niet meer dan een proof of concept.
Ze waren enkel nuttig als inspiratie om specifieke problemen die zich tijdens de ontwikkeling van Ghent Prolog voordeden op te lossen.
Voorbeelden van zulke implementaties zijn:
\begin{itemize}
\item \href{https://github.com/adamjstewart/prolog}{adamjstewart/prolog}, in OCaml
\item \href{https://plzoo.andrej.com/language/miniprolog.html}{miniprolog}, in OCaml
\item \href{https://github.com/benjamin-hodgson/Amateurlog}{benjamin-hodgson/Amateurlog}, in C\#
\item \href{https://github.com/fmidue/prolog}{fmidue/prolog}, in Haskell
\item \href{https://github.com/patirasam/Prolog-Interpreter}{patirasam/Prolog-Interpreter}, in Python
\end{itemize}
Van de implementaties die wel vermeld worden in~\cite{enwiki:1274527056}, zijn
\href{https://www.swi-prolog.org/}{SWI-Prolog},
\href{https://sicstus.sics.se/index.html}{SICStus Prolog} en
\href{https://dobrev.com/}{Strawberry Prolog} de meest interessante.
\section{Dankwoord}\label{sec:dankwoord} \section{Dankwoord}\label{sec:dankwoord}
Bedankt, \href{https://www.swi-prolog.org/user/view_profile?user=c86f61d8-c201-11e6-84af-00163e986a2a}{LogicalCaptain} 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.
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} \end{document}

View file

@ -1,15 +0,0 @@
printer :-
writeln("Good evening everyone!"),
write("Thanks for coming "),
shift(Name),
write(Name), write(", ").
main :-
writeln("/Ceremony starts/"),
reset(printer, Name, Cont),
\+ \+ ( Name = "John", call(Cont) ),
\+ \+ ( Name = "Mary", call(Cont) ),
writeln("and my parents!"),
writeln("/Ceremony ends/").
:- initialization(main).

View file

@ -65,7 +65,6 @@ class Examples {
) )
fun meta() = listOf( fun meta() = listOf(
Arguments.of("ceremony.pl", "/Ceremony starts/\nGood evening everyone!\nThanks for coming John, Mary, and my parents!\n/Ceremony ends/\n"),
Arguments.of("continuations.pl", "Inside test\nEntering reset\nAfter reset\nCalling Cont(2)\nIn test X = 5; done\nCalling Cont(4)\nIn test X = 9; done\n"), Arguments.of("continuations.pl", "Inside test\nEntering reset\nAfter reset\nCalling Cont(2)\nIn test X = 5; done\nCalling Cont(4)\nIn test X = 9; done\n"),
Arguments.of("mib_voorbeelden.pl", "b\nf(b)\nf(g(a,a),h(c,d),i(e,f))\nf(g(a,a),h(c,c),i(e,f))\nf(g(a,a),h(c,c),i(e,e))\n") Arguments.of("mib_voorbeelden.pl", "b\nf(b)\nf(g(a,a),h(c,d),i(e,f))\nf(g(a,a),h(c,c),i(e,f))\nf(g(a,a),h(c,c),i(e,e))\n")
) )