Sound, performant OWL 2 DL (SROIQ) reasoner in Rust — Python bindings
Project description
rustdl
Sound, performant OWL 2 DL (SROIQ) reasoner in Rust, with Python bindings. No JVM, no subprocess — native classification via PyO3.
rustdl beats HermiT on every measured ORE workload and wins outright against
Konclude on Horn-fragment ontologies. See the
project README for the full
benchmark table.
Install
pip install rustdl
Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS (Apple Silicon), and Windows (AMD64). Other platforms build from the sdist (needs a Rust toolchain).
Quick start
Prefer a guided walkthrough? See Debugging an ontology with rustdl — an end-to-end QA tutorial (classify →
debug()→ justify/repair → fix → read inferred facts).
import rustdl
# A small OWL 2 DL ontology ships inside the wheel (gzip-compressed) — no
# download needed. `examples.pizza()` returns its file path (decompressed
# into a per-user cache dir on first use); `examples.PIZZA_NS` is its
# namespace, so class IRIs are PIZZA_NS + local name (e.g. + "Pizza").
from rustdl.examples import pizza, PIZZA_NS, SULO_NS
# Classify. Format is auto-detected from the extension:
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML), .omn (Manchester).
result = rustdl.classify(pizza())
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable, "
f"complete={result.complete}")
# -> 88 classes, 0 unsatisfiable, complete=True
# Query the computed hierarchy
print(result.is_subclass(PIZZA_NS + "BoxedPizza", PIZZA_NS + "Pizza"))
# -> True
print(len(result.subclasses_of(PIZZA_NS + "FoodMaterial")))
# -> 25
# The pizza ontology is aligned to the SULO upper ontology, so reasoning
# spans both — e.g. a pizza-making timestamp is inferred to be a SULO StartTime:
print(result.is_subclass(PIZZA_NS + "BakingStartTime", SULO_NS + "StartTime"))
# -> True
# Other hierarchy queries (all take full class IRIs):
result.superclasses_of(PIZZA_NS + "Cheese") # -> list[str]
result.equivalent_classes(PIZZA_NS + "Pizza") # -> list[str]
result.direct_subsumers(PIZZA_NS + "BoxedPizza") # -> list[str] (Hasse-direct parents)
Bundled examples
Three real ontologies ship inside the wheel, gzip-compressed (~200 KB total).
They classify with no network access — each examples.X() decompresses
its ontology into a per-user cache dir ($XDG_CACHE_HOME/rustdl/examples or
~/.cache/rustdl/examples) on first use, then reuses it. Each examples.X_NS
is the namespace, so a class IRI is the namespace plus the local name.
| helper | ontology | classes | notes |
|---|---|---|---|
pizza() / PIZZA_NS |
ontostart pizza | 88 | SULO-aligned pizza-making ontology; classifies instantly + complete |
sulo() / SULO_NS |
SULO (Simple Upper-Level Ontology) | 17 | tiny; classifies in milliseconds |
sio() / SIO_NS |
SIO (Semanticscience Integrated Ontology) | ~1600 | realistic larger workload; takes tens of seconds. Class IRIs are numeric codes, e.g. SIO_NS + "SIO_000006" ("process") |
import rustdl
from rustdl import examples
r = rustdl.classify(examples.sulo())
print(r.is_subclass(examples.SULO_NS + "StartTime", examples.SULO_NS + "Object"))
# -> True
API
Classification
result = rustdl.classify(path, *, per_pair_timeout_ms=1000, saturation_only=False)
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=1000, saturation_only=False)
per_pair_timeout_ms— bound each subsumption test (default 1000;0= unbounded). A pair that exceeds the budget is recorded as "not subsumed": sound (never a false subsumption) but the result may be incomplete. When that happens, anIncompleteClassificationWarningis emitted andresult.completeisFalse. Pass0for the complete, unbounded classification. The default bounds pathological SROIQ inputs so classification can't hang silently. Conversely, on nominal-heavy ontologies (e.g. the W3C wine ontology) the engines never terminate on the hard pairs and only burn the full budget, so a low value likeper_pair_timeout_ms=25is much faster with no completeness loss (wine: 7.5× faster, identical hierarchy, MISSED=0 vs HermiT).saturation_only— skip the tableau entirely; EL-closure-only under-approximation. Dramatically faster on mostly-EL ontologies, and alwayscomplete(no tableau ⇒ no timeout).
classify / classify_bytes return a Classification:
| member | type | meaning |
|---|---|---|
.classes |
list[str] |
all declared class IRIs |
.unsatisfiable |
list[str] |
classes proved ⊑ ⊥ |
.inconsistent |
bool |
whole ontology unsatisfiable |
.complete |
bool |
False if any pair hit the timeout (result may miss edges) |
.timed_out_pairs |
int |
how many pairs hit the timeout |
.is_subclass(sub, sup) |
bool |
is sub ⊑ sup entailed? |
.subclasses_of(cls) |
list[str] |
every D with D ⊑ cls |
.superclasses_of(cls) |
list[str] |
every D with cls ⊑ D |
.equivalent_classes(cls) |
list[str] |
classes equivalent to cls |
.direct_subsumers(cls) |
list[str] |
Hasse-direct parents of cls |
One-shot queries
Each parses the file, answers one question, and returns:
rustdl.is_consistent(path) # -> bool
rustdl.is_class_satisfiable(path, class_iri) # -> bool
rustdl.is_subclass_of(path, sub_iri, sup_iri) # -> bool
rustdl.is_instance_of(path, class_iri, indiv_iri) # -> bool
rustdl.instances_of(path, class_iri) # -> list[str]
rustdl.realize(path) # -> dict[str, list[str]]
realize returns each individual IRI mapped to its most-specific entailed
class IRIs.
For repeated queries over the same ontology, prefer
classify(path)once and query the returnedClassification— each top-level function re-parses.
Inference materialization
rustdl.materialize_inferred_subclass_axioms(path) # -> list[tuple[str, str]]
rustdl.materialize_inferred_class_assertions(path) # -> list[tuple[str, str]]
materialize_inferred_subclass_axioms yields (sub, sup) pairs for every
entailed subsumption (excluding reflexive, owl:Thing/owl:Nothing, and
unsatisfiable classes). materialize_inferred_class_assertions yields
(class, individual) pairs. Useful for writing an inferred ontology back to
disk.
Errors
rustdl.RustdlError # base — catches everything from the library
rustdl.ParseError # the OWL file couldn't be parsed
rustdl.UnsupportedAxiomError # HasKey, role chains > length 2, etc.
rustdl.UnknownClassError # an IRI argument isn't a declared class
try:
result = rustdl.classify("ontology.ofn")
except rustdl.ParseError as e:
print(f"bad input: {e}")
except rustdl.RustdlError as e:
print(f"reasoning failed: {e}")
Soundness & coverage
rustdl is sound: every reported subsumption is a genuine entailment
(FP=0 against Konclude on the validation corpus). Completeness is partial — the
default classifier is empirically near-complete across the measured corpus but
not provably complete on all of SROIQ. saturation_only and
per_pair_timeout_ms are sound-but-incomplete by construction.
Data-property and datatype axioms outside the recognized preprocessing patterns
are silently dropped (a sound under-approximation). HasKey and role chains
longer than length 2 raise UnsupportedAxiomError. SWRL rules are skipped.
See the project documentation for the full coverage matrix, soundness contract, and architecture notes.
License
Apache-2.0 OR MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 rustdl-0.3.27.tar.gz.
File metadata
- Download URL: rustdl-0.3.27.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7afcbb4ec4ecc3971a8356adc56506a585e691c11ce3af9cfd2e2b8a9b4f89ed
|
|
| MD5 |
5935d7573b35c9bc50e926b5e3adf9c0
|
|
| BLAKE2b-256 |
c09c755438766a960f8f5cfe50728a8f7ba36c566f69bba054b80620ceaaf45a
|
Provenance
The following attestation bundles were made for rustdl-0.3.27.tar.gz:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27.tar.gz -
Subject digest:
7afcbb4ec4ecc3971a8356adc56506a585e691c11ce3af9cfd2e2b8a9b4f89ed - Sigstore transparency entry: 2207126125
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustdl-0.3.27-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: rustdl-0.3.27-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c1e48cec2667f6a0392391b33b4f50af27a2aa30f9f5d425a619f9a4194601c
|
|
| MD5 |
a2c9bbdcacbdf806a0f0b4af7f6fc81b
|
|
| BLAKE2b-256 |
b209db25e7beabf800602885c92abfe3a6c7d763b74e5b9a5f6fc5a357b718e5
|
Provenance
The following attestation bundles were made for rustdl-0.3.27-cp310-abi3-win_amd64.whl:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27-cp310-abi3-win_amd64.whl -
Subject digest:
1c1e48cec2667f6a0392391b33b4f50af27a2aa30f9f5d425a619f9a4194601c - Sigstore transparency entry: 2207126143
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustdl-0.3.27-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: rustdl-0.3.27-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
931380d77ddec8b69030679fbdbcdd6515702752cffdc734b7cc1e8fc7364948
|
|
| MD5 |
d66585840f6641dc3040c73325b128f9
|
|
| BLAKE2b-256 |
e3abbeb730dbc0171c15f39aa9eaa8f7069260c3eeb0b5a927f56219770e2e76
|
Provenance
The following attestation bundles were made for rustdl-0.3.27-cp310-abi3-musllinux_1_2_x86_64.whl:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27-cp310-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
931380d77ddec8b69030679fbdbcdd6515702752cffdc734b7cc1e8fc7364948 - Sigstore transparency entry: 2207126163
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustdl-0.3.27-cp310-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: rustdl-0.3.27-cp310-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.10+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27afcf3298431948c31b9ef719acabde4f2717fe66dc544dbde085c90455d441
|
|
| MD5 |
2eaa2e0fb61dee0444e9a2e7064f62ad
|
|
| BLAKE2b-256 |
2e8bca09766be45b37e985ea92e5c3121dcd86124299638bb662a06bbccc76c6
|
Provenance
The following attestation bundles were made for rustdl-0.3.27-cp310-abi3-musllinux_1_2_aarch64.whl:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27-cp310-abi3-musllinux_1_2_aarch64.whl -
Subject digest:
27afcf3298431948c31b9ef719acabde4f2717fe66dc544dbde085c90455d441 - Sigstore transparency entry: 2207126157
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustdl-0.3.27-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: rustdl-0.3.27-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c1e8a9d4f0a0c0b740bc758a86f0b98a44c3ed0dd6c76fa09d84681a2c9bca1
|
|
| MD5 |
71f1c823206564536fab7da0ea2a4865
|
|
| BLAKE2b-256 |
e6591768bc218d1ff1a07cfd5e550b74b468f2031ce6ceaf70a79b571edd8b5b
|
Provenance
The following attestation bundles were made for rustdl-0.3.27-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
2c1e8a9d4f0a0c0b740bc758a86f0b98a44c3ed0dd6c76fa09d84681a2c9bca1 - Sigstore transparency entry: 2207126172
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustdl-0.3.27-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: rustdl-0.3.27-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8ed5b56181e68bae3d00566d5ebc8ba1b8679c0aeb7811a530590bff2a75ebd
|
|
| MD5 |
11ec14ae5987636c6c0244cd4b63c8da
|
|
| BLAKE2b-256 |
1123485a30d7f3026ce29731b39325660ebbf431ccafffddebaf40b5d46dc54c
|
Provenance
The following attestation bundles were made for rustdl-0.3.27-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
c8ed5b56181e68bae3d00566d5ebc8ba1b8679c0aeb7811a530590bff2a75ebd - Sigstore transparency entry: 2207126132
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustdl-0.3.27-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: rustdl-0.3.27-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4b6dfebb80d977f7183b3b9bfdf07263ac1d7289e58ae1a7667dd82df2b68a6
|
|
| MD5 |
f03d843b1c3f61b2b03abeee8b98c6df
|
|
| BLAKE2b-256 |
3515603898428e21e0a9d79a33e0e688411ad6240ed07c1fe414ce3414a82eb8
|
Provenance
The following attestation bundles were made for rustdl-0.3.27-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release-python.yml on MaastrichtU-IDS/rustdl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustdl-0.3.27-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
f4b6dfebb80d977f7183b3b9bfdf07263ac1d7289e58ae1a7667dd82df2b68a6 - Sigstore transparency entry: 2207126154
- Sigstore integration time:
-
Permalink:
MaastrichtU-IDS/rustdl@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Branch / Tag:
refs/tags/v0.3.27 - Owner: https://github.com/MaastrichtU-IDS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@154f1db84ea5d3fba30cb6fc6c47637f3676f9d5 -
Trigger Event:
push
-
Statement type: