diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index b83ae68e4..b0cb19d29 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -63,8 +63,11 @@ public class SimpleReasoner extends StatementListener { private OntModel fullModel; // contains at least the // asserted and inferred ABox - private static final String mostSpecificTypePropertyURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#mostSpecificType"; - private static final AnnotationProperty mostSpecificType = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createAnnotationProperty(mostSpecificTypePropertyURI); + private static final String mostSpecificTypePropertyURI = + "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#mostSpecificType"; + private static final AnnotationProperty mostSpecificType = + (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)) + .createAnnotationProperty(mostSpecificTypePropertyURI); // DeltaComputer private CumulativeDeltaModeler aBoxDeltaModeler1 = null; @@ -77,13 +80,18 @@ public class SimpleReasoner extends StatementListener { private boolean stopRequested = false; private List pluginList = new CopyOnWriteArrayList(); + + private boolean doSameAs = true; /** * @param tboxModel - input. This model contains both asserted and inferred TBox axioms * @param aboxModel - input. This model contains asserted ABox statements - * @param inferenceModel - output. This is the model in which inferred (materialized) ABox statements are maintained (added or retracted). - * @param inferenceRebuildModel - output. This the model is temporarily used when the whole ABox inference model is rebuilt - * @param inferenceScratchpadModel - output. This the model is temporarily used when the whole ABox inference model is rebuilt + * @param inferenceModel - output. This is the model in which inferred (materialized) + * ABox statements are maintained (added or retracted). + * @param inferenceRebuildModel - output. This the model is temporarily used when the + * whole ABox inference model is rebuilt + * @param inferenceScratchpadModel - output. This the model is temporarily used when + * the whole ABox inference model is rebuilt */ public SimpleReasoner(OntModel tboxModel, RDFService rdfService, @@ -125,7 +133,8 @@ public class SimpleReasoner extends StatementListener { * * @param tboxModel - input. This model contains both asserted and inferred TBox axioms * @param aboxModel - input. This model contains asserted ABox statements - * @param inferenceModel - output. This is the model in which inferred (materialized) ABox statements are maintained (added or retracted). + * @param inferenceModel - output. This is the model in which inferred (materialized) + * ABox statements are maintained (added or retracted). */ public SimpleReasoner(OntModel tboxModel, OntModel aboxModel, Model inferenceModel) { this.tboxModel = tboxModel; @@ -148,7 +157,11 @@ public class SimpleReasoner extends StatementListener { public List getPluginList() { return this.pluginList; } - + + public void setSameAsEnabled( boolean tf){ + this.doSameAs = tf; + } + /* * Performs incremental ABox reasoning based * on the addition of a new statement @@ -158,9 +171,9 @@ public class SimpleReasoner extends StatementListener { public void addedStatement(Statement stmt) { try { if (stmt.getPredicate().equals(RDF.type)) { - addedABoxTypeAssertion(stmt, inferenceModel, new HashSet()); + addedABoxTypeAssertion(stmt, inferenceModel, new HashSet()); setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet()); - } else if (stmt.getPredicate().equals(OWL.sameAs)) { + } else if ( doSameAs && stmt.getPredicate().equals(OWL.sameAs)) { addedABoxSameAsAssertion(stmt, inferenceModel); } else { addedABoxAssertion(stmt, inferenceModel); @@ -168,8 +181,7 @@ public class SimpleReasoner extends StatementListener { doPlugins(ModelUpdate.Operation.ADD,stmt); - } catch (Exception e) { - // don't stop the edit if there's an exception + } catch (Exception e) { // don't stop the edit if there's an exception log.error("Exception while computing inferences: " + e.getMessage()); } } @@ -180,20 +192,16 @@ public class SimpleReasoner extends StatementListener { * from the ABox. */ @Override - public void removedStatement(Statement stmt) { - + public void removedStatement(Statement stmt) { try { - handleRemovedStatement(stmt); - - } catch (Exception e) { - // don't stop the edit if there's an exception + handleRemovedStatement(stmt); + } catch (Exception e) { // don't stop the edit if there's an exception log.error("Exception while retracting inferences: ", e); } } /* - * Synchronized part of removedStatement. Interacts - * with DeltaComputer. + * Synchronized part of removedStatement. Interacts with DeltaComputer. */ protected synchronized void handleRemovedStatement(Statement stmt) { if (batchMode == 1) { @@ -204,7 +212,7 @@ public class SimpleReasoner extends StatementListener { if (stmt.getPredicate().equals(RDF.type)) { removedABoxTypeAssertion(stmt, inferenceModel); setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet()); - } else if (stmt.getPredicate().equals(OWL.sameAs)) { + } else if ( doSameAs && stmt.getPredicate().equals(OWL.sameAs)) { removedABoxSameAsAssertion(stmt, inferenceModel); } else { removedABoxAssertion(stmt, inferenceModel); @@ -212,16 +220,21 @@ public class SimpleReasoner extends StatementListener { doPlugins(ModelUpdate.Operation.RETRACT,stmt); } } - - /* + + /** * Performs incremental ABox reasoning based * on changes to the class hierarchy. - * - * Handles rdfs:subclassOf, owl:equivalentClass, and owl:inverseOf - */ - public void addedTBoxStatement(Statement stmt) { - try { - if (!(stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) || stmt.getPredicate().equals(OWL.inverseOf))) { + * + * addedTBoxStatement and removedTBoxStatement use the + * same tests so the are merged into this method. + * + * Handles rdfs:subclassOf, owl:equivalentClass, and owl:inverseOf + */ + protected void changedTBoxStatement( Statement stmt , boolean add){ + try { + if (!(stmt.getPredicate().equals(RDFS.subClassOf) + || stmt.getPredicate().equals(OWL.equivalentClass) + || stmt.getPredicate().equals(OWL.inverseOf))) { return; } @@ -230,7 +243,9 @@ public class SimpleReasoner extends StatementListener { return; } - if (stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass)) { + if (stmt.getPredicate().equals(RDFS.subClassOf) + || stmt.getPredicate().equals(OWL.equivalentClass)) { + // ignore anonymous classes if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) { return; @@ -238,22 +253,33 @@ public class SimpleReasoner extends StatementListener { OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI()); if (subject == null) { - log.debug("didn't find subject class in the tbox: " + (stmt.getSubject()).getURI()); + log.debug("didn't find subject class in the tbox: " + + (stmt.getSubject()).getURI()); return; } OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI()); if (object == null) { - log.debug("didn't find object class in the tbox: " + ((Resource)stmt.getObject()).getURI()); + log.debug("didn't find object class in the tbox: " + + ((Resource)stmt.getObject()).getURI()); return; } if (stmt.getPredicate().equals(RDFS.subClassOf)) { + if( add ){ addedSubClass(subject,object,inferenceModel); + }else{ + removedSubClass( subject,object,inferenceModel); + } } else { // equivalent class is the same as subclass in both directions - addedSubClass(subject,object,inferenceModel); - addedSubClass(object,subject,inferenceModel); + if(add){ + addedSubClass(subject,object,inferenceModel); + addedSubClass(object,subject,inferenceModel); + }else{ + removedSubClass( subject,object,inferenceModel); + removedSubClass(object,subject,inferenceModel); + } } } else { if ( stmt.getObject().asResource().getURI() == null ) { @@ -268,99 +294,50 @@ public class SimpleReasoner extends StatementListener { OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI()); if (prop1 == null) { - 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()); return; } OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI()); if (prop2 == null) { - 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()); return; } - addedInverseProperty(prop1, prop2, inferenceModel); + if( add ){ + addedInverseProperty(prop1, prop2, inferenceModel); + } else { + removedInverseProperty(prop1,prop2,inferenceModel); + } } - } catch (Exception e) { - // don't stop the edit if there's an exception - log.error("Exception while adding inference(s)",e); - } + } catch (Exception e) { // don't stop the edit if there's an exception + log.error("Exception while " + (add?"adding":"removing") + " inference(s)",e); + } + } + + /** + * Performs incremental ABox reasoning based + * on changes to the class hierarchy. + * + * Handles rdfs:subclassOf, owl:equivalentClass, and owl:inverseOf + */ + public void addedTBoxStatement(Statement stmt) { + changedTBoxStatement( stmt, true); } - /* + /** * Performs incremental ABox reasoning based * on changes to the class hierarchy. * * Handles rdfs:subclassOf, owl:equivalentClass, and owl:inverseOf */ public void removedTBoxStatement(Statement stmt) { - try { - if (!(stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) || stmt.getPredicate().equals(OWL.inverseOf))) { - return; - } - - if (!stmt.getObject().isResource()) { - log.warn("The object of this assertion is not a resource: " + stmtString(stmt)); - return; - } - - if ( stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) ) { - - // ignore anonymous classes - if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) { - return; - } - - OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI()); - if (subject == null) { - log.debug("didn't find subject class in the tbox: " + (stmt.getSubject()).getURI()); - return; - } - - OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI()); - if (object == null) { - log.debug("didn't find object class in the tbox: " + ((Resource)stmt.getObject()).getURI()); - return; - } - - if (stmt.getPredicate().equals(RDFS.subClassOf)) { - removedSubClass(subject,object,inferenceModel); - } else { - // equivalent class is the same as subclass in both directions - removedSubClass(subject,object,inferenceModel); - removedSubClass(object,subject,inferenceModel); - } - } else { - if ( stmt.getObject().asResource().getURI() == null ) { - log.warn("The object of this assertion has a null URI: " + stmtString(stmt)); - return; - } - - if ( stmt.getSubject().getURI() == null ) { - log.warn("The subject of this assertion has a null URI: " + stmtString(stmt)); - return; - } - - OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI()); - if (prop1 == null) { - log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI()); - return; - } - - OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI()); - if (prop2 == null) { - log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI()); - return; - } - - removedInverseProperty(prop1, prop2, inferenceModel); - } - } catch (Exception e) { - // don't stop the edit if there's an exception - log.error("Exception while removing inference(s)",e); - } + changedTBoxStatement(stmt, false); } - /* + /** * Performs incremental reasoning based on a new type assertion * added to the ABox (assertion that an individual is of a certain * type). @@ -368,7 +345,9 @@ public class SimpleReasoner extends StatementListener { * If it is added that B is of type A, then for each superclass of * A assert that B is of that type. */ - protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet unknownTypes) { + protected void addedABoxTypeAssertion(Statement stmt, + Model inferenceModel, + HashSet unknownTypes) { tboxModel.enterCriticalSection(Lock.READ); try { @@ -391,7 +370,9 @@ public class SimpleReasoner extends StatementListener { // of classes not individuals. if (parentClass.isAnon()) continue; - Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), RDF.type, parentClass); + Statement infStmt = + ResourceFactory.createStatement(stmt.getSubject(), + RDF.type, parentClass); addInference(infStmt,inferenceModel,true); } } @@ -399,13 +380,17 @@ public class SimpleReasoner extends StatementListener { if ( !(stmt.getObject().asResource().getNameSpace()).equals(OWL.NS)) { if (!unknownTypes.contains(stmt.getObject().asResource().getURI())) { unknownTypes.add(stmt.getObject().asResource().getURI()); - log.warn("Didn't find the target class (the object of an added rdf:type statement) in the TBox: " + - (stmt.getObject().asResource()).getURI() + ". No class subsumption reasoning will be done based on type assertions of this type."); + log.warn("Didn't find the target class (the object of an added " + + "rdf:type statement) in the TBox: " + + (stmt.getObject().asResource()).getURI() + + ". No class subsumption reasoning will be done " + + "based on type assertions of this type."); } } } } else { - log.debug("The object of this rdf:type assertion has a null URI, no reasoning will be done based on this assertion: " + stmtString(stmt)); + log.debug("The object of this rdf:type assertion has a null URI, no reasoning" + + " will be done based on this assertion: " + stmtString(stmt)); return; } } finally { @@ -422,7 +407,7 @@ public class SimpleReasoner extends StatementListener { } } - /* + /** * 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 * that B is of that type. @@ -432,7 +417,7 @@ public class SimpleReasoner extends StatementListener { removedABoxTypeAssertion(stmt, inferenceModel, null); } - /* + /** * 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 * that B is of that type. @@ -442,7 +427,9 @@ public class SimpleReasoner extends StatementListener { * improvement when this method is called repeatedly for the same subject. * */ - protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel, List remainingTypeURIs) { + protected void removedABoxTypeAssertion(Statement stmt, + Model inferenceModel, + List remainingTypeURIs) { tboxModel.enterCriticalSection(Lock.READ); try { Resource cls = null; @@ -469,22 +456,27 @@ public class SimpleReasoner extends StatementListener { // of classes not individuals. if (parentClass.isAnon()) continue; - List typeURIs = (remainingTypeURIs == null) ? getRemainingAssertedTypeURIs(stmt.getSubject()) : remainingTypeURIs; + List typeURIs = (remainingTypeURIs == null) + ? getRemainingAssertedTypeURIs(stmt.getSubject()) : remainingTypeURIs; if (entailedType(stmt.getSubject(),parentClass, typeURIs)) { continue; // if a type is still entailed without the } - // removed statement, then don't remove it - // from the inferences + // removed statement, then don't remove it + // from the inferences - Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), RDF.type, parentClass); + Statement infStmt = + ResourceFactory.createStatement(stmt.getSubject(), RDF.type, parentClass); removeInference(infStmt,inferenceModel,true,false); } } else { - log.warn("Didn't find target class (the object of the removed rdf:type statement) in the TBox: " - + ((Resource)stmt.getObject()).getURI() + ". No class subsumption reasoning will be performed based on the removal of this assertion."); + log.warn("Didn't find target class (the object of the removed rdf:type" + + "statement) in the TBox: " + + ((Resource)stmt.getObject()).getURI() + ". No class subsumption" + +" reasoning will be performed based on the removal of this assertion."); } } else { - log.warn("The object of this rdf:type assertion has a null URI: " + stmtString(stmt)); + log.warn("The object of this rdf:type assertion has a null URI: " + + stmtString(stmt)); } } catch (Exception e) { log.warn("exception while removing abox type assertions: " + e.getMessage()); @@ -493,7 +485,206 @@ public class SimpleReasoner extends StatementListener { } } - /* + /** + * Performs incremental property-based reasoning. + * + * Retracts inferences based on the owl:inverseOf relationship. + * + * If it is removed that x prop1 y, and prop2 is an inverseOf prop1 + * then remove y prop2 x from the inference graph, unless it is + * otherwise entailed by the assertions graph independently of + * this removed statement. + */ + protected void removedABoxAssertion(Statement stmt, Model inferenceModel) { + + if (!stmt.getObject().isLiteral()) { + List inverseProperties = getInverseProperties(stmt); + Iterator inverseIter = inverseProperties.iterator(); + + while (inverseIter.hasNext()) { + OntProperty inverseProp = inverseIter.next(); + Statement infStmt = ResourceFactory.createStatement( + stmt.getObject().asResource(), inverseProp, stmt.getSubject()); + removeInference(infStmt,inferenceModel); + } + } + + if( doSameAs ) + doSameAsForRemovedABoxAssertion( stmt, inferenceModel ); + + // if a statement has been removed that is otherwise entailed, + // add it to the inference graph. + inferenceModel.enterCriticalSection(Lock.WRITE); + try { + if (entailedStatement(stmt) && !inferenceModel.contains(stmt)) { + inferenceModel.add(stmt); + } + } finally { + inferenceModel.leaveCriticalSection(); + } + } + + + /** + * If it is added that B is a subClass of A, then for each + * individual that is typed as B, either in the ABox or in the + * inferred model, infer that it is of type A. + */ + protected void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { + //log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI()); + OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + unionModel.addSubModel(aboxModel); + unionModel.addSubModel(inferenceModel); + List subjectList = new ArrayList(); + aboxModel.enterCriticalSection(Lock.READ); + try { + StmtIterator iter = unionModel.listStatements((Resource) null, RDF.type, subClass); + while (iter.hasNext()) { + Statement stmt = iter.next(); + subjectList.add(stmt.getSubject()); + } + } finally { + aboxModel.leaveCriticalSection(); + } + + for (Resource subject : subjectList) { + Statement infStmt = ResourceFactory.createStatement(subject, RDF.type, superClass); + addInference(infStmt, inferenceModel, true); + setMostSpecificTypes(infStmt.getSubject(), inferenceModel, new HashSet()); + } + } + + /** + * If removed that B is a subclass of A, then for each individual + * that is of type B, either inferred or in the ABox, remove the + * assertion that it is of type A from the inferred model, + * UNLESS the individual is of some type C that is a subClass + * of A (including A itself) + */ + protected void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { + OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + unionModel.addSubModel(aboxModel); + unionModel.addSubModel(inferenceModel); + List subjectList = new ArrayList(); + aboxModel.enterCriticalSection(Lock.READ); + try { + StmtIterator iter = unionModel.listStatements((Resource) null, RDF.type, subClass); + while (iter.hasNext()) { + Statement stmt = iter.next(); + subjectList.add(stmt.getSubject()); + } + } finally { + aboxModel.leaveCriticalSection(); + } + + for (Resource ind : subjectList) { + if (entailedType(ind,superClass)) { + continue; + } + Statement infStmt = ResourceFactory.createStatement(ind, RDF.type, superClass); + inferenceModel.enterCriticalSection(Lock.WRITE); + try { + if (inferenceModel.contains(infStmt)) { + inferenceModel.remove(infStmt); + } + + } finally { + inferenceModel.leaveCriticalSection(); + } + + setMostSpecificTypes(ind, inferenceModel, new HashSet()); + } + } + + /** + * If it is added that P is an inverse of Q, then: + * 1. For each statement involving predicate P in + * the assertions model add the inverse statement + * to the inference model if that inverse is + * in the assertions model. + * + * 2. Repeat the same for predicate Q. + * + */ + protected void addedInverseProperty(OntProperty prop1, OntProperty prop2, Model inferenceModel) { + + if ( !prop1.isObjectProperty() || !prop2.isObjectProperty() ) { + log.warn("The subject and object of the inverseOf statement are not both object properties. No inferencing will be performed. property 1: " + prop1.getURI() + " property 2:" + prop2.getURI()); + return; + } + + Model inferences = ModelFactory.createDefaultModel(); + inferences.add(generateInverseInferences(prop1, prop2)); + inferences.add(generateInverseInferences(prop2, prop1)); + + if (inferences.isEmpty()) return; + + StmtIterator iter = inferences.listStatements(); + + while (iter.hasNext()) { + Statement infStmt = iter.next(); + addInference(infStmt, inferenceModel, true); + } + } + + /** + * If it is removed that P is an inverse of Q, then: + * 1. For each statement involving predicate P in + * the abox assertions model remove the inverse + * statement from the inference model unless + * that statement is otherwise entailed. + * + * 2. Repeat the same for predicate Q. + */ + protected void removedInverseProperty(OntProperty prop1, OntProperty prop2, Model inferenceModel) { + + if ( !prop1.isObjectProperty() || !prop2.isObjectProperty() ) { + log.warn("The subject and object of the inverseOf statement are not both object properties. No inferencing will be performed. property 1: " + prop1.getURI() + " property 2:" + prop2.getURI()); + return; + } + + Model inferences = ModelFactory.createDefaultModel(); + inferences.add(generateInverseInferences(prop1, prop2)); + inferences.add(generateInverseInferences(prop2, prop1)); + + if (inferences.isEmpty()) return; + + StmtIterator iter = inferences.listStatements(); + + while (iter.hasNext()) { + Statement infStmt = iter.next(); + + if (entailedStatement(infStmt)) { + continue; + } + + removeInference(infStmt,inferenceModel); + } + } + + /** + * Get a list of individuals the same as the given individual + */ + protected List getSameIndividuals(Resource ind, Model inferenceModel) { + ArrayList sameIndividuals = new ArrayList(); + fullModel.enterCriticalSection(Lock.READ); + try { + Iterator iter = fullModel.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) { + sameIndividuals.add(stmt.getObject().asResource()); + } + } + } finally { + fullModel.leaveCriticalSection(); + } + return sameIndividuals; + } + + /** * Materializes inferences based on the owl:sameAs relationship. * * If it is added that x owl:sameAs y, then all asserted and inferred @@ -542,7 +733,7 @@ public class SimpleReasoner extends StatementListener { generateSameAsInferences(object, subject, inferenceModel); } - /* + /** * Materializes inferences based on the owl:sameAs relationship. * * If it is removed that x is sameAs y, then remove y sameAs x from @@ -589,9 +780,30 @@ public class SimpleReasoner extends StatementListener { computeInferencesForIndividual(sIter2.next(), inferenceModel); } } + protected void doSameAsForAddedABoxAssertion(Statement stmt, Model inferenceModel){ + List sameIndividuals = + getSameIndividuals(stmt.getSubject().asResource(), inferenceModel); - /* - * + Iterator sameIter = sameIndividuals.iterator(); + while (sameIter.hasNext()) { + Resource subject = sameIter.next(); + Statement sameStmt = + ResourceFactory.createStatement(subject,stmt.getPredicate(),stmt.getObject()); + addInference(sameStmt,inferenceModel,false); + } + + inferenceModel.enterCriticalSection(Lock.WRITE); + try { + if (inferenceModel.contains(stmt)) { + inferenceModel.remove(stmt); + } + } finally { + inferenceModel.leaveCriticalSection(); + } + } + + + /** * Materializes inferences based on the owl:inverseOf relationship. * and owl:sameAs * @@ -613,223 +825,22 @@ public class SimpleReasoner extends StatementListener { addInference(infStmt,inferenceModel,true); } } - - List sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(), inferenceModel); - Iterator sameIter = sameIndividuals.iterator(); - while (sameIter.hasNext()) { - Resource subject = sameIter.next(); - Statement sameStmt = ResourceFactory.createStatement(subject,stmt.getPredicate(),stmt.getObject()); - addInference(sameStmt,inferenceModel,false); - } - inferenceModel.enterCriticalSection(Lock.WRITE); - try { - if (inferenceModel.contains(stmt)) { - inferenceModel.remove(stmt); - } - } finally { - inferenceModel.leaveCriticalSection(); - } + doSameAsForAddedABoxAssertion( stmt, inferenceModel); } - - /* - * Performs incremental property-based reasoning. - * - * Retracts inferences based on the owl:inverseOf relationship. - * - * If it is removed that x prop1 y, and prop2 is an inverseOf prop1 - * then remove y prop2 x from the inference graph, unless it is - * otherwise entailed by the assertions graph independently of - * this removed statement. - */ - protected void removedABoxAssertion(Statement stmt, Model inferenceModel) { - - if (!stmt.getObject().isLiteral()) { - List inverseProperties = getInverseProperties(stmt); - Iterator inverseIter = inverseProperties.iterator(); - - while (inverseIter.hasNext()) { - OntProperty inverseProp = inverseIter.next(); - Statement infStmt = ResourceFactory.createStatement( - stmt.getObject().asResource(), inverseProp, stmt.getSubject()); - removeInference(infStmt,inferenceModel); - } - } - - List sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(), inferenceModel); + + void doSameAsForRemovedABoxAssertion(Statement stmt, Model inferenceModel){ + List sameIndividuals = + getSameIndividuals(stmt.getSubject().asResource(), inferenceModel); Iterator sameIter = sameIndividuals.iterator(); while (sameIter.hasNext()) { - Statement stmtSame = ResourceFactory.createStatement(sameIter.next(), stmt.getPredicate(), stmt.getObject()); + Statement stmtSame = + ResourceFactory.createStatement(sameIter.next(), + stmt.getPredicate(), + stmt.getObject()); removeInference(stmtSame,inferenceModel,false,true); - } - - // if a statement has been removed that is otherwise entailed, - // add it to the inference graph. - inferenceModel.enterCriticalSection(Lock.WRITE); - try { - if (entailedStatement(stmt) && !inferenceModel.contains(stmt)) { - inferenceModel.add(stmt); - } - } finally { - inferenceModel.leaveCriticalSection(); - } - } - - /* - * If it is added that B is a subClass of A, then for each - * individual that is typed as B, either in the ABox or in the - * inferred model, infer that it is of type A. - */ - protected void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { - //log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI()); - OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - unionModel.addSubModel(aboxModel); - unionModel.addSubModel(inferenceModel); - List subjectList = new ArrayList(); - aboxModel.enterCriticalSection(Lock.READ); - try { - StmtIterator iter = unionModel.listStatements((Resource) null, RDF.type, subClass); - while (iter.hasNext()) { - Statement stmt = iter.next(); - subjectList.add(stmt.getSubject()); - } - } finally { - aboxModel.leaveCriticalSection(); - } - - for (Resource subject : subjectList) { - Statement infStmt = ResourceFactory.createStatement(subject, RDF.type, superClass); - addInference(infStmt, inferenceModel, true); - setMostSpecificTypes(infStmt.getSubject(), inferenceModel, new HashSet()); - } - } - - /* - * If removed that B is a subclass of A, then for each individual - * that is of type B, either inferred or in the ABox, remove the - * assertion that it is of type A from the inferred model, - * UNLESS the individual is of some type C that is a subClass - * of A (including A itself) - */ - protected void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { - OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - unionModel.addSubModel(aboxModel); - unionModel.addSubModel(inferenceModel); - List subjectList = new ArrayList(); - aboxModel.enterCriticalSection(Lock.READ); - try { - StmtIterator iter = unionModel.listStatements((Resource) null, RDF.type, subClass); - while (iter.hasNext()) { - Statement stmt = iter.next(); - subjectList.add(stmt.getSubject()); - } - } finally { - aboxModel.leaveCriticalSection(); - } - - for (Resource ind : subjectList) { - if (entailedType(ind,superClass)) { - continue; - } - Statement infStmt = ResourceFactory.createStatement(ind, RDF.type, superClass); - inferenceModel.enterCriticalSection(Lock.WRITE); - try { - if (inferenceModel.contains(infStmt)) { - inferenceModel.remove(infStmt); - } - - } finally { - inferenceModel.leaveCriticalSection(); - } - - setMostSpecificTypes(ind, inferenceModel, new HashSet()); - } - } - - /* - * If it is added that P is an inverse of Q, then: - * 1. For each statement involving predicate P in - * the assertions model add the inverse statement - * to the inference model if that inverse is - * in the assertions model. - * - * 2. Repeat the same for predicate Q. - * - */ - protected void addedInverseProperty(OntProperty prop1, OntProperty prop2, Model inferenceModel) { - - if ( !prop1.isObjectProperty() || !prop2.isObjectProperty() ) { - log.warn("The subject and object of the inverseOf statement are not both object properties. No inferencing will be performed. property 1: " + prop1.getURI() + " property 2:" + prop2.getURI()); - return; - } - - Model inferences = ModelFactory.createDefaultModel(); - inferences.add(generateInverseInferences(prop1, prop2)); - inferences.add(generateInverseInferences(prop2, prop1)); - - if (inferences.isEmpty()) return; - - StmtIterator iter = inferences.listStatements(); - - while (iter.hasNext()) { - Statement infStmt = iter.next(); - addInference(infStmt, inferenceModel, true); - } - } - - /* - * If it is removed that P is an inverse of Q, then: - * 1. For each statement involving predicate P in - * the abox assertions model remove the inverse - * statement from the inference model unless - * that statement is otherwise entailed. - * - * 2. Repeat the same for predicate Q. - */ - protected void removedInverseProperty(OntProperty prop1, OntProperty prop2, Model inferenceModel) { - - if ( !prop1.isObjectProperty() || !prop2.isObjectProperty() ) { - log.warn("The subject and object of the inverseOf statement are not both object properties. No inferencing will be performed. property 1: " + prop1.getURI() + " property 2:" + prop2.getURI()); - return; - } - - Model inferences = ModelFactory.createDefaultModel(); - inferences.add(generateInverseInferences(prop1, prop2)); - inferences.add(generateInverseInferences(prop2, prop1)); - - if (inferences.isEmpty()) return; - - StmtIterator iter = inferences.listStatements(); - - while (iter.hasNext()) { - Statement infStmt = iter.next(); - - if (entailedStatement(infStmt)) { - continue; - } - - removeInference(infStmt,inferenceModel); - } - } - - /* - * Get a list of individuals the same as the given individual - */ - protected List getSameIndividuals(Resource ind, Model inferenceModel) { - ArrayList sameIndividuals = new ArrayList(); - fullModel.enterCriticalSection(Lock.READ); - try { - Iterator iter = fullModel.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 { - fullModel.leaveCriticalSection(); - } - return sameIndividuals; - } + } + } protected void generateSameAsInferences(Resource ind1, Resource ind2, Model inferenceModel) { @@ -839,11 +850,13 @@ public class SimpleReasoner extends StatementListener { aboxModel.enterCriticalSection(Lock.READ); try { - Iterator iter = unionModel.listStatements(ind1, (Property) null, (RDFNode) null); + Iterator iter = + unionModel.listStatements(ind1, (Property) null, (RDFNode) null); while (iter.hasNext()) { Statement stmt = iter.next(); if (stmt.getObject() == null) continue; - Statement infStmt = ResourceFactory.createStatement(ind2,stmt.getPredicate(),stmt.getObject()); + Statement infStmt = + ResourceFactory.createStatement(ind2,stmt.getPredicate(),stmt.getObject()); addInference(infStmt, inferenceModel,true); } } finally { @@ -853,7 +866,7 @@ public class SimpleReasoner extends StatementListener { return; } - /* + /** * Remove inferences for individual */ protected void removeInferencesForIndividual(Resource ind, Model inferenceModel) { @@ -862,7 +875,8 @@ public class SimpleReasoner extends StatementListener { inferenceModel.enterCriticalSection(Lock.READ); try { - Iterator iter = inferenceModel.listStatements(ind, (Property) null, (RDFNode) null); + Iterator iter = + inferenceModel.listStatements(ind, (Property) null, (RDFNode) null); while (iter.hasNext()) { individualInferences.add(iter.next()); @@ -881,7 +895,7 @@ public class SimpleReasoner extends StatementListener { return; } - /* + /** * compute inferences for individual */ protected void computeInferencesForIndividual(Resource ind, Model inferenceModel) { @@ -902,17 +916,21 @@ public class SimpleReasoner extends StatementListener { return; } - // Returns true if it is entailed by class subsumption that - // subject is of type cls; otherwise returns false. + /** + * Returns true if it is entailed by class subsumption that + * subject is of type cls; otherwise returns false. + */ protected boolean entailedType(Resource subject, Resource cls) { return entailedType(subject, cls, null); } - // Returns true if it is entailed by class subsumption that - // subject is of type cls; otherwise returns false. - // remainingTypeURIs is an optional list of asserted type URIs for the subject - // resource, and may be null. Supplying a precompiled list can yield performance - // improvement when this method is called repeatedly for the same subject. + /** + * Returns true if it is entailed by class subsumption that + * subject is of type cls; otherwise returns false. + * remainingTypeURIs is an optional list of asserted type URIs for the subject + * resource, and may be null. Supplying a precompiled list can yield performance + * improvement when this method is called repeatedly for the same subject. + */ protected boolean entailedType(Resource subject, Resource cls, List remainingTypeURIs) { List subClasses = getSubClasses(cls); @@ -923,7 +941,8 @@ public class SimpleReasoner extends StatementListener { } } - List typeURIs = (remainingTypeURIs == null) ? getRemainingAssertedTypeURIs(subject) : remainingTypeURIs; + List typeURIs = (remainingTypeURIs == null) ? + getRemainingAssertedTypeURIs(subject) : remainingTypeURIs; for (String typeURI : typeURIs) { if (!typeURI.equals(cls.getURI()) && subClassURIs.contains(typeURI)) { @@ -967,10 +986,12 @@ public class SimpleReasoner extends StatementListener { List subClasses = new ArrayList(); tboxModel.enterCriticalSection(Lock.READ); try { - Iterator iter = tboxModel.listStatements((Resource) null, RDFS.subClassOf, cls); + Iterator iter = + tboxModel.listStatements((Resource) null, RDFS.subClassOf, cls); while (iter.hasNext()) { Statement stmt = iter.next(); - if (stmt.getSubject() == null || stmt.getSubject().asResource().getURI() == null) continue; + if (stmt.getSubject() == null + || stmt.getSubject().asResource().getURI() == null) continue; if (!subClasses.contains(stmt.getSubject())) { subClasses.add(stmt.getSubject()); } @@ -1012,7 +1033,8 @@ public class SimpleReasoner extends StatementListener { iter = tboxModel.listStatements((Resource) null, OWL.equivalentClass, cls); while (iter.hasNext()) { Statement stmt = iter.next(); - if (stmt.getSubject() == null || stmt.getSubject().asResource().getURI() == null) continue; + if (stmt.getSubject() == null + || stmt.getSubject().asResource().getURI() == null) continue; if (!superClasses.contains(stmt.getSubject())) { superClasses.add(stmt.getSubject()); } @@ -1023,8 +1045,10 @@ public class SimpleReasoner extends StatementListener { } } - // Returns true if the triple is entailed by inverse property - // reasoning or sameAs reasoning; otherwise returns false. + /** + * Returns true if the triple is entailed by inverse property + * reasoning or sameAs reasoning; otherwise returns false. + */ protected boolean entailedStatement(Statement stmt) { //TODO think about checking class subsumption here (for convenience) @@ -1036,8 +1060,9 @@ public class SimpleReasoner extends StatementListener { try { while (iIter.hasNext()) { Property invProp = iIter.next(); - - Statement invStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), invProp, stmt.getSubject()); + Statement invStmt = + ResourceFactory.createStatement(stmt.getObject().asResource(), + invProp, stmt.getSubject()); if (aboxModel.contains(invStmt)) { return true; } @@ -1048,27 +1073,30 @@ public class SimpleReasoner extends StatementListener { } // individuals sameAs each other - List sameIndividuals = getSameIndividuals(stmt.getSubject().asResource(),inferenceModel); - Iterator rIter = sameIndividuals.iterator(); - if (rIter.hasNext()) { - aboxModel.enterCriticalSection(Lock.READ); - try { - while (rIter.hasNext()) { - Resource subject = rIter.next(); + if( doSameAs ){ + List sameIndividuals = + getSameIndividuals(stmt.getSubject().asResource(),inferenceModel); + Iterator 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(); - } - } + 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 * in the given statement. */ @@ -1091,7 +1119,8 @@ public class SimpleReasoner extends StatementListener { } if (!stmt.getObject().isResource()) { - log.debug("The predicate of this statement is an object property, but the object is not a resource."); + log.debug("The predicate of this statement is an object property, " + +"but the object is not a resource."); return inverses; } @@ -1131,7 +1160,9 @@ public class SimpleReasoner extends StatementListener { while (iter.hasNext()) { Statement stmt = iter.next(); if (!stmt.getObject().isResource()) continue; - Statement infStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), inverseProp, stmt.getSubject()); + Statement infStmt = + ResourceFactory.createStatement(stmt.getObject().asResource(), + inverseProp, stmt.getSubject()); inferences.add(infStmt); } } finally { @@ -1141,7 +1172,7 @@ public class SimpleReasoner extends StatementListener { return inferences; } - /* + /** * Add an inference from the inference model * * Adds the inference to the inference model if it is not already in @@ -1163,17 +1194,22 @@ public class SimpleReasoner extends StatementListener { } if (handleSameAs) { - List sameIndividuals = getSameIndividuals(infStmt.getSubject().asResource(), inferenceModel); + List sameIndividuals = + getSameIndividuals(infStmt.getSubject().asResource(), inferenceModel); Iterator sameIter = sameIndividuals.iterator(); while (sameIter.hasNext()) { Resource subject = sameIter.next(); - Statement sameStmt = ResourceFactory.createStatement(subject,infStmt.getPredicate(),infStmt.getObject()); - if (subject.equals(infStmt.getObject()) && OWL.sameAs.equals(infStmt.getPredicate())) { + Statement sameStmt = + ResourceFactory.createStatement(subject,infStmt.getPredicate(), + infStmt.getObject()); + if (subject.equals(infStmt.getObject()) + && OWL.sameAs.equals(infStmt.getPredicate())) { continue; } - if (!inferenceModel.contains(sameStmt) && !aboxModel.contains(sameStmt)) { + if (!inferenceModel.contains(sameStmt) + && !aboxModel.contains(sameStmt)) { inferenceModel.add(sameStmt); } } @@ -1186,7 +1222,7 @@ public class SimpleReasoner extends StatementListener { } } - /* + /** * Remove an inference from the inference model * * Removes the inference if it is not entailed by the abox model @@ -1203,7 +1239,9 @@ public class SimpleReasoner extends StatementListener { inferenceModel.enterCriticalSection(Lock.WRITE); try { - if ( (!checkEntailment || !entailedStatement(infStmt)) && inferenceModel.contains(infStmt)) { + if ( (!checkEntailment + || !entailedStatement(infStmt)) + && inferenceModel.contains(infStmt)) { inferenceModel.remove(infStmt); } } finally { @@ -1213,12 +1251,17 @@ public class SimpleReasoner extends StatementListener { if (handleSameAs) { inferenceModel.enterCriticalSection(Lock.WRITE); try { - List sameIndividuals = getSameIndividuals(infStmt.getSubject().asResource(), inferenceModel); + List sameIndividuals = + getSameIndividuals(infStmt.getSubject().asResource(), inferenceModel); Iterator sameIter = sameIndividuals.iterator(); while (sameIter.hasNext()) { - Statement infStmtSame = ResourceFactory.createStatement(sameIter.next(), infStmt.getPredicate(), infStmt.getObject()); - if ((!checkEntailment || !entailedStatement(infStmtSame)) && inferenceModel.contains(infStmtSame)) { + Statement infStmtSame = + ResourceFactory.createStatement(sameIter.next(), + infStmt.getPredicate(), infStmt.getObject()); + if ((!checkEntailment + || !entailedStatement(infStmtSame)) + && inferenceModel.contains(infStmtSame)) { inferenceModel.remove(infStmtSame); } } @@ -1228,7 +1271,8 @@ public class SimpleReasoner extends StatementListener { } } - /* + + /** * Find the most specific types (classes) of an individual and * infer them for the individual with the mostSpecificType * annotation. @@ -1481,18 +1525,10 @@ public class SimpleReasoner extends StatementListener { this.stopRequested = true; } - /* - * Utility method for logging - */ - public static String stmtString(Statement statement) { - return " [subject = " + statement.getSubject().getURI() + - "] [property = " + statement.getPredicate().getURI() + - "] [object = " + (statement.getObject().isLiteral() ? ((Literal)statement.getObject()).getLexicalForm() + " (Literal)" - : ((Resource)statement.getObject()).getURI() + " (Resource)") + "]"; - } + // DeltaComputer - /* + /** * Asynchronous reasoning mode (DeltaComputer) is used in the case of batch removals. */ public boolean isABoxReasoningAsynchronous() { @@ -1685,4 +1721,18 @@ public class SimpleReasoner extends StatementListener { log.info("ending DeltaComputer.run. batchMode = " + batchMode); } } + + + + /** + * Utility method for logging + */ + public static String stmtString(Statement statement) { + return " [subject = " + statement.getSubject().getURI() + + "] [property = " + statement.getPredicate().getURI() + + "] [object = " + (statement.getObject().isLiteral() + ? ((Literal)statement.getObject()).getLexicalForm() + " (Literal)" + : ((Resource)statement.getObject()).getURI() + " (Resource)") + "]"; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java new file mode 100644 index 000000000..15c34a98b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java @@ -0,0 +1,54 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.reasoner.plugin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; +import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; + +/** + * Disables sameAs in associated SimpleReasoner. + */ +public abstract class DisableSameAs implements ReasonerPlugin { + + private static final Log log = LogFactory.getLog(DisableSameAs.class); + + private SimpleReasoner simpleReasoner; + + public void setSimpleReasoner(SimpleReasoner simpleReasoner) { + this.simpleReasoner = simpleReasoner; + this.simpleReasoner.setSameAsEnabled( false ); + log.info("owl:sameAs disabled in SimpleReasoner."); + } + + public SimpleReasoner getSimpleReasoner() { + return this.simpleReasoner; + } + + public boolean isInterestedInAddedStatement(Statement stmt) { + return false; + } + + public boolean isInterestedInRemovedStatement(Statement stmt) { + return false; + } + + public void addedABoxStatement(Statement stmt, + Model aboxAssertionsModel, + Model aboxInferencesModel, + OntModel TBoxInferencesModel) { + return; + } + + + public void removedABoxStatement(Statement stmt, + Model aboxAssertionsModel, + Model aboxInferencesModel, + OntModel TBoxInferencesModel) { + return; + } + +} + diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java index de3b0ff0b..e0f81bb74 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java @@ -31,6 +31,16 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { setLoggerLevel(ABoxRecomputer.class, Level.OFF); } + @Test + public void addABoxAssertion1Test(){ + addABoxAssertion1(true); + } + + @Test + public void addABoxAssertion1NoSameAsTest(){ + addABoxAssertion1(false); + } + /* * basic scenarios around adding abox data * @@ -40,8 +50,7 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { * Add a statement c Q d and verify that d Q c * is inferred. */ - @Test - public void addABoxAssertion1() { + public void addABoxAssertion1(boolean sameAs ) { // set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -57,7 +66,11 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // create an abox and register the SimpleReasoner listener with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + + SimpleReasoner sr = new SimpleReasoner(tBox,aBox,inf); + sr.setSameAsEnabled( sameAs ); + + aBox.register( sr ); // add assertions to the abox and verify inferences Resource a = aBox.createResource("http://test.vivo/a"); @@ -68,15 +81,24 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { aBox.add(a,P,b); Assert.assertTrue(inf.contains(b,Q,a)); aBox.add(c,Q,d); - Assert.assertTrue(inf.contains(d,P,c)); + Assert.assertTrue(inf.contains(d,P,c)); } - + + @Test + public void addABoxAssertion2Test() { + addABoxAssertion2(true); + } + + @Test + public void addABoxAssertion2NoSameAsTest() { + addABoxAssertion2(false); + } + /* * don't infer statements already in the abox * (never infer because it's in the abox already) */ - @Test - public void addABoxAssertion2() { + public void addABoxAssertion2(boolean sameAs ) { // set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -107,12 +129,20 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { Assert.assertFalse(inf.contains(b,Q,a)); } + @Test + public void addABoxAssertion3Test() { + addABoxAssertion3(true); + } + @Test + public void addABoxAssertion3NoSameAsTest(){ + addABoxAssertion3(false); + } + /* * don't infer statements already in the abox * (remove the inference when it is asserted) */ - @Test - public void addABoxAssertion3() { + public void addABoxAssertion3(boolean sameAs) { // set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -127,7 +157,11 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // create abox and register SimpleReasoner OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( sameAs ); + + aBox.register( sr ); // add statements to the abox and verify inferences Resource a = aBox.createResource("http://test.vivo/a"); @@ -138,13 +172,21 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { aBox.add(b,Q,a); // this should cause the inference to be removed Assert.assertFalse(inf.contains(b,Q,a)); } - + + @Test + public void addABoxAssertion4Test() { + addABoxAssertion4(true); + } + @Test + public void addABoxAssertion4NoSameAsTest() { + addABoxAssertion4(false); + } + /* * adding abox data where the property has an inverse and * and equivalent property. */ - @Test - public void addABoxAssertion4() { + public void addABoxAssertion4( boolean sameAs ) { // set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -163,7 +205,10 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // create an ABox and register the SimpleReasoner with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( sameAs ); + aBox.register( sr ); // add abox statements and verify inferences Resource a = aBox.createResource("http://test.vivo/a"); @@ -179,13 +224,22 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { Assert.assertTrue(inf.contains(d,R,c)); } + @Test + public void removedABoxAssertion1Test(){ + removedABoxAssertion1(true); + } + + @Test + public void removedABoxAssertion1NoSameAsTest(){ + removedABoxAssertion1(false); + } + /* * basic scenarios around removing abox data * don't remove an inference if it's still * entailed by something else in the abox. */ - @Test - public void removedABoxAssertion1() { + public void removedABoxAssertion1(boolean sameAs) { // set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -203,7 +257,9 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // create an ABox and register the SimpleReasoner with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( sameAs ); + aBox.register( sr ); // add statements to the abox and verify inferences Resource a = aBox.createResource("http://test.vivo/a"); @@ -226,12 +282,21 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { Assert.assertTrue(inf.contains(d,P,c)); // still inferred from c T d } + @Test + public void removedABoxAssertion2Test(){ + removedABoxAssertion2(true); + } + + @Test + public void removedABoxAssertion2NoSameAsTest(){ + removedABoxAssertion2(false); + } + /* * removing abox data with equivalent and inverse properties * don't remove inference if it's still inferred. */ - @Test - public void removedABoxAssertion2() { + public void removedABoxAssertion2(boolean sameAs) { // set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -253,7 +318,9 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // create an abox and register the SimpleReasoner listener with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( sameAs ); + aBox.register( sr ); // add abox data and verify inferences Resource a = aBox.createResource("http://test.vivo/a"); @@ -270,11 +337,20 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { Assert.assertTrue(inf.contains(b,Q,a)); } + @Test + public void removedABoxAssertion3Test(){ + removedABoxAssertion3(true); + } + + @Test + public void removedABoxAssertion3NoSameAsTest(){ + removedABoxAssertion3(false); + } + /* * removing abox data with equivalent and inverse properties */ - @Test - public void removedABoxAssertion3() { + public void removedABoxAssertion3(boolean sameAs) { //set up the tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -297,7 +373,9 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { aBox.add(a,P,b); // register the SimpleReasoner - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( sameAs ); + aBox.register( sr ); // add abox statements and verify inferences aBox.add(b,Q,a); @@ -309,11 +387,20 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // when it's removed from the abox } + @Test + public void addTBoxInverseAssertion1Test() throws InterruptedException { + addTBoxInverseAssertion1(true); + } + + @Test + public void addTBoxInverseAssertion1NoSameAsTest() throws InterruptedException { + addTBoxInverseAssertion1(false); + } + /* * adding an inverseOf assertion to the tbox */ - @Test - public void addTBoxInverseAssertion1() throws InterruptedException { + public void addTBoxInverseAssertion1(boolean sameAs) throws InterruptedException { // Set up the TBox. OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -330,7 +417,8 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // set up SimpleReasoner and register it with abox. register // SimpleReasonerTBoxListener with the tbox. - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf ); + simpleReasoner.setSameAsEnabled( sameAs ); aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -361,12 +449,21 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } - + + @Test + public void removeTBoxInverseAssertion1Test() throws InterruptedException { + removeTBoxInverseAssertion1(true); + } + + @Test + public void removeTBoxInverseAssertion1NoSameAsTest() throws InterruptedException { + removeTBoxInverseAssertion1(false); + } + /* * removing an inverseOf assertion from the tbox */ - @Test - public void removeTBoxInverseAssertion1() throws InterruptedException { + public void removeTBoxInverseAssertion1(boolean sameAs) throws InterruptedException { // set up the tbox. OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -385,7 +482,8 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { // set up SimpleReasoner and SimpleReasonerTBox listener, // register them with abox and tbox - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + simpleReasoner.setSameAsEnabled( sameAs ); aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -411,11 +509,20 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } + @Test + public void recomputeABox1Test() throws InterruptedException { + recomputeABox1(true); + } + + @Test + public void recomputeABox1NoSameAsTest() throws InterruptedException { + recomputeABox1(false); + } + /* * Basic scenario around recomputing the ABox inferences */ - @Test - public void recomputeABox1() throws InterruptedException { + public void recomputeABox1(boolean sameAs) throws InterruptedException { // set up tbox OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC); @@ -437,6 +544,7 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + simpleReasoner.setSameAsEnabled( sameAs ); aBox.register(simpleReasoner); // abox statements @@ -487,4 +595,4 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { ontModel.writeAll(System.out,"N3",null); } -} \ No newline at end of file +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java index 493a7d60a..c3b485803 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java @@ -91,6 +91,37 @@ public class SimpleReasonerSameAsTest extends AbstractTestClass { Assert.assertFalse(aBox.contains(b,S,literal1)); Assert.assertFalse(aBox.contains(a,Q,d)); Assert.assertFalse(aBox.contains(a,T,literal2)); + + //run same test with sameAs = false + inf = ModelFactory.createDefaultModel(); + aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + SimpleReasoner sres = new SimpleReasoner(tBox,aBox,inf); + sres.setSameAsEnabled( false ); + aBox.register(sres); + + a = aBox.createResource("http://test.vivo/a"); + b = aBox.createResource("http://test.vivo/b"); + c = aBox.createResource("http://test.vivo/c"); + 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); + + //these are now false since sameAs is off + 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)); + //these still shouldn't be in the abox + 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)); } /* @@ -246,7 +277,93 @@ public class SimpleReasonerSameAsTest extends AbstractTestClass { Assert.assertFalse(inf.contains(f,Q,d)); Assert.assertFalse(inf.contains(f,T,literal2)); } - + + /** + * test of enableSameAs( false ) + */ + @Test + public void disabledSameAs() { + + 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)); + + //run same test with sameAs = false + inf = ModelFactory.createDefaultModel(); + aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + SimpleReasoner sres = new SimpleReasoner(tBox,aBox,inf); + sres.setSameAsEnabled( false ); + aBox.register(sres); + + a = aBox.createResource("http://test.vivo/a"); + b = aBox.createResource("http://test.vivo/b"); + c = aBox.createResource("http://test.vivo/c"); + 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); + + //these are now false since sameAs is off + 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)); + //these still shouldn't be in the abox + 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)); + } + /* * sameAs with datatype properties */ @@ -723,4 +840,4 @@ public class SimpleReasonerSameAsTest extends AbstractTestClass { ontModel.writeAll(System.out,"N3",null); } -} \ No newline at end of file +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTest.java index 0c6427377..7b17d1303 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTest.java @@ -2,10 +2,10 @@ package edu.cornell.mannlib.vitro.webapp.reasoner; - import org.apache.log4j.Level; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.mindswap.pellet.jena.PelletReasonerFactory; @@ -38,12 +38,20 @@ public class SimpleReasonerTest extends AbstractTestClass { setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF); } + @Test + public void addABoxTypeAssertion1Test(){ + addABoxTypeAssertion1(true); + } + + @Test + public void addABoxTypeAssertion1NoSameAsTest(){ + addABoxTypeAssertion1(false); + } /* * Test that when an individual is asserted to be of a type, * its asserted type is not added to the inference graph */ - @Test - public void addABoxTypeAssertion1(){ + public void addABoxTypeAssertion1( boolean sameAsEnabled ){ // Create a Tbox with a simple class hierarchy. B is a subclass of A. // Pellet will compute TBox inferences @@ -62,7 +70,9 @@ public class SimpleReasonerTest extends AbstractTestClass { // create an ABox and register the SimpleReasoner listener with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + simpleReasoner.setSameAsEnabled( sameAsEnabled ); + aBox.register(simpleReasoner); // Individual x Resource ind_x = aBox.createResource("http://test.vivo/x"); @@ -75,13 +85,20 @@ public class SimpleReasonerTest extends AbstractTestClass { Assert.assertFalse(inf.contains(xisb)); } + @Test + public void addABoxTypeAssertion2Test(){ + addABoxTypeAssertion2(true); + } + @Test + public void addABoxTypeAssertion2NoSameAs(){ + addABoxTypeAssertion2(false); + } /* * Test that when an individual is asserted have a type, * that inferences are materialized that it has the types * of its superclasses */ - @Test - public void addABoxTypeAssertion2(){ + public void addABoxTypeAssertion2(boolean enableSameAs){ // Create a Tbox with a simple class hierarchy. D and E are subclasses // of C. B and C are subclasses of A. Pellet will compute TBox inferences. @@ -113,7 +130,9 @@ public class SimpleReasonerTest extends AbstractTestClass { // create an Abox and register the SimpleReasoner listener with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + aBox.register( sr ); // add a statement to the ABox that individual x is of type E. Resource ind_x = aBox.createResource("http://test.vivo/x"); @@ -128,11 +147,18 @@ public class SimpleReasonerTest extends AbstractTestClass { Assert.assertTrue(inf.contains(xisa)); } + @Test + public void addABoxTypeAssertion3Test() throws InterruptedException{ + addABoxTypeAssertion3(true); + } + @Test + public void addABoxTypeAssertion3NoSameAs() throws InterruptedException{ + addABoxTypeAssertion3(false); + } /* * Test inference based on class equivalence */ - @Test - public void addABoxTypeAssertion3() throws InterruptedException { + public void addABoxTypeAssertion3(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox @@ -142,7 +168,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -182,11 +210,18 @@ public class SimpleReasonerTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested();; } + @Test + public void addABoxTypeAssertion4Test()throws InterruptedException{ + addABoxTypeAssertion4(true); + } + @Test + public void addABoxTypeAssertion4NoSameAs()throws InterruptedException{ + addABoxTypeAssertion4(false); + } /* * Test inference based on class equivalence */ - @Test - public void addABoxTypeAssertion4() throws InterruptedException { + public void addABoxTypeAssertion4(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox @@ -196,7 +231,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -228,11 +265,18 @@ public class SimpleReasonerTest extends AbstractTestClass { } + @Test + public void addABoxTypeAssertion5Test()throws InterruptedException{ + addABoxTypeAssertion5(true); + } + @Test + public void addABoxTypeAssertion5NoSameAs()throws InterruptedException{ + addABoxTypeAssertion5(false); + } /* * Test inference based on class equivalence */ - @Test - public void addABoxTypeAssertion5() throws InterruptedException { + public void addABoxTypeAssertion5(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox @@ -242,7 +286,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -279,6 +325,14 @@ public class SimpleReasonerTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } + @Test + public void removeABoxTypeAssertion1Test()throws InterruptedException{ + removeABoxTypeAssertion1(true); + } + @Test + public void removeABoxTypeAssertion1NoSameAs()throws InterruptedException{ + removeABoxTypeAssertion1(false); + } /* * 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 @@ -287,8 +341,7 @@ public class SimpleReasonerTest extends AbstractTestClass { * TBox, ABox and inference graph minus the retracted type statement) * should not be retracted. */ - @Test - public void removeABoxTypeAssertion1(){ + public void removeABoxTypeAssertion1(boolean enableSameAs){ // 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. @@ -312,7 +365,9 @@ public class SimpleReasonerTest extends AbstractTestClass { // create an Abox and register the SimpleReasoner listener with it OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - aBox.register(new SimpleReasoner(tBox, aBox, inf)); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + aBox.register( sr ); // add a statement to the ABox that individual x is of type C. Resource ind_x = aBox.createResource("http://test.vivo/x"); @@ -335,6 +390,14 @@ public class SimpleReasonerTest extends AbstractTestClass { } + @Test + public void addTBoxSubClassAssertion1Test()throws InterruptedException{ + addTBoxSubClassAssertion1(true); + } + @Test + public void addTBoxSubClassAssertion1NoSameAs()throws InterruptedException{ + addTBoxSubClassAssertion1(false); + } /* * Test the addition of a subClassOf statement to * the TBox. The instance data that is the basis @@ -351,8 +414,7 @@ public class SimpleReasonerTest extends AbstractTestClass { * rdfs:subClassOf statement, this test serves * as a test of equivalentClass statements also. */ - @Test - public void addTBoxSubClassAssertion1() throws InterruptedException { + public void addTBoxSubClassAssertion1(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox @@ -362,7 +424,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -408,6 +472,14 @@ public class SimpleReasonerTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } + @Test + public void addTBoxSubClassAssertion2Test()throws InterruptedException{ + addTBoxSubClassAssertion2(true); + } + @Test + public void addTBoxSubClassAssertion2NoSameAs()throws InterruptedException{ + addTBoxSubClassAssertion2(false); + } /* * Test the addition of a subClassOf statement to * the TBox. The instance data that is the basis @@ -424,8 +496,7 @@ public class SimpleReasonerTest extends AbstractTestClass { * as some test of equivalentClass statements also. * */ - @Test - public void addTBoxSubClassAssertion2() throws InterruptedException { + public void addTBoxSubClassAssertion2(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox @@ -435,7 +506,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -480,6 +553,14 @@ public class SimpleReasonerTest extends AbstractTestClass { } + @Test + public void removeTBoxSubClassAssertion1Test()throws InterruptedException{ + removeTBoxSubClassAssertion1(true); + } + @Test + public void removeTBoxSubClassAssertion1NoSameAs()throws InterruptedException{ + removeTBoxSubClassAssertion1(false); + } /* * Test the removal of a subClassOf statement from * the TBox. The instance data that is the basis @@ -487,8 +568,7 @@ public class SimpleReasonerTest extends AbstractTestClass { * inference graph. * */ - @Test - public void removeTBoxSubClassAssertion1() throws InterruptedException { + public void removeTBoxSubClassAssertion1(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox // Pellet will compute TBox inferences @@ -497,7 +577,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -582,6 +664,17 @@ public class SimpleReasonerTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } + @Ignore(" needs PelletListener infrastructure which is not in this suite.") + @Test + public void bcdTest()throws InterruptedException{ + bcd(true); + } + + @Ignore(" needs PelletListener infrastructure which is not in this suite.") + @Test + public void bcdNoSameAsTest()throws InterruptedException{ + bcd(false); + } /* * Test the removal of a subClassOf statement from * the TBox. The instance data that is the basis @@ -589,12 +682,12 @@ public class SimpleReasonerTest extends AbstractTestClass { * inference graph. * */ - //@Test - this test would need PelletListener infrastructure, which we're not + // this test would need PelletListener infrastructure, which we're not // testing in this suite. The reason it doesn't work as it is because // the SimpleReasonerTBoxListener is not listening to the tBox inference // model as Pellet is updating it. I could simulate it by adding to the // tBox assertions what we can count on Pellet to infer. - public void bcdTest() throws InterruptedException { + public void bcd(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox // Pellet will compute TBox inferences @@ -604,6 +697,7 @@ public class SimpleReasonerTest extends AbstractTestClass { Model inf = ModelFactory.createDefaultModel(); SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + simpleReasoner.setSameAsEnabled( enableSameAs ); aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -654,12 +748,19 @@ public class SimpleReasonerTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } + @Test + public void mstTest1Test()throws InterruptedException{ + mstTest1(true); + } + @Test + public void mstTest1NoSameAs()throws InterruptedException{ + mstTest1(false); + } /* * Test computation of mostSpecificType annotations in response * to an added/removed ABox type assertion. */ - @Test - public void mstTest1() throws InterruptedException { + public void mstTest1(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox // Pellet will compute TBox inferences @@ -668,7 +769,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -732,12 +835,19 @@ public class SimpleReasonerTest extends AbstractTestClass { } + @Test + public void mstTest2Test()throws InterruptedException{ + mstTest2(true); + } + @Test + public void mstTest2NoSameAs()throws InterruptedException{ + mstTest2(false); + } /* * Test computation of mostSpecificType annotations in response * to an added ABox type assertion. */ - @Test - public void mstTest2() throws InterruptedException { + public void mstTest2(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox // Pellet will compute TBox inferences @@ -746,7 +856,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -785,13 +897,20 @@ public class SimpleReasonerTest extends AbstractTestClass { simpleReasonerTBoxListener.setStopRequested(); } - + + @Test + public void mstTest3Test()throws InterruptedException{ + mstTest3(true); + } + @Test + public void mstTest3NoSameAs()throws InterruptedException{ + mstTest3(false); + } /* * Test computation of mostSpecificType annotations in response * to an added/removed TBox assertions. */ - @Test - public void mstTest3() throws InterruptedException { + public void mstTest3(boolean enableSameAs) throws InterruptedException { // Create TBox, ABox and Inference models and register // the ABox reasoner listeners with the ABox and TBox // Pellet will compute TBox inferences @@ -800,7 +919,9 @@ public class SimpleReasonerTest extends AbstractTestClass { OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); Model inf = ModelFactory.createDefaultModel(); - SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf); + SimpleReasoner sr = new SimpleReasoner(tBox, aBox, inf); + sr.setSameAsEnabled( enableSameAs ); + SimpleReasoner simpleReasoner = sr ; aBox.register(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner); tBox.register(simpleReasonerTBoxListener); @@ -906,4 +1027,4 @@ public class SimpleReasonerTest extends AbstractTestClass { ontModel.writeAll(System.out,"N3",null); } -} \ No newline at end of file +}