ripple-down-rules 0.6.20__tar.gz → 0.6.22__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 (153) hide show
  1. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/PKG-INFO +1 -1
  2. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/scripts/live_dot_server.py +15 -8
  3. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/__init__.py +1 -1
  4. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/rdr.py +11 -7
  5. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/rdr_decorators.py +7 -2
  6. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/rules.py +10 -0
  7. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/utils.py +8 -7
  8. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules.egg-info/PKG-INFO +1 -1
  9. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_is_a_robot/rdr_metadata/datasets_physical_object_is_a_robot.json +4 -4
  10. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_output__mcrdr.py +3 -3
  11. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/.github/workflows/build_and_deploy_doc.yml +0 -0
  12. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/.github/workflows/ci.yml +0 -0
  13. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/.github/workflows/publish-to-test-pypi.yml +0 -0
  14. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/.gitignore +0 -0
  15. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
  16. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
  17. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/LICENSE +0 -0
  18. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/README.md +0 -0
  19. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/doc/_config.yml +0 -0
  20. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/doc/_toc.yml +0 -0
  21. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/doc/bibliography.md +0 -0
  22. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/doc/intro.md +0 -0
  23. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/doc/references.bib +0 -0
  24. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/doc/requirements.txt +0 -0
  25. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/__init__.py +0 -0
  26. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/animal_species.py +0 -0
  27. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/part_containment_rdr/__init__.py +0 -0
  28. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json +0 -0
  29. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/part_containment_rdr/robot_contained_objects_mcrdr.py +0 -0
  30. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py +0 -0
  31. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/part_containment_rdr/robot_rdr.py +0 -0
  32. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/examples/relational_example.py +0 -0
  33. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/images/scrdr.dot +0 -0
  34. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/images/scrdr.png +0 -0
  35. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/images/thinking_pr2.jpg +0 -0
  36. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/pyproject.toml +0 -0
  37. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/pytest.ini +0 -0
  38. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/requirements-dev-ci.txt +0 -0
  39. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/requirements-dev.txt +0 -0
  40. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/requirements-gui.txt +0 -0
  41. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/requirements-viz.txt +0 -0
  42. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/requirements.txt +0 -0
  43. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_mcrdr_extra.dot +0 -0
  44. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_mcrdr_extra.png +0 -0
  45. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_mcrdr_stop_only.dot +0 -0
  46. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_mcrdr_stop_only.png +0 -0
  47. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
  48. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_mcrdr_stop_plus_rule.png +0 -0
  49. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_scrdr.dot +0 -0
  50. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_scrdr.png +0 -0
  51. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_scrdr_2.dot +0 -0
  52. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_scrdr_2.png +0 -0
  53. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_scrdr_3.dot +0 -0
  54. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/complete_scrdr_3.png +0 -0
  55. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/grdr_Habitat.dot +0 -0
  56. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/grdr_Habitat.png +0 -0
  57. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/grdr_Species.dot +0 -0
  58. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/grdr_Species.png +0 -0
  59. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/mcrdr_extra.dot +0 -0
  60. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/mcrdr_extra.png +0 -0
  61. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/mcrdr_extra_classify.dot +0 -0
  62. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/mcrdr_extra_classify.png +0 -0
  63. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
  64. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/mcrdr_stop_plus_rule_combined.png +0 -0
  65. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/partial_mcrdr_extra.dot +0 -0
  66. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/partial_mcrdr_extra.png +0 -0
  67. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/relational_scrdr_classify.dot +0 -0
  68. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/results/relational_scrdr_classify.png +0 -0
  69. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/setup.cfg +0 -0
  70. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/datastructures/__init__.py +0 -0
  71. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
  72. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/datastructures/case.py +0 -0
  73. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
  74. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/datastructures/enums.py +0 -0
  75. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/experts.py +0 -0
  76. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/helpers.py +0 -0
  77. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/start-code-server.sh +0 -0
  78. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/user_interface/__init__.py +0 -0
  79. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/user_interface/gui.py +0 -0
  80. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
  81. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
  82. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/user_interface/prompt.py +0 -0
  83. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules/user_interface/template_file_creator.py +0 -0
  84. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules.egg-info/SOURCES.txt +0 -0
  85. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
  86. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules.egg-info/requires.txt +0 -0
  87. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
  88. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/__init__.py +0 -0
  89. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/conf/__init__.py +0 -0
  90. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/conf/world/__init__.py +0 -0
  91. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/conf/world/base_config.py +0 -0
  92. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/conf/world/handles_and_containers.py +0 -0
  93. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/conftest.py +0 -0
  94. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/datasets.py +0 -0
  95. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/factories/__init__.py +0 -0
  96. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/factories/world/__init__.py +0 -0
  97. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/factories/world/handles_and_containers.py +0 -0
  98. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
  99. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/drawer_cabinet_expert_answers_fit.json +0 -0
  100. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
  101. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
  102. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
  103. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
  104. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
  105. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
  106. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
  107. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
  108. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
  109. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
  110. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
  111. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
  112. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
  113. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
  114. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
  115. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
  116. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
  117. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
  118. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
  119. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
  120. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
  121. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_generated_rdrs/__init__.py +0 -0
  122. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_helpers/__init__.py +0 -0
  123. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_helpers/helpers.py +0 -0
  124. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_helpers/object_diagram_case_query.png +0 -0
  125. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_helpers/object_diagram_person.png +0 -0
  126. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_json_serialization.py +0 -0
  127. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_object_diagram.py +0 -0
  128. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_on_mutagenic.py +0 -0
  129. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr.py +0 -0
  130. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr_alchemy.py +0 -0
  131. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr_decorators.py +0 -0
  132. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr_helpers_rdrs.py +0 -0
  133. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr_world/__init__.py +0 -0
  134. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr_world/conftest.py +0 -0
  135. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_rdr_world/test_rdr_world.py +0 -0
  136. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_relational_rdr.py +0 -0
  137. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_relational_rdr_alchemy.py +0 -0
  138. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_is_a_robot/__init__.py +0 -0
  139. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +1 -1
  140. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +0 -0
  141. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +1 -1
  142. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +0 -0
  143. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_output__mcrdr_defs.py +0 -0
  144. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_rdr.py +1 -1
  145. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/rdr_metadata/datasets_physical_object_select_objects_that_are_parts_of_robot.json +0 -0
  146. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_sql_model.py +0 -0
  147. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_template_file_creator.py +0 -0
  148. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_user_interface/__init__.py +0 -0
  149. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_user_interface/test_ipython.py +0 -0
  150. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_user_interface/test_ipython_copilot.py +0 -0
  151. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_user_interface/test_prompt.py +0 -0
  152. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_user_interface/test_qt_gui_inline.py +0 -0
  153. {ripple_down_rules-0.6.20 → ripple_down_rules-0.6.22}/test/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.6.20
3
+ Version: 0.6.22
4
4
  Summary: Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning.
5
5
  Author-email: Abdelrhman Bassiouny <abassiou@uni-bremen.de>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1,18 +1,29 @@
1
1
  import http.server
2
+ import shutil
2
3
  import socketserver
3
4
  import threading
4
5
  import time
5
6
  import os
6
7
  import sys
8
+ import urllib.request
7
9
 
8
10
  dot_path = None
9
11
  last_modified = None
10
12
 
11
13
  def get_dot_content():
12
- with open(dot_path, "r", encoding="utf-8") as f:
13
- return f.read().replace("`", "\\`")
14
+ if dot_path.startswith("http://") or dot_path.startswith("https://"):
15
+ try:
16
+ with urllib.request.urlopen(dot_path) as response:
17
+ return response.read().decode("utf-8").replace("`", "\\`")
18
+ except Exception as e:
19
+ print(f"[ERROR] Failed to fetch DOT from URL: {e}")
20
+ return "digraph G { ErrorFetching -> DOT; }"
21
+ else:
22
+ with open(dot_path, "r", encoding="utf-8") as f:
23
+ return f.read().replace("`", "\\`")
14
24
 
15
25
  def generate_html(dot_output="graph.html"):
26
+ shutil.copy(dot_file, "graph.dot")
16
27
  html_template = f"""<!DOCTYPE html>
17
28
  <html>
18
29
  <head>
@@ -41,7 +52,7 @@ def generate_html(dot_output="graph.html"):
41
52
  }}
42
53
 
43
54
  fetchAndRender();
44
- setInterval(fetchAndRender, 2000); // Refresh every 2 seconds
55
+ setInterval(fetchAndRender, 500); // Refresh every 2 seconds
45
56
  </script>
46
57
  </body>
47
58
  </html>"""
