package org.semanticweb.HermiT.reasoner; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.semanticweb.HermiT.datalog.ConjunctiveQuery; import org.semanticweb.HermiT.datalog.DatalogEngine; import org.semanticweb.HermiT.datalog.QueryResultCollector; import org.semanticweb.HermiT.model.Atom; import org.semanticweb.HermiT.model.AtomicConcept; import org.semanticweb.HermiT.model.AtomicRole; import org.semanticweb.HermiT.model.DLPredicate; import org.semanticweb.HermiT.model.Individual; import org.semanticweb.HermiT.model.Term; import org.semanticweb.HermiT.model.Variable; public class DatalogEngineTest extends AbstractReasonerTest { public DatalogEngineTest(String name) { super(name); } public void testBasic() throws Exception { loadOntologyWithAxioms( "SubClassOf( ObjectSomeValuesFrom( :R :A ) :A )"+LB+ "SubClassOf( ObjectSomeValuesFrom( :R :B ) :B )"+LB+ "SubClassOf( ObjectIntersectionOf( :A :B ) :C )"+LB+ "ClassAssertion( :A :a )"+LB+ "ObjectPropertyAssertion( :R :b :a )"+LB+ "ObjectPropertyAssertion( :R :c :b )"+LB+ "ObjectPropertyAssertion( :R :d :c )"+LB+ "ClassAssertion( :B :k )"+LB+ "ObjectPropertyAssertion( :R :l :k )"+LB+ "ObjectPropertyAssertion( :R :m :l )"+LB+ "ObjectPropertyAssertion( :R :c :m )"+LB+ "ObjectPropertyAssertion( :R :n :c )" ); createReasoner(); DatalogEngine datalogEngine=new DatalogEngine(m_reasoner.getDLOntology()); QueryChecker queryChecker=new QueryChecker(); new ConjunctiveQuery(datalogEngine, AS( A(CN("A"),V("X")) ), TS( V("X") ) ).evaluate(queryChecker); queryChecker. add(I("a")). add(I("b")). add(I("c")). add(I("d")). add(I("n")). assertEquals(); new ConjunctiveQuery(datalogEngine, AS( A(CN("B"),V("X")) ), TS( V("X") ) ).evaluate(queryChecker); queryChecker. add(I("c")). add(I("d")). add(I("k")). add(I("l")). add(I("m")). add(I("n")). assertEquals(); new ConjunctiveQuery(datalogEngine, AS( A(CN("C"),V("X")) ), TS( V("X") ) ).evaluate(queryChecker); queryChecker. add(I("c")). add(I("d")). add(I("n")). assertEquals(); } public void testEquality() throws Exception { loadOntologyWithAxioms( "FunctionalObjectProperty( :R )"+LB+ "ObjectPropertyAssertion( :R :b :a )"+LB+ "ObjectPropertyAssertion( :R :b :c )"+LB+ "ObjectPropertyAssertion( :R :d :c )"+LB+ "ObjectPropertyAssertion( :R :d :e )"+LB+ "ObjectPropertyAssertion( :R :f :e )"+LB+ "ObjectPropertyAssertion( :R :f :g )" ); createReasoner(); DatalogEngine datalogEngine=new DatalogEngine(m_reasoner.getDLOntology()); datalogEngine.materialize(); assertContainsAll( datalogEngine.getEquivalenceClass(I("a")), TS( I("a"), I("c"), I("e"), I("g") ) ); QueryChecker queryChecker=new QueryChecker(); new ConjunctiveQuery(datalogEngine, AS( A(R("R"),V("X"),V("Y")) ), TS( V("X"),V("Y") ) ).evaluate(queryChecker); queryChecker. add(I("b"),datalogEngine.getRepresentative(I("a"))). add(I("d"),datalogEngine.getRepresentative(I("a"))). add(I("f"),datalogEngine.getRepresentative(I("a"))). assertEquals(); } public void testQueryWithIndividualsAndEquality() throws Exception { loadOntologyWithAxioms( "ObjectPropertyAssertion( :R :c :b )"+LB+ "ObjectPropertyAssertion( :S :c :a )"+LB+ "SameIndividual( :a :b )"+LB+ "ObjectPropertyAssertion( :R :d :e )"+LB+ "ObjectPropertyAssertion( :S :d :f )" ); createReasoner(); DatalogEngine datalogEngine=new DatalogEngine(m_reasoner.getDLOntology()); datalogEngine.materialize(); assertContainsAll( datalogEngine.getEquivalenceClass(I("a")), TS( I("a"), I("b") ) ); QueryChecker queryChecker=new QueryChecker(); new ConjunctiveQuery(datalogEngine, AS( A(R("R"),V("X"),I("a")), A(R("S"),V("X"),I("b")) ), TS( V("X") ) ).evaluate(queryChecker); queryChecker. add(I("c")). assertEquals(); } public void testQueryWithIndividuals() throws Exception { loadOntologyWithAxioms( "DLSafeRule(Body(ClassAtom(:D0 Variable(:X))) Head(ClassAtom(:A Variable(:X))))" + LB+ "DLSafeRule(Body(ClassAtom(:D0 Variable(:X))) Head(ClassAtom(:B Variable(:X))))" + LB+ "DLSafeRule(Body(ClassAtom(:A Variable(:X))ClassAtom(:RD0 Variable(:Z))) Head(ClassAtom(:D0 Variable(:Z))))" + LB+ "DLSafeRule(Body(ClassAtom(:A Variable(:X))ClassAtom(:RD0 Variable(:Z))) Head(ObjectPropertyAtom(:R Variable(:X) Variable(:Z))))" + LB+ "ClassAssertion( owl:Thing :a )"+LB+ "ClassAssertion( :RD0 :rd0 )"+LB+ "ClassAssertion( :A :a )" ); createReasoner(); DatalogEngine datalogEngine=new DatalogEngine(m_reasoner.getDLOntology()); datalogEngine.materialize(); QueryChecker queryChecker=new QueryChecker(); new ConjunctiveQuery(datalogEngine, AS( A(R("R"),V("X"),I("a")) ), TS( V("X") ) ).evaluate(queryChecker); queryChecker.assertEquals(); } protected static class AnswerTuple { protected final Term[] m_terms; protected final int m_hashCode; public AnswerTuple(Term[] terms) { m_terms=terms; int hashCode=0; for (Term term : terms) hashCode=hashCode*7+term.hashCode(); m_hashCode=hashCode; } public int hashCode() { return m_hashCode; } public boolean equals(Object that) { if (this==that) return true; if (!(that instanceof AnswerTuple)) return false; AnswerTuple thatTuple=(AnswerTuple)that; int arity=m_terms.length; if (arity!=thatTuple.m_terms.length) return false; for (int index=0;index<arity;++index) if (!m_terms[index].equals(thatTuple.m_terms[index])) return false; return true; } public String toString() { StringBuffer buffer=new StringBuffer(); buffer.append('['); for (int index=0;index<m_terms.length;++index) { if (index!=0) buffer.append(", "); buffer.append(m_terms[index].toString()); } buffer.append(']'); return buffer.toString(); } } protected static class QueryChecker implements QueryResultCollector { protected final Set<AnswerTuple> m_answerTuples; protected final List<AnswerTuple> m_controlTuples; public QueryChecker() { m_answerTuples=new HashSet<AnswerTuple>(); m_controlTuples=new ArrayList<AnswerTuple>(); } public void processResult(ConjunctiveQuery conjunctiveQuery,Term[] result) { m_answerTuples.add(new AnswerTuple(result.clone())); } public QueryChecker add(Term... terms) { m_controlTuples.add(new AnswerTuple(terms)); return this; } public void assertEquals() { assertContainsAll(m_answerTuples,m_controlTuples.toArray(new AnswerTuple[m_controlTuples.size()])); m_answerTuples.clear(); m_controlTuples.clear(); } } protected static Variable V(String name) { return Variable.create(name); } protected static Individual I(String localName) { return Individual.create(NS+localName); } protected static AtomicConcept CN(String localName) { return AtomicConcept.create(NS+localName); } protected static AtomicRole R(String localName) { return AtomicRole.create(NS+localName); } protected static Atom A(DLPredicate dlPredicate,Term... arguments) { return Atom.create(dlPredicate,arguments); } protected static Term[] TS(Term... terms) { return terms; } protected static Atom[] AS(Atom... atoms) { return atoms; } }