rustdl 0.3.4__tar.gz → 0.3.6__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.
Files changed (152) hide show
  1. {rustdl-0.3.4 → rustdl-0.3.6}/Cargo.lock +9 -9
  2. {rustdl-0.3.4 → rustdl-0.3.6}/Cargo.toml +6 -6
  3. {rustdl-0.3.4 → rustdl-0.3.6}/PKG-INFO +1 -1
  4. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/src/classify.rs +233 -0
  5. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/src/lib.rs +26 -0
  6. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/konclude_closure_diff.rs +5 -1
  7. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-saturation/src/lib.rs +410 -0
  8. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/hyper.rs +207 -4
  9. {rustdl-0.3.4 → rustdl-0.3.6}/README.md +0 -0
  10. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/Cargo.toml +0 -0
  11. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/README.md +0 -0
  12. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/absorb.rs +0 -0
  13. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/clause.rs +0 -0
  14. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/convert.rs +0 -0
  15. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/convert_back.rs +0 -0
  16. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/data_axioms.rs +0 -0
  17. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/definitions.rs +0 -0
  18. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/disjunction_existential.rs +0 -0
  19. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/ir.rs +0 -0
  20. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/lib.rs +0 -0
  21. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/locality.rs +0 -0
  22. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/normalize.rs +0 -0
  23. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/ontology.rs +0 -0
  24. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/residual_trigger.rs +0 -0
  25. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/role_hierarchy.rs +0 -0
  26. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/told.rs +0 -0
  27. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/transform.rs +0 -0
  28. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/src/vocab.rs +0 -0
  29. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/tests/concept_pool_proptest.proptest-regressions +0 -0
  30. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/tests/concept_pool_proptest.rs +0 -0
  31. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/tests/convert_round_trip_proptest.rs +0 -0
  32. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-core/tests/role_hierarchy_proptest.rs +0 -0
  33. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-datatypes/Cargo.toml +0 -0
  34. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-datatypes/README.md +0 -0
  35. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-datatypes/src/lib.rs +0 -0
  36. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/.gitignore +0 -0
  37. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/Cargo.toml +0 -0
  38. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/README.md +0 -0
  39. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/src/classify.rs +0 -0
  40. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/src/errors.rs +0 -0
  41. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/src/lib.rs +0 -0
  42. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/src/load.rs +0 -0
  43. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/src/materialize.rs +0 -0
  44. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/src/queries.rs +0 -0
  45. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/conftest.py +0 -0
  46. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/test_classify.py +0 -0
  47. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/test_examples.py +0 -0
  48. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/test_materialize.py +0 -0
  49. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/test_queries.py +0 -0
  50. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/test_smoke.py +0 -0
  51. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-py/tests/python/test_soundness.py +0 -0
  52. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/Cargo.toml +0 -0
  53. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/README.md +0 -0
  54. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/src/abox_check.rs +0 -0
  55. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/src/model_cache.rs +0 -0
  56. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/src/realize.rs +0 -0
  57. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/src/union_find.rs +0 -0
  58. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/abox_consistency.rs +0 -0
  59. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/anon349_diagnostic.rs +0 -0
  60. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/datatype_completeness.rs +0 -0
  61. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p1_direct_bot.ofn +0 -0
  62. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p1_no_bot.ofn +0 -0
  63. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p2_disjoint_different_individuals.ofn +0 -0
  64. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p2_disjoint_types.ofn +0 -0
  65. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_neg_opa.ofn +0 -0
  66. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_neg_opa_no_clash.ofn +0 -0
  67. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_role_hierarchy_neg_consistent.ofn +0 -0
  68. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p3_role_hierarchy_neg_inconsistent.ofn +0 -0
  69. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p4_same_different.ofn +0 -0
  70. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p4_same_without_different.ofn +0 -0
  71. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p5_functional_diff.ofn +0 -0
  72. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p5_functional_same_target.ofn +0 -0
  73. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_asymmetric.ofn +0 -0
  74. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_asymmetric_one_way.ofn +0 -0
  75. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_irreflexive.ofn +0 -0
  76. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p6_irreflexive_distinct.ofn +0 -0
  77. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p7_range_compatible.ofn +0 -0
  78. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/abox/p7_range_disjoint.ofn +0 -0
  79. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_cardinality_disjoint.ofn +0 -0
  80. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_property_domain-classified.owx +0 -0
  81. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/data_property_domain.ofn +0 -0
  82. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_definition-classified.owx +0 -0
  83. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_definition.ofn +0 -0
  84. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/datatype_facet.ofn +0 -0
  85. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/functional_data_property.ofn +0 -0
  86. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/sub_data_property-classified.owx +0 -0
  87. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/datatype/sub_data_property.ofn +0 -0
  88. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/functional-equiv-some-bug.ofn +0 -0
  89. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/named-pizza-country-bug.ofn +0 -0
  90. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-01.txt +0 -0
  91. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-02.txt +0 -0
  92. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-03.txt +0 -0
  93. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-04.txt +0 -0
  94. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-05.txt +0 -0
  95. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-06.txt +0 -0
  96. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-07.txt +0 -0
  97. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/p2b0-terms-08.txt +0 -0
  98. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.hermit.owx +0 -0
  99. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.ofn +0 -0
  100. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_01.owx +0 -0
  101. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.hermit.owx +0 -0
  102. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.ofn +0 -0
  103. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_02.owx +0 -0
  104. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.hermit.owx +0 -0
  105. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.ofn +0 -0
  106. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_03.owx +0 -0
  107. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.hermit.owx +0 -0
  108. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.ofn +0 -0
  109. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_04.owx +0 -0
  110. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.hermit.owx +0 -0
  111. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.ofn +0 -0
  112. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_05.owx +0 -0
  113. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.hermit.owx +0 -0
  114. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.ofn +0 -0
  115. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_06.owx +0 -0
  116. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.hermit.owx +0 -0
  117. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.ofn +0 -0
  118. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_07.owx +0 -0
  119. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.hermit.owx +0 -0
  120. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.ofn +0 -0
  121. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/pair_08.owx +0 -0
  122. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/fixtures/phase2b/phase2b-verdicts.log +0 -0
  123. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/label_heuristic_canary.rs +0 -0
  124. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/phase2c_pair_06_canary.rs +0 -0
  125. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/real_ontology_corpus.rs +0 -0
  126. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-reasoner/tests/snapshot_phase0_canary.rs +0 -0
  127. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-saturation/Cargo.toml +0 -0
  128. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-saturation/README.md +0 -0
  129. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-saturation/tests/fixtures/phase2a_functional_role_canary.ofn +0 -0
  130. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-saturation/tests/fixtures/phase2b_compound_existential_canary.ofn +0 -0
  131. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/Cargo.toml +0 -0
  132. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/README.md +0 -0
  133. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/counters.rs +0 -0
  134. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/deps.rs +0 -0
  135. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/graph.rs +0 -0
  136. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/lib.rs +0 -0
  137. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/replay.rs +0 -0
  138. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/rules.rs +0 -0
  139. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/saturate.rs +0 -0
  140. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/search.rs +0 -0
  141. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/snapshot.rs +0 -0
  142. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/src/trail.rs +0 -0
  143. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/tests/backprop_risk.rs +0 -0
  144. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/tests/replay_driver.rs +0 -0
  145. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/tests/replay_roundtrip.rs +0 -0
  146. {rustdl-0.3.4 → rustdl-0.3.6}/crates/owl-dl-tableau/tests/snapshot_capture.rs +0 -0
  147. {rustdl-0.3.4 → rustdl-0.3.6}/pyproject.toml +0 -0
  148. {rustdl-0.3.4 → rustdl-0.3.6}/python/rustdl/__init__.py +0 -0
  149. {rustdl-0.3.4 → rustdl-0.3.6}/python/rustdl/data/pizza.owl.gz +0 -0
  150. {rustdl-0.3.4 → rustdl-0.3.6}/python/rustdl/data/sio.owl.gz +0 -0
  151. {rustdl-0.3.4 → rustdl-0.3.6}/python/rustdl/data/sulo.owl.gz +0 -0
  152. {rustdl-0.3.4 → rustdl-0.3.6}/python/rustdl/examples.py +0 -0
