Added simple form of concept composition
This commit is contained in:
+68
-41
@@ -258,6 +258,7 @@ class Sheerka(Concept):
|
||||
# execution_context.log(logger or self.log, f"Parsing {debug_text}")
|
||||
|
||||
with execution_context.push(desc=f"Parsing using {parser.name}") as sub_context:
|
||||
sub_context.add_inputs(to_parse=to_parse)
|
||||
res = parser.parse(sub_context, to_parse)
|
||||
if res is not None:
|
||||
if hasattr(res, "__iter__"):
|
||||
@@ -278,6 +279,7 @@ class Sheerka(Concept):
|
||||
to_process.append(res)
|
||||
if res.status:
|
||||
return_value_success_found = True
|
||||
sub_context.add_values(return_values=res)
|
||||
|
||||
if return_value_success_found:
|
||||
stop_processing = True
|
||||
@@ -347,51 +349,69 @@ class Sheerka(Concept):
|
||||
sorted_priorities = sorted(grouped_evaluators.keys(), reverse=True)
|
||||
|
||||
# process
|
||||
iteration = 0
|
||||
while True:
|
||||
simple_digest = return_values[:]
|
||||
with execution_context.push(desc=f"iteration #{iteration}", iteration=iteration) as iteration_context:
|
||||
simple_digest = return_values[:]
|
||||
iteration_context.add_inputs(return_values=simple_digest)
|
||||
|
||||
for priority in sorted_priorities:
|
||||
for priority in sorted_priorities:
|
||||
|
||||
original_items = return_values[:]
|
||||
evaluated_items = []
|
||||
to_delete = []
|
||||
for evaluator in grouped_evaluators[priority]:
|
||||
evaluator = _preprocess_evaluators(execution_context, evaluator.__class__()) # fresh copy
|
||||
original_items = return_values[:]
|
||||
evaluated_items = []
|
||||
to_delete = []
|
||||
for evaluator in grouped_evaluators[priority]:
|
||||
evaluator = _preprocess_evaluators(execution_context, evaluator.__class__()) # fresh copy
|
||||
|
||||
# process evaluators that work on return value
|
||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||
if isinstance(evaluator, OneReturnValueEvaluator):
|
||||
for item in original_items:
|
||||
if evaluator.matches(execution_context, item):
|
||||
result = evaluator.eval(execution_context, item)
|
||||
if result is None:
|
||||
continue
|
||||
elif isinstance(result, list):
|
||||
evaluated_items.extend(result)
|
||||
to_delete.append(item)
|
||||
elif isinstance(result, ReturnValueConcept):
|
||||
evaluated_items.append(result)
|
||||
to_delete.append(item)
|
||||
sub_context_desc = f"Evaluating using {evaluator.name} ({priority=})"
|
||||
with iteration_context.push(desc=sub_context_desc) as sub_context:
|
||||
sub_context.add_inputs(return_values=original_items)
|
||||
|
||||
# process evaluators that work on one simple return value at the time
|
||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||
if isinstance(evaluator, OneReturnValueEvaluator):
|
||||
debug_result = []
|
||||
for item in original_items:
|
||||
if evaluator.matches(sub_context, item):
|
||||
result = evaluator.eval(sub_context, item)
|
||||
if result is None:
|
||||
debug_result.append({"input": item, "return_value": None})
|
||||
continue
|
||||
|
||||
to_delete.append(item)
|
||||
if isinstance(result, list):
|
||||
evaluated_items.extend(result)
|
||||
elif isinstance(result, ReturnValueConcept):
|
||||
evaluated_items.append(result)
|
||||
else:
|
||||
error = self.new(BuiltinConcepts.INVALID_RETURN_VALUE, body=result,
|
||||
evaluator=evaluator)
|
||||
result = self.ret("sheerka.process", False, error, parents=[item])
|
||||
evaluated_items.append(result)
|
||||
debug_result.append({"input": item, "return_value": result})
|
||||
else:
|
||||
debug_result.append({"input": item, "return_value": "** No Match **"})
|
||||
sub_context.add_values(return_values=debug_result)
|
||||
|
||||
# process evaluators that work on all return values
|
||||
else:
|
||||
if evaluator.matches(sub_context, original_items):
|
||||
results = evaluator.eval(sub_context, original_items)
|
||||
if results is None:
|
||||
continue
|
||||
if not isinstance(results, list):
|
||||
results = [results]
|
||||
for result in results:
|
||||
evaluated_items.append(result)
|
||||
to_delete.extend(result.parents)
|
||||
sub_context.add_values(return_values=results)
|
||||
else:
|
||||
error = self.new(BuiltinConcepts.INVALID_RETURN_VALUE, body=result,
|
||||
evaluator=evaluator)
|
||||
evaluated_items.append(self.ret("sheerka.process", False, error, parents=[item]))
|
||||
to_delete.append(item)
|
||||
sub_context.add_values(return_values="** No Match **")
|
||||
|
||||
# process evaluators that work on all return values
|
||||
else:
|
||||
if evaluator.matches(execution_context, original_items):
|
||||
results = evaluator.eval(execution_context, original_items)
|
||||
if results is None:
|
||||
continue
|
||||
if not isinstance(results, list):
|
||||
results = [results]
|
||||
for result in results:
|
||||
evaluated_items.append(result)
|
||||
to_delete.extend(result.parents)
|
||||
return_values = evaluated_items
|
||||
return_values.extend([item for item in original_items if item not in to_delete])
|
||||
|
||||
return_values = evaluated_items
|
||||
return_values.extend([item for item in original_items if item not in to_delete])
|
||||
iteration_context.add_values(return_values=return_values[:])
|
||||
|
||||
# have we done something ?
|
||||
to_compare = return_values[:]
|
||||
@@ -399,7 +419,7 @@ class Sheerka(Concept):
|
||||
break
|
||||
|
||||
# inc the iteration and continue
|
||||
execution_context = execution_context.push(iteration=execution_context.iteration + 1)
|
||||
iteration += 1
|
||||
|
||||
# remove all evaluation context that are not reduced
|
||||
return_values = core.utils.remove_list_from_list(return_values, evaluation_return_values)
|
||||
@@ -879,11 +899,11 @@ class Sheerka(Concept):
|
||||
|
||||
return obj
|
||||
|
||||
def is_unknown(self, obj):
|
||||
def is_known(self, obj):
|
||||
if not isinstance(obj, Concept):
|
||||
return True
|
||||
|
||||
return obj.key == BuiltinConcepts.UNKNOWN_CONCEPT
|
||||
return obj.key != str(BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
|
||||
def isinstance(self, a, b):
|
||||
"""
|
||||
@@ -1049,6 +1069,8 @@ class ExecutionContext:
|
||||
self.desc = desc # human description of what is going on
|
||||
self.children = []
|
||||
self.preprocess = None
|
||||
|
||||
self.inputs = {} # what was the parameters of the execution context
|
||||
self.values = {} # what was produced by the execution context
|
||||
|
||||
self.obj = kwargs.pop("obj", None)
|
||||
@@ -1105,6 +1127,11 @@ class ExecutionContext:
|
||||
self.preprocess.add(preprocess)
|
||||
return self
|
||||
|
||||
def add_inputs(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
self.inputs[k] = v
|
||||
return self
|
||||
|
||||
def add_values(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
self.values[k] = v
|
||||
|
||||
Reference in New Issue
Block a user