Source code for owlapy.utils.signature
"""Signature extraction: the set of named entities referenced by an axiom or class expression/data range."""
from functools import singledispatchmethod
from typing import Set
from owlapy.class_expression import OWLDataOneOf, OWLDatatypeRestriction, OWLHasValueRestriction, OWLNaryBooleanClassExpression, OWLObjectComplementOf, OWLObjectOneOf, OWLQuantifiedRestriction
from owlapy.owl_axiom import (
OWLAnnotationAssertionAxiom,
OWLAnnotationProperty,
OWLAnnotationPropertyDomainAxiom,
OWLAnnotationPropertyRangeAxiom,
OWLClassAssertionAxiom,
OWLDatatypeDefinitionAxiom,
OWLDeclarationAxiom,
OWLDisjointUnionAxiom,
OWLHasKeyAxiom,
OWLNaryClassAxiom,
OWLNaryIndividualAxiom,
OWLNaryPropertyAxiom,
OWLPropertyAssertionAxiom,
OWLPropertyDomainAxiom,
OWLPropertyRangeAxiom,
OWLSubAnnotationPropertyOfAxiom,
OWLSubClassOfAxiom,
OWLSubPropertyAxiom,
OWLSubPropertyChainAxiom,
OWLUnaryPropertyAxiom,
)
from owlapy.owl_individual import OWLAnonymousIndividual, OWLNamedIndividual
from ..class_expression import OWLClass, OWLObjectHasSelf
from ..iri import IRI
from ..owl_data_ranges import OWLDataComplementOf, OWLNaryDataRange
from ..owl_datatype import OWLDatatype
from ..owl_literal import OWLLiteral
from ..owl_object import OWLEntity, OWLObject
from ..owl_property import OWLDataProperty, OWLObjectInverseOf, OWLObjectProperty
[docs]
class SignatureExtractor:
"""Computes the signature of an axiom or class expression/data range: the set of named entities
(:class:`OWLClass`, :class:`OWLObjectProperty`, :class:`OWLDataProperty`, :class:`OWLNamedIndividual`,
:class:`OWLDatatype`) that it references, collected recursively.
Mirrors the ``signature()`` method of OWLAPI's ``OWLObject`` interface. :class:`OWLAnonymousIndividual`
is intentionally excluded (it is not an :class:`OWLEntity`, per the OWL 2 specification). Likewise, a
bare :class:`~owlapy.iri.IRI` (used as an annotation subject/value or as the domain/range of an
annotation property axiom) contributes nothing to the signature unless it has been resolved to a
concrete entity elsewhere in the expression.
Covers the full set of class expression/data range constructs plus all :class:`OWLAxiom` subtypes,
including property characteristics, sub-property (and property chain) axioms, has-key, disjoint union,
datatype definition, (un)equal individuals and annotation axioms. See
https://github.com/dice-group/owlapy/issues/231.
"""
[docs]
@singledispatchmethod
def get_signature(self, o: OWLObject) -> Set[OWLEntity]:
"""Compute the signature of *o*.
Args:
o: An axiom, class expression, data range, property expression, individual or literal.
Returns:
The set of named entities referenced by *o*.
"""
raise NotImplementedError(
f"signature() is not yet implemented for {type(o).__name__}. See "
"https://github.com/dice-group/owlapy/issues/231 to track extending coverage."
)
# -- entities (leaves) -----------------------------------------------------
@get_signature.register
def _(self, o: OWLClass) -> Set[OWLEntity]:
return {o}
@get_signature.register
def _(self, o: OWLObjectProperty) -> Set[OWLEntity]:
return {o}
@get_signature.register
def _(self, o: OWLDataProperty) -> Set[OWLEntity]:
return {o}
@get_signature.register
def _(self, o: OWLObjectInverseOf) -> Set[OWLEntity]:
return self.get_signature(o.get_inverse())
@get_signature.register
def _(self, o: OWLNamedIndividual) -> Set[OWLEntity]:
return {o}
@get_signature.register
def _(self, o: OWLAnonymousIndividual) -> Set[OWLEntity]:
return set()
@get_signature.register
def _(self, o: OWLDatatype) -> Set[OWLEntity]:
return {o}
@get_signature.register
def _(self, o: OWLAnnotationProperty) -> Set[OWLEntity]:
return {o}
@get_signature.register
def _(self, o: OWLLiteral) -> Set[OWLEntity]:
return self.get_signature(o.get_datatype())
@get_signature.register
def _(self, o: IRI) -> Set[OWLEntity]:
# A raw IRI (annotation subject/value, annotation property domain/range) is not itself an
# OWLEntity -- it is only a name, not a resolved reference to one.
return set()
# -- class expressions / data ranges ---------------------------------------
@get_signature.register(OWLNaryBooleanClassExpression)
@get_signature.register(OWLObjectComplementOf)
@get_signature.register(OWLObjectOneOf)
@get_signature.register(OWLNaryDataRange)
@get_signature.register(OWLDataOneOf)
def _(self, o) -> Set[OWLEntity]:
result: Set[OWLEntity] = set()
for op in o.operands():
result |= self.get_signature(op)
return result
@get_signature.register
def _(self, o: OWLDataComplementOf) -> Set[OWLEntity]:
return self.get_signature(o.get_data_range())
@get_signature.register(OWLQuantifiedRestriction)
@get_signature.register(OWLHasValueRestriction)
def _(self, o) -> Set[OWLEntity]:
return self.get_signature(o.get_property()) | self.get_signature(o.get_filler())
@get_signature.register
def _(self, o: OWLObjectHasSelf) -> Set[OWLEntity]:
return self.get_signature(o.get_property())
@get_signature.register
def _(self, o: OWLDatatypeRestriction) -> Set[OWLEntity]:
return self.get_signature(o.get_datatype())
# -- axioms ------------------------------------------------------------
@get_signature.register
def _(self, o: OWLDeclarationAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_entity())
@get_signature.register
def _(self, o: OWLClassAssertionAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_individual()) | self.get_signature(o.get_class_expression())
@get_signature.register
def _(self, o: OWLPropertyAssertionAxiom) -> Set[OWLEntity]:
return (self.get_signature(o.get_subject()) | self.get_signature(o.get_property())
| self.get_signature(o.get_object()))
@get_signature.register
def _(self, o: OWLSubClassOfAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_sub_class()) | self.get_signature(o.get_super_class())
@get_signature.register
def _(self, o: OWLNaryClassAxiom) -> Set[OWLEntity]:
result: Set[OWLEntity] = set()
for ce in o.class_expressions():
result |= self.get_signature(ce)
return result
@get_signature.register
def _(self, o: OWLPropertyDomainAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_property()) | self.get_signature(o.get_domain())
@get_signature.register
def _(self, o: OWLPropertyRangeAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_property()) | self.get_signature(o.get_range())
@get_signature.register
def _(self, o: OWLUnaryPropertyAxiom) -> Set[OWLEntity]:
# Property characteristic axioms (Functional/InverseFunctional/Symmetric/Asymmetric/
# Transitive/Reflexive/Irreflexive ObjectProperty, FunctionalDataProperty). Domain/range axioms
# are handled by the more specific registrations above.
return self.get_signature(o.get_property())
@get_signature.register
def _(self, o: OWLSubPropertyAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_sub_property()) | self.get_signature(o.get_super_property())
@get_signature.register
def _(self, o: OWLSubPropertyChainAxiom) -> Set[OWLEntity]:
result: Set[OWLEntity] = self.get_signature(o.get_super_property())
for p in o.get_property_chain():
result |= self.get_signature(p)
return result
@get_signature.register
def _(self, o: OWLNaryIndividualAxiom) -> Set[OWLEntity]:
result: Set[OWLEntity] = set()
for ind in o.individuals():
result |= self.get_signature(ind)
return result
@get_signature.register
def _(self, o: OWLNaryPropertyAxiom) -> Set[OWLEntity]:
result: Set[OWLEntity] = set()
for p in o.properties():
result |= self.get_signature(p)
return result
@get_signature.register
def _(self, o: OWLDisjointUnionAxiom) -> Set[OWLEntity]:
result = self.get_signature(o.get_owl_class())
for ce in o.get_class_expressions():
result |= self.get_signature(ce)
return result
@get_signature.register
def _(self, o: OWLHasKeyAxiom) -> Set[OWLEntity]:
result = self.get_signature(o.get_class_expression())
for p in o.get_property_expressions():
result |= self.get_signature(p)
return result
@get_signature.register
def _(self, o: OWLDatatypeDefinitionAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_datatype()) | self.get_signature(o.get_datarange())
@get_signature.register
def _(self, o: OWLAnnotationAssertionAxiom) -> Set[OWLEntity]:
return (self.get_signature(o.get_subject()) | self.get_signature(o.get_property())
| self.get_signature(o.get_value()))
@get_signature.register
def _(self, o: OWLSubAnnotationPropertyOfAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_sub_property()) | self.get_signature(o.get_super_property())
@get_signature.register
def _(self, o: OWLAnnotationPropertyDomainAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_property()) | self.get_signature(o.get_domain())
@get_signature.register
def _(self, o: OWLAnnotationPropertyRangeAxiom) -> Set[OWLEntity]:
return self.get_signature(o.get_property()) | self.get_signature(o.get_range())