@@ -1037,7 +1037,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
1037
1037
 
1038
1038
  [[package]]
1039
1039
  name = "owl-dl-bench"
1040
- version = "0.3.4"
1040
+ version = "0.3.6"
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.3.4"
1057
+ version = "0.3.6"
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.3.4"
1069
+ version = "0.3.6"
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.3.4"
1083
+ version = "0.3.6"
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.3.4"
1093
+ version = "0.3.6"
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.3.4"
1104
+ version = "0.3.6"
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.3.4"
1120
+ version = "0.3.6"
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.3.4"
1136
+ version = "0.3.6"
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.3.4"
2572
+ version = "0.3.6"
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.3.4"
6
+ version = "0.3.6"
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.3.4" }
19
- owl-dl-saturation = { path = "crates/owl-dl-saturation", version = "0.3.4" }
20
- owl-dl-tableau = { path = "crates/owl-dl-tableau", version = "0.3.4" }
21
- owl-dl-datatypes = { path = "crates/owl-dl-datatypes", version = "0.3.4" }
22
- owl-dl-reasoner = { path = "crates/owl-dl-reasoner", version = "0.3.4" }
18
+ owl-dl-core = { path = "crates/owl-dl-core", version = "0.3.6" }
19
+ owl-dl-saturation = { path = "crates/owl-dl-saturation", version = "0.3.6" }
20
+ owl-dl-tableau = { path = "crates/owl-dl-tableau", version = "0.3.6" }
21
+ owl-dl-datatypes = { path = "crates/owl-dl-datatypes", version = "0.3.6" }
22
+ owl-dl-reasoner = { path = "crates/owl-dl-reasoner", version = "0.3.6" }
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.4
3
+ Version: 0.3.6
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -138,6 +138,10 @@ pub struct ClassificationStats {
138
138
  /// entailment matrix — sound (never reports a false positive),
139
139
  /// but may under-report subsumption.
140
140
  pub timed_out_pairs: usize,
141
+ /// Subsumptions recovered by the defined-SUB sweep: a union-defined
142
+ /// `C ≡ D₁ ⊔ … ⊔ Dₙ` ⊑ a primitive sup `X` where every `Dᵢ ⊑ X` holds
143
+ /// in the EL closure (sound by construction). Added directly, no tableau.
144
+ pub defined_sub_sweep_recovered: usize,
141
145
  /// Pairs proved subsumed by the H4 hypertableau wedge (sound
142
146
  /// `Unsat`), skipping the tableau. Zero unless the wedge is
143
147
  /// enabled (`RUSTDL_HYPERTABLEAU`).
@@ -1262,6 +1266,84 @@ pub(crate) fn classify_top_down_internal(
1262
1266
  }
1263
1267
  }
