Jena reasoning with rules

In this tutorial we explain, how you can perform reasoning with rules using Apache Jena. The example code is available on Github.

1. Create a Dataset

Starting of with an example dataset called dataset.n3:

@prefix : <http://tutorialacademy.com/2015/jena#> .

:John :hasClass :Math .
:Bill :teaches :Math .

We have two statements. John has a class which is Math. Bill teaches a Math class. Consequently, Bill has a student called John. That is exactly what we want to infer later on.

2. Writing a rule

We create a rule file called rules.txt and add the following rule:

@prefix : <http://tutorialacademy.com/2015/jena#> .

[ruleHasStudent: (?s :hasClass ?c) (?p :teaches ?c) -> (?p :hasStudent ?s)]

This basically means, if we find a triple where ?s has a class ?c and another triple where ?p teaches some class ?c, then we can conclude that ?p has a student ?s.

3. Perform the reasoning with rules

The following code will do the trick:

package com.tutorialacademy.jena.reasoning;

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

public class JenaReasoningWithRules
{
	public static void main(String[] args) 
	{
		Model model = ModelFactory.createDefaultModel();
		model.read( "dataset.n3" );
		
		Reasoner reasoner = new GenericRuleReasoner( Rule.rulesFromURL( "rules.txt" ) );
		
		InfModel infModel = ModelFactory.createInfModel( reasoner, model );

		StmtIterator it = infModel.listStatements();
		
		while ( it.hasNext() )
		{
			Statement stmt = it.nextStatement();
			
			Resource subject = stmt.getSubject();
			Property predicate = stmt.getPredicate();
			RDFNode object = stmt.getObject();

			System.out.println( subject.toString() + " " + predicate.toString() + " " + object.toString() );
		}
	}
}

Before you run this code make sure you have the dataset and the rules in the root folder of the project, or adapt it accordingly. The code explained:

  1. Create an empty default model and load our dataset
  2. Create a reasoner from our rule
  3. Create new model (infModel) from our default model using the reasoner to infer new relationships
  4. Get all statement from the infModel and write to console

After executing, you should see the following output:

http://tutorialacademy.com/2015/jena#Bill http://tutorialacademy.com/2015/jena#hasStudent http://tutorialacademy.com/2015/jena#John
http://tutorialacademy.com/2015/jena#Bill http://tutorialacademy.com/2015/jena#teaches http://tutorialacademy.com/2015/jena#Math
http://tutorialacademy.com/2015/jena#John http://tutorialacademy.com/2015/jena#hasClass http://tutorialacademy.com/2015/jena#Math

We can see that our Jena model now contains three statements (in contrast to our example dataset which contains two statements). The new statement is exactly what we concluded when looking at the dataset. Bill has a student called John.

While this is an extremly small example, you can perform powerful reasoning and inference with more rules and more data.

If you have problems to run or understand the example, feel free to ask or comment.

Facebooktwitterredditpinterestlinkedinmail

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.