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.13.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.13-cp310-abi3-win_amd64.whl (2.7 MB view details)

Uploaded CPython 3.10+Windows x86-64

rustdl-0.4.13-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.13-cp310-abi3-musllinux_1_2_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

rustdl-0.4.13-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.13-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.13-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.13.tar.gz.

File metadata

  • Download URL: rustdl-0.4.13.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.13.tar.gz
Algorithm Hash digest
SHA256 47743bddec9b7609be0755f33cf18676168db9e22cabe236362828ba3b2a402b
MD5 e9e47cb698ec613f0fa4cff0af2a68a8
BLAKE2b-256 c1dbd13b9345e042f31cab6a0d499d8a642d54618765b2d4682ecbf6315a103c

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: rustdl-0.4.13-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.13-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5a7cac2d96f66eca892f491de92c8f48e7175c4d52644cca2640af858f17acec
MD5 7f87ed40329fb25b9218e64b73db6912
BLAKE2b-256 021c44131598a8a6721c8d645613036889daa14ecf2b5e8db1eaf43f5a910be0

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.13-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ab7374c23c14eaca7c868021246025b1008c2838a8efd3d3c1ca6d86314c508d
MD5 d9a36de45cb0f48aeaef567fe34f571d
BLAKE2b-256 3addb41b8dfe400d9feb04e043859c5b0b1266456d204d726807c7eb56bba92d

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.13-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e28a5eabb8026209294f6bb5c9f83205df116f757e43cd7b55ecc8ea8b0af67b
MD5 e8d07e00a59b7bfb0a87cbaa17ed76ca
BLAKE2b-256 e0c4dc4abdd4d28514dc7da82ce4fe2ac03947bd0252266fa94054ef571d6f44

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.13-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e7356a8ed15af7332096be9d20afab345631acfa7dcc2f97566ef0f78a0c0003
MD5 3e928ccb2361573cf1b22c2a96e4ae02
BLAKE2b-256 96718a9a95345b2343b5eae8275ea8ba588ce16b5d4c38ca4cef96d8c780daef

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.13-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f2b114f7cbf5f6bc480e85f417a0127a5a5479d60deb853c27f5401b5cc4ed0e
MD5 8eb80d589b7ec53e292d31c221434484
BLAKE2b-256 1f4664b35b3c5b65e3fddc2f06872a599a69efcd8a774323133943c4066ee117

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.13-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 013ae8b26a7ade3ebc0fc8ea3e7e30324b0b8c1a2972d7f1a55a2650c6482f71
MD5 b91f8d674918a984efdddf8459c05c5b
BLAKE2b-256 2c88fbdef8685f531d5144a24e53fd11323e2f71e751b6b0e91b6552fefdfd7b

See more details on using hashes here.

Provenance

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

This release

0.4.13 This release

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