From 64671892be4fce3b626b7404ea3d41e0b2d99fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Fri, 5 Dec 2014 12:54:28 +0000 Subject: [PATCH] - progressing in tutorial4 --- html/tutorial/tutorial4/index.html | 662 +++++++++++++++++++++----- html/tutorial/tutorial4/ontology1.owl | 11 +- html/tutorial/tutorial4/ontology2.owl | 2 +- 3 files changed, 543 insertions(+), 132 deletions(-) diff --git a/html/tutorial/tutorial4/index.html b/html/tutorial/tutorial4/index.html index 90527745..b8a15698 100644 --- a/html/tutorial/tutorial4/index.html +++ b/html/tutorial/tutorial4/index.html @@ -64,7 +64,8 @@ related APIs. Other tutorials are <a href="../index.html">available</a>.</p> <p style="border-top: 2px solid #AAAAAA;"> <small>This tutorial has been initially designed for the Alignment API 4.0 using Jena, Pellet and IDDL. -It has been reengineered in the Alignment API 4.5 to use Jena, HermiT and IDDL 1.4.</small></p> +It has been reengineered in the Alignment API 4.5 to use Jena, HermiT + 1.3.8, IDDL (now DRaon) 1.4 and LogMap 2.</small></p> <h2>Preparation</h2> @@ -124,21 +125,47 @@ This can be achieved: </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> +<h3>by finding an alignment from the web/server</h3> + <div class="button"> - <input type="button" onclick="show('qu0')" value="Various variables"/> - <input type="button" onclick="show('qu1')" value="Show server searching"/> - <input type="button" onclick="show('qu2')" value="Show local matching"/> - <input type="button" onclick="show('qu3')" value="Show server matching"/> - <input type="button" onclick="hide('qu0');hide('qu1');hide('qu2');hide('qu3');" value="Hide solutions"/> + <input type="button" onclick="show('qu0cli')" value="Command line"/> + <input type="button" onclick="show('qu0java')" value="Java"/> + <!--input type="button" onclick="show('qu0serv')" value="Browser"/--> + <input type="button" onclick="hide('qu0cli');hide('qu0java');hide('qu0serv');" value="Hide solutions"/> +</div> +<div class="explain" id="qu0cli"> +<p>After introducing the main variables:</p> +<div class="terminal"> +RESTSERV=http://aserv.inrialpes.fr/rest +U1=http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl +U2=http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl +CWD=`pwd` </div> -<div class="explain" id="qu0"> +<p></p> +<div class="terminal"> +$ curl -L -H "Accept:application/rdf+xml" ${RESTSERV}'/find?onto1='${U1}'&onto2='${U2} +</div> +resulting in something like: +<div class="result"> + <findResponse + xml:base='http://exmo.inrialpes.fr/align/service#' + xmlns='http://exmo.inrialpes.fr/align/service#'> + <id>274</id> + <sender>http://aserv.inrialpes.fr</sender> + <alignmentList> + <alid>http://aserv.inrialpes.fr/alid/1417700303045/7849</alid> + </alignmentList> + </findResponse> +</div> +which can always been retrieved in RDF/XML by +<div class="terminal"> +$ curl -L -H "Accept:application/rdf+xml" http://aserv.inrialpes.fr/alid/1417700303045/7849 +</div> +</div> +<div class="explain" id="qu0java"> <p>After introducing the main variables:</p> <div class="java"> +String RESTServ = "http://aserv.inrialpes.fr/rest/"; String myId = "Test"; Alignment al = null; URI uri1 = null; @@ -152,8 +179,6 @@ try { uri2 = new URI( u2 ); } catch (URISyntaxException use) { use.printStackTrace(); } </div> -</div> -<div class="explain" id="qu1"> <p>The programme will invoke the alignment server:</p> <div class="java"> // (Sol1) Try to find an alignment between two ontologies from the server @@ -174,7 +199,34 @@ Alignment alu = aparser.parseString( xmlString ); al = ObjectAlignment.toObjectAlignment((URIAlignment)alu); </div> </div> -<div class="explain" id="qu2"> +<!--div class="explain" id="qu0serv"> +<p>After introducing the main variables:</p> +<div class="java"> +</div> +</div--> +<div class="explain" id="qu0cli"> +<p>After introducing the main variables:</p> +<div class="java"> +</div> +</div> + +<h3>by running a matcher locally</h3> +<div class="button"> + <input type="button" onclick="show('qu2cli')" value="Command line"/> + <input type="button" onclick="show('qu2java')" value="Java"/> + <!--input type="button" onclick="show('qu2serv')" value="Browser"/--> + <input type="button" onclick="hide('qu2cli');hide('qu2java');hide('qu2serv');" value="Hide solutions"/> +</div> +<div class="explain" id="qu2cli"> +<div class="terminal"> +$ java -cp $CLASSPATH fr.inrialpes.exmo.align.cli.Procalign -i fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=smoaDistance -Dnoinst=1 http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl +</div> +or: +<div class="terminal"> +$ java -cp $CLASSPATH fr.inrialpes.exmo.align.cli.Procalign -i fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=smoaDistance -Dnoinst=1 file:ontology1.owl file:ontology2.owl +</div> +</div> +<div class="explain" id="qu2java"> <p>Just create an instance of AlignmentProcess and call it:</p> <div class="java"> // (Sol2) Match the ontologies with a local algorithm @@ -188,7 +240,35 @@ if ( al == null ){ // Unfortunatelly no alignment was available } </div> </div> -<div class="explain" id="qu3"><p>Match on the server:</p> +<!--div class="explain" id="qu2serv"> +<p>After introducing the main variables:</p> +<div class="java"> +</div--> +</div> + +<h3>by running a matcher on the alignment server</h3> + +<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('qu3cli')" value="Command line"/> + <input type="button" onclick="show('qu3java')" value="Java"/> + <!--input type="button" onclick="show('qu3serv')" value="Browser"/--> + <input type="button" onclick="hide('qu3cli');hide('qu3java');hide('qu3serv');" value="Hide solutions"/> +</div> +<div class="explain" id="qu3cli"> +<p>After introducing the main variables:</p> +<div class="terminal"> +$ curl -L -H "Accept:application/rdf+xml" ${RESTSERV}'/match?method=fr.inrialpes.exmo.align.impl.method.StringDistAlignment&stringFunction=smoaDistance&noinst=1&onto1='${U1}'&onto2='${U2} +</div> +returning the URL: +</div> +<div class="explain" id="qu3java"> +<p>Match on the server:</p> <div class="java"> // (Sol3) Match the ontologies on the server if ( alset.getLength() == 0 ) { @@ -196,6 +276,23 @@ if ( alset.getLength() == 0 ) { String match = getFromURLString( RESTServ+"match?onto1="+u1+"&onto2="+u2+"&method="+method+"&pretty="+myId+"&action=Match", true ); } </div> +</div> +</div> +<!--div class="explain" id="qu3serv"> +<p>After introducing the main variables:</p> +<div class="java"> +</div> +</div--> +<div class="explain" id="qu3cli"> +<p>After introducing the main variables:</p> +<div class="java"> +</div> +</div> + +<!--h3>by finding a chain of alignments from the web/server</h3> + +<p>Not yet ready</p--> + <p>The remainder is the same as in the first solution.</p> </div> <div class="note"> @@ -211,25 +308,30 @@ if ( alset.getLength() == 0 ) { </pre> </div> -<h2>Manipulating data</h2> +<h2>Merge ontologies and test consistency</h2> +<h3>Generating an OWL ontology merging the two ontologies</h3> <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> +Generating OWL axioms from the alignments and merge the ontologies can be done with the alignment API support. </p> -<p> -This can be done with the alignment API support. -</p> - <div class="button"> - <input type="button" onclick="show('qu5')" value="Show generating OWL"/> - <!--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="show('qu5cli')" value="Command line"/> + <input type="button" onclick="show('qu5java')" value="Java"/> + <!--input type="button" onclick="show('qu5serv')" value="Show solution 2"/--> + <input type="button" onclick="hide('qu5cli');hide('qu5java');hide('qu5serv');" value="Hide solutions"/> +</div> +<div class="explain" id="qu5cli"> +<p>Considering that the alignment has been stored in a file: + alignment.rdf, this can be obtained locally:</p> +<div class="terminal"> +$ java -cp $CLASSPATH fr.inrialpes.exmo.align.cli.ParserPrinter file:alignment.rdf -r fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor -o result/alignment.owl +</div> +or from the server: +<div class="terminal"> +$ curl -L -H "Accept:application/rdf+xml" ${RESTSERV}'/retrieve?method=fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor&id=http://aserv.inrialpes.fr/alid/1417700303045/7849' > result/alignment.owl +</div> </div> -<div class="explain" id="qu5"> +<div class="explain" id="qu5java"> <p>In fact everything is done in one step:</p> <div class="java"> // (Sol1) generate a merged ontology between the ontologies (OWLAxioms) @@ -240,77 +342,46 @@ al.render(renderer); writer.flush(); writer.close(); </div> -<p>You can look at the result in <a href="results/myresult.owl">results/myresult.owl</a>.</p> +<p>You can look at the result in <a href="results/alignment.owl">results/alignment.owl</a>.</p> </div> <div class="explain" id="qu6"><p>Not ready yet</p> <pre> </pre> </div> -<h2>Generating answers</h2> +<h3>Testing ontology consistency with HermiT</h3> -<p> -This can be done in three ways: -<ul> -<li>using SPARQL</li> -<li>using an OWLReasoner such as HermiT 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> -</p> <div class="button"> - <input type="button" onclick="show('qu7')" value="Show SPARQL solution"/> - <input type="button" onclick="show('qu8')" value="Show HermiT solution"/> - <input type="button" onclick="show('qu9')" value="Show IDDL solution"/> - <input type="button" onclick="hide('qu7');hide('qu8');hide('qu9');" value="Hide solutions"/> + <input type="button" onclick="show('qu8cli')" value="Command line with HermiT"/> + <input type="button" onclick="show('qu8java')" value="Java with HermiT"/> + <input type="button" onclick="show('qu9java')" value="Java with Draon"/> + <!--input type="button" onclick="show('qu8serv')" value="Browser"/--> + <input type="button" onclick="hide('qu8cli');hide('qu8java');hide('qu9java');" value="Hide solutions"/> +</div> +<div class="explain" id="qu8cli"> +<p>Considering that the merged ontologies in a file: results/alignment.owl, + and that you have <a href="http://hermit-reasoner.com/">downloaded HermiT</a> (the Command line version of + hermit requires gnu getopt which is not shipped anymore with the + Alignment API):</p> +<!--div class="terminal"> +$ java -jar HermiT.jar -l result/alignment.owl -k +http://www.w3.org/2002/07/owl#Thing is satisfiable. +</div> +another option is:--> +<div class="terminal"> +$ java -jar HermiT.jar results/alignment.owl -U </div> -<div class="explain" id="qu7"> -<p>Prepare the system:</p> -<div class="java"> -// (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:"+merged.getPath() ); -in.close(); -</div> -<p>Query (please play by changing the query)</p> -<div class="java"> -// 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#> " + - "SELECT ?fn ?ln ?t ?s " + - "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); - -</div> -<p>Evaluation:</p> -<div class="java"> -// 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); +<p>which displays</p> +<div class="result"> +Exception in thread "main" org.semanticweb.owlapi.reasoner.InconsistentOntologyException: Inconsistent ontology + at org.semanticweb.HermiT.Reasoner.throwInconsistentOntologyExceptionIfNecessary(Unknown Source) + at org.semanticweb.HermiT.Reasoner.checkPreConditions(Unknown Source) + at org.semanticweb.HermiT.Reasoner.isSatisfiable(Unknown Source) + at org.semanticweb.HermiT.cli.CommandLine$SatisfiabilityAction.run(Unknown Source) + at org.semanticweb.HermiT.cli.CommandLine.main(Unknown Source) </div> </div> -<div class="explain" id="qu8"> +<div class="explain" id="qu8java"> <p>Create Reasoner instance and load the merged ontologies:</p> <div class="java"> OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); @@ -318,16 +389,129 @@ OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); OWLOntology ontology = manager.loadOntology( IRI.create( "file:"+merged.getPath() ) ); OWLReasoner reasoner = new Reasoner( ontology ); </div> -<p>Get the instances of "Estudiantes":</p> +<p>Test consistency:</p> <div class="java"> -// 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<OWLNamedIndividual> instances = reasoner.getInstances( estud, false ).getFlattened(); -System.err.println("OWLReasoner(Merged): There are "+instances.size()+" students ("+clname(estud)+")"); +// Test consistency +if ( reasoner.isConsistent() ) { + System.out.println( " *** The aligned ontologies are consistent" ); +} else { + System.out.println( " *** The aligned ontologies are inconsistent" ); + return; +} +</div> +<p>It is even possible to test the satisfiability of classes:</p> +<div class="java"> +// Test coherence +for ( OWLClass cl : ontology.getClassesInSignature( true ) ) { + if ( !reasoner.isSatisfiable( cl ) ) { + System.out.println( cl+" is incoherent" ); + } +} +</div> +</div> +<div class="explain" id="qu9java"> +<p>Load the two ontologies and the alignment in the IDDL reasoner:</p> +<div class="java"> +ArrayList<Alignment> allist = new ArrayList<Alignment>(); +allist.add( al ); +IDDLReasoner dreasoner = new IDDLReasoner( allist, Semantics.DL ); +</div> +<p>Test consistency and check if a particular correspondence is a consequence:</p> +<div class="java"> +if ( dreasoner.isConsistent() ) { + System.out.println( "IDDL: the alignment network is consistent"); +} else { + System.out.println( "IDDL: the alignment network is inconsistent"); +} +</div> +</div> + +<h3>Repairing an alignment with LogMap repair</h3> +<div class="button"> + <input type="button" onclick="show('qu10cli')" value="Command line"/> + <!--input type="button" onclick="show('qu10java')" value="Java"/--> + <input type="button" onclick="hide('qu10cli');" value="Hide solutions"/> +</div> +<div class="explain" id="qu10cli"> +<p>Assuming + that <a href="https://code.google.com/p/logmap-matcher/">LogMap has + been downloaded</a> (it takes directly the Alignment format as input): +<div class="terminal"> +$ java -jar logmap2_standalone.jar DEBUGGER http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl RDF $CWD/alignment.rdf $CWD/results false false +</div> +this displays the following output: +<div class="result"> +Loading ontologies... +IRI: http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl +IRI: http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl +...Done +Read RDF Align mapping objects: 1 +Num original mappings: 1 +Num repaired mappings: 1 +TOTAL REPAIR TIME (s): 0.164 +</div> +obviously it had nothing to do since the aligned ontologies are consistent. +</div> + +<!--h3>Repairing an alignment with Alcomo</h3> +<div class="button"> + <input type="button" onclick="show('qu11cli')" value="Command line"/> + <input type="button" onclick="show('qu11java')" value="Java"/> + <input type="button" onclick="hide('qu11cli');" value="Hide solutions"/> +</div> +<div class="explain" id="qu11cli"> +<p>Assuming that <a href="http://web.informatik.uni-mannheim.de/alcomo/">Alcomo has been downloaded</a> as well +<div class="terminal"> +$ +</div> +</div--> + +<h3>Testing subsumption</h3> + +<p> +It is now possible to check that the newly generated alignment is +consistent. Hence we can check some entailment results. +</p> + +<div class="button"> + <input type="button" onclick="show('qu11cli')" value="Command line with HermiT"/> + <input type="button" onclick="show('qu11java')" value="Java with HermiT"/> + <input type="button" onclick="show('qu11iddljava')" value="Java with DRaon"/> + <!--input type="button" onclick="show('qu11serv')" value="Browser"/--> + <input type="button" onclick="hide('qu11cli');hide('qu11java');hide('qu11iddljava');" value="Hide solutions"/> +</div> +<div class="explain" id="qu11cli"> +<p>Considering that the merged ontologies in a file: result/alignment.owl, + and that you have uploaded HermiT (the Command line version of + hermit requires gnu getopt which is not shipped anymore with the + Alignment API):</p> +<div class="terminal"> +$ java -jar HermiT.jar results/alignment.owl -s http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante -e http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante +</div> +<p>which displays</p> +<div class="result"> +All sub-classes of 'http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante': + owl:Nothing +Classes equivalent to '<http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante>': + <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante> + <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student> </div> -<p>Some subsumption tests:</p> +and +<div class="terminal"> +$ java -jar HermiT.jar results/alignment.owl -s http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student -e http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student +</div> +<p>which displays</p> +<div class="result"> +All sub-classes of 'http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student': + owl:Nothing +Classes equivalent to '<http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student>': + <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#Estudiante> + <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#Student> +</div> +</div> +<div class="explain" id="qu11java"> +<p>Create Reasoner instance and load the merged ontologies as before + and perform some subsumption tests:</p> <div class="java"> testOWLReasonerSubClass( manager, reasoner, estud, person ); testOWLReasonerSubClass( manager, reasoner, estud, student ); @@ -347,23 +531,17 @@ public void testOWLReasonerSubClass( OWLOntologyManager manager, OWLReasoner rea } } </div> +The answer should be: +<div class="result"> +OWLReasoner(Merged): Estudiante is not necessarily subclass of Person +OWLReasoner(Merged): Estudiante is subclass of Student </div> -<div class="explain" id="qu9"> -<p>Load the two ontologies and the alignment in the IDDL reasoner:</p> -<div class="java"> - ArrayList<Alignment> allist = new ArrayList<Alignment>(); - allist.add( al ); - IDDLReasoner dreasoner = new IDDLReasoner( allist, Semantics.DL ); </div> -<p>Test consistency and check if a particular correspondence is a consequence:</p> +<div class="explain" id="qu11iddljava"> +<p>Check if a particular correspondence is a consequence:</p> <div class="java"> - 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"); - } + testIDDLSubClass( dreasoner, uri1, uri2, estud, person ); + testIDDLSubClass( dreasoner, uri1, uri2, estud, student ); </div> <p>Such that:</p> <div class="java"> @@ -381,9 +559,135 @@ public void testOWLReasonerSubClass( OWLOntologyManager manager, OWLReasoner rea } } </div> +the result should be: +<div class="result"> +IDDL: Estudiante <= Person is not entailed +IDDL: Estudiante <= Student is entailed </div> -The results for these execution are, for SPARQL: -<pre> +</div> + +<h2>SPARQL querying with an alignment</h2> + +<p>Our final goal is to get that list of students. +For that purpose, several strategies may be adopted: +<ul> +<li><a href="inst">Using a reasonner for retrieving all instances of the + aligned classes;</a></li> +<li><a href="transf">Using a SPARQL query against one data set and + transforming the query to apply it to the other dataset;</a></li> +<li><a href="merged">Using this same query against the merged data sets;</a></li> +<li><a href="construct">Generating a SPARQL CONSTRUCT query from the alignment + to merge the instances of both data sets.</a></li> +</ul> +Let explore them. +</p> + +<h3><a name="inst"></a>Instance reasoning</h3> + +<div class="button"> + <input type="button" onclick="show('qu13java')" value="Java"/> + <!--input type="button" onclick="show('qu14serv')" value="Browser"/--> + <input type="button" onclick="hide('qu13java')" value="Hide solution"/> +</div> +<div class="explain" id="qu13java"> +<p>Starting from where we were with the HermiT reasonner, it is + possible to retrive the instances of "Estudiantes" and to + manipulate them:</p> +<div class="java"> +// 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<OWLNamedIndividual> instances = reasoner.getInstances( estud, false ).getFlattened(); +System.err.println("OWLReasoner(Merged): There are "+instances.size()+" students ("+clname(estud)+")"); +</div> +This should output: +<div class="result"> +OWLReasoner(Merged): There are 47 students (Estudiante) +</div> +</div> + +<h3><a name="transf"></a>Transforming queries</h3> + +<p>The following solutions use the query in the file <a href="query.sparql">query.sparql</a>.</p> + +<div class="button"> + <input type="button" onclick="show('qu14cli')" value="Command line"/> + <input type="button" onclick="show('qu14java')" value="Java"/> + <!--input type="button" onclick="show('qu14serv')" value="Browser"/--> + <input type="button" onclick="hide('qu14cli');hide('qu14java');hide('qu14serv');" value="Hide solutions"/> +</div> +<div class="explain" id="qu14cli"> +The query can be transformed on command line through: +<div class="terminal"> +$ java -cp $CLASSPATH fr.inrialpes.exmo.align.cli.TransformQuery -a file:alignment.rdf -q query.sparql -Donto2=http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl# +</div> +The result will be: +<div class="result"> +PREFIX onto2: <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#> +PREFIX aa: <http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#> +PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> +PREFIX foaf: <http://xmlns.com/foaf/0.1/> + + +SELECT ?fn ?ln ?t ?s +WHERE { + ?student rdf:type onto2:Student . + ?student onto2:first-name ?fn. + ?student onto2:name ?ln. +OPTIONAL { ?student onto2:institution ?t . } +OPTIONAL { ?student onto2:phd-advisor ?s . } +} +</div> +</div> +<div class="explain" id="qu14java"> +<p>In fact everything is done in one step:</p> +<div class="java"> +Not ready yet... USE MY TRANSFORM + USE THE EVALUATION AGAINST A DATA SET. +</div> +</div> + +<h3><a name="merged"></a>Querying with the merged ontology</h3> + +<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> +<div class="button"> + <!--input type="button" onclick="show('qu7cli')" value="Command line"/--> + <input type="button" onclick="show('qu7java')" value="Java"/> + <!--input type="button" onclick="show('qu7serv')" value="Browser"/--> + <input type="button" onclick="hide('qu7java')" value="Hide solutions"/> +</div> +<div class="explain" id="qu7java"> +<p>Load the merged ontology under Jena:</p> +<div class="java"> +// (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:"+merged.getPath() ); +in.close(); +</div> +<p>Read the query (please play by changing the query)</p> +<div class="java"> +// Create a new query +<!--String queryString = readFile( "query.sparql", Charset.defaultCharset() ); +create(queryString);--> +Query query = QueryFactory.read( "file:query.sparql" ); +</div> +<p>Evaluation:</p> +<div class="java"> +// 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); +</div> +The results for this evaluation is: +<div class="result"> --------------------------------------------------------------------------------------- | fn | ln | t | s | ======================================================================================= @@ -391,20 +695,122 @@ The results for these execution are, for SPARQL: | "Chet" | "Baker" | "University Pie XXIII" | | | "McCoy" | "Tyner" | "University of Soupaloignon" | "Dr Nanni Girasole" | ... -</pre> -for OWLReasoner: -<pre> -OWLReasoner(Merged): There are 47 students (Estudiante) -OWLReasoner(Merged): Estudiante is not necessarily subclass of Person -OWLReasoner(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> - +</div> +</div> + +<h3><a name="construct"></a>Generating SPARQL constructs</h3> + +<p> +A SPARQL construct query may be use for extracting data expressed +in one ontology and generate this data with respect to the other +ontology. +It is possible to generate such constructs from + + +<div class="button"> + <input type="button" onclick="show('qu15cli')" value="Command line"/> + <!--input type="button" onclick="show('qu15java')" value="Java"/--> + <!--input type="button" onclick="show('qu15serv')" value="Browser"/--> + <input type="button" onclick="hide('qu15cli')" value="Hide solutions"/> +</div> +<div class="explain" id="qu15cli"> +<div class="terminal"> +$ java -cp $CLASSPATH fr.inrialpes.exmo.align.cli.ParserPrinter file:alignment.rdf -r fr.inrialpes.exmo.align.impl.renderer.SPARQLConstructRendererVisitor +</div> +which generates a set of queries containing at least this: +<div class="result"> +PREFIX ns1:<http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology2.owl#> +PREFIX ns0:<http://alignapi.gforge.inria.fr/tutorial/tutorial4/ontology1.owl#> +PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> + +CONSTRUCT { +?s rdf:type ns0:Estudiante . +} +WHERE { +?s rdf:type ns1:Student . +} + +CONSTRUCT { +?s ns0:supervisor ?o . +} +WHERE { +?s ns1:phd-advisor ?o . +} + +[...] + +CONSTRUCT { +?s rdf:type ns0:Tutor . +} +WHERE { +?s rdf:type ns1:Professor . +} + +[...] + +CONSTRUCT { +?s ns0:lastname ?o . +} +WHERE { +?s ns1:name ?o . +} + +[...] + +CONSTRUCT { +?s ns0:year ?o . +} +WHERE { +?s ns1:year-in-phd ?o . +} + +PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> +CONSTRUCT { +?s ns0:country ?o . +} +WHERE { +?s ns1:country-of-study ?o . +} + +CONSTRUCT { +?s ns0:gender ?o . +} +WHERE { +?s ns1:gender ?o . +} + +CONSTRUCT { +?s ns0:firstname ?o . +} +WHERE { +?s ns1:first-name ?o . +} + +CONSTRUCT { +?s ns0:city ?o . +} +WHERE { +?s ns1:city-of-study ?o . +} + +CONSTRUCT { +?s ns0:topic ?o . +} +WHERE { +?s ns1:topics-of-interest ?o . +} + +CONSTRUCT { +?s ns0:affiliation ?o . +} +WHERE { +?s ns1:institution ?o . +} +</div> +These queries may be applied to the entries of ontology2.owl and +generates triples using ontology1. +</div> + <h2>Full solution</h2> <p>Do you want to see a possible solution?</p> diff --git a/html/tutorial/tutorial4/ontology1.owl b/html/tutorial/tutorial4/ontology1.owl index d2ff1297..c3a6c887 100644 --- a/html/tutorial/tutorial4/ontology1.owl +++ b/html/tutorial/tutorial4/ontology1.owl @@ -39,6 +39,12 @@ <rdfs:label xml:lang="es">Professor</rdfs:label> </owl:Class> + <owl:Class rdf:ID="TutorEstudiante"> + <rdfs:subClassOf rdf:resource="#Estudiante" /> + <rdfs:subClassOf rdf:resource="#Tutor" /> + <rdfs:label xml:lang="es">Professor</rdfs:label> + </owl:Class> + <owl:DatatypeProperty rdf:ID="lastname"> <rdfs:domain rdf:resource="#Participante" /> <rdfs:range rdf:resource="&xsd;string" /> @@ -304,8 +310,7 @@ <supervisor>Prof. Pierpaolo Polenta</supervisor> </Estudiante> -<Estudiante rdf:about="#Zorn"> - <rdf:type rdf:resource="#Tutor" /> +<TutorEstudiante rdf:about="#Zorn"> <lastname>Zorn</lastname> <firstname>John</firstname> <gender>Male</gender> @@ -315,7 +320,7 @@ <year>1</year> <topic>Complex Event Processing</topic> <supervisor>Prof. Pierpaolo Polenta</supervisor> -</Estudiante> +</TutorEstudiante> <Estudiante rdf:about="#Tyner"> <lastname>Tyner</lastname> diff --git a/html/tutorial/tutorial4/ontology2.owl b/html/tutorial/tutorial4/ontology2.owl index bcae1c86..b0a22905 100644 --- a/html/tutorial/tutorial4/ontology2.owl +++ b/html/tutorial/tutorial4/ontology2.owl @@ -31,7 +31,7 @@ <rdfs:label xml:lang="en">Student</rdfs:label> </owl:Class> - <owl:Class rdf:ID="Professor"> + <owl:Class rdf:ID="Teacher"> <rdfs:subClassOf rdf:resource="http://xmlns.com/foaf/0.1/Person" /> <owl:disjointWith rdf:resource="#Student" /> <rdfs:label xml:lang="en">Staff</rdfs:label> -- GitLab