ripple-down-rules 0.6.49__tar.gz → 0.6.51__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.
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/PKG-INFO +1 -1
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/intro.md +1 -1
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/relational_example_tutorial.md +2 -2
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/relational_example_with_decorator_tutorial.md +5 -3
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/__init__.py +1 -1
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/callable_expression.py +6 -3
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/rdr_decorators.py +97 -81
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/PKG-INFO +1 -1
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr_decorators.py +0 -2
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr_helpers_rdrs.py +1 -2
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.github/workflows/build_and_deploy_doc.yml +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.github/workflows/ci.yml +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.github/workflows/publish-to-test-pypi.yml +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.gitignore +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/LICENSE +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/README.md +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/_config.yml +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/_toc.yml +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/bibliography.md +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/propositional_example_tutorial.md +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/references.bib +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/requirements.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/test_driven_rdr_fitting_tutorial.md +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/animal_species.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/decorator_example.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/decorator_model.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/relational_example.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/relational_model.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/examples/test_relational_example.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/images/scrdr.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/images/scrdr.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/images/thinking_pr2.jpg +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/pyproject.toml +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/pytest.ini +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/requirements-dev-ci.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/requirements-dev.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/requirements-gui.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/requirements-viz.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/requirements.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_extra.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_stop_only.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_stop_only.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_stop_plus_rule.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_scrdr.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_scrdr.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_scrdr_2.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_scrdr_2.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_scrdr_3.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_scrdr_3.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/grdr_Habitat.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/grdr_Habitat.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/grdr_Species.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/grdr_Species.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_extra.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_extra_classify.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_extra_classify.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_stop_plus_rule_combined.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/partial_mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/partial_mcrdr_extra.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/relational_scrdr_classify.dot +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/relational_scrdr_classify.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/scripts/live_dot_server_client.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/setup.cfg +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/case.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/enums.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/experts.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/failures.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/helpers.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/rdr.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/rules.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/start-code-server.sh +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/gui.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/prompt.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/template_file_creator.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/utils.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/SOURCES.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/requires.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/conf/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/conf/world/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/conf/world/base_config.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/conf/world/handles_and_containers.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/conftest.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/datasets.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/factories/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/factories/world/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/factories/world/handles_and_containers.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/drawer_cabinet_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/grdr_expert_answers_fit.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_expert_answers_fit.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_generated_rdrs/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_helpers/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_helpers/helpers.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_helpers/object_diagram_case_query.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_helpers/object_diagram_person.png +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_json_serialization.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_object_diagram.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_on_mutagenic.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr_world/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr_world/conftest.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_rdr_world/test_rdr_world.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_relational_rdr.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_relational_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_results/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_results/datasets_physical_object_is_a_robot/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/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
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/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
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/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
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_sql_model.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_template_file_creator.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/__init__.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_ipython.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_ipython_copilot.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_prompt.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_qt_gui_inline.py +0 -0
- {ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/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.
|
3
|
+
Version: 0.6.51
|
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
|
-
## 🚀
|
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
|
118
|
-
|
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"
|
@@ -130,8 +130,10 @@ class CallableExpression(SubclassJSONSerializer):
|
|
130
130
|
conclusion_type = (conclusion_type,)
|
131
131
|
self.conclusion_type = conclusion_type
|
132
132
|
self.expected_types: Set[Type] = set(conclusion_type) if conclusion_type is not None else set()
|
133
|
-
if
|
134
|
-
self.expected_types.
|
133
|
+
if list in self.expected_types:
|
134
|
+
self.expected_types.remove(list)
|
135
|
+
if set in self.expected_types:
|
136
|
+
self.expected_types.add(set)
|
135
137
|
self.scope: Optional[Dict[str, Any]] = scope if scope is not None else {}
|
136
138
|
self.scope = get_used_scope(self.user_input, self.scope)
|
137
139
|
self.expression_tree: AST = expression_tree if expression_tree else parse_string_to_expression(self.user_input)
|
@@ -149,6 +151,8 @@ class CallableExpression(SubclassJSONSerializer):
|
|
149
151
|
|
150
152
|
def __call__(self, case: Any, **kwargs) -> Any:
|
151
153
|
try:
|
154
|
+
# if not self.mutually_exclusive:
|
155
|
+
# self.expected_types.update({list, set})
|
152
156
|
if self.user_input is not None:
|
153
157
|
if not isinstance(case, Case):
|
154
158
|
case = create_case(case, max_recursion_idx=3)
|
@@ -160,7 +164,6 @@ class CallableExpression(SubclassJSONSerializer):
|
|
160
164
|
if self.mutually_exclusive and issubclass(type(output), (list, set)):
|
161
165
|
raise ValueError(f"Mutually exclusive types cannot be lists or sets, got {type(output)}")
|
162
166
|
output_types = {type(o) for o in make_list(output)}
|
163
|
-
output_types.add(type(output))
|
164
167
|
if not are_results_subclass_of_types(output_types, self.expected_types):
|
165
168
|
raise ValueError(f"Not all result types {output_types} are subclasses of expected types"
|
166
169
|
f" {self.conclusion_type}")
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/rdr_decorators.py
RENAMED
@@ -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
|
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,91 @@ 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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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 is through refinement rules which happens automatically by the rdr prompting for refinements.
|
106
|
+
"""
|
107
|
+
_not_none_output_found: bool = field(init=False, default=False)
|
108
|
+
"""
|
109
|
+
This is a flag that indicates that a not None output for the rdr has been inferred, this is used to update the
|
110
|
+
generated dot file if it is set to `True`.
|
111
|
+
"""
|
83
112
|
|
84
113
|
def decorator(self, func: Callable) -> Callable:
|
85
114
|
|
@@ -102,33 +131,33 @@ class RDRDecorator:
|
|
102
131
|
if len(self.parsed_output_type) == 0:
|
103
132
|
self.parsed_output_type = self.parse_output_type(func, self.output_type, *args)
|
104
133
|
if self.expert is None:
|
105
|
-
self.expert = Human(answers_save_path=self.
|
134
|
+
self.expert = Human(answers_save_path=self.models_dir + f'/{self.model_name}/expert_answers')
|
106
135
|
case_query = self.create_case_query_from_method(func, func_output,
|
107
136
|
self.parsed_output_type,
|
108
137
|
self.mutual_exclusive,
|
109
138
|
case, case_dict,
|
110
139
|
*args, **kwargs)
|
111
140
|
output = self.rdr.fit_case(case_query, expert=self.expert,
|
112
|
-
update_existing_rules=self.update_existing_rules
|
113
|
-
viewer=self.viewer)
|
141
|
+
update_existing_rules=self.update_existing_rules)
|
114
142
|
return output
|
115
|
-
|
143
|
+
|
116
144
|
if self.fit and not self.use_generated_classifier and self.ask_now(case_dict):
|
117
145
|
output = fit()
|
118
146
|
else:
|
119
147
|
if self.use_generated_classifier:
|
120
148
|
if self.generated_classifier is None:
|
121
|
-
model_path = os.path.join(self.
|
149
|
+
model_path = os.path.join(self.models_dir, self.model_name)
|
122
150
|
self.generated_classifier = self.rdr.get_rdr_classifier_from_python_file(model_path)
|
123
151
|
output = self.generated_classifier(case)
|
124
152
|
else:
|
125
153
|
output = self.rdr.classify(case)
|
126
154
|
if self.generate_dot_file:
|
127
155
|
eval_rule_tree = self.rdr.get_evaluated_rule_tree()
|
128
|
-
if not self.
|
129
|
-
self.rdr.render_evaluated_rule_tree(self.
|
156
|
+
if not self._not_none_output_found or (eval_rule_tree and len(eval_rule_tree) > 1):
|
157
|
+
self.rdr.render_evaluated_rule_tree(self.models_dir + f'/{self.model_name}',
|
158
|
+
show_full_tree=True)
|
130
159
|
if eval_rule_tree and len(eval_rule_tree) > 1:
|
131
|
-
self.
|
160
|
+
self._not_none_output_found = True
|
132
161
|
|
133
162
|
if self.output_name in output:
|
134
163
|
if self.origin_type == list:
|
@@ -189,7 +218,6 @@ class RDRDecorator:
|
|
189
218
|
return Case(dict, id(case_dict), case_name, case_dict, **case_dict), case_dict
|
190
219
|
|
191
220
|
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
221
|
model_file_name = get_func_rdr_model_name(func, include_file_name=True)
|
194
222
|
self.model_name = str_to_snake_case(model_file_name)
|
195
223
|
self.load()
|
@@ -209,20 +237,8 @@ class RDRDecorator:
|
|
209
237
|
parsed_output_type.append(ot)
|
210
238
|
return parsed_output_type
|
211
239
|
|
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
240
|
def load(self):
|
219
241
|
"""
|
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.
|
242
|
+
Load the RDR model from the specified directory, otherwise create a new one.
|
227
243
|
"""
|
228
|
-
self.rdr
|
244
|
+
self.rdr = GeneralRDR(save_dir=self.models_dir, model_name=self.model_name)
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.51
|
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
|
@@ -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
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.github/workflows/build_and_deploy_doc.yml
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/.github/workflows/publish-to-test-pypi.yml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/doc/test_driven_rdr_fitting_tutorial.md
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_stop_plus_rule.dot
RENAMED
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/complete_mcrdr_stop_plus_rule.png
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_stop_plus_rule_combined.dot
RENAMED
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/results/mcrdr_stop_plus_rule_combined.png
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/case.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/datastructures/enums.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/start-code-server.sh
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/gui.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules/user_interface/prompt.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/requires.txt
RENAMED
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/src/ripple_down_rules.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/conf/world/handles_and_containers.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/factories/world/handles_and_containers.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_helpers/object_diagram_person.png
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_ipython.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_prompt.py
RENAMED
File without changes
|
{ripple_down_rules-0.6.49 → ripple_down_rules-0.6.51}/test/test_user_interface/test_qt_gui_inline.py
RENAMED
File without changes
|
File without changes
|