Mentions légales du service

Skip to content
Snippets Groups Projects
index.html 15.3 KiB
Newer Older
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Exploiting alignments and reasoning</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link rel="stylesheet" type="text/css" href="../../base.css" />
<link rel="stylesheet" type="text/css" href="../../style.css" />
<script type="text/javascript">
<!--
function show(id) {
	var element = document.getElementById(id);
	element.style.display = "block";
}
function hide(id) {
	var element = document.getElementById(id);
	element.style.display = "none";
}
-->
</script>
<style type="text/css">
<!--
div.logic {
	padding-left: 5px;
	padding-right: 5px;
	margin-top: 10px;
	margin-bottom: 10px;
}
-->
</style>
</head>
<body style="background-color: #FFFFFF;">

<h1>Exploiting alignments and reasoning: advanced tutorial on the Alignment <abbr title="Application Programming Interface">API</abbr> and server</h1>

<p>
<dl>
<dt>This version:</dt>
<dd>http://alignapi.gforge.inria.fr/tutorial/tutorial4/</dd>
<dt>Author:</dt>
<dd><a href="http://exmo.inrialpes.fr/people/euzenat">J&eacute;r&ocirc;me Euzenat</a>, INRIA  &amp; LIG
</dd>
</dl>
</p>

<p style="border-top: 2px solid
	  #AAAAAA; padding-top: 15px; padding-bottom: 15px;">
Here is a more advanced tutorial for the
alignment <abbr>API</abbr> which explains how to interface the API
with other components.
This tutorial will show how to:
<ul>
<li>communicate the alignment server
through its REST web service API,</li>
<li>manipulate alignments with the Alignment API in Java,</li>
<li>perform OWL reasoning on aligned ontologies and compose
  alignments.</li>
</ul>
This time, the tutorial is based on Java programming and using various
related APIs.
</p>
<p>
Other tutorials are <a href="../index.html">available</a>.</p>
<p  style="border-top: 2px solid #AAAAAA;"><small>This tutorial has
    been designed for the Alignment API version 4.0. It is currently
    incomplete due to the upgrade of Pellet to version 2.1 and IDDL.</small></p>
	
<h2>Preparation</h2>
	
<p>Just:
<div class="fragment">
$ cd tutorial4
</div>
</p>
	
<h2>Data</h2>
	
<p>
We have two ontologies, <a href="ontology1.owl">ontology1.owl</a>
and <a href="ontology2.owl">ontology2.owl</a>, under which two sets of
students are described. Unfortunately, the
administration started to record participants with their own ontology
before finding that using <a href="http://foaf-project.org">FOAF</a>
would be a better idea. We now end up with two incomplete lists of
participants.
</p>
<p>
The goal is to have a unified view of these participants. For that
purpose, we will match the two ontologies and reason with the result
in order to view participants from boths ontologies under the other
ontology. This is not a difficult task, the goal here is only to show
how this could be achieved.
</p>
	
<p>For that purpose, you have to develop a program in Java. 
We first define the CLASSPATH because a lot of external software is required
<div class="fragment">
$ setenv CLASSPATH ../../../lib/align.jar:../../../lib/procalign.jar:../../../lib/jena/jena.jar:../../../lib/jena/arq.jar:../../../lib/iddl/iddl.jar:../../../lib/pellet/pellet-core.jar:../../../lib/pellet/pellet-owlapiv3.jar:../../../lib/pellet/pellet-rules.jar:../../../lib/pellet/pellet-datatypes.jar:../../../lib/pellet/aterm-java-1.6.jar:../../../lib/pellet/pellet-query.jar:../../../lib/ontosim/ontosim.jar:../../../lib/pellet/pellet-el.jar:../../../lib/log4j/commons-logging.jar:../../../lib/log4j/log4j.jar:../../../lib/xerces/xercesImpl.jar:../../../lib/jena/iri.jar:../../../lib/jena/icu4j_3_4.jar:../../../lib/jena/concurrent.jar:../../../lib/xsdlib/relaxngDatatype.jar:../../../lib/xsdlib/xsdlib.jar:results
</div>
The list of jars is long, but at least it is explicit and you
should be safe with this one.
This programme can be compiled by:
<div class="fragment">
$ javac -d results Skeleton.java
<p>This programme can be run by:
<div class="fragment">
$ java Skeleton
</div>
It provides no output for the moment.
</p>

