diff --git a/src/core/sheerka/Sheerka.py b/src/core/sheerka/Sheerka.py index f83c1d2..1ba087d 100644 --- a/src/core/sheerka/Sheerka.py +++ b/src/core/sheerka/Sheerka.py @@ -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 diff --git a/src/core/sheerka/services/SheerkaCreateNewConcept.py b/src/core/sheerka/services/SheerkaCreateNewConcept.py index 4fdb74f..ca8d7fa 100644 --- a/src/core/sheerka/services/SheerkaCreateNewConcept.py +++ b/src/core/sheerka/services/SheerkaCreateNewConcept.py @@ -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 diff --git a/src/core/sheerka/services/SheerkaDump.py b/src/core/sheerka/services/SheerkaDump.py index 4c6154a..1da4bf6 100644 --- a/src/core/sheerka/services/SheerkaDump.py +++ b/src/core/sheerka/services/SheerkaDump.py @@ -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) diff --git a/src/core/sheerka/services/SheerkaEvaluateConcept.py b/src/core/sheerka/services/SheerkaEvaluateConcept.py index 4b00f7d..d6ca0c5 100644 --- a/src/core/sheerka/services/SheerkaEvaluateConcept.py +++ b/src/core/sheerka/services/SheerkaEvaluateConcept.py @@ -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: diff --git a/src/core/sheerka/services/SheerkaExecute.py b/src/core/sheerka/services/SheerkaExecute.py index 35217c7..78aec4c 100644 --- a/src/core/sheerka/services/SheerkaExecute.py +++ b/src/core/sheerka/services/SheerkaExecute.py @@ -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) diff --git a/src/core/sheerka/services/SheerkaHistoryManager.py b/src/core/sheerka/services/SheerkaHistoryManager.py index 0f949d5..e4a03cc 100644 --- a/src/core/sheerka/services/SheerkaHistoryManager.py +++ b/src/core/sheerka/services/SheerkaHistoryManager.py @@ -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 diff --git a/src/core/sheerka/services/SheerkaModifyConcept.py b/src/core/sheerka/services/SheerkaModifyConcept.py index f640d17..319bfd0 100644 --- a/src/core/sheerka/services/SheerkaModifyConcept.py +++ b/src/core/sheerka/services/SheerkaModifyConcept.py @@ -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 diff --git a/src/core/sheerka/services/SheerkaSetsManager.py b/src/core/sheerka/services/SheerkaSetsManager.py index 732aca1..57c0b65 100644 --- a/src/core/sheerka/services/SheerkaSetsManager.py +++ b/src/core/sheerka/services/SheerkaSetsManager.py @@ -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 diff --git a/src/core/sheerka/services/SheerkaVariableManager.py b/src/core/sheerka/services/SheerkaVariableManager.py index 3fa2e95..c40b745 100644 --- a/src/core/sheerka/services/SheerkaVariableManager.py +++ b/src/core/sheerka/services/SheerkaVariableManager.py @@ -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) diff --git a/src/core/sheerka/services/sheerka_service.py b/src/core/sheerka/services/sheerka_service.py index 52eb297..52e8e72 100644 --- a/src/core/sheerka/services/sheerka_service.py +++ b/src/core/sheerka/services/sheerka_service.py @@ -12,3 +12,10 @@ class BaseService: """ def __init__(self, sheerka): self.sheerka = sheerka + + def initialize(self): + """ + Adds cache or bind methods + :return: + """ + pass diff --git a/src/evaluators/PythonEvaluator.py b/src/evaluators/PythonEvaluator.py index 076eacf..da7a775 100644 --- a/src/evaluators/PythonEvaluator.py +++ b/src/evaluators/PythonEvaluator.py @@ -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, } diff --git a/tests/core/test_SheerkaSetsManager.py b/tests/core/test_SheerkaSetsManager.py index 7db7f48..9710079 100644 --- a/tests/core/test_SheerkaSetsManager.py +++ b/tests/core/test_SheerkaSetsManager.py @@ -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} } @@ -275,15 +280,16 @@ class TestSheerkaSetsManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka): foo4 = Concept("foo4") 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} } diff --git a/tests/core/test_SheerkaVariableManager.py b/tests/core/test_SheerkaVariableManager.py index b8982f4..f210413 100644 --- a/tests/core/test_SheerkaVariableManager.py +++ b/tests/core/test_SheerkaVariableManager.py @@ -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 diff --git a/tests/core/test_sheerka.py b/tests/core/test_sheerka.py index e889117..8134bbc 100644 --- a/tests/core/test_sheerka.py +++ b/tests/core/test_sheerka.py @@ -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() diff --git a/tests/evaluators/test_EvalEvaluator.py b/tests/evaluators/test_EvalEvaluator.py index 9189beb..363bff6 100644 --- a/tests/evaluators/test_EvalEvaluator.py +++ b/tests/evaluators/test_EvalEvaluator.py @@ -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)])