Using JSON Prolog to communicate with KnowRob (under construction)

The following tutorial will show how to query the knowledge base, KnowRob, for information using prolog queries within LISP and CRAM, using the json-prolog package, and also how to process and extract the data from the gained results.

Prerequisites

We will assume that the previous tutorials have already been completed, and therefore CRAM, roslisp_repl and ROS have been installed. Make sure you have Java 8 and Gradle 5.1 or higher, already installed. Otherwise you won't be able to build KnowRob.

Installation

We need to install KnowRob. For that, please follow the tutorial here: http://www.knowrob.org/installation The basic KnowRob installation is enough. Note: make sure to select the right branch for your current ROS version.

Installation troubleshooting

If it complains about missing swi-prolog, you can install it via:

  sudo apt-get install swi-prolog

Make sure however, that it is version 7. There are major problems with locations of libraries with version 8. apt-get should install version 7 by default. To make sure, you can check it with:

  
  dpkg -s swi-prolog

Launch

In addition to a roscore and the roslisp_repl you need to launch json_prolog with the following command:

  roslaunch json_prolog json_prolog.launch 
  

Adding dependencies to your code

in your *.asd* add cram-json-prolog as a dependency. For convenience, you can also add #:json-prolog to the :use part of the *package.lisp*. Don't forget to add cram_json_prolog to the *package.xml* as build and run dependency.

Once that is done, load your package as usual and start a ros-node.

  (roslisp-utilities:startup-ros)
  

If you don't have a robot description currently published, use:

  (start-ros-node "my-node")

Cram-json-prolog

There are multiple ways to call a query, depending on if one needs only one result or all possible results, etc. We will go through them in the following, explaining the differences between them. In general, it helps if one is familiar with prolog, since essentially everything that can be done in prolog, can be done via cram-json-prolog as well. Some Prolog tutorials are provided here: http://www.swi-prolog.org/pldoc/man?section=quickstart

prolog-simple-1

The simplest way is using the prolog-simple-1 function, which gets the query as a string parameter, and closes the query after the first result, returning the first result only.

  (json-prolog:prolog-simple-1 "member(X, [1,2,3])")

The result in this case is:

  (((?X . 1)))
  

X being the variable we asked Prolog to fill with a value. Whenever Prolog returns a value for a varibale, the variable name gets prefixed with a questionmark. “1” is the first value in the list we passed on to the *member* function of prolog. The *member* function is true if the element is a member of the given list, or in this case since it is a variable, it will return the first element of the list.

If we want to check, if a certain number is member of the list, we must declare the variable accordingly. e.g.

  (json-prolog:prolog-simple-1 "X=2, member(X, [1,2,3])")

Which will return

  (((?X . 2)))
  

One could also pose a query like this:

  (json-prolog:prolog-simple-1 "member(2, [1,2,3])")

and while one would expect Prolog to return “true”, in json-prolog what we get is

  (NIL)

Meaning a list with only one element, the element being NIL. If one were to test this out within the prolog console itself, the result would be “true”. We can actually test this with json-prolog as well.

  (json-prolog:prolog-simple-1 "true")
  (NIL)
  
  (json-prolog:prolog-simple-1 "false")
  NIL
  

We can note that if the result is “true” we get returned a list, even if NIL is the only member of this list. If the result is “false”, we just get the element NIL as a result.