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 class TestResolveAmbiguityEvaluator(TestUsingMemoryBasedSheerka): @pytest.mark.parametrize("return_values, expected", [ ([pretval(Concept("foo"), source="source"), pretval(Concept("bar"), source="source")], True), ([pretval(Concept("foo"), source="source"), pretval(Concept("bar"), source="source", status=False)], False), ([pretval(Concept("foo"), source="source1"), pretval(Concept("bar"), source="source2")], False), ]) def test_i_can_match(self, return_values, expected): 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"))] assert not ResolveAmbiguityEvaluator().matches(context, return_values) def test_i_can_eval(self): context = self.get_context() return_values = [ self.pretval(Concept("hello a").def_var("a", "world"), "hello word"), self.pretval(Concept("hello world"), "hello word"), self.pretval(Concept("hello world", pre="False"), "hello word"), self.retval(Concept("not a parser result")), self.retval(Concept("status is false"), status=False), self.pretval(Concept("false parser result"), status=False), ] evaluator = ResolveAmbiguityEvaluator() evaluator.matches(context, return_values) res = evaluator.eval(context, return_values) assert len(res) == 1 resolved = res[0] assert resolved.who == evaluator.name assert resolved.body == return_values[1].body assert resolved.parents == [ return_values[0], return_values[1], 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 = [ self.pretval(Concept("hello world", pre="2 < 1"), "hello word"), self.pretval(Concept("hello world", pre="False"), "hello word"), ] evaluator = ResolveAmbiguityEvaluator() evaluator.matches(context, return_values) res = evaluator.eval(context, return_values) assert len(res) == 1 resolved = res[0] assert resolved.who == evaluator.name assert resolved.body == BuiltinConcepts.NO_RESULT assert resolved.parents == [ return_values[0], return_values[1], ] def test_i_can_eval_all_pass(self): """ If they all pass, that means that no concept was reduced -> We need to act like resolve ambiguity was not called :return: """ context = self.get_context() return_values = [ self.pretval(Concept("hello world 1"), "hello word"), self.pretval(Concept("hello world 2"), "hello word"), ] evaluator = ResolveAmbiguityEvaluator() evaluator.matches(context, return_values) 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