From c12c3a7b37000cb7c6a1199237ca9e11b65efd8c Mon Sep 17 00:00:00 2001 From: Alkid Date: Wed, 4 Sep 2024 15:05:47 +0200 Subject: [PATCH 1/9] moved reasoner abstract classes to new module --- owlapy/abstracts/abstract_owl_reasoner.py | 462 ++++++++++++++++++++++ owlapy/owl_hierarchy.py | 2 +- owlapy/owl_reasoner.py | 454 +-------------------- owlapy/render.py | 2 +- 4 files changed, 468 insertions(+), 452 deletions(-) create mode 100644 owlapy/abstracts/abstract_owl_reasoner.py diff --git a/owlapy/abstracts/abstract_owl_reasoner.py b/owlapy/abstracts/abstract_owl_reasoner.py new file mode 100644 index 00000000..8b7bcd07 --- /dev/null +++ b/owlapy/abstracts/abstract_owl_reasoner.py @@ -0,0 +1,462 @@ +"""OWL Reasoner""" +from abc import ABCMeta, abstractmethod +from typing import Iterable + + +from owlapy.class_expression import OWLClassExpression +from owlapy.class_expression import OWLClass +from owlapy.owl_data_ranges import OWLDataRange +from owlapy.owl_object import OWLEntity +from owlapy.owl_ontology import OWLOntology +from owlapy.owl_property import OWLObjectPropertyExpression, OWLDataProperty, OWLObjectProperty +from owlapy.owl_individual import OWLNamedIndividual +from owlapy.owl_literal import OWLLiteral + + +class OWLReasoner(metaclass=ABCMeta): + """An OWLReasoner reasons over a set of axioms (the set of reasoner axioms) that is based on the imports closure of + a particular ontology - the "root" ontology.""" + __slots__ = () + + @abstractmethod + def __init__(self, ontology: OWLOntology): + pass + + @abstractmethod + def data_property_domains(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLClassExpression]: + """Gets the class expressions that are the direct or indirect domains of this property with respect to the + imports closure of the root ontology. + + Args: + pe: The property expression whose domains are to be retrieved. + direct: Specifies if the direct domains should be retrieved (True), or if all domains should be retrieved + (False). + + Returns: + :Let N = equivalent_classes(DataSomeValuesFrom(pe rdfs:Literal)). If direct is True: then if N is not + empty then the return value is N, else the return value is the result of + super_classes(DataSomeValuesFrom(pe rdfs:Literal), true). If direct is False: then the result of + super_classes(DataSomeValuesFrom(pe rdfs:Literal), false) together with N if N is non-empty. + (Note, rdfs:Literal is the top datatype). + """ + pass + + @abstractmethod + def object_property_domains(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]: + """Gets the class expressions that are the direct or indirect domains of this property with respect to the + imports closure of the root ontology. + + Args: + pe: The property expression whose domains are to be retrieved. + direct: Specifies if the direct domains should be retrieved (True), or if all domains should be retrieved + (False). + + Returns: + :Let N = equivalent_classes(ObjectSomeValuesFrom(pe owl:Thing)). If direct is True: then if N is not empty + then the return value is N, else the return value is the result of + super_classes(ObjectSomeValuesFrom(pe owl:Thing), true). If direct is False: then the result of + super_classes(ObjectSomeValuesFrom(pe owl:Thing), false) together with N if N is non-empty. + """ + pass + + @abstractmethod + def object_property_ranges(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]: + """Gets the class expressions that are the direct or indirect ranges of this property with respect to the + imports closure of the root ontology. + + Args: + pe: The property expression whose ranges are to be retrieved. + direct: Specifies if the direct ranges should be retrieved (True), or if all ranges should be retrieved + (False). + + Returns: + :Let N = equivalent_classes(ObjectSomeValuesFrom(ObjectInverseOf(pe) owl:Thing)). If direct is True: then + if N is not empty then the return value is N, else the return value is the result of + super_classes(ObjectSomeValuesFrom(ObjectInverseOf(pe) owl:Thing), true). If direct is False: then + the result of super_classes(ObjectSomeValuesFrom(ObjectInverseOf(pe) owl:Thing), false) together with N + if N is non-empty. + """ + pass + + @abstractmethod + def equivalent_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]: + """Gets the class expressions that are equivalent to the specified class expression with respect to the set of + reasoner axioms. + + Args: + ce: The class expression whose equivalent classes are to be retrieved. + only_named: Whether to only retrieve named equivalent classes or also complex class expressions. + + Returns: + All class expressions C where the root ontology imports closure entails EquivalentClasses(ce C). If ce is + not a class name (i.e. it is an anonymous class expression) and there are no such classes C then there will + be no result. If ce is unsatisfiable with respect to the set of reasoner axioms then owl:Nothing, i.e. the + bottom node, will be returned. + """ + pass + + @abstractmethod + def disjoint_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]: + """Gets the class expressions that are disjoint with specified class expression with respect to the set of + reasoner axioms. + + Args: + ce: The class expression whose disjoint classes are to be retrieved. + only_named: Whether to only retrieve named disjoint classes or also complex class expressions. + + Returns: + All class expressions D where the set of reasoner axioms entails EquivalentClasses(D ObjectComplementOf(ce)) + or StrictSubClassOf(D ObjectComplementOf(ce)). + """ + pass + + @abstractmethod + def different_individuals(self, ind: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]: + """Gets the individuals that are different from the specified individual with respect to the set of + reasoner axioms. + + Args: + ind: The individual whose different individuals are to be retrieved. + + Returns: + All individuals x where the set of reasoner axioms entails DifferentIndividuals(ind x). + """ + pass + + @abstractmethod + def same_individuals(self, ind: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]: + """Gets the individuals that are the same as the specified individual with respect to the set of + reasoner axioms. + + Args: + ind: The individual whose same individuals are to be retrieved. + + Returns: + All individuals x where the root ontology imports closure entails SameIndividual(ind x). + """ + pass + + @abstractmethod + def equivalent_object_properties(self, op: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]: + """Gets the simplified object properties that are equivalent to the specified object property with respect + to the set of reasoner axioms. + + Args: + op: The object property whose equivalent object properties are to be retrieved. + + Returns: + All simplified object properties e where the root ontology imports closure entails + EquivalentObjectProperties(op e). If op is unsatisfiable with respect to the set of reasoner axioms + then owl:bottomDataProperty will be returned. + """ + pass + + @abstractmethod + def equivalent_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]: + """Gets the data properties that are equivalent to the specified data property with respect to the set of + reasoner axioms. + + Args: + dp: The data property whose equivalent data properties are to be retrieved. + + Returns: + All data properties e where the root ontology imports closure entails EquivalentDataProperties(dp e). + If dp is unsatisfiable with respect to the set of reasoner axioms then owl:bottomDataProperty will + be returned. + """ + pass + + @abstractmethod + def data_property_values(self, e: OWLEntity, pe: OWLDataProperty, direct: bool = True) \ + -> Iterable['OWLLiteral']: + """Gets the data property values for the specified entity and data property expression. + + Args: + e: The owl entity (usually an individual) that is the subject of the data property values. + pe: The data property expression whose values are to be retrieved for the specified entity. + direct: Specifies if the direct values should be retrieved (True), or if all values should be retrieved + (False), so that sub properties are taken into account. + + Note: Can be used to get values, for example, of 'label' property of owl entities such as classes and properties + too (not only individuals). + + Returns: + A set of OWLLiterals containing literals such that for each literal l in the set, the set of reasoner + axioms entails DataPropertyAssertion(pe ind l). + """ + pass + + @abstractmethod + def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyExpression, direct: bool = True) \ + -> Iterable[OWLNamedIndividual]: + """Gets the object property values for the specified individual and object property expression. + + Args: + ind: The individual that is the subject of the object property values. + pe: The object property expression whose values are to be retrieved for the specified individual. + direct: Specifies if the direct values should be retrieved (True), or if all values should be retrieved + (False), so that sub properties are taken into account. + + Returns: + The named individuals such that for each individual j, the set of reasoner axioms entails + ObjectPropertyAssertion(pe ind j). + """ + pass + + @abstractmethod + def instances(self, ce: OWLClassExpression, direct: bool = False) -> Iterable[OWLNamedIndividual]: + """Gets the individuals which are instances of the specified class expression. + + Args: + ce: The class expression whose instances are to be retrieved. + direct: Specifies if the direct instances should be retrieved (True), or if all instances should be + retrieved (False). + + Returns: + If direct is True, each named individual j where the set of reasoner axioms entails + DirectClassAssertion(ce, j). If direct is False, each named individual j where the set of reasoner axioms + entails ClassAssertion(ce, j). If ce is unsatisfiable with respect to the set of reasoner axioms then + nothing returned. + """ + pass + + @abstractmethod + def sub_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \ + -> Iterable[OWLClassExpression]: + """Gets the set of named classes that are the strict (potentially direct) subclasses of the specified class + expression with respect to the reasoner axioms. + + Args: + ce: The class expression whose strict (direct) subclasses are to be retrieved. + direct: Specifies if the direct subclasses should be retrieved (True) or if the all subclasses + (descendant) classes should be retrieved (False). + only_named: Whether to only retrieve named sub-classes or also complex class expressions. + + Returns: + If direct is True, each class C where reasoner axioms entails DirectSubClassOf(C, ce). If direct is False, + each class C where reasoner axioms entails StrictSubClassOf(C, ce). If ce is equivalent to owl:Nothing then + nothing will be returned. + """ + pass + + @abstractmethod + def disjoint_object_properties(self, op: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]: + """Gets the simplified object properties that are disjoint with the specified object property with respect + to the set of reasoner axioms. + + Args: + op: The object property whose disjoint object properties are to be retrieved. + + Returns: + All simplified object properties e where the root ontology imports closure entails + EquivalentObjectProperties(e ObjectPropertyComplementOf(op)) or + StrictSubObjectPropertyOf(e ObjectPropertyComplementOf(op)). + """ + pass + + @abstractmethod + def disjoint_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]: + """Gets the data properties that are disjoint with the specified data property with respect + to the set of reasoner axioms. + + Args: + dp: The data property whose disjoint data properties are to be retrieved. + + Returns: + All data properties e where the root ontology imports closure entails + EquivalentDataProperties(e DataPropertyComplementOf(dp)) or + StrictSubDataPropertyOf(e DataPropertyComplementOf(dp)). + """ + pass + + @abstractmethod + def sub_data_properties(self, dp: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataProperty]: + """Gets the set of named data properties that are the strict (potentially direct) subproperties of the + specified data property expression with respect to the imports closure of the root ontology. + + Args: + dp: The data property whose strict (direct) subproperties are to be retrieved. + direct: Specifies if the direct subproperties should be retrieved (True) or if the all subproperties + (descendants) should be retrieved (False). + + Returns: + If direct is True, each property P where the set of reasoner axioms entails DirectSubDataPropertyOf(P, pe). + If direct is False, each property P where the set of reasoner axioms entails + StrictSubDataPropertyOf(P, pe). If pe is equivalent to owl:bottomDataProperty then nothing will be + returned. + """ + pass + + @abstractmethod + def super_data_properties(self, dp: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataProperty]: + """Gets the stream of data properties that are the strict (potentially direct) super properties of the + specified data property with respect to the imports closure of the root ontology. + + Args: + dp (OWLDataProperty): The data property whose super properties are to be retrieved. + direct (bool): Specifies if the direct super properties should be retrieved (True) or if the all + super properties (ancestors) should be retrieved (False). + + Returns: + Iterable of super properties. + """ + pass + + @abstractmethod + def sub_object_properties(self, op: OWLObjectPropertyExpression, direct: bool = False) \ + -> Iterable[OWLObjectPropertyExpression]: + """Gets the stream of simplified object property expressions that are the strict (potentially direct) + subproperties of the specified object property expression with respect to the imports closure of the root + ontology. + + Args: + op: The object property expression whose strict (direct) subproperties are to be retrieved. + direct: Specifies if the direct subproperties should be retrieved (True) or if the all subproperties + (descendants) should be retrieved (False). + + Returns: + If direct is True, simplified object property expressions, such that for each simplified object property + expression, P, the set of reasoner axioms entails DirectSubObjectPropertyOf(P, pe). + If direct is False, simplified object property expressions, such that for each simplified object property + expression, P, the set of reasoner axioms entails StrictSubObjectPropertyOf(P, pe). + If pe is equivalent to owl:bottomObjectProperty then nothing will be returned. + """ + pass + + @abstractmethod + def super_object_properties(self, op: OWLObjectPropertyExpression, direct: bool = False) \ + -> Iterable[OWLObjectPropertyExpression]: + """Gets the stream of object properties that are the strict (potentially direct) super properties of the + specified object property with respect to the imports closure of the root ontology. + + Args: + op (OWLObjectPropertyExpression): The object property expression whose super properties are to be + retrieved. + direct (bool): Specifies if the direct super properties should be retrieved (True) or if the all + super properties (ancestors) should be retrieved (False). + + Returns: + Iterable of super properties. + """ + pass + + @abstractmethod + def types(self, ind: OWLNamedIndividual, direct: bool = False) -> Iterable[OWLClass]: + """Gets the named classes which are (potentially direct) types of the specified named individual. + + Args: + ind: 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). + + Returns: + If direct is True, each named class C where the set of reasoner axioms entails + DirectClassAssertion(C, ind). If direct is False, each named class C where the set of reasoner axioms + entails ClassAssertion(C, ind). + """ + pass + + @abstractmethod + def get_root_ontology(self) -> OWLOntology: + """Gets the "root" ontology that is loaded into this reasoner. The reasoner takes into account the axioms in + this ontology and its import's closure.""" + pass + + @abstractmethod + def super_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \ + -> Iterable[OWLClassExpression]: + """Gets the stream of named classes that are the strict (potentially direct) super classes of the specified + class expression with respect to the imports closure of the root ontology. + + Args: + ce: The class expression whose strict (direct) super classes are to be retrieved. + direct: Specifies if the direct super classes should be retrieved (True) or if the all super classes + (ancestors) classes should be retrieved (False). + only_named: Whether to only retrieve named super classes or also complex class expressions. + + Returns: + If direct is True, each class C where the set of reasoner axioms entails DirectSubClassOf(ce, C). + If direct is False, each class C where set of reasoner axioms entails StrictSubClassOf(ce, C). + If ce is equivalent to owl:Thing then nothing will be returned. + """ + pass +class OWLReasonerEx(OWLReasoner, metaclass=ABCMeta): + """Extra convenience methods for OWL Reasoners""" + + # default + def data_property_ranges(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataRange]: + """Gets the data ranges that are the direct or indirect ranges of this property with respect to the imports + closure of the root ontology. + + Args: + pe: The property expression whose ranges are to be retrieved. + direct: Specifies if the direct ranges should be retrieved (True), or if all ranges should be retrieved + (False). + + Returns: + """ + for ax in self.get_root_ontology().data_property_range_axioms(pe): + yield ax.get_range() + if not direct: + logger.warning("indirect not implemented") + # TODO: + + # default + def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> Iterable[OWLLiteral]: + """Gets all values for the given data property expression that appear in the knowledge base. + + Args: + pe: The data property expression whose values are to be retrieved + direct: Specifies if only the direct values of the data property pe should be retrieved (True), or if + the values of sub properties of pe should be taken into account (False). + + Returns: + A set of OWLLiterals containing literals such that for each literal l in the set, the set of reasoner + axioms entails DataPropertyAssertion(pe ind l) for any ind. + """ + onto = self.get_root_ontology() + for ind in onto.individuals_in_signature(): + for lit in self.data_property_values(ind, pe, direct): + yield lit + + # default + def ind_data_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> Iterable[OWLDataProperty]: + """Gets all data properties for the given individual that appear in the knowledge base. + + Args: + ind: The named individual whose data properties are to be retrieved + direct: Specifies if the direct data properties should be retrieved (True), or if all + data properties should be retrieved (False), so that sub properties are taken into account. + + Returns: + All data properties pe where the set of reasoner axioms entails DataPropertyAssertion(pe ind l) + for atleast one l. + """ + onto = self.get_root_ontology() + for dp in onto.data_properties_in_signature(): + try: + next(iter(self.data_property_values(ind, dp, direct))) + yield dp + except StopIteration: + pass + + # default + def ind_object_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> Iterable[OWLObjectProperty]: + """Gets all object properties for the given individual that appear in the knowledge base. + + Args: + ind: The named individual whose object properties are to be retrieved + direct: Specifies if the direct object properties should be retrieved (True), or if all + object properties should be retrieved (False), so that sub properties are taken into account. + + Returns: + All data properties pe where the set of reasoner axioms entails ObjectPropertyAssertion(pe ind ind2) + for atleast one ind2. + """ + onto = self.get_root_ontology() + for op in onto.object_properties_in_signature(): + try: + next(iter(self.object_property_values(ind, op, direct))) + yield op + except StopIteration: + pass \ No newline at end of file diff --git a/owlapy/owl_hierarchy.py b/owlapy/owl_hierarchy.py index 108e35db..3cc2b8be 100644 --- a/owlapy/owl_hierarchy.py +++ b/owlapy/owl_hierarchy.py @@ -9,7 +9,7 @@ from owlapy.meta_classes import HasIRI from owlapy.owl_literal import OWLTopObjectProperty, OWLBottomObjectProperty, OWLTopDataProperty, OWLBottomDataProperty from owlapy.owl_property import OWLObjectProperty, OWLDataProperty -from owlapy.owl_reasoner import OWLReasoner +from owlapy.abstracts.abstract_owl_reasoner import OWLReasoner _S = TypeVar('_S', bound=HasIRI) #: _U = TypeVar('_U', bound='AbstractHierarchy') #: diff --git a/owlapy/owl_reasoner.py b/owlapy/owl_reasoner.py index e9e7ff24..9c2b708f 100644 --- a/owlapy/owl_reasoner.py +++ b/owlapy/owl_reasoner.py @@ -1,14 +1,13 @@ """OWL Reasoner""" import operator -from abc import ABCMeta, abstractmethod +import logging +import owlready2 + from collections import defaultdict from functools import singledispatchmethod, reduce from itertools import chain, repeat from types import MappingProxyType, FunctionType from typing import DefaultDict, Iterable, Dict, Mapping, Set, Type, TypeVar, Optional, FrozenSet, List, Union -import logging - -import owlready2 from owlapy.class_expression import OWLClassExpression, OWLObjectSomeValuesFrom, OWLObjectUnionOf, \ OWLObjectIntersectionOf, OWLObjectComplementOf, OWLObjectAllValuesFrom, OWLObjectOneOf, OWLObjectHasValue, \ @@ -28,6 +27,7 @@ from owlapy.owl_individual import OWLNamedIndividual from owlapy.owl_literal import OWLLiteral from owlapy.utils import LRUCache +from owlapy.abstracts.abstract_owl_reasoner import OWLReasoner, OWLReasonerEx logger = logging.getLogger(__name__) @@ -37,453 +37,7 @@ # TODO:CD: An instance cannot be created from those classes. # TODO:CD: We should move those Abstract Base Classes into a respective package, e.g. # TODO:CD: owlapy/abstract_owl_reasoner/abstract_owl_reasoner.py should contain OWLReasoner and OWLReasonerEx -class OWLReasoner(metaclass=ABCMeta): - """An OWLReasoner reasons over a set of axioms (the set of reasoner axioms) that is based on the imports closure of - a particular ontology - the "root" ontology.""" - __slots__ = () - - @abstractmethod - def __init__(self, ontology: OWLOntology): - pass - - @abstractmethod - def data_property_domains(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLClassExpression]: - """Gets the class expressions that are the direct or indirect domains of this property with respect to the - imports closure of the root ontology. - - Args: - pe: The property expression whose domains are to be retrieved. - direct: Specifies if the direct domains should be retrieved (True), or if all domains should be retrieved - (False). - - Returns: - :Let N = equivalent_classes(DataSomeValuesFrom(pe rdfs:Literal)). If direct is True: then if N is not - empty then the return value is N, else the return value is the result of - super_classes(DataSomeValuesFrom(pe rdfs:Literal), true). If direct is False: then the result of - super_classes(DataSomeValuesFrom(pe rdfs:Literal), false) together with N if N is non-empty. - (Note, rdfs:Literal is the top datatype). - """ - pass - - @abstractmethod - def object_property_domains(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]: - """Gets the class expressions that are the direct or indirect domains of this property with respect to the - imports closure of the root ontology. - - Args: - pe: The property expression whose domains are to be retrieved. - direct: Specifies if the direct domains should be retrieved (True), or if all domains should be retrieved - (False). - - Returns: - :Let N = equivalent_classes(ObjectSomeValuesFrom(pe owl:Thing)). If direct is True: then if N is not empty - then the return value is N, else the return value is the result of - super_classes(ObjectSomeValuesFrom(pe owl:Thing), true). If direct is False: then the result of - super_classes(ObjectSomeValuesFrom(pe owl:Thing), false) together with N if N is non-empty. - """ - pass - - @abstractmethod - def object_property_ranges(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]: - """Gets the class expressions that are the direct or indirect ranges of this property with respect to the - imports closure of the root ontology. - - Args: - pe: The property expression whose ranges are to be retrieved. - direct: Specifies if the direct ranges should be retrieved (True), or if all ranges should be retrieved - (False). - - Returns: - :Let N = equivalent_classes(ObjectSomeValuesFrom(ObjectInverseOf(pe) owl:Thing)). If direct is True: then - if N is not empty then the return value is N, else the return value is the result of - super_classes(ObjectSomeValuesFrom(ObjectInverseOf(pe) owl:Thing), true). If direct is False: then - the result of super_classes(ObjectSomeValuesFrom(ObjectInverseOf(pe) owl:Thing), false) together with N - if N is non-empty. - """ - pass - - @abstractmethod - def equivalent_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]: - """Gets the class expressions that are equivalent to the specified class expression with respect to the set of - reasoner axioms. - - Args: - ce: The class expression whose equivalent classes are to be retrieved. - only_named: Whether to only retrieve named equivalent classes or also complex class expressions. - - Returns: - All class expressions C where the root ontology imports closure entails EquivalentClasses(ce C). If ce is - not a class name (i.e. it is an anonymous class expression) and there are no such classes C then there will - be no result. If ce is unsatisfiable with respect to the set of reasoner axioms then owl:Nothing, i.e. the - bottom node, will be returned. - """ - pass - - @abstractmethod - def disjoint_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]: - """Gets the class expressions that are disjoint with specified class expression with respect to the set of - reasoner axioms. - - Args: - ce: The class expression whose disjoint classes are to be retrieved. - only_named: Whether to only retrieve named disjoint classes or also complex class expressions. - - Returns: - All class expressions D where the set of reasoner axioms entails EquivalentClasses(D ObjectComplementOf(ce)) - or StrictSubClassOf(D ObjectComplementOf(ce)). - """ - pass - - @abstractmethod - def different_individuals(self, ind: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]: - """Gets the individuals that are different from the specified individual with respect to the set of - reasoner axioms. - - Args: - ind: The individual whose different individuals are to be retrieved. - - Returns: - All individuals x where the set of reasoner axioms entails DifferentIndividuals(ind x). - """ - pass - - @abstractmethod - def same_individuals(self, ind: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]: - """Gets the individuals that are the same as the specified individual with respect to the set of - reasoner axioms. - - Args: - ind: The individual whose same individuals are to be retrieved. - - Returns: - All individuals x where the root ontology imports closure entails SameIndividual(ind x). - """ - pass - - @abstractmethod - def equivalent_object_properties(self, op: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]: - """Gets the simplified object properties that are equivalent to the specified object property with respect - to the set of reasoner axioms. - - Args: - op: The object property whose equivalent object properties are to be retrieved. - - Returns: - All simplified object properties e where the root ontology imports closure entails - EquivalentObjectProperties(op e). If op is unsatisfiable with respect to the set of reasoner axioms - then owl:bottomDataProperty will be returned. - """ - pass - - @abstractmethod - def equivalent_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]: - """Gets the data properties that are equivalent to the specified data property with respect to the set of - reasoner axioms. - - Args: - dp: The data property whose equivalent data properties are to be retrieved. - - Returns: - All data properties e where the root ontology imports closure entails EquivalentDataProperties(dp e). - If dp is unsatisfiable with respect to the set of reasoner axioms then owl:bottomDataProperty will - be returned. - """ - pass - - @abstractmethod - def data_property_values(self, e: OWLEntity, pe: OWLDataProperty, direct: bool = True) \ - -> Iterable['OWLLiteral']: - """Gets the data property values for the specified entity and data property expression. - - Args: - e: The owl entity (usually an individual) that is the subject of the data property values. - pe: The data property expression whose values are to be retrieved for the specified entity. - direct: Specifies if the direct values should be retrieved (True), or if all values should be retrieved - (False), so that sub properties are taken into account. - - Note: Can be used to get values, for example, of 'label' property of owl entities such as classes and properties - too (not only individuals). - - Returns: - A set of OWLLiterals containing literals such that for each literal l in the set, the set of reasoner - axioms entails DataPropertyAssertion(pe ind l). - """ - pass - - @abstractmethod - def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyExpression, direct: bool = True) \ - -> Iterable[OWLNamedIndividual]: - """Gets the object property values for the specified individual and object property expression. - - Args: - ind: The individual that is the subject of the object property values. - pe: The object property expression whose values are to be retrieved for the specified individual. - direct: Specifies if the direct values should be retrieved (True), or if all values should be retrieved - (False), so that sub properties are taken into account. - - Returns: - The named individuals such that for each individual j, the set of reasoner axioms entails - ObjectPropertyAssertion(pe ind j). - """ - pass - - @abstractmethod - def instances(self, ce: OWLClassExpression, direct: bool = False) -> Iterable[OWLNamedIndividual]: - """Gets the individuals which are instances of the specified class expression. - - Args: - ce: The class expression whose instances are to be retrieved. - direct: Specifies if the direct instances should be retrieved (True), or if all instances should be - retrieved (False). - - Returns: - If direct is True, each named individual j where the set of reasoner axioms entails - DirectClassAssertion(ce, j). If direct is False, each named individual j where the set of reasoner axioms - entails ClassAssertion(ce, j). If ce is unsatisfiable with respect to the set of reasoner axioms then - nothing returned. - """ - pass - @abstractmethod - def sub_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \ - -> Iterable[OWLClassExpression]: - """Gets the set of named classes that are the strict (potentially direct) subclasses of the specified class - expression with respect to the reasoner axioms. - - Args: - ce: The class expression whose strict (direct) subclasses are to be retrieved. - direct: Specifies if the direct subclasses should be retrieved (True) or if the all subclasses - (descendant) classes should be retrieved (False). - only_named: Whether to only retrieve named sub-classes or also complex class expressions. - - Returns: - If direct is True, each class C where reasoner axioms entails DirectSubClassOf(C, ce). If direct is False, - each class C where reasoner axioms entails StrictSubClassOf(C, ce). If ce is equivalent to owl:Nothing then - nothing will be returned. - """ - pass - - @abstractmethod - def disjoint_object_properties(self, op: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]: - """Gets the simplified object properties that are disjoint with the specified object property with respect - to the set of reasoner axioms. - - Args: - op: The object property whose disjoint object properties are to be retrieved. - - Returns: - All simplified object properties e where the root ontology imports closure entails - EquivalentObjectProperties(e ObjectPropertyComplementOf(op)) or - StrictSubObjectPropertyOf(e ObjectPropertyComplementOf(op)). - """ - pass - - @abstractmethod - def disjoint_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]: - """Gets the data properties that are disjoint with the specified data property with respect - to the set of reasoner axioms. - - Args: - dp: The data property whose disjoint data properties are to be retrieved. - - Returns: - All data properties e where the root ontology imports closure entails - EquivalentDataProperties(e DataPropertyComplementOf(dp)) or - StrictSubDataPropertyOf(e DataPropertyComplementOf(dp)). - """ - pass - - @abstractmethod - def sub_data_properties(self, dp: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataProperty]: - """Gets the set of named data properties that are the strict (potentially direct) subproperties of the - specified data property expression with respect to the imports closure of the root ontology. - - Args: - dp: The data property whose strict (direct) subproperties are to be retrieved. - direct: Specifies if the direct subproperties should be retrieved (True) or if the all subproperties - (descendants) should be retrieved (False). - - Returns: - If direct is True, each property P where the set of reasoner axioms entails DirectSubDataPropertyOf(P, pe). - If direct is False, each property P where the set of reasoner axioms entails - StrictSubDataPropertyOf(P, pe). If pe is equivalent to owl:bottomDataProperty then nothing will be - returned. - """ - pass - - @abstractmethod - def super_data_properties(self, dp: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataProperty]: - """Gets the stream of data properties that are the strict (potentially direct) super properties of the - specified data property with respect to the imports closure of the root ontology. - - Args: - dp (OWLDataProperty): The data property whose super properties are to be retrieved. - direct (bool): Specifies if the direct super properties should be retrieved (True) or if the all - super properties (ancestors) should be retrieved (False). - - Returns: - Iterable of super properties. - """ - pass - - @abstractmethod - def sub_object_properties(self, op: OWLObjectPropertyExpression, direct: bool = False) \ - -> Iterable[OWLObjectPropertyExpression]: - """Gets the stream of simplified object property expressions that are the strict (potentially direct) - subproperties of the specified object property expression with respect to the imports closure of the root - ontology. - - Args: - op: The object property expression whose strict (direct) subproperties are to be retrieved. - direct: Specifies if the direct subproperties should be retrieved (True) or if the all subproperties - (descendants) should be retrieved (False). - - Returns: - If direct is True, simplified object property expressions, such that for each simplified object property - expression, P, the set of reasoner axioms entails DirectSubObjectPropertyOf(P, pe). - If direct is False, simplified object property expressions, such that for each simplified object property - expression, P, the set of reasoner axioms entails StrictSubObjectPropertyOf(P, pe). - If pe is equivalent to owl:bottomObjectProperty then nothing will be returned. - """ - pass - - @abstractmethod - def super_object_properties(self, op: OWLObjectPropertyExpression, direct: bool = False) \ - -> Iterable[OWLObjectPropertyExpression]: - """Gets the stream of object properties that are the strict (potentially direct) super properties of the - specified object property with respect to the imports closure of the root ontology. - - Args: - op (OWLObjectPropertyExpression): The object property expression whose super properties are to be - retrieved. - direct (bool): Specifies if the direct super properties should be retrieved (True) or if the all - super properties (ancestors) should be retrieved (False). - - Returns: - Iterable of super properties. - """ - pass - - @abstractmethod - def types(self, ind: OWLNamedIndividual, direct: bool = False) -> Iterable[OWLClass]: - """Gets the named classes which are (potentially direct) types of the specified named individual. - - Args: - ind: 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). - - Returns: - If direct is True, each named class C where the set of reasoner axioms entails - DirectClassAssertion(C, ind). If direct is False, each named class C where the set of reasoner axioms - entails ClassAssertion(C, ind). - """ - pass - - @abstractmethod - def get_root_ontology(self) -> OWLOntology: - """Gets the "root" ontology that is loaded into this reasoner. The reasoner takes into account the axioms in - this ontology and its import's closure.""" - pass - - @abstractmethod - def super_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \ - -> Iterable[OWLClassExpression]: - """Gets the stream of named classes that are the strict (potentially direct) super classes of the specified - class expression with respect to the imports closure of the root ontology. - - Args: - ce: The class expression whose strict (direct) super classes are to be retrieved. - direct: Specifies if the direct super classes should be retrieved (True) or if the all super classes - (ancestors) classes should be retrieved (False). - only_named: Whether to only retrieve named super classes or also complex class expressions. - - Returns: - If direct is True, each class C where the set of reasoner axioms entails DirectSubClassOf(ce, C). - If direct is False, each class C where set of reasoner axioms entails StrictSubClassOf(ce, C). - If ce is equivalent to owl:Thing then nothing will be returned. - """ - pass -class OWLReasonerEx(OWLReasoner, metaclass=ABCMeta): - """Extra convenience methods for OWL Reasoners""" - - # default - def data_property_ranges(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataRange]: - """Gets the data ranges that are the direct or indirect ranges of this property with respect to the imports - closure of the root ontology. - - Args: - pe: The property expression whose ranges are to be retrieved. - direct: Specifies if the direct ranges should be retrieved (True), or if all ranges should be retrieved - (False). - - Returns: - """ - for ax in self.get_root_ontology().data_property_range_axioms(pe): - yield ax.get_range() - if not direct: - logger.warning("indirect not implemented") - # TODO: - - # default - def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> Iterable[OWLLiteral]: - """Gets all values for the given data property expression that appear in the knowledge base. - - Args: - pe: The data property expression whose values are to be retrieved - direct: Specifies if only the direct values of the data property pe should be retrieved (True), or if - the values of sub properties of pe should be taken into account (False). - - Returns: - A set of OWLLiterals containing literals such that for each literal l in the set, the set of reasoner - axioms entails DataPropertyAssertion(pe ind l) for any ind. - """ - onto = self.get_root_ontology() - for ind in onto.individuals_in_signature(): - for lit in self.data_property_values(ind, pe, direct): - yield lit - - # default - def ind_data_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> Iterable[OWLDataProperty]: - """Gets all data properties for the given individual that appear in the knowledge base. - - Args: - ind: The named individual whose data properties are to be retrieved - direct: Specifies if the direct data properties should be retrieved (True), or if all - data properties should be retrieved (False), so that sub properties are taken into account. - - Returns: - All data properties pe where the set of reasoner axioms entails DataPropertyAssertion(pe ind l) - for atleast one l. - """ - onto = self.get_root_ontology() - for dp in onto.data_properties_in_signature(): - try: - next(iter(self.data_property_values(ind, dp, direct))) - yield dp - except StopIteration: - pass - - # default - def ind_object_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> Iterable[OWLObjectProperty]: - """Gets all object properties for the given individual that appear in the knowledge base. - - Args: - ind: The named individual whose object properties are to be retrieved - direct: Specifies if the direct object properties should be retrieved (True), or if all - object properties should be retrieved (False), so that sub properties are taken into account. - - Returns: - All data properties pe where the set of reasoner axioms entails ObjectPropertyAssertion(pe ind ind2) - for atleast one ind2. - """ - onto = self.get_root_ontology() - for op in onto.object_properties_in_signature(): - try: - next(iter(self.object_property_values(ind, op, direct))) - yield op - except StopIteration: - pass class OntologyReasoner(OWLReasonerEx): __slots__ = '_ontology', '_world' diff --git a/owlapy/render.py b/owlapy/render.py index 4658886c..0e30bb6d 100644 --- a/owlapy/render.py +++ b/owlapy/render.py @@ -20,7 +20,7 @@ from .owl_data_ranges import OWLNaryDataRange, OWLDataComplementOf, OWLDataUnionOf, OWLDataIntersectionOf from .class_expression import OWLObjectHasValue, OWLFacetRestriction, OWLDatatypeRestriction, OWLObjectOneOf from .owl_datatype import OWLDatatype -from .owl_reasoner import OWLReasoner +from .abstracts.abstract_owl_reasoner import OWLReasoner import requests import warnings import abc From e48c25df19bb72aea5f78137f6451cec05dfbac9 Mon Sep 17 00:00:00 2001 From: Alkid Date: Mon, 9 Sep 2024 15:06:16 +0200 Subject: [PATCH 2/9] removed optional arguments from abstract methods of OWLReasoner --- owlapy/abstracts/abstract_owl_reasoner.py | 37 +++++++++-------------- owlapy/owl_reasoner.py | 14 +++------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/owlapy/abstracts/abstract_owl_reasoner.py b/owlapy/abstracts/abstract_owl_reasoner.py index 8b7bcd07..c70ca218 100644 --- a/owlapy/abstracts/abstract_owl_reasoner.py +++ b/owlapy/abstracts/abstract_owl_reasoner.py @@ -1,7 +1,7 @@ """OWL Reasoner""" from abc import ABCMeta, abstractmethod from typing import Iterable - +import logging from owlapy.class_expression import OWLClassExpression from owlapy.class_expression import OWLClass @@ -12,6 +12,8 @@ from owlapy.owl_individual import OWLNamedIndividual from owlapy.owl_literal import OWLLiteral +logger = logging.getLogger(__name__) + class OWLReasoner(metaclass=ABCMeta): """An OWLReasoner reasons over a set of axioms (the set of reasoner axioms) that is based on the imports closure of @@ -79,13 +81,12 @@ def object_property_ranges(self, pe: OWLObjectProperty, direct: bool = False) -> pass @abstractmethod - def equivalent_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]: + def equivalent_classes(self, ce: OWLClassExpression) -> Iterable[OWLClassExpression]: """Gets the class expressions that are equivalent to the specified class expression with respect to the set of reasoner axioms. Args: ce: The class expression whose equivalent classes are to be retrieved. - only_named: Whether to only retrieve named equivalent classes or also complex class expressions. Returns: All class expressions C where the root ontology imports closure entails EquivalentClasses(ce C). If ce is @@ -96,13 +97,12 @@ def equivalent_classes(self, ce: OWLClassExpression, only_named: bool = True) -> pass @abstractmethod - def disjoint_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]: + def disjoint_classes(self, ce: OWLClassExpression) -> Iterable[OWLClassExpression]: """Gets the class expressions that are disjoint with specified class expression with respect to the set of reasoner axioms. Args: ce: The class expression whose disjoint classes are to be retrieved. - only_named: Whether to only retrieve named disjoint classes or also complex class expressions. Returns: All class expressions D where the set of reasoner axioms entails EquivalentClasses(D ObjectComplementOf(ce)) @@ -167,15 +167,13 @@ def equivalent_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataPro pass @abstractmethod - def data_property_values(self, e: OWLEntity, pe: OWLDataProperty, direct: bool = True) \ + def data_property_values(self, e: OWLEntity, pe: OWLDataProperty) \ -> Iterable['OWLLiteral']: """Gets the data property values for the specified entity and data property expression. Args: e: The owl entity (usually an individual) that is the subject of the data property values. pe: The data property expression whose values are to be retrieved for the specified entity. - direct: Specifies if the direct values should be retrieved (True), or if all values should be retrieved - (False), so that sub properties are taken into account. Note: Can be used to get values, for example, of 'label' property of owl entities such as classes and properties too (not only individuals). @@ -187,15 +185,13 @@ def data_property_values(self, e: OWLEntity, pe: OWLDataProperty, direct: bool = pass @abstractmethod - def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyExpression, direct: bool = True) \ + def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyExpression) \ -> Iterable[OWLNamedIndividual]: """Gets the object property values for the specified individual and object property expression. Args: ind: The individual that is the subject of the object property values. pe: The object property expression whose values are to be retrieved for the specified individual. - direct: Specifies if the direct values should be retrieved (True), or if all values should be retrieved - (False), so that sub properties are taken into account. Returns: The named individuals such that for each individual j, the set of reasoner axioms entails @@ -221,7 +217,7 @@ def instances(self, ce: OWLClassExpression, direct: bool = False) -> Iterable[OW pass @abstractmethod - def sub_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \ + def sub_classes(self, ce: OWLClassExpression, direct: bool = False) \ -> Iterable[OWLClassExpression]: """Gets the set of named classes that are the strict (potentially direct) subclasses of the specified class expression with respect to the reasoner axioms. @@ -230,7 +226,6 @@ def sub_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: ce: The class expression whose strict (direct) subclasses are to be retrieved. direct: Specifies if the direct subclasses should be retrieved (True) or if the all subclasses (descendant) classes should be retrieved (False). - only_named: Whether to only retrieve named sub-classes or also complex class expressions. Returns: If direct is True, each class C where reasoner axioms entails DirectSubClassOf(C, ce). If direct is False, @@ -363,7 +358,7 @@ def get_root_ontology(self) -> OWLOntology: pass @abstractmethod - def super_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \ + def super_classes(self, ce: OWLClassExpression, direct: bool = False) \ -> Iterable[OWLClassExpression]: """Gets the stream of named classes that are the strict (potentially direct) super classes of the specified class expression with respect to the imports closure of the root ontology. @@ -372,7 +367,6 @@ class expression with respect to the imports closure of the root ontology. ce: The class expression whose strict (direct) super classes are to be retrieved. direct: Specifies if the direct super classes should be retrieved (True) or if the all super classes (ancestors) classes should be retrieved (False). - only_named: Whether to only retrieve named super classes or also complex class expressions. Returns: If direct is True, each class C where the set of reasoner axioms entails DirectSubClassOf(ce, C). @@ -380,6 +374,8 @@ class expression with respect to the imports closure of the root ontology. If ce is equivalent to owl:Thing then nothing will be returned. """ pass + + class OWLReasonerEx(OWLReasoner, metaclass=ABCMeta): """Extra convenience methods for OWL Reasoners""" @@ -399,16 +395,13 @@ def data_property_ranges(self, pe: OWLDataProperty, direct: bool = False) -> Ite yield ax.get_range() if not direct: logger.warning("indirect not implemented") - # TODO: # default - def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> Iterable[OWLLiteral]: + def all_data_property_values(self, pe: OWLDataProperty) -> Iterable[OWLLiteral]: """Gets all values for the given data property expression that appear in the knowledge base. Args: pe: The data property expression whose values are to be retrieved - direct: Specifies if only the direct values of the data property pe should be retrieved (True), or if - the values of sub properties of pe should be taken into account (False). Returns: A set of OWLLiterals containing literals such that for each literal l in the set, the set of reasoner @@ -416,7 +409,7 @@ def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> """ onto = self.get_root_ontology() for ind in onto.individuals_in_signature(): - for lit in self.data_property_values(ind, pe, direct): + for lit in self.data_property_values(ind, pe): yield lit # default @@ -456,7 +449,7 @@ def ind_object_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> onto = self.get_root_ontology() for op in onto.object_properties_in_signature(): try: - next(iter(self.object_property_values(ind, op, direct))) + next(iter(self.object_property_values(ind, op))) yield op except StopIteration: - pass \ No newline at end of file + pass diff --git a/owlapy/owl_reasoner.py b/owlapy/owl_reasoner.py index 9c2b708f..be190f7f 100644 --- a/owlapy/owl_reasoner.py +++ b/owlapy/owl_reasoner.py @@ -33,11 +33,6 @@ _P = TypeVar('_P', bound=OWLPropertyExpression) -# TODO:CD:The name of the classes defined with metaclass=ABCMeta should reflect that -# TODO:CD: An instance cannot be created from those classes. -# TODO:CD: We should move those Abstract Base Classes into a respective package, e.g. -# TODO:CD: owlapy/abstract_owl_reasoner/abstract_owl_reasoner.py should contain OWLReasoner and OWLReasonerEx - class OntologyReasoner(OWLReasonerEx): __slots__ = '_ontology', '_world' @@ -1149,7 +1144,7 @@ def _retrieve_triples(self, pe: OWLPropertyExpression) -> Iterable: yield from relations -class SyncReasoner: +class SyncReasoner(OWLReasonerEx): def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"): """ @@ -1633,9 +1628,10 @@ def infer_axioms_and_save(self, output_path: str = None, output_format: str = No def generate_and_save_inferred_class_assertion_axioms(self, output="temp.ttl", output_format: str = None): """ - Generates inferred class assertion axioms for the ontology managed by this instance's reasoner and saves them to a file. - This function uses the OWL API to generate inferred class assertion axioms based on the ontology and reasoner - associated with this instance. The inferred axioms are saved to the specified output file in the desired format. + Generates inferred class assertion axioms for the ontology managed by this instance's reasoner and saves them + to a file. This function uses the OWL API to generate inferred class assertion axioms based on the ontology + and reasoner associated with this instance. The inferred axioms are saved to the specified output file in + the desired format. Parameters: ----------- output : str, optional From 7016b29524d112d60bf578251a79bb013cd534eb Mon Sep 17 00:00:00 2001 From: Alkid Date: Mon, 9 Sep 2024 15:43:40 +0200 Subject: [PATCH 3/9] flexible 'direct' argument --- owlapy/abstracts/abstract_owl_reasoner.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/owlapy/abstracts/abstract_owl_reasoner.py b/owlapy/abstracts/abstract_owl_reasoner.py index c70ca218..eab7b9e9 100644 --- a/owlapy/abstracts/abstract_owl_reasoner.py +++ b/owlapy/abstracts/abstract_owl_reasoner.py @@ -1,5 +1,6 @@ """OWL Reasoner""" from abc import ABCMeta, abstractmethod +from inspect import signature from typing import Iterable import logging @@ -397,19 +398,26 @@ def data_property_ranges(self, pe: OWLDataProperty, direct: bool = False) -> Ite logger.warning("indirect not implemented") # default - def all_data_property_values(self, pe: OWLDataProperty) -> Iterable[OWLLiteral]: + def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> Iterable[OWLLiteral]: """Gets all values for the given data property expression that appear in the knowledge base. Args: pe: The data property expression whose values are to be retrieved + direct: Specifies if only the direct values of the data property pe should be retrieved (True), or if + the values of sub properties of pe should be taken into account (False). Returns: A set of OWLLiterals containing literals such that for each literal l in the set, the set of reasoner axioms entails DataPropertyAssertion(pe ind l) for any ind. """ onto = self.get_root_ontology() + has_direct = "direct" in str(signature(self.data_property_values)) for ind in onto.individuals_in_signature(): - for lit in self.data_property_values(ind, pe): + if has_direct: + dpv = self.data_property_values(ind, pe, direct) + else: + dpv = self.data_property_values(ind, pe) + for lit in dpv: yield lit # default @@ -447,9 +455,13 @@ def ind_object_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> for atleast one ind2. """ onto = self.get_root_ontology() + has_direct = "direct" in str(signature(self.object_property_values)) for op in onto.object_properties_in_signature(): try: - next(iter(self.object_property_values(ind, op))) + if has_direct: + next(iter(self.object_property_values(ind, op, direct))) + else: + next(iter(self.object_property_values(ind, op))) yield op except StopIteration: pass From aada5506ce377702317c59615a2a9ee4bd185b56 Mon Sep 17 00:00:00 2001 From: Alkid Date: Mon, 9 Sep 2024 15:47:49 +0200 Subject: [PATCH 4/9] flexible 'direct' argument for ind_data_properties --- owlapy/abstracts/abstract_owl_reasoner.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/owlapy/abstracts/abstract_owl_reasoner.py b/owlapy/abstracts/abstract_owl_reasoner.py index eab7b9e9..3881d8fd 100644 --- a/owlapy/abstracts/abstract_owl_reasoner.py +++ b/owlapy/abstracts/abstract_owl_reasoner.py @@ -434,9 +434,13 @@ def ind_data_properties(self, ind: OWLNamedIndividual, direct: bool = True) -> I for atleast one l. """ onto = self.get_root_ontology() + has_direct = "direct" in str(signature(self.data_property_values)) for dp in onto.data_properties_in_signature(): try: - next(iter(self.data_property_values(ind, dp, direct))) + if has_direct: + next(iter(self.data_property_values(ind, dp, direct))) + else: + next(iter(self.data_property_values(ind, dp))) yield dp except StopIteration: pass From 1afb0fa7d2f28fe35a811c63a089f073eb8326df Mon Sep 17 00:00:00 2001 From: Alkid Date: Mon, 9 Sep 2024 16:00:06 +0200 Subject: [PATCH 5/9] Moved abstract classes to 'abstracts' directory --- owlapy/abstracts/abstract_owl_ontology.py | 183 ++++++++++++++++++ .../abstract_owl_ontology_manager.py | 70 +++++++ owlapy/abstracts/abstract_owl_reasoner.py | 2 +- owlapy/owl_ontology.py | 174 +---------------- owlapy/owl_ontology_manager.py | 70 +------ owlapy/owl_reasoner.py | 3 +- 6 files changed, 260 insertions(+), 242 deletions(-) create mode 100644 owlapy/abstracts/abstract_owl_ontology.py create mode 100644 owlapy/abstracts/abstract_owl_ontology_manager.py diff --git a/owlapy/abstracts/abstract_owl_ontology.py b/owlapy/abstracts/abstract_owl_ontology.py new file mode 100644 index 00000000..c24f9176 --- /dev/null +++ b/owlapy/abstracts/abstract_owl_ontology.py @@ -0,0 +1,183 @@ +from abc import ABCMeta, abstractmethod +from typing import Final, Iterable, Union, Optional + +from owlapy.class_expression import OWLClass +from owlapy.iri import IRI +from owlapy.owl_axiom import OWLEquivalentClassesAxiom, OWLClassAxiom, OWLDataPropertyDomainAxiom, \ + OWLDataPropertyRangeAxiom, OWLObjectPropertyDomainAxiom, OWLObjectPropertyRangeAxiom, OWLAxiom +from owlapy.owl_individual import OWLNamedIndividual +from owlapy.owl_object import OWLObject +from owlapy.owl_ontology import _M, OWLOntologyID +from owlapy.owl_property import OWLDataProperty, OWLObjectProperty + + +class OWLOntology(OWLObject, metaclass=ABCMeta): + """Represents an OWL 2 Ontology in the OWL 2 specification. + + An OWLOntology consists of a possibly empty set of OWLAxioms and a possibly empty set of OWLAnnotations. + An ontology can have an ontology IRI which can be used to identify the ontology. If it has an ontology IRI then + it may also have an ontology version IRI. Since OWL 2, an ontology need not have an ontology IRI. (See the OWL 2 + Structural Specification). + + An ontology cannot be modified directly. Changes must be applied via its OWLOntologyManager. + """ + __slots__ = () + type_index: Final = 1 + + @abstractmethod + def classes_in_signature(self) -> Iterable[OWLClass]: + """Gets the classes in the signature of this object. + + Returns: + Classes in the signature of this object. + """ + pass + + @abstractmethod + def data_properties_in_signature(self) -> Iterable[OWLDataProperty]: + """Get the data properties that are in the signature of this object. + + Returns: + Data properties that are in the signature of this object. + """ + pass + + @abstractmethod + def object_properties_in_signature(self) -> Iterable[OWLObjectProperty]: + """A convenience method that obtains the object properties that are in the signature of this object. + + Returns: + Object properties that are in the signature of this object. + """ + pass + + @abstractmethod + def individuals_in_signature(self) -> Iterable[OWLNamedIndividual]: + """A convenience method that obtains the individuals that are in the signature of this object. + + Returns: + Individuals that are in the signature of this object. + """ + pass + + @abstractmethod + def equivalent_classes_axioms(self, c: OWLClass) -> Iterable[OWLEquivalentClassesAxiom]: + """ Gets all of the equivalent axioms in this ontology that contain the specified class as an operand. + + Args: + c: The class for which the EquivalentClasses axioms should be retrieved. + + Returns: + EquivalentClasses axioms contained in this ontology. + """ + pass + + @abstractmethod + def general_class_axioms(self) -> Iterable[OWLClassAxiom]: + """Get the general class axioms of this ontology. This includes SubClass axioms with a complex class expression + as the sub class and EquivalentClass axioms and DisjointClass axioms with only complex class expressions. + + Returns: + General class axioms contained in this ontology. + """ + pass + + @abstractmethod + def data_property_domain_axioms(self, property: OWLDataProperty) -> Iterable[OWLDataPropertyDomainAxiom]: + """Gets the OWLDataPropertyDomainAxiom objects where the property is equal to the specified property. + + Args: + property: The property which is equal to the property of the retrieved axioms. + + Returns: + The axioms matching the search. + """ + pass + + @abstractmethod + def data_property_range_axioms(self, property: OWLDataProperty) -> Iterable[OWLDataPropertyRangeAxiom]: + """Gets the OWLDataPropertyRangeAxiom objects where the property is equal to the specified property. + + Args: + property: The property which is equal to the property of the retrieved axioms. + + Returns: + The axioms matching the search. + """ + pass + + @abstractmethod + def object_property_domain_axioms(self, property: OWLObjectProperty) -> Iterable[OWLObjectPropertyDomainAxiom]: + """Gets the OWLObjectPropertyDomainAxiom objects where the property is equal to the specified property. + + Args: + property: The property which is equal to the property of the retrieved axioms. + + Returns: + The axioms matching the search. + """ + pass + + @abstractmethod + def object_property_range_axioms(self, property: OWLObjectProperty) -> Iterable[OWLObjectPropertyRangeAxiom]: + """Gets the OWLObjectPropertyRangeAxiom objects where the property is equal to the specified property. + + Args: + property: The property which is equal to the property of the retrieved axioms. + + Returns: + The axioms matching the search. + """ + pass + + @abstractmethod + def get_owl_ontology_manager(self) -> _M: + """Gets the manager that manages this ontology.""" + pass + + @abstractmethod + def get_ontology_id(self) -> OWLOntologyID: + """Gets the OWLOntologyID belonging to this object. + + Returns: + The OWLOntologyID. + """ + pass + + def is_anonymous(self) -> bool: + """Check whether this ontology does contain an IRI or not.""" + return self.get_ontology_id().is_anonymous() + + @abstractmethod + def add_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]): + """Add the specified axiom/axioms to the ontology. + + Args: + axiom: Can be a single axiom or a collection of axioms. + + Returns: + Nothing. + """ + pass + + @abstractmethod + def remove_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]): + """Removes the specified axiom/axioms to the ontology. + + Args: + axiom: Can be a single axiom or a collection of axioms. + + Returns: + Nothing. + """ + pass + + def save(self, document_iri: Optional[IRI] = None): + """Saves this ontology, using its IRI to determine where/how the ontology should be + saved. + + Args: + document_iri: Whether you want to save in a different location. + + """ + pass diff --git a/owlapy/abstracts/abstract_owl_ontology_manager.py b/owlapy/abstracts/abstract_owl_ontology_manager.py new file mode 100644 index 00000000..891b29a8 --- /dev/null +++ b/owlapy/abstracts/abstract_owl_ontology_manager.py @@ -0,0 +1,70 @@ +from abc import ABCMeta, abstractmethod +from typing import Union + +from owlapy.abstracts.abstract_owl_ontology import OWLOntology +from owlapy.iri import IRI + + +class OWLOntologyChange(metaclass=ABCMeta): + """Represents an ontology change.""" + __slots__ = () + + _ont: OWLOntology + + @abstractmethod + def __init__(self, ontology: OWLOntology): + self._ont = ontology + + def get_ontology(self) -> OWLOntology: + """Gets the ontology that the change is/was applied to. + + Returns: + The ontology that the change is applicable to. + """ + return self._ont + + +class OWLOntologyManager(metaclass=ABCMeta): + """An OWLOntologyManager manages a set of ontologies. It is the main point for creating, loading and accessing + ontologies.""" + + @abstractmethod + def create_ontology(self, iri: Union[str, IRI]) -> OWLOntology: + """Creates a new (empty) ontology that that has the specified ontology IRI (and no version IRI). + + Args: + iri: The IRI of the ontology to be created, can also be a string. + + Returns: + The newly created ontology. + """ + pass + + @abstractmethod + def load_ontology(self, iri: Union[IRI, str]) -> OWLOntology: + """Loads an ontology that is assumed to have the specified ontology IRI as its IRI or version IRI. The ontology + IRI will be mapped to an ontology document IRI. + + Args: + iri: The IRI that identifies the ontology, can also be a string. + It is expected that the ontology will also have this IRI + (although the OWL API should tolerate situations where this is not the case). + + Returns: + The OWLOntology representation of the ontology that was loaded. + """ + pass + + @abstractmethod + def apply_change(self, change: OWLOntologyChange): + """A convenience method that applies just one change to an ontology. When this method is used through an + OWLOntologyManager implementation, the instance used should be the one that the ontology returns through the + get_owl_ontology_manager() call. + + Args: + change: The change to be applied. + + Raises: + ChangeApplied.UNSUCCESSFULLY: if the change was not applied successfully. + """ + pass diff --git a/owlapy/abstracts/abstract_owl_reasoner.py b/owlapy/abstracts/abstract_owl_reasoner.py index 3881d8fd..1ed1e01a 100644 --- a/owlapy/abstracts/abstract_owl_reasoner.py +++ b/owlapy/abstracts/abstract_owl_reasoner.py @@ -8,7 +8,7 @@ from owlapy.class_expression import OWLClass from owlapy.owl_data_ranges import OWLDataRange from owlapy.owl_object import OWLEntity -from owlapy.owl_ontology import OWLOntology +from owlapy.abstracts.abstract_owl_ontology import OWLOntology from owlapy.owl_property import OWLObjectPropertyExpression, OWLDataProperty, OWLObjectProperty from owlapy.owl_individual import OWLNamedIndividual from owlapy.owl_literal import OWLLiteral diff --git a/owlapy/owl_ontology.py b/owlapy/owl_ontology.py index ebd4389a..fdf7acbf 100644 --- a/owlapy/owl_ontology.py +++ b/owlapy/owl_ontology.py @@ -1,5 +1,4 @@ """OWL Ontology""" -from abc import ABCMeta, abstractmethod from functools import singledispatchmethod, singledispatch from itertools import chain, islice, combinations import types @@ -9,6 +8,7 @@ import owlready2 from pandas import Timedelta from owlapy import namespaces +from owlapy.abstracts.abstract_owl_ontology import OWLOntology from owlapy.owl_data_ranges import OWLDataRange, OWLDataComplementOf, OWLDataUnionOf, OWLDataIntersectionOf from owlapy.owl_datatype import OWLDatatype from owlapy.owl_individual import OWLNamedIndividual, OWLIndividual @@ -123,178 +123,6 @@ def __eq__(self, other): return NotImplemented -class OWLOntology(OWLObject, metaclass=ABCMeta): - """Represents an OWL 2 Ontology in the OWL 2 specification. - - An OWLOntology consists of a possibly empty set of OWLAxioms and a possibly empty set of OWLAnnotations. - An ontology can have an ontology IRI which can be used to identify the ontology. If it has an ontology IRI then - it may also have an ontology version IRI. Since OWL 2, an ontology need not have an ontology IRI. (See the OWL 2 - Structural Specification). - - An ontology cannot be modified directly. Changes must be applied via its OWLOntologyManager. - """ - __slots__ = () - type_index: Final = 1 - - @abstractmethod - def classes_in_signature(self) -> Iterable[OWLClass]: - """Gets the classes in the signature of this object. - - Returns: - Classes in the signature of this object. - """ - pass - - @abstractmethod - def data_properties_in_signature(self) -> Iterable[OWLDataProperty]: - """Get the data properties that are in the signature of this object. - - Returns: - Data properties that are in the signature of this object. - """ - pass - - @abstractmethod - def object_properties_in_signature(self) -> Iterable[OWLObjectProperty]: - """A convenience method that obtains the object properties that are in the signature of this object. - - Returns: - Object properties that are in the signature of this object. - """ - pass - - @abstractmethod - def individuals_in_signature(self) -> Iterable[OWLNamedIndividual]: - """A convenience method that obtains the individuals that are in the signature of this object. - - Returns: - Individuals that are in the signature of this object. - """ - pass - - @abstractmethod - def equivalent_classes_axioms(self, c: OWLClass) -> Iterable[OWLEquivalentClassesAxiom]: - """ Gets all of the equivalent axioms in this ontology that contain the specified class as an operand. - - Args: - c: The class for which the EquivalentClasses axioms should be retrieved. - - Returns: - EquivalentClasses axioms contained in this ontology. - """ - pass - - @abstractmethod - def general_class_axioms(self) -> Iterable[OWLClassAxiom]: - """Get the general class axioms of this ontology. This includes SubClass axioms with a complex class expression - as the sub class and EquivalentClass axioms and DisjointClass axioms with only complex class expressions. - - Returns: - General class axioms contained in this ontology. - """ - pass - - @abstractmethod - def data_property_domain_axioms(self, property: OWLDataProperty) -> Iterable[OWLDataPropertyDomainAxiom]: - """Gets the OWLDataPropertyDomainAxiom objects where the property is equal to the specified property. - - Args: - property: The property which is equal to the property of the retrieved axioms. - - Returns: - The axioms matching the search. - """ - pass - - @abstractmethod - def data_property_range_axioms(self, property: OWLDataProperty) -> Iterable[OWLDataPropertyRangeAxiom]: - """Gets the OWLDataPropertyRangeAxiom objects where the property is equal to the specified property. - - Args: - property: The property which is equal to the property of the retrieved axioms. - - Returns: - The axioms matching the search. - """ - pass - - @abstractmethod - def object_property_domain_axioms(self, property: OWLObjectProperty) -> Iterable[OWLObjectPropertyDomainAxiom]: - """Gets the OWLObjectPropertyDomainAxiom objects where the property is equal to the specified property. - - Args: - property: The property which is equal to the property of the retrieved axioms. - - Returns: - The axioms matching the search. - """ - pass - - @abstractmethod - def object_property_range_axioms(self, property: OWLObjectProperty) -> Iterable[OWLObjectPropertyRangeAxiom]: - """Gets the OWLObjectPropertyRangeAxiom objects where the property is equal to the specified property. - - Args: - property: The property which is equal to the property of the retrieved axioms. - - Returns: - The axioms matching the search. - """ - pass - - @abstractmethod - def get_owl_ontology_manager(self) -> _M: - """Gets the manager that manages this ontology.""" - pass - - @abstractmethod - def get_ontology_id(self) -> OWLOntologyID: - """Gets the OWLOntologyID belonging to this object. - - Returns: - The OWLOntologyID. - """ - pass - - def is_anonymous(self) -> bool: - """Check whether this ontology does contain an IRI or not.""" - return self.get_ontology_id().is_anonymous() - - @abstractmethod - def add_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]): - """Add the specified axiom/axioms to the ontology. - - Args: - axiom: Can be a single axiom or a collection of axioms. - - Returns: - Nothing. - """ - pass - - @abstractmethod - def remove_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]): - """Removes the specified axiom/axioms to the ontology. - - Args: - axiom: Can be a single axiom or a collection of axioms. - - Returns: - Nothing. - """ - pass - - def save(self, document_iri: Optional[IRI] = None): - """Saves this ontology, using its IRI to determine where/how the ontology should be - saved. - - Args: - document_iri: Whether you want to save in a different location. - - """ - pass - - def _check_expression(expr: OWLObject, ontology: OWLOntology, world: owlready2.namespace.World): """ @TODO:CD: Documentation diff --git a/owlapy/owl_ontology_manager.py b/owlapy/owl_ontology_manager.py index 2475d623..0f384f05 100644 --- a/owlapy/owl_ontology_manager.py +++ b/owlapy/owl_ontology_manager.py @@ -1,80 +1,16 @@ -from abc import ABCMeta, abstractmethod from typing import Union import jpype import owlready2 +from owlapy.abstracts.abstract_owl_ontology_manager import OWLOntologyChange, OWLOntologyManager from owlapy.iri import IRI from owlapy.meta_classes import HasIRI -from owlapy.owl_ontology import OWLOntology, Ontology, SyncOntology +from owlapy.owl_ontology import Ontology, SyncOntology +from owlapy.abstracts.abstract_owl_ontology import OWLOntology from owlapy.static_funcs import startJVM -class OWLOntologyChange(metaclass=ABCMeta): - """Represents an ontology change.""" - __slots__ = () - - _ont: OWLOntology - - @abstractmethod - def __init__(self, ontology: OWLOntology): - self._ont = ontology - - def get_ontology(self) -> OWLOntology: - """Gets the ontology that the change is/was applied to. - - Returns: - The ontology that the change is applicable to. - """ - return self._ont - - -class OWLOntologyManager(metaclass=ABCMeta): - """An OWLOntologyManager manages a set of ontologies. It is the main point for creating, loading and accessing - ontologies.""" - - @abstractmethod - def create_ontology(self, iri: Union[str, IRI]) -> OWLOntology: - """Creates a new (empty) ontology that that has the specified ontology IRI (and no version IRI). - - Args: - iri: The IRI of the ontology to be created, can also be a string. - - Returns: - The newly created ontology. - """ - pass - - @abstractmethod - def load_ontology(self, iri: Union[IRI, str]) -> OWLOntology: - """Loads an ontology that is assumed to have the specified ontology IRI as its IRI or version IRI. The ontology - IRI will be mapped to an ontology document IRI. - - Args: - iri: The IRI that identifies the ontology, can also be a string. - It is expected that the ontology will also have this IRI - (although the OWL API should tolerate situations where this is not the case). - - Returns: - The OWLOntology representation of the ontology that was loaded. - """ - pass - - @abstractmethod - def apply_change(self, change: OWLOntologyChange): - """A convenience method that applies just one change to an ontology. When this method is used through an - OWLOntologyManager implementation, the instance used should be the one that the ontology returns through the - get_owl_ontology_manager() call. - - Args: - change: The change to be applied. - - Raises: - ChangeApplied.UNSUCCESSFULLY: if the change was not applied successfully. - """ - pass - - class OWLImportsDeclaration(HasIRI): """Represents an import statement in an ontology.""" __slots__ = '_iri' diff --git a/owlapy/owl_reasoner.py b/owlapy/owl_reasoner.py index be190f7f..289deb47 100644 --- a/owlapy/owl_reasoner.py +++ b/owlapy/owl_reasoner.py @@ -20,7 +20,8 @@ from owlapy.owl_data_ranges import OWLDataRange, OWLDataComplementOf, OWLDataUnionOf, OWLDataIntersectionOf from owlapy.owl_datatype import OWLDatatype from owlapy.owl_object import OWLEntity -from owlapy.owl_ontology import OWLOntology, Ontology, _parse_concept_to_owlapy, SyncOntology +from owlapy.owl_ontology import Ontology, _parse_concept_to_owlapy, SyncOntology +from owlapy.abstracts.abstract_owl_ontology import OWLOntology from owlapy.owl_ontology_manager import SyncOntologyManager from owlapy.owl_property import OWLObjectPropertyExpression, OWLDataProperty, OWLObjectProperty, OWLObjectInverseOf, \ OWLPropertyExpression, OWLDataPropertyExpression From 4e30719814b6e26b4649d1c1bef595b428cef189 Mon Sep 17 00:00:00 2001 From: Alkid Date: Mon, 9 Sep 2024 16:12:46 +0200 Subject: [PATCH 6/9] Fixed circular imports --- owlapy/abstracts/abstract_owl_ontology.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/owlapy/abstracts/abstract_owl_ontology.py b/owlapy/abstracts/abstract_owl_ontology.py index c24f9176..2b8b5172 100644 --- a/owlapy/abstracts/abstract_owl_ontology.py +++ b/owlapy/abstracts/abstract_owl_ontology.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from typing import Final, Iterable, Union, Optional +from typing import Final, Iterable, Union, Optional, TypeVar from owlapy.class_expression import OWLClass from owlapy.iri import IRI @@ -7,9 +7,11 @@ OWLDataPropertyRangeAxiom, OWLObjectPropertyDomainAxiom, OWLObjectPropertyRangeAxiom, OWLAxiom from owlapy.owl_individual import OWLNamedIndividual from owlapy.owl_object import OWLObject -from owlapy.owl_ontology import _M, OWLOntologyID from owlapy.owl_property import OWLDataProperty, OWLObjectProperty +_M = TypeVar('_M', bound='OWLOntologyManager') # noqa: F821 +_OI = TypeVar('_OI', bound='OWLOntologyID') # noqa: F821 + class OWLOntology(OWLObject, metaclass=ABCMeta): """Represents an OWL 2 Ontology in the OWL 2 specification. @@ -136,7 +138,7 @@ def get_owl_ontology_manager(self) -> _M: pass @abstractmethod - def get_ontology_id(self) -> OWLOntologyID: + def get_ontology_id(self) -> _OI: """Gets the OWLOntologyID belonging to this object. Returns: From 8ecb9eb4c4577b6b63ee6910c39580c2e2f153ef Mon Sep 17 00:00:00 2001 From: Alkid Date: Mon, 9 Sep 2024 17:06:36 +0200 Subject: [PATCH 7/9] Added structural reasoner --- owlapy/owl_reasoner.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/owlapy/owl_reasoner.py b/owlapy/owl_reasoner.py index 289deb47..45d02bca 100644 --- a/owlapy/owl_reasoner.py +++ b/owlapy/owl_reasoner.py @@ -1153,11 +1153,13 @@ def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"): Args: ontology(SyncOntology): Ontology that will be used by this reasoner. - reasoner: Name of the reasoner. Possible values (case-sensitive): ["HermiT", "Pellet", "JFact", "Openllet"]. + reasoner: Name of the reasoner. Possible values (case-sensitive): ["HermiT", "Pellet", "JFact", "Openllet", + "Structural"]. Default: "HermiT". """ - assert reasoner in ["HermiT", "Pellet", "JFact", "Openllet"], \ - (f"'{reasoner}' is not implemented. Available reasoners: ['HermiT', 'Pellet', 'JFact', 'Openllet']. " + assert reasoner in ["HermiT", "Pellet", "JFact", "Openllet", "Structural"], \ + (f"'{reasoner}' is not implemented. Available reasoners: ['HermiT', 'Pellet', 'JFact', 'Openllet', " + f"'Structural']. " f"This field is case sensitive.") if isinstance(ontology, SyncOntology): self.manager = ontology.manager @@ -1194,7 +1196,7 @@ def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"): "InferredObjectPropertyCharacteristicAxiomGenerator": InferredObjectPropertyCharacteristicAxiomGenerator(), } - # () Create a reasoner for the loaded ontology + # () Create a reasoner using the ontology if reasoner == "HermiT": from org.semanticweb.HermiT import ReasonerFactory self._owlapi_reasoner = ReasonerFactory().createReasoner(self._owlapi_ontology) @@ -1208,6 +1210,9 @@ def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"): 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") From 25f08480eb16efc218741466c30fa2913e99e476 Mon Sep 17 00:00:00 2001 From: Alkid Date: Tue, 10 Sep 2024 12:33:50 +0200 Subject: [PATCH 8/9] turned 'abstracts' into a package --- owlapy/abstracts/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 owlapy/abstracts/__init__.py diff --git a/owlapy/abstracts/__init__.py b/owlapy/abstracts/__init__.py new file mode 100644 index 00000000..473f64d3 --- /dev/null +++ b/owlapy/abstracts/__init__.py @@ -0,0 +1,4 @@ +from .abstract_owl_ontology_manager import OWLOntologyManager, OWLOntologyChange, OWLOntology +from .abstract_owl_reasoner import OWLReasoner, OWLReasonerEx + +__all__ = ['OWLOntologyManager', 'OWLOntologyChange', 'OWLOntology', 'OWLReasoner', 'OWLReasonerEx'] From 612beb943b92b8cdf8ea21f0fe56e407367a4225 Mon Sep 17 00:00:00 2001 From: Alkid Date: Tue, 10 Sep 2024 13:41:14 +0200 Subject: [PATCH 9/9] new release --- README.md | 4 ++-- docs/conf.py | 2 +- docs/usage/main.md | 2 +- owlapy/__init__.py | 2 +- setup.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3f4c24a5..53b448f1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OWLAPY [![Coverage](https://img.shields.io/badge/coverage-78%25-green)](https://dice-group.github.io/owlapy/usage/further_resources.html#coverage-report) -[![Pypi](https://img.shields.io/badge/pypi-1.2.0-blue)](https://pypi.org/project/owlapy/1.2.0/) -[![Docs](https://img.shields.io/badge/documentation-1.2.0-yellow)](https://dice-group.github.io/owlapy/usage/main.html) +[![Pypi](https://img.shields.io/badge/pypi-1.2.2-blue)](https://pypi.org/project/owlapy/1.2.2/) +[![Docs](https://img.shields.io/badge/documentation-1.2.2-yellow)](https://dice-group.github.io/owlapy/usage/main.html) ![OWLAPY](docs/_static/images/owlapy_logo.png) diff --git a/docs/conf.py b/docs/conf.py index 55a57422..84e52baf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,7 +13,7 @@ project = 'OWLAPY' author = 'Ontolearn Team' -release = '1.2.0' +release = '1.2.2' # -- 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 fa94d25d..74916798 100644 --- a/docs/usage/main.md +++ b/docs/usage/main.md @@ -1,6 +1,6 @@ # About owlapy -**Version:** owlapy 1.2.0 +**Version:** owlapy 1.2.2 **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 bcbfb32b..e8bdfdff 100644 --- a/owlapy/__init__.py +++ b/owlapy/__init__.py @@ -3,4 +3,4 @@ from .parser import (dl_to_owl_expression as dl_to_owl_expression, manchester_to_owl_expression as manchester_to_owl_expression) from .converter import owl_expression_to_sparql as owl_expression_to_sparql -__version__ = '1.2.1' +__version__ = '1.2.2' diff --git a/setup.py b/setup.py index 80b77624..9aac5346 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.2.1", + version="1.2.2", packages=find_packages(), include_package_data=True, package_data={