NetProLogo (NetLogo + Prolog) is a NetLogo extension that allows running Prolog code inside NetLogo in order to take advantage of Prolog features to provide NetLogo agents (turtles, links and patches... or the observer) with reasoning capabilities.
This repo contains an updated version compatible with SWI-Prolog, and uses the JPL library that comes with SWI-Prolog and provides a Java API to interact with it.
The last NetProLogo version can be downloaded here.
The extension comes with a set of sample models in order to enlighten extension usage. Some of the sample models load an auxiliary Prolog file from the same directory using absolute paths, thus it could be necessary to fix the path inside the NetLogo model in order to point to the required prolog file.
Any feedback you can provide regarding use cases, installation issues or future improvements will be very appreciated.
Before using the extension make sure you have installed the proper NetLogo and SWI-Prolog versions. Different SWI-Prolog versions can be found here.
- NetPrologo is compatible with SWI-Prolog version 9.0.4 for x86_64-linux. Previous versions are not guaranteed to work.
- Macos and Windows are not tested, but should work with the right classpath settings
- Note that some SWI-Prolog packages for Linux comes without the JPL library. In this case you can install it separately.
- In many Linux repositories this library is called
swi-prolog-java
(alternatively it could be swi-prolog-jpl). - You can find the path that contains these libraries by running
swipl --dump-runtime-variables
, and reading the value ofPLLIBDIR
- check that
PLLIBDIR
contains the native library:- Windows:
C:\Program Files (x86)\swipl\bin\
(there should be files likelibswipl.dll
,jpl.dll
, etc.) - Mac OS:
/opt/local/lib/swipl-x.x.x/lib/x86_64-darwinx.x.x/
(there should be files likelibjpl.dylib
) - Linux:
/usr/lib/swi-prolog/lib/x86_64-linux/
(there should be files likelibjpl.so
)
- Windows:
- In many Linux repositories this library is called
-
Go to the NetLogo folder. In
extensions
folder extract the content of the Zip file in a netprologo folder. -
To use the bundled version of Java you can run the
Netlogo
file- Before you run check that you have the jpl.jar file in the
extensions/netprologo
folder (should be included by default) - Modify the
lib/app/netlogo.cfg
file, and add the following just before the last line:
java-options=-Djava.library.path=<PLLIBDIR>
- Before you run check that you have the jpl.jar file in the
-
To use the system version of Java you can run the
netlogo-gui.sh
file- Before you run it you should edit it, and add the following just before the last line:
JVM_OPTS=($JVM_OPTS -Djava.library.path="<PLLIBDIR>")
ABSOLUTE_CLASSPATH="$ABSOLUTE_CLASSPATH:<PLLIBDIR parent>/jpl.jar"
- Before you run it you should edit it, and add the following just before the last line:
In order to use NetProLogo load the extension in the first line of the model:
extensions[netprologo]
Note for Windows users: When typing paths inside Prolog code you must use Unix flavor paths (i.e. using slash /
, not backslash \
).
The following primitives are available:
- Open a new Prolog query:
<Boolean> netprologo:run-query <PrologCall-String>
. This primitive will close a former query after doing the call, thus it will not be possible to obtain more solutions from it. It returnstrue
if the query was successful (to obtain query results seerun-next
anddereference-var
) or the solution is true, orfalse
otherwise. - Build Prolog Call:
<Query-String> netprologo:build-prolog-call <Rear-Query-String> <Value-1> ... <Value-N>
. It is useful to make automatic arguments replacement in order to build the Prolog call, especially when using lists as arguments. Arguments are automatically translated from NetLogo to Prolog. The place of every argument should be marked with?X
in theRear-Query-String
whereX
is an integer argument ID (as it is common in NetLogo). The same argument can be used more than once by placing the same ID twice in theRear-Query-String
. Example:
let call (netprologo:build-prolog-call "assert(fact(?1,?2,?3,?2))" nl-arg1 nl-arg2 nl-arg3)
The result will be something like:
assert(fact(nl-arg1,nl-arg2,nl-arg3,nl-arg2))
- Advance till next solution:
<Boolean> netprologo:run-next <>
. Load the next solution of the open query. It returnsfalse
if there are no more results to be read, in this case, the query is closed automatically. If it returnstrue
, this next solution is ready to be read (seedereference-var
). - Read the value of a variable for the last loaded solution:
<List/String/Number> netprologo:dereference-var <Var-name>
. In the current version it can readStrings
, numbers (Float
orInteger
) andNetLogo lists
made of any of the former elements, includingnested lists
. Currently, other prolog data types likefunctors
are not supported. - Close active query:
<> netprologo:close-query <>
. Closes the last active query. Normally this primitive is not necessary sincerun-query
primitive automatically closes the query before opening a new one. - Make a Prolog query to obtain several solutions: In the former NetProLogo version (based on a GPJ) it was possible to have multiple Prolog instances running at the same time (and therefore multiple active queries). However in the current version this is not longer possible, as it is just an interface between NetLogo and the local SWI-Prolog installation. That is why some primitives have been added to allow querying and storing multiple solutions, to be read later, before running a new query:
- Open a query and store N solutions:
<Solution-storage> run-for-n-solutions <N> <PrologCall-String>
. Opens a new Prolog query, reads and store the firstN
solutions. It returns a reference to the solutions storage. - Advance till next stored solution:
<Boolean> netprologo:next-stored-solution <Solution-storage>
. Load the next solution of the stored query. It returnsfalse
if there are no more results to be read. If it returnstrue
, this next solution is ready to be read (seedereference-stored-var
). - Read the value of a variable for the last loaded solution from storage:
<List/String/Number> netprologo:dereference-stored-var <Solution-storage> <Var-name>
. In the current version it can readStrings
, numbers (Float
orInteger
) andNetLogo lists
made of any of the former elements, includingnested lists
. Other Prolog data types likefunctors
are not supported.