ripple-down-rules 0.6.48__tar.gz → 0.6.50__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 (167) hide show
  1. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/PKG-INFO +1 -1
  2. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/intro.md +1 -1
  3. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/relational_example_tutorial.md +2 -2
  4. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/relational_example_with_decorator_tutorial.md +5 -3
  5. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/__init__.py +1 -1
  6. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/rdr_decorators.py +98 -81
  7. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules.egg-info/PKG-INFO +1 -1
  8. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules.egg-info/SOURCES.txt +1 -1
  9. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr_decorators.py +0 -2
  10. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr_helpers_rdrs.py +1 -2
  11. ripple_down_rules-0.6.50/test/test_results/__init__.py +1 -0
  12. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +9 -9
  13. ripple_down_rules-0.6.50/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 +19 -0
  14. ripple_down_rules-0.6.48/test/test_results/datasets_physical_object_is_a_robot/rdr_metadata/datasets_physical_object_is_a_robot.json +0 -56
  15. ripple_down_rules-0.6.48/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 -19
  16. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/.github/workflows/build_and_deploy_doc.yml +0 -0
  17. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/.github/workflows/ci.yml +0 -0
  18. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/.github/workflows/publish-to-test-pypi.yml +0 -0
  19. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/.gitignore +0 -0
  20. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
  21. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
  22. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/LICENSE +0 -0
  23. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/README.md +0 -0
  24. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/_config.yml +0 -0
  25. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/_toc.yml +0 -0
  26. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/bibliography.md +0 -0
  27. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/propositional_example_tutorial.md +0 -0
  28. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/references.bib +0 -0
  29. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/requirements.txt +0 -0
  30. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/doc/test_driven_rdr_fitting_tutorial.md +0 -0
  31. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/__init__.py +0 -0
  32. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/animal_species.py +0 -0
  33. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/decorator_example.py +0 -0
  34. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/decorator_model.py +0 -0
  35. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/relational_example.py +0 -0
  36. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/relational_model.py +0 -0
  37. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/examples/test_relational_example.py +0 -0
  38. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/images/scrdr.dot +0 -0
  39. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/images/scrdr.png +0 -0
  40. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/images/thinking_pr2.jpg +0 -0
  41. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/pyproject.toml +0 -0
  42. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/pytest.ini +0 -0
  43. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/requirements-dev-ci.txt +0 -0
  44. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/requirements-dev.txt +0 -0
  45. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/requirements-gui.txt +0 -0
  46. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/requirements-viz.txt +0 -0
  47. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/requirements.txt +0 -0
  48. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_mcrdr_extra.dot +0 -0
  49. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_mcrdr_extra.png +0 -0
  50. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_mcrdr_stop_only.dot +0 -0
  51. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_mcrdr_stop_only.png +0 -0
  52. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
  53. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_mcrdr_stop_plus_rule.png +0 -0
  54. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_scrdr.dot +0 -0
  55. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_scrdr.png +0 -0
  56. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_scrdr_2.dot +0 -0
  57. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_scrdr_2.png +0 -0
  58. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_scrdr_3.dot +0 -0
  59. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/complete_scrdr_3.png +0 -0
  60. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/grdr_Habitat.dot +0 -0
  61. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/grdr_Habitat.png +0 -0
  62. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/grdr_Species.dot +0 -0
  63. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/grdr_Species.png +0 -0
  64. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/mcrdr_extra.dot +0 -0
  65. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/mcrdr_extra.png +0 -0
  66. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/mcrdr_extra_classify.dot +0 -0
  67. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/mcrdr_extra_classify.png +0 -0
  68. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
  69. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/mcrdr_stop_plus_rule_combined.png +0 -0
  70. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/partial_mcrdr_extra.dot +0 -0
  71. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/partial_mcrdr_extra.png +0 -0
  72. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/relational_scrdr_classify.dot +0 -0
  73. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/results/relational_scrdr_classify.png +0 -0
  74. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/scripts/live_dot_server_client.py +0 -0
  75. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/setup.cfg +0 -0
  76. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/datastructures/__init__.py +0 -0
  77. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
  78. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/datastructures/case.py +0 -0
  79. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
  80. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/datastructures/enums.py +0 -0
  81. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/experts.py +0 -0
  82. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/failures.py +0 -0
  83. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/helpers.py +0 -0
  84. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/rdr.py +0 -0
  85. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/rules.py +0 -0
  86. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/start-code-server.sh +0 -0
  87. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/user_interface/__init__.py +0 -0
  88. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/user_interface/gui.py +0 -0
  89. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
  90. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
  91. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/user_interface/prompt.py +0 -0
  92. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/user_interface/template_file_creator.py +0 -0
  93. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules/utils.py +0 -0
  94. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
  95. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules.egg-info/requires.txt +0 -0
  96. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
  97. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/__init__.py +0 -0
  98. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/conf/__init__.py +0 -0
  99. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/conf/world/__init__.py +0 -0
  100. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/conf/world/base_config.py +0 -0
  101. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/conf/world/handles_and_containers.py +0 -0
  102. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/conftest.py +0 -0
  103. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/datasets.py +0 -0
  104. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/factories/__init__.py +0 -0
  105. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/factories/world/__init__.py +0 -0
  106. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/factories/world/handles_and_containers.py +0 -0
  107. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/__init__.py +0 -0
  108. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
  109. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/drawer_cabinet_expert_answers_fit.json +0 -0
  110. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
  111. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
  112. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/grdr_expert_answers_fit.py +0 -0
  113. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
  114. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
  115. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.py +0 -0
  116. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
  117. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
  118. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.py +0 -0
  119. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
  120. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.py +0 -0
  121. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
  122. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
  123. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
  124. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.py +0 -0
  125. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
  126. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
  127. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
  128. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
  129. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
  130. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
  131. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
  132. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
  133. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_expert_answers_fit.py +0 -0
  134. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
  135. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.py +0 -0
  136. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
  137. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.py +0 -0
  138. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
  139. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_generated_rdrs/__init__.py +0 -0
  140. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_helpers/__init__.py +0 -0
  141. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_helpers/helpers.py +0 -0
  142. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_helpers/object_diagram_case_query.png +0 -0
  143. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_helpers/object_diagram_person.png +0 -0
  144. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_json_serialization.py +0 -0
  145. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_object_diagram.py +0 -0
  146. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_on_mutagenic.py +0 -0
  147. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr.py +0 -0
  148. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr_alchemy.py +0 -0
  149. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr_world/__init__.py +0 -0
  150. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr_world/conftest.py +0 -0
  151. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_rdr_world/test_rdr_world.py +0 -0
  152. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_relational_rdr.py +0 -0
  153. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_relational_rdr_alchemy.py +0 -0
  154. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_results/datasets_physical_object_is_a_robot/__init__.py +0 -0
  155. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +2 -2
  156. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +1 -1
  157. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +0 -0
  158. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/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 +2 -2
  159. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/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
  160. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_sql_model.py +0 -0
  161. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_template_file_creator.py +0 -0
  162. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_user_interface/__init__.py +0 -0
  163. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_user_interface/test_ipython.py +0 -0
  164. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_user_interface/test_ipython_copilot.py +0 -0
  165. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_user_interface/test_prompt.py +0 -0
  166. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/test/test_user_interface/test_qt_gui_inline.py +0 -0
  167. {ripple_down_rules-0.6.48 → ripple_down_rules-0.6.50}/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.48
