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:
+19
-5
@@ -104,7 +104,7 @@ class BaseTest:
|
||||
def get_sheerka(self, **kwargs) -> Sheerka:
|
||||
pass
|
||||
|
||||
def get_context(self, sheerka=None, eval_body=False, eval_where=False, message=""):
|
||||
def get_context(self, sheerka=None, eval_body=False, eval_where=False, global_truth=False, message=""):
|
||||
context = ExecutionContext("test",
|
||||
Event(message=message),
|
||||
sheerka or self.get_sheerka(),
|
||||
@@ -114,20 +114,29 @@ class BaseTest:
|
||||
context.protected_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
if eval_where:
|
||||
context.protected_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
if global_truth:
|
||||
context.protected_hints.add(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
return context
|
||||
|
||||
@staticmethod
|
||||
def get_init_test_args(**kwargs):
|
||||
return {k: v for k, v in kwargs.items() if k in ["cache_only", "ontology", "eval_body", "eval_where"]}
|
||||
return {k: v for k, v in kwargs.items() if k in ["cache_only",
|
||||
"ontology",
|
||||
"eval_body",
|
||||
"eval_where",
|
||||
"global_truth"]}
|
||||
|
||||
@staticmethod
|
||||
def get_with_concepts_args(**kwargs):
|
||||
return {k: v for k, v in kwargs.items() if k in ["create_new"]}
|
||||
|
||||
def init_test(self, cache_only=None, ontology=None, eval_body=False, eval_where=False):
|
||||
def init_test(self, cache_only=None, ontology=None, eval_body=False, eval_where=False, global_truth=False):
|
||||
sheerka = self.get_sheerka(cache_only=cache_only, ontology=ontology)
|
||||
context = self.get_context(sheerka=sheerka, eval_body=eval_body, eval_where=eval_where)
|
||||
context = self.get_context(sheerka=sheerka,
|
||||
eval_body=eval_body,
|
||||
eval_where=eval_where,
|
||||
global_truth=global_truth)
|
||||
|
||||
return InitTestHelper(sheerka, context)
|
||||
|
||||
@@ -255,14 +264,19 @@ class BaseTest:
|
||||
concept.get_metadata().variables[k] = v
|
||||
return concept
|
||||
|
||||
def init_scenario(self, init_expressions):
|
||||
def init_scenario(self, init_expressions, global_truth=False):
|
||||
sheerka = self.get_sheerka()
|
||||
if global_truth:
|
||||
sheerka.add_to_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
for expression in init_expressions:
|
||||
res = sheerka.evaluate_user_input(expression)
|
||||
assert len(res) == 1, f"Failed to execute '{expression}'"
|
||||
assert res[0].status, f"Error while executing '{expression}'"
|
||||
|
||||
if global_truth:
|
||||
sheerka.remove_fom_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
return sheerka
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -7,9 +7,9 @@ from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_add_concepts(self):
|
||||
sheerka, context, man, human, male, driver, licence, car = self.init_concepts(
|
||||
sheerka, context, man, human, male, driver, licence, car = self.init_test(global_truth=True).with_concepts(
|
||||
"man", "human", "male",
|
||||
"driver", "licence", "car")
|
||||
"driver", "licence", "car").unpack()
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("man"), human)
|
||||
sheerka.set_isa(context, sheerka.new("man"), male)
|
||||
@@ -23,8 +23,8 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
BuiltinConcepts.HASA: {car, licence}, }
|
||||
|
||||
def test_can_add_concepts_when_property_already_exist(self):
|
||||
sheerka, context, man, human, king, male = self.init_concepts(
|
||||
"man", "human", "king", "male")
|
||||
sheerka, context, man, human, king, male = self.init_test(global_truth=True).with_concepts(
|
||||
"man", "human", "king", "male").unpack()
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("man"), human)
|
||||
sheerka.set_isa(context, sheerka.new("king"), male)
|
||||
@@ -35,9 +35,9 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
assert res.get_metadata().props == {BuiltinConcepts.ISA: {male, human}}
|
||||
|
||||
def test_i_can_subtract_concepts(self):
|
||||
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_concepts(
|
||||
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_test(global_truth=True).with_concepts(
|
||||
"foo", "bar",
|
||||
"isa1", "isa2", "has1", "has2")
|
||||
"isa1", "isa2", "has1", "has2").unpack()
|
||||
|
||||
new_foo = sheerka.new("foo")
|
||||
sheerka.set_isa(context, new_foo, isa1)
|
||||
@@ -61,9 +61,10 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
BuiltinConcepts.HASA: {hasa2}, }
|
||||
|
||||
def test_i_can_recognize_myself_when_using_sdp_repository(self):
|
||||
sheerka, context, foo, isa1, hasa1, = self.init_test(cache_only=False). \
|
||||
with_concepts("foo", "isa1", "has1", create_new=True). \
|
||||
unpack()
|
||||
sheerka, context, foo, isa1, hasa1, = self.init_test(cache_only=False, global_truth=True).with_concepts(
|
||||
"foo",
|
||||
"isa1",
|
||||
"has1", create_new=True).unpack()
|
||||
sheerka.om.commit(context)
|
||||
|
||||
new_foo = sheerka.new("foo")
|
||||
@@ -74,7 +75,10 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.recognize(new_foo, all_scores=True) == [ConceptScore(1, new_foo, new_foo)]
|
||||
|
||||
def test_i_can_recognize_myself_when_not_using_sdp_repository(self):
|
||||
sheerka, context, foo, isa1, hasa1, = self.init_concepts("foo", "isa1", "has1")
|
||||
sheerka, context, foo, isa1, hasa1, = self.init_test(global_truth=True).with_concepts(
|
||||
"foo",
|
||||
"isa1",
|
||||
"has1").unpack()
|
||||
|
||||
new_foo = sheerka.new("foo")
|
||||
sheerka.set_isa(context, new_foo, isa1)
|
||||
@@ -100,9 +104,9 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.recognize(Concept(), all_scores=True) == []
|
||||
|
||||
def test_i_can_recognize_multiple_concepts_with_the_proper_score(self):
|
||||
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_concepts(
|
||||
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_test(global_truth=True).with_concepts(
|
||||
"foo", "bar",
|
||||
"isa1", "isa2", "has1", "has2")
|
||||
"isa1", "isa2", "has1", "has2").unpack()
|
||||
|
||||
new_foo = sheerka.new("foo")
|
||||
sheerka.set_isa(context, new_foo, isa1)
|
||||
@@ -131,9 +135,9 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
ConceptScore(0.5, sheerka.new("bar"), to_recognize)]
|
||||
|
||||
def test_i_can_recognize_if_all_scores_is_disabled(self):
|
||||
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_concepts(
|
||||
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_test(global_truth=True).with_concepts(
|
||||
"foo", "bar",
|
||||
"isa1", "isa2", "has1", "has2")
|
||||
"isa1", "isa2", "has1", "has2").unpack()
|
||||
|
||||
new_foo = sheerka.new("foo")
|
||||
sheerka.set_isa(context, new_foo, isa1)
|
||||
@@ -153,9 +157,9 @@ class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
|
||||
assert res == ConceptScore(1.0, sheerka.new("bar"), to_recognize)
|
||||
|
||||
def test_i_can_recognize_if_all_scores_is_disabled_but_multiple_high_scores(self):
|
||||
sheerka, context, foo, bar, isa1, hasa1 = self.init_concepts(
|
||||
sheerka, context, foo, bar, isa1, hasa1 = self.init_test(global_truth=True).with_concepts(
|
||||
"foo", "bar",
|
||||
"isa1", "has1")
|
||||
"isa1", "has1").unpack()
|
||||
|
||||
new_foo = sheerka.new("foo")
|
||||
sheerka.set_isa(context, new_foo, isa1)
|
||||
|
||||
@@ -1105,13 +1105,14 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
Concept("hundreds", definition="number hundred"),
|
||||
)
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("one"), number)
|
||||
sheerka.set_isa(context, sheerka.new("two"), number)
|
||||
sheerka.set_isa(context, sheerka.new("twenty"), number)
|
||||
sheerka.set_isa(context, sheerka.new("thirty"), number)
|
||||
sheerka.set_isa(context, sheerka.new("hundred"), number)
|
||||
sheerka.set_isa(context, sheerka.new("twenties"), number)
|
||||
sheerka.set_isa(context, sheerka.new("hundreds"), number)
|
||||
global_truth_context = self.get_context(sheerka, global_truth=True)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("one"), number)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("two"), number)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("twenty"), number)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("thirty"), number)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("hundred"), number)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("twenties"), number)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("hundreds"), number)
|
||||
|
||||
sheerka.clear_bnf_definition() # reset all the grammar to simulate Sheerka restart
|
||||
|
||||
@@ -1129,12 +1130,12 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
def test_i_can_resolve_when_concepts_have_multiple_levels_of_sets(self):
|
||||
sheerka, context, adjective, color, red, qualified_table = self.init_concepts(
|
||||
sheerka, context, adjective, color, red, qualified_table = self.init_test(global_truth=True).with_concepts(
|
||||
"adjective",
|
||||
"color",
|
||||
"red",
|
||||
Concept("qualified table", definition="adjective 'table'"),
|
||||
)
|
||||
).unpack()
|
||||
|
||||
sheerka.set_isa(context, color, adjective)
|
||||
sheerka.set_isa(context, red, color)
|
||||
@@ -1404,7 +1405,8 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_cannot_smart_get_attr_when_attribute_does_not_exist(self):
|
||||
sheerka, context, adjective, color, red, size, table = self.init_concepts("adjective",
|
||||
"color",
|
||||
Concept("red", body="red").auto_init(),
|
||||
Concept("red",
|
||||
body="red").auto_init(),
|
||||
"size",
|
||||
"table",
|
||||
create_new=True)
|
||||
|
||||
@@ -391,8 +391,8 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
:return:
|
||||
"""
|
||||
sheerka, context, predicate, foo = self.init_concepts(
|
||||
Concept("Sometimes True", body="in_context('a')"),
|
||||
Concept("foo", pre="c:Sometimes True:"))
|
||||
Concept("Sometimes True", body="in_context('a')", pre="is_question()"),
|
||||
Concept("foo", pre="Sometimes True"))
|
||||
|
||||
foo1 = sheerka.new("foo")
|
||||
foo1 = sheerka.evaluate_concept(context, foo1) # 'a' is not in context, so it fails
|
||||
@@ -400,7 +400,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
context2 = self.get_context(sheerka)
|
||||
context2.add_to_protected_hints('a')
|
||||
foo2 = sheerka.new("foo")
|
||||
foo2 = sheerka.evaluate_concept(context2, foo2) # 'a' in context + new instance of 'Sometimes True'
|
||||
foo2 = sheerka.evaluate_concept(context2, foo2) # 'a' is now in context
|
||||
|
||||
assert sheerka.isinstance(foo1, BuiltinConcepts.CONDITION_FAILED)
|
||||
assert sheerka.isinstance(foo2, "foo")
|
||||
|
||||
@@ -7,6 +7,33 @@ class TestSheerkaHasAManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_set_hasa(self):
|
||||
sheerka, context, king, kingdom = self.init_concepts("king", "kingdom")
|
||||
|
||||
king_instance = sheerka.new("king")
|
||||
res = sheerka.set_hasa(context, king_instance, kingdom)
|
||||
assert res.status
|
||||
|
||||
# when global truth is not activated, only the current instance is modified
|
||||
another_king = sheerka.get_by_key("king")
|
||||
assert not another_king.get_prop(BuiltinConcepts.HASA) == {kingdom}
|
||||
assert not sheerka.hasa(another_king, kingdom)
|
||||
|
||||
def test_i_cannot_set_the_same_attribute_twice(self):
|
||||
sheerka, context, king, kingdom = self.init_concepts("king", "kingdom")
|
||||
|
||||
king_instance = sheerka.new("king")
|
||||
sheerka.set_hasa(context, king_instance, kingdom)
|
||||
res = sheerka.set_hasa(context, king_instance, kingdom)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.PROPERTY_ALREADY_DEFINED)
|
||||
assert res.body.property_name == BuiltinConcepts.HASA
|
||||
assert res.body.property_value == kingdom
|
||||
assert res.body.concept == king_instance
|
||||
|
||||
def test_i_can_set_hasa_when_global_truth_is_activated(self):
|
||||
sheerka, context, king, kingdom = self.init_test(global_truth=True).with_concepts(
|
||||
"king",
|
||||
"kingdom").unpack()
|
||||
|
||||
res = sheerka.set_hasa(context, sheerka.new("king"), kingdom)
|
||||
assert res.status
|
||||
|
||||
@@ -16,8 +43,10 @@ class TestSheerkaHasAManager(TestUsingMemoryBasedSheerka):
|
||||
# check that the definition of the concept has been updated
|
||||
assert sheerka.hasa(sheerka.new("king"), kingdom)
|
||||
|
||||
def test_i_cannot_set_the_same_attribute_twice(self):
|
||||
sheerka, context, king, kingdom = self.init_concepts("king", "kingdom")
|
||||
def test_i_cannot_set_the_same_attribute_twice_when_global_truth_is_activated(self):
|
||||
sheerka, context, king, kingdom = self.init_test(global_truth=True).with_concepts(
|
||||
"king",
|
||||
"kingdom").unpack()
|
||||
|
||||
sheerka.set_hasa(context, sheerka.new("king"), kingdom)
|
||||
res = sheerka.set_hasa(context, sheerka.new("king"), kingdom)
|
||||
|
||||
@@ -86,15 +86,46 @@ class TestSheerkaIsAManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_isa(self):
|
||||
sheerka, context, blue, color = self.init_concepts(Concept("blue"), Concept("color"))
|
||||
|
||||
assert not sheerka.isa(blue, color)
|
||||
|
||||
sheerka.set_isa(context, blue, color)
|
||||
assert sheerka.isa(blue, color)
|
||||
blue_instance = sheerka.new("blue")
|
||||
assert not sheerka.isa(blue_instance, color)
|
||||
|
||||
sheerka.set_isa(context, blue_instance, color)
|
||||
assert sheerka.isa(blue_instance, color)
|
||||
|
||||
# isa tests the id of a concept, not it's content
|
||||
another_color_instance_but_with_a_body = sheerka.new(color, body="a body")
|
||||
assert sheerka.isa(blue, another_color_instance_but_with_a_body)
|
||||
assert sheerka.isa(blue_instance, another_color_instance_but_with_a_body)
|
||||
|
||||
# isa, when EVAL_GLOBAL_TRUTH_REQUESTED is not activated, only affect the current concept
|
||||
another_blue_instance = sheerka.new("blue")
|
||||
assert not sheerka.isa(another_blue_instance, color)
|
||||
|
||||
# when EVAL_GLOBAL_TRUTH_REQUESTED is not activated, color is not a set
|
||||
assert not sheerka.isinset(blue_instance, color)
|
||||
assert not sheerka.isaset(context, color)
|
||||
|
||||
def test_isa_global_truth(self):
|
||||
sheerka, context, blue, color = self.init_concepts(Concept("blue"), Concept("color"))
|
||||
|
||||
blue_instance = sheerka.new("blue")
|
||||
assert not sheerka.isa(blue_instance, color)
|
||||
assert not sheerka.isaset(context, color)
|
||||
assert not sheerka.isinset(blue_instance, color)
|
||||
|
||||
context.add_to_private_hints(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
sheerka.set_isa(context, blue_instance, color)
|
||||
assert sheerka.isa(blue_instance, color)
|
||||
assert sheerka.isaset(context, color)
|
||||
assert sheerka.isinset(blue_instance, color)
|
||||
|
||||
# all blue instances are now a color
|
||||
another_blue_instance = sheerka.new("blue")
|
||||
assert sheerka.isa(another_blue_instance, color)
|
||||
assert sheerka.isaset(context, color)
|
||||
assert sheerka.isinset(another_blue_instance, color)
|
||||
|
||||
def test_isaset(self):
|
||||
sheerka, context, group, foo = self.init_concepts(Concept("group"), Concept("foo"))
|
||||
@@ -246,13 +277,28 @@ class TestSheerkaIsAManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
foo = sheerka.new(foo.key) # new instance
|
||||
sheerka.set_isa(context, foo, all_foo)
|
||||
sheerka.set_isa(context, foo, all_bar)
|
||||
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == {all_foo, all_bar}
|
||||
assert sheerka.isa(foo, all_foo)
|
||||
assert sheerka.isa(foo, all_bar)
|
||||
|
||||
def test_a_concept_can_be_in_multiple_sets_when_global_truth_is_activated(self):
|
||||
sheerka, context, foo, all_foo, all_bar = self.init_test(global_truth=True).with_concepts(
|
||||
Concept("foo"),
|
||||
Concept("all_foo"),
|
||||
Concept("all_bar"),
|
||||
create_new=True).unpack()
|
||||
|
||||
foo = sheerka.new(foo.key) # new instance
|
||||
sheerka.set_isa(context, foo, all_foo)
|
||||
foo = sheerka.new(foo.key) # new instance
|
||||
sheerka.set_isa(context, foo, all_bar)
|
||||
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == {all_foo, all_bar}
|
||||
assert sheerka.isa(foo, all_foo)
|
||||
assert sheerka.isa(foo, all_bar)
|
||||
|
||||
assert sheerka.isinset(foo, all_foo)
|
||||
assert sheerka.isinset(foo, all_bar)
|
||||
assert sheerka.isaset(context, all_foo)
|
||||
@@ -270,6 +316,25 @@ class TestSheerkaIsAManager(TestUsingMemoryBasedSheerka):
|
||||
Concept("baz"),
|
||||
)
|
||||
|
||||
sheerka.set_isa(context, foo, bar)
|
||||
sheerka.set_isa(context, bar, baz)
|
||||
|
||||
assert sheerka.isa(foo, bar)
|
||||
assert sheerka.isa(bar, baz)
|
||||
assert sheerka.isa(foo, baz)
|
||||
|
||||
def test_i_can_manage_isa_transitivity_when_global_truth_is_activated(self):
|
||||
"""
|
||||
if foo isa bar and bar isa baz, then foo isa baz
|
||||
:return:
|
||||
"""
|
||||
|
||||
sheerka, context, foo, bar, baz = self.init_test(global_truth=True).with_concepts(
|
||||
Concept("foo"),
|
||||
Concept("bar"),
|
||||
Concept("baz"),
|
||||
).unpack()
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("foo"), bar)
|
||||
sheerka.set_isa(context, sheerka.new("bar"), baz)
|
||||
|
||||
@@ -278,11 +343,11 @@ class TestSheerkaIsAManager(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isa(sheerka.new("foo"), baz)
|
||||
|
||||
def test_i_cannot_manage_isa_transitivity_when_using_body(self):
|
||||
sheerka, context, one, another_one, number = self.init_concepts(
|
||||
sheerka, context, one, another_one, number = self.init_test(global_truth=True).with_concepts(
|
||||
"one",
|
||||
Concept("another one", body="one"),
|
||||
"number"
|
||||
)
|
||||
).unpack()
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("one"), number)
|
||||
|
||||
@@ -290,7 +355,10 @@ class TestSheerkaIsAManager(TestUsingMemoryBasedSheerka):
|
||||
assert not sheerka.isa(another_one, number) # Correct this misbehaviour when BuiltinConcepts.IS is implemented
|
||||
|
||||
def test_concepts_in_group_cache_is_updated(self):
|
||||
sheerka, context, one, two, number = self.init_concepts("one", "two", "number")
|
||||
sheerka, context, one, two, number = self.init_test(global_truth=True).with_concepts(
|
||||
"one",
|
||||
"two",
|
||||
"number").unpack()
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("one"), number)
|
||||
|
||||
@@ -315,12 +383,12 @@ class TestSheerkaIsAManager(TestUsingMemoryBasedSheerka):
|
||||
assert number.id not in sheerka.get_concepts_bnf_definitions()
|
||||
|
||||
def test_i_can_get_and_set_isa_when_multiple_ontology_layers(self):
|
||||
sheerka, context, foo, group1, group2 = self.init_concepts(
|
||||
sheerka, context, foo, group1, group2 = self.init_test(global_truth=True).with_concepts(
|
||||
Concept("foo"),
|
||||
Concept("group1"),
|
||||
Concept("group2"),
|
||||
cache_only=False
|
||||
)
|
||||
).unpack()
|
||||
|
||||
sheerka.set_isa(context, foo, group1)
|
||||
|
||||
@@ -401,10 +469,10 @@ class TestSheerkaSetsManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
}
|
||||
|
||||
def test_i_can_set_isa(self):
|
||||
sheerka, context, foo, bar, group = self.init_test().with_concepts("foo",
|
||||
"bar",
|
||||
"group",
|
||||
).unpack()
|
||||
sheerka, context, foo, bar, group = self.init_test(global_truth=True).with_concepts("foo",
|
||||
"bar",
|
||||
"group",
|
||||
).unpack()
|
||||
|
||||
# nothing was previously in ISA
|
||||
foo = sheerka.new(foo.key)
|
||||
|
||||
@@ -116,6 +116,15 @@ class TestSheerkaMemory(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert sheerka.memory(context, "self.name == 'foo'") == foo
|
||||
|
||||
def test_i_can_use_memory_when_the_entry_does_not_exist(self):
|
||||
sheerka, context, foo, bar = self.init_test().with_concepts("foo", "bar", create_new=True).unpack()
|
||||
|
||||
sheerka.add_to_memory(context, "foo", foo) # add at least one element
|
||||
|
||||
res = sheerka.memory(context, "bar")
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.NOT_FOUND)
|
||||
assert res.body == {'#name': 'bar'}
|
||||
|
||||
def test_i_retrieve_the_last_entry_when_requesting_memory_with_a_query(self):
|
||||
sheerka, context, foo, bar, foo2 = self.init_concepts("foo", "bar", Concept("foo", body="2"))
|
||||
|
||||
|
||||
@@ -52,22 +52,16 @@ class TestSheerkaQueryManager(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.filter_objects(context, lst, prop2={"key": "value"}) == [lst[3]]
|
||||
# assert sheerka.filter_objects(context, lst, prop1={1, "v"}) == [lst[2]] set are not supported
|
||||
|
||||
# complex properties
|
||||
assert sheerka.filter_objects(context, lst, prop1_contains="a") == [lst[0], lst[1]]
|
||||
assert sheerka.filter_objects(context, lst, prop1_contains=1) == [lst[2], lst[3]]
|
||||
|
||||
def test_i_can_filter_by_object_type(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
lst = [A("a11", "a12"), Concept("foo", body="a").auto_init(), Concept("foo", body="b").auto_init()]
|
||||
|
||||
assert sheerka.filter_objects(context, lst, __type="foo") == [lst[1], lst[2]]
|
||||
|
||||
def test_i_can_filter_on_atomic_def(self):
|
||||
sheerka, context, isa, plus, isa2 = self.init_concepts(
|
||||
Concept('x is a y').def_var("x").def_var("y"),
|
||||
Concept('a plus b').def_var("a").def_var("b"),
|
||||
Concept('u is a v').def_var("u").def_var("v"),
|
||||
)
|
||||
|
||||
lst = [isa, plus, isa2]
|
||||
assert sheerka.filter_objects(context, lst, atomic_def="is a") == [lst[0], lst[2]]
|
||||
|
||||
def test_i_can_filter_on_as_bag_property(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
lst = [B("a11", "a12"), B("a21", "a22"), B("a31", "a32")]
|
||||
|
||||
@@ -253,6 +253,28 @@ class TestBuiltinHelpers(TestUsingMemoryBasedSheerka):
|
||||
# a second time, now that bar is already evaluated
|
||||
assert core.builtin_helpers.ensure_evaluated(context, bar) == foo
|
||||
|
||||
@pytest.mark.parametrize("concept, concepts_parts, expected", [
|
||||
(Concept("foo"), ["where"], 0),
|
||||
(Concept("foo", where="x"), ["where"], 1),
|
||||
(Concept("foo", where="x and y"), ["where"], 2),
|
||||
(Concept("foo", where="x or y"), ["where"], 1),
|
||||
(Concept("foo", where="x or y and z"), ["where"], 2),
|
||||
(Concept("foo", where="not w"), ["where"], 1),
|
||||
(Concept("foo", where=""), ["where"], 0),
|
||||
|
||||
(Concept("foo", pre="x"), ["pre", "where"], 101),
|
||||
(Concept("foo", where="x"), ["pre", "where"], 1),
|
||||
(Concept("foo", where="x and y", pre="z"), ["pre", "where"], 103),
|
||||
|
||||
(Concept("foo", pre="x"), ["pre|where"], 1),
|
||||
(Concept("foo", where="x"), ["pre|where"], 1),
|
||||
(Concept("foo", where="x and y", pre="z"), ["pre|where"], 3),
|
||||
|
||||
])
|
||||
def test_i_can_get_concept_complexity(self, concept, concepts_parts, expected):
|
||||
context = self.get_context()
|
||||
assert core.builtin_helpers.get_concept_complexity(context, concept, concepts_parts) == expected
|
||||
|
||||
# @pytest.mark.parametrize("return_values", [
|
||||
# None,
|
||||
# []
|
||||
|
||||
@@ -559,6 +559,37 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
ret_val = ReturnValueConcept("Test", True, sheerka.err("an error"))
|
||||
assert sheerka.get_errors(context, ret_val) == []
|
||||
|
||||
def test_i_can_add_and_remove_global_context_hints(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
sheerka.add_to_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
|
||||
assert sheerka._global_context_hints == {BuiltinConcepts.EVAL_QUESTION_REQUESTED}
|
||||
|
||||
sheerka.remove_fom_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
|
||||
assert sheerka._global_context_hints == set()
|
||||
|
||||
sheerka.add_to_context(sheerka.new(BuiltinConcepts.EVAL_QUESTION_REQUESTED))
|
||||
assert sheerka._global_context_hints == {BuiltinConcepts.EVAL_QUESTION_REQUESTED}
|
||||
|
||||
sheerka.remove_fom_context(sheerka.new(BuiltinConcepts.EVAL_QUESTION_REQUESTED))
|
||||
assert sheerka._global_context_hints == set()
|
||||
|
||||
def test_global_context_hints_are_added_to_every_user_input_execution(self):
|
||||
sheerka, context, foo = self.init_test().with_concepts(
|
||||
Concept("foo", pre="in_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)")
|
||||
).unpack()
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foo", "testing_user")
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONDITION_FAILED) # sanity check
|
||||
|
||||
sheerka.add_to_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
res = sheerka.evaluate_user_input("eval foo", "testing_user")
|
||||
assert sheerka.isinstance(res[0].value, "foo")
|
||||
|
||||
sheerka.remove_fom_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
res = sheerka.evaluate_user_input("eval foo", "testing_user")
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONDITION_FAILED)
|
||||
|
||||
|
||||
class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
|
||||
|
||||
@@ -842,11 +842,9 @@ class TestSheerkaOntology(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, foo = self.init_concepts("foo", cache_only=False)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("by_id", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_id", key))
|
||||
cache = Cache().auto_configure("by_id")
|
||||
manager.register_concept_cache("by_id", cache, lambda obj: obj.id, use_ref=True)
|
||||
cache = ListIfNeededCache(default=lambda sdp, key: sdp.get("by_key", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_key", key))
|
||||
cache = ListIfNeededCache().auto_configure("by_key")
|
||||
manager.register_concept_cache("by_key", cache, lambda obj: obj.key, use_ref=True)
|
||||
manager.freeze()
|
||||
|
||||
@@ -863,11 +861,9 @@ class TestSheerkaOntology(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, foo = self.init_concepts("foo", cache_only=False)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("by_id", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_id", key))
|
||||
cache = Cache().auto_configure("by_id")
|
||||
manager.register_concept_cache("by_id", cache, lambda obj: obj.id, use_ref=True)
|
||||
cache = ListIfNeededCache(default=lambda sdp, key: sdp.get("by_key", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_key", key))
|
||||
cache = ListIfNeededCache().auto_configure("by_key")
|
||||
manager.register_concept_cache("by_key", cache, lambda obj: obj.key, use_ref=True)
|
||||
manager.freeze()
|
||||
|
||||
@@ -887,15 +883,33 @@ class TestSheerkaOntology(TestUsingMemoryBasedSheerka):
|
||||
assert list(manager.ontologies[0].cache_manager.sdp.state.data.keys()) == ['by_id', 'by_key']
|
||||
assert manager.ontologies[1].cache_manager.sdp.state.data == {}
|
||||
|
||||
def test_i_can_add_the_concepts_with_the_same_key_from_different_layers(self):
|
||||
sheerka, context, foo_1, foo_2 = self.init_concepts(
|
||||
Concept("foo x", body="x + 1").def_var("x"),
|
||||
Concept("foo x", body="x + 2").def_var("x"),
|
||||
cache_only=False)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
cache = ListIfNeededCache().auto_configure("by_key")
|
||||
manager.register_concept_cache("by_key", cache, lambda obj: obj.key, use_ref=True)
|
||||
manager.freeze()
|
||||
|
||||
manager.add_concept(foo_1)
|
||||
manager.commit(context)
|
||||
|
||||
manager.push_ontology("new ontology")
|
||||
manager.add_concept(foo_2)
|
||||
manager.commit(context)
|
||||
|
||||
assert manager.current_sdp().get("by_key", foo_1.key) == [foo_1, foo_2]
|
||||
|
||||
def test_i_can_update_concept_in_default_layer(self):
|
||||
sheerka, context, foo = self.init_concepts("foo", cache_only=False)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("by_id", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_id", key))
|
||||
cache = Cache().auto_configure("by_id")
|
||||
manager.register_concept_cache("by_id", cache, lambda obj: obj.id, use_ref=True)
|
||||
cache = ListIfNeededCache(default=lambda sdp, key: sdp.get("by_key", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_key", key))
|
||||
cache = ListIfNeededCache().auto_configure("by_key")
|
||||
manager.register_concept_cache("by_key", cache, lambda obj: obj.key, use_ref=True)
|
||||
manager.freeze()
|
||||
|
||||
@@ -953,11 +967,9 @@ class TestSheerkaOntology(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, foo = self.init_concepts("foo", cache_only=False)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("by_id", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_id", key))
|
||||
cache = Cache().auto_configure("by_id")
|
||||
manager.register_concept_cache("by_id", cache, lambda obj: obj.id, use_ref=True)
|
||||
cache = ListIfNeededCache(default=lambda sdp, key: sdp.get("by_key", key),
|
||||
extend_exists=lambda sdp, key: sdp.get("by_key", key))
|
||||
cache = ListIfNeededCache().auto_configure("by_key")
|
||||
manager.register_concept_cache("by_key", cache, lambda obj: obj.key, use_ref=True)
|
||||
manager.freeze()
|
||||
|
||||
|
||||
@@ -193,6 +193,8 @@ def test_i_can_escape():
|
||||
("c:|id:", None, "id"),
|
||||
("c:key|:", "key", None),
|
||||
("c:key|id:x", None, None),
|
||||
("c:one: plus c:two:", None, None),
|
||||
("c:one|id: plus c:two:", None, None),
|
||||
])
|
||||
def test_i_can_unstr_concept(text, expected_key, expected_id):
|
||||
k, i = core.utils.unstr_concept(text)
|
||||
@@ -494,3 +496,19 @@ def test_sheerka_hasattr_get_attr():
|
||||
assert not core.utils.sheerka_hasattr(concept, "b")
|
||||
with pytest.raises(AttributeError):
|
||||
core.utils.sheerka_getattr(concept, "b")
|
||||
|
||||
|
||||
def test_i_can_replace_after():
|
||||
my_new_items = ["alpha", "beta", "gamma"]
|
||||
|
||||
my_list1 = ["a", "b", "c", "d"]
|
||||
core.utils.replace_after(my_list1, "c", my_new_items)
|
||||
assert my_list1 == ["a", "b", "alpha", "beta", "gamma"]
|
||||
|
||||
my_list2 = ["a", "b", "c", "d"]
|
||||
core.utils.replace_after(my_list2, "a", my_new_items)
|
||||
assert my_list2 == ["alpha", "beta", "gamma"]
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
my_list3 = ["a", "b", "c", "d"]
|
||||
core.utils.replace_after(my_list3, "x", my_new_items)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -362,6 +362,7 @@ as:
|
||||
])
|
||||
def test_i_can_mix_concept_with_python_to_define_numbers(self, desc, definitions):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_to_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
for definition in definitions:
|
||||
sheerka.evaluate_user_input(definition)
|
||||
@@ -396,6 +397,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 23
|
||||
sheerka.remove_fom_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
def test_i_can_mix_bnf_and_isa(self):
|
||||
"""
|
||||
@@ -406,8 +408,8 @@ as:
|
||||
sheerka.evaluate_user_input("def concept one as 1")
|
||||
sheerka.evaluate_user_input("def concept two as 2")
|
||||
sheerka.evaluate_user_input("def concept number")
|
||||
sheerka.evaluate_user_input("set_isa(one, number)")
|
||||
sheerka.evaluate_user_input("set_isa(two, number)")
|
||||
sheerka.evaluate_user_input("global_truth(set_isa(one, number))")
|
||||
sheerka.evaluate_user_input("global_truth(set_isa(two, number))")
|
||||
sheerka.evaluate_user_input("def concept twenties from bnf 'twenty' number as 20 + number")
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
@@ -443,6 +445,7 @@ as:
|
||||
|
||||
def test_i_can_mix_bnf_and_isa_2(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_to_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
init = [
|
||||
"def concept one as 1",
|
||||
@@ -460,6 +463,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 21
|
||||
sheerka.remove_fom_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
|
||||
def test_i_can_use_concepts_defined_with_from(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -565,7 +569,7 @@ as:
|
||||
"def concept plus_one from bnf number=n1 'plus_one' as n1 + 1",
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(definitions)
|
||||
sheerka = self.init_scenario(definitions, global_truth=True)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval two plus_one")
|
||||
assert len(res) == 1
|
||||
@@ -642,8 +646,6 @@ as:
|
||||
assert res[0].body == 21
|
||||
|
||||
def test_i_can_use_where_in_bnf(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
init = [
|
||||
"def concept one as 1",
|
||||
"def concept two as 2",
|
||||
@@ -656,8 +658,8 @@ as:
|
||||
"def concept twenties from bnf twenty number where number <= 2 as twenty + number"
|
||||
]
|
||||
|
||||
for exp in init:
|
||||
sheerka.evaluate_user_input(exp)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
assert len(res) == 1
|
||||
@@ -765,7 +767,7 @@ as:
|
||||
sheerka.evaluate_user_input("def concept two as 2")
|
||||
sheerka.evaluate_user_input("def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit")
|
||||
|
||||
res = sheerka.evaluate_user_input("set_isa(twenties, number)")
|
||||
res = sheerka.evaluate_user_input("global_truth(set_isa(twenties, number))")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
|
||||
@@ -946,7 +948,7 @@ as:
|
||||
"set_isa(twenties, number)",
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
|
||||
# simulate that sheerka was stopped and restarted
|
||||
sheerka.clear_bnf_definition()
|
||||
@@ -967,8 +969,8 @@ as:
|
||||
res = sheerka.evaluate_user_input("set_isa(last_created_concept(), number)")
|
||||
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
|
||||
assert sheerka.isa(sheerka.new("one"), sheerka.new("number"))
|
||||
assert sheerka.isinstance(res[0].body, "one")
|
||||
assert sheerka.isa(res[0].body, sheerka.new("number"))
|
||||
|
||||
def test_i_can_evaluate_sya_and_ret_concepts(self):
|
||||
init = [
|
||||
@@ -1001,7 +1003,7 @@ as:
|
||||
# Since command is a __COMMAND, the body is auto evaluated
|
||||
# and we return the body, not the concept
|
||||
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
res = sheerka.evaluate_user_input("command")
|
||||
assert res[0].status
|
||||
assert res[0].body == "Executed !"
|
||||
@@ -1016,7 +1018,7 @@ as:
|
||||
"def concept x is a y as set_isa(x,y)",
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
res = sheerka.evaluate_user_input("question(one is a number)") # automatically evaluated
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
@@ -1042,7 +1044,7 @@ as:
|
||||
# So the first one should be picked.
|
||||
# the second concept 'one' 's value is an integer, to make sure that it won't be rejected because of its type
|
||||
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
res = sheerka.evaluate_user_input("def concept x plus y where x is a number as x + y")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
@@ -1065,7 +1067,7 @@ as:
|
||||
"set_is_greater_than(BuiltinConcepts.PRECEDENCE, c:is_a:, c:q:, 'Sya')",
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
res = sheerka.evaluate_user_input("one is a number ?") # automatically evaluated
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
@@ -1133,7 +1135,7 @@ as:
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
assert len(res) > 1 # not recognized
|
||||
|
||||
sheerka.evaluate_user_input("set_isa(one, number)")
|
||||
sheerka.evaluate_user_input("global_truth(set_isa(one, number))")
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
@@ -1252,9 +1254,9 @@ as:
|
||||
"def concept two",
|
||||
"def concept number",
|
||||
"def concept nb times from bnf number 'times'",
|
||||
"set_isa(two, number)",
|
||||
"set_isa(two, number)", # defined after 'nb times'
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
|
||||
res = sheerka.evaluate_user_input("two times")
|
||||
|
||||
@@ -1270,7 +1272,7 @@ as:
|
||||
"def concept cars",
|
||||
"def concept quantify x from bnf number x as set_attr(x, 'qty', number) ret x"
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval two cars")
|
||||
|
||||
@@ -1287,7 +1289,7 @@ as:
|
||||
"def concept cars",
|
||||
"def concept quantify x from bnf number=n1 x as set_attr(x, 'qty', n1) ret x"
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval two cars")
|
||||
|
||||
@@ -1317,7 +1319,7 @@ as:
|
||||
"def concept she ret memory('isa(self, female)')",
|
||||
"girl"
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
res = sheerka.evaluate_user_input("set_attr(she, 'my_attr', 'my value')")
|
||||
@@ -1337,7 +1339,7 @@ as:
|
||||
"def concept x attribute y equals z as set_attr(x, y, z)",
|
||||
"girl"
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval she attribute 'my_attr' equals 'my value'")
|
||||
@@ -1392,7 +1394,7 @@ as:
|
||||
"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)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
|
||||
res = sheerka.evaluate_user_input("what is the color of the short ?")
|
||||
assert len(res) == 1
|
||||
|
||||
@@ -13,6 +13,34 @@ class TestSheerkaNonRegMemory2(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = sheerka.evaluate_user_input("question(foo is a foo)")
|
||||
|
||||
# assert len(res) == 1
|
||||
# assert res[0].status
|
||||
# assert res[0].value
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].value # value is True since 'x is a foo' was chosen
|
||||
|
||||
def test_i_can_select_the_correct_concept_vs_bnf(self):
|
||||
init = [
|
||||
"def concept one as 1",
|
||||
"def concept two as 2",
|
||||
"def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit",
|
||||
"def concept twenty two as 'specific occurrence'",
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty one")
|
||||
assert res[0].value == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty two")
|
||||
assert res[0].value == "specific occurrence" # thanks to ExactConceptParser
|
||||
|
||||
def test_i_can_use_global_truth_when_calling_a_concept(self):
|
||||
init = [
|
||||
"def concept one",
|
||||
"def concept number",
|
||||
"def concept x is a y as set_isa(x, y)",
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
|
||||
res = sheerka.evaluate_user_input("global_truth(one is a number)")
|
||||
|
||||
assert res[0].status
|
||||
assert sheerka.isa(sheerka.new("one"), sheerka.new("number"))
|
||||
|
||||
@@ -85,7 +85,7 @@ class TestSheerkaNonRegFile(TestUsingFileBasedSheerka):
|
||||
"set_isa(thirty, number)",
|
||||
"def concept thirties from bnf thirty number where number < 10 as thirty + number",
|
||||
"set_isa(thirties, number)",
|
||||
])
|
||||
], global_truth=True)
|
||||
|
||||
sheerka = self.new_sheerka_instance()
|
||||
|
||||
|
||||
@@ -53,6 +53,45 @@ post : None
|
||||
ret : None
|
||||
vars : []
|
||||
props : {}
|
||||
"""
|
||||
|
||||
def test_i_can_display_multiple_concepts_description_when_concept_definition(self, capsys):
|
||||
init = [
|
||||
"def concept foo as 1",
|
||||
"def concept foo as 2 where True",
|
||||
]
|
||||
sheerka = self.init_scenario(init)
|
||||
capsys.readouterr()
|
||||
|
||||
sheerka.enable_process_return_values = True
|
||||
sheerka.evaluate_user_input("desc(c:foo:)")
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == """id : 1001
|
||||
name : foo
|
||||
key : foo
|
||||
definition: None
|
||||
type : None
|
||||
hash : 16f7fbb8bc509b8c652edaf3d0c0457d15a37f0a862fbe03fa357b0c77249c46
|
||||
body : 1
|
||||
where : None
|
||||
pre : None
|
||||
post : None
|
||||
ret : None
|
||||
vars : []
|
||||
props : {}
|
||||
id : 1002
|
||||
name : foo
|
||||
key : foo
|
||||
definition: None
|
||||
type : None
|
||||
hash : e8dd1af1b6bc0eca0fb4a87a6fabb16655caa4b7a6ea9dbbd1f887757e6caf89
|
||||
body : 2
|
||||
where : True
|
||||
pre : None
|
||||
post : None
|
||||
ret : None
|
||||
vars : []
|
||||
props : {}
|
||||
"""
|
||||
|
||||
def test_i_can_describe_a_rule(self, capsys):
|
||||
|
||||
@@ -35,7 +35,7 @@ class TestSheerkaNonRegPipeFunctions(TestUsingMemoryBasedSheerka):
|
||||
"add_to_memory('x', [one])"
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(init)
|
||||
sheerka = self.init_scenario(init, global_truth=True)
|
||||
res = sheerka.evaluate_user_input("x | where('isa(self, number)')")
|
||||
|
||||
assert len(res) == 1
|
||||
|
||||
@@ -98,22 +98,24 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
init_test_helper = cls().init_test(cache_only=False, ontology="#TestBnfNodeParser#")
|
||||
test_instance = cls()
|
||||
init_test_helper = test_instance.init_test(cache_only=False, ontology="#TestBnfNodeParser#")
|
||||
sheerka, context, *updated = init_test_helper.with_concepts(*cmap.values(), create_new=True).unpack()
|
||||
for i, concept_name in enumerate(cmap):
|
||||
cmap[concept_name] = updated[i]
|
||||
|
||||
# end of initialisation
|
||||
global_truth_context = test_instance.get_context(sheerka, global_truth=True)
|
||||
sheerka = TestBnfNodeParser.sheerka
|
||||
sheerka.set_isa(context, cmap["one"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["two"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["three"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["four"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["thirty"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["forty"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["fifty"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["one hundred"], cmap["number"])
|
||||
sheerka.set_isa(context, cmap["hundreds"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["one"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["two"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["three"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["four"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["thirty"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["forty"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["fifty"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["one hundred"], cmap["number"])
|
||||
sheerka.set_isa(global_truth_context, cmap["hundreds"], cmap["number"])
|
||||
|
||||
# Pay attention. 'twenties (t1 and t2) are not set as 'number'
|
||||
|
||||
@@ -122,28 +124,28 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
where="number < 10",
|
||||
body="thirty + number").def_var("thirty").def_var("number"))
|
||||
cmap["thirties"] = sheerka.create_new_concept(context, thirties).body.body
|
||||
sheerka.set_isa(context, sheerka.new("thirties"), sheerka.new("number"))
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("thirties"), sheerka.new("number"))
|
||||
|
||||
forties = cls.update_bnf(context, Concept("forties",
|
||||
definition="forty number",
|
||||
where="number < 10",
|
||||
body="forty + number").def_var("forty").def_var("number"))
|
||||
cmap["forties"] = sheerka.create_new_concept(context, forties).body.body
|
||||
sheerka.set_isa(context, sheerka.new("forties"), sheerka.new("number"))
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("forties"), sheerka.new("number"))
|
||||
|
||||
fifties = cls.update_bnf(context, Concept("fifties",
|
||||
definition="fifty number",
|
||||
where="number < 10",
|
||||
body="fifty + number").def_var("fifty").def_var("number"))
|
||||
cmap["fifties"] = sheerka.create_new_concept(context, fifties).body.body
|
||||
sheerka.set_isa(context, sheerka.new("fifties"), sheerka.new("number"))
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("fifties"), sheerka.new("number"))
|
||||
|
||||
thousands = cls.update_bnf(context, Concept("thousands",
|
||||
definition="number 'thousand'",
|
||||
where="number < 999",
|
||||
body="number * 1000").def_var("number"))
|
||||
cmap["thousands"] = sheerka.create_new_concept(context, thousands).body.body
|
||||
sheerka.set_isa(context, sheerka.new("thousands"), sheerka.new("number"))
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("thousands"), sheerka.new("number"))
|
||||
|
||||
cls.shared_ontology = sheerka.get_ontology(context)
|
||||
sheerka.pop_ontology(context)
|
||||
@@ -1217,10 +1219,11 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
"twenties": self.bnf_concept("twenties", Sequence(ConceptExpression("twenty"), ConceptExpression("number")))
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(my_map)
|
||||
global_truth_context = self.get_context(sheerka, global_truth=True)
|
||||
parser.context = context
|
||||
parser.sheerka = sheerka
|
||||
sheerka.set_isa(context, sheerka.new("one"), my_map["number"])
|
||||
sheerka.set_isa(context, sheerka.new("twenty"), my_map["number"])
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("one"), my_map["number"])
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("twenty"), my_map["number"])
|
||||
|
||||
parser.concepts_grammars.clear() # make sure parsing expression is created from scratch
|
||||
|
||||
@@ -1251,9 +1254,10 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, parser = self.init_parser(my_map, singleton=True)
|
||||
parser.context = context
|
||||
parser.sheerka = sheerka
|
||||
sheerka.set_isa(context, sheerka.new("one"), my_map["number"])
|
||||
sheerka.set_isa(context, sheerka.new("two"), my_map["number"])
|
||||
sheerka.set_isa(context, sheerka.new("hundreds"), my_map["number"])
|
||||
global_truth_context = self.get_context(sheerka, global_truth=True)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("one"), my_map["number"])
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("two"), my_map["number"])
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("hundreds"), my_map["number"])
|
||||
|
||||
parser.concepts_grammars.clear() # make sure parsing expression is created from scratch
|
||||
parsing_expression = parser.get_parsing_expression(context, my_map["hundreds"])
|
||||
@@ -1281,9 +1285,10 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, parser = self.init_parser(my_map, singleton=True)
|
||||
parser.context = context
|
||||
parser.sheerka = sheerka
|
||||
sheerka.set_isa(context, sheerka.new("one"), my_map["number"])
|
||||
sheerka.set_isa(context, sheerka.new("twenty"), my_map["number"])
|
||||
sheerka.set_isa(context, sheerka.new("twenties"), my_map["number"]) # <- twenties is also a number
|
||||
global_truth_context = self.get_context(sheerka, global_truth=True)
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("one"), my_map["number"])
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("twenty"), my_map["number"])
|
||||
sheerka.set_isa(global_truth_context, sheerka.new("twenties"), my_map["number"]) # <- twenties is also a number
|
||||
|
||||
parser.concepts_grammars.clear() # make sure parsing expression is created from scratch
|
||||
|
||||
@@ -1900,15 +1905,16 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(my_map, init_from_sheerka=True, create_new=True)
|
||||
sheerka.set_isa(context, my_map["light_red"], my_map["adjective"])
|
||||
sheerka.set_isa(context, my_map["dark_red"], my_map["adjective"])
|
||||
sheerka.set_isa(context, my_map["light_red"], my_map["color"])
|
||||
sheerka.set_isa(context, my_map["dark_red"], my_map["color"])
|
||||
sheerka.set_isa(context, my_map["light_red"], my_map["red colors"])
|
||||
sheerka.set_isa(context, my_map["dark_red"], my_map["red colors"])
|
||||
sheerka.set_isa(context, my_map["color"], my_map["adjective"])
|
||||
sheerka.set_isa(context, my_map["red colors"], my_map["color"])
|
||||
sheerka.set_isa(context, my_map["red colors"], my_map["adjective"])
|
||||
global_truth_context = self.get_context(sheerka, global_truth=True)
|
||||
sheerka.set_isa(global_truth_context, my_map["light_red"], my_map["adjective"])
|
||||
sheerka.set_isa(global_truth_context, my_map["dark_red"], my_map["adjective"])
|
||||
sheerka.set_isa(global_truth_context, my_map["light_red"], my_map["color"])
|
||||
sheerka.set_isa(global_truth_context, my_map["dark_red"], my_map["color"])
|
||||
sheerka.set_isa(global_truth_context, my_map["light_red"], my_map["red colors"])
|
||||
sheerka.set_isa(global_truth_context, my_map["dark_red"], my_map["red colors"])
|
||||
sheerka.set_isa(global_truth_context, my_map["color"], my_map["adjective"])
|
||||
sheerka.set_isa(global_truth_context, my_map["red colors"], my_map["color"])
|
||||
sheerka.set_isa(global_truth_context, my_map["red colors"], my_map["adjective"])
|
||||
|
||||
text = "light red table"
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert concept_found == foo
|
||||
assert not concept_found.get_hints().need_validation
|
||||
assert concept_found.get_hints().is_evaluated
|
||||
assert not concept_found.get_hints().is_instance
|
||||
|
||||
def test_i_can_parse_concept_with_concept_tokens(self):
|
||||
sheerka, context, one, two, plus = self.init_concepts(
|
||||
|
||||
@@ -4,7 +4,7 @@ from core.builtin_concepts import BuiltinConcepts
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import TokenKind
|
||||
from parsers.BaseExpressionParser import TrueifyVisitor, IsAQuestionVisitor, LeftPartNotFoundError, \
|
||||
ParenthesisMismatchError
|
||||
ParenthesisMismatchError, compile_disjunctions, NotNode, AndNode, OrNode
|
||||
from parsers.BaseParser import UnexpectedEofParsingError, UnexpectedTokenParsingError
|
||||
from parsers.LogicalOperatorParser import LogicalOperatorParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
@@ -12,6 +12,46 @@ from tests.parsers.parsers_utils import EXPR, OR, AND, NOT, \
|
||||
get_expr_node_from_test_node
|
||||
|
||||
|
||||
class DoNotCompareStartStopContextManager:
|
||||
def __init__(self):
|
||||
self.original_not_eq = None
|
||||
self.original_and_eq = None
|
||||
self.original_or_eq = None
|
||||
|
||||
@staticmethod
|
||||
def not_eq(self, other):
|
||||
if not isinstance(other, NotNode):
|
||||
return False
|
||||
return self.node == other.node
|
||||
|
||||
@staticmethod
|
||||
def and_eq(self, other):
|
||||
if not isinstance(other, AndNode):
|
||||
return False
|
||||
|
||||
return self.parts == other.parts
|
||||
|
||||
@staticmethod
|
||||
def or_eq(self, other):
|
||||
if not isinstance(other, OrNode):
|
||||
return False
|
||||
|
||||
return self.parts == other.parts
|
||||
|
||||
def __enter__(self):
|
||||
self.original_not_eq = NotNode.__eq__
|
||||
self.original_and_eq = AndNode.__eq__
|
||||
self.original_or_eq = OrNode.__eq__
|
||||
NotNode.__eq__ = self.not_eq
|
||||
AndNode.__eq__ = self.and_eq
|
||||
OrNode.__eq__ = self.or_eq
|
||||
|
||||
def __exit__(self, *args):
|
||||
NotNode.__eq__ = self.original_not_eq
|
||||
AndNode.__eq__ = self.original_and_eq
|
||||
OrNode.__eq__ = self.original_or_eq
|
||||
|
||||
|
||||
class TestLogicalOperatorParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init_parser(self):
|
||||
@@ -175,6 +215,50 @@ class TestLogicalOperatorParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert IsAQuestionVisitor().visit(expr_node) == expected
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("a", [EXPR("a")]),
|
||||
("a and b and c", [AND(EXPR("a"), EXPR("b"), EXPR("c"))]),
|
||||
("a or b or c", [EXPR("a"),
|
||||
EXPR("b"),
|
||||
EXPR("c")]),
|
||||
("a and b or c", [AND(EXPR("a"), EXPR("b")), EXPR("c")]),
|
||||
("a or b and c", [EXPR("a"),
|
||||
AND(EXPR("b"), EXPR("c"))]),
|
||||
("(a or b) and c", [AND(EXPR("a"), EXPR("c")),
|
||||
AND(EXPR("b"), EXPR("c"))]),
|
||||
("a or (b or c) and d", [EXPR("a"),
|
||||
AND(EXPR("b"), EXPR("d")),
|
||||
AND(EXPR("c"), EXPR("d"))]),
|
||||
|
||||
("not a", [NOT(EXPR("a"))]),
|
||||
("not (a and b)", [NOT(AND(EXPR("a"), EXPR("b")))]),
|
||||
("not (a or b)", [AND(NOT(EXPR("a")), NOT(EXPR("b")))]),
|
||||
|
||||
("(a or b) and not (c or d)", [AND(EXPR("a"), NOT(EXPR("c")), NOT(EXPR("d"))),
|
||||
AND(EXPR("b"), NOT(EXPR("c")), NOT(EXPR("d")))]),
|
||||
("(a or b) or not (c or d)", [EXPR("a"),
|
||||
EXPR("b"),
|
||||
AND(NOT(EXPR("c")), NOT(EXPR("d")))]),
|
||||
|
||||
("(a and b) and not (c or d)", [AND(EXPR("a"), EXPR("b"), NOT(EXPR("c")), NOT(EXPR("d")))]),
|
||||
("(a and b) or not (c or d)", [AND(EXPR("a"), EXPR("b")),
|
||||
AND(NOT(EXPR("c")), NOT(EXPR("d")))]),
|
||||
|
||||
("a and (b and c)", [AND(EXPR("a"), EXPR("b"), EXPR("c"))]),
|
||||
("a or (b or c)", [EXPR("a"),
|
||||
EXPR("b"),
|
||||
EXPR("c")]),
|
||||
])
|
||||
def test_i_can_compile_disjunction(self, expression, expected):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
resolved_expected = [get_expr_node_from_test_node(expression, e) for e in expected]
|
||||
|
||||
expr_node = parser.parse(context, ParserInput(expression)).body.body
|
||||
|
||||
with DoNotCompareStartStopContextManager():
|
||||
res = compile_disjunctions(expr_node)
|
||||
assert res == resolved_expected
|
||||
|
||||
# @pytest.mark.parametrize("expression, expected", [
|
||||
# ("foo", "foo"),
|
||||
# ("one two", "one two"),
|
||||
|
||||
@@ -258,6 +258,23 @@ class TestSequenceNodeParser(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
@pytest.mark.parametrize("concept", [
|
||||
Concept("foo x", body="1").def_var("x"),
|
||||
Concept("foo"),
|
||||
])
|
||||
def test_i_can_parse_token_concepts(self, concept):
|
||||
concepts_map = {
|
||||
"foo": concept,
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True, use_sheerka=True)
|
||||
res = parser.parse(context, ParserInput(f"c:{concept.name}:"))
|
||||
|
||||
assert res.status
|
||||
concept_found = res.body.body[0].concept
|
||||
assert concept_found.get_hints().is_evaluated
|
||||
assert not concept_found.get_hints().is_instance
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"foo",
|
||||
f"foo one",
|
||||
|
||||
@@ -709,6 +709,65 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
self.compare_results(res, expected_sequences, cmap, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("suffixed2 a b", ['a', 'b', "suffixed2"]),
|
||||
("suffixed3 a b c", ['a', 'b', 'c', "suffixed3"]),
|
||||
("a b prefixed2", ['a', 'b', "prefixed2"]),
|
||||
("a b c prefixed3", ['a', 'b', 'c', "prefixed3"]),
|
||||
("start2 a b stop", ['a', 'b', "start2"]),
|
||||
("start3 a b c stop", ['a', 'b', 'c', "start3"]),
|
||||
])
|
||||
def test_i_can_post_fix_when_multiple_parameters_are_expected(self, expression, expected):
|
||||
concepts_map = {
|
||||
"a": Concept("a"),
|
||||
"b": Concept("b"),
|
||||
"c": Concept("c"),
|
||||
"suffixed2": Concept("suffixed2 x y").def_var("x").def_var("y"),
|
||||
"suffixed3": Concept("suffixed3 x y z").def_var("x").def_var("y").def_var("z"),
|
||||
"prefixed2": Concept("x y prefixed2").def_var("x").def_var("y"),
|
||||
"prefixed3": Concept("x y z prefixed3").def_var("x").def_var("y").def_var("z"),
|
||||
"start2": Concept("start2 x y stop").def_var("x").def_var("y"),
|
||||
"start3": Concept("start3 x y z stop").def_var("x").def_var("y").def_var("z"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("suffixed3 x y z", ['x', 'y', 'z', "suffixed3"]),
|
||||
("suffixed3 a y z", ['a', 'y', 'z', "suffixed3"]),
|
||||
("suffixed3 x a z", ['x ', 'a', ' z', "suffixed3"]), # this one was not managed by the second chance
|
||||
("suffixed3 x y a", ['x', 'y', 'a', "suffixed3"]),
|
||||
("x y z prefixed3", ['x', 'y', 'z', "prefixed3"]),
|
||||
("a y z prefixed3", ['a', 'y', 'z', "prefixed3"]),
|
||||
("x a z prefixed3", ['x ', 'a', ' z', "prefixed3"]),
|
||||
("x y a prefixed3", ['x', 'y', 'a', "prefixed3"]),
|
||||
("start3 x y z stop", ['x', 'y', 'z', "start3"]),
|
||||
("start3 a y z stop", ['a', 'y', 'z', "start3"]),
|
||||
("start3 x a z stop", ['x ', 'a', ' z ', "start3"]),
|
||||
("start3 x y a stop", ['x', 'y', 'a', "start3"]),
|
||||
])
|
||||
def test_i_can_post_fix_when_multiple_parameters_are_expected_but_unrecognized_tokens(self, expression, expected):
|
||||
concepts_map = {
|
||||
"a": Concept("a"),
|
||||
"suffixed3": Concept("suffixed3 x y z").def_var("x").def_var("y").def_var("z"),
|
||||
"prefixed3": Concept("x y z prefixed3").def_var("x").def_var("y").def_var("z"),
|
||||
"start3": Concept("start3 x y z stop").def_var("x").def_var("y").def_var("z"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("(", ("(", 0)),
|
||||
("one plus ( 1 + ", ("(", 4)),
|
||||
@@ -1080,6 +1139,28 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
assert isinstance(concept_plus_b[0].body.body, PythonNode)
|
||||
assert concept_suffixed_a == cmap["two"]
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("suffixed3 a b c", [("x", "a"), ("y", "b"), ("z", "c")]),
|
||||
("a b c prefixed3", [("x", "a"), ("y", "b"), ("z", "c")]),
|
||||
("start3 a b c stop", [("x", "a"), ("y", "b"), ("z", "c")]),
|
||||
])
|
||||
def test_i_can_parse_when_multiple_parameters_are_expected(self, text, expected):
|
||||
concepts_map = {
|
||||
"a": Concept("a"),
|
||||
"b": Concept("b"),
|
||||
"c": Concept("c"),
|
||||
"suffixed3": Concept("suffixed3 x y z").def_var("x").def_var("y").def_var("z"),
|
||||
"prefixed3": Concept("x y z prefixed3").def_var("x").def_var("y").def_var("z"),
|
||||
"start3": Concept("start3 x y z stop").def_var("x").def_var("y").def_var("z"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
lexer_nodes = res.body.body
|
||||
|
||||
assert res.status
|
||||
assert lexer_nodes[0].concept.get_metadata().variables == expected
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"function(suffixed one)",
|
||||
"function(one plus two mult three)",
|
||||
|
||||
@@ -433,6 +433,10 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
compare_with_test_object(actual_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_when_multiple_atom_and_sya(self):
|
||||
"""
|
||||
Testing that the ambiguity between hello_atom and hello_sya is correctly managed
|
||||
:return:
|
||||
"""
|
||||
sheerka, context, parser = self.init_parser()
|
||||
expression = "two hello one three"
|
||||
nodes = get_input_nodes_from(concepts_map, expression,
|
||||
@@ -440,25 +444,15 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
parser_input = ParserResultConcept("parsers.xxx", source=expression, value=nodes)
|
||||
|
||||
res = parser.parse(context, parser_input)
|
||||
assert len(res) == 2
|
||||
assert res[0].status
|
||||
assert res[1].status
|
||||
assert res.status
|
||||
|
||||
actual_nodes0 = res[0].body.body
|
||||
actual_nodes0 = res.body.body
|
||||
expected_0 = compute_expected_array(concepts_map, expression, [
|
||||
CN("two", start=0, end=0),
|
||||
CN("hello_atom", source="hello one", start=2, end=4),
|
||||
CN("three", start=6, end=6)])
|
||||
compare_with_test_object(actual_nodes0, expected_0)
|
||||
|
||||
actual_nodes1 = res[1].body.body
|
||||
expected_1 = compute_expected_array(concepts_map, expression, [
|
||||
CN("two", start=0, end=0),
|
||||
CNC("hello_sya", "hello one", start=2, end=4, a="one"),
|
||||
CN("three", start=6, end=6)],
|
||||
exclude_body=True)
|
||||
compare_with_test_object(actual_nodes1, expected_1)
|
||||
|
||||
def test_i_can_parse_when_multiple_sya_concepts(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
expression = "greetings two"
|
||||
|
||||
Reference in New Issue
Block a user