ripple-down-rules 0.6.52__tar.gz → 0.6.60__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 (184) hide show
  1. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/.github/workflows/ci.yml +2 -0
  2. ripple_down_rules-0.6.60/.gitmodules +3 -0
  3. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/PKG-INFO +3 -1
  4. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/propositional_example_tutorial.md +1 -1
  5. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/pyproject.toml +1 -1
  6. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/requirements.txt +3 -1
  7. ripple_down_rules-0.6.60/src/ripple_down_rules/__init__.py +25 -0
  8. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/datastructures/dataclasses.py +52 -9
  9. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/datastructures/enums.py +14 -87
  10. ripple_down_rules-0.6.60/src/ripple_down_rules/datastructures/field_info.py +177 -0
  11. ripple_down_rules-0.6.60/src/ripple_down_rules/datastructures/tracked_object.py +208 -0
  12. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/helpers.py +37 -2
  13. ripple_down_rules-0.6.60/src/ripple_down_rules/predicates.py +97 -0
  14. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/rdr.py +10 -6
  15. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/rdr_decorators.py +44 -34
  16. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/rules.py +166 -97
  17. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +9 -1
  18. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/user_interface/prompt.py +37 -37
  19. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/user_interface/template_file_creator.py +3 -0
  20. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/utils.py +32 -5
  21. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules.egg-info/PKG-INFO +3 -1
  22. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules.egg-info/SOURCES.txt +6 -0
  23. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules.egg-info/requires.txt +2 -0
  24. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/conftest.py +2 -1
  25. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/datasets.py +20 -3
  26. ripple_down_rules-0.6.60/test/test_predicates.py +15 -0
  27. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr.py +4 -2
  28. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr_world/conftest.py +4 -11
  29. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr_world/test_rdr_world.py +15 -1
  30. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_template_file_creator.py +3 -2
  31. ripple_down_rules-0.6.60/test/test_tracked_object.py +36 -0
  32. ripple_down_rules-0.6.52/src/ripple_down_rules/__init__.py +0 -17
  33. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/.github/workflows/build_and_deploy_doc.yml +0 -0
  34. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/.github/workflows/publish-to-test-pypi.yml +0 -0
  35. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/.gitignore +0 -0
  36. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
  37. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
  38. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/LICENSE +0 -0
  39. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/README.md +0 -0
  40. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/_config.yml +0 -0
  41. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/_toc.yml +0 -0
  42. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/bibliography.md +0 -0
  43. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/intro.md +0 -0
  44. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/references.bib +0 -0
  45. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/relational_example_tutorial.md +0 -0
  46. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/relational_example_with_decorator_tutorial.md +0 -0
  47. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/requirements.txt +0 -0
  48. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/doc/test_driven_rdr_fitting_tutorial.md +0 -0
  49. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/__init__.py +0 -0
  50. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/animal_species.py +0 -0
  51. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_example.py +0 -0
  52. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model.py +0 -0
  53. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model_robot_get_contained_objects/__init__.py +0 -0
  54. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model_robot_get_contained_objects/rdr_metadata/decorator_model_robot_get_contained_objects.json +0 -0
  55. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model_robot_get_contained_objects/robot_get_contained_objects_output__mcrdr.py +0 -0
  56. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model_robot_get_contained_objects/robot_get_contained_objects_output__mcrdr_cases.py +0 -0
  57. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model_robot_get_contained_objects/robot_get_contained_objects_output__mcrdr_defs.py +0 -0
  58. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/decorator_model_robot_get_contained_objects/robot_get_contained_objects_rdr.py +0 -0
  59. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/part_containment_rdr/__init__.py +0 -0
  60. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json +0 -0
  61. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/part_containment_rdr/robot_contained_objects_mcrdr.py +0 -0
  62. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/part_containment_rdr/robot_contained_objects_mcrdr_cases.py +0 -0
  63. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py +0 -0
  64. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/part_containment_rdr/robot_rdr.py +0 -0
  65. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/relational_example.py +0 -0
  66. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/relational_model.py +0 -0
  67. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/examples/test_relational_example.py +0 -0
  68. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/images/scrdr.dot +0 -0
  69. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/images/scrdr.png +0 -0
  70. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/images/thinking_pr2.jpg +0 -0
  71. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/pytest.ini +0 -0
  72. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/requirements-dev-ci.txt +0 -0
  73. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/requirements-dev.txt +0 -0
  74. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/requirements-gui.txt +0 -0
  75. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/requirements-viz.txt +0 -0
  76. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_mcrdr_extra.dot +0 -0
  77. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_mcrdr_extra.png +0 -0
  78. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_mcrdr_stop_only.dot +0 -0
  79. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_mcrdr_stop_only.png +0 -0
  80. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
  81. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_mcrdr_stop_plus_rule.png +0 -0
  82. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_scrdr.dot +0 -0
  83. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_scrdr.png +0 -0
  84. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_scrdr_2.dot +0 -0
  85. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_scrdr_2.png +0 -0
  86. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_scrdr_3.dot +0 -0
  87. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/complete_scrdr_3.png +0 -0
  88. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/grdr_Habitat.dot +0 -0
  89. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/grdr_Habitat.png +0 -0
  90. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/grdr_Species.dot +0 -0
  91. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/grdr_Species.png +0 -0
  92. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/mcrdr_extra.dot +0 -0
  93. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/mcrdr_extra.png +0 -0
  94. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/mcrdr_extra_classify.dot +0 -0
  95. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/mcrdr_extra_classify.png +0 -0
  96. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
  97. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/mcrdr_stop_plus_rule_combined.png +0 -0
  98. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/partial_mcrdr_extra.dot +0 -0
  99. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/partial_mcrdr_extra.png +0 -0
  100. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/relational_scrdr_classify.dot +0 -0
  101. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/results/relational_scrdr_classify.png +0 -0
  102. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/scripts/live_dot_server_client.py +0 -0
  103. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/setup.cfg +0 -0
  104. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/datastructures/__init__.py +0 -0
  105. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
  106. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/datastructures/case.py +0 -0
  107. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/experts.py +0 -0
  108. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/failures.py +0 -0
  109. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/start-code-server.sh +0 -0
  110. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/user_interface/__init__.py +0 -0
  111. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/user_interface/gui.py +0 -0
  112. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
  113. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
  114. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
  115. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/__init__.py +0 -0
  116. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/conf/__init__.py +0 -0
  117. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/conf/world/__init__.py +0 -0
  118. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/conf/world/base_config.py +0 -0
  119. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/conf/world/handles_and_containers.py +0 -0
  120. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/factories/__init__.py +0 -0
  121. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/factories/world/__init__.py +0 -0
  122. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/factories/world/handles_and_containers.py +0 -0
  123. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/__init__.py +0 -0
  124. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
  125. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/drawer_cabinet_expert_answers_fit.json +0 -0
  126. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
  127. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
  128. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/grdr_expert_answers_fit.py +0 -0
  129. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
  130. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
  131. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.py +0 -0
  132. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
  133. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
  134. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.py +0 -0
  135. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
  136. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.py +0 -0
  137. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
  138. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
  139. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
  140. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.py +0 -0
  141. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
  142. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
  143. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
  144. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
  145. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
  146. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
  147. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
  148. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
  149. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_expert_answers_fit.py +0 -0
  150. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
  151. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.py +0 -0
  152. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
  153. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.py +0 -0
  154. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
  155. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_generated_rdrs/__init__.py +0 -0
  156. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_helpers/__init__.py +0 -0
  157. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_helpers/helpers.py +0 -0
  158. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_helpers/object_diagram_case_query.png +0 -0
  159. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_helpers/object_diagram_person.png +0 -0
  160. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_json_serialization.py +0 -0
  161. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_object_diagram.py +0 -0
  162. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_on_mutagenic.py +0 -0
  163. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr_alchemy.py +0 -0
  164. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr_decorators.py +0 -0
  165. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr_helpers_rdrs.py +0 -0
  166. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_rdr_world/__init__.py +0 -0
  167. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_relational_rdr.py +0 -0
  168. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_relational_rdr_alchemy.py +0 -0
  169. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_results/__init__.py +0 -0
  170. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_results/datasets_physical_object_is_a_robot/__init__.py +0 -0
  171. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +0 -0
  172. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +0 -0
  173. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +0 -0
  174. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +0 -0
  175. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/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
  176. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/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
  177. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/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
  178. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_sql_model.py +0 -0
  179. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_user_interface/__init__.py +0 -0
  180. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_user_interface/test_ipython.py +0 -0
  181. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_user_interface/test_ipython_copilot.py +0 -0
  182. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_user_interface/test_prompt.py +0 -0
  183. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_user_interface/test_qt_gui_inline.py +0 -0
  184. {ripple_down_rules-0.6.52 → ripple_down_rules-0.6.60}/test/test_utils.py +0 -0
