Source code for owlapy.owlapi_dlsyntax

"""OWLAPI-based DL Syntax parser and renderer.

This module provides DL (Description Logic) syntax parsing and rendering
using the OWLAPI Java library via JPype. It leverages OWLAPI's
``DLSyntaxObjectRenderer`` and ``DLSyntaxParser`` to handle both OWL class
expressions and OWL axioms in DL notation, and uses :class:`OWLAPIMapper`
to convert between owlapi Java objects and owlapy Python objects.

Usage example::

    from owlapy.owlapi_dlsyntax import OWLAPIDLSyntaxParser, OWLAPIDLSyntaxRenderer

    renderer = OWLAPIDLSyntaxRenderer()
    parser = OWLAPIDLSyntaxParser(namespace="http://example.org/")

    # Render an owlapy object to DL syntax string
    dl_string = renderer.render(some_owlapy_class_expression)
    dl_axiom_string = renderer.render(some_owlapy_axiom)

    # Parse a DL syntax string to an owlapy object
    ce = parser.parse_expression("∃ r.A ⊓ B")
    axiom = parser.parse_axiom("A ⊑ ∃ r.B")
"""
from typing import List, Optional

import jpype
import jpype.imports

from owlapy.class_expression import OWLClassExpression
from owlapy.owl_axiom import OWLAxiom
from owlapy.owl_object import OWLObject
from owlapy.owlapi_mapper import OWLAPIMapper
from owlapy.static_funcs import startJVM

if not jpype.isJVMStarted():
    startJVM()

from org.semanticweb.owlapi.apibinding import OWLManager as _OWLManager
from org.semanticweb.owlapi.dlsyntax.parser import DLSyntaxParser as _OWLAPI_DLSyntaxParser
from org.semanticweb.owlapi.dlsyntax.renderer import DLSyntaxObjectRenderer as _OWLAPI_DLSyntaxObjectRenderer

# Shared data factory for creating OWLAPI objects
_manager = _OWLManager.createOWLOntologyManager()
_data_factory = _manager.getOWLDataFactory()


[docs] class OWLAPIDLSyntaxRenderer: """DL Syntax renderer backed by OWLAPI's ``DLSyntaxObjectRenderer``. Renders owlapy OWL objects (class expressions and axioms) into Description Logic syntax strings by first mapping them to OWLAPI Java objects, then delegating to the OWLAPI renderer. Examples: >>> from owlapy.owlapi_dlsyntax import OWLAPIDLSyntaxRenderer >>> from owlapy.class_expression import OWLClass, OWLObjectSomeValuesFrom >>> from owlapy.owl_property import OWLObjectProperty >>> from owlapy.iri import IRI >>> renderer = OWLAPIDLSyntaxRenderer() >>> A = OWLClass(IRI.create("http://example.org/", "A")) >>> r = OWLObjectProperty(IRI.create("http://example.org/", "r")) >>> expr = OWLObjectSomeValuesFrom(r, A) >>> renderer.render(expr) '∃ r.A' """ def __init__(self): self._mapper = OWLAPIMapper() self._renderer = _OWLAPI_DLSyntaxObjectRenderer()
[docs] def render(self, obj: OWLObject) -> str: """Render an owlapy OWL object to a DL syntax string. Args: obj: An owlapy OWL object — can be an ``OWLClassExpression``, ``OWLAxiom``, or any other ``OWLObject`` supported by the OWLAPI DL renderer. Returns: The DL syntax string representation. Raises: NotImplementedError: If the object type is not supported by the mapper. """ owlapi_obj = self._mapper.map_(obj) return str(self._renderer.render(owlapi_obj))
[docs] class OWLAPIDLSyntaxParser: """DL Syntax parser backed by OWLAPI's ``DLSyntaxParser``. Parses DL syntax strings into owlapy OWL objects (class expressions and axioms) by delegating to the OWLAPI Java parser, then mapping the result back using :class:`OWLAPIMapper`. Args: namespace: Default namespace for resolving unqualified names. For example ``"http://example.org/"`` will resolve ``A`` to ``<http://example.org/#A>``. Note that OWLAPI's DL parser appends ``#`` between the namespace and local name. Examples: >>> from owlapy.owlapi_dlsyntax import OWLAPIDLSyntaxParser >>> parser = OWLAPIDLSyntaxParser(namespace="http://example.org/") >>> ce = parser.parse_expression("∃ r.A ⊓ B") >>> axiom = parser.parse_axiom("A ⊑ ∃ r.B") """ def __init__(self, namespace: Optional[str] = None): self._mapper = OWLAPIMapper() self._namespace = namespace @property def namespace(self) -> Optional[str]: """The default namespace used for resolving unqualified names.""" return self._namespace @namespace.setter def namespace(self, value: Optional[str]): self._namespace = value def _create_parser(self, expression_str: str) -> '_OWLAPI_DLSyntaxParser': """Create a fresh OWLAPI DLSyntaxParser for the given string. The OWLAPI ``DLSyntaxParser`` is stateful (token-stream based), so a new instance is created for each parse operation. """ parser = _OWLAPI_DLSyntaxParser(jpype.JString(expression_str)) parser.setOWLDataFactory(_data_factory) if self._namespace is not None: parser.setDefaultNamespace(self._namespace) return parser
[docs] def parse_expression(self, expression_str: str) -> OWLClassExpression: """Parse a DL syntax string into an owlapy ``OWLClassExpression``. Args: expression_str: DL syntax string representing a class expression. Examples: ``"A"``, ``"∃ r.A ⊓ B"``, ``"¬A ⊔ (∀ r.B)"``. Returns: The corresponding owlapy ``OWLClassExpression``. Raises: Exception: If the string cannot be parsed as a valid DL class expression (wraps OWLAPI's ``ParseException``). """ parser = self._create_parser(expression_str) owlapi_ce = parser.parseDescription() return self._mapper.map_(owlapi_ce)
[docs] def parse_axiom(self, axiom_str: str) -> OWLAxiom: """Parse a DL syntax string into an owlapy ``OWLAxiom``. Args: axiom_str: DL syntax string representing an axiom. Examples: ``"A ⊑ ∃ r.B"`` (subclass), ``"A ≡ B ⊓ C"`` (equivalent classes). Returns: The corresponding owlapy ``OWLAxiom``. Raises: Exception: If the string cannot be parsed as a valid DL axiom (wraps OWLAPI's ``ParseException``). """ parser = self._create_parser(axiom_str) owlapi_axiom = parser.parseAxiom() return self._mapper.map_(owlapi_axiom)
[docs] def parse_axioms(self, axioms_str: str) -> List[OWLAxiom]: """Parse a DL syntax string containing multiple axioms. The OWLAPI ``DLSyntaxParser.parseAxioms()`` expects axioms to be newline-separated. Args: axioms_str: DL syntax string with multiple axioms separated by newlines. Returns: A list of owlapy ``OWLAxiom`` objects. Raises: Exception: If any axiom cannot be parsed (wraps OWLAPI's ``ParseException``). """ parser = self._create_parser(axioms_str) owlapi_axiom_set = parser.parseAxioms() return [self._mapper.map_(ax) for ax in owlapi_axiom_set]