<h2>Matching ontologies</h2>

<p>
This can be achieved:
<ul>
<li>by finding an alignment from the web/server</li>
<li>by running a matcher locally</li>
<li>by running a matcher on the alignment server</li>
<li>by finding a chain of alignments from the web/server</li>
</ul>
</p>

<p>
Write a program that does try to find an alignment on the alignment
server <a href="http://aserv.inrialpes.fr">http://aserv.inrialpes.fr</a>
and, if none is found, computes one.
</p>
<div class="button">
  <input type="button" onclick="show('qu0')" value="Various variables"/>
  <input type="button" onclick="show('qu1')" value="Show solution 1"/>
  <input type="button" onclick="show('qu2')" value="Show solution 2"/>
  <input type="button" onclick="show('qu3')" value="Show solution 3"/>
  <input type="button" onclick="hide('qu0');hide('qu1');hide('qu2');hide('qu3');" value="Hide solutions"/>
</div>
<div class="explain" id="qu0">
<p>After introducing the main variables:</p>
<pre>
String myId = "Test";
Alignment al = null;
URI uri1 = null;
URI uri2 = null;
String u1 = "file:ontology1.owl";
String u2 = "file:ontology2.owl";
String method = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment";
String tempOntoFileName = "results/myresult.owl";
Properties params = new BasicParameters();
try {
  uri1 = new URI( u1 );
  uri2 = new URI( u2 );
} catch (URISyntaxException use) { use.printStackTrace(); }
</pre>
</div>
<div class="explain" id="qu1">
<p>The programme will invoke the alignment server:</p>
<pre>
// (Sol1) Try to find an alignment between two ontologies from the server
// ask for it
String found = getFromURLString( RESTServ+"find?onto1="+u1+"&onto2="+u2, false );
</pre>
<p>Retrieve the alignment itself:</p>
<pre>
// retrieve it
// If there exists alignments, ask for the first one
NodeList alset = extractFromResult( found, "//findResponse/alignmentList/alid[1]/text()", false );
</pre>
<p>And parse it:</p>
<pre>
// parse it as an alignment
AlignmentParser aparser = new AlignmentParser(0);
Alignment alu = aparser.parseString( xmlString );
al = ObjectAlignment.toObjectAlignment((URIAlignment)alu);
</pre>
</div>
<div class="explain" id="qu2">
<p>Just create an instance of AlignmentProcess and call it:</p>
// (Sol2) Match the ontologies with a local algorithm
if ( al == null ){ // Unfortunatelly no alignment was available
  AlignmentProcess ap = new StringDistAlignment();
  ap.init( uri1, uri2 );
  params.setProperty("stringFunction","smoaDistance");
  params.setProperty("noinst","1");
  ap.align( (Alignment)null, params );
  al = ap;
}
</pre>
</div>
<div class="explain" id="qu3"><p>Match on the server:</p>
<pre>
// (Sol3) Match the ontologies on the server
if ( alset.getLength() == 0 ) {
  // call for matching
  String match = getFromURLString( RESTServ+"match?onto1="+u1+"&onto2="+u2+"&method="+method+"&pretty="+myId+"&action=Match", true );
}
</pre>
<p>The remainder is the same as in the first solution.</p>
</div>
<div class="logic">
<p><b>More work:</b> You can also store localy computed alignments on
  the alignment server.</p>
</div>
<div class="button">
  <input type="button" onclick="show('qu4')" value="Show solution"/>
  <input type="button" onclick="hide('qu4');" value="Hide solution"/>
</div>
<div class="explain" id="qu4"><p>Not ready yet (but not difficult)</p>
<pre>
</pre>
</div>

<h2>Manipulate the data</h2>

<p>
Again, this is either:
<ul>
<li>generating OWL axioms from the alignments and merge the ontologies</li>
<li>transforming data from one ontology to another</li>
</ul>
</p>
<p>
This can be done with the alignment API support.
</p>

