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:
@@ -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"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaNonRegMemory2(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_select_the_correct_concept_when_ambiguity(self):
|
||||
init = [
|
||||
"def concept foo",
|
||||
"def concept x is a y pre is_question() as isa(x,y)",
|
||||
"def concept x is a foo pre is_question() as isinstance(x, foo)",
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
|
||||
res = sheerka.evaluate_user_input("question(foo is a foo)")
|
||||
|
||||
# assert len(res) == 1
|
||||
# assert res[0].status
|
||||
# assert res[0].value
|
||||
Reference in New Issue
Block a user