Fixed #49 : ExpressionParser: Implement ExpressionParser

This commit is contained in:
2021-03-15 19:41:06 +01:00
parent 42bc6abf97
commit 27bc6c4ba1
7 changed files with 245 additions and 57 deletions
+139 -3
View File
@@ -2,7 +2,7 @@ import ast
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
from core.concept import Concept, DEFINITION_TYPE_DEF, DoNotResolve
from core.global_symbols import RULE_COMPARISON_CONTEXT, NotFound, EVENT_RULE_DELETED
from core.rule import Rule, ACTION_TYPE_PRINT, ACTION_TYPE_EXEC
@@ -21,6 +21,7 @@ from parsers.ExpressionParser import ExpressionParser
from parsers.PythonParser import PythonNode
from sheerkarete.common import V
from sheerkarete.conditions import Condition, AndConditions
from sheerkarete.network import ReteNetwork
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import CMV, CC, compare_with_test_object, get_test_obj, get_rete_conditions
@@ -1029,7 +1030,7 @@ isinstance(var, Concept) and var.key == 'hello __var__0'""" + \
),
])
def test_i_can_get_rete_conditions(self, expression, expected_as_str):
sheerka, context, = self.init_test().unpack()
sheerka, context = self.init_test().unpack()
parser = ExpressionParser()
expected = get_rete_conditions(*expected_as_str)
@@ -1041,7 +1042,142 @@ isinstance(var, Concept) and var.key == 'hello __var__0'""" + \
visitor = ReteConditionExprVisitor(context)
conditions = visitor.get_conditions(parsed)
assert conditions == expected
assert conditions == [expected]
# check against a Rete network
network = ReteNetwork()
rule = Rule("test", expression, None)
rule.metadata.id = 9999
rule.metadata.is_compiled = True
rule.metadata.is_enabled = True
rule.rete_disjunctions = conditions
network.add_rule(rule)
network.add_obj("__ret", ReturnValueConcept("Test", True, None))
matches = list(network.matches)
assert len(matches) == 1
@pytest.mark.parametrize("test_name, expression, variable_name, expected_as_str", [
(
"recognize by name",
"recognize(__ret.body, greetings)",
None,
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'"]
),
(
"recognize by id",
"recognize(__ret.body, c:|1001:)",
None,
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|id|'1001'"]
),
(
"recognize by name using c_str",
"recognize(__ret.body, c:greetings:)",
None,
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'"]
),
(
"recognize by name and variable sheerka",
"recognize(__ret.body, greetings, a=sheerka)",
"sheerka",
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'",
"#__x_01__|a|'__sheerka__'"]
),
(
"recognize by name and str variable",
"recognize(__ret.body, greetings, a='my friend')",
"'my friend'",
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'",
"#__x_01__|a|'my friend'"]
),
(
"recognize by name and concept variable",
"recognize(__ret.body, greetings, a=foo)",
"foo",
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'",
"#__x_01__|a.name|'foo'"]
),
(
"recognize by name and add other conditions (str)",
"recognize(__ret.body, greetings) and __ret.body.a == 'my friend'",
"foo",
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'",
"#__x_01__|a|'my friend'"]
),
(
"recognize by name and add other conditions (sheerka)",
"recognize(__ret.body, greetings) and __ret.body.a == sheerka",
"foo",
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'",
"#__x_01__|a|'kodjo'"]
),
(
"recognize by name and add other conditions (concept)",
"recognize(__ret.body, greetings) and __ret.body.a == foo",
"foo",
["#__x_00__|__name__|'__ret'",
"#__x_00__|body|#__x_01__",
"#__x_01__|__is_concept__|True",
"#__x_01__|name|'greetings'",
"#__x_01__|a|'kodjo'"]
),
])
def test_i_can_get_rete_conditions_from_recognized(self, test_name, expression, variable_name, expected_as_str):
sheerka, context, greetings, foo = self.init_test().with_concepts(
Concept("greetings", definition="hello a", definition_type=DEFINITION_TYPE_DEF).def_var("a"),
Concept("foo"),
).unpack()
parser = ExpressionParser()
expected = get_rete_conditions(*expected_as_str)
error_sink = ErrorSink()
parser_input = ParserInput(expression)
parser.reset_parser_input(parser_input, error_sink)
parsed = parser.parse_input(context, parser_input, error_sink)
visitor = ReteConditionExprVisitor(context)
conditions = visitor.get_conditions(parsed)
assert conditions == [expected]
# check against a Rete network
network = ReteNetwork()
rule = Rule("test", expression, None)
rule.metadata.id = 9999
rule.metadata.is_compiled = True
rule.metadata.is_enabled = True
rule.rete_disjunctions = conditions
network.add_rule(rule)
variable = foo if variable_name == "foo" else variable_name
to_recognize = sheerka.new_from_template(greetings, greetings.key, a=variable)
network.add_obj("__ret", ReturnValueConcept("Test", True, to_recognize))
matches = list(network.matches)
assert len(matches) == 1
class TestSheerkaRuleManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):