Managing concept properties in ConceptEvaluator

This commit is contained in:
2019-11-16 18:11:29 +01:00
parent 3a1dea19e8
commit 7fa509555d
13 changed files with 808 additions and 57 deletions
+59 -22
View File
@@ -150,19 +150,24 @@ class Sheerka(Concept):
evt_digest = self.sdp.save_event(Event(text))
exec_context = ExecutionContext(self.key, evt_digest, self)
before_parsing = self.ret(self.eval.__name__, True, self.new(BuiltinConcepts.BEFORE_PARSING))
# Before parsing
before_parsing = self.new(BuiltinConcepts.BEFORE_PARSING)
return_values = self.process(exec_context, [], [before_parsing])
return_values = core.utils.remove_from_list(return_values, [before_parsing])
return_values = core.utils.remove_from_list(return_values, lambda x: x.value == before_parsing)
# parse
parsing_results = self.parse(exec_context, text)
return_values.extend(parsing_results)
processing_parsing = self.ret(self.eval.__name__, True, self.new(BuiltinConcepts.PARSING))
return_values = self.process(exec_context, return_values, [processing_parsing])
return_values = core.utils.remove_from_list(return_values, [processing_parsing])
after_parsing = self.ret(self.eval.__name__, True, self.new(BuiltinConcepts.AFTER_PARSING))
return_values = self.process(exec_context, return_values, [after_parsing])
return_values = core.utils.remove_from_list(return_values, [after_parsing])
# evaluate
evaluating = self.new(BuiltinConcepts.EVALUATION)
return_values = self.process(exec_context, return_values, [evaluating])
return_values = core.utils.remove_from_list(return_values, lambda x: x.value == evaluating)
# post evaluation
after_evaluation = self.new(BuiltinConcepts.AFTER_EVALUATION)
return_values = self.process(exec_context, return_values, [after_evaluation])
return_values = core.utils.remove_from_list(return_values, lambda x: x.value == after_evaluation)
return return_values
@@ -207,17 +212,17 @@ class Sheerka(Concept):
result.append(res)
return result
def process(self, context, return_values, contextual_concepts=None):
contextual_concepts_values = [c.value for c in contextual_concepts] if contextual_concepts else []
log.debug(f"Processing parsing result. context concept={contextual_concepts_values}")
def process(self, context, return_values, initial_concepts=None):
log.debug(f"Processing parsing result. context concept={initial_concepts}")
# return_values must be a list
if not isinstance(return_values, list):
return_values = [return_values]
# adds contextual concepts
if contextual_concepts:
return_values.extend(contextual_concepts)
if initial_concepts:
for concept in initial_concepts:
return_values.append(self.ret(context.who, True, concept))
# group the evaluators by priority and sort them
# The first one to be applied will be the one with the highest priority
@@ -261,6 +266,8 @@ class Sheerka(Concept):
else:
if evaluator.matches(context, original_items):
results = evaluator.eval(context, original_items)
if results is None:
continue
if not isinstance(results, list):
results = [results]
for result in results:
@@ -277,6 +284,24 @@ class Sheerka(Concept):
return return_values
def chain_process(self, context, return_values, initial_concepts):
"""
Executes process for all initial contexts
:param context:
:param return_values:
:param initial_concepts:
:return:
"""
for concept in initial_concepts:
if isinstance(concept, BuiltinConcepts):
concept = self.new(BuiltinConcepts)
init = [self.ret(context.who, True, concept)]
return_values = self.process(context, return_values, [init])
return_values = core.utils.remove_from_list(return_values, lambda x: x.value == init)
return return_values
def create_new_concept(self, context, concept):
"""
Adds a new concept to the system
@@ -319,13 +344,14 @@ class Sheerka(Concept):
for part_key in ConceptParts:
source = getattr(concept, part_key.value)
if source is None or not isinstance(source, str) or source == "":
# the only sources that I am sure to parse are strings
# I refuse empty strings for performance, I don't want to handle useless NOPConcepts
continue
else:
concept.codes[part_key] = self.parse(context, source)
ret_val = self.expect_one(context, self.parse(context, source))
concept.codes[part_key] = ret_val
for prop in concept.props:
concept.codes[prop] = self.parse(context, concept.props[prop].value)
def add_in_cache(self, concept):
"""
@@ -334,7 +360,16 @@ class Sheerka(Concept):
:param concept:
:return:
"""
# sanity check
if concept.key is None:
concept.init_key()
if concept.key is None:
raise KeyError()
self.concepts_cache[concept.key] = concept
return concept
def get(self, concept_key):
"""
@@ -455,7 +490,7 @@ class Sheerka(Concept):
base_class = core.utils.get_class("parsers.BaseParser.BaseParser")
for c in core.utils.get_classes_recursive("parsers"):
#if issubclass(c, base_class) and c != base_class:
# if issubclass(c, base_class) and c != base_class:
res.append(c)
return res
@@ -470,9 +505,11 @@ class ExecutionContext:
"""
To keep track of the execution of a request
"""
who: object
event_digest: str
sheerka: Sheerka
who: object # who is asking
event_digest: str # what was the (original) trigger
sheerka: Sheerka # sheerka
desc: str = None # human description of what is going on
obj: Concept = None # what is the subject of the execution context (if known)
def push(self, who):
return ExecutionContext(who, self.event_digest, self.sheerka)
def push(self, who, desc=None, obj=None):
return ExecutionContext(who, self.event_digest, self.sheerka, desc=desc, obj=obj)