Here is a more advanced tutorial for the alignment API which explains how to interface the API with other components. This tutorial will show how to:
Other tutorials are available.
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.0.2 and IDDL.
Just:
We have two ontologies, ontology1.owl and ontology2.owl, under which two sets of students are described. Unfortunately, the administration started to record participants with their own ontology before finding that using FOAF would be a better idea. We now end up with two incomplete lists of participants.
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.
For that purpose, you have to develop a program in Java. We first define the CLASSPATH because a lot of external software is required
This programme can be run by:
This can be achieved:
Write a program that does try to find an alignment on the alignment server http://aserv.inrialpes.fr and, if none is found, computes one.
After introducing the main variables:
String myId = "JETest";
Alignment al = null;
URI uri1 = null;
URI uri2 = null;
//String u1 = "http://alignapi.gforge.inria.fr/tutorial/tutorial2/ontology1.owl";
//String u2 = "http://alignapi.gforge.inria.fr/tutorial/tutorial2/ontology2.owl";
String u1 = "file:ontology1.owl";
String u2 = "file:ontology2.owl";
String method = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment";
String tempOntoFileName = "/tmp/myresult.owl";
Parameters params = new BasicParameters();
try {
uri1 = new URI( u1 );
uri2 = new URI( u2 );
} catch (URISyntaxException use) { use.printStackTrace(); }
The programme will invoke the alignment server:
// (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 );
Retrieve the alignment itself:
// retrieve it // If there exists alignments, ask for the first one NodeList alset = extractFromResult( found, "//findResponse/alignmentList/alid[1]/text()", false );
And parse it:
// 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);
Just create an instance of AlignmentProcess and call it:
// (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;
}
Match on the server:
// (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 );
}
The remainder is the same as in the first solution.
More work: You can also store localy computed alignments on the alignment server.
Not ready yet (but not difficult)
Again, this is either:
This can be done with the alignment API support.
In fact everything is done in one step:
// (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();
You can look at the result in myresult.owl
Not ready yet
This can be done in three ways:
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.
Prepare the system:
// (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();
Query (please play by changing the query)
// Create a new query
String queryString =
"PREFIX foaf: " +
"PREFIX rdf: " +
"PREFIX aa: " +
"SELECT ?fn ?ln ?t " +
"WHERE {" +
" ?student rdf:type aa:Person . " +
" ?student aa:firstname ?fn. " +
" ?student aa:lastname ?ln. " +
" ?student aa:topic ?t . " +
" }";
Evaluation:
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);
Create Reasoner instance and load the merged ontologies:
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
Reasoner reasoner = new Reasoner( manager );
try {
OWLOntology ontology = manager.loadOntology( URI.create( "file://"+tempOntoFileName ) );
reasoner.loadOntology( ontology );
} catch (OWLOntologyCreationException ooce) { ooce.printStackTrace(); }
Get the instances of "Estudiantes":
OWLClass estud = manager.getOWLDataFactory().getOWLClass( URI.create( "http://alignapi.gforge.inria.fr/tutorial/tutorial2/ontology1.owl#Estudiante" ) );
OWLClass person = manager.getOWLDataFactory().getOWLClass( URI.create( "http://alignapi.gforge.inria.fr/tutorial/tutorial2/ontology2.owl#Person" ) );
OWLClass student = manager.getOWLDataFactory().getOWLClass( URI.create( "http://alignapi.gforge.inria.fr/tutorial/tutorial2/ontology2.owl#Student" ) );
Set instances = reasoner.getIndividuals( estud, false );
System.err.println("Pellet(Merged): There are "+instances.size()+" students "+estud.getURI());
Some subsumption tests:
testPelletSubClass( manager, reasoner, estud, person ); testPelletSubClass( manager, reasoner, estud, student );
Such that:
public void testPelletSubClass( OWLOntologyManager manager, Reasoner reasoner, OWLDescription d1, OWLDescription d2 ) {
OWLAxiom axiom = manager.getOWLDataFactory().getOWLSubClassAxiom( d1, d2 );
boolean isit = reasoner.isEntailed( axiom );
if ( isit ) {
System.out.println( "Pellet(Merged): "+d1+" is subclass of "+d2 );
} else {
System.out.println( "Pellet(Merged): "+d1+" is not necessarily subclass of "+d2 );
}
}
Load the two ontologies and the alignment in the IDDL reasoner:
IDDLReasoner dreasoner = new IDDLReasoner( Semantics.DL ); dreasoner.addOntology( uri1 ); dreasoner.addOntology( uri2 ); dreasoner.addAlignment( al );
Test consistency and check if a particular correspondence is a consequence:
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");
}
Such that:
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, "<", 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" );
}
}
Pellet(Merged): There are 47 students http://alignapi.gforge.inria.fr/tutorial/tutorial2/ontology1.owl#Estudiante Pellet(Merged): Estudiante is not necessarily subclass of Person Pellet(Merged): Estudiante is subclass of Studentand for IDDL:
IDDL: the alignment network is consistent IDDL: Estudiante <= Person is not entailed IDDL: Estudiante <= Student is entailed
http://alignapi.gforge.inria.fr/tutorial/tutorial2/
$Id: index.html 1402 2010-03-31 08:43:56Z euzenat $