../_images/tiagopro-icon.png ../_images/kangaroo-icon.png ../_images/tiago-icon.png ../_images/ari-icon.png ../_images/talos-icon.png ../_images/mobile-bases-icon.png

KnowledgeCore API#

KnowledgeCore uses the underlying framework of Description Logics to represent symbolic facts about the world, and reason about them. More specifically, KnowledgeCore uses the OWL/RDF language to represent facts (or statements).

If you have no prior experience with ontologies and/or OWL/RDF, we recommend you to read the W3C RDF Primer for a good overview of the language.

Statements#

Facts (or statements) are represented using triples subject predicate object. For instance: sky0 hasColor blue, john rdf:type Human.

KnowledgeCore currently only support binary predicates, using the infix syntax to represent symbolic statements as triples: subject predicate object.

Triples must follow the Turtle syntax: statements are represented as a single string, with the subject, predicate and object separated by a space character.

In a nutshell:

  • subjects and predicates must by valid RDF identifiers;

  • objects can be either RDF identifiers, or literals. String literals must be surrounded by double quotes.

  • RDF identifiers might include XML namespaces. Prefixes can be used (see below the list of recognised prefixes), separated with a semi colon. For instance: james rdf:type oro:Human

  • as the triples are actually parsed with the N3 grammar (a super-set of Turtle), the namespace/prefix can actually be omitted altogether. In that case, the default prefix of the OpenRobots Ontology (oro:) is used.

  • it follows that all the terms defined in the OpenRobots ontology (eg Robot) can be used without prefix, and all new terms added without a specific prefix will be added to the OpenRobots ontology namespace.

Triples might occasionaly also include variables (eg, unbound terms). Variables must start with a question mark ?. For instance: ["?agent sees obj1", "?agent rdf:type Human"]. Sets of triples that include variables are refered to as patterns by KnowledgeCore, and used as such in methods like find.

Instead of such named variables, you can also use * as an unnamed variable. For instance, kb["* rdf:type Agent"] would return the list of all agents.

Note however that if you mix named and unnamed variables, only the named variables will be returned: kb["?agent looksAt *"] would therefore return a list of agents looking at ā€˜somethingā€™.

Knowledge models#

Models can be understood as independent knowledge bases, meant for instance to store the (inferred) knowledge of the humans that are interacting with the robot.

The default model is the robotā€™s own knowledge, while for instance johnā€™s model might contain what the robot thinks that John knows.

../_images/perspective.svg

In the picture above, the robot might be able to compute that, while both the pawns are visible to the robot, only the green one is visible to the human. Therefore, the human might not know about it:

  • robotā€™s model:

["pawn1 hasColor green",
 "pawn1 isOn table0",
 "pawn2 hasColor red",
 "pawn2 isOn table0"
]
  • humanā€™s model:

["pawn1 hasColor green",
 "pawn1 isOn table0"
]

Several methods take an optional models parameter. If set to None or to an empty list, the method will update/query statements in the robotā€™s base cognitive model. If set to a list containing a single string all, all the existing models are update/queried. Otherwise, you can pass a list of models you want to update/query.

Python API#

Note

See Using the knowledge base from Python for example of the Python API usage.

class knowledge_core.api.KB#
__contains__(pattern)#

Returns True if either a concept - described by its ID or label - or a statement or a set of statement is present (or can be infered) in the ontology.

This allows syntax like:

if 'Toto' in kb:
    #...
if 'toto sees tata' in kb:
    #...

See also: KB.exist()

__getitem__(*args)#

This method introduces a different way of querying the ontology server. It uses the args (be it a string or a set of strings) to find concepts that match the pattern. An optional ā€˜modelsā€™ parameter can be given to specify the list of models the query is executed on.

Depending on the argument, 4 differents behaviours are possible:

  • with a string that can not be lexically split into 3 tokens (ie, a string that do not look like a s p o tuple), a lookup is performed, and matching resource are returned

  • with a single s p o pattern:
    • if only one of s, p, o is an unbound variable, returns the list of resources matching this pattern.

    • if 2 or 3 of the tokens are unbound variables (like kb["* * *"] or kb["* rdf:type *"]), a list of statements matching the pattern is returned.

  • with a list of patterns, a list of dictionaries is returned with possible combination of values for the different variables. For instance, kb[["?agent desires ?action", "?action rdf:type Jump"]] would return something like: [{"agent":"james", "action": "jumpHigh"}, {"agent": "laurel", "action":"jumpHigher"}]

