Refactored services to inherit from BaseService

This commit is contained in:
2020-05-18 09:43:05 +02:00
parent d080cbb05a
commit c822ff6a7f
15 changed files with 197 additions and 230 deletions
+3 -115
View File
@@ -7,19 +7,10 @@ from cache.CacheManager import CacheManager
from cache.DictionaryCache import DictionaryCache
from cache.IncCache import IncCache
from cache.ListIfNeededCache import ListIfNeededCache
from cache.SetCache import SetCache
from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConcept, BuiltinErrors, BuiltinUnique, \
UnknownConcept
from core.concept import Concept, ConceptParts, PROPERTIES_FOR_NEW
from core.sheerka.ExecutionContext import ExecutionContext
from core.sheerka.services.SheerkaCreateNewConcept import SheerkaCreateNewConcept
from core.sheerka.services.SheerkaDump import SheerkaDump
from core.sheerka.services.SheerkaEvaluateConcept import SheerkaEvaluateConcept
from core.sheerka.services.SheerkaExecute import SheerkaExecute
from core.sheerka.services.SheerkaHistoryManager import SheerkaHistoryManager
from core.sheerka.services.SheerkaModifyConcept import SheerkaModifyConcept
from core.sheerka.services.SheerkaSetsManager import SheerkaSetsManager
from core.sheerka.services.SheerkaVariableManager import SheerkaVariableManager
from core.sheerka_logger import console_handler
from printer.SheerkaPrinter import SheerkaPrinter
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
@@ -44,9 +35,6 @@ class Sheerka(Concept):
RESOLVED_CONCEPTS_SYA_DEFINITION_ENTRY = "Resolved_Concepts_Sya_Definitions"
CONCEPTS_GRAMMARS_ENTRY = "Concepts_Grammars"
CONCEPTS_GROUPS_ENTRY = "Concepts_Groups"
VARIABLES_ENTRY = "Variables" # entry for admin or internal variables
CONCEPTS_KEYS_ENTRY = "Concepts_Keys"
BUILTIN_CONCEPTS_KEYS = "Builtins_Concepts" # sequential key for builtin concepts
USER_CONCEPTS_KEYS = "User_Concepts" # sequential key for user defined concepts
@@ -81,15 +69,7 @@ class Sheerka(Concept):
self.evaluators_prefix: str = None
self.parsers_prefix: str = None
self.execute_handler = SheerkaExecute(self)
self.create_new_concept_handler = SheerkaCreateNewConcept(self)
self.modify_concept_handler = SheerkaModifyConcept(self)
self.dump_handler = SheerkaDump(self)
self.sets_handler = SheerkaSetsManager(self)
self.evaluate_concept_handler = SheerkaEvaluateConcept(self)
self.history_handler = SheerkaHistoryManager(self)
self.printer_handler = SheerkaPrinter(self)
self.variable_handler = SheerkaVariableManager(self)
self.during_restore = False
self._builtins_classes_cache = None
@@ -148,6 +128,7 @@ class Sheerka(Concept):
self.sdp = SheerkaDataProvider(root_folder, self)
self.initialize_caching()
self.initialize_services()
event = Event("Initializing Sheerka.", user_id=self.name)
self.sdp.save_event(event)
@@ -155,7 +136,6 @@ class Sheerka(Concept):
if self.sdp.first_time:
self.first_time_initialisation(exec_context)
self.initialize_services()
self.initialize_builtin_parsers()
self.initialize_builtin_evaluators()
self.initialize_builtin_concepts()
@@ -209,12 +189,6 @@ class Sheerka(Concept):
self.cache_manager.register_cache(self.CONCEPTS_SYA_DEFINITION_ENTRY, cache)
self.cache_manager.get(self.CONCEPTS_SYA_DEFINITION_ENTRY, None) # to init from sdp
cache = SetCache(default=lambda k: self.sdp.get(self.CONCEPTS_GROUPS_ENTRY, k))
self.cache_manager.register_cache(self.CONCEPTS_GROUPS_ENTRY, cache)
cache = Cache(default=lambda k: self.sdp.get(self.VARIABLES_ENTRY, k))
self.cache_manager.register_cache(self.VARIABLES_ENTRY, cache, True, True)
cache = DictionaryCache()
self.cache_manager.register_cache(self.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, cache, persist=False)
@@ -227,7 +201,7 @@ class Sheerka(Concept):
def first_time_initialisation(self, context):
self.cache_manager.put(self.CONCEPTS_KEYS_ENTRY, self.USER_CONCEPTS_KEYS, 1000)
self.variable_handler.record(context, self.name, "save_execution_context", True)
self.record(context, self.name, "save_execution_context", True)
def initialize_services(self):
"""
@@ -375,7 +349,7 @@ class Sheerka(Concept):
if self.cache_manager.is_dirty:
self.cache_manager.commit(execution_context)
if self.save_execution_context and self.variable_handler.load(self.name, "save_execution_context"):
if self.save_execution_context and self.load(self.name, "save_execution_context"):
self.sdp.save_result(execution_context)
# # hack to save valid concept definition
@@ -396,25 +370,6 @@ class Sheerka(Concept):
"""
self.printer_handler.print(result, instructions)
def record(self, context, who, key, value):
return self.variable_handler.record(context, who, key, value)
def load(self, who, key):
return self.variable_handler.load(who, key)
def delete(self, context, who, key):
return self.variable_handler.delete(context, who, key)
def execute(self, execution_context, return_values, execution_steps):
"""
Executes process for all initial contexts
:param execution_context:
:param return_values:
:param execution_steps:
:return:
"""
return self.execute_handler.execute(execution_context, return_values, execution_steps)
def set_id_if_needed(self, obj: Concept, is_builtin: bool):
"""
Set the key for the concept if needed
@@ -430,39 +385,6 @@ class Sheerka(Concept):
obj.metadata.id = str(self.cache_manager.get(self.CONCEPTS_KEYS_ENTRY, key))
self.log.debug(f"Setting id '{obj.metadata.id}' to concept '{obj.metadata.name}'.")
def create_new_concept(self, context, concept: Concept):
"""
Adds a new concept to the system
:param context:
:param concept: DefConceptNode
:return: digest of the new concept
"""
return self.create_new_concept_handler.create_new_concept(context, concept)
def modify_concept(self, context, concept: Concept):
return self.modify_concept_handler.modify_concept(context, concept)
def add_concept_to_set(self, context, concept, concept_set):
"""
Add an entry in sdp to tell that concept isa concept_set
:param context:
:param concept:
:param concept_set:
:return:
"""
return self.sets_handler.add_concept_to_set(context, concept, concept_set)
def set_isa(self, context, concept, concept_set):
"""
:param context:
:param concept:
:param concept_set:
:return:
"""
return self.sets_handler.set_isa(context, concept, concept_set)
def force_sya_def(self, context, list_of_def):
"""
Set the precedence and/or the associativity of a concept
@@ -497,27 +419,6 @@ class Sheerka(Concept):
return self.ret(self.name, True, self.new(BuiltinConcepts.SUCCESS))
def get_set_elements(self, context, concept):
"""
Concept is supposed to be a set
Returns all elements if the set
:param context:
:param concept:
:return:
"""
return self.sets_handler.get_set_elements(context, concept)
def evaluate_concept(self, context, concept: Concept):
"""
Evaluation a concept
It means that if the where clause is True, will evaluate the body
:param context:
:param concept:
:return: value of the evaluation or error
"""
return self.evaluate_concept_handler.evaluate_concept(context, concept)
def add_in_cache(self, concept: Concept):
"""
Adds a concept template in cache.
@@ -788,15 +689,6 @@ class Sheerka(Concept):
return a.key == b_key
def isinset(self, a, b):
return self.sets_handler.isinset(a, b)
def isa(self, a, b):
return self.sets_handler.isa(a, b)
def isaset(self, context, concept):
return self.sets_handler.isaset(context, concept)
def get_evaluator_name(self, name):
if self.evaluators_prefix is None:
base_evaluator_class = core.utils.get_class("evaluators.BaseEvaluator.BaseEvaluator")
@@ -826,10 +718,6 @@ class Sheerka(Concept):
return sorted(res, key=lambda i: int(i.id))
def history(self, page=10, start=0):
"""Gets the history of all commands"""
return self.history_handler.history(page, start)
def restore(self):
"""
Restore the state with all previous valid concept definitions
@@ -1,22 +1,27 @@
import core.utils
from core.builtin_concepts import BuiltinConcepts, ErrorConcept
from core.concept import Concept
from core.sheerka.services.sheerka_service import BaseService
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
BNF_NODE_PARSER_CLASS = "parsers.BnfNodeParser_Old.BnfNodeParser"
BASE_NODE_PARSER_CLASS = "parsers.BaseNodeParser.BaseNodeParser"
class SheerkaCreateNewConcept:
class SheerkaCreateNewConcept(BaseService):
"""
Manage the creation of a new concept
"""
NAME = "CreateNewConcept"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "CreateNewConcept"
super().__init__(sheerka)
self.bnp = core.utils.get_class(BASE_NODE_PARSER_CLASS) # BaseNodeParser
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaCreateNewConcept.create_new_concept)
def create_new_concept(self, context, concept: Concept):
"""
Adds a new concept to the system
@@ -36,7 +41,7 @@ class SheerkaCreateNewConcept:
error = SheerkaDataProviderDuplicateKeyError(sheerka.CONCEPTS_BY_KEY_ENTRY + "." + concept.key,
concept)
return sheerka.ret(
self.logger_name,
self.NAME,
False,
sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=concept),
error.args[0])
@@ -47,13 +52,13 @@ class SheerkaCreateNewConcept:
# update the dictionary of concepts by first key
init_ret_value = self.bnp.get_concepts_by_first_keyword(context, [concept], True)
if not init_ret_value.status:
return sheerka.ret(self.logger_name, False, ErrorConcept(init_ret_value.value))
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
concepts_by_first_keyword = init_ret_value.body
# update resolved dictionary
init_ret_value = self.bnp.resolve_concepts_by_first_keyword(context, concepts_by_first_keyword)
if not init_ret_value.status:
return sheerka.ret(self.logger_name, False, ErrorConcept(init_ret_value.value))
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
resolved_concepts_by_first_keyword = init_ret_value.body
concept.freeze_definition_hash()
@@ -66,5 +71,5 @@ class SheerkaCreateNewConcept:
sheerka.cache_manager.clear(sheerka.CONCEPTS_GRAMMARS_ENTRY)
# process the return if needed
ret = sheerka.ret(self.logger_name, True, sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
ret = sheerka.ret(self.NAME, True, sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
return ret
+33 -24
View File
@@ -4,6 +4,7 @@ import pprint
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.ExecutionContext import ExecutionContext
from core.sheerka.services.sheerka_service import BaseService
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
@@ -13,9 +14,17 @@ def get_pp():
return pp
class SheerkaDump:
class SheerkaDump(BaseService):
NAME = "Dump"
def __init__(self, sheerka):
self.sheerka = sheerka
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaDump.dump_concepts, "concepts")
self.sheerka.bind_service_method(self, SheerkaDump.dump_desc, "desc")
self.sheerka.bind_service_method(self, SheerkaDump.dump_state, "state")
def dump_concepts(self):
lst = self.sheerka.sdp.list(self.sheerka.CONCEPTS_BY_ID_ENTRY)
@@ -69,28 +78,28 @@ class SheerkaDump:
first = False
def dump_history(self, page=20, start=0):
count = 0
resolved_page = page if page > 0 else 50
page_count = 0
while count < page if page > 0 else True:
history = self.sheerka.history(resolved_page, start + page_count * resolved_page)
try:
h = next(history)
except StopIteration:
break
while True:
try:
if h.result:
self.sheerka.log.info(h)
count += 1
h = next(history)
except StopIteration:
break
page_count += 1
# def dump_history(self, page=20, start=0):
# count = 0
# resolved_page = page if page > 0 else 50
# page_count = 0
#
# while count < page if page > 0 else True:
# history = self.sheerka.history(resolved_page, start + page_count * resolved_page)
# try:
# h = next(history)
# except StopIteration:
# break
#
# while True:
# try:
# if h.result:
# self.sheerka.log.info(h)
# count += 1
# h = next(history)
# except StopIteration:
# break
#
# page_count += 1
def dump_state(self):
snapshot = self.sheerka.sdp.get_snapshot(SheerkaDataProvider.HeadFile)
@@ -1,6 +1,7 @@
from core.builtin_concepts import BuiltinConcepts
from core.builtin_helpers import expect_one, only_successful
from core.concept import Concept, DoNotResolve, ConceptParts, InfiniteRecursionResolved
from core.sheerka.services.sheerka_service import BaseService
CONCEPT_EVALUATION_STEPS = [
BuiltinConcepts.BEFORE_EVALUATION,
@@ -8,10 +9,14 @@ CONCEPT_EVALUATION_STEPS = [
BuiltinConcepts.AFTER_EVALUATION]
class SheerkaEvaluateConcept:
class SheerkaEvaluateConcept(BaseService):
NAME = "EvaluateConcept"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "EvaluateConcept"
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaEvaluateConcept.evaluate_concept)
@staticmethod
def infinite_recursion_detected(context, concept):
@@ -51,14 +56,14 @@ class SheerkaEvaluateConcept:
if parent.who == context.who and parent.desc == context.desc:
body = parent.obj.metadata.body
try:
return self.sheerka.ret(self.logger_name, True, InfiniteRecursionResolved(eval(body)))
return self.sheerka.ret(self.NAME, True, InfiniteRecursionResolved(eval(body)))
except Exception:
pass
concepts_found.add(parent.obj)
parent = parent.get_parent()
return self.sheerka.ret(
self.logger_name,
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.CHICKEN_AND_EGG, body=concepts_found))
@@ -71,10 +76,11 @@ class SheerkaEvaluateConcept:
:param logger:
:return:
"""
def is_only_successful(r):
# return False
# return False
return context.sheerka.isinstance(r, BuiltinConcepts.RETURN_VALUE) and \
context.sheerka.isinstance(r.body, BuiltinConcepts.ONLY_SUCCESSFUL)
context.sheerka.isinstance(r.body, BuiltinConcepts.ONLY_SUCCESSFUL)
steps = [BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.PARSING, BuiltinConcepts.AFTER_PARSING]
for part_key in ConceptParts:
@@ -134,7 +140,7 @@ class SheerkaEvaluateConcept:
return ret_val.body
desc = f"Evaluating {current_prop} (concept={current_concept})"
context.log(desc, self.logger_name)
context.log(desc, self.NAME)
with context.push(desc=desc, obj=current_concept) as sub_context:
if force_evaluation:
+21 -15
View File
@@ -1,18 +1,24 @@
import core.utils
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
from core.sheerka.services.sheerka_service import BaseService
NO_MATCH = "** No Match **"
class SheerkaExecute:
class SheerkaExecute(BaseService):
"""
Manage the execution of a process flow
"""
def __init__(self, sheerka):
self.sheerka = sheerka
NAME = "Execute"
def call_parsers(self, execution_context, return_values):
def __init__(self, sheerka):
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaExecute.execute)
def call_parsers(self, context, return_values):
# return_values must be a list
if not isinstance(return_values, list):
@@ -35,7 +41,7 @@ class SheerkaExecute:
# group the parsers by priorities
instantiated_parsers = [parser(sheerka=self.sheerka) for parser in self.sheerka.parsers.values()]
instantiated_parsers = self.preprocess(execution_context, instantiated_parsers)
instantiated_parsers = self.preprocess(context, instantiated_parsers)
grouped_parsers = {}
for parser in [p for p in instantiated_parsers if p.enabled]:
@@ -57,10 +63,10 @@ class SheerkaExecute:
# if self.sheerka.log.isEnabledFor(logging.DEBUG):
# debug_text = "'" + to_parse + "'" if isinstance(to_parse, str) \
# else "'" + BaseParser.get_text_from_tokens(to_parse) + "' as tokens"
# execution_context.log(f"Parsing {debug_text}")
# context.log(f"Parsing {debug_text}")
with execution_context.push(desc=f"Parsing using {parser.name}",
logger=parser.verbose_log) as sub_context:
with context.push(desc=f"Parsing using {parser.name}",
logger=parser.verbose_log) as sub_context:
sub_context.add_inputs(to_parse=to_parse)
res = parser.parse(sub_context, to_parse)
if res is not None:
@@ -94,7 +100,7 @@ class SheerkaExecute:
result = core.utils.remove_list_from_list(result, user_inputs)
return result
def call_evaluators(self, execution_context, return_values, process_step):
def call_evaluators(self, context, return_values, process_step):
# return_values must be a list
if not isinstance(return_values, list):
@@ -106,7 +112,7 @@ class SheerkaExecute:
instantiated_evaluators = [e_class() for e_class in self.sheerka.evaluators]
# pre-process evaluators if needed
instantiated_evaluators = self.preprocess(execution_context, instantiated_evaluators)
instantiated_evaluators = self.preprocess(context, instantiated_evaluators)
for evaluator in [e for e in instantiated_evaluators if e.enabled and process_step in e.steps]:
grouped_evaluators.setdefault(evaluator.priority, []).append(evaluator)
@@ -117,7 +123,7 @@ class SheerkaExecute:
# process
iteration = 0
while True:
with execution_context.push(desc=f"iteration #{iteration}", iteration=iteration) as iteration_context:
with context.push(desc=f"iteration #{iteration}", iteration=iteration) as iteration_context:
simple_digest = return_values[:]
iteration_context.add_inputs(return_values=simple_digest)
@@ -127,7 +133,7 @@ class SheerkaExecute:
evaluated_items = []
to_delete = []
for evaluator in grouped_evaluators[priority]:
evaluator = self.preprocess(execution_context, evaluator.__class__()) # fresh copy
evaluator = self.preprocess(context, evaluator.__class__()) # fresh copy
sub_context_desc = f"Evaluating using {evaluator.name} ({priority=})"
with iteration_context.push(desc=sub_context_desc, logger=evaluator.verbose_log) as sub_context:
@@ -194,10 +200,10 @@ class SheerkaExecute:
return return_values
def execute(self, execution_context, return_values, execution_steps):
def execute(self, context, return_values, execution_steps):
"""
Executes process for all initial contexts
:param execution_context:
:param context:
:param return_values:
:param execution_steps:
:return:
@@ -205,7 +211,7 @@ class SheerkaExecute:
for step in execution_steps:
copy = return_values[:] if hasattr(return_values, "__iter__") else [return_values]
with execution_context.push(step=step, iteration=0, desc=f"{step=}") as sub_context:
with context.push(step=step, iteration=0, desc=f"{step=}") as sub_context:
if step == BuiltinConcepts.PARSING:
return_values = self.call_parsers(sub_context, return_values)
@@ -1,5 +1,6 @@
from collections import namedtuple
from core.sheerka.services.sheerka_service import BaseService
from sdp.sheerkaDataProvider import Event
hist = namedtuple("HistoryTest", "text status") # tests purposes only
@@ -42,11 +43,16 @@ class History:
return self._status
class SheerkaHistoryManager:
def __init__(self, sheerka):
self.sheerka = sheerka
class SheerkaHistoryManager(BaseService):
NAME = "History"
def history(self, depth, start):
def __init__(self, sheerka):
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaHistoryManager.history)
def history(self, depth=10, start=0):
"""
Load history
:param depth: number of items
@@ -1,10 +1,15 @@
from core.builtin_concepts import BuiltinConcepts
from core.sheerka.services.sheerka_service import BaseService
class SheerkaModifyConcept:
class SheerkaModifyConcept(BaseService):
NAME = "ModifyConcept"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "ModifyConcept"
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaModifyConcept.modify_concept)
def modify_concept(self, context, concept):
old_version = self.sheerka.get_by_id(concept.id)
@@ -12,7 +17,7 @@ class SheerkaModifyConcept:
if old_version is None:
# nothing found in cache
return self.sheerka.ret(
self.logger_name, False,
self.NAME, False,
self.sheerka.new(
BuiltinConcepts.UNKNOWN_CONCEPT,
body=[("key", concept.key), ("id", concept.id)]))
@@ -20,13 +25,13 @@ class SheerkaModifyConcept:
if not self.sheerka.is_success(old_version) and concept.key != old_version.key:
# an error concept is returned
return self.sheerka.ret(
self.logger_name, False,
self.NAME, False,
old_version)
if old_version == concept:
# the concept is not modified
return self.sheerka.ret(
self.logger_name, False,
self.NAME, False,
self.sheerka.new(
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
body=concept))
@@ -37,5 +42,5 @@ class SheerkaModifyConcept:
# TODO : update resolved by first keyword
# TODO : update concepts grammars
ret = self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
ret = self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
return ret
+30 -15
View File
@@ -1,15 +1,30 @@
import core.builtin_helpers
from cache.SetCache import SetCache
from core.ast.nodes import python_to_concept
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, ConceptParts
from core.sheerka.services.sheerka_service import BaseService
GROUP_PREFIX = 'All_'
class SheerkaSetsManager:
class SheerkaSetsManager(BaseService):
NAME = "SetsManager"
CONCEPTS_GROUPS_ENTRY = "Concepts_Groups"
def __init__(self, sheerka):
self.sheerka = sheerka
self.logger_name = "SetsManager"
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaSetsManager.set_isa)
self.sheerka.bind_service_method(self, SheerkaSetsManager.get_set_elements)
self.sheerka.bind_service_method(self, SheerkaSetsManager.add_concept_to_set)
self.sheerka.bind_service_method(self, SheerkaSetsManager.isinset)
self.sheerka.bind_service_method(self, SheerkaSetsManager.isa)
self.sheerka.bind_service_method(self, SheerkaSetsManager.isaset)
cache = SetCache(default=lambda k: self.sheerka.sdp.get(self.CONCEPTS_GROUPS_ENTRY, k))
self.sheerka.cache_manager.register_cache(self.CONCEPTS_GROUPS_ENTRY, cache)
def set_isa(self, context, concept, concept_set):
"""
@@ -20,11 +35,11 @@ class SheerkaSetsManager:
:return:
"""
context.log(f"Setting concept {concept} is a {concept_set}", who=self.logger_name)
context.log(f"Setting concept {concept} is a {concept_set}", who=self.NAME)
if BuiltinConcepts.ISA in concept.metadata.props and concept_set in concept.metadata.props[BuiltinConcepts.ISA]:
return self.sheerka.ret(
self.logger_name,
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_IN_SET, body=concept, concept_set=concept_set))
@@ -45,25 +60,25 @@ class SheerkaSetsManager:
:return:
"""
context.log(f"Adding concept {concept} to set {concept_set}", who=self.logger_name)
context.log(f"Adding concept {concept} to set {concept_set}", who=self.NAME)
assert concept.id
assert concept_set.id
set_elements = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, concept_set.id)
set_elements = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, concept_set.id)
if set_elements and concept.id in set_elements:
return self.sheerka.ret(
self.logger_name,
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_IN_SET, body=concept, concept_set=concept_set))
self.sheerka.cache_manager.put(self.sheerka.CONCEPTS_GROUPS_ENTRY, concept_set.id, concept.id)
return self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
self.sheerka.cache_manager.put(self.CONCEPTS_GROUPS_ENTRY, concept_set.id, concept.id)
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
def add_concepts_to_set(self, context, concepts, concept_set):
"""Adding multiple concepts at the same time"""
context.log(f"Adding concepts {concepts} to set {concept_set}", who=self.logger_name)
context.log(f"Adding concepts {concepts} to set {concept_set}", who=self.NAME)
already_in_set = []
for concept in concepts:
res = self.add_concept_to_set(context, concept, concept_set)
@@ -77,7 +92,7 @@ class SheerkaSetsManager:
else:
body = self.sheerka.new(BuiltinConcepts.SUCCESS)
return self.sheerka.ret(self.logger_name, len(already_in_set) != len(concepts), body)
return self.sheerka.ret(self.NAME, len(already_in_set) != len(concepts), body)
def get_set_elements(self, context, concept):
"""
@@ -93,7 +108,7 @@ class SheerkaSetsManager:
return self.sheerka.new(BuiltinConcepts.NOT_A_SET, body=concept)
# first, try to see if sub_context has it's own group entry
ids = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, sub_concept.id)
ids = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, sub_concept.id)
concepts = self._get_concepts(context, ids, True)
# aggregate with en entries from its body
@@ -143,7 +158,7 @@ class SheerkaSetsManager:
if not (a.id and b.id):
return False
group_elements = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, b.id)
group_elements = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, b.id)
return group_elements and a.id in group_elements
def isa(self, a, b):
@@ -173,7 +188,7 @@ class SheerkaSetsManager:
# check if it has a group
# TODO: use cache instead of directly requesting sdp
if self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_GROUPS_ENTRY, concept.id):
if self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, concept.id):
return True
# it may be a concept that references a set
@@ -1,7 +1,8 @@
from dataclasses import dataclass
from typing import List
from core.sheerka.services.sheerka_service import ServiceObj
from cache.Cache import Cache
from core.sheerka.services.sheerka_service import ServiceObj, BaseService
@dataclass
@@ -18,10 +19,20 @@ class Variable(ServiceObj):
return f"{self.who}|{self.key}"
class SheerkaVariableManager:
class SheerkaVariableManager(BaseService):
NAME = "VariableManager"
VARIABLES_ENTRY = "Variables" # entry for admin or internal variables
def __init__(self, sheerka):
self.sheerka = sheerka
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self, SheerkaVariableManager.record)
self.sheerka.bind_service_method(self, SheerkaVariableManager.load)
self.sheerka.bind_service_method(self, SheerkaVariableManager.delete)
cache = Cache(default=lambda k: self.sheerka.sdp.get(self.VARIABLES_ENTRY, k))
self.sheerka.cache_manager.register_cache(self.VARIABLES_ENTRY, cache, True, True)
def record(self, context, who, key, value):
"""
@@ -34,14 +45,14 @@ class SheerkaVariableManager:
"""
variable = Variable(context.event.get_digest(), who, key, value, None)
self.sheerka.cache_manager.put(self.sheerka.VARIABLES_ENTRY, variable.get_key(), variable)
self.sheerka.cache_manager.put(self.VARIABLES_ENTRY, variable.get_key(), variable)
def load(self, who, key):
variable = self.sheerka.cache_manager.get(self.sheerka.VARIABLES_ENTRY, who + "|" + key)
variable = self.sheerka.cache_manager.get(self.VARIABLES_ENTRY, who + "|" + key)
if variable is None:
return None
return variable.value
def delete(self, context, who, key):
self.sheerka.cache_manager.delete(self.sheerka.VARIABLES_ENTRY, who + "|" + key)
self.sheerka.cache_manager.delete(self.VARIABLES_ENTRY, who + "|" + key)
@@ -12,3 +12,10 @@ class BaseService:
"""
def __init__(self, sheerka):
self.sheerka = sheerka
def initialize(self):
"""
Adds cache or bind methods
:return:
"""
pass
+4 -4
View File
@@ -66,10 +66,10 @@ class PythonEvaluator(OneReturnValueEvaluator):
def get_globals(self, context, node):
my_locals = {
"sheerka": context.sheerka,
"desc": context.sheerka.dump_handler.dump_desc,
"concepts": context.sheerka.dump_handler.dump_concepts,
"history": context.sheerka.dump_handler.dump_history,
"state": context.sheerka.dump_handler.dump_state,
# "desc": context.sheerka.dump_handler.dump_desc,
# "concepts": context.sheerka.dump_handler.dump_concepts,
# "history": context.sheerka.dump_handler.dump_history,
# "state": context.sheerka.dump_handler.dump_state,
"Concept": core.concept.Concept,
"BuiltinConcepts": core.builtin_concepts.BuiltinConcepts,
}
+24 -18
View File
@@ -1,5 +1,6 @@
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaSetsManager import SheerkaSetsManager
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -15,12 +16,12 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
)
assert sheerka.add_concept_to_set(context, foo, group).status
group_elements = sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group.id)
group_elements = sheerka.cache_manager.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY, group.id)
assert group_elements == {foo.id}
# it can be persisted
sheerka.cache_manager.commit(context)
assert sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY, group.id) == {foo.id}
assert sheerka.sdp.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY, group.id) == {foo.id}
def test_i_cannot_add_the_same_concept_twice_in_a_set(self):
sheerka, context, foo, group = self.init_concepts(Concept("foo"), Concept("group"))
@@ -34,7 +35,7 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
assert res.body.body == foo
assert res.body.concept_set == group
all_entries = sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group.id)
all_entries = sheerka.cache_manager.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY, group.id)
assert all_entries == {foo.id}
def test_i_can_have_multiple_groups(self):
@@ -52,12 +53,12 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
assert sheerka.add_concept_to_set(context, bar, group2).status
assert sheerka.add_concept_to_set(context, baz, group2).status
assert sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group1.id) == {foo.id, bar.id}
assert sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group2.id) == {baz.id, bar.id}
assert sheerka.cache_manager.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY, group1.id) == {foo.id, bar.id}
assert sheerka.cache_manager.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY, group2.id) == {baz.id, bar.id}
# I can save in db
sheerka.cache_manager.commit(context)
assert sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY) == {
assert sheerka.sdp.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY) == {
'1004': {'1001', '1002'}, '1005': {'1002', '1003'}
}
@@ -95,7 +96,8 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
sheerka, context, foo, bar, group1, group2 = self.init_concepts(
"foo", "bar", "group1", Concept("group2", body="group1"))
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar], group1)
service = sheerka.services[SheerkaSetsManager.NAME]
service.add_concepts_to_set(context, [foo, bar], group1)
assert sheerka.isaset(context, group2)
assert set(sheerka.get_set_elements(context, group2)) == {foo, bar}
@@ -110,7 +112,8 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
Concept("number"),
Concept("sub_number", body="number", where="number < 4")
)
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
service = sheerka.services[SheerkaSetsManager.NAME]
service.add_concepts_to_set(context, [one, two, three, four, five], number)
assert sheerka.isaset(context, sub_number)
assert set(sheerka.get_set_elements(context, sub_number)) == {one, two, three}
@@ -126,7 +129,8 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
Concept("sub_number", body="number", where="number < 4"),
Concept("sub_sub_number", body="sub_number", where="sub_number > 2")
)
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
service = sheerka.services[SheerkaSetsManager.NAME]
service.add_concepts_to_set(context, [one, two, three, four, five], number)
assert sheerka.isaset(context, sub_sub_number)
assert set(sheerka.get_set_elements(context, sub_sub_number)) == {three}
@@ -149,7 +153,8 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
Concept("number"),
Concept("sub_number", body="number", where="number < 4")
)
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
service = sheerka.services[SheerkaSetsManager.NAME]
service.add_concepts_to_set(context, [one, two, three, four, five], number)
assert sheerka.isaset(context, sub_number)
assert set(sheerka.get_set_elements(context, sub_number)) == {one, three}
@@ -170,8 +175,8 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
Concept("number"),
Concept("sub_number", body="number", where="number >= 20")
)
sheerka.sets_handler.add_concepts_to_set(context, [one, two, twenty, twenties], number)
service = sheerka.services[SheerkaSetsManager.NAME]
service.add_concepts_to_set(context, [one, two, twenty, twenties], number)
assert sheerka.isaset(context, sub_number)
assert sheerka.get_set_elements(context, sub_number) == [twenty] # what is expected ?
@@ -195,8 +200,8 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
Concept("number"),
create_new=True
)
sheerka.sets_handler.add_concepts_to_set(context, [one, two, twenty, twenties], number)
service = sheerka.services[SheerkaSetsManager.NAME]
service.add_concepts_to_set(context, [one, two, twenty, twenties], number)
assert sheerka.isinset(twenties, number)
twenty_one = sheerka.evaluate_user_input("twenty one", "")[0].body
@@ -264,7 +269,7 @@ class TestSheerkaSetsManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
assert set(sheerka.get_set_elements(context, group)) == {foo, bar}
sheerka.cache_manager.commit(context) # save in db
all_entries = sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY) # check the db
all_entries = sheerka.sdp.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY) # check the db
assert all_entries == {
group.id: {foo.id, bar.id}
}
@@ -276,14 +281,15 @@ class TestSheerkaSetsManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
for c in [foo3, foo4]:
sheerka.create_new_concept(context, c)
res = sheerka.sets_handler.add_concepts_to_set(context, (foo3, foo4), group)
sets_handler = sheerka.services[SheerkaSetsManager.NAME]
res = sets_handler.add_concepts_to_set(context, (foo3, foo4), group)
assert res.status
# I can get the elements
assert set(sheerka.get_set_elements(context, group)) == {foo, bar, foo3, foo4}
sheerka.cache_manager.commit(context) # save in db
all_entries = sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY) # check the db
all_entries = sheerka.sdp.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY) # check the db
assert all_entries == {
group.id: {foo.id, bar.id, foo3.id, foo4.id}
}
@@ -322,7 +328,7 @@ class TestSheerkaSetsManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
# they are both in the same group
sheerka = self.get_sheerka()
all_entries = sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY)
all_entries = sheerka.sdp.get(SheerkaSetsManager.CONCEPTS_GROUPS_ENTRY)
assert all_entries == {
group.id: {foo.id, bar.id}
}
+5 -4
View File
@@ -1,5 +1,6 @@
from core.concept import Concept, ConceptParts
from core.sheerka.Sheerka import Sheerka
from core.sheerka.services.SheerkaVariableManager import SheerkaVariableManager
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -16,8 +17,8 @@ class TestSheerkaVariable(TestUsingMemoryBasedSheerka):
# I can persist in db
sheerka.cache_manager.commit(context)
assert sheerka.sdp.exists(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable|my_variable")
loaded = sheerka.sdp.get(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable|my_variable")
assert sheerka.sdp.exists(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable|my_variable")
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable|my_variable")
assert loaded.event_id == context.event.get_digest()
assert loaded.key == "my_variable"
assert loaded.value == 1
@@ -58,7 +59,7 @@ class TestSheerkaVariable(TestUsingMemoryBasedSheerka):
# res = sheerka.load("TestSheerkaVariable", "my_variable")
# assert res == 2
#
# loaded = sheerka.sdp.get(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
# loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
# assert loaded.event_id == context.event.get_digest()
# assert loaded.key == "my_variable"
# assert loaded.value == 2
@@ -79,7 +80,7 @@ class TestSheerkaVariable(TestUsingMemoryBasedSheerka):
# sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
# sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
#
# loaded = sheerka.sdp.get(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
# loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
# assert loaded.event_id == context.event.get_digest()
# assert loaded.key == "my_variable"
# assert loaded.value == 1
+1 -1
View File
@@ -21,7 +21,7 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
assert len(sheerka.services) > 0
assert None not in sheerka.services
assert "ComparisonManager" in sheerka.services # test at least one service
assert "VariableManager" in sheerka.services # test at least one service
def test_i_can_initialize_builtin_parsers(self):
sheerka = self.get_sheerka()
+3 -1
View File
@@ -2,6 +2,7 @@ import pytest
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaSetsManager import SheerkaSetsManager
from evaluators.EvalEvaluator import EvalEvaluator
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -69,7 +70,8 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
Concept("bar"),
Concept("baz"),
Concept("number"))
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar, baz], number)
sets_handler = sheerka.services[SheerkaSetsManager.NAME]
sets_handler.add_concepts_to_set(context, [foo, bar, baz], number)
evaluated = EvalEvaluator().eval(context, [retval(number)])