Elk is a blindingly fast EL++ reasoner. Unfortunately, it doesn’t yet support the full EL++ profile – in particular it lacks disjointness axioms. This is unfortunate, as these kinds of axioms are incredibly useful for integrity checking. See the methods section of the Uberon paper for some details on how partwise disjointness axioms were created.
However, Elk does support intersection and equivalence. This means we should be able to perform a translation:
DisjointClasses(x1, x2, …, xn) ⇒
EquivalentClasses(owl:Nothing IntersectionOf(xi xj)) for all i<j<=n
I asked about this on the Elk mail list – see Satisfiability checking and DisjointClasses axioms
The problem is that whilst Elk supports intersection and equivalence, it doesn’t support Nothing. This means that there may be corner cases in which it doesn’t work.
Proper disjointness support may be coming in the next version Elk, but it’s been a few months so I decided to go ahead and implement the above translation in OWLTools (also available in Oort).
If we have an ontology such as foo.owl:
Ontology: <http://example.org/x.owl> Class: :reasoner Class: :animal DisjointWith: :reasoner Class: :elk SubClassOf: :reasoner, :animal
We can translate it using owltools:
owltools foo.owl --translate-disjoints-to-equivalents -o file://`pwd`/foo-x.owl
Remeber, ordering of arguments is significant in owltools -make sure you translate *after* the ontology is loaded.
And then load this into Protege and reason over it using Elk. As expected, “elk” is unsatisfiable:
You can also do the checking directly in owltools:
owltools foo.owl --translate-disjoints-to-equivalents --run-reasoner -r elk -u
The “-u” option will check for unsatisfiable classes and exit with a nonzero code if any are found, allowing this to be used within a CI system like Jenkins (see this previous post).
You can also use this transform within Oort (command line version only):
ontology-release-runner --translate-disjoints-to-equivalents --reasoner elk foo.owl
Remember, there are corner cases where this translation will not work. Nevertheless, this can be useful as part of an “early warning” system, backed up by slower guaranteed checks running in the background with HermiT or some other reasoner.
Perhaps the ontologies I work with have a simpler structure, but so far I have found this strategy to be successful, identifying subtle part-disjointness problems, and not giving any false positives. There don’t appear to be any scalability problems, with Elk being its usual zippy self even when uberon is loaded with ncbitaxon/taxslim and taxon constraints translated into Nothing-axioms (~3000 disjointness axioms).