Managing concept properties in ConceptEvaluator
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from core.builtin_concepts import ParserResultConcept
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts
|
||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||
import logging
|
||||
@@ -9,6 +9,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ConceptEvaluator(OneReturnValueEvaluator):
|
||||
evaluation_steps = [BuiltinConcepts.EVALUATION, BuiltinConcepts.AFTER_EVALUATION]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Concept Evaluator", 50)
|
||||
|
||||
@@ -31,12 +33,32 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
||||
# TODO; check pre
|
||||
# if pre is not true, return Concept with a false value
|
||||
|
||||
if ConceptParts.BODY in concept.codes:
|
||||
body = concept.codes[ConceptParts.BODY]
|
||||
if body is None:
|
||||
return None # nothing to do
|
||||
# Evaluate the properties
|
||||
for prop in concept.props:
|
||||
sub_context = context.push(self.name, f"Evaluating property '{prop}'", concept)
|
||||
res = self.evaluate_parsing(sheerka, sub_context, concept.codes[prop])
|
||||
if res.status:
|
||||
concept.set_prop(prop, res.value)
|
||||
else:
|
||||
return sheerka.ret(
|
||||
self.name,
|
||||
False,
|
||||
sheerka.new(BuiltinConcepts.PROPERTY_EVAL_ERROR, body=prop, concept=concept, error=res.value),
|
||||
parents=[return_value])
|
||||
|
||||
return sheerka.ret(self.name, True, body.value, parents=[return_value])
|
||||
|
||||
else:
|
||||
# Evaluate body
|
||||
if ConceptParts.BODY not in concept.codes:
|
||||
return sheerka.ret(self.name, True, concept, parents=[return_value])
|
||||
|
||||
body = concept.codes[ConceptParts.BODY]
|
||||
if body is None:
|
||||
return None # seems weird
|
||||
|
||||
sub_context = context.push(self.name, "Evaluating body", concept)
|
||||
res = self.evaluate_parsing(sheerka, sub_context, body)
|
||||
return sheerka.ret(self.name, res.status, res.value, parents=[return_value])
|
||||
|
||||
def evaluate_parsing(self, sheerka, context, parsing_result):
|
||||
res = sheerka.chain_process(context, parsing_result, self.evaluation_steps)
|
||||
res = sheerka.expect_one(context, res)
|
||||
return res
|
||||
|
||||
@@ -19,7 +19,7 @@ class DuplicateConceptEvaluator(AllReturnValuesEvaluator):
|
||||
only_parsers = True
|
||||
|
||||
for ret in return_values:
|
||||
if sheerka.isinstance(ret.value, BuiltinConcepts.PARSING):
|
||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
||||
if ret.status:
|
||||
parsing = True
|
||||
elif ret.who == "Evaluators:Add new Concept":
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.BaseEvaluator import AllReturnValuesEvaluator, BaseEvaluator
|
||||
import logging
|
||||
|
||||
from parsers.BaseParser import BaseParser
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MultipleSameSuccessEvaluator(AllReturnValuesEvaluator):
|
||||
"""
|
||||
Used to filter the responses
|
||||
It has a low priority to let other evaluators try to resolve the errors
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Parsers Evaluator", 10)
|
||||
self.success = []
|
||||
|
||||
def matches(self, context, return_values):
|
||||
sheerka = context.sheerka
|
||||
after_evaluation = False
|
||||
nb_successful_evaluators = 0
|
||||
only_parsers_in_error = True
|
||||
unlisted = False
|
||||
|
||||
for ret in return_values:
|
||||
|
||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
||||
if ret.status:
|
||||
after_evaluation = True
|
||||
|
||||
elif ret.who.startswith(BaseEvaluator.PREFIX):
|
||||
if ret.status:
|
||||
nb_successful_evaluators += 1
|
||||
self.success.append(ret.value)
|
||||
elif ret.who.startswith(BaseParser.PREFIX):
|
||||
if ret.status:
|
||||
only_parsers_in_error = False
|
||||
else:
|
||||
unlisted = True
|
||||
|
||||
return after_evaluation and nb_successful_evaluators > 1 and only_parsers_in_error and not unlisted
|
||||
|
||||
def eval(self, context, return_values):
|
||||
reference = self.get_value(self.success[0])
|
||||
|
||||
for return_value in self.success[1:]:
|
||||
actual = self.get_value(return_value)
|
||||
if actual != reference:
|
||||
return None
|
||||
|
||||
sheerka = context.sheerka
|
||||
return sheerka.ret(self.name, True, reference, parents=return_values)
|
||||
|
||||
@staticmethod
|
||||
def get_value(obj):
|
||||
if not isinstance(obj, Concept):
|
||||
return obj
|
||||
|
||||
return obj if obj.body is None else obj.body
|
||||
@@ -1,5 +1,4 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.BaseEvaluator import AllReturnValuesEvaluator
|
||||
import logging
|
||||
|
||||
@@ -8,7 +7,7 @@ from parsers.BaseParser import BaseParser
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ParsersEvaluator(AllReturnValuesEvaluator):
|
||||
class OneSuccessEvaluator(AllReturnValuesEvaluator):
|
||||
"""
|
||||
Used to filter the responses
|
||||
It has a low priority to let other evaluators try to resolve the errors
|
||||
@@ -20,13 +19,13 @@ class ParsersEvaluator(AllReturnValuesEvaluator):
|
||||
|
||||
def matches(self, context, return_values):
|
||||
sheerka = context.sheerka
|
||||
after_parsing = False
|
||||
after_evaluation = False
|
||||
nb_successful_evaluators = 0
|
||||
only_parsers = True
|
||||
for ret in return_values:
|
||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_PARSING):
|
||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
||||
if ret.status:
|
||||
after_parsing = True
|
||||
after_evaluation = True
|
||||
elif ret.who.startswith(self.PREFIX):
|
||||
if ret.status:
|
||||
nb_successful_evaluators += 1
|
||||
@@ -35,7 +34,7 @@ class ParsersEvaluator(AllReturnValuesEvaluator):
|
||||
if not ret.who.startswith(BaseParser.PREFIX):
|
||||
only_parsers = False
|
||||
|
||||
return after_parsing and nb_successful_evaluators == 1 and only_parsers
|
||||
return after_evaluation and nb_successful_evaluators == 1 and only_parsers
|
||||
|
||||
def eval(self, context, return_values):
|
||||
sheerka = context.sheerka
|
||||
@@ -13,8 +13,8 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
|
||||
def matches(self, context, return_value):
|
||||
return return_value.status and \
|
||||
isinstance(return_value.value, ParserResultConcept) and \
|
||||
isinstance(return_value.value.value, PythonNode)
|
||||
isinstance(return_value.value, ParserResultConcept) and \
|
||||
isinstance(return_value.value.value, PythonNode)
|
||||
|
||||
def eval(self, context, return_value):
|
||||
sheerka = context.sheerka
|
||||
@@ -23,10 +23,18 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
try:
|
||||
log.debug(f"Evaluating python node {node}")
|
||||
compiled = compile(node.ast_, "<string>", "eval")
|
||||
evaluated = eval(compiled, {}, {"sheerka": context.sheerka})
|
||||
evaluated = eval(compiled, {}, self.get_locals(context))
|
||||
return sheerka.ret(self.name, True, evaluated, parents=[return_value])
|
||||
except Exception as error:
|
||||
error = sheerka.new(BuiltinConcepts.ERROR, body=error)
|
||||
return sheerka.ret(self.name, False, error, parents=[return_value])
|
||||
else:
|
||||
return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.ERROR), parents=[return_value])
|
||||
|
||||
@staticmethod
|
||||
def get_locals(context):
|
||||
my_locals = {"sheerka": context.sheerka}
|
||||
if context.obj:
|
||||
for prop_name, prop_value in context.obj.props.items():
|
||||
my_locals[prop_name] = prop_value.value
|
||||
return my_locals
|
||||
|
||||
Reference in New Issue
Block a user