@@ -67,7 +78,7 @@ def serve_dot(dot_file, port=8000):
67
78
  generate_html("graph.html")
68
79
 
69
80
  handler = CustomHandler
70
- with socketserver.TCPServer(("", port), handler) as httpd:
81
+ with socketserver.TCPServer(("0.0.0.0", port), handler) as httpd:
71
82
  print(f"Serving at http://localhost:{port}/graph.html")
72
83
  try:
73
84
  httpd.serve_forever()
@@ -82,8 +93,4 @@ if __name__ == "__main__":
82
93
  dot_file = sys.argv[1]
83
94
  port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
84
95
 
85
- if not os.path.exists(dot_file):
86
- print(f"Error: File '{dot_file}' does not exist.")
87
- sys.exit(1)
88
-
89
96
  serve_dot(dot_file, port)
@@ -1,4 +1,4 @@
1
- __version__ = "0.6.20"
1
+ __version__ = "0.6.22"
2
2
 
3
3
  import logging
4
4
  logger = logging.Logger("rdr")
@@ -92,7 +92,7 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
92
92
  self.start_rule = start_rule
93
93
  self.fig: Optional[Figure] = None
94
94
  self.viewer: Optional[RDRCaseViewer] = viewer
95
- if viewer is None:
95
+ if viewer is None and RDRCaseViewer is not None:
96
96
  if len(RDRCaseViewer.instances) > 0:
97
97
  self.viewer = RDRCaseViewer.instances[0]
98
98
  logger.error("No viewer was provided, but there is already an existing viewer. "
@@ -108,11 +108,14 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
108
108
  if value is not None:
109
109
  value.set_save_function(self.save)
110
110
 
111
- def render_evaluated_rule_tree(self, filename: str) -> None:
112
- evaluated_rules = self.get_evaluated_rule_tree()
113
- if len(evaluated_rules) > 0:
114
- render_tree(evaluated_rules[0], use_dot_exporter=True, filename=filename,
115
- only_nodes=evaluated_rules)
111
+ def render_evaluated_rule_tree(self, filename: str, show_full_tree: bool = False) -> None:
112
+ if show_full_tree:
113
+ render_tree(self.start_rule, use_dot_exporter=True, filename=filename)
114
+ else:
115
+ evaluated_rules = self.get_evaluated_rule_tree()
116
+ if evaluated_rules is not None and len(evaluated_rules) > 0:
117
+ render_tree(evaluated_rules[0], use_dot_exporter=True, filename=filename,
118
+ only_nodes=evaluated_rules)
116
119
 
117
120
  def get_evaluated_rule_tree(self) -> List[Rule]:
118
121
  """
@@ -121,7 +124,8 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
121
124
  :return: The evaluated rule tree.
122
125
  """
123
126
  if self.start_rule is None:
124
- raise ValueError("The start rule is not set. Please set the start rule before getting the evaluated rule tree.")
127
+ return
128
+ # raise ValueError("The start rule is not set. Please set the start rule before getting the evaluated rule tree.")
125
129
  evaluated_rule_tree = [r for r in [self.start_rule] + list(self.start_rule.descendants) if r.evaluated]
126
130
  return evaluated_rule_tree
127
131
 
@@ -75,6 +75,7 @@ class RDRDecorator:
75
75
  self.fitting_decorator = fitting_decorator if fitting_decorator is not None else \
76
76
  lambda f: f # Default to no fitting decorator
77
77
  self.generate_dot_file = generate_dot_file
78
+ self.not_none_output_found: bool = False
78
79
  self.load()
79
80
 
80
81
  def decorator(self, func: Callable) -> Callable:
@@ -117,7 +118,11 @@ class RDRDecorator:
117
118
  else:
118
119
  output = self.rdr.classify(case)
119
120
  if self.generate_dot_file:
120
- self.rdr.render_evaluated_rule_tree(self.rdr_models_dir + f'/{self.model_name}')
121
+ eval_rule_tree = self.rdr.get_evaluated_rule_tree()
122
+ if not self.not_none_output_found or (eval_rule_tree and len(eval_rule_tree) > 1):
123
+ self.rdr.render_evaluated_rule_tree(self.rdr_models_dir + f'/{self.model_name}', show_full_tree=True)
124
+ if eval_rule_tree and len(eval_rule_tree) > 1:
125
+ self.not_none_output_found = True
121
126
 
122
127
  if self.output_name in output:
123
128
  return output[self.output_name]
@@ -176,7 +181,7 @@ class RDRDecorator:
176
181
  return Case(dict, id(case_dict), case_name, case_dict, **case_dict), case_dict
177
182
 
178
183
  def initialize_rdr_model_name_and_load(self, func: Callable) -> None:
179
- self.viewer = RDRCaseViewer.instances[0] if len(RDRCaseViewer.instances) > 0 else self.viewer
184
+ self.viewer = RDRCaseViewer.instances[0] if RDRCaseViewer is not None and len(RDRCaseViewer.instances) > 0 else self.viewer
180
185
  model_file_name = get_func_rdr_model_name(func, include_file_name=True)
181
186
  self.model_name = str_to_snake_case(model_file_name)
182
187
  self.load()
@@ -60,6 +60,16 @@ class Rule(NodeMixin, SubclassJSONSerializer, ABC):
60
60
  self.evaluated: bool = False
61
61
  self._user_defined_name: Optional[str] = None
62
62
 
63
+ @property
64
+ def color(self) -> str:
65
+ if self.evaluated:
66
+ if self.fired:
67
+ return "green"
68
+ else:
69
+ return "red"
70
+ else:
71
+ return "white"
72
+
63
73
  @property
64
74
  def user_defined_name(self) -> Optional[str]:
65
75
  """
@@ -1839,7 +1839,7 @@ class FilteredDotExporter(object):
1839
1839
  continue
1840
1840
  nodeattr = nodeattrfunc(node)
1841
1841
  nodeattr = " [%s]" % nodeattr if nodeattr is not None else ""
1842
- yield '%s"%s"%s;' % (indent, DotExporter.esc(nodename), nodeattr)
1842
+ yield '%s"%s"%s;' % (indent, FilteredDotExporter.esc(nodename), nodeattr)
1843
1843
 
1844
1844
  def __iter_edges(self, indent, nodenamefunc, edgeattrfunc, edgetypefunc):
1845
1845
  maxlevel = self.maxlevel - 1 if self.maxlevel else None
@@ -1854,8 +1854,8 @@ class FilteredDotExporter(object):
1854
1854
  edgeattr = edgeattrfunc(node, child)
1855
1855
  edgetype = edgetypefunc(node, child)
1856
1856
  edgeattr = " [%s]" % edgeattr if edgeattr is not None else ""
1857
- yield '%s"%s" %s "%s"%s;' % (indent, DotExporter.esc(nodename), edgetype,
1858
- DotExporter.esc(childname), edgeattr)
1857
+ yield '%s"%s" %s "%s"%s;' % (indent, FilteredDotExporter.esc(nodename), edgetype,
1858
+ FilteredDotExporter.esc(childname), edgeattr)
1859
1859
 
1860
1860
  def to_dotfile(self, filename):
1861
1861
  """
@@ -1925,18 +1925,19 @@ def render_tree(root: Node, use_dot_exporter: bool = False,
1925
1925
  if not root:
1926
1926
  logging.warning("No rules to render")
1927
1927
  return
1928
- for pre, _, node in RenderTree(root):
1929
- print(f"{pre}{node.weight if hasattr(node, 'weight') and node.weight else ''} {node.__str__()}")
1928
+ # for pre, _, node in RenderTree(root):
1929
+ # print(f"{pre}{node.weight if hasattr(node, 'weight') and node.weight else ''} {node.__str__()}")
1930
1930
  if use_dot_exporter:
1931
1931
  unique_node_names = get_unique_node_names_func(root)
1932
1932
 
1933
1933
  de = FilteredDotExporter(root,
1934
1934
  include_nodes=only_nodes,
1935
1935
  nodenamefunc=unique_node_names,
1936
- edgeattrfunc=edge_attr_setter
1936
+ edgeattrfunc=edge_attr_setter,
1937
+ nodeattrfunc=lambda node: f'style=filled, fillcolor={node.color}'
1937
1938
  )
1938
1939
  de.to_dotfile(f"{filename}{'.dot'}")
1939
- de.to_picture(f"{filename}{'.png'}")
1940
+ # de.to_picture(f"{filename}{'.png'}")
1940
1941
 
1941
1942
 
1942
1943
  def draw_tree(root: Node, fig: Figure):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.6.20
3
+ Version: 0.6.22
4
4
  Summary: Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning.
5
5
  Author-email: Abdelrhman Bassiouny <abassiou@uni-bremen.de>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -15,9 +15,9 @@
15
15
  "Dict": "typing.Dict",
16
16
  "Optional": "typing.Optional",
17
17
  "Union": "typing.Union",
18
- "NoneType": "builtins.NoneType",
19
18
  "PhysicalObject": "test.datasets.PhysicalObject",
20
- "Robot": "test.datasets.Robot"
19
+ "Robot": "test.datasets.Robot",
20
+ "NoneType": "builtins.NoneType"
21
21
  },
22
22
  "conclusion": {
23
23
  "_type": "builtins.NoneType",
@@ -35,9 +35,9 @@
35
35
  "Dict": "typing.Dict",
36
36
  "Optional": "typing.Optional",
37
37
  "Union": "typing.Union",
38
- "NoneType": "builtins.NoneType",
39
38
  "PhysicalObject": "test.datasets.PhysicalObject",
40
- "Robot": "test.datasets.Robot"
39
+ "Robot": "test.datasets.Robot",
40
+ "NoneType": "builtins.NoneType"
41
41
  },
42
42
  "conclusion": {
43
43
  "_type": "builtins.NoneType",
@@ -1,11 +1,11 @@
1
- from ripple_down_rules.utils import make_set
2
- from ripple_down_rules.datastructures.case import Case, create_case
3
1
  from typing_extensions import Optional, Set
2
+ from ripple_down_rules.datastructures.case import Case, create_case
3
+ from ripple_down_rules.utils import make_set
4
4
  from .physical_object_select_objects_that_are_parts_of_robot_output__mcrdr_defs import *
5
5
 
6
6
 
7
7
  attribute_name = 'output_'
8
- conclusion_type = (set, PhysicalObject, list,)
8
+ conclusion_type = (set, list, PhysicalObject,)
9
9
  mutually_exclusive = False
10
10
 
11
11
 
@@ -1,5 +1,5 @@
1
- from ripple_down_rules.datastructures.case import Case, create_case
2
1
  from typing_extensions import Optional
2
+ from ripple_down_rules.datastructures.case import Case, create_case
3
3
  from types import NoneType
4
4
  from .physical_object_is_a_robot_output__scrdr_defs import *
5
5
 
@@ -1,6 +1,6 @@
1
+ from ripple_down_rules.helpers import general_rdr_classify
1
2
  from typing_extensions import Any, Dict
2
3
  from ripple_down_rules.datastructures.case import Case, create_case
3
- from ripple_down_rules.helpers import general_rdr_classify
4
4
  from . import physical_object_is_a_robot_output__scrdr as output__classifier
5
5
 
6
6
  classifiers_dict = dict()
@@ -1,6 +1,6 @@
1
+ from ripple_down_rules.helpers import general_rdr_classify
1
2
  from typing_extensions import Any, Dict
2
3
  from ripple_down_rules.datastructures.case import Case, create_case
3
- from ripple_down_rules.helpers import general_rdr_classify
4
4
  from . import physical_object_select_objects_that_are_parts_of_robot_output__mcrdr as output__classifier
5
5
 
6
6
  classifiers_dict = dict()