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.18.tar.gz (1.5 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.18-cp310-abi3-win_amd64.whl (2.8 MB view details)

Uploaded CPython 3.10+Windows x86-64

rustdl-0.4.18-cp310-abi3-musllinux_1_2_x86_64.whl (2.7 MB view details)

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

rustdl-0.4.18-cp310-abi3-musllinux_1_2_aarch64.whl (2.5 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

rustdl-0.4.18-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.18-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.18-cp310-abi3-macosx_11_0_arm64.whl (2.4 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: rustdl-0.4.18.tar.gz
  • Upload date:
  • Size: 1.5 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.18.tar.gz
Algorithm Hash digest
SHA256 59357a43bf8bb9300f961f79f5aa87401c81de6cd9ab754b325bdf973cd61988
MD5 e63d3c50e8841c2a9a67f04ddb7e5ac8
BLAKE2b-256 929d3d4a8cf532baeb8631617cc0fee4216abe48d1c05dd1d2a447a9dc6e305b

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18.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.18-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: rustdl-0.4.18-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.8 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.18-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 1896d358bd34411602eacc0d4aa9b6c5f2adfbed1d8645cc521d3aa1001c6578
MD5 1ca8e95427703d911fed539f7c4aa144
BLAKE2b-256 e10b608bd7cbb55efe75ebf0b254e4baf042af77564189a570a96a2dda5f98d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18-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.18-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.18-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 73f11c2e749296069744fbcbfad27332300f893693b7e66a4911621f6877fa38
MD5 ca834a406efdcb4b64f8ebfd1612c00f
BLAKE2b-256 3cdf18271b0dcc248f019fffbe9aec80a47fe7ee86e19157496f006e0eb5de22

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18-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.18-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.18-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d8c5182e77f21fddd6ea0e7056c8dcd25cc9b69777097ad8b8ae51f3160d5427
MD5 ae564ca71455901154aed7fe6a03ca8c
BLAKE2b-256 187985a20128d4f22cdae9b9cbef91a79f85fc60f1bad95cd549b59235fab2c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18-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.18-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.18-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 648a72af3de0e95184d374726728089f96ac0f816f6e175b4f4925a9e543e503
MD5 90ebee18fab61fdbb6d06d3c16aeb9d6
BLAKE2b-256 9461268b936acf2a610ca02d04ab15dd6976ce1d789d3b7cd4c02816c38349e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18-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.18-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.18-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 bfce658e5e80cf628b43180fc21b85c9632a290bcc9f3d10a84a09d61c20eb6e
MD5 a23dd40d7fc654a26cb379122848808a
BLAKE2b-256 b2de507e289c445d91811754bc82d73957a63d732c086e323c9327ab844fbbaf

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18-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.18-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustdl-0.4.18-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 05e6ca108c46893502eaec6e8a433561460de03ab19eb3dc3f7ce8888cfc251a
MD5 d36e08c67a34c334ccd7c40544c99948
BLAKE2b-256 67446a53b10cd803e4385e4fed86c7dc5fc37dcad7d6bb9226c9833628964167

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustdl-0.4.18-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

This release

0.4.18 This release

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

0.4.8

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