First version of explain. Creating a new parser was a wrong approach. Need to reimplement
This commit is contained in:
@@ -3,6 +3,7 @@ import time
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.Services.SheerkaExecute import NO_MATCH
|
||||
from core.sheerka_logger import get_logger
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
@@ -261,6 +262,74 @@ class ExecutionContext:
|
||||
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _is_return_value(obj):
|
||||
return isinstance(obj, Concept) and obj.key == str(BuiltinConcepts.RETURN_VALUE)
|
||||
|
||||
def _at_least_one_success(self, return_values):
|
||||
status = False
|
||||
for ret_val in return_values:
|
||||
if not self._is_return_value(ret_val):
|
||||
return None
|
||||
status |= ret_val.status
|
||||
return status
|
||||
|
||||
def _all_success(self, return_values):
|
||||
status = True
|
||||
for ret_val in return_values:
|
||||
if not self._is_return_value(ret_val):
|
||||
return None
|
||||
status &= ret_val.status
|
||||
return status
|
||||
|
||||
def get_status(self):
|
||||
# In the function, I cannot use sheerka.isinstance() as self.sheerka may not be initialized
|
||||
# This is the case when ExecutionContext is deserialized
|
||||
|
||||
if "return_values" not in self.values:
|
||||
return None
|
||||
|
||||
if hasattr(self.values["return_values"], "__iter__"):
|
||||
values = self.values["return_values"]
|
||||
if len(values) == 0:
|
||||
return None
|
||||
|
||||
if isinstance(values, str):
|
||||
return "No Match" if values == NO_MATCH else values
|
||||
|
||||
if isinstance(values[0], dict):
|
||||
for result in values:
|
||||
if "return_value" not in result:
|
||||
return None
|
||||
if self._is_return_value(result["return_value"]):
|
||||
return result["return_value"].status
|
||||
return "No Match"
|
||||
else:
|
||||
return self._at_least_one_success(self.values["return_values"])
|
||||
|
||||
else:
|
||||
ret_val = self.values["return_values"]
|
||||
if not isinstance(ret_val, Concept) or not ret_val.key == str(BuiltinConcepts.RETURN_VALUE):
|
||||
return None
|
||||
return ret_val.status
|
||||
|
||||
def to_bag(self):
|
||||
"""
|
||||
Creates a dictionary with the useful properties of the concept
|
||||
It quicker to implement than creating the actual property mechanism with @property
|
||||
And it removes the visibility from the other attributes/methods
|
||||
"""
|
||||
bag = {}
|
||||
for k, v in self._bag.items():
|
||||
bag[k] = v
|
||||
bag["bag." + k] = v
|
||||
for prop in ("id", "who", "desc", "obj", "inputs", "values", "concepts"):
|
||||
bag[prop] = getattr(self, prop)
|
||||
bag["status"] = self.get_status()
|
||||
bag["elapsed"] = self.elapsed
|
||||
bag["digest"] = self.event.get_digest() if self.event else None
|
||||
return bag
|
||||
|
||||
@staticmethod
|
||||
def return_value_to_str(r):
|
||||
value = str(r.value)
|
||||
|
||||
@@ -86,7 +86,7 @@ class SheerkaDump:
|
||||
|
||||
while True:
|
||||
try:
|
||||
if h.event.user != self.sheerka.name:
|
||||
if h.result:
|
||||
self.sheerka.log.info(h)
|
||||
count += 1
|
||||
h = next(history)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
|
||||
import core.utils
|
||||
|
||||
NO_MATCH = "** No Match **"
|
||||
|
||||
class SheerkaExecute:
|
||||
"""
|
||||
@@ -159,7 +160,7 @@ class SheerkaExecute:
|
||||
evaluated_items.append(result)
|
||||
debug_result.append({"input": item, "return_value": result})
|
||||
else:
|
||||
debug_result.append({"input": item, "return_value": "** No Match **"})
|
||||
debug_result.append({"input": item, "return_value": NO_MATCH})
|
||||
sub_context.add_values(return_values=debug_result)
|
||||
|
||||
# process evaluators that work on all return values
|
||||
@@ -175,7 +176,7 @@ class SheerkaExecute:
|
||||
to_delete.extend(result.parents)
|
||||
sub_context.add_values(return_values=results)
|
||||
else:
|
||||
sub_context.add_values(return_values="** No Match **")
|
||||
sub_context.add_values(return_values=NO_MATCH)
|
||||
|
||||
return_values = evaluated_items
|
||||
return_values.extend([item for item in original_items if item not in to_delete])
|
||||
|
||||
@@ -2,7 +2,7 @@ from collections import namedtuple
|
||||
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
hist = namedtuple("History", "text status") # tests purposes only
|
||||
hist = namedtuple("HistoryTest", "text status") # tests purposes only
|
||||
|
||||
|
||||
class History:
|
||||
@@ -38,34 +38,23 @@ class History:
|
||||
if self._status:
|
||||
return self._status
|
||||
|
||||
if not self.result or "return_values" not in self.result.values:
|
||||
return
|
||||
|
||||
if hasattr(self.result.values["return_values"], "__iter__"):
|
||||
if len(self.result.values["return_values"]) != 1:
|
||||
self._status = False
|
||||
return self._status
|
||||
else:
|
||||
self._status = self.result.values["return_values"][0].status
|
||||
return self._status
|
||||
else:
|
||||
self._status = self.result.values["return_values"].status
|
||||
return self._status
|
||||
self._status = self.result.get_status() if self.result else None
|
||||
return self._status
|
||||
|
||||
|
||||
class SheerkaHistoryManager:
|
||||
def __init__(self, sheerka):
|
||||
self.sheerka = sheerka
|
||||
|
||||
def history(self, depth_or_digest, start):
|
||||
def history(self, depth, start):
|
||||
"""
|
||||
Load history
|
||||
:param depth_or_digest: number of items or digest
|
||||
:param depth: number of items
|
||||
:param start:
|
||||
:return:
|
||||
"""
|
||||
|
||||
events = list(self.sheerka.sdp.load_events(depth_or_digest, start))
|
||||
events = list(self.sheerka.sdp.load_events(depth, start))
|
||||
for event in events:
|
||||
try:
|
||||
result = self.sheerka.sdp.load_result(event.get_digest())
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
from sdp.sheerkaSerializer import Serializer
|
||||
|
||||
|
||||
@dataclass
|
||||
class Variable:
|
||||
"""
|
||||
Variable to store
|
||||
"""
|
||||
event_id: str # event where the variable is modified
|
||||
who: str # who is the modifier
|
||||
key: str # key of the variable
|
||||
value: object # value
|
||||
parents: List[str] # previous references of the variable (Note that there should be only one parent)
|
||||
|
||||
def get_key(self):
|
||||
return f"{self.who}.{self.key}"
|
||||
|
||||
|
||||
class SheerkaVariableManager:
|
||||
VARIABLES_ENTRY = "All_Variables" # to store all the concepts
|
||||
|
||||
def __init__(self, sheerka):
|
||||
self.sheerka = sheerka
|
||||
|
||||
def record(self, context, who, key, value):
|
||||
"""Persist a variable"""
|
||||
# first check if there is a previous version of the variable
|
||||
try:
|
||||
old = self.sheerka.sdp.get(self.VARIABLES_ENTRY, who + "." + key)
|
||||
if old.value == value:
|
||||
return
|
||||
|
||||
parent = getattr(old, Serializer.ORIGIN)
|
||||
except IndexError:
|
||||
parent = None
|
||||
|
||||
variable = Variable(context.event.get_digest(), who, key, value, [parent] if parent else None)
|
||||
self.sheerka.sdp.set(context.event.get_digest(), self.VARIABLES_ENTRY, variable, use_ref=True)
|
||||
|
||||
def load(self, who, key):
|
||||
variable = self.sheerka.sdp.get_safe(self.VARIABLES_ENTRY, who + "." + key)
|
||||
if variable is None:
|
||||
return None
|
||||
|
||||
return variable.value
|
||||
|
||||
def delete(self, context, who, key):
|
||||
self.sheerka.sdp.remove(
|
||||
context.event.get_digest(),
|
||||
self.VARIABLES_ENTRY,
|
||||
lambda _key, _var: _key == who + "." + key)
|
||||
@@ -1,3 +1,7 @@
|
||||
import logging
|
||||
|
||||
import core.builtin_helpers
|
||||
import core.utils
|
||||
from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConcept, BuiltinErrors, BuiltinUnique, \
|
||||
UnknownConcept
|
||||
from core.concept import Concept, ConceptParts, PROPERTIES_FOR_NEW
|
||||
@@ -9,13 +13,10 @@ from core.sheerka.Services.SheerkaExecute import SheerkaExecute
|
||||
from core.sheerka.Services.SheerkaHistoryManager import SheerkaHistoryManager
|
||||
from core.sheerka.Services.SheerkaModifyConcept import SheerkaModifyConcept
|
||||
from core.sheerka.Services.SheerkaSetsManager import SheerkaSetsManager
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||
import core.utils
|
||||
import core.builtin_helpers
|
||||
|
||||
from core.sheerka.Services.SheerkaVariableManager import SheerkaVariableManager
|
||||
from core.sheerka_logger import console_handler
|
||||
|
||||
import logging
|
||||
from printer.SheerkaPrinter import SheerkaPrinter
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||
|
||||
CONCEPT_LEXER_PARSER_CLASS = "parsers.BnfNodeParser.BnfNodeParser"
|
||||
BNF_PARSER_CLASS = "parsers.BnfParser.BnfParser"
|
||||
@@ -93,6 +94,8 @@ class Sheerka(Concept):
|
||||
self.sets_handler = SheerkaSetsManager(self)
|
||||
self.evaluate_concept_handler = SheerkaEvaluateConcept(self)
|
||||
self.history_handler = SheerkaHistoryManager(self)
|
||||
self.printer_handler = SheerkaPrinter(self)
|
||||
self.variable_handler = SheerkaVariableManager(self)
|
||||
|
||||
self.during_restore = False
|
||||
self._builtins_classes_cache = None
|
||||
@@ -127,7 +130,7 @@ class Sheerka(Concept):
|
||||
|
||||
exec_context.add_values(return_values=res)
|
||||
if not self.skip_builtins_in_db:
|
||||
self.sdp.save_result(exec_context)
|
||||
self.sdp.save_result(exec_context, is_admin=True)
|
||||
self.init_log.debug(f"Sheerka successfully initialized")
|
||||
|
||||
except IOError as e:
|
||||
@@ -299,9 +302,26 @@ class Sheerka(Concept):
|
||||
# if len(ret) == 1 and ret[0].status and self.isinstance(ret[0].value, BuiltinConcepts.NEW_CONCEPT):
|
||||
# with open(CONCEPTS_FILE, "a") as f:
|
||||
# f.write(text + "\n")
|
||||
|
||||
return ret
|
||||
|
||||
def print(self, result, instructions=None):
|
||||
"""
|
||||
Print the result to output
|
||||
:param result:
|
||||
:param instructions:
|
||||
:return:
|
||||
"""
|
||||
self.printer_handler.print(result, instructions)
|
||||
|
||||
def record(self, context, who, key, value):
|
||||
return self.variable_handler.record(context, who, key, value)
|
||||
|
||||
def load(self, who, key):
|
||||
return self.variable_handler.load(who, key)
|
||||
|
||||
def delete(self, context, who, key):
|
||||
return self.variable_handler.delete(context, who, key)
|
||||
|
||||
def execute(self, execution_context, return_values, execution_steps):
|
||||
"""
|
||||
Executes process for all initial contexts
|
||||
@@ -639,12 +659,27 @@ class Sheerka(Concept):
|
||||
|
||||
return self.value(body_to_use)
|
||||
|
||||
def value_by_concept(self, obj, concept):
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, Concept):
|
||||
return None
|
||||
|
||||
if isinstance(concept, tuple) and obj.key in [str(key) for key in concept]:
|
||||
return obj
|
||||
|
||||
if obj.key == str(concept):
|
||||
return obj
|
||||
|
||||
return self.value_by_concept(obj.body, concept)
|
||||
|
||||
def get_error(self, obj):
|
||||
if isinstance(obj, Concept) and obj.metadata.is_builtin and obj.key in BuiltinErrors:
|
||||
return obj
|
||||
|
||||
if isinstance(obj, list):
|
||||
return obj
|
||||
return obj
|
||||
|
||||
if self.isinstance(obj, BuiltinConcepts.RETURN_VALUE):
|
||||
if obj.status:
|
||||
|
||||
Reference in New Issue
Block a user