462 lines
24 KiB
TeX
462 lines
24 KiB
TeX
%! Author = tdpeuter
|
|
%! Date = 27/03/2025
|
|
|
|
\documentclass[11pt,a4paper]{article}
|
|
|
|
\usepackage{amsmath}
|
|
\usepackage[dutch]{babel} % Nederlands taal
|
|
\usepackage[style=apa]{biblatex} % Bronnen
|
|
\usepackage{enumitem} % Aanpasbare lijsten
|
|
\usepackage{float} % Figures
|
|
\usepackage[margin=2cm]{geometry} % Sane marges
|
|
\usepackage{graphicx} % Figures
|
|
\usepackage{hyperref} % Hyperlinks
|
|
\usepackage{minted} % Syntax highlighting
|
|
\usepackage{multicol} % Meerdere kolommen
|
|
\usepackage{url} % Beter geformatteerde URLs
|
|
|
|
\addbibresource{bibliography.bib}
|
|
|
|
\title{Ghent Prolog}
|
|
\author{Tibo De Peuter}
|
|
\date{\today}
|
|
|
|
\begin{document}
|
|
\maketitle
|
|
|
|
\abstract{
|
|
% 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.
|
|
}
|
|
|
|
|
|
\section{Overzicht}\label{sec:overzicht}
|
|
|
|
% KERN: Insteek
|
|
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}
|
|
\item De databank geeft de goal beurtelings door aan de overeenkomende clauses, aan de hand van \mintinline{kotlin}{solve}.
|
|
\item Voor elke clause wordt de goal met de head geünificeerd, wat nieuwe substituties kan introduceren.
|
|
\item De body van de clause wordt geëvalueerd (\mintinline{kotlin}{Body.satisfy}), die zo de nieuwe goal wordt.
|
|
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}
|
|
|
|
Doorheen dit proces kunnen variabelen hernoemd worden aan de hand van \mintinline{prolog}{numbervars/1}.
|
|
Een schematisch overzicht van dit proces is te zien in figuur~\ref{fig:renaming}.
|
|
|
|
% TODO Verklarende figuur met substitutie toevoegen
|
|
|
|
% Overzicht van geïmplementeerde predicaten in appendix.
|
|
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}
|
|
|
|
Het unificatie-algoritme is gebaseerd op Robinsons Unificatie-algoritme, zoals beschreven door~\cite{boizumault-1993}, met inspiratie van~\cite{russell2016}.
|
|
Merk op dat er gebruik gemaakt wordt van de \textit{occurs check}.
|
|
|
|
De broncode voor het algoritme kan teruggevonden worden in \texttt{prolog/logic/unification.kt}.
|
|
|
|
\subsection{Cut}\label{subsec:cut}
|
|
|
|
De cut operator geeft altijd een \mintinline{kotlin}{Result.failure(AppliedCut)} terug wanneer \mintinline{kotlin}{satisfy} wordt opgeroepen.
|
|
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}
|
|
|
|
% KERN: Wat wordt ondersteund?
|
|
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?
|
|
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.
|
|
|
|
De broncode voor de meta abstracties kan teruggevonden worden in
|
|
|
|
\texttt{prolog/builtins/delimitedContinuationsOperators.kt}.
|
|
|
|
|
|
\section{Resultaat}\label{sec:resultaat}
|
|
|
|
De implementatie van Ghent Prolog ondersteunt de gevraagde functionaliteit, waaronder database operaties en meta abstracties.
|
|
De architecturele verschillen met SWI-Prolog zijn echter groot, wat zowel positieve als negatieve gevolgen heeft.
|
|
|
|
% KERN: Uitbreidbaarheid
|
|
\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
|
|
\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}
|
|
|
|
|
|
\section{Toekomstig werk}\label{sec:toekomstig-werk}
|
|
|
|
% KERN: Wat moet volgende keer anders?
|
|
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}
|
|
|
|
% 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
|
|
\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}
|
|
|
|
\subsection{Operator precedentie en associativiteit}\label{subsec:operator-precedence}
|
|
|
|
Ghent Prolog 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{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}
|
|
|
|
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}}.
|
|
|
|
|
|
\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}.
|
|
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}.
|
|
|
|
\subsection{Testen}\label{subsec:testen}
|
|
|
|
De testen kunnen uitgevoerd worden door de meeste IDE's.
|
|
|
|
Alternatief kunnen de testen uitgevoerd worden met \texttt{./gradlew test}.
|
|
|
|
|
|
\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{itemize}[label={}]
|
|
\item \textbf{Analysing and Constructing Terms}
|
|
\begin{itemize}
|
|
\item \texttt{functor/3}
|
|
\item \texttt{arg/3}
|
|
\item \texttt{=../2}
|
|
\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{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}
|
|
|
|
Bedankt, \href{https://www.swi-prolog.org/user/view_profile?user=c86f61d8-c201-11e6-84af-00163e986a2a}{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}
|