package org.semanticweb.HermiT.reasoner;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.semanticweb.HermiT.AbstractOntologyTest;
import org.semanticweb.HermiT.Configuration;
import org.semanticweb.HermiT.EntailmentChecker;
import org.semanticweb.HermiT.Prefixes;
import org.semanticweb.HermiT.Reasoner;
import org.semanticweb.HermiT.Reasoner.ReasonerFactory;
import org.semanticweb.HermiT.model.Constant;
import org.semanticweb.HermiT.model.DescriptionGraph;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLLogicalAxiom;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.reasoner.Node;
import org.semanticweb.owlapi.reasoner.NodeSet;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
public abstract class AbstractReasonerTest extends AbstractOntologyTest {
protected Reasoner m_reasoner;
public AbstractReasonerTest(String name) {
super(name);
}
protected void tearDown() {
super.tearDown();
m_reasoner=null;
m_dataFactory=null;
m_ontology=null;
m_ontologyManager=null;
}
protected void loadReasonerFromResource(String resourceName) throws Exception {
IRI physicalIRI=IRI.create(getClass().getResource(resourceName).toURI());
m_ontology=m_ontologyManager.loadOntologyFromOntologyDocument(physicalIRI);
createReasoner();
}
protected void loadReasonerWithAxioms(String axioms) throws Exception {
loadOntologyWithAxioms(axioms);
createReasoner();
}
protected void createReasoner() {
createReasoner(getConfiguration(),null);
}
protected void createReasoner(Configuration configuration,Set<DescriptionGraph> descriptionGraphs) {
if (descriptionGraphs==null)
descriptionGraphs=Collections.emptySet();
m_reasoner=new Reasoner(configuration,m_ontology,descriptionGraphs);
}
protected void createOWLReasoner(Configuration c) {
OWLReasonerFactory factory=new ReasonerFactory();
m_reasoner=(Reasoner)factory.createReasoner(m_ontology,c);
}
protected void createOWLReasoner() {
createOWLReasoner(getConfiguration());
}
/**
* Returns the class and the property hierarchies as text.
*/
protected String getHierarchiesAsText() {
CharArrayWriter buffer=new CharArrayWriter();
PrintWriter output=new PrintWriter(buffer);
m_reasoner.printHierarchies(output,true,true,true);
output.flush();
return buffer.toString();
}
/**
* Loads the ontology from ontologyResource and the string in controlResource and compares the computed taxonomy for the ontology with the one in the controlResource by comparing the sorted ancestor list.
*
* @param ontologyResource
* the ontology
* @param controlResource
* the expected taxonomy (sorted ancestor list)
*/
protected void assertHierarchies(String controlResource) throws Exception {
String taxonomy=getHierarchiesAsText();
String controlString=getResourceText(controlResource);
assertEquals(controlString,taxonomy);
}
/**
* Tests whether the loaded ontology is consistent or not and asserts that this coincides with the given parameter satisfiable.
*
* @param satisfiable
* if the currently loaded ontology is expected to be satisfiable
*/
protected void assertABoxSatisfiable(boolean satisfiable) {
assertEquals(satisfiable,m_reasoner.isConsistent());
}
/**
* Tests whether the atomic concept subAtomicConcept is subsumed by the atomic concept superAtomicConcept and asserts that this coincides with the expected result.
*
* @param subAtomicConcept
* a string that represents an atomic concept. If no prefix is given, NS is used as prefix
* @param superAtomicConcept
* a string that represents an atomic concept. If no prefix is given, NS is used as prefix
* @param expectedResult
*/
protected void assertSubsumedBy(String subAtomicConcept,String superAtomicConcept,boolean expectedResult) {
if (!subAtomicConcept.contains("#"))
subAtomicConcept=NS+subAtomicConcept;
if (!superAtomicConcept.contains("#"))
superAtomicConcept=NS+superAtomicConcept;
OWLClass subClass=m_dataFactory.getOWLClass(IRI.create(subAtomicConcept));
OWLClass superClass=m_dataFactory.getOWLClass(IRI.create(superAtomicConcept));
boolean result=m_reasoner.isEntailed(m_dataFactory.getOWLSubClassOfAxiom(subClass, superClass));
assertEquals(expectedResult,result);
}
/**
* Tests whether the possibly complex concept subConcept is subsumed by the possibly complex concept superConcept and asserts that this coincides with the expected result.
*/
protected void assertSubsumedBy(OWLClassExpression subClass,OWLClassExpression superClass,boolean expectedResult) {
boolean result=m_reasoner.isEntailed(m_dataFactory.getOWLSubClassOfAxiom(subClass, superClass));
assertEquals(expectedResult,result);
}
/**
* Tests whether the atomic concept atomicConcept is satisfiable and asserts that this coincides with the expected result (satisfiable).
*/
protected void assertSatisfiable(String atomicConcept,boolean expectedResult) {
if (!atomicConcept.contains("#"))
atomicConcept=NS+atomicConcept;
OWLClass clazz=m_dataFactory.getOWLClass(IRI.create(atomicConcept));
boolean result=m_reasoner.isSatisfiable(clazz);
assertEquals(expectedResult,result);
}
/**
* Tests whether the given possibly complex concept is satisfiable and asserts that this coincides with the expected result (satisfiable).
*/
protected void assertSatisfiable(OWLClassExpression concept,boolean satisfiable) throws Exception {
assertEquals(satisfiable,m_reasoner.isSatisfiable(concept));
}
/**
* Tests whether the given individual is an instance of the given concept and asserts that this coincides with the expected result.
*/
protected void assertInstanceOf(OWLClassExpression concept,OWLNamedIndividual individual,boolean expectedResult) {
boolean result=m_reasoner.hasType(individual,concept,false);
assertEquals(expectedResult,result);
}
/**
* Tests whether the given concept has the specified individuals.
*/
protected void assertInstancesOf(OWLClassExpression concept,boolean direct,String... expectedIndividuals) {
NodeSet<OWLNamedIndividual> actual=m_reasoner.getInstances(concept,direct);
Set<String> actualIndividualIRIs=new HashSet<String>();
for (OWLIndividual individual : actual.getFlattened()) {
if (!individual.isAnonymous())
actualIndividualIRIs.add(individual.asOWLNamedIndividual().getIRI().toString());
}
String[] expectedModified=expectedIndividuals.clone();
assertContainsAll(actualIndividualIRIs,expectedModified);
}
/**
* Checks the direct superproperties of some object property.
*/
@SuppressWarnings("all")
protected void assertDirectSuperObjectProperties(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSuperObjectProperties(ope,true));
assertContainsAll(actual,control);
}
/**
* Checks the direct superproperties of some object property.
*/
@SuppressWarnings("all")
protected void assertDirectSuperObjectPropertiesOfInverse(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectProperty op=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectInverseOf(op);
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSuperObjectProperties(ope,true));
assertContainsAll(actual,control);
}
/**
* Checks the superproperties of some object property.
*/
@SuppressWarnings("all")
protected void assertSuperObjectProperties(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSuperObjectProperties(ope,false));
assertContainsAll(actual,control);
}
/**
* Checks the superproperties of some object property.
*/
@SuppressWarnings("all")
protected void assertSuperObjectPropertiesOfInverse(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectProperty op=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectInverseOf(op);
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSuperObjectProperties(ope,false));
assertContainsAll(actual,control);
}
/**
* Checks the direct subproperties of some object property.
*/
@SuppressWarnings("all")
protected void assertDirectSubObjectProperties(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSubObjectProperties(ope,true));
assertContainsAll(actual,control);
}
/**
* Checks the direct subproperties of the inverse of the given object property.
*/
@SuppressWarnings("all")
protected void assertDirectSubObjectPropertiesOfInverse(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectProperty op=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectInverseOf(op);
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSubObjectProperties(ope,true));
assertContainsAll(actual,control);
}
/**
* Checks the subproperties of some object property.
*/
@SuppressWarnings("all")
protected void assertSubObjectProperties(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSubObjectProperties(ope,false));
assertContainsAll(actual,control);
}
/**
* Checks the subproperties of the inverse of the given object property.
*/
@SuppressWarnings("all")
protected void assertSubObjectPropertiesOfInverse(String objectProperty,Set<String>... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectProperty op=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectInverseOf(op);
Set<Set<String>> actual=nodeSetOfOPEsToStrings(m_reasoner.getSubObjectProperties(ope,false));
assertContainsAll(actual,control);
}
/**
* Checks the equivalents of some object property.
*/
protected void assertEquivalentObjectProperties(String objectProperty,String... control) {
if (!objectProperty.contains("#"))
objectProperty=NS+objectProperty;
OWLObjectPropertyExpression ope=m_dataFactory.getOWLObjectProperty(IRI.create(objectProperty));
Set<String> actual=nodeOfOPEs(m_reasoner.getEquivalentObjectProperties(ope));
assertContainsAll(actual,control);
}
/**
* Checks the superproperties of some data property.
*/
@SuppressWarnings("all")
protected void assertSuperDataProperties(String dataProperty,Set<String>... control) {
if (!dataProperty.contains("#"))
dataProperty=NS+dataProperty;
OWLDataProperty dp=m_dataFactory.getOWLDataProperty(IRI.create(dataProperty));
Set<Set<String>> actual=nodeSetOfDPsToStrings(m_reasoner.getSuperDataProperties(dp,false));
assertContainsAll(actual,control);
}
/**
* Checks the direct superproperties of some data property.
*/
@SuppressWarnings("all")
protected void assertDirectSuperDataProperties(String dataProperty,Set<String>... control) {
if (!dataProperty.contains("#"))
dataProperty=NS+dataProperty;
OWLDataProperty dp=m_dataFactory.getOWLDataProperty(IRI.create(dataProperty));
Set<Set<String>> actual=nodeSetOfDPsToStrings(m_reasoner.getSuperDataProperties(dp,true));
assertContainsAll(actual,control);
}
/**
* Checks the subproperties of some data property.
*/
@SuppressWarnings("all")
protected void assertSubDataProperties(String dataProperty,Set<String>... control) {
if (!dataProperty.contains("#"))
dataProperty=NS+dataProperty;
OWLDataProperty dp=m_dataFactory.getOWLDataProperty(IRI.create(dataProperty));
Set<Set<String>> actual=nodeSetOfDPsToStrings(m_reasoner.getSubDataProperties(dp,false));
assertContainsAll(actual,control);
}
/**
* Checks the direct subproperties of some data property.
*/
@SuppressWarnings("all")
protected void assertDirectSubDataProperties(String dataProperty,Set<String>... control) {
if (!dataProperty.contains("#"))
dataProperty=NS+dataProperty;
OWLDataProperty dp=m_dataFactory.getOWLDataProperty(IRI.create(dataProperty));
Set<Set<String>> actual=nodeSetOfDPsToStrings(m_reasoner.getSubDataProperties(dp,true));
assertContainsAll(actual,control);
}
/**
* Checks the equivalents of some data property.
*/
protected void assertEquivalentDataProperties(String dataProperty,String... control) {
if (!dataProperty.contains("#"))
dataProperty=NS+dataProperty;
OWLDataProperty dp=m_dataFactory.getOWLDataProperty(IRI.create(dataProperty));
Set<String> actual=nodeOfDPEs(m_reasoner.getEquivalentDataProperties(dp));
assertContainsAll(actual,control);
}
protected void assertEntails(OWLAxiom axiom,boolean expectedResult) {
assertTrue(new EntailmentChecker(m_reasoner,m_dataFactory).entails(axiom)==expectedResult);
}
protected void assertEntails(Set<OWLLogicalAxiom> axioms,boolean expectedResult) {
assertTrue(new EntailmentChecker(m_reasoner,m_dataFactory).entails(axioms)==expectedResult);
}
protected static Set<Set<String>> nodeSetOfOPEsToStrings(NodeSet<OWLObjectPropertyExpression> nodeSet) {
Set<Set<String>> result=new HashSet<Set<String>>();
for (Node<OWLObjectPropertyExpression> node : nodeSet.getNodes()) {
result.add(nodeOfOPEs(node));
}
return result;
}
protected static Set<String> nodeOfOPEs(Node<OWLObjectPropertyExpression> node) {
Set<String> translatedSet=new HashSet<String>();
for (OWLObjectPropertyExpression ope : node.getEntities()) {
if (ope.getSimplified().isAnonymous()) {
// inverse
translatedSet.add("InverseOf("+ope.getNamedProperty().getIRI().toString()+")");
}
else
translatedSet.add(ope.asOWLObjectProperty().getIRI().toString());
}
return translatedSet;
}
protected static Set<Set<String>> nodeSetOfDPsToStrings(NodeSet<OWLDataProperty> nodeSet) {
Set<Set<String>> result=new HashSet<Set<String>>();
for (Node<OWLDataProperty> set : nodeSet) {
Set<String> translatedSet=nodeOfDPEs(set);
result.add(translatedSet);
}
return result;
}
protected static Set<String> nodeOfDPEs(Node<OWLDataProperty> node) {
Set<String> translatedSet=new HashSet<String>();
for (OWLDataProperty dp : node)
translatedSet.add(dp.getIRI().toString());
return translatedSet;
}
/**
* Can be overridden by the subclass to provide a different configuration for the tests.
*/
protected Configuration getConfiguration() {
Configuration c=new Configuration();
c.throwInconsistentOntologyException=false;
return c;
}
protected void assertDRSatisfiable(boolean value,String... parts) throws Exception {
assertDRSatisfiableNEQ(value,1,null,parts);
}
protected void assertDRSatisfiable(boolean value,int cardinality,String... parts) throws Exception {
// The dummy forbidden value is used to turn off the "symmetric clique" optimization in the DatatypeManager.
// This is useful only when value>=1 (otherwise, there is just one individual and the D-conjunction is a clique).
// This is so that we test the basic algorithm.
assertDRSatisfiableNEQ(value,cardinality,new String[] { STR("$internal$") },parts);
}
protected void assertDRSatisfiableUseCliqueOptimization(boolean value,int cardinality,String... parts) throws Exception {
// This version of the method does not introduce any forbidden values, which allows the DatatypeManager
// to use the "symmetric clique" optimization if possible.
assertDRSatisfiableNEQ(value,cardinality,null,parts);
}
protected void assertDRSatisfiableNEQ(boolean value,String[] forbiddenValues,String... parts) throws Exception {
assertDRSatisfiableNEQ(value,1,forbiddenValues,parts);
}
protected void assertDRSatisfiableNEQ(boolean value,int cardinality,String[] forbiddenValues,String... parts) throws Exception {
StringBuffer buffer=new StringBuffer();
buffer.append("Declaration(NamedIndividual(test:a)) Declaration(Class(test:A)) Declaration(DataProperty(test:dp)) SubClassOf( test:A DataMinCardinality( ");
buffer.append(cardinality);
buffer.append(" test:dp rdfs:Literal ) ) ");
for (String part : parts) {
buffer.append("SubClassOf( test:A DataAllValuesFrom( test:dp ");
buffer.append(part);
buffer.append(" ) ) ");
}
buffer.append("ClassAssertion( test:A test:a ) ");
if (forbiddenValues!=null) {
int index=0;
for (String forbiddenValue : forbiddenValues) {
String fvName="test:fv"+index;
buffer.append("DisjointDataProperties( test:dp ");
buffer.append(fvName);
buffer.append(" ) ");
buffer.append("DataPropertyAssertion( ");
buffer.append(fvName);
buffer.append(" test:a ");
buffer.append(forbiddenValue);
buffer.append(" ) ");
index++;
}
}
loadReasonerWithAxioms(buffer.toString());
assertABoxSatisfiable(value);
}
protected void assertRegular(String axioms,boolean b) throws Exception {
boolean regular=true;
try {
loadReasonerWithAxioms(axioms);
}
catch (IllegalArgumentException e) {
if (e.getMessage().contains("The given property hierarchy is not regular"))
regular=false;
else
throw new Exception(e.getMessage());
}
assertEquals(regular,b);
}
protected void assertSimple(String axioms,boolean b) throws Exception {
boolean simple=true;
try {
loadReasonerWithAxioms(axioms);
}
catch (IllegalArgumentException e) {
if (e.getMessage().contains("Non-simple property '"))
simple=false;
else
throw new Exception(e.getMessage());
}
assertEquals(simple,b);
}
protected static Set<String> EQ(String... args) {
Set<String> result=new HashSet<String>();
for (String arg : args) {
if (!arg.contains("#"))
arg=NS+arg;
result.add(arg);
}
return result;
}
protected static Set<String> EQInv(String... args) {
Set<String> result=new HashSet<String>();
for (String arg : args) {
if (!arg.contains("#"))
arg=NS+arg;
result.add("InverseOf("+arg+")");
}
return result;
}
protected static String[] IRIs(String... args) {
for (int index=0;index<args.length;index++)
args[index]=IRI(args[index]);
return args;
}
protected static String IRI(String arg) {
if (!arg.contains("#"))
arg=NS+arg;
return arg;
}
protected static String NOT(String argument) {
return "DataComplementOf( "+argument+" )";
}
protected static String DR(String datatype,String... restrictions) {
StringBuffer buffer=new StringBuffer();
if (restrictions.length==0)
buffer.append(datatype);
else {
buffer.append("DatatypeRestriction( ");
buffer.append(datatype);
for (String restriction : restrictions) {
buffer.append(' ');
buffer.append(restriction);
}
buffer.append(" )");
}
return buffer.toString();
}
protected static String OO(String... elements) {
StringBuffer buffer=new StringBuffer();
buffer.append("DataOneOf(");
for (String element : elements) {
buffer.append(' ');
buffer.append(element);
}
buffer.append(" )");
return buffer.toString();
}
protected static String INT(String value) {
return '\"'+value+"\"^^xsd:integer";
}
protected static Constant INT_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"integer");
}
protected static String DEC(String value) {
return '\"'+value+"\"^^xsd:decimal";
}
protected static Constant DEC_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"decimal");
}
protected static String RAT(String num,String denom) {
return '\"'+num+"/"+denom+"\"^^owl:rational";
}
protected static Constant RAT_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"rational");
}
protected static String FLT(String value) {
return '\"'+value+"\"^^xsd:float";
}
protected static Constant FLT_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"float");
}
protected static String DBL(String value) {
return '\"'+value+"\"^^xsd:double";
}
protected static Constant DBL_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"double");
}
protected static String DATE(String value) {
return '\"'+value+"\"^^xsd:dateTime";
}
protected static Constant DATE_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"dateTime");
}
protected static String DATES(String value) {
return '\"'+value+"\"^^xsd:dateTimeStamp";
}
protected static Constant DATES_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"dateTimeStamp");
}
protected static String XMLL(String value) {
return '\"'+value+"\"^^rdf:XMLLiteral";
}
protected static Constant XMLL_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("rdf:")+"XMLLiteral");
}
protected static String HEXB(String value) {
return '\"'+value+"\"^^xsd:hexBinary";
}
protected static Constant HEXB_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"hexBinary");
}
protected static String B64B(String value) {
return '\"'+value+"\"^^xsd:base64Binary";
}
protected static Constant B64B_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"has64Binary");
}
protected static String STR(String value) {
return '\"'+value+"\"^^xsd:string";
}
protected static Constant STR_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"string");
}
protected static String STR(String value,String languageTag) {
return '\"'+value+"\"@"+languageTag;
}
protected static Constant STR_C(String value,String languageTag) {
return Constant.create(value+"\"@"+languageTag,Prefixes.s_semanticWebPrefixes.get("xsd:")+"string");
}
protected static String AURI(String value) {
return '\"'+value+"\"^^xsd:anyURI";
}
protected static Constant AURI_C(String value) {
return Constant.create(value,Prefixes.s_semanticWebPrefixes.get("xsd:")+"anyURI");
}
protected static String[] S(String... args) {
return args;
}
}