ripple-down-rules 0.5.4__tar.gz → 0.5.5__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 (138) hide show
  1. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/PKG-INFO +15 -2
  2. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/README.md +13 -0
  3. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/intro.md +46 -21
  4. ripple_down_rules-0.5.5/images/scrdr.dot +127 -0
  5. ripple_down_rules-0.5.5/images/scrdr.png +0 -0
  6. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements.txt +1 -1
  7. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/__init__.py +1 -1
  8. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/template_file_creator.py +1 -0
  9. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/utils.py +2 -2
  10. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/PKG-INFO +15 -2
  11. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/SOURCES.txt +2 -0
  12. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/requires.txt +1 -1
  13. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/build_and_deploy_doc.yml +0 -0
  14. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/ci.yml +0 -0
  15. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/publish-to-test-pypi.yml +0 -0
  16. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
  17. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
  18. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/LICENSE +0 -0
  19. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/_config.yml +0 -0
  20. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/_toc.yml +0 -0
  21. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/bibliography.md +0 -0
  22. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/references.bib +0 -0
  23. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/requirements.txt +0 -0
  24. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/__init__.py +0 -0
  25. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/animal_species.py +0 -0
  26. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/__init__.py +0 -0
  27. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json +0 -0
  28. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_contained_objects_mcrdr.py +0 -0
  29. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py +0 -0
  30. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_rdr.py +0 -0
  31. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/relational_example.py +0 -0
  32. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/images/thinking_pr2.jpg +0 -0
  33. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/pyproject.toml +0 -0
  34. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/pytest.ini +0 -0
  35. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-dev-ci.txt +0 -0
  36. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-dev.txt +0 -0
  37. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-gui.txt +0 -0
  38. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-viz.txt +0 -0
  39. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_extra.dot +0 -0
  40. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_extra.png +0 -0
  41. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_only.dot +0 -0
  42. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_only.png +0 -0
  43. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
  44. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_plus_rule.png +0 -0
  45. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr.dot +0 -0
  46. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr.png +0 -0
  47. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_2.dot +0 -0
  48. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_2.png +0 -0
  49. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_3.dot +0 -0
  50. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_3.png +0 -0
  51. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Habitat.dot +0 -0
  52. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Habitat.png +0 -0
  53. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Species.dot +0 -0
  54. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Species.png +0 -0
  55. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra.dot +0 -0
  56. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra.png +0 -0
  57. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra_classify.dot +0 -0
  58. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra_classify.png +0 -0
  59. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
  60. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_stop_plus_rule_combined.png +0 -0
  61. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/partial_mcrdr_extra.dot +0 -0
  62. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/partial_mcrdr_extra.png +0 -0
  63. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/relational_scrdr_classify.dot +0 -0
  64. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/relational_scrdr_classify.png +0 -0
  65. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/setup.cfg +0 -0
  66. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/__init__.py +0 -0
  67. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
  68. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/case.py +0 -0
  69. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
  70. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/enums.py +0 -0
  71. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/experts.py +0 -0
  72. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/helpers.py +0 -0
  73. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/rdr.py +0 -0
  74. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/rdr_decorators.py +0 -0
  75. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/rules.py +0 -0
  76. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/start-code-server.sh +0 -0
  77. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/__init__.py +0 -0
  78. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/gui.py +0 -0
  79. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
  80. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
  81. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/prompt.py +0 -0
  82. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
  83. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
  84. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/datasets.py +0 -0
  85. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
  86. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
  87. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
  88. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
  89. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
  90. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
  91. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
  92. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
  93. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
  94. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
  95. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
  96. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
  97. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
  98. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
  99. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
  100. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
  101. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
  102. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
  103. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
  104. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
  105. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
  106. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
  107. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/view_rdr_expert_answers_fit.json +0 -0
  108. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_generated_rdrs/__init__.py +0 -0
  109. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/__init__.py +0 -0
  110. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/helpers.py +0 -0
  111. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/object_diagram_case_query.png +0 -0
  112. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/object_diagram_person.png +0 -0
  113. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_json_serialization.py +0 -0
  114. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_object_diagram.py +0 -0
  115. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_on_mutagenic.py +0 -0
  116. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr.py +0 -0
  117. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr_alchemy.py +0 -0
  118. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr_decorators.py +0 -0
  119. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr_world.py +0 -0
  120. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_relational_rdr.py +0 -0
  121. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_relational_rdr_alchemy.py +0 -0
  122. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/__init__.py +0 -0
  123. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +0 -0
  124. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +0 -0
  125. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +0 -0
  126. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/rdr_metadata/datasets_physical_object_is_a_robot.json +0 -0
  127. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +0 -0
  128. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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 +0 -0
  129. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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
  130. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_rdr.py +0 -0
  131. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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
  132. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_sql_model.py +0 -0
  133. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_template_file_creator.py +0 -0
  134. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/__init__.py +0 -0
  135. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_ipython.py +0 -0
  136. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_ipython_copilot.py +0 -0
  137. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_qt_gui_inline.py +0 -0
  138. {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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.5.4
3
+ Version: 0.5.5
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
@@ -693,7 +693,7 @@ Requires-Dist: colorama
693
693
  Requires-Dist: pygments
694
694
  Requires-Dist: sqlalchemy
695
695
  Requires-Dist: pandas
696
- Requires-Dist: pyparsing
696
+ Requires-Dist: pyparsing>=3.2.3
697
697
  Provides-Extra: viz
698
698
  Requires-Dist: networkx>=3.1; extra == "viz"
699
699
  Requires-Dist: matplotlib>=3.7.5; extra == "viz"
@@ -799,6 +799,19 @@ cat = grdr.classify(all_cases[50])['species']
799
799
  assert cat == targets[50]
800
800
  ```
801
801
 
802
+ When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
803
+ ```python
804
+ return case.milk == 1
805
+ ```
806
+ then
807
+ ```python
808
+ return case.aquatic == 1
809
+ ```
810
+
811
+ The rule tree generated from fitting all the dataset will look like this:
812
+ ![species_rdr](https://raw.githubusercontent.com/AbdelrhmanBassiouny/ripple_down_rules/main/images/scrdr.png)
813
+
814
+
802
815
  ### Relational Example
803
816
 
804
817
  By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
@@ -95,6 +95,19 @@ cat = grdr.classify(all_cases[50])['species']
95
95
  assert cat == targets[50]
96
96
  ```
97
97
 
98
+ When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
99
+ ```python
100
+ return case.milk == 1
101
+ ```
102
+ then
103
+ ```python
104
+ return case.aquatic == 1
105
+ ```
106
+
107
+ The rule tree generated from fitting all the dataset will look like this:
108
+ ![species_rdr](https://raw.githubusercontent.com/AbdelrhmanBassiouny/ripple_down_rules/main/images/scrdr.png)
109
+
110
+
98
111
  ### Relational Example
99
112
 
100
113
  By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
@@ -13,27 +13,39 @@ SCRDR, MCRDR, and GRDR logic were inspired from the book:
13
13
  ["Ripple Down Rules: An Alternative to Machine Learning"](https://www.taylorfrancis.com/books/mono/10.1201/9781003126157/ripple-rules-paul-compton-byeong-ho-kang) by Paul Compton, Byeong Ho Kang.
14
14
 
15
15
 
16
- Additionally, to the main ripple down rules benefits, this package also features:
17
-
18
- - Ontology and Rule base as one entity
19
- - Both use same python data structures.
20
- - Update in data structures reflects in Rule base.
21
- - Both are under one versioning system, the rule base is generated as a python module that becomes part of your
22
- project.
23
- - First, second, and higher order logic is achieved by freely writing python code.
24
- - Rule conditions and conclusions are python functions that can do anything that python can do.
25
- - Automatic maintenance of rule base.
26
- - When rules are added contradictions are detected and prompted to the user to add a refinement rule for
27
- to resolve the contradiction.
28
- - Transparent Editable rule base
29
- - Rules are understandable python code that can be manually edited and reloaded.
30
- - Interface that makes coders feel at home by using their favorite IDE.
31
- - Uses latest technologies like LLMs to help in writing the rules (Inherited feature from IDEs).
32
- - Auto completions and suggestions in the IDE.
33
- - Ask AI available with the press of a button to help in writing the rule.
34
- - Rules can be for instances on very specific scenarios and can be very general on super class relations.
35
- - Accompanied by a GUI with an object explorer panel and an expandable/retractable object diagram to help in
36
- writing the rules about the object at hand.
16
+ ## 🚀 Enhanced Ripple-Down Rules Engine Key Features
17
+
18
+ ### 🧠 Ontology + Rule Base as One Entity
19
+ - 🧬 Unified data structure: Ontology and rules use the same Python data structures.
20
+ - 🔄 Automatic sync: Updates to the ontology instantly reflect in the rule base.
21
+ - 📦 Version controlled: The rule base is a Python module, versioned with your project.
22
+
23
+ ### 🔁 Supports First, Second & Higher-Order Logic
24
+ - 🧩 Unlimited expressiveness: Rule conditions and conclusions are plain Python functions anything Python can do, your rules can too!
25
+
26
+ ### 🛡️ Automatic Rule Base Maintenance
27
+ - ⚠️ Contradiction detection: New rules are auto-checked for logical conflicts.
28
+ - 🔧 Prompted refinements: If a contradiction arises, you're guided to add a refinement rule.
29
+
30
+ ### 📝 Transparent & Editable Rule Base
31
+ - 📖 Readable rules: Rules are clean, understandable Python code.
32
+ - 🔄 Reload-friendly: Easily edit and reload rules manually as needed.
33
+
34
+ ### 💻 Developer-Centric Interface
35
+ - 👨‍💻 Feels like home: Seamless integration with your favorite IDE.
36
+ - Modern coding experience: Auto-completion and suggestions supported via IDE plugins.
37
+
38
+ ### 🤖 LLM-Powered Rule Writing
39
+ - 💡 AI-assisted authoring: Ask AI for help or suggestions directly within the IDE.
40
+ - ⚡ Smart completion: Context-aware completions streamline rule writing.
41
+
42
+ ### 🎯 Flexible Rule Specificity
43
+ - 🧪 Instance-level precision: Write rules for highly specific object scenarios.
44
+ - 🏛️ Generalization-ready: Create broad rules for superclass relationships.
45
+
46
+ ### 🖼️ GUI for Rule Exploration
47
+ - 🧭 Object Explorer Panel: Navigate and inspect objects easily.
48
+ - 🧯 Interactive Diagram: Expandable/collapsible object diagram to guide rule creation visually.
37
49
 
38
50
  This work aims to provide a flexible and powerful rule-based system that can be used in various applications,
39
51
  from simple classification tasks to complex decision-making systems. Furthermore, one of the main goals is to
@@ -186,6 +198,19 @@ cat = grdr.classify(all_cases[50])['species']
186
198
  assert cat == targets[50]
187
199
  ```
188
200
 
201
+ When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
202
+ ```python
203
+ return case.milk == 1
204
+ ```
205
+ then
206
+ ```python
207
+ return case.aquatic == 1
208
+ ```
209
+
210
+ The rule tree generated from fitting all the dataset will look like this:
211
+ ![species_rdr](https://raw.githubusercontent.com/AbdelrhmanBassiouny/ripple_down_rules/main/images/scrdr.png)
212
+
213
+
189
214
  ### Relational Example
190
215
 
191
216
  By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
@@ -0,0 +1,127 @@
1
+ digraph tree {
2
+ "def _get_value(case):
3
+ return case.milk == 1
4
+ => def _get_value(case):
5
+ return Species.mammal";
6
+ "def _get_value(case):
7
+ return case.aquatic == 1
8
+ => def _get_value(case):
9
+ return Species.fish";
10
+ "def _get_value(case):
11
+ return case.feathers == 1
12
+ => def _get_value(case):
13
+ return Species.bird";
14
+ "def _get_value(case):
15
+ return case.backbone == 0 and case.breathes == 0
16
+ => def _get_value(case):
17
+ return Species.molusc";
18
+ "def _get_value(case):
19
+ return case.eggs == 1 and case.backbone == 0
20
+ => def _get_value(case):
21
+ return Species.insect";
22
+ "def _get_value(case):
23
+ return case.backbone == 1 and case.tail == 1
24
+ => def _get_value(case):
25
+ return Species.reptile";
26
+ "def _get_value(case):
27
+ return case.backbone == 0 and case.eggs == 0
28
+ => def _get_value(case):
29
+ return Species.molusc";
30
+ "def _get_value(case):
31
+ return case.legs == 0
32
+ => def _get_value(case):
33
+ return Species.molusc";
34
+ "def _get_value(case):
35
+ return case.fins == 0
36
+ => def _get_value(case):
37
+ return Species.molusc";
38
+ "def _get_value(case):
39
+ return case.feathers == 1
40
+ => def _get_value(case):
41
+ return Species.bird_1";
42
+ "def _get_value(case):
43
+ return case.backbone == 1
44
+ => def _get_value(case):
45
+ return Species.amphibian";
46
+ "def _get_value(case):
47
+ return case.breathes == 0
48
+ => def _get_value(case):
49
+ return Species.reptile";
50
+ "def _get_value(case):
51
+ return case.milk == 1
52
+ => def _get_value(case):
53
+ return Species.mammal" -> "def _get_value(case):
54
+ return case.aquatic == 1
55
+ => def _get_value(case):
56
+ return Species.fish" [style="bold", label=" else if"];
57
+ "def _get_value(case):
58
+ return case.aquatic == 1
59
+ => def _get_value(case):
60
+ return Species.fish" -> "def _get_value(case):
61
+ return case.feathers == 1
62
+ => def _get_value(case):
63
+ return Species.bird" [style="bold", label=" else if"];
64
+ "def _get_value(case):
65
+ return case.aquatic == 1
66
+ => def _get_value(case):
67
+ return Species.fish" -> "def _get_value(case):
68
+ return case.fins == 0
69
+ => def _get_value(case):
70
+ return Species.molusc" [style="bold", label=" except if"];
71
+ "def _get_value(case):
72
+ return case.feathers == 1
73
+ => def _get_value(case):
74
+ return Species.bird" -> "def _get_value(case):
75
+ return case.backbone == 0 and case.breathes == 0
76
+ => def _get_value(case):
77
+ return Species.molusc" [style="bold", label=" else if"];
78
+ "def _get_value(case):
79
+ return case.backbone == 0 and case.breathes == 0
80
+ => def _get_value(case):
81
+ return Species.molusc" -> "def _get_value(case):
82
+ return case.eggs == 1 and case.backbone == 0
83
+ => def _get_value(case):
84
+ return Species.insect" [style="bold", label=" else if"];
85
+ "def _get_value(case):
86
+ return case.eggs == 1 and case.backbone == 0
87
+ => def _get_value(case):
88
+ return Species.insect" -> "def _get_value(case):
89
+ return case.backbone == 1 and case.tail == 1
90
+ => def _get_value(case):
91
+ return Species.reptile" [style="bold", label=" else if"];
92
+ "def _get_value(case):
93
+ return case.eggs == 1 and case.backbone == 0
94
+ => def _get_value(case):
95
+ return Species.insect" -> "def _get_value(case):
96
+ return case.legs == 0
97
+ => def _get_value(case):
98
+ return Species.molusc" [style="bold", label=" except if"];
99
+ "def _get_value(case):
100
+ return case.backbone == 1 and case.tail == 1
101
+ => def _get_value(case):
102
+ return Species.reptile" -> "def _get_value(case):
103
+ return case.backbone == 0 and case.eggs == 0
104
+ => def _get_value(case):
105
+ return Species.molusc" [style="bold", label=" else if"];
106
+ "def _get_value(case):
107
+ return case.fins == 0
108
+ => def _get_value(case):
109
+ return Species.molusc" -> "def _get_value(case):
110
+ return case.feathers == 1
111
+ => def _get_value(case):
112
+ return Species.bird_1" [style="bold", label=" except if"];
113
+ "def _get_value(case):
114
+ return case.feathers == 1
115
+ => def _get_value(case):
116
+ return Species.bird_1" -> "def _get_value(case):
117
+ return case.backbone == 1
118
+ => def _get_value(case):
119
+ return Species.amphibian" [style="bold", label=" else if"];
120
+ "def _get_value(case):
121
+ return case.backbone == 1
122
+ => def _get_value(case):
123
+ return Species.amphibian" -> "def _get_value(case):
124
+ return case.breathes == 0
125
+ => def _get_value(case):
126
+ return Species.reptile" [style="bold", label=" except if"];
127
+ }
Binary file
@@ -10,4 +10,4 @@ colorama
10
10
  pygments
11
11
  sqlalchemy
12
12
  pandas
13
- pyparsing
13
+ pyparsing>=3.2.3
@@ -1,4 +1,4 @@
1
- __version__ = "0.5.4"
1
+ __version__ = "0.5.5"
2
2
 
3
3
  import logging
4
4
  logger = logging.Logger("rdr")
@@ -300,6 +300,7 @@ class TemplateFileCreator:
300
300
  if isinstance(node, ast.FunctionDef) and node.name == func_name:
301
301
  exec_globals = {}
302
302
  scope = extract_imports(tree=tree)
303
+ updates.update(scope)
303
304
  exec(source, scope, exec_globals)
304
305
  user_function = exec_globals[func_name]
305
306
  updates[func_name] = user_function
@@ -1370,8 +1370,8 @@ def draw_tree(root: Node, fig: Figure):
1370
1370
  """
1371
1371
  Draw the tree using matplotlib and networkx.
1372
1372
  """
1373
- if matplotlib.get_backend().lower() not in ['qt5agg', 'qt4agg', 'qt6agg']:
1374
- matplotlib.use("Qt6Agg") # or "Qt6Agg", depending on availability
1373
+ # if matplotlib.get_backend().lower() not in ['qt5agg', 'qt4agg', 'qt6agg']:
1374
+ # matplotlib.use("Qt6Agg") # or "Qt6Agg", depending on availability
1375
1375
 
1376
1376
  if root is None:
1377
1377
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.5.4
3
+ Version: 0.5.5
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
@@ -693,7 +693,7 @@ Requires-Dist: colorama
693
693
  Requires-Dist: pygments
694
694
  Requires-Dist: sqlalchemy
695
695
  Requires-Dist: pandas
696
- Requires-Dist: pyparsing
696
+ Requires-Dist: pyparsing>=3.2.3
697
697
  Provides-Extra: viz
698
698
  Requires-Dist: networkx>=3.1; extra == "viz"
699
699
  Requires-Dist: matplotlib>=3.7.5; extra == "viz"
@@ -799,6 +799,19 @@ cat = grdr.classify(all_cases[50])['species']
799
799
  assert cat == targets[50]
800
800
  ```
801
801
 
802
+ When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
803
+ ```python
804
+ return case.milk == 1
805
+ ```
806
+ then
807
+ ```python
808
+ return case.aquatic == 1
809
+ ```
810
+
811
+ The rule tree generated from fitting all the dataset will look like this:
812
+ ![species_rdr](https://raw.githubusercontent.com/AbdelrhmanBassiouny/ripple_down_rules/main/images/scrdr.png)
813
+
814
+
802
815
  ### Relational Example
803
816
 
804
817
  By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
@@ -26,6 +26,8 @@ examples/part_containment_rdr/robot_contained_objects_mcrdr.py
26
26
  examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py
27
27
  examples/part_containment_rdr/robot_rdr.py
28
28
  examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json
29
+ images/scrdr.dot
30
+ images/scrdr.png
29
31
  images/thinking_pr2.jpg
30
32
  results/complete_mcrdr_extra.dot
31
33
  results/complete_mcrdr_extra.png
@@ -10,7 +10,7 @@ colorama
10
10
  pygments
11
11
  sqlalchemy
12
12
  pandas
13
- pyparsing
13
+ pyparsing>=3.2.3
14
14
 
15
15
  [gui]
16
16
  pyqt6