Attention: if more than one argument is passed, and if the last argument is a list, this list is used as the set of models to execute the query on. If not such list is provided, the query is executed on all models.

Usage example:

for agent in kb["* rdf:type Agent"]:
    #...

if kb["* livesIn ?house", "?house isIn toulouse", ['GERALD']]:
    #...

#Assuming 'toulouse' has label "ville rose":
city_id = kb["ville rose"]

See also: KB.find()

__iadd__(stmts)#

This method allows to easily add new statements to the ontology with the += operator. It can only add statement to the default robotā€™s model (other agentsā€™ model are not accessible).

kb += "toto likes icecream"
kb += ["toto loves tata", "tata rdf:type Robot"]
__isub__(stmts)#

This method allows to easily retract statements from the ontology with the -= operator. It can only add statement to the robotā€™s model (other agentsā€™ model are not accessible). If a statement doesnā€™t exist, it is silently skipped.

kb -= "toto likes icecream"
kb -= ["toto loves tata", "tata rdf:type Robot"]
about(term, models=[])#

Returns the list of triples where term is either subject, predicate or object

add(stmts, models=[], lifespan=0)#

Adds statements to the given model(s) with the given lifespan. Alias for revise with policy['method']='add'

See KB.revise() for more details.

clear()#

Resets the knowledge base, deleting all facts and all models.

details(resource, models=[])#

Returns a dictionary containing the following details on a given resource:

  • name: resource label, if any, literal value for literals, else resource ID.

  • id: resource ID or literal for literals

  • type: one of ['instance', 'class', 'object_property', 'datatype_property', 'undecided']

  • sameAs: list of equivalent classes or instances, if any

  • attributes:

    • for classes, a list of three dictionaries: {"name": "Parents","id": "superClasses", "values":[ids...]} {"name": "Children","id": "subClasses", "values":[ids...]} {"name": "Instances","id": "instances", "values":[ids...]} (only direct super/sub-classes and instances)

    • for instances, a list of one dictionary: {"name": "Classes","id": "classes", "values":[ids...]} (only direct classes)

exist(pattern, models=[])#

Returns True if the pattern is present in the ontology, False otherwise.

See also: KB.__contains__()

find(patterns, vars=[], models=[])#

Performs a query on one or several models.

vars: the list of variables (prefixed with ?) that you want to select. If None or an empty list, returns all the variables found in the patterns.

patterns: a list of triples containing unbound terms (eg, variables). As a convenience, if the patterns do not contain any variable, find will return whether the provided list of triples is present in the model(s).

models: the list of models you want to run the query against. The returned result will be the conjunction of results when running the query on each models separately.

A list of dictionaries is returned with possible combination of values for the different variables. For instance, find(["?agent", "?action"], ["?agent desires ?action", "?action rdf:type Jump"]) would return something like: [{"agent":"james", "action": "jumpHigh"}, {"agent": "laurel", "action":"jumpHigher"}].

If you were using anonymous variables (starting with ?__) in your query (eg generated by pykb when using a * wildcard), they will be renamed var1, var2, etc.

See also: KB.__getitem__()

hello()#

Returns the version number of the KnowledgeCore server as a string. Can be used to check connection status.

label(term, models=[])#

Returns the labels attached to a term, as a dictionary {"default":"label1", "lang_code1": label1, "lang_code2": "label2",...} where the default key returns either the English version of the label, or the name of the term, if no label is available, and the other keys provide localised version of the label, if available in the knowledge base.

lookup(query, models=[])#

Searches the knowledge base for a term matching a string. The search is performed both on termsā€™ names and on label.

Returns the list of found terms, alongside with their type (one of instance, class, datatype_property, object_property, literal or undecided).

remove(stmts, models=[])#

Alias for revise with policy['method']='retract'.

See KB.revise() for more details.

revise(stmts, policy)#

Add/retract/updates one or several statements in the specified model.

policy is a dictionary with the following fields:

  • method (required): string in [add, safe_add, retract, update, safe_update, revision]

  • models (optional, default to None): list of strings

  • lifespan (optional, default to 0): duration before automatic removal of statements, in seconds, float. If set to 0, statements do not expire.