<div class="button">
  <input type="button" onclick="show('qu5')" value="Show solution 1"/>
  <!--input type="button" onclick="show('qu6')" value="Show solution 2"/-->
  <input type="button" onclick="hide('qu5');hide('qu6');" value="Hide solutions"/>
</div>
<div class="explain" id="qu5">
<p>In fact everything is done in one step:</p>
<pre>
// (Sol1) generate a merged ontology between the ontologies (OWLAxioms)
PrintWriter writer = null;
File merged = new File( tempOntoFileName );
writer = new PrintWriter ( new FileWriter( merged, false ), true );
AlignmentVisitor renderer = new OWLAxiomsRendererVisitor(writer);
al.render(renderer);
writer.flush();
writer.close();
<p>You can look at the result in <a href="results/myresult.owl">results/myresult.owl</a>.</p>
</div>
<div class="explain" id="qu6"><p>Not ready yet</p>
<pre>
</pre>
</div>

<h2>Generate the answers</h2>

<p>
This can be done in three ways:
<ul>
<li>using SPARQL</li>
<li>using a reasonner such as Pellet to answer these queries against
  the merged ontologies.</li>
<li>using a "distributed" reasoner, in our case IDDL, to answer these
  queries against non merged aligned ontologies.</li>
</ul>
</p>
<p>
In case you go for SPARQL please, take care of the inference regime
and observe what are the differences in this case. You can of course
run various queries and start by running them in one of the initial
ontologies instead of the merged one.
</p>
For using Pellet, which is not bundled with the Alignment API, it will be necessary
to <a href="http://clarkparsia.com/pellet/download">download
it</a>  and add in
the classpath the corresponding aterm-java-1.6.jar, pellet-core.jar, pellet-rules.jar,
pellet-datatypes.jar, pellet-jena.jar, pellet-query.jar, pellet-owlapiv3.jar and pellet-el.jar jar-files
which are not shipped with the Alignment API.
</p>
</p>
<div class="button">
  <input type="button" onclick="show('qu7')" value="Show solution 1"/>
  <input type="button" onclick="show('qu8')" value="Show solution 2"/>
  <!--input type="button" onclick="show('qu9')" value="Show solution 3"/-->
  <input type="button" onclick="hide('qu7');hide('qu8');hide('qu9');" value="Hide solutions"/>
</div>
<div class="explain" id="qu7">
<p>Prepare the system:</p>
<pre>
// (Sol1) Use SPARQL to answer queries (at the data level)
InputStream in = new FileInputStream( merged );
Model model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF,null);
model.read( in, "file:"+tempOntoFileName );
in.close();
</pre>	
<p>Query (please play by changing the query)</p>
<pre>
// Create a new query
String queryString = 
		"PREFIX foaf: <http://xmlns.com/foaf/0.1/> " +
		"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
		"PREFIX aa: <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#> " +
		"WHERE {" +
                "      ?student rdf:type aa:Estudiante . " +
		"      ?student aa:firstname  ?fn. " +
		"      ?student aa:lastname  ?ln. " +
		"OPTIONAL   {   ?student aa:affiliation ?t . } " +
		"OPTIONAL   {   ?student aa:supervisor ?s . } " +

Query query = QueryFactory.create(queryString);

</pre>	
<p>Evaluation:</p>
<pre>
// Execute the query and obtain results
QueryExecution qe = QueryExecutionFactory.create(query, model);
ResultSet results = qe.execSelect();
// Output query results	
ResultSetFormatter.out(System.out, results, query);
</pre>
</div>
<div class="explain" id="qu8">
<p>Create Reasoner instance and load the merged ontologies:</p>
<pre>
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
// Load the ontology 
OWLOntology ontology = manager.loadOntology( IRI.create( "file:"+tempOntoFileName ) );
OWLReasoner reasoner = new PelletReasoner( ontology, org.semanticweb.owlapi.reasoner.BufferingMode.NON_BUFFERING );
reasoner.prepareReasoner();
</pre>
<p>Get the instances of "Estudiantes":</p>
<pre>
// get the instances of a class
OWLClass estud = manager.getOWLDataFactory().getOWLClass( IRI.create( "http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante" ) );   
OWLClass person = manager.getOWLDataFactory().getOWLClass( IRI.create( "http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Person" ) );   
OWLClass student = manager.getOWLDataFactory().getOWLClass( IRI.create( "http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student" ) );   
Set&lt;OWLNamedIndividual> instances  = reasoner.getInstances( estud, false ).getFlattened();
System.err.println("Pellet(Merged): There are "+instances.size()+" students "+clname(estud));
</pre>
<p>Some subsumption tests:</p>
<pre>
testPelletSubClass( manager, reasoner, estud, person );
testPelletSubClass( manager, reasoner, estud, student );
</pre>
<p>Such that:</p>
<pre>
private String clname( OWLClassExpression cl ) {
  return cl.asOWLClass().getIRI().getFragment();
}

