rustdl 0.2.2__tar.gz → 0.3.1__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.2 → rustdl-0.3.1}/Cargo.lock +9 -9
- {rustdl-0.2.2 → rustdl-0.3.1}/Cargo.toml +6 -6
- {rustdl-0.2.2 → rustdl-0.3.1}/PKG-INFO +62 -15
- {rustdl-0.2.2/crates/owl-dl-py → rustdl-0.3.1}/README.md +61 -14
- {rustdl-0.2.2 → rustdl-0.3.1/crates/owl-dl-py}/README.md +61 -14
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/src/classify.rs +25 -3
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/tests/python/test_classify.py +30 -0
- rustdl-0.3.1/crates/owl-dl-py/tests/python/test_examples.py +34 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/pyproject.toml +1 -0
- rustdl-0.3.1/python/rustdl/__init__.py +132 -0
- rustdl-0.3.1/python/rustdl/data/pizza.owl.gz +0 -0
- rustdl-0.3.1/python/rustdl/data/sio.owl.gz +0 -0
- rustdl-0.3.1/python/rustdl/data/sulo.owl.gz +0 -0
- rustdl-0.3.1/python/rustdl/examples.py +115 -0
- rustdl-0.2.2/python/rustdl/__init__.py +0 -69
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/Cargo.toml +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/README.md +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/absorb.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/clause.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/convert.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/convert_back.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/data_axioms.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/definitions.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/ir.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/lib.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/locality.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/normalize.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/ontology.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/residual_trigger.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/role_hierarchy.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/told.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/transform.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/src/vocab.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/tests/concept_pool_proptest.proptest-regressions +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/tests/concept_pool_proptest.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/tests/convert_round_trip_proptest.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-core/tests/role_hierarchy_proptest.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-datatypes/Cargo.toml +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-datatypes/README.md +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-datatypes/src/lib.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/.gitignore +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/Cargo.toml +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/src/errors.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/src/lib.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/src/load.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/src/materialize.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/src/queries.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/tests/python/conftest.py +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/tests/python/test_materialize.py +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/tests/python/test_queries.py +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/tests/python/test_smoke.py +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-py/tests/python/test_soundness.py +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/Cargo.toml +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/README.md +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/src/abox_check.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/src/classify.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/src/lib.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/src/model_cache.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/src/realize.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/src/union_find.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/abox_consistency.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/anon349_diagnostic.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/datatype_completeness.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p1_direct_bot.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p1_no_bot.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p2_disjoint_different_individuals.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p2_disjoint_types.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_neg_opa.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_neg_opa_no_clash.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_role_hierarchy_neg_consistent.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_role_hierarchy_neg_inconsistent.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p4_same_different.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p4_same_without_different.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p5_functional_diff.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p5_functional_same_target.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_asymmetric.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_asymmetric_one_way.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_irreflexive.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_irreflexive_distinct.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p7_range_compatible.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/abox/p7_range_disjoint.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_cardinality_disjoint.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_property_domain-classified.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_property_domain.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_definition-classified.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_definition.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_facet.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/functional_data_property.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/sub_data_property-classified.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/datatype/sub_data_property.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/functional-equiv-some-bug.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/named-pizza-country-bug.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-01.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-02.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-03.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-04.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-05.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-06.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-07.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-08.txt +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.hermit.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.owx +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/fixtures/phase2b/phase2b-verdicts.log +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/konclude_closure_diff.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/label_heuristic_canary.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/phase2c_pair_06_canary.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/real_ontology_corpus.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-reasoner/tests/snapshot_phase0_canary.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-saturation/Cargo.toml +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-saturation/README.md +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-saturation/src/lib.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-saturation/tests/fixtures/phase2a_functional_role_canary.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-saturation/tests/fixtures/phase2b_compound_existential_canary.ofn +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/Cargo.toml +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/README.md +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/counters.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/deps.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/graph.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/hyper.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/lib.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/replay.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/rules.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/saturate.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/search.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/snapshot.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/src/trail.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/tests/backprop_risk.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/tests/replay_driver.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/tests/replay_roundtrip.rs +0 -0
- {rustdl-0.2.2 → rustdl-0.3.1}/crates/owl-dl-tableau/tests/snapshot_capture.rs +0 -0
|
@@ -1037,7 +1037,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
|
|
1037
1037
|
|
|
1038
1038
|
[[package]]
|
|
1039
1039
|
name = "owl-dl-bench"
|
|
1040
|
-
version = "0.
|
|
1040
|
+
version = "0.3.1"
|
|
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.
|
|
1057
|
+
version = "0.3.1"
|
|
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.
|
|
1069
|
+
version = "0.3.1"
|
|
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.
|
|
1083
|
+
version = "0.3.1"
|
|
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.
|
|
1093
|
+
version = "0.3.1"
|
|
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.
|
|
1104
|
+
version = "0.3.1"
|
|
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.
|
|
1120
|
+
version = "0.3.1"
|
|
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.
|
|
1136
|
+
version = "0.3.1"
|
|
1137
1137
|
dependencies = [
|
|
1138
1138
|
"bitvec",
|
|
1139
1139
|
"bumpalo",
|
|
@@ -2569,7 +2569,7 @@ dependencies = [
|
|
|
2569
2569
|
|
|
2570
2570
|
[[package]]
|
|
2571
2571
|
name = "xtask"
|
|
2572
|
-
version = "0.
|
|
2572
|
+
version = "0.3.1"
|
|
2573
2573
|
dependencies = [
|
|
2574
2574
|
"anyhow",
|
|
2575
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.
|
|
6
|
+
version = "0.3.1"
|
|
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.
|
|
19
|
-
owl-dl-saturation = { path = "crates/owl-dl-saturation", version = "0.
|
|
20
|
-
owl-dl-tableau = { path = "crates/owl-dl-tableau", version = "0.
|
|
21
|
-
owl-dl-datatypes = { path = "crates/owl-dl-datatypes", version = "0.
|
|
22
|
-
owl-dl-reasoner = { path = "crates/owl-dl-reasoner", version = "0.
|
|
18
|
+
owl-dl-core = { path = "crates/owl-dl-core", version = "0.3.1" }
|
|
19
|
+
owl-dl-saturation = { path = "crates/owl-dl-saturation", version = "0.3.1" }
|
|
20
|
+
owl-dl-tableau = { path = "crates/owl-dl-tableau", version = "0.3.1" }
|
|
21
|
+
owl-dl-datatypes = { path = "crates/owl-dl-datatypes", version = "0.3.1" }
|
|
22
|
+
owl-dl-reasoner = { path = "crates/owl-dl-reasoner", version = "0.3.1" }
|
|
23
23
|
|
|
24
24
|
horned-owl = { version = "1.4", default-features = false }
|
|
25
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rustdl
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Science/Research
|
|
6
6
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -48,18 +48,58 @@ Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS
|
|
|
48
48
|
```python
|
|
49
49
|
import rustdl
|
|
50
50
|
|
|
51
|
-
#
|
|
51
|
+
# A small OWL 2 DL ontology ships inside the wheel (gzip-compressed) — no
|
|
52
|
+
# download needed. `examples.pizza()` returns its file path (decompressed
|
|
53
|
+
# into a per-user cache dir on first use); `examples.PIZZA_NS` is its
|
|
54
|
+
# namespace, so class IRIs are PIZZA_NS + local name (e.g. + "Pizza").
|
|
55
|
+
from rustdl.examples import pizza, PIZZA_NS, SULO_NS
|
|
56
|
+
|
|
57
|
+
# Classify. Format is auto-detected from the extension:
|
|
52
58
|
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML).
|
|
53
|
-
result = rustdl.classify(
|
|
59
|
+
result = rustdl.classify(pizza())
|
|
54
60
|
|
|
55
|
-
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable"
|
|
61
|
+
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable, "
|
|
62
|
+
f"complete={result.complete}")
|
|
63
|
+
# -> 88 classes, 0 unsatisfiable, complete=True
|
|
56
64
|
|
|
57
65
|
# Query the computed hierarchy
|
|
58
|
-
result.is_subclass("
|
|
59
|
-
|
|
60
|
-
result.
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
print(result.is_subclass(PIZZA_NS + "BoxedPizza", PIZZA_NS + "Pizza"))
|
|
67
|
+
# -> True
|
|
68
|
+
print(len(result.subclasses_of(PIZZA_NS + "FoodMaterial")))
|
|
69
|
+
# -> 25
|
|
70
|
+
|
|
71
|
+
# The pizza ontology is aligned to the SULO upper ontology, so reasoning
|
|
72
|
+
# spans both — e.g. a pizza-making timestamp is inferred to be a SULO StartTime:
|
|
73
|
+
print(result.is_subclass(PIZZA_NS + "BakingStartTime", SULO_NS + "StartTime"))
|
|
74
|
+
# -> True
|
|
75
|
+
|
|
76
|
+
# Other hierarchy queries (all take full class IRIs):
|
|
77
|
+
result.superclasses_of(PIZZA_NS + "Cheese") # -> list[str]
|
|
78
|
+
result.equivalent_classes(PIZZA_NS + "Pizza") # -> list[str]
|
|
79
|
+
result.direct_subsumers(PIZZA_NS + "BoxedPizza") # -> list[str] (Hasse-direct parents)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Bundled examples
|
|
83
|
+
|
|
84
|
+
Three real ontologies ship inside the wheel, gzip-compressed (~200 KB total).
|
|
85
|
+
They classify with **no network access** — each `examples.X()` decompresses
|
|
86
|
+
its ontology into a per-user cache dir (`$XDG_CACHE_HOME/rustdl/examples` or
|
|
87
|
+
`~/.cache/rustdl/examples`) on first use, then reuses it. Each `examples.X_NS`
|
|
88
|
+
is the namespace, so a class IRI is the namespace plus the local name.
|
|
89
|
+
|
|
90
|
+
| helper | ontology | classes | notes |
|
|
91
|
+
|---|---|---|---|
|
|
92
|
+
| `pizza()` / `PIZZA_NS` | ontostart pizza | 88 | SULO-aligned pizza-making ontology; classifies instantly + complete |
|
|
93
|
+
| `sulo()` / `SULO_NS` | SULO (Simple Upper-Level Ontology) | 17 | tiny; classifies in milliseconds |
|
|
94
|
+
| `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") |
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import rustdl
|
|
98
|
+
from rustdl import examples
|
|
99
|
+
|
|
100
|
+
r = rustdl.classify(examples.sulo())
|
|
101
|
+
print(r.is_subclass(examples.SULO_NS + "StartTime", examples.SULO_NS + "Object"))
|
|
102
|
+
# -> True
|
|
63
103
|
```
|
|
64
104
|
|
|
65
105
|
## API
|
|
@@ -67,15 +107,20 @@ result.direct_subsumers("http://ex.org/Margherita") # -> list[str] (Hasse-direct
|
|
|
67
107
|
### Classification
|
|
68
108
|
|
|
69
109
|
```python
|
|
70
|
-
result = rustdl.classify(path, *, per_pair_timeout_ms=
|
|
71
|
-
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=
|
|
110
|
+
result = rustdl.classify(path, *, per_pair_timeout_ms=1000, saturation_only=False)
|
|
111
|
+
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=1000, saturation_only=False)
|
|
72
112
|
```
|
|
73
113
|
|
|
74
|
-
- `per_pair_timeout_ms` — bound each subsumption test
|
|
75
|
-
|
|
76
|
-
|
|
114
|
+
- `per_pair_timeout_ms` — bound each subsumption test (**default 1000**;
|
|
115
|
+
`0` = unbounded). A pair that exceeds the budget is recorded as "not
|
|
116
|
+
subsumed": **sound** (never a false subsumption) but the result may be
|
|
117
|
+
**incomplete**. When that happens, an `IncompleteClassificationWarning`
|
|
118
|
+
is emitted and `result.complete` is `False`. Pass `0` for the complete,
|
|
119
|
+
unbounded classification. The default bounds pathological SROIQ inputs
|
|
120
|
+
so classification can't hang silently.
|
|
77
121
|
- `saturation_only` — skip the tableau entirely; EL-closure-only
|
|
78
|
-
under-approximation. Dramatically faster on mostly-EL ontologies
|
|
122
|
+
under-approximation. Dramatically faster on mostly-EL ontologies, and
|
|
123
|
+
always `complete` (no tableau ⇒ no timeout).
|
|
79
124
|
|
|
80
125
|
`classify` / `classify_bytes` return a `Classification`:
|
|
81
126
|
|
|
@@ -84,6 +129,8 @@ result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=None,
|
|
|
84
129
|
| `.classes` | `list[str]` | all declared class IRIs |
|
|
85
130
|
| `.unsatisfiable` | `list[str]` | classes proved `⊑ ⊥` |
|
|
86
131
|
| `.inconsistent` | `bool` | whole ontology unsatisfiable |
|
|
132
|
+
| `.complete` | `bool` | `False` if any pair hit the timeout (result may miss edges) |
|
|
133
|
+
| `.timed_out_pairs` | `int` | how many pairs hit the timeout |
|
|
87
134
|
| `.is_subclass(sub, sup)` | `bool` | is `sub ⊑ sup` entailed? |
|
|
88
135
|
| `.subclasses_of(cls)` | `list[str]` | every `D` with `D ⊑ cls` |
|
|
89
136
|
| `.superclasses_of(cls)` | `list[str]` | every `D` with `cls ⊑ D` |
|
|
@@ -23,18 +23,58 @@ Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS
|
|
|
23
23
|
```python
|
|
24
24
|
import rustdl
|
|
25
25
|
|
|
26
|
-
#
|
|
26
|
+
# A small OWL 2 DL ontology ships inside the wheel (gzip-compressed) — no
|
|
27
|
+
# download needed. `examples.pizza()` returns its file path (decompressed
|
|
28
|
+
# into a per-user cache dir on first use); `examples.PIZZA_NS` is its
|
|
29
|
+
# namespace, so class IRIs are PIZZA_NS + local name (e.g. + "Pizza").
|
|
30
|
+
from rustdl.examples import pizza, PIZZA_NS, SULO_NS
|
|
31
|
+
|
|
32
|
+
# Classify. Format is auto-detected from the extension:
|
|
27
33
|
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML).
|
|
28
|
-
result = rustdl.classify(
|
|
34
|
+
result = rustdl.classify(pizza())
|
|
29
35
|
|
|
30
|
-
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable"
|
|
36
|
+
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable, "
|
|
37
|
+
f"complete={result.complete}")
|
|
38
|
+
# -> 88 classes, 0 unsatisfiable, complete=True
|
|
31
39
|
|
|
32
40
|
# Query the computed hierarchy
|
|
33
|
-
result.is_subclass("
|
|
34
|
-
|
|
35
|
-
result.
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
print(result.is_subclass(PIZZA_NS + "BoxedPizza", PIZZA_NS + "Pizza"))
|
|
42
|
+
# -> True
|
|
43
|
+
print(len(result.subclasses_of(PIZZA_NS + "FoodMaterial")))
|
|
44
|
+
# -> 25
|
|
45
|
+
|
|
46
|
+
# The pizza ontology is aligned to the SULO upper ontology, so reasoning
|
|
47
|
+
# spans both — e.g. a pizza-making timestamp is inferred to be a SULO StartTime:
|
|
48
|
+
print(result.is_subclass(PIZZA_NS + "BakingStartTime", SULO_NS + "StartTime"))
|
|
49
|
+
# -> True
|
|
50
|
+
|
|
51
|
+
# Other hierarchy queries (all take full class IRIs):
|
|
52
|
+
result.superclasses_of(PIZZA_NS + "Cheese") # -> list[str]
|
|
53
|
+
result.equivalent_classes(PIZZA_NS + "Pizza") # -> list[str]
|
|
54
|
+
result.direct_subsumers(PIZZA_NS + "BoxedPizza") # -> list[str] (Hasse-direct parents)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Bundled examples
|
|
58
|
+
|
|
59
|
+
Three real ontologies ship inside the wheel, gzip-compressed (~200 KB total).
|
|
60
|
+
They classify with **no network access** — each `examples.X()` decompresses
|
|
61
|
+
its ontology into a per-user cache dir (`$XDG_CACHE_HOME/rustdl/examples` or
|
|
62
|
+
`~/.cache/rustdl/examples`) on first use, then reuses it. Each `examples.X_NS`
|
|
63
|
+
is the namespace, so a class IRI is the namespace plus the local name.
|
|
64
|
+
|
|
65
|
+
| helper | ontology | classes | notes |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| `pizza()` / `PIZZA_NS` | ontostart pizza | 88 | SULO-aligned pizza-making ontology; classifies instantly + complete |
|
|
68
|
+
| `sulo()` / `SULO_NS` | SULO (Simple Upper-Level Ontology) | 17 | tiny; classifies in milliseconds |
|
|
69
|
+
| `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") |
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import rustdl
|
|
73
|
+
from rustdl import examples
|
|
74
|
+
|
|
75
|
+
r = rustdl.classify(examples.sulo())
|
|
76
|
+
print(r.is_subclass(examples.SULO_NS + "StartTime", examples.SULO_NS + "Object"))
|
|
77
|
+
# -> True
|
|
38
78
|
```
|
|
39
79
|
|
|
40
80
|
## API
|
|
@@ -42,15 +82,20 @@ result.direct_subsumers("http://ex.org/Margherita") # -> list[str] (Hasse-direct
|
|
|
42
82
|
### Classification
|
|
43
83
|
|
|
44
84
|
```python
|
|
45
|
-
result = rustdl.classify(path, *, per_pair_timeout_ms=
|
|
46
|
-
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=
|
|
85
|
+
result = rustdl.classify(path, *, per_pair_timeout_ms=1000, saturation_only=False)
|
|
86
|
+
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=1000, saturation_only=False)
|
|
47
87
|
```
|
|
48
88
|
|
|
49
|
-
- `per_pair_timeout_ms` — bound each subsumption test
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
- `per_pair_timeout_ms` — bound each subsumption test (**default 1000**;
|
|
90
|
+
`0` = unbounded). A pair that exceeds the budget is recorded as "not
|
|
91
|
+
subsumed": **sound** (never a false subsumption) but the result may be
|
|
92
|
+
**incomplete**. When that happens, an `IncompleteClassificationWarning`
|
|
93
|
+
is emitted and `result.complete` is `False`. Pass `0` for the complete,
|
|
94
|
+
unbounded classification. The default bounds pathological SROIQ inputs
|
|
95
|
+
so classification can't hang silently.
|
|
52
96
|
- `saturation_only` — skip the tableau entirely; EL-closure-only
|
|
53
|
-
under-approximation. Dramatically faster on mostly-EL ontologies
|
|
97
|
+
under-approximation. Dramatically faster on mostly-EL ontologies, and
|
|
98
|
+
always `complete` (no tableau ⇒ no timeout).
|
|
54
99
|
|
|
55
100
|
`classify` / `classify_bytes` return a `Classification`:
|
|
56
101
|
|
|
@@ -59,6 +104,8 @@ result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=None,
|
|
|
59
104
|
| `.classes` | `list[str]` | all declared class IRIs |
|
|
60
105
|
| `.unsatisfiable` | `list[str]` | classes proved `⊑ ⊥` |
|
|
61
106
|
| `.inconsistent` | `bool` | whole ontology unsatisfiable |
|
|
107
|
+
| `.complete` | `bool` | `False` if any pair hit the timeout (result may miss edges) |
|
|
108
|
+
| `.timed_out_pairs` | `int` | how many pairs hit the timeout |
|
|
62
109
|
| `.is_subclass(sub, sup)` | `bool` | is `sub ⊑ sup` entailed? |
|
|
63
110
|
| `.subclasses_of(cls)` | `list[str]` | every `D` with `D ⊑ cls` |
|
|
64
111
|
| `.superclasses_of(cls)` | `list[str]` | every `D` with `cls ⊑ D` |
|
|
@@ -23,18 +23,58 @@ Wheels are published for CPython 3.10+ on Linux (x86_64, aarch64), macOS
|
|
|
23
23
|
```python
|
|
24
24
|
import rustdl
|
|
25
25
|
|
|
26
|
-
#
|
|
26
|
+
# A small OWL 2 DL ontology ships inside the wheel (gzip-compressed) — no
|
|
27
|
+
# download needed. `examples.pizza()` returns its file path (decompressed
|
|
28
|
+
# into a per-user cache dir on first use); `examples.PIZZA_NS` is its
|
|
29
|
+
# namespace, so class IRIs are PIZZA_NS + local name (e.g. + "Pizza").
|
|
30
|
+
from rustdl.examples import pizza, PIZZA_NS, SULO_NS
|
|
31
|
+
|
|
32
|
+
# Classify. Format is auto-detected from the extension:
|
|
27
33
|
# .ofn (OWL Functional), .owx (OWL/XML), .rdf / .owl (RDF/XML).
|
|
28
|
-
result = rustdl.classify(
|
|
34
|
+
result = rustdl.classify(pizza())
|
|
29
35
|
|
|
30
|
-
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable"
|
|
36
|
+
print(f"{len(result.classes)} classes, {len(result.unsatisfiable)} unsatisfiable, "
|
|
37
|
+
f"complete={result.complete}")
|
|
38
|
+
# -> 88 classes, 0 unsatisfiable, complete=True
|
|
31
39
|
|
|
32
40
|
# Query the computed hierarchy
|
|
33
|
-
result.is_subclass("
|
|
34
|
-
|
|
35
|
-
result.
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
print(result.is_subclass(PIZZA_NS + "BoxedPizza", PIZZA_NS + "Pizza"))
|
|
42
|
+
# -> True
|
|
43
|
+
print(len(result.subclasses_of(PIZZA_NS + "FoodMaterial")))
|
|
44
|
+
# -> 25
|
|
45
|
+
|
|
46
|
+
# The pizza ontology is aligned to the SULO upper ontology, so reasoning
|
|
47
|
+
# spans both — e.g. a pizza-making timestamp is inferred to be a SULO StartTime:
|
|
48
|
+
print(result.is_subclass(PIZZA_NS + "BakingStartTime", SULO_NS + "StartTime"))
|
|
49
|
+
# -> True
|
|
50
|
+
|
|
51
|
+
# Other hierarchy queries (all take full class IRIs):
|
|
52
|
+
result.superclasses_of(PIZZA_NS + "Cheese") # -> list[str]
|
|
53
|
+
result.equivalent_classes(PIZZA_NS + "Pizza") # -> list[str]
|
|
54
|
+
result.direct_subsumers(PIZZA_NS + "BoxedPizza") # -> list[str] (Hasse-direct parents)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Bundled examples
|
|
58
|
+
|
|
59
|
+
Three real ontologies ship inside the wheel, gzip-compressed (~200 KB total).
|
|
60
|
+
They classify with **no network access** — each `examples.X()` decompresses
|
|
61
|
+
its ontology into a per-user cache dir (`$XDG_CACHE_HOME/rustdl/examples` or
|
|
62
|
+
`~/.cache/rustdl/examples`) on first use, then reuses it. Each `examples.X_NS`
|
|
63
|
+
is the namespace, so a class IRI is the namespace plus the local name.
|
|
64
|
+
|
|
65
|
+
| helper | ontology | classes | notes |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| `pizza()` / `PIZZA_NS` | ontostart pizza | 88 | SULO-aligned pizza-making ontology; classifies instantly + complete |
|
|
68
|
+
| `sulo()` / `SULO_NS` | SULO (Simple Upper-Level Ontology) | 17 | tiny; classifies in milliseconds |
|
|
69
|
+
| `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") |
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import rustdl
|
|
73
|
+
from rustdl import examples
|
|
74
|
+
|
|
75
|
+
r = rustdl.classify(examples.sulo())
|
|
76
|
+
print(r.is_subclass(examples.SULO_NS + "StartTime", examples.SULO_NS + "Object"))
|
|
77
|
+
# -> True
|
|
38
78
|
```
|
|
39
79
|
|
|
40
80
|
## API
|
|
@@ -42,15 +82,20 @@ result.direct_subsumers("http://ex.org/Margherita") # -> list[str] (Hasse-direct
|
|
|
42
82
|
### Classification
|
|
43
83
|
|
|
44
84
|
```python
|
|
45
|
-
result = rustdl.classify(path, *, per_pair_timeout_ms=
|
|
46
|
-
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=
|
|
85
|
+
result = rustdl.classify(path, *, per_pair_timeout_ms=1000, saturation_only=False)
|
|
86
|
+
result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=1000, saturation_only=False)
|
|
47
87
|
```
|
|
48
88
|
|
|
49
|
-
- `per_pair_timeout_ms` — bound each subsumption test
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
- `per_pair_timeout_ms` — bound each subsumption test (**default 1000**;
|
|
90
|
+
`0` = unbounded). A pair that exceeds the budget is recorded as "not
|
|
91
|
+
subsumed": **sound** (never a false subsumption) but the result may be
|
|
92
|
+
**incomplete**. When that happens, an `IncompleteClassificationWarning`
|
|
93
|
+
is emitted and `result.complete` is `False`. Pass `0` for the complete,
|
|
94
|
+
unbounded classification. The default bounds pathological SROIQ inputs
|
|
95
|
+
so classification can't hang silently.
|
|
52
96
|
- `saturation_only` — skip the tableau entirely; EL-closure-only
|
|
53
|
-
under-approximation. Dramatically faster on mostly-EL ontologies
|
|
97
|
+
under-approximation. Dramatically faster on mostly-EL ontologies, and
|
|
98
|
+
always `complete` (no tableau ⇒ no timeout).
|
|
54
99
|
|
|
55
100
|
`classify` / `classify_bytes` return a `Classification`:
|
|
56
101
|
|
|
@@ -59,6 +104,8 @@ result = rustdl.classify_bytes(data, format="ofn", *, per_pair_timeout_ms=None,
|
|
|
59
104
|
| `.classes` | `list[str]` | all declared class IRIs |
|
|
60
105
|
| `.unsatisfiable` | `list[str]` | classes proved `⊑ ⊥` |
|
|
61
106
|
| `.inconsistent` | `bool` | whole ontology unsatisfiable |
|
|
107
|
+
| `.complete` | `bool` | `False` if any pair hit the timeout (result may miss edges) |
|
|
108
|
+
| `.timed_out_pairs` | `int` | how many pairs hit the timeout |
|
|
62
109
|
| `.is_subclass(sub, sup)` | `bool` | is `sub ⊑ sup` entailed? |
|
|
63
110
|
| `.subclasses_of(cls)` | `list[str]` | every `D` with `D ⊑ cls` |
|
|
64
111
|
| `.superclasses_of(cls)` | `list[str]` | every `D` with `cls ⊑ D` |
|
|
@@ -38,6 +38,25 @@ impl PyClassification {
|
|
|
38
38
|
self.inner.stats().inconsistent
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/// Number of class pairs that exceeded the per-pair timeout and
|
|
42
|
+
/// were recorded as "not subsumed". `> 0` means the classification
|
|
43
|
+
/// is a sound under-approximation — no false subsumptions, but real
|
|
44
|
+
/// ones may be missing. `0` when classification ran to completion
|
|
45
|
+
/// (or no timeout was set).
|
|
46
|
+
#[getter]
|
|
47
|
+
fn timed_out_pairs(&self) -> usize {
|
|
48
|
+
self.inner.stats().timed_out_pairs
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// True iff classification ran to completion — no pair hit the
|
|
52
|
+
/// timeout. When `False`, the hierarchy may be missing real
|
|
53
|
+
/// subsumptions (see `timed_out_pairs`); re-classify with
|
|
54
|
+
/// `per_pair_timeout_ms=0` for the complete (unbounded) result.
|
|
55
|
+
#[getter]
|
|
56
|
+
fn complete(&self) -> bool {
|
|
57
|
+
self.inner.stats().timed_out_pairs == 0
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
/// True iff `sub ⊑ sup` is entailed.
|
|
42
61
|
fn is_subclass(&self, sub: &str, sup: &str) -> bool {
|
|
43
62
|
self.inner.is_subclass(sub, sup)
|
|
@@ -74,7 +93,7 @@ impl PyClassification {
|
|
|
74
93
|
/// `rustdl.classify(path)` — classify the ontology at `path`.
|
|
75
94
|
/// Format auto-detected from the file extension.
|
|
76
95
|
#[pyfunction]
|
|
77
|
-
#[pyo3(signature = (path, *, per_pair_timeout_ms=
|
|
96
|
+
#[pyo3(signature = (path, *, per_pair_timeout_ms=1000, saturation_only=false))]
|
|
78
97
|
pub(crate) fn classify(
|
|
79
98
|
path: &str,
|
|
80
99
|
per_pair_timeout_ms: Option<u64>,
|
|
@@ -86,7 +105,7 @@ pub(crate) fn classify(
|
|
|
86
105
|
|
|
87
106
|
/// `rustdl.classify_bytes(data, format="ofn")` — same but from bytes.
|
|
88
107
|
#[pyfunction]
|
|
89
|
-
#[pyo3(signature = (data, *, format, per_pair_timeout_ms=
|
|
108
|
+
#[pyo3(signature = (data, *, format, per_pair_timeout_ms=1000, saturation_only=false))]
|
|
90
109
|
pub(crate) fn classify_bytes(
|
|
91
110
|
data: &[u8],
|
|
92
111
|
format: &str,
|
|
@@ -103,9 +122,12 @@ fn do_classify(
|
|
|
103
122
|
saturation_only: bool,
|
|
104
123
|
) -> PyResult<PyClassification> {
|
|
105
124
|
use std::time::Duration;
|
|
125
|
+
// `None` or `0` → unbounded (complete); any positive value bounds
|
|
126
|
+
// each pair (sound under-approximation; check `.complete` after).
|
|
127
|
+
let bounded = per_pair_timeout_ms.filter(|&ms| ms > 0);
|
|
106
128
|
let inner = if saturation_only {
|
|
107
129
|
owl_dl_reasoner::classify_saturation_only(ontology).map_err(reason_error_to_py)?
|
|
108
|
-
} else if let Some(ms) =
|
|
130
|
+
} else if let Some(ms) = bounded {
|
|
109
131
|
owl_dl_reasoner::classify_top_down_with_timeout(ontology, Duration::from_millis(ms))
|
|
110
132
|
.map_err(reason_error_to_py)?
|
|
111
133
|
} else {
|
|
@@ -46,3 +46,33 @@ def test_superclasses_of(fixtures_dir):
|
|
|
46
46
|
result = rustdl.classify(str(fixture))
|
|
47
47
|
sups = result.superclasses_of("http://t/Adult")
|
|
48
48
|
assert "http://t/Person" in sups
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_completeness_signal_and_warning(fixtures_dir):
|
|
52
|
+
import warnings
|
|
53
|
+
fixture = fixtures_dir / "datatype" / "datatype_definition.ofn"
|
|
54
|
+
|
|
55
|
+
# Default budget on a tiny EL-ish ontology: completes, no warning.
|
|
56
|
+
with warnings.catch_warnings(record=True) as rec:
|
|
57
|
+
warnings.simplefilter("always")
|
|
58
|
+
r = rustdl.classify(str(fixture))
|
|
59
|
+
assert r.complete is True
|
|
60
|
+
assert r.timed_out_pairs == 0
|
|
61
|
+
assert not any(
|
|
62
|
+
issubclass(w.category, rustdl.IncompleteClassificationWarning) for w in rec
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_saturation_only_is_complete(fixtures_dir):
|
|
67
|
+
fixture = fixtures_dir / "datatype" / "datatype_definition.ofn"
|
|
68
|
+
r = rustdl.classify(str(fixture), saturation_only=True)
|
|
69
|
+
# saturation-only never invokes the tableau, so no pair can time out
|
|
70
|
+
assert r.complete is True
|
|
71
|
+
assert r.timed_out_pairs == 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_unbounded_timeout_accepted(fixtures_dir):
|
|
75
|
+
fixture = fixtures_dir / "datatype" / "datatype_definition.ofn"
|
|
76
|
+
# per_pair_timeout_ms=0 means unbounded — must classify, complete.
|
|
77
|
+
r = rustdl.classify(str(fixture), per_pair_timeout_ms=0)
|
|
78
|
+
assert r.complete is True
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Bundled example ontologies — must work fully offline (shipped in the wheel)."""
|
|
2
|
+
import os
|
|
3
|
+
import rustdl
|
|
4
|
+
from rustdl import examples
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_all_three_examples_materialize():
|
|
8
|
+
for fn in (examples.pizza, examples.sulo, examples.sio):
|
|
9
|
+
path = fn()
|
|
10
|
+
assert os.path.exists(path)
|
|
11
|
+
assert os.path.getsize(path) > 0
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_pizza_classifies_complete():
|
|
15
|
+
# ontostart pizza: 88 classes, no unsat, classifies instantly + complete.
|
|
16
|
+
r = rustdl.classify(examples.pizza())
|
|
17
|
+
assert len(r.classes) == 88
|
|
18
|
+
assert len(r.unsatisfiable) == 0
|
|
19
|
+
assert r.complete is True
|
|
20
|
+
ns = examples.PIZZA_NS
|
|
21
|
+
assert r.is_subclass(ns + "BoxedPizza", ns + "Pizza")
|
|
22
|
+
# cross-ontology: aligned to SULO upper ontology
|
|
23
|
+
assert r.is_subclass(ns + "BakingStartTime", examples.SULO_NS + "StartTime")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_sulo_classifies():
|
|
27
|
+
r = rustdl.classify(examples.sulo())
|
|
28
|
+
assert len(r.classes) == 17
|
|
29
|
+
assert r.complete is True
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_namespace_constants_are_strings():
|
|
33
|
+
for ns in (examples.PIZZA_NS, examples.SULO_NS, examples.SIO_NS):
|
|
34
|
+
assert isinstance(ns, str) and ns
|
|
@@ -35,5 +35,6 @@ Changelog = "https://github.com/MaastrichtU-IDS/rustdl/blob/main/CHANGELOG.md"
|
|
|
35
35
|
module-name = "rustdl._native"
|
|
36
36
|
features = ["pyo3/extension-module"]
|
|
37
37
|
strip = true
|
|
38
|
+
include = ["python/rustdl/data/*.owl.gz"]
|
|
38
39
|
manifest-path = "crates/owl-dl-py/Cargo.toml"
|
|
39
40
|
python-source = "python"
|