ripple-down-rules 0.5.4__tar.gz → 0.5.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/PKG-INFO +15 -2
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/README.md +13 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/intro.md +46 -21
- ripple_down_rules-0.5.5/images/scrdr.dot +127 -0
- ripple_down_rules-0.5.5/images/scrdr.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements.txt +1 -1
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/__init__.py +1 -1
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/template_file_creator.py +1 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/utils.py +2 -2
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/PKG-INFO +15 -2
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/SOURCES.txt +2 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/requires.txt +1 -1
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/build_and_deploy_doc.yml +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/ci.yml +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/publish-to-test-pypi.yml +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]/shelved.patch +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.idea/shelf/Uncommitted_changes_before_Checkout_at_2_4_25,_6_32_PM_[Changes]1/shelved.patch +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/LICENSE +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/_config.yml +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/_toc.yml +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/bibliography.md +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/references.bib +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/doc/requirements.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/animal_species.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_contained_objects_mcrdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_rdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/relational_example.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/images/thinking_pr2.jpg +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/pyproject.toml +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/pytest.ini +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-dev-ci.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-dev.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-gui.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/requirements-viz.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_extra.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_only.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_only.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_plus_rule.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_plus_rule.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_2.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_2.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_3.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_scrdr_3.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Habitat.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Habitat.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Species.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/grdr_Species.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra_classify.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_extra_classify.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_stop_plus_rule_combined.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_stop_plus_rule_combined.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/partial_mcrdr_extra.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/partial_mcrdr_extra.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/relational_scrdr_classify.dot +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/relational_scrdr_classify.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/setup.cfg +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/case.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/enums.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/experts.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/helpers.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/rdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/rdr_decorators.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/rules.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/start-code-server.sh +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/gui.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/ipython_custom_shell.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/object_diagram.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/prompt.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/datasets.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/correct_drawer_rdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_fit_extra.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/grdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_expert_answers_stop_only_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_extra_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_extra_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_multi_line_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_only_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_plus_rule_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_plus_rule_combined_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mcrdr_stop_plus_rule_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/mutagenic_expert_answers.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/relational_scrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_expert_answers_classify.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_expert_answers_fit_no_targets.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_multi_line_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/scrdr_world_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_expert_answers/view_rdr_expert_answers_fit.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_generated_rdrs/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/helpers.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/object_diagram_case_query.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/object_diagram_person.png +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_json_serialization.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_object_diagram.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_on_mutagenic.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr_decorators.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_rdr_world.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_relational_rdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_relational_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_output__scrdr_defs.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/physical_object_is_a_robot_rdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_is_a_robot/rdr_metadata/datasets_physical_object_is_a_robot.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_output__mcrdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_output__mcrdr_defs.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/physical_object_select_objects_that_are_parts_of_robot_rdr.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_results/datasets_physical_object_select_objects_that_are_parts_of_robot/rdr_metadata/datasets_physical_object_select_objects_that_are_parts_of_robot.json +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_sql_model.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_template_file_creator.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/__init__.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_ipython.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_ipython_copilot.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_qt_gui_inline.py +0 -0
- {ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.5
|
4
4
|
Summary: Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning.
|
5
5
|
Author-email: Abdelrhman Bassiouny <abassiou@uni-bremen.de>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -693,7 +693,7 @@ Requires-Dist: colorama
|
|
693
693
|
Requires-Dist: pygments
|
694
694
|
Requires-Dist: sqlalchemy
|
695
695
|
Requires-Dist: pandas
|
696
|
-
Requires-Dist: pyparsing
|
696
|
+
Requires-Dist: pyparsing>=3.2.3
|
697
697
|
Provides-Extra: viz
|
698
698
|
Requires-Dist: networkx>=3.1; extra == "viz"
|
699
699
|
Requires-Dist: matplotlib>=3.7.5; extra == "viz"
|
@@ -799,6 +799,19 @@ cat = grdr.classify(all_cases[50])['species']
|
|
799
799
|
assert cat == targets[50]
|
800
800
|
```
|
801
801
|
|
802
|
+
When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
|
803
|
+
```python
|
804
|
+
return case.milk == 1
|
805
|
+
```
|
806
|
+
then
|
807
|
+
```python
|
808
|
+
return case.aquatic == 1
|
809
|
+
```
|
810
|
+
|
811
|
+
The rule tree generated from fitting all the dataset will look like this:
|
812
|
+

|
813
|
+
|
814
|
+
|
802
815
|
### Relational Example
|
803
816
|
|
804
817
|
By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
|
@@ -95,6 +95,19 @@ cat = grdr.classify(all_cases[50])['species']
|
|
95
95
|
assert cat == targets[50]
|
96
96
|
```
|
97
97
|
|
98
|
+
When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
|
99
|
+
```python
|
100
|
+
return case.milk == 1
|
101
|
+
```
|
102
|
+
then
|
103
|
+
```python
|
104
|
+
return case.aquatic == 1
|
105
|
+
```
|
106
|
+
|
107
|
+
The rule tree generated from fitting all the dataset will look like this:
|
108
|
+

|
109
|
+
|
110
|
+
|
98
111
|
### Relational Example
|
99
112
|
|
100
113
|
By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
|
@@ -13,27 +13,39 @@ SCRDR, MCRDR, and GRDR logic were inspired from the book:
|
|
13
13
|
["Ripple Down Rules: An Alternative to Machine Learning"](https://www.taylorfrancis.com/books/mono/10.1201/9781003126157/ripple-rules-paul-compton-byeong-ho-kang) by Paul Compton, Byeong Ho Kang.
|
14
14
|
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
-
|
29
|
-
|
30
|
-
|
31
|
-
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
-
|
36
|
-
|
16
|
+
## 🚀 Enhanced Ripple-Down Rules Engine – Key Features
|
17
|
+
|
18
|
+
### 🧠 Ontology + Rule Base as One Entity
|
19
|
+
- 🧬 Unified data structure: Ontology and rules use the same Python data structures.
|
20
|
+
- 🔄 Automatic sync: Updates to the ontology instantly reflect in the rule base.
|
21
|
+
- 📦 Version controlled: The rule base is a Python module, versioned with your project.
|
22
|
+
|
23
|
+
### 🔁 Supports First, Second & Higher-Order Logic
|
24
|
+
- 🧩 Unlimited expressiveness: Rule conditions and conclusions are plain Python functions — anything Python can do, your rules can too!
|
25
|
+
|
26
|
+
### 🛡️ Automatic Rule Base Maintenance
|
27
|
+
- ⚠️ Contradiction detection: New rules are auto-checked for logical conflicts.
|
28
|
+
- 🔧 Prompted refinements: If a contradiction arises, you're guided to add a refinement rule.
|
29
|
+
|
30
|
+
### 📝 Transparent & Editable Rule Base
|
31
|
+
- 📖 Readable rules: Rules are clean, understandable Python code.
|
32
|
+
- 🔄 Reload-friendly: Easily edit and reload rules manually as needed.
|
33
|
+
|
34
|
+
### 💻 Developer-Centric Interface
|
35
|
+
- 👨💻 Feels like home: Seamless integration with your favorite IDE.
|
36
|
+
- ✨ Modern coding experience: Auto-completion and suggestions supported via IDE plugins.
|
37
|
+
|
38
|
+
### 🤖 LLM-Powered Rule Writing
|
39
|
+
- 💡 AI-assisted authoring: Ask AI for help or suggestions directly within the IDE.
|
40
|
+
- ⚡ Smart completion: Context-aware completions streamline rule writing.
|
41
|
+
|
42
|
+
### 🎯 Flexible Rule Specificity
|
43
|
+
- 🧪 Instance-level precision: Write rules for highly specific object scenarios.
|
44
|
+
- 🏛️ Generalization-ready: Create broad rules for superclass relationships.
|
45
|
+
|
46
|
+
### 🖼️ GUI for Rule Exploration
|
47
|
+
- 🧭 Object Explorer Panel: Navigate and inspect objects easily.
|
48
|
+
- 🧯 Interactive Diagram: Expandable/collapsible object diagram to guide rule creation visually.
|
37
49
|
|
38
50
|
This work aims to provide a flexible and powerful rule-based system that can be used in various applications,
|
39
51
|
from simple classification tasks to complex decision-making systems. Furthermore, one of the main goals is to
|
@@ -186,6 +198,19 @@ cat = grdr.classify(all_cases[50])['species']
|
|
186
198
|
assert cat == targets[50]
|
187
199
|
```
|
188
200
|
|
201
|
+
When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
|
202
|
+
```python
|
203
|
+
return case.milk == 1
|
204
|
+
```
|
205
|
+
then
|
206
|
+
```python
|
207
|
+
return case.aquatic == 1
|
208
|
+
```
|
209
|
+
|
210
|
+
The rule tree generated from fitting all the dataset will look like this:
|
211
|
+

|
212
|
+
|
213
|
+
|
189
214
|
### Relational Example
|
190
215
|
|
191
216
|
By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
|
@@ -0,0 +1,127 @@
|
|
1
|
+
digraph tree {
|
2
|
+
"def _get_value(case):
|
3
|
+
return case.milk == 1
|
4
|
+
=> def _get_value(case):
|
5
|
+
return Species.mammal";
|
6
|
+
"def _get_value(case):
|
7
|
+
return case.aquatic == 1
|
8
|
+
=> def _get_value(case):
|
9
|
+
return Species.fish";
|
10
|
+
"def _get_value(case):
|
11
|
+
return case.feathers == 1
|
12
|
+
=> def _get_value(case):
|
13
|
+
return Species.bird";
|
14
|
+
"def _get_value(case):
|
15
|
+
return case.backbone == 0 and case.breathes == 0
|
16
|
+
=> def _get_value(case):
|
17
|
+
return Species.molusc";
|
18
|
+
"def _get_value(case):
|
19
|
+
return case.eggs == 1 and case.backbone == 0
|
20
|
+
=> def _get_value(case):
|
21
|
+
return Species.insect";
|
22
|
+
"def _get_value(case):
|
23
|
+
return case.backbone == 1 and case.tail == 1
|
24
|
+
=> def _get_value(case):
|
25
|
+
return Species.reptile";
|
26
|
+
"def _get_value(case):
|
27
|
+
return case.backbone == 0 and case.eggs == 0
|
28
|
+
=> def _get_value(case):
|
29
|
+
return Species.molusc";
|
30
|
+
"def _get_value(case):
|
31
|
+
return case.legs == 0
|
32
|
+
=> def _get_value(case):
|
33
|
+
return Species.molusc";
|
34
|
+
"def _get_value(case):
|
35
|
+
return case.fins == 0
|
36
|
+
=> def _get_value(case):
|
37
|
+
return Species.molusc";
|
38
|
+
"def _get_value(case):
|
39
|
+
return case.feathers == 1
|
40
|
+
=> def _get_value(case):
|
41
|
+
return Species.bird_1";
|
42
|
+
"def _get_value(case):
|
43
|
+
return case.backbone == 1
|
44
|
+
=> def _get_value(case):
|
45
|
+
return Species.amphibian";
|
46
|
+
"def _get_value(case):
|
47
|
+
return case.breathes == 0
|
48
|
+
=> def _get_value(case):
|
49
|
+
return Species.reptile";
|
50
|
+
"def _get_value(case):
|
51
|
+
return case.milk == 1
|
52
|
+
=> def _get_value(case):
|
53
|
+
return Species.mammal" -> "def _get_value(case):
|
54
|
+
return case.aquatic == 1
|
55
|
+
=> def _get_value(case):
|
56
|
+
return Species.fish" [style="bold", label=" else if"];
|
57
|
+
"def _get_value(case):
|
58
|
+
return case.aquatic == 1
|
59
|
+
=> def _get_value(case):
|
60
|
+
return Species.fish" -> "def _get_value(case):
|
61
|
+
return case.feathers == 1
|
62
|
+
=> def _get_value(case):
|
63
|
+
return Species.bird" [style="bold", label=" else if"];
|
64
|
+
"def _get_value(case):
|
65
|
+
return case.aquatic == 1
|
66
|
+
=> def _get_value(case):
|
67
|
+
return Species.fish" -> "def _get_value(case):
|
68
|
+
return case.fins == 0
|
69
|
+
=> def _get_value(case):
|
70
|
+
return Species.molusc" [style="bold", label=" except if"];
|
71
|
+
"def _get_value(case):
|
72
|
+
return case.feathers == 1
|
73
|
+
=> def _get_value(case):
|
74
|
+
return Species.bird" -> "def _get_value(case):
|
75
|
+
return case.backbone == 0 and case.breathes == 0
|
76
|
+
=> def _get_value(case):
|
77
|
+
return Species.molusc" [style="bold", label=" else if"];
|
78
|
+
"def _get_value(case):
|
79
|
+
return case.backbone == 0 and case.breathes == 0
|
80
|
+
=> def _get_value(case):
|
81
|
+
return Species.molusc" -> "def _get_value(case):
|
82
|
+
return case.eggs == 1 and case.backbone == 0
|
83
|
+
=> def _get_value(case):
|
84
|
+
return Species.insect" [style="bold", label=" else if"];
|
85
|
+
"def _get_value(case):
|
86
|
+
return case.eggs == 1 and case.backbone == 0
|
87
|
+
=> def _get_value(case):
|
88
|
+
return Species.insect" -> "def _get_value(case):
|
89
|
+
return case.backbone == 1 and case.tail == 1
|
90
|
+
=> def _get_value(case):
|
91
|
+
return Species.reptile" [style="bold", label=" else if"];
|
92
|
+
"def _get_value(case):
|
93
|
+
return case.eggs == 1 and case.backbone == 0
|
94
|
+
=> def _get_value(case):
|
95
|
+
return Species.insect" -> "def _get_value(case):
|
96
|
+
return case.legs == 0
|
97
|
+
=> def _get_value(case):
|
98
|
+
return Species.molusc" [style="bold", label=" except if"];
|
99
|
+
"def _get_value(case):
|
100
|
+
return case.backbone == 1 and case.tail == 1
|
101
|
+
=> def _get_value(case):
|
102
|
+
return Species.reptile" -> "def _get_value(case):
|
103
|
+
return case.backbone == 0 and case.eggs == 0
|
104
|
+
=> def _get_value(case):
|
105
|
+
return Species.molusc" [style="bold", label=" else if"];
|
106
|
+
"def _get_value(case):
|
107
|
+
return case.fins == 0
|
108
|
+
=> def _get_value(case):
|
109
|
+
return Species.molusc" -> "def _get_value(case):
|
110
|
+
return case.feathers == 1
|
111
|
+
=> def _get_value(case):
|
112
|
+
return Species.bird_1" [style="bold", label=" except if"];
|
113
|
+
"def _get_value(case):
|
114
|
+
return case.feathers == 1
|
115
|
+
=> def _get_value(case):
|
116
|
+
return Species.bird_1" -> "def _get_value(case):
|
117
|
+
return case.backbone == 1
|
118
|
+
=> def _get_value(case):
|
119
|
+
return Species.amphibian" [style="bold", label=" else if"];
|
120
|
+
"def _get_value(case):
|
121
|
+
return case.backbone == 1
|
122
|
+
=> def _get_value(case):
|
123
|
+
return Species.amphibian" -> "def _get_value(case):
|
124
|
+
return case.breathes == 0
|
125
|
+
=> def _get_value(case):
|
126
|
+
return Species.reptile" [style="bold", label=" except if"];
|
127
|
+
}
|
Binary file
|
@@ -300,6 +300,7 @@ class TemplateFileCreator:
|
|
300
300
|
if isinstance(node, ast.FunctionDef) and node.name == func_name:
|
301
301
|
exec_globals = {}
|
302
302
|
scope = extract_imports(tree=tree)
|
303
|
+
updates.update(scope)
|
303
304
|
exec(source, scope, exec_globals)
|
304
305
|
user_function = exec_globals[func_name]
|
305
306
|
updates[func_name] = user_function
|
@@ -1370,8 +1370,8 @@ def draw_tree(root: Node, fig: Figure):
|
|
1370
1370
|
"""
|
1371
1371
|
Draw the tree using matplotlib and networkx.
|
1372
1372
|
"""
|
1373
|
-
if matplotlib.get_backend().lower() not in ['qt5agg', 'qt4agg', 'qt6agg']:
|
1374
|
-
|
1373
|
+
# if matplotlib.get_backend().lower() not in ['qt5agg', 'qt4agg', 'qt6agg']:
|
1374
|
+
# matplotlib.use("Qt6Agg") # or "Qt6Agg", depending on availability
|
1375
1375
|
|
1376
1376
|
if root is None:
|
1377
1377
|
return
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.5
|
4
4
|
Summary: Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning.
|
5
5
|
Author-email: Abdelrhman Bassiouny <abassiou@uni-bremen.de>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -693,7 +693,7 @@ Requires-Dist: colorama
|
|
693
693
|
Requires-Dist: pygments
|
694
694
|
Requires-Dist: sqlalchemy
|
695
695
|
Requires-Dist: pandas
|
696
|
-
Requires-Dist: pyparsing
|
696
|
+
Requires-Dist: pyparsing>=3.2.3
|
697
697
|
Provides-Extra: viz
|
698
698
|
Requires-Dist: networkx>=3.1; extra == "viz"
|
699
699
|
Requires-Dist: matplotlib>=3.7.5; extra == "viz"
|
@@ -799,6 +799,19 @@ cat = grdr.classify(all_cases[50])['species']
|
|
799
799
|
assert cat == targets[50]
|
800
800
|
```
|
801
801
|
|
802
|
+
When prompted to write a rule, I wrote the following inside the template function that the Ripple Down Rules created:
|
803
|
+
```python
|
804
|
+
return case.milk == 1
|
805
|
+
```
|
806
|
+
then
|
807
|
+
```python
|
808
|
+
return case.aquatic == 1
|
809
|
+
```
|
810
|
+
|
811
|
+
The rule tree generated from fitting all the dataset will look like this:
|
812
|
+

|
813
|
+
|
814
|
+
|
802
815
|
### Relational Example
|
803
816
|
|
804
817
|
By relational, I mean that each rule conclusion is not a constant value, but is related to the case being classified,
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules.egg-info/SOURCES.txt
RENAMED
@@ -26,6 +26,8 @@ examples/part_containment_rdr/robot_contained_objects_mcrdr.py
|
|
26
26
|
examples/part_containment_rdr/robot_contained_objects_mcrdr_defs.py
|
27
27
|
examples/part_containment_rdr/robot_rdr.py
|
28
28
|
examples/part_containment_rdr/rdr_metadata/part_containment_rdr.json
|
29
|
+
images/scrdr.dot
|
30
|
+
images/scrdr.png
|
29
31
|
images/thinking_pr2.jpg
|
30
32
|
results/complete_mcrdr_extra.dot
|
31
33
|
results/complete_mcrdr_extra.png
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.github/workflows/build_and_deploy_doc.yml
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/.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
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/examples/part_containment_rdr/robot_rdr.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
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/results/complete_mcrdr_stop_plus_rule.dot
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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.5.4 → ripple_down_rules-0.5.5}/results/mcrdr_stop_plus_rule_combined.dot
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/__init__.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/datastructures/case.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/start-code-server.sh
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/__init__.py
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/gui.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/src/ripple_down_rules/user_interface/prompt.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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
|
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.5.4 → ripple_down_rules-0.5.5}/test/test_helpers/object_diagram_case_query.png
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/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.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_ipython.py
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_ipython_copilot.py
RENAMED
File without changes
|
{ripple_down_rules-0.5.4 → ripple_down_rules-0.5.5}/test/test_user_interface/test_qt_gui_inline.py
RENAMED
File without changes
|
File without changes
|