Querying RDF/OWL using Bossam

(Last Update: 2007-07-04T09:01:58)

Here’s a simple example of loading and querying RDF documents. Currently, Bossam does not support SPARQL. You need to write queries in Buchingae rule language for Bossam, and it’s very easy. :-)

First, we need to load RDF documents into a Bossam reasoner. For our lesson, let’s load the W3C Wine ontology. Once the ontology is loaded, we should perform a reasoning over the wine ontology. As Bossam is a forward-chaining reasoner, a full forward-chaining derivation should be performed first to get full query results. The following is the code sequence.

1) Create an OWL reasoner instance.
IReasoner r = ReasonerFactory.getInstance().createOwlDlTrMReasoner();

2) Load the W3C Wine ontology from a URL.
r.load(IReasoner.OWL, "http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine.rdf");

3) Perform a silent but full forward-chaining derivation. silentRun() does not return conclusions, which benefits it with a slight better performance than run().
r.silentRun();

4) Set some namespaces to write queries in a more compact form.
r.setNamespacePrefix("w", "http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#");
r.setNamespacePrefix("o", "http://www.w3.org/2002/07/owl#");

Now, we’re ready to query the ontology. Some samples follow:

Query 1) (A Simple Query) Retrieve all the Wine instances.
Answer answer = r.ask1("query q is w:Wine(?x);");

Query 2) (A Conjunctive Query) Retrieve all the wines with White color and Full body.
Answer answer = r.ask1("query q is w:hasColor(?x,w:White) and w:hasBody(?x,w:Full);");

Query 3) (A Disjunctive Query) Retrieve all the wines with White color or Rose color.
Answer answer = r.ask1("query q is w:hasColor(?x,w:White) or w:hasColor(?x,w:Rose);");

Query 4) (A Query with Negation As Failure) Retrieve all the wines that are neither White wine nor Red wine.
Answer answer = r.ask1("query q is w:Wine(?x) and not w:WhiteWine(?x) and not w:RedWine(?x);");

Also, not for the Wine ontology, but it’s possible to use filters in the query, as shown below.

Query 5) Retrieve all the teen agers.
Answer answer = r.ask1("query q is p:hasAge(?x,?age) and [?age >= 10] and [?age < 20];");

Well, that’s it for today. Any questions or suggestions are welcomed!

The following is a full Java code for testing. Be sure to add all the JAR files included in the bossam release to your project’s classpath.

package org.etri.bossam.test;

import bossam.app.Answer;
import bossam.app.IReasoner;
import bossam.app.IReasonerFactory;
import bossam.app.ReasonerFactory;

public class WineQuery01
{
 final static String wineURI = "http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#";

 public static void main(String[] args)
 {
  try
  {
   // Creates a reasoner factory
   IReasonerFactory factory = ReasonerFactory.getInstance();
   // Creates a rule-based OWL DL reasoner
   IReasoner r = factory.createOwlDlTrMReasoner();
   // Loads the wine ontology into Bossam
   r.load(IReasoner.OWL, wineURI);
   // Perform a reasoning session
   String result = r.run();
   // Prints out the conclusions
   System.out.println("Conclusions: n" + result);
   // Sets the namespace prefix for querying the wine ontology
   r.setNamespacePrefix("w", wineURI);
   // Throws a query and gets an answer
   Answer answer = r.ask1("query q is w:WhiteWine(?x);");
   // Prints out the query result
   if (answer == null)
   {
    System.out.println("The query returns false!");
   }
   else
   {
    System.out.println("Answer (" + answer.getBindings().size() + "):n"
                             + answer);
   }
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}

Using OwlDlTrHReasoner

OwlDlTrHReasoner is a new OWL DL reasoning module added to Bossam, which shows much better performance than Bossam’s default OWL DL reasoning module. You can create an instance of OwlDlTrHReasoner by calling bossam.app.IReasoner.createOwlDlTrHReasoner().

In Bossam shell, instead of owl, use owltr as follows:

load owltr from http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine;

Yeap. That’s it. OwlDlTrHReasoner completes a forward-chaining reasoning session over the W3C wine ontology in less than 3 seconds, on my 1.8Ghz Core Duo notebook with 128MB of Java heap memory. Not bad, right?

Doesn’t that reasoner lose too many derivations? Well, actually, I have to see from now on… :-) I’d be greatly appreciated for any feedback and problem reports on this new reasoner. :)

Bossam 0.9b40 Released!

Now, big improvements in performance. With newly added reasoners for OWL reasoning, OwlDlTrHReasoner, resonable performance measures are obtained. Refer to the preliminary LUBM benchmark results. Also, this release includes a feature to present the derivation tree for conclusions. Please refer to the short explanations on explanation.

Highlights for Bossam 0.9b40 Release

  • New Reasoners: OwlDlTrHReasoner and SwrlRdfTrHReasoner are OWL and SWRL reasoners respectively. These reasoners provide better performance than previous reasoners e.g. OwlDlReasoner.
    • Use load owltr to utilize the new OwlDlTrHReasoner in Bossam shell!
  • Explanation: It’s now possible to print out the derivation tree of a derived facts. Please refer to an explanation on the explanation feature.
  • Derived facts with blank nodes now do not appear in the conclusions! It provides more compact view on the conclusions.
  • Several bug-fixes as always…

Notes for the Bossam users!

Highly regarded Bossam users! Please note the following guides!

  • You should always use bossam.app.ReasonerFactory to create reasoner instances. Creators of reasoner classes are now protected so you cannot directly create instances of reasoner classes.
  • You should create an OWL reasoner to load OWL documents, and a SWRL reasoner to load SWRL documents. You cannot load OWL or SWRL documents with the default reasoner created by IReasoner.createReasoner().
  • Use IReasonerFactory.createOwlDlTrHReasoner() for better OWL reasoning performance!
  • Query performance is better optimized for this release. Try querying.

Thank you so much for using Bossam!

Bossam’s Performance over LUBM

Recently, a big performance-wise improvement was injected into Bossam. ;-) I performed a preliminary LUBM benchmark with Bossam and got a promising results. The machine was a notebook with a fast Intel Core Duo 1.8Ghz processor and 2 GB of RAM. I assigned 256MB heap memory for the Java machine (JDK 1.3.1) for the test. The test was done on two data sets: one with about 50,000 triples and another with 100,000 triples. As Bossam is the forward-chaining engine, it took a while to finish the full derivation phase. It took about 100 seconds for 100,000 triples and 22 seconds for 50,000 triples. The following chart shows the elapsed time for 13 LUBM queries. Answers were correct. I think the performance figure shown in the chart is not bad for a rule-based OWL reasoner. :-)

Bossam’s LUBM Benchmark (as of 2007-01-23)

Explanations in Bossam

As of 0.9b40, Bossam comes with a small explanation feature. You can easily utilize the explanation feature in Bossam shell. The command is simple as follows:

explain fact-id;

fact-id is the ID of the fact for which an explanation is requested.

Suppose we assert a set of knowledge and run a reasoning session in the Bossam shell as follows:

> assert fact f1 is hasParent(a,b);
> assert fact f2 is hasParent(b,c);
> assert fact f3 is hasParent(c,d);
> assert rule r2 is if hasParent(?x,?y)
  then hasAncestor(?x,?y);
> run;
Running.....
Reasoning Completed.
fact def:Fact2 is def:hasAncestor(def:c,def:d);
fact def:Fact1 is def:hasAncestor(def:b,def:c);
fact def:Fact0 is def:hasAncestor(def:a,def:b);

With explanation, it’s possible to see which set of facts contributed to the derivation of a specific fact. For example, we can see the explanation for the Fact2 as follows:

> explain def:Fact2;
Fact2: def:hasAncestor(def:c,def:d) [from r2]
 f3: def:hasParent(def:c,def:d) [Given]

We can see that the Fact2 is derived by the rule r2 with the support of the fact f3 which is given. As such, we can track the derivation path of conclusions. For a slightly more complex example, we add one more rule and request an explanation as follows.

> assert rule r2 is if hasAncestor(?x,?y) and hasParent(?y,?z)
  then hasAncestor(?x,?z);
