The OULx software implements the Ontology Update Language (OUL) together with several extensions, inspired by the existing SQL-triggers mechanism, making use of SPARQL and SPARQL/Update statements. Programming work has been done by Jordy Sangers.

OUL

The Ontology Update Language (OUL) is a combination between active database triggers and SPARQL/Update statements, which updates ontologies in an event-driven manner. By defining so-called changehandlers, specific ontology change events can be caught and handled individually using an Event-Condition-Action model. This method however, does not support a fully automated ontology update process. OUL does feature a dynamic update process using an existing RDF update language, and hence we extend this language to OULx in such a way that no human intervention is needed for multiple updates.

OUL makes use of changehandlers that perform SPARQL/Update actions whenever a certain change event occurs. A change event is represented as an RDF-graph that is either added to or deleted from the ontology. In case we want to perform particular actions, we can specify them in a changehandler. When the changerequest matches the change event, a precondition on the ontologies is checked. If this precondition is met or if no precondition has been defined, a list of actions will be executed. In contrast to active databases, ontology updates do not require SQL statements, but events, conditions, and actions have to be defined in SPARQL and SPARQL/Update.

OUL defines two different types of changerequests, i.e., insertion and deletion of information. The add and delete keywords distinguish between the two different types and every changerequest is further defined by a WHERE-clause of a SPARQL SELECT query. When all the triples in the query can be deduced from a change event and the event-type matches the changerequests' type, the changerequest is matched. The set of bindings that are returned from the query can be reused later in the changehandler definition.

Whenever a changerequest matches, also optional preconditions defined in the changehandler have to be met in order for the actions to be executed. In contrast to the changerequest, which is used to match the occurring event, the precondition is used to check the current state of the ontology. Three different types of preconditions can be used. First, contains checks whether the ontology contains a set of triples. Second, entails checks whether the ontology entails a set of triples, i.e., from reasoning can be concluded that the statement is logically entailed by the ontology. Third, entailsChanged checks whether the ontology that would result after executing the actions, entails a set of triples.

When the changerequest is matched and the precondition is met, a list of actions is executed. Actions make use of the binding information that resulted from matching the changerequest and the precondition. We distinguish between four types of actions, i.e., SPARQL/Update queries, feedback actions that give feedback to the user using text containing bounded variables, applyRequest actions that execute the events caught by the changehandler, and finally, the for actions that iteratively execute a set of actions with binding information from a for-condition.

OULx

Syntax-wise, OULx differs from OUL in the additional support for negation and prefixes. This results in the following syntax:

CREATE CHANGEHANDLER <name>
[<prefixes>]
FOR <changerequest>
AS
  [ IF <precondition>
    THEN ] <actions>

<prefixes>      ::== <prefix>[<prefixes>]
<prefix>        ::== <SPARQL prefix>
<changerequest> ::== add [unique] (<SPARQL>)
                   | delete [unique] (<SPARQL>)
<precondition>  ::== contains(<SPARQL>)
                   | entails(<SPARQL>)
                   | entailsChanged(<SPARQL>)
                   | (<precondition>)
                   | <precondition> and <precondition>
                   | <precondition> or <precondition>
                   | !<precondition>
<actions>       ::== [<action>]|<action><actions>
<action>        ::== <SPARQL update>
                   | for( <precondition> ) <actions> end;
                   | feedback(<text>)
                   | applyRequest
<SPARQL prefix> ::== PREFIX statement of a SPARQL query
<SPARQL>        ::== WHERE clause of a SPARQL SELECT query
<SPARQL update> ::== a MODIFY action (in SPARQL/Update)
<text>          ::== string (may contain SPARQL variables)