3
+ Version: 0.6.50
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
@@ -13,7 +13,7 @@ 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
- ## 🚀 Enhanced Ripple-Down Rules Engine – Key Features
16
+ ## 🚀 Key Features
17
17
 
18
18
  ### 🧠 Data Model (Ontology) + Rule Base as One Entity
19
19
  - 🧬 Unified data structure: Data Model (Ontology) and rules use the same Python data structures.
@@ -73,7 +73,7 @@ from ripple_down_rules import CaseQuery, GeneralRDR
73
73
 
74
74
  grdr = GeneralRDR(save_dir='./', model_name='part_containment_rdr')
75
75
 
76
- case_query = CaseQuery(robot, "contained_objects", (PhysicalObject,), False)
76
+ case_query = CaseQuery(robot, "contained_objects", (PhysicalObject,), mutually_exclusive=False)
77
77
  ```
78
78
 
79
79
  ### Fit the Model to the Case Query by Answering the prompts.
@@ -83,7 +83,7 @@ grdr.fit_case(case_query)
83
83
 
84
84
  When prompted to write a rule, I press edit in GUI (or type %edit in the Ipython interface if not using GUI),
85
85
  I wrote the following inside the template function that the Ripple Down Rules created for me, this function takes a
86
- `case` object as input:
86
+ `case` object as input, in this exampke the case is the `Robot` instance:
87
87
 
88
88
  ```python
