Implemented SheerkaOntology
This commit is contained in:
@@ -3,8 +3,8 @@ import ast
|
||||
import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, CMV
|
||||
from core.global_symbols import RULE_COMPARISON_CONTEXT
|
||||
from core.rule import Rule
|
||||
from core.global_symbols import RULE_COMPARISON_CONTEXT, NotFound
|
||||
from core.rule import Rule, ACTION_TYPE_PRINT, ACTION_TYPE_EXEC
|
||||
from core.sheerka.services.SheerkaRuleManager import SheerkaRuleManager, FormatRuleParser, \
|
||||
FormatAstRawText, FormatAstVariable, FormatAstSequence, FormatAstFunction, \
|
||||
FormatRuleSyntaxError, FormatAstList, UnexpectedEof, FormatAstColor, RulePredicate, FormatAstDict, FormatAstMulti
|
||||
@@ -28,13 +28,12 @@ CONCEPT_EVALUATOR_NAME = "Concept"
|
||||
class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("action_type, cache_entry", [
|
||||
("print", SheerkaRuleManager.FORMAT_RULE_ENTRY),
|
||||
("exec", SheerkaRuleManager.EXEC_RULE_ENTRY),
|
||||
(ACTION_TYPE_PRINT, SheerkaRuleManager.FORMAT_RULE_ENTRY),
|
||||
(ACTION_TYPE_EXEC, SheerkaRuleManager.EXEC_RULE_ENTRY),
|
||||
])
|
||||
def test_i_can_create_a_new_rule(self, action_type, cache_entry):
|
||||
sheerka, context = self.init_concepts(cache_only=False)
|
||||
previous_rules_number = sheerka.cache_manager.caches[sheerka.OBJECTS_IDS_ENTRY].cache.copy()[
|
||||
SheerkaRuleManager.RULE_IDS]
|
||||
previous_rules_number = sheerka.om.get_all(sheerka.OBJECTS_IDS_ENTRY)[SheerkaRuleManager.RULE_IDS]
|
||||
|
||||
rule = Rule(action_type, "name", "True", "Hello world")
|
||||
|
||||
@@ -52,33 +51,50 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
assert created_rule.metadata.action == "Hello world"
|
||||
|
||||
# saved in cache
|
||||
assert len(sheerka.cache_manager.caches[cache_entry].cache) > 0
|
||||
from_cache = sheerka.cache_manager.get(cache_entry, expected_id)
|
||||
assert len(sheerka.om.current_cache_manager().caches[cache_entry].cache) > 0
|
||||
from_cache = sheerka.om.get(cache_entry, expected_id)
|
||||
assert from_cache.metadata.id == expected_id
|
||||
assert from_cache.metadata.name == "name"
|
||||
assert from_cache.metadata.predicate == "True"
|
||||
assert from_cache.metadata.action_type == action_type
|
||||
assert from_cache.metadata.action == "Hello world"
|
||||
|
||||
sheerka.cache_manager.commit(context)
|
||||
# the rule is also saved by name
|
||||
by_name = sheerka.get_rule_by_name("name")
|
||||
assert by_name.metadata.id == expected_id
|
||||
assert by_name.metadata.name == "name"
|
||||
assert by_name.metadata.predicate == "True"
|
||||
assert by_name.metadata.action_type == action_type
|
||||
assert by_name.metadata.action == "Hello world"
|
||||
|
||||
sheerka.om.commit(context)
|
||||
|
||||
# saved in sdp
|
||||
from_sdp = sheerka.sdp.get(cache_entry, expected_id)
|
||||
from_sdp = sheerka.om.current_sdp().get(cache_entry, expected_id)
|
||||
assert from_sdp.metadata.id == expected_id
|
||||
assert from_sdp.metadata.name == "name"
|
||||
assert from_sdp.metadata.predicate == "True"
|
||||
assert from_sdp.metadata.action_type == action_type
|
||||
assert from_sdp.metadata.action == "Hello world"
|
||||
|
||||
by_name = sheerka.om.current_sdp().get(SheerkaRuleManager.RULES_BY_NAME_ENTRY, "name")
|
||||
assert by_name.metadata.id == expected_id
|
||||
assert by_name.metadata.name == "name"
|
||||
assert by_name.metadata.predicate == "True"
|
||||
assert by_name.metadata.action_type == action_type
|
||||
assert by_name.metadata.action == "Hello world"
|
||||
|
||||
def test_i_can_create_multiple_rules(self):
|
||||
sheerka, context = self.init_concepts(cache_only=False)
|
||||
previous_rules_number = len(sheerka.cache_manager.caches[SheerkaRuleManager.FORMAT_RULE_ENTRY].cache)
|
||||
previous_rules_number = len(
|
||||
sheerka.om.current_cache_manager().caches[SheerkaRuleManager.FORMAT_RULE_ENTRY].cache)
|
||||
|
||||
sheerka.create_new_rule(context, Rule("print", "name1", "True", "Hello world"))
|
||||
sheerka.create_new_rule(context, Rule("print", "name2", "value() is __EXPLANATION", "list(value())"))
|
||||
|
||||
assert len(
|
||||
sheerka.cache_manager.caches[SheerkaRuleManager.FORMAT_RULE_ENTRY].cache) == 2 + previous_rules_number
|
||||
sheerka.om.current_cache_manager().caches[
|
||||
SheerkaRuleManager.FORMAT_RULE_ENTRY].cache) == 2 + previous_rules_number
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("", FormatAstRawText("")),
|
||||
@@ -186,7 +202,7 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
assert res[0].concept is None
|
||||
|
||||
def test_i_can_compile_predicate_when_python_and_concept(self):
|
||||
sheerka, context, *concepts = self.init_concepts(Concept("foo bar"), create_new=True)
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(Concept("foo bar"), create_new=True).unpack()
|
||||
service = sheerka.services[SheerkaRuleManager.NAME]
|
||||
text = "foo bar == 5"
|
||||
ast_ = ast.parse("__C__foo0bar__1001__C__ == 5", "<source>", 'eval')
|
||||
@@ -207,12 +223,12 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
("cat is an b", ["cat", "b"]),
|
||||
])
|
||||
def test_i_can_compile_predicate_when_exact_concept(self, text, expected_variables):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(
|
||||
Concept("x is an y", pre="is_question()", body="isinstance(x, y)").def_var("x").def_var("y"),
|
||||
Concept("cat"),
|
||||
Concept("animal"),
|
||||
create_new=True
|
||||
)
|
||||
).unpack()
|
||||
service = sheerka.services[SheerkaRuleManager.NAME]
|
||||
|
||||
expected = concepts[0]
|
||||
@@ -232,12 +248,12 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
("a cat is an b", ["a cat", "b"]),
|
||||
])
|
||||
def test_i_can_compile_predicate_when_sya_node_parser(self, text, expected_variables):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(
|
||||
Concept("x is an y", pre="is_question()", body="isinstance(x, y)").def_var("x").def_var("y"),
|
||||
Concept("a cat"),
|
||||
Concept("animal"),
|
||||
create_new=True
|
||||
)
|
||||
).unpack()
|
||||
service = sheerka.services[SheerkaRuleManager.NAME]
|
||||
expected = CMV(concepts[0], x=expected_variables[0], y=expected_variables[1])
|
||||
|
||||
@@ -251,11 +267,11 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
assert res[0].concept == expected
|
||||
|
||||
def test_i_can_compile_predicate_when_bnf_node_parser(self):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(
|
||||
Concept("animal"),
|
||||
Concept("x is an y", pre="is_question()", definition="('cat'|'bird')=x 'is an' animal").def_var("x"),
|
||||
create_new=True
|
||||
)
|
||||
).unpack()
|
||||
service = sheerka.services[SheerkaRuleManager.NAME]
|
||||
expected = concepts[1]
|
||||
|
||||
@@ -269,11 +285,11 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
assert res[0].concept == expected
|
||||
|
||||
def test_i_can_compile_predicate_when_multiple_choices(self):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(
|
||||
Concept("x is a y", pre="is_question()", body="isinstance(x, y)").def_var("x").def_var("y"),
|
||||
Concept("x is a y", pre="is_question()", body="isa(x, y)").def_var("x").def_var("y"),
|
||||
create_new=True
|
||||
)
|
||||
).unpack()
|
||||
service = sheerka.services[SheerkaRuleManager.NAME]
|
||||
|
||||
res = service.compile_when(context, "test", "a is a b")
|
||||
@@ -291,6 +307,34 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.objvalue(res[1].predicate)[0].concept == CMV(concepts[1], x="a", y="b")
|
||||
assert res[1].concept == CMV(concepts[1], x="a", y="b")
|
||||
|
||||
def test_i_can_get_rule_priorities(self):
|
||||
sheerka, context, rule_true, rule_false = self.init_test().with_rules(("True", "True"),
|
||||
("False", "False")).unpack()
|
||||
|
||||
sheerka.set_is_greater_than(context, BuiltinConcepts.PRECEDENCE,
|
||||
rule_true,
|
||||
rule_false,
|
||||
RULE_COMPARISON_CONTEXT)
|
||||
|
||||
rules_from_cache = sheerka.om.get_all(SheerkaRuleManager.FORMAT_RULE_ENTRY)
|
||||
|
||||
assert rules_from_cache[rule_true.id].priority == 2
|
||||
assert rules_from_cache[rule_false.id].priority == 1
|
||||
|
||||
def test_i_can_get_and_retrieve_rules_when_multiple_ontology_layers(self):
|
||||
sheerka, context, rule_true = self.init_test().with_rules(("true", "True", "True")).unpack()
|
||||
|
||||
sheerka.push_ontology(context, "new ontology")
|
||||
rule_false = sheerka.create_new_rule(context, Rule(ACTION_TYPE_EXEC, "false", "False", "False")).body.body
|
||||
|
||||
# All rules are visible
|
||||
assert sheerka.get_rule_by_id(rule_true.id) == rule_true
|
||||
assert sheerka.get_rule_by_id(rule_false.id) == rule_false
|
||||
|
||||
sheerka.pop_ontology()
|
||||
assert sheerka.get_rule_by_id(rule_true.id) == rule_true
|
||||
assert not sheerka.is_known(sheerka.get_rule_by_id(rule_false.id))
|
||||
|
||||
# @pytest.mark.skip
|
||||
# @pytest.mark.parametrize("text, expected", [
|
||||
# ("cat is an animal", set()),
|
||||
@@ -337,24 +381,58 @@ class TestSheerkaRuleManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
rules[1],
|
||||
RULE_COMPARISON_CONTEXT)
|
||||
|
||||
sheerka.cache_manager.commit(context)
|
||||
assert len(sheerka.cache_manager.copy(SheerkaRuleManager.FORMAT_RULE_ENTRY)) == len(rules)
|
||||
sheerka.om.commit(context)
|
||||
expected_rules_by_id = sheerka.om.get_all(SheerkaRuleManager.FORMAT_RULE_ENTRY)
|
||||
|
||||
sheerka = self.get_sheerka() # new instance
|
||||
assert len(sheerka.cache_manager.copy(SheerkaRuleManager.FORMAT_RULE_ENTRY)) == len(rules)
|
||||
sheerka = self.new_sheerka_instance(False) # new instance
|
||||
rules_by_id = sheerka.om.get_all(SheerkaRuleManager.FORMAT_RULE_ENTRY)
|
||||
|
||||
# manually update the rules (I need their new priorities)
|
||||
service = sheerka.services[SheerkaRuleManager.NAME]
|
||||
rules = [service.format_rule_cache.get(rule_id) for rule_id in service.format_rule_cache]
|
||||
assert len(rules_by_id) == len(expected_rules_by_id)
|
||||
|
||||
# check if the rules are correctly initialized
|
||||
rules_as_map = {rule.id: rule for rule in rules}
|
||||
for rule_id in service.format_rule_cache:
|
||||
actual = service.format_rule_cache.get(rule_id)
|
||||
expected = rules_as_map[rule_id]
|
||||
assert actual.metadata.is_compiled == expected.metadata.is_compiled
|
||||
assert actual.metadata.is_enabled == expected.metadata.is_enabled
|
||||
assert actual.compiled_action == expected.compiled_action
|
||||
assert actual.compiled_predicate == expected.compiled_predicate
|
||||
assert actual.priority is not None
|
||||
assert actual.priority == expected.priority
|
||||
for rule_id, rule in rules_by_id.items():
|
||||
expected = expected_rules_by_id[rule_id]
|
||||
|
||||
assert rule.metadata.action_type == expected.metadata.action_type
|
||||
assert rule.metadata.name == expected.metadata.name
|
||||
assert rule.metadata.predicate == expected.metadata.predicate
|
||||
assert rule.metadata.action == expected.metadata.action
|
||||
assert rule.metadata.id == expected.metadata.id
|
||||
assert rule.metadata.is_compiled == expected.metadata.is_compiled
|
||||
assert rule.metadata.is_enabled == expected.metadata.is_enabled
|
||||
assert rule.compiled_action == expected.compiled_action
|
||||
assert rule.compiled_predicate == expected.compiled_predicate
|
||||
assert rule.priority is not None
|
||||
assert rule.priority == expected.priority
|
||||
|
||||
def test_rules_are_still_accessible_after_a_new_ontology_layer(self):
|
||||
sheerka, context, *rules = self.init_format_rules(
|
||||
Rule("print", "name1", "True", "Hello world"),
|
||||
Rule("print", "name2", "value() is __EXPLANATION", "list(value())")
|
||||
)
|
||||
sheerka.set_is_greater_than(context, BuiltinConcepts.PRECEDENCE,
|
||||
rules[0],
|
||||
rules[1],
|
||||
RULE_COMPARISON_CONTEXT)
|
||||
|
||||
sheerka.om.commit(context)
|
||||
expected_rules_by_id = sheerka.om.get_all(SheerkaRuleManager.FORMAT_RULE_ENTRY)
|
||||
|
||||
sheerka.push_ontology(context, "new ontology")
|
||||
rules_by_id = sheerka.om.get_all(SheerkaRuleManager.FORMAT_RULE_ENTRY)
|
||||
|
||||
assert len(rules_by_id) == len(expected_rules_by_id)
|
||||
|
||||
for rule_id, rule in rules_by_id.items():
|
||||
expected = expected_rules_by_id[rule_id]
|
||||
|
||||
assert rule.metadata.action_type == expected.metadata.action_type
|
||||
assert rule.metadata.name == expected.metadata.name
|
||||
assert rule.metadata.predicate == expected.metadata.predicate
|
||||
assert rule.metadata.action == expected.metadata.action
|
||||
assert rule.metadata.id == expected.metadata.id
|
||||
assert rule.metadata.is_compiled == expected.metadata.is_compiled
|
||||
assert rule.metadata.is_enabled == expected.metadata.is_enabled
|
||||
assert rule.compiled_action == expected.compiled_action
|
||||
assert rule.compiled_predicate == expected.compiled_predicate
|
||||
assert rule.priority is not None
|
||||
assert rule.priority == expected.priority
|
||||
|
||||
Reference in New Issue
Block a user