@@ -24,6 +24,8 @@ jobs:
24
24
 
25
25
  - name: Install dependencies
26
26
  run: |
27
+ git submodule init
28
+ git submodule update
27
29
  sudo apt-get update
28
30
  sudo apt install graphviz graphviz-dev
29
31
  python -m pip install --upgrade pip
@@ -0,0 +1,3 @@
1
+ [submodule "src/ripple_down_rules_meta"]
2
+ path = src/ripple_down_rules_meta
3
+ url = https://github.com/AbdelrhmanBassiouny/ripple_down_rules_meta.git
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.6.52
3
+ Version: 0.6.60
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
@@ -696,6 +696,8 @@ Requires-Dist: sqlalchemy
696
696
  Requires-Dist: pandas
697
697
  Requires-Dist: pyparsing>=3.2.3
698
698
  Requires-Dist: omegaconf
699
+ Requires-Dist: rustworkx
700
+ Requires-Dist: pydot
699
701
  Provides-Extra: viz
700
702
  Requires-Dist: networkx>=3.1; extra == "viz"
701
703
  Requires-Dist: matplotlib>=3.7.5; extra == "viz"
@@ -85,7 +85,7 @@ grdr = GeneralRDR(save_dir="./", model_name="species_rdr")
85
85
  grdr.fit(case_queries, animate_tree=True)
