Concept validation must be requested
This commit is contained in:
@@ -42,11 +42,30 @@ twenty isa number
|
||||
def concept twenties from bnf twenty number where number < 10 as twenty + number
|
||||
twenties isa number
|
||||
def concept thirty as 30
|
||||
thirty isa number
|
||||
def concept thirties from bnf thirty number where number < 10 as thirty + number
|
||||
thirties isa number
|
||||
def concept forty as 40
|
||||
forty isa number
|
||||
def concept forties from bnf forty number where number < 10 as forty + number
|
||||
forties isa number
|
||||
def concept fifty as 50
|
||||
fifty isa number
|
||||
def concept fifties from bnf fifty number where number < 10 as fifty + number
|
||||
fifties isa number
|
||||
def concept sixty as 60
|
||||
sixty isa number
|
||||
def concept sixties from bnf sixty number where number < 10 as sixty + number
|
||||
sixties isa number
|
||||
def concept seventy as 70
|
||||
seventy isa number
|
||||
def concept seventies from bnf seventy number where number < 10 as seventy + number
|
||||
seventies isa number
|
||||
def concept eighty as 80
|
||||
eighty isa number
|
||||
def concept eighties from bnf eighty number where number < 10 as eighty + number
|
||||
eighties isa number
|
||||
def concept ninety as 90
|
||||
ninety isa number
|
||||
def concept nineties from bnf ninety number where number < 10 as ninety + number
|
||||
nineties isa number
|
||||
|
||||
@@ -47,13 +47,14 @@ class BuiltinConcepts(Enum):
|
||||
LIST = "list" # represents a list
|
||||
CONCEPT_ALREADY_IN_SET = "concept already in set"
|
||||
EVALUATOR_PRE_PROCESS = "evaluator pre process" # used modify / tweak behaviour of evaluators
|
||||
CONCEPT_EVAL_REQUESTED = "concept eval requested"
|
||||
EVAL_BODY_REQUESTED = "eval body requested" # to evaluate the body
|
||||
EVAL_WHERE_REQUESTED = "eval where requested" # to evaluate the where clause
|
||||
CONCEPT_VALUE_REQUESTED = "concept value requested" # returns the body of the concept instead of the concept itself
|
||||
REDUCE_REQUESTED = "reduce requested" # remove meaningless error when possible
|
||||
NOT_A_SET = "not a set" # the concept has no entry in sets
|
||||
WHERE_CLAUSE_FAILED = "where clause failed" # failed to validate where clause during evaluation
|
||||
CHICKEN_AND_EGG = "chicken and egg" # infinite recursion when declaring concept
|
||||
ISA = "is a" # builtin concept to express that a concept is an instance of another one
|
||||
CONCEPT_VALUE_REQUESTED = "concept value requested" # returns the body of the concept instead of the concept itself
|
||||
|
||||
NODE = "node"
|
||||
GENERIC_NODE = "generic node"
|
||||
@@ -78,7 +79,7 @@ BuiltinUnique = [
|
||||
BuiltinConcepts.AFTER_RENDERING,
|
||||
BuiltinConcepts.SUCCESS,
|
||||
BuiltinConcepts.NOP,
|
||||
BuiltinConcepts.CONCEPT_EVAL_REQUESTED,
|
||||
BuiltinConcepts.EVAL_BODY_REQUESTED,
|
||||
BuiltinConcepts.REDUCE_REQUESTED,
|
||||
]
|
||||
|
||||
@@ -248,7 +249,7 @@ class ParserResultConcept(Concept):
|
||||
Result of a parsing
|
||||
"""
|
||||
|
||||
def __init__(self, parser=None, source=None, value=None, try_parsed=None):
|
||||
def __init__(self, parser=None, source=None, value=None, try_parsed=None, validate_concept=None):
|
||||
super().__init__(BuiltinConcepts.PARSER_RESULT, True, False, BuiltinConcepts.PARSER_RESULT)
|
||||
self.set_metadata_value(ConceptParts.BODY, value)
|
||||
self.set_prop("parser", parser)
|
||||
|
||||
+23
-21
@@ -17,32 +17,34 @@ def is_same_success(context, return_values):
|
||||
"""
|
||||
assert isinstance(return_values, list)
|
||||
|
||||
if not return_values[0].status:
|
||||
return False
|
||||
def _get_value(ret_val):
|
||||
if not ret_val.status:
|
||||
raise Exception("Status is false")
|
||||
|
||||
if isinstance(return_values[0].body, Concept):
|
||||
evaluated = context.sheerka.evaluate_concept(context, return_values[0].body, True)
|
||||
if evaluated.key != return_values[0].body.key:
|
||||
return False
|
||||
reference = context.sheerka.value(evaluated)
|
||||
else:
|
||||
reference = context.sheerka.value(return_values[0])
|
||||
if isinstance(ret_val.body, Concept):
|
||||
if not ret_val.body.metadata.is_evaluated:
|
||||
with context.push(desc=f"Evaluating concept '{ret_val.body}'") as sub_context:
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
evaluated = context.sheerka.evaluate_concept(sub_context, ret_val.body)
|
||||
if evaluated.key != ret_val.body.key:
|
||||
raise Exception("Failed to evaluate evaluate")
|
||||
return context.sheerka.value(evaluated)
|
||||
else:
|
||||
return context.sheerka.value(ret_val.body)
|
||||
else:
|
||||
return context.sheerka.value(ret_val)
|
||||
|
||||
for return_value in return_values[1:]:
|
||||
if not return_value.status:
|
||||
return False
|
||||
try:
|
||||
reference = _get_value(return_values[0])
|
||||
|
||||
if isinstance(return_value.body, Concept):
|
||||
evaluated = context.sheerka.evaluate_concept(context, return_value.body, True)
|
||||
if evaluated.key != return_value.body.key:
|
||||
for return_value in return_values[1:]:
|
||||
actual = _get_value(return_value)
|
||||
if actual != reference:
|
||||
return False
|
||||
|
||||
actual = context.sheerka.value(evaluated)
|
||||
else:
|
||||
actual = context.sheerka.value(return_value)
|
||||
|
||||
if actual != reference:
|
||||
return False
|
||||
except Exception as ex:
|
||||
context.log_error(ex)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class ConceptMetadata:
|
||||
id: str # unique identifier for a concept. The id will never be modified (but the key can)
|
||||
props: list # list properties, with their default values
|
||||
is_evaluated: bool = False # True is the concept is evaluated by sheerka.eval_concept()
|
||||
need_validation = False # True if the properties of the concept need to be validated
|
||||
full_serialization: bool = False # If True, the full object will be serialized, rather than just the diff
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ PROPERTIES_TO_SERIALIZE = ("_id",
|
||||
"concepts")
|
||||
|
||||
|
||||
|
||||
|
||||
class ExecutionContext:
|
||||
"""
|
||||
To keep track of the execution of a request
|
||||
@@ -44,6 +42,7 @@ class ExecutionContext:
|
||||
sheerka,
|
||||
desc: str = None,
|
||||
logger=None,
|
||||
global_hints=None,
|
||||
**kwargs):
|
||||
|
||||
self._parent = None
|
||||
@@ -60,7 +59,8 @@ class ExecutionContext:
|
||||
self.children = []
|
||||
self.preprocess = None
|
||||
self.logger = logger
|
||||
self.extra_info = []
|
||||
self.local_hints = set()
|
||||
self.global_hints = set() if global_hints is None else global_hints
|
||||
|
||||
self.inputs = {} # what was the parameters of the execution context
|
||||
self.values = {} # what was produced by the execution context
|
||||
@@ -211,11 +211,12 @@ class ExecutionContext:
|
||||
self.sheerka,
|
||||
desc,
|
||||
logger,
|
||||
self.global_hints,
|
||||
**_kwargs)
|
||||
new._parent = self
|
||||
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
||||
new.preprocess = self.preprocess
|
||||
new.extra_info.extend(self.extra_info)
|
||||
new.local_hints.update(self.local_hints)
|
||||
|
||||
self.children.append(new)
|
||||
return new
|
||||
@@ -247,6 +248,15 @@ class ExecutionContext:
|
||||
def get_parent(self):
|
||||
return self._parent
|
||||
|
||||
def in_context(self, concept_key):
|
||||
if concept_key in self.local_hints:
|
||||
return True
|
||||
|
||||
if concept_key in self.global_hints:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def return_value_to_str(r):
|
||||
value = str(r.value)
|
||||
|
||||
@@ -53,9 +53,10 @@ class SheerkaDump:
|
||||
if not first:
|
||||
self.sheerka.log.info("")
|
||||
self.sheerka.log.info(f"name : {c.name}")
|
||||
self.sheerka.log.info(f"bnf : {c.metadata.definition}")
|
||||
self.sheerka.log.info(f"key : {c.key}")
|
||||
self.sheerka.log.info(f"bnf : {c.metadata.definition}")
|
||||
self.sheerka.log.info(f"body : {c.metadata.body}")
|
||||
self.sheerka.log.info(f"where : {c.metadata.where}")
|
||||
if eval:
|
||||
self.sheerka.log.info(f"value : {value}")
|
||||
for p in c.props:
|
||||
|
||||
@@ -118,7 +118,7 @@ class SheerkaEvaluateConcept:
|
||||
else:
|
||||
self.sheerka.cache_by_key[concept.key].compiled = concept.compiled
|
||||
|
||||
def resolve(self, context, to_resolve, current_prop, current_concept, evaluate_body):
|
||||
def resolve(self, context, to_resolve, current_prop, current_concept, force_evaluation):
|
||||
if isinstance(to_resolve, DoNotResolve):
|
||||
return to_resolve.value
|
||||
|
||||
@@ -134,10 +134,13 @@ class SheerkaEvaluateConcept:
|
||||
context.log(desc, self.logger_name)
|
||||
with context.push(desc=desc, obj=current_concept) as sub_context:
|
||||
|
||||
if force_evaluation:
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
|
||||
# when it's a concept, evaluate it
|
||||
if isinstance(to_resolve, Concept) and \
|
||||
not context.sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE):
|
||||
evaluated = self.evaluate_concept(sub_context, to_resolve, evaluate_body)
|
||||
evaluated = self.evaluate_concept(sub_context, to_resolve)
|
||||
sub_context.add_values(return_values=evaluated)
|
||||
if evaluated.key == to_resolve.key:
|
||||
return evaluated
|
||||
@@ -147,8 +150,6 @@ class SheerkaEvaluateConcept:
|
||||
# otherwise, execute all return values to find out what is the value
|
||||
else:
|
||||
use_copy = [r for r in to_resolve] if hasattr(to_resolve, "__iter__") else to_resolve
|
||||
if evaluate_body:
|
||||
sub_context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||
r = self.sheerka.execute(sub_context, use_copy, CONCEPT_EVALUATION_STEPS)
|
||||
|
||||
one_r = expect_one(context, r)
|
||||
@@ -164,7 +165,7 @@ class SheerkaEvaluateConcept:
|
||||
concept=current_concept,
|
||||
property_name=current_prop)
|
||||
|
||||
def resolve_list(self, context, list_to_resolve, current_prop, current_concept, evaluate_body):
|
||||
def resolve_list(self, context, list_to_resolve, current_prop, current_concept, force_evaluation):
|
||||
"""When dealing with a list, there are two possibilities"""
|
||||
# It may be a list of ReturnValueConcept to execute (always the case for metadata)
|
||||
# or a list of single values (may be the case for properties)
|
||||
@@ -173,7 +174,7 @@ class SheerkaEvaluateConcept:
|
||||
return []
|
||||
|
||||
if self.sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE):
|
||||
return self.resolve(context, list_to_resolve, current_prop, current_concept, evaluate_body)
|
||||
return self.resolve(context, list_to_resolve, current_prop, current_concept, force_evaluation)
|
||||
|
||||
res = []
|
||||
for to_resolve in list_to_resolve:
|
||||
@@ -184,14 +185,14 @@ class SheerkaEvaluateConcept:
|
||||
concept=current_concept,
|
||||
property_name=current_prop)
|
||||
|
||||
r = self.resolve(context, to_resolve, current_prop, current_concept, evaluate_body)
|
||||
r = self.resolve(context, to_resolve, current_prop, current_concept, force_evaluation)
|
||||
if self.sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR):
|
||||
return r
|
||||
res.append(r)
|
||||
|
||||
return res
|
||||
|
||||
def evaluate_concept(self, context, concept: Concept, evaluate_body=False):
|
||||
def evaluate_concept(self, context, concept: Concept):
|
||||
"""
|
||||
Evaluation a concept
|
||||
It means that if the where clause is True, will evaluate the body
|
||||
@@ -208,7 +209,7 @@ class SheerkaEvaluateConcept:
|
||||
|
||||
# to make sure of the order, it don't use ConceptParts.get_parts()
|
||||
# props must be evaluated first, body must be evaluated before where
|
||||
all_metadata_to_eval = self.choose_metadata_to_eval(concept, evaluate_body)
|
||||
all_metadata_to_eval = self.choose_metadata_to_eval(context, concept)
|
||||
|
||||
for metadata_to_eval in all_metadata_to_eval:
|
||||
if metadata_to_eval == "props":
|
||||
@@ -221,6 +222,7 @@ class SheerkaEvaluateConcept:
|
||||
else:
|
||||
# Do not send the current concept for the properties
|
||||
resolved = self.resolve(context, prop_ast, prop_name, None, True)
|
||||
|
||||
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
|
||||
resolved.set_prop("concept", concept) # since current concept was not sent
|
||||
return resolved
|
||||
@@ -236,7 +238,10 @@ class SheerkaEvaluateConcept:
|
||||
|
||||
if part_key in concept.compiled and concept.compiled[part_key] is not None:
|
||||
metadata_ast = concept.compiled[part_key]
|
||||
resolved = self.resolve(context, metadata_ast, part_key, concept, evaluate_body)
|
||||
# if part_key is PRE, POST or WHERE, the concepts need to be evaluated
|
||||
# otherwise the predicates cannot be resolved
|
||||
force_concept_eval = False if part_key == ConceptParts.BODY else True
|
||||
resolved = self.resolve(context, metadata_ast, part_key, concept, force_concept_eval)
|
||||
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
|
||||
return resolved
|
||||
else:
|
||||
@@ -260,49 +265,57 @@ class SheerkaEvaluateConcept:
|
||||
concept.metadata.is_evaluated = "body" in all_metadata_to_eval
|
||||
return concept
|
||||
|
||||
def choose_metadata_to_eval(self, concept, evaluate_body):
|
||||
if evaluate_body:
|
||||
def choose_metadata_to_eval(self, context, concept):
|
||||
if context.in_context(BuiltinConcepts.EVAL_BODY_REQUESTED):
|
||||
return ["pre", "post", "props", "body", "where"]
|
||||
|
||||
metadata = ["pre", "post"] + self.needed_metadata(concept) + ["where"]
|
||||
metadata = ["pre", "post"]
|
||||
if context.in_context(BuiltinConcepts.EVAL_WHERE_REQUESTED) or concept.metadata.need_validation:
|
||||
needed = self.needed_metadata(concept, ConceptParts.WHERE)
|
||||
for e in needed:
|
||||
if e not in metadata:
|
||||
metadata.append(e)
|
||||
if "where" not in metadata:
|
||||
metadata.append("where")
|
||||
|
||||
return metadata
|
||||
|
||||
def needed_metadata(self, concept):
|
||||
def needed_metadata(self, concept, metadata):
|
||||
"""
|
||||
Tries to find out if the evaluation of the body is necessary
|
||||
It's a very basic approach that will need to be improved
|
||||
:param concept:
|
||||
:param metadata:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if metadata not in concept.compiled:
|
||||
return []
|
||||
|
||||
return_values = concept.compiled[metadata]
|
||||
if not isinstance(return_values, list):
|
||||
return []
|
||||
|
||||
needed = []
|
||||
|
||||
for metadata in (ConceptParts.PRE, ConceptParts.POST, ConceptParts.WHERE):
|
||||
if metadata not in concept.compiled:
|
||||
for return_value in return_values:
|
||||
if not self.sheerka.isinstance(return_value, BuiltinConcepts.RETURN_VALUE):
|
||||
continue
|
||||
|
||||
return_values = concept.compiled[metadata]
|
||||
if not isinstance(return_values, list):
|
||||
if not return_value.status:
|
||||
continue
|
||||
|
||||
for return_value in return_values:
|
||||
if not self.sheerka.isinstance(return_value, BuiltinConcepts.RETURN_VALUE):
|
||||
continue
|
||||
if not self.sheerka.isinstance(return_value.body, BuiltinConcepts.PARSER_RESULT):
|
||||
continue
|
||||
|
||||
if not return_value.status:
|
||||
continue
|
||||
if not isinstance(return_value.body.source, str):
|
||||
continue
|
||||
|
||||
if not self.sheerka.isinstance(return_value.body, BuiltinConcepts.PARSER_RESULT):
|
||||
continue
|
||||
for prop_name in (p[0] for p in concept.metadata.props):
|
||||
if prop_name in return_value.body.source:
|
||||
needed.append("props")
|
||||
break
|
||||
|
||||
if not isinstance(return_value.body.source, str):
|
||||
continue
|
||||
if "self" in return_value.body.source:
|
||||
needed.append("body")
|
||||
|
||||
for prop_name in (p[0] for p in concept.metadata.props):
|
||||
if prop_name in return_value.body.source:
|
||||
needed.append("props")
|
||||
break
|
||||
|
||||
if "self" in return_value.body.source:
|
||||
needed.append("body")
|
||||
return needed
|
||||
|
||||
@@ -90,27 +90,12 @@ class SheerkaExecute:
|
||||
result = core.utils.remove_list_from_list(result, user_inputs)
|
||||
return result
|
||||
|
||||
def call_evaluators(self, execution_context, return_values, process_step, evaluation_context=None):
|
||||
def call_evaluators(self, execution_context, return_values, process_step):
|
||||
|
||||
# return_values must be a list
|
||||
if not isinstance(return_values, list):
|
||||
return_values = [return_values]
|
||||
|
||||
# Evaluation context are contexts that may modify the behaviour of the execution
|
||||
# For example, a concept to indicate that the value is not wanted
|
||||
# Or a concept to indicate that we want the letter form of the response
|
||||
# But first, they need to be transformed into return values
|
||||
if evaluation_context is None:
|
||||
evaluation_return_values = []
|
||||
else:
|
||||
evaluation_return_values = [self.sheerka.ret(execution_context.who, True, c) for c in evaluation_context]
|
||||
|
||||
# add the current step as part as the evaluation context
|
||||
evaluation_return_values.append(self.sheerka.ret(execution_context.who, True, self.sheerka.new(process_step)))
|
||||
|
||||
# the pool of return values are the mix
|
||||
return_values.extend(evaluation_return_values)
|
||||
|
||||
# group the evaluators by priority and sort them
|
||||
# The first one to be applied will be the one with the highest priority
|
||||
grouped_evaluators = {}
|
||||
@@ -203,8 +188,6 @@ class SheerkaExecute:
|
||||
# inc the iteration and continue
|
||||
iteration += 1
|
||||
|
||||
# remove all evaluation context that are not reduced
|
||||
return_values = core.utils.remove_list_from_list(return_values, evaluation_return_values)
|
||||
return return_values
|
||||
|
||||
def execute(self, execution_context, return_values, execution_steps):
|
||||
@@ -223,7 +206,7 @@ class SheerkaExecute:
|
||||
if step == BuiltinConcepts.PARSING:
|
||||
return_values = self.call_parsers(sub_context, return_values)
|
||||
else:
|
||||
return_values = self.call_evaluators(sub_context, return_values, step, None)
|
||||
return_values = self.call_evaluators(sub_context, return_values, step)
|
||||
|
||||
if copy != return_values:
|
||||
sub_context.log_result(return_values)
|
||||
|
||||
@@ -108,7 +108,8 @@ class SheerkaSetsManager:
|
||||
# it may be a concept that references a set
|
||||
if not sub_concept.metadata.is_evaluated:
|
||||
with context.push(desc=f"Evaluating concept {sub_concept}") as sub_context:
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, sub_concept, True)
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, sub_concept)
|
||||
if evaluated.key != concept.key:
|
||||
return False
|
||||
return _get_set_elements(context, concept, sub_concept.body)
|
||||
@@ -167,7 +168,8 @@ class SheerkaSetsManager:
|
||||
# it may be a concept that references a set
|
||||
if not concept.metadata.is_evaluated:
|
||||
with context.push(desc=f"Evaluating concept {concept}") as sub_context:
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept, True)
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept)
|
||||
if evaluated.key != concept.key:
|
||||
return False
|
||||
|
||||
@@ -216,9 +218,10 @@ for x in xx__concepts__xx:
|
||||
|
||||
result = []
|
||||
with context.push(desc=f"Evaluating concepts of a set") as sub_context:
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
for element_id in ids:
|
||||
concept = self.sheerka.get_by_id(element_id)
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept, True)
|
||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept)
|
||||
result.append(evaluated)
|
||||
|
||||
return result
|
||||
|
||||
@@ -239,6 +239,7 @@ class Sheerka(Concept):
|
||||
with ExecutionContext(self.key, event, self, f"Evaluating '{text}'", self.log) as execution_context:
|
||||
user_input = self.ret(self.name, True, self.new(BuiltinConcepts.USER_INPUT, body=text, user_name=user_name))
|
||||
reduce_requested = self.ret(self.name, True, self.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
#execution_context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
|
||||
steps = [
|
||||
BuiltinConcepts.BEFORE_PARSING,
|
||||
@@ -332,17 +333,15 @@ class Sheerka(Concept):
|
||||
|
||||
return self.sets_handler.get_set_elements(context, concept)
|
||||
|
||||
def evaluate_concept(self, context, concept: Concept, evaluate_body=False):
|
||||
def evaluate_concept(self, context, concept: Concept):
|
||||
"""
|
||||
Evaluation a concept
|
||||
It means that if the where clause is True, will evaluate the body
|
||||
:param evaluate_body:
|
||||
:param context:
|
||||
:param concept:
|
||||
:param evaluate_body:
|
||||
:return: value of the evaluation or error
|
||||
"""
|
||||
return self.evaluate_concept_handler.evaluate_concept(context, concept, evaluate_body)
|
||||
return self.evaluate_concept_handler.evaluate_concept(context, concept)
|
||||
|
||||
def add_in_cache(self, concept: Concept):
|
||||
"""
|
||||
|
||||
@@ -15,19 +15,17 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
||||
def __init__(self, return_body=False):
|
||||
super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 50)
|
||||
self.return_body = return_body
|
||||
self.evaluate_body = False
|
||||
self.is_initialized = False
|
||||
|
||||
def init_evaluator(self, context, return_values):
|
||||
if BuiltinConcepts.CONCEPT_EVAL_REQUESTED in context.extra_info:
|
||||
self.evaluate_body = True
|
||||
|
||||
for r in return_values:
|
||||
if r.status and context.sheerka.isinstance(r.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED):
|
||||
self.evaluate_body = True
|
||||
break
|
||||
|
||||
self.is_initialized = True
|
||||
# def init_evaluator(self, context, return_values):
|
||||
# if BuiltinConcepts.EVAL_BODY_REQUESTED in context.local_hints:
|
||||
# self.evaluate_body = True
|
||||
#
|
||||
# for r in return_values:
|
||||
# if r.status and context.sheerka.isinstance(r.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED):
|
||||
# self.evaluate_body = True
|
||||
# break
|
||||
#
|
||||
# self.is_initialized = True
|
||||
|
||||
def matches(self, context, return_value):
|
||||
return return_value.status and \
|
||||
@@ -49,7 +47,7 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
||||
|
||||
return sheerka.ret(self.name, True, value, parents=[return_value])
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, concept, self.evaluate_body)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
if evaluated.key != concept.key:
|
||||
# evaluated.key != concept.key means that we have transformed the concept
|
||||
|
||||
@@ -12,16 +12,9 @@ class EvalEvaluator(AllReturnValuesEvaluator):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80)
|
||||
self.eval_requested = None
|
||||
|
||||
def matches(self, context, return_values):
|
||||
sheerka = context.sheerka
|
||||
for ret in return_values:
|
||||
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED):
|
||||
self.eval_requested = ret
|
||||
return True
|
||||
|
||||
return False
|
||||
return context.in_context(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
|
||||
|
||||
def eval(self, context, return_values):
|
||||
sheerka = context.sheerka
|
||||
@@ -30,22 +23,16 @@ class EvalEvaluator(AllReturnValuesEvaluator):
|
||||
for ret_val in return_values:
|
||||
if ret_val.status and isinstance(ret_val.body, Concept) and ret_val.body.body:
|
||||
context.log(f"Evaluating {ret_val.body}", who=self)
|
||||
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested]))
|
||||
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val]))
|
||||
elif ret_val.status and sheerka.isaset(context, ret_val.body):
|
||||
context.log(f"Evaluating set {ret_val.body}", who=self)
|
||||
result.append(sheerka.ret(
|
||||
self.name,
|
||||
True,
|
||||
sheerka.get_set_elements(context, ret_val.body),
|
||||
parents=[ret_val, self.eval_requested]))
|
||||
parents=[ret_val]))
|
||||
|
||||
if len(result) > 0:
|
||||
return result
|
||||
else:
|
||||
# suppress the successful BuiltinConcepts.CONCEPT_EVAL_REQUESTED
|
||||
# status of CONCEPT_EVAL_REQUESTED is now set to False
|
||||
return sheerka.ret(
|
||||
self.name,
|
||||
False,
|
||||
sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED),
|
||||
parents=[self.eval_requested])
|
||||
|
||||
return None
|
||||
|
||||
@@ -33,8 +33,7 @@ class PrepareEvalEvaluator(OneReturnValueEvaluator):
|
||||
self.name,
|
||||
True, sheerka.new(BuiltinConcepts.USER_INPUT, body=self.text[5:], user_name=context.event.user))
|
||||
|
||||
evaluation_requested = sheerka.ret(
|
||||
self.name,
|
||||
True, sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
|
||||
context.global_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
context.global_hints.add(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
|
||||
|
||||
return [new_text_to_parse, evaluation_requested]
|
||||
return new_text_to_parse
|
||||
|
||||
@@ -112,7 +112,8 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
|
||||
context.log(f"Evaluating '{concept}'", self.name)
|
||||
with context.push(self.name, desc=f"Evaluating '{concept}'", obj=concept) as sub_context:
|
||||
evaluated = context.sheerka.evaluate_concept(sub_context, concept, True)
|
||||
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
evaluated = context.sheerka.evaluate_concept(sub_context, concept)
|
||||
sub_context.add_values(return_values=evaluated)
|
||||
|
||||
if evaluated.key == concept.key:
|
||||
|
||||
@@ -944,6 +944,7 @@ class ConceptLexerParser(BaseParser):
|
||||
if _underlying.parsing_expression.rule_name:
|
||||
value = _get_underlying_value(_underlying)
|
||||
_add_prop(_concept, _underlying.parsing_expression.rule_name, value)
|
||||
_concept.metadata.need_validation = True
|
||||
|
||||
if isinstance(_underlying, NonTerminalNode):
|
||||
for child in _underlying.children:
|
||||
|
||||
@@ -41,21 +41,22 @@ class ExactConceptParser(BaseParser):
|
||||
for combination in self.combinations(words):
|
||||
|
||||
concept_key = " ".join(combination)
|
||||
result = sheerka.new(concept_key)
|
||||
result = sheerka.new(concept_key) # use new(), not get() because we need a new instance
|
||||
|
||||
if sheerka.isinstance(result, BuiltinConcepts.UNKNOWN_CONCEPT):
|
||||
continue
|
||||
|
||||
# concepts = result.body if sheerka.isinstance(result, BuiltinConcepts.ENUMERATION) else [result]
|
||||
concepts = result if isinstance(result, list) else [result]
|
||||
|
||||
for concept in concepts:
|
||||
context.log(f"Recognized concept {concept}.", self.name)
|
||||
# update the properties if needed
|
||||
need_validation = False
|
||||
for i, token in enumerate(combination):
|
||||
if token.startswith(VARIABLE_PREFIX):
|
||||
index = int(token[len(VARIABLE_PREFIX):])
|
||||
concept.def_prop_by_index(index, words[i])
|
||||
concept.metadata.need_validation = True
|
||||
if self.verbose_log.isEnabledFor(logging.DEBUG):
|
||||
prop_name = list(concept.props.keys())[index]
|
||||
context.log(
|
||||
|
||||
+9
-3
@@ -1,6 +1,6 @@
|
||||
import ast
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from parsers.BnfParser import BnfParser
|
||||
@@ -11,8 +11,14 @@ class BaseTest:
|
||||
def get_sheerka(self, **kwargs):
|
||||
pass
|
||||
|
||||
def get_context(self, sheerka=None):
|
||||
return ExecutionContext("test", Event(), sheerka or self.get_sheerka())
|
||||
def get_context(self, sheerka=None, eval_body=False, eval_where=False):
|
||||
context = ExecutionContext("test", Event(), sheerka or self.get_sheerka())
|
||||
if eval_body:
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
if eval_where:
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
|
||||
return context
|
||||
|
||||
def get_default_concept(self):
|
||||
concept = Concept(
|
||||
|
||||
@@ -34,7 +34,8 @@ def test_i_can_push():
|
||||
concepts={"bar": Concept("bar")})
|
||||
a.preprocess = set()
|
||||
a.preprocess.add("preprocess")
|
||||
a.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||
a.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
a.global_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
|
||||
b = a.push()
|
||||
|
||||
@@ -50,7 +51,8 @@ def test_i_can_push():
|
||||
assert b.id == a.id + 1
|
||||
assert b._tab == a._tab + " "
|
||||
assert b.preprocess == a.preprocess
|
||||
assert b.extra_info == [BuiltinConcepts.CONCEPT_EVAL_REQUESTED]
|
||||
assert b.local_hints == {BuiltinConcepts.EVAL_BODY_REQUESTED}
|
||||
assert b.global_hints == a.global_hints
|
||||
|
||||
|
||||
def test_children_i_created_when_i_push():
|
||||
@@ -72,3 +74,29 @@ def test_i_can_add_variable_when_i_push():
|
||||
assert sub_e.my_new_var == "new var value"
|
||||
with pytest.raises(AttributeError):
|
||||
assert e.my_new_var == "" # my_new_var does not exist in parent
|
||||
|
||||
|
||||
def test_local_hints_are_local_and_global_hints_are_global():
|
||||
a = ExecutionContext("foo", Event("event_1"), "fake_sheerka")
|
||||
a.local_hints.add("local hint 1")
|
||||
a.global_hints.add("global hint 1")
|
||||
|
||||
b = a.push()
|
||||
b.local_hints.add("local hint 2")
|
||||
b.global_hints.add("global hint 2")
|
||||
|
||||
assert a.local_hints == {"local hint 1"}
|
||||
assert a.global_hints == {"global hint 1", "global hint 2"}
|
||||
|
||||
assert b.local_hints == {"local hint 1", "local hint 2"}
|
||||
assert b.global_hints == {"global hint 1", "global hint 2"}
|
||||
|
||||
|
||||
def test_global_hits_are_global_even_when_empty():
|
||||
a = ExecutionContext("foo", Event("event_1"), "fake_sheerka")
|
||||
|
||||
b = a.push()
|
||||
b.global_hints.add("global hint 2")
|
||||
|
||||
assert a.global_hints == {"global hint 2"}
|
||||
assert b.global_hints == {"global hint 2"}
|
||||
|
||||
@@ -22,7 +22,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo", body=body).init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == expected
|
||||
@@ -80,7 +80,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo").def_prop("a", expr)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka,True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.metadata.pre is None
|
||||
@@ -95,7 +95,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
concept = Concept("foo")
|
||||
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.body == "do not resolve"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
@@ -105,7 +105,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
concept = Concept("foo").def_prop("a")
|
||||
concept.compiled["a"] = DoNotResolve("do not resolve")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.get_prop("a") == "do not resolve"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
@@ -116,7 +116,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
concept.compiled["a"] = DoNotResolve("do not resolve")
|
||||
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.body == "do not resolve"
|
||||
assert evaluated.get_prop("a") == "do not resolve"
|
||||
@@ -126,7 +126,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo", body="a+1").def_prop("a", "10").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 11
|
||||
@@ -137,7 +137,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(concept_a)
|
||||
|
||||
concept = Concept("foo", body="a").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated == simplec("foo", simplec("a", None))
|
||||
assert id(evaluated.body) != id(concept_a)
|
||||
@@ -150,7 +150,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(concept_a)
|
||||
|
||||
concept = Concept("foo", body="a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == simplec("a", 1)
|
||||
@@ -164,7 +164,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept_d)
|
||||
|
||||
assert evaluated.key == concept_d.key
|
||||
expected = simplec("c", simplec("b", simplec("a", "a")))
|
||||
@@ -179,7 +179,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept_d)
|
||||
|
||||
assert evaluated.key == concept_d.key
|
||||
expected = simplec("c", simplec("b", simplec("a", None)))
|
||||
@@ -192,7 +192,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a").init_key())
|
||||
|
||||
concept = Concept("foo", body="a").def_prop("a", "a").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
# first prop a is evaluated to concept_a
|
||||
# then body is evaluated to prop a -> concept_a
|
||||
@@ -209,7 +209,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a"))
|
||||
|
||||
concept = Concept("foo", body="concept_a").def_prop("concept_a", "a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == concept_a
|
||||
@@ -220,7 +220,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(Concept(name="b", body="2"))
|
||||
|
||||
concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 3
|
||||
@@ -231,7 +231,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
concept = Concept("foo").def_prop("a")
|
||||
concept.compiled["a"] = concept_a
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.get_prop("a") == simplec("a", "a")
|
||||
@@ -242,7 +242,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
concept = Concept("to_eval").def_prop("prop")
|
||||
concept.compiled["prop"] = [foo, DoNotResolve("1")]
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
props = evaluated.get_prop("prop")
|
||||
assert len(props) == 2
|
||||
@@ -257,20 +257,20 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
concept = Concept("to_eval").def_prop("prop")
|
||||
concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)]
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.get_prop("prop") == 2
|
||||
|
||||
# also works when only one return value
|
||||
concept = Concept("to_eval").def_prop("prop")
|
||||
concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.get_prop("prop") == 2
|
||||
|
||||
def test_i_can_reference_sheerka(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo", body="sheerka.test()").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == sheerka.test()
|
||||
@@ -281,19 +281,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||
|
||||
concept = Concept("foo", body="a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == simplec("a", "concept_a") # this test was already done
|
||||
|
||||
# so check this one.
|
||||
concept = Concept("foo", body="a").def_prop("a", "'property_a'")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'property_a'
|
||||
|
||||
# or this one.
|
||||
concept = Concept("foo", body="a").def_prop("a", "b")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == simplec(name="b", body="concept_b")
|
||||
|
||||
@@ -303,7 +303,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||
|
||||
concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'prop_aconcept_b'
|
||||
|
||||
@@ -312,21 +312,21 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(Concept(name="concept_a").def_prop("subProp", "'sub_a'"))
|
||||
|
||||
concept = Concept("foo", body="a.props['subProp'].value").def_prop("a", "concept_a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated == simplec(concept.key, "sub_a")
|
||||
|
||||
def test_i_cannot_evaluate_concept_if_property_is_in_error(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept(name="concept_a").def_prop("subProp", "undef_concept")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
def test_key_is_initialized_by_evaluation(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
assert evaluated.key == concept.init_key().key
|
||||
|
||||
@@ -345,7 +345,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
concept = Concept("foo", body="10", where=where_clause).def_prop("a", "20")
|
||||
sheerka.add_in_cache(concept)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
|
||||
|
||||
if expected:
|
||||
assert evaluated.key == concept.key
|
||||
@@ -362,14 +362,32 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(foo_true)
|
||||
|
||||
concept = Concept("foo", where="foo_true").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
concept = Concept("foo", where="foo_false")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
assert evaluated.body == concept
|
||||
|
||||
concept = Concept("foo", where="foo_false").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, False), concept)
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
def test_i_can_evaluate_disable_where_clause_evaluation(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo", body="10", where="a > 10").def_prop("a", None)
|
||||
sheerka.add_in_cache(concept)
|
||||
|
||||
context = self.get_context(sheerka)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_numeric_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -379,11 +397,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(one_str)
|
||||
sheerka.add_in_cache(one_digit)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one_digit)
|
||||
assert evaluated.key == one_digit.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one_str)
|
||||
assert evaluated.key == one_str.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||
|
||||
@@ -396,11 +414,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.add_in_cache(true_str)
|
||||
sheerka.add_in_cache(true_bool)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), true_str)
|
||||
assert evaluated.key == true_str.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), true_bool)
|
||||
assert evaluated.key == true_bool.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||
|
||||
@@ -413,7 +431,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
c4 = sheerka.add_in_cache(Concept("3", body="one"))
|
||||
|
||||
for concept in (c1, c2, c3, c4):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(3)
|
||||
|
||||
@@ -425,19 +443,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
baz = sheerka.add_in_cache(Concept("baz", body="qux"))
|
||||
qux = sheerka.add_in_cache(Concept("qux", body="foo"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), foo)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), bar)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), baz)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), qux)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
@@ -446,7 +464,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
foo = sheerka.add_in_cache(Concept("foo", body="foo"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), foo)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo}
|
||||
|
||||
@@ -454,7 +472,9 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
one = Concept("1", body="1")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one)
|
||||
assert evaluated.key == one.key
|
||||
assert evaluated.body == 1
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -249,22 +249,16 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
assert Out.debug_out == [
|
||||
'__EVALUATION [0] priority20 - matches - target=foo',
|
||||
'__EVALUATION [0] priority20 - eval - target=foo',
|
||||
'__EVALUATION [0] priority20 - matches - target=__EVALUATION',
|
||||
'__EVALUATION [0] priority20 - eval - target=__EVALUATION',
|
||||
"__EVALUATION [0] all_priority20 - matches - target=['foo', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_priority20 - eval - target=['foo', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_priority15 - matches - target=['foo', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_priority15 - eval - target=['foo', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_priority20 - matches - target=['foo']",
|
||||
"__EVALUATION [0] all_priority20 - eval - target=['foo']",
|
||||
"__EVALUATION [0] all_priority15 - matches - target=['foo']",
|
||||
"__EVALUATION [0] all_priority15 - eval - target=['foo']",
|
||||
'__EVALUATION [0] priority15 - matches - target=foo',
|
||||
'__EVALUATION [0] priority15 - eval - target=foo',
|
||||
'__EVALUATION [0] priority15 - matches - target=__EVALUATION',
|
||||
'__EVALUATION [0] priority15 - eval - target=__EVALUATION',
|
||||
"__EVALUATION [0] all_priority10 - matches - target=['foo', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_priority10 - eval - target=['foo', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_priority10 - matches - target=['foo']",
|
||||
"__EVALUATION [0] all_priority10 - eval - target=['foo']",
|
||||
'__EVALUATION [0] priority10 - matches - target=foo',
|
||||
'__EVALUATION [0] priority10 - eval - target=foo',
|
||||
'__EVALUATION [0] priority10 - matches - target=__EVALUATION',
|
||||
'__EVALUATION [0] priority10 - eval - target=__EVALUATION'
|
||||
]
|
||||
|
||||
def test_that_predicate_is_checked_before_evaluation_for_one_return(self):
|
||||
@@ -279,10 +273,8 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
'__EVALUATION [0] modifyFoo - matches - target=foo',
|
||||
'__EVALUATION [0] modifyFoo - eval - target=foo',
|
||||
'__EVALUATION [0] modifyFoo - matches - target=baz',
|
||||
'__EVALUATION [0] modifyFoo - matches - target=__EVALUATION',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=bar',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=baz',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
|
||||
]
|
||||
|
||||
def test_that_predicate_is_checked_before_evaluation_for_all_return(self):
|
||||
@@ -293,8 +285,8 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
Out.debug_out = []
|
||||
sheerka.execute(self.get_context(sheerka), entries, [BuiltinConcepts.EVALUATION])
|
||||
assert Out.debug_out == [
|
||||
"__EVALUATION [0] all_reduce_foobar - matches - target=['foo', 'bar', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_reduce_foobar - eval - target=['foo', 'bar', '__EVALUATION']",
|
||||
"__EVALUATION [0] all_reduce_foobar - matches - target=['foo', 'bar']",
|
||||
"__EVALUATION [0] all_reduce_foobar - eval - target=['foo', 'bar']",
|
||||
"__EVALUATION [1] all_reduce_foobar - matches - target=['__SUCCESS']"
|
||||
]
|
||||
|
||||
@@ -302,7 +294,7 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
Out.debug_out = []
|
||||
sheerka.execute(self.get_context(sheerka), entries, [BuiltinConcepts.EVALUATION])
|
||||
assert Out.debug_out == [
|
||||
"__EVALUATION [0] all_reduce_foobar - matches - target=['foo', '__EVALUATION']"
|
||||
"__EVALUATION [0] all_reduce_foobar - matches - target=['foo']"
|
||||
]
|
||||
|
||||
def test_evaluation_continue_until_no_more_modification(self):
|
||||
@@ -317,23 +309,17 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
'__EVALUATION [0] modifyFoo - matches - target=foo',
|
||||
'__EVALUATION [0] modifyFoo - eval - target=foo',
|
||||
'__EVALUATION [0] modifyFoo - matches - target=baz',
|
||||
'__EVALUATION [0] modifyFoo - matches - target=__EVALUATION',
|
||||
'__EVALUATION [0] modifyBar - matches - target=foo',
|
||||
'__EVALUATION [0] modifyBar - matches - target=baz',
|
||||
'__EVALUATION [0] modifyBar - matches - target=__EVALUATION',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=bar',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=baz',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION',
|
||||
'__EVALUATION [1] modifyBar - matches - target=bar',
|
||||
'__EVALUATION [1] modifyBar - eval - target=bar',
|
||||
'__EVALUATION [1] modifyBar - matches - target=baz',
|
||||
'__EVALUATION [1] modifyBar - matches - target=__EVALUATION',
|
||||
'__EVALUATION [2] modifyFoo - matches - target=baz',
|
||||
'__EVALUATION [2] modifyFoo - matches - target=baz',
|
||||
'__EVALUATION [2] modifyFoo - matches - target=__EVALUATION',
|
||||
'__EVALUATION [2] modifyBar - matches - target=baz',
|
||||
'__EVALUATION [2] modifyBar - matches - target=baz',
|
||||
'__EVALUATION [2] modifyBar - matches - target=__EVALUATION'
|
||||
]
|
||||
|
||||
def test_evaluation_steps_are_respected(self):
|
||||
@@ -347,8 +333,7 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
assert Out.debug_out == [
|
||||
'__BEFORE_EVALUATION [0] preEval - matches - target=foo',
|
||||
'__BEFORE_EVALUATION [0] preEval - eval - target=foo',
|
||||
'__BEFORE_EVALUATION [0] preEval - matches - target=__BEFORE_EVALUATION',
|
||||
'__BEFORE_EVALUATION [0] preEval - eval - target=__BEFORE_EVALUATION']
|
||||
]
|
||||
|
||||
def test_evaluation_multi_steps_are_respected(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -362,12 +347,8 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
assert Out.debug_out == [
|
||||
'__BEFORE_EVALUATION [0] multiStep - matches - target=foo',
|
||||
'__BEFORE_EVALUATION [0] multiStep - eval - target=foo',
|
||||
'__BEFORE_EVALUATION [0] multiStep - matches - target=__BEFORE_EVALUATION',
|
||||
'__BEFORE_EVALUATION [0] multiStep - eval - target=__BEFORE_EVALUATION',
|
||||
'__EVALUATION [0] multiStep - matches - target=foo',
|
||||
'__EVALUATION [0] multiStep - eval - target=foo',
|
||||
'__EVALUATION [0] multiStep - matches - target=__EVALUATION',
|
||||
'__EVALUATION [0] multiStep - eval - target=__EVALUATION'
|
||||
]
|
||||
|
||||
def test_evaluators_can_be_pre_processed(self):
|
||||
@@ -389,9 +370,7 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
assert Out.debug_out == [
|
||||
'__EVALUATION [0] modifyFoo - matches - target=foo',
|
||||
'__EVALUATION [0] modifyFoo - eval - target=foo',
|
||||
'__EVALUATION [0] modifyFoo - matches - target=__EVALUATION',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=bar',
|
||||
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
|
||||
]
|
||||
|
||||
def test_i_can_initialize_evaluator_if_initialize_evaluator_is_defined(self):
|
||||
@@ -407,14 +386,12 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
|
||||
assert Out.debug_out == [
|
||||
'__EVALUATION [0] init_once - matches - target=foo',
|
||||
"__EVALUATION [0] init_once - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
|
||||
"__EVALUATION [0] init_once - init_evaluator - target=['foo', 'bar', 'baz']",
|
||||
'__EVALUATION [0] init_once - eval - target=foo',
|
||||
'__EVALUATION [0] init_once - matches - target=bar',
|
||||
'__EVALUATION [0] init_once - eval - target=bar',
|
||||
'__EVALUATION [0] init_once - matches - target=baz',
|
||||
'__EVALUATION [0] init_once - eval - target=baz',
|
||||
'__EVALUATION [0] init_once - matches - target=__EVALUATION',
|
||||
'__EVALUATION [0] init_once - eval - target=__EVALUATION'
|
||||
]
|
||||
|
||||
def test_i_can_initialize_evaluators_multiple_times(self):
|
||||
@@ -430,15 +407,12 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
|
||||
assert Out.debug_out == [
|
||||
'__EVALUATION [0] init_multiple - matches - target=foo',
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz']",
|
||||
'__EVALUATION [0] init_multiple - eval - target=foo',
|
||||
'__EVALUATION [0] init_multiple - matches - target=bar',
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz']",
|
||||
'__EVALUATION [0] init_multiple - eval - target=bar',
|
||||
'__EVALUATION [0] init_multiple - matches - target=baz',
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz']",
|
||||
'__EVALUATION [0] init_multiple - eval - target=baz',
|
||||
'__EVALUATION [0] init_multiple - matches - target=__EVALUATION',
|
||||
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
|
||||
'__EVALUATION [0] init_multiple - eval - target=__EVALUATION'
|
||||
]
|
||||
|
||||
@@ -20,7 +20,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_evaluate_concept(self):
|
||||
context = self.get_context()
|
||||
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
concept = Concept(name="foo",
|
||||
where="True",
|
||||
pre="2",
|
||||
@@ -28,7 +28,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
evaluator = ConceptEvaluator()
|
||||
item = self.pretval(concept)
|
||||
evaluator.init_evaluator(context, [item])
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
@@ -44,7 +43,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_body_is_returned_when_defined_and_requested(self):
|
||||
context = self.get_context()
|
||||
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
concept = Concept(name="foo",
|
||||
body="'I have a value'",
|
||||
where="True",
|
||||
@@ -53,7 +52,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
evaluator = ConceptEvaluator(return_body=True)
|
||||
item = self.pretval(concept)
|
||||
evaluator.init_evaluator(context, [item])
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
@@ -71,7 +69,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
|
||||
item = self.pretval(concept)
|
||||
evaluator.init_evaluator(context, [item])
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
@@ -95,7 +92,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(self):
|
||||
context = self.get_context()
|
||||
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
context.sheerka.add_in_cache(Concept(name="one").init_key())
|
||||
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b")
|
||||
.def_prop("a", "one")
|
||||
@@ -103,7 +100,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
evaluator = ConceptEvaluator()
|
||||
item = self.pretval(concept_plus)
|
||||
evaluator.init_evaluator(context, [item])
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert not result.status
|
||||
|
||||
@@ -5,8 +5,6 @@ from core.concept import Concept
|
||||
from evaluators.EvalEvaluator import EvalEvaluator
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
value_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
|
||||
|
||||
|
||||
def retval(obj, who="who", status=True):
|
||||
"""ret_val"""
|
||||
@@ -16,6 +14,7 @@ def retval(obj, who="who", status=True):
|
||||
class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_match_and_eval(self):
|
||||
context = self.get_context()
|
||||
context.global_hints.add(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
|
||||
|
||||
to_eval1 = ReturnValueConcept("some_name", True, Concept(name="2", body="to eval").auto_init())
|
||||
to_eval2 = ReturnValueConcept("some_name", True, Concept(name="3", body="also to eval").auto_init())
|
||||
@@ -26,7 +25,6 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
ReturnValueConcept("some_name", False, Concept(name="1", body="'not to eval'")),
|
||||
to_eval1,
|
||||
to_eval2,
|
||||
value_requested
|
||||
]
|
||||
|
||||
evaluator = EvalEvaluator()
|
||||
@@ -35,41 +33,35 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert len(evaluated) == 2
|
||||
assert evaluated[0].value == to_eval1.body.body
|
||||
assert evaluated[0].parents == [to_eval1, value_requested]
|
||||
assert evaluated[0].parents == [to_eval1]
|
||||
|
||||
assert evaluated[1].value == to_eval2.body.body
|
||||
assert evaluated[1].parents == [to_eval2, value_requested]
|
||||
assert evaluated[1].parents == [to_eval2]
|
||||
|
||||
@pytest.mark.parametrize("return_values, expected", [
|
||||
([retval(Concept("foo", body="bar")), value_requested], True),
|
||||
([retval(Concept("status is false", body="bar"), status=False), value_requested], True),
|
||||
([retval("string_value"), value_requested], True),
|
||||
([retval(Concept("no body")), value_requested], True),
|
||||
([retval(Concept("eval requested missing", body="bar"))], False),
|
||||
@pytest.mark.parametrize("return_value", [
|
||||
retval(Concept("foo", body="bar")),
|
||||
retval(Concept("status is false", body="bar"), status=False),
|
||||
retval("string_value"),
|
||||
retval(Concept("no body")),
|
||||
])
|
||||
def test_i_cannot_match_if_eval_request_is_not_present(self, return_values, expected):
|
||||
def test_i_cannot_match_if_eval_request_is_not_present(self, return_value):
|
||||
context = self.get_context()
|
||||
assert EvalEvaluator().matches(context, return_values) == expected
|
||||
assert not EvalEvaluator().matches(context, [return_value])
|
||||
|
||||
context.global_hints.add(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
|
||||
assert EvalEvaluator().matches(context, [return_value])
|
||||
|
||||
def test_concept_eval_requested_is_reduced_when_nothing_to_reduce(self):
|
||||
context = self.get_context()
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept("some_name", True, "not to eval"),
|
||||
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
||||
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
|
||||
value_requested
|
||||
ReturnValueConcept("some_name", True, "not to eval"), # not a concept
|
||||
ReturnValueConcept("some_name", True, Concept(name="not to eval")), # no body
|
||||
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")), # no evaluated body
|
||||
]
|
||||
|
||||
evaluator = EvalEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated == ReturnValueConcept(
|
||||
"evaluators.Eval",
|
||||
False,
|
||||
context.sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
|
||||
assert evaluated.parents == [value_requested]
|
||||
evaluated = EvalEvaluator().eval(context, return_values)
|
||||
assert evaluated is None
|
||||
|
||||
def test_i_can_evaluate_sets(self):
|
||||
sheerka, context, foo, bar, baz, number = self.init_concepts(
|
||||
@@ -79,11 +71,7 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
Concept("number"))
|
||||
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar, baz], number)
|
||||
|
||||
return_values = [retval(number), value_requested]
|
||||
|
||||
evaluator = EvalEvaluator()
|
||||
evaluator.matches(context, return_values)
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
evaluated = EvalEvaluator().eval(context, [retval(number)])
|
||||
|
||||
assert len(evaluated) == 1
|
||||
assert evaluated[0].status
|
||||
|
||||
@@ -40,10 +40,9 @@ class TestPrepareEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
prepare_evaluator.matches(context, ret_val)
|
||||
res = prepare_evaluator.eval(context, ret_val)
|
||||
|
||||
assert len(res) == 2
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.USER_INPUT)
|
||||
assert res[0].body.body == expected
|
||||
assert res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.USER_INPUT)
|
||||
assert res.body.body == expected
|
||||
|
||||
assert res[1].status
|
||||
assert sheerka.isinstance(res[1].body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
|
||||
assert BuiltinConcepts.EVAL_BODY_REQUESTED in context.global_hints
|
||||
assert BuiltinConcepts.CONCEPT_VALUE_REQUESTED in context.global_hints
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
assert res[0].value == concept
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
|
||||
assert evaluated == simplec("one", 1)
|
||||
|
||||
def test_i_can_recognize_concept_with_concept_body(self):
|
||||
@@ -53,7 +53,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
assert return_value == concept_un
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
|
||||
assert evaluated == simplec("un", simplec("one", None))
|
||||
|
||||
def test_i_can_recognize_concept_with_no_body(self):
|
||||
@@ -194,7 +194,7 @@ as:
|
||||
assert return_value.metadata.props[0] == ('a', "foo")
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
|
||||
assert evaluated.props["a"].value == concept_foo
|
||||
|
||||
def test_i_can_recognize_concept_with_variable_and_python_as_body(self):
|
||||
@@ -208,7 +208,7 @@ as:
|
||||
assert sheerka.isinstance(res[0].value, hello_a)
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
|
||||
assert evaluated.body == "hello foo"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.props["a"].value == simplec("foo", "foo")
|
||||
@@ -323,7 +323,7 @@ as:
|
||||
assert sheerka.isinstance(return_value, concept_b)
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
|
||||
assert evaluated.body == "one three"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
|
||||
@@ -355,7 +355,7 @@ as:
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_b)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
|
||||
assert evaluated.body == "one two three"
|
||||
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
||||
|
||||
@@ -406,7 +406,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
assert sheerka.evaluate_concept(self.get_context(), res[0].body, True).body == 21
|
||||
assert sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].body).body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||
assert len(res) == 1
|
||||
@@ -450,7 +450,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
assert sheerka.evaluate_concept(self.get_context(), res[0].value, True).body == 21
|
||||
assert sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value).body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||
assert len(res) == 1
|
||||
@@ -695,8 +695,15 @@ as:
|
||||
res = sheerka.evaluate_user_input("eval twenty two")
|
||||
assert len(res) == 1 and res[0].status and res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty three")
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty three")
|
||||
assert len(res) > 1
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
# def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
@@ -722,10 +729,7 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 2
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_evaluate_bnf_concept_with_where_clause(self):
|
||||
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
sheerka.evaluate_user_input("def concept a from bnf 'bar' | 'baz'")
|
||||
@@ -741,7 +745,7 @@ as:
|
||||
res = sheerka.evaluate_user_input("eval foo bar")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == "hello world"
|
||||
assert res[0].body == "hello world"
|
||||
|
||||
res = sheerka.evaluate_user_input("foo baz")
|
||||
assert len(res) == 1
|
||||
@@ -749,17 +753,18 @@ as:
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foo baz")
|
||||
assert len(res) > 1
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
# The following test fails
|
||||
# the Where clause is evaluated while it should not
|
||||
res = sheerka.evaluate_user_input("foobar")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foobar")
|
||||
assert len(res) > 1 # error
|
||||
assert res[0].status
|
||||
assert len(res) == 1 # error
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
def test_i_can_say_than_bnf_concept_isa_another_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -1225,6 +1225,28 @@ class TestConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
OneOrMore(ConceptExpression(baz, rule_name="baz")), rule_name="oc"), rule_name="s")
|
||||
assert parse_res.value.value == expected
|
||||
|
||||
def test_i_concept_validation_is_not_set_when_no_variables(self):
|
||||
foo = Concept(name="foo")
|
||||
grammar = {foo: "foo"}
|
||||
|
||||
context, res, wrapper, return_value = self.execute([foo], grammar, "foo")
|
||||
assert not return_value[0].concept.metadata.need_validation
|
||||
|
||||
def test_i_concept_validation_is_set_when_unnamed_variables_are_found(self):
|
||||
foo = Concept(name="foo")
|
||||
grammar = {foo: Sequence("foo", OrderedChoice("a", "b"))}
|
||||
|
||||
context, res, wrapper, return_value = self.execute([foo], grammar, "foo a")
|
||||
assert not return_value[0].concept.metadata.need_validation
|
||||
|
||||
def test_i_concept_validation_is_set_when_named_variables_are_found(self):
|
||||
foo = Concept(name="foo")
|
||||
grammar = {foo: Sequence("foo", OrderedChoice("a", "b", rule_name="var"))}
|
||||
|
||||
context, res, wrapper, return_value = self.execute([foo], grammar, "foo a")
|
||||
assert return_value[0].concept.metadata.need_validation
|
||||
|
||||
|
||||
#
|
||||
# def test_i_can_parse_basic_arithmetic_operations_and_resolve_properties(self):
|
||||
# context = self.get_context()
|
||||
|
||||
@@ -93,7 +93,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
assert return_value.compiled["b"] == bar
|
||||
|
||||
# sanity check, I can evaluate the result
|
||||
evaluated = context.sheerka.evaluate_concept(context, return_value, True)
|
||||
evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
assert evaluated.key == return_value.key
|
||||
assert evaluated.get_prop("a") == foo.init_key()
|
||||
assert evaluated.get_prop("b") == bar.init_key()
|
||||
@@ -116,7 +116,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, right_parser_result)]
|
||||
|
||||
# sanity check, I can evaluate the result
|
||||
evaluated = context.sheerka.evaluate_concept(context, return_value, True)
|
||||
evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
assert evaluated.key == return_value.key
|
||||
assert evaluated.get_prop("a") == 2
|
||||
assert evaluated.get_prop("b") == 4
|
||||
@@ -139,7 +139,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, code_parser_result)]
|
||||
|
||||
# sanity check, I can evaluate the result
|
||||
evaluated = context.sheerka.evaluate_concept(context, return_value, True)
|
||||
evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
assert evaluated.key == return_value.key
|
||||
assert evaluated.get_prop("a") == foo.init_key()
|
||||
assert evaluated.get_prop("b") == 2
|
||||
|
||||
@@ -56,10 +56,12 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
source = "hello world"
|
||||
results = ExactConceptParser().parse(context, source)
|
||||
concept_found = results[0].value.value
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
assert results[0].value.value == concept
|
||||
assert concept_found == concept
|
||||
assert not concept_found.metadata.need_validation
|
||||
|
||||
def test_i_can_recognize_concepts_defined_several_times(self):
|
||||
context = self.get_context()
|
||||
@@ -75,9 +77,11 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert results[0].status
|
||||
assert results[0].value.value.name == "hello a"
|
||||
assert metadata_prop(results[0].value.value, "a") == "world"
|
||||
assert results[0].value.value.metadata.need_validation
|
||||
|
||||
assert results[1].status
|
||||
assert results[1].value.value.name == "hello world"
|
||||
assert not results[1].value.value.metadata.need_validation
|
||||
|
||||
def test_i_can_recognize_a_concept_with_variables(self):
|
||||
context = self.get_context()
|
||||
@@ -88,10 +92,12 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
|
||||
concept_found = results[0].value.value
|
||||
assert concept_found.key == concept.key
|
||||
assert metadata_prop(concept_found, "a") == "10"
|
||||
assert metadata_prop(concept_found, "b") == "5"
|
||||
assert concept_found.metadata.need_validation
|
||||
|
||||
def test_i_can_recognize_a_concept_with_duplicate_variables(self):
|
||||
context = self.get_context()
|
||||
@@ -102,10 +108,12 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
|
||||
concept_found = results[0].value.value
|
||||
assert concept_found.key == concept.key
|
||||
assert metadata_prop(concept_found, "a") == "10"
|
||||
assert metadata_prop(concept_found, "b") == "5"
|
||||
assert concept_found.metadata.need_validation
|
||||
|
||||
def test_i_can_manage_unknown_concept(self):
|
||||
context = self.get_context()
|
||||
@@ -136,3 +144,4 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
assert results[0].value.value == concept
|
||||
assert not results[0].value.value.metadata.need_validation
|
||||
|
||||
Reference in New Issue
Block a user