1264
1268
 
1269
+ // Defined-SUB sweep (cluster A; wine residual-31, 2026-06-07). The
1270
+ // defined-sup sweep above only tests pairs whose SUP is a defined class.
1271
+ // A union/covering-defined SUB `C ≡ D₁ ⊔ … ⊔ Dₙ` ⊑ a *primitive* sup X
1272
+ // (e.g. `Fruit ≡ NonSweetFruit ⊔ SweetFruit ⊑ EdibleThing`, where
1273
+ // `EdibleThing` is `SubClassOf`-only) is missed by BOTH the tier-walk (the
1274
+ // covering subsumption isn't in the EL closure) AND the defined-sup sweep
1275
+ // (X is primitive). Recover it soundly *by construction*: if the sound EL
1276
+ // closure has `Dᵢ ⊑ X` for EVERY disjunct, then `C ⊑ ⊔Dᵢ ⊑ X`. So the
1277
+ // candidate sups are exactly the common closure-supersumers of the
1278
+ // disjuncts (`∩ᵢ subsumers(Dᵢ)`); each is a genuine entailment — added
1279
+ // directly, no tableau/wedge call (hence no per-pair-budget timeout risk).
1280
+ // See docs/classify-recovery-scope-2026-06-07.md.
1281
+ for ax in &internal.axioms {
1282
+ let owl_dl_core::ontology::Axiom::EquivalentClasses(ids) = ax else {
1283
+ continue;
1284
+ };
1285
+ // Identify the named class `C` (an Atomic operand) and a union
1286
+ // operand whose disjuncts are all atomic.
1287
+ let mut name: Option<usize> = None;
1288
+ let mut disjuncts: Option<Vec<usize>> = None;
1289
+ for cid in ids {
1290
+ match internal.concepts.get(*cid) {
1291
+ owl_dl_core::ir::ConceptExpr::Atomic(cls) => name = Some(cls.index() as usize),
1292
+ owl_dl_core::ir::ConceptExpr::Or(ds) => {
1293
+ let atoms: Option<Vec<usize>> = ds
1294
+ .iter()
1295
+ .map(|d| match internal.concepts.get(*d) {
1296
+ owl_dl_core::ir::ConceptExpr::Atomic(dc) => Some(dc.index() as usize),
1297
+ _ => None,
1298
+ })
1299
+ .collect();
1300
+ if let Some(a) = atoms {
1301
+ disjuncts = Some(a);
1302
+ }
1303
+ }
1304
+ _ => {}
1305
+ }
1306
+ }
1307
+ let (Some(c), Some(ds)) = (name, disjuncts) else {
1308
+ continue;
1309
+ };
1310
+ if c >= n || ds.is_empty() || unsatisfiable_idxs.contains(&c) {
1311
+ continue;
1312
+ }
1313
+ // Candidate sups = intersection of the disjuncts' closure-subsumers.
1314
+ let mut cand: Option<std::collections::HashSet<usize>> = None;
1315
+ for &d in &ds {
1316
+ let d_id =
1317
+ owl_dl_core::ClassId::new(u32::try_from(d).expect("class index fits in u32"));
1318
+ let subs: std::collections::HashSet<usize> = closure
1319
+ .subsumers_of(d_id)
1320
+ .into_iter()
1321
+ .map(|s| s.index() as usize)
1322
+ .filter(|&j| j < n)
1323
+ .collect();
1324
+ cand = Some(match cand {
1325
+ None => subs,
1326
+ Some(prev) => prev.intersection(&subs).copied().collect(),
1327
+ });
1328
+ }
1329
+ let c_id = owl_dl_core::ClassId::new(u32::try_from(c).expect("class index fits in u32"));
1330
+ for x in cand.unwrap_or_default() {
1331
+ if x == c || unsatisfiable_idxs.contains(&x) {
1332
+ continue;
1333
+ }
1334
+ let x_id =
1335
+ owl_dl_core::ClassId::new(u32::try_from(x).expect("class index fits in u32"));
1336
+ // Skip subsumptions already on `C`'s closure ray (the entailment
1337
+ // matrix seeds those) or already recorded.
1338
+ if closure.contains(c_id, x_id) || direct_supers[c].contains(&x) {
1339
+ continue;
1340
+ }
1341
+ stats.defined_sub_sweep_recovered += 1;
1342
+ direct_supers[c].push(x);
1343
+ direct_children[x].push(c);
1344
+ }
1345
+ }
1346
+
1265
1347
  // Build the full entailment matrix. Three sources contribute:
