Fixed #29: Parsers: Implement parsing memoization

Fixed #77 : Parser: ShortTermMemoryParser should be called separately
Fixed #78 : Remove VariableNode usage
Fixed #79 : ConceptManager: Implement compile caching
Fixed #80 : SheerkaExecute : parsers_key is not correctly computed
Fixed #81 : ValidateConceptEvaluator : Validate concept's where and pre clauses right after the parsing
Fixed #82 : SheerkaIsAManager: isa() failed when the set as a body
Fixed #83 : ValidateConceptEvaluator : Support BNF and SYA Concepts
Fixed #84 : ExpressionParser: Implement the parser as a standard parser
Fixed #85 : Services: Give order to services
Fixed #86 : cannot manage smart_get_attr(the short, color)
This commit is contained in:
2021-06-07 21:14:03 +02:00
parent 1059ce25c5
commit 7dcaa9c111
92 changed files with 4263 additions and 1890 deletions
+74 -32
View File
@@ -7,7 +7,6 @@ from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
from evaluators.OneSuccessEvaluator import OneSuccessEvaluator
from evaluators.PythonEvaluator import PythonEvalError
from sheerkapython.python_wrapper import MethodAccessError
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import CMV, CC, compare_with_test_object, CB
@@ -211,9 +210,9 @@ as:
# sanity check
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
assert evaluated.body == "hello foo"
assert evaluated.get_metadata().is_evaluated
assert evaluated.get_hints().is_evaluated
compare_with_test_object(evaluated.get_value("a"), CB("foo", "foo"))
assert evaluated.get_value("a").get_metadata().is_evaluated
assert evaluated.get_value("a").get_hints().is_evaluated
def test_i_can_recognize_duplicate_concepts_with_same_value(self):
# when multiple result, choose the one that is the more specific (that has the less variables)
@@ -296,9 +295,9 @@ as:
# sanity check
evaluated = sheerka.evaluate_concept(self.get_context(sheerka=sheerka, eval_body=True), return_value)
assert evaluated.body == "one three"
assert evaluated.get_metadata().is_evaluated
assert evaluated.get_hints().is_evaluated
assert evaluated.get_value("a") == sheerka.new(concept_a.key, body="one").init_key()
assert evaluated.get_value("a").get_metadata().is_evaluated
assert evaluated.get_value("a").get_hints().is_evaluated
@pytest.mark.parametrize("user_input", [
"def concept greetings from def hello a where a",
@@ -314,7 +313,7 @@ as:
concept_found = res[0].value
assert sheerka.isinstance(concept_found, greetings)
assert concept_found.get_value("a") == "foo"
assert concept_found.get_metadata().need_validation
assert concept_found.get_hints().need_validation
res = sheerka.evaluate_user_input("greetings")
assert len(res) == 1
@@ -322,7 +321,7 @@ as:
concept_found = res[0].value
assert sheerka.isinstance(concept_found, greetings)
assert concept_found.get_value("a") == NotInit
assert not concept_found.get_metadata().need_validation
assert not concept_found.get_hints().need_validation
@pytest.mark.parametrize("desc, definitions", [
("Simple form", [
@@ -681,14 +680,9 @@ as:
assert res[0].body == 22
res = sheerka.evaluate_user_input("twenty three")
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.MULTIPLE_ERRORS)
assert sheerka.has_error(context, res, __type=BuiltinConcepts.CONDITION_FAILED)
res = sheerka.evaluate_user_input("eval twenty three")
assert len(res) == 1
assert not res[0].status
assert sheerka.has_error(context, res, __type=BuiltinConcepts.CONDITION_FAILED)
def test_i_can_manage_some_type_of_infinite_recursion(self):
@@ -725,20 +719,20 @@ as:
assert res[0].body == "hello world"
res = sheerka.evaluate_user_input("foo baz")
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONDITION_FAILED)
assert sheerka.has_error(self.get_context(sheerka), res, __type=BuiltinConcepts.CONDITION_FAILED)
res = sheerka.evaluate_user_input("eval foo baz")
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONDITION_FAILED)
assert sheerka.has_error(self.get_context(sheerka), res, __type=BuiltinConcepts.CONDITION_FAILED)
res = sheerka.evaluate_user_input("foobar")
res = sheerka.evaluate_user_input("c:foobar:") # where clause must not be evaluated
assert len(res) == 1
assert res[0].status
res = sheerka.evaluate_user_input("eval foobar")
res = sheerka.evaluate_user_input("foobar") # where clause must not be evaluated
assert len(res) == 1
assert res[0].status
res = sheerka.evaluate_user_input("eval foobar") # where clause is forced
assert len(res) == 1 # error
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONDITION_FAILED)
@@ -835,7 +829,6 @@ as:
def test_concepts_parsed_by_atom_parser_must_not_be_evaluated(self):
definitions = [
"def concept mult from a mult b as a * b",
"def concept a mult b as a * b",
]
sheerka = self.init_scenario(definitions)
@@ -844,9 +837,17 @@ as:
assert res[0].status
assert isinstance(res[0].body, Concept)
# res = sheerka.evaluate_user_input("eval a mult b")
# assert res[0].status
# assert isinstance(res[0].body, Concept)
@pytest.mark.skip("Need to be fixed")
def test_concepts_parsed_by_atom_parser_must_not_be_evaluated_2(self):
definitions = [
"def concept a mult b as a * b",
]
sheerka = self.init_scenario(definitions)
res = sheerka.evaluate_user_input("eval a mult b")
assert res[0].status
assert isinstance(res[0].body, Concept)
def test_i_can_express_comparison(self):
definitions = [
@@ -1059,8 +1060,7 @@ as:
"def concept foo",
"def concept number",
"set_isa(one, number)",
"def concept q from q ? as question(q)",
"set_auto_eval(q)",
"def concept q from q ? as question(q) auto_eval True",
"def concept is_a from x is a y as isa(x,y) pre in_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)",
"set_is_greater_than(BuiltinConcepts.PRECEDENCE, c:is_a:, c:q:, 'Sya')",
]
@@ -1069,18 +1069,16 @@ as:
res = sheerka.evaluate_user_input("one is a number ?") # automatically evaluated
assert len(res) == 1
assert res[0].status
assert res[0].body == True # the body MUST be a boolean
assert isinstance(res[0].body, bool) and res[0].body # the body MUST be a boolean
res = sheerka.evaluate_user_input("foo is a number ?") # automatically evaluated
assert len(res) == 1
assert res[0].status
assert res[0].body == False # the body MUST be a boolean
assert isinstance(res[0].body, bool) and not res[0].body # the body MUST be a boolean
# x is a y is supposed to be a question. It cannot be used if not in a context of a question
res = sheerka.evaluate_user_input("one is a number")
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONDITION_FAILED)
assert sheerka.has_error(self.get_context(sheerka), res, __type=BuiltinConcepts.CONDITION_FAILED)
def test_i_can_evaluate_source_code_with_concept(self):
init = [
@@ -1299,7 +1297,7 @@ as:
assert sheerka.objvalue(res[0].body.get_value("qty")) == 2
def test_i_can_implement_the_concept_and(self):
# Normally, redefining and leads to a circular ref between the concept and the python
# Normally, redefining 'and' leads to a circular ref between the concept and the python
init = [
"def concept x and y as x and y",
"set_is_lesser(__PRECEDENCE, c:x and y:, 'Sya')",
@@ -1362,3 +1360,47 @@ as:
res = sheerka.evaluate_user_input("eval foo")
assert sheerka.has_error(context, res, __type="MethodAccessError")
def test_i_can_use_function_parser_and_complex_concept(self):
init = [
"def concept the x ret x",
"def concept foo",
"def concept bar",
]
sheerka = self.init_scenario(init)
res = sheerka.evaluate_user_input("smart_get_attr(the foo, bar)")
assert len(res) == 1
assert res[0].status
def test_i_can_get_smart_get_attr_for_complex_concepts(self):
init = [
"def concept q from q ? as question(q) auto_eval True",
"set_is_lesser(__PRECEDENCE, q, 'Sya')",
"def concept a x ret x where isinstance(x, Concept)",
"def concept the x ret memory(x)",
"def concept short",
"def concept color",
"def concept red",
"def concept blue",
"def concept adjective",
"set_isa(red, color)",
"set_isa(blue, color)",
"set_isa(color, adjective)",
"def concept what is the x of y pre is_question() as smart_get_attr(y, x)",
"def concept qualify x from bnf adjective x as set_attr(x, c:adjective:, adjective) ret x",
"eval a red short",
]
sheerka = self.init_scenario(init)
res = sheerka.evaluate_user_input("what is the color of the short ?")
assert len(res) == 1
assert res[0].status
assert res[0].value == "red"
res = sheerka.evaluate_user_input("eval a blue short")
res = sheerka.evaluate_user_input("what is the color of the short ?")
assert len(res) == 1
assert res[0].status
assert res[0].value == "blue"