Added first version of DebugManager. Implemented draft of the rule engine
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.builtin_helpers import expect_one
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from evaluators.ConceptEvaluator import ConceptEvaluator
|
||||
|
||||
DISABLED_RULES = "#disabled#"
|
||||
LOW_PRIORITY_RULES = "#low_priority#"
|
||||
|
||||
|
||||
class SheerkaEvaluateRules(BaseService):
|
||||
NAME = "EvaluateRules"
|
||||
|
||||
def __init__(self, sheerka):
|
||||
super().__init__(sheerka)
|
||||
self.evaluators_by_name = None
|
||||
|
||||
def initialize(self):
|
||||
self.sheerka.bind_service_method(self.evaluate_format_rules, False)
|
||||
self.reset_evaluators()
|
||||
|
||||
def reset_evaluators(self):
|
||||
# instantiate evaluators, once for all, only keep when it's enabled
|
||||
evaluators = [e_class() for e_class in self.sheerka.evaluators]
|
||||
evaluators = [e for e in evaluators if e.enabled]
|
||||
self.evaluators_by_name = {e.short_name: e for e in evaluators}
|
||||
|
||||
def evaluate_format_rules(self, context, bag, disabled):
|
||||
return self.evaluate_rules(context, self.sheerka.get_format_rules(), bag, disabled)
|
||||
|
||||
def evaluate_rules(self, context, rules, bag, disabled):
|
||||
"""
|
||||
evaluate the format rules, in the context of 'bag'
|
||||
CAUTION : the rules MUST be sorted by priority
|
||||
:param context:
|
||||
:param rules:
|
||||
:param bag:
|
||||
:param disabled: disabled rules (because they have already been fired or whatever)
|
||||
:return: { True : list of success, False :list of failed, '#disabled"': list of disabled...}
|
||||
"""
|
||||
with context.push(BuiltinConcepts.EVALUATING_RULES, bag, desc="Evaluating rules...") as sub_context:
|
||||
sub_context.protected_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
sub_context.protected_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
sub_context.protected_hints.add(BuiltinConcepts.EVAL_UNTIL_SUCCESS_REQUESTED)
|
||||
sub_context.protected_hints.add(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
|
||||
sub_context.add_inputs(bag=bag)
|
||||
|
||||
debugger = sub_context.get_debugger(SheerkaEvaluateRules.NAME, "evaluate_rules")
|
||||
debugger.debug_entering(bag=bag)
|
||||
|
||||
results = {}
|
||||
|
||||
sub_context.sheerka.add_many_to_short_term_memory(sub_context, bag)
|
||||
success_priority = None
|
||||
for rule in rules:
|
||||
if not rule.metadata.is_enabled or rule.id in disabled:
|
||||
results.setdefault(DISABLED_RULES, []).append(rule)
|
||||
continue
|
||||
|
||||
if success_priority and rule.priority != success_priority:
|
||||
results.setdefault(LOW_PRIORITY_RULES, []).append(rule)
|
||||
continue
|
||||
|
||||
res = self.evaluate_rule(sub_context, rule, bag)
|
||||
ok = res.status and self.sheerka.is_success(self.sheerka.objvalue(res))
|
||||
results.setdefault(ok, []).append(rule)
|
||||
if ok and success_priority is None:
|
||||
success_priority = rule.priority
|
||||
|
||||
debugger.debug_var("results", self.get_debug_format(results))
|
||||
|
||||
sub_context.add_values(rules_result=results)
|
||||
return results
|
||||
|
||||
def evaluate_rule(self, context, rule, bag):
|
||||
"""
|
||||
Evaluate all the predicate
|
||||
:param context:
|
||||
:param rule:
|
||||
:param bag:
|
||||
:return:
|
||||
"""
|
||||
|
||||
results = []
|
||||
for rule_predicate in rule.compiled_predicate:
|
||||
|
||||
if rule_predicate.source in bag:
|
||||
# simple case where the rule is an item of the bag. No need of complicate evaluation
|
||||
results.append(context.sheerka.ret(self.NAME, True, bag[rule_predicate.source]))
|
||||
|
||||
else:
|
||||
|
||||
# do not forget to reset the 'is_evaluated' in the case of a concept
|
||||
if rule_predicate.evaluator == ConceptEvaluator.NAME:
|
||||
rule_predicate.concept.get_metadata().is_evaluated = False
|
||||
|
||||
evaluator = self.evaluators_by_name[rule_predicate.evaluator]
|
||||
results.append(evaluator.eval(context, rule_predicate.predicate))
|
||||
|
||||
debugger = context.get_debugger(SheerkaEvaluateRules.NAME, "evaluate_rule")
|
||||
debugger.debug_rule(rule, results)
|
||||
# if context.sheerka.debug_rule_activated(rule_id, context.id):
|
||||
# context.debug(SheerkaEvaluateRules.NAME, "evaluate_rules", f"result(#{rule_id})", results)
|
||||
|
||||
return expect_one(context, results)
|
||||
|
||||
@staticmethod
|
||||
def get_debug_format(result):
|
||||
"""
|
||||
Return the same dictionary, the with the short formatting of the rules
|
||||
eg without the action clause
|
||||
:param result:
|
||||
:return:
|
||||
"""
|
||||
return {key: [str(r) if key == True else r.short_str() for r in rules] for key, rules in result.items()}
|
||||
Reference in New Issue
Block a user