Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into issues-solving
Browse files Browse the repository at this point in the history
  • Loading branch information
alkidbaci committed Sep 18, 2024
2 parents 4365a73 + c78ab2f commit f8220ba
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 62 deletions.
108 changes: 57 additions & 51 deletions examples/ontology_reasoning_retrieval_agreements_and_runtimes.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,28 @@
""" A script to show that OWL Reasoners return the same retrieval results in different runtimes """
import time

from owlapy.class_expression import OWLClass, OWLObjectSomeValuesFrom, OWLObjectAllValuesFrom
from owlapy.class_expression import (OWLClass, OWLObjectSomeValuesFrom, OWLObjectAllValuesFrom,
OWLObjectIntersectionOf, OWLObjectUnionOf)
from owlapy.owl_ontology_manager import OntologyManager
from owlapy.owl_reasoner import SyncReasoner
from owlapy.utils import concept_reducer_properties

from owlapy.utils import concept_reducer_properties, concept_reducer
from owlapy import owl_expression_to_dl
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from tqdm import tqdm

ontology_path = "../KGs/Family/family-benchmark_rich_background.owl"

owl_reasoners = dict()
owl_reasoners["HermiT"] = SyncReasoner(ontology=ontology_path, reasoner="HermiT")
owl_reasoners["Pellet"] = SyncReasoner(ontology=ontology_path, reasoner="Pellet")
owl_reasoners["JFact"] = SyncReasoner(ontology=ontology_path, reasoner="JFact")
owl_reasoners["Openllet"] = SyncReasoner(ontology=ontology_path, reasoner="Openllet")
onto = OntologyManager().load_ontology(ontology_path)
c: OWLClass
###################################################################
# GENERATE ALCQ CONCEPTS TO EVALUATE RETRIEVAL PERFORMANCES
# (3) R: Extract object properties.
object_properties = {i for i in onto.object_properties_in_signature()}
# (4) R⁻: Inverse of object properties.
object_properties_inverse = {i.get_inverse_property() for i in object_properties}
# (5) R*: R UNION R⁻.
object_properties_and_inverse = object_properties.union(object_properties_inverse)
# (6) NC: Named owl concepts.
nc = {i for i in onto.classes_in_signature()}
# (7) NC⁻: Complement of NC.
nnc = {i.get_object_complement_of() for i in nc}
# (8) \exist r. C s.t. C \in NC and r \in R* .
exist_nc = concept_reducer_properties(
concepts=nc,
properties=object_properties_and_inverse,
cls=OWLObjectSomeValuesFrom)
# (9) \forall r. C s.t. C \in NC and r \in R* .
forall_nc = concept_reducer_properties(
concepts=nc,
properties=object_properties_and_inverse,
cls=OWLObjectAllValuesFrom,
)


def eval_reasoners(iter_owl_exp, mapping):
def eval_reasoners(iter_owl_exp, mapping,info:str=""):
results = dict()
runtime_results = dict()
for c in tqdm(iter_owl_exp):
for c in (tqdm_bar:=tqdm(iter_owl_exp)):
for name_i, reasoner_i in mapping.items():
start_time_i = time.time()
result_reasoner_i = {i.str for i in reasoner_i.instances(c)}
runtime_results.setdefault(name_i, []).append(time.time() - start_time_i)

tqdm_bar.set_description_str(f"{owl_expression_to_dl(c)}\t")

for name_j, reasoner_j in mapping.items():
if name_i == name_j:
continue # Skip self-comparison
Expand Down Expand Up @@ -108,21 +78,57 @@ def plot_similarity_btw_reasoners(results):
plt.ylabel('Reasoner')
plt.show()

ontology_path = "../KGs/Family/father.owl"

