Implemented a first and basic version of a Rete rule engine

This commit is contained in:
2021-02-09 16:06:32 +01:00
parent 821dbed189
commit a2a8d5c5e5
110 changed files with 7301 additions and 1654 deletions
+56
View File
@@ -0,0 +1,56 @@
import core.utils
from core.builtin_concepts import BuiltinConcepts, ParserResultConcept
from core.global_symbols import NotInit
from core.rule import Rule, ACTION_TYPE_PRINT, ACTION_TYPE_EXEC
from core.tokenizer import Keywords
from evaluators.BaseEvaluator import OneReturnValueEvaluator
from parsers.DefRuleParser import DefRuleNode, DefFormatRuleNode
class DefRuleEvaluator(OneReturnValueEvaluator):
"""
Used to store a new format rule
"""
NAME = "DefRule"
def __init__(self):
super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 50)
def matches(self, context, return_value):
return return_value.status and \
isinstance(return_value.value, ParserResultConcept) and \
isinstance(return_value.value.value, DefRuleNode)
def eval(self, context, return_value):
"""
Creates a Rule out of a DefRule and saves it in db
:param context:
:param return_value:
:return:
"""
context.log("Adding a new rule", self.name)
rule_definition = return_value.value.value
sheerka = context.sheerka
name = None if rule_definition.name is NotInit else str(rule_definition.name)
predicate = core.utils.get_text_from_tokens(rule_definition.tokens[Keywords.WHEN][1:])
if isinstance(rule_definition, DefFormatRuleNode):
action_type = ACTION_TYPE_PRINT
action = core.utils.get_text_from_tokens(rule_definition.tokens[Keywords.PRINT][1:])
compiled_action = rule_definition.print
else:
action_type = ACTION_TYPE_EXEC
action = core.utils.get_text_from_tokens(rule_definition.tokens[Keywords.THEN][1:])
compiled_action = rule_definition.then
rule = Rule(action_type, name, predicate, action)
rule.compiled_predicates = rule_definition.when
rule.rete_disjunctions = rule_definition.rete
rule.compiled_action = compiled_action
ret = sheerka.create_new_rule(context, rule)
if not ret.status:
error_cause = sheerka.objvalue(ret.body)
context.log(f"Failed to add new rule '{rule}'. Reason: {error_cause}", self.name)
return sheerka.ret(self.name, ret.status, ret.value, parents=[return_value])