86
86
 
87
87
  # Render the tree to a file
88
- render_tree(grdr.start_rules[0], use_dot_exporter=True, filename="species_rdr")
88
+ render_tree(grdr.start_rules[0].node, use_dot_exporter=True, filename="species_rdr")
89
89
 
90
90
  # Classify a case
91
91
  cat = grdr.classify(all_cases[50])
@@ -21,7 +21,7 @@ Homepage = "https://github.com/AbdelrhmanBassiouny/ripple_down_rules"
21
21
 
22
22
  [tool.setuptools.packages.find]
23
23
  where = ["src"]
24
- include = ["ripple_down_rules*"]
24
+ include = ["ripple_down_rules"]
25
25
 
26
26
  [tool.setuptools.dynamic]
27
27
  version = {attr = "ripple_down_rules.__version__"}
@@ -11,4 +11,6 @@ pygments
11
11
  sqlalchemy
12
12
  pandas
13
13
  pyparsing>=3.2.3
14
- omegaconf
14
+ omegaconf
15
+ rustworkx
16
+ pydot
@@ -0,0 +1,25 @@
1
+ __version__ = "0.6.60"
2
+
3
+ import logging
4
+ import sys
5
+
6
+ logger = logging.Logger("rdr")
7
+ logger.setLevel(logging.INFO)
8
+
9
+ try:
10
+ from PyQt6.QtWidgets import QApplication
11
+ app = QApplication(sys.argv)
12
+ except ImportError:
13
+ pass
14
+
15
+
16
+ # Trigger patch
17
+ try:
18
+ from .predicates import *
19
+ from .datastructures.tracked_object import TrackedObjectMixin
20
+ from .datastructures.dataclasses import CaseQuery
21
+ from .rdr_decorators import RDRDecorator
22
+ from .rdr import MultiClassRDR, SingleClassRDR, GeneralRDR
23
+ import ripple_down_rules_meta._apply_overrides
24
+ except ImportError:
25
+ pass
@@ -12,7 +12,7 @@ from typing_extensions import Any, Optional, Dict, Type, Tuple, Union, List, Set
12
12
  from .callable_expression import CallableExpression
13
13
  from .case import create_case, Case
14
14
  from ..utils import copy_case, make_list, make_set, get_origin_and_args_from_type_hint, render_tree, \
15
- get_function_representation
15
+ get_function_representation, get_method_object_from_pytest_request
16
16
 
17
17
  if TYPE_CHECKING:
18
18
  from ..rdr import RippleDownRules
@@ -60,9 +60,14 @@ class CaseQuery:
60
60
  The executable scenario is the root callable that recreates the situation that the case is
61
61
  created in, for example, when the case is created from a test function, this would be the test function itself.
62
62
  """
63
+ this_case_target_value: Optional[Any] = None
64
+ """
65
+ The non relational case query instance target value.
66
+ """
63
67
  _target: Optional[CallableExpression] = None
64
68
  """
65
- The target expression of the attribute.
69
+ The relational target (the evaluatable conclusion of the rule) which is a callable expression that varies with
70
+ the case.
66
71
  """
67
72
  default_value: Optional[Any] = None
68
73
  """
