Added first version of DebugManager. Implemented draft of the rule engine
This commit is contained in:
@@ -1,17 +1,26 @@
|
||||
import logging
|
||||
import os
|
||||
import pprint
|
||||
import time
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts, ParserResultConcept
|
||||
from core.concept import Concept
|
||||
from core.concept import Concept, get_concept_attrs
|
||||
from core.global_symbols import CONTEXT_DISPOSED
|
||||
from core.sheerka.services.SheerkaExecute import NO_MATCH
|
||||
from core.sheerka.services.SheerkaMemory import SheerkaMemory
|
||||
from core.sheerka_logger import get_logger
|
||||
from core.utils import CONSOLE_COLORS_MAP as CCM
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
try:
|
||||
rows, columns = os.popen('stty size', 'r').read().split()
|
||||
except ValueError:
|
||||
rows, columns = 50, 80
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=2, width=columns)
|
||||
|
||||
DEBUG_TAB_SIZE = 4
|
||||
|
||||
PROPERTIES_TO_SERIALIZE = ("_id",
|
||||
"_bag",
|
||||
"_children",
|
||||
"_start",
|
||||
"_stop",
|
||||
@@ -50,19 +59,17 @@ class ExecutionContext:
|
||||
logger=None,
|
||||
global_hints=None,
|
||||
errors=None,
|
||||
**kwargs):
|
||||
obj=None,
|
||||
concepts=None):
|
||||
|
||||
self._id = ExecutionContext.get_id(event.get_digest()) if event else None
|
||||
self._parent = None
|
||||
self._children = []
|
||||
self._tab = ""
|
||||
self._bag = {} # context variables
|
||||
self._start = 0 # when the execution starts (to measure elapsed time)
|
||||
self._stop = 0 # when the execution stops (to measure elapses time)
|
||||
self._logger = logger
|
||||
self._format_instructions = None # how to print the execution context
|
||||
self._stat_log = get_logger("stats")
|
||||
self._show_stats = False
|
||||
self._push = None
|
||||
|
||||
self.who = who # who is asking
|
||||
self.event = event # what was the (original) trigger
|
||||
@@ -70,6 +77,8 @@ class ExecutionContext:
|
||||
self.action = action
|
||||
self.action_context = action_context
|
||||
self.desc = desc # human description of what is going on
|
||||
self.preprocess_parsers = None
|
||||
self.preprocess_evaluators = None
|
||||
self.preprocess = None
|
||||
self.stm = False # True if the context has short term memory entries
|
||||
|
||||
@@ -80,13 +89,11 @@ class ExecutionContext:
|
||||
|
||||
self.inputs = {} # what were the parameters of the execution context
|
||||
self.values = {} # what was produced by the execution context
|
||||
self.obj = kwargs.pop("obj", None) # current obj we are working on
|
||||
self.obj = obj
|
||||
self.concepts = concepts
|
||||
|
||||
self.concepts = kwargs.pop("concepts", {}) # known concepts specific to this context
|
||||
|
||||
# update the other elements
|
||||
for k, v in kwargs.items():
|
||||
self._bag[k] = v
|
||||
self_debug, self.debug_mode = sheerka.get_context_debug_mode(self.id)
|
||||
self.debug_enabled = self_debug is not None
|
||||
|
||||
@property
|
||||
def elapsed(self):
|
||||
@@ -117,24 +124,19 @@ class ExecutionContext:
|
||||
"""
|
||||
return self._children
|
||||
|
||||
def __getattr__(self, item):
|
||||
if item in self._bag:
|
||||
return self._bag[item]
|
||||
|
||||
raise AttributeError(f"'ExecutionContext' object has no attribute '{item}'")
|
||||
|
||||
def __enter__(self):
|
||||
self._start = time.time_ns()
|
||||
self.log_new()
|
||||
# self.log_new()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self._push:
|
||||
return
|
||||
|
||||
if self.stm:
|
||||
self.sheerka.services[SheerkaMemory.NAME].remove_context(self)
|
||||
self.sheerka.publish(self, CONTEXT_DISPOSED)
|
||||
|
||||
self._stop = time.time_ns()
|
||||
if self._show_stats:
|
||||
self._stat_log.debug(f"[{self._id:2}]" + self._tab + "Execution time: " + self.elapsed_str)
|
||||
|
||||
def __repr__(self):
|
||||
msg = f"ExecutionContext(who={self.who}, id={self._id}, action={self.action}, context={self.action_context}"
|
||||
@@ -143,11 +145,6 @@ class ExecutionContext:
|
||||
msg += ")"
|
||||
return msg
|
||||
|
||||
# def __str__(self):
|
||||
# msg = self.desc or "New Context"
|
||||
# msg += f", who={self.who}, id={self.id}"
|
||||
# return msg
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
@@ -168,12 +165,12 @@ class ExecutionContext:
|
||||
|
||||
return True
|
||||
|
||||
def push(self, action: BuiltinConcepts, action_context, who=None, desc=None, logger=None, **kwargs):
|
||||
def push(self, action: BuiltinConcepts, action_context, who=None, desc=None, logger=None, obj=None, concepts=None):
|
||||
if self._push:
|
||||
return self._push
|
||||
|
||||
who = who or self.who
|
||||
logger = logger or self._logger
|
||||
_kwargs = {"obj": self.obj, "concepts": self.concepts}
|
||||
_kwargs.update(self._bag)
|
||||
_kwargs.update(kwargs)
|
||||
new = ExecutionContext(
|
||||
who,
|
||||
self.event,
|
||||
@@ -184,19 +181,40 @@ class ExecutionContext:
|
||||
logger,
|
||||
self.global_hints,
|
||||
self.errors,
|
||||
**_kwargs)
|
||||
obj or self.obj,
|
||||
concepts or self.concepts)
|
||||
new._parent = self
|
||||
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
||||
new.preprocess = self.preprocess
|
||||
new.preprocess_parsers = self.preprocess_parsers
|
||||
new.preprocess_evaluators = self.preprocess_evaluators
|
||||
new.protected_hints.update(self.protected_hints)
|
||||
|
||||
if new.debug_mode is None and self.debug_mode == "protected":
|
||||
new.debug_mode = "protected"
|
||||
new.debug_enabled = True
|
||||
|
||||
self._children.append(new)
|
||||
|
||||
return new
|
||||
|
||||
def deactivate_push(self):
|
||||
self._push = self.push(BuiltinConcepts.NOP, None)
|
||||
self._push._push = self._push
|
||||
if self.stm:
|
||||
bag = self.sheerka.services[SheerkaMemory.NAME].get_all_short_term_memory(self)
|
||||
self.sheerka.add_many_to_short_term_memory(self._push, bag)
|
||||
|
||||
def activate_push(self):
|
||||
if self._push:
|
||||
if self._push.stm:
|
||||
self.sheerka.publish(self._push, CONTEXT_DISPOSED)
|
||||
self._push._stop = time.time_ns()
|
||||
|
||||
self._push = None
|
||||
|
||||
def add_preprocess(self, name, **kwargs):
|
||||
preprocess = self.sheerka.new(BuiltinConcepts.EVALUATOR_PRE_PROCESS)
|
||||
preprocess.set_value("name", name)
|
||||
preprocess.set_value("preprocess_name", name)
|
||||
for k, v in kwargs.items():
|
||||
preprocess.set_value(k, v)
|
||||
|
||||
@@ -206,13 +224,17 @@ class ExecutionContext:
|
||||
return self
|
||||
|
||||
def add_inputs(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
self.inputs[k] = v
|
||||
if self._push:
|
||||
return
|
||||
|
||||
self.inputs.update(kwargs)
|
||||
return self
|
||||
|
||||
def add_values(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
self.values[k] = v
|
||||
if self._push:
|
||||
return
|
||||
|
||||
self.values.update(kwargs)
|
||||
return self
|
||||
|
||||
def add_to_short_term_memory(self, key, concept):
|
||||
@@ -224,6 +246,9 @@ class ExecutionContext:
|
||||
"""
|
||||
self.sheerka.add_to_short_term_memory(self, key, concept)
|
||||
|
||||
def clear_short_term_memory(self):
|
||||
self.sheerka.clear_short_term_memory(self)
|
||||
|
||||
def get_from_short_term_memory(self, key):
|
||||
"""
|
||||
|
||||
@@ -237,11 +262,10 @@ class ExecutionContext:
|
||||
if isinstance(self.obj, Concept):
|
||||
if self.obj.key == key:
|
||||
return self.obj
|
||||
for var_name in self.obj.values:
|
||||
if var_name == key:
|
||||
value = self.obj.get_value(var_name)
|
||||
if isinstance(value, Concept):
|
||||
return value
|
||||
if key in get_concept_attrs(self.obj):
|
||||
value = self.obj.get_value(key)
|
||||
if isinstance(value, Concept):
|
||||
return value
|
||||
|
||||
# search in concepts
|
||||
if self.concepts:
|
||||
@@ -296,8 +320,34 @@ class ExecutionContext:
|
||||
to_str = self.return_value_to_str(r)
|
||||
self._logger.debug(f"[{self._id:2}]" + self._tab + "-> " + to_str)
|
||||
|
||||
def debug(self, text):
|
||||
print(text)
|
||||
def get_debugger(self, who, method_name):
|
||||
return self.sheerka.get_debugger(self, who, method_name)
|
||||
|
||||
def debug(self, who, method_name, variable_name, text, is_error=False):
|
||||
activated = self.sheerka.debug_activated_for(who)
|
||||
if activated:
|
||||
str_text = pp.pformat(text)
|
||||
color = 'red' if is_error else 'green'
|
||||
if "\n" not in str(str_text):
|
||||
self.sheerka.debug(
|
||||
f"[{self._id:3}] {CCM[color]}{who}.{method_name}.{variable_name}: {CCM['reset']}{str_text}")
|
||||
else:
|
||||
self.sheerka.debug(f"[{self._id:3}] {CCM[color]}{who}.{method_name}.{variable_name}: {CCM['reset']}")
|
||||
self.sheerka.debug(str_text)
|
||||
|
||||
def debug_entering(self, who, method_name, **kwargs):
|
||||
if self.sheerka.debug_activated_for(who):
|
||||
str_text = pp.pformat(kwargs)
|
||||
if "\n" not in str(str_text):
|
||||
self.sheerka.debug(
|
||||
f"[{self._id:3}] {CCM['blue']}Entering {who}.{method_name} with {CCM['reset']}{str_text}")
|
||||
else:
|
||||
self.sheerka.debug(f"[{self._id:3}] {CCM['blue']}Entering {who}.{method_name}:{CCM['reset']}")
|
||||
self.sheerka.debug(f"[{self._id:3}] {str_text}")
|
||||
|
||||
def debug_log(self, who, text):
|
||||
if self.sheerka.debug_activated_for(who):
|
||||
self.sheerka.debug(f"[{self._id:3}] {CCM['blue']}{text}{CCM['reset']}")
|
||||
|
||||
def get_parent(self):
|
||||
return self._parent
|
||||
@@ -384,9 +434,6 @@ class ExecutionContext:
|
||||
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", "action", "desc", "obj", "inputs", "values", "concepts"):
|
||||
bag[prop] = getattr(self, prop)
|
||||
bag["context"] = self.action_context
|
||||
@@ -396,6 +443,7 @@ class ExecutionContext:
|
||||
bag["elapsed"] = self.elapsed
|
||||
bag["elapsed_str"] = self.elapsed_str
|
||||
bag["digest"] = self.event.get_digest() if self.event else None
|
||||
bag["_children"] = self._children
|
||||
return bag
|
||||
|
||||
@staticmethod
|
||||
@@ -438,3 +486,17 @@ class ExecutionContext:
|
||||
break
|
||||
|
||||
current = current._parent
|
||||
|
||||
def has_parent(self, context_id):
|
||||
current = self
|
||||
|
||||
while current._parent:
|
||||
current = current._parent
|
||||
if current.id == context_id:
|
||||
return True
|
||||
if current.id < context_id:
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user