diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml
deleted file mode 100644
index b6690e05..00000000
--- a/.github/workflows/ruff.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: Ruff
-on: [push, pull_request]
-jobs:
- ruff:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: chartboost/ruff-action@v1
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6bee0285..a0e107e9 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -18,7 +18,9 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -e .
-
+ - name: Lint with ruff
+ run: |
+ ruff check owlapy --line-length=200
- name: Test with pytest
run: |
wget https://files.dice-research.org/projects/Ontolearn/KGs.zip
diff --git a/README.md b/README.md
index 9eb842a7..2cfcbc91 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# OWLAPY
[](https://dice-group.github.io/owlapy/usage/further_resources.html#coverage-report)
-[](https://pypi.org/project/owlapy/1.3.2/)
-[](https://dice-group.github.io/owlapy/usage/main.html)
+[](https://pypi.org/project/owlapy/1.3.3/)
+[](https://dice-group.github.io/owlapy/usage/main.html)

@@ -30,6 +30,54 @@ pytest -p no:warnings -x # Running 142 tests ~ 30 secs
## Examples
+### Exploring OWL Ontology
+
+ Click me!
+
+```python
+from owlapy.owl_ontology_manager import SyncOntologyManager
+
+ontology_path = "KGs/Family/father.owl"
+onto = SyncOntologyManager().load_ontology(ontology_path)
+
+print({owl_class.reminder for owl_class in onto.classes_in_signature()})
+# {'Thing', 'female', 'male', 'person'}
+
+print({individual.reminder for individual in onto.individuals_in_signature()})
+# {'michelle', 'stefan', 'martin', 'anna', 'heinz', 'markus'}
+
+print({object_property.reminder for object_property in onto.object_properties_in_signature()})
+# {'hasChild'}
+
+for owl_subclass_of_axiom in onto.get_tbox_axioms():
+ print(owl_subclass_of_axiom)
+
+# OWLEquivalentClassesAxiom([OWLClass(IRI('http://example.com/father#', 'male')), OWLObjectComplementOf(OWLClass(IRI('http://example.com/father#', 'female')))],[])
+# OWLSubClassOfAxiom(sub_class=OWLClass(IRI('http://example.com/father#', 'female')),super_class=OWLClass(IRI('http://example.com/father#', 'person')),annotations=[])
+# OWLSubClassOfAxiom(sub_class=OWLClass(IRI('http://example.com/father#', 'male')),super_class=OWLClass(IRI('http://example.com/father#', 'person')),annotations=[])
+# OWLSubClassOfAxiom(sub_class=OWLClass(IRI('http://example.com/father#', 'person')),super_class=OWLClass(IRI('http://www.w3.org/2002/07/owl#', 'Thing')),annotations=[])
+# OWLObjectPropertyRangeAxiom(OWLObjectProperty(IRI('http://example.com/father#', 'hasChild')),OWLClass(IRI('http://example.com/father#', 'person')),[])
+# OWLObjectPropertyDomainAxiom(OWLObjectProperty(IRI('http://example.com/father#', 'hasChild')),OWLClass(IRI('http://example.com/father#', 'person')),[])
+
+
+for axiom in onto.get_abox_axioms():
+ print(axiom)
+
+# OWLClassAssertionAxiom(individual=OWLNamedIndividual(IRI('http://example.com/father#', 'anna')),class_expression=OWLClass(IRI('http://example.com/father#', 'female')),annotations=[])
+# OWLClassAssertionAxiom(individual=OWLNamedIndividual(IRI('http://example.com/father#', 'michelle')),class_expression=OWLClass(IRI('http://example.com/father#', 'female')),annotations=[])
+# OWLClassAssertionAxiom(individual=OWLNamedIndividual(IRI('http://example.com/father#', 'martin')),class_expression=OWLClass(IRI('http://example.com/father#', 'male')),annotations=[])
+# OWLClassAssertionAxiom(individual=OWLNamedIndividual(IRI('http://example.com/father#', 'markus')),class_expression=OWLClass(IRI('http://example.com/father#', 'male')),annotations=[])
+# OWLClassAssertionAxiom(individual=OWLNamedIndividual(IRI('http://example.com/father#', 'heinz')),class_expression=OWLClass(IRI('http://example.com/father#', 'male')),annotations=[])
+# OWLClassAssertionAxiom(individual=OWLNamedIndividual(IRI('http://example.com/father#', 'stefan')),class_expression=OWLClass(IRI('http://example.com/father#', 'male')),annotations=[])
+# OWLObjectPropertyAssertionAxiom(subject=OWLNamedIndividual(IRI('http://example.com/father#', 'markus')),property_=OWLObjectProperty(IRI('http://example.com/father#', 'hasChild')),object_=OWLNamedIndividual(IRI('http://example.com/father#', 'anna')),annotations=[])
+# OWLObjectPropertyAssertionAxiom(subject=OWLNamedIndividual(IRI('http://example.com/father#', 'martin')),property_=OWLObjectProperty(IRI('http://example.com/father#', 'hasChild')),object_=OWLNamedIndividual(IRI('http://example.com/father#', 'heinz')),annotations=[])
+# OWLObjectPropertyAssertionAxiom(subject=OWLNamedIndividual(IRI('http://example.com/father#', 'stefan')),property_=OWLObjectProperty(IRI('http://example.com/father#', 'hasChild')),object_=OWLNamedIndividual(IRI('http://example.com/father#', 'markus')),annotations=[])
+# OWLObjectPropertyAssertionAxiom(subject=OWLNamedIndividual(IRI('http://example.com/father#', 'anna')),property_=OWLObjectProperty(IRI('http://example.com/father#', 'hasChild')),object_=OWLNamedIndividual(IRI('http://example.com/father#', 'heinz')),annotations=[])
+
+```
+
+
+
### Creating OWL Class Expressions
Click me!
diff --git a/docs/conf.py b/docs/conf.py
index 9e37f605..641cf1fb 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -13,7 +13,7 @@
project = 'OWLAPY'
author = 'Ontolearn Team'
-release = '1.3.2'
+release = '1.3.3'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
diff --git a/docs/usage/main.md b/docs/usage/main.md
index 36b77c2b..c646825c 100644
--- a/docs/usage/main.md
+++ b/docs/usage/main.md
@@ -1,6 +1,6 @@
# About owlapy
-**Version:** owlapy 1.3.2
+**Version:** owlapy 1.3.3
**GitHub repository:** [https://github.com/dice-group/owlapy](https://github.com/dice-group/owlapy)
diff --git a/owlapy/__init__.py b/owlapy/__init__.py
index 84aec36b..78a0a08e 100644
--- a/owlapy/__init__.py
+++ b/owlapy/__init__.py
@@ -3,7 +3,7 @@
from .converter import owl_expression_to_sparql, owl_expression_to_sparql_with_confusion_matrix
from .owl_ontology_manager import OntologyManager
-__version__ = '1.3.2'
+__version__ = '1.3.3'
__all__ = [
'owl_expression_to_dl', 'owl_expression_to_manchester',
diff --git a/owlapy/class_expression/restriction.py b/owlapy/class_expression/restriction.py
index 911a718a..0e6658a9 100644
--- a/owlapy/class_expression/restriction.py
+++ b/owlapy/class_expression/restriction.py
@@ -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
@@ -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)
@@ -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
@@ -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
@@ -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})'
@@ -403,7 +405,7 @@ def __init__(self, values: OWLIndividual | Iterable[OWLIndividual]):
else:
for _ in values:
assert isinstance(_, OWLIndividual)
- self._values = {i for i in values}
+ self._values = frozenset(values)
def individuals(self) -> Iterable[OWLIndividual]:
"""Gets the individuals that are in the oneOf. These individuals represent the exact instances (extension)
@@ -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})'
@@ -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
@@ -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
@@ -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
@@ -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.
@@ -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.
@@ -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
@@ -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)})'
@@ -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)})'
diff --git a/owlapy/iri.py b/owlapy/iri.py
index 66166bb4..af6a3238 100644
--- a/owlapy/iri.py
+++ b/owlapy/iri.py
@@ -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
@@ -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))
diff --git a/owlapy/owl_axiom.py b/owlapy/owl_axiom.py
index 6c10ea5d..3c0cfd96 100644
--- a/owlapy/owl_axiom.py
+++ b/owlapy/owl_axiom.py
@@ -523,6 +523,13 @@ def __init__(self, sub_class: OWLClassExpression, super_class: OWLClassExpressio
self._super_class = super_class
super().__init__(annotations=annotations)
+ @property
+ def sub_class(self) -> OWLClassExpression:
+ return self._sub_class
+ @property
+ def super_class(self) -> OWLClassExpression:
+ return self._super_class
+
def get_sub_class(self) -> OWLClassExpression:
return self._sub_class
@@ -533,7 +540,8 @@ def __eq__(self, other):
if type(other) is type(self):
return self._super_class == other._super_class and self._sub_class == other._sub_class \
and self._annotations == other._annotations
- return NotImplemented
+ else:
+ return False
def __hash__(self):
return hash((self._super_class, self._sub_class, *self._annotations))
diff --git a/owlapy/owl_individual.py b/owlapy/owl_individual.py
index 3d98ff7b..2e0fd626 100644
--- a/owlapy/owl_individual.py
+++ b/owlapy/owl_individual.py
@@ -35,11 +35,12 @@ def __init__(self, iri: Union[IRI, str]):
self._iri = iri
else:
self._iri = IRI.create(iri)
-
@property
def iri(self) -> IRI:
return self._iri
-
@property
def str(self):
return self._iri.as_str()
+ @property
+ def reminder(self):
+ return self._iri.reminder
\ No newline at end of file
diff --git a/owlapy/owl_object.py b/owlapy/owl_object.py
index 02894034..00032820 100644
--- a/owlapy/owl_object.py
+++ b/owlapy/owl_object.py
@@ -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):
diff --git a/owlapy/owl_ontology.py b/owlapy/owl_ontology.py
index d527383e..03a2d4af 100644
--- a/owlapy/owl_ontology.py
+++ b/owlapy/owl_ontology.py
@@ -126,7 +126,6 @@ def __eq__(self, other):
def _check_expression(expr: OWLObject, ontology: AbstractOWLOntology, world: owlready2.namespace.World):
"""
- @TODO:CD: Documentation
Creates all entities (individuals, classes, properties) that appear in the given (complex) class expression
and do not exist in the given ontology yet
@@ -1035,7 +1034,6 @@ def _get_imports_enum(self, include_imports_closure: bool):
else:
imports = Imports.EXCLUDED
return imports
-
def get_signature(self, include_imports_closure: bool = True):
"""Gets the entities that are in the signature of this ontology.
@@ -1045,6 +1043,7 @@ def get_signature(self, include_imports_closure: bool = True):
Returns:
Entities in signature.
"""
+ # @TODO: CD: Is this class method redundant given that we have the individuals_in_signature ?
return self.mapper.map_(self.owlapi_ontology.getSignature(self._get_imports_enum(include_imports_closure)))
def get_abox_axioms(self, include_imports_closure: bool = True) -> Iterable[OWLAxiom]:
@@ -1056,7 +1055,6 @@ def get_abox_axioms(self, include_imports_closure: bool = True) -> Iterable[OWLA
Returns:
ABox axioms.
"""
-
return self.mapper.map_(self.owlapi_ontology.getABoxAxioms(self._get_imports_enum(include_imports_closure)))
def get_tbox_axioms(self, include_imports_closure: bool = True) -> Iterable[OWLAxiom]:
@@ -1100,7 +1098,14 @@ def __hash__(self):
return int(self.owlapi_ontology.getOntologyID().hashCode())
def __repr__(self):
- return f'SyncOntology({self.manager}, {self.path}, {self.new})'
+ return (f'SyncOntology:'
+ f'\t|Tbox|={len(self.get_tbox_axioms())}'
+ f'\t|Abox|={len(self.get_abox_axioms())}'
+ f'\t|Individuals|={len(self.individuals_in_signature())}'
+ f'\t|Classes|={len(self.classes_in_signature())}'
+ f'\t|Object Properties|={len(self.object_properties_in_signature())}'
+ f'\t|Data Properties|={len(self.data_properties_in_signature())}'
+ f'\n{self.manager}\tPath:{self.path}\tNew:{self.new}')
OWLREADY2_FACET_KEYS = MappingProxyType({
diff --git a/owlapy/owl_ontology_manager.py b/owlapy/owl_ontology_manager.py
index 4d58d58a..2df6cdd7 100644
--- a/owlapy/owl_ontology_manager.py
+++ b/owlapy/owl_ontology_manager.py
@@ -103,8 +103,7 @@ def apply_change(self, change: AbstractOWLOntologyChange):
ont_x.imported_ontologies.append(
self._world.get_ontology(change.get_import_declaration().str))
else:
- # TODO XXX
- raise NotImplementedError
+ raise NotImplementedError("Change is not yet implemented.")
def save_world(self):
"""Saves the actual state of the quadstore in the SQLite3 file.
@@ -139,4 +138,4 @@ def get_owlapi_manager(self):
return self.owlapi_manager
def apply_change(self, change: AbstractOWLOntologyChange):
- raise NotImplementedError()
+ raise NotImplementedError("A change cannot be applied at the moment.")
diff --git a/owlapy/owl_property.py b/owlapy/owl_property.py
index cef05361..4f3ee257 100644
--- a/owlapy/owl_property.py
+++ b/owlapy/owl_property.py
@@ -113,6 +113,10 @@ class OWLObjectProperty(OWLObjectPropertyExpression, OWLProperty):
_iri: IRI
+ @property
+ def reminder(self):
+ return self._iri.reminder
+
def get_named_property(self) -> 'OWLObjectProperty':
# documented in parent
return self
diff --git a/owlapy/owl_reasoner.py b/owlapy/owl_reasoner.py
index 211460d9..5069338f 100644
--- a/owlapy/owl_reasoner.py
+++ b/owlapy/owl_reasoner.py
@@ -27,7 +27,7 @@
OWLPropertyExpression, OWLDataPropertyExpression
from owlapy.owl_individual import OWLNamedIndividual
from owlapy.owl_literal import OWLLiteral
-from owlapy.utils import LRUCache, run_with_timeout
+from owlapy.utils import run_with_timeout
from owlapy.abstracts.abstract_owl_reasoner import AbstractOWLReasoner
logger = logging.getLogger(__name__)
@@ -36,37 +36,6 @@
class StructuralReasoner(AbstractOWLReasoner):
"""Tries to check instances fast (but maybe incomplete)."""
- __slots__ = '_ontology', '_world', \
- '_ind_set', '_cls_to_ind', \
- '_has_prop', 'class_cache', \
- '_objectsomevalues_cache', '_datasomevalues_cache', '_objectcardinality_cache', \
- '_property_cache', \
- '_obj_prop', '_obj_prop_inv', '_data_prop', \
- '_negation_default', '_sub_properties', \
- '__warned'
-
- _ontology: Ontology
- _world: owlready2.World
- _cls_to_ind: Dict[OWLClass, FrozenSet[OWLNamedIndividual]] # Class => individuals
- _has_prop: Mapping[Type[_P], LRUCache[_P, FrozenSet[OWLNamedIndividual]]] # Type => Property => individuals
- _ind_set: FrozenSet[OWLNamedIndividual]
- # ObjectSomeValuesFrom => individuals
- _objectsomevalues_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
- # DataSomeValuesFrom => individuals
- _datasomevalues_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
- # ObjectCardinalityRestriction => individuals
- _objectcardinality_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
- # ObjectProperty => { individual => individuals }
- _obj_prop: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]]
- # ObjectProperty => { individual => individuals }
- _obj_prop_inv: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]]
- # DataProperty => { individual => literals }
- _data_prop: Dict[OWLDataProperty, Mapping[OWLNamedIndividual, Set[OWLLiteral]]]
- class_cache: bool
- _property_cache: bool
- _negation_default: bool
- _sub_properties: bool
-
def __init__(self, ontology: AbstractOWLOntology, *, class_cache: bool = True,
property_cache: bool = True, negation_default: bool = True, sub_properties: bool = False):
"""Fast instance checker.
@@ -80,36 +49,34 @@ def __init__(self, ontology: AbstractOWLOntology, *, class_cache: bool = True,
"""
super().__init__(ontology)
assert isinstance(ontology, Ontology)
- self._world = ontology._world
- self._ontology = ontology
- self.class_cache = class_cache
- self._property_cache = property_cache
- self._negation_default = negation_default
- self._sub_properties = sub_properties
- self.__warned = 0
+ self._world: owlready2.World = ontology._world
+ self._ontology: Ontology = ontology
+ self.class_cache: bool = class_cache
+ self._property_cache: bool = property_cache
+ self._negation_default: bool = negation_default
+ self._sub_properties: bool = sub_properties
+ self.__warned: int = 0
self._init()
- def _init(self, cache_size=128):
-
- individuals = self._ontology.individuals_in_signature()
- self._ind_set = frozenset(individuals)
- self._objectsomevalues_cache = LRUCache(maxsize=cache_size)
- self._datasomevalues_cache = LRUCache(maxsize=cache_size)
- self._objectcardinality_cache = LRUCache(maxsize=cache_size)
+ def _init(self):
if self.class_cache:
- self._cls_to_ind = dict()
+ # Class => individuals
+ self._cls_to_ind: Dict[OWLClass, FrozenSet[OWLNamedIndividual]] = {}
if self._property_cache:
- self._obj_prop = dict()
- self._obj_prop_inv = dict()
- self._data_prop = dict()
+ # ObjectProperty => { individual => individuals }
+ self._obj_prop: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]] = dict()
+ # ObjectProperty => { individual => individuals }
+ self._obj_prop_inv: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]] = dict()
+ # DataProperty => { individual => literals }
+ self._data_prop: Dict[OWLDataProperty, Mapping[OWLNamedIndividual, Set[OWLLiteral]]] = dict()
else:
- self._has_prop = MappingProxyType({
- OWLDataProperty: LRUCache(maxsize=cache_size),
- OWLObjectProperty: LRUCache(maxsize=cache_size),
- OWLObjectInverseOf: LRUCache(maxsize=cache_size),
- })
-
+ self._has_prop: Mapping[Type[_P], Dict[_P, FrozenSet[OWLNamedIndividual]]] = {
+ OWLDataProperty: {},
+ OWLObjectProperty: {},
+ OWLObjectInverseOf: {},
+ }
+
def reset(self):
"""The reset method shall reset any cached state."""
self._init()
@@ -636,7 +603,8 @@ def _lazy_cache_obj_prop(self, pe: OWLObjectPropertyExpression) -> None:
opc[s] = set()
opc[s] |= {o}
else:
- for s in self._ind_set:
+ all_ = frozenset(self._ontology.individuals_in_signature())
+ for s in all_:
individuals = set(self.object_property_values(s, pe, not self._sub_properties))
if individuals:
opc[s] = individuals
@@ -676,8 +644,8 @@ def _some_values_subject_index(self, pe: OWLPropertyExpression) -> FrozenSet[OWL
func = self.data_property_values
else:
func = self.object_property_values
-
- for s in self._ind_set:
+ all_ = frozenset(self._ontology.individuals_in_signature())
+ for s in all_:
try:
next(iter(func(s, pe, not self._sub_properties)))
subs |= {s}
@@ -782,9 +750,6 @@ def _(self, ce: OWLObjectIntersectionOf) -> FrozenSet[OWLNamedIndividual]:
@_find_instances.register
def _(self, ce: OWLObjectSomeValuesFrom) -> FrozenSet[OWLNamedIndividual]:
- if ce in self._objectsomevalues_cache:
- return self._objectsomevalues_cache[ce]
-
p = ce.get_property()
assert isinstance(p, OWLObjectPropertyExpression)
if not self._property_cache and ce.get_filler().is_owl_thing():
@@ -794,13 +759,12 @@ def _(self, ce: OWLObjectSomeValuesFrom) -> FrozenSet[OWLNamedIndividual]:
ind = self._find_some_values(p, filler_ind)
- self._objectsomevalues_cache[ce] = ind
return ind
@_find_instances.register
def _(self, ce: OWLObjectComplementOf) -> FrozenSet[OWLNamedIndividual]:
if self._negation_default:
- all_ = self._ind_set
+ all_ = frozenset(self._ontology.individuals_in_signature())
complement_ind = self._find_instances(ce.get_operand())
return all_ ^ complement_ind
else:
@@ -836,7 +800,7 @@ def _(self, ce: OWLObjectMinCardinality) -> FrozenSet[OWLNamedIndividual]:
@_find_instances.register
def _(self, ce: OWLObjectMaxCardinality) -> FrozenSet[OWLNamedIndividual]:
- all_ = self._ind_set
+ all_ = frozenset(self._ontology.individuals_in_signature())
min_ind = self._find_instances(OWLObjectMinCardinality(cardinality=ce.get_cardinality() + 1,
property=ce.get_property(),
filler=ce.get_filler()))
@@ -847,9 +811,6 @@ def _(self, ce: OWLObjectExactCardinality) -> FrozenSet[OWLNamedIndividual]:
return self._get_instances_object_card_restriction(ce)
def _get_instances_object_card_restriction(self, ce: OWLObjectCardinalityRestriction):
- if ce in self._objectcardinality_cache:
- return self._objectcardinality_cache[ce]
-
p = ce.get_property()
assert isinstance(p, OWLObjectPropertyExpression)
@@ -871,14 +832,10 @@ def _get_instances_object_card_restriction(self, ce: OWLObjectCardinalityRestric
ind = self._find_some_values(p, filler_ind, min_count=min_count, max_count=max_count)
- self._objectcardinality_cache[ce] = ind
return ind
@_find_instances.register
def _(self, ce: OWLDataSomeValuesFrom) -> FrozenSet[OWLNamedIndividual]:
- if ce in self._datasomevalues_cache:
- return self._datasomevalues_cache[ce]
-
pe = ce.get_property()
filler = ce.get_filler()
assert isinstance(pe, OWLDataProperty)
@@ -967,7 +924,6 @@ def include(lv: OWLLiteral):
raise ValueError
r = frozenset(ind)
- self._datasomevalues_cache[ce] = r
return r
@_find_instances.register
@@ -1057,53 +1013,9 @@ def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"):
self._owlapi_manager = self.manager.get_owlapi_manager()
self._owlapi_ontology = self.ontology.get_owlapi_ontology()
- # super().__init__(self.ontology)
self.mapper = self.ontology.mapper
- from org.semanticweb.owlapi.util import (InferredClassAssertionAxiomGenerator, InferredSubClassAxiomGenerator,
- InferredEquivalentClassAxiomGenerator,
- InferredDisjointClassesAxiomGenerator,
- InferredEquivalentDataPropertiesAxiomGenerator,
- InferredEquivalentObjectPropertyAxiomGenerator,
- InferredInverseObjectPropertiesAxiomGenerator,
- InferredSubDataPropertyAxiomGenerator,
- InferredSubObjectPropertyAxiomGenerator,
- InferredDataPropertyCharacteristicAxiomGenerator,
- InferredObjectPropertyCharacteristicAxiomGenerator)
-
- self.inference_types_mapping = {"InferredClassAssertionAxiomGenerator": InferredClassAssertionAxiomGenerator(),
- "InferredSubClassAxiomGenerator": InferredSubClassAxiomGenerator(),
- "InferredDisjointClassesAxiomGenerator": InferredDisjointClassesAxiomGenerator(),
- "InferredEquivalentClassAxiomGenerator": InferredEquivalentClassAxiomGenerator(),
- "InferredInverseObjectPropertiesAxiomGenerator": InferredInverseObjectPropertiesAxiomGenerator(),
- "InferredEquivalentDataPropertiesAxiomGenerator": InferredEquivalentDataPropertiesAxiomGenerator(),
- "InferredEquivalentObjectPropertyAxiomGenerator": InferredEquivalentObjectPropertyAxiomGenerator(),
- "InferredSubDataPropertyAxiomGenerator": InferredSubDataPropertyAxiomGenerator(),
- "InferredSubObjectPropertyAxiomGenerator": InferredSubObjectPropertyAxiomGenerator(),
- "InferredDataPropertyCharacteristicAxiomGenerator": InferredDataPropertyCharacteristicAxiomGenerator(),
- "InferredObjectPropertyCharacteristicAxiomGenerator": InferredObjectPropertyCharacteristicAxiomGenerator(),
- }
-
- # () Create a reasoner using the ontology
- if reasoner == "HermiT":
- from org.semanticweb.HermiT import ReasonerFactory
- self._owlapi_reasoner = ReasonerFactory().createReasoner(self._owlapi_ontology)
- assert self._owlapi_reasoner.getReasonerName() == "HermiT"
- elif reasoner == "JFact":
- from uk.ac.manchester.cs.jfact import JFactFactory
- self._owlapi_reasoner = JFactFactory().createReasoner(self._owlapi_ontology)
- elif reasoner == "Pellet":
- from openllet.owlapi import PelletReasonerFactory
- self._owlapi_reasoner = PelletReasonerFactory().createReasoner(self._owlapi_ontology)
- elif reasoner == "Openllet":
- from openllet.owlapi import OpenlletReasonerFactory
- self._owlapi_reasoner = OpenlletReasonerFactory().getInstance().createReasoner(self._owlapi_ontology)
- elif reasoner == "Structural":
- from org.semanticweb.owlapi.reasoner.structural import StructuralReasonerFactory
- self._owlapi_reasoner = StructuralReasonerFactory().createReasoner(self._owlapi_ontology)
- else:
- raise NotImplementedError("Not implemented")
-
- self.reasoner = reasoner
+ self.inference_types_mapping = import_and_include_axioms_generators()
+ self._owlapi_reasoner = initialize_reasoner(reasoner,self._owlapi_ontology)
def _instances(self, ce: OWLClassExpression, direct=False) -> Set[OWLNamedIndividual]:
"""
@@ -1422,11 +1334,11 @@ def disjoint_data_properties(self, p: OWLDataProperty):
yield from [self.mapper.map_(pe) for pe in
self._owlapi_reasoner.getDisjointDataProperties(self.mapper.map_(p)).getFlattened()]
- def types(self, i: OWLNamedIndividual, direct: bool = False):
+ def types(self, individual: OWLNamedIndividual, direct: bool = False):
"""Gets the named classes which are (potentially direct) types of the specified named individual.
Args:
- i: The individual whose types are to be retrieved.
+ individual: The individual whose types are to be retrieved.
direct: Specifies if the direct types should be retrieved (True), or if all types should be retrieved
(False).
@@ -1436,7 +1348,7 @@ def types(self, i: OWLNamedIndividual, direct: bool = False):
entails ClassAssertion(C, ind).
"""
yield from [self.mapper.map_(ind) for ind in
- self._owlapi_reasoner.getTypes(self.mapper.map_(i), direct).getFlattened()]
+ self._owlapi_reasoner.getTypes(self.mapper.map_(individual), direct).getFlattened()]
def has_consistent_ontology(self) -> bool:
"""
@@ -1588,3 +1500,48 @@ def unsatisfiable_classes(self):
def get_root_ontology(self) -> AbstractOWLOntology:
return self.ontology
+
+def initialize_reasoner(reasoner:str, owlapi_ontology):
+ # () Create a reasoner using the ontology
+ if reasoner == "HermiT":
+ from org.semanticweb.HermiT import ReasonerFactory
+ owlapi_reasoner = ReasonerFactory().createReasoner(owlapi_ontology)
+ assert owlapi_reasoner.getReasonerName() == "HermiT"
+ elif reasoner == "JFact":
+ from uk.ac.manchester.cs.jfact import JFactFactory
+ owlapi_reasoner = JFactFactory().createReasoner(owlapi_ontology)
+ elif reasoner == "Pellet":
+ from openllet.owlapi import PelletReasonerFactory
+ owlapi_reasoner = PelletReasonerFactory().createReasoner(owlapi_ontology)
+ elif reasoner == "Openllet":
+ from openllet.owlapi import OpenlletReasonerFactory
+ owlapi_reasoner = OpenlletReasonerFactory().getInstance().createReasoner(owlapi_ontology)
+ elif reasoner == "Structural":
+ from org.semanticweb.owlapi.reasoner.structural import StructuralReasonerFactory
+ owlapi_reasoner = StructuralReasonerFactory().createReasoner(owlapi_ontology)
+ else:
+ raise NotImplementedError("Not implemented")
+ return owlapi_reasoner
+def import_and_include_axioms_generators():
+ from org.semanticweb.owlapi.util import (InferredClassAssertionAxiomGenerator, InferredSubClassAxiomGenerator,
+ InferredEquivalentClassAxiomGenerator,
+ InferredDisjointClassesAxiomGenerator,
+ InferredEquivalentDataPropertiesAxiomGenerator,
+ InferredEquivalentObjectPropertyAxiomGenerator,
+ InferredInverseObjectPropertiesAxiomGenerator,
+ InferredSubDataPropertyAxiomGenerator,
+ InferredSubObjectPropertyAxiomGenerator,
+ InferredDataPropertyCharacteristicAxiomGenerator,
+ InferredObjectPropertyCharacteristicAxiomGenerator)
+
+ return {"InferredClassAssertionAxiomGenerator": InferredClassAssertionAxiomGenerator(),
+ "InferredSubClassAxiomGenerator": InferredSubClassAxiomGenerator(),
+ "InferredDisjointClassesAxiomGenerator": InferredDisjointClassesAxiomGenerator(),
+ "InferredEquivalentClassAxiomGenerator": InferredEquivalentClassAxiomGenerator(),
+ "InferredInverseObjectPropertiesAxiomGenerator": InferredInverseObjectPropertiesAxiomGenerator(),
+ "InferredEquivalentDataPropertiesAxiomGenerator": InferredEquivalentDataPropertiesAxiomGenerator(),
+ "InferredEquivalentObjectPropertyAxiomGenerator": InferredEquivalentObjectPropertyAxiomGenerator(),
+ "InferredSubDataPropertyAxiomGenerator": InferredSubDataPropertyAxiomGenerator(),
+ "InferredSubObjectPropertyAxiomGenerator": InferredSubObjectPropertyAxiomGenerator(),
+ "InferredDataPropertyCharacteristicAxiomGenerator": InferredDataPropertyCharacteristicAxiomGenerator(),
+ "InferredObjectPropertyCharacteristicAxiomGenerator": InferredObjectPropertyCharacteristicAxiomGenerator()}
diff --git a/owlapy/util_owl_static_funcs.py b/owlapy/util_owl_static_funcs.py
new file mode 100644
index 00000000..20ee01e5
--- /dev/null
+++ b/owlapy/util_owl_static_funcs.py
@@ -0,0 +1,57 @@
+from .owl_ontology import Ontology
+from .owl_ontology_manager import OntologyManager
+from typing import List
+from .class_expression import OWLClassExpression, OWLClass
+from .iri import IRI
+from .owl_axiom import OWLEquivalentClassesAxiom
+
+def save_owl_class_expressions(expressions: OWLClassExpression | List[OWLClassExpression],
+ path: str = 'predictions',
+ rdf_format: str = 'rdfxml',
+ namespace:str=None) -> None:
+ """
+ Saves a set of OWL class expressions to an ontology file in RDF/XML format.
+
+ This function takes one or more OWL class expressions, creates an ontology,
+ and saves the expressions as OWL equivalent class axioms in the specified RDF format.
+ By default, it saves the file to the specified path using the 'rdfxml' format.
+
+ Args:
+ expressions (OWLClassExpression | List[OWLClassExpression]): A single or a list of OWL class expressions
+ to be saved as equivalent class axioms.
+ path (str, optional): The file path where the ontology will be saved. Defaults to 'predictions'.
+ rdf_format (str, optional): RDF serialization format for saving the ontology. Currently only
+ supports 'rdfxml'. Defaults to 'rdfxml'.
+ namespace (str, optional): The namespace URI used for the ontology. If None, defaults to
+ 'https://dice-research.org/predictions#'. Must end with '#'.
+
+ Raises:
+ AssertionError: If `expressions` is neither an OWLClassExpression nor a list of OWLClassExpression.
+ AssertionError: If `rdf_format` is not 'rdfxml'.
+ AssertionError: If `namespace` does not end with a '#'.
+
+ Example:
+ >>> from some_module import OWLClassExpression
+ >>> expr1 = OWLClassExpression("SomeExpression1")
+ >>> expr2 = OWLClassExpression("SomeExpression2")
+ >>> save_owl_class_expressions([expr1, expr2], path="my_ontology.owl", rdf_format="rdfxml")
+ """
+ assert isinstance(expressions, OWLClassExpression) or isinstance(expressions[0],
+ OWLClassExpression), "expressions must be either OWLClassExpression or a list of OWLClassExpression"
+ assert rdf_format == 'rdfxml', f'Format {rdf_format} not implemented. Please use rdfxml'
+
+ if isinstance(expressions, OWLClassExpression):
+ expressions = [expressions]
+
+ namespace= 'https://dice-research.org/predictions#' if namespace is None else namespace
+ assert "#" == namespace[-1], "namespace must end with #"
+ # ()
+ manager = OntologyManager()
+ # ()
+ ontology:Ontology = manager.create_ontology(namespace)
+ # () Iterate over concepts
+ for th, i in enumerate(expressions):
+ cls_a = OWLClass(IRI.create(namespace, str(th)))
+ equivalent_classes_axiom = OWLEquivalentClassesAxiom([cls_a, i])
+ ontology.add_axiom(equivalent_classes_axiom)
+ ontology.save(path=path, inplace=False, rdf_format=rdf_format)
\ No newline at end of file
diff --git a/setup.py b/setup.py
index bf8d39f5..e3e8e579 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
setup(
name="owlapy",
description="OWLAPY is a Python Framework for creating and manipulating OWL Ontologies.",
- version="1.3.2",
+ version="1.3.3",
packages=find_packages(),
include_package_data=True,
package_data={'owlapy': ['jar_dependencies/*.jar'],},
@@ -13,6 +13,7 @@
"pandas>=1.5.0",
"requests>=2.32.3",
"rdflib>=6.0.2",
+ "ruff>=0.7.2",
"parsimonious>=0.8.1",
"pytest>=8.1.1",
"sortedcontainers>=2.4.0",
diff --git a/tests/test_hashing.py b/tests/test_hashing.py
new file mode 100644
index 00000000..f30dfc72
--- /dev/null
+++ b/tests/test_hashing.py
@@ -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
\ No newline at end of file
diff --git a/tests/test_save_owl_expressions.py b/tests/test_save_owl_expressions.py
new file mode 100644
index 00000000..3beda87b
--- /dev/null
+++ b/tests/test_save_owl_expressions.py
@@ -0,0 +1,25 @@
+from owlapy.util_owl_static_funcs import save_owl_class_expressions
+from owlapy.class_expression import OWLClass, OWLObjectIntersectionOf, OWLObjectSomeValuesFrom
+from owlapy.owl_property import OWLObjectProperty
+from owlapy import owl_expression_to_sparql, owl_expression_to_dl
+from owlapy.owl_ontology_manager import OntologyManager
+from owlapy.owl_axiom import OWLDeclarationAxiom, OWLClassAssertionAxiom
+from owlapy.owl_individual import OWLNamedIndividual, IRI
+import rdflib
+
+class TestRunningExamples:
+ def test_readme(self):
+ # Using owl classes to create a complex class expression
+ male = OWLClass("http://example.com/society#male")
+ hasChild = OWLObjectProperty("http://example.com/society#hasChild")
+ hasChild_male = OWLObjectSomeValuesFrom(hasChild, male)
+ teacher = OWLClass("http://example.com/society#teacher")
+ teacher_that_hasChild_male = OWLObjectIntersectionOf([hasChild_male, teacher])
+
+ expressions= [male, teacher_that_hasChild_male]
+ save_owl_class_expressions(expressions=expressions,
+ namespace="https://ontolearn.org/predictions#",
+ path="owl_class_expressions.owl",
+ rdf_format= 'rdfxml')
+ g=rdflib.Graph().parse("owl_class_expressions.owl")
+ assert len(g)==22
\ No newline at end of file
diff --git a/tests/test_sync_ontology.py b/tests/test_sync_ontology.py
index c35d7462..f02c198e 100644
--- a/tests/test_sync_ontology.py
+++ b/tests/test_sync_ontology.py
@@ -80,6 +80,13 @@ class TestSyncReasoner(unittest.TestCase):
manager = SyncOntologyManager()
onto = manager.load_ontology(ontology_path)
+ def test_interface_father_dataset(self):
+ ontology_path = "KGs/Family/father.owl"
+ onto = SyncOntologyManager().load_ontology(ontology_path)
+ assert {owl_class.reminder for owl_class in onto.classes_in_signature()}=={'male', 'female', 'Thing', 'person'}
+ assert {individual.reminder for individual in onto.individuals_in_signature()}=={'markus', 'anna', 'martin', 'stefan', 'heinz', 'michelle'}
+ assert {object_property.reminder for object_property in onto.object_properties_in_signature()}=={'hasChild'}
+
# NOTE AB: The name of "assertCountEqual" may be misleading,but it's essentially an order-insensitive "assertEqual".
def test_classes_in_signature(self):
diff --git a/tests/test_sync_reasoner.py b/tests/test_sync_reasoner.py
index f45cb8a8..9b157457 100644
--- a/tests/test_sync_reasoner.py
+++ b/tests/test_sync_reasoner.py
@@ -3,7 +3,7 @@
from jpype import JDouble
from owlapy.class_expression import OWLClass, OWLDataSomeValuesFrom, OWLObjectIntersectionOf, OWLNothing, OWLThing, \
- OWLClassExpression, OWLObjectSomeValuesFrom
+ OWLClassExpression, OWLObjectSomeValuesFrom, OWLObjectOneOf
from owlapy.iri import IRI
from owlapy.owl_axiom import OWLDisjointClassesAxiom, OWLDeclarationAxiom, OWLClassAssertionAxiom, OWLSubClassOfAxiom, \
OWLEquivalentClassesAxiom, OWLSubDataPropertyOfAxiom, OWLSubObjectPropertyOfAxiom
@@ -15,6 +15,7 @@
from owlapy.owl_reasoner import SyncReasoner
from owlapy.providers import owl_datatype_min_inclusive_restriction
+
NS = 'http://www.semanticweb.org/stefan/ontologies/2023/1/untitled-ontology-11#'
a = OWLNamedIndividual(IRI(NS, "a"))
@@ -82,6 +83,26 @@ class TestSyncReasoner(unittest.TestCase):
ce = OWLObjectIntersectionOf([nitrogen38, has_charge_more_than_0_85])
reasoner = SyncReasoner(ontology_path)
+ def test_father_dataset(self):
+ ontology_path = "KGs/Family/father.owl"
+ # Available OWL Reasoners: 'HermiT', 'Pellet', 'JFact', 'Openllet'
+ 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")
+
+ for k, reasoner in owl_reasoners.items():
+ exist_haschild_female = OWLObjectSomeValuesFrom(
+ property=OWLObjectProperty('http://example.com/father#hasChild'),
+ filler=OWLClass('http://example.com/father#female'))
+
+ exist_haschild_anna = OWLObjectSomeValuesFrom(property=OWLObjectProperty('http://example.com/father#hasChild'),
+ filler=OWLObjectOneOf(
+ OWLNamedIndividual('http://example.com/father#anna')))
+ assert reasoner.instances(ce=exist_haschild_female) == reasoner.instances(ce=exist_haschild_anna) == {
+ OWLNamedIndividual('http://example.com/father#markus')}
+
def test_consistency_check(self):
self.assertEqual(self.reasoner.has_consistent_ontology(), True)