@@ -306,6 +311,12 @@ class CaseFactoryMetaData:
306
311
  factory_idx: Optional[int] = None
307
312
  case_conf: Optional[CaseConf] = None
308
313
  scenario: Optional[Callable] = None
314
+ pytest_request: Optional[Callable] = field(hash=False, compare=False, default=None)
315
+ this_case_target_value: Optional[Any] = None
316
+
317
+ def __post_init__(self):
318
+ if self.pytest_request is not None and self.scenario is None:
319
+ self.scenario = get_method_object_from_pytest_request(self.pytest_request)
309
320
 
310
321
  @classmethod
311
322
  def from_case_query(cls, case_query: CaseQuery) -> CaseFactoryMetaData:
@@ -322,8 +333,9 @@ class CaseFactoryMetaData:
322
333
  return (f"CaseFactoryMetaData("
323
334
  f"factory_method={factory_method_repr}, "
324
335
  f"factory_idx={self.factory_idx}, "
325
- f"case_conf={self.case_conf},"
326
- f" scenario={scenario_repr})")
336
+ f"case_conf={self.case_conf}, "
337
+ f"scenario={scenario_repr}, "
338
+ f"this_case_target_value={self.this_case_target_value})")
327
339
 
328
340
  def __str__(self):
329
341
  return self.__repr__()
@@ -335,26 +347,57 @@ class RDRConclusion:
335
347
  This dataclass represents a conclusion of a Ripple Down Rule.
336
348
  It contains the conclusion expression, the type of the conclusion, and the scope in which it is evaluated.
337
349
  """
338
- value: Any
350
+ _conclusion: Any
339
351
  """
340
352
  The conclusion value.
341
353
  """
342
- frozen_case: Any
354
+ _frozen_case: Any
343
355
  """
344
356
  The frozen case that the conclusion was made for.
345
357
  """
346
- rule: Rule
358
+ _rule: Rule
347
359
  """
348
360
  The rule that gave this conclusion.
349
361
  """
350
- rdr: RippleDownRules
362
+ _rdr: RippleDownRules
351
363
  """
352
364
  The Ripple Down Rules that classified the case and produced this conclusion.
353
365
  """
354
- id: int = field(default_factory=lambda: uuid.uuid4().int)
366
+ _id: int = field(default_factory=lambda: uuid.uuid4().int)
355
367
  """
356
368
  The unique identifier of the conclusion.
357
369
  """
370
+ def __getattribute__(self, name: str) -> Any:
371
+ if name.startswith('_'):
372
+ return object.__getattribute__(self, name)
373
+ else:
374
+ conclusion = object.__getattribute__(self, "_conclusion")
375
+
376
+ value = getattr(conclusion, name)
377
+
378
+ self._record_dependency(name)
379
+
380
+ return value
381
+
382
+ def __setattr__(self, name, value):
383
+ if name.startswith('_'):
384
+ object.__setattr__(self, name, value)
385
+ else:
386
+ setattr(self._wrapped, name, value)
387
+
388
+ def _record_dependency(self, attr_name):
389
+ # Inspect stack to find instance of CallableExpression
390
+ for frame_info in inspect.stack():
391
+ func_name = frame_info.function
392
+ local_self = frame_info.frame.f_locals.get("self", None)
393
+ if (
394
+ func_name == "__call__" and
395
+ local_self is not None and
396
+ type(local_self) is CallableExpression
397
+ ):
398
+ self._used_in_tracker = True
399
+ print("RDRConclusion used inside CallableExpression")
400
+ break
358
401
 
359
402
  def __hash__(self):
360
403
  return hash(self.id)
@@ -93,20 +93,6 @@ class Stop(Category):
93
93
  stop = "stop"
94
94
 
95
95
 
96
- class ExpressionParser(Enum):
97
- """
98
- Parsers for expressions to evaluate and encapsulate the expression into a callable function.
99
- """
100
- ASTVisitor: int = auto()
101
- """
102
- Generic python Abstract Syntax Tree that detects variables, attributes, binary/boolean expressions , ...etc.
103
- """
104
- SQLAlchemy: int = auto()
105
- """
106
- Specific for SQLAlchemy expressions on ORM Tables.
107
- """
108
-
109
-
110
96
  class PromptFor(Enum):
111
97
  """
112
98
  The reason of the prompt. (e.g. get conditions, conclusions, or affirmation).
@@ -131,51 +117,6 @@ class PromptFor(Enum):
131
117
  return self.__str__()
132
118
 
133
119
 
