Skip to main content

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, an IncompleteClassificationWarning is emitted and result.complete is False. Pass 0 for 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 like per_pair_timeout_ms=25 is 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 always complete (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 returned Classification — 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rustdl-0.4.8.tar.gz (1.4 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rustdl-0.4.8-cp310-abi3-win_amd64.whl (2.7 MB view details)

Uploaded CPython 3.10+Windows x86-64

rustdl-0.4.8-cp310-abi3-musllinux_1_2_x86_64.whl (2.6 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

rustdl-0.4.8-cp310-abi3-musllinux_1_2_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

rustdl-0.4.8-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

rustdl-0.4.8-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

rustdl-0.4.8-cp310-abi3-macosx_11_0_arm64.whl (2.3 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file rustdl-0.4.8.tar.gz.

File metadata

  • Download URL: rustdl-0.4.8.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rustdl-0.4.8.tar.gz
Algorithm Hash digest
SHA256 858291b9e5d8e109e880e0b4e34afbdf09dd5d29588e7ec9a8d68fe7d7598326
MD5 1dca673342878cb04379a074835f9983
BLAKE2b-256 70b872cea771bbe287c3ca54a3be950d5927b3e7c92d6e50025f996877cbda05

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8.tar.gz:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustdl-0.4.8-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: rustdl-0.4.8-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.7 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rustdl-0.4.8-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4d0f50d2681c478bb825994f3ce046dc7d9a23e7bd20de8c5d3a94051386427a
MD5 3f5ef62bfcaf4048bfda2afe21edf03e
BLAKE2b-256 02fc7713f76c9f17c88f1f2670a626d620523d84dd6859ce838f845321f80177

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8-cp310-abi3-win_amd64.whl:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustdl-0.4.8-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.8-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 fed65a2895020e8713809896af327a477a165b33480da0d13cdb116400144afb
MD5 f5165359c5e9fbd6e7142e0429d5a1e1
BLAKE2b-256 2f3d001ced4c902be73b902d050ad64b0846b7b2b8fa5e93a7263d4f674f5632

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustdl-0.4.8-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.8-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c9653efe6e9d9feca3ec865ff79ef39187680f251655b2b9c270a29fe75bf42b
MD5 668c047d14d7f29c82d7ebb6e35af3b4
BLAKE2b-256 53a56bfc382b9cf37367481177b932cb8c76f4c6fb745e42e3c2ae273422715e

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8-cp310-abi3-musllinux_1_2_aarch64.whl:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustdl-0.4.8-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.8-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 dbe93b3fa6bdd500c4c2348a0c28face755e96ead7b1caa4e986a56deb6c1e11
MD5 19b93c58b20b86a686f86648ffbe8a0c
BLAKE2b-256 c6aafe221edd61a0a70bb4664b4307c4f37a3433b24489cb1c7cf9bfbba99b1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustdl-0.4.8-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.8-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 76f602b39407e37a59719143b115aa9af940f041da85c0e078b56cb3835b9990
MD5 f8a4b112d8fddf9621bb09ee0e9a76b3
BLAKE2b-256 51b945cd1bedeea5c4c1c812f840729fa9f238192901ccd6e61b6b471ee071f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustdl-0.4.8-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.8-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bef2d1d477c0a6ac074ac2ac77209bfd30e861d9932afef75356ecc600c254e1
MD5 ddc53998ed4e5ddc9e6faa442df2e29a
BLAKE2b-256 6047fd2d6b51fe9ef2c125e6c249740d8e563bdde0aaa19edd7420213b541629

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.8-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release-python.yml on MaastrichtU-IDS/rustdl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.26

7 files

0.4.25

7 files

0.4.24

7 files

0.4.23

7 files

0.4.22

7 files

0.4.21

7 files

0.4.20

7 files

0.4.19

7 files

0.4.18

7 files

0.4.17

7 files

0.4.16

7 files

0.4.15

7 files

0.4.14

7 files

0.4.13

7 files

0.4.12

7 files

0.4.11

7 files

0.4.10

7 files

0.4.9

7 files

This release

0.4.8 This release

7 files

0.4.7

7 files

0.4.6

7 files

0.4.5

7 files

0.4.4

7 files

0.4.3

7 files

0.4.2

7 files

0.4.1

7 files

0.4.0

7 files

0.3.41

7 files

0.3.40

7 files

0.3.39

7 files

0.3.38

7 files

0.3.37

7 files

0.3.36

7 files

0.3.35

7 files

0.3.34

7 files

0.3.33

7 files

0.3.32

7 files

0.3.31

7 files

0.3.30

7 files

0.3.29

7 files

0.3.28

7 files

0.3.27

7 files

0.3.26

7 files

0.3.25

7 files

0.3.24

7 files

0.3.23

7 files

0.3.21

7 files

0.3.20

7 files

0.3.19

7 files

0.3.18

7 files

0.3.17

7 files

0.3.16

7 files

0.3.15

7 files

0.3.14

7 files

0.3.12

7 files

0.3.11

7 files

0.3.10

7 files

0.3.8

7 files

0.3.6

7 files

0.3.4

7 files

0.3.3

7 files

0.3.2

7 files

0.3.1

7 files

0.3.0

7 files

0.2.2

7 files

0.2.1

7 files

0.2.0

5 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page