From 04aa601b0d46bb07cae7c68bc944a3ff32949859 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Tue, 7 Jul 2009 10:47:21 +0000
Subject: [PATCH] - full tutorial nearly ready

---
 html/tutorial2/index.html | 225 +++++++++++++++++++++++++-------------
 1 file changed, 151 insertions(+), 74 deletions(-)

diff --git a/html/tutorial2/index.html b/html/tutorial2/index.html
index 68d04d41..7da5f389 100644
--- a/html/tutorial2/index.html
+++ b/html/tutorial2/index.html
@@ -51,31 +51,51 @@ This tutorial will learn you to:
 <ul>
 <li>communicate the alignment server
 through its REST web service API,</li>
-<li>manipulate the Alignments with the Alignment API in Java,</li>
-<li>perform OWL reasoning on alignmed ontologies and compose
+<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>
-
 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>
-<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>
 	
-<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>
 	
 <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>
-The goal is to have a unified view of these participants.
-.</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 
+</p>
 	
 <p>For that purpose, you have to develop a program in Java. This
   programme can be compiled by:
@@ -84,9 +104,13 @@ $ javac -classpath ../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/je
 </div>
 and run by:
 <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>
-
+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>
 
 <h2>Matching ontologies</h2>
@@ -94,8 +118,9 @@ $ java -classpath .:../../lib/align.jar:../../lib/procalign.jar:../../lib/jena/j
 <p>
 This can be achieved:
 <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 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>
@@ -103,84 +128,88 @@ This can be achieved:
 <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, compute one and store it on the server.
+and, if none is found, computes one.
 </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">
+  <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('qu1');hide('qu2');hide('qu3');" value="Hide solutions"/>
 </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>
-	URI onto1 = null;
-	URI onto2 = null;
 	String myId = "JETest";
-	String u1 = "http://alignapi.gforge.inria.fr/tutorial/edu.mit.visus.bibtex.owl";
-	String u2 = "http://alignapi.gforge.inria.fr/tutorial/myOnto.owl";
+	Alignment al = null;
+	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";
-	//	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>
-<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>
-	// ***** First exercise: matching *****
-	// Try to find an alignment between two ontologies from the server
-	String match = getFromURLString( RESTServ+"find?onto1="+u1+"&onto2="+u2, true );
+	// (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
+	// (better passing to the SAXHandler)
+	AlignmentParser aparser = new AlignmentParser(0);
+	Alignment alu = aparser.parseString( xmlString );
+	al = ObjectAlignment.toObjectAlignment((URIAlignment)alu);
 </pre>
 </div>
-<div class="explain" id="qu2"><p>This programs use a local simple matching
-    algorithm (StringDistAlignment) for obtaining an alignment:</p>
+<div class="explain" id="qu2"><p>:</p>
 <pre>
-
-
-
-
-// Threshold at various thresholds
-// Evaluate them against the references
-// and choose the one with the best F-Measure
-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();
+	// (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.setParameter("stringFunction","smoaDistance");
+	    ap.align( (Alignment)null, params );
+	    al = ap;
 	}
-}
-
-// Displays it as SWRL Rules
-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>
+</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&force=true", 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 have the matching algorithms run on
-  the server instead of localy.</p>
+<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>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>
 </div>
@@ -193,52 +222,100 @@ Again, this is either:
 <li>generating OWL axioms from the alignments and merge the ontologies</li>
 <li>transforming data from one ontology to another</li>
 </ul>
-This can be done with the alignment API support.
 </p>
 <p>
-Show how it can be done in both cases:
+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>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>
+	// (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>
+<p>You can look at the result in myresult.owl</p>
 </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>
 </div>
 
-
 <h2>Generate the answers</h2>
 
 <p>
 This can be done in two ways:
 <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>
 </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>
 <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="hide('qu7');hide('qu8');" value="Hide solutions"/>
 </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>
+        // 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>
 </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>
 </div>
 	
+<h2>Full solution</h2>
+	
 <p>Do you want to see a possible solution?</p>
-
 <p>A full working solution is <a href="MyApp.java">MyApp.java</a>.</p>
 
 
-- 
GitLab