Archive

Archive for the ‘manual’ Category

Representing and Processing Time & Dates

February 20, 2007 Leave a comment

Time Data Types

(Some of the features explained in this post are available in the next Bossam release.)

With Bossam, time data can be represented and processed. The following time types supported.

Date (corresponds to xsd:date)

  • Syntax: yyyy-MM-dd
  • Example: 2004-10-09

Time (corresponds to xsd:time)

  • Syntax: HH:mm:ss
  • Example: 22:10:30

DateTime (corresponds to xsd:dateTime)

  • Syntax: yyyy-MM-dd'T'HH:mm:ss
  • Example: 2004-10-09T22:10:30

Time Duration (corresponds to xsd:duration)

(refer to XSD Duration on how to write time durations)

  • ex1) P10Y9M8DT10H9M8S represents 10 years 9 months 8 days 10 hours 9 minutes 8 seconds.
  • ex2) P10Y8DT10H represents 10 years 8 days 10 hours.
  • ex1) P10Y9M8D represents 10 years 9 months 8 days.
  • ex1) PT10H9S represents 10 hours 9 seconds.

Getting the Current Time/Date

Three builtin functions are available for getting the current time, current date, and current dateTime, as follows.
The namespace URI, http://www.etri.re.kr/2003/10/bossam-builtin#, is the reserved namespace for designating Bossam’s builtin functions. Let’s assume func corresponds to http://www.etri.re.kr/2003/10/bossam-builtin#.

  • func:thisTime(): returns the current time
  • func:thisDate(): returns the current date
  • func:thisDateTime(): returns the current date-time

Builtin Functions for Comparing Date/Time

There are three builtin functions for processing time data.

  • func:after(time-const1,time-const2)
    • returns true if time-const1 follows time-const2
  • func:before(time-const1,time-const2)
    • returns true if time-const1 precedes time-const2
  • func:containedIn(time-const1,time-begin,time-end)
    • returns true if time-const1 is in the duration formed by time-begin and time-end

A sample rulebase utilizing time constants is shown below.

prefix xsd = http://www.w3.org/2001/XMLSchema#;
prefix rdfs = http://www.w3.org/2000/01/rdf-schema#;
prefix func = http://www.etri.re.kr/2003/10/bossam-builtin#;
namespace is http://etri.re.kr/2003/10/Bossam#;
rulebase TimeConstants
{
 class Person;
 property birthdate for Person is xsd:date;
 individual John is Person and birthdate = 1970-10-05;
 individual Sam is Person and birthdate = 1970-05-05;

 rule r1 is
 if
  birthdate(?x,?date1) and birthdate(?y,?date2)
  and [func:after(?date1,?date2) = true]
 then
  isYoungerThan(?x,?y);

 rule r2 is
 if
  birthdate(?x,?date1) and birthdate(?y,?date2)
  and [func:before(?date1,?date2) = true]
 then
  isOlderThan(?x,?y);

 fact f01 is beginsAt(MeetingA,2005-10-04T12:00:00);
 fact f02 is endsAt(MeetingA,2005-10-04T15:00:00);
 fact f03 is beginsAt(MeetingB,2005-10-04T14:00:00);
 fact f04 is endsAt(MeetingB,2005-10-04T17:00:00);
 fact f05 is beginsAt(MeetingC,2005-10-04T16:00:00);
 fact f06 is endsAt(MeetingC,2005-10-04T17:00:00);

 rule CompatibleMeetings is
 if
  endsAt(?m1,?t1) and beginsAt(?m2,?t2)
  and [func:after(?t2,?t1) = true]
 then
  Compatible(?m1,?m2);
}

Expressions on Time Data

Simple addition and subtraction on time and duration can be processed.

Calculating Time Difference

