Skip to content

Commit

Permalink
Merge pull request #102 from dice-group/test_hashes
Browse files Browse the repository at this point in the history
Test hashes
  • Loading branch information
Demirrr authored Nov 8, 2024
2 parents a9d55ce + aa99ec6 commit e43df09
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 47 deletions.
85 changes: 40 additions & 45 deletions owlapy/class_expression/restriction.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ..owl_individual import OWLIndividual
from ..owl_datatype import OWLDatatype
from ..owl_object import OWLObject
from owlapy.vocab import OWLFacet
from ..vocab import OWLFacet
from datetime import datetime, date
from pandas import Timedelta

Expand Down Expand Up @@ -65,7 +65,7 @@ def __init__(self, value: _T):
def __eq__(self, other):
if type(other) is type(self):
return self._v == other._v
return NotImplemented
return False

def __hash__(self):
return hash(self._v)
Expand Down Expand Up @@ -272,10 +272,11 @@ def __repr__(self):
def __eq__(self, other):
if type(other) is type(self):
return self._filler == other._filler and self._property == other._property
return NotImplemented
else:
return False

def __hash__(self):
return hash((self._filler, self._property))
return hash(("OWLObjectSomeValuesFrom",self._filler, self._property))

def get_property(self) -> OWLObjectPropertyExpression:
# documented in parent
Expand Down Expand Up @@ -303,7 +304,7 @@ def __eq__(self, other):
return False

def __hash__(self):
return hash((self._filler, self._property))
return hash(("OWLObjectAllValuesFrom",self._filler, self._property))

def get_property(self) -> OWLObjectPropertyExpression:
# documented in parent
Expand Down Expand Up @@ -341,8 +342,9 @@ def __eq__(self, other):
else:
return False


def __hash__(self):
return hash(self._property)
return hash(("OWLObjectHasSelf", self._property))

def __repr__(self):
return f'OWLObjectHasSelf({self._property})'
Expand Down Expand Up @@ -428,16 +430,13 @@ def as_object_union_of(self) -> OWLClassExpression:
if len(self._values) == 1:
return self
return OWLObjectUnionOf(map(lambda _: OWLObjectOneOf(_), self.individuals()))

def __hash__(self):
return hash(self._values)

return hash(("OWLObjectOneOf", self._values))
def __eq__(self, other):
if type(other) is type(self):
return self._values == other._values
else:
return False

def __repr__(self):
return f'OWLObjectOneOf({self._values})'

