Redundant super class in ontology after reasoning

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Redundant super class in ontology after reasoning

cknoll
I try to understand the rector-normalization-technique for ontologies in detail.

The article recommends to have a asserted single inheritance structure and introduce multiple inheritance by inference. As example it uses classes as `Protein`, `Insulin`, and `Protein_Hormone`, `Hormone_Role`.

Asserted facts:

- `Insulin` `is_subclass_of` `Protein`
- `Insulin` `plays_role` `Hormone_Role`
- `Protein_Hormone` is equivalent to (`Protein` `and` `plays_role` `owl:someValuesFrom` `Hormone_Role`) (defined class)

After the reasoner ran, `Insulin` is correctly recognized as subclass of `Protein_Hormone`    (expected result).

However, `Insulin` is still also classified as direct subclass of protein. This relation I deem redundant because every instance of `Protein_Hormone` must be a `Protein` by definition. Also, if I apply ProtegĂ©, the inferred class structure does not contain this redundant relation, as shown here:



Is there a (canonical) way to get rid of this superfluous subclass relation?


Code for this problem (see also this notebook for outputs):

```python
import owlready2 as owl2

# rme: rector-modularization-example
onto = owl2.get_ontology("https://w3id.org/yet/undefined/rme#")

with onto:

    class Protein(owl2.Thing):
        pass

    class Insulin(Protein):
        pass

    class Hormone_Role(owl2.Thing):
        pass

    class plays_role(owl2.ObjectProperty):
        pass


    class Protein_Hormone(owl2.Thing):
        equivalent_to = [Protein & plays_role.some(Hormone_Role)]

Insulin.is_a.append(plays_role.some(Hormone_Role))

# before reasoning
print(list(Protein.subclasses()))

owl2.sync_reasoner_hermit(infer_property_values=True, debug=1)

# after reasoning
print(list(Protein.subclasses()))
```

Reply | Threaded
Open this post in threaded view
|

Re: Redundant super class in ontology after reasoning

Jiba
Administrator
Hi,

I consider keeping the redundant super class as normal, because reasoning cannot remove asserted fact (such as the "Insulin subclassOf Protein" fact).

You may use the _keep_most_specific internal function of owlready2.reasoning to keep the most specific classes of a list, for example :

from owlready2.reasoning import _keep_most_specific

Insulin.is_a = _keep_most_specific(Insulin.is_a)

Notice that by default, _keep_most_specific also consider equivalent classes (use consider_equivalence=False to prevent that).

Jiba