1266
1348
  //
1267
1349
  // 1. **Closure seed.** Every saturation-derived subsumption is
@@ -1625,6 +1707,122 @@ mod tests {
1625
1707
  ontology
1626
1708
  }
1627
1709
 
1710
+ /// Diagnostic probe (wine residual-31, cluster A): why does classify miss
1711
+ /// `food#Fruit ⊑ food#EdibleThing` when `is_subclass_of` proves it in 0.01s?
1712
+ /// Compares the fresh tableau (`is_subclass_of_internal`) against the
1713
+ /// classify-path `PreparedOntology::decide` (the ABox-seeded snapshot) on the
1714
+ /// exact query `Fruit ⊓ ¬EdibleThing`, unbounded and at the 200ms classify
1715
+ /// budget. Settles timeout-vs-wrong-verdict. See
1716
+ /// `docs/wine-residual-31-diagnosis-2026-06-07.md`. `#[ignore]`d (needs the
1717
+ /// gitignored wine fixture); run with `-- --ignored --nocapture`.
1718
+ #[test]
1719
+ #[ignore = "needs ontologies/real/wine.ofn; diagnostic for the Fruit cluster-A classify miss"]
1720
+ fn wine_fruit_prepared_vs_fresh_probe() {
1721
+ use horned_owl::io::ofn::reader::read as read_ofn;
1722
+ let path = std::path::Path::new("../../ontologies/real/wine.ofn");
1723
+ if !path.exists() {
1724
+ eprintln!("SKIP: missing {}", path.display());
1725
+ return;
1726
+ }
1727
+ let f = "http://www.w3.org/TR/2003/PR-owl-guide-20031209/food#Fruit";
1728
+ let e = "http://www.w3.org/TR/2003/PR-owl-guide-20031209/food#EdibleThing";
1729
+ let src = std::fs::read_to_string(path).expect("read wine");
1730
+ let parse_onto = || {
1731
+ let mut r = Cursor::new(src.clone());
1732
+ let (o, _): (SetOntology<RcStr>, _) =
1733
+ read_ofn(&mut r, ParserConfiguration::default()).expect("parse wine");
1734
+ o
1735
+ };
1736
+
1737
+ // Fresh path (what subclass / explain use).
1738
+ let fresh = crate::is_subclass_of(&parse_onto(), f, e).expect("fresh is_subclass_of");
1739
+ eprintln!("FRESH is_subclass_of(Fruit, EdibleThing) = {fresh}");
1740
+
1741
+ // Classify-path: PreparedOntology::decide on `Fruit ⊓ ¬EdibleThing`.
1742
+ let internal = owl_dl_core::convert::convert_ontology(&parse_onto()).expect("convert");
1743
+ let cons = "http://www.w3.org/TR/2003/PR-owl-guide-20031209/food#ConsumableThing";
1744
+ let fid = internal.vocabulary.class_id(f).expect("Fruit id");
1745
+ let eid = internal.vocabulary.class_id(e).expect("EdibleThing id");
1746
+ let cid = internal
1747
+ .vocabulary
1748
+ .class_id(cons)
1749
+ .expect("ConsumableThing id");
1750
+ // EL closure witness?
1751
+ let closure = owl_dl_saturation::saturate(&internal);
1752
+ eprintln!(
1753
+ "CLOSURE.contains(Fruit, EdibleThing) = {}",
1754
+ closure.contains(fid, eid)
1755
+ );
1756
+ let prepared = PreparedOntology::from_internal(internal).expect("prepare");
1757
+ // The classify walk tries the WEDGE first (hyper_decide), only falling
1758
+ // to the tableau on a non-proof. Measure both deadlines.
1759
+ let tw = std::time::Instant::now();
1760
+ let wedge_unbounded = prepared.hyper_decide(fid, eid, None);
1761
+ eprintln!(
1762
+ "WEDGE prepared.hyper_decide(None) = {wedge_unbounded:?} in {} ms",
1763
+ tw.elapsed().as_millis()
1764
+ );
1765
+ let tw2 = std::time::Instant::now();
1766
+ let wdl = std::time::Instant::now() + std::time::Duration::from_millis(200);
1767
+ let wedge_200 = prepared.hyper_decide(fid, eid, Some(wdl));
1768
+ eprintln!(
1769
+ "WEDGE prepared.hyper_decide(Fruit,EdibleThing,200ms) = {wedge_200:?} in {} ms",
1770
+ tw2.elapsed().as_millis()
1771
+ );
1772
+ // The descent GATE: EdibleThing ⊑ ConsumableThing (top-level), so the
1773
+ // walk reaches EdibleThing only by first accepting ConsumableThing.
1774
+ let tc = std::time::Instant::now();
1775
+ let cdl = std::time::Instant::now() + std::time::Duration::from_millis(200);
1776
+ let wedge_cons = prepared.hyper_decide(fid, cid, Some(cdl));
1777
+ eprintln!(
1778
+ "WEDGE prepared.hyper_decide(Fruit,ConsumableThing,200ms) = {wedge_cons:?} in {} ms [descent gate]",
1779
+ tc.elapsed().as_millis()
1780
+ );
1781
+ // SEPARATE finding (NOT cluster A's cause — the WEDGE proves Fruit ⊑
1782
+ // EdibleThing in 0 ms above, so the tableau is never reached for this
1783
+ // pair in classify). The ABox/nominal-seeded `prepared.decide` is
1784
+ // pathologically slow / non-terminating: a 5 s deadline times out, vs the
1785
+ // fresh path's 0.01 s (unbounded does not return in 150 s — do NOT call
1786
+ // it). This matters for the B/C/D pairs (whose wedge does NOT prove them
1787
+ // → tableau fallback). Cluster A's actual cause is the defined-sup sweep
1788
+ // coverage gap; see docs/classify-recovery-scope-2026-06-07.md.
1789
+ let build = |pool: &mut owl_dl_core::ir::ConceptPool| {
1790
+ let fc = pool.atomic(fid);
1791
+ let ec = pool.atomic(eid);
1792
+ let nec = pool.not(ec);
1793
+ pool.and(vec![fc, nec])
1794
+ };
1795
+ let t0 = std::time::Instant::now();
1796
+ let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
1797
+ let bounded = prepared
1798
+ .decide_with_deadline(deadline, build)
1799
+ .expect("prepared.decide_with_deadline");
1800
+ let ms = t0.elapsed().as_millis();
1801
+ eprintln!("PREPARED.decide_with_deadline(5s) = {bounded:?} (None=timeout) in {ms} ms");
1802
+
1803
+ eprintln!(
1804
+ "VERDICT: {}",
1805
+ match (fresh, bounded) {
1806
+ (true, None) =>
1807
+ "wedge proves it in 0ms (cluster A = defined-sup-sweep gap); \
1808
+ SEPARATELY the ABox-seeded prepared.decide tableau times out even at 5s \
1809
+ (non-termination, affects B/C/D)",
1810
+ (true, Some(false)) =>
1811
+ "prepared agrees (subsumed) within 5s ⇒ the miss is only the 200ms budget",
1812
+ (true, Some(true)) =>
1813
+ "prepared returns WRONG Sat ⇒ PreparedOntology completeness bug",
1814
+ _ => "fresh disagrees — re-examine",
1815
+ }
1816
+ );
1817
+ // Pin the established finding: fresh proves it; prepared cannot in 5s.
1818
+ assert!(fresh, "fresh is_subclass_of must prove Fruit ⊑ EdibleThing");
1819
+ assert_eq!(
1820
+ bounded, None,
1821
+ "regression: prepared.decide now finishes in 5s — the ABox-seeding \
1822
+ pathology may be fixed; update docs/wine-residual-31-diagnosis"
1823
+ );
1824
+ }
1825
+
1628
1826
  const HEADER: &str = "\
1629
1827
  Prefix(:=<http://rustdl.test/>)\n\
1630
1828
  Prefix(owl:=<http://www.w3.org/2002/07/owl#>)\n";
@@ -1700,6 +1898,41 @@ Ontology(<http://rustdl.test/test>\n\
1700
1898
  assert_eq!(direct, vec![iri("B")]);
1701
1899
  }
1702
1900
 
1901
+ /// Regression for the defined-SUB sweep (cluster A; wine residual-31,
1902
+ /// 2026-06-07). A union/covering-defined sub `C ≡ A ⊔ B` ⊑ a PRIMITIVE sup
1903
+ /// `X` (every disjunct `⊑ X`) is missed by both the tier-walk (the covering
1904
+ /// subsumption isn't in the EL closure) and the defined-sup sweep (`X` is
1905
+ /// primitive). The companion defined-SUB sweep recovers it soundly by
1906
+ /// construction. Mirrors wine's `Fruit ≡ NonSweetFruit ⊔ SweetFruit ⊑
1907
+ /// EdibleThing`. See docs/classify-recovery-scope-2026-06-07.md.
1908
+ #[test]
1909
+ fn defined_union_sub_under_primitive_sup() {
1910
+ let onto = parse(&format!(
1911
+ "{HEADER}\
1912
+ Ontology(<http://rustdl.test/test>\n\
1913
+ Declaration(Class(:C))\n\
1914
+ Declaration(Class(:A))\n\
1915
+ Declaration(Class(:B))\n\
1916
+ Declaration(Class(:X))\n\
1917
+ EquivalentClasses(:C ObjectUnionOf(:A :B))\n\
1918
+ SubClassOf(:A :X)\n\
1919
+ SubClassOf(:B :X)\n\
1920
+ )\n"
1921
+ ));
1922
+ let h = classify(&onto).expect("classification");
1923
+ let iri = |s: &str| format!("http://rustdl.test/{s}");
1924
+ // C ≡ A ⊔ B, A ⊑ X, B ⊑ X ⟹ C ⊑ X (every model element of C is in
1925
+ // A or B, both ⊑ X). `X` is primitive, so only the defined-SUB sweep
1926
+ // recovers this.
1927
+ assert!(
1928
+ h.is_subclass(&iri("C"), &iri("X")),
1929
+ "defined-SUB sweep must place C ⊑ X"
1930
+ );
1931
+ // Disjuncts and the union are mutually subsumed by X but not vice versa.
1932
+ assert!(h.is_subclass(&iri("A"), &iri("X")));
1933
+ assert!(!h.is_subclass(&iri("X"), &iri("C")));
1934
+ }
1935
+
1703
1936
  #[test]
1704
1937
  fn classify_groups_equivalents() {
1705
1938
  // EquivalentClasses(A, B) — they should appear as each
@@ -577,6 +577,9 @@ pub fn hyper_subsumption_probe<A: horned_owl::model::ForIRI>(
577
577
  if hyper_double_block_enabled() {
578
578
  engine = engine.with_double_blocking();
579
579
  }
580
+ if hyper_precise_card_deps_enabled() {
581
+ engine = engine.with_precise_card_deps();
582
+ }
580
583
  let result = engine.decide_with_deadline(max_depth, deadline);
581
584
  let stats = engine.stats();
582
585
  let wall_ms = start.elapsed().as_secs_f64() * 1000.0;
@@ -637,6 +640,23 @@ pub fn hyper_double_block_enabled() -> bool {
637
640
  std::env::var_os("RUSTDL_HYPER_DOUBLE_BLOCK").is_none_or(|v| v != "0" && !v.is_empty())
638
641
  }
639
642
 
643
+ /// Precise (sound over-approx) `≤n`-cardinality clash deps
644
+ /// (`RUSTDL_PRECISE_CARD_DEPS`). At the `forced_distinct_exceeds` pre-check site
645
+ /// replaces the conservative `DepSet::ALL` with `parent.at_most_dep ∪ ⋃(birth ∪
646
+ /// label of succs) ∪ parent(birth ∪ label)` — a provable superset of the clash's
647
+ /// true deps (sound by construction; see `card_clash_deps`), guarded by the
648
+ /// own-successor / `≠`-only / merge-taint fallbacks. Unblocks dependency-directed
649
+ /// backjumping on cardinality clashes (wine MISSED 34→31, −25% wall, FP=0;
650
+ /// see `docs/backjump-reconcile-2026-06-06.md`). **Default on** as of the flip
651
+ /// (2026-06-06): sound by construction, FP=0 across the cardinality/nominal
652
+ /// corpus, and inert on the EL/Horn corpus (Horn-shortcircuited, never enters
653
+ /// the wedge cardinality path). Set `RUSTDL_PRECISE_CARD_DEPS=0` to revert to the
654
+ /// conservative `DepSet::ALL` behaviour.
655
+ #[must_use]
656
+ pub fn hyper_precise_card_deps_enabled() -> bool {
657
+ std::env::var_os("RUSTDL_PRECISE_CARD_DEPS").is_none_or(|v| v != "0" && !v.is_empty())
658
+ }
659
+
640
660
  /// HF5: whether the wedge is allowed to *trust* the engine's `Sat`
641
661
  /// verdict (concluding "not subsumed" without consulting the tableau).
642
662
  /// `Unsat` is sound by construction for any ontology; `Sat` is sound
@@ -914,6 +934,9 @@ impl HyperCache {
914
934
  if hyper_double_block_enabled() {
915
935
  engine = engine.with_double_blocking();
916
936
  }
937
+ if hyper_precise_card_deps_enabled() {
938
+ engine = engine.with_precise_card_deps();
939
+ }
917
940
  match engine.decide_with_deadline(HYPER_WEDGE_DEPTH, deadline) {
918
941
  HyperResult::Unsat => HyperVerdict::Subsumed,
919
942
  HyperResult::Sat => HyperVerdict::NotSubsumed,
@@ -942,6 +965,9 @@ impl HyperCache {
942
965
  if hyper_double_block_enabled() {
943
966
  engine = engine.with_double_blocking();
944
967
  }
968
+ if hyper_precise_card_deps_enabled() {
969
+ engine = engine.with_precise_card_deps();
970
+ }
945
971
  match engine.decide_with_deadline(HYPER_WEDGE_DEPTH, deadline) {
946
972
  HyperResult::Unsat => LabelOracle::Unsat,
947
973
  HyperResult::Sat => engine
@@ -390,7 +390,11 @@ fn wine_closure_matches_konclude() {
390
390
  eprintln!("SKIP: missing wine fixture");
391
391
  return;
392
392
  }
393
- let (_r, _k, fp, _m) = diff_corpus_ontology("wine", input, truth, 200);
393
+ let budget = std::env::var("RUSTDL_TEST_PAIR_MS")
394
+ .ok()
395
+ .and_then(|v| v.parse().ok())
396
+ .unwrap_or(200);
397
+ let (_r, _k, fp, _m) = diff_corpus_ontology("wine", input, truth, budget);
394
398
  assert_eq!(
395
399
  fp, 0,
396
400
  "wine has FPs — soundness regression on nominals/datatypes"