incremental development for sameAs reasoning
This commit is contained in:
parent
cd8daf7f55
commit
e6577f5034
3 changed files with 1026 additions and 259 deletions
|
@ -133,6 +133,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
if (stmt.getPredicate().equals(RDF.type)) {
|
if (stmt.getPredicate().equals(RDF.type)) {
|
||||||
addedABoxTypeAssertion(stmt, inferenceModel, new HashSet<String>());
|
addedABoxTypeAssertion(stmt, inferenceModel, new HashSet<String>());
|
||||||
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
|
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
|
||||||
|
} else if (stmt.getPredicate().equals(OWL.sameAs)) {
|
||||||
|
addedABoxSameAsAssertion(stmt, inferenceModel);
|
||||||
} else {
|
} else {
|
||||||
addedABoxAssertion(stmt, inferenceModel);
|
addedABoxAssertion(stmt, inferenceModel);
|
||||||
}
|
}
|
||||||
|
@ -179,6 +181,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
if (stmt.getPredicate().equals(RDF.type)) {
|
if (stmt.getPredicate().equals(RDF.type)) {
|
||||||
removedABoxTypeAssertion(stmt, inferenceModel);
|
removedABoxTypeAssertion(stmt, inferenceModel);
|
||||||
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
|
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
|
||||||
|
} else if (stmt.getPredicate().equals(OWL.sameAs)) {
|
||||||
|
removedABoxSameAsAssertion(stmt, inferenceModel);
|
||||||
} else {
|
} else {
|
||||||
removedABoxAssertion(stmt, inferenceModel);
|
removedABoxAssertion(stmt, inferenceModel);
|
||||||
}
|
}
|
||||||
|
@ -360,11 +364,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet<String> unknownTypes) {
|
protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet<String> unknownTypes) {
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
OntClass cls = null;
|
OntClass cls = null;
|
||||||
|
|
||||||
if ( (stmt.getObject().asResource()).getURI() != null ) {
|
if ( (stmt.getObject().asResource()).getURI() != null ) {
|
||||||
|
|
||||||
cls = tboxModel.getOntClass(stmt.getObject().asResource().getURI());
|
cls = tboxModel.getOntClass(stmt.getObject().asResource().getURI());
|
||||||
|
@ -374,6 +375,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
parents.addAll((cls.listEquivalentClasses()).toList());
|
parents.addAll((cls.listEquivalentClasses()).toList());
|
||||||
Iterator<OntClass> parentIt = parents.iterator();
|
Iterator<OntClass> parentIt = parents.iterator();
|
||||||
|
|
||||||
|
if (parentIt.hasNext()) {
|
||||||
|
List<Resource> sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(), inferenceModel);
|
||||||
while (parentIt.hasNext()) {
|
while (parentIt.hasNext()) {
|
||||||
OntClass parentClass = parentIt.next();
|
OntClass parentClass = parentIt.next();
|
||||||
|
|
||||||
|
@ -389,9 +392,17 @@ public class SimpleReasoner extends StatementListener {
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt)) {
|
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt)) {
|
||||||
//log.debug("Adding this inferred statement: " + infStmt.toString() );
|
|
||||||
inferenceModel.add(infStmt);
|
inferenceModel.add(infStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iterator<Resource> sameIter = sameIndividuals.iterator();
|
||||||
|
while (sameIter.hasNext()) {
|
||||||
|
Resource subject = sameIter.next();
|
||||||
|
if (!inferenceModel.contains(subject,infStmt.getPredicate(),infStmt.getObject()) && !aboxModel.contains(subject,infStmt.getPredicate(),infStmt.getObject())) {
|
||||||
|
inferenceModel.add(subject,infStmt.getPredicate(),infStmt.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
@ -399,6 +410,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( !(stmt.getObject().asResource().getNameSpace()).equals(OWL.NS)) {
|
if ( !(stmt.getObject().asResource().getNameSpace()).equals(OWL.NS)) {
|
||||||
if (!unknownTypes.contains(stmt.getObject().asResource().getURI())) {
|
if (!unknownTypes.contains(stmt.getObject().asResource().getURI())) {
|
||||||
|
@ -418,24 +430,47 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental property-based reasoning.
|
* Materializes inferences based on the owl:sameAs relationship.
|
||||||
*
|
*
|
||||||
* Materializes inferences based on the owl:inverseOf relationship.
|
* If it is added that x owl:sameAs y, then all asserted and inferred
|
||||||
*
|
* statements about x will become inferred about y if they are not already
|
||||||
* If it is added that x prop1 y, and prop2 is an inverseOf prop1
|
* asserted about y, and vice versa.
|
||||||
* then add y prop2 x to the inference graph, if it is not already in
|
|
||||||
* the assertions graph.
|
|
||||||
*/
|
*/
|
||||||
public void addedABoxAssertion(Statement stmt, Model inferenceModel) {
|
public void addedABoxSameAsAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
Resource subject = null;
|
||||||
|
Resource object = null;
|
||||||
|
|
||||||
List<OntProperty> inverseProperties = getInverseProperties(stmt);
|
if (stmt.getSubject().isResource()) {
|
||||||
Iterator<OntProperty> inverseIter = inverseProperties.iterator();
|
subject = stmt.getSubject().asResource();
|
||||||
|
if (tboxModel.containsResource(subject) || subject.isAnon()) {
|
||||||
|
log.debug("the subject of this sameAs statement is either in the tbox or an anonymous node, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("the subject of this sameAs statement is not a resource, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (inverseIter.hasNext()) {
|
if (stmt.getObject().isResource()) {
|
||||||
Property inverseProp = inverseIter.next();
|
object = stmt.getObject().asResource();
|
||||||
|
if (tboxModel.containsResource(object) || object.isAnon()) {
|
||||||
|
log.debug("the object of this sameAs statement is either in the tbox or an anonymous node, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("the object of this sameAs statement is not a resource, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Statement infStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), inverseProp, stmt.getSubject());
|
Model inferences = ModelFactory.createDefaultModel();
|
||||||
|
inferences.add(generateSameAsInferences(subject, object, inferenceModel));
|
||||||
|
inferences.add(generateSameAsInferences(object, subject, inferenceModel));
|
||||||
|
inferences.add(object, OWL.sameAs, subject);
|
||||||
|
|
||||||
|
Iterator<Statement> infIter = inferences.listStatements();
|
||||||
|
|
||||||
|
while (infIter.hasNext()) {
|
||||||
|
Statement infStmt = infIter.next();
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
@ -456,6 +491,214 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a model that contains every assertion about indB as exists for
|
||||||
|
* indA in the Abox assertions or inference model
|
||||||
|
*/
|
||||||
|
public Model generateSameAsInferences(Resource indA, Resource indB, Model inferenceModel) {
|
||||||
|
|
||||||
|
Model inferences = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
unionModel.addSubModel(aboxModel);
|
||||||
|
unionModel.addSubModel(inferenceModel);
|
||||||
|
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
Iterator<Statement> iter = unionModel.listStatements(indA, (Property) null, (RDFNode) null);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
if (stmt.getObject() == null) continue;
|
||||||
|
if (OWL.sameAs.equals(stmt.getPredicate()) && indB.equals(stmt.getObject())) continue;
|
||||||
|
inferences.add(indB, stmt.getPredicate(), stmt.getObject());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return inferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a list of individuals the same as the given individual
|
||||||
|
*/
|
||||||
|
public List<Resource> getSameIndividuals(Resource ind, Model inferenceModel) {
|
||||||
|
|
||||||
|
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
unionModel.addSubModel(aboxModel);
|
||||||
|
unionModel.addSubModel(inferenceModel);
|
||||||
|
|
||||||
|
ArrayList<Resource> sameIndividuals = new ArrayList<Resource>();
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
inferenceModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
Iterator<Statement> iter = unionModel.listStatements(ind, OWL.sameAs, (RDFNode) null);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
if (stmt.getObject() == null || !stmt.getObject().isResource() || stmt.getObject().asResource().getURI() == null) continue;
|
||||||
|
sameIndividuals.add(stmt.getObject().asResource());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sameIndividuals;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Materializes inferences based on the owl:sameAs relationship.
|
||||||
|
*
|
||||||
|
* If it is removed that x is sameAs y, then remove y sameAs x from
|
||||||
|
* the inference graph and then recompute the inferences for x and
|
||||||
|
* y based on their respective assertions. that x owl:sameAs y, then all asserted and inferred
|
||||||
|
*/
|
||||||
|
public void removedABoxSameAsAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
|
Resource subject = null;
|
||||||
|
Resource object = null;
|
||||||
|
|
||||||
|
if (stmt.getSubject().isResource()) {
|
||||||
|
subject = stmt.getSubject().asResource();
|
||||||
|
if (tboxModel.containsResource(subject) || subject.isAnon()) {
|
||||||
|
log.debug("the subject of this removed sameAs statement is either in the tbox or an anonymous node, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("the subject of this removed sameAs statement is not a resource, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt.getObject().isResource()) {
|
||||||
|
object = stmt.getObject().asResource();
|
||||||
|
if (tboxModel.containsResource(object) || object.isAnon()) {
|
||||||
|
log.debug("the object of this removed sameAs statement is either in the tbox or an anonymous node, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("the object of this removed sameAs statement is not a resource, no reasoning will be done: " + stmtString(stmt));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
if (inferenceModel.contains(stmt)) {
|
||||||
|
inferenceModel.remove(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inferenceModel.contains(object, OWL.sameAs, subject) && !aboxModel.contains(object, OWL.sameAs, subject) ) {
|
||||||
|
inferenceModel.add(object, OWL.sameAs, subject);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
recomputeInferencesForIndividual(subject, inferenceModel);
|
||||||
|
recomputeInferencesForIndividual(object, inferenceModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recompute inferences for individual
|
||||||
|
*/
|
||||||
|
public void recomputeInferencesForIndividual(Resource ind, Model inferenceModel) {
|
||||||
|
|
||||||
|
Model inferencesToRemove = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
Iterator<Statement> iter = inferenceModel.listStatements(ind, (Property) null, (RDFNode) null);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
inferencesToRemove.add(iter.next());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
inferenceModel.remove(inferencesToRemove);
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Statement> iter = null;
|
||||||
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
iter = aboxModel.listStatements(ind, (Property) null, (RDFNode) null);
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
addedStatement(iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Performs incremental property-based reasoning.
|
||||||
|
*
|
||||||
|
* Materializes inferences based on the owl:inverseOf relationship.
|
||||||
|
*
|
||||||
|
* If it is added that x prop1 y, and prop2 is an inverseOf prop1
|
||||||
|
* then add y prop2 x to the inference graph, if it is not already in
|
||||||
|
* the assertions graph.
|
||||||
|
*/
|
||||||
|
public void addedABoxAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
List<Resource> sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(), inferenceModel);
|
||||||
|
List<OntProperty> inverseProperties = getInverseProperties(stmt);
|
||||||
|
Iterator<OntProperty> inverseIter = inverseProperties.iterator();
|
||||||
|
|
||||||
|
while (inverseIter.hasNext()) {
|
||||||
|
Property inverseProp = inverseIter.next();
|
||||||
|
|
||||||
|
Statement infStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), inverseProp, stmt.getSubject());
|
||||||
|
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt) ) {
|
||||||
|
inferenceModel.add(infStmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Resource> sameIter = sameIndividuals.iterator();
|
||||||
|
while (sameIter.hasNext()) {
|
||||||
|
Resource subject = sameIter.next();
|
||||||
|
if (!inferenceModel.contains(subject,infStmt.getPredicate(),infStmt.getObject()) && !aboxModel.contains(subject,infStmt.getPredicate(),infStmt.getObject())) {
|
||||||
|
inferenceModel.add(subject,infStmt.getPredicate(),infStmt.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
if (inferenceModel.contains(stmt)) {
|
||||||
|
inferenceModel.remove(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Resource> sameIter = sameIndividuals.iterator();
|
||||||
|
while (sameIter.hasNext()) {
|
||||||
|
Resource subject = sameIter.next();
|
||||||
|
if (!inferenceModel.contains(subject,stmt.getPredicate(),stmt.getObject()) && !aboxModel.contains(subject,stmt.getPredicate(),stmt.getObject())) {
|
||||||
|
inferenceModel.add(subject,stmt.getPredicate(),stmt.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.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
|
||||||
|
@ -484,7 +727,6 @@ public class SimpleReasoner extends StatementListener {
|
||||||
} finally {
|
} finally {
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,6 +785,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
* this removed statement.
|
* this removed statement.
|
||||||
*/
|
*/
|
||||||
public void removedABoxAssertion(Statement stmt, Model inferenceModel) {
|
public void removedABoxAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
|
List<Resource> sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(), inferenceModel);
|
||||||
List<OntProperty> inverseProperties = getInverseProperties(stmt);
|
List<OntProperty> inverseProperties = getInverseProperties(stmt);
|
||||||
Iterator<OntProperty> inverseIter = inverseProperties.iterator();
|
Iterator<OntProperty> inverseIter = inverseProperties.iterator();
|
||||||
|
|
||||||
|
@ -553,19 +797,40 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
if (!entailedInverseStmt(infStmt) && inferenceModel.contains(infStmt)) {
|
if (!entailedStatement(infStmt) && inferenceModel.contains(infStmt)) {
|
||||||
inferenceModel.remove(infStmt);
|
inferenceModel.remove(infStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a statement has been removed that is otherwise entailed,
|
Iterator<Resource> sameIter = sameIndividuals.iterator();
|
||||||
// add it to the inference graph.
|
while (sameIter.hasNext()) {
|
||||||
if (entailedInverseStmt(stmt) && !inferenceModel.contains(stmt)) {
|
Statement infStmtSame = ResourceFactory.createStatement(sameIter.next(), infStmt.getPredicate(), infStmt.getObject());
|
||||||
inferenceModel.add(stmt);
|
if (!entailedStatement(infStmtSame) && inferenceModel.contains(infStmtSame)) {
|
||||||
|
inferenceModel.remove(infStmtSame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
// if a statement has been removed that is otherwise entailed,
|
||||||
|
// add it to the inference graph.
|
||||||
|
if (entailedStatement(stmt) && !inferenceModel.contains(stmt)) {
|
||||||
|
inferenceModel.add(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Resource> sameIter = sameIndividuals.iterator();
|
||||||
|
while (sameIter.hasNext()) {
|
||||||
|
Statement stmtSame = ResourceFactory.createStatement(sameIter.next(), stmt.getPredicate(), stmt.getObject());
|
||||||
|
if (!entailedStatement(stmtSame) && inferenceModel.contains(stmtSame)) {
|
||||||
|
inferenceModel.remove(stmtSame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inferenceModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if it is entailed by class subsumption that
|
// Returns true if it is entailed by class subsumption that
|
||||||
|
@ -600,22 +865,25 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the triple is entailed by inverse property
|
// Returns true if the triple is entailed by inverse property
|
||||||
// reasoning; otherwise returns false.
|
// reasoning or sameAs reasoning; otherwise returns false.
|
||||||
protected boolean entailedInverseStmt(Statement stmt) {
|
protected boolean entailedStatement(Statement stmt) {
|
||||||
ExtendedIterator <? extends OntProperty> iter = null;
|
|
||||||
|
List<OntProperty> inverses = new ArrayList<OntProperty>();
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().asResource().getURI());
|
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().asResource().getURI());
|
||||||
iter = prop.listInverse();
|
inverses.addAll(prop.listInverse().toList());
|
||||||
} finally {
|
} finally {
|
||||||
tboxModel.leaveCriticalSection();
|
tboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iterator<OntProperty> oIter = inverses.iterator();
|
||||||
|
if (oIter.hasNext()) {
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
while (iter.hasNext()) {
|
while (oIter.hasNext()) {
|
||||||
Property invProp = iter.next();
|
Property invProp = oIter.next();
|
||||||
|
|
||||||
// not reasoning on properties in the OWL, RDF or RDFS namespace
|
// not reasoning on properties in the OWL, RDF or RDFS namespace
|
||||||
if ((invProp.getNameSpace()).equals(OWL.NS) ||
|
if ((invProp.getNameSpace()).equals(OWL.NS) ||
|
||||||
|
@ -629,12 +897,31 @@ public class SimpleReasoner extends StatementListener {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} finally {
|
} finally {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Resource> sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(),inferenceModel);
|
||||||
|
Iterator<Resource> rIter = sameIndividuals.iterator();
|
||||||
|
if (rIter.hasNext()) {
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
while (rIter.hasNext()) {
|
||||||
|
Resource subject = rIter.next();
|
||||||
|
|
||||||
|
if (aboxModel.contains(subject, stmt.getPredicate(), stmt.getObject())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a list of properties that are inverses of the property
|
* Returns a list of properties that are inverses of the property
|
||||||
* in the given statement.
|
* in the given statement.
|
||||||
|
@ -800,12 +1087,21 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement infStmt = iter.next();
|
Statement infStmt = iter.next();
|
||||||
|
List<Resource> sameIndividuals = getSameIndividuals(infStmt.getSubject().asResource(), inferenceModel);
|
||||||
|
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt)) {
|
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt)) {
|
||||||
inferenceModel.add(infStmt);
|
inferenceModel.add(infStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iterator<Resource> sameIter = sameIndividuals.iterator();
|
||||||
|
while (sameIter.hasNext()) {
|
||||||
|
Resource subject = sameIter.next();
|
||||||
|
if (!inferenceModel.contains(subject,infStmt.getPredicate(),infStmt.getObject()) && !aboxModel.contains(subject,infStmt.getPredicate(),infStmt.getObject())) {
|
||||||
|
inferenceModel.add(subject,infStmt.getPredicate(),infStmt.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
@ -862,7 +1158,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement infStmt = iter.next();
|
Statement infStmt = iter.next();
|
||||||
|
|
||||||
if (entailedInverseStmt(infStmt)) {
|
if (entailedStatement(infStmt)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,19 +1347,18 @@ public class SimpleReasoner extends StatementListener {
|
||||||
* inference models.
|
* inference models.
|
||||||
*/
|
*/
|
||||||
protected synchronized void recomputeABox() {
|
protected synchronized void recomputeABox() {
|
||||||
HashSet<String> unknownTypes = new HashSet<String>();
|
|
||||||
|
|
||||||
// recompute the inferences
|
// recompute class subsumption inferences
|
||||||
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
|
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
log.info("Computing ABox inferences.");
|
HashSet<String> unknownTypes = new HashSet<String>();
|
||||||
inferenceRebuildModel.removeAll();
|
inferenceRebuildModel.removeAll();
|
||||||
|
|
||||||
|
log.info("Computing class subsumtion ABox inferences.");
|
||||||
int numStmts = 0;
|
int numStmts = 0;
|
||||||
ArrayList<String> individuals = this.getAllIndividualURIs();
|
ArrayList<String> individuals = this.getAllIndividualURIs();
|
||||||
|
|
||||||
for (String individualURI : individuals) {
|
for (String individualURI : individuals) {
|
||||||
|
|
||||||
Resource individual = ResourceFactory.createResource(individualURI);
|
Resource individual = ResourceFactory.createResource(individualURI);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1091,7 +1386,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
numStmts++;
|
numStmts++;
|
||||||
if ((numStmts % 10000) == 0) {
|
if ((numStmts % 10000) == 0) {
|
||||||
log.info("Still computing class-based ABox inferences...");
|
log.info("Still computing class subsumption ABox inferences...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopRequested) {
|
if (stopRequested) {
|
||||||
|
@ -1100,8 +1395,9 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Finished computing class-based ABox inferences");
|
log.info("Finished computing class subsumption ABox inferences");
|
||||||
|
|
||||||
|
log.info("Computing inverse property ABox inferences");
|
||||||
Iterator<Statement> invStatements = null;
|
Iterator<Statement> invStatements = null;
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
|
@ -1110,18 +1406,21 @@ public class SimpleReasoner extends StatementListener {
|
||||||
tboxModel.leaveCriticalSection();
|
tboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
numStmts = 0;
|
||||||
while (invStatements.hasNext()) {
|
while (invStatements.hasNext()) {
|
||||||
Statement stmt = invStatements.next();
|
Statement stmt = invStatements.next();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
|
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
|
||||||
if (prop1 == null) {
|
if (prop1 == null) {
|
||||||
|
//TODO make sure not to print out a million of these for the same property
|
||||||
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
|
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
|
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
|
||||||
if (prop2 == null) {
|
if (prop2 == null) {
|
||||||
|
//TODO make sure not to print out a million of these for the same property
|
||||||
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
|
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1142,7 +1441,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
numStmts++;
|
numStmts++;
|
||||||
if ((numStmts % 10000) == 0) {
|
if ((numStmts % 10000) == 0) {
|
||||||
log.info("Still computing property-based ABox inferences...");
|
log.info("Still computing inverse property ABox inferences...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopRequested) {
|
if (stopRequested) {
|
||||||
|
@ -1150,26 +1449,80 @@ public class SimpleReasoner extends StatementListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("Finished computing inverse property ABox inferences");
|
||||||
|
|
||||||
|
log.info("Computing sameAs ABox inferences");
|
||||||
|
|
||||||
|
Iterator<Statement> sameAsStatements = null;
|
||||||
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
sameAsStatements = aboxModel.listStatements((Resource) null, OWL.sameAs, (Resource) null);
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
numStmts = 0;
|
||||||
|
while (sameAsStatements.hasNext()) {
|
||||||
|
Statement stmt = sameAsStatements.next();
|
||||||
|
|
||||||
|
try {
|
||||||
|
addedABoxSameAsAssertion(stmt, inferenceRebuildModel);
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
|
||||||
|
return;
|
||||||
|
} catch (JenaException je) {
|
||||||
|
if (je.getMessage().equals("Statement models must no be null")) {
|
||||||
|
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.error("Exception while recomputing ABox inference model: ", je);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Exception while recomputing ABox inference model", e);
|
log.error("Exception while recomputing ABox inference model: ", e);
|
||||||
inferenceRebuildModel.removeAll(); // don't do this in the finally, it's needed in the case
|
}
|
||||||
// where there isn't an exception
|
|
||||||
|
numStmts++;
|
||||||
|
if ((numStmts % 10000) == 0) {
|
||||||
|
log.info("Still computing sameAs ABox inferences...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stopRequested) {
|
||||||
|
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("Finished computing sameAs ABox inferences");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (updateInferenceModel(inferenceRebuildModel)) {
|
||||||
|
log.info("a stopRequested signal was received during updateInferenceModel. Halting Processing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Exception while reconciling the current and recomputed ABox inference model for class subsumption inferences. Halting processing." , e);
|
||||||
|
inferenceRebuildModel.removeAll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Exception while recomputing ABox inferences. Halting processing.", e);
|
||||||
|
inferenceRebuildModel.removeAll();
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
inferenceRebuildModel.leaveCriticalSection();
|
inferenceRebuildModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.info("Finished computing property-based ABox inferences");
|
/*
|
||||||
|
* reconcile a set of inferences into the application inference model
|
||||||
|
*/
|
||||||
|
protected synchronized boolean updateInferenceModel(Model inferenceRebuildModel) {
|
||||||
|
|
||||||
// reflect the recomputed inferences into the application
|
|
||||||
// inference model.
|
|
||||||
log.info("Updating ABox inference model");
|
log.info("Updating ABox inference model");
|
||||||
StmtIterator iter = null;
|
StmtIterator iter = null;
|
||||||
|
|
||||||
// Remove everything from the current inference model that is not
|
// Remove everything from the current inference model that is not
|
||||||
// in the recomputed inference model
|
// in the recomputed inference model
|
||||||
int num = 0;
|
int num = 0;
|
||||||
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
|
|
||||||
scratchpadModel.enterCriticalSection(Lock.WRITE);
|
scratchpadModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
inferenceModel.enterCriticalSection(Lock.READ);
|
inferenceModel.enterCriticalSection(Lock.READ);
|
||||||
|
@ -1189,18 +1542,15 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopRequested) {
|
if (stopRequested) {
|
||||||
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Exception while reconciling the current and recomputed ABox inference models", e);
|
|
||||||
return;
|
|
||||||
} finally {
|
} finally {
|
||||||
iter.close();
|
iter.close();
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
iter = scratchpadModel.listStatements();
|
iter = scratchpadModel.listStatements();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement stmt = iter.next();
|
Statement stmt = iter.next();
|
||||||
|
@ -1208,12 +1558,13 @@ public class SimpleReasoner extends StatementListener {
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
inferenceModel.remove(stmt);
|
inferenceModel.remove(stmt);
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Exception while reconciling the current and recomputed ABox inference models", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
iter.close();
|
||||||
|
}
|
||||||
|
|
||||||
// Add everything from the recomputed inference model that is not already
|
// Add everything from the recomputed inference model that is not already
|
||||||
// in the current inference model to the current inference model.
|
// in the current inference model to the current inference model.
|
||||||
|
@ -1239,13 +1590,9 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopRequested) {
|
if (stopRequested) {
|
||||||
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Exception while reconciling the current and recomputed ABox inference models", e);
|
|
||||||
return;
|
|
||||||
} finally {
|
} finally {
|
||||||
iter.close();
|
iter.close();
|
||||||
}
|
}
|
||||||
|
@ -1257,24 +1604,19 @@ public class SimpleReasoner extends StatementListener {
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
inferenceModel.add(stmt);
|
inferenceModel.add(stmt);
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Exception while reconciling the current and recomputed ABox inference models", e);
|
|
||||||
return;
|
|
||||||
} finally {
|
} finally {
|
||||||
inferenceModel.leaveCriticalSection();
|
inferenceModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
iter.close();
|
iter.close();
|
||||||
inferenceRebuildModel.removeAll();
|
|
||||||
scratchpadModel.removeAll();
|
scratchpadModel.removeAll();
|
||||||
inferenceRebuildModel.leaveCriticalSection();
|
|
||||||
scratchpadModel.leaveCriticalSection();
|
scratchpadModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("ABox inference model updated");
|
log.info("ABox inference model updated");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the URIs for all individuals in the system
|
* Get the URIs for all individuals in the system
|
||||||
*/
|
*/
|
||||||
|
@ -1492,7 +1834,6 @@ public class SimpleReasoner extends StatementListener {
|
||||||
log.info("started computing inferences for batch " + qualifier + " updates");
|
log.info("started computing inferences for batch " + qualifier + " updates");
|
||||||
iter = retractions.listStatements();
|
iter = retractions.listStatements();
|
||||||
|
|
||||||
|
|
||||||
while (iter.hasNext() && !stopRequested) {
|
while (iter.hasNext() && !stopRequested) {
|
||||||
Statement stmt = iter.next();
|
Statement stmt = iter.next();
|
||||||
num++;
|
num++;
|
||||||
|
|
|
@ -18,7 +18,7 @@ import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
||||||
|
|
||||||
public class SimpleReasonerPropertyTest extends AbstractTestClass {
|
public class SimpleReasonerInversePropertyTest extends AbstractTestClass {
|
||||||
|
|
||||||
long delay = 50;
|
long delay = 50;
|
||||||
|
|
||||||
|
@ -439,8 +439,6 @@ public class SimpleReasonerPropertyTest extends AbstractTestClass {
|
||||||
|
|
||||||
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||||
aBox.register(simpleReasoner);
|
aBox.register(simpleReasoner);
|
||||||
SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner);
|
|
||||||
tBox.register(simpleReasonerTBoxListener);
|
|
||||||
// Individuals a, b, c and d
|
// Individuals a, b, c and d
|
||||||
Resource a = aBox.createResource("http://test.vivo/a");
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
Resource b = aBox.createResource("http://test.vivo/b");
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
@ -460,8 +458,6 @@ public class SimpleReasonerPropertyTest extends AbstractTestClass {
|
||||||
// Verify inferences
|
// Verify inferences
|
||||||
Assert.assertTrue(inf.contains(b,Q,a));
|
Assert.assertTrue(inf.contains(b,Q,a));
|
||||||
Assert.assertTrue(inf.contains(d,Y,c));
|
Assert.assertTrue(inf.contains(d,Y,c));
|
||||||
|
|
||||||
simpleReasonerTBoxListener.setStopRequested();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================== Utility methods ====================
|
//==================================== Utility methods ====================
|
|
@ -0,0 +1,430 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.reasoner;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mindswap.pellet.jena.PelletReasonerFactory;
|
||||||
|
|
||||||
|
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.Literal;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
|
import com.hp.hpl.jena.vocabulary.RDF;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
||||||
|
|
||||||
|
public class SimpleReasonerSameAsTest extends AbstractTestClass {
|
||||||
|
|
||||||
|
long delay = 50;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void suppressErrorOutput() {
|
||||||
|
suppressSyserr();
|
||||||
|
//Turn off log messages to console
|
||||||
|
setLoggerLevel(SimpleReasoner.class, Level.OFF);
|
||||||
|
setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* basic scenario of adding an abox sameAs assertion
|
||||||
|
//*/
|
||||||
|
@Test
|
||||||
|
public void addSameAsABoxAssertion1() {
|
||||||
|
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
OntProperty P = tBox.createObjectProperty("http://test.vivo/P");
|
||||||
|
P.setLabel("property P", "en-US");
|
||||||
|
|
||||||
|
OntProperty Q = tBox.createObjectProperty("http://test.vivo/Q");
|
||||||
|
Q.setLabel("property Q", "en-US");
|
||||||
|
|
||||||
|
OntProperty S = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
S.setLabel("property S", "en-US");
|
||||||
|
|
||||||
|
OntProperty T = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
T.setLabel("property T", "en-US");
|
||||||
|
|
||||||
|
Literal literal1 = tBox.createLiteral("Literal value 1");
|
||||||
|
Literal literal2 = tBox.createLiteral("Literal value 2");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
||||||
|
|
||||||
|
// Individuals a, b, c and d
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
Resource c = aBox.createResource("http://test.vivo/c");
|
||||||
|
Resource d = aBox.createResource("http://test.vivo/d");
|
||||||
|
|
||||||
|
aBox.add(a,P,c);
|
||||||
|
aBox.add(a,S,literal1);
|
||||||
|
aBox.add(b,Q,d);
|
||||||
|
aBox.add(b,T,literal2);
|
||||||
|
aBox.add(a,OWL.sameAs,b);
|
||||||
|
|
||||||
|
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertTrue(inf.contains(b,P,c));
|
||||||
|
Assert.assertTrue(inf.contains(b,S,literal1));
|
||||||
|
Assert.assertTrue(inf.contains(a,Q,d));
|
||||||
|
Assert.assertTrue(inf.contains(a,T,literal2));
|
||||||
|
|
||||||
|
Assert.assertFalse(aBox.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertFalse(aBox.contains(b,P,c));
|
||||||
|
Assert.assertFalse(aBox.contains(b,S,literal1));
|
||||||
|
Assert.assertFalse(aBox.contains(a,Q,d));
|
||||||
|
Assert.assertFalse(aBox.contains(a,T,literal2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* basic scenario of removing an abox sameAs assertion
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void removeSameAsABoxAssertion1() {
|
||||||
|
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
OntProperty P = tBox.createObjectProperty("http://test.vivo/P");
|
||||||
|
P.setLabel("property P", "en-US");
|
||||||
|
|
||||||
|
OntProperty Q = tBox.createObjectProperty("http://test.vivo/Q");
|
||||||
|
Q.setLabel("property Q", "en-US");
|
||||||
|
|
||||||
|
OntProperty S = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
S.setLabel("property S", "en-US");
|
||||||
|
|
||||||
|
OntProperty T = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
T.setLabel("property T", "en-US");
|
||||||
|
|
||||||
|
Literal literal1 = tBox.createLiteral("Literal value 1");
|
||||||
|
Literal literal2 = tBox.createLiteral("Literal value 2");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
||||||
|
|
||||||
|
// Individuals a, b, c and d
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
Resource c = aBox.createResource("http://test.vivo/c");
|
||||||
|
Resource d = aBox.createResource("http://test.vivo/d");
|
||||||
|
|
||||||
|
aBox.add(a,P,c);
|
||||||
|
aBox.add(a,S,literal1);
|
||||||
|
aBox.add(b,Q,d);
|
||||||
|
aBox.add(b,T,literal2);
|
||||||
|
aBox.add(a,OWL.sameAs,b);
|
||||||
|
|
||||||
|
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertTrue(inf.contains(b,P,c));
|
||||||
|
Assert.assertTrue(inf.contains(b,S,literal1));
|
||||||
|
Assert.assertTrue(inf.contains(a,Q,d));
|
||||||
|
Assert.assertTrue(inf.contains(a,T,literal2));
|
||||||
|
|
||||||
|
aBox.remove(a,OWL.sameAs,b);
|
||||||
|
|
||||||
|
Assert.assertFalse(inf.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertFalse(inf.contains(b,P,c));
|
||||||
|
Assert.assertFalse(inf.contains(b,S,literal1));
|
||||||
|
Assert.assertFalse(inf.contains(a,Q,d));
|
||||||
|
Assert.assertFalse(inf.contains(a,T,literal2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* basic scenario of adding an abox assertion for
|
||||||
|
* an individual is sameAs another.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addABoxAssertion1() {
|
||||||
|
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
OntProperty P = tBox.createObjectProperty("http://test.vivo/P");
|
||||||
|
P.setLabel("property P", "en-US");
|
||||||
|
|
||||||
|
OntProperty Q = tBox.createObjectProperty("http://test.vivo/Q");
|
||||||
|
Q.setLabel("property Q", "en-US");
|
||||||
|
|
||||||
|
OntProperty S = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
S.setLabel("property S", "en-US");
|
||||||
|
|
||||||
|
OntProperty T = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
T.setLabel("property T", "en-US");
|
||||||
|
|
||||||
|
Literal literal1 = tBox.createLiteral("Literal value 1");
|
||||||
|
Literal literal2 = tBox.createLiteral("Literal value 2");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
||||||
|
|
||||||
|
// Individuals a, b, c and d
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
Resource c = aBox.createResource("http://test.vivo/c");
|
||||||
|
Resource d = aBox.createResource("http://test.vivo/d");
|
||||||
|
|
||||||
|
aBox.add(a,OWL.sameAs,b);
|
||||||
|
|
||||||
|
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
|
||||||
|
|
||||||
|
aBox.add(a,P,c);
|
||||||
|
aBox.add(a,S,literal1);
|
||||||
|
aBox.add(b,Q,d);
|
||||||
|
aBox.add(b,T,literal2);
|
||||||
|
|
||||||
|
Assert.assertTrue(inf.contains(b,P,c));
|
||||||
|
Assert.assertTrue(inf.contains(b,S,literal1));
|
||||||
|
Assert.assertTrue(inf.contains(a,Q,d));
|
||||||
|
Assert.assertTrue(inf.contains(a,T,literal2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adding abox assertion for individuals that are sameAs
|
||||||
|
* each other.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addABoxAssertion2() {
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
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.addSubClass(classB);
|
||||||
|
|
||||||
|
OntProperty desc = tBox.createDatatypeProperty("http://test.vivo/desc");
|
||||||
|
desc.setLabel("property desc", "en-US");
|
||||||
|
|
||||||
|
Literal desc1 = tBox.createLiteral("individual 1");
|
||||||
|
Literal desc2 = tBox.createLiteral("individual 2");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
||||||
|
|
||||||
|
// Individuals a and b
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
|
||||||
|
aBox.add(a,desc,desc1);
|
||||||
|
aBox.add(b,desc,desc2);
|
||||||
|
aBox.add(a,OWL.sameAs,b);
|
||||||
|
aBox.add(a, RDF.type, classB);
|
||||||
|
|
||||||
|
Assert.assertTrue(inf.contains(a,desc,desc2));
|
||||||
|
Assert.assertTrue(inf.contains(a,RDF.type,classA));
|
||||||
|
Assert.assertTrue(inf.contains(b,desc,desc1));
|
||||||
|
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertTrue(inf.contains(b,RDF.type,classB));
|
||||||
|
Assert.assertTrue(inf.contains(b,RDF.type,classA));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* basic scenario of removing an abox assertion for
|
||||||
|
* an individual is sameAs another.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void removeABoxAssertion1() {
|
||||||
|
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
OntProperty P = tBox.createObjectProperty("http://test.vivo/P");
|
||||||
|
P.setLabel("property P", "en-US");
|
||||||
|
|
||||||
|
OntProperty Q = tBox.createObjectProperty("http://test.vivo/Q");
|
||||||
|
Q.setLabel("property Q", "en-US");
|
||||||
|
|
||||||
|
OntProperty S = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
S.setLabel("property S", "en-US");
|
||||||
|
|
||||||
|
OntProperty T = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
T.setLabel("property T", "en-US");
|
||||||
|
|
||||||
|
Literal literal1 = tBox.createLiteral("Literal value 1");
|
||||||
|
Literal literal2 = tBox.createLiteral("Literal value 2");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
aBox.register(new SimpleReasoner(tBox, aBox, inf));
|
||||||
|
|
||||||
|
// Individuals a, b, c and d
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
Resource c = aBox.createResource("http://test.vivo/c");
|
||||||
|
Resource d = aBox.createResource("http://test.vivo/d");
|
||||||
|
|
||||||
|
aBox.add(a,P,c);
|
||||||
|
aBox.add(a,S,literal1);
|
||||||
|
aBox.add(b,Q,d);
|
||||||
|
aBox.add(b,T,literal2);
|
||||||
|
aBox.add(a,OWL.sameAs,b);
|
||||||
|
|
||||||
|
aBox.remove(a,P,c);
|
||||||
|
aBox.remove(a,S,literal1);
|
||||||
|
|
||||||
|
Assert.assertFalse(inf.contains(b,P,c));
|
||||||
|
Assert.assertFalse(inf.contains(b,S,literal1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adding an inverseOf assertion for individuals who are sameAs
|
||||||
|
* each other.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void addTBoxInverseAssertion1() throws InterruptedException {
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
|
||||||
|
P.setLabel("property P", "en-US");
|
||||||
|
|
||||||
|
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
|
||||||
|
Q.setLabel("property Q", "en-US");
|
||||||
|
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||||
|
aBox.register(simpleReasoner);
|
||||||
|
SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner);
|
||||||
|
tBox.register(simpleReasonerTBoxListener);
|
||||||
|
|
||||||
|
// Individuals a and b
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
|
||||||
|
// abox statements
|
||||||
|
aBox.add(a,P,b);
|
||||||
|
aBox.add(a, OWL.sameAs,b);
|
||||||
|
|
||||||
|
// Assert P and Q as inverses and wait for SimpleReasoner TBox
|
||||||
|
// thread to end
|
||||||
|
|
||||||
|
Q.addInverseOf(P);
|
||||||
|
|
||||||
|
tBox.rebind();
|
||||||
|
tBox.prepare();
|
||||||
|
|
||||||
|
while (!VitroBackgroundThread.getLivingThreads().isEmpty()) {
|
||||||
|
Thread.sleep(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify inferences
|
||||||
|
Assert.assertTrue(inf.contains(b,Q,a));
|
||||||
|
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertTrue(inf.contains(b,P,b));
|
||||||
|
Assert.assertTrue(inf.contains(a,Q,a));
|
||||||
|
simpleReasonerTBoxListener.setStopRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic scenario around recomputing the ABox inferences
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void recomputeABox1() throws InterruptedException {
|
||||||
|
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
OntProperty P = tBox.createObjectProperty("http://test.vivo/P");
|
||||||
|
P.setLabel("property P", "en-US");
|
||||||
|
|
||||||
|
OntProperty Q = tBox.createObjectProperty("http://test.vivo/Q");
|
||||||
|
Q.setLabel("property Q", "en-US");
|
||||||
|
|
||||||
|
OntProperty S = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
S.setLabel("property S", "en-US");
|
||||||
|
|
||||||
|
OntProperty T = tBox.createDatatypeProperty("http://test.vivo/");
|
||||||
|
T.setLabel("property T", "en-US");
|
||||||
|
|
||||||
|
Literal literal1 = tBox.createLiteral("Literal value 1");
|
||||||
|
Literal literal2 = tBox.createLiteral("Literal value 2");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||||
|
aBox.register(simpleReasoner);
|
||||||
|
|
||||||
|
// Individuals a, b, c and d
|
||||||
|
Resource a = aBox.createResource("http://test.vivo/a");
|
||||||
|
Resource b = aBox.createResource("http://test.vivo/b");
|
||||||
|
Resource c = aBox.createResource("http://test.vivo/c");
|
||||||
|
Resource d = aBox.createResource("http://test.vivo/d");
|
||||||
|
|
||||||
|
aBox.add(a,P,c);
|
||||||
|
aBox.add(a,S,literal1);
|
||||||
|
aBox.add(b,Q,d);
|
||||||
|
aBox.add(b,T,literal2);
|
||||||
|
aBox.add(a,OWL.sameAs,b);
|
||||||
|
|
||||||
|
simpleReasoner.recompute();
|
||||||
|
|
||||||
|
while (simpleReasoner.isRecomputing()) {
|
||||||
|
Thread.sleep(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify inferences
|
||||||
|
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
|
||||||
|
Assert.assertTrue(inf.contains(b,P,c));
|
||||||
|
Assert.assertTrue(inf.contains(b,S,literal1));
|
||||||
|
Assert.assertTrue(inf.contains(a,Q,d));
|
||||||
|
Assert.assertTrue(inf.contains(a,T,literal2));
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================== Utility methods ====================
|
||||||
|
SimpleReasonerTBoxListener getTBoxListener(SimpleReasoner simpleReasoner) {
|
||||||
|
return new SimpleReasonerTBoxListener(simpleReasoner, new Exception().getStackTrace()[1].getMethodName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// To help in debugging the unit test
|
||||||
|
void printModel(Model model, String modelName) {
|
||||||
|
|
||||||
|
System.out.println("\nThe " + modelName + " model has " + model.size() + " statements:");
|
||||||
|
System.out.println("---------------------------------------------------------------------");
|
||||||
|
model.write(System.out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To help in debugging the unit test
|
||||||
|
void printModel(OntModel ontModel, String modelName) {
|
||||||
|
|
||||||
|
System.out.println("\nThe " + modelName + " model has " + ontModel.size() + " statements:");
|
||||||
|
System.out.println("---------------------------------------------------------------------");
|
||||||
|
ontModel.writeAll(System.out,"N3",null);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue