Sunday 4 November 2012

Jena tutorial - Reasoning with user defined rules

Hi,

This tutorial will provide you with Java code and jar libraries that you need to run a simple rule reasoning example using the Jena framework.

I used Eclipse, so my tutorial will be around its functionality. This tutorial will also assume that you know the basics of Eclipse and Java.

At the end of the tutorial you should have an Eclipse project looking like:



1) So, first create a Java project in Eclipse, name it whatever you want (I call it SWIFC) and create a package inside the project where you will create your main class (I call it com.oanaureche.swifc).

2) Second, create a folder in your Eclipse project and name it lib. In here you will put all the jar libraries needed to run the main class.

3) Download the jars that you will need for running the main class and copy or cut and paste them in the lib directory. The figure above shows what libraries you will need for running the tutorial's code.

4) Add the libraries to the project's Build path in Eclipse. I will skip the instructions on how to do this. There is plenty material on the internet that show you how to do this. It's not that complicated really.

5) Create two text files inside the project and a) Add the dataset (raw data, RDF data) to the dataset.txt file and b) write the rule in the rule.txt file

These are the contents of the dataset.txt file:


@prefix : <http://oanaureche.com/prefix#> .
@prefix pre: <http://jena.hpl.hp.com/prefix#> .
:Joseph pre:father :Mary .
:John pre:brother :Joseph .


These are the contents of the rule.txt file:


@prefix pre: <http://jena.hpl.hp.com/prefix#>.
[rule1: (?f pre:father ?a) (?u pre:brother ?f) -> (?u pre:uncle ?a)]

6) For your main class, create a class inside the package that you create in step 1 (I call it ReasonWithRules.java) . The contents of this file are:


package com.oanaureche.swifc;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.rulesys.Rule;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.rdf.model.Statement;
import java.net.MalformedURLException;

public class ReasonWithRules {

/**
* @param args
* @throws MalformedURLException 
*/
public static void main(String[] args) throws MalformedURLException {
// TODO Auto-generated method stub

Model instances = ModelFactory.createDefaultModel();
instances.read ("file:dataset.txt","N3");
Reasoner reasoner = new  
                    GenericRuleReasoner(Rule.rulesFromURL("file:rule.txt"));
reasoner.setDerivationLogging(true);
InfModel inf = ModelFactory.createInfModel(reasoner, instances); 

        //print out the statements in the model
StmtIterator iter = inf.listStatements();
while (iter.hasNext()) {
   Statement stmt      = iter.nextStatement();  
   Resource  subject   = stmt.getSubject();     
   Property  predicate = stmt.getPredicate();   
   RDFNode   object    = stmt.getObject();      

   System.out.print(subject.toString());
   System.out.print(" " + predicate.toString() + " ");
   if (object instanceof Resource) {
      System.out.print(object.toString());
   } else {
       // object is a literal
       System.out.print(" \"" + object.toString() + "\"");
   }
   System.out.println(" .");

}
}

7) Run this Java application and you should see the following in the console:


http://oanaureche.com/prefix#John http://jena.hpl.hp.com/prefix#uncle http://oanaureche.com/prefix#Mary .

http://oanaureche.com/prefix#John http://jena.hpl.hp.com/prefix#brother http://oanaureche.com/prefix#Joseph .

http://oanaureche.com/prefix#Joseph http://jena.hpl.hp.com/prefix#father http://oanaureche.com/prefix#Mary .


The reasoner inferred a third statement: that John is the uncle of Mary. Pretty cool!