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.
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["* * *"]
orkb["* rdf:type *"]
), a list of statements matching the pattern is returned.
- with a single
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
withpolicy['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 orliteral
for literalstype
: one of['instance', 'class', 'object_property', 'datatype_property', 'undecided']
sameAs
: list of equivalent classes or instances, if anyattributes
: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 bypykb
when using a*
wildcard), they will be renamedvar1
,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 thedefault
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
orundecided
).
- remove(stmts, models=[])#
Alias for
revise
withpolicy['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 toNone
): list of stringslifespan
(optional, default to0
): 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
withpolicy['method']='update'
. If the predicate(s) are not inferred to be functional (i.e., it accept only one single value), behaves likeadd
.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.
This maps the
knowledge_core.api.KB.subscribe()
API.
/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 modelsload
: loads an external ontology (XML/RDF, n3, turtle or n-triple format) into the knowledge basesave
: saves the knowledge base to the RDF format. The knowledge base will then be saved aspath/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