Expand Down Expand Up @@ -485,25 +484,22 @@ def __init__(self, cardinality: int, property: OWLDataPropertyExpression, filler
assert isinstance(filler, OWLDataRange), "filler must be an OWLDataRange"
super().__init__(cardinality, filler)
self._property = property

def get_property(self) -> OWLDataPropertyExpression:
# documented in parent
return self._property

def __hash__(self):
return hash(("OWLDataCardinalityRestriction",self._property, self._cardinality, self._filler))
def __repr__(self):
return f"{type(self).__name__}(" \
f"property={repr(self.get_property())},{self.get_cardinality()},filler={repr(self.get_filler())})"

def __eq__(self, other):
if type(other) is type(self):
return self._property == other._property \
and self._cardinality == other._cardinality \
and self._filler == other._filler
return NotImplemented

def __hash__(self):
return hash((self._property, self._cardinality, self._filler))
return (self._property == other._property and self._cardinality == other._cardinality
and self._filler == other._filler)
else:
return False

def get_property(self) -> OWLDataPropertyExpression:
# documented in parent
return self._property

class OWLDataMinCardinality(OWLDataCardinalityRestriction):
"""A minimum cardinality expression DataMinCardinality( n DPE DR ) consists of a nonnegative integer n, a data
Expand Down Expand Up @@ -619,7 +615,7 @@ def __eq__(self, other):
else:
return False
def __hash__(self):
return hash((self._filler, self._property))
return hash(("OWLDataSomeValuesFrom",self._filler, self._property))

def get_property(self) -> OWLDataPropertyExpression:
# documented in parent
Expand Down Expand Up @@ -661,9 +657,8 @@ def __eq__(self, other):
return self._filler == other._filler and self._property == other._property
else:
return False

def __hash__(self):
return hash((self._filler, self._property))
return hash(("OWLDataAllValuesFrom",self._filler, self._property))

def get_property(self) -> OWLDataPropertyExpression:
# documented in parent
Expand Down Expand Up @@ -703,10 +698,10 @@ def __repr__(self):
def __eq__(self, other):
if type(other) is type(self):
return self._v == other._v and self._property == other._property
return NotImplemented

else:
return False
def __hash__(self):
return hash((self._v, self._property))
return hash(("OWLDataHasValue",self._v, self._property))

def as_some_values_from(self) -> OWLClassExpression:
"""A convenience method that obtains this restriction as an existential restriction with a nominal filler.
Expand Down Expand Up @@ -735,6 +730,17 @@ def __init__(self, values: Union[OWLLiteral, Iterable[OWLLiteral]]):
for _ in values:
assert isinstance(_, OWLLiteral)
self._values = tuple(values)
def __repr__(self):
return f'OWLDataOneOf({self._values})'

def __hash__(self):
return hash(("OWLDataOneOf",self._values))

def __eq__(self, other):
if type(other) is type(self):
return {i for i in self._values} == {j for j in other._values}
else:
return False
# TODO:CD: define it as @property as the name of the class method does not correspond to an action
def values(self) -> Iterable[OWLLiteral]:
"""Gets the values that are in the oneOf.
Expand All @@ -748,18 +754,6 @@ def operands(self) -> Iterable[OWLLiteral]:
# documented in parent
yield from self.values()

def __hash__(self):
return hash(self._values)

def __eq__(self, other):
if type(other) is type(self):
return {i for i in self._values} == {j for j in other._values}
else:
return False

def __repr__(self):
return f'OWLDataOneOf({self._values})'


class OWLDatatypeRestriction(OWLDataRange):
"""A datatype restriction DatatypeRestriction( DT F1 lt1 ... Fn ltn ) consists of a unary datatype DT and n pairs
Expand Down Expand Up @@ -792,10 +786,10 @@ def __eq__(self, other):
if type(other) is type(self):
return self._type == other._type \
and self._facet_restrictions == other._facet_restrictions
return NotImplemented

else:
return False
def __hash__(self):
return hash((self._type, self._facet_restrictions))
return hash(("OWLDatatypeRestriction", self._type, self._facet_restrictions))

def __repr__(self):
return f'OWLDatatypeRestriction({repr(self._type)}, {repr(self._facet_restrictions)})'
Expand Down Expand Up @@ -827,10 +821,11 @@ def get_facet_value(self) -> 'OWLLiteral':
def __eq__(self, other):
if type(other) is type(self):
return self._facet == other._facet and self._literal == other._literal
return NotImplemented
else:
return False

def __hash__(self):
return hash((self._facet, self._literal))
return hash(("OWLFacetRestriction",self._facet, self._literal))

def __repr__(self):
return f'OWLFacetRestriction({self._facet}, {repr(self._literal)})'
Expand Down
4 changes: 3 additions & 1 deletion owlapy/iri.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def __init__(self, namespace: Union[str, Namespaces], remainder: str=""):
else:
assert namespace[-1] in ("/", ":", "#"), "It should be a valid IRI based on /, :, and #"
import sys
# https://docs.python.org/3.2/library/sys.html?highlight=sys.intern#sys.intern
self._namespace = sys.intern(namespace)
self._remainder = remainder

Expand Down Expand Up @@ -94,7 +95,8 @@ def __repr__(self):
def __eq__(self, other):
if type(other) is type(self):
return self._namespace is other._namespace and self._remainder == other._remainder
return NotImplemented
else:
raise RuntimeError(f"Invalid equality checking:{self} cannot be compared with {other}")

def __hash__(self):
return hash((self._namespace, self._remainder))
Expand Down
4 changes: 3 additions & 1 deletion owlapy/owl_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ class OWLNamedObject(OWLObject, HasIRI, metaclass=ABCMeta):
def __eq__(self, other):
if type(other) is type(self):
return self._iri == other._iri
return NotImplemented
else:
return False
# raise RuntimeError(f"Invalid equality checking:{self} cannot be compared with {other}")

def __lt__(self, other):
if type(other) is type(self):
Expand Down
52 changes: 52 additions & 0 deletions tests/test_hashing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from owlapy.owl_property import OWLObjectProperty
from owlapy.class_expression import OWLObjectSomeValuesFrom, OWLObjectAllValuesFrom
from owlapy.converter import owl_expression_to_sparql
from owlapy.render import owl_expression_to_dl
from owlapy.iri import IRI
from owlapy.class_expression import OWLClass, OWLObjectUnionOf, OWLObjectIntersectionOf

class TestHashing:

def test_el_description_logic_hash(self):
"""
EL allows complex concepts of the following form:
C := \top | A | C1 u C2 | \existr.C
where A is a concept and r a role name.
For more, refer to https://www.emse.fr/~zimmermann/Teaching/KRR/el.html
"""
memory = dict()
# An OWL Class can be used as a key in a dictionary.
memory[OWLClass("http://example.com/father#A")] = OWLClass("http://example.com/father#A")
memory[OWLClass("http://example.com/father#B")] = OWLClass("http://example.com/father#B")
memory[OWLClass("http://example.com/father#C")] = OWLClass("http://example.com/father#C")

unions = set()
intersections = set()
for k, v in memory.items():
assert k == v
# An OWLObjectUnionOf over two OWL Classes can be added into a set.
unions.add(OWLObjectUnionOf((k, v)))
# Since the order doesn't matter in an OWLObjectUnionOf the following also holds
assert OWLObjectUnionOf((v, k)) in unions

# This also works for intersections.
intersections.add(OWLObjectIntersectionOf((k, v)))
# Since the order doesn't matter in an OWLObjectUnionOf the following also holds
assert OWLObjectIntersectionOf((v, k)) in intersections
# OWLObjectUnionOf and OWLObjectIntersectionOf can also be used as keys
for i in unions | intersections:
memory[i]=i
for k, v in memory.items():
assert k == v

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)

for k, v in memory.items():
assert k == v

0 comments on commit e43df09

Please sign in to comment.