dice-group / owlapy

OWLAPY is a Python Framework for creating and manipulating OWL Ontologies.
MIT License
21 stars 2 forks source link

Equivalence Check error OWLObjectAllValuesFrom #103

Closed Demirrr closed 3 weeks ago

Demirrr commented 3 weeks ago
atomic_concepts = {OWLClass("http://example.com/father#A"), OWLClass("http://example.com/father#B")}
properties = {OWLObjectProperty("http://example.com/society#hasChild")}
memory = dict()
for ac in atomic_concepts:
    for op in properties:
        # OWLObjectSomeValuesFrom can be used as a key.
        memory[OWLObjectSomeValuesFrom(property=op, filler=ac)] = OWLObjectSomeValuesFrom(property=op, filler=ac)
        memory[OWLObjectAllValuesFrom(property=op, filler=ac)] = OWLObjectAllValuesFrom(property=op, filler=ac)

leads to

 File "/home/cdemir/Desktop/Softwares/owlapy/owlapy/class_expression/restriction.py", line 276, in __eq__
    raise RuntimeError(f"Invalid equality checking:{self} cannot be compared with {other}")
RuntimeError: Invalid equality checking:OWLObjectSomeValuesFrom(property=OWLObjectProperty(IRI('http://example.com/society#', 'hasChild')),filler=OWLClass(IRI('http://example.com/father#', 'B'))) cannot be compared with OWLObjectAllValuesFrom(property=OWLObjectProperty(IRI('http://example.com/society#', 'hasChild')),filler=OWLClass(IRI('http://example.com/father#', 'B')))
class OWLObjectSomeValuesFrom(OWLQuantifiedObjectRestriction):
...
    def __eq__(self, other):
        if type(other) is type(self):
            return self._filler == other._filler and self._property == other._property
        else:
            raise RuntimeError(f"Invalid equality checking:{self} cannot be compared with {other}")
Demirrr commented 3 weeks ago

If we comment one of the operations, then it works without a problem.

for ac in atomic_concepts:
    for op in properties:
        # memory[OWLObjectSomeValuesFrom(property=op, filler=ac)] = OWLObjectSomeValuesFrom(property=op, filler=ac)
        memory[OWLObjectAllValuesFrom(property=op, filler=ac)] = OWLObjectAllValuesFrom(property=op, filler=ac)

This stems from the fact that the usage of hash does not differ between OWLObjectSomeValuesFrom and OWLObjectAllValuesFrom

  def __hash__(self):
      return hash((self._filler, self._property))
Demirrr commented 3 weeks ago

Solved in #102 by adding the class name into the tuple, e.g.,

    def __hash__(self):
        return hash(("OWLFacetRestriction",self._facet, self._literal))
..
    def __hash__(self):
        return hash(("OWLDatatypeRestriction", self._type, self._facet_restrictions))
..
    def __hash__(self):
        return hash(("OWLDataOneOf",self._values))
..
    def __hash__(self):
        return hash(("OWLDataHasValue",self._v, self._property))