134
- class CategoricalValue(Enum):
135
- """
136
- A categorical value is a value that is a category.
137
- """
138
-
139
- def __eq__(self, other):
140
- if isinstance(other, CategoricalValue):
141
- return self.name == other.name
142
- elif isinstance(other, str):
143
- return self.name == other
144
- return self.name == other
145
-
146
- def __hash__(self):
147
- return hash(self.name)
148
-
149
- @classmethod
150
- def to_list(cls):
151
- return list(cls._value2member_map_.keys())
152
-
153
- @classmethod
154
- def from_str(cls, category: str):
155
- return cls[category.lower()]
156
-
157
- @classmethod
158
- def from_strs(cls, categories: List[str]):
159
- return [cls.from_str(c) for c in categories]
160
-
161
- def __str__(self):
162
- return self.name
163
-
164
- def __repr__(self):
165
- return self.__str__()
166
-
167
-
168
- class RDRMode(Enum):
169
- Propositional = auto()
170
- """
171
- Propositional mode, the mode where the rules are propositional.
172
- """
173
- Relational = auto()
174
- """
175
- Relational mode, the mode where the rules are relational.
176
- """
177
-
178
-
179
120
  class MCRDRMode(Enum):
180
121
  """
181
122
  The modes of the MultiClassRDR.
@@ -213,33 +154,19 @@ class RDREdge(Enum):
213
154
  """
214
155
  Filter edge, the edge that represents the filter condition.