By subtracting a time from another time, it’s possible to calculate the difference between the two time points. Some examples follow:

  • 2005-10-20 - 2005-09-10 gives P0Y0M40DT0H0M0S which is 40 days.
  • 23:10:20 - 10:30:40 gives P0Y0M0DT12H39M40S which is 12 hours 39 minutes 40 seconds.
  • 2007-12-31T24:00:00 - 2007-02-20T10:48:18 gives P0Y0M314DT13H11M42S which is 314 days 13 hours 11 minutes 42 seconds.

As such, it’s possible to get a time difference between two points in time.

Forwarding and Backwarding Times

By adding a duration to a time, we get a forwarded time. By subtracting a duration from a time, we get a bacwarded time. Addition examples follow:

  • 0003-12-10 + P1Y1M1D gives 0005-01-11.
  • 0003-12-10 + P13M9D gives 0005-01-19.
  • 12:10:20 + PT1H1M1S gives 13:11:21.
  • 12:10:20 + PT13H20M30S gives 01:30:50.
  • 0003-12-10T12:10:20 + P1Y1M1DT1H1M1S gives 0005-01-11T13:11:21.
  • 0003-12-10T12:10:20 + P1Y13M2DT13H20M30S gives 0006-01-13T01:30:50.

Subtraction examples follow:

  • 0003-12-10 - P1Y1M1D gives 0002-11-09.
  • 0003-12-10 - P13M9D gives 0002-11-01.
  • 12:10:20 - PT1H1M1S gives 11:09:19.
  • 12:10:20 - PT13H20M30S gives 22:49:50.
  • 0003-12-10T12:10:20 - P1Y1M1DT1H1M1S gives 0002-11-09T11:09:19.
  • 0003-12-10T12:10:20 - P1Y13M2DT13H20M30S gives 0001-11-07T22:49:50.

Some rule examples are as follows.

fact f is time(2002-10-10);
fact g is time(2002-12-31);
rule r is
   if time(?t1) and time(?t2)
   then result([?t1 - ?t2]);

fact f is time(2002-10-10);
fact g is duration(P10Y3M);
rule r is
   if time(?t) and duration(?d)
   then result([?t - ?d]);

fact f is time(12:30:00);
fact g is duration(PT1H30M);
rule r is
   if time(?t) and duration(?d)
   then result([?t + ?d]);

fact f is time(2002-10-10T12:30:00);
fact g is duration(P10DT1H30M);
rule r is
   if time(?t) and duration(?d)
   then result([?t - ?d]);
Categories: bossam, manual

Creating OwlTrMReasoner

February 7, 2007 3 comments

OwlTrMReasoner is a new OWL-DL reasoner added to Bossam. This reasoner is the most recommended OWL reasoner among the reasoners provided by Bossam. The following is the sample codes for creating and utilizing the reasoner.

// Create a reasoner
IReasonerFactory factory = ReasonerFactory.getInstance();
IReasoner r = factory.createOwlDlTrMReasoner();
// Load an ontology
r.load(IReasoner.OWL, "....");
// Perform a silent reasoning session, 
//  which does not return conclusions
r.silentRun();
Categories: bossam, manual

Rule Generating Rules

February 7, 2007 Leave a comment

Bossam supports asserting rules at the consequent of rules. Here’s a simple example.

rule r is
   if father(?x,?y)
   then
      assert if Man(?x) then hasChild(?x);

The pattern at the consequent part is called the rule template. Instead of deriving facts, RGRs generate rule instances from the rule templates.

I believe that RGR will be very useful for encoding dynamic & complex knowledge. Also, RGR is an essential tool for performance optimization because it’s possible to reduce the number of facts by utilizing RGRs.

Hope RGRs be of a useful toy for Bossam users!

Categories: bossam, manual

Querying RDF/OWL using Bossam

February 1, 2007 4 comments

(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();
  }
 }
}

Categories: bossam, manual

Using OwlDlTrHReasoner

January 24, 2007 Leave a comment

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

Categories: bossam, manual, rambling

Explanations in Bossam

January 23, 2007 1 comment

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?

Categories: bossam, manual

Calling Java Methods from SWRL Rules

October 10, 2006 Leave a comment

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>
Categories: manual