Search code examples
rdfdroolssemantic-webowlowl-api

Infer domains/ranges with OWL reasoners


How can I infer OWL domains/ranges of a given data/object property with a reasoner?

For example, I have two classes Rat, Bird and a data property hasName. I want these classes to be the solely domains of hasName:

<Declaration><Class IRI="#Rat"/></Declaration>
<Declaration><Class IRI="#Bird"/></Declaration>
<Declaration><DataProperty IRI="#hasName"/></Declaration>
<DataPropertyDomain>
    <DataProperty IRI="#hasName"/>
    <ObjectUnionOf>
        <Class IRI="#Rat"/>
        <Class IRI="#Bird"/>
    </ObjectUnionOf>
</DataPropertyDomain>

When I used HermiT reasoner to infer domain, I got the owl:Thing class, and not Rat or Bird:

Set<OWLClass> inferedDomains = hermitReasoner
                            .getDataPropertyDomains(hasNameProperty, false)
                            .getFlattened();

I can manually extract the domains by using owl-api to read DataPropertyDomainAxioms of hasName, to get Rat, Bird classes. But then I'll unable to get other inferable classes (e.g. Rat has an equivalent class Mouse).

So I'd like to use inference engines to infer the result, such as:

  • Reasoners: HermiT, FacT++,...
  • SQWRL rule engines: Drools,...

Is there any approach to achieve such results?


Solution

  • The class you've defined as domain is an anonymous one (the union of two named classes), so it cannot be returned by an implementation of OWLReasoner.

    To work around this limitation, you can search for subclasses of the asserted domains of your property - so, using OWLOntology::getDataPropertyDomainAxioms(OWLDataProperty) you will retrieve the union from the root ontology; with OWLReasoner::getSubClasses(OWLClassExpression, false) you will be able to retrieve all nodes that contain subclasses of the disjunction. Each node will contain a set of equivalent classes; in your case, I'd expect to see a node containing {Rat, Mouse} and a node containing {Bird}.

    Edit: added example to answer comments.

    OWLOntology o = ... //root ontology for the reasoner
    OWLReasoner r = ...
    OWLDataProperty p = ...
    for (OWLDataPropertyDomainAxiom ax: o.getDataPropertyDomainAxioms(p)) {
        OWLClassExpression c = ax.getDomain();
        NodeSet<OWLClass> allSubClasses = r.getSubClasses(c, false);
        // allSubClasses contains all named subclasses of the domain
    }
    

    As suggested by @AKSW in the comments, the reason why OWLReasoner does not return anonymous expressions in any of its methods is due to the fact that anonymous expressions in these methods are infinite: for example, given any class, there are infinite anonymous subclasses of this class. The proof is too long to be replicated here but can be easily found in description logics articles and books.

    So, when OWLReasoner was designed, the choice was between making the reasoning incomplete (by only returning a more or less arbitrary set of anonymous expressions), undecidable (by returning an infinite set) or restrict it to named classes only. The latter was judged the best solution.