ripple-down-rules 0.1.62__py3-none-any.whl → 0.1.64__py3-none-any.whl
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/datastructures/case.py +2 -2
- ripple_down_rules/experts.py +1 -1
- ripple_down_rules/rdr.py +18 -14
- ripple_down_rules/rules.py +1 -1
- {ripple_down_rules-0.1.62.dist-info → ripple_down_rules-0.1.64.dist-info}/METADATA +1 -1
- {ripple_down_rules-0.1.62.dist-info → ripple_down_rules-0.1.64.dist-info}/RECORD +9 -9
- {ripple_down_rules-0.1.62.dist-info → ripple_down_rules-0.1.64.dist-info}/WHEEL +1 -1
- {ripple_down_rules-0.1.62.dist-info → ripple_down_rules-0.1.64.dist-info}/licenses/LICENSE +0 -0
- {ripple_down_rules-0.1.62.dist-info → ripple_down_rules-0.1.64.dist-info}/top_level.txt +0 -0
@@ -307,7 +307,7 @@ def show_current_and_corner_cases(case: Any, targets: Optional[Dict[str, Any]] =
|
|
307
307
|
"""
|
308
308
|
corner_case = None
|
309
309
|
targets = {f"target_{name}": value for name, value in targets.items()} if targets else {}
|
310
|
-
current_conclusions = {name: value for name, value in current_conclusions.items} if current_conclusions else {}
|
310
|
+
current_conclusions = {name: value for name, value in current_conclusions.items()} if current_conclusions else {}
|
311
311
|
if last_evaluated_rule:
|
312
312
|
action = "Refinement" if last_evaluated_rule.fired else "Alternative"
|
313
313
|
print(f"{action} needed for rule: {last_evaluated_rule}\n")
|
@@ -324,7 +324,7 @@ def show_current_and_corner_cases(case: Any, targets: Optional[Dict[str, Any]] =
|
|
324
324
|
corner_row_dict = corner_case
|
325
325
|
|
326
326
|
if corner_row_dict:
|
327
|
-
corner_conclusion = last_evaluated_rule.conclusion
|
327
|
+
corner_conclusion = last_evaluated_rule.conclusion(case)
|
328
328
|
corner_row_dict.update({corner_conclusion.__class__.__name__: corner_conclusion})
|
329
329
|
print(table_rows_as_str(corner_row_dict))
|
330
330
|
print("=" * 50)
|
ripple_down_rules/experts.py
CHANGED
@@ -122,7 +122,7 @@ class Human(Expert):
|
|
122
122
|
last_evaluated_rule: Optional[Rule] = None) \
|
123
123
|
-> CallableExpression:
|
124
124
|
if not self.use_loaded_answers:
|
125
|
-
show_current_and_corner_cases(case_query.case, {case_query.attribute_name: case_query.
|
125
|
+
show_current_and_corner_cases(case_query.case, {case_query.attribute_name: case_query.target_value},
|
126
126
|
last_evaluated_rule=last_evaluated_rule)
|
127
127
|
return self._get_conditions(case_query)
|
128
128
|
|
ripple_down_rules/rdr.py
CHANGED
@@ -217,13 +217,16 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
|
|
217
217
|
for rule in [self.start_rule] + list(self.start_rule.descendants):
|
218
218
|
if not rule.conditions:
|
219
219
|
continue
|
220
|
-
|
221
|
-
|
222
|
-
for k, v in rule.conditions.scope.items():
|
223
|
-
new_imports = f"from {v.__module__} import {v.__name__}\n"
|
224
|
-
if new_imports in imports:
|
220
|
+
for scope in [rule.conditions.scope, rule.conclusion.scope]:
|
221
|
+
if scope is None:
|
225
222
|
continue
|
226
|
-
|
223
|
+
for k, v in scope.items():
|
224
|
+
if not hasattr(v, "__module__") or not hasattr(v, "__name__"):
|
225
|
+
continue
|
226
|
+
new_imports = f"from {v.__module__} import {v.__name__}\n"
|
227
|
+
if new_imports in imports:
|
228
|
+
continue
|
229
|
+
imports += new_imports
|
227
230
|
return imports
|
228
231
|
|
229
232
|
def get_rdr_classifier_from_python_file(self, package_name: str) -> Callable[[Any], Any]:
|
@@ -722,7 +725,7 @@ class GeneralRDR(RippleDownRules):
|
|
722
725
|
def start_rules(self) -> List[Union[SingleClassRule, MultiClassTopRule]]:
|
723
726
|
return [rdr.start_rule for rdr in self.start_rules_dict.values()]
|
724
727
|
|
725
|
-
def classify(self, case:
|
728
|
+
def classify(self, case: Any) -> Optional[Dict[str, Any]]:
|
726
729
|
"""
|
727
730
|
Classify a case by going through all RDRs and adding the categories that are classified, and then restarting
|
728
731
|
the classification until no more categories can be added.
|
@@ -734,7 +737,7 @@ class GeneralRDR(RippleDownRules):
|
|
734
737
|
|
735
738
|
@staticmethod
|
736
739
|
def _classify(classifiers_dict: Dict[str, Union[ModuleType, RippleDownRules]],
|
737
|
-
case:
|
740
|
+
case: Any) -> Dict[str, Any]:
|
738
741
|
"""
|
739
742
|
Classify a case by going through all classifiers and adding the categories that are classified,
|
740
743
|
and then restarting the classification until no more categories can be added.
|
@@ -775,7 +778,7 @@ class GeneralRDR(RippleDownRules):
|
|
775
778
|
return conclusions
|
776
779
|
|
777
780
|
def fit_case(self, case_queries: List[CaseQuery], expert: Optional[Expert] = None, **kwargs) \
|
778
|
-
->
|
781
|
+
-> Dict[str, Any]:
|
779
782
|
"""
|
780
783
|
Fit the GRDR on a case, if the target is a new type of category, a new RDR is created for it,
|
781
784
|
else the existing RDR of that type will be fitted on the case, and then classification is done and all
|
@@ -790,7 +793,7 @@ class GeneralRDR(RippleDownRules):
|
|
790
793
|
:return: The categories that the case belongs to.
|
791
794
|
"""
|
792
795
|
expert = expert if expert else Human()
|
793
|
-
case_queries =
|
796
|
+
case_queries = make_list(case_queries)
|
794
797
|
assert len(case_queries) > 0, "No case queries provided"
|
795
798
|
case = case_queries[0].case
|
796
799
|
assert all([case is case_query.case for case_query in case_queries]), ("fit_case requires only one case,"
|
@@ -823,10 +826,11 @@ class GeneralRDR(RippleDownRules):
|
|
823
826
|
else:
|
824
827
|
conclusions = self.start_rules_dict[rdr_attribute_name].fit_case(case_query_cp, expert,
|
825
828
|
**kwargs)
|
826
|
-
if conclusions is not None
|
827
|
-
conclusions
|
828
|
-
|
829
|
-
|
829
|
+
if conclusions is not None:
|
830
|
+
if (not is_iterable(conclusions)) or len(conclusions) > 0:
|
831
|
+
conclusions = {rdr_attribute_name: conclusions}
|
832
|
+
case_query_cp.mutually_exclusive = True if isinstance(rdr, SingleClassRDR) else False
|
833
|
+
self.update_case(case_query_cp, conclusions)
|
830
834
|
case_query.conditions = case_query_cp.conditions
|
831
835
|
|
832
836
|
return self.classify(case)
|
ripple_down_rules/rules.py
CHANGED
@@ -288,7 +288,7 @@ class MultiClassStopRule(Rule, HasAlternativeRule):
|
|
288
288
|
|
289
289
|
def __init__(self, *args, **kwargs):
|
290
290
|
super(MultiClassStopRule, self).__init__(*args, **kwargs)
|
291
|
-
self.conclusion = Stop.stop
|
291
|
+
self.conclusion = CallableExpression(conclusion_type=(Stop,), conclusion=Stop.stop)
|
292
292
|
|
293
293
|
def evaluate_next_rule(self, x: Case) -> Optional[Union[MultiClassStopRule, MultiClassTopRule]]:
|
294
294
|
if self.fired:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.64
|
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
|
@@ -1,20 +1,20 @@
|
|
1
1
|
ripple_down_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
ripple_down_rules/datasets.py,sha256=rCSpeFeu1gTuKESwjHUdQkPPvomI5OMRNGpbdKmHwMg,4639
|
3
|
-
ripple_down_rules/experts.py,sha256=
|
3
|
+
ripple_down_rules/experts.py,sha256=TretkdR1IY2RjcSh4WJUFJtYEbItsand7SYFmzouE_Y,10348
|
4
4
|
ripple_down_rules/failures.py,sha256=E6ajDUsw3Blom8eVLbA7d_Qnov2conhtZ0UmpQ9ZtSE,302
|
5
5
|
ripple_down_rules/helpers.py,sha256=TvTJU0BA3dPcAyzvZFvAu7jZqsp8Lu0HAAwvuizlGjg,2018
|
6
6
|
ripple_down_rules/prompt.py,sha256=cHqhMJqubGhfGpOOY_uXv5L7PBNb64O0IBWSfiY0ui0,6682
|
7
|
-
ripple_down_rules/rdr.py,sha256=
|
7
|
+
ripple_down_rules/rdr.py,sha256=tJDbPF3D2qJ5cw2WPmZrs_C2Jj6b7cCxEJDp2SK9GCI,47863
|
8
8
|
ripple_down_rules/rdr_decorators.py,sha256=8SclpceI3EtrsbuukWJu8HGLh7Q1ZCgYGLX-RPlG-w0,2018
|
9
|
-
ripple_down_rules/rules.py,sha256=
|
9
|
+
ripple_down_rules/rules.py,sha256=4oQSb4p36A-YzW0hJ8HH2FhmIvokjXKK1rIXEn-8WcE,16203
|
10
10
|
ripple_down_rules/utils.py,sha256=JIF99Knqzqjgny7unvEnib3sCmExqU-w9xYOSGIT86Q,32276
|
11
11
|
ripple_down_rules/datastructures/__init__.py,sha256=V2aNgf5C96Y5-IGghra3n9uiefpoIm_QdT7cc_C8cxQ,111
|
12
12
|
ripple_down_rules/datastructures/callable_expression.py,sha256=TW_u6CJfelW2CiJj9pWFpdOBNIxeEuhhsQEz_pLpFVE,9092
|
13
|
-
ripple_down_rules/datastructures/case.py,sha256=
|
13
|
+
ripple_down_rules/datastructures/case.py,sha256=uM5YkJOfYfARrZZ3oAxKMWE5QBSnvHLLZa9Atoxb7eY,13800
|
14
14
|
ripple_down_rules/datastructures/dataclasses.py,sha256=_aabVXsgdVUeAmgGA9K_LZpO2U5a6-htrg2Tka7qc30,5960
|
15
15
|
ripple_down_rules/datastructures/enums.py,sha256=RdyPUp9Ls1QuLmkcMMkBbCWrmXIZI4xWuM-cLPYZhR0,4666
|
16
|
-
ripple_down_rules-0.1.
|
17
|
-
ripple_down_rules-0.1.
|
18
|
-
ripple_down_rules-0.1.
|
19
|
-
ripple_down_rules-0.1.
|
20
|
-
ripple_down_rules-0.1.
|
16
|
+
ripple_down_rules-0.1.64.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
17
|
+
ripple_down_rules-0.1.64.dist-info/METADATA,sha256=PChgWG-I8g-_yaKMDwrxJPuIHOe0fIrThGu_vOqrQkE,42576
|
18
|
+
ripple_down_rules-0.1.64.dist-info/WHEEL,sha256=ooBFpIzZCPdw3uqIQsOo4qqbA4ZRPxHnOH7peeONza0,91
|
19
|
+
ripple_down_rules-0.1.64.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
|
20
|
+
ripple_down_rules-0.1.64.dist-info/RECORD,,
|
File without changes
|
File without changes
|