Implemented SheerkaOntology

This commit is contained in:
2021-01-11 15:36:03 +01:00
parent e3c2adb533
commit e26c83a825
119 changed files with 6876 additions and 2002 deletions
+117 -39
View File
@@ -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