-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrule_engine.py
108 lines (91 loc) · 3.25 KB
/
rule_engine.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
class RuleEngine:
def __init__(self, rules):
self.rules = rules
def execute(self, facts):
for rule in self.rules:
rule.evaluate(facts)
class Rule:
def __init__(self, condition, action):
self.condition = condition
self.action = action
def evaluate(self, facts):
if self.condition.evaluate(facts):
self.action.execute(facts)
class Condition:
def __init__(self, expression):
self.expression = expression
def evaluate(self, facts):
return self.expression.evaluate(facts)
class Action:
def __init__(self, expression):
self.expression = expression
def execute(self, facts):
self.expression.execute(facts)
class Expression:
def __init__(self, operator, left, right=None):
self.operator = operator
self.left = left
self.right = right
def evaluate(self, facts):
if isinstance(self.left, Expression):
left_value = self.left.evaluate(facts)
elif isinstance(self.left, str):
left_value = facts.get(self.left)
if left_value is None:
left_value = self.left
else:
left_value = self.left
if isinstance(self.right, Expression):
right_value = self.right.evaluate(facts)
elif isinstance(self.right, str):
right_value = facts.get(self.right)
if right_value is None:
right_value = self.right
else:
right_value = self.right
if self.operator == 'AND':
return left_value and right_value
elif self.operator == 'OR':
return left_value or right_value
elif self.operator == 'NOT':
return not left_value
elif self.operator == '>':
return left_value > right_value
elif self.operator == '<':
return left_value < right_value
elif self.operator == '==':
return left_value == right_value
elif self.operator == '!=':
return left_value != right_value
elif self.operator == '>=':
return left_value >= right_value
elif self.operator == '<=':
return left_value <= right_value
else:
raise Exception('Invalid operator')
def execute(self, facts):
if isinstance(self.right, Expression):
right_value = self.right.evaluate(facts)
elif isinstance(self.right, str):
if self.right.lower() == 'true':
right_value = True
elif self.right.lower() == 'false':
right_value = False
else:
right_value = facts.get(self.right)
if right_value is None:
right_value = self.right
else:
right_value = self.right
if self.operator == '=':
facts[self.left] = right_value
elif self.operator == '+=':
facts[self.left] += right_value
elif self.operator == '-=':
facts[self.left] -= right_value
elif self.operator == '*=':
facts[self.left] *= right_value
elif self.operator == '/=':
facts[self.left] /= right_value
else:
raise Exception('Invalid operator')