89
89
  contained_objects = []
@@ -86,7 +86,7 @@ assert contained_objects == [part_b]
86
86
 
87
87
  When prompted to write a rule, I press edit in GUI (or type %edit in the Ipython interface if not using GUI),
88
88
  I wrote the following inside the template function that the Ripple Down Rules created for me, this function takes a
89
- `case` object as input:
89
+ `case` object as input, in this exampke the case is the `Robot` instance:
90
90
 
91
91
  ```python
92
92
  contained_objects = []
@@ -114,8 +114,10 @@ This means that the rule will only be applied if the robot has parts.
114
114
  We can let the fit mode be `True`, but give the rdr a function that tells it when to prompt for an answer.
115
115
  For example, we can ask for an answer only when the robot's name is "tracy", which will result in the rdr not asking
116
116
  for an answer because the robot name is "pr2" for the current case.
117
- The input to the `ask_now` function is a dictionary with the original function arguments, while arguments like
118
- `self` and `cls` are passed as a special key `'self_'` or `'cls_'` respectively.
117
+ The {py:attr}`ripple_down_rules.rdr_decorators.RDRDecorator.ask_now` is a user provided callable function that outputs
118
+ a boolean indicating when to ask the expert for an answer. The input to the `ask_now` function is a dictionary with the
119
+ original function arguments, while arguments like `self` and `cls` are passed as a special key `'self_'` or `'cls_'`
120
+ respectively.
119
121
  ```python
120
122
  robot.containment_rdr.fit = True
121
123
  robot.containment_rdr.ask_now = lambda case: case['self_'].name == "tracy"
@@ -1,4 +1,4 @@
1
- __version__ = "0.6.48"
1
+ __version__ = "0.6.50"
2
2
 
3
3
  import logging
4
4
  import sys
@@ -4,17 +4,18 @@ that can be used with any python function such that this function can benefit fr
4
4
  of the RDRs.
