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

Uploaded CPython 3.10+Windows x86-64

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

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

rustdl-0.4.17-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.17-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.17-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.17.tar.gz.

File metadata

  • Download URL: rustdl-0.4.17.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.17.tar.gz
Algorithm Hash digest
SHA256 f7a2f0630e137be30185af9d2526633e1e059a188acf572ea66226b2e9e66d9c
MD5 a0798767dfddf9ac7dd9962e6b50a831
BLAKE2b-256 273055282f8377d0ace71a2c3b867a67a4f5f4d2ad00fe87916b879a8a6f7f58

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: rustdl-0.4.17-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.17-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4ae386260c9259e8d0bad644ba960e2dadb139268e89780d6522b82f3291195e
MD5 b92dc075dd31d5f257dd0415a062ae13
BLAKE2b-256 cd9f01eec9622ae8877b7de2b9e71b3982fe6db917704976892f1660d00151b5

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.17-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 95111f51287f9b50295c5997bce50da2943f7516d9407ea0d1ac4a2e573c9bc3
MD5 baaf65df85a3f2fe46e39b525d80a317
BLAKE2b-256 7c00e7f0cad290fc16fc365b3cd9533ade3ae3e428ccbf877ffcf0fd20697d79

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.17-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 0192cea2e549a631b4dbe9ff26cd6f155628dfa56084d0cd1b25c87e687a76d1
MD5 b83f650bb723421b5eb3504d74c5d379
BLAKE2b-256 020343f03a8be18e69a5de90b32e3d447f56c2e54473737a97794afd83b1d1ae

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.17-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 32e71319d89a0410e02afe82cc3b7a5d5fd56d3b731f2cc5d66ad4c9132401e2
MD5 7ce90a529147c28a42410a88a5fd34f4
BLAKE2b-256 be61f2d63a7c82265779280f4091545ee848e1f683202447f5aa5ab9627de758

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.17-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 736d313a2196b6e0a50a394cf0ec8213da106d6be418e2a7aeb48713e882706b
MD5 c09297eddd8b1e434e3bc21c972db0bb
BLAKE2b-256 a3c0632a6917157feafeea84c97daefad76fc2792cc9b8ac84716f3268aaaa44

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.17-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d0fe6ad1e72f7db3a94c8c2f6f2737ecdd8595f429f3e928b0340f1381dc9286
MD5 e2e4e97cdc3ce8eadd0f769684af9cbe
BLAKE2b-256 de3b530c03fad92ebfb33fe400229c71fbec770173ef79bf1cf90efe2a6a6c95

See more details on using hashes here.

Provenance

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

This release

0.4.17 This release

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