ripple-down-rules 0.1.65__tar.gz → 0.1.66__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.1.65 → ripple_down_rules-0.1.66}/PKG-INFO +1 -1
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/pyproject.toml +1 -1
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/rdr.py +13 -13
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/rules.py +25 -25
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/utils.py +4 -5
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules.egg-info/PKG-INFO +1 -1
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/LICENSE +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/README.md +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/setup.cfg +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/__init__.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datasets.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/__init__.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/callable_expression.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/case.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/enums.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/experts.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/failures.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/helpers.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/prompt.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/rdr_decorators.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules.egg-info/SOURCES.txt +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_json_serialization.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_on_mutagenic.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_rdr.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_rdr_world.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_relational_rdr.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_relational_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/test/test_sql_model.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.66
|
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
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
6
6
|
|
7
7
|
[project]
|
8
8
|
name = "ripple_down_rules"
|
9
|
-
version = "0.1.
|
9
|
+
version = "0.1.66"
|
10
10
|
description = "Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning."
|
11
11
|
readme = "README.md"
|
12
12
|
authors = [{ name = "Abdelrhman Bassiouny", email = "abassiou@uni-bremen.de" }]
|
@@ -326,13 +326,10 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
|
|
326
326
|
"""
|
327
327
|
:return: The type of the conclusion of the RDR classifier.
|
328
328
|
"""
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
if isinstance(conclusion, set):
|
334
|
-
return type(list(conclusion)[0]), set
|
335
|
-
return (type(conclusion),)
|
329
|
+
all_types = []
|
330
|
+
for rule in [self.start_rule] + list(self.start_rule.descendants):
|
331
|
+
all_types.extend(list(rule.conclusion.conclusion_type))
|
332
|
+
return tuple(set(all_types))
|
336
333
|
|
337
334
|
@property
|
338
335
|
def attribute_name(self) -> str:
|
@@ -419,7 +416,8 @@ class SingleClassRDR(RDRWithCodeWriter):
|
|
419
416
|
self.write_rules_as_source_code_to_file(rule.refinement, file, parent_indent + " ",
|
420
417
|
defs_file=defs_file)
|
421
418
|
|
422
|
-
|
419
|
+
conclusion_call = rule.write_conclusion_as_source_code(parent_indent, defs_file)
|
420
|
+
file.write(conclusion_call)
|
423
421
|
|
424
422
|
if rule.alternative:
|
425
423
|
self.write_rules_as_source_code_to_file(rule.alternative, file, parent_indent, defs_file=defs_file)
|
@@ -532,18 +530,20 @@ class MultiClassRDR(RDRWithCodeWriter):
|
|
532
530
|
defs_file=defs_file)
|
533
531
|
conclusion_indent = parent_indent + " " * 4
|
534
532
|
file.write(f"{conclusion_indent}else:\n")
|
535
|
-
|
533
|
+
|
534
|
+
conclusion_call = rule.write_conclusion_as_source_code(conclusion_indent, defs_file)
|
535
|
+
file.write(conclusion_call)
|
536
536
|
|
537
537
|
if rule.alternative:
|
538
538
|
self.write_rules_as_source_code_to_file(rule.alternative, file, parent_indent, defs_file=defs_file)
|
539
539
|
|
540
540
|
@property
|
541
541
|
def conclusion_type_hint(self) -> str:
|
542
|
-
return f"Set[{self.conclusion_type[
|
542
|
+
return f"Set[Union[{', '.join([ct.__name__ for ct in self.conclusion_type if ct not in [list, set]])}]]"
|
543
543
|
|
544
544
|
def _get_imports(self) -> str:
|
545
545
|
imports = super()._get_imports()
|
546
|
-
imports += "from typing_extensions import Set\n"
|
546
|
+
imports += "from typing_extensions import Set, Union\n"
|
547
547
|
imports += "from ripple_down_rules.utils import make_set\n"
|
548
548
|
return imports
|
549
549
|
|
@@ -871,7 +871,7 @@ class GeneralRDR(RippleDownRules):
|
|
871
871
|
|
872
872
|
@property
|
873
873
|
def conclusion_type_hint(self) -> str:
|
874
|
-
return f"
|
874
|
+
return f"Dict[str, Any]"
|
875
875
|
|
876
876
|
def _get_imports(self, file_path: str) -> str:
|
877
877
|
"""
|
@@ -882,7 +882,7 @@ class GeneralRDR(RippleDownRules):
|
|
882
882
|
"""
|
883
883
|
imports = ""
|
884
884
|
# add type hints
|
885
|
-
imports += f"from typing_extensions import
|
885
|
+
imports += f"from typing_extensions import Dict, Any, Union, Set\n"
|
886
886
|
# import rdr type
|
887
887
|
imports += f"from ripple_down_rules.rdr import GeneralRDR\n"
|
888
888
|
# add case type
|
@@ -5,7 +5,7 @@ from abc import ABC, abstractmethod
|
|
5
5
|
from enum import Enum
|
6
6
|
|
7
7
|
from anytree import NodeMixin
|
8
|
-
from typing_extensions import List, Optional, Self, Union, Dict, Any
|
8
|
+
from typing_extensions import List, Optional, Self, Union, Dict, Any, Tuple
|
9
9
|
|
10
10
|
from .datastructures.callable_expression import CallableExpression
|
11
11
|
from .datastructures.case import Case
|
@@ -78,24 +78,26 @@ class Rule(NodeMixin, SubclassJSONSerializer, ABC):
|
|
78
78
|
"""
|
79
79
|
pass
|
80
80
|
|
81
|
-
def write_conclusion_as_source_code(self, parent_indent: str = "") -> str:
|
81
|
+
def write_conclusion_as_source_code(self, parent_indent: str = "", defs_file: Optional[str] = None) -> str:
|
82
82
|
"""
|
83
83
|
Get the source code representation of the conclusion of the rule.
|
84
84
|
|
85
85
|
:param parent_indent: The indentation of the parent rule.
|
86
|
+
:param defs_file: The file to write the conclusion to if it is a definition.
|
87
|
+
:return: The source code representation of the conclusion of the rule.
|
86
88
|
"""
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
return
|
89
|
+
if self.conclusion.user_input is not None:
|
90
|
+
conclusion = self.conclusion.user_input
|
91
|
+
else:
|
92
|
+
conclusion = self.conclusion.conclusion
|
93
|
+
conclusion_func, conclusion_func_call = self._conclusion_source_code(conclusion, parent_indent=parent_indent)
|
94
|
+
if conclusion_func is not None:
|
95
|
+
with open(defs_file, 'a') as f:
|
96
|
+
f.write(conclusion_func + "\n\n")
|
97
|
+
return conclusion_func_call
|
96
98
|
|
97
99
|
@abstractmethod
|
98
|
-
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> str:
|
100
|
+
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> Tuple[Optional[str], str]:
|
99
101
|
pass
|
100
102
|
|
101
103
|
def write_condition_as_source_code(self, parent_indent: str = "", defs_file: Optional[str] = None) -> str:
|
@@ -118,7 +120,7 @@ class Rule(NodeMixin, SubclassJSONSerializer, ABC):
|
|
118
120
|
conditions_lines[0] = re.sub(r"def (\w+)", new_function_name, conditions_lines[0])
|
119
121
|
def_code = "\n".join(conditions_lines)
|
120
122
|
with open(defs_file, 'a') as f:
|
121
|
-
f.write(def_code + "\n")
|
123
|
+
f.write(def_code + "\n\n")
|
122
124
|
return f"\n{parent_indent}{if_clause} {new_function_name.replace('def ', '')}(case):\n"
|
123
125
|
|
124
126
|
@abstractmethod
|
@@ -266,11 +268,11 @@ class SingleClassRule(Rule, HasAlternativeRule, HasRefinementRule):
|
|
266
268
|
loaded_rule.alternative = SingleClassRule.from_json(data["alternative"])
|
267
269
|
return loaded_rule
|
268
270
|
|
269
|
-
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> str:
|
271
|
+
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> Tuple[Optional[str], str]:
|
270
272
|
conclusion = str(conclusion)
|
271
273
|
indent = parent_indent + " " * 4
|
272
274
|
if '\n' not in conclusion:
|
273
|
-
return f"{indent}return {conclusion}\n"
|
275
|
+
return None, f"{indent}return {conclusion}\n"
|
274
276
|
else:
|
275
277
|
return get_rule_conclusion_as_source_code(self, conclusion, parent_indent=parent_indent)
|
276
278
|
|
@@ -317,8 +319,8 @@ class MultiClassStopRule(Rule, HasAlternativeRule):
|
|
317
319
|
loaded_rule.alternative = MultiClassStopRule.from_json(data["alternative"])
|
318
320
|
return loaded_rule
|
319
321
|
|
320
|
-
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> str:
|
321
|
-
return f"{parent_indent}{' ' * 4}pass\n"
|
322
|
+
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> Tuple[None, str]:
|
323
|
+
return None, f"{parent_indent}{' ' * 4}pass\n"
|
322
324
|
|
323
325
|
def _if_statement_source_code_clause(self) -> str:
|
324
326
|
return "elif" if self.weight == RDREdge.Alternative.value else "if"
|
@@ -362,25 +364,23 @@ class MultiClassTopRule(Rule, HasRefinementRule, HasAlternativeRule):
|
|
362
364
|
loaded_rule.alternative = MultiClassTopRule.from_json(data["alternative"])
|
363
365
|
return loaded_rule
|
364
366
|
|
365
|
-
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> str:
|
367
|
+
def _conclusion_source_code(self, conclusion: Any, parent_indent: str = "") -> Tuple[str, str]:
|
366
368
|
conclusion_str = str(conclusion)
|
367
369
|
indent = parent_indent + " " * 4
|
368
|
-
statement = ""
|
369
370
|
if '\n' not in conclusion_str:
|
371
|
+
func = None
|
370
372
|
if is_iterable(conclusion):
|
371
373
|
conclusion_str = "{" + ", ".join([str(c) for c in conclusion]) + "}"
|
372
374
|
else:
|
373
375
|
conclusion_str = "{" + str(conclusion) + "}"
|
374
376
|
else:
|
375
|
-
|
376
|
-
|
377
|
-
conclusion_str = lines[-2].replace("return ", "").strip()
|
378
|
-
statement += "\n".join(lines[:-2]) + "\n"
|
377
|
+
func, func_call = get_rule_conclusion_as_source_code(self, conclusion_str, parent_indent=parent_indent)
|
378
|
+
conclusion_str = func_call.replace("return ", "").strip()
|
379
379
|
|
380
|
-
statement
|
380
|
+
statement = f"{indent}conclusions.update(make_set({conclusion_str}))\n"
|
381
381
|
if self.alternative is None:
|
382
382
|
statement += f"{parent_indent}return conclusions\n"
|
383
|
-
return statement
|
383
|
+
return func, statement
|
384
384
|
|
385
385
|
def _if_statement_source_code_clause(self) -> str:
|
386
386
|
return "if"
|
@@ -119,14 +119,14 @@ def calculate_precision_and_recall(pred_cat: Dict[str, Any], target: Dict[str, A
|
|
119
119
|
return precision, recall
|
120
120
|
|
121
121
|
|
122
|
-
def get_rule_conclusion_as_source_code(rule: Rule, conclusion: str, parent_indent: str = "") -> str:
|
122
|
+
def get_rule_conclusion_as_source_code(rule: Rule, conclusion: str, parent_indent: str = "") -> Tuple[str, str]:
|
123
123
|
"""
|
124
124
|
Convert the conclusion of a rule to source code.
|
125
125
|
|
126
126
|
:param rule: The rule to get the conclusion from.
|
127
127
|
:param conclusion: The conclusion to convert to source code.
|
128
128
|
:param parent_indent: The indentation to use for the source code.
|
129
|
-
:return: The source code of the conclusion.
|
129
|
+
:return: The source code of the conclusion as a tuple of strings, one for the function and one for the call.
|
130
130
|
"""
|
131
131
|
indent = f"{parent_indent}{' ' * 4}"
|
132
132
|
if "def " in conclusion:
|
@@ -135,9 +135,8 @@ def get_rule_conclusion_as_source_code(rule: Rule, conclusion: str, parent_inden
|
|
135
135
|
# use regex to replace the function name
|
136
136
|
new_function_name = f"def conclusion_{id(rule)}"
|
137
137
|
conclusion_lines[0] = re.sub(r"def (\w+)", new_function_name, conclusion_lines[0])
|
138
|
-
|
139
|
-
|
140
|
-
return "\n".join(conclusion_lines)
|
138
|
+
func_call = f"{indent}return {new_function_name.replace('def ', '')}(case)\n"
|
139
|
+
return "\n".join(conclusion_lines).strip(' '), func_call
|
141
140
|
else:
|
142
141
|
raise ValueError(f"Conclusion is format is not valid, it should be a one line string or "
|
143
142
|
f"contain a function definition. Instead got:\n{conclusion}\n")
|
{ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/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.1.
|
3
|
+
Version: 0.1.66
|
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
|
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.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/case.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/datastructures/enums.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules/rdr_decorators.py
RENAMED
File without changes
|
{ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/src/ripple_down_rules.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.1.65 → ripple_down_rules-0.1.66}/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
|