Asserted.
> run;
Running.....
Reasoning Completed.
fact def:Fact5 is def:hasAncestor(def:a,def:d);
fact def:Fact3 is def:hasAncestor(def:b,def:d);
fact def:Fact4 is def:hasAncestor(def:a,def:c);
> explain def:Fact5;
Fact5: def:hasAncestor(def:a,def:d) [from r2]
 Fact4: def:hasAncestor(def:a,def:c) [from r2]
  Fact0: def:hasAncestor(def:a,def:b) [from r2]
   f1: def:hasParent(def:a,def:b) [Given]
  f2: def:hasParent(def:b,def:c) [Given]
 f3: def:hasParent(def:c,def:d) [Given]
>

We see an embedded hierarchy of derivation relations. Fact5 is derived by the rule r2 with the support of the facts Fact4 and f3. Fact4 is derived again by r2 with the support of Fact0 and f2, and Fact0 is soley supported by the given fact f1.

Currently, Bossam does not provide a data structure for explanations. The bossam.app.IReasoner interface provides a method getProof() that accepts a fact ID and returns an explanation string.

I’m considering a number of ways to provide an object model or an XML markup for the explanations. Any suggestions?

Thanks, Claire Costello!

Claire gave a series of feedbacks on bugs in SWRL/RDF processing. Based on Claire’s comments, I could fix several data type processing bugs. Thanks so much, Claire!!

Claire is at Department of Information Technology, National University of Ireland, Galway.

Speeding up Bossam…

I’m working on a new implementation of Bossam’s OWL reasoning module. There’re roughly two approaches for rule-based OWL reasoning. One is translation-based approach and the other is meta-reasoning approach. Bossam’s OWL reasoning module originally is implemented in meta-reasoning approach, but now I’m working on a translation-based OWL reasonnig implementation for Bossam. I’ve just finished the first draft of the code and it looks quite promising in the sense of performance!

  • A full forward-chained reasoning session on the W3C wine ontology completed in 1.5 seconds!
  • A full forward-chained reasoning session on the LUBM benchmark with 100,000 triples completed in 97 seconds! All the 13 sample queries are processed in less than 1 second!

Stay tuned! One major performance-tuned Bossam is coming!

Bossam 0.9b33 Released

The RETE core is refactored for performance improvements. Generally, this release is *three times* faster than the previous release. Also, some SWRL/RDF processing bugs are fixed, and this release runs on J2ME CDC/PP platform as well as J2SE platforms of JDK 1.3 or later. Download at http://projects.semwebcentral.org/projects/bossam/

Calling Java Methods from SWRL Rules

With Bossam, it’s possible to introduce Java method calls into SWRL rules. In Bossam, Java method calls are represented as SWRL builtin atoms. It’s necessary to read first about the Bossam’s mechanism of URI-based Java method call.

The namespaces related are as follows:
- bossam: http://www.etri.re.kr/2003/10/bossam#
- tc: java://etri.bossam.swrl/TemperatureController#
- swrl: http://www.w3.org/2003/11/swrl#

bossam:serviceCall

Java method call is wrapped around a new SWRL builtin atom: bossam:serviceCall. There’re two forms of bossam:serviceCall, each of which is for object binding and method call.

Object Binding Format

The format is defined as follows:

bossam:serviceCall(java-class-sig, java-obj)

java-class-sig is the URI specification of a Java class. out-arg is bound to the Java objects in the current inference context which are of the type specified by java-class-sig.

Method Call Format

The format is defined as follows:

bossam:serviceCall(java-method-sig, java-obj, in-arg-1, in-arg-2,..., in-arg-n, out-arg)

java-method-sig is the URI specification of the Java method to call. java-obj refers to the Java objects for which the method call shall be made. in-arg-1,...,in-arg-n are input arguments for the method. Not necessary to specify if method has no input parameters. out-arg is bound to the result of the method call. Not necessary to specify if method has no output.

Sample 1: Binding Java objects

The following code binds to the instances of etri.bossam.swrl.TemperatureController to the variable ?o.

<swrl:BuiltinAtom>
  <swrl:builtin rdf:resource="&bossam;#serviceCall"/>
    <swrl:arguments>
      <rdf:List>
        <rdf:first rdf:resource="&tc;#class"/>
        <rdf:rest>
          <rdf:List>
            <rdf:first rdf:resource="#o" />
            <rdf:rest rdf:resource="&rdf;#nil"/>
          </rdf:List>
        </rdf:rest>
      </rdf:List>
    </swrl:arguments>
</swrl:BuiltinAtom>

Sample 2: Calling a Getter Method With No Input Argument

