Hi,
I have defined an ontology below. with onto: class Element(Thing):pass class Material(Thing): pass AllDisjoint([Material, Element]) class Al(Element): pass class O(Element): pass class N(Element): pass class P(Element): pass class hasElement(Material>> Element): python_name = "has_element" class ON(Material): equivalent_to = [Material & hasElement.some(And([O,N])) & hasElement.only(And([O,N]))] class AlO(Material): equivalent_to = [Material & hasElement.some(And([Al,O])) & hasElement.only(And([Al,O]))] class AlON(Material): equivalent_to = [Material & hasElement.some(And([Al, O, N])) & hasElement.only(And([Al,O,N]))] class AlONP(Material): equivalent_to = [Material & hasElement.some(And([Al ,O, N, P])) & hasElement.only(And([Al,O,N,P]))] AllDisjoint([ AlON, ON, AlO, AlONP]) When I do the reasoning with pellet, I am surprise to have the following results: Owlready2 * Running Pellet... * Owlready2 * Pellet took 4.674990653991699 seconds * Owlready * Equivalenting: base.AlON base.AlONP * Owlready * Equivalenting: base.AlON owl.Nothing * Owlready * Equivalenting: base.AlONP base.AlON * Owlready * Equivalenting: base.AlONP owl.Nothing * Owlready * Equivalenting: owl.Nothing base.AlON * Owlready * Equivalenting: owl.Nothing base.AlONP * Owlready * (NB: only changes on entities loaded in Python are shown, other changes are done but not listed) I find this result inconsistent because materials with only 2 elements bound with And construct such as ON didn't get to be equivalented to owl.Nothing, whereas materials with more than 2 elements bound with And construct got equivalented to owl.Nothing. What would be the reason to this? Thanks for your kind reply. |
Administrator
|
Hi,
I think the problem is in the use of SOME and AND. Here, AlON has an element that belongs to 3 classes: Al, O and N. ON has an element that belongs to 2 classes: O and N. Consequently, AlON is a subclass of ON: since its element belongs to Al, O and N classes, it therefore belongs to O and N. However, you declared AlON and ON disjoint, thus leading to inconsistent classes (Nothing). Notice that the use of ONLY in the definition of ON (hasElement.only(And([O,N])) do not prevent instance of ON to have an element that belongs to other classes than O and N (such as Al). The ONLY construct just says that all elements of an ON instance must belongs to class O and N (and possibly other). I see two possible solution: * possibly the use of SOME and AND is not exactly what you mean. Does an ON instance have a single element belonging to two classes (O and N), or two distinct elements (one O and one N)? In the second case, you should declare it as follows: class ON(Material): equivalent_to = [Material & hasElement.some(O) & hasElement.some(N) & hasElement.only(Or([O,N]))] This means that ON instance has one O element and one N element, and no other elements (notice the OR in the ONLY). * otherwise, you can use NOT to express that ON has no element that does not belong to another class than O and N, as follows: class ON(Material): equivalent_to = [Material & hasElement.some(And([O,N])) & Not(hasElement.some(Not(And([O,N]))))] (this might complicate the reasoning however). Jiba |
Hi Jiba,
Thanks for your reply. It's clearer for me the usage of SOME and AND. I think I didn't completely understand the meaning of these operators. Actually, what I would like is the first case where an ON instance has a single element belonging to two classes (O and N), an ALON instance would have a single element belonging to 3 classes (Al, O and N) and this AlON instance should not be an element of class ON etc... What would you suggest? Cheers, Patrick |
Administrator
|
Hi,
In that case, you can use the "NOT ... NOT" pattern: class ON(Material): equivalent_to = [Material & hasElement.some(And([O,N])) & Not(hasElement.some(Not(Or([O,N]))))] You should also declare hasElement as a functional property, to ensure there is a single element. Jiba |
Free forum by Nabble | Edit this page |