Our main contribution however lies in the extension of OUL's execution mechanism. We incorporated immediate updating, as opposed to deferred updating. Also, we added an internal triggering mechanisms for changehandlers (through events fired by other changehandlers), i.e., we have added to the OUL execution mechanism the possibility to chain changehandlers. This allows for automatic triggering of events based on the matched changehandlers' actions, and also contributes to the usability of the language by separating atomic update actions and thus delivering modularity and an increased possibility to reuse changehandlers. Additionally, we added support for looping. Finally, it is also possible to execute all event-related changehandlers, instead of just the first handler that is matched.

Example

Below are three examples of changehandlers in OULx that can be executed using a chained, deferred, non-looped execution mechanism that executes the first matching changehandler. These rules make use of a financial ontology containing products, companies, prices, etc.

CREATE CHANGEHANDLER AddProductAndPrice
PREFIX kb:<http://www.hermes.com/knowledgebase.owl#>
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
FOR    add{?company kb:hasProduct ?product.
           ?product kb:hasPrice ?price}
AS IF  contains{?company rdf:type kb:Company}
THEN   insert{?company kb:hasProduct ?product};
       insert{?product kb:hasPrice ?price};

CREATE CHANGEHANDLER AddProduct
PREFIX kb:<http://www.hermes.com/knowledgebase.owl#>
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
FOR    add{?company kb:hasProduct ?product}
AS IF  contains{?company rdf:type kb:Company}
THEN   insert{?product rdf:type kb:Product};
       applyRequest;
       insert{?product kb:isProducedBy ?company};
       feedback{?product is a product produced by ?company};

CREATE CHANGEHANDLER AddPrice
PREFIX kb:<http://www.hermes.com/knowledgebase.owl#>
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
FOR    add{?product kb:hasPrice ?price}
AS IF  contains{?product rdf:type kb:Product}
THEN   applyRequest;
       feedback{The price of ?product is set to ?price};

The first changehandler is fired when a request is made for the addition of two RDF triples to the ontology, i.e., ?company kb:hasProduct ?product and ?product kb:hasPrice ?price, whenever the precondition is met that ?company is of type kb:Company. The rule subsequently inserts the triples in the database. As OULx implements chaining, the second and third changehandlers are triggered automatically.

The second changehandler is triggered after a request to add the RDF triple ?company kb:hasProduct ?product to the ontology (in case ?product is of type kb:Product) and inserts multiple triples into the ontology. Additionally, the user is given feedback about the update progress.

Last, the third changehandler becomes active when a request is made for adding the RDF triple ?product kb:hasPrice ?price to the ontology (if and only if ?product is of type kb:Product). It applies the requests (i.e., it inserts the triple into the ontology) and gives feedback about the status of the update.

Note that when utilizing different execution mechanisms, these rules should be slightly changed. For instance, when using immediate execution mechanisms, one could make use of recursion, causing actions to trigger themselves. Additionally, it should be noted that compound changehandlers like our first example become redundant when using execution mechanisms that execute all matching changehandlers. Furthermore, selecting an execution mechanism that allows for looping requires the use of additional preconditions, as events get re-thrown until no changehandlers match.

Software

OULxOur stand-alone implementation can be downloaded here as a zip-file, which can be extracted to any desired location on your harddrive. It contains several different execution models, providing flexibility with respect to the update process. The provided software assumes that all queries are chained, which provides us with eight different execution models:

To run OULx, execute the following command line in the OULx root folder:

java -jar OULx.jar Ontology.owl ChangeHandlers.txt

Here, Ontology.owl points to the default but interchangeable (financial) ontology on products, companies, etc. The file ChangeHandlers.txt contains several changehandlers, which can be adapted to your needs. After executing the command, you will be prompted to select an execution model, after which you will be able to provide a change event. Please note that the file ExampleEvents.txt contains example change events that can be used by OULx.

Non-commercial and private use of the software is allowed. When publishing work that is based on my software, please ensure that proper citations are included. In case of questions, comments, or suggestions, feel free to contact me. Also, please notify me when you have developed extensions, additional components, etc., so that I can add them to the next software release.

Contact

Frederik Hogenboom, Ph.D.