stats()#

Returns basic stats on the knowledge base, as a dictionary. For instance,

{
"name": "KnowledgeCore, v.3.2.1",
"version": "3.2.1",
"reasoning_enabled": true
}
subscribe(pattern, callback, one_shot=False, models=None)#

Allows to subscribe to an event, and get notified when the event is triggered.

import rclpy
from rclpy.node import Node
from knowledge_core.api import KB

rclpy.init()
node = Node("test_kb_client")
kb = KB(node)

def on_event(evt):
    print(f"Event triggered! {evt}")

kb.subscribe(["?o isIn room"], on_event)

kb += ["john isIn room"]
rclpy.spin(node)

# Event triggered! [{'o': 'john'}]

The models parameter allows for registering an event in a specific list of models. By default, the pattern is monitored on every models.

If one_shot is set to true, the event is discarded once it has fired once.

Returns the event id of the newly created event.

update(stmts, models=[], lifespan=0)#

Updates statements in the given model(s) with the given lifespan. Alias for revise with policy['method']='update'. If the predicate(s) are not inferred to be functional (i.e., it accept only one single value), behaves like add.

See KB.revise() for more details.

exception knowledge_core.api.KbError(value)#

Bases: Exception

ROS API#

Note

See Using the knowledge base with the ROS API for examples of the ROS API usage.

Topics#

/kb/add_fact#

Statements published to this topic are added to the knowledge base. The string must represent a <s, p, o> triple, with terms separated by a space.

See knowledge_core.api.KB.add() for details.

/kb/remove_fact#

Statements published to this topic are removed from the knowledge base. The string must represent a <s, p, o> triple, with terms separated by a space.

/kb/active_concepts#

Lists the symbolic concepts that are currently active (an active concept is a concept of rdf:type ActiveConcept).

/kb/events/*#

Event notifications for previously subscribed events. See service /kb/events for details.

Services#

/kb/about#

/kb/about returns the list of triples where term is either subject, predicate or object.

This maps the knowledge_core.api.KB.about() API.

/kb/events#

/kb/events allows to subscribe to events by providing a (set of) partially-bound triples. Calling the service returns an event id. Subscribe then to /kb/events/<id> to be notified everytime a new instance/class match the provided pattern.

/kb/lookup#

/kb/lookup searches the knowledge base for a term matching a string. The search is performed both on termsā€™ names and on label.

This maps the knowledge_core.api.KB.lookup() API.

/kb/label#

/kb/label returns the labels attached to a term, as a dictionary {"default":"label1", "lang_code1": label1, "lang_code2": "label2",...} where the ā€˜defaultā€™ key returns either the English version of the label, or the name of the term, if no label is available, and the other keys provide localised version of the label, if available in the knowledge base.

This maps the knowledge_core.api.KB.label() API.

/kb/details#

/kb/details returns a dictionary containing the several details on a given resource (including its type, class, properties, etc.)

This maps the knowledge_core.api.KB.details() API.

/kb/manage#

/kb/manage lets you manage the knowledge base, including clearing all content and loading external ontologies.

The action field of the service request can be one of the following:

  • clear: fully reset the knowledge base: remove all statements and delete all existing models

  • load: loads an external ontology (XML/RDF, n3, turtle or n-triple format) into the knowledge base

  • save: saves the knowledge base to the RDF format. The knowledge base will then be saved as path/basename-<model>.rdf

  • status: returns the status of the knowledge base

/kb/query#

/kb/query performs a simple query against the knowledge base.

This maps the knowledge_core.api.KB.query() API.

/kb/revise#

/kb/revise adds/removes facts to/from the knowledge base using a synchronous interface.

This maps the knowledge_core.api.KB.revise() API.

/kb/sparql#

/kb/sparql performs a complex query on the knowledge base, using the SPARQL syntax.

The SPARQL PREFIX and BASE are automatically added, no need to do it manually (even though you can if you want to use non-standard prefixes).

Caution

You are responsible for writing a syntactically correct SPARQL query. In particualar, all non-literal/non-variable terms must have a namespace (or a prefix).

Results is returned as a JSON object that follow the standard JSON serialization of SPARQL Results.

See also#

Return to šŸ’” Knowledge and reasoning