Sync
This commit is contained in:
parent
e5ef4244e3
commit
a5110f5a9d
3 changed files with 152 additions and 39 deletions
|
@ -1,11 +0,0 @@
|
|||
@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}
|
||||
}
|
21
documentatie/bibliography.bib
Normal file
21
documentatie/bibliography.bib
Normal file
|
@ -0,0 +1,21 @@
|
|||
@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]"
|
||||
}
|
||||
|
||||
@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}
|
||||
}
|
|
@ -5,62 +5,134 @@
|
|||
|
||||
\usepackage{amsmath}
|
||||
\usepackage[dutch]{babel} % Nederlands taal
|
||||
\usepackage[style=apa]{biblatex} % Bronnen
|
||||
\usepackage{enumitem} % Aanpasbare lijsten
|
||||
\usepackage[margin=1in]{geometry} % Sane marges
|
||||
\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}
|
||||
|
||||
% Document
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\section{Inleiding}\label{sec:inleiding}
|
||||
\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.
|
||||
}
|
||||
|
||||
% Uitvoeren van testen ref appendix
|
||||
|
||||
\section{Architectuur}\label{sec:architectuur}
|
||||
\section{Overzicht}\label{sec:overzicht}
|
||||
|
||||
% Overzicht van programma-loop
|
||||
% 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:
|
||||
|
||||
\begin{itemize}
|
||||
\item \href{https://github.com/h0tk3y/better-parse}{\texttt{better-parse}}, voor het parsen van een gegeven grammatica,
|
||||
\item \href{https://github.com/xenomachina/kotlin-argparser}{\texttt{kotlin-argparser}}, voor het gebruik van command-line argumenten.
|
||||
\end{itemize}
|
||||
|
||||
% KERN: Hoe ziet Ghent Prolog er abstract uit?
|
||||
De interpreter bestaat uit een aantal fases, die zo onafhankelijk mogelijk zijn om de implementatie modulair en uitbreidbaar te maken.
|
||||
|
||||
\begin{enumerate}
|
||||
\item Lexing and parsing
|
||||
\item Preprocessor
|
||||
\item Programma en Repl
|
||||
\item Programma en read-eval-print loop (REPL)
|
||||
\end{enumerate}
|
||||
|
||||
% Parser maakt gebruik van welk Grammar???
|
||||
|
||||
% Preprocessor om parser eenvoudig te houden (eventueel later eigen implementatie
|
||||
\section{Lexing, parsing en preprocessing}\label{sec:lexing-parsing-preprocessing}
|
||||
|
||||
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.
|
||||
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}.
|
||||
|
||||
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.
|
||||
Daarna worden de termen in de AST omgezet naar specifieke klassen die de ingebouwde operatoren voorstellen.
|
||||
|
||||
|
||||
\section{Programma en REPL}\label{sec:programma-repl}
|
||||
|
||||
% KERN: Datastructuur
|
||||
Ghent Prolog maakt gebruik van functie-oproepen streams om het backtracking mechanisme te implementeren.
|
||||
Bijzondere logica met betrekking tot \textit{choicepoints} en foutenafhandeling maakt gebruik van de Kotlin \texttt{Result} klasse.
|
||||
Om de resultaten van unificatie en evaluatie lazy te verwerken, wordt er gebruik gemaakt van Kotlin \texttt{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 \texttt{Sequence} betekent dat er geen oplossingen zijn gevonden.
|
||||
Een \texttt{Result} met een \texttt{Substitutions} representeert een oplossing met de resulterende substituties (die leeg kan zijn).
|
||||
Een \texttt{Result} met een \texttt{Failure} betekent een fout of bijzondere logica die afgehandeld moet worden.
|
||||
|
||||
Er werden twee interfaces gedefinieerd:
|
||||
|
||||
\begin{minted}{kotlin}
|
||||
interface Resolvent {
|
||||
fun resolvent(goal: Goal, substitutions: Substitutions): Answers
|
||||
}
|
||||
|
||||
interface Satisfiable {
|
||||
fun satisfy(substitutions: Substitutions): Answers
|
||||
}
|
||||
\end{minted}
|
||||
|
||||
Klassen die \texttt{Resolvent} implementeren kunnen een goal oplossen, bijvoorbeeld een database of een regel (\textit{rule}).
|
||||
Klassen die \texttt{Satisfiable} implementeren kunnen worden geëvalueerd, bijvoorbeeld operatoren.
|
||||
|
||||
\subsection{Evaluatiestrategie}\label{subsec:evaluatiestrategie}
|
||||
|
||||
% KERN: Evaluatiestrategie
|
||||
Ghent Prolog maakt gebruik van een depth-first zoekstrategie.
|
||||
Op het moment dat de databank een goal gevraagd wordt (\textit{query}), geeft die de goal beurtelings door aan de overeenkomende clauses, aan de hand van \texttt{solve}.
|
||||
Eerst wordt de goal met de head van de clause geünificeerd, wat nieuwe substituties kan introduceren.
|
||||
Daarna wordt de body van de clause geëvalueerd (\texttt{body.solve}), die zo de nieuwe goal wordt.
|
||||
Deze procedure wordt herhaald totdat de goal \texttt{true} of \texttt{false} is.
|
||||
Vervolgens zal het programma backtracken naar de functie die de laatste stap uitvoerde, en de pas geïntroduceerde substituties omhoog doorgeven.
|
||||
Daar kan dan logica uitgevoerd worden, of het resultaat verder doorgegeven worden aan de volgende stap.
|
||||
|
||||
% 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.
|
||||
|
||||
% 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}
|
||||
\subsection{Cut}\label{subsec:cut}
|
||||
|
||||
% 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
|
||||
\subsection{Meta abstracties}\label{subsec:meta-abstractions}
|
||||
|
||||
% 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.
|
||||
% Code wordt lelijk en onoverzichtelijk. Door de geneste datatypes veel boilerplate.
|
||||
|
||||
Omdat er veel overerving is, waarbij toch steeds methoden moeten worden overschreven, is er vaak boilerplate code nodig.
|
||||
Waarschijnlijk is een visitor-patroon beter geschikt.
|
||||
|
||||
\subsection{Afwijkingen van SWI-Prolog}\label{subsec:afwijkingen}
|
||||
% TODO Maak appendix?
|
||||
|
||||
% Occurs check
|
||||
|
||||
|
@ -70,20 +142,25 @@
|
|||
% 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}
|
||||
|
||||
\printbibliography
|
||||
|
||||
\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.
|
||||
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}.
|
||||
|
@ -94,7 +171,8 @@
|
|||
|
||||
\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
|
||||
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.
|
||||
|
||||
|
@ -103,25 +181,28 @@
|
|||
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}.
|
||||
Er wordt 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}
|
||||
\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}. Resultaten worden naar \texttt{stdout} geschreven of kunnen bekeken worden met
|
||||
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}
|
||||
|
@ -223,8 +304,30 @@
|
|||
\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.
|
||||
|
||||
\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\#
|
||||
\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 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.
|
||||
Bedankt, LogicalCaptain
|
||||
% TODO Link naar account
|
||||
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}
|
||||
|
|
Reference in a new issue