The following code calls the method getTemperature() on the instances of etri.bossam.swrl.TemperatureController, and binds the results to the variable ?v.

<swrl:BuiltinAtom>
  <swrl:builtin rdf:resource="&bossam;#serviceCall"/>
  <swrl:arguments>
    <rdf:List>
      <rdf:first rdf:resource="&tc;#getTemperature"/>
      <rdf:rest>
        <rdf:List>
          <rdf:first rdf:resource="#o" />
          <rdf:rest>
            <rdf:List>
              <rdf:first rdf:resource="#v" />
              <rdf:rest rdf:resource="&rdf;#nil"/>
            </rdf:List>
          </rdf:rest>
        </rdf:List>
      </rdf:rest>
    </rdf:List>
  </swrl:arguments>
</swrl:BuiltinAtom>

Sample 3: Calling a Getter Method With Input Arguments

The following code calls the method getTemperatureInFahrenheit(double) on the instances of etri.bossam.swrl.TemperatureController, and binds the results to the variable ?v.

<swrl:BuiltinAtom>
  <swrl:builtin rdf:resource="&bossam;#serviceCall"/>
  <swrl:arguments>
    <rdf:List>
      <rdf:first rdf:resource="&tc;#getTemperatureInFahrenheit"/>
      <rdf:rest>
        <rdf:List>
          <rdf:first rdf:resource="#o" />
          <rdf:rest>
            <rdf:List>
              <rdf:first rdf:datatype="&xsd;#double">10.0</rdf:first>
              <rdf:rest>
                <rdf:List>
                  <rdf:first rdf:resource="#v" />
                  <rdf:rest rdf:resource="&rdf;#nil"/>
                </rdf:List>
              </rdf:rest>
            </rdf:List>
          </rdf:rest>
        </rdf:List>
      </rdf:rest>
    </rdf:List>
  </swrl:arguments>
</swrl:BuiltinAtom>

Sample 4: Calling a Setter Method with No Input Argument

The following code calls the method turnOn() on the instances of etri.bossam.swrl.TemperatureController.

<swrl:BuiltinAtom>
  <swrl:builtin rdf:resource="&bossam;#serviceCall"/>
  <swrl:arguments>
    <rdf:List>
      <rdf:first rdf:resource="&tc;#turnOn"/>
      <rdf:rest>
        <rdf:List>
          <rdf:first rdf:resource="#o" />
          <rdf:rest rdf:resource="&rdf;#nil"/>
        </rdf:List>
      </rdf:rest>
    </rdf:List>
  </swrl:arguments>
</swrl:BuiltinAtom>

Bossam and Ubiquitous Robots

‘Robots in the ubiquitous environments’ are called ubiquitous robots. Ubiquitous robots are basically networked robots. They natively possess communication channels through which they can interact with any kinds of networked agents e.g. information appliances, mobile phones, web services, internet agents, networked sensors and actuators etc. The channels pave the broad way for the robots to the world of globalized and ubiquitous interactions with the real world.

For ubiquitous robots to intelligently interact with the world, they need to understand the situations aroud and react appropriately. Traditional robots did similar things only through their own sensors like camera, ultrasonic sensors, laser scanners, etc. Ubiquitous robots can utilize wider spectrum of data sources e.g. sensors remotely installed in the environment, web services on the internet, and any kinds of other devices wired to the network. As such, ubiquitous robots need context-awareness.

Recently, semantic web technologies are widely adopted for context-awareness. Why? That’s because the semantic web provides tools for building common knowledge infrastructure. The ‘common’ is used to mean that ‘it can be interchanged for global communication’. The semantic web provides ‘the semantic glue’. RDF and OWL are used to define vocabularies for representing various kinds of contexts. The vocabularies are used to build context models and instances. Context-awarenss applications or services convert raw context data into the symbolic representation using the vocabularies and try to exploit application-level contexts that’re meaningul to trigger context-aware functionalities. OWL inferencing and rule reasoning are two main enabling technologies for the process.

Since 2004, we developed context-aware service platform for ubiquitous robots based on the semantic web and web services. Bossam has been one of the main tools for the development; it has been used for context interpretation, context model inferencing, robot service coordination, mixing results from various semantic web services, etc.

Bossam is under ongoing improvement.