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!


7 comments:

  1. Hi ,
    thanks for this great tuto :)
    i have a question , plz , what if i want to reason jena rules basing on an ontology built with portégé , how can i do this ? thank you

    ReplyDelete
  2. Hi, sorry for the late reply. As far as I know you can reason with rules on data, not on an ontology.. but feel free to ask this question on the jena mailing list. They should be able to help you. Oana.

    ReplyDelete
  3. Oana: thank you...

    To folks trying to recreate this...you may need to change the file extensions .txt to .n3.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. thank you for posting such helping material....
    i am getting with this error in my eclipse please help me how can i remove this error
    SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding.
    SLF4J: Your binding is version 1.5.5 or earlier.
    SLF4J: Upgrade your binding to version 1.6.x.

    ReplyDelete
    Replies
    1. i read some material on the link below but i was unable to resolve

      http://stackoverflow.com/questions/32826250/slf4j-slf4j-api-1-6-x-or-later-is-incompatible-with-this-binding

      Delete
    2. the above link worked for me thank you so much
      i tried one dependencies mismatched now it works fine

      Delete