diff --git a/owlapy/class_expression/class_expression.py b/owlapy/class_expression/class_expression.py index 50dbb4f0..ede6b151 100644 --- a/owlapy/class_expression/class_expression.py +++ b/owlapy/class_expression/class_expression.py @@ -1,10 +1,16 @@ from abc import abstractmethod, ABCMeta -from ..data_ranges import OWLPropertyRange, OWLDataRange +from ..data_ranges import OWLPropertyRange from ..meta_classes import HasOperands from typing import Final, Iterable + + class OWLClassExpression(OWLPropertyRange): - """An OWL 2 Class Expression (https://www.w3.org/TR/owl2-syntax/#Class_Expressions) """ + """OWL Class expressions represent sets of individuals by formally specifying conditions on the individuals' properties; + individuals satisfying these conditions are said to be instances of the respective class expressions. + In the structural specification of OWL 2, class expressions are represented by ClassExpression. + (https://www.w3.org/TR/owl2-syntax/#Class_Expressions) + """ __slots__ = () @abstractmethod diff --git a/owlapy/class_expression/nary_boolean_expression.py b/owlapy/class_expression/nary_boolean_expression.py index 682c8bc2..390b5f89 100644 --- a/owlapy/class_expression/nary_boolean_expression.py +++ b/owlapy/class_expression/nary_boolean_expression.py @@ -1,6 +1,8 @@ from .class_expression import OWLClassExpression, OWLBooleanClassExpression from ..meta_classes import HasOperands from typing import Final, Sequence, Iterable + + class OWLNaryBooleanClassExpression(OWLBooleanClassExpression, HasOperands[OWLClassExpression]): """OWLNaryBooleanClassExpression.""" __slots__ = () @@ -30,10 +32,11 @@ def __hash__(self): return hash(self._operands) - - class OWLObjectUnionOf(OWLNaryBooleanClassExpression): - """Represents an ObjectUnionOf class expression in the OWL 2 Specification.""" + """A union class expression ObjectUnionOf( CE1 ... CEn ) contains all individuals that are instances + of at least one class expression CEi for 1 ≤ i ≤ n. + (https://www.w3.org/TR/owl2-syntax/#Union_of_Class_Expressions) + """ __slots__ = '_operands' type_index: Final = 3002 @@ -41,7 +44,10 @@ class OWLObjectUnionOf(OWLNaryBooleanClassExpression): class OWLObjectIntersectionOf(OWLNaryBooleanClassExpression): - """Represents an OWLObjectIntersectionOf class expression in the OWL 2 Specification.""" + """An intersection class expression ObjectIntersectionOf( CE1 ... CEn ) contains all individuals that are instances + of all class expressions CEi for 1 ≤ i ≤ n. + (https://www.w3.org/TR/owl2-syntax/#Intersection_of_Class_Expressions) + """ __slots__ = '_operands' type_index: Final = 3001 diff --git a/owlapy/class_expression/owl_class.py b/owlapy/class_expression/owl_class.py index 208f585d..0bb69de9 100644 --- a/owlapy/class_expression/owl_class.py +++ b/owlapy/class_expression/owl_class.py @@ -1,11 +1,12 @@ from .class_expression import OWLClassExpression, OWLObjectComplementOf -from ..owlobject import OWLObject, OWLEntity +from ..owlobject import OWLEntity from typing import Final, Union from ..iri import IRI class OWLClass(OWLClassExpression, OWLEntity): - """An OWL 2 named Class""" + """An OWL 2 named Class. Classes can be understood as sets of individuals. + (https://www.w3.org/TR/owl2-syntax/#Classes)""" __slots__ = '_iri', '_is_nothing', '_is_thing' type_index: Final = 1001 diff --git a/owlapy/class_expression/restriction.py b/owlapy/class_expression/restriction.py index 24f2c8d4..f9f303cc 100644 --- a/owlapy/class_expression/restriction.py +++ b/owlapy/class_expression/restriction.py @@ -9,7 +9,7 @@ from ..owl_individual import OWLIndividual from ..types import OWLDatatype from ..owlobject import OWLObject -from owlapy.vocab import OWLRDFVocabulary, XSDVocabulary, OWLFacet +from owlapy.vocab import OWLFacet from datetime import datetime, date from pandas import Timedelta @@ -18,6 +18,7 @@ Literals = Union['OWLLiteral', int, float, bool, Timedelta, datetime, date, str] #: + class OWLRestriction(OWLAnonymousClassExpression): """Represents an Object Property Restriction or Data Property Restriction in the OWL 2 specification.""" __slots__ = () @@ -45,29 +46,10 @@ def is_object_restriction(self) -> bool: True if this is an object restriction. """ return False -class OWLDataRestriction(OWLRestriction, metaclass=ABCMeta): - """Represents a Data Property Restriction in the OWL 2 specification.""" - __slots__ = () - def is_data_restriction(self) -> bool: - # documented in parent - return True - pass -class OWLObjectRestriction(OWLRestriction, metaclass=ABCMeta): - """Represents a Object Property Restriction in the OWL 2 specification.""" - __slots__ = () - - def is_object_restriction(self) -> bool: - # documented in parent - return True - - @abstractmethod - def get_property(self) -> OWLObjectPropertyExpression: - # documented in parent - pass class OWLHasValueRestriction(Generic[_T], OWLRestriction, HasFiller[_T], metaclass=ABCMeta): - """OWLHasValueRestriction. + """Represent a HasValue restriction in the OWL 2 Args: _T: The value type. @@ -90,82 +72,36 @@ def __hash__(self): def get_filler(self) -> _T: # documented in parent return self._v -class OWLQuantifiedRestriction(Generic[_T], OWLRestriction, HasFiller[_T], metaclass=ABCMeta): - """Represents a quantified restriction. - Args: - _T: value type - """ - __slots__ = () - pass -class OWLQuantifiedObjectRestriction(OWLQuantifiedRestriction[OWLClassExpression], OWLObjectRestriction, - metaclass=ABCMeta): - """Represents a quantified object restriction.""" - __slots__ = () - _filler: OWLClassExpression - - def __init__(self, filler: OWLClassExpression): - self._filler = filler - - def get_filler(self) -> OWLClassExpression: - # documented in parent (HasFiller) - return self._filler -class OWLObjectSomeValuesFrom(OWLQuantifiedObjectRestriction): - """Represents an ObjectSomeValuesFrom class expression in the OWL 2 Specification.""" - __slots__ = '_property', '_filler' - type_index: Final = 3005 - - def __init__(self, property: OWLObjectPropertyExpression, filler: OWLClassExpression): - """Gets an OWLObjectSomeValuesFrom restriction. +# ================================================================================================================= +# =========================================OBJECT RESTRICTIONS===================================================== +# ================================================================================================================= - Args: - property: The object property that the restriction acts along. - filler: The class expression that is the filler. - - Returns: - An OWLObjectSomeValuesFrom restriction along the specified property with the specified filler. - """ - super().__init__(filler) - self._property = property - def __repr__(self): - return f"OWLObjectSomeValuesFrom(property={repr(self._property)},filler={repr(self._filler)})" - - def __eq__(self, other): - if type(other) is type(self): - return self._filler == other._filler and self._property == other._property - return NotImplemented +class OWLObjectRestriction(OWLRestriction, metaclass=ABCMeta): + """Represents an Object Property Restriction in the OWL 2 specification.""" + __slots__ = () - def __hash__(self): - return hash((self._filler, self._property)) + def is_object_restriction(self) -> bool: + # documented in parent + return True + @abstractmethod def get_property(self) -> OWLObjectPropertyExpression: # documented in parent - return self._property -class OWLObjectAllValuesFrom(OWLQuantifiedObjectRestriction): - """Represents an ObjectAllValuesFrom class expression in the OWL 2 Specification.""" - __slots__ = '_property', '_filler' - type_index: Final = 3006 - - def __init__(self, property: OWLObjectPropertyExpression, filler: OWLClassExpression): - super().__init__(filler) - self._property = property + pass - def __repr__(self): - return f"OWLObjectAllValuesFrom(property={repr(self._property)},filler={repr(self._filler)})" - def __eq__(self, other): - if type(other) is type(self): - return self._filler == other._filler and self._property == other._property - return NotImplemented +class OWLQuantifiedRestriction(Generic[_T], OWLRestriction, HasFiller[_T], metaclass=ABCMeta): + """Represents a quantified restriction. - def __hash__(self): - return hash((self._filler, self._property)) + Args: + _T: value type + """ + __slots__ = () + pass - def get_property(self) -> OWLObjectPropertyExpression: - # documented in parent - return self._property class OWLCardinalityRestriction(Generic[_F], OWLQuantifiedRestriction[_F], HasCardinality, metaclass=ABCMeta): """Base interface for owl min and max cardinality restriction. @@ -191,6 +127,21 @@ def get_filler(self) -> _F: return self._filler +class OWLQuantifiedObjectRestriction(OWLQuantifiedRestriction[OWLClassExpression], OWLObjectRestriction, + metaclass=ABCMeta): + """Represents a quantified object restriction.""" + __slots__ = () + + _filler: OWLClassExpression + + def __init__(self, filler: OWLClassExpression): + self._filler = filler + + def get_filler(self) -> OWLClassExpression: + # documented in parent (HasFiller) + return self._filler + + class OWLObjectCardinalityRestriction(OWLCardinalityRestriction[OWLClassExpression], OWLQuantifiedObjectRestriction): """Represents Object Property Cardinality Restrictions in the OWL 2 specification.""" __slots__ = () @@ -220,8 +171,12 @@ def __eq__(self, other): def __hash__(self): return hash((self._property, self._cardinality, self._filler)) + class OWLObjectMinCardinality(OWLObjectCardinalityRestriction): - """Represents a ObjectMinCardinality restriction in the OWL 2 Specification.""" + """A minimum cardinality expression ObjectMinCardinality( n OPE CE ) consists of a nonnegative integer n, an object + property expression OPE, and a class expression CE, and it contains all those individuals that are connected by OPE + to at least n different individuals that are instances of CE. + (https://www.w3.org/TR/owl2-syntax/#Minimum_Cardinality)""" __slots__ = '_cardinality', '_filler', '_property' type_index: Final = 3008 @@ -236,8 +191,13 @@ def __init__(self, cardinality: int, property: OWLObjectPropertyExpression, fill An ObjectMinCardinality on the specified property. """ super().__init__(cardinality, property, filler) + + class OWLObjectMaxCardinality(OWLObjectCardinalityRestriction): - """Represents a ObjectMaxCardinality restriction in the OWL 2 Specification.""" + """A maximum cardinality expression ObjectMaxCardinality( n OPE CE ) consists of a nonnegative integer n, an object + property expression OPE, and a class expression CE, and it contains all those individuals that are connected by OPE + to at most n different individuals that are instances of CE. + (https://www.w3.org/TR/owl2-syntax/#Maximum_Cardinality)""" __slots__ = '_cardinality', '_filler', '_property' type_index: Final = 3010 @@ -252,8 +212,14 @@ def __init__(self, cardinality: int, property: OWLObjectPropertyExpression, fill An ObjectMaxCardinality on the specified property. """ super().__init__(cardinality, property, filler) + + class OWLObjectExactCardinality(OWLObjectCardinalityRestriction): - """Represents an ObjectExactCardinality restriction in the OWL 2 Specification.""" + """An exact cardinality expression ObjectExactCardinality( n OPE CE ) consists of a nonnegative integer n, an object + property expression OPE, and a class expression CE, and it contains all those individuals that are connected by + to exactly n different individuals that are instances of CE. + (https://www.w3.org/TR/owl2-syntax/#Exact_Cardinality) + """ __slots__ = '_cardinality', '_filler', '_property' type_index: Final = 3009 @@ -277,8 +243,76 @@ def as_intersection_of_min_max(self) -> OWLObjectIntersectionOf: """ args = self.get_cardinality(), self.get_property(), self.get_filler() return OWLObjectIntersectionOf((OWLObjectMinCardinality(*args), OWLObjectMaxCardinality(*args))) + + +class OWLObjectSomeValuesFrom(OWLQuantifiedObjectRestriction): + """An existential class expression ObjectSomeValuesFrom( OPE CE ) consists of an object property expression OPE and + a class expression CE, and it contains all those individuals that are connected by OPE to an individual that is + an instance of CE. """ + __slots__ = '_property', '_filler' + type_index: Final = 3005 + + def __init__(self, property: OWLObjectPropertyExpression, filler: OWLClassExpression): + """Gets an OWLObjectSomeValuesFrom restriction. + + Args: + property: The object property that the restriction acts along. + filler: The class expression that is the filler. + + Returns: + An OWLObjectSomeValuesFrom restriction along the specified property with the specified filler. + """ + super().__init__(filler) + self._property = property + + def __repr__(self): + return f"OWLObjectSomeValuesFrom(property={repr(self._property)},filler={repr(self._filler)})" + + def __eq__(self, other): + if type(other) is type(self): + return self._filler == other._filler and self._property == other._property + return NotImplemented + + def __hash__(self): + return hash((self._filler, self._property)) + + def get_property(self) -> OWLObjectPropertyExpression: + # documented in parent + return self._property + + +class OWLObjectAllValuesFrom(OWLQuantifiedObjectRestriction): + """A universal class expression ObjectAllValuesFrom( OPE CE ) consists of an object property expression OPE and a + class expression CE, and it contains all those individuals that are connected by OPE only to + individuals that are instances of CE. (https://www.w3.org/TR/owl2-syntax/#Universal_Quantification)""" + __slots__ = '_property', '_filler' + type_index: Final = 3006 + + def __init__(self, property: OWLObjectPropertyExpression, filler: OWLClassExpression): + super().__init__(filler) + self._property = property + + def __repr__(self): + return f"OWLObjectAllValuesFrom(property={repr(self._property)},filler={repr(self._filler)})" + + def __eq__(self, other): + if type(other) is type(self): + return self._filler == other._filler and self._property == other._property + return NotImplemented + + def __hash__(self): + return hash((self._filler, self._property)) + + def get_property(self) -> OWLObjectPropertyExpression: + # documented in parent + return self._property + + class OWLObjectHasSelf(OWLObjectRestriction): - """Represents an ObjectHasSelf class expression in the OWL 2 Specification.""" + """A self-restriction ObjectHasSelf( OPE ) consists of an object property expression OPE, + and it contains all those individuals that are connected by OPE to themselves. + (https://www.w3.org/TR/owl2-syntax/#Self-Restriction) + """ __slots__ = '_property' type_index: Final = 3011 @@ -311,62 +345,132 @@ def __repr__(self): return f'OWLObjectHasSelf({self._property})' +class OWLObjectHasValue(OWLHasValueRestriction[OWLIndividual], OWLObjectRestriction): + """A has-value class expression ObjectHasValue( OPE a ) consists of an object property expression OPE and an + individual a, and it contains all those individuals that are connected by OPE to a. Each such class expression + can be seen as a syntactic shortcut for the class expression ObjectSomeValuesFrom( OPE ObjectOneOf( a ) ). + (https://www.w3.org/TR/owl2-syntax/#Individual_Value_Restriction) + """ + __slots__ = '_property', '_v' + type_index: Final = 3007 -class OWLQuantifiedDataRestriction(OWLQuantifiedRestriction[OWLDataRange], - OWLDataRestriction, metaclass=ABCMeta): - """Represents a quantified data restriction.""" - __slots__ = () + _property: OWLObjectPropertyExpression + _v: OWLIndividual - _filler: OWLDataRange + def __init__(self, property: OWLObjectPropertyExpression, individual: OWLIndividual): + """ + Args: + property: The property that the restriction acts along. + individual: Individual for restriction. - def __init__(self, filler: OWLDataRange): - self._filler = filler + Returns: + A HasValue restriction with specified property and value + """ + super().__init__(individual) + self._property = property - def get_filler(self) -> OWLDataRange: - # documented in parent (HasFiller) - return self._filler -class OWLDataAllValuesFrom(OWLQuantifiedDataRestriction): - """Represents DataAllValuesFrom class expressions in the OWL 2 Specification.""" - __slots__ = '_property' + def get_property(self) -> OWLObjectPropertyExpression: + # documented in parent + return self._property - type_index: Final = 3013 + def as_some_values_from(self) -> OWLClassExpression: + """A convenience method that obtains this restriction as an existential restriction with a nominal filler. - _property: OWLDataPropertyExpression + Returns: + The existential equivalent of this value restriction. simp(HasValue(p a)) = some(p {a}). + """ + return OWLObjectSomeValuesFrom(self.get_property(), OWLObjectOneOf(self.get_filler())) - def __init__(self, property: OWLDataPropertyExpression, filler: OWLDataRange): - """Gets an OWLDataAllValuesFrom restriction. + def __repr__(self): + return f'OWLObjectHasValue(property={self.get_property()}, individual={self._v})' - Args: - property: The data property that the restriction acts along. - filler: The data range that is the filler. + +class OWLObjectOneOf(OWLAnonymousClassExpression, HasOperands[OWLIndividual]): + """An enumeration of individuals ObjectOneOf( a1 ... an ) contains exactly the individuals ai with 1 ≤ i ≤ n. + (https://www.w3.org/TR/owl2-syntax/#Enumeration_of_Individuals) + """ + __slots__ = '_values' + type_index: Final = 3004 + + def __init__(self, values: Union[OWLIndividual, Iterable[OWLIndividual]]): + if isinstance(values, OWLIndividual): + self._values = values, + else: + for _ in values: + assert isinstance(_, OWLIndividual) + self._values = tuple(values) + + def individuals(self) -> Iterable[OWLIndividual]: + """Gets the individuals that are in the oneOf. These individuals represent the exact instances (extension) + of this class expression. + + Returns: + The individuals that are the values of this {@code ObjectOneOf} class expression. + """ + yield from self._values + + def operands(self) -> Iterable[OWLIndividual]: + # documented in parent + yield from self.individuals() + + def as_object_union_of(self) -> OWLClassExpression: + """Simplifies this enumeration to a union of singleton nominals. Returns: - An OWLDataAllValuesFrom restriction along the specified property with the specified filler. + This enumeration in a more standard DL form. + simp({a}) = {a} simp({a0, ... , {an}) = unionOf({a0}, ... , {an}) """ - super().__init__(filler) - self._property = property + if len(self._values) == 1: + return self + return OWLObjectUnionOf(map(lambda _: OWLObjectOneOf(_), self.individuals())) - def __repr__(self): - return f"OWLDataAllValuesFrom(property={repr(self._property)},filler={repr(self._filler)})" + def __hash__(self): + return hash(self._values) def __eq__(self, other): - if type(other) is type(self): - return self._filler == other._filler and self._property == other._property + if type(other) == type(self): + return self._values == other._values return NotImplemented - def __hash__(self): - return hash((self._filler, self._property)) + def __repr__(self): + return f'OWLObjectOneOf({self._values})' - def get_property(self) -> OWLDataPropertyExpression: + +# ================================================================================================================= +# =========================================DATA RESTRICTIONS======================================================= +# ================================================================================================================= + + +class OWLDataRestriction(OWLRestriction, metaclass=ABCMeta): + """Represents a Data Property Restriction.""" + __slots__ = () + + def is_data_restriction(self) -> bool: # documented in parent - return self._property + return True + + pass + + +class OWLQuantifiedDataRestriction(OWLQuantifiedRestriction[OWLDataRange], + OWLDataRestriction, metaclass=ABCMeta): + """Represents a quantified data restriction.""" + __slots__ = () + _filler: OWLDataRange + + def __init__(self, filler: OWLDataRange): + self._filler = filler + + def get_filler(self) -> OWLDataRange: + # documented in parent (HasFiller) + return self._filler class OWLDataCardinalityRestriction(OWLCardinalityRestriction[OWLDataRange], OWLQuantifiedDataRestriction, OWLDataRestriction, metaclass=ABCMeta): - """Represents Data Property Cardinality Restrictions in the OWL 2 specification.""" + """Represents Data Property Cardinality Restrictions.""" __slots__ = () _property: OWLDataPropertyExpression @@ -395,36 +499,35 @@ def __hash__(self): return hash((self._property, self._cardinality, self._filler)) - -class OWLDataExactCardinality(OWLDataCardinalityRestriction): - """Represents DataExactCardinality restrictions in the OWL 2 Specification.""" +class OWLDataMinCardinality(OWLDataCardinalityRestriction): + """A minimum cardinality expression DataMinCardinality( n DPE DR ) consists of a nonnegative integer n, a data + property expression DPE, and a unary data range DR, and it contains all those individuals that are connected by + DPE to at least n different literals in DR. + (https://www.w3.org/TR/owl2-syntax/#Minimum_Cardinality) + """ __slots__ = '_cardinality', '_filler', '_property' - type_index: Final = 3016 + type_index: Final = 3015 def __init__(self, cardinality: int, property: OWLDataPropertyExpression, filler: OWLDataRange): """ Args: cardinality: Cannot be negative. property: The property that the restriction acts along. - filler: Data range for restriction + filler: Data range for restriction. Returns: - A DataExactCardinality on the specified property. + A DataMinCardinality on the specified property. """ super().__init__(cardinality, property, filler) - def as_intersection_of_min_max(self) -> OWLObjectIntersectionOf: - """Obtains an equivalent form that is a conjunction of a min cardinality and max cardinality restriction. - - Returns: - The semantically equivalent but structurally simpler form (= 1 R D) = >= 1 R D and <= 1 R D. - """ - args = self.get_cardinality(), self.get_property(), self.get_filler() - return OWLObjectIntersectionOf((OWLDataMinCardinality(*args), OWLDataMaxCardinality(*args))) class OWLDataMaxCardinality(OWLDataCardinalityRestriction): - """Represents DataMaxCardinality restrictions in the OWL 2 Specification.""" + """A maximum cardinality expression ObjectMaxCardinality( n OPE CE ) consists of a nonnegative integer n, an object + property expression OPE, and a class expression CE, and it contains all those individuals that are connected by OPE + to at most n different individuals that are instances of CE. + (https://www.w3.org/TR/owl2-syntax/#Maximum_Cardinality) + """ __slots__ = '_cardinality', '_filler', '_property' type_index: Final = 3017 @@ -440,27 +543,48 @@ def __init__(self, cardinality: int, property: OWLDataPropertyExpression, filler A DataMaxCardinality on the specified property. """ super().__init__(cardinality, property, filler) -class OWLDataMinCardinality(OWLDataCardinalityRestriction): - """Represents DataMinCardinality restrictions in the OWL 2 Specification.""" + + +class OWLDataExactCardinality(OWLDataCardinalityRestriction): + """An exact cardinality expression ObjectExactCardinality( n OPE CE ) consists of a nonnegative integer n, an + object property expression OPE, and a class expression CE, and it contains all those individuals that are connected + by OPE to exactly n different individuals that are instances of CE + (https://www.w3.org/TR/owl2-syntax/#Exact_Cardinality) + """ __slots__ = '_cardinality', '_filler', '_property' - type_index: Final = 3015 + type_index: Final = 3016 def __init__(self, cardinality: int, property: OWLDataPropertyExpression, filler: OWLDataRange): """ Args: cardinality: Cannot be negative. property: The property that the restriction acts along. - filler: Data range for restriction. + filler: Data range for restriction Returns: - A DataMinCardinality on the specified property. + A DataExactCardinality on the specified property. """ super().__init__(cardinality, property, filler) + def as_intersection_of_min_max(self) -> OWLObjectIntersectionOf: + """Obtains an equivalent form that is a conjunction of a min cardinality and max cardinality restriction. + + Returns: + The semantically equivalent but structurally simpler form (= 1 R D) = >= 1 R D and <= 1 R D. + """ + args = self.get_cardinality(), self.get_property(), self.get_filler() + return OWLObjectIntersectionOf((OWLDataMinCardinality(*args), OWLDataMaxCardinality(*args))) + class OWLDataSomeValuesFrom(OWLQuantifiedDataRestriction): - """Represents a DataSomeValuesFrom restriction in the OWL 2 Specification.""" + """An existential class expression DataSomeValuesFrom( DPE1 ... DPEn DR ) consists of n data property expressions + DPEi, 1 ≤ i ≤ n, and a data range DR whose arity must be n. Such a class expression contains all those individuals + that are connected by DPEi to literals lti, 1 ≤ i ≤ n, such that the tuple ( lt1 , ..., ltn ) is in DR. A class + expression of the form DataSomeValuesFrom( DPE DR ) can be seen as a syntactic shortcut for the class expression + DataMinCardinality( 1 DPE DR ). + (https://www.w3.org/TR/owl2-syntax/#Existential_Quantification_2) + """ __slots__ = '_property' type_index: Final = 3012 @@ -495,8 +619,56 @@ def get_property(self) -> OWLDataPropertyExpression: # documented in parent return self._property + +class OWLDataAllValuesFrom(OWLQuantifiedDataRestriction): + """A universal class expression DataAllValuesFrom( DPE1 ... DPEn DR ) consists of n data property expressions DPEi, + 1 ≤ i ≤ n, and a data range DR whose arity must be n. Such a class expression contains all those individuals that + are connected by DPEi only to literals lti, 1 ≤ i ≤ n, such that each tuple ( lt1 , ..., ltn ) is in DR. A class + expression of the form DataAllValuesFrom( DPE DR ) can be seen as a syntactic shortcut for the class expression + DataMaxCardinality( 0 DPE DataComplementOf( DR ) ). + (https://www.w3.org/TR/owl2-syntax/#Universal_Quantification_2) + """ + __slots__ = '_property' + + type_index: Final = 3013 + + _property: OWLDataPropertyExpression + + def __init__(self, property: OWLDataPropertyExpression, filler: OWLDataRange): + """Gets an OWLDataAllValuesFrom restriction. + + Args: + property: The data property that the restriction acts along. + filler: The data range that is the filler. + + Returns: + An OWLDataAllValuesFrom restriction along the specified property with the specified filler. + """ + super().__init__(filler) + self._property = property + + def __repr__(self): + return f"OWLDataAllValuesFrom(property={repr(self._property)},filler={repr(self._filler)})" + + def __eq__(self, other): + if type(other) is type(self): + return self._filler == other._filler and self._property == other._property + return NotImplemented + + def __hash__(self): + return hash((self._filler, self._property)) + + def get_property(self) -> OWLDataPropertyExpression: + # documented in parent + return self._property + + class OWLDataHasValue(OWLHasValueRestriction[OWLLiteral], OWLDataRestriction): - """Represents DataHasValue restrictions in the OWL 2 Specification.""" + """A has-value class expression DataHasValue( DPE lt ) consists of a data property expression DPE and a literal lt, + and it contains all those individuals that are connected by DPE to lt. Each such class expression can be seen as a + syntactic shortcut for the class expression DataSomeValuesFrom( DPE DataOneOf( lt ) ). + (https://www.w3.org/TR/owl2-syntax/#Literal_Value_Restriction) + """ __slots__ = '_property' type_index: Final = 3014 @@ -540,58 +712,9 @@ def get_property(self) -> OWLDataPropertyExpression: return self._property - -class OWLObjectOneOf(OWLAnonymousClassExpression, HasOperands[OWLIndividual]): - """Represents an ObjectOneOf class expression in the OWL 2 Specification.""" - __slots__ = '_values' - type_index: Final = 3004 - - def __init__(self, values: Union[OWLIndividual, Iterable[OWLIndividual]]): - if isinstance(values, OWLIndividual): - self._values = values, - else: - for _ in values: - assert isinstance(_, OWLIndividual) - self._values = tuple(values) - - def individuals(self) -> Iterable[OWLIndividual]: - """Gets the individuals that are in the oneOf. These individuals represent the exact instances (extension) - of this class expression. - - Returns: - The individuals that are the values of this {@code ObjectOneOf} class expression. - """ - yield from self._values - - def operands(self) -> Iterable[OWLIndividual]: - # documented in parent - yield from self.individuals() - - def as_object_union_of(self) -> OWLClassExpression: - """Simplifies this enumeration to a union of singleton nominals. - - Returns: - This enumeration in a more standard DL form. - simp({a}) = {a} simp({a0, ... , {an}) = unionOf({a0}, ... , {an}) - """ - if len(self._values) == 1: - return self - return OWLObjectUnionOf(map(lambda _: OWLObjectOneOf(_), self.individuals())) - - def __hash__(self): - return hash(self._values) - - def __eq__(self, other): - if type(other) == type(self): - return self._values == other._values - return NotImplemented - - def __repr__(self): - return f'OWLObjectOneOf({self._values})' - - class OWLDataOneOf(OWLDataRange, HasOperands[OWLLiteral]): - """Represents DataOneOf in the OWL 2 Specification.""" + """An enumeration of literals DataOneOf( lt1 ... ltn ) contains exactly the explicitly specified literals lti with + 1 ≤ i ≤ n. The resulting data range has arity one. (https://www.w3.org/TR/owl2-syntax/#Enumeration_of_Literals)""" type_index: Final = 4003 _values: Sequence[OWLLiteral] @@ -628,42 +751,13 @@ def __repr__(self): return f'OWLDataOneOf({self._values})' -class OWLObjectHasValue(OWLHasValueRestriction[OWLIndividual], OWLObjectRestriction): - """Represents an ObjectHasValue class expression in the OWL 2 Specification.""" - __slots__ = '_property', '_v' - type_index: Final = 3007 - - _property: OWLObjectPropertyExpression - _v: OWLIndividual - - def __init__(self, property: OWLObjectPropertyExpression, individual: OWLIndividual): - """ - Args: - property: The property that the restriction acts along. - individual: Individual for restriction. - - Returns: - A HasValue restriction with specified property and value - """ - super().__init__(individual) - self._property = property - - def get_property(self) -> OWLObjectPropertyExpression: - # documented in parent - return self._property - - def as_some_values_from(self) -> OWLClassExpression: - """A convenience method that obtains this restriction as an existential restriction with a nominal filler. - - Returns: - The existential equivalent of this value restriction. simp(HasValue(p a)) = some(p {a}). - """ - return OWLObjectSomeValuesFrom(self.get_property(), OWLObjectOneOf(self.get_filler())) - - def __repr__(self): - return f'OWLObjectHasValue(property={self.get_property()}, individual={self._v})' class OWLDatatypeRestriction(OWLDataRange): - """Represents a DatatypeRestriction data range in the OWL 2 Specification.""" + """A datatype restriction DatatypeRestriction( DT F1 lt1 ... Fn ltn ) consists of a unary datatype DT and n pairs + ( Fi , lti ). The resulting data range is unary and is obtained by restricting the value space of DT according to + the semantics of all ( Fi , vi ) (multiple pairs are interpreted conjunctively), where vi are the data values of + the literals lti. + (https://www.w3.org/TR/owl2-syntax/#Datatype_Restrictions) + """ __slots__ = '_type', '_facet_restrictions' type_index: Final = 4006 @@ -695,6 +789,8 @@ def __hash__(self): def __repr__(self): return f'OWLDatatypeRestriction({repr(self._type)}, {repr(self._facet_restrictions)})' + + class OWLFacetRestriction(OWLObject): """A facet restriction is used to restrict a particular datatype.""" diff --git a/owlapy/data_ranges/__init__.py b/owlapy/data_ranges/__init__.py index 885570b1..c14484c8 100644 --- a/owlapy/data_ranges/__init__.py +++ b/owlapy/data_ranges/__init__.py @@ -2,16 +2,14 @@ DataRange := Datatype | DataIntersectionOf | DataUnionOf | DataComplementOf | DataOneOf | DatatypeRestriction """ -from abc import abstractmethod, ABCMeta -from ..owlobject import OWLObject, OWLEntity + +from ..owlobject import OWLObject from ..meta_classes import HasOperands -from typing import Final, Iterable, Sequence -# from ..owl_literal import OWLLiteral -from typing import Final, Sequence, Union, Iterable -from ..iri import IRI +from typing import Final, Sequence, Iterable from abc import ABCMeta + class OWLPropertyRange(OWLObject, metaclass=ABCMeta): """OWL Objects that can be the ranges of properties.""" @@ -20,37 +18,6 @@ class OWLDataRange(OWLPropertyRange, metaclass=ABCMeta): """Represents a DataRange in the OWL 2 Specification.""" -class OWLDataComplementOf(OWLDataRange): - """Represents DataComplementOf in the OWL 2 Specification.""" - type_index: Final = 4002 - - _data_range: OWLDataRange - - def __init__(self, data_range: OWLDataRange): - """ - Args: - data_range: Data range to complement. - """ - self._data_range = data_range - - def get_data_range(self) -> OWLDataRange: - """ - Returns: - The wrapped data range. - """ - return self._data_range - - def __repr__(self): - return f"OWLDataComplementOf({repr(self._data_range)})" - - def __eq__(self, other): - if type(other) is type(self): - return self._data_range == other._data_range - return NotImplemented - - def __hash__(self): - return hash(self._data_range) - class OWLNaryDataRange(OWLDataRange, HasOperands[OWLDataRange]): """OWLNaryDataRange.""" __slots__ = () @@ -79,17 +46,59 @@ def __eq__(self, other): def __hash__(self): return hash(self._operands) -class OWLDataUnionOf(OWLNaryDataRange): - """Represents a DataUnionOf data range in the OWL 2 Specification.""" + +class OWLDataIntersectionOf(OWLNaryDataRange): + """An intersection data range DataIntersectionOf( DR1 ... DRn ) contains all tuples of literals that are contained + in each data range DRi for 1 ≤ i ≤ n. All data ranges DRi must be of the same arity, and the resulting data range + is of that arity as well. + (https://www.w3.org/TR/owl2-syntax/#Intersection_of_Data_Ranges) + """ __slots__ = '_operands' - type_index: Final = 4005 + type_index: Final = 4004 _operands: Sequence[OWLDataRange] -class OWLDataIntersectionOf(OWLNaryDataRange): - """Represents DataIntersectionOf in the OWL 2 Specification.""" + +class OWLDataUnionOf(OWLNaryDataRange): + """A union data range DataUnionOf( DR1 ... DRn ) contains all tuples of literals that are contained in the at least + one data range DRi for 1 ≤ i ≤ n. All data ranges DRi must be of the same arity, and the resulting data range is of + that arity as well. (https://www.w3.org/TR/owl2-syntax/#Union_of_Data_Ranges)""" __slots__ = '_operands' - type_index: Final = 4004 + type_index: Final = 4005 _operands: Sequence[OWLDataRange] + +class OWLDataComplementOf(OWLDataRange): + """A complement data range DataComplementOf( DR ) contains all tuples of literals that are not contained in the + data range DR. The resulting data range has the arity equal to the arity of DR. + (https://www.w3.org/TR/owl2-syntax/#Complement_of_Data_Ranges) + """ + type_index: Final = 4002 + + _data_range: OWLDataRange + + def __init__(self, data_range: OWLDataRange): + """ + Args: + data_range: Data range to complement. + """ + self._data_range = data_range + + def get_data_range(self) -> OWLDataRange: + """ + Returns: + The wrapped data range. + """ + return self._data_range + + def __repr__(self): + return f"OWLDataComplementOf({repr(self._data_range)})" + + def __eq__(self, other): + if type(other) is type(self): + return self._data_range == other._data_range + return NotImplemented + + def __hash__(self): + return hash(self._data_range) diff --git a/owlapy/namespaces.py b/owlapy/namespaces.py index 23217fa1..af9d3b61 100644 --- a/owlapy/namespaces.py +++ b/owlapy/namespaces.py @@ -3,7 +3,8 @@ class Namespaces: - """A Namespace and its prefix.""" + """Namespaces provide a simple method for qualifying element and attribute names used in Extensible Markup + Language documents by associating them with namespaces identified by URI references""" __slots__ = '_prefix', '_ns' _prefix: str diff --git a/owlapy/owl_annotation.py b/owlapy/owl_annotation.py index 870b855a..2ab8449d 100644 --- a/owlapy/owl_annotation.py +++ b/owlapy/owl_annotation.py @@ -23,11 +23,13 @@ def as_anonymous_individual(self): """ return None + class OWLAnnotationSubject(OWLAnnotationObject, metaclass=ABCMeta): """A marker interface for annotation subjects, which can either be IRIs or anonymous individuals""" __slots__ = () pass + class OWLAnnotationValue(OWLAnnotationObject, metaclass=ABCMeta): """A marker interface for annotation values, which can either be an IRI (URI), Literal or Anonymous Individual.""" __slots__ = () diff --git a/owlapy/owl_axiom.py b/owlapy/owl_axiom.py index 22135c4a..52385533 100644 --- a/owlapy/owl_axiom.py +++ b/owlapy/owl_axiom.py @@ -16,6 +16,7 @@ _P = TypeVar('_P', bound='OWLPropertyExpression') #: _R = TypeVar('_R', bound='OWLPropertyRange') #: + class OWLAxiom(OWLObject, metaclass=ABCMeta): """Represents Axioms in the OWL 2 Specification. @@ -44,8 +45,8 @@ def is_annotation_axiom(self) -> bool: class OWLLogicalAxiom(OWLAxiom, metaclass=ABCMeta): - """A base interface of all axioms that affect the logical meaning of an ontology. This excludes declaration axioms - (including imports declarations) and annotation axioms. + """A base interface of all axioms that affect the logical meaning of an ontology. This excludes declaration + axioms (including imports declarations) and annotation axioms. """ __slots__ = () @@ -117,7 +118,12 @@ def __repr__(self): class OWLDatatypeDefinitionAxiom(OWLLogicalAxiom): - """Represents a DatatypeDefinition axiom in the OWL 2 Specification.""" + """A datatype definition DatatypeDefinition( DT DR ) defines a new datatype DT as being semantically + equivalent to the data range DR; the latter must be a unary data range. This axiom allows one to use + the defined datatype DT as a synonym for DR — that is, in any expression in the ontology containing + such an axiom, DT can be replaced with DR without affecting the meaning of the ontology. + + (https://www.w3.org/TR/owl2-syntax/#Datatype_Definitions)""" __slots__ = '_datatype', '_datarange' _datatype: OWLDatatype @@ -150,7 +156,20 @@ def __repr__(self): class OWLHasKeyAxiom(OWLLogicalAxiom, HasOperands[OWLPropertyExpression]): - """Represents a HasKey axiom in the OWL 2 Specification.""" + """A key axiom HasKey( CE ( OPE1 ... OPEm ) ( DPE1 ... DPEn ) ) states that each + (named) instance of the class expression CE is uniquely identified by the object + property expressions OPEi and/or the data property expressions DPEj — that is, + no two distinct (named) instances of CE can coincide on the values of all + object property expressions OPEi and all data property expressions DPEj. In each + such axiom in an OWL ontology, m or n (or both) must be larger than zero. A key + axiom of the form HasKey( owl:Thing ( OPE ) () ) is similar to the axiom + InverseFunctionalObjectProperty( OPE ), the main differences being that the + former axiom is applicable only to individuals that are explicitly named in an + ontology, while the latter axiom is also applicable to anonymous individuals and + individuals whose existence is implied by existential quantification. + + (https://www.w3.org/TR/owl2-syntax/#Keys) + """ __slots__ = '_class_expression', '_property_expressions' _class_expression: OWLClassExpression @@ -247,7 +266,13 @@ def __repr__(self): class OWLEquivalentClassesAxiom(OWLNaryClassAxiom): - """Represents an EquivalentClasses axiom in the OWL 2 Specification.""" + """An equivalent classes axiom EquivalentClasses( CE1 ... CEn ) states that all of the class expressions CEi, + 1 ≤ i ≤ n, are semantically equivalent to each other. This axiom allows one to use each CEi as a synonym + for each CEj — that is, in any expression in the ontology containing such an axiom, CEi can be replaced + with CEj without affecting the meaning of the ontology. + + (https://www.w3.org/TR/owl2-syntax/#Equivalent_Classes) + """ __slots__ = () def __init__(self, class_expressions: List[OWLClassExpression], @@ -268,7 +293,11 @@ def named_classes(self) -> Iterable[OWLClass]: class OWLDisjointClassesAxiom(OWLNaryClassAxiom): - """Represents a DisjointClasses axiom in the OWL 2 Specification.""" + """A disjoint classes axiom DisjointClasses( CE1 ... CEn ) states that all of the class expressions CEi, 1 ≤ i ≤ n, + are pairwise disjoint; that is, no individual can be at the same time an instance of both CEi and CEj for i ≠ j. + + (https://www.w3.org/TR/owl2-syntax/#Disjoint_Classes) + """ __slots__ = () def __init__(self, class_expressions: List[OWLClassExpression], @@ -316,7 +345,11 @@ def __repr__(self): class OWLDifferentIndividualsAxiom(OWLNaryIndividualAxiom): - """Represents a DifferentIndividuals axiom in the OWL 2 Specification.""" + """An individual inequality axiom DifferentIndividuals( a1 ... an ) states that all of the individuals ai, + 1 ≤ i ≤ n, are different from each other; that is, no individuals ai and aj with i ≠ j can be derived to be equal. + This axiom can be used to axiomatize the unique name assumption — the assumption that all different individual + names denote different individuals. (https://www.w3.org/TR/owl2-syntax/#Individual_Inequality) + """ __slots__ = () def __init__(self, individuals: List[OWLIndividual], @@ -325,7 +358,13 @@ def __init__(self, individuals: List[OWLIndividual], class OWLSameIndividualAxiom(OWLNaryIndividualAxiom): - """Represents a SameIndividual axiom in the OWL 2 Specification.""" + """An individual equality axiom SameIndividual( a1 ... an ) states that all of the individuals ai, 1 ≤ i ≤ n, + are equal to each other. This axiom allows one to use each ai as a synonym for each aj — that is, in any + expression in the ontology containing such an axiom, ai can be replaced with aj without affecting the + meaning of the ontology. + + (https://www.w3.org/TR/owl2-syntax/#Individual_Equality) + """ __slots__ = () def __init__(self, individuals: List[OWLIndividual], @@ -372,7 +411,13 @@ def __repr__(self): class OWLEquivalentObjectPropertiesAxiom(OWLNaryPropertyAxiom[OWLObjectPropertyExpression], OWLObjectPropertyAxiom): - """Represents EquivalentObjectProperties axioms in the OWL 2 Specification.""" + """An equivalent object properties axiom EquivalentObjectProperties( OPE1 ... OPEn ) states that all of the object + property expressions OPEi, 1 ≤ i ≤ n, are semantically equivalent to each other. This axiom allows one to use each + OPEi as a synonym for each OPEj — that is, in any expression in the ontology containing such an axiom, OPEi can be + replaced with OPEj without affecting the meaning of the ontology. + + (https://www.w3.org/TR/owl2-syntax/#Equivalent_Object_Properties) + """ __slots__ = () def __init__(self, properties: List[OWLObjectPropertyExpression], @@ -381,7 +426,11 @@ def __init__(self, properties: List[OWLObjectPropertyExpression], class OWLDisjointObjectPropertiesAxiom(OWLNaryPropertyAxiom[OWLObjectPropertyExpression], OWLObjectPropertyAxiom): - """Represents DisjointObjectProperties axioms in the OWL 2 Specification.""" + """A disjoint object properties axiom DisjointObjectProperties( OPE1 ... OPEn ) states that all of the object + property expressions OPEi, 1 ≤ i ≤ n, are pairwise disjoint; that is, no individual x can be connected to an + individual y by both OPEi and OPEj for i ≠ j. + + (https://www.w3.org/TR/owl2-syntax/#Disjoint_Object_Properties)""" __slots__ = () def __init__(self, properties: List[OWLObjectPropertyExpression], @@ -390,7 +439,12 @@ def __init__(self, properties: List[OWLObjectPropertyExpression], class OWLInverseObjectPropertiesAxiom(OWLNaryPropertyAxiom[OWLObjectPropertyExpression], OWLObjectPropertyAxiom): - """Represents InverseObjectProperties axioms in the OWL 2 Specification.""" + """An inverse object properties axiom InverseObjectProperties( OPE1 OPE2 ) states that the object property + expression OPE1 is an inverse of the object property expression OPE2. Thus, if an individual x is connected by + OPE1 to an individual y, then y is also connected by OPE2 to x, and vice versa. + + (https://www.w3.org/TR/owl2-syntax/#Inverse_Object_Properties_2) + """ __slots__ = '_first', '_second' _first: OWLObjectPropertyExpression @@ -414,7 +468,13 @@ def __repr__(self): class OWLEquivalentDataPropertiesAxiom(OWLNaryPropertyAxiom[OWLDataPropertyExpression], OWLDataPropertyAxiom): - """Represents EquivalentDataProperties axioms in the OWL 2 Specification.""" + """An equivalent data properties axiom EquivalentDataProperties( DPE1 ... DPEn ) states that all the data property + expressions DPEi, 1 ≤ i ≤ n, are semantically equivalent to each other. This axiom allows one to use each DPEi as a + synonym for each DPEj — that is, in any expression in the ontology containing such an axiom, DPEi can be replaced + with DPEj without affecting the meaning of the ontology. + + (https://www.w3.org/TR/owl2-syntax/#Equivalent_Data_Properties) + """ __slots__ = () def __init__(self, properties: List[OWLDataPropertyExpression], @@ -423,7 +483,11 @@ def __init__(self, properties: List[OWLDataPropertyExpression], class OWLDisjointDataPropertiesAxiom(OWLNaryPropertyAxiom[OWLDataPropertyExpression], OWLDataPropertyAxiom): - """Represents DisjointDataProperties axioms in the OWL 2 Specification.""" + """A disjoint data properties axiom DisjointDataProperties( DPE1 ... DPEn ) states that all of the data property + expressions DPEi, 1 ≤ i ≤ n, are pairwise disjoint; that is, no individual x can be connected to a literal y by both + DPEi and DPEj for i ≠ j. + + (https://www.w3.org/TR/owl2-syntax/#Disjoint_Data_Properties)""" __slots__ = () def __init__(self, properties: List[OWLDataPropertyExpression], @@ -432,7 +496,13 @@ def __init__(self, properties: List[OWLDataPropertyExpression], class OWLSubClassOfAxiom(OWLClassAxiom): - """Represents an SubClassOf axiom in the OWL 2 Specification.""" + """A subclass axiom SubClassOf( CE1 CE2 ) states that the class expression CE1 is a subclass of the class + expression CE2. Roughly speaking, this states that CE1 is more specific than CE2. Subclass axioms are a + fundamental type of axioms in OWL 2 and can be used to construct a class hierarchy. Other kinds of class + expression axiom can be seen as syntactic shortcuts for one or more subclass axioms. + + (https://www.w3.org/TR/owl2-syntax/#Subclass_Axioms) + """ __slots__ = '_sub_class', '_super_class' _sub_class: OWLClassExpression @@ -472,7 +542,13 @@ def __repr__(self): class OWLDisjointUnionAxiom(OWLClassAxiom): - """Represents a DisjointUnion axiom in the OWL 2 Specification.""" + """A disjoint union axiom DisjointUnion( C CE1 ... CEn ) states that a class C is a disjoint union of the class + expressions CEi, 1 ≤ i ≤ n, all of which are pairwise disjoint. Such axioms are sometimes referred to as + covering axioms, as they state that the extensions of all CEi exactly cover the extension of C. Thus, each + instance of C is an instance of exactly one CEi, and each instance of CEi is an instance of C. + + (https://www.w3.org/TR/owl2-syntax/#Disjoint_Union_of_Class_Expressions) + """ __slots__ = '_cls', '_class_expressions' _cls: OWLClass @@ -511,7 +587,10 @@ def __repr__(self): class OWLClassAssertionAxiom(OWLIndividualAxiom): - """Represents ClassAssertion axioms in the OWL 2 Specification.""" + """A class assertion ClassAssertion( CE a ) states that the individual a is an instance of the class expression CE. + + (https://www.w3.org/TR/owl2-syntax/#Class_Assertions) + """ __slots__ = '_individual', '_class_expression' _individual: OWLIndividual @@ -547,6 +626,8 @@ def __hash__(self): def __repr__(self): return f'OWLClassAssertionAxiom(individual={self._individual},class_expression={self._class_expression},' \ f'annotations={self._annotations})' + + class OWLAnnotationProperty(OWLProperty): """Represents an AnnotationProperty in the OWL 2 specification.""" __slots__ = '_iri' @@ -565,6 +646,7 @@ def get_iri(self) -> IRI: # documented in parent return self._iri + class OWLAnnotation(OWLObject): """Annotations are used in the various types of annotation axioms, which bind annotations to their subjects (i.e. axioms or declarations).""" @@ -610,14 +692,23 @@ def __hash__(self): def __repr__(self): return f'OWLAnnotation({self._property}, {self._value})' + + class OWLAnnotationAxiom(OWLAxiom, metaclass=ABCMeta): """A super interface for annotation axioms.""" __slots__ = () def is_annotation_axiom(self) -> bool: return True + + class OWLAnnotationAssertionAxiom(OWLAnnotationAxiom): - """Represents AnnotationAssertion axioms in the OWL 2 specification.""" + """An annotation assertion AnnotationAssertion( AP as av ) states that the annotation subject as — an IRI or an + anonymous individual — is annotated with the annotation property AP and the annotation value av. + + + (https://www.w3.org/TR/owl2-syntax/#Annotation_Assertion) + """ __slots__ = '_subject', '_annotation' _subject: OWLAnnotationSubject @@ -671,7 +762,11 @@ def __hash__(self): def __repr__(self): return f'OWLAnnotationAssertionAxiom({self._subject}, {self._annotation})' class OWLSubAnnotationPropertyOfAxiom(OWLAnnotationAxiom): - """Represents an SubAnnotationPropertyOf axiom in the OWL 2 specification.""" + """An annotation subproperty axiom SubAnnotationPropertyOf( AP1 AP2 ) states that the annotation property AP1 is + a subproperty of the annotation property AP2. + + (https://www.w3.org/TR/owl2-syntax/#Annotation_Subproperties) + """ __slots__ = '_sub_property', '_super_property' _sub_property: OWLAnnotationProperty @@ -701,8 +796,13 @@ def __hash__(self): def __repr__(self): return f'OWLSubAnnotationPropertyOfAxiom(sub_property={self._sub_property},' \ f'super_property={self._super_property},annotations={self._annotations})' + + class OWLAnnotationPropertyDomainAxiom(OWLAnnotationAxiom): - """Represents an AnnotationPropertyDomain axiom in the OWL 2 specification.""" + """An annotation property domain axiom AnnotationPropertyDomain( AP U ) states that the domain of the annotation + property AP is the IRI U. + + (https://www.w3.org/TR/owl2-syntax/#Annotation_Property_Domain)""" __slots__ = '_property', '_domain' _property: OWLAnnotationProperty @@ -732,8 +832,13 @@ def __hash__(self): def __repr__(self): return f'OWLAnnotationPropertyDomainAxiom({repr(self._property)},{repr(self._domain)},' \ f'{repr(self._annotations)})' + + class OWLAnnotationPropertyRangeAxiom(OWLAnnotationAxiom): - """Represents an AnnotationPropertyRange axiom in the OWL 2 specification.""" + """An annotation property range axiom AnnotationPropertyRange( AP U ) + states that the range of the annotation property AP is the IRI U. + + (https://www.w3.org/TR/owl2-syntax/#Annotation_Property_Range)""" __slots__ = '_property', '_range' _property: OWLAnnotationProperty @@ -763,6 +868,8 @@ def __hash__(self): def __repr__(self): return f'OWLAnnotationPropertyRangeAxiom({repr(self._property)},{repr(self._range)},' \ f'{repr(self._annotations)})' + + class OWLSubPropertyAxiom(Generic[_P], OWLPropertyAxiom): """ Base interface for object and data sub-property axioms. @@ -797,23 +904,39 @@ def __hash__(self): def __repr__(self): return f'{type(self).__name__}(sub_property={self._sub_property},super_property={self._super_property},' \ f'annotations={self._annotations})' + + class OWLSubObjectPropertyOfAxiom(OWLSubPropertyAxiom[OWLObjectPropertyExpression], OWLObjectPropertyAxiom): - """Represents a SubObjectPropertyOf axiom in the OWL 2 specification.""" + """Object subproperty axioms are analogous to subclass axioms, and they come in two forms. + The basic form is SubObjectPropertyOf( OPE1 OPE2 ). This axiom states that the object property expression OPE1 + is a subproperty of the object property expression OPE2 — that is, if an individual x is connected by OPE1 to an + individual y, then x is also connected by OPE2 to y. + The more complex form is SubObjectPropertyOf( ObjectPropertyChain( OPE1 ... OPEn ) OPE ) + but ObjectPropertyChain is not represented in owlapy yet. + + (https://www.w3.org/TR/owl2-syntax/#Object_Subproperties)""" __slots__ = () def __init__(self, sub_property: OWLObjectPropertyExpression, super_property: OWLObjectPropertyExpression, annotations: Optional[Iterable['OWLAnnotation']] = None): super().__init__(sub_property=sub_property, super_property=super_property, annotations=annotations) + + class OWLSubDataPropertyOfAxiom(OWLSubPropertyAxiom[OWLDataPropertyExpression], OWLDataPropertyAxiom): - """Represents a SubDataPropertyOf axiom in the OWL 2 specification.""" + """A data subproperty axiom SubDataPropertyOf( DPE1 DPE2 ) states that the data property expression DPE1 is a + subproperty of the data property expression DPE2 — that is, if an individual x is connected by DPE1 to a literal y, + then x is connected by DPE2 to y as well. + + (https://www.w3.org/TR/owl2-syntax/#Data_Subproperties)""" __slots__ = () def __init__(self, sub_property: OWLDataPropertyExpression, super_property: OWLDataPropertyExpression, annotations: Optional[Iterable['OWLAnnotation']] = None): super().__init__(sub_property=sub_property, super_property=super_property, annotations=annotations) + class OWLPropertyAssertionAxiom(Generic[_P, _C], OWLIndividualAxiom, metaclass=ABCMeta): - """Represents a PropertyAssertion axiom in the OWL 2 specification.""" + """Base class for Property Assertion axioms.""" __slots__ = '_subject', '_property', '_object' _subject: OWLIndividual @@ -858,36 +981,62 @@ def __hash__(self): def __repr__(self): return f'{type(self).__name__}(subject={self._subject},property={self._property},' \ f'object={self._object},annotation={self._annotations})' + + class OWLObjectPropertyAssertionAxiom(OWLPropertyAssertionAxiom[OWLObjectPropertyExpression, OWLIndividual]): - """Represents an ObjectPropertyAssertion axiom in the OWL 2 specification.""" + """A positive object property assertion ObjectPropertyAssertion( OPE a1 a2 ) states that the individual a1 is + connected by the object property expression OPE to the individual a2. + + (https://www.w3.org/TR/owl2-syntax/#Positive_Object_Property_Assertions) + """ __slots__ = () def __init__(self, subject: OWLIndividual, property_: OWLObjectPropertyExpression, object_: OWLIndividual, annotations: Optional[Iterable['OWLAnnotation']] = None): super().__init__(subject, property_, object_, annotations) + + class OWLNegativeObjectPropertyAssertionAxiom(OWLPropertyAssertionAxiom[OWLObjectPropertyExpression, OWLIndividual]): - """Represents a NegativeObjectPropertyAssertion axiom in the OWL 2 specification.""" + """A negative object property assertion NegativeObjectPropertyAssertion( OPE a1 a2 ) states that the individual a1 + is not connected by the object property expression OPE to the individual a2. + + (https://www.w3.org/TR/owl2-syntax/#Negative_Object_Property_Assertions) + """ __slots__ = () def __init__(self, subject: OWLIndividual, property_: OWLObjectPropertyExpression, object_: OWLIndividual, annotations: Optional[Iterable['OWLAnnotation']] = None): super().__init__(subject, property_, object_, annotations) + + class OWLDataPropertyAssertionAxiom(OWLPropertyAssertionAxiom[OWLDataPropertyExpression, OWLLiteral]): - """Represents an DataPropertyAssertion axiom in the OWL 2 specification.""" + """A positive data property assertion DataPropertyAssertion( DPE a lt ) states that the individual a is connected + by the data property expression DPE to the literal lt. + + (https://www.w3.org/TR/owl2-syntax/#Positive_Data_Property_Assertions) + """ __slots__ = () def __init__(self, subject: OWLIndividual, property_: OWLDataPropertyExpression, object_: OWLLiteral, annotations: Optional[Iterable['OWLAnnotation']] = None): super().__init__(subject, property_, object_, annotations) + + class OWLNegativeDataPropertyAssertionAxiom(OWLPropertyAssertionAxiom[OWLDataPropertyExpression, OWLLiteral]): - """Represents an NegativeDataPropertyAssertion axiom in the OWL 2 specification.""" + """A negative data property assertion NegativeDataPropertyAssertion( DPE a lt ) states that the individual a is not + connected by the data property expression DPE to the literal lt. + + (https://www.w3.org/TR/owl2-syntax/#Negative_Data_Property_Assertions) + """ __slots__ = () def __init__(self, subject: OWLIndividual, property_: OWLDataPropertyExpression, object_: OWLLiteral, annotations: Optional[Iterable['OWLAnnotation']] = None): super().__init__(subject, property_, object_, annotations) + + class OWLUnaryPropertyAxiom(Generic[_P], OWLPropertyAxiom, metaclass=ABCMeta): - """Unary property axiom.""" + """Base class for Unary property axiom.""" __slots__ = '_property' _property: _P @@ -922,7 +1071,11 @@ def __repr__(self): class OWLFunctionalObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents FunctionalObjectProperty axioms in the OWL 2 specification.""" + """An object property functionality axiom FunctionalObjectProperty( OPE ) states that + the object property expression OPE is functional — that is, for each individual x, + there can be at most one distinct individual y such that x is connected by OPE to y. + + (https://www.w3.org/TR/owl2-syntax/#Functional_Object_Properties)""" __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -930,7 +1083,11 @@ def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional class OWLAsymmetricObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents AsymmetricObjectProperty axioms in the OWL 2 specification.""" + """An object property asymmetry axiom AsymmetricObjectProperty( OPE ) states that + the object property expression OPE is asymmetric — that is, if an individual x is + connected by OPE to an individual y, then y cannot be connected by OPE to x. + + (https://www.w3.org/TR/owl2-syntax/#Symmetric_Object_Properties)""" __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -938,7 +1095,12 @@ def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional class OWLInverseFunctionalObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents InverseFunctionalObjectProperty axioms in the OWL 2 specification.""" + """An object property inverse functionality axiom InverseFunctionalObjectProperty( OPE ) + states that the object property expression OPE is inverse-functional — that is, for each + individual x, there can be at most one individual y such that y is connected by OPE with x. + + (https://www.w3.org/TR/owl2-syntax/#Inverse-Functional_Object_Properties) + """ __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -946,7 +1108,12 @@ def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional class OWLIrreflexiveObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents IrreflexiveObjectProperty axioms in the OWL 2 specification.""" + """An object property irreflexivity axiom IrreflexiveObjectProperty( OPE ) states that the + object property expression OPE is irreflexive — that is, no individual is connected by + OPE to itself. + + (https://www.w3.org/TR/owl2-syntax/#Irreflexive_Object_Properties) + """ __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -954,7 +1121,12 @@ def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional class OWLReflexiveObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents ReflexiveObjectProperty axioms in the OWL 2 specification.""" + """An object property reflexivity axiom ReflexiveObjectProperty( OPE ) states that the + object property expression OPE is reflexive — that is, each individual is connected + by OPE to itself. Each such axiom can be seen as a syntactic shortcut for the + following axiom: SubClassOf( owl:Thing ObjectHasSelf( OPE ) ) + + (https://www.w3.org/TR/owl2-syntax/#Reflexive_Object_Properties)""" __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -962,7 +1134,14 @@ def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional class OWLSymmetricObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents SymmetricObjectProperty axioms in the OWL 2 specification.""" + """An object property symmetry axiom SymmetricObjectProperty( OPE ) states that + the object property expression OPE is symmetric — that is, if an individual x + is connected by OPE to an individual y, then y is also connected by OPE to x. + Each such axiom can be seen as a syntactic shortcut for the following axiom: + SubObjectPropertyOf( OPE ObjectInverseOf( OPE ) ) + + (https://www.w3.org/TR/owl2-syntax/#Symmetric_Object_Properties) + """ __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -970,7 +1149,14 @@ def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional class OWLTransitiveObjectPropertyAxiom(OWLObjectPropertyCharacteristicAxiom): - """Represents TransitiveObjectProperty axioms in the OWL 2 specification.""" + """An object property transitivity axiom TransitiveObjectProperty( OPE ) states that the + object property expressionOPE is transitive — that is, if an individual x is connected + by OPE to an individual y that is connected by OPE to an individual z, then x is also + connected by OPE to z. Each such axiom can be seen as a syntactic shortcut for the + following axiom: SubObjectPropertyOf( ObjectPropertyChain( OPE OPE ) OPE ) + + (https://www.w3.org/TR/owl2-syntax/#Transitive_Object_Properties) + """ __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -999,7 +1185,14 @@ def __repr__(self): class OWLFunctionalDataPropertyAxiom(OWLDataPropertyCharacteristicAxiom): - """Represents FunctionalDataProperty axioms in the OWL 2 specification.""" + """A data property functionality axiom FunctionalDataProperty( DPE ) states that + the data property expression DPE is functional — that is, for each individual x, + there can be at most one distinct literal y such that x is connected by DPE with + y. Each such axiom can be seen as a syntactic shortcut for the following axiom: + SubClassOf( owl:Thing DataMaxCardinality( 1 DPE ) ) + + (https://www.w3.org/TR/owl2-syntax/#Transitive_Object_Properties) + """ __slots__ = () def __init__(self, property_: OWLDataPropertyExpression, annotations: Optional[Iterable[OWLAnnotation]] = None): @@ -1007,7 +1200,7 @@ def __init__(self, property_: OWLDataPropertyExpression, annotations: Optional[I class OWLPropertyDomainAxiom(Generic[_P], OWLUnaryPropertyAxiom[_P], metaclass=ABCMeta): - """Represents ObjectPropertyDomain axioms in the OWL 2 specification.""" + """Base class for Property Domain axioms.""" __slots__ = '_domain' _domain: OWLClassExpression @@ -1035,7 +1228,7 @@ def __repr__(self): class OWLPropertyRangeAxiom(Generic[_P, _R], OWLUnaryPropertyAxiom[_P], metaclass=ABCMeta): - """Represents ObjectPropertyRange axioms in the OWL 2 specification.""" + """Base class for Property Range axioms.""" __slots__ = '_range' _range: _R @@ -1062,7 +1255,14 @@ def __repr__(self): class OWLObjectPropertyDomainAxiom(OWLPropertyDomainAxiom[OWLObjectPropertyExpression]): - """ Represents a ObjectPropertyDomain axiom in the OWL 2 Specification.""" + """ An object property domain axiom ObjectPropertyDomain( OPE CE ) states that the domain of the + object property expression OPE is the class expression CE — that is, if an individual x is + connected by OPE with some other individual, then x is an instance of CE. Each such axiom can + be seen as a syntactic shortcut for the following axiom: + SubClassOf( ObjectSomeValuesFrom( OPE owl:Thing ) CE ) + + (https://www.w3.org/TR/owl2-syntax/#Object_Property_Domain) + """ __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, domain: OWLClassExpression, @@ -1071,7 +1271,14 @@ def __init__(self, property_: OWLObjectPropertyExpression, domain: OWLClassExpre class OWLDataPropertyDomainAxiom(OWLPropertyDomainAxiom[OWLDataPropertyExpression]): - """ Represents a DataPropertyDomain axiom in the OWL 2 Specification.""" + """ A data property domain axiom DataPropertyDomain( DPE CE ) states that the domain of the + data property expression DPE is the class expression CE — that is, if an individual x is + connected by DPE with some literal, then x is an instance of CE. Each such axiom can be + seen as a syntactic shortcut for the following axiom: + SubClassOf( DataSomeValuesFrom( DPE rdfs:Literal) CE ) + + (https://www.w3.org/TR/owl2-syntax/#Data_Property_Domain) + """ __slots__ = () def __init__(self, property_: OWLDataPropertyExpression, domain: OWLClassExpression, @@ -1080,7 +1287,13 @@ def __init__(self, property_: OWLDataPropertyExpression, domain: OWLClassExpress class OWLObjectPropertyRangeAxiom(OWLPropertyRangeAxiom[OWLObjectPropertyExpression, OWLClassExpression]): - """ Represents a ObjectPropertyRange axiom in the OWL 2 Specification.""" + """ An object property range axiom ObjectPropertyRange( OPE CE ) states that the range of the object property + expression OPE is the class expression CE — that is, if some individual is connected by OPE with an individual x, + then x is an instance of CE. Each such axiom can be seen as a syntactic shortcut for the following axiom: + SubClassOf( owl:Thing ObjectAllValuesFrom( OPE CE ) ) + + (https://www.w3.org/TR/owl2-syntax/#Object_Property_Range) + """ __slots__ = () def __init__(self, property_: OWLObjectPropertyExpression, range_: OWLClassExpression, @@ -1089,7 +1302,13 @@ def __init__(self, property_: OWLObjectPropertyExpression, range_: OWLClassExpre class OWLDataPropertyRangeAxiom(OWLPropertyRangeAxiom[OWLDataPropertyExpression, OWLDataRange]): - """ Represents a DataPropertyRange axiom in the OWL 2 Specification.""" + """ A data property range axiom DataPropertyRange( DPE DR ) states that the range of the data property + expression DPE is the data range DR — that is, if some individual is connected by DPE with a literal x, + then x is in DR. The arity of DR must be one. Each such axiom can be seen as a syntactic shortcut for + the following axiom: SubClassOf( owl:Thing DataAllValuesFrom( DPE DR ) ) + + (https://www.w3.org/TR/owl2-syntax/#Data_Property_Range) + """ __slots__ = () def __init__(self, property_: OWLDataPropertyExpression, range_: OWLDataRange,