When trying to change the following attributes of a Restriction axiom: "type", "cadinality", "property", the "value" attribute it's lost and will be None.
Example: ontology = owlready2.get_ontology('file://{}'.format('test_ontology.owl')).load() for axiom in ontology.general_axioms(): if not isinstance(axiom, owlready2.Restriction): continue if not axiom.type is owlready2.MIN: continue axiom.cardinality = 2 The cause of the issue may be this: 1. the "value" field is initialized only when it's accessed for the first time (not at object creation) so it doesn't exist at this point 2. axiom.cardinality = 2 -> will call __setattr__("cardinality", 2) def __setattr__(self, attr, v): super().__setattr__(attr, v) if ((attr == "property") or (attr == "type") or (attr == "cardinality") or (attr == "value")) and self.ontology: self._destroy_triples(self.ontology) if (attr == "value") and isinstance(v, ClassConstruct) and (not v.ontology): v._set_ontology(self.ontology) self._create_triples (self.ontology) self._destroy_triples(self.ontology) - will remove from data base all data related to this axiom self._create_triples (self.ontology) - will try to create back all data for the axiom in the data base (including "value") - "value" field is missing (because step 1) so it will call __getattr__("value") - __getattr__("value") will try to get the data from the data base - no data found because it was destroyed earlier Hope i understood and explained well what is happening. Is this a bug or am I doing something wrong? Sorry for the long post. Thanks! |
Administrator
|
Hi,
I tried the test case below, but everything is Ok. Possibly the problem is related to the fact that your restriction is part of a general axioms? What kind of general axioms are you using? Jiba ---8<---------- def test_construct_restriction_7(self): w = self.new_world() o = w.get_ontology("http://test.org/onto.owl") with o: class p(Thing >> Thing): pass class C(Thing): pass class D(Thing): is_a = [p.some(C)] assert D.is_a[1].value is C D.is_a[1].type = MIN D.is_a[1].cardinality = 2 assert D.is_a[1].value is C |
Hello,
Sorry for my bad explanation, i am new to ontologies and owlready2. In your example the restriction value is set in the program. So it's available from the start and everything is ok. For reference, how the Restriction constructor looks like: Restriction - class constructor def __init__(self, Property, type, cardinality = None, value = None, ontology = None, bnode = None) In your case the flow is something like this: 1. is_a = [p.some(C)] - will call the function bellow 2. def some(Prop, value): return Restriction(Prop, SOME, None, value) # the value is set here In my case it goes like this: 1. ontology.general_axioms(): # calls the method bellow that creates the Restriction 2. def _parse_bnode(self, bnode): ... some code... r = Restriction(restriction_property, restriction_type, None, None, self, bnode) ... some code... You can see here that the restriction value is set to None. It will be lazy initialized from db when it's retrieved (by Restriction.__getattr__) If we do the following hack: for axiom in ontology.general_axioms(): # here axiom.value is none print(axiom.value) # value is initialized here properly because it was accessed # here axiom.value is loaded correctly axiom.cardinality = 2 # all works ok, because value was initialized earlier If we do it like this: for axiom in ontology.general_axioms(): # here axiom.value is None axiom.cardinality = 2 # it set's the cardinality to 2, but it fails to intialize value because of the reason i tried to explain in the initial post # here axiom.value is still None, and it's also gone from loaded db I will also attach the test ontology for this: test_check_.owl |
Administrator
|
Hi,
Ok, I think I now understand the problem better. I've tested it with your ontology I can reproduce it. I think I fixed it in the development version of Owlready on Bitbucket, could you verify that? Jiba |
Free forum by Nabble | Edit this page |