5
5
  """
6
6
  import os.path
7
+ from dataclasses import dataclass, field
7
8
  from functools import wraps
8
9
  from typing import get_origin
9
10
 
10
11
  from typing_extensions import Callable, Optional, Type, Tuple, Dict, Any, Self, get_type_hints, List, Union, Sequence
11
12
 
12
- from .utils import get_type_from_type_hint
13
13
  from .datastructures.case import Case
14
14
  from .datastructures.dataclasses import CaseQuery
15
15
  from .experts import Expert, Human
16
16
  from .rdr import GeneralRDR
17
- from . import logger
17
+ from .utils import get_type_from_type_hint
18
+
18
19
  try:
19
20
  from .user_interface.gui import RDRCaseViewer
20
21
  except ImportError:
@@ -23,63 +24,92 @@ from .utils import get_method_args_as_dict, get_func_rdr_model_name, make_set, \
23
24
  get_method_class_if_exists, str_to_snake_case, make_list
24
25
 
25
26
 
27
+ @dataclass(unsafe_hash=True)
26
28
  class RDRDecorator:
27
- rdr: GeneralRDR
28
-
29
- def __init__(self, models_dir: str,
30
- output_type: Tuple[Type],
31
- mutual_exclusive: bool,
32
- output_name: str = "output_",
33
- fit: bool = True,
34
- expert: Optional[Expert] = None,
35
- update_existing_rules: bool = True,
36
- viewer: Optional[RDRCaseViewer] = None,
37
- package_name: Optional[str] = None,
38
- use_generated_classifier: bool = False,
39
- ask_now: Callable[Dict[str, Any], bool] = lambda _: True,
40
- fitting_decorator: Optional[Callable] = None,
41
- generate_dot_file: bool = False) -> None:
42
- """
43
- :param models_dir: The directory to save/load the RDR models.
44
- :param output_type: The type of the output. This is used to create the RDR model.
45
- :param mutual_exclusive: If True, the output types are mutually exclusive.
46
- If None, the RDR model will not be saved as a python file.
47
- :param output_name: The name of the output. This is used to create the RDR model.
48
- :param fit: If True, the function will be in fit mode. This means that the RDR will prompt the user for the
49
- correct output if the function's output is not in the RDR model. If False, the function will be in
50
- classification mode. This means that the RDR will classify the function's output based on the RDR model.
51
- :param expert: The expert that will be used to prompt the user for the correct output. If None, a Human
52
- expert will be used.
53
- :param update_existing_rules: If True, the function will update the existing RDR rules
54
- even if they gave an output.
55
- :param viewer: The viewer to use for the RDR model. If None, no viewer will be used.
56
- :param package_name: The package name to use for relative imports in the RDR model.
57
- :param use_generated_classifier: If True, the function will use the generated classifier instead of the RDR model.
58
- :param ask_now: A callable that takes the case dictionary and returns True if the user should be asked for
59
- the output, or False if the function should return the output without asking.
60
- :param fitting_decorator: A decorator to use for the fitting function. If None, no decorator will be used.
61
- :param generate_dot_file: If True, the RDR model will generate a dot file for visualization.
62
- :return: A decorator to use a GeneralRDR as a classifier that monitors and modifies the function's output.
63
- """
64
- self.rdr_models_dir = models_dir
65
- self.model_name: Optional[str] = None
66
- self.output_type = output_type
67
- self.parsed_output_type: List[Type] = []
68
- self.mutual_exclusive = mutual_exclusive
69
- self.output_name = output_name
70
- self.fit: bool = fit
71
- self.expert: Optional[Expert] = expert
72
- self.update_existing_rules = update_existing_rules
73
- self.viewer = viewer
74
- self.package_name = package_name
75
- self.use_generated_classifier = use_generated_classifier
76
- self.generated_classifier: Optional[Callable] = None
77
- self.ask_now = ask_now
78
- self.fitting_decorator = fitting_decorator if fitting_decorator is not None else \
79
- lambda f: f # Default to no fitting decorator
80
- self.generate_dot_file = generate_dot_file
81
- self.not_none_output_found: bool = False
82
- self.origin_type: Optional[Type] = None
29
+ models_dir: str
30
+ """
31
+ The directory to save the RDR models in.
32
+ """
33
+ output_type: Tuple[Type, ...]
34
+ """
35
+ The type(s) of the output produced by the RDR model (The type(s) of the queried attribute).
36
+ """
37
+ mutual_exclusive: bool
38
+ """
39
+ Whether the queried attribute is mutually exclusive (i.e. allows for only one possible value) or not.
40
+ """
41
+ fit: bool = field(default=True)
42
+ """
43
+ Whether to run in fitting mode and prompt the expert or just classify using existing rules.
44
+ """
45
+ expert: Optional[Expert] = field(default=None)
46
+ """
47
+ The expert instance, this is used by the rdr to prompt for answers.
48
+ """
49
+ update_existing_rules: bool = field(default=True)
50
+ """
51
+ When in fitting mode, whether to ask for answers for existing rules as well or not.
52
+ """
53
+ package_name: Optional[str] = field(default=None)
54
+ """
55
+ The name of the user python package where the RDR model will be saved, this is useful for generating relative
56
+ imports in the generated rdr model files.
57
+ """
58
+ use_generated_classifier: bool = field(default=False)
59
+ """
60
+ Whether to use the generated classifier files of the rdr model instead of the RDR instance itself, this is useful
61
+ when you want to debug inside the rules.
62
+ """
63
+ ask_now: Callable[Dict[str, Any], bool] = field(default=lambda _: True)
64
+ """
65
+ A user provided callable function that outputs a boolean indicating when to ask the expert for an answer. The input
66
+ to the `ask_now` function is a dictionary with the original function arguments, while arguments like `self` and
67
+ `cls` are passed as a special key `self_` or `cls_` respectively.
68
+ """
69
+ fitting_decorator: Optional[Callable] = field(default=lambda f: f)
70
+ """
71
+ A user provided decorator that wraps the `py:meth:ripple_down_rules.rdr.RippleDownRules.fit_case` method which is
72
+ used when in fitting mode, this is useful when you want special logic pre and post the fitting operation, you can
73
+ for example freeze your system during fitting such that you have a stable state that you can query and use while
74
+ writing and testing your answer/rule.
75
+ """
76
+ generate_dot_file: bool = field(default=False)
77
+ """
78
+ Whether to generate a dynamic dot file representing the state of the rule tree each time the rdr is queried, showing
79
+ which rules fired and which rules didn't get evaluated, ...etc.
80
+ """
81
+ model_name: Optional[str] = field(default=None)
82
+ """
83
+ The name of the rdr model, this gets auto generated from the function signature and the class/file it is contained
84
+ in.
85
+ """
86
+ rdr: GeneralRDR = field(init=False)
87
+ """
88
+ The ripple down rules instance of the decorator class.
89
+ """
90
+ parsed_output_type: List[Type] = field(init=False, default_factory=list)
91
+ """
92
+ The output of a post processing done on the output types, for example converting typing module types
93
+ (i.e. type hints) to python types.
94
+ """
95
+ origin_type: Optional[Type] = field(init=False, default=None)
96
+ """
97
+ The origin of the type hint of the attribute, useful in the case of not mutually exclusive attributes to map the
98
+ result to the specified container type (e.g. a list instead of a set which is the default container type for rdr
99
+ output).
100
+ """
101
+ output_name: str = field(init=False, default='output_')
102
+ """
103
+ This is used to refer to the output value of the decorated function, this is used as part of the case as input to
104
+ the rdr model, but is never used in the rule logic to prevent cycles from happening. The correct way to use the
105
+ output of an rdr in the rules logic is in the case when mutually exclusive is False, or through refinements of
106
+ existing rules when mutually exclusive is True, which happens automatically by the rdr prompting for refinements.
107
+ """
108
+ _not_none_output_found: bool = field(init=False, default=False)
109
+ """
110
+ This is a flag that indicates that a not None output for the rdr has been inferred, this is used to update the
111
+ generated dot file if it is set to `True`.
112
+ """
83
113
 
84
114
  def decorator(self, func: Callable) -> Callable:
85
115
 
@@ -102,33 +132,33 @@ class RDRDecorator:
102
132
  if len(self.parsed_output_type) == 0:
103
133
  self.parsed_output_type = self.parse_output_type(func, self.output_type, *args)
104
134
  if self.expert is None:
105
- self.expert = Human(answers_save_path=self.rdr_models_dir + f'/{self.model_name}/expert_answers')
135
+ self.expert = Human(answers_save_path=self.models_dir + f'/{self.model_name}/expert_answers')
106
136
  case_query = self.create_case_query_from_method(func, func_output,
107
137
  self.parsed_output_type,
108
138
  self.mutual_exclusive,
109
139
  case, case_dict,
110
140
  *args, **kwargs)
111
141
  output = self.rdr.fit_case(case_query, expert=self.expert,
112
- update_existing_rules=self.update_existing_rules,
113
- viewer=self.viewer)
142
+ update_existing_rules=self.update_existing_rules)
114
143
  return output
115
-
144
+
116
145
  if self.fit and not self.use_generated_classifier and self.ask_now(case_dict):
117
146
  output = fit()
118
147
  else:
119
148
  if self.use_generated_classifier:
120
149
  if self.generated_classifier is None:
121
- model_path = os.path.join(self.rdr_models_dir, self.model_name)
150
+ model_path = os.path.join(self.models_dir, self.model_name)
122
151
  self.generated_classifier = self.rdr.get_rdr_classifier_from_python_file(model_path)
123
152
  output = self.generated_classifier(case)
124
153
  else:
125
154
  output = self.rdr.classify(case)
126
155
  if self.generate_dot_file:
127
156
  eval_rule_tree = self.rdr.get_evaluated_rule_tree()
128
- if not self.not_none_output_found or (eval_rule_tree and len(eval_rule_tree) > 1):
129
- self.rdr.render_evaluated_rule_tree(self.rdr_models_dir + f'/{self.model_name}', show_full_tree=True)
157
+ if not self._not_none_output_found or (eval_rule_tree and len(eval_rule_tree) > 1):
158
+ self.rdr.render_evaluated_rule_tree(self.models_dir + f'/{self.model_name}',
159
+ show_full_tree=True)
130
160
  if eval_rule_tree and len(eval_rule_tree) > 1:
131
- self.not_none_output_found = True
161
+ self._not_none_output_found = True
132
162
 
133
163
  if self.output_name in output:
134
164
  if self.origin_type == list:
@@ -189,7 +219,6 @@ class RDRDecorator:
189
219
  return Case(dict, id(case_dict), case_name, case_dict, **case_dict), case_dict
190
220
 
191
221
  def initialize_rdr_model_name_and_load(self, func: Callable) -> None:
192
- self.viewer = RDRCaseViewer.instances[0] if RDRCaseViewer is not None and len(RDRCaseViewer.instances) > 0 else self.viewer
193
222
  model_file_name = get_func_rdr_model_name(func, include_file_name=True)
194
223
  self.model_name = str_to_snake_case(model_file_name)
195
224
  self.load()
@@ -209,20 +238,8 @@ class RDRDecorator:
209
238
  parsed_output_type.append(ot)
210
239
  return parsed_output_type
211
240
 
212
- def save(self):
213
- """
214
- Save the RDR model to the specified directory.
215
- """
216
- self.rdr.save(self.rdr_models_dir, self.model_name, package_name=self.package_name)
217
-
218
241
  def load(self):
219
242
  """
