Concepts bodies are now evaluated on demand
This commit is contained in:
+8
-1
@@ -40,6 +40,13 @@ eighteen isa number
|
|||||||
nineteen isa number
|
nineteen isa number
|
||||||
twenty isa number
|
twenty isa number
|
||||||
def concept twenties from bnf twenty number where number < 10 as twenty + number
|
def concept twenties from bnf twenty number where number < 10 as twenty + number
|
||||||
|
twenties isa number
|
||||||
def concept thirty as 30
|
def concept thirty as 30
|
||||||
|
def concept thirties from bnf thirty number where number < 10 as thirty + number
|
||||||
|
thirties isa number
|
||||||
def concept forty as 40
|
def concept forty as 40
|
||||||
|
def concept forties from bnf forty number where number < 10 as forty + number
|
||||||
|
forties isa number
|
||||||
|
def concept fifty as 50
|
||||||
|
def concept fifties from bnf fifty number where number < 10 as fifty + number
|
||||||
|
fifties isa number
|
||||||
@@ -53,6 +53,7 @@ class BuiltinConcepts(Enum):
|
|||||||
WHERE_CLAUSE_FAILED = "where clause failed" # failed to validate where clause during evaluation
|
WHERE_CLAUSE_FAILED = "where clause failed" # failed to validate where clause during evaluation
|
||||||
CHICKEN_AND_EGG = "chicken and egg" # infinite recursion when declaring concept
|
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
|
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"
|
NODE = "node"
|
||||||
GENERIC_NODE = "generic node"
|
GENERIC_NODE = "generic node"
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import core.ast.nodes
|
|||||||
from core.ast.nodes import CallNodeConcept, GenericNodeConcept
|
from core.ast.nodes import CallNodeConcept, GenericNodeConcept
|
||||||
from core.ast.visitors import UnreferencedNamesVisitor
|
from core.ast.visitors import UnreferencedNamesVisitor
|
||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
|
from core.concept import Concept
|
||||||
|
|
||||||
|
|
||||||
def is_same_success(sheerka, return_values):
|
def is_same_success(context, return_values):
|
||||||
"""
|
"""
|
||||||
Returns True if all returns values are successful and have the same value
|
Returns True if all returns values are successful and have the same value
|
||||||
:param sheerka:
|
:param context:
|
||||||
:param return_values:
|
:param return_values:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
@@ -19,13 +20,27 @@ def is_same_success(sheerka, return_values):
|
|||||||
if not return_values[0].status:
|
if not return_values[0].status:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
reference = sheerka.value(return_values[0].value)
|
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])
|
||||||
|
|
||||||
for return_value in return_values[1:]:
|
for return_value in return_values[1:]:
|
||||||
if not return_value.status:
|
if not return_value.status:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
actual = sheerka.value(return_value.value)
|
if isinstance(return_value.body, Concept):
|
||||||
|
evaluated = context.sheerka.evaluate_concept(context, return_value.body, True)
|
||||||
|
if evaluated.key != return_value.body.key:
|
||||||
|
return False
|
||||||
|
|
||||||
|
actual = context.sheerka.value(evaluated)
|
||||||
|
else:
|
||||||
|
actual = context.sheerka.value(return_value)
|
||||||
|
|
||||||
if actual != reference:
|
if actual != reference:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -67,7 +82,7 @@ def expect_one(context, return_values):
|
|||||||
|
|
||||||
# too many winners, which one to choose ?
|
# too many winners, which one to choose ?
|
||||||
if number_of_successful > 1:
|
if number_of_successful > 1:
|
||||||
if is_same_success(sheerka, successful_results):
|
if is_same_success(context, successful_results):
|
||||||
return sheerka.ret(
|
return sheerka.ret(
|
||||||
context.who,
|
context.who,
|
||||||
True,
|
True,
|
||||||
@@ -218,3 +233,22 @@ def _extract_predicates(sheerka, node, variables_to_include, variables_to_exclud
|
|||||||
predicates.append(res)
|
predicates.append(res)
|
||||||
|
|
||||||
return predicates
|
return predicates
|
||||||
|
|
||||||
|
|
||||||
|
def add_to_ret_val(sheerka, context, return_values, concept_key):
|
||||||
|
concept = sheerka.new(concept_key)
|
||||||
|
ret_val = sheerka.ret(context.who, True, concept)
|
||||||
|
return_values.append(ret_val)
|
||||||
|
return return_values
|
||||||
|
|
||||||
|
|
||||||
|
def remove_from_ret_val(sheerka, return_values, concept_key):
|
||||||
|
to_remove = []
|
||||||
|
for ret_val in return_values:
|
||||||
|
if ret_val.status and sheerka.isinstance(ret_val.body, concept_key):
|
||||||
|
to_remove.append(ret_val)
|
||||||
|
|
||||||
|
for item in to_remove:
|
||||||
|
return_values.remove(item)
|
||||||
|
|
||||||
|
return return_values
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class ExecutionContext:
|
|||||||
self.children = []
|
self.children = []
|
||||||
self.preprocess = None
|
self.preprocess = None
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
|
self.extra_info = []
|
||||||
|
|
||||||
self.inputs = {} # what was the parameters of the execution context
|
self.inputs = {} # what was the parameters of the execution context
|
||||||
self.values = {} # what was produced by the execution context
|
self.values = {} # what was produced by the execution context
|
||||||
@@ -210,11 +211,11 @@ class ExecutionContext:
|
|||||||
self.sheerka,
|
self.sheerka,
|
||||||
desc,
|
desc,
|
||||||
logger,
|
logger,
|
||||||
**_kwargs,
|
**_kwargs)
|
||||||
)
|
|
||||||
new._parent = self
|
new._parent = self
|
||||||
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
||||||
new.preprocess = self.preprocess
|
new.preprocess = self.preprocess
|
||||||
|
new.extra_info.extend(self.extra_info)
|
||||||
|
|
||||||
self.children.append(new)
|
self.children.append(new)
|
||||||
return new
|
return new
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from core.concept import Concept, DoNotResolve, ConceptParts, InfiniteRecursionResolved
|
from core.concept import Concept, DoNotResolve, ConceptParts, InfiniteRecursionResolved
|
||||||
import core.builtin_helpers
|
from core.builtin_helpers import add_to_ret_val, remove_from_ret_val, expect_one
|
||||||
|
|
||||||
CONCEPT_EVALUATION_STEPS = [
|
CONCEPT_EVALUATION_STEPS = [
|
||||||
BuiltinConcepts.BEFORE_EVALUATION,
|
BuiltinConcepts.BEFORE_EVALUATION,
|
||||||
@@ -118,7 +118,7 @@ class SheerkaEvaluateConcept:
|
|||||||
else:
|
else:
|
||||||
self.sheerka.cache_by_key[concept.key].compiled = concept.compiled
|
self.sheerka.cache_by_key[concept.key].compiled = concept.compiled
|
||||||
|
|
||||||
def resolve(self, context, to_resolve, current_prop, current_concept):
|
def resolve(self, context, to_resolve, current_prop, current_concept, evaluate_body):
|
||||||
if isinstance(to_resolve, DoNotResolve):
|
if isinstance(to_resolve, DoNotResolve):
|
||||||
return to_resolve.value
|
return to_resolve.value
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ class SheerkaEvaluateConcept:
|
|||||||
# when it's a concept, evaluate it
|
# when it's a concept, evaluate it
|
||||||
if isinstance(to_resolve, Concept) and \
|
if isinstance(to_resolve, Concept) and \
|
||||||
not context.sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE):
|
not context.sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE):
|
||||||
evaluated = self.evaluate_concept(sub_context, to_resolve)
|
evaluated = self.evaluate_concept(sub_context, to_resolve, evaluate_body)
|
||||||
sub_context.add_values(return_values=evaluated)
|
sub_context.add_values(return_values=evaluated)
|
||||||
if evaluated.key == to_resolve.key:
|
if evaluated.key == to_resolve.key:
|
||||||
return evaluated
|
return evaluated
|
||||||
@@ -147,8 +147,11 @@ class SheerkaEvaluateConcept:
|
|||||||
# otherwise, execute all return values to find out what is the value
|
# otherwise, execute all return values to find out what is the value
|
||||||
else:
|
else:
|
||||||
use_copy = [r for r in to_resolve] if hasattr(to_resolve, "__iter__") else to_resolve
|
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)
|
r = self.sheerka.execute(sub_context, use_copy, CONCEPT_EVALUATION_STEPS)
|
||||||
one_r = core.builtin_helpers.expect_one(context, r)
|
|
||||||
|
one_r = expect_one(context, r)
|
||||||
sub_context.add_values(return_values=one_r)
|
sub_context.add_values(return_values=one_r)
|
||||||
if one_r.status:
|
if one_r.status:
|
||||||
return one_r.value
|
return one_r.value
|
||||||
@@ -161,7 +164,7 @@ class SheerkaEvaluateConcept:
|
|||||||
concept=current_concept,
|
concept=current_concept,
|
||||||
property_name=current_prop)
|
property_name=current_prop)
|
||||||
|
|
||||||
def resolve_list(self, context, list_to_resolve, current_prop, current_concept):
|
def resolve_list(self, context, list_to_resolve, current_prop, current_concept, evaluate_body):
|
||||||
"""When dealing with a list, there are two possibilities"""
|
"""When dealing with a list, there are two possibilities"""
|
||||||
# It may be a list of ReturnValueConcept to execute (always the case for metadata)
|
# 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)
|
# or a list of single values (may be the case for properties)
|
||||||
@@ -170,7 +173,7 @@ class SheerkaEvaluateConcept:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
if self.sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE):
|
if self.sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE):
|
||||||
return self.resolve(context, list_to_resolve, current_prop, current_concept)
|
return self.resolve(context, list_to_resolve, current_prop, current_concept, evaluate_body)
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
for to_resolve in list_to_resolve:
|
for to_resolve in list_to_resolve:
|
||||||
@@ -181,35 +184,31 @@ class SheerkaEvaluateConcept:
|
|||||||
concept=current_concept,
|
concept=current_concept,
|
||||||
property_name=current_prop)
|
property_name=current_prop)
|
||||||
|
|
||||||
r = self.resolve(context, to_resolve, current_prop, current_concept)
|
r = self.resolve(context, to_resolve, current_prop, current_concept, evaluate_body)
|
||||||
if self.sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR):
|
if self.sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR):
|
||||||
return r
|
return r
|
||||||
res.append(r)
|
res.append(r)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def evaluate_concept(self, context, concept: Concept):
|
def evaluate_concept(self, context, concept: Concept, evaluate_body=False):
|
||||||
"""
|
"""
|
||||||
Evaluation a concept
|
Evaluation a concept
|
||||||
It means that if the where clause is True, will evaluate the body
|
It means that if the where clause is True, will evaluate the body
|
||||||
:param context:
|
:param context:
|
||||||
:param concept:
|
:param concept:
|
||||||
:param logger:
|
:param evaluate_body: If false, only evaluate body when necessary
|
||||||
:return: value of the evaluation or error
|
:return: value of the evaluation or error
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if concept.metadata.is_evaluated:
|
if concept.metadata.is_evaluated:
|
||||||
return concept
|
return concept
|
||||||
|
|
||||||
#
|
|
||||||
# TODO : Validate the PRE condition
|
|
||||||
#
|
|
||||||
|
|
||||||
self.initialize_concept_asts(context, concept)
|
self.initialize_concept_asts(context, concept)
|
||||||
|
|
||||||
# to make sure of the order, it don't use ConceptParts.get_parts()
|
# to make sure of the order, it don't use ConceptParts.get_parts()
|
||||||
# props must be evaluated first, body must be evaluated before where
|
# props must be evaluated first, body must be evaluated before where
|
||||||
all_metadata_to_eval = ["pre", "post", "props", "body", "where"]
|
all_metadata_to_eval = self.choose_metadata_to_eval(concept, evaluate_body)
|
||||||
|
|
||||||
for metadata_to_eval in all_metadata_to_eval:
|
for metadata_to_eval in all_metadata_to_eval:
|
||||||
if metadata_to_eval == "props":
|
if metadata_to_eval == "props":
|
||||||
@@ -218,10 +217,10 @@ class SheerkaEvaluateConcept:
|
|||||||
|
|
||||||
if isinstance(prop_ast, list):
|
if isinstance(prop_ast, list):
|
||||||
# Do not send the current concept for the properties
|
# Do not send the current concept for the properties
|
||||||
resolved = self.resolve_list(context, prop_ast, prop_name, None)
|
resolved = self.resolve_list(context, prop_ast, prop_name, None, True)
|
||||||
else:
|
else:
|
||||||
# Do not send the current concept for the properties
|
# Do not send the current concept for the properties
|
||||||
resolved = self.resolve(context, prop_ast, prop_name, None)
|
resolved = self.resolve(context, prop_ast, prop_name, None, True)
|
||||||
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
|
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
|
||||||
resolved.set_prop("concept", concept) # since current concept was not sent
|
resolved.set_prop("concept", concept) # since current concept was not sent
|
||||||
return resolved
|
return resolved
|
||||||
@@ -237,12 +236,16 @@ class SheerkaEvaluateConcept:
|
|||||||
|
|
||||||
if part_key in concept.compiled and concept.compiled[part_key] is not None:
|
if part_key in concept.compiled and concept.compiled[part_key] is not None:
|
||||||
metadata_ast = concept.compiled[part_key]
|
metadata_ast = concept.compiled[part_key]
|
||||||
resolved = self.resolve(context, metadata_ast, part_key, concept)
|
resolved = self.resolve(context, metadata_ast, part_key, concept, evaluate_body)
|
||||||
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
|
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
|
||||||
return resolved
|
return resolved
|
||||||
else:
|
else:
|
||||||
concept.values[part_key] = self.get_infinite_recursion_resolution(resolved) or resolved
|
concept.values[part_key] = self.get_infinite_recursion_resolution(resolved) or resolved
|
||||||
|
|
||||||
|
#
|
||||||
|
# TODO : Validate the PRE condition
|
||||||
|
#
|
||||||
|
|
||||||
# validate where clause
|
# validate where clause
|
||||||
if ConceptParts.WHERE in concept.values:
|
if ConceptParts.WHERE in concept.values:
|
||||||
where_value = concept.values[ConceptParts.WHERE]
|
where_value = concept.values[ConceptParts.WHERE]
|
||||||
@@ -254,5 +257,52 @@ class SheerkaEvaluateConcept:
|
|||||||
#
|
#
|
||||||
|
|
||||||
concept.init_key() # only does it if needed
|
concept.init_key() # only does it if needed
|
||||||
concept.metadata.is_evaluated = True
|
concept.metadata.is_evaluated = "body" in all_metadata_to_eval
|
||||||
return concept
|
return concept
|
||||||
|
|
||||||
|
def choose_metadata_to_eval(self, concept, evaluate_body):
|
||||||
|
if evaluate_body:
|
||||||
|
return ["pre", "post", "props", "body", "where"]
|
||||||
|
|
||||||
|
metadata = ["pre", "post"] + self.needed_metadata(concept) + ["where"]
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
def needed_metadata(self, concept):
|
||||||
|
"""
|
||||||
|
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:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
needed = []
|
||||||
|
|
||||||
|
for metadata in (ConceptParts.PRE, ConceptParts.POST, ConceptParts.WHERE):
|
||||||
|
if metadata not in concept.compiled:
|
||||||
|
continue
|
||||||
|
|
||||||
|
return_values = concept.compiled[metadata]
|
||||||
|
if not isinstance(return_values, list):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for return_value in return_values:
|
||||||
|
if not self.sheerka.isinstance(return_value, BuiltinConcepts.RETURN_VALUE):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not return_value.status:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not self.sheerka.isinstance(return_value.body, BuiltinConcepts.PARSER_RESULT):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not isinstance(return_value.body.source, str):
|
||||||
|
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 "self" in return_value.body.source:
|
||||||
|
needed.append("body")
|
||||||
|
return needed
|
||||||
|
|||||||
@@ -150,6 +150,11 @@ class SheerkaExecute:
|
|||||||
debug_result = []
|
debug_result = []
|
||||||
for item in original_items:
|
for item in original_items:
|
||||||
if evaluator.matches(sub_context, item):
|
if evaluator.matches(sub_context, item):
|
||||||
|
|
||||||
|
# init the evaluator is possible
|
||||||
|
if hasattr(evaluator, "init_evaluator") and not evaluator.is_initialized:
|
||||||
|
evaluator.init_evaluator(sub_context, original_items)
|
||||||
|
|
||||||
result = evaluator.eval(sub_context, item)
|
result = evaluator.eval(sub_context, item)
|
||||||
if result is None:
|
if result is None:
|
||||||
debug_result.append({"input": item, "return_value": None})
|
debug_result.append({"input": item, "return_value": None})
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class SheerkaSetsManager:
|
|||||||
# it may be a concept that references a set
|
# it may be a concept that references a set
|
||||||
if not sub_concept.metadata.is_evaluated:
|
if not sub_concept.metadata.is_evaluated:
|
||||||
with context.push(desc=f"Evaluating concept {sub_concept}") as sub_context:
|
with context.push(desc=f"Evaluating concept {sub_concept}") as sub_context:
|
||||||
evaluated = self.sheerka.evaluate_concept(sub_context, sub_concept)
|
evaluated = self.sheerka.evaluate_concept(sub_context, sub_concept, True)
|
||||||
if evaluated.key != concept.key:
|
if evaluated.key != concept.key:
|
||||||
return False
|
return False
|
||||||
return _get_set_elements(context, concept, sub_concept.body)
|
return _get_set_elements(context, concept, sub_concept.body)
|
||||||
@@ -167,7 +167,7 @@ class SheerkaSetsManager:
|
|||||||
# it may be a concept that references a set
|
# it may be a concept that references a set
|
||||||
if not concept.metadata.is_evaluated:
|
if not concept.metadata.is_evaluated:
|
||||||
with context.push(desc=f"Evaluating concept {concept}") as sub_context:
|
with context.push(desc=f"Evaluating concept {concept}") as sub_context:
|
||||||
evaluated = self.sheerka.evaluate_concept(sub_context, concept)
|
evaluated = self.sheerka.evaluate_concept(sub_context, concept, True)
|
||||||
if evaluated.key != concept.key:
|
if evaluated.key != concept.key:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ for x in xx__concepts__xx:
|
|||||||
with context.push(desc=f"Evaluating concepts of a set") as sub_context:
|
with context.push(desc=f"Evaluating concepts of a set") as sub_context:
|
||||||
for element_id in ids:
|
for element_id in ids:
|
||||||
concept = self.sheerka.get_by_id(element_id)
|
concept = self.sheerka.get_by_id(element_id)
|
||||||
evaluated = self.sheerka.evaluate_concept(context, concept)
|
evaluated = self.sheerka.evaluate_concept(sub_context, concept, True)
|
||||||
result.append(evaluated)
|
result.append(evaluated)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -269,7 +269,6 @@ class Sheerka(Concept):
|
|||||||
:param execution_context:
|
:param execution_context:
|
||||||
:param return_values:
|
:param return_values:
|
||||||
:param execution_steps:
|
:param execution_steps:
|
||||||
:param logger: logger to use (if not directly called by sheerka)
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return self.execute_handler.execute(execution_context, return_values, execution_steps)
|
return self.execute_handler.execute(execution_context, return_values, execution_steps)
|
||||||
@@ -294,7 +293,6 @@ class Sheerka(Concept):
|
|||||||
Adds a new concept to the system
|
Adds a new concept to the system
|
||||||
:param context:
|
:param context:
|
||||||
:param concept: DefConceptNode
|
:param concept: DefConceptNode
|
||||||
:param logger
|
|
||||||
:return: digest of the new concept
|
:return: digest of the new concept
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -309,7 +307,6 @@ class Sheerka(Concept):
|
|||||||
:param context:
|
:param context:
|
||||||
:param concept:
|
:param concept:
|
||||||
:param concept_set:
|
:param concept_set:
|
||||||
:param logger:
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return self.sets_handler.add_concept_to_set(context, concept, concept_set)
|
return self.sets_handler.add_concept_to_set(context, concept, concept_set)
|
||||||
@@ -320,7 +317,6 @@ class Sheerka(Concept):
|
|||||||
:param context:
|
:param context:
|
||||||
:param concept:
|
:param concept:
|
||||||
:param concept_set:
|
:param concept_set:
|
||||||
:param logger:
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return self.sets_handler.set_isa(context, concept, concept_set)
|
return self.sets_handler.set_isa(context, concept, concept_set)
|
||||||
@@ -336,16 +332,17 @@ class Sheerka(Concept):
|
|||||||
|
|
||||||
return self.sets_handler.get_set_elements(context, concept)
|
return self.sets_handler.get_set_elements(context, concept)
|
||||||
|
|
||||||
def evaluate_concept(self, context, concept: Concept):
|
def evaluate_concept(self, context, concept: Concept, evaluate_body=False):
|
||||||
"""
|
"""
|
||||||
Evaluation a concept
|
Evaluation a concept
|
||||||
It means that if the where clause is True, will evaluate the body
|
It means that if the where clause is True, will evaluate the body
|
||||||
|
:param evaluate_body:
|
||||||
:param context:
|
:param context:
|
||||||
:param concept:
|
:param concept:
|
||||||
:param logger:
|
:param evaluate_body:
|
||||||
:return: value of the evaluation or error
|
:return: value of the evaluation or error
|
||||||
"""
|
"""
|
||||||
return self.evaluate_concept_handler.evaluate_concept(context, concept)
|
return self.evaluate_concept_handler.evaluate_concept(context, concept, evaluate_body)
|
||||||
|
|
||||||
def add_in_cache(self, concept: Concept):
|
def add_in_cache(self, concept: Concept):
|
||||||
"""
|
"""
|
||||||
@@ -393,7 +390,9 @@ class Sheerka(Concept):
|
|||||||
if result is None:
|
if result is None:
|
||||||
metadata = [("key", concept_key), ("id", concept_id)] if concept_id else ("key", concept_key)
|
metadata = [("key", concept_key), ("id", concept_id)] if concept_id else ("key", concept_key)
|
||||||
result = self._get_unknown(metadata)
|
result = self._get_unknown(metadata)
|
||||||
|
# Do not put in cache_by_key or cache_by_id unknown concept
|
||||||
|
# TODO: implement an MRU cache for them
|
||||||
|
else:
|
||||||
self.cache_by_key[concept_key] = result
|
self.cache_by_key[concept_key] = result
|
||||||
for r in (result if isinstance(result, list) else [result]):
|
for r in (result if isinstance(result, list) else [result]):
|
||||||
if r.id:
|
if r.id:
|
||||||
@@ -640,7 +639,9 @@ class Sheerka(Concept):
|
|||||||
if line == "" or line.startswith("#"):
|
if line == "" or line.startswith("#"):
|
||||||
continue
|
continue
|
||||||
self.log.info(line)
|
self.log.info(line)
|
||||||
self.evaluate_user_input(line)
|
res = self.evaluate_user_input(line)
|
||||||
|
if len(res) > 1 or not res[0].status:
|
||||||
|
self.log.error("Error detected !")
|
||||||
self.during_restore = False
|
self.during_restore = False
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ console_handler = logging.StreamHandler(sys.stdout)
|
|||||||
|
|
||||||
all_loggers = {}
|
all_loggers = {}
|
||||||
|
|
||||||
|
|
||||||
def init_config(loggers):
|
def init_config(loggers):
|
||||||
if loggers is None:
|
if loggers is None:
|
||||||
return
|
return
|
||||||
@@ -55,7 +56,7 @@ def get_logger(logger_name):
|
|||||||
logger.disabled = True
|
logger.disabled = True
|
||||||
|
|
||||||
for e in enabled:
|
for e in enabled:
|
||||||
if logger_name.startswith("verbose." + e):
|
if logger_name.startswith("verbose." + e) or logger_name == e:
|
||||||
logger.disabled = False
|
logger.disabled = False
|
||||||
|
|
||||||
return logger
|
return logger
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
|||||||
|
|
||||||
class ConceptEvaluator(OneReturnValueEvaluator):
|
class ConceptEvaluator(OneReturnValueEvaluator):
|
||||||
"""
|
"""
|
||||||
The concept evaluatuor is the main class that know what to do with a concept
|
The concept evaluator is the main class that know what to do with a concept
|
||||||
It verifies the PRE
|
It verifies the PRE
|
||||||
If ok, can execute or not the BODY
|
If ok, can execute or not the BODY
|
||||||
Then checks the POST conditions
|
Then checks the POST conditions
|
||||||
@@ -15,6 +15,19 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
|||||||
def __init__(self, return_body=False):
|
def __init__(self, return_body=False):
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 50)
|
super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 50)
|
||||||
self.return_body = return_body
|
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 matches(self, context, return_value):
|
def matches(self, context, return_value):
|
||||||
return return_value.status and \
|
return return_value.status and \
|
||||||
@@ -36,7 +49,7 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
|||||||
|
|
||||||
return sheerka.ret(self.name, True, value, parents=[return_value])
|
return sheerka.ret(self.name, True, value, parents=[return_value])
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(context, concept)
|
evaluated = sheerka.evaluate_concept(context, concept, self.evaluate_body)
|
||||||
|
|
||||||
if evaluated.key != concept.key:
|
if evaluated.key != concept.key:
|
||||||
# evaluated.key != concept.key means that we have transformed the concept
|
# evaluated.key != concept.key means that we have transformed the concept
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class EvalEvaluator(AllReturnValuesEvaluator):
|
|||||||
def matches(self, context, return_values):
|
def matches(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
for ret in return_values:
|
for ret in return_values:
|
||||||
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED):
|
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED):
|
||||||
self.eval_requested = ret
|
self.eval_requested = ret
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -47,5 +47,5 @@ class EvalEvaluator(AllReturnValuesEvaluator):
|
|||||||
return sheerka.ret(
|
return sheerka.ret(
|
||||||
self.name,
|
self.name,
|
||||||
False,
|
False,
|
||||||
sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED),
|
sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED),
|
||||||
parents=[self.eval_requested])
|
parents=[self.eval_requested])
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class MultipleSameSuccessEvaluator(AllReturnValuesEvaluator):
|
|||||||
for s in self.success:
|
for s in self.success:
|
||||||
context.log(f"{s}", who=self)
|
context.log(f"{s}", who=self)
|
||||||
|
|
||||||
if not core.builtin_helpers.is_same_success(sheerka, self.success):
|
if not core.builtin_helpers.is_same_success(context, self.success):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# ######################################
|
# ######################################
|
||||||
|
|||||||
@@ -35,6 +35,6 @@ class PrepareEvalEvaluator(OneReturnValueEvaluator):
|
|||||||
|
|
||||||
evaluation_requested = sheerka.ret(
|
evaluation_requested = sheerka.ret(
|
||||||
self.name,
|
self.name,
|
||||||
True, sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
True, sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
|
||||||
|
|
||||||
return [new_text_to_parse, evaluation_requested]
|
return [new_text_to_parse, evaluation_requested]
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
|||||||
|
|
||||||
context.log(f"Evaluating '{concept}'", self.name)
|
context.log(f"Evaluating '{concept}'", self.name)
|
||||||
with context.push(self.name, desc=f"Evaluating '{concept}'", obj=concept) as sub_context:
|
with context.push(self.name, desc=f"Evaluating '{concept}'", obj=concept) as sub_context:
|
||||||
evaluated = context.sheerka.evaluate_concept(sub_context, concept)
|
evaluated = context.sheerka.evaluate_concept(sub_context, concept, True)
|
||||||
sub_context.add_values(return_values=evaluated)
|
sub_context.add_values(return_values=evaluated)
|
||||||
|
|
||||||
if evaluated.key == concept.key:
|
if evaluated.key == concept.key:
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class TooManySuccessEvaluator(AllReturnValuesEvaluator):
|
|||||||
context.log(s, self.name)
|
context.log(s, self.name)
|
||||||
context.log(f"value={sheerka.value(s.value)}", self.name)
|
context.log(f"value={sheerka.value(s.value)}", self.name)
|
||||||
|
|
||||||
if not core.builtin_helpers.is_same_success(sheerka, self.success):
|
if not core.builtin_helpers.is_same_success(context, self.success):
|
||||||
context.log(f"Values are different. Raising {BuiltinConcepts.TOO_MANY_SUCCESS}.", self.name)
|
context.log(f"Values are different. Raising {BuiltinConcepts.TOO_MANY_SUCCESS}.", self.name)
|
||||||
too_many_success = sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS, body=self.success)
|
too_many_success = sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS, body=self.success)
|
||||||
return sheerka.ret(self.name, False, too_many_success, parents=self.eaten)
|
return sheerka.ret(self.name, False, too_many_success, parents=self.eaten)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ def test_i_can_push():
|
|||||||
concepts={"bar": Concept("bar")})
|
concepts={"bar": Concept("bar")})
|
||||||
a.preprocess = set()
|
a.preprocess = set()
|
||||||
a.preprocess.add("preprocess")
|
a.preprocess.add("preprocess")
|
||||||
|
a.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||||
|
|
||||||
b = a.push()
|
b = a.push()
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ def test_i_can_push():
|
|||||||
assert b.id == a.id + 1
|
assert b.id == a.id + 1
|
||||||
assert b._tab == a._tab + " "
|
assert b._tab == a._tab + " "
|
||||||
assert b.preprocess == a.preprocess
|
assert b.preprocess == a.preprocess
|
||||||
|
assert b.extra_info == [BuiltinConcepts.CONCEPT_EVAL_REQUESTED]
|
||||||
|
|
||||||
|
|
||||||
def test_children_i_created_when_i_push():
|
def test_children_i_created_when_i_push():
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
def test_i_can_evaluate_a_concept_with_simple_body(self, body, expected):
|
def test_i_can_evaluate_a_concept_with_simple_body(self, body, expected):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept("foo", body=body)
|
concept = Concept("foo", body=body).init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == expected
|
assert evaluated.body == expected
|
||||||
@@ -53,7 +53,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept("foo", pre=expr)
|
concept = Concept("foo", pre=expr).init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
@@ -63,7 +63,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
assert evaluated.metadata.where is None
|
assert evaluated.metadata.where is None
|
||||||
assert evaluated.get_metadata_value(ConceptParts.PRE) == expected
|
assert evaluated.get_metadata_value(ConceptParts.PRE) == expected
|
||||||
assert evaluated.props == {}
|
assert evaluated.props == {}
|
||||||
assert evaluated.metadata.is_evaluated
|
assert not evaluated.metadata.is_evaluated
|
||||||
assert len(evaluated.values) == 0 if expr is None else 1
|
assert len(evaluated.values) == 0 if expr is None else 1
|
||||||
|
|
||||||
@pytest.mark.parametrize("expr, expected", [
|
@pytest.mark.parametrize("expr, expected", [
|
||||||
@@ -80,7 +80,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept("foo").def_prop("a", expr)
|
concept = Concept("foo").def_prop("a", expr)
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.metadata.pre is None
|
assert evaluated.metadata.pre is None
|
||||||
@@ -95,7 +95,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
concept = Concept("foo")
|
concept = Concept("foo")
|
||||||
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.body == "do not resolve"
|
assert evaluated.body == "do not resolve"
|
||||||
assert evaluated.metadata.is_evaluated
|
assert evaluated.metadata.is_evaluated
|
||||||
@@ -105,7 +105,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
concept = Concept("foo").def_prop("a")
|
concept = Concept("foo").def_prop("a")
|
||||||
concept.compiled["a"] = DoNotResolve("do not resolve")
|
concept.compiled["a"] = DoNotResolve("do not resolve")
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.get_prop("a") == "do not resolve"
|
assert evaluated.get_prop("a") == "do not resolve"
|
||||||
assert evaluated.metadata.is_evaluated
|
assert evaluated.metadata.is_evaluated
|
||||||
@@ -116,7 +116,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
concept.compiled["a"] = DoNotResolve("do not resolve")
|
concept.compiled["a"] = DoNotResolve("do not resolve")
|
||||||
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.body == "do not resolve"
|
assert evaluated.body == "do not resolve"
|
||||||
assert evaluated.get_prop("a") == "do not resolve"
|
assert evaluated.get_prop("a") == "do not resolve"
|
||||||
@@ -126,7 +126,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept("foo", body="a+1").def_prop("a", "10").init_key()
|
concept = Concept("foo", body="a+1").def_prop("a", "10").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == 11
|
assert evaluated.body == 11
|
||||||
@@ -137,7 +137,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(concept_a)
|
sheerka.add_in_cache(concept_a)
|
||||||
|
|
||||||
concept = Concept("foo", body="a").init_key()
|
concept = Concept("foo", body="a").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated == simplec("foo", simplec("a", None))
|
assert evaluated == simplec("foo", simplec("a", None))
|
||||||
assert id(evaluated.body) != id(concept_a)
|
assert id(evaluated.body) != id(concept_a)
|
||||||
@@ -150,7 +150,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(concept_a)
|
sheerka.add_in_cache(concept_a)
|
||||||
|
|
||||||
concept = Concept("foo", body="a")
|
concept = Concept("foo", body="a")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == simplec("a", 1)
|
assert evaluated.body == simplec("a", 1)
|
||||||
@@ -164,7 +164,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True)
|
||||||
|
|
||||||
assert evaluated.key == concept_d.key
|
assert evaluated.key == concept_d.key
|
||||||
expected = simplec("c", simplec("b", simplec("a", "a")))
|
expected = simplec("c", simplec("b", simplec("a", "a")))
|
||||||
@@ -179,7 +179,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True)
|
||||||
|
|
||||||
assert evaluated.key == concept_d.key
|
assert evaluated.key == concept_d.key
|
||||||
expected = simplec("c", simplec("b", simplec("a", None)))
|
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_a = sheerka.add_in_cache(Concept(name="a").init_key())
|
||||||
|
|
||||||
concept = Concept("foo", body="a").def_prop("a", "a").init_key()
|
concept = Concept("foo", body="a").def_prop("a", "a").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
# first prop a is evaluated to concept_a
|
# first prop a is evaluated to concept_a
|
||||||
# then body is evaluated to prop a -> 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_a = sheerka.add_in_cache(Concept(name="a"))
|
||||||
|
|
||||||
concept = Concept("foo", body="concept_a").def_prop("concept_a", "a")
|
concept = Concept("foo", body="concept_a").def_prop("concept_a", "a")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == concept_a
|
assert evaluated.body == concept_a
|
||||||
@@ -220,7 +220,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(Concept(name="b", body="2"))
|
sheerka.add_in_cache(Concept(name="b", body="2"))
|
||||||
|
|
||||||
concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b")
|
concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == 3
|
assert evaluated.body == 3
|
||||||
@@ -231,7 +231,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
concept = Concept("foo").def_prop("a")
|
concept = Concept("foo").def_prop("a")
|
||||||
concept.compiled["a"] = concept_a
|
concept.compiled["a"] = concept_a
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.get_prop("a") == simplec("a", "a")
|
assert evaluated.get_prop("a") == simplec("a", "a")
|
||||||
@@ -242,7 +242,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
concept = Concept("to_eval").def_prop("prop")
|
concept = Concept("to_eval").def_prop("prop")
|
||||||
concept.compiled["prop"] = [foo, DoNotResolve("1")]
|
concept.compiled["prop"] = [foo, DoNotResolve("1")]
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
props = evaluated.get_prop("prop")
|
props = evaluated.get_prop("prop")
|
||||||
assert len(props) == 2
|
assert len(props) == 2
|
||||||
@@ -257,20 +257,20 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
concept = Concept("to_eval").def_prop("prop")
|
concept = Concept("to_eval").def_prop("prop")
|
||||||
concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)]
|
concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)]
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.get_prop("prop") == 2
|
assert evaluated.get_prop("prop") == 2
|
||||||
|
|
||||||
# also works when only one return value
|
# also works when only one return value
|
||||||
concept = Concept("to_eval").def_prop("prop")
|
concept = Concept("to_eval").def_prop("prop")
|
||||||
concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result)
|
concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result)
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.get_prop("prop") == 2
|
assert evaluated.get_prop("prop") == 2
|
||||||
|
|
||||||
def test_i_can_reference_sheerka(self):
|
def test_i_can_reference_sheerka(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept("foo", body="sheerka.test()").init_key()
|
concept = Concept("foo", body="sheerka.test()").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == sheerka.test()
|
assert evaluated.body == sheerka.test()
|
||||||
@@ -281,19 +281,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||||
|
|
||||||
concept = Concept("foo", body="a")
|
concept = Concept("foo", body="a")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == simplec("a", "concept_a") # this test was already done
|
assert evaluated.body == simplec("a", "concept_a") # this test was already done
|
||||||
|
|
||||||
# so check this one.
|
# so check this one.
|
||||||
concept = Concept("foo", body="a").def_prop("a", "'property_a'")
|
concept = Concept("foo", body="a").def_prop("a", "'property_a'")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == 'property_a'
|
assert evaluated.body == 'property_a'
|
||||||
|
|
||||||
# or this one.
|
# or this one.
|
||||||
concept = Concept("foo", body="a").def_prop("a", "b")
|
concept = Concept("foo", body="a").def_prop("a", "b")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == simplec(name="b", body="concept_b")
|
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'"))
|
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||||
|
|
||||||
concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key()
|
concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == 'prop_aconcept_b'
|
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'"))
|
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")
|
concept = Concept("foo", body="a.props['subProp'].value").def_prop("a", "concept_a")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated == simplec(concept.key, "sub_a")
|
assert evaluated == simplec(concept.key, "sub_a")
|
||||||
|
|
||||||
def test_i_cannot_evaluate_concept_if_property_is_in_error(self):
|
def test_i_cannot_evaluate_concept_if_property_is_in_error(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept(name="concept_a").def_prop("subProp", "undef_concept")
|
concept = Concept(name="concept_a").def_prop("subProp", "undef_concept")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||||
|
|
||||||
def test_key_is_initialized_by_evaluation(self):
|
def test_key_is_initialized_by_evaluation(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
concept = Concept("foo")
|
concept = Concept("foo")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
assert evaluated.key == concept.init_key().key
|
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")
|
concept = Concept("foo", body="10", where=where_clause).def_prop("a", "20")
|
||||||
sheerka.add_in_cache(concept)
|
sheerka.add_in_cache(concept)
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
|
|
||||||
if expected:
|
if expected:
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
@@ -362,11 +362,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(foo_true)
|
sheerka.add_in_cache(foo_true)
|
||||||
|
|
||||||
concept = Concept("foo", where="foo_true").init_key()
|
concept = Concept("foo", where="foo_true").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
|
|
||||||
concept = Concept("foo", where="foo_false")
|
concept = Concept("foo", where="foo_false")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||||
assert evaluated.body == concept
|
assert evaluated.body == concept
|
||||||
|
|
||||||
@@ -379,11 +379,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(one_str)
|
sheerka.add_in_cache(one_str)
|
||||||
sheerka.add_in_cache(one_digit)
|
sheerka.add_in_cache(one_digit)
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit, True)
|
||||||
assert evaluated.key == one_digit.key
|
assert evaluated.key == one_digit.key
|
||||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str, True)
|
||||||
assert evaluated.key == one_str.key
|
assert evaluated.key == one_str.key
|
||||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||||
|
|
||||||
@@ -396,11 +396,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka.add_in_cache(true_str)
|
sheerka.add_in_cache(true_str)
|
||||||
sheerka.add_in_cache(true_bool)
|
sheerka.add_in_cache(true_bool)
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str, True)
|
||||||
assert evaluated.key == true_str.key
|
assert evaluated.key == true_str.key
|
||||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool, True)
|
||||||
assert evaluated.key == true_bool.key
|
assert evaluated.key == true_bool.key
|
||||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
c4 = sheerka.add_in_cache(Concept("3", body="one"))
|
c4 = sheerka.add_in_cache(Concept("3", body="one"))
|
||||||
|
|
||||||
for concept in (c1, c2, c3, c4):
|
for concept in (c1, c2, c3, c4):
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True)
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == InfiniteRecursionResolved(3)
|
assert evaluated.body == InfiniteRecursionResolved(3)
|
||||||
|
|
||||||
@@ -425,19 +425,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
baz = sheerka.add_in_cache(Concept("baz", body="qux"))
|
baz = sheerka.add_in_cache(Concept("baz", body="qux"))
|
||||||
qux = sheerka.add_in_cache(Concept("qux", body="foo"))
|
qux = sheerka.add_in_cache(Concept("qux", body="foo"))
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||||
assert evaluated.body == {foo, bar, baz, qux}
|
assert evaluated.body == {foo, bar, baz, qux}
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||||
assert evaluated.body == {foo, bar, baz, qux}
|
assert evaluated.body == {foo, bar, baz, qux}
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||||
assert evaluated.body == {foo, bar, baz, qux}
|
assert evaluated.body == {foo, bar, baz, qux}
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||||
assert evaluated.body == {foo, bar, baz, qux}
|
assert evaluated.body == {foo, bar, baz, qux}
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
foo = sheerka.add_in_cache(Concept("foo", body="foo"))
|
foo = sheerka.add_in_cache(Concept("foo", body="foo"))
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True)
|
||||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||||
assert evaluated.body == {foo}
|
assert evaluated.body == {foo}
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
one = Concept("1", body="1")
|
one = Concept("1", body="1")
|
||||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one)
|
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one, True)
|
||||||
assert evaluated.key == one.key
|
assert evaluated.key == one.key
|
||||||
assert evaluated.body == 1
|
assert evaluated.body == 1
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
|||||||
|
|
||||||
def test_i_can_define_a_group_from_another_group(self):
|
def test_i_can_define_a_group_from_another_group(self):
|
||||||
sheerka, context, foo, bar, group1, group2 = self.init_concepts(
|
sheerka, context, foo, bar, group1, group2 = self.init_concepts(
|
||||||
Concept("foo"), Concept("bar"), Concept("group1"), Concept("group2", body="group1"))
|
"foo", "bar", "group1", Concept("group2", body="group1"))
|
||||||
|
|
||||||
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar], group1)
|
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar], group1)
|
||||||
|
|
||||||
@@ -122,7 +122,8 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
|||||||
Concept("four", body="4"),
|
Concept("four", body="4"),
|
||||||
Concept("five", body="5"),
|
Concept("five", body="5"),
|
||||||
Concept("number"),
|
Concept("number"),
|
||||||
Concept("sub_number", body="number", where="number < 4")
|
Concept("sub_number", body="number", where="number < 4"),
|
||||||
|
create_new=True
|
||||||
)
|
)
|
||||||
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
|
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,26 @@ class EvaluatorOnePreEvaluation(OneReturnValueEvaluatorForTestingPurpose):
|
|||||||
super().__init__("preEval", [BuiltinConcepts.BEFORE_EVALUATION], 10)
|
super().__init__("preEval", [BuiltinConcepts.BEFORE_EVALUATION], 10)
|
||||||
|
|
||||||
|
|
||||||
|
class EvaluatorOneInitializationOnce(OneReturnValueEvaluatorForTestingPurpose):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("init_once", [BuiltinConcepts.EVALUATION], 10)
|
||||||
|
self.is_initialized = False
|
||||||
|
|
||||||
|
def init_evaluator(self, context, return_values):
|
||||||
|
self.out_all("init_evaluator", self.name, context, return_values)
|
||||||
|
self.is_initialized = True
|
||||||
|
|
||||||
|
|
||||||
|
class EvaluatorOneInitializationMultiple(OneReturnValueEvaluatorForTestingPurpose):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("init_multiple", [BuiltinConcepts.EVALUATION], 10)
|
||||||
|
self.is_initialized = False
|
||||||
|
|
||||||
|
def init_evaluator(self, context, return_values):
|
||||||
|
self.out_all("init_evaluator", self.name, context, return_values)
|
||||||
|
# self.is_initialized = True
|
||||||
|
|
||||||
|
|
||||||
class EvaluatorOneMultiSteps(OneReturnValueEvaluatorForTestingPurpose):
|
class EvaluatorOneMultiSteps(OneReturnValueEvaluatorForTestingPurpose):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("multiStep", [BuiltinConcepts.EVALUATION, BuiltinConcepts.BEFORE_EVALUATION], 10)
|
super().__init__("multiStep", [BuiltinConcepts.EVALUATION, BuiltinConcepts.BEFORE_EVALUATION], 10)
|
||||||
@@ -373,3 +393,52 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
|||||||
'__EVALUATION [1] modifyFoo - matches - target=bar',
|
'__EVALUATION [1] modifyFoo - matches - target=bar',
|
||||||
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
|
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def test_i_can_initialize_evaluator_if_initialize_evaluator_is_defined(self):
|
||||||
|
sheerka, context, foo, bar, baz = self.init_concepts("foo", "bar", "baz")
|
||||||
|
sheerka.evaluators = [EvaluatorOneInitializationOnce]
|
||||||
|
|
||||||
|
entries = [
|
||||||
|
self.tretval(sheerka, foo),
|
||||||
|
self.tretval(sheerka, bar),
|
||||||
|
self.tretval(sheerka, baz)
|
||||||
|
]
|
||||||
|
Out.debug_out = []
|
||||||
|
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 - 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):
|
||||||
|
sheerka, context, foo, bar, baz = self.init_concepts("foo", "bar", "baz")
|
||||||
|
sheerka.evaluators = [EvaluatorOneInitializationMultiple]
|
||||||
|
|
||||||
|
entries = [
|
||||||
|
self.tretval(sheerka, foo),
|
||||||
|
self.tretval(sheerka, bar),
|
||||||
|
self.tretval(sheerka, baz)
|
||||||
|
]
|
||||||
|
Out.debug_out = []
|
||||||
|
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 - 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 - 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 - 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'
|
||||||
|
]
|
||||||
|
|||||||
@@ -66,6 +66,31 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
foo_from_sheerka = context.sheerka.get("foo")
|
foo_from_sheerka = context.sheerka.get("foo")
|
||||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == [bar]
|
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == [bar]
|
||||||
|
|
||||||
|
def test_i_can_add_bnf_concept_to_a_set_of_concept(self):
|
||||||
|
"""
|
||||||
|
This test is the reason why I have started the whole eval on demand stuff
|
||||||
|
Sheerka tries to evaluate the body but it can (as a and b are not defined)
|
||||||
|
So 'foo' cannot be put is set
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
sheerka, context, foo, bar = self.init_concepts(
|
||||||
|
Concept("foo", definition="a plus b", body="a + b").def_prop("a").def_prop("b"),
|
||||||
|
"bar",
|
||||||
|
create_new=True)
|
||||||
|
|
||||||
|
ret_val = get_ret_val("foo", "bar")
|
||||||
|
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||||
|
foo = sheerka.new("foo") # reload it
|
||||||
|
|
||||||
|
assert res.status
|
||||||
|
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
||||||
|
assert context.sheerka.isaset(context, bar)
|
||||||
|
assert context.sheerka.isinset(foo, bar)
|
||||||
|
assert context.sheerka.isa(foo, bar)
|
||||||
|
|
||||||
|
foo_from_sheerka = context.sheerka.get("foo")
|
||||||
|
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == [bar]
|
||||||
|
|
||||||
def test_i_can_add_concept_with_a_body_to_a_set_of_concept(self):
|
def test_i_can_add_concept_with_a_body_to_a_set_of_concept(self):
|
||||||
context = self.get_context()
|
context = self.get_context()
|
||||||
foo = Concept("foo", body="1")
|
foo = Concept("foo", body="1")
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
def test_i_can_evaluate_concept(self):
|
def test_i_can_evaluate_concept(self):
|
||||||
context = self.get_context()
|
context = self.get_context()
|
||||||
|
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||||
concept = Concept(name="foo",
|
concept = Concept(name="foo",
|
||||||
where="True",
|
where="True",
|
||||||
pre="2",
|
pre="2",
|
||||||
@@ -27,6 +28,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
evaluator = ConceptEvaluator()
|
evaluator = ConceptEvaluator()
|
||||||
item = self.pretval(concept)
|
item = self.pretval(concept)
|
||||||
|
evaluator.init_evaluator(context, [item])
|
||||||
result = evaluator.eval(context, item)
|
result = evaluator.eval(context, item)
|
||||||
|
|
||||||
assert result.who == evaluator.name
|
assert result.who == evaluator.name
|
||||||
@@ -42,6 +44,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
def test_body_is_returned_when_defined_and_requested(self):
|
def test_body_is_returned_when_defined_and_requested(self):
|
||||||
context = self.get_context()
|
context = self.get_context()
|
||||||
|
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||||
concept = Concept(name="foo",
|
concept = Concept(name="foo",
|
||||||
body="'I have a value'",
|
body="'I have a value'",
|
||||||
where="True",
|
where="True",
|
||||||
@@ -50,6 +53,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
evaluator = ConceptEvaluator(return_body=True)
|
evaluator = ConceptEvaluator(return_body=True)
|
||||||
item = self.pretval(concept)
|
item = self.pretval(concept)
|
||||||
|
evaluator.init_evaluator(context, [item])
|
||||||
result = evaluator.eval(context, item)
|
result = evaluator.eval(context, item)
|
||||||
|
|
||||||
assert result.who == evaluator.name
|
assert result.who == evaluator.name
|
||||||
@@ -67,6 +71,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
|
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
|
||||||
item = self.pretval(concept)
|
item = self.pretval(concept)
|
||||||
|
evaluator.init_evaluator(context, [item])
|
||||||
result = evaluator.eval(context, item)
|
result = evaluator.eval(context, item)
|
||||||
|
|
||||||
assert result.who == evaluator.name
|
assert result.who == evaluator.name
|
||||||
@@ -90,6 +95,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(self):
|
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(self):
|
||||||
context = self.get_context()
|
context = self.get_context()
|
||||||
|
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||||
context.sheerka.add_in_cache(Concept(name="one").init_key())
|
context.sheerka.add_in_cache(Concept(name="one").init_key())
|
||||||
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b")
|
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b")
|
||||||
.def_prop("a", "one")
|
.def_prop("a", "one")
|
||||||
@@ -97,6 +103,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
|
|
||||||
evaluator = ConceptEvaluator()
|
evaluator = ConceptEvaluator()
|
||||||
item = self.pretval(concept_plus)
|
item = self.pretval(concept_plus)
|
||||||
|
evaluator.init_evaluator(context, [item])
|
||||||
result = evaluator.eval(context, item)
|
result = evaluator.eval(context, item)
|
||||||
|
|
||||||
assert not result.status
|
assert not result.status
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from core.concept import Concept
|
|||||||
from evaluators.EvalEvaluator import EvalEvaluator
|
from evaluators.EvalEvaluator import EvalEvaluator
|
||||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||||
|
|
||||||
eval_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
value_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
|
||||||
|
|
||||||
|
|
||||||
def retval(obj, who="who", status=True):
|
def retval(obj, who="who", status=True):
|
||||||
@@ -26,7 +26,7 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
ReturnValueConcept("some_name", False, Concept(name="1", body="'not to eval'")),
|
ReturnValueConcept("some_name", False, Concept(name="1", body="'not to eval'")),
|
||||||
to_eval1,
|
to_eval1,
|
||||||
to_eval2,
|
to_eval2,
|
||||||
eval_requested
|
value_requested
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = EvalEvaluator()
|
evaluator = EvalEvaluator()
|
||||||
@@ -35,16 +35,16 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
evaluated = evaluator.eval(context, return_values)
|
evaluated = evaluator.eval(context, return_values)
|
||||||
assert len(evaluated) == 2
|
assert len(evaluated) == 2
|
||||||
assert evaluated[0].value == to_eval1.body.body
|
assert evaluated[0].value == to_eval1.body.body
|
||||||
assert evaluated[0].parents == [to_eval1, eval_requested]
|
assert evaluated[0].parents == [to_eval1, value_requested]
|
||||||
|
|
||||||
assert evaluated[1].value == to_eval2.body.body
|
assert evaluated[1].value == to_eval2.body.body
|
||||||
assert evaluated[1].parents == [to_eval2, eval_requested]
|
assert evaluated[1].parents == [to_eval2, value_requested]
|
||||||
|
|
||||||
@pytest.mark.parametrize("return_values, expected", [
|
@pytest.mark.parametrize("return_values, expected", [
|
||||||
([retval(Concept("foo", body="bar")), eval_requested], True),
|
([retval(Concept("foo", body="bar")), value_requested], True),
|
||||||
([retval(Concept("status is false", body="bar"), status=False), eval_requested], True),
|
([retval(Concept("status is false", body="bar"), status=False), value_requested], True),
|
||||||
([retval("string_value"), eval_requested], True),
|
([retval("string_value"), value_requested], True),
|
||||||
([retval(Concept("no body")), eval_requested], True),
|
([retval(Concept("no body")), value_requested], True),
|
||||||
([retval(Concept("eval requested missing", body="bar"))], False),
|
([retval(Concept("eval requested missing", body="bar"))], False),
|
||||||
])
|
])
|
||||||
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_values, expected):
|
||||||
@@ -58,7 +58,7 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
ReturnValueConcept("some_name", True, "not to eval"),
|
ReturnValueConcept("some_name", True, "not to eval"),
|
||||||
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
||||||
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
|
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
|
||||||
eval_requested
|
value_requested
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = EvalEvaluator()
|
evaluator = EvalEvaluator()
|
||||||
@@ -68,8 +68,8 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
assert evaluated == ReturnValueConcept(
|
assert evaluated == ReturnValueConcept(
|
||||||
"evaluators.Eval",
|
"evaluators.Eval",
|
||||||
False,
|
False,
|
||||||
context.sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
context.sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
|
||||||
assert evaluated.parents == [eval_requested]
|
assert evaluated.parents == [value_requested]
|
||||||
|
|
||||||
def test_i_can_evaluate_sets(self):
|
def test_i_can_evaluate_sets(self):
|
||||||
sheerka, context, foo, bar, baz, number = self.init_concepts(
|
sheerka, context, foo, bar, baz, number = self.init_concepts(
|
||||||
@@ -79,7 +79,7 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
Concept("number"))
|
Concept("number"))
|
||||||
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar, baz], number)
|
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar, baz], number)
|
||||||
|
|
||||||
return_values = [retval(number), eval_requested]
|
return_values = [retval(number), value_requested]
|
||||||
|
|
||||||
evaluator = EvalEvaluator()
|
evaluator = EvalEvaluator()
|
||||||
evaluator.matches(context, return_values)
|
evaluator.matches(context, return_values)
|
||||||
|
|||||||
@@ -46,4 +46,4 @@ class TestPrepareEvalEvaluator(TestUsingMemoryBasedSheerka):
|
|||||||
assert res[0].body.body == expected
|
assert res[0].body.body == expected
|
||||||
|
|
||||||
assert res[1].status
|
assert res[1].status
|
||||||
assert sheerka.isinstance(res[1].body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
assert sheerka.isinstance(res[1].body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
|||||||
("1 + 1", 2),
|
("1 + 1", 2),
|
||||||
("sheerka.test()", 'I have access to Sheerka !')
|
("sheerka.test()", 'I have access to Sheerka !')
|
||||||
])
|
])
|
||||||
def test_i_can_eval_python_expressions_with_no_variable(self, text, expected):
|
def test_i_can_evaluate_python_expressions_with_no_variable(self, text, expected):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input(text)
|
res = sheerka.evaluate_user_input(text)
|
||||||
@@ -24,7 +24,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
|||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].value == expected
|
assert res[0].value == expected
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_python_body(self):
|
def test_i_can_recognize_concept_with_python_body(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
concept = Concept(name="one", body="1")
|
concept = Concept(name="one", body="1")
|
||||||
sheerka.add_in_cache(concept)
|
sheerka.add_in_cache(concept)
|
||||||
@@ -33,9 +33,13 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
|||||||
res = sheerka.evaluate_user_input(text)
|
res = sheerka.evaluate_user_input(text)
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].value == simplec("one", 1) # by default, the concept is returned
|
assert res[0].value == concept
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_concept_body(self):
|
# sanity check
|
||||||
|
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||||
|
assert evaluated == simplec("one", 1)
|
||||||
|
|
||||||
|
def test_i_can_recognize_concept_with_concept_body(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
concept_one = Concept(name="one")
|
concept_one = Concept(name="one")
|
||||||
concept_un = Concept(name="un", body="one")
|
concept_un = Concept(name="un", body="one")
|
||||||
@@ -46,9 +50,13 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
|||||||
return_value = res[0].value
|
return_value = res[0].value
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert return_value == simplec("un", simplec("one", None))
|
assert return_value == concept_un
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_no_body(self):
|
# sanity check
|
||||||
|
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||||
|
assert evaluated == simplec("un", simplec("one", None))
|
||||||
|
|
||||||
|
def test_i_can_recognize_concept_with_no_body(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
concept = Concept(name="one")
|
concept = Concept(name="one")
|
||||||
sheerka.add_in_cache(concept)
|
sheerka.add_in_cache(concept)
|
||||||
@@ -72,7 +80,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
|||||||
assert res[0].value == concept
|
assert res[0].value == concept
|
||||||
assert id(res[0].value) == id(concept)
|
assert id(res[0].value) == id(concept)
|
||||||
|
|
||||||
def test_i_can_eval_def_concept_request(self):
|
def test_i_can_evaluate_def_concept_request(self):
|
||||||
text = """
|
text = """
|
||||||
def concept a + b
|
def concept a + b
|
||||||
where isinstance(a, int) and isinstance(b, int)
|
where isinstance(a, int) and isinstance(b, int)
|
||||||
@@ -107,7 +115,7 @@ as:
|
|||||||
assert sheerka.sdp.io.exists(
|
assert sheerka.sdp.io.exists(
|
||||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
||||||
|
|
||||||
def test_i_can_eval_def_concept_part_when_one_part_is_a_ref_of_another_concept(self):
|
def test_i_can_evaluate_def_concept_part_when_one_part_is_a_ref_of_another_concept(self):
|
||||||
"""
|
"""
|
||||||
In this test, we test that the properties of 'concept a xx b' (which are 'a' and 'b')
|
In this test, we test that the properties of 'concept a xx b' (which are 'a' and 'b')
|
||||||
are correctly detected, thanks to the source code 'a plus b' in its body
|
are correctly detected, thanks to the source code 'a plus b' in its body
|
||||||
@@ -137,7 +145,7 @@ as:
|
|||||||
assert sheerka.sdp.io.exists(
|
assert sheerka.sdp.io.exists(
|
||||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
||||||
|
|
||||||
def test_i_cannot_eval_the_same_def_concept_twice(self):
|
def test_i_cannot_evaluate_the_same_def_concept_twice(self):
|
||||||
text = """
|
text = """
|
||||||
def concept a + b
|
def concept a + b
|
||||||
where isinstance(a, int) and isinstance(b, int)
|
where isinstance(a, int) and isinstance(b, int)
|
||||||
@@ -162,7 +170,7 @@ as:
|
|||||||
" ",
|
" ",
|
||||||
"\n",
|
"\n",
|
||||||
])
|
])
|
||||||
def test_i_can_eval_a_empty_input(self, text):
|
def test_i_can_recognize_a_empty_input(self, text):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input(text)
|
res = sheerka.evaluate_user_input(text)
|
||||||
@@ -171,7 +179,7 @@ as:
|
|||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.NOP)
|
assert sheerka.isinstance(res[0].value, BuiltinConcepts.NOP)
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_variable(self):
|
def test_i_can_recognize_concept_with_variable(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
concept_hello = Concept(name="hello a").def_prop("a")
|
concept_hello = Concept(name="hello a").def_prop("a")
|
||||||
concept_foo = Concept(name="foo")
|
concept_foo = Concept(name="foo")
|
||||||
@@ -183,9 +191,13 @@ as:
|
|||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(return_value, concept_hello)
|
assert sheerka.isinstance(return_value, concept_hello)
|
||||||
assert return_value.props["a"].value == concept_foo
|
assert return_value.metadata.props[0] == ('a', "foo")
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_variable_and_python_as_body(self):
|
# sanity check
|
||||||
|
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||||
|
assert evaluated.props["a"].value == concept_foo
|
||||||
|
|
||||||
|
def test_i_can_recognize_concept_with_variable_and_python_as_body(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
hello_a = sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
hello_a = sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||||
sheerka.add_in_cache(Concept(name="foo", body="'foo'"))
|
sheerka.add_in_cache(Concept(name="foo", body="'foo'"))
|
||||||
@@ -194,12 +206,15 @@ as:
|
|||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].value, hello_a)
|
assert sheerka.isinstance(res[0].value, hello_a)
|
||||||
assert res[0].value.body == "hello foo"
|
|
||||||
assert res[0].value.metadata.is_evaluated
|
|
||||||
assert res[0].value.props["a"].value == simplec("foo", "foo")
|
|
||||||
assert res[0].value.props["a"].value.metadata.is_evaluated
|
|
||||||
|
|
||||||
def test_i_can_eval_duplicate_concepts_with_same_value(self):
|
# sanity check
|
||||||
|
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||||
|
assert evaluated.body == "hello foo"
|
||||||
|
assert evaluated.metadata.is_evaluated
|
||||||
|
assert evaluated.props["a"].value == simplec("foo", "foo")
|
||||||
|
assert evaluated.props["a"].value.metadata.is_evaluated
|
||||||
|
|
||||||
|
def test_i_can_recognize_duplicate_concepts_with_same_value(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
|
|
||||||
sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||||
@@ -248,11 +263,11 @@ as:
|
|||||||
context = self.get_context(sheerka)
|
context = self.get_context(sheerka)
|
||||||
|
|
||||||
sheerka.create_new_concept(context, Concept(name="concepts", body="sheerka.concepts()"))
|
sheerka.create_new_concept(context, Concept(name="concepts", body="sheerka.concepts()"))
|
||||||
res = sheerka.evaluate_user_input("concepts")
|
res = sheerka.evaluate_user_input("eval concepts")
|
||||||
|
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert isinstance(res[0].value.body, list)
|
assert isinstance(res[0].value, list)
|
||||||
|
|
||||||
def test_i_can_create_concept_with_bnf_definition(self):
|
def test_i_can_create_concept_with_bnf_definition(self):
|
||||||
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
||||||
@@ -284,7 +299,7 @@ as:
|
|||||||
assert "a" in new_concept.props
|
assert "a" in new_concept.props
|
||||||
assert "plus" in new_concept.props
|
assert "plus" in new_concept.props
|
||||||
|
|
||||||
def test_i_can_eval_bnf_definitions(self):
|
def test_i_can_recognize_bnf_definitions(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' | 'two'")[0].body.body
|
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' | 'two'")[0].body.body
|
||||||
|
|
||||||
@@ -294,7 +309,7 @@ as:
|
|||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].value, concept_a)
|
assert sheerka.isinstance(res[0].value, concept_a)
|
||||||
|
|
||||||
def test_i_can_eval_bnf_definitions_with_variables(self):
|
def test_i_can_recognize_bnf_definitions_with_variables(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' | 'two'")[0].body.body
|
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' | 'two'")[0].body.body
|
||||||
concept_b = sheerka.evaluate_user_input("def concept b from bnf a 'three'")[0].body.body
|
concept_b = sheerka.evaluate_user_input("def concept b from bnf a 'three'")[0].body.body
|
||||||
@@ -306,13 +321,15 @@ as:
|
|||||||
return_value = res[0].value
|
return_value = res[0].value
|
||||||
|
|
||||||
assert sheerka.isinstance(return_value, concept_b)
|
assert sheerka.isinstance(return_value, concept_b)
|
||||||
assert return_value.body == "one three"
|
|
||||||
assert return_value.metadata.is_evaluated
|
|
||||||
|
|
||||||
assert return_value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
|
# sanity check
|
||||||
assert return_value.props["a"].value.metadata.is_evaluated
|
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||||
|
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())
|
||||||
|
assert evaluated.props["a"].value.metadata.is_evaluated
|
||||||
|
|
||||||
def test_i_can_eval_bnf_definitions_from_separate_instances(self):
|
def test_i_can_recognize_bnf_definitions_from_separate_instances(self):
|
||||||
"""
|
"""
|
||||||
Same test then before,
|
Same test then before,
|
||||||
but make sure that the BNF are correctly persisted and loaded
|
but make sure that the BNF are correctly persisted and loaded
|
||||||
@@ -337,8 +354,10 @@ as:
|
|||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].value, concept_b)
|
assert sheerka.isinstance(res[0].value, concept_b)
|
||||||
assert res[0].value.body == "one two three"
|
|
||||||
assert res[0].value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||||
|
assert evaluated.body == "one two three"
|
||||||
|
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
||||||
|
|
||||||
@pytest.mark.parametrize("desc, definitions", [
|
@pytest.mark.parametrize("desc, definitions", [
|
||||||
("Simple form", [
|
("Simple form", [
|
||||||
@@ -387,7 +406,7 @@ as:
|
|||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].body, "twenties")
|
assert sheerka.isinstance(res[0].body, "twenties")
|
||||||
assert res[0].body.body == 21
|
assert sheerka.evaluate_concept(self.get_context(), res[0].body, True).body == 21
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
@@ -430,7 +449,8 @@ as:
|
|||||||
res = sheerka.evaluate_user_input("twenty one")
|
res = sheerka.evaluate_user_input("twenty one")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body == simplec("twenties", 21)
|
assert sheerka.isinstance(res[0].body, "twenties")
|
||||||
|
assert sheerka.evaluate_concept(self.get_context(), res[0].value, True).body == 21
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
@@ -472,10 +492,10 @@ as:
|
|||||||
for exp in init:
|
for exp in init:
|
||||||
sheerka.evaluate_user_input(exp)
|
sheerka.evaluate_user_input(exp)
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one")
|
res = sheerka.evaluate_user_input("eval twenty one")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body == simplec("twenties", 21)
|
assert res[0].body == 21
|
||||||
|
|
||||||
def test_i_can_mix_concept_of_concept(self):
|
def test_i_can_mix_concept_of_concept(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
@@ -490,55 +510,55 @@ as:
|
|||||||
for definition in definitions:
|
for definition in definitions:
|
||||||
sheerka.evaluate_user_input(definition)
|
sheerka.evaluate_user_input(definition)
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("1 plus 2")
|
res = sheerka.evaluate_user_input("eval 1 plus 2")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 3
|
assert res[0].body == 3
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("1 plus one")
|
res = sheerka.evaluate_user_input("eval 1 plus one")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 2
|
assert res[0].body == 2
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("1 + 1 plus 1")
|
res = sheerka.evaluate_user_input("eval 1 + 1 plus 1")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 3
|
assert res[0].body == 3
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("1 plus twenty one")
|
res = sheerka.evaluate_user_input("eval 1 plus twenty one")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 22
|
assert res[0].body == 22
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("one plus 1")
|
res = sheerka.evaluate_user_input("eval one plus 1")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 2
|
assert res[0].body == 2
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("one plus two")
|
res = sheerka.evaluate_user_input("eval one plus two")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 3
|
assert res[0].body == 3
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("one plus twenty one")
|
res = sheerka.evaluate_user_input("eval one plus twenty one")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 22
|
assert res[0].body == 22
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one plus 1")
|
res = sheerka.evaluate_user_input("eval twenty one plus 1")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 22
|
assert res[0].body == 22
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one plus one")
|
res = sheerka.evaluate_user_input("eval twenty one plus one")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 22
|
assert res[0].body == 22
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one plus twenty two")
|
res = sheerka.evaluate_user_input("eval twenty one plus twenty two")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body.body == 43
|
assert res[0].body == 43
|
||||||
|
|
||||||
@pytest.mark.xfail
|
@pytest.mark.xfail
|
||||||
def test_i_can_evaluate_concept_of_concept_when_multiple_choices(self):
|
def test_i_can_evaluate_concept_of_concept_when_multiple_choices(self):
|
||||||
@@ -663,23 +683,29 @@ as:
|
|||||||
for exp in init:
|
for exp in init:
|
||||||
sheerka.evaluate_user_input(exp)
|
sheerka.evaluate_user_input(exp)
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("twenty one")
|
||||||
|
assert len(res) == 1 and res[0].status and sheerka.isinstance(res[0].body, "twenties")
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("eval twenty one")
|
res = sheerka.evaluate_user_input("eval twenty one")
|
||||||
assert len(res) == 1 and res[0].status and res[0].body == 21
|
assert len(res) == 1 and res[0].status and res[0].body == 21
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("twenty two")
|
||||||
|
assert len(res) == 1 and res[0].status and sheerka.isinstance(res[0].body, "twenties")
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("eval twenty two")
|
res = sheerka.evaluate_user_input("eval twenty two")
|
||||||
assert len(res) == 1 and res[0].status and res[0].body == 22
|
assert len(res) == 1 and res[0].status and res[0].body == 22
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("eval twenty three")
|
res = sheerka.evaluate_user_input("eval twenty three")
|
||||||
assert len(res) > 1
|
assert len(res) > 1
|
||||||
|
|
||||||
def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
|
# def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
|
||||||
sheerka = self.get_sheerka()
|
# sheerka = self.get_sheerka()
|
||||||
|
#
|
||||||
sheerka.evaluate_user_input("def concept 1 as one")
|
# sheerka.evaluate_user_input("def concept 1 as one")
|
||||||
res = sheerka.evaluate_user_input("1")
|
# res = sheerka.evaluate_user_input("eval 1")
|
||||||
assert len(res) == 1
|
# assert len(res) == 1
|
||||||
assert not res[0].status
|
# assert not res[0].status
|
||||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
# assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||||
|
|
||||||
def test_i_can_manage_some_type_of_infinite_recursion(self):
|
def test_i_can_manage_some_type_of_infinite_recursion(self):
|
||||||
sheerka = self.get_sheerka()
|
sheerka = self.get_sheerka()
|
||||||
@@ -696,3 +722,56 @@ as:
|
|||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body == 2
|
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'")
|
||||||
|
sheerka.evaluate_user_input("def concept b as 'hello world'")
|
||||||
|
sheerka.evaluate_user_input("def concept foobar from bnf 'foo' a where a=='bar' as b")
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("foo bar")
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0].status
|
||||||
|
assert sheerka.isinstance(res[0].body, "foobar")
|
||||||
|
assert res[0].body.body is None
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("eval foo bar")
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0].status
|
||||||
|
assert res[0].body.body == "hello world"
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("foo baz")
|
||||||
|
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 foo baz")
|
||||||
|
assert len(res) > 1
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
def test_i_can_say_than_bnf_concept_isa_another_concept(self):
|
||||||
|
sheerka = self.get_sheerka()
|
||||||
|
sheerka.evaluate_user_input("def concept number")
|
||||||
|
sheerka.evaluate_user_input("def concept one as 1")
|
||||||
|
sheerka.evaluate_user_input("def concept two as 2")
|
||||||
|
sheerka.evaluate_user_input("def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit")
|
||||||
|
|
||||||
|
res = sheerka.evaluate_user_input("twenties isa number")
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0].status
|
||||||
|
|
||||||
|
twenties = sheerka.get("twenties")
|
||||||
|
number = sheerka.get("number")
|
||||||
|
assert sheerka.isa(twenties, number)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
|
|||||||
assert return_value.compiled["b"] == bar
|
assert return_value.compiled["b"] == bar
|
||||||
|
|
||||||
# sanity check, I can evaluate the result
|
# sanity check, I can evaluate the result
|
||||||
evaluated = context.sheerka.evaluate_concept(context, return_value)
|
evaluated = context.sheerka.evaluate_concept(context, return_value, True)
|
||||||
assert evaluated.key == return_value.key
|
assert evaluated.key == return_value.key
|
||||||
assert evaluated.get_prop("a") == foo.init_key()
|
assert evaluated.get_prop("a") == foo.init_key()
|
||||||
assert evaluated.get_prop("b") == bar.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)]
|
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, right_parser_result)]
|
||||||
|
|
||||||
# sanity check, I can evaluate the result
|
# sanity check, I can evaluate the result
|
||||||
evaluated = context.sheerka.evaluate_concept(context, return_value)
|
evaluated = context.sheerka.evaluate_concept(context, return_value, True)
|
||||||
assert evaluated.key == return_value.key
|
assert evaluated.key == return_value.key
|
||||||
assert evaluated.get_prop("a") == 2
|
assert evaluated.get_prop("a") == 2
|
||||||
assert evaluated.get_prop("b") == 4
|
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)]
|
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, code_parser_result)]
|
||||||
|
|
||||||
# sanity check, I can evaluate the result
|
# sanity check, I can evaluate the result
|
||||||
evaluated = context.sheerka.evaluate_concept(context, return_value)
|
evaluated = context.sheerka.evaluate_concept(context, return_value, True)
|
||||||
assert evaluated.key == return_value.key
|
assert evaluated.key == return_value.key
|
||||||
assert evaluated.get_prop("a") == foo.init_key()
|
assert evaluated.get_prop("a") == foo.init_key()
|
||||||
assert evaluated.get_prop("b") == 2
|
assert evaluated.get_prop("b") == 2
|
||||||
|
|||||||
Reference in New Issue
Block a user