Fixed EvalEvaluator when there is nothing to evaluate
This commit is contained in:
@@ -750,3 +750,21 @@ The [Non]TerminalNode
|
|||||||
represents what was found. So similarly to the ConceptNode, you will find the start, end and token attributes
|
represents what was found. So similarly to the ConceptNode, you will find the start, end and token attributes
|
||||||
|
|
||||||
That's all for today !
|
That's all for today !
|
||||||
|
|
||||||
|
2019-27-12
|
||||||
|
**********
|
||||||
|
|
||||||
|
How to manage variables resolutions
|
||||||
|
"""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
I have to admit that I am a little bit stuck with how to manage variable resolution with PythonEvaluator.
|
||||||
|
What is expected by the expression depends on the expression itself.
|
||||||
|
|
||||||
|
Let's see an example
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
def concept one as 1
|
||||||
|
def concept two as 2
|
||||||
|
|
||||||
|
eval one + two
|
||||||
@@ -12,8 +12,6 @@ class EvalEvaluator(AllReturnValuesEvaluator):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80)
|
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80)
|
||||||
self.successful_return_value = None
|
|
||||||
self.to_eval = []
|
|
||||||
self.eval_requested = None
|
self.eval_requested = None
|
||||||
|
|
||||||
def matches(self, context, return_values):
|
def matches(self, context, return_values):
|
||||||
@@ -21,18 +19,25 @@ class EvalEvaluator(AllReturnValuesEvaluator):
|
|||||||
for ret in return_values:
|
for ret in return_values:
|
||||||
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED):
|
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED):
|
||||||
self.eval_requested = ret
|
self.eval_requested = ret
|
||||||
elif ret.status and isinstance(ret.body, Concept) and ret.body.body:
|
return True
|
||||||
self.to_eval.append(ret)
|
|
||||||
|
|
||||||
return self.eval_requested is not None and len(self.to_eval) > 0
|
return False
|
||||||
|
|
||||||
def eval(self, context, return_value):
|
def eval(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
result = []
|
result = []
|
||||||
context.log(self.verbose_log, f"{len(self.to_eval)} return value(s) to eval", who=self)
|
|
||||||
|
|
||||||
for ret_val in self.to_eval:
|
for ret_val in return_values:
|
||||||
context.log(self.verbose_log, f"{ret_val}", who=self)
|
if ret_val.status and isinstance(ret_val.body, Concept) and ret_val.body.body:
|
||||||
|
context.log(self.verbose_log, f"Evaluating {ret_val}", who=self)
|
||||||
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested]))
|
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested]))
|
||||||
|
|
||||||
|
if len(result) > 0:
|
||||||
return result
|
return result
|
||||||
|
else:
|
||||||
|
# suppress the successful BuiltinConcepts.CONCEPT_EVAL_REQUESTED
|
||||||
|
return sheerka.ret(
|
||||||
|
self.name,
|
||||||
|
False,
|
||||||
|
sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED),
|
||||||
|
parents=[self.eval_requested])
|
||||||
|
|||||||
@@ -49,11 +49,32 @@ def test_i_can_match_and_eval():
|
|||||||
|
|
||||||
@pytest.mark.parametrize("return_values, expected", [
|
@pytest.mark.parametrize("return_values, expected", [
|
||||||
([r(Concept("foo", body="bar")), eval_requested], True),
|
([r(Concept("foo", body="bar")), eval_requested], True),
|
||||||
([r(Concept("status is false", body="bar"), False), eval_requested], False),
|
([r(Concept("status is false", body="bar"), False), eval_requested], True),
|
||||||
([r("string_value"), eval_requested], False),
|
([r("string_value"), eval_requested], True),
|
||||||
([r(Concept("no body")), eval_requested], False),
|
([r(Concept("no body")), eval_requested], True),
|
||||||
([r(Concept("eval requested missing", body="bar"))], False),
|
([r(Concept("eval requested missing", body="bar"))], False),
|
||||||
])
|
])
|
||||||
def test_i_cannot_match_if_eval_request_is_not_present(return_values, expected):
|
def test_i_cannot_match_if_eval_request_is_not_present(return_values, expected):
|
||||||
context = get_context()
|
context = get_context()
|
||||||
assert EvalEvaluator().matches(context, return_values) == expected
|
assert EvalEvaluator().matches(context, return_values) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_concept_eval_requested_is_reduced_when_nothing_to_reduce():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
ReturnValueConcept("some_name", True, "not to eval"),
|
||||||
|
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
||||||
|
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
|
||||||
|
eval_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = EvalEvaluator()
|
||||||
|
assert evaluator.matches(context, return_values)
|
||||||
|
|
||||||
|
evaluated = evaluator.eval(context, return_values)
|
||||||
|
assert evaluated == ReturnValueConcept(
|
||||||
|
"evaluators.Eval",
|
||||||
|
False,
|
||||||
|
context.sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
||||||
|
assert evaluated.parents == [eval_requested]
|
||||||
|
|||||||
@@ -162,6 +162,28 @@ class EvaluatorAllReduceFooBar(EvaluatorAllWithPriority):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
class EvaluatorAllSuppressFooEntry(EvaluatorAllWithPriority):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("suppress", 100)
|
||||||
|
|
||||||
|
def matches(self, context, return_values):
|
||||||
|
super().matches(context, return_values)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def eval(self, context, return_values):
|
||||||
|
super().eval(context, return_values)
|
||||||
|
foo = None
|
||||||
|
for ret in return_values:
|
||||||
|
if ret.body.name == "foo":
|
||||||
|
foo = ret
|
||||||
|
|
||||||
|
if foo:
|
||||||
|
return context.sheerka.ret(self.name, False, Concept("does not matter"), parents=[foo])
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def test_that_return_values_is_unchanged_when_no_evaluator():
|
def test_that_return_values_is_unchanged_when_no_evaluator():
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
sheerka.evaluators = []
|
sheerka.evaluators = []
|
||||||
|
|||||||
@@ -400,3 +400,19 @@ def test_i_can_say_that_a_concept_isa_another_concept():
|
|||||||
res = sheerka.evaluate_user_input("foo isa bar")
|
res = sheerka.evaluate_user_input("foo isa bar")
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
|
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
|
||||||
|
|
||||||
|
|
||||||
|
def test_eval_does_not_break_valid_result():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
sheerka.evaluate_user_input("def concept one as 1")
|
||||||
|
sheerka.evaluate_user_input("def concept two as 2")
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("one + two")
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0].status
|
||||||
|
assert res[0].body == 3
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("eval one + two")
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0].status
|
||||||
|
assert res[0].body == 3
|
||||||
|
|||||||
Reference in New Issue
Block a user