220
- Load the RDR model from the specified directory.
221
- """
222
- self.rdr = GeneralRDR(save_dir=self.rdr_models_dir, model_name=self.model_name)
223
-
224
- def update_from_python(self):
225
- """
226
- Update the RDR model from a python file.
243
+ Load the RDR model from the specified directory, otherwise create a new one.
227
244
  """
228
- self.rdr.update_from_python(self.rdr_models_dir, parent_package_name=self.package_name)
245
+ self.rdr = GeneralRDR(save_dir=self.models_dir, model_name=self.model_name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripple_down_rules
3
- Version: 0.6.48
3
+ Version: 0.6.50
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
@@ -147,11 +147,11 @@ test/test_helpers/object_diagram_person.png
147
147
  test/test_rdr_world/__init__.py
148
148
  test/test_rdr_world/conftest.py
149
149
  test/test_rdr_world/test_rdr_world.py
150
+ test/test_results/__init__.py
150
151
  test/test_results/datasets_physical_object_is_a_robot/__init__.py
151
152
  test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py
152
153
  test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py
153
154
  test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py
154
- test/test_results/datasets_physical_object_is_a_robot/rdr_metadata/datasets_physical_object_is_a_robot.json
155
155
  test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py
156
156
  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
157
157
  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
@@ -14,7 +14,6 @@ class RDRDecoratorsTestCase(unittest.TestCase):
14
14
  self.physical_object._is_a_robot_rdr.fit = False
15
15
  self.assertFalse(self.physical_object.is_a_robot())
16
16
  self.assertTrue(self.robot.is_a_robot())
17
- self.physical_object._is_a_robot_rdr.save()
18
17
 
19
18
  def test_select_objects_that_are_parts_of_robots(self):
20
19
  self.physical_object._select_parts_rdr.fit = False
@@ -24,4 +23,3 @@ class RDRDecoratorsTestCase(unittest.TestCase):
24
23
  self.assertIn(part, self.robot.parts)
25
24
  self.assertNotIn(self.part_3, selected_parts)
26
25
  self.assertNotIn(self.robot, selected_parts)
27
- self.physical_object._select_parts_rdr.save()
@@ -11,8 +11,7 @@ save_dir = join(dirname(__file__), '..', 'src', 'ripple_down_rules')
11
11
  # viewer = RDRCaseViewer(save_dir=save_dir)
12
12
  viewer = None
13
13
  rdr_decorator: RDRDecorator = RDRDecorator(save_dir, (bool,), True,
14
- fit=False,
15
- viewer=viewer)
14
+ fit=False)
16
15
 
17
16
 
18
17
  @rdr_decorator.decorator
@@ -0,0 +1 @@
1
+ # This is an empty __init__.py file to make the directory a package.
@@ -1,19 +1,19 @@
1
- from types import NoneType
2
1
  from typing_extensions import Dict, Optional, Union
3
2
  from ...datasets import PhysicalObject, Robot
3
+ from types import NoneType
4
4
 
5
5
 
6
6
  def conditions_226969243620390858682731042391766665817(case) -> bool:
7
- def conditions_for_physical_object_is_a_robot(self_: PhysicalObject, output_: bool) -> bool:
8
- """Get conditions on whether it's possible to conclude a value for PhysicalObject_is_a_robot.output_ of type ."""
9
- return True
10
- return conditions_for_physical_object_is_a_robot(**case)
7
+ def conditions_for_physical_object_is_a_robot(self_: PhysicalObject, output_: bool) -> bool:
8
+ """Get conditions on whether it's possible to conclude a value for PhysicalObject_is_a_robot.output_ of type ."""
9
+ return True
10
+ return conditions_for_physical_object_is_a_robot(**case)
11
11
 
