Fixed infinite recursion when parsing complex BNF node
This commit is contained in:
@@ -334,7 +334,10 @@ class ExecutionContext:
|
||||
for k, v in self._bag.items():
|
||||
bag[k] = v
|
||||
bag["bag." + k] = v
|
||||
for prop in ("id", "who", "desc", "obj", "inputs", "values", "concepts"):
|
||||
for prop in ("id", "who", "action", "desc", "obj", "inputs", "values", "concepts"):
|
||||
bag[prop] = getattr(self, prop)
|
||||
bag["action"] = self.action_context
|
||||
for prop in ("desc", "obj", "inputs", "values", "concepts"):
|
||||
bag[prop] = getattr(self, prop)
|
||||
bag["status"] = self.get_status()
|
||||
bag["elapsed"] = self.elapsed
|
||||
@@ -362,15 +365,23 @@ class ExecutionContext:
|
||||
:param predicate:
|
||||
:return:
|
||||
"""
|
||||
res = []
|
||||
current = self
|
||||
while True:
|
||||
parent = current._parent
|
||||
if parent:
|
||||
if predicate is None or predicate(parent):
|
||||
res.append(parent)
|
||||
current = parent
|
||||
else:
|
||||
return list(self.search(predicate, None, False))
|
||||
|
||||
def search(self, predicate=None, get_obj=None, start_with_self=False, stop=None):
|
||||
"""
|
||||
Iter thru execution context parent and return the list of obj
|
||||
:param predicate: what execution context to keep
|
||||
:param get_obj: lambda to compute what to return
|
||||
:param start_with_self: include the current execution context in the search
|
||||
:param stop: stop the search if matched
|
||||
:return:
|
||||
"""
|
||||
current = self if start_with_self else self._parent
|
||||
while current:
|
||||
if stop and stop(current):
|
||||
break
|
||||
|
||||
return res
|
||||
if predicate is None or predicate(current):
|
||||
yield current if get_obj is None else get_obj(current)
|
||||
|
||||
current = current._parent
|
||||
|
||||
@@ -328,7 +328,7 @@ class Sheerka(Concept):
|
||||
self.evaluators.append(evaluator)
|
||||
|
||||
def initialize_concept_node_parsing(self, context):
|
||||
self.init_log.debug("Initializing concept node parsing.")
|
||||
self.init_log.debug("siInitializing concepts by first keyword.")
|
||||
|
||||
concepts_by_first_keyword = self.cache_manager.copy(self.CONCEPTS_BY_FIRST_KEYWORD_ENTRY)
|
||||
res = self.bnp.resolve_concepts_by_first_keyword(context, concepts_by_first_keyword)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import time
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
|
||||
@@ -39,6 +41,7 @@ class SheerkaAdmin(BaseService):
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
start = time.time_ns()
|
||||
self.sheerka.during_restore = True
|
||||
with open(CONCEPTS_FILE, "r") as f:
|
||||
for line in f.readlines():
|
||||
@@ -50,5 +53,11 @@ class SheerkaAdmin(BaseService):
|
||||
if len(res) > 1 or not res[0].status:
|
||||
self.sheerka.log.error("Error detected !")
|
||||
self.sheerka.during_restore = False
|
||||
stop = time.time_ns()
|
||||
|
||||
nano_sec = stop - start
|
||||
dt = nano_sec / 1e6
|
||||
elapsed = f"{dt} ms" if dt < 1000 else f"{dt / 1000} s"
|
||||
print(f"Execution time: {elapsed}")
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
@@ -90,12 +90,12 @@ class SheerkaComparisonManager(BaseService):
|
||||
cache = Cache()
|
||||
self.sheerka.cache_manager.register_cache(self.RESOLVED_COMPARISON_ENTRY, cache, persist=False)
|
||||
|
||||
self.sheerka.bind_service_method(self.is_greater_than)
|
||||
self.sheerka.bind_service_method(self.is_less_than)
|
||||
self.sheerka.bind_service_method(self.set_is_greater_than)
|
||||
self.sheerka.bind_service_method(self.set_is_less_than)
|
||||
self.sheerka.bind_service_method(self.get_partition)
|
||||
self.sheerka.bind_service_method(self.get_concepts_weights)
|
||||
|
||||
def is_greater_than(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||
def set_is_greater_than(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||
"""
|
||||
Records that the property of concept a is greater than concept b's one
|
||||
:param context:
|
||||
@@ -112,7 +112,7 @@ class SheerkaComparisonManager(BaseService):
|
||||
comparison_obj = ComparisonObj(event_digest, prop_name, concept_a.id, concept_b.id, ">", comparison_context)
|
||||
return self._inner_add_comparison(comparison_obj)
|
||||
|
||||
def is_less_than(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||
def set_is_less_than(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||
"""
|
||||
Records that the property of concept a is lesser than concept b's one
|
||||
:param context:
|
||||
|
||||
@@ -52,7 +52,7 @@ class SheerkaCreateNewConcept(BaseService):
|
||||
sheerka.set_id_if_needed(concept, False)
|
||||
|
||||
# compute new concepts_by_first_keyword
|
||||
init_ret_value = self.bnp.get_concepts_by_first_keyword(context, [concept], True)
|
||||
init_ret_value = self.bnp.get_concepts_by_first_token(context, [concept], True)
|
||||
if not init_ret_value.status:
|
||||
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
|
||||
concepts_by_first_keyword = init_ret_value.body
|
||||
|
||||
@@ -296,6 +296,11 @@ class SheerkaEvaluateConcept(BaseService):
|
||||
|
||||
concept.init_key() # only does it if needed
|
||||
concept.metadata.is_evaluated = "body" in all_metadata_to_eval
|
||||
|
||||
# # update the cache for concepts with no variable
|
||||
# if len(concept.metadata.variables) == 0:
|
||||
# self.sheerka.cache_manager.put(self.sheerka.CONCEPTS_BY_ID_ENTRY, concept.id, concept)
|
||||
|
||||
return concept
|
||||
|
||||
def choose_metadata_to_eval(self, context, concept):
|
||||
|
||||
@@ -173,6 +173,17 @@ class SheerkaExecute(BaseService):
|
||||
return pi
|
||||
|
||||
def call_parsers(self, context, return_values):
|
||||
"""
|
||||
Call all the parsers, ordered by priority
|
||||
Possible return value for a parser:
|
||||
None : indicate that you do no need to care about the result
|
||||
ParserResult with status False : Success
|
||||
ParserResult with status False : failed to parse, but the result will be reused by other parsers
|
||||
NotForMe (status is False) : Failed to parse. Do no reuse the result
|
||||
:param context:
|
||||
:param return_values:
|
||||
:return:
|
||||
"""
|
||||
|
||||
# return_values must be a list
|
||||
if not isinstance(return_values, list):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import core.builtin_helpers
|
||||
from cache.Cache import Cache
|
||||
from cache.SetCache import SetCache
|
||||
from core.ast.nodes import python_to_concept
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
@@ -11,9 +12,12 @@ GROUP_PREFIX = 'All_'
|
||||
class SheerkaSetsManager(BaseService):
|
||||
NAME = "SetsManager"
|
||||
CONCEPTS_GROUPS_ENTRY = "SetsManager:Concepts_Groups"
|
||||
CONCEPTS_IN_GROUPS_ENTRY = "SetsManager:Concepts_In_Groups" # cache for get_set_elements()
|
||||
|
||||
def __init__(self, sheerka):
|
||||
super().__init__(sheerka)
|
||||
self.sets = SetCache(default=lambda k: self.sheerka.sdp.get(self.CONCEPTS_GROUPS_ENTRY, k))
|
||||
self.concepts_in_set = Cache()
|
||||
|
||||
def initialize(self):
|
||||
self.sheerka.bind_service_method(self.set_isa)
|
||||
@@ -23,8 +27,8 @@ class SheerkaSetsManager(BaseService):
|
||||
self.sheerka.bind_service_method(self.isa)
|
||||
self.sheerka.bind_service_method(self.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)
|
||||
self.sheerka.cache_manager.register_cache(self.CONCEPTS_GROUPS_ENTRY, self.sets)
|
||||
self.sheerka.cache_manager.register_cache(self.CONCEPTS_IN_GROUPS_ENTRY, self.concepts_in_set, persist=False)
|
||||
|
||||
def set_isa(self, context, concept, concept_set):
|
||||
"""
|
||||
@@ -64,14 +68,14 @@ class SheerkaSetsManager(BaseService):
|
||||
context.log(f"Adding concept {concept} to set {concept_set}", who=self.NAME)
|
||||
ensure_concept(concept, concept_set)
|
||||
|
||||
set_elements = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, concept_set.id)
|
||||
set_elements = self.sets.get(concept_set.id)
|
||||
if set_elements and concept.id in set_elements:
|
||||
return self.sheerka.ret(
|
||||
self.NAME,
|
||||
False,
|
||||
self.sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_IN_SET, body=concept, concept_set=concept_set))
|
||||
|
||||
self.sheerka.cache_manager.put(self.CONCEPTS_GROUPS_ENTRY, concept_set.id, concept.id)
|
||||
self.sets.put(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):
|
||||
@@ -109,8 +113,8 @@ class SheerkaSetsManager(BaseService):
|
||||
if not self.isaset(context, sub_concept):
|
||||
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.CONCEPTS_GROUPS_ENTRY, sub_concept.id)
|
||||
# first, try to see if sub_concept has it's own group entry
|
||||
ids = self.sets.get(sub_concept.id)
|
||||
concepts = self._get_concepts(context, ids, True)
|
||||
|
||||
# aggregate with en entries from its body
|
||||
@@ -139,7 +143,12 @@ class SheerkaSetsManager(BaseService):
|
||||
|
||||
return concepts
|
||||
|
||||
return _get_set_elements(concept)
|
||||
if res := self.concepts_in_set.get(concept.id):
|
||||
return res
|
||||
|
||||
res = _get_set_elements(concept)
|
||||
self.concepts_in_set.put(concept.id, res)
|
||||
return res
|
||||
|
||||
def isinset(self, a, b):
|
||||
"""
|
||||
@@ -156,7 +165,7 @@ class SheerkaSetsManager(BaseService):
|
||||
if not (a.id and b.id):
|
||||
return False
|
||||
|
||||
group_elements = self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, b.id)
|
||||
group_elements = self.sets.get(b.id)
|
||||
return group_elements and a.id in group_elements
|
||||
|
||||
def isa(self, a, b):
|
||||
@@ -187,7 +196,7 @@ class SheerkaSetsManager(BaseService):
|
||||
|
||||
# check if it has a group
|
||||
# TODO: use cache instead of directly requesting sdp
|
||||
if self.sheerka.cache_manager.get(self.CONCEPTS_GROUPS_ENTRY, concept.id):
|
||||
if self.sets.get(concept.id):
|
||||
return True
|
||||
|
||||
# it may be a concept that references a set
|
||||
@@ -240,9 +249,18 @@ for x in xx__concepts__xx:
|
||||
desc=f"Evaluating concepts of a set") as sub_context:
|
||||
sub_context.add_inputs(ids=ids)
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
errors = []
|
||||
for element_id in ids:
|
||||
concept = self.sheerka.get_by_id(element_id)
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept)
|
||||
result.append(evaluated)
|
||||
sub_context.add_inputs(return_value=result)
|
||||
if len(concept.metadata.variables) == 0:
|
||||
# only evaluate
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept)
|
||||
if context.sheerka.is_success(evaluated):
|
||||
result.append(evaluated)
|
||||
else:
|
||||
errors.append(evaluated)
|
||||
else:
|
||||
result.append(concept)
|
||||
sub_context.add_values(return_value=result)
|
||||
sub_context.add_values(errors=errors)
|
||||
return result
|
||||
|
||||
@@ -30,6 +30,8 @@ class SheerkaVariableManager(BaseService):
|
||||
self.sheerka.bind_service_method(self.record)
|
||||
self.sheerka.bind_service_method(self.load)
|
||||
self.sheerka.bind_service_method(self.delete)
|
||||
self.sheerka.bind_service_method(self.set)
|
||||
self.sheerka.bind_service_method(self.get)
|
||||
|
||||
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)
|
||||
@@ -56,3 +58,9 @@ class SheerkaVariableManager(BaseService):
|
||||
|
||||
def delete(self, context, who, key):
|
||||
self.sheerka.cache_manager.delete(self.VARIABLES_ENTRY, who + "|" + key)
|
||||
|
||||
def set(self, context, key, value):
|
||||
return self.record(context, context.event.user_id, key, value)
|
||||
|
||||
def get(self, context, key):
|
||||
return self.load(context.event.user_id, key)
|
||||
|
||||
Reference in New Issue
Block a user