Fixed #100 : SheerkaAdmin: Add builtins() command

Fixed #99 : SheerkaQueryManager: I can manage contains predicate when filtering objects
Fixed #97 : ERROR: list indices must be integers or slices, not Concept
Fixed #96 : SequenceNodeParser: SequenceNodeParser must correctly handle concept definition
Fixed #95 : ResolveAmbiguity must not remove concepts that do not require evaluation
Fixed #94 : Concepts with the same key are lost when new ontology
Fixed #93 : Introduce BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED
Fixed #92 : ExpressionParser: Implement compile_disjunctions()
Fixed #91 : Implement get_concepts_complexity(context, concepts, concept_parts)
Fixed #90 : ResolveAmbiguity : where predicate is not used to resolve ambiguity
Fixed #89 : ResolveAmbiguityEvaluator: Concepts embedded in ConceptNode are not resolved
Fixed #88: SyaNodeParser: Parse multiple parameters when some of the are not recognized
Fixed #87: SyaNodeParser : Parse the multiple parameters
This commit is contained in:
2021-07-31 08:52:00 +02:00
parent 7dcaa9c111
commit e69745adc8
70 changed files with 1561 additions and 455 deletions
@@ -1,10 +1,10 @@
import pytest
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
from core.concept import Concept
from core.tokenizer import Tokenizer
from evaluators.AddConceptInSetEvaluator import AddConceptInSetEvaluator
from parsers.DefConceptParser import IsaConceptNode, NameNode
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -51,7 +51,20 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
assert res.value.body == "bar"
def test_i_can_add_concept_to_a_set_of_concept(self):
sheerka, context, foo, bar = self.init_test().with_concepts("foo", "bar", create_new=True).unpack()
sheerka, context, foo, bar = self.init_test().with_concepts("foo", "bar").unpack()
ret_val = get_isa_ret_val("foo", "bar")
res = AddConceptInSetEvaluator().eval(context, ret_val)
foo = res.body # get the created instance
assert res.status
assert context.sheerka.isinstance(res.value, foo.key)
assert context.sheerka.isa(foo, bar)
assert foo.get_prop(BuiltinConcepts.ISA) == {bar}
def test_i_can_add_concept_to_a_set_of_concept_when_global_truth_is_activated(self):
sheerka, context, foo, bar = self.init_test(global_truth=True).with_concepts("foo", "bar").unpack()
ret_val = get_isa_ret_val("foo", "bar")
res = AddConceptInSetEvaluator().eval(context, ret_val)
@@ -65,19 +78,18 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
assert foo.get_prop(BuiltinConcepts.ISA) == {bar}
def test_i_can_add_bnf_concept_to_a_set_of_concept(self):
def test_i_can_add_bnf_concept_to_a_set_of_concept_when_global_truth_is_activated(self):
"""
This test is the reason why I have started the whole eval on demand stuff
Sheerka tries to evaluate the body but it can't (as a and b are not defined)
So 'foo' cannot be put is set
:return:
"""
sheerka, context, one, two, foo, bar = self.init_test().with_concepts(
sheerka, context, one, two, foo, bar = self.init_test(global_truth=True).with_concepts(
"one",
"two",
Concept("foo", definition="(one|two)=a 'plus' (one|two)=b", body="a + b").def_var("a").def_var("b"),
"bar",
create_new=True).unpack()
"bar").unpack()
ret_val = get_isa_ret_val("foo", "bar")
res = AddConceptInSetEvaluator().eval(context, ret_val)
@@ -103,11 +115,25 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
ret_val = get_isa_ret_val("foo", "bar")
res = AddConceptInSetEvaluator().eval(context, ret_val)
assert res.status
assert context.sheerka.isinstance(res.value, foo.key)
def test_i_can_add_concept_with_a_body_to_a_set_of_concept_when_global_truth_is_activated(self):
context = self.get_context(global_truth=True)
foo = Concept("foo", body="1")
context.sheerka.create_new_concept(context, foo)
bar = Concept("bar")
context.sheerka.create_new_concept(context, bar)
ret_val = get_isa_ret_val("foo", "bar")
res = AddConceptInSetEvaluator().eval(context, ret_val)
assert res.status
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
def test_i_cannot_add_the_same_concept_twice(self):
sheerka, context, foo, bar = self.init_test().with_concepts("foo", "bar", create_new=True).unpack()
sheerka, context, foo, bar = self.init_test(global_truth=True).with_concepts("foo", "bar").unpack()
ret_val = get_isa_ret_val("foo", "bar")
AddConceptInSetEvaluator().eval(context, ret_val)
+2 -1
View File
@@ -43,7 +43,8 @@ class TestExpressionEvaluator(TestUsingMemoryBasedSheerka):
assert not res.body
# second time
sheerka.set_isa(context, one, number)
global_truth_context = self.get_context(sheerka, global_truth=True)
sheerka.set_isa(global_truth_context, one, number)
parsed_return_value = ExpressionParser().parse(context, ParserInput("one is a number"))
res = evaluator.eval(context, parsed_return_value)
assert res.status
@@ -0,0 +1,49 @@
import pytest
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
from core.concept import Concept
from evaluators.PrepareEvalGlobalTruthEvaluator import PrepareEvalGlobalTruthEvaluator
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
r = ReturnValueConcept
class TestPrepareEvalGlobalTruthEvaluator(TestUsingMemoryBasedSheerka):
@pytest.mark.parametrize("ret_val, expected", [
(r("name", True, UserInputConcept("global_truth(1 + 1)")), True),
(r("name", True, UserInputConcept(" global_truth(1 + 1) ")), True),
(r("name", True, UserInputConcept("global_truth()")), False),
(r("name", True, UserInputConcept("1+1")), False),
(r("name", True, UserInputConcept("")), False),
(r("name", True, UserInputConcept("global_truth(")), False),
(r("name", True, UserInputConcept(")")), False),
(r("name", True, UserInputConcept([])), False),
(r("name", True, Concept("foo")), False),
(r("name", True, "not a concept"), False),
(r("name", False, UserInputConcept("global_truth(1 + 1)")), False),
])
def test_i_can_match(self, ret_val, expected):
context = self.get_context()
assert PrepareEvalGlobalTruthEvaluator().matches(context, ret_val) == expected
@pytest.mark.parametrize("ret_val, expected", [
(r("name", True, UserInputConcept("global_truth(1 + 1)")), "1 + 1"),
(r("name", True, UserInputConcept(" global_truth( 1 + 1 ) ")), "1 + 1"),
])
def test_i_can_eval(self, ret_val, expected):
context = self.get_context()
sheerka = context.sheerka
prepare_evaluator = PrepareEvalGlobalTruthEvaluator()
prepare_evaluator.matches(context, ret_val)
res = prepare_evaluator.eval(context, ret_val)
assert res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.USER_INPUT)
assert res.body.body == expected
assert BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED in context.protected_hints
assert BuiltinConcepts.EVAL_BODY_REQUESTED in context.protected_hints
assert BuiltinConcepts.RETURN_BODY_REQUESTED in context.protected_hints
@@ -1,12 +1,15 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaExecute import ParserInput
from evaluators.BaseEvaluator import BaseEvaluator
from evaluators.ResolveAmbiguityEvaluator import ResolveAmbiguityEvaluator
from parsers.ExactConceptParser import ExactConceptParser
from parsers.SyaNodeParser import SyaNodeParser
from tests.BaseTest import BaseTest
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
pretval = BaseTest.pretval
@@ -21,6 +24,37 @@ class TestResolveAmbiguityEvaluator(TestUsingMemoryBasedSheerka):
context = self.get_context()
assert ResolveAmbiguityEvaluator().matches(context, return_values) == expected
def test_i_can_match_when_the_input_comes_from_an_evaluator(self):
ret_val1 = pretval(Concept("foo"), source="source", parser=BaseEvaluator.get_name("evaluator"))
ret_val2 = pretval(Concept("bar"), source="source", parser=BaseEvaluator.get_name("evaluator"))
return_values = [ret_val1, ret_val2]
context = self.get_context()
assert ResolveAmbiguityEvaluator().matches(context, return_values)
def test_i_can_match_when_concept_nodes(self):
sheerka, context, a, foo_1, foo_2 = self.init_concepts(
Concept("a"),
Concept("foo x").def_var("x"),
Concept("foo y").def_var("y"),
create_new=True
)
return_values = SyaNodeParser().parse(context, ParserInput("foo a"))
assert ResolveAmbiguityEvaluator().matches(context, return_values)
def test_i_can_match_when_concept_node_mixed_with_concept(self):
sheerka, context, a, foo_1, foo_a = self.init_concepts(
Concept("a"),
Concept("foo x").def_var("x"),
Concept("foo a"),
create_new=True
)
sya_return_value = SyaNodeParser().parse(context, ParserInput("foo a"))
assert ResolveAmbiguityEvaluator().matches(context, [sya_return_value, pretval(foo_a, source="foo a")])
def test_i_can_manage_when_no_source(self):
context = self.get_context()
return_values = [BaseTest.retval(Concept("foo"))]
@@ -53,6 +87,44 @@ class TestResolveAmbiguityEvaluator(TestUsingMemoryBasedSheerka):
return_values[2],
]
@pytest.mark.parametrize("concepts, expected", [
([Concept("c1"), Concept("c2", where="True")], "c2"),
([Concept("c1"), Concept("c2", pre="True")], "c2"),
([Concept("c1"), Concept("c2", where="False")], "c1"),
([Concept("c1"), Concept("c2", pre="False")], "c1"),
([Concept("c1", pre="True"), Concept("c2", where="True")], "c1"),
([Concept("c1", pre="False"), Concept("c2", where="True")], "c2"),
([Concept("c1", pre="False"), Concept("c2", where="False")], BuiltinConcepts.NO_RESULT),
])
def test_i_can_eval_2(self, concepts, expected):
context = self.get_context()
return_values = [self.pretval(c, source="foo") for c in concepts]
evaluator = ResolveAmbiguityEvaluator()
evaluator.matches(context, return_values)
res = evaluator.eval(context, return_values)
assert len(res) == 1
if expected != BuiltinConcepts.NO_RESULT:
selected_concept = res[0].body.body
assert selected_concept.name == expected
else:
assert res[0].body == BuiltinConcepts.NO_RESULT
@pytest.mark.parametrize("concepts", [
[Concept("c1"), Concept("c2")],
[Concept("c1", pre="True"), Concept("c2", pre="True")],
])
def test_i_can_eval_when_same_complexity(self, concepts):
context = self.get_context()
return_values = [self.pretval(c, "foo") for c in concepts]
evaluator = ResolveAmbiguityEvaluator()
evaluator.matches(context, return_values)
res = evaluator.eval(context, return_values)
assert res is None
def test_i_can_eval_all_fail(self):
context = self.get_context()
return_values = [
@@ -91,3 +163,70 @@ class TestResolveAmbiguityEvaluator(TestUsingMemoryBasedSheerka):
res = evaluator.eval(context, return_values)
assert res is None
def test_i_can_eval_to_the_simplest_concept(self):
"""
def concept foo x where x
def concept foo a
When the input is foo a, 'foo x' must be discarded as concept 'foo a' is more accurate
:return:
"""
sheerka, context, a, foo_1, foo_a = self.init_concepts(
Concept("a"),
Concept("foo x").def_var("x"),
Concept("foo a"),
create_new=True
)
sya_return_value = SyaNodeParser().parse(context, ParserInput("foo a"))
exact_concept_return_value = pretval(foo_a, source="foo a")
return_values = [sya_return_value, exact_concept_return_value]
evaluator = ResolveAmbiguityEvaluator()
evaluator.matches(context, return_values)
res = evaluator.eval(context, return_values)
assert len(res) == 1
assert res[0].who == evaluator.name
assert res[0].body == exact_concept_return_value.body
assert res[0].parents == return_values
def test_i_can_eval_to_the_simplest_concept_when_concept_nodes(self):
"""
Same explanation than test_i_can_eval_to_the_simplest_concept()
:return:
"""
sheerka, context, a, b, foo_1, foo_2 = self.init_concepts(
Concept("a"),
Concept("b"),
Concept("foo x y").def_var("x").def_var("y"),
Concept("foo a x").def_var("x"),
create_new=True
)
return_values = SyaNodeParser().parse(context, ParserInput("foo a b"))
evaluator = ResolveAmbiguityEvaluator()
evaluator.matches(context, return_values)
res = evaluator.eval(context, return_values)
assert len(res) == 1
assert res[0].who == evaluator.name
assert sheerka.isinstance(res[0].body.body[0].concept, foo_2)
def test_i_can_eval_when_non_instance_concepts(self):
sheerka, context, foo_1, foo_2 = self.init_concepts(
Concept("foo x", body="1", pre="True").def_var("x"),
Concept("foo x", body="2", pre="True").def_var("x"),
create_new=True
)
exact_parser_return_values = ExactConceptParser().parse(context, ParserInput("c:foo x:"))
evaluator = ResolveAmbiguityEvaluator()
evaluator.matches(context, exact_parser_return_values)
res = evaluator.eval(context, exact_parser_return_values)
assert res is None # means that there is nothing to resolve as the concepts are not instances
@@ -185,14 +185,3 @@ class TestValidateConceptEvaluator(TestUsingMemoryBasedSheerka):
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.FILTERED)
assert res.body.body == ret_val.body.body
def test_i_can_manage_infinite_recursion(self):
sheerka, context, a_and_b = self.init_concepts(
Concept("a and b", where="is_question()", body="a and b").def_var("a").def_var("b"),
create_new=True)
evaluator = ValidateConceptEvaluator()
ret_val = pr_ret_val(a_and_b)
res = evaluator.eval(context, ret_val)
assert res is None # infinite recursion detected, res is None to drop the validator