12
12
 
13
13
  def conclusion_226969243620390858682731042391766665817(case) -> bool:
14
- def physical_object_is_a_robot(self_: PhysicalObject, output_: bool) -> bool:
15
- """Get possible value(s) for PhysicalObject_is_a_robot.output_ of type ."""
16
- return isinstance(self_, Robot)
17
- return physical_object_is_a_robot(**case)
14
+ def physical_object_is_a_robot(self_: PhysicalObject, output_: bool) -> bool:
15
+ """Get possible value(s) for PhysicalObject_is_a_robot.output_ of type ."""
16
+ return isinstance(self_, Robot)
17
+ return physical_object_is_a_robot(**case)
18
18
 
19
19
 
@@ -0,0 +1,19 @@
1
+ from ...datasets import PhysicalObject, Robot
2
+ from typing_extensions import Dict, List, Set, Union
3
+
4
+
5
+ def conditions_164855806603893754507167918997373216146(case) -> bool:
6
+ def conditions_for_physical_object_select_objects_that_are_parts_of_robot(self_: PhysicalObject, objects: List[PhysicalObject], robot: Robot, output_: PhysicalObject) -> bool:
7
+ """Get conditions on whether it's possible to conclude a value for PhysicalObject_select_objects_that_are_parts_of_robot.output_ of type PhysicalObject."""
8
+ return robot is not None
9
+ return conditions_for_physical_object_select_objects_that_are_parts_of_robot(**case)
10
+
11
+
12
+ def conclusion_164855806603893754507167918997373216146(case) -> List[PhysicalObject]:
13
+ def physical_object_select_objects_that_are_parts_of_robot(self_: PhysicalObject, objects: List[PhysicalObject], robot: Robot, output_: PhysicalObject) -> List[PhysicalObject]:
14
+ """Get possible value(s) for PhysicalObject_select_objects_that_are_parts_of_robot.output_ of type PhysicalObject."""
15
+ robot_parts = [obj for obj in objects if obj in robot.parts]
16
+ return robot_parts
17
+ return physical_object_select_objects_that_are_parts_of_robot(**case)
18
+
19
+
@@ -1,56 +0,0 @@
1
- {
2
- "_type": "ripple_down_rules.rdr.GeneralRDR",
3
- "start_rules": {
4
- "output_": {
5
- "_type": "ripple_down_rules.rdr.SingleClassRDR",
6
- "start_rule": {
7
- "_type": "ripple_down_rules.rules.SingleClassRule",
8
- "conditions": {
9
- "_type": "ripple_down_rules.datastructures.callable_expression.CallableExpression",
10
- "user_input": "def _get_value(case):\n def conditions_for_physical_object_is_a_robot(self_: PhysicalObject, output_: bool) -> bool:\n \"\"\"Get conditions on whether it's possible to conclude a value for PhysicalObject_is_a_robot.output_ of type .\"\"\"\n return True\n return conditions_for_physical_object_is_a_robot(**case)\n ",
11
- "conclusion_type": [
12
- "builtins.bool"
13
- ],
14
- "scope": {
15
- "PhysicalObject": "test.datasets.PhysicalObject"
16
- },
17
- "conclusion": {
18
- "_type": "builtins.NoneType",
19
- "value": null
20
- },
21
- "mutually_exclusive": true
22
- },
23
- "conclusion": {
24
- "_type": "ripple_down_rules.datastructures.callable_expression.CallableExpression",
25
- "user_input": "def _get_value(case):\n def physical_object_is_a_robot(self_: PhysicalObject, output_: bool) -> bool:\n \"\"\"Get possible value(s) for PhysicalObject_is_a_robot.output_ of type .\"\"\"\n return isinstance(self_, Robot)\n return physical_object_is_a_robot(**case)\n ",
26
- "conclusion_type": [
27
- "builtins.bool"
28
- ],
29
- "scope": {
30
- "Robot": "test.datasets.Robot",
31
- "PhysicalObject": "test.datasets.PhysicalObject"
32
- },
33
- "conclusion": {
34
- "_type": "builtins.NoneType",
35
- "value": null
36
- },
37
- "mutually_exclusive": true
38
- },
39
- "parent": null,
40
- "conclusion_name": "output_",
41
- "weight": "",
42
- "uid": "226969243620390858682731042391766665817",
43
- "refinement": null,
44
- "alternative": null
45
- },
46
- "generated_python_file_name": "physical_object_is_a_robot_output__scrdr",
47
- "name": "output_",
48
- "case_type": "typing.Dict",
49
- "case_name": "PhysicalObject_is_a_robot"
50
- }
51
- },
52
- "generated_python_file_name": "physical_object_is_a_robot_rdr",
53
- "name": "output_",
54
- "case_type": "typing.Dict",
55
- "case_name": "PhysicalObject_is_a_robot"
56
- }
@@ -1,19 +0,0 @@
1
- from typing_extensions import Dict, List, Set, Union
2
- from ...datasets import PhysicalObject, Robot
3
-
4
-
5
- def conditions_164855806603893754507167918997373216146(case) -> bool:
6
- def conditions_for_physical_object_select_objects_that_are_parts_of_robot(self_: PhysicalObject, objects: List[PhysicalObject], robot: Robot, output_: PhysicalObject) -> bool:
7
- """Get conditions on whether it's possible to conclude a value for PhysicalObject_select_objects_that_are_parts_of_robot.output_ of type PhysicalObject."""
8
- return robot is not None
9
- return conditions_for_physical_object_select_objects_that_are_parts_of_robot(**case)
10
-
11
-
12
- def conclusion_164855806603893754507167918997373216146(case) -> List[PhysicalObject]:
13
- def physical_object_select_objects_that_are_parts_of_robot(self_: PhysicalObject, objects: List[PhysicalObject], robot: Robot, output_: PhysicalObject) -> List[PhysicalObject]:
14
- """Get possible value(s) for PhysicalObject_select_objects_that_are_parts_of_robot.output_ of type PhysicalObject."""
15
- robot_parts = [obj for obj in objects if obj in robot.parts]
16
- return robot_parts
17
- return physical_object_select_objects_that_are_parts_of_robot(**case)
18
-
19
-
@@ -1,6 +1,6 @@
1
- from types import NoneType
2
- from ripple_down_rules.datastructures.case import Case, create_case
3
1
  from typing_extensions import Optional
