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.
Methods#
Caution
The following list is the low-level API of the KnowledgeCore server.
Only some of these methods are exposed via the Python API or the ROS API.
about(term, models=None)
: returns the list of triples whereterm
is either subject, predicate or objectadd(stmts, models=None, lifespan=0)
: adds statements to the given model(s) with the given lifespan. Alias forrevise
withpolicy['method']='add'
classesof(term, direct=False, models=None)
: returns the list of (direct of direct + indirect) classes of the given termclear()
: reset the knowledge base, deleting all facts and all modelsdetails(resource, models=None)
: 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 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(stmts, models=None)
find(vars, patterns, constraints=None, models=None)
: 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.hello()
: returns the version number of theKnowledgeCore
server as a string. Can be used to check connection status.label(self, 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.load(filename, models=None)
: loads the content of the specified OWL ontology. Format is inferred from the file content. Currently support RDF/XML, n3, n-triples, turtle.lookup(resource, models=None)
: search 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)
methods()
: list available methods exposed by the serverremove(stmts, models=None)
: alias forrevise
withpolicy['method']='retract'
.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.
sparql(query, model='default')
: performs a raw SPARQL query on a given model. 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).Note that you are responsible for writing a syntactically corret 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
subscribe(patterns, one_shot=False, models=None)
: subscribes to a specified event in the ontology.Every time the model(s) is(are) updated, the provided
patterns
are evaluated against the set of asserted and inferred triples. If at least one triple is returned, the event is fired.The terms bounded to the named variables in the patterns are attached to the fired event.
For instance:
from kb import KB def on_new_robot_instance(instances): print("New robots: " + ", ".join(instances)) with KB() as kb: kb.subscribe(["?robot rdf:type Robot"]) kb += ["myself rdf:type Robot"] # should print "New robots: myself" time.sleep()
If
one_shot
is set to true, the event is discarded once it has fired once.update(stmts, models=None, lifespan=0)
: updates statements in the given model(s) with the given lifespan. Alias forrevise
withpolicy['method']='update'
. If the predicate(s) are not inferred to be functional (i.e., it accept only one single value), behaves likeadd
.