# EVAL Named Concepts
print("Evaluation over named concepts...")
similarity_results, average_runtime_owl_reasoners = eval_reasoners(nc, owl_reasoners)
owl_reasoners = dict()
owl_reasoners["HermiT"] = SyncReasoner(ontology=ontology_path, reasoner="HermiT")
owl_reasoners["Pellet"] = SyncReasoner(ontology=ontology_path, reasoner="Pellet")
owl_reasoners["JFact"] = SyncReasoner(ontology=ontology_path, reasoner="JFact")
owl_reasoners["Openllet"] = SyncReasoner(ontology=ontology_path, reasoner="Openllet")
onto = OntologyManager().load_ontology(ontology_path)
c: OWLClass
# () C: OWL Class.
c = {i for i in onto.classes_in_signature()}
similarity_results, average_runtime_owl_reasoners = eval_reasoners(c, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Named Concepts")
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Classes")

# EVAL Negated Concepts
print("Evaluation over negated named concepts...")
similarity_results, average_runtime_owl_reasoners = eval_reasoners(nnc, owl_reasoners)
# () Negated OWL CLasses.
nc = {i.get_object_complement_of() for i in c}
similarity_results, average_runtime_owl_reasoners = eval_reasoners(nc, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Negated Named Concepts")
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Negated Classes")
# () Intersection of OWL Classes
intersections_classes = concept_reducer(c, opt=OWLObjectIntersectionOf)
similarity_results, average_runtime_owl_reasoners = eval_reasoners(intersections_classes, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Intersection of Classes")
# () Union of OWL Classes
unions_classes = concept_reducer(c, opt=OWLObjectUnionOf)
similarity_results, average_runtime_owl_reasoners = eval_reasoners(unions_classes, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Union of Classes")
# () Object Property Restrictions - Existential Quantification
object_properties = {i for i in onto.object_properties_in_signature()}
exist_c = concept_reducer_properties(concepts=c, properties=object_properties, cls=OWLObjectSomeValuesFrom)
similarity_results, average_runtime_owl_reasoners = eval_reasoners(exist_c, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Existential Quantifiers")
# () Object Property Restrictions - Universal Quantification
forall_c = concept_reducer_properties(concepts=c, properties=object_properties, cls=OWLObjectAllValuesFrom)
similarity_results, average_runtime_owl_reasoners = eval_reasoners(forall_c, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Universal Quantifiers")

# EVAL Exist R. NC
print("Evaluation over existential object property restrictions... takes some time")
similarity_results, average_runtime_owl_reasoners = eval_reasoners(exist_nc, owl_reasoners)
# () Object Property Restrictions - Existential Quantification
inverse_object_properties = {i.get_inverse_property() for i in onto.object_properties_in_signature()}
exist_inverse_c = concept_reducer_properties(concepts=c, properties=inverse_object_properties, cls=OWLObjectSomeValuesFrom)
similarity_results, average_runtime_owl_reasoners = eval_reasoners(exist_inverse_c, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Existential Quantifiers with inverse properties")
# () Object Property Restrictions - Universal Quantification
forall_inverse_c = concept_reducer_properties(concepts=c, properties=inverse_object_properties, cls=OWLObjectAllValuesFrom)
similarity_results, average_runtime_owl_reasoners = eval_reasoners(forall_inverse_c, owl_reasoners)
plot_similarity_btw_reasoners(similarity_results)
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on OWLObjectSomeValuesFrom")
plot_runtimes(average_runtime_owl_reasoners, title="Avg Runtime of Reasoners on Universal Quantifiers with inverse properties")

6 changes: 0 additions & 6 deletions owlapy/class_expression/owl_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,4 @@ def get_nnf(self) -> 'OWLClass':
# documented in parent
return self

def __str__(self):
return f"OWLClass({self.reminder})"

def __repr__(self):
return f"OWLClass({self._iri})"


15 changes: 10 additions & 5 deletions owlapy/owl_reasoner.py
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,10 @@ def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"):
else:
raise NotImplementedError("Not implemented")

def instances(self, ce: OWLClassExpression, direct=False) -> List[OWLNamedIndividual]:

self.reasoner=reasoner

def instances(self, ce: OWLClassExpression, direct=False) -> Set[OWLNamedIndividual]:
"""
Get the instances for a given class expression using HermiT.
Expand All @@ -1225,11 +1228,13 @@ def instances(self, ce: OWLClassExpression, direct=False) -> List[OWLNamedIndivi
direct (bool): Whether to get direct instances or not. Defaults to False.
Returns:
list: A list of individuals classified by the given class expression.
set: A set of individuals classified by the given class expression.
"""
inds = self._owlapi_reasoner.getInstances(self.mapper.map_(ce), direct).getFlattened()
assert str(type(inds)) == "<java class 'java.util.LinkedHashSet'>"
return [self.mapper.map_(ind) for ind in inds]
mapped_ce=self.mapper.map_(ce)
instances = self._owlapi_reasoner.getInstances(mapped_ce, direct)
flattended_instances = instances.getFlattened()
assert str(type(flattended_instances)) == "<java class 'java.util.LinkedHashSet'>"
return {self.mapper.map_(ind) for ind in flattended_instances}

def equivalent_classes(self, ce: OWLClassExpression) -> List[OWLClassExpression]:
"""
Expand Down
44 changes: 44 additions & 0 deletions tests/test_reasoner_alc_father_ontology.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from owlapy.owl_reasoner import SyncReasoner
from owlapy.class_expression import OWLClass, OWLObjectSomeValuesFrom
from owlapy.owl_individual import OWLNamedIndividual
from owlapy.iri import IRI
from owlapy.owl_property import OWLObjectProperty


class TestHermitFather:
def test_readme(self):

ontology_path = "KGs/Family/father.owl"
hermit = SyncReasoner(ontology=ontology_path, reasoner="HermiT")

# Thing
thing = OWLClass(IRI('http://www.w3.org/2002/07/owl#', 'Thing'))
# Person OWL Class
person = eval("OWLClass(IRI('http://example.com/father#', 'person'))")
# Female OWL CLass
female = eval("OWLClass(IRI('http://example.com/father#', 'female'))")
# hasChild object property
hasChild = OWLObjectProperty(IRI('http://example.com/father#', 'hasChild'))

# Things
assert hermit.instances(thing) == {OWLNamedIndividual(IRI('http://example.com/father#', 'anna')), OWLNamedIndividual(IRI('http://example.com/father#', 'martin')), OWLNamedIndividual(IRI('http://example.com/father#', 'heinz')), OWLNamedIndividual(IRI('http://example.com/father#', 'stefan')), OWLNamedIndividual(IRI('http://example.com/father#', 'michelle')), OWLNamedIndividual(IRI('http://example.com/father#', 'markus'))}

# hasChild a thing.
assert hermit.instances(OWLObjectSomeValuesFrom(property=hasChild, filler=thing)) == eval(
"{OWLNamedIndividual(IRI('http://example.com/father#', 'markus')), OWLNamedIndividual(IRI('http://example.com/father#', 'martin')), OWLNamedIndividual(IRI('http://example.com/father#', 'stefan')), OWLNamedIndividual(IRI('http://example.com/father#', 'anna'))}")

# hasChild a person.
assert hermit.instances(OWLObjectSomeValuesFrom(property=hasChild, filler=person)) == eval(
"{OWLNamedIndividual(IRI('http://example.com/father#', 'markus')), OWLNamedIndividual(IRI('http://example.com/father#', 'martin')), OWLNamedIndividual(IRI('http://example.com/father#', 'stefan')), OWLNamedIndividual(IRI('http://example.com/father#', 'anna'))}")

# hasChild a female.
assert hermit.instances(OWLObjectSomeValuesFrom(property=hasChild, filler=female)) == eval(
"{OWLNamedIndividual(IRI('http://example.com/father#', 'markus'))}")
# Question: hasChild something that hasChild a female.
# Answer: stefan
# (stefan haschild markus) and markus haschild anna
assert hermit.instances(OWLObjectSomeValuesFrom(property=hasChild,
filler=OWLObjectSomeValuesFrom(property=hasChild,
filler=female))) == eval(
"{OWLNamedIndividual(IRI('http://example.com/father#', 'stefan'))}")

0 comments on commit f8220ba

Please sign in to comment.