2
+ from ripple_down_rules.datastructures.case import Case, create_case
3
+ from types import NoneType
4
4
  from .physical_object_is_a_robot_output__scrdr_defs import *
5
5
 
6
6
 
@@ -1,6 +1,6 @@
1
- from typing_extensions import Any, Dict
2
1
  from ripple_down_rules.datastructures.case import Case, create_case
3
2
  from ripple_down_rules.helpers import general_rdr_classify
3
+ from typing_extensions import Any, Dict
4
4
  from . import physical_object_is_a_robot_output__scrdr as output__classifier
5
5
 
6
6
  name = 'output_'
@@ -1,7 +1,7 @@
1
+ from typing_extensions import Optional, Set
1
2
  from ripple_down_rules.datastructures.case import Case, create_case
2
- from ripple_down_rules.helpers import get_an_updated_case_copy
3
3
  from ripple_down_rules.utils import make_set
4
- from typing_extensions import Optional, Set
4
+ from ripple_down_rules.helpers import get_an_updated_case_copy
5
5
  from .physical_object_select_objects_that_are_parts_of_robot_output__mcrdr_defs import *
6
6
 
7
7
 
@@ -1,6 +1,6 @@
1
- from typing_extensions import Any, Dict
2
1
  from ripple_down_rules.datastructures.case import Case, create_case
3
2
  from ripple_down_rules.helpers import general_rdr_classify
3
+ from typing_extensions import Any, Dict
4
4
  from . import physical_object_select_objects_that_are_parts_of_robot_output__mcrdr as output__classifier
5
5
 
6
6
  name = 'output_'