NIHVIVO-2314 add support for property-based inferencing to the SimpleReasoner
This commit is contained in:
parent
a1e87a10b9
commit
87b87c8edf
2 changed files with 896 additions and 275 deletions
|
@ -24,11 +24,12 @@ import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||||
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
import com.hp.hpl.jena.vocabulary.RDF;
|
import com.hp.hpl.jena.vocabulary.RDF;
|
||||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows for instant incremental materialization or retraction of RDFS-
|
* Allows for real-time incremental materialization or retraction of RDFS-
|
||||||
* style class and property subsumption based ABox inferences as statements
|
* style class and property subsumption based ABox inferences as statements
|
||||||
* are added to or removed from the (ABox or TBox) knowledge base.
|
* are added to or removed from the (ABox or TBox) knowledge base.
|
||||||
*
|
*
|
||||||
|
@ -77,41 +78,39 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental selected ABox reasoning based
|
* Performs selected incremental ABox reasoning based
|
||||||
* on a new type assertion (assertion that an individual
|
* on the addition of a new statement (aka assertion)
|
||||||
* is of a certain type) added to the ABox.
|
* to the ABox.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addedStatement(Statement stmt) {
|
public void addedStatement(Statement stmt) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (stmt.getPredicate().equals(RDF.type)) {
|
if (stmt.getPredicate().equals(RDF.type)) {
|
||||||
addedType(stmt, inferenceModel);
|
addedABoxTypeAssertion(stmt, inferenceModel);
|
||||||
|
} else {
|
||||||
|
addedABoxAssertion(stmt,inferenceModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// don't stop the edit if there's an exception
|
// don't stop the edit if there's an exception
|
||||||
log.error("Exception while adding incremental inferences: ", e);
|
log.error("Exception while adding inferences: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental selected ABox reasoning based
|
* Performs selected incremental ABox reasoning based
|
||||||
* on a removed type assertion (assertion that an individual
|
* on the retraction of a statement (aka assertion)
|
||||||
* is of a certain type) from the ABox.
|
* from the ABox.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removedStatement(Statement stmt) {
|
public void removedStatement(Statement stmt) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (stmt.getPredicate().equals(RDF.type)) {
|
if (stmt.getPredicate().equals(RDF.type)) {
|
||||||
removedType(stmt);
|
removedABoxTypeAssertion(stmt, inferenceModel);
|
||||||
|
} else {
|
||||||
|
removedABoxAssertion(stmt, inferenceModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// don't stop the edit if there's an exception
|
// don't stop the edit if there's an exception
|
||||||
log.error("Exception while retracting inferences: ", e);
|
log.error("Exception while retracting inferences: ", e);
|
||||||
|
@ -120,27 +119,26 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental selected ABox reasoning based
|
* Performs incremental selected ABox reasoning based
|
||||||
* on changes to the class hierarchy.
|
* on changes to the class or property hierarchy.
|
||||||
*
|
|
||||||
* Handles subclassOf and equivalentClass assertions
|
|
||||||
*
|
*
|
||||||
|
* Handles rdfs:subclassOf, owl:equivalentClass,
|
||||||
|
* rdfs:subPropertyOf and owl:equivalentProperty assertions
|
||||||
*/
|
*/
|
||||||
public void addedTBoxStatement(Statement stmt) {
|
public void addedTBoxStatement(Statement stmt) {
|
||||||
|
addedTBoxStatement(stmt, inferenceModel);
|
||||||
try {
|
|
||||||
|
|
||||||
if ( !(stmt.getPredicate().equals(RDFS.subClassOf)
|
|
||||||
|| stmt.getPredicate().equals(RDFS.subClassOf) ) ) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addedTBoxStatement(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.debug("added TBox assertion = " + stmt.toString());
|
||||||
|
|
||||||
|
if ( stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) ) {
|
||||||
// ignore anonymous classes
|
// ignore anonymous classes
|
||||||
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
|
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("stmt = " + stmt.toString());
|
|
||||||
|
|
||||||
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
|
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
|
||||||
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
|
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
|
||||||
|
|
||||||
|
@ -151,36 +149,42 @@ public class SimpleReasoner extends StatementListener {
|
||||||
addedSubClass(subject,object);
|
addedSubClass(subject,object);
|
||||||
addedSubClass(object,subject);
|
addedSubClass(object,subject);
|
||||||
}
|
}
|
||||||
|
} 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);
|
||||||
|
} else {
|
||||||
|
// equivalent property is the same as subProperty in both directions
|
||||||
|
addedSubProperty(subject, object, inferenceModel);
|
||||||
|
addedSubProperty(object, subject, inferenceModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// don't stop the edit if there's an exception
|
// don't stop the edit if there's an exception
|
||||||
log.error("Exception while adding incremental inferences: ", e);
|
log.error("Exception while adding inference(s): ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental selected ABox reasoning based
|
* Performs incremental selected ABox reasoning based
|
||||||
* on changes to the class hierarchy.
|
* on changes to the class or property hierarchy.
|
||||||
*
|
|
||||||
* Handles subclassOf and equivalentClass assertions
|
|
||||||
*
|
*
|
||||||
|
* Handles rdfs:subclassOf, owl:equivalentClass,
|
||||||
|
* rdfs:subPropertyOf and owl:equivalentProperty assertions
|
||||||
*/
|
*/
|
||||||
public void removedTBoxStatement(Statement stmt) {
|
public void removedTBoxStatement(Statement stmt) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
log.debug("removed TBox assertion = " + stmt.toString());
|
||||||
|
|
||||||
if ( !(stmt.getPredicate().equals(RDFS.subClassOf)
|
if ( stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) ) {
|
||||||
|| stmt.getPredicate().equals(RDFS.subClassOf) ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore anonymous classes
|
// ignore anonymous classes
|
||||||
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
|
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("stmt = " + stmt.toString());
|
|
||||||
|
|
||||||
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
|
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
|
||||||
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
|
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
|
||||||
|
|
||||||
|
@ -191,21 +195,34 @@ public class SimpleReasoner extends StatementListener {
|
||||||
removedSubClass(subject,object);
|
removedSubClass(subject,object);
|
||||||
removedSubClass(object,subject);
|
removedSubClass(object,subject);
|
||||||
}
|
}
|
||||||
|
} 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)) {
|
||||||
|
removedSubProperty(subject,object);
|
||||||
|
} else {
|
||||||
|
// equivalent property is the same as subProperty in both directions
|
||||||
|
removedSubProperty(subject,object);
|
||||||
|
removedSubProperty(object,subject);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// don't stop the edit if there's an exception
|
// don't stop the edit if there's an exception
|
||||||
log.error("Exception while removing incremental inferences: ", e);
|
log.error("Exception while removing inference(s): ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Performs incremental reasoning based on a new type assertion
|
||||||
|
* added to the ABox (assertion that an individual is of a certain
|
||||||
|
* type).
|
||||||
|
*
|
||||||
* If it is added that B is of type A, then for each superclass of
|
* If it is added that B is of type A, then for each superclass of
|
||||||
* A assert that B is of that type.
|
* A assert that B is of that type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void addedType(Statement stmt, Model inferenceModel) {
|
public void addedABoxTypeAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
//log.debug("stmt = " + stmt.toString());
|
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
@ -216,7 +233,6 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
List<OntClass> parents = (cls.listSuperClasses(false)).toList();
|
List<OntClass> parents = (cls.listSuperClasses(false)).toList();
|
||||||
parents.addAll((cls.listEquivalentClasses()).toList());
|
parents.addAll((cls.listEquivalentClasses()).toList());
|
||||||
|
|
||||||
Iterator<OntClass> parentIt = parents.iterator();
|
Iterator<OntClass> parentIt = parents.iterator();
|
||||||
|
|
||||||
while (parentIt.hasNext()) {
|
while (parentIt.hasNext()) {
|
||||||
|
@ -247,13 +263,61 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Performs incremental property-based reasoning.
|
||||||
|
*
|
||||||
|
* Materializes inferences based on the rdfs:subPropertyOf relationship.
|
||||||
|
* If it is added that x propB y and propB is a sub-property of propA
|
||||||
|
* then add x propA y to the inference graph.
|
||||||
|
*/
|
||||||
|
public void addedABoxAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().getURI());
|
||||||
|
|
||||||
|
if (prop != null) {
|
||||||
|
|
||||||
|
//TODO: have trouble parametizing the template with ? extends OntProperty
|
||||||
|
List superProperties = prop.listSuperProperties(false).toList();
|
||||||
|
superProperties.addAll(prop.listEquivalentProperties().toList());
|
||||||
|
Iterator<OntProperty> superIt = superProperties.iterator();
|
||||||
|
|
||||||
|
while (superIt.hasNext()) {
|
||||||
|
OntProperty superProp = superIt.next();
|
||||||
|
|
||||||
|
if ( !((prop.isObjectProperty() && superProp.isObjectProperty()) || (prop.isDatatypeProperty() && superProp.isDatatypeProperty())) ) {
|
||||||
|
log.warn("sub-property and super-property do not have the same type. No inferencing will be performed. sub-property: " + prop.getURI() + " super-property:" + superProp.getURI());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), superProp, stmt.getObject());
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
if (!inferenceModel.contains(infStmt) && !infStmt.equals(stmt) ) {
|
||||||
|
//log.debug("Adding this inferred statement: " + infStmt.toString() );
|
||||||
|
inferenceModel.add(infStmt);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Didn't find target property (the predicate of the added statement) in the TBox: " + stmt.getPredicate().getURI());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
tboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it is removed that B is of type A, then for each superclass of A remove
|
* If it is removed that B is of type A, then for each superclass of A remove
|
||||||
* the inferred statement that B is of that type UNLESS it is otherwise entailed
|
* the inferred statement that B is of that type UNLESS it is otherwise entailed
|
||||||
* that B is of that type.
|
* that B is of that type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void removedType(Statement stmt) {
|
public void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
//log.debug("stmt = " + stmt.toString());
|
//log.debug("stmt = " + stmt.toString());
|
||||||
|
|
||||||
|
@ -266,7 +330,6 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
List<OntClass> parents = (cls.listSuperClasses(false)).toList();
|
List<OntClass> parents = (cls.listSuperClasses(false)).toList();
|
||||||
parents.addAll((cls.listEquivalentClasses()).toList());
|
parents.addAll((cls.listEquivalentClasses()).toList());
|
||||||
|
|
||||||
Iterator<OntClass> parentIt = parents.iterator();
|
Iterator<OntClass> parentIt = parents.iterator();
|
||||||
|
|
||||||
while (parentIt.hasNext()) {
|
while (parentIt.hasNext()) {
|
||||||
|
@ -302,8 +365,62 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if it is entailed by class subsumption that subject is
|
/*
|
||||||
// of type cls; otherwise returns false.
|
* Performs incremental property-based reasoning.
|
||||||
|
*
|
||||||
|
* Retracts inferences based on the rdfs:subPropertyOf relationship.
|
||||||
|
* If it is removed that x propB y and propB is a sub-property of propA
|
||||||
|
* then remove x propA y from the inference graph UNLESS it that
|
||||||
|
* statement is otherwise entailed.
|
||||||
|
*/
|
||||||
|
public void removedABoxAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().getURI());
|
||||||
|
|
||||||
|
if (prop != null) {
|
||||||
|
|
||||||
|
//TODO: trouble parameterizing these templates with "? extends OntProperty"
|
||||||
|
List superProperties = prop.listSuperProperties(false).toList();
|
||||||
|
superProperties.addAll(prop.listEquivalentProperties().toList());
|
||||||
|
Iterator<OntProperty> superIt = superProperties.iterator();
|
||||||
|
|
||||||
|
while (superIt.hasNext()) {
|
||||||
|
OntProperty superProp = superIt.next();
|
||||||
|
|
||||||
|
if ( !((prop.isObjectProperty() && superProp.isObjectProperty()) || (prop.isDatatypeProperty() && superProp.isDatatypeProperty())) ) {
|
||||||
|
log.warn("sub-property and super-property do not have the same type. No inferencing will be performed. sub-property: " + prop.getURI() + " super-property:" + superProp.getURI());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the statement is still entailed without the removed
|
||||||
|
// statement then don't remove it from the inferences
|
||||||
|
if (entailedByPropertySubsumption(stmt.getSubject(), superProp, stmt.getObject())) continue;
|
||||||
|
|
||||||
|
Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), superProp, stmt.getObject());
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
if (inferenceModel.contains(infStmt)) {
|
||||||
|
//log.debug("Removing this inferred statement: " + infStmt.toString() + " - " + infStmt.getSubject().toString() + " - " + infStmt.getPredicate().toString() + " - " + infStmt.getObject().toString());
|
||||||
|
inferenceModel.remove(infStmt);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("Didn't find target predicate (the predicate of the removed statement) in the TBox: " + stmt.getPredicate().getURI());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
tboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if it is entailed by class subsumption that
|
||||||
|
// subject is of type cls; otherwise returns false.
|
||||||
public boolean entailedType(Resource subject, OntClass cls) {
|
public boolean entailedType(Resource subject, OntClass cls) {
|
||||||
|
|
||||||
//log.debug("subject = " + subject.getURI() + " class = " + cls.getURI());
|
//log.debug("subject = " + subject.getURI() + " class = " + cls.getURI());
|
||||||
|
@ -313,8 +430,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ExtendedIterator<OntClass> iter = cls.listSubClasses(false);
|
ExtendedIterator<OntClass> iter = cls.listSubClasses(false);
|
||||||
while (iter.hasNext()) {
|
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
OntClass childClass = iter.next();
|
OntClass childClass = iter.next();
|
||||||
Statement stmt = ResourceFactory.createStatement(subject, RDF.type, childClass);
|
Statement stmt = ResourceFactory.createStatement(subject, RDF.type, childClass);
|
||||||
if (aboxModel.contains(stmt)) return true;
|
if (aboxModel.contains(stmt)) return true;
|
||||||
|
@ -327,10 +444,33 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if the statement is entailed by property subsumption
|
||||||
|
public boolean entailedByPropertySubsumption(Resource subject, OntProperty prop, RDFNode object) {
|
||||||
|
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
ExtendedIterator<? extends OntProperty> iter = prop.listSubProperties(false);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
OntProperty subProp = iter.next();
|
||||||
|
Statement stmt = ResourceFactory.createStatement(subject, subProp, object);
|
||||||
|
if (aboxModel.contains(stmt)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
tboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If added that B is a subclass of A, then find all individuals
|
* If it is added that B is a subClass of A, then for each
|
||||||
* that are typed as B, either in the ABox or in the inferred model
|
* individual that is typed as B, either in the ABox or in the
|
||||||
* and assert that they are of type A.
|
* inferred model, assert that it is of type A.
|
||||||
*/
|
*/
|
||||||
public void addedSubClass(OntClass subClass, OntClass superClass) {
|
public void addedSubClass(OntClass subClass, OntClass superClass) {
|
||||||
|
|
||||||
|
@ -366,11 +506,10 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If removed that B is a subclass of A, then for each individual
|
* If removed that B is a subclass of A, then for each individual
|
||||||
* that is of type B, either inferred or in the ABox, then
|
* that is of type B, either inferred or in the ABox, remove the
|
||||||
* remove the inferred assertion that it is of type A,
|
* assertion that it is of type A from the inferred model,
|
||||||
* UNLESS the individual is of some type C that is
|
* UNLESS the individual is of some type C that is a subClass
|
||||||
* a subClass of A (including A itself)
|
* of A (including A itself)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public void removedSubClass(OntClass subClass, OntClass superClass) {
|
public void removedSubClass(OntClass subClass, OntClass superClass) {
|
||||||
|
|
||||||
|
@ -408,6 +547,97 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is added that B is a subProperty of A, then for each assertion
|
||||||
|
* involving predicate B, either in the ABox or in the inferred model
|
||||||
|
* assert the same relationship for predicate A
|
||||||
|
*/
|
||||||
|
public void addedSubProperty(OntProperty subProp, OntProperty superProp, Model inferenceModel) {
|
||||||
|
|
||||||
|
log.debug("subProperty = " + subProp.getURI() + " superProperty = " + subProp.getURI());
|
||||||
|
|
||||||
|
if ( !((subProp.isObjectProperty() && superProp.isObjectProperty()) || (subProp.isDatatypeProperty() && superProp.isDatatypeProperty())) ) {
|
||||||
|
log.warn("sub-property and super-property do not have the same type. No inferencing will be performed. sub-property: " + subProp.getURI() + " super-property:" + superProp.getURI());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
unionModel.addSubModel(aboxModel);
|
||||||
|
unionModel.addSubModel(inferenceModel);
|
||||||
|
|
||||||
|
StmtIterator iter = unionModel.listStatements((Resource) null, subProp, (RDFNode) null);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), superProp, stmt.getObject());
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
|
||||||
|
if (!inferenceModel.contains(infStmt)) {
|
||||||
|
//log.debug("Adding this inferred statement: " + infStmt.toString() );
|
||||||
|
inferenceModel.add(infStmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is removed that B is a subProperty of A, then for each
|
||||||
|
* assertion involving predicate B, either in the ABox or in the
|
||||||
|
* inferred model, remove the same assertion involving predicate
|
||||||
|
* A from the inferred model, UNLESS the assertion is otherwise
|
||||||
|
* entailed by property subsumption.
|
||||||
|
*/
|
||||||
|
public void removedSubProperty(OntProperty subProp, OntProperty superProp) {
|
||||||
|
|
||||||
|
log.debug("subProperty = " + subProp.getURI() + " superProperty = " + subProp.getURI());
|
||||||
|
|
||||||
|
if ( !((subProp.isObjectProperty() && superProp.isObjectProperty()) || (subProp.isDatatypeProperty() && superProp.isDatatypeProperty())) ) {
|
||||||
|
log.warn("sub-property and super-property do not have the same type. No inferencing will be performed. sub-property: " + subProp.getURI() + " super-property:" + superProp.getURI());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
unionModel.addSubModel(aboxModel);
|
||||||
|
unionModel.addSubModel(inferenceModel);
|
||||||
|
|
||||||
|
StmtIterator iter = unionModel.listStatements((Resource) null, subProp, (RDFNode) null);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
|
||||||
|
// if the statement is entailed without the removed subPropertyOf
|
||||||
|
// relationship then don't remove it from the inferences
|
||||||
|
if (entailedByPropertySubsumption(stmt.getSubject(), superProp, stmt.getObject())) continue;
|
||||||
|
|
||||||
|
Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), superProp, stmt.getObject());
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
|
||||||
|
if (inferenceModel.contains(infStmt)) {
|
||||||
|
//log.debug("Adding this inferred statement: " + infStmt.toString() );
|
||||||
|
inferenceModel.remove(infStmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean recomputing = false;
|
private boolean recomputing = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -441,26 +671,53 @@ public class SimpleReasoner extends StatementListener {
|
||||||
*/
|
*/
|
||||||
public synchronized void recomputeABox() {
|
public synchronized void recomputeABox() {
|
||||||
|
|
||||||
// recompute the inferences
|
// recompute the ABox inferences
|
||||||
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
|
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
inferenceRebuildModel.removeAll();
|
inferenceRebuildModel.removeAll();
|
||||||
|
|
||||||
|
// compute the class-based inferences
|
||||||
|
log.info("Computing class-based ABox inferences");
|
||||||
|
|
||||||
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, (RDFNode) null);
|
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, (RDFNode) null);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement stmt = iter.next();
|
Statement stmt = iter.next();
|
||||||
addedType(stmt, inferenceRebuildModel);
|
addedABoxTypeAssertion(stmt, inferenceRebuildModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the property-based inferences
|
||||||
|
log.info("Computing property-based ABox inferences");
|
||||||
|
iter = tboxModel.listStatements((Resource) null, RDFS.subPropertyOf, (RDFNode) null);
|
||||||
|
int numStmts = 0;
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
numStmts++;
|
||||||
|
if ((numStmts % 400) == 0) {
|
||||||
|
log.info("Still computing property-based ABox inferences...");
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
addedTBoxStatement(stmt, inferenceRebuildModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = tboxModel.listStatements((Resource) null, OWL.equivalentProperty, (RDFNode) null);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
addedTBoxStatement(stmt, inferenceRebuildModel);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Exception while recomputing ABox inference model", e);
|
log.error("Exception while recomputing ABox inference model", e);
|
||||||
} finally {
|
} finally {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
|
tboxModel.leaveCriticalSection();
|
||||||
inferenceRebuildModel.leaveCriticalSection();
|
inferenceRebuildModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// reflect the recomputed inferences into the application inference
|
// reflect the recomputed inferences into the application inference
|
||||||
// model.
|
// model.
|
||||||
inferenceRebuildModel.enterCriticalSection(Lock.READ);
|
inferenceRebuildModel.enterCriticalSection(Lock.READ);
|
||||||
|
@ -532,99 +789,6 @@ public class SimpleReasoner extends StatementListener {
|
||||||
log.info("ABox inferences recomputed.");
|
log.info("ABox inferences recomputed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following three methods aren't currently called; the default behavior of VIVO is to not materialize such inferences.
|
|
||||||
public void addedProperty(Statement stmt) {
|
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
|
||||||
|
|
||||||
try {
|
|
||||||
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().getURI());
|
|
||||||
|
|
||||||
if (prop != null) {
|
|
||||||
ExtendedIterator<? extends OntProperty> superIt = prop.listSuperProperties(false);
|
|
||||||
|
|
||||||
while (superIt.hasNext()) {
|
|
||||||
OntProperty parentProp = superIt.next();
|
|
||||||
Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), parentProp, stmt.getObject());
|
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
if (!inferenceModel.contains(infStmt)) {
|
|
||||||
//log.debug("Adding inferred statement: " + infStmt.toString() + " - " + infStmt.getSubject().toString() + " - " + infStmt.getPredicate().toString() + " - " + infStmt.getObject().toString());
|
|
||||||
inferenceModel.add(infStmt);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
inferenceModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.debug("Didn't find predicate of the added statement in the TBox: " + stmt.getPredicate().getURI());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
tboxModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removedProperty(Statement stmt) {
|
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
|
||||||
|
|
||||||
try {
|
|
||||||
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().getURI());
|
|
||||||
|
|
||||||
if (prop != null) {
|
|
||||||
ExtendedIterator<? extends OntProperty> superIt = prop.listSuperProperties(false);
|
|
||||||
|
|
||||||
while (superIt.hasNext()) {
|
|
||||||
OntProperty parentProp = superIt.next();
|
|
||||||
|
|
||||||
if (entailedStmt(stmt.getSubject(),parentProp,stmt.getObject() )) continue; // if the statement is still entailed
|
|
||||||
// don't remove it from the inference graph.
|
|
||||||
|
|
||||||
Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), parentProp, stmt.getObject());
|
|
||||||
|
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
if (inferenceModel.contains(infStmt)) {
|
|
||||||
//log.debug("Removing inferred statement: " + infStmt.toString() + " - " + infStmt.getSubject().toString() + " - " + infStmt.getPredicate().toString() + " - " + infStmt.getObject().toString());
|
|
||||||
inferenceModel.remove(infStmt);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
inferenceModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.debug("Didn't find predicate of the removed statement in the TBox: " + stmt.getPredicate().getURI());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
tboxModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the statement is entailed by property subsumption
|
|
||||||
public boolean entailedStmt(Resource subject, OntProperty prop, RDFNode object) {
|
|
||||||
|
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
ExtendedIterator<? extends OntProperty> iter = prop.listSubProperties(false);
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
|
|
||||||
OntProperty childProp = iter.next();
|
|
||||||
|
|
||||||
Statement stmt = ResourceFactory.createStatement(subject, childProp, object);
|
|
||||||
if (aboxModel.contains(stmt)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
aboxModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SimpleReasoner getSimpleReasonerFromServletContext(ServletContext ctx) {
|
public static SimpleReasoner getSimpleReasonerFromServletContext(ServletContext ctx) {
|
||||||
Object simpleReasoner = ctx.getAttribute("simpleReasoner");
|
Object simpleReasoner = ctx.getAttribute("simpleReasoner");
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.mindswap.pellet.jena.PelletReasonerFactory;
|
||||||
import com.hp.hpl.jena.ontology.OntClass;
|
import com.hp.hpl.jena.ontology.OntClass;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
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.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
|
@ -24,16 +25,20 @@ import edu.cornell.mannlib.vitro.webapp.reasoner.support.SimpleReasonerTBoxListe
|
||||||
|
|
||||||
public class SimpleReasonerTest extends AbstractTestClass {
|
public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
|
|
||||||
|
|
||||||
|
private Resource objectProperty = ResourceFactory.createResource("http://www.w3.org/2002/07/owl#ObjectProperty");
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void suppressErrorOutput() {
|
public void suppressErrorOutput() {
|
||||||
suppressSyserr();
|
suppressSyserr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that when an individual is asserted to be of a type,
|
||||||
|
* its asserted type is not added to the inference graph
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void addType(){
|
public void addABoxTypeAssertion1(){
|
||||||
|
|
||||||
// Test that when a new instance is asserted, its asserted type is not added to the
|
|
||||||
// inference graph
|
|
||||||
|
|
||||||
// Create a Tbox with a simple class hierarchy. B is a subclass of A.
|
// Create a Tbox with a simple class hierarchy. B is a subclass of A.
|
||||||
// Pellet will compute TBox inferences
|
// Pellet will compute TBox inferences
|
||||||
|
@ -50,7 +55,7 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
// this is the model to receive inferences
|
// this is the model to receive inferences
|
||||||
Model inf = ModelFactory.createDefaultModel();
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
// create an Abox and register the SimpleReasoner listener with it
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
||||||
|
|
||||||
|
@ -65,11 +70,16 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
Assert.assertFalse(inf.contains(xisb));
|
Assert.assertFalse(inf.contains(xisb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that when an individual is asserted have a type,
|
||||||
|
* that inferences are materialized that it has the types
|
||||||
|
* of its superclasses
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void addTypes(){
|
public void addABoxTypeAssertion2(){
|
||||||
|
|
||||||
// Create a Tbox with a simple class hierarchy. D and E are subclasses of C. B and C are subclasses of A.
|
// Create a Tbox with a simple class hierarchy. D and E are subclasses
|
||||||
// Pellet will compute TBox inferences
|
// of C. B and C are subclasses of A. Pellet will compute TBox inferences.
|
||||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||||
|
@ -113,13 +123,150 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
Assert.assertTrue(inf.contains(xisa));
|
Assert.assertTrue(inf.contains(xisa));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test inference based on class equivalence
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void removeTypes(){
|
public void addABoxTypeAssertion3(){
|
||||||
|
|
||||||
// Create a Tbox with a simple class hierarchy. C is a subclass of B and B is a subclass of A.
|
// Create TBox, ABox and Inference models and register
|
||||||
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
// Pellet will compute TBox inferences
|
// 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));
|
||||||
|
|
||||||
|
// Add classes A, B and C to the TBox
|
||||||
|
// A is equivalent to B
|
||||||
|
// C is a subclass of A
|
||||||
|
|
||||||
|
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.addEquivalentClass(classB);
|
||||||
|
classA.addSubClass(classC);
|
||||||
|
|
||||||
|
// Add a statement that individual x is of type C to the ABox
|
||||||
|
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||||
|
aBox.add(ind_x, RDF.type, classC);
|
||||||
|
|
||||||
|
// Verify that "x is of type A" was inferred
|
||||||
|
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
||||||
|
Assert.assertTrue(inf.contains(xisa));
|
||||||
|
|
||||||
|
// Verify that "x is of type B" was inferred
|
||||||
|
Statement xisb = ResourceFactory.createStatement(ind_x, RDF.type, classB);
|
||||||
|
Assert.assertTrue(inf.contains(xisb));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test inference based on class equivalence
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addABoxTypeAssertion4() {
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Add classes A and B to the TBox
|
||||||
|
// A is equivalent to B
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
classA.addEquivalentClass(classB);
|
||||||
|
|
||||||
|
// Add a statement that 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);
|
||||||
|
|
||||||
|
// Verify that "x is of type A" was inferred
|
||||||
|
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
||||||
|
Assert.assertTrue(inf.contains(xisa));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test inference based on class equivalence
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addABoxTypeAssertion5() {
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Add classes classes A and B to the TBox
|
||||||
|
// A is equivalent to B
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
classA.addEquivalentClass(classB);
|
||||||
|
|
||||||
|
// Add a statement that 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);
|
||||||
|
|
||||||
|
// Verify that "x is of type A" was inferred
|
||||||
|
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
||||||
|
Assert.assertTrue(inf.contains(xisa));
|
||||||
|
|
||||||
|
// Remove the statement that x is of type B from the ABox
|
||||||
|
aBox.remove(ind_x, RDF.type, classB);
|
||||||
|
|
||||||
|
// Verify that "x is of type A" was removed from the inference graph
|
||||||
|
Assert.assertFalse(inf.contains(xisa));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that when it is retracted that an individual is of a type,
|
||||||
|
* that the inferences that it is of the type of all superclasses
|
||||||
|
* of the retracted type are retracted from the inference graph.
|
||||||
|
* However, any assertions that are otherwise entailed (by the
|
||||||
|
* TBox, ABox and inference graph minus the retracted type statement)
|
||||||
|
* should not be retracted.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void removeABoxTypeAssertion1(){
|
||||||
|
|
||||||
|
// Create a Tbox with a simple class hierarchy. C is a subclass of B
|
||||||
|
// and B is a subclass of A. Pellet will compute TBox inferences.
|
||||||
|
|
||||||
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
OntClass classA = tBox.createClass("http://test.vivo/A");
|
||||||
|
@ -154,14 +301,32 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
// Verify that the inference graph contains the statement that x is of type A.
|
// Verify that the inference graph contains the statement that x is of type A.
|
||||||
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
||||||
Assert.assertTrue(inf.contains(xisa));
|
Assert.assertTrue(inf.contains(xisa));
|
||||||
|
|
||||||
|
// Hopefully the assertion that x is b got removed from
|
||||||
|
// the inference graph
|
||||||
|
Statement xisb = ResourceFactory.createStatement(ind_x, RDF.type, classB);
|
||||||
|
Assert.assertFalse(inf.contains(xisb));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// This tests added TBox subClassOf and equivalentClass statements.
|
* Test the addition of a subClassOf statement to
|
||||||
// The ABox data that will be the basis for the inference will
|
* the TBox. The instance data that is the basis
|
||||||
// be in the ABox graph.
|
* for the inference is in the ABox. The existing
|
||||||
|
* instance of the newly declared subclass should
|
||||||
|
* be inferred to have the type of the superclass.
|
||||||
|
* There are also a few checks that the instance
|
||||||
|
* is not inferred to have the types of some other
|
||||||
|
* random classes.
|
||||||
|
*
|
||||||
|
* Since the addition of an owl:equivalentClass
|
||||||
|
* statement is implemented as two calls to the
|
||||||
|
* method that handles the addition of an
|
||||||
|
* rdfs:subClassOf statement, this test serves
|
||||||
|
* as a test of equivalentClass statements also.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void addSubClass1(){
|
public void addTBoxSubClassAssertion1(){
|
||||||
|
|
||||||
// Create TBox, ABox and Inference models and register
|
// Create TBox, ABox and Inference models and register
|
||||||
// the ABox reasoner listeners with the ABox and TBox
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
|
@ -211,12 +376,24 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// this tests added TBox subClassOf and equivalentClass statements.
|
* Test the addition of a subClassOf statement to
|
||||||
// The ABox data that is the basis for the inference will be
|
* the TBox. The instance data that is the basis
|
||||||
// in the inferred graph
|
* for the inference is in the ABox graph and the
|
||||||
|
* inference graph. The existing instance of the
|
||||||
|
* subclass of the newly added subclass should
|
||||||
|
* be inferred to have the type of the superclass
|
||||||
|
* of the newly added subclass.
|
||||||
|
*
|
||||||
|
* Since the addition of an owl:equivalentClass
|
||||||
|
* statement is implemented as two calls to the
|
||||||
|
* method that handles the addition of an
|
||||||
|
* rdfs:subClassOf statement, this test serves
|
||||||
|
* as some test of equivalentClass statements also.
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void addSubClass2(){
|
public void addTBoxSubClassAssertion2() {
|
||||||
|
|
||||||
// Create TBox, ABox and Inference models and register
|
// Create TBox, ABox and Inference models and register
|
||||||
// the ABox reasoner listeners with the ABox and TBox
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
|
@ -260,9 +437,23 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// this tests incremental reasoning as a result of the removal of a subClassOf
|
/*
|
||||||
// or equivalentClass statement from the TBox.
|
* Test the removal of a subClassOf statement from
|
||||||
public void removeSubClass(){
|
* the TBox. The instance data that is the basis
|
||||||
|
* for the inference is in the ABox graph and the
|
||||||
|
* inference graph. The existing instance of the
|
||||||
|
* subclass of the newly added subclass should
|
||||||
|
* be inferred to have the type of the superclass
|
||||||
|
* of the newly added subclass.
|
||||||
|
*
|
||||||
|
* Since the addition of an owl:equivalentClass
|
||||||
|
* statement is implemented as two calls to the
|
||||||
|
* method that handles the addition of an
|
||||||
|
* rdfs:subClassOf statement, this test serves
|
||||||
|
* as a test of equivalentClass assertions also.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void removeTBoxSubClassAssertion1(){
|
||||||
// Create TBox, ABox and Inference models and register
|
// Create TBox, ABox and Inference models and register
|
||||||
// the ABox reasoner listeners with the ABox and TBox
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
// Pellet will compute TBox inferences
|
// Pellet will compute TBox inferences
|
||||||
|
@ -324,7 +515,6 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
||||||
Assert.assertFalse(inf.contains(xisa));
|
Assert.assertFalse(inf.contains(xisa));
|
||||||
|
|
||||||
|
|
||||||
// Verify that "x is of type B" is in the inference graph
|
// Verify that "x is of type B" is in the inference graph
|
||||||
Statement xisb = ResourceFactory.createStatement(ind_x, RDF.type, classB);
|
Statement xisb = ResourceFactory.createStatement(ind_x, RDF.type, classB);
|
||||||
Assert.assertTrue(inf.contains(xisb));
|
Assert.assertTrue(inf.contains(xisb));
|
||||||
|
@ -340,13 +530,14 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
// Verify that "y is of type A" is in the inference graph
|
// Verify that "y is of type A" is in the inference graph
|
||||||
Statement yisa = ResourceFactory.createStatement(ind_y, RDF.type, classA);
|
Statement yisa = ResourceFactory.createStatement(ind_y, RDF.type, classA);
|
||||||
Assert.assertTrue(inf.contains(yisa));
|
Assert.assertTrue(inf.contains(yisa));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test inference based on class equivalence
|
|
||||||
//
|
/*
|
||||||
|
* tests rdfs:subPropertyOf materialization for object properties.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void equivClass1(){
|
public void addABoxAssertion1(){
|
||||||
|
|
||||||
// Create TBox, ABox and Inference models and register
|
// Create TBox, ABox and Inference models and register
|
||||||
// the ABox reasoner listeners with the ABox and TBox
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
|
@ -360,40 +551,130 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
aBox.register(simpleReasoner);
|
aBox.register(simpleReasoner);
|
||||||
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
||||||
|
|
||||||
// Add classes classes A, B and C to the TBox
|
// Add object properties propA and propB to the TBox.
|
||||||
|
// propB is a sub-property of propA.
|
||||||
|
|
||||||
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/propA");
|
||||||
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("propA", "en-US");
|
||||||
|
|
||||||
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/propB");
|
||||||
|
tBox.add(propB, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("propB", "en-US");
|
||||||
|
|
||||||
|
propA.addSubProperty(propB);
|
||||||
|
|
||||||
|
// Add the assertion that x propB y 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, propB, ind_y);
|
||||||
|
|
||||||
|
// Verify that x propA y was inferred
|
||||||
|
Statement xay = ResourceFactory.createStatement(ind_x, propA, ind_y);
|
||||||
|
Assert.assertTrue(inf.contains(xay));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that when a statement is asserted, that it not
|
||||||
|
* added to the inference graph.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addABoxAssertion2(){
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Add object properties propA and propB to the TBox.
|
||||||
|
// propB is a sub-property of propA.
|
||||||
|
|
||||||
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/propA");
|
||||||
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("propA", "en-US");
|
||||||
|
|
||||||
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/propB");
|
||||||
|
tBox.add(propB, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("propB", "en-US");
|
||||||
|
|
||||||
|
propA.addSubProperty(propB);
|
||||||
|
|
||||||
|
// Add the assertion that x propB y 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, propB, ind_y);
|
||||||
|
|
||||||
|
// Verify that x propA y was inferred
|
||||||
|
Statement xby = ResourceFactory.createStatement(ind_x, propB, ind_y);
|
||||||
|
Assert.assertFalse(inf.contains(xby));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test inference based on property equivalence
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addABoxAssertion4(){
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Add properties A, B and C to the TBox
|
||||||
// A is equivalent to B
|
// A is equivalent to B
|
||||||
// C is a subclass of A
|
// C is a subclass of A
|
||||||
|
|
||||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/A");
|
||||||
classA.setLabel("class A", "en-US");
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("property A", "en-US");
|
||||||
|
|
||||||
OntClass classB = tBox.createClass("http://test.vivo/B");
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/B");
|
||||||
classB.setLabel("class B", "en-US");
|
tBox.add(propB, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property B", "en-US");
|
||||||
|
|
||||||
OntClass classC = tBox.createClass("http://test.vivo/C");
|
OntProperty propC = tBox.createOntProperty("http://test.vivo/C");
|
||||||
classC.setLabel("class C", "en-US");
|
tBox.add(propC, RDF.type, objectProperty);
|
||||||
|
propC.setLabel("property C", "en-US");
|
||||||
|
|
||||||
classA.addEquivalentClass(classB);
|
propA.addEquivalentProperty(propB);
|
||||||
classA.addSubClass(classC);
|
propA.addSubProperty(propC);
|
||||||
|
|
||||||
// Add a statement that individual x is of type C to the ABox
|
// Add a statement that individual x is of type C to the ABox
|
||||||
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||||
aBox.add(ind_x, RDF.type, classC);
|
Resource ind_y = aBox.createResource("http://test.vivo/y");
|
||||||
|
|
||||||
// Verify that "x is of type A" was inferred
|
aBox.add(ind_x, propC, ind_y);
|
||||||
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
|
||||||
Assert.assertTrue(inf.contains(xisa));
|
|
||||||
|
|
||||||
// Verify that "x is of type B" was inferred
|
// Verify that "x A y" was inferred
|
||||||
Statement xisb = ResourceFactory.createStatement(ind_x, RDF.type, classB);
|
Statement xAy = ResourceFactory.createStatement(ind_x, propA, ind_y);
|
||||||
Assert.assertTrue(inf.contains(xisb));
|
Assert.assertTrue(inf.contains(xAy));
|
||||||
|
|
||||||
|
// Verify that "x B y" was inferred
|
||||||
|
Statement xBy = ResourceFactory.createStatement(ind_x, propB, ind_y);
|
||||||
|
Assert.assertTrue(inf.contains(xBy));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test inference based on class equivalence
|
/*
|
||||||
//
|
* The sub-property is not of the same type as the super
|
||||||
|
* property so no inference should be materialized.
|
||||||
|
*/
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void equivClass2(){
|
public void addABoxAssertion5(){
|
||||||
|
|
||||||
// Create TBox, ABox and Inference models and register
|
// Create TBox, ABox and Inference models and register
|
||||||
// the ABox reasoner listeners with the ABox and TBox
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
|
@ -407,31 +688,35 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
aBox.register(simpleReasoner);
|
aBox.register(simpleReasoner);
|
||||||
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
||||||
|
|
||||||
// Add classes classes A and B to the TBox
|
// Add object properties propA and propB to the TBox.
|
||||||
// A is equivalent to B
|
// propB is a sub-property of propA.
|
||||||
|
|
||||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/propA");
|
||||||
classA.setLabel("class A", "en-US");
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("propA", "en-US");
|
||||||
|
|
||||||
OntClass classB = tBox.createClass("http://test.vivo/B");
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/propB");
|
||||||
classB.setLabel("class B", "en-US");
|
Resource datatypeProperty = ResourceFactory.createResource("http://www.w3.org/2002/07/owl#DatatypeProperty");
|
||||||
|
tBox.add(propB, RDF.type, datatypeProperty);
|
||||||
|
propB.setLabel("propB", "en-US");
|
||||||
|
|
||||||
classA.addEquivalentClass(classB);
|
propA.addSubProperty(propB);
|
||||||
|
|
||||||
// Add a statement that individual x is of type B to the ABox
|
// Add the assertion that x propB y to the ABox
|
||||||
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||||
aBox.add(ind_x, RDF.type, classB);
|
Resource ind_y = aBox.createResource("http://test.vivo/y");
|
||||||
|
aBox.add(ind_x, propB, ind_y);
|
||||||
|
|
||||||
// Verify that "x is of type A" was inferred
|
// Verify that x propA y was not inferred
|
||||||
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
Statement xay = ResourceFactory.createStatement(ind_x, propA, ind_y);
|
||||||
Assert.assertTrue(inf.contains(xisa));
|
Assert.assertFalse(inf.contains(xay));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Test inference based on class equivalence
|
* Test inference based on property equivalence
|
||||||
//
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void equivClass3(){
|
public void addABoxAssertion6() {
|
||||||
|
|
||||||
// Create TBox, ABox and Inference models and register
|
// Create TBox, ABox and Inference models and register
|
||||||
// the ABox reasoner listeners with the ABox and TBox
|
// the ABox reasoner listeners with the ABox and TBox
|
||||||
|
@ -445,31 +730,203 @@ public class SimpleReasonerTest extends AbstractTestClass {
|
||||||
aBox.register(simpleReasoner);
|
aBox.register(simpleReasoner);
|
||||||
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
tBox.register(new SimpleReasonerTBoxListener(simpleReasoner));
|
||||||
|
|
||||||
// Add classes classes A and B to the TBox
|
// Add properties A and B to the TBox
|
||||||
// A is equivalent to B
|
// A is equivalent to B
|
||||||
|
|
||||||
OntClass classA = tBox.createClass("http://test.vivo/A");
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/A");
|
||||||
classA.setLabel("class A", "en-US");
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("property A", "en-US");
|
||||||
|
|
||||||
OntClass classB = tBox.createClass("http://test.vivo/B");
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/B");
|
||||||
classB.setLabel("class B", "en-US");
|
tBox.add(propB, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property B", "en-US");
|
||||||
|
|
||||||
classA.addEquivalentClass(classB);
|
propA.addEquivalentProperty(propB);
|
||||||
|
|
||||||
// Add a statement that individual x is of type B to the ABox
|
// Add the statement x B y to the ABox
|
||||||
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
Resource ind_x = aBox.createResource("http://test.vivo/x");
|
||||||
aBox.add(ind_x, RDF.type, classB);
|
Resource ind_y = aBox.createResource("http://test.vivo/y");
|
||||||
|
aBox.add(ind_x, propB, ind_y);
|
||||||
|
|
||||||
// Verify that "x is of type A" was inferred
|
// Verify that "x A y" was inferred
|
||||||
Statement xisa = ResourceFactory.createStatement(ind_x, RDF.type, classA);
|
Statement xAy = ResourceFactory.createStatement(ind_x, propA, ind_y);
|
||||||
Assert.assertTrue(inf.contains(xisa));
|
Assert.assertTrue(inf.contains(xAy));
|
||||||
|
|
||||||
// Remove the statement that x is of type B from the ABox
|
// Remove the statement that x B y from the ABox
|
||||||
aBox.remove(ind_x, RDF.type, classB);
|
aBox.remove(ind_x, propB, ind_y);
|
||||||
|
|
||||||
// Verify that "x is of type A" was removed from the inference graph
|
// Verify that "x is of type A" was removed from the inference graph
|
||||||
Assert.assertFalse(inf.contains(xisa));
|
Assert.assertFalse(inf.contains(xAy));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test the addition of a subPropertyOf statement to
|
||||||
|
* the TBox. The instance data that is the basis
|
||||||
|
* for the inference is in the ABox.
|
||||||
|
*
|
||||||
|
* Since the addition of an owl:equivalentProperty
|
||||||
|
* statement is implemented as two calls to the
|
||||||
|
* method that handles the addition of an
|
||||||
|
* rdfs:subPropetyOf statement, this test serves
|
||||||
|
* as a test of equivalentProperty assertions also.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addTBoxSubPropertyAssertion1(){
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Add properties A, B, C and D to the TBox
|
||||||
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/A");
|
||||||
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("property A", "en-US");
|
||||||
|
|
||||||
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/B");
|
||||||
|
tBox.add(propB, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property B", "en-US");
|
||||||
|
|
||||||
|
OntProperty propC = tBox.createOntProperty("http://test.vivo/C");
|
||||||
|
tBox.add(propC, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property C", "en-US");
|
||||||
|
|
||||||
|
OntProperty propD = tBox.createOntProperty("http://test.vivo/D");
|
||||||
|
tBox.add(propD, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property D", "en-US");
|
||||||
|
|
||||||
|
// Add the statement "x C y" 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, propC, ind_y);
|
||||||
|
|
||||||
|
// Add a statement that C is a sub-property of A to the TBox
|
||||||
|
|
||||||
|
propA.addSubProperty(propC);
|
||||||
|
|
||||||
|
// Verify that "x A y" was inferred
|
||||||
|
Statement xAy = ResourceFactory.createStatement(ind_x, propA, ind_y);
|
||||||
|
Assert.assertTrue(inf.contains(xAy));
|
||||||
|
|
||||||
|
// Verify that "x B y" was not inferred
|
||||||
|
Statement xBy = ResourceFactory.createStatement(ind_x, propB, ind_y);
|
||||||
|
Assert.assertFalse(inf.contains(xBy));
|
||||||
|
|
||||||
|
// Verify that "x D y" was not inferred
|
||||||
|
Statement xDy = ResourceFactory.createStatement(ind_x, propD, ind_y);
|
||||||
|
Assert.assertFalse(inf.contains(xDy));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/*
|
||||||
|
* Test the removal of a subPropertyOf statement from
|
||||||
|
* the TBox. The instance data that is the basis
|
||||||
|
* for the inference is in the ABox graph and the
|
||||||
|
* inference graph.
|
||||||
|
*
|
||||||
|
* Since the addition of an owl:equivalentProperty
|
||||||
|
* statement is implemented as two calls to the
|
||||||
|
* method that handles the addition of an
|
||||||
|
* rdfs:subPropertyOf statement, this test serves
|
||||||
|
* as a test of equivalentProperty assertions also.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void removeTBoxSubPropertyAssertion1(){
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Add properties A, B, C, D, E, F, G and H to the TBox.
|
||||||
|
// B, C and D are subproperties of A.
|
||||||
|
// E is a subproperty of B.
|
||||||
|
// F and G are subproperties of C.
|
||||||
|
// H is a subproperty of D.
|
||||||
|
|
||||||
|
OntProperty propA = tBox.createOntProperty("http://test.vivo/A");
|
||||||
|
tBox.add(propA, RDF.type, objectProperty);
|
||||||
|
propA.setLabel("property A", "en-US");
|
||||||
|
|
||||||
|
OntProperty propB = tBox.createOntProperty("http://test.vivo/B");
|
||||||
|
tBox.add(propB, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property B", "en-US");
|
||||||
|
|
||||||
|
OntProperty propC = tBox.createOntProperty("http://test.vivo/C");
|
||||||
|
tBox.add(propC, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property C", "en-US");
|
||||||
|
|
||||||
|
OntProperty propD = tBox.createOntProperty("http://test.vivo/D");
|
||||||
|
tBox.add(propD, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property D", "en-US");
|
||||||
|
|
||||||
|
OntProperty propE = tBox.createOntProperty("http://test.vivo/E");
|
||||||
|
tBox.add(propE, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property E", "en-US");
|
||||||
|
|
||||||
|
OntProperty propF = tBox.createOntProperty("http://test.vivo/F");
|
||||||
|
tBox.add(propF, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property F", "en-US");
|
||||||
|
|
||||||
|
OntProperty propG = tBox.createOntProperty("http://test.vivo/G");
|
||||||
|
tBox.add(propG, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property G", "en-US");
|
||||||
|
|
||||||
|
OntProperty propH = tBox.createOntProperty("http://test.vivo/H");
|
||||||
|
tBox.add(propH, RDF.type, objectProperty);
|
||||||
|
propB.setLabel("property H", "en-US");
|
||||||
|
|
||||||
|
propA.addSubProperty(propB);
|
||||||
|
propA.addSubProperty(propC);
|
||||||
|
propA.addSubProperty(propD);
|
||||||
|
propB.addSubProperty(propE);
|
||||||
|
propC.addSubProperty(propF);
|
||||||
|
propC.addSubProperty(propG);
|
||||||
|
propD.addSubProperty(propH);
|
||||||
|
|
||||||
|
// Add the statement "x E y" 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, propE, ind_y);
|
||||||
|
|
||||||
|
// Remove the statement that B is a subproperty of A from the TBox
|
||||||
|
propA.removeSubProperty(propB);
|
||||||
|
|
||||||
|
// Verify that "x A y" is not in the inference graph
|
||||||
|
Statement xAy = ResourceFactory.createStatement(ind_x, propA, ind_y);
|
||||||
|
Assert.assertFalse(inf.contains(xAy));
|
||||||
|
|
||||||
|
// Verify that "x B y" is in the inference graph
|
||||||
|
Statement xBy = ResourceFactory.createStatement(ind_x, propB, ind_y);
|
||||||
|
Assert.assertTrue(inf.contains(xBy));
|
||||||
|
|
||||||
|
// Add statements "w F z" and "w H z" to the ABox
|
||||||
|
Resource ind_z = aBox.createResource("http://test.vivo/z");
|
||||||
|
Resource ind_w = aBox.createResource("http://test.vivo/w");
|
||||||
|
aBox.add(ind_w, propF, ind_z);
|
||||||
|
aBox.add(ind_w, propH, ind_z);
|
||||||
|
|
||||||
|
// Remove the statement that C is a subproperty of A from the TBox
|
||||||
|
propA.removeSubProperty(propC);
|
||||||
|
|
||||||
|
// Verify that "w A z" is in the inference graph
|
||||||
|
Statement wAz = ResourceFactory.createStatement(ind_w, propA, ind_z);
|
||||||
|
Assert.assertTrue(inf.contains(wAz));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue