Working on #98 : Persist attribute value when global_truth is set to true

This commit is contained in:
2021-08-03 11:26:57 +02:00
parent e69745adc8
commit c798c2c570
22 changed files with 496 additions and 106 deletions
@@ -295,7 +295,7 @@ class SheerkaConceptManager(BaseService):
# 'props' : {<key>: <value>} of properties to add/update,
# 'variables': {<key>: <value>} of variables to add/update,
# }
# if the <key> already exists, the entry is updated, otherwise a new value is created
# for variables, if the <key> already exists, the entry is updated, otherwise a new value is created
# for props, if the <key> already exists, a new entry is added to the set
#
# to_remove = {
@@ -391,9 +391,10 @@ class SheerkaConceptManager(BaseService):
sheerka.publish(context, EVENT_CONCEPT_DELETED, concept)
return sheerka.ret(self.NAME, True, sheerka.new(BuiltinConcepts.SUCCESS))
def set_attr(self, concept, attribute, value):
def set_attr(self, context, concept, attribute, value):
"""
Modifies an attribute of a concept (concept.values)
:param context:
:param concept:
:param attribute:
:param value:
@@ -402,8 +403,16 @@ class SheerkaConceptManager(BaseService):
ensure_concept(concept)
attr = attribute.str_id if isinstance(attribute, Concept) else attribute
old_value = concept.get_value(attr)
if (old_value := concept.get_value(attr)) is not NotInit:
if context.in_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED):
old_value = self.sheerka.get_by_id(concept.id).get_value(attr)
else:
old_value = concept.get_value(attr)
# Caution, creating a list when a set_attr is called for the second time is not always
# what is expected
if old_value is not NotInit:
if old_value == value:
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
@@ -413,8 +422,15 @@ class SheerkaConceptManager(BaseService):
else:
value = [old_value, value]
concept.set_value(attr, value)
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
if context.in_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED):
to_add = {"variables": {attr: value}}
res = self.sheerka.modify_concept(context, concept, to_add, modify_source=True)
concept.set_value(attr, value)
return res
else:
concept.set_value(attr, value)
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
def get_attr(self, concept, attribute):
"""
@@ -857,6 +873,7 @@ class SheerkaConceptManager(BaseService):
concept.set_bnf(None)
ensure_bnf(context, concept)
self.recompute_concept_parameters(context, concept)
concept.init_key()
return
@@ -1252,3 +1269,27 @@ class SheerkaConceptManager(BaseService):
# update the compiled regex
self.compiled_concepts_by_regex.clear()
self.compiled_concepts_by_regex.extend(compiled_by_first_regex)
@staticmethod
def recompute_concept_parameters(context, concept):
concept.get_metadata().parameters.clear()
if concept.get_metadata().definition_type == DEFINITION_TYPE_DEF:
tokens = list(Tokenizer(concept.get_metadata().definition, yield_eof=False))
else:
tokens = list(Tokenizer(concept.get_metadata().name, yield_eof=False))
# all variables that appear in the name are concept parameters
if len(tokens) > 0:
variables = [p[0] for p in concept.get_metadata().variables]
for token in [t for t in tokens if t.value in variables]:
concept.get_metadata().parameters.append(token.value)
# for bnf concept, use the visitor to extract parameters
if concept.get_bnf():
from evaluators.DefConceptEvaluator import ConceptOrRuleVariableVisitor, ParameterVariable
visitor = ConceptOrRuleVariableVisitor(context)
visitor.visit(concept.get_bnf())
for variable in [v for v in visitor.variables if isinstance(v, ParameterVariable)]:
if variable.name not in concept.get_metadata().parameters:
concept.get_metadata().parameters.append(variable.name)
@@ -432,15 +432,18 @@ class SheerkaEvaluateConcept(BaseService):
if default_value is None:
continue
if not isinstance(default_value, str):
raise Exception("Invalid concept init. variable metadata must be a string")
if not isinstance(default_value, (str, Concept)):
raise Exception("Invalid concept init. variable metadata must be a string (or a concept)")
concept.get_compiled()[var_name] = self.get_asts(context,
self.NAME,
default_value,
concept,
var_name,
possible_variables)
if isinstance(default_value, Concept):
concept.get_compiled()[var_name] = default_value.copy()
else:
concept.get_compiled()[var_name] = self.get_asts(context,
self.NAME,
default_value,
concept,
var_name,
possible_variables)
def resolve(self,
context,
@@ -740,8 +743,6 @@ class SheerkaEvaluateConcept(BaseService):
# TODO : Validate the POST condition
#
concept.init_key() # Necessary for old unit tests. To remove someday
if ConceptParts.BODY in all_metadata_to_eval and not failed_to_evaluate_body:
concept.get_hints().is_evaluated = True