Fixed #100 : SheerkaAdmin: Add builtins() command
Fixed #99 : SheerkaQueryManager: I can manage contains predicate when filtering objects Fixed #97 : ERROR: list indices must be integers or slices, not Concept Fixed #96 : SequenceNodeParser: SequenceNodeParser must correctly handle concept definition Fixed #95 : ResolveAmbiguity must not remove concepts that do not require evaluation Fixed #94 : Concepts with the same key are lost when new ontology Fixed #93 : Introduce BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED Fixed #92 : ExpressionParser: Implement compile_disjunctions() Fixed #91 : Implement get_concepts_complexity(context, concepts, concept_parts) Fixed #90 : ResolveAmbiguity : where predicate is not used to resolve ambiguity Fixed #89 : ResolveAmbiguityEvaluator: Concepts embedded in ConceptNode are not resolved Fixed #88: SyaNodeParser: Parse multiple parameters when some of the are not recognized Fixed #87: SyaNodeParser : Parse the multiple parameters
This commit is contained in:
+66
-15
@@ -46,6 +46,7 @@ RULES_EXECUTE_STEPS = [
|
||||
# It indicate which parameter was used to recognize the concept
|
||||
RECOGNIZED_BY_ID = "by_id"
|
||||
RECOGNIZED_BY_NAME = "by_name"
|
||||
RECOGNIZED_BY_KEY = "by_key"
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -53,9 +54,17 @@ class SheerkaMethod:
|
||||
"""
|
||||
Wrapper to sheerka method, to indicate if it's safe to call
|
||||
"""
|
||||
name: str
|
||||
service: str
|
||||
method: object
|
||||
has_side_effect: bool
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.name, self.service))
|
||||
|
||||
|
||||
class Sheerka(Concept):
|
||||
"""
|
||||
@@ -111,16 +120,18 @@ class Sheerka(Concept):
|
||||
self.methods_with_context = {"test_using_context"} # only the names, the method is defined in sheerka_methods
|
||||
self.pipe_functions = set()
|
||||
self.sheerka_methods = {
|
||||
"test": SheerkaMethod(self.test, False),
|
||||
"test_using_context": SheerkaMethod(self.test_using_context, False),
|
||||
"test_dict": SheerkaMethod(self.test_dict, False),
|
||||
"test_error": SheerkaMethod(self.test_error, False),
|
||||
"is_sheerka": SheerkaMethod(self.is_sheerka, False),
|
||||
"objvalue": SheerkaMethod(self.objvalue, False),
|
||||
"test": SheerkaMethod("test", self.name, self.test, False),
|
||||
"test_using_context": SheerkaMethod("test_using_context", self.name, self.test_using_context, False),
|
||||
"test_dict": SheerkaMethod("test_dict", self.name, self.test_dict, False),
|
||||
"test_error": SheerkaMethod("test_error", self.name, self.test_error, False),
|
||||
"is_sheerka": SheerkaMethod("is_sheerka", self.name, self.is_sheerka, False),
|
||||
"objvalue": SheerkaMethod("objvalue", self.name, self.objvalue, False),
|
||||
}
|
||||
|
||||
self.concepts_ids = None
|
||||
|
||||
self._global_context_hints = set() # hints to add to every execution contexts before every execution
|
||||
|
||||
def __copy__(self):
|
||||
return self
|
||||
|
||||
@@ -135,9 +146,10 @@ class Sheerka(Concept):
|
||||
def root_folder(self):
|
||||
return self.om.root_folder
|
||||
|
||||
def bind_service_method(self, bound_method, has_side_effect, as_name=None, visible=True):
|
||||
def bind_service_method(self, service_name, bound_method, has_side_effect, as_name=None, visible=True):
|
||||
"""
|
||||
Bind service method to sheerka instance for ease of use ?
|
||||
:param service_name:
|
||||
:param bound_method:
|
||||
:param has_side_effect: False if the method is safe
|
||||
:param as_name: give another name to the method
|
||||
@@ -157,7 +169,7 @@ class Sheerka(Concept):
|
||||
signature = inspect.signature(bound_method)
|
||||
if len(signature.parameters) > 0 and list(signature.parameters.keys())[0] == "context":
|
||||
self.methods_with_context.add(as_name)
|
||||
self.sheerka_methods[as_name] = SheerkaMethod(bound_method, has_side_effect)
|
||||
self.sheerka_methods[as_name] = SheerkaMethod(as_name, service_name, bound_method, has_side_effect)
|
||||
if is_pipe_function:
|
||||
self.pipe_functions.add(as_name)
|
||||
|
||||
@@ -368,6 +380,9 @@ class Sheerka(Concept):
|
||||
text,
|
||||
desc=f"Evaluating '{text}'") as execution_context:
|
||||
|
||||
# adds the global context hints if any
|
||||
execution_context.global_hints = self._global_context_hints.copy()
|
||||
|
||||
user_input = self.ret(self.name, True, self.new(BuiltinConcepts.USER_INPUT, body=text, user_name=user_name))
|
||||
execution_context.add_inputs(user_input=user_input)
|
||||
|
||||
@@ -465,17 +480,35 @@ class Sheerka(Concept):
|
||||
|
||||
return None
|
||||
|
||||
def fast_resolve(self, key, return_new=True):
|
||||
def add_recognized_by(c, _recognized_by):
|
||||
c.get_hints().recognized_by = _recognized_by
|
||||
def fast_resolve(self, key, return_new=True, force_instance=False):
|
||||
"""
|
||||
Resolve a concept, but do not use get_by_name() or get_by_id()
|
||||
:param key:
|
||||
:param return_new:
|
||||
:param force_instance: When set, return an concept instance, not a concept definition
|
||||
:return:
|
||||
"""
|
||||
|
||||
def update_hints(c, rec_by, is_inst, is_eval):
|
||||
c.get_hints().recognized_by = rec_by
|
||||
c.get_hints().is_instance = is_inst
|
||||
if is_eval is None:
|
||||
c.get_hints().is_evaluated = len(c.get_metadata().variables) > 0
|
||||
else:
|
||||
c.get_hints().is_evaluated = is_eval
|
||||
return c
|
||||
|
||||
def new_instances(concepts, _recognized_by):
|
||||
def new_instances(concepts, rec_by, is_inst, is_eval):
|
||||
if hasattr(concepts, "__iter__"):
|
||||
return [add_recognized_by(self.new_from_template(c, c.key), _recognized_by) for c in concepts]
|
||||
return [update_hints(self.new_from_template(c, c.key), rec_by, is_inst, is_eval) for c in
|
||||
concepts]
|
||||
|
||||
return add_recognized_by(self.new_from_template(concepts, concepts.key), _recognized_by)
|
||||
return update_hints(self.new_from_template(concepts, concepts.key), rec_by, is_inst, is_eval)
|
||||
|
||||
# ##############
|
||||
# PREPROCESS
|
||||
# ##############
|
||||
# if the entry is a concept token, use its values.
|
||||
if isinstance(key, Token):
|
||||
if key.type == TokenKind.RULE: # do not recognize rules !!!
|
||||
return None
|
||||
@@ -484,10 +517,15 @@ class Sheerka(Concept):
|
||||
elif isinstance(key, str) and key.startswith("c:"):
|
||||
key = core.utils.unstr_concept(key)
|
||||
|
||||
# ##############
|
||||
# Get the concept(s)
|
||||
# ##############
|
||||
if isinstance(key, tuple):
|
||||
if key == (None, None):
|
||||
return None
|
||||
|
||||
is_instance = force_instance
|
||||
is_evaluated = not force_instance
|
||||
if key[1]:
|
||||
concept = self.om.get(self.CONCEPTS_BY_ID_ENTRY, key[1])
|
||||
recognized_by = RECOGNIZED_BY_ID
|
||||
@@ -495,12 +533,15 @@ class Sheerka(Concept):
|
||||
concept = self.om.get(self.CONCEPTS_BY_NAME_ENTRY, key[0])
|
||||
recognized_by = RECOGNIZED_BY_NAME
|
||||
else:
|
||||
is_instance = True
|
||||
is_evaluated = None
|
||||
concept = self.om.get(self.CONCEPTS_BY_NAME_ENTRY, key)
|
||||
recognized_by = RECOGNIZED_BY_NAME
|
||||
|
||||
if concept is NotFound:
|
||||
return None
|
||||
return new_instances(concept, recognized_by) if return_new else concept
|
||||
|
||||
return new_instances(concept, recognized_by, is_instance, is_evaluated) if return_new else concept
|
||||
|
||||
def new(self, concept_key, **kwargs):
|
||||
"""
|
||||
@@ -632,6 +673,16 @@ class Sheerka(Concept):
|
||||
if hasattr(service, "reset_state"):
|
||||
service.reset_state()
|
||||
|
||||
def add_to_context(self, concept_key):
|
||||
concept_key = concept_key.name if isinstance(concept_key, Concept) else concept_key
|
||||
self._global_context_hints.add(concept_key)
|
||||
return self.ret(self.name, True, self.new(BuiltinConcepts.SUCCESS))
|
||||
|
||||
def remove_fom_context(self, concept_key):
|
||||
concept_key = concept_key.name if isinstance(concept_key, Concept) else concept_key
|
||||
self._global_context_hints.remove(concept_key)
|
||||
return self.ret(self.name, True, self.new(BuiltinConcepts.SUCCESS))
|
||||
|
||||
def ret(self, who: str, status: bool, value, parents=None):
|
||||
"""
|
||||
Creates and returns a ReturnValue concept
|
||||
|
||||
Reference in New Issue
Block a user