Search code examples
owl-api

OWLAPI slow calculating disjoint axioms


My goal: find the disjoint axioms (asserted and inferred) in an ontology which contains around 5000 axioms.

My code:

for (OWLClass clazz1 : ontology.getClassesInSignature()) {
    for (OWLClass clazz2 : ontology.getClassesInSignature()) {
        OWLAxiom axiom = MyModel.factory.getOWLDisjointClassesAxiom(clazz2, clazz1);
            if(  !(ontology.containsAxiom(axiom)) && reasoner.isEntailed(axiom))
            {
                System.out.println(clazz2.toString() + " disjoint with " + clazz1.toString());
            }

The problem: the execution time is extremely slow, I'd say eternal. Even if I reduce the number of comparison with some if statement, the situation is still the same.

Protege seems to be very quick to compute those inferred axioms and it's based on the same API I am using (OWLAPI). So, am I in the wrong approach?


Solution

  • Profiling the code will very likely reveal that the slow part is

    reasoner.isEntailed(axiom)
    

    This form requires the reasoner to recompute entailments for each class pair, including the pairs where clazz1 and clazz2 are equal (you might want to skip that).

    Alternatively, you can iterate through the classes in signature once and use the reasoner to get all disjoint classes:

    Set<OWLClass> visited=new HashSet<>();
    for (OWLClass c: ontology.getClassesInSignature()) {
      if (visited.add(c)) {
        NodeSet set = reasoner.getDisjointClasses(c);
        for (Node node: set.getNodes()) {
            System.out.println("Disjoint with "+c+": "+node);
            visited.addAll(node.getEntities());
        }
      }
    }
    

    Worst case scenario, this will make one reasoner call per class (because no class is disjoint). Best case scenario, all classes are disjoint or equivalent to another class, so only one reasoner call is required.