rustdl 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rustdl-0.2.0 → rustdl-0.2.2}/Cargo.lock +21 -22
- {rustdl-0.2.0 → rustdl-0.2.2}/Cargo.toml +6 -6
- rustdl-0.2.2/PKG-INFO +161 -0
- rustdl-0.2.2/README.md +135 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/Cargo.toml +1 -1
- rustdl-0.2.2/crates/owl-dl-py/README.md +135 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/src/errors.rs +4 -4
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/src/abox_check.rs +7 -0
- rustdl-0.2.0/PKG-INFO +0 -34
- rustdl-0.2.0/README.md +0 -8
- rustdl-0.2.0/crates/owl-dl-py/README.md +0 -8
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/Cargo.toml +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/README.md +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/absorb.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/clause.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/convert.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/convert_back.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/data_axioms.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/definitions.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/ir.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/lib.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/locality.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/normalize.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/ontology.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/residual_trigger.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/role_hierarchy.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/told.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/transform.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/src/vocab.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/tests/concept_pool_proptest.proptest-regressions +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/tests/concept_pool_proptest.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/tests/convert_round_trip_proptest.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-core/tests/role_hierarchy_proptest.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-datatypes/Cargo.toml +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-datatypes/README.md +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-datatypes/src/lib.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/.gitignore +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/src/classify.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/src/lib.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/src/load.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/src/materialize.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/src/queries.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/tests/python/conftest.py +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/tests/python/test_classify.py +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/tests/python/test_materialize.py +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/tests/python/test_queries.py +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/tests/python/test_smoke.py +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-py/tests/python/test_soundness.py +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/Cargo.toml +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/README.md +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/src/classify.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/src/lib.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/src/model_cache.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/src/realize.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/src/union_find.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/abox_consistency.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/anon349_diagnostic.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/datatype_completeness.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p1_direct_bot.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p1_no_bot.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p2_disjoint_different_individuals.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p2_disjoint_types.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_neg_opa.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_neg_opa_no_clash.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_role_hierarchy_neg_consistent.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_role_hierarchy_neg_inconsistent.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p4_same_different.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p4_same_without_different.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p5_functional_diff.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p5_functional_same_target.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_asymmetric.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_asymmetric_one_way.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_irreflexive.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_irreflexive_distinct.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p7_range_compatible.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/abox/p7_range_disjoint.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_cardinality_disjoint.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_property_domain-classified.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_property_domain.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_definition-classified.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_definition.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_facet.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/functional_data_property.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/sub_data_property-classified.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/datatype/sub_data_property.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/functional-equiv-some-bug.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/named-pizza-country-bug.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-01.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-02.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-03.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-04.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-05.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-06.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-07.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-08.txt +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.hermit.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.owx +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/fixtures/phase2b/phase2b-verdicts.log +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/konclude_closure_diff.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/label_heuristic_canary.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/phase2c_pair_06_canary.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/real_ontology_corpus.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-reasoner/tests/snapshot_phase0_canary.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-saturation/Cargo.toml +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-saturation/README.md +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-saturation/src/lib.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-saturation/tests/fixtures/phase2a_functional_role_canary.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-saturation/tests/fixtures/phase2b_compound_existential_canary.ofn +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/Cargo.toml +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/README.md +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/counters.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/deps.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/graph.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/hyper.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/lib.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/replay.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/rules.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/saturate.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/search.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/snapshot.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/src/trail.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/tests/backprop_risk.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/tests/replay_driver.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/tests/replay_roundtrip.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/crates/owl-dl-tableau/tests/snapshot_capture.rs +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/pyproject.toml +0 -0
- {rustdl-0.2.0 → rustdl-0.2.2}/python/rustdl/__init__.py +0 -0
|
@@ -1037,7 +1037,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
|
|
1037
1037
|
|
|
1038
1038
|
[[package]]
|
|
1039
1039
|
name = "owl-dl-bench"
|
|
1040
|
-
version = "0.2.
|
|
1040
|
+
version = "0.2.2"
|
|
1041
1041
|
dependencies = [
|
|
1042
1042
|
"anyhow",
|
|
1043
1043
|
"clap",
|
|
@@ -1054,7 +1054,7 @@ dependencies = [
|
|
|
1054
1054
|
|
|
1055
1055
|
[[package]]
|
|
1056
1056
|
name = "owl-dl-cli"
|
|
1057
|
-
version = "0.2.
|
|
1057
|
+
version = "0.2.2"
|
|
1058
1058
|
dependencies = [
|
|
1059
1059
|
"anyhow",
|
|
1060
1060
|
"clap",
|
|
@@ -1066,7 +1066,7 @@ dependencies = [
|
|
|
1066
1066
|
|
|
1067
1067
|
[[package]]
|
|
1068
1068
|
name = "owl-dl-core"
|
|
1069
|
-
version = "0.2.
|
|
1069
|
+
version = "0.2.2"
|
|
1070
1070
|
dependencies = [
|
|
1071
1071
|
"bitvec",
|
|
1072
1072
|
"bumpalo",
|
|
@@ -1080,7 +1080,7 @@ dependencies = [
|
|
|
1080
1080
|
|
|
1081
1081
|
[[package]]
|
|
1082
1082
|
name = "owl-dl-datatypes"
|
|
1083
|
-
version = "0.2.
|
|
1083
|
+
version = "0.2.2"
|
|
1084
1084
|
dependencies = [
|
|
1085
1085
|
"owl-dl-core",
|
|
1086
1086
|
"proptest",
|
|
@@ -1090,7 +1090,7 @@ dependencies = [
|
|
|
1090
1090
|
|
|
1091
1091
|
[[package]]
|
|
1092
1092
|
name = "owl-dl-py"
|
|
1093
|
-
version = "0.2.
|
|
1093
|
+
version = "0.2.2"
|
|
1094
1094
|
dependencies = [
|
|
1095
1095
|
"horned-owl",
|
|
1096
1096
|
"owl-dl-core",
|
|
@@ -1101,7 +1101,7 @@ dependencies = [
|
|
|
1101
1101
|
|
|
1102
1102
|
[[package]]
|
|
1103
1103
|
name = "owl-dl-reasoner"
|
|
1104
|
-
version = "0.2.
|
|
1104
|
+
version = "0.2.2"
|
|
1105
1105
|
dependencies = [
|
|
1106
1106
|
"dashmap",
|
|
1107
1107
|
"horned-owl",
|
|
@@ -1117,7 +1117,7 @@ dependencies = [
|
|
|
1117
1117
|
|
|
1118
1118
|
[[package]]
|
|
1119
1119
|
name = "owl-dl-saturation"
|
|
1120
|
-
version = "0.2.
|
|
1120
|
+
version = "0.2.2"
|
|
1121
1121
|
dependencies = [
|
|
1122
1122
|
"dashmap",
|
|
1123
1123
|
"fixedbitset",
|
|
@@ -1133,7 +1133,7 @@ dependencies = [
|
|
|
1133
1133
|
|
|
1134
1134
|
[[package]]
|
|
1135
1135
|
name = "owl-dl-tableau"
|
|
1136
|
-
version = "0.2.
|
|
1136
|
+
version = "0.2.2"
|
|
1137
1137
|
dependencies = [
|
|
1138
1138
|
"bitvec",
|
|
1139
1139
|
"bumpalo",
|
|
@@ -1392,11 +1392,10 @@ dependencies = [
|
|
|
1392
1392
|
|
|
1393
1393
|
[[package]]
|
|
1394
1394
|
name = "pyo3"
|
|
1395
|
-
version = "0.
|
|
1395
|
+
version = "0.25.1"
|
|
1396
1396
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1397
|
-
checksum = "
|
|
1397
|
+
checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a"
|
|
1398
1398
|
dependencies = [
|
|
1399
|
-
"cfg-if",
|
|
1400
1399
|
"indoc",
|
|
1401
1400
|
"libc",
|
|
1402
1401
|
"memoffset",
|
|
@@ -1410,9 +1409,9 @@ dependencies = [
|
|
|
1410
1409
|
|
|
1411
1410
|
[[package]]
|
|
1412
1411
|
name = "pyo3-build-config"
|
|
1413
|
-
version = "0.
|
|
1412
|
+
version = "0.25.1"
|
|
1414
1413
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1415
|
-
checksum = "
|
|
1414
|
+
checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598"
|
|
1416
1415
|
dependencies = [
|
|
1417
1416
|
"once_cell",
|
|
1418
1417
|
"target-lexicon",
|
|
@@ -1420,9 +1419,9 @@ dependencies = [
|
|
|
1420
1419
|
|
|
1421
1420
|
[[package]]
|
|
1422
1421
|
name = "pyo3-ffi"
|
|
1423
|
-
version = "0.
|
|
1422
|
+
version = "0.25.1"
|
|
1424
1423
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1425
|
-
checksum = "
|
|
1424
|
+
checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c"
|
|
1426
1425
|
dependencies = [
|
|
1427
1426
|
"libc",
|
|
1428
1427
|
"pyo3-build-config",
|
|
@@ -1430,9 +1429,9 @@ dependencies = [
|
|
|
1430
1429
|
|
|
1431
1430
|
[[package]]
|
|
1432
1431
|
name = "pyo3-macros"
|
|
1433
|
-
version = "0.
|
|
1432
|
+
version = "0.25.1"
|
|
1434
1433
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1435
|
-
checksum = "
|
|
1434
|
+
checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50"
|
|
1436
1435
|
dependencies = [
|
|
1437
1436
|
"proc-macro2",
|
|
1438
1437
|
"pyo3-macros-backend",
|
|
@@ -1442,9 +1441,9 @@ dependencies = [
|
|
|
1442
1441
|
|
|
1443
1442
|
[[package]]
|
|
1444
1443
|
name = "pyo3-macros-backend"
|
|
1445
|
-
version = "0.
|
|
1444
|
+
version = "0.25.1"
|
|
1446
1445
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1447
|
-
checksum = "
|
|
1446
|
+
checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc"
|
|
1448
1447
|
dependencies = [
|
|
1449
1448
|
"heck",
|
|
1450
1449
|
"proc-macro2",
|
|
@@ -1935,9 +1934,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
|
|
1935
1934
|
|
|
1936
1935
|
[[package]]
|
|
1937
1936
|
name = "target-lexicon"
|
|
1938
|
-
version = "0.
|
|
1937
|
+
version = "0.13.5"
|
|
1939
1938
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1940
|
-
checksum = "
|
|
1939
|
+
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
1941
1940
|
|
|
1942
1941
|
[[package]]
|
|
1943
1942
|
name = "tempfile"
|
|
@@ -2570,7 +2569,7 @@ dependencies = [
|
|
|
2570
2569
|
|
|
2571
2570
|
[[package]]
|
|
2572
2571
|
name = "xtask"
|
|
2573
|
-
version = "0.2.
|
|
2572
|
+
version = "0.2.2"
|
|
2574
2573
|
dependencies = [
|
|
2575
2574
|
"anyhow",
|
|
2576
2575
|
"clap",
|
|
@@ -3,7 +3,7 @@ resolver = "2"
|
|
|
3
3
|
members = ["crates/owl-dl-core", "crates/owl-dl-saturation", "crates/owl-dl-tableau", "crates/owl-dl-datatypes", "crates/owl-dl-reasoner", "crates/owl-dl-py"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.2"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
rust-version = "1.88"
|
|
9
9
|
license = "Apache-2.0 OR MIT"
|
|
@@ -15,11 +15,11 @@ keywords = ["owl", "ontology", "reasoner", "description-logic", "semantic-web"]
|
|
|
15
15
|
categories = ["science", "data-structures"]
|
|
16
16
|
|
|
17
17
|
[workspace.dependencies]
|
|
18
|
-
owl-dl-core = { path = "crates/owl-dl-core", version = "0.2.
|
|
19
|
-
owl-dl-saturation = { path = "crates/owl-dl-saturation", version = "0.2.
|
|
20
|
-
owl-dl-tableau = { path = "crates/owl-dl-tableau", version = "0.2.
|
|
21
|
-
owl-dl-datatypes = { path = "crates/owl-dl-datatypes", version = "0.2.
|
|
22
|
-
owl-dl-reasoner = { path = "crates/owl-dl-reasoner", version = "0.2.
|
|
18
|
+
owl-dl-core = { path = "crates/owl-dl-core", version = "0.2.2" }
|
|
19
|
+
owl-dl-saturation = { path = "crates/owl-dl-saturation", version = "0.2.2" }
|
|
20
|
+
owl-dl-tableau = { path = "crates/owl-dl-tableau", version = "0.2.2" }
|
|
21
|
+
owl-dl-datatypes = { path = "crates/owl-dl-datatypes", version = "0.2.2" }
|
|
22
|
+
owl-dl-reasoner = { path = "crates/owl-dl-reasoner", version = "0.2.2" }
|
|
23
23
|
|
|
24
24
|
horned-owl = { version = "1.4", default-features = false }
|
|
25
25
|
|
rustdl-0.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rustdl
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Rust
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Summary: Sound, performant OWL 2 DL (SROIQ) reasoner in Rust — Python bindings
|
|
16
|
+
Keywords: owl,ontology,reasoner,description-logic,semantic-web
|
|
17
|
+
Author: rustdl contributors
|
|
18
|
+
License: Apache-2.0 OR MIT
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
21
|
+
Project-URL: Changelog, https://github.com/MaastrichtU-IDS/rustdl/blob/main/CHANGELOG.md
|
|
22
|
+
Project-URL: Documentation, https://github.com/MaastrichtU-IDS/rustdl/blob/main/README.md
|
|
23
|
+
Project-URL: Homepage, https://github.com/MaastrichtU-IDS/rustdl
|
|
24
|
+
Project-URL: Repository, https://github.com/MaastrichtU-IDS/rustdl
|
|
25
|
+
|
|
26
|
+
# rustdl
|
|
27
|
+
|
|
28
|
+
Sound, performant **OWL 2 DL (SROIQ) reasoner** in Rust, with Python bindings.
|
|
29
|
+
No JVM, no subprocess — native classification via [PyO3](https://pyo3.rs).
|
|
30
|
+
|
|
31
|
+
`rustdl` beats HermiT on every measured ORE workload and wins outright against
|
|
32
|
+
Konclude on Horn-fragment ontologies. See the
|
|
33
|
+
[project README](https://github.com/MaastrichtU-IDS/rustdl) for the full
|
|
34
|
+
benchmark table.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pip install rustdl
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS
|
|
43
|
+
(Apple Silicon), and Windows (AMD64). Other platforms build from the sdist
|
|
44
|
+
(needs a Rust toolchain).
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import rustdl
|
|
50
|
+
|
|
51
|
+
# Classify an ontology. Format auto-detected from the extension:
|
|
52
|
+
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML).
|
|
53
|
+
result = rustdl.classify("pizza.ofn")
|
|
54
|
+
|
|
55
|
+
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable")
|
|
56
|
+
|
|
57
|
+
# Query the computed hierarchy
|
|
58
|
+
result.is_subclass("http://ex.org/Margherita", "http://ex.org/Pizza") # -> bool
|
|
59
|
+
result.subclasses_of("http://ex.org/Pizza") # -> list[str]
|
|
60
|
+
result.superclasses_of("http://ex.org/Margherita") # -> list[str]
|
|
61
|
+
result.equivalent_classes("http://ex.org/Pizza") # -> list[str]
|
|
62
|
+
result.direct_subsumers("http://ex.org/Margherita") # -> list[str] (Hasse-direct parents)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API
|
|
66
|
+
|
|
67
|
+
### Classification
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
result = rustdl.classify(path, *, per_pair_timeout_ms=None, saturation_only=False)
|
|
71
|
+
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=None, saturation_only=False)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- `per_pair_timeout_ms` — bound each subsumption test; pairs that exceed it
|
|
75
|
+
default to "not subsumed" (a sound under-approximation — robust against
|
|
76
|
+
pathological SROIQ inputs).
|
|
77
|
+
- `saturation_only` — skip the tableau entirely; EL-closure-only
|
|
78
|
+
under-approximation. Dramatically faster on mostly-EL ontologies.
|
|
79
|
+
|
|
80
|
+
`classify` / `classify_bytes` return a `Classification`:
|
|
81
|
+
|
|
82
|
+
| member | type | meaning |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `.classes` | `list[str]` | all declared class IRIs |
|
|
85
|
+
| `.unsatisfiable` | `list[str]` | classes proved `⊑ ⊥` |
|
|
86
|
+
| `.inconsistent` | `bool` | whole ontology unsatisfiable |
|
|
87
|
+
| `.is_subclass(sub, sup)` | `bool` | is `sub ⊑ sup` entailed? |
|
|
88
|
+
| `.subclasses_of(cls)` | `list[str]` | every `D` with `D ⊑ cls` |
|
|
89
|
+
| `.superclasses_of(cls)` | `list[str]` | every `D` with `cls ⊑ D` |
|
|
90
|
+
| `.equivalent_classes(cls)` | `list[str]` | classes equivalent to `cls` |
|
|
91
|
+
| `.direct_subsumers(cls)` | `list[str]` | Hasse-direct parents of `cls` |
|
|
92
|
+
|
|
93
|
+
### One-shot queries
|
|
94
|
+
|
|
95
|
+
Each parses the file, answers one question, and returns:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
rustdl.is_consistent(path) # -> bool
|
|
99
|
+
rustdl.is_class_satisfiable(path, class_iri) # -> bool
|
|
100
|
+
rustdl.is_subclass_of(path, sub_iri, sup_iri) # -> bool
|
|
101
|
+
rustdl.is_instance_of(path, class_iri, indiv_iri) # -> bool
|
|
102
|
+
rustdl.instances_of(path, class_iri) # -> list[str]
|
|
103
|
+
rustdl.realize(path) # -> dict[str, list[str]]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`realize` returns each individual IRI mapped to its most-specific entailed
|
|
107
|
+
class IRIs.
|
|
108
|
+
|
|
109
|
+
> For repeated queries over the same ontology, prefer `classify(path)` once and
|
|
110
|
+
> query the returned `Classification` — each top-level function re-parses.
|
|
111
|
+
|
|
112
|
+
### Inference materialization
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
rustdl.materialize_inferred_subclass_axioms(path) # -> list[tuple[str, str]]
|
|
116
|
+
rustdl.materialize_inferred_class_assertions(path) # -> list[tuple[str, str]]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`materialize_inferred_subclass_axioms` yields `(sub, sup)` pairs for every
|
|
120
|
+
entailed subsumption (excluding reflexive, `owl:Thing`/`owl:Nothing`, and
|
|
121
|
+
unsatisfiable classes). `materialize_inferred_class_assertions` yields
|
|
122
|
+
`(class, individual)` pairs. Useful for writing an inferred ontology back to
|
|
123
|
+
disk.
|
|
124
|
+
|
|
125
|
+
### Errors
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
rustdl.RustdlError # base — catches everything from the library
|
|
129
|
+
rustdl.ParseError # the OWL file couldn't be parsed
|
|
130
|
+
rustdl.UnsupportedAxiomError # HasKey, role chains > length 2, etc.
|
|
131
|
+
rustdl.UnknownClassError # an IRI argument isn't a declared class
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
try:
|
|
136
|
+
result = rustdl.classify("ontology.ofn")
|
|
137
|
+
except rustdl.ParseError as e:
|
|
138
|
+
print(f"bad input: {e}")
|
|
139
|
+
except rustdl.RustdlError as e:
|
|
140
|
+
print(f"reasoning failed: {e}")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Soundness & coverage
|
|
144
|
+
|
|
145
|
+
`rustdl` is **sound**: every reported subsumption is a genuine entailment
|
|
146
|
+
(FP=0 against Konclude on the validation corpus). Completeness is partial — the
|
|
147
|
+
default classifier is empirically near-complete across the measured corpus but
|
|
148
|
+
not provably complete on all of SROIQ. `saturation_only` and
|
|
149
|
+
`per_pair_timeout_ms` are sound-but-incomplete by construction.
|
|
150
|
+
|
|
151
|
+
Data-property and datatype axioms outside the recognized preprocessing patterns
|
|
152
|
+
are silently dropped (a sound under-approximation). `HasKey` and role chains
|
|
153
|
+
longer than length 2 raise `UnsupportedAxiomError`. SWRL rules are skipped.
|
|
154
|
+
|
|
155
|
+
See the [project documentation](https://github.com/MaastrichtU-IDS/rustdl) for
|
|
156
|
+
the full coverage matrix, soundness contract, and architecture notes.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
Apache-2.0 OR MIT.
|
|
161
|
+
|
rustdl-0.2.2/README.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# rustdl
|
|
2
|
+
|
|
3
|
+
Sound, performant **OWL 2 DL (SROIQ) reasoner** in Rust, with Python bindings.
|
|
4
|
+
No JVM, no subprocess — native classification via [PyO3](https://pyo3.rs).
|
|
5
|
+
|
|
6
|
+
`rustdl` beats HermiT on every measured ORE workload and wins outright against
|
|
7
|
+
Konclude on Horn-fragment ontologies. See the
|
|
8
|
+
[project README](https://github.com/MaastrichtU-IDS/rustdl) for the full
|
|
9
|
+
benchmark table.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install rustdl
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS
|
|
18
|
+
(Apple Silicon), and Windows (AMD64). Other platforms build from the sdist
|
|
19
|
+
(needs a Rust toolchain).
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import rustdl
|
|
25
|
+
|
|
26
|
+
# Classify an ontology. Format auto-detected from the extension:
|
|
27
|
+
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML).
|
|
28
|
+
result = rustdl.classify("pizza.ofn")
|
|
29
|
+
|
|
30
|
+
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable")
|
|
31
|
+
|
|
32
|
+
# Query the computed hierarchy
|
|
33
|
+
result.is_subclass("http://ex.org/Margherita", "http://ex.org/Pizza") # -> bool
|
|
34
|
+
result.subclasses_of("http://ex.org/Pizza") # -> list[str]
|
|
35
|
+
result.superclasses_of("http://ex.org/Margherita") # -> list[str]
|
|
36
|
+
result.equivalent_classes("http://ex.org/Pizza") # -> list[str]
|
|
37
|
+
result.direct_subsumers("http://ex.org/Margherita") # -> list[str] (Hasse-direct parents)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### Classification
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
result = rustdl.classify(path, *, per_pair_timeout_ms=None, saturation_only=False)
|
|
46
|
+
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=None, saturation_only=False)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `per_pair_timeout_ms` — bound each subsumption test; pairs that exceed it
|
|
50
|
+
default to "not subsumed" (a sound under-approximation — robust against
|
|
51
|
+
pathological SROIQ inputs).
|
|
52
|
+
- `saturation_only` — skip the tableau entirely; EL-closure-only
|
|
53
|
+
under-approximation. Dramatically faster on mostly-EL ontologies.
|
|
54
|
+
|
|
55
|
+
`classify` / `classify_bytes` return a `Classification`:
|
|
56
|
+
|
|
57
|
+
| member | type | meaning |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `.classes` | `list[str]` | all declared class IRIs |
|
|
60
|
+
| `.unsatisfiable` | `list[str]` | classes proved `⊑ ⊥` |
|
|
61
|
+
| `.inconsistent` | `bool` | whole ontology unsatisfiable |
|
|
62
|
+
| `.is_subclass(sub, sup)` | `bool` | is `sub ⊑ sup` entailed? |
|
|
63
|
+
| `.subclasses_of(cls)` | `list[str]` | every `D` with `D ⊑ cls` |
|
|
64
|
+
| `.superclasses_of(cls)` | `list[str]` | every `D` with `cls ⊑ D` |
|
|
65
|
+
| `.equivalent_classes(cls)` | `list[str]` | classes equivalent to `cls` |
|
|
66
|
+
| `.direct_subsumers(cls)` | `list[str]` | Hasse-direct parents of `cls` |
|
|
67
|
+
|
|
68
|
+
### One-shot queries
|
|
69
|
+
|
|
70
|
+
Each parses the file, answers one question, and returns:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
rustdl.is_consistent(path) # -> bool
|
|
74
|
+
rustdl.is_class_satisfiable(path, class_iri) # -> bool
|
|
75
|
+
rustdl.is_subclass_of(path, sub_iri, sup_iri) # -> bool
|
|
76
|
+
rustdl.is_instance_of(path, class_iri, indiv_iri) # -> bool
|
|
77
|
+
rustdl.instances_of(path, class_iri) # -> list[str]
|
|
78
|
+
rustdl.realize(path) # -> dict[str, list[str]]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`realize` returns each individual IRI mapped to its most-specific entailed
|
|
82
|
+
class IRIs.
|
|
83
|
+
|
|
84
|
+
> For repeated queries over the same ontology, prefer `classify(path)` once and
|
|
85
|
+
> query the returned `Classification` — each top-level function re-parses.
|
|
86
|
+
|
|
87
|
+
### Inference materialization
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
rustdl.materialize_inferred_subclass_axioms(path) # -> list[tuple[str, str]]
|
|
91
|
+
rustdl.materialize_inferred_class_assertions(path) # -> list[tuple[str, str]]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`materialize_inferred_subclass_axioms` yields `(sub, sup)` pairs for every
|
|
95
|
+
entailed subsumption (excluding reflexive, `owl:Thing`/`owl:Nothing`, and
|
|
96
|
+
unsatisfiable classes). `materialize_inferred_class_assertions` yields
|
|
97
|
+
`(class, individual)` pairs. Useful for writing an inferred ontology back to
|
|
98
|
+
disk.
|
|
99
|
+
|
|
100
|
+
### Errors
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
rustdl.RustdlError # base — catches everything from the library
|
|
104
|
+
rustdl.ParseError # the OWL file couldn't be parsed
|
|
105
|
+
rustdl.UnsupportedAxiomError # HasKey, role chains > length 2, etc.
|
|
106
|
+
rustdl.UnknownClassError # an IRI argument isn't a declared class
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
try:
|
|
111
|
+
result = rustdl.classify("ontology.ofn")
|
|
112
|
+
except rustdl.ParseError as e:
|
|
113
|
+
print(f"bad input: {e}")
|
|
114
|
+
except rustdl.RustdlError as e:
|
|
115
|
+
print(f"reasoning failed: {e}")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Soundness & coverage
|
|
119
|
+
|
|
120
|
+
`rustdl` is **sound**: every reported subsumption is a genuine entailment
|
|
121
|
+
(FP=0 against Konclude on the validation corpus). Completeness is partial — the
|
|
122
|
+
default classifier is empirically near-complete across the measured corpus but
|
|
123
|
+
not provably complete on all of SROIQ. `saturation_only` and
|
|
124
|
+
`per_pair_timeout_ms` are sound-but-incomplete by construction.
|
|
125
|
+
|
|
126
|
+
Data-property and datatype axioms outside the recognized preprocessing patterns
|
|
127
|
+
are silently dropped (a sound under-approximation). `HasKey` and role chains
|
|
128
|
+
longer than length 2 raise `UnsupportedAxiomError`. SWRL rules are skipped.
|
|
129
|
+
|
|
130
|
+
See the [project documentation](https://github.com/MaastrichtU-IDS/rustdl) for
|
|
131
|
+
the full coverage matrix, soundness contract, and architecture notes.
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
Apache-2.0 OR MIT.
|
|
@@ -17,7 +17,7 @@ name = "rustdl" # Python import name: `import rustdl`
|
|
|
17
17
|
crate-type = ["cdylib"] # Python C extension
|
|
18
18
|
|
|
19
19
|
[dependencies]
|
|
20
|
-
pyo3 = { version = "0.
|
|
20
|
+
pyo3 = { version = "0.25", features = ["abi3-py310", "extension-module"] }
|
|
21
21
|
owl-dl-reasoner.workspace = true
|
|
22
22
|
owl-dl-core.workspace = true
|
|
23
23
|
horned-owl.workspace = true
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# rustdl
|
|
2
|
+
|
|
3
|
+
Sound, performant **OWL 2 DL (SROIQ) reasoner** in Rust, with Python bindings.
|
|
4
|
+
No JVM, no subprocess — native classification via [PyO3](https://pyo3.rs).
|
|
5
|
+
|
|
6
|
+
`rustdl` beats HermiT on every measured ORE workload and wins outright against
|
|
7
|
+
Konclude on Horn-fragment ontologies. See the
|
|
8
|
+
[project README](https://github.com/MaastrichtU-IDS/rustdl) for the full
|
|
9
|
+
benchmark table.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install rustdl
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS
|
|
18
|
+
(Apple Silicon), and Windows (AMD64). Other platforms build from the sdist
|
|
19
|
+
(needs a Rust toolchain).
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import rustdl
|
|
25
|
+
|
|
26
|
+
# Classify an ontology. Format auto-detected from the extension:
|
|
27
|
+
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML).
|
|
28
|
+
result = rustdl.classify("pizza.ofn")
|
|
29
|
+
|
|
30
|
+
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable")
|
|
31
|
+
|
|
32
|
+
# Query the computed hierarchy
|
|
33
|
+
result.is_subclass("http://ex.org/Margherita", "http://ex.org/Pizza") # -> bool
|
|
34
|
+
result.subclasses_of("http://ex.org/Pizza") # -> list[str]
|
|
35
|
+
result.superclasses_of("http://ex.org/Margherita") # -> list[str]
|
|
36
|
+
result.equivalent_classes("http://ex.org/Pizza") # -> list[str]
|
|
37
|
+
result.direct_subsumers("http://ex.org/Margherita") # -> list[str] (Hasse-direct parents)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### Classification
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
result = rustdl.classify(path, *, per_pair_timeout_ms=None, saturation_only=False)
|
|
46
|
+
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=None, saturation_only=False)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `per_pair_timeout_ms` — bound each subsumption test; pairs that exceed it
|
|
50
|
+
default to "not subsumed" (a sound under-approximation — robust against
|
|
51
|
+
pathological SROIQ inputs).
|
|
52
|
+
- `saturation_only` — skip the tableau entirely; EL-closure-only
|
|
53
|
+
under-approximation. Dramatically faster on mostly-EL ontologies.
|
|
54
|
+
|
|
55
|
+
`classify` / `classify_bytes` return a `Classification`:
|
|
56
|
+
|
|
57
|
+
| member | type | meaning |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `.classes` | `list[str]` | all declared class IRIs |
|
|
60
|
+
| `.unsatisfiable` | `list[str]` | classes proved `⊑ ⊥` |
|
|
61
|
+
| `.inconsistent` | `bool` | whole ontology unsatisfiable |
|
|
62
|
+
| `.is_subclass(sub, sup)` | `bool` | is `sub ⊑ sup` entailed? |
|
|
63
|
+
| `.subclasses_of(cls)` | `list[str]` | every `D` with `D ⊑ cls` |
|
|
64
|
+
| `.superclasses_of(cls)` | `list[str]` | every `D` with `cls ⊑ D` |
|
|
65
|
+
| `.equivalent_classes(cls)` | `list[str]` | classes equivalent to `cls` |
|
|
66
|
+
| `.direct_subsumers(cls)` | `list[str]` | Hasse-direct parents of `cls` |
|
|
67
|
+
|
|
68
|
+
### One-shot queries
|
|
69
|
+
|
|
70
|
+
Each parses the file, answers one question, and returns:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
rustdl.is_consistent(path) # -> bool
|
|
74
|
+
rustdl.is_class_satisfiable(path, class_iri) # -> bool
|
|
75
|
+
rustdl.is_subclass_of(path, sub_iri, sup_iri) # -> bool
|
|
76
|
+
rustdl.is_instance_of(path, class_iri, indiv_iri) # -> bool
|
|
77
|
+
rustdl.instances_of(path, class_iri) # -> list[str]
|
|
78
|
+
rustdl.realize(path) # -> dict[str, list[str]]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`realize` returns each individual IRI mapped to its most-specific entailed
|
|
82
|
+
class IRIs.
|
|
83
|
+
|
|
84
|
+
> For repeated queries over the same ontology, prefer `classify(path)` once and
|
|
85
|
+
> query the returned `Classification` — each top-level function re-parses.
|
|
86
|
+
|
|
87
|
+
### Inference materialization
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
rustdl.materialize_inferred_subclass_axioms(path) # -> list[tuple[str, str]]
|
|
91
|
+
rustdl.materialize_inferred_class_assertions(path) # -> list[tuple[str, str]]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`materialize_inferred_subclass_axioms` yields `(sub, sup)` pairs for every
|
|
95
|
+
entailed subsumption (excluding reflexive, `owl:Thing`/`owl:Nothing`, and
|
|
96
|
+
unsatisfiable classes). `materialize_inferred_class_assertions` yields
|
|
97
|
+
`(class, individual)` pairs. Useful for writing an inferred ontology back to
|
|
98
|
+
disk.
|
|
99
|
+
|
|
100
|
+
### Errors
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
rustdl.RustdlError # base — catches everything from the library
|
|
104
|
+
rustdl.ParseError # the OWL file couldn't be parsed
|
|
105
|
+
rustdl.UnsupportedAxiomError # HasKey, role chains > length 2, etc.
|
|
106
|
+
rustdl.UnknownClassError # an IRI argument isn't a declared class
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
try:
|
|
111
|
+
result = rustdl.classify("ontology.ofn")
|
|
112
|
+
except rustdl.ParseError as e:
|
|
113
|
+
print(f"bad input: {e}")
|
|
114
|
+
except rustdl.RustdlError as e:
|
|
115
|
+
print(f"reasoning failed: {e}")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Soundness & coverage
|
|
119
|
+
|
|
120
|
+
`rustdl` is **sound**: every reported subsumption is a genuine entailment
|
|
121
|
+
(FP=0 against Konclude on the validation corpus). Completeness is partial — the
|
|
122
|
+
default classifier is empirically near-complete across the measured corpus but
|
|
123
|
+
not provably complete on all of SROIQ. `saturation_only` and
|
|
124
|
+
`per_pair_timeout_ms` are sound-but-incomplete by construction.
|
|
125
|
+
|
|
126
|
+
Data-property and datatype axioms outside the recognized preprocessing patterns
|
|
127
|
+
are silently dropped (a sound under-approximation). `HasKey` and role chains
|
|
128
|
+
longer than length 2 raise `UnsupportedAxiomError`. SWRL rules are skipped.
|
|
129
|
+
|
|
130
|
+
See the [project documentation](https://github.com/MaastrichtU-IDS/rustdl) for
|
|
131
|
+
the full coverage matrix, soundness contract, and architecture notes.
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
Apache-2.0 OR MIT.
|
|
@@ -35,15 +35,15 @@ create_exception!(
|
|
|
35
35
|
/// Register all rustdl exception types on the module so Python
|
|
36
36
|
/// callers can `except rustdl.RustdlError:` etc.
|
|
37
37
|
pub(crate) fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
38
|
-
m.add("RustdlError", m.py().
|
|
39
|
-
m.add("ParseError", m.py().
|
|
38
|
+
m.add("RustdlError", m.py().get_type::<RustdlError>())?;
|
|
39
|
+
m.add("ParseError", m.py().get_type::<ParseError>())?;
|
|
40
40
|
m.add(
|
|
41
41
|
"UnsupportedAxiomError",
|
|
42
|
-
m.py().
|
|
42
|
+
m.py().get_type::<UnsupportedAxiomError>(),
|
|
43
43
|
)?;
|
|
44
44
|
m.add(
|
|
45
45
|
"UnknownClassError",
|
|
46
|
-
m.py().
|
|
46
|
+
m.py().get_type::<UnknownClassError>(),
|
|
47
47
|
)?;
|
|
48
48
|
Ok(())
|
|
49
49
|
}
|
|
@@ -34,7 +34,14 @@ pub(crate) enum AboxVerdict {
|
|
|
34
34
|
/// The specific clash the check detected. Surfaced in `RUSTDL_TRACE`
|
|
35
35
|
/// output and intended for a future `consistent --explain` extension
|
|
36
36
|
/// (not part of this project's scope).
|
|
37
|
+
///
|
|
38
|
+
/// The per-variant fields are read only through the derived `Debug`
|
|
39
|
+
/// impl (the `RUSTDL_TRACE=1` `abox_check: inconsistent — {reason:?}`
|
|
40
|
+
/// line). Rust's dead-code analysis doesn't count `Debug`-only reads,
|
|
41
|
+
/// so the fields would warn without this allow. They're load-bearing
|
|
42
|
+
/// for the trace output and the planned `--explain` surface — keep them.
|
|
37
43
|
#[derive(Debug, Clone)]
|
|
44
|
+
#[allow(dead_code, reason = "fields read via Debug in RUSTDL_TRACE output + future --explain")]
|
|
38
45
|
pub(crate) enum ClashReason {
|
|
39
46
|
/// P1: `ClassAssertion(C, a)` with `Subsumers::is_unsatisfiable(C)`.
|
|
40
47
|
AssertedBot { individual: IndividualId, class: ClassId },
|