public void testPelletSubClass( OWLOntologyManager manager, OWLReasoner reasoner, OWLClassExpression d1, OWLClassExpression d2 ) {
  OWLAxiom axiom = manager.getOWLDataFactory().getOWLSubClassOfAxiom( d1, d2 );
  if ( reasoner.isEntailed( axiom ) ) {
    System.out.println( "Pellet(Merged): "+clname(d1)+" is subclass of "+clname(d2) );
  } else {
    System.out.println( "Pellet(Merged): "+clname(d1)+" is not necessarily subclass of "+clname(d2) );
  }
}
</pre>
</div>
<div class="explain" id="qu9">
<p>Load the two ontologies and the alignment in the IDDL reasoner:</p>
<pre>
	IDDLReasoner dreasoner = new IDDLReasoner( Semantics.DL );
	dreasoner.addOntology( uri1 );
	dreasoner.addOntology( uri2 );
	dreasoner.addAlignment( al );
</pre>
<p>Test consistency and check if a particular correspondence is a consequence:</p>
<pre>
	if ( dreasoner.isConsistent() ) {
	    System.out.println( "IDDL: the alignment network is consistent");
	    testIDDLSubClass( dreasoner, uri1, uri2, estud, person );
	    testIDDLSubClass( dreasoner, uri1, uri2, estud, student );
         } else {
	    System.out.println( "IDDL: the alignment network is inconsistent");
	}
</pre>
<p>Such that:</p>
<pre>
    public void testIDDLSubClass( IDDLReasoner dreasoner, URI onto1, URI onto2, OWLDescription d1, OWLDescription d2 ) {
	Alignment al2 = new ObjectAlignment();
	try {
	    al2.init( onto1, onto2 );
	    // add the cell
	    al2.addAlignCell( d1, d2, "&lt;", 1. );
	} catch (AlignmentException ae) { ae.printStackTrace(); }
	if ( dreasoner.isEntailed( al2 ) ) {
	    System.out.println( "IDDL: "+d1+" <= "+d2+" is entailed" );
	} else {
	    System.out.println( "IDDL: "+d1+" <= "+d2+" is not entailed" );
	}
    }
</pre>
</div>
The results for these execution are, for SPARQL:
<pre>
---------------------------------------------------------------------------------------
| fn      | ln      | t                            | s                                |
=======================================================================================
| "Miles" | "Davis" | "JOHANNISBEER RESEARCH"      | "Univ.-Prof. Dr. Paolo Carciofo" |
| "Chet"  | "Baker" | "University Pie XXIII"       |                                  |
| "McCoy" | "Tyner" | "University of Soupaloignon" | "Dr Nanni Girasole"              |
...
</pre>
for Pellet:
Pellet(Merged): There are 47 students http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante
Pellet(Merged): Estudiante is not necessarily subclass of Person
Pellet(Merged): Estudiante is subclass of Student
</pre>
and for IDDL:
<pre>
IDDL: the alignment network is consistent
IDDL: Estudiante <= Person is not entailed
IDDL: Estudiante <= Student is entailed
</pre>
	
	
<p>Do you want to see a possible solution?</p>
<p>A full working solution is <a href="MyApp.java">MyApp.java</a>.</p>
<p style="text-align: center;">http://alignapi.gforge.inria.fr/tutorial/tutorial4/</p>
</small>
<hr />
<p>$Id$</p>
</body>
</html>