215
156
  """
216
-
217
- class ValueType(Enum):
218
- Unary = auto()
219
- """
220
- Unary value type (eg. null).
221
- """
222
- Binary = auto()
223
- """
224
- Binary value type (eg. True, False).
225
- """
226
- Discrete = auto()
227
- """
228
- Discrete value type (eg. 1, 2, 3).
157
+ Empty = ""
229
158
  """
230
- Continuous = auto()
231
- """
232
- Continuous value type (eg. 1.0, 2.5, 3.4).
233
- """
234
- Nominal = auto()
235
- """
236
- Nominal value type (eg. red, blue, green), categories where the values have no natural order.
237
- """
238
- Ordinal = auto()
239
- """
240
- Ordinal value type (eg. low, medium, high), categories where the values have a natural order.
241
- """
242
- Iterable = auto()
243
- """
244
- Iterable value type (eg. [1, 2, 3]).
159
+ Empty edge, used for example for the root/input node of the tree.
245
160
  """
161
+
162
+ @classmethod
163
+ def from_value(cls, value: str) -> RDREdge:
164
+ """
165
+ Convert a string value to an RDREdge enum.
166
+
167
+ :param value: The string that represents the edge type.
168
+ :return: The RDREdge enum.
169
+ """
170
+ if value not in cls._value2member_map_:
171
+ raise ValueError(f"RDREdge {value} is not supported.")
172
+ return cls._value2member_map_[value]
@@ -0,0 +1,177 @@
1
+ from __future__ import annotations
2
+
3
+ import enum
4
+ import importlib
5
+ import inspect
6
+ import logging
7
+ import sys
8
+ import typing
9
+ from dataclasses import dataclass, Field
10
+ from datetime import datetime
11
+ from functools import lru_cache
12
+ from types import NoneType
13
+
14
+ from typing_extensions import Type, get_origin, Optional, get_type_hints, Tuple
15
+
16
+ from ripple_down_rules.utils import make_tuple
17
+
18
+
19
+ class ParseError(TypeError):
20
+ """
21
+ Error that will be raised when the parser encounters something that can/should not be parsed.
22
+
23
+ For instance, Union types
24
+ """
25
+ pass
26
+
27
+
28
+ @dataclass
29
+ class FieldInfo:
30
+ """
31
+ A class that wraps a field of dataclass and provides some utility functions.
32
+ """
33
+
34
+ clazz: Type
35
+ """
36
+ The class that the field is in.
37
+ """
38
+
39
+ name: str
40
+ """
41
+ The name of the field.
42
+ """
43
+
44
+ type: Tuple[Type, ...]
45
+ """
46
+ The type of the field or inner type of the container if it is a container.
47
+ """
48
+
49
+ optional: bool
50
+ """
51
+ True if the field is optional, False otherwise.
52
+ """
53
+
54
+ container: Optional[Type]
55
+ """
56
+ The type of the container if it is one (list, set, tuple, etc.). If there is no container this is None
57
+ """
58
+
59
+ is_type_field: bool = False
60
+ """
61
+ The field value is a type.
62
+ """
63
+
64
+ field: Field = None
65
+ """
66
+ The field instance.
67
+ """
68
+
69
+ def __init__(self, clazz: Type, f: Field):
70
+ self.field = f
71
+ self.name = f.name
72
+ self.clazz = clazz
73
+
74
+ try:
75
+ type_hints = get_type_hints(clazz)[self.name]
76
+ except NameError as e:
77
+ found_clazz = manually_search_for_class_name(e.name)
78
+ module = importlib.import_module(found_clazz.__module__)
79
+ locals()[e.name] = getattr(module, e.name)
80
+ type_hints = get_type_hints(clazz, localns=locals())[self.name]
81
+ type_args = typing.get_args(type_hints)
82
+
83
+ # try to unpack the type if it is a nested type
84
+ if len(type_args) > 0:
85
+ self.optional = NoneType in type_args
86
+
87
+ if self.optional:
88
+ self.container = None
89
+ else:
90
+ self.container = get_origin(type_hints)
91
+
92
+ if not self.optional and type_hints == Type[type_args]:
93
+ self.is_type_field = True
94
+
95
+ self.type = type_args
96
+ else:
97
+ self.optional = False
98
+ self.container = None
99
+ self.type = make_tuple(type_hints)
100
+
101
+ @property
102
+ def is_builtin_class(self) -> bool:
103
+ return not self.container and all(t.__module__ == 'builtins' for t in self.type)
104
+
105
+ @property
106
+ def is_container_of_builtin(self) -> bool:
107
+ return self.container and all(t.__module__ == 'builtins' for t in self.type)
108
+
109
+ @property
110
+ def is_type_type(self) -> bool:
111
+ return self.is_type_field
112
+
113
+ @property
114
+ def is_enum(self):
115
+ return len(self.type) == 1 and issubclass(self.type[0], enum.Enum)
116
+
117
+ @property
118
+ def is_datetime(self):
119
+ return len(self.type) == 1 and self.type[0] == datetime
120
+
121
+
122
+ def is_container(clazz: Type) -> bool:
123
+ """
124
+ Check if a class is an iterable.
125
+
126
+ :param clazz: The class to check
127
+ :return: True if the class is an iterable, False otherwise
128
+ """
129
+ return get_origin(clazz) in [list, set, tuple]
130
+
131
+
132
+ def manually_search_for_class_name(target_class_name: str) -> Type:
133
+ """
134
+ Searches for a class with the specified name in the current module's `globals()` dictionary
135
+ and all loaded modules present in `sys.modules`. This function attempts to find and resolve
136
+ the first class that matches the given name. If multiple classes are found with the same
137
+ name, a warning is logged, and the first one is returned. If no matching class is found,
138
+ an exception is raised.
139
+
140
+ :param target_class_name: Name of the class to search for.
141
+ :return: The resolved class with the matching name.
142
+
143
+ :raises ValueError: Raised when no class with the specified name can be found.
144
+ """
145
+ found_classes = []
146
+
147
+ # Search 1: In the current module's globals()
148
+ for name, obj in globals().items():
149
+ if inspect.isclass(obj) and obj.__name__ == target_class_name:
150
+ found_classes.append(obj)
151
+
152
+ # Search 2: In all loaded modules (via sys.modules)
153
+ for module_name, module in sys.modules.items():
154
+ if module is None or not hasattr(module, '__dict__'):
155
+ continue # Skip built-in modules or modules without a __dict__
156
+
157
+ for name, obj in module.__dict__.items():
158
+ if inspect.isclass(obj) and obj.__name__ == target_class_name:
159
+ # Avoid duplicates if a class is imported into multiple namespaces
160
+ if (obj, f"from module '{module_name}'") not in found_classes:
161
+ found_classes.append(obj)
162
+
163
+ # If you wanted to "resolve" the forward ref based on this
164
+ if len(found_classes) == 0:
165
+ raise ValueError(f"Could not find any class with name {target_class_name} in globals or sys.modules.")
166
+ elif len(found_classes) == 1:
167
+ resolved_class = found_classes[0]
168
+ else:
169
+ warn_multiple_classes(target_class_name, tuple(found_classes))
170
+ resolved_class = found_classes[0]
171
+
172
+ return resolved_class
173
+
174
+
175
+ @lru_cache(maxsize=None)
176
+ def warn_multiple_classes(target_class_name, found_classes):
177
+ logging.warning(f"Found multiple classes with name {target_class_name}. Found classes: {found_classes} ")