def __recollect(self, itoms): itoms = Itoms(itoms) recollected = False if self.__substitutions is None \ or set(itoms.keys()) != set(self.__itoms.keys()): self.__substitutions = self.__collect_substitutions(itoms) recollected = True return recollected
itoms = Itoms() try: for head in data.columns.values: head = head.strip().split(':') v = head[0] i = head[1] # empty value and timestamp for this itom describing the header only itom = Itom(i, None, variable=v, timestamp=None) itoms[itom.name] = itom except Exception as e: raise SystemExit( "Failed to parse column name 'variable:itom'. {}".format(e)) # problog knows the mapping now, so we can change the column names to itoms only # substitution only needs itom names data.columns = itoms.keys() # append available itoms to program with "itomsOf(variable,[itom1,..])" program = "\n" for variable, il in itoms.availability.items(): names = [itom.name for itom in il] program += "itomsOf({},[{}]).\n".format(variable, ','.join(names)) pli.append(program) print("Program:\n{}".format(pli.program)) # # monitor with Prolog model # # variable to monitor
class BaseMonitor(object): """Base class for monitors.""" def __init__(self, model, domain, itoms=[], librarypaths=["./model/"], recollect=True): """Initialize the monitor. model -- SHSA knowledge base collecting the relations between variables. domain -- Common domain (a variable in the knowledge base) where the itoms will be compared to each other. itoms -- Itoms-object holding inputs to the monitor. librarypaths -- Set paths of problog libraries used in model. filter_window_size -- Set the size of the window for the median filter. """ self.__pli = ProblogInterface(librarypaths=librarypaths) self.__pli.load(model) """SHSA knowledge base.""" self.__domain = domain """Variable domain where the itoms shall be compared.""" self.__recollect_enabled = recollect """Indicates that a change in the itoms should trigger a re-query of the substitutions.""" self.__itoms = Itoms(itoms) """Available itoms or last itoms monitored. Used to identify a change in the itoms.""" self.__substitutions = None """List of substitutions used to bring the itoms into the common domain.""" # workaround: for ROS monitor (subscribe based on model) try: self.__substitutions = self.__collect_substitutions(itoms) # workaround: triggers reset on first monitor (necessary to fully initialize) self.__itoms = Itoms(itoms) except problog.engine.UnknownClause as e: # no itomsOf in the problog model (needed to find substitutions) # we will try later (monitor) pass # debugging self._debug_callback = None """Called at the end of monitor(.) to debug the monitor step.""" @property def model(self): """Returns the underlying SHSA model.""" return self.__pli.program @property def domain(self): """Returns the monitoring domain.""" return self.__domain @property def substitutions(self): """Returns the list of substitutions used to bring the itoms into the common domain.""" return self.__substitutions def update(self, model, domain): """Resets the model and the domain, i.e., variable to monitor.""" self.__domain = domain self.__pli.reset() self.__pli.load(model) def set_debug_callback(self, fct): self._debug_callback = fct return def __collect_substitutions(self, itoms=[]): """Find relations from variables (given itoms) to domain.""" program = "\n" if "itomsOf" not in self.__pli.program and len(itoms) > 0: # be sure itoms is of the right type 'Itoms' itoms = Itoms(itoms) # append available itoms to program with "itomsOf(variable,[itom1,..])" for variable, il in itoms.availability.items(): assert variable is not None and variable != "" names = [i.name for i in il] program += "itomsOf({},[{}]).\n".format(variable, ','.join(names)) program += "\n" if len(itoms) > 0: assert "itomsOf" in program or "itomsOf" in self.__pli.program # get all valid substitutions for the domain # -> query problog knowledge base program += "query(substitution({},S)).".format(self.__domain) result = self.__pli.evaluate(program) S = [] for r in result.keys(): s = self.__pli.parse_substitution(str(r)) S.append(s) if len(itoms) == 0: # set itoms used (default value) for s in S: for v in s.vin: self.__itoms[v.name] = Itom(v.name, 0.0, variable=v.name) return S def __recollect(self, itoms): itoms = Itoms(itoms) recollected = False if self.__substitutions is None \ or set(itoms.keys()) != set(self.__itoms.keys()): self.__substitutions = self.__collect_substitutions(itoms) recollected = True return recollected def _monitor(self, itoms, reset=False): raise NotImplementedError def monitor(self, itoms): reset = False if self.__recollect_enabled: # recollect substitutions if itoms changed reset = self.__recollect(itoms) self.__itoms = itoms # save to identify changes in the next monitor step # monitor implemented in sub class failed = self._monitor(itoms, reset) # done return failed