Fixed infinite recursion when parsing complex BNF node

This commit is contained in:
2020-06-23 15:22:27 +02:00
parent 912455c343
commit 7310bc5522
28 changed files with 1082 additions and 276 deletions
+30 -12
View File
@@ -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