Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 04aa601b authored by Jérôme Euzenat's avatar Jérôme Euzenat
Browse files

- full tutorial nearly ready

parent b569193c
No related branches found
No related tags found
No related merge requests found
...@@ -51,31 +51,51 @@ This tutorial will learn you to: ...@@ -51,31 +51,51 @@ This tutorial will learn you to:
<ul> <ul>
<li>communicate the alignment server <li>communicate the alignment server
through its REST web service API,</li> through its REST web service API,</li>
<li>manipulate the Alignments with the Alignment API in Java,</li> <li>manipulate alignments with the Alignment API in Java,</li>
<li>perform OWL reasoning on alignmed ontologies and compose <li>perform OWL reasoning on aligned ontologies and compose
alignments.</li> alignments.</li>
</ul> </ul>
This time, the tutorial is based on Java programming and using various This time, the tutorial is based on Java programming and using various
related APIs. related APIs.
</p> </p>
<p> <p>
A more <a href="../tutorial/index.html">simple tutorial</a> as well as A more <a href="../tutorial/index.html">simple tutorial</a> as well as
a small <a href="../tutorial/server.html">server tutorial</a> are also available.</p> a small <a href="../tutorial/server.html">server tutorial</a> are also available.</p>
<p style="border-top: 2px solid #AAAAAA;"><small>This tutorial has been designed for the Alignment API version 3.6.</small></p> <p style="border-top: 2px solid #AAAAAA;"><small>This tutorial has been designed for the Alignment API version 4.0.</small></p>
<h2>Preparation</h2> <h2>Preparation</h2>
<p>See the <a href="../tutorial/index.html">simple tutorial preparation part</a>.</p> <p>
See the <a href="../tutorial/index.html">simple tutorial
preparation part</a>.
</p>
<p>
Looking at the last section of this tutorial can help to manipulate
the Alignment API constructs alone. In the present tutorial, we will
interface the Alignment API with other components:
<ul>
<li>The Alignment server as a web service;</li>
<li>A SPARQL reasoner (<a href=""></a>ARQ) using <a href=""></a>Jena;</li>
<li>An OWL reasoner (<a href=""></a>Pellet) using OWL API.</li>
</ul>
</p>
<h2>Data</h2> <h2>Data</h2>
<p> <p>
We have two ontologies, to be found on the web, under which two half of the summerschool participants are described. We have two ontologies, <a href="ontology1.owl">ontology1.owl</a>
and <a href="ontology2.owl">ontology2.owl</a>, under which two half of
the summerschool participants are described. Unfortunately, the
organiser started to record participants with their own ontology
before recogning 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>
<p> <p>
The goal is to have a unified view of these participants. The goal is to have a unified view of these participants. For that
.</p> purpose, we will match the two ontologies and reason with the result
in order to
</p>
<p>For that purpose, you have to develop a program in Java. This <p>For that purpose, you have to develop a program in Java. This
programme can be compiled by: programme can be compiled by:
...@@ -84,9 +104,13 @@ $ javac -classpath ../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/je ...@@ -84,9 +104,13 @@ $ javac -classpath ../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/je
</div> </div>
and run by: and run by:
<div class="fragment"> <div class="fragment">
$ java -classpath .:../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/jena.jar:../../lib/jena/arq.jar:../../lib/iddl/iddl.jar:../../lib/pellet/pellet.jar MyApp $ java -classpath .:../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/jena.jar:../../lib/jena/arq.jar:../../lib/iddl/iddl.jar:../../lib/pellet/pellet.jar:../../lib/ontosim/ontosim.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 MyApp
</div> </div>
The long list of jar is boring, but at list it is explicit and you
should be safe with this one.
<p>
</p>
You can start with the empty template <a href="Skeleton.java">Skeleton.java</a>.
</p> </p>
<h2>Matching ontologies</h2> <h2>Matching ontologies</h2>
...@@ -94,8 +118,9 @@ $ java -classpath .:../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/j ...@@ -94,8 +118,9 @@ $ java -classpath .:../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/j
<p> <p>
This can be achieved: This can be achieved:
<ul> <ul>
<li>by running programs either locally or from the alignment server</li>
<li>by finding an alignment from the web/server</li> <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> <li>by finding a chain of alignments from the web/server</li>
</ul> </ul>
</p> </p>
...@@ -103,84 +128,88 @@ This can be achieved: ...@@ -103,84 +128,88 @@ This can be achieved:
<p> <p>
Write a program that does try to find an alignment on the alignment 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> server <a href="http://aserv.inrialpes.fr">http://aserv.inrialpes.fr</a>
and, if none is found, compute one and store it on the server. and, if none is found, computes one.
</p> </p>
<p>A skeleton of program using the Alignment <abbr>API</abbr> is <a href="Skeleton.java">Skeleton.java</a>. It can be compiled by invoking:</p>
<div class="button"> <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('qu1')" value="Show solution 1"/>
<input type="button" onclick="show('qu2')" value="Show solution 2"/> <input type="button" onclick="show('qu2')" value="Show solution 2"/>
<input type="button" onclick="show('qu3')" value="Show solution 3"/> <input type="button" onclick="show('qu3')" value="Show solution 3"/>
<input type="button" onclick="hide('qu1');hide('qu2');hide('qu3');" value="Hide solutions"/> <input type="button" onclick="hide('qu1');hide('qu2');hide('qu3');" value="Hide solutions"/>
</div> </div>
<div class="explain" id="qu1"><p>After introducing the main variables:</p> <div class="explain" id="qu0">
<p>After introducing the main variables:</p>
<pre> <pre>
URI onto1 = null;
URI onto2 = null;
String myId = "JETest"; String myId = "JETest";
String u1 = "http://alignapi.gforge.inria.fr/tutorial/edu.mit.visus.bibtex.owl"; Alignment al = null;
String u2 = "http://alignapi.gforge.inria.fr/tutorial/myOnto.owl"; URI uri1 = null;
URI uri2 = null;
//String u1 = "http://alignapi.gforge.inria.fr/tutorial2/ontology1.owl";
//String u2 = "http://alignapi.gforge.inria.fr/tutorial2/ontology2.owl";
String u1 = "file:ontology1.owl";
String u2 = "file:ontology2.owl";
String method = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment"; String method = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment";
// Parameters params = new BasicParameters(); String tempOntoFileName = "/tmp/myresult.owl";
Parameters params = new BasicParameters();
try {
uri1 = new URI( u1 );
uri2 = new URI( u2 );
} catch (URISyntaxException use) { use.printStackTrace(); }
</pre> </pre>
<p>The programme will invoke the alignment server and parse the result:</p> </div>
<div class="explain" id="qu1">
<p>The programme will invoke the alignment server:</p>
<pre> <pre>
// ***** First exercise: matching ***** // (Sol1) Try to find an alignment between two ontologies from the server
// Try to find an alignment between two ontologies from the server // ask for it
String match = getFromURLString( RESTServ+"find?onto1="+u1+"&onto2="+u2, true ); 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
// (better passing to the SAXHandler)
AlignmentParser aparser = new AlignmentParser(0);
Alignment alu = aparser.parseString( xmlString );
al = ObjectAlignment.toObjectAlignment((URIAlignment)alu);
</pre> </pre>
</div> </div>
<div class="explain" id="qu2"><p>This programs use a local simple matching <div class="explain" id="qu2"><p>:</p>
algorithm (StringDistAlignment) for obtaining an alignment:</p>
<pre> <pre>
// (Sol2) Match the ontologies with a local algorithm
if ( al == null ){ // Unfortunatelly no alignment was available
AlignmentProcess ap = new StringDistAlignment();
ap.init( uri1, uri2 );
// Threshold at various thresholds params.setParameter("stringFunction","smoaDistance");
// Evaluate them against the references ap.align( (Alignment)null, params );
// and choose the one with the best F-Measure al = ap;
AlignmentParser aparser = new AlignmentParser(0);
Alignment reference = aparser.parse( "file://"+(new File ( "refalign.rdf" ) . getAbsolutePath()) );
Evaluator evaluator = new PRecEvaluator( reference, a1 );
double best = 0.;
Alignment result = null;
for ( int i = 0; i &lt;= 10 ; i = i+2 ){
a1.cut( ((double)i)/10 );
evaluator.eval( new BasicParameters() );
System.err.println("Threshold "+(((double)i)/10)+" : "+((PRecEvaluator)evaluator).getFmeasure());
if ( ((PRecEvaluator)evaluator).getFmeasure() &gt; best ) {
result = (BasicAlignment)((BasicAlignment)a1).clone();
best = ((PRecEvaluator)evaluator).getFmeasure();
} }
} </pre>
</div>
// Displays it as SWRL Rules <div class="explain" id="qu3"><p>Match on the server:</p>
PrintWriter writer = new PrintWriter (
new BufferedWriter(
new OutputStreamWriter( System.out, "UTF-8" )), true);
AlignmentVisitor renderer = new SWRLRendererVisitor(writer);
result.render(renderer);
writer.flush();
writer.close();
</pre></div>
<div class="explain" id="qu3"><p>The main piece of code in Skeleton.java is replaced by:</p>
<pre> <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&force=true", true );
}
</pre> </pre>
<p>The remainder is the same as in the first solution.</p>
</div> </div>
<div class="logic"> <div class="logic">
<p><b>More work:</b> You can also have the matching algorithms run on <p><b>More work:</b> You can also store localy computed alignments on
the server instead of localy.</p> the alignment server.</p>
</div> </div>
<div class="button"> <div class="button">
<input type="button" onclick="show('qu4')" value="Show solution"/> <input type="button" onclick="show('qu4')" value="Show solution"/>
<input type="button" onclick="hide('qu4');" value="Hide solution"/> <input type="button" onclick="hide('qu4');" value="Hide solution"/>
</div> </div>
<div class="explain" id="qu4"><p>The main piece of code in Skeleton.java is replaced by:</p> <div class="explain" id="qu4"><p>Not ready yet (but not difficult)</p>
<pre> <pre>
</pre> </pre>
</div> </div>
...@@ -193,52 +222,100 @@ Again, this is either: ...@@ -193,52 +222,100 @@ Again, this is either:
<li>generating OWL axioms from the alignments and merge the ontologies</li> <li>generating OWL axioms from the alignments and merge the ontologies</li>
<li>transforming data from one ontology to another</li> <li>transforming data from one ontology to another</li>
</ul> </ul>
This can be done with the alignment API support.
</p> </p>
<p> <p>
Show how it can be done in both cases: This can be done with the alignment API support.
</p> </p>
<div class="button"> <div class="button">
<input type="button" onclick="show('qu5')" value="Show solution 1"/> <input type="button" onclick="show('qu5')" value="Show solution 1"/>
<input type="button" onclick="show('qu6')" value="Show solution 2"/> <input type="button" onclick="show('qu6')" value="Show solution 2"/>
<input type="button" onclick="hide('qu5');hide('qu6');" value="Hide solutions"/> <input type="button" onclick="hide('qu5');hide('qu6');" value="Hide solutions"/>
</div> </div>
<div class="explain" id="qu5"><p>The main piece of code in Skeleton.java is replaced by:</p> <div class="explain" id="qu5">
<p>In fact everything is done in one step:</p>
<pre> <pre>
// (Sol1) generate a merged ontology between the ontologies (OWLAxioms)
File merged = new File( tempOntoFileName );
PrintWriter writer = new PrintWriter ( new FileWriter( merged, false ), true );
AlignmentVisitor renderer = new OWLAxiomsRendererVisitor(writer);
al.render(renderer);
writer.flush();
writer.close();
</pre> </pre>
<p>You can look at the result in myresult.owl</p>
</div> </div>
<div class="explain" id="qu6"><p>The main piece of code in Skeleton.java is replaced by:</p> <div class="explain" id="qu6"><p>Not ready yet</p>
<pre> <pre>
</pre> </pre>
</div> </div>
<h2>Generate the answers</h2> <h2>Generate the answers</h2>
<p> <p>
This can be done in two ways: This can be done in two ways:
<ul> <ul>
<li>using SPARQL but I think that I already</li> <li>using SPARQL</li>
<li>using Pellet or something to answer these queries.</li> <li>using Pellet or something to answer these queries.</li>
</ul> </ul>
Indeed, I will go for the second one (too bad because the first one is nice). </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 runing them in one of the initial
ontologies instead of the merged one.
</p>
</p> </p>
<div class="button"> <div class="button">
<input type="button" onclick="show('qu7')" value="Show solution 1"/> <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('qu8')" value="Show solution 2"/>
<input type="button" onclick="hide('qu7');hide('qu8');" value="Hide solutions"/> <input type="button" onclick="hide('qu7');hide('qu8');" value="Hide solutions"/>
</div> </div>
<div class="explain" id="qu7"><p>The main piece of code in Skeleton.java is replaced by:</p> <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 );
//OntModelSpec.OWL_MEM_RDFS_INF or no arguments to see the difference...
Model model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF,null);
model.read(in,"file:///tmp/myresult.owl");
in.close();
</pre>
<p>Query (please play by chaging the query)</p>
<pre> <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/tutorial2/ontology1.owl#> " +
"SELECT ?fn ?ln ?t " +
"WHERE {" +
" ?student rdf:type aa:Person . " +
" ?student aa:firstname ?fn. " +
" ?student aa:lastname ?ln. " +
" ?student aa:topic ?t . " +
" }";
</pre>
<p>Evaluation:</p>
<pre>
Query query = QueryFactory.create(queryString);
// 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> </pre>
</div> </div>
<div class="explain" id="qu8"><p>The main piece of code in Skeleton.java is replaced by:</p> <div class="explain" id="qu8"><p>Not yet available</p>
<pre> <pre>
</pre> </pre>
</div> </div>
<h2>Full solution</h2>
<p>Do you want to see a possible solution?</p> <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>A full working solution is <a href="MyApp.java">MyApp.java</a>.</p>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment