How-to: How to add/remove/query facts#

This section describes how to add/remove/query the robot’s knowledge base.

Note

You might want to check first intro_knowledge_base to know more about ARI’s knowledge base.

You have two main options to access the knowledge base:

  • use the Python wrapper, that uses an idomatic python syntax to add/remove/query facts. If you are programming with Python, we recommend this approach. See section Python API.

  • use the ROS interface directly: the knowledge base exposes standard topics and services to manipulate knowledge. See section ROS API.

Using the knowledge base from Python#

The Python wrapper makes it easy to update or query the knowledge base from a Python script or application controller.

Our Python wrapper follows closely the API of the pykb library: pykb. pykb examples and documentation are largely applicable here as well.

If not already running, start the knowledge base:

rosrun knowledge_core knowledge_core

Then, create a new Python script and import the Python wrapper as follows:

1from knowledge_core.api import KB
2kb = KB()

You can then add/remove statements with kb += "s p o", kb += ["s1 p1 o1", "s2 p2 o2"], kb -= "s p o", etc.

Then let’s assume that we want to add the following facts to the kb: “ari is-a Robot”, “tiago is-a Robot”, and “stockbot is-a Robot”.

We can do it as it follows:

1with kb.KB() as kb:
2
3  kb += ["ari rdf:type Robot",
4         "tiago rdf:type Robot",
5         "stockbot rdf:type Robot"]

We can then query the knowledge base and to retrieve this information:

1for known_robot in kb["?robot rdf:type Robot"]:
2    print(known_robot)

If the facts have been correctly added, you should get ari, tiago, and stockbot as output.

Let’s now remove some facts from the knowledge base. Suppose we want to remove the following facts: “tiago rdf:type Robot”, and “stockbot rdf:type Robot”.

1kb -= ["tiago rdf:type Robot"]
2kb -= ["stockbot rdf:type Robot"]
3
4for known_robot in kb["?robot rdt:type Robot"]:
5    print(known_robot)

If the facts have been correctly removed, you should only get ari as output.

Refer to the pykb reference for more advanced examples, including subscribing to semantic events (ie, get notifications when eg a specific fact becomes true).

Using the knowledge base with the ROS API#

First, start the knowledge base:

rosrun knowledge_core knowledge_core

You should see the following output on your terminal:

KnowledgeCore
=============

Knowledge base started.

Available topics:
- /kb/add_fact [std_msgs/String]
- /kb/remove_fact [std_msgs/String]
- /kb/events/<id> [std_msgs/String] for each subscribed event

Available services:
- /kb/manage [knowledge_core/Manage]
- /kb/revise [knowledge_core/Revise]
- /kb/query [knowledge_core/Query]
- /kb/about [knowledge_core/About]
- /kb/lookup [knowledge_core/Lookup]
- /kb/sparql [knowledge_core/Sparql]
- /kb/events [knowledge_core/Event]

KnowledgeCore exposes two main topics, /kb/add_fact and /kb/remove_fact, to add/remove triples to the knowledge base. Both topics expect a simple string with 3 tokens separated by spaces (if the object is a literal string, use double quotes to escape it).

Note

The thrid topic, /kb/events/<id>, is used for events: you can subscribe to specific ‘semantic’ events (eg, a given fact becomes true), and get notified.

See the KnowledgeCore API documentation for details.

It also exposes the following services:

  • /kb/revise to add/remove facts using a synchronous interface

  • /kb/query to perform simple queries

  • /kb/manage to manage the knowledge base (including for instance the wipe-off of all the facts)

For more details about the API please refer to the KnowledgeCore API.

We are now ready to see how we can add, remove and query the knowledge base.

To add facts to the knowledge base, we can do it using the topics or the services. For instance, suppose we want to add the following facts: [ari rdf:type Robot, tiago rdf:type Robot, stockbot rdf:type Robot].

1# add facts using the /kb/add_fact topic
2facts_pub = rospy.Publisher("/kb/add_fact", String, queue_size=1)
3facts_pub.publish("ari rdf:type Robot")
4
5# add facts using the Revise service
6revise = rospy.ServiceProxy("/kb/revise", Revise)
7revise(statements=["tiago rdf:type Robot",
8                   "stockbot rdf:type Robot"],
9       method=ReviseRequest.ADD)

We can then query the knowledge base and check if we can retrieve this information.

1query = rospy.ServiceProxy("/kb/query", Query)
2
3results = query(patterns=["?robot rdf:type Robot"],
4                vars=[],
5                models=[])
6
7print(json.loads(results.json))

If the facts have been correctly added, you should get the following output:

[{'robot': 'stockbot'}, {'robot': 'tiago'}, {'robot': 'ari'}]

Let’s now remove some facts from the knowledge base. Suppose we want to remove the following facts: [tiago rdf:type Robot, stockbot rdf:type Robot].

1# either via topics...
2facts_pub = rospy.Publisher("/kb/remove_fact", String, queue_size=1)
3facts_pub.publish("tiago rdf:type Robot")
4
5# ...or with a service call
6revise = rospy.ServiceProxy("/kb/revise", Revise)
7revise(statements=["stockbot rdf:type Robot"],
8       method=ReviseRequest.DELETE)

We can then query the knowledge base again:

1query = rospy.ServiceProxy("/kb/query", Query)
2results = query(patterns=["?robot rdf:type Robot"],
3               vars=[],
4               models=[])
5
6print(json.loads(results.json))

If the facts have been correctly removed, you should get the following output:

[{'robot': 'ari'}]

Next steps#