Via Python, I have defined an inverse property ("is_idealized_by") for an existing property defined in an OWL file ("idealizes").
When accessing an individual that has this property set (artifact.is_idealized_by), I retrieve the proper value. Now I expected the inverse property "is_idealized_by" to also be listed when calling "get_properties()" on this individual, however, this is not the case. Is this a bug? Is there another way to retrieve a list of these inverse properties? |
Administrator
|
Hi,
Individual.get_properties() should normally also return inverse properties. Here is an example: from owlready2 import * onto = get_ontology("http://test.org/t.owl") with onto: class C(Thing): pass class p(Thing >> Thing): pass class i(Thing >> Thing): inverse = p c1 = C() c2 = C() c1.p = [c2] print(c1.get_properties()) # prints "{t.p}" print(c2.get_properties()) # prints "{t.i}" In what kind of situations are you encountering this problem? Could you send me a small example to reproduce it? Jiba |
Thank you for testing this. I could now find out, what line of code causes the example to fail:
from owlready2 import * corax = get_ontology("http://purl.org/ieee1872-owl/corax#") sumo_cora = get_ontology("http://purl.org/ieee1872-owl/sumo-cora#") with corax: class idealizes(ObjectProperty): pass with sumo_cora: class is_idealized_by(ObjectProperty): inverse_property = idealizes corax.load(reload=True) sumo_cora.load(reload=True) my_design = corax.Design() my_artifact = sumo_cora.Artifact() my_design.idealizes.append(my_artifact) print("artifact", my_artifact, my_artifact.is_idealized_by, my_artifact.get_properties()) print("design", my_design, my_design.idealizes, my_design.get_properties()) This code correctly prints artifact sumo-cora.artifact1 [corax.design1] {sumo-cora.is_idealized_by} design corax.design1 [sumo-cora.artifact1] {corax.idealizes} However, when I comment the line "with sumo_cora:", this defining "is_idealized_by" in the corax namespace, that property is no longer listed: artifact sumo-cora.artifact1 [corax.design1] set() design corax.design1 [sumo-cora.artifact1] {corax.idealizes} Is that intended? |
Administrator
|
Hi,
I think the problem is the use of reload(). It reloads the ontology, but previously remove its current content -- thus removing the inverse property assertion. If you want to modify an existing ontology, you should load it, and then modify it, as follows: from owlready2 import * corax = get_ontology("http://purl.org/ieee1872-owl/corax#").load() sumo_cora = get_ontology("http://purl.org/ieee1872-owl/sumo-cora#").load() with corax: class idealizes(ObjectProperty): pass #with sumo_cora: class is_idealized_by(ObjectProperty): inverse_property = idealizes my_design = corax.Design() my_artifact = sumo_cora.Artifact() my_design.idealizes.append(my_artifact) print("artifact", my_artifact, my_artifact.is_idealized_by, my_artifact.get_properties()) print("design", my_design, my_design.idealizes, my_design.get_properties()) This code works as expected, with is_idealized_by defined in either ontology. Jiba |
Thank you for investigating this. Knowing that an ontology first needs to be loaded before being extended is very valuable!
I would suggest to make this clear in the documentation, too, as one can get the impression and this is not required and even not suggested: * Forward declarations tells you, that definitions are extended (but I guess this is quite limited?) * Associating a Python module to an OWL ontology tells you that the ontology should _not_ be loaded before extending it (but I guess that only holds true then for empty ontologies?) |
I forgot to mention that I did some more variations to see where the issue comes from. In a previous post, I showed that the code works when specifying the inverse property in another ontology using `with`. However, this does not work when setting the namespace using the class property:
with corax: class idealizes(ObjectProperty): pass class is_idealized_by(ObjectProperty): namespace = sumo_cora inverse_property = idealizes |
Administrator
|
Hi,
I obtain the same results using the namespace attribute, as in the following example: from owlready2 import * corax = get_ontology("http://purl.org/ieee1872-owl/corax#").load() sumo_cora = get_ontology("http://purl.org/ieee1872-owl/sumo-cora#").load() with corax: class idealizes(ObjectProperty): pass class is_idealized_by(ObjectProperty): namespace = sumo_cora inverse_property = idealizes my_design = corax.Design() my_artifact = sumo_cora.Artifact() my_design.idealizes.append(my_artifact) print("artifact", my_artifact, my_artifact.is_idealized_by, my_artifact.get_properties()) print("design", my_design, my_design.idealizes, my_design.get_properties()) Is it the same for you? Jiba |
Free forum by Nabble | Edit this page |