<?xml version="1.0" encoding="UTF-8"?>
<tells uri="" xmlns="http://dl.kr.org/dig/2003/02/lang"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://potato.cs.man.ac.uk/dig/level0/dig.xsd">
<equalc>
<catom name="owl:Thing"/>
<top/>
</equalc>
<defconcept name="ParmezanTopping"/>
<equalc>
<catom name="ParmezanTopping"/>
<and>
<catom name="CheeseTopping"/>
<some>
<ratom name="hasSpicyness"/>
<catom name="MildSpiciness"/>
</some>
</and>
</equalc>
<disjoint>
<catom name="ParmezanTopping"/>
<catom name="MozzarellaTopping"/>
</disjoint>
<disjoint>
<catom name="ParmezanTopping"/>
.
.
.
The advantage of DIG is that applications can communicate with any DIG compliant reasoner, without needing to know specific
reasoner details or reasoner interaction protocols. This means that it is possible to "plug in" any DIG compliant
reasoner into any DIG aware application. For example, RACER, FaCT++ or any other DIG compliant reasoner may be used with
Protégé-OWL.Protégé-OWL provides an API that can be used to interact with an external DIG reasoner. Fortunately for developers, the Protégé-OWL reasoning API abstracts away from the DIG language/reasoner, meaning that it is not really necessary to know the fine grained details of DIG, or that the reasoning services are being provided by an external DIG reasoner.
The Reasoning APIThe following sections provide a rough outline of how to use the Protégé-OWL reasoning API. The examples use an ontology that describes pizzas, which can be downloaded from the CO-ODE Web site at the University of Manchester. This ontology is roughly based on the "Pizzas" ontology that is constructed in the popular Protégé-OWL tutorial, written by Matthew Horridge of the University of Manchester.
Theinference Package
The reasoning API is encapsulated in the edu.stanford.smi.protegex.owl.inference package. The main classes
that will be used are the ReasonerManager (used to obtain a reasoner) and
ProtegeOWLReasoner (an interface to the external DIG reasoner). More information about
downloading the
Protégé-OWL source code is available on the main developer documentation page.
In general, the first step when using the reasoning API is to obtain an instance of ProtegeOWLReasoner for an
OWL model. This instance of the reasoner can then be used to obtain inferred information about the model such as inferred
superclasses, inferred equivalent classes, and inferred types for individuals. The ProtegeOWLReasoner manages
communication with the external DIG reasoner, ensuring that it is always properly synchronised with the internal
Protégé-OWL model.
In order to get an instance of ProtegeOWLReasoner for an OWL model, the ReasonerManager, which is
found in the edu.stanford.smi.protegex.owl.inference.protegeowl package, must be used. The
ReasonerManager is a singleton class (a class with only one instance), whose instance can be obtained by using the
static method getInstance().
getReasoner(OWLModel kb) method on the ReasonerManager can be used to obtain the reasoner
for the specified OWLModel. This method will return the same instance of ProtegeOWLReasoner for
a given model each time it is called. An alternative method getReasoner(OWLModel kb, boolean createNew) may be
used to obtain a reasoner for a knowledge base. If the createNew flag is set to true, then this
method will create a brand new instance of ProtegeOWLReasoner for the specified knowledge base. In general,
the former method is preferred since the default implementation of ProtegeOWLReasoner only synchronizes the
external DIG reasoner with the Protégé-OWL model when necessary (when changes have occurred to the OWL model) -
creating a new reasoner every time will cause the external DIG reasoner to be resynchronised every time, which could be costly
in terms of time for large ontologies. The code snippet below shows how to obtain a ProtegeOWLReasoner for
an OWLModel:
// Get the reasoner manager and obtain a reasoner for the OWL model. ReasonerManager reasonerManager = ReasonerManager.getInstance(); ProtegeOWLReasoner reasoner = reasonerManager.getReasoner(model);Setting and Checking the Reasoner Connection
Communication with an external DIG compliant reasoner is facilitated over HTTP, so the URL of the external DIG Reasoner
needs to be provided. This is done with the setReaonerURL(String url) method on
ProtegeOWLReasoner. Having set the URL, the connection may be tested using the
isConnected() method. An example is shown in the following code snippet:
// Set the reasoner URL (using the default URL for Racer here) and test the connection.
reasoner.setURL(http://localhost:8080);
if (reasoner.isConnected()) {
// Get the reasoner identity - this contains information
// about the reasoner, such as it's name and version,
// and the tell and ask operations that it supports.
DIGReasonerIdentity reasonerIdentity = reasoner.getIdentity();
System.out.println("Connected to " + reasonerIdentity.getName());
}
Querying the Reasoner for Inferred Information
Once the connection to a reasoner has been established, the reasoner can be queried for information about the ontology.
The ProtegeOWLReasoner interface contains several methods to obtain inferred information about classes and
individuals. For example, there are methods to get the inferred superclasses and subclasses of a given class. The example
below shows how to get the inferred subclasses for a specific class, in this case VegetarianPizza, which is a
named class in the Pizza ontology. First, the asserted named subclasses of VegetarianPizza are
retrieved via the OWLModel using vegetarianPizza.getNamedSubclasses(). In the case of
this example, the number of asserted subclasses should be zero. Next, the inferred subclasses of
VegetarianPizza are retrieved by querying the reasoner, and are then are printed out.
// Get the VegetarianPizza OWLNamedClass from the OWLModel
OWLNamedClass vegetarianPizza = model.getOWLNamedClass("VegetarianPizza");
if (vegetarianPizza != null) {
// Get the number of asserted subclasses of VegetarianPizza
Collection assertedSubclasses = vegetarianPizza.getNamedSubclasses();
System.out.println("Number of asserted VegetarianPizzas: " + assertedSubclasses.size());
// Now get the inferred subclasses of VegetarianPizza
Collection inferredSubclasses = reasoner.getSubclasses(vegetarianPizza, null);
System.out.println("Number of inferred VegetarianPizzas: " + inferredSubclasses.size());
// Print out the inferred subclasses
System.out.println("VegetarianPizzas:");
for (Iterator it = inferredSubclasses.iterator(); it.hasNext();) {
OWLNamedClass curClass = (OWLNamedClass) it.next();
System.out.println(curClass.getName());
}
}
Updating Protégé-OWL with Inferred InformationProtegeOWLReasoner query the external DIG reasoner to obtain inferred information
and then insert this information into the OWLModel. To some extent this can be useful for large models, because
rather than querying the reasoner for information about every class in the ontology manually (each time incurring the cost
of an HTTP request/response), a 'bulk' query is performed - once for consistency checking, once for inferred superclass
checking, and once for equivalent class checking. After these bulk queries have been performed, the OWLModel
is updated, which means that the model can be examined "offline" from the reasoner. An example of this is shown
below. The classifyTaxonomy method bulk queries the reasoner for the consistency, inferred superclasses, and
equivalent classes of every class in the ontology (using only 3 HTTP request/responses) and then inserts this information
into the Protégé-OWL model. The model can then be queried for the stored inferred information.
// We can classify the whole ontology, which will put the
// inferred class hierarchy information directly into the Protégé-OWL model.
System.out.println("Classifying taxonomy...");
reasoner.classifyTaxonomy(null);
System.out.println("...Classified taxonomy!");
// We can then use the methods on OWLNamedClass for getting inferred
// information, without having to make separate queries to the external
// DIG reasoner.
System.out.println("Inferred subclasses of VegetarianPizza:");
inferredSubclasses = vegetarianPizza.getInferredSubclasses();
for (Iterator it = inferredSubclasses.iterator(); it.hasNext();) {
OWLNamedClass curClass = (OWLNamedClass) it.next();
System.out.println(curClass.getName());
}
Examples of other methods that update the OWLModel are computeInconsistentClasses, which queries
the reasoner for the consistency of all classes in the ontology and the updates the OWLModel. Also,
the computeInferredTypes method queries the reasoner for the inferred types of all individuals in the ontology
and then updates the OWLModel.plugins/edu.stanford.smi.protegex.owl) are on your classpath.
import edu.stanford.smi.protegex.owl.model.OWLModel;
import edu.stanford.smi.protegex.owl.model.OWLNamedClass;
import edu.stanford.smi.protegex.owl.ProtegeOWL;
import edu.stanford.smi.protegex.owl.inference.protegeowl.ReasonerManager;
import edu.stanford.smi.protegex.owl.inference.protegeowl.ProtegeOWLReasoner;
import edu.stanford.smi.protegex.owl.inference.dig.reasoner.DIGReasonerIdentity;
import java.util.Iterator;
import java.util.Collection;
/**
* The Univeristy Of Manchester
* Medical Informatics Group
* Date: Jan 7, 2005
*/
public class ReasonerExample {
public static void main(String[] args) {
try {
final String ONTOLOGY_URL = "http://www.co-ode.org/ontologies/pizza/pizza_20041007.owl";
final String REASONER_URL = "http://localhost:8080";
// Load the ontology from the specified URL
OWLModel model = ProtegeOWL.createJenaOWLModelFromURI(ONTOLOGY_URL);
// Get the reasoner manager and obtain a reasoner for the OWL model.
ReasonerManager reasonerManager = ReasonerManager.getInstance();
ProtegeOWLReasoner reasoner = reasonerManager.getReasoner(model);
// Set the reasoner URL and test the connection
reasoner.setURL(REASONER_URL);
if(reasoner.isConnected()) {
// Get the reasoner identity - this contains information
// about the reasoner, such as it's name and version,
// and the tell and ask operations that it supports.
DIGReasonerIdentity reasonerIdentity = reasoner.getIdentity();
System.out.println("Connected to " + reasonerIdentity.getName());
// Get the VegetarianPizza OWLNamedClass from the OWLModel
OWLNamedClass vegetarianPizza = model.getOWLNamedClass("VegetarianPizza");
if(vegetarianPizza != null) {
// Get the number of asserted subclasses of VegetarianPizza
Collection assertedSubclasses = vegetarianPizza.getNamedSubclasses();
System.out.println("Number of asserted VegetarianPizzas: " + assertedSubclasses.size());
// Now get the inferred subclasses of VegetarianPizza
Collection inferredSubclasses = reasoner.getSubclasses(vegetarianPizza, null);
System.out.println("Number of inferred VegetarianPizzas: " + inferredSubclasses.size());
System.out.println("VegetarianPizzas:");
for(Iterator it = inferredSubclasses.iterator(); it.hasNext();) {
OWLNamedClass curClass = (OWLNamedClass) it.next();
System.out.println(curClass.getName());
}
// We can classify the whole ontology, which will put the
// inferred class hierarchy information directly into the Protégé-OWL model.
System.out.println("Classifying taxonomy...");
reasoner.classifyTaxonomy(null);
System.out.println("...Classified taxonomy!");
// We can then use the methods on OWLNamedClass for getting inferred
// information, without having to make separate queries to the external
// DIG reasoner, as this information is now in the OWLModel.
System.out.println("Inferred subclasses of VegetarianPizza:");
inferredSubclasses = vegetarianPizza.getInferredSubclasses();
for(Iterator it = inferredSubclasses.iterator(); it.hasNext();) {
OWLNamedClass curClass = (OWLNamedClass) it.next();
System.out.println(curClass.getName());
}
}
else {
System.out.println("Could not find VegetarianPizza");
}
}
else {
System.out.println("Reasoner not connected!");
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Example output from the program above looks as follows:
Connected to Racer Number of asserted VegetarianPizzas: 0 Number of inferred VegetarianPizzas: 10 VegetarianPizzas: Caprina QuattroFormaggi Fiorentina Giardiniera Margherita Soho Veneziana Mushroom PrinceCarlo Rosa Classifying taxonomy... ...Classified taxonomy! Inferred subclasses of VegetarianPizza: Margherita QuattroFormaggi PrinceCarlo Mushroom Soho Giardiniera Rosa Veneziana Caprina FiorentinaOWL-Full Models
ReasonerLogger. An example of how to listen for and print out log messages
is shown below:
ReasonerLoggerListener lsnr = new ReasonerLoggerListener() {
public void logRecordPosted(ReasonerLogRecord reasonerLogRecord) {
if (reasonerLogRecord instanceof MessageLogRecord) {
MessageLogRecord msgLog = (MessageLogRecord) reasonerLogRecord;
System.out.println(msgLog.getMessage());
}
} };
ReasonerLogger.getInstance().addListener(lsnr);
Summary