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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user