This release is a pre-release and may not be stable for production use.
PyHermit: Python OWL 2 DL Reasoner
PyHermit is a Python port of HermiT, an OWL 2 DL reasoner developed at the University of Oxford. It reasons about OWL ontologies with tableau-based decision procedures and needs no JVM.
Features
- OWL 2 DL reasoning: a tableau decision procedure over the OWL 2 Direct Semantics constructs.
- Tableau algorithm: hyperresolution with configurable blocking strategies.
- Non-simple property validation: the OWL 2 spec forbids transitive, role-chain, and inherited-superrole properties in cardinality restrictions,
hasSelf, asymmetric, irreflexive, or disjoint axioms. PyHermit rejects these at clausification time with aValueError. - All OWL 2 datatypes:
xsd:string,decimal,integer,float,double,dateTime,boolean,anyURI, and more. - SWRL rules and Datalog queries: DL-safe rule support with query evaluation.
- OWL file parsing: load RDF/XML, OWL/XML, and Functional-Style Syntax through a pure stdlib reader (
hermit.parser.load_ontology). - Pure Python: no JVM, no external binaries, a single
pip install. - Full type hints: the code passes
mypy --strict.
Install
pip install hermit-reasoner
Basic usage
from hermit import Reasoner
from hermit.model import AtomicConcept, AtomicRole, Individual
from hermit.owl_model.class_expression import OWLClass
from hermit.owl_model.owl_individual import OWLNamedIndividual
from hermit.owl_model.owl_property import OWLObjectProperty
from hermit.owl_model.owl_axiom import (
OWLClassAssertionAxiom, OWLObjectPropertyAssertionAxiom, OWLSubClassOfAxiom,
)
from hermit.structural.owl_clausification import OWLClausification
from hermit.structural.owl_normalization import OWLNormalization
NS = "http://example.org/"
Animal = OWLClass(NS + "Animal")
Dog = OWLClass(NS + "Dog")
hasOwner = OWLObjectProperty(NS + "hasOwner")
fido = OWLNamedIndividual(NS + "fido")
john = OWLNamedIndividual(NS + "john")
axioms = [
OWLSubClassOfAxiom(Dog, Animal),
OWLClassAssertionAxiom(fido, Dog),
OWLObjectPropertyAssertionAxiom(fido, hasOwner, john),
]
normalized = OWLNormalization().process_ontology(axioms)
dl_ontology = OWLClausification().clausify(normalized, ontology_iri="urn:example:pets")
reasoner = Reasoner(dl_ontology)
reasoner.precompute_inferences()
animal = AtomicConcept.create(NS + "Animal") # query handles
fido_h = Individual.create(NS + "fido")
assert reasoner.is_consistent()
assert reasoner.has_type(fido_h, animal) # inferred
assert reasoner.has_role_relationship(
fido_h, AtomicRole.create(NS + "hasOwner"), Individual.create(NS + "john")
)
instances = reasoner.get_instances(animal) # {fido}
reasoner.dispose()
Load from OWL files
from hermit.parser import load_ontology
from hermit.structural.owl_normalization import OWLNormalization
from hermit.structural.owl_clausification import OWLClausification
from hermit import Reasoner
axioms = load_ontology("path/to/ontology.owl") # stdlib reader: RDF/XML, OWL/XML, FSS
normalized = OWLNormalization().process_ontology(axioms)
dl_ontology = OWLClausification().clausify(normalized) # raises ValueError on OWL 2 violations
reasoner = Reasoner(dl_ontology)
reasoner.precompute_inferences()
Architecture
OWL Ontology
|
v
OWLNormalization (NNF, fresh-concept introduction, simple/complex property classification)
|
v
OWLClausification (DL clauses, non-simple property validation via ObjectPropertyInclusionManager)
|
v
Tableau Expansion (hyperresolution with blocking)
|
v
Classification & Instance Retrieval
See docs/ for architecture detail and API reference.
Non-simple property enforcement
OWL 2 forbids non-simple properties (transitive, or a superrole of a role chain) in certain axiom positions. PyHermit enforces this at clausification time:
from hermit.structural.owl_clausification import OWLClausification
clausification = OWLClausification()
try:
dl_ontology = clausification.clausify(normalized)
except ValueError as e:
# e.g. "Non-simple property '...' cannot be asymmetric (OWL 2 violation)"
print(e)
PyHermit checks these constraints, per OWL 2 spec Section 11.2:
AsymmetricObjectPropertyIrreflexiveObjectPropertyDisjointObjectProperties- Cardinality restrictions (
ObjectMinCardinality,ObjectMaxCardinality,ObjectExactCardinality) ObjectHasSelf
Source: ObjectPropertyInclusionManager._validate_complex_property_constraints, at src/hermit/structural/object_property_inclusion_manager.py:360.
Project status
PyHermit is a structural port of Java HermiT. The reasoning core is implemented: tableau, blocking, hyperresolution, classification, datatype reasoning, and SWRL/Datalog query answering. Ontology loading uses a pure stdlib reader (RDF/XML, OWL/XML, Functional-Style Syntax).
- TBox reasoning (classification, subsumption)
- ABox instance retrieval
- Datatype reasoning
- SWRL rules and Datalog query answering
- Non-simple property validation
- OWL file parsing through a pure stdlib reader (RDF/XML, OWL/XML, FSS)
Conformance: PyHermit passes 340 of 350 W3C OWL WG Approved-DL test cases at a 20-second per-case budget. Run this with pytest -m slow tests/test_wg_conformance.py, or python scripts/wg_run.py approved --list-fails --timeout=20. It reports zero wrong answers, zero errors, and zero unchecked conclusions. The 10 non-passing cases time out on hard combinatorial ontologies. Several of them pass with the 300-second budget the Java harness uses. FAITHFULNESS_AUDIT.md documents intentional divergences from the Java original.
The unit suite passes under pytest (the W3C conformance corpus is marked slow and excluded by default). The code passes mypy --strict and ruff.
Documentation
- docs/README.md: a learning guide covering OWL 2 DL reasoning and the hypertableau calculus from scratch, mapped to this codebase (see the algorithms series).
- FAITHFULNESS_AUDIT.md: where and why PyHermit diverges from Java HermiT.
- docs/: architecture, API reference, tutorials, and recipes.
- examples/: working examples, from basic to advanced.
- Original source: Java HermiT.
Related projects
- phillord/hermit-reasoner: the Java HermiT reasoner this project ports.
License
Apache 2.0. See LICENSE.
Based on HermiT, copyright Oxford University Computing Laboratory 2008-2014.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermit_reasoner-0.3.1a2.tar.gz.
File metadata
- Download URL: hermit_reasoner-0.3.1a2.tar.gz
- Upload date:
- Size: 290.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79041553400ee876230b2fe2903b71637511d0afa8097b0b36cf6444268cdf32
|
|
| MD5 |
7281a6e056334129c345fe584978a09a
|
|
| BLAKE2b-256 |
0b527a62fb7f0db70a8861bad39f075a799285c8d53c1cf5f04db740ad835907
|
File details
Details for the file hermit_reasoner-0.3.1a2-py3-none-any.whl.
File metadata
- Download URL: hermit_reasoner-0.3.1a2-py3-none-any.whl
- Upload date:
- Size: 353.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c3aed3af9da5684ea0ccb6747d3bfffe80468df1b57654e7a07bb70fe7ff4d1
|
|
| MD5 |
eab1d82c0f65f9da07a3195610ff3144
|
|
| BLAKE2b-256 |
ae4c319ae0d7527a3bfaa1ef66d41cfcd0a1ebc998a354daf9102b3b0c1a5271
|