../_images/tiago-icon.png ../_images/tiagopro-icon.png ../_images/ari-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.

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 where term is either subject, predicate or object

  • add(stmts, models=None, lifespan=0): adds statements to the given model(s) with the given lifespan. Alias for revise with policy['method']='add'

  • classesof(term, direct=False, models=None): returns the list of (direct of direct + indirect) classes of the given term

  • clear(): reset the knowledge base, deleting all facts and all models

  • details(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 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(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 by pykb when using a * wildcard), they will be renamed var1, var2, etc.

  • hello(): returns the version number of the KnowledgeCore 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 server

  • remove(stmts, models=None): alias for revise with policy['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 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.

  • 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 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.