Search code examples
owlprotegeowl-apidescription-logic

(Un)Inferred Subclass Rules Protégé vs OWL API


I am a bit confused about the subclass handling in Protégé as compared to when using the OWL API directly.

I have built a simple ontology where I logically define what a "Man" or a "Woman" is, namely male or female humans.

The classes are

Human
Woman
Man
Gender
    Female
    Male

Properties:

hasSex (Human -> Gender)

So a Woman is Human and hasGender some Female

My issue: When I display this ontology in Protégé, it automatically organizes Man and Woman as subclasses of Human, WITHOUT using a reasoner. However, when I iterate over all classes in the OWL API and print their subclasses, only the asserted subclasses are found:

Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female>
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Woman>
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male>
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human>
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender>
    <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female>
    <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male>
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Man>

I need to use a reasoner to get the expected result, that Protégé shows without using one:

Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female>
    Node( owl:Nothing )
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Woman>
    Node( owl:Nothing )
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male>
    Node( owl:Nothing )
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human>
    Node( <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Man> )
    Node( <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Woman> )
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender>
    Node( <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female> )
    Node( <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male> )
Subclasses of <http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Man>
    Node( owl:Nothing )

What am I doing wrong here? Has Protégé some built-in rules for "clear" cases of subclasses? Where can I find them?

For reference, the example ontology and the OWL API code follow:

<!-- 
///////////////////////////////////////////////////////////////////////////////////////
//
// Object Properties
//
///////////////////////////////////////////////////////////////////////////////////////
 -->




<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#hasAge -->

<owl:ObjectProperty rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#hasAge">
    <rdfs:domain rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human"/>
</owl:ObjectProperty>



<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#hasSex -->

<owl:ObjectProperty rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#hasSex">
    <rdfs:domain rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human"/>
    <rdfs:range rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender"/>
</owl:ObjectProperty>



<!-- 
///////////////////////////////////////////////////////////////////////////////////////
//
// Classes
//
///////////////////////////////////////////////////////////////////////////////////////
 -->




<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female -->

<owl:Class rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female">
    <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender"/>
</owl:Class>



<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender -->

<owl:Class rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender"/>



<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human -->

<owl:Class rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human"/>



<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male -->

<owl:Class rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male">
    <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Gender"/>
</owl:Class>



<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Man -->

<owl:Class rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Man">
    <owl:equivalentClass>
        <owl:Class>
            <owl:intersectionOf rdf:parseType="Collection">
                <rdf:Description rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human"/>
                <owl:Restriction>
                    <owl:onProperty rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#hasSex"/>
                    <owl:someValuesFrom rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Male"/>
                </owl:Restriction>
            </owl:intersectionOf>
        </owl:Class>
    </owl:equivalentClass>
</owl:Class>



<!-- http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Woman -->

<owl:Class rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Woman">
    <owl:equivalentClass>
        <owl:Class>
            <owl:intersectionOf rdf:parseType="Collection">
                <rdf:Description rdf:about="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Human"/>
                <owl:Restriction>
                    <owl:onProperty rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#hasSex"/>
                    <owl:someValuesFrom rdf:resource="http://www.semanticweb.org/user/ontologies/2017/4/untitled-ontology-222#Female"/>
                </owl:Restriction>
            </owl:intersectionOf>
        </owl:Class>
    </owl:equivalentClass>
</owl:Class>

public static void main(String[] args) throws OWLOntologyCreationException {
    OWLOntologyManager m = OWLManager.createOWLOntologyManager();
    OWLOntology o = m.loadOntologyFromOntologyDocument(new File("testonto/Untitled.owl"));
    OWLReasonerFactory reasonerFactory = new JFactFactory();
    OWLReasoner reasoner = reasonerFactory.createReasoner(o);
    o.classesInSignature().forEach(c -> {
        System.out.println("Subclasses of " + c);
        reasoner.getSubClasses(c, true).forEach(sc -> System.out.println("    " + sc));
//          EntitySearcher.getSubClasses(c, o).forEach(sc -> System.out.println("    " + sc));
    });
}

Solution

  • Short answer is yes, Protégé has some minimal reasoning to organise the asserted hierarchy.