development for NIHVIVO-2410 (specific type inference in lieu of moniker)
This commit is contained in:
parent
73e0916a04
commit
132cbdce2c
2 changed files with 303 additions and 41 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.reasoner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -36,7 +37,6 @@ import com.hp.hpl.jena.vocabulary.RDFS;
|
|||
* Allows for real-time incremental materialization or retraction of RDFS-
|
||||
* style class and property subsumption based ABox inferences as statements
|
||||
* are added to or removed from the (ABox or TBox) knowledge base.
|
||||
*
|
||||
*/
|
||||
|
||||
public class SimpleReasoner extends StatementListener {
|
||||
|
@ -101,6 +101,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
try {
|
||||
if (stmt.getPredicate().equals(RDF.type)) {
|
||||
addedABoxTypeAssertion(stmt, inferenceModel);
|
||||
setMostSpecificTypes(stmt.getSubject(), inferenceModel);
|
||||
} else {
|
||||
addedABoxAssertion(stmt,inferenceModel);
|
||||
}
|
||||
|
@ -121,6 +122,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
try {
|
||||
if (stmt.getPredicate().equals(RDF.type)) {
|
||||
removedABoxTypeAssertion(stmt, inferenceModel);
|
||||
setMostSpecificTypes(stmt.getSubject(), inferenceModel);
|
||||
} else {
|
||||
removedABoxAssertion(stmt, inferenceModel);
|
||||
}
|
||||
|
@ -156,22 +158,22 @@ public class SimpleReasoner extends StatementListener {
|
|||
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
|
||||
|
||||
if (stmt.getPredicate().equals(RDFS.subClassOf)) {
|
||||
addedSubClass(subject,object);
|
||||
addedSubClass(subject,object,inferenceModel);
|
||||
} else {
|
||||
// equivalent class is the same as subclass in both directions
|
||||
addedSubClass(subject,object);
|
||||
addedSubClass(object,subject);
|
||||
addedSubClass(subject,object,inferenceModel);
|
||||
addedSubClass(object,subject,inferenceModel);
|
||||
}
|
||||
} else if (stmt.getPredicate().equals(RDFS.subPropertyOf) || stmt.getPredicate().equals(OWL.equivalentProperty)) {
|
||||
OntProperty subject = tboxModel.getOntProperty((stmt.getSubject()).getURI());
|
||||
OntProperty object = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
|
||||
|
||||
if (stmt.getPredicate().equals(RDFS.subPropertyOf)) {
|
||||
addedSubProperty(subject, object, inferenceModel);
|
||||
addedSubProperty(subject,object,inferenceModel);
|
||||
} else {
|
||||
// equivalent property is the same as subProperty in both directions
|
||||
addedSubProperty(subject, object, inferenceModel);
|
||||
addedSubProperty(object, subject, inferenceModel);
|
||||
addedSubProperty(subject,object,inferenceModel);
|
||||
addedSubProperty(object,subject,inferenceModel);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -202,11 +204,11 @@ public class SimpleReasoner extends StatementListener {
|
|||
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
|
||||
|
||||
if (stmt.getPredicate().equals(RDFS.subClassOf)) {
|
||||
removedSubClass(subject,object);
|
||||
removedSubClass(subject,object,inferenceModel);
|
||||
} else {
|
||||
// equivalent class is the same as subclass in both directions
|
||||
removedSubClass(subject,object);
|
||||
removedSubClass(object,subject);
|
||||
removedSubClass(subject,object,inferenceModel);
|
||||
removedSubClass(object,subject,inferenceModel);
|
||||
}
|
||||
} else if (stmt.getPredicate().equals(RDFS.subPropertyOf) || stmt.getPredicate().equals(OWL.equivalentProperty)) {
|
||||
OntProperty subject = tboxModel.getOntProperty((stmt.getSubject()).getURI());
|
||||
|
@ -494,11 +496,11 @@ public class SimpleReasoner extends StatementListener {
|
|||
* individual that is typed as B, either in the ABox or in the
|
||||
* inferred model, assert that it is of type A.
|
||||
*/
|
||||
public void addedSubClass(OntClass subClass, OntClass superClass) {
|
||||
public void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
|
||||
|
||||
log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI());
|
||||
|
||||
aboxModel.enterCriticalSection(Lock.READ);
|
||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||
|
||||
try {
|
||||
|
@ -517,6 +519,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
|
||||
if (!inferenceModel.contains(infStmt)) {
|
||||
inferenceModel.add(infStmt);
|
||||
setMostSpecificTypes(infStmt.getSubject(), inferenceModel);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -532,11 +535,11 @@ public class SimpleReasoner extends StatementListener {
|
|||
* UNLESS the individual is of some type C that is a subClass
|
||||
* of A (including A itself)
|
||||
*/
|
||||
public void removedSubClass(OntClass subClass, OntClass superClass) {
|
||||
public void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
|
||||
|
||||
log.debug("subClass = " + subClass.getURI() + ". superClass = " + superClass.getURI());
|
||||
|
||||
aboxModel.enterCriticalSection(Lock.READ);
|
||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||
|
||||
try {
|
||||
|
@ -559,6 +562,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
|
||||
if (inferenceModel.contains(infStmt)) {
|
||||
inferenceModel.remove(infStmt);
|
||||
setMostSpecificTypes(infStmt.getSubject(), inferenceModel);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -661,9 +665,9 @@ public class SimpleReasoner extends StatementListener {
|
|||
* indicate them for the individual with the core:mostSpecificType
|
||||
* annotation.
|
||||
*/
|
||||
public void setMostSpecificTypes(Resource individual) {
|
||||
public void setMostSpecificTypes(Resource individual, Model inferenceModel) {
|
||||
|
||||
aboxModel.enterCriticalSection(Lock.READ);
|
||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||
inferenceModel.enterCriticalSection(Lock.READ);
|
||||
tboxModel.enterCriticalSection(Lock.READ);
|
||||
|
||||
|
@ -672,12 +676,13 @@ public class SimpleReasoner extends StatementListener {
|
|||
unionModel.addSubModel(aboxModel);
|
||||
unionModel.addSubModel(inferenceModel);
|
||||
|
||||
HashSet<String> typeURIs = new HashSet<String>();
|
||||
StmtIterator iter = unionModel.listStatements((Resource) null, RDF.type, (RDFNode) null);
|
||||
List<OntClass> types = new ArrayList<OntClass>();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
StmtIterator stmtIter = unionModel.listStatements(individual, RDF.type, (RDFNode) null);
|
||||
|
||||
Statement stmt = iter.next();
|
||||
while (stmtIter.hasNext()) {
|
||||
|
||||
Statement stmt = stmtIter.next();
|
||||
|
||||
if ( !stmt.getObject().isResource() ) {
|
||||
log.warn("The object of this rdf:type assertion is expected to be a resource: " + stmtString(stmt));
|
||||
|
@ -693,11 +698,37 @@ public class SimpleReasoner extends StatementListener {
|
|||
|
||||
if (ontClass.isAnon()) continue;
|
||||
|
||||
if (ontClass.hasSubClass()) continue;
|
||||
types.add(ontClass);
|
||||
}
|
||||
|
||||
typeURIs.add(ontClass.getURI());
|
||||
HashSet<String> typeURIs = new HashSet<String>();
|
||||
List<OntClass> types2 = new ArrayList<OntClass>();
|
||||
types2.addAll(types);
|
||||
|
||||
Iterator<OntClass> eIter = ontClass.listEquivalentClasses();
|
||||
Iterator<OntClass> typeIter = types.iterator();
|
||||
|
||||
while (typeIter.hasNext()) {
|
||||
OntClass type = typeIter.next();
|
||||
|
||||
boolean add = true;
|
||||
Iterator<OntClass> typeIter2 = types2.iterator();
|
||||
while (typeIter2.hasNext()) {
|
||||
OntClass type2 = typeIter2.next();
|
||||
|
||||
if (type.equals(type2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type.hasSubClass(type2, false) && !type2.hasSubClass(type, false)) {
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
typeURIs.add(type.getURI());
|
||||
|
||||
Iterator<OntClass> eIter = type.listEquivalentClasses();
|
||||
|
||||
while (eIter.hasNext()) {
|
||||
OntClass equivClass = eIter.next();
|
||||
|
@ -705,8 +736,9 @@ public class SimpleReasoner extends StatementListener {
|
|||
typeURIs.add(equivClass.getURI());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setMostSpecificTypes(individual, typeURIs);
|
||||
setMostSpecificTypes(individual, typeURIs, inferenceModel);
|
||||
|
||||
} finally {
|
||||
aboxModel.leaveCriticalSection();
|
||||
|
@ -717,13 +749,14 @@ public class SimpleReasoner extends StatementListener {
|
|||
return;
|
||||
}
|
||||
|
||||
public void setMostSpecificTypes(Resource individual, HashSet<String> typeURIs) {
|
||||
public void setMostSpecificTypes(Resource individual, HashSet<String> typeURIs, Model inferenceModel) {
|
||||
|
||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||
|
||||
try {
|
||||
Model retractions = ModelFactory.createDefaultModel();
|
||||
// remove obsolete most-specific-type assertions
|
||||
StmtIterator iter = aboxModel.listStatements((Resource) null, mostSpecificType, (RDFNode) null);
|
||||
StmtIterator iter = aboxModel.listStatements(individual, mostSpecificType, (RDFNode) null);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Statement stmt = iter.next();
|
||||
|
@ -734,10 +767,12 @@ public class SimpleReasoner extends StatementListener {
|
|||
}
|
||||
|
||||
if (!typeURIs.contains(stmt.getObject().asLiteral().getLexicalForm())) {
|
||||
aboxModel.remove(stmt);
|
||||
retractions.add(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
aboxModel.remove(retractions);
|
||||
|
||||
// add new most-specific-type assertions
|
||||
Iterator<String> typeIter = typeURIs.iterator();
|
||||
|
||||
|
@ -746,6 +781,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
Literal uriLiteral = ResourceFactory.createTypedLiteral(typeURI, XSDDatatype.XSDanyURI);
|
||||
|
||||
if (!aboxModel.contains(individual, mostSpecificType, uriLiteral)) {
|
||||
Statement toAdd = ResourceFactory.createStatement(individual, mostSpecificType, uriLiteral);
|
||||
aboxModel.add(individual, mostSpecificType, uriLiteral);
|
||||
}
|
||||
}
|
||||
|
@ -791,7 +827,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
|
||||
// recompute the inferences
|
||||
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
|
||||
aboxModel.enterCriticalSection(Lock.READ);
|
||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||
tboxModel.enterCriticalSection(Lock.READ);
|
||||
|
||||
try {
|
||||
|
@ -802,6 +838,7 @@ public class SimpleReasoner extends StatementListener {
|
|||
while (iter.hasNext()) {
|
||||
Statement stmt = iter.next();
|
||||
addedABoxTypeAssertion(stmt, inferenceRebuildModel);
|
||||
setMostSpecificTypes(stmt.getSubject(), inferenceRebuildModel);
|
||||
}
|
||||
|
||||
log.info("Computing property-based ABox inferences");
|
||||
|
|
|
@ -9,15 +9,20 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.mindswap.pellet.jena.PelletReasonerFactory;
|
||||
|
||||
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
|
||||
import com.hp.hpl.jena.ontology.AnnotationProperty;
|
||||
import com.hp.hpl.jena.ontology.OntClass;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.ontology.OntProperty;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||
import com.hp.hpl.jena.rdf.model.Statement;
|
||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
@ -28,6 +33,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
|
||||
|
||||
private Resource objectProperty = ResourceFactory.createResource("http://www.w3.org/2002/07/owl#ObjectProperty");
|
||||
private static final String mostSpecificTypePropertyURI = "http://vivoweb.org/ontology/core#mostSpecificType";
|
||||
|
||||
@Before
|
||||
public void suppressErrorOutput() {
|
||||
|
@ -46,6 +52,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Create a Tbox with a simple class hierarchy. B is a subclass of A.
|
||||
// Pellet will compute TBox inferences
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||
classA.setLabel("class A", "en-US");
|
||||
|
@ -84,6 +91,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Create a Tbox with a simple class hierarchy. D and E are subclasses
|
||||
// of C. B and C are subclasses of A. Pellet will compute TBox inferences.
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||
classA.setLabel("class A", "en-US");
|
||||
|
@ -137,6 +145,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -184,6 +193,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -223,6 +233,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -271,6 +282,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// and B is a subclass of A. Pellet will compute TBox inferences.
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||
classA.setLabel("class A", "en-US");
|
||||
|
@ -336,6 +348,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -403,6 +416,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -462,6 +476,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -547,6 +562,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -589,6 +605,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -630,6 +647,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -684,6 +702,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -726,6 +745,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -782,6 +802,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -849,6 +870,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
|
@ -933,6 +955,209 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
/*
|
||||
* Test computation of mostSpecificType annotations in response
|
||||
* to an added/removed ABox type assertion.
|
||||
*/
|
||||
public void mstTest1(){
|
||||
// Create TBox, ABox and Inference models and register
|
||||
// the ABox reasoner listeners with the ABox and TBox
|
||||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||
aBox.register(simpleReasoner);
|
||||
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
||||
|
||||
// Set up the Tbox with a class hierarchy. C is a subclass of A
|
||||
// and Y. D and E are subclasses C. B is a subclass of D.
|
||||
// Pellet will compute TBox inferences.
|
||||
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||
classA.setLabel("class A", "en-US");
|
||||
|
||||
OntClass classB = tBox.createClass("http://test.vivo/B");
|
||||
classB.setLabel("class B", "en-US");
|
||||
|
||||
OntClass classC = tBox.createClass("http://test.vivo/C");
|
||||
classC.setLabel("class C", "en-US");
|
||||
|
||||
OntClass classD = tBox.createClass("http://test.vivo/D");
|
||||
classD.setLabel("class D", "en-US");
|
||||
|
||||
OntClass classE = tBox.createClass("http://test.vivo/E");
|
||||
classE.setLabel("class E", "en-US");
|
||||
|
||||
OntClass classY = tBox.createClass("http://test.vivo/Y");
|
||||
classE.setLabel("class Y", "en-US");
|
||||
|
||||
classY.addSubClass(classC);
|
||||
classA.addSubClass(classC);
|
||||
|
||||
classC.addSubClass(classD);
|
||||
classC.addSubClass(classE);
|
||||
|
||||
classD.addSubClass(classB);
|
||||
|
||||
// Add the statement individual x is of type Y to the ABox
|
||||
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||
aBox.add(ind_x, RDF.type, classD);
|
||||
|
||||
// Verify ind_x mostSpecificType annotation for D
|
||||
Assert.assertTrue(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classD.getURI(), XSDDatatype.XSDanyURI)));
|
||||
|
||||
// Verify ind_x doesn't have a mostSpecificType annotation for
|
||||
// A, Y, C, E or B.
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classA.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classY.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classC.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classE.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classB.getURI(), XSDDatatype.XSDanyURI)));
|
||||
|
||||
aBox.remove(ind_x, RDF.type, classD); // retract assertion that x is of type D.
|
||||
// Verify that D is not longer the most specific type
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classD.getURI(), XSDDatatype.XSDanyURI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
/*
|
||||
* Test computation of mostSpecificType annotations in response
|
||||
* to an added ABox type assertion.
|
||||
*/
|
||||
public void mstTest2(){
|
||||
// Create TBox, ABox and Inference models and register
|
||||
// the ABox reasoner listeners with the ABox and TBox
|
||||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||
aBox.register(simpleReasoner);
|
||||
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
||||
|
||||
// Set up the Tbox with a class hierarchy. B is a subclass of A,
|
||||
// C is a subclass of B, and A is a subclass of C.
|
||||
// Pellet should infer these three classes to be equivalent.
|
||||
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||
classA.setLabel("class A", "en-US");
|
||||
|
||||
OntClass classB = tBox.createClass("http://test.vivo/B");
|
||||
classB.setLabel("class B", "en-US");
|
||||
|
||||
OntClass classC = tBox.createClass("http://test.vivo/C");
|
||||
classC.setLabel("class C", "en-US");
|
||||
|
||||
classA.addSubClass(classB);
|
||||
classB.addSubClass(classC);
|
||||
classC.addSubClass(classA);
|
||||
|
||||
// Add the statement individual x is of type B to the ABox
|
||||
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||
aBox.add(ind_x, RDF.type, classB);
|
||||
|
||||
StmtIterator stmtIterator = aBox.listStatements(ind_x, mostSpecificType, (RDFNode)null);
|
||||
|
||||
// Verify ind_x mostSpecificType annotation for A, B and C
|
||||
Assert.assertTrue(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classA.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classB.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classC.getURI(), XSDDatatype.XSDanyURI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
/*
|
||||
* Test computation of mostSpecificType annotations in response
|
||||
* to an added/removed TBox assertions.
|
||||
*/
|
||||
public void mstTest3(){
|
||||
// Create TBox, ABox and Inference models and register
|
||||
// the ABox reasoner listeners with the ABox and TBox
|
||||
// Pellet will compute TBox inferences
|
||||
|
||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
Model inf = ModelFactory.createDefaultModel();
|
||||
|
||||
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||
aBox.register(simpleReasoner);
|
||||
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
||||
|
||||
OntClass OWL_THING = tBox.createClass(OWL.Thing.getURI());
|
||||
AnnotationProperty mostSpecificType = tBox.createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
// Set up the Tbox with classes A, B, C, D,
|
||||
// E, F and G
|
||||
|
||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||
classA.setLabel("class A", "en-US");
|
||||
|
||||
OntClass classB = tBox.createClass("http://test.vivo/B");
|
||||
classB.setLabel("class B", "en-US");
|
||||
|
||||
OntClass classC = tBox.createClass("http://test.vivo/C");
|
||||
classC.setLabel("class C", "en-US");
|
||||
|
||||
OntClass classD = tBox.createClass("http://test.vivo/D");
|
||||
classD.setLabel("class D", "en-US");
|
||||
|
||||
OntClass classE = tBox.createClass("http://test.vivo/E");
|
||||
classE.setLabel("class E", "en-US");
|
||||
|
||||
OntClass classF = tBox.createClass("http://test.vivo/F");
|
||||
classE.setLabel("class F", "en-US");
|
||||
|
||||
OntClass classG = tBox.createClass("http://test.vivo/G");
|
||||
classE.setLabel("class G", "en-US");
|
||||
|
||||
// add individuals x, y and z to the aBox
|
||||
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||
Resource ind_y = aBox.createResource("http://test.vivo/y");
|
||||
|
||||
aBox.add(ind_x, RDF.type, OWL_THING);
|
||||
aBox.add(ind_y, RDF.type, classD);
|
||||
|
||||
Assert.assertTrue(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(OWL.Thing.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_y, mostSpecificType, ResourceFactory.createTypedLiteral(classD.getURI(), XSDDatatype.XSDanyURI)));
|
||||
|
||||
aBox.add(ind_x, RDF.type, classC);
|
||||
aBox.add(ind_y, RDF.type, classF);
|
||||
|
||||
Assert.assertFalse(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(OWL.Thing.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_x, mostSpecificType, ResourceFactory.createTypedLiteral(classC.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_y, mostSpecificType, ResourceFactory.createTypedLiteral(classD.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_y, mostSpecificType, ResourceFactory.createTypedLiteral(classF.getURI(), XSDDatatype.XSDanyURI)));
|
||||
|
||||
// Set up a class hierarchy.
|
||||
// Pellet will compute TBox inferences.
|
||||
|
||||
classA.addSubClass(classB);
|
||||
classA.addSubClass(classC);
|
||||
classA.addSubClass(classD);
|
||||
|
||||
classC.addSubClass(classE);
|
||||
|
||||
classD.addSubClass(classF);
|
||||
classD.addSubClass(classG);
|
||||
|
||||
Assert.assertFalse(aBox.contains(ind_y, mostSpecificType, ResourceFactory.createTypedLiteral(classD.getURI(), XSDDatatype.XSDanyURI)));
|
||||
Assert.assertTrue(aBox.contains(ind_y, mostSpecificType, ResourceFactory.createTypedLiteral(classF.getURI(), XSDDatatype.XSDanyURI)));
|
||||
|
||||
// If F is removed as a subclass of D, then D should once again be a most specific type
|
||||
// for y.
|
||||
classD.removeSubClass(classF);
|
||||
Assert.assertTrue(aBox.contains(ind_y, mostSpecificType, ResourceFactory.createTypedLiteral(classD.getURI(), XSDDatatype.XSDanyURI)));
|
||||
|
||||
}
|
||||
// To help in debugging the unit test
|
||||
void printModels(OntModel ontModel) {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue