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

Uploaded CPython 3.10+Windows x86-64

rustdl-0.4.20-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.20-cp310-abi3-musllinux_1_2_aarch64.whl (2.5 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

rustdl-0.4.20-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.20-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.20-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.20.tar.gz.

File metadata

  • Download URL: rustdl-0.4.20.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.20.tar.gz
Algorithm Hash digest
SHA256 96d6b2326366ce723101daa873f3a17dd8950d4d4515b14aa22548987b831079
MD5 211dd71e5b8f9f77b5da9b743597cb6e
BLAKE2b-256 b9fb70e3dd8e3c5f4a197050ba8ff3b0ee8d62b85f5676e786cc4c2008323767

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: rustdl-0.4.20-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.20-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 9e0fec260dd213dbddd676860bd5b625232ce79dbcaf405c3038cff5fd40c05a
MD5 103bc259c8f338dd9d965e02dbc348e1
BLAKE2b-256 62715380fd4c9d83bf61ce364fded6d533a0c493e5d601d800df4338fe600845

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.20-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ff10c1d27b599e086163e2c8d677abf3d1d6722f6e828742bf703398455ccba9
MD5 15b908b98fe4374c47dc82857ebd1f6f
BLAKE2b-256 cbd98ccff22ab5ef64dc260c23e6f5bfb3b8261d45020eb9bd420cd22a79a912

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.20-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 01a795291947862eaa218479123dfae998899a891a3bea4a73594a97db8b7d41
MD5 5dff262761655e39ca87a6fc4ab50cd9
BLAKE2b-256 0bc307457eb0860fe7d3e682bdcbb3dacc90c2602bd237e09278c5c12213f779

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.20-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 54e99336971db49f926a3375aadde480c815cc44c0a02473ed72e9cce3852e3e
MD5 985f2e2af978c4e0f0a1c1507c868abf
BLAKE2b-256 508af2a704a25ff3b476dad6b53a60bb742ef3a74e863de522e5b8f31cebf91a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.20-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6de6f80a33f411b92a31f1f53898e29e3acc9cf89242583dacec803e079956c4
MD5 346deca9b4397e29bfa9ee7997796d4d
BLAKE2b-256 83263727b0e9288513c2dd94d9cb602cfaececa3734eafd0ae571b86d979545f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rustdl-0.4.20-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 749601a0f6031473d1f8e5ba8b1d7e42406932bd27285278cdcec318d19a5d7b
MD5 9fb32e7de28e73bd952da5f5b1c7ccdf
BLAKE2b-256 fe83e8fc16d285b0a75333e29ee7dd930e4d0ee3fe6ca49e5fff04da1e0322e2

See more details on using hashes here.

Provenance

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

This release

0.4.20 This release

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

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