def what(self, G: InferenceGraph, alist: Alist, is_reduced: bool, in_place=True): ''' Explain a reduction of this alist. ''' what = '' how = '' time = "" if alist.get(tt.TIME): time = f" in {alist.get(tt.TIME)}" if not is_reduced: if alist.get(tt.OP) in ['eq', 'gt', 'gte', 'lt', 'lte']: what = f"Failed to compare the values since the values of all items being compare are not known. " elif alist.get(tt.OP) in ['comp']: what = f"Failed to solve the sub-problem. " elif alist.get(tt.OP) in ['value', 'values']: what = f"Failed to determine the {self.ops_text[alist.get(tt.OP)]} of {alist.get(tt.PROPERTY)}{time}." else: what = f"Failed to calculate the {self.ops_text[alist.get(tt.OP)]} of {alist.get(tt.PROPERTY)}{time}." else: if alist.get(tt.OP) in ['eq', 'gt', 'gte', 'lt', 'lte']: vars_compared = alist.get(tt.OPVAR).split(' ') if len(vars_compared) > 1: what = f"Inferred value is '{alist.instantiation_value('?'+ alist.get(tt.OP))}'." how = f"Did a comparison to determine if {alist.instantiation_value(vars_compared[0])} is " + \ f"{self.ops_text[alist.get(tt.OP)]} {alist.instantiation_value(vars_compared[1])}." elif alist.get(tt.OP) in ['comp']: listed_str = '' listed = alist.instantiation_value(alist.get(tt.OPVAR)) if listed: listed = listed.split(',') if len(listed) > 8: listed_str += f"{', '.join(listed[0:8])}, etc" else: listed_str += ', '.join(listed) if listed_str: what = f"Solved the sub-query and found the following values: {listed_str}." else: inferred_value = '' projected = alist.projection_variables() if projected: inferred_value = list(projected.values())[0] if not inferred_value: inferred_value = alist.instantiation_value( alist.get(tt.OPVAR)) if inferred_value: if ':' in alist.get(tt.PROPERTY): listed_str = '' listed = alist.instantiation_value(alist.get( tt.OPVAR)).split(',') if len(listed) > 8: listed_str += f"{', '.join(listed[0:8])}, etc" else: listed_str += ', '.join(listed) what = f"The {alist.get(tt.PROPERTY).split(':')[1]} values found for the sub-query include: {listed_str}." elif (projected or inferred_value) and not alist.get(tt.PROPERTY): # for alists with just a projected value but no property what = f"An input value for operation is {inferred_value}." elif projected and alist.get( tt.OPVAR) not in projected and alist.get( tt.OP) in ['max', 'min']: what = f"The entity whose {alist.get(tt.PROPERTY)}{time} has the {self.ops_text[alist.get(tt.OP)]} of {alist.instantiation_value(alist.get(tt.OPVAR))} is {inferred_value}." elif projected and alist.get( tt.OPVAR) not in projected and alist.get( tt.OP) not in ['max', 'min']: what = f"The {self.ops_text[alist.get(tt.OP)]} of the {alist.get(tt.PROPERTY)}{time} of {inferred_value} is {alist.instantiation_value(alist.get(tt.OPVAR))}." else: what = f"The {self.ops_text[alist.get(tt.OP)]} of the {alist.get(tt.PROPERTY)} of {alist.instantiation_value(tt.SUBJECT)}{time} is {inferred_value}." if alist.get(tt.OP) in [ 'regress', 'nnpredict', 'linregress', 'gpregress', 'nnregress' ]: decomp_items = [] children = G.child_alists(alist.id) # for c in alist.children[0].children: for c in G.child_alists(children[0].id): decomp_items.append(c.get(tt.TIME)) if len(decomp_items) > 0: how = f"Generated a regression function from times between {min(decomp_items)} and {max(decomp_items)}." if in_place: alist.set("what", what) alist.set("how", how) G.add_alist(alist)
def run_frank(self, alist: Alist): """ Run the FRANK algorithm for an alist Args ---- alist : Alist Return ------ Return True if the instantiation of the project variable of an alist is propagated to the root node. Notes ----- For the given alist, attempt to instantiate projection variable. If instantiation is successful, attempt to reduce Else decompose and add new children to queue """ self.last_heartbeat = time.time() curr_propagated_alists = [] self.max_depth = alist.depth if alist.state is states.PRUNED: self.write_trace( f"{pcol.RED}ignore pruned {alist.id}{pcol.RESET}-{alist}{pcol.RESETALL}" ) return propagated_alists bool_result = False proj_vars = alist.projection_variables() proj_instantiated = True if proj_vars: for p, _ in proj_vars.items(): proj_instantiated = proj_instantiated and alist.is_instantiated( p) agg_vars = alist.get(tt.OPVAR).split(' ') agg_instantiated = True if agg_vars: for v in agg_vars: agg_instantiated = agg_instantiated and alist.is_instantiated( v) if agg_instantiated: bool_result = True if bool_result: alist.state = states.REDUCIBLE self.G.add_alist(alist) # if OPVAR not instantiated, search KB elif not bool_result: bool_result = self.search_kb(alist) # search kb for the variable instantiation if bool_result: is_propagated = False if alist.state != states.REDUCIBLE: # if in reducible state, don't change alist.state = states.EXPLORED self.G.add_alist(alist) if agg_instantiated and proj_instantiated: alist.state = states.REDUCIBLE self.G.add_alist(alist) if self.G.child_ids(alist.id): is_propagated = self.propagate(self.G.child_ids(alist.id)[0]) else: is_propagated = self.propagate( self.G.child_ids(self.G.parent_ids(alist.id)[0])[0]) if is_propagated: prop_alist = self.G.alist(self.root.id) self.write_trace( f"{pcol.CYAN}intermediate ans: " f"{pcol.RESET}-{prop_alist}{pcol.RESETALL}", loglevel=processLog.LogLevel.ANSWER) curr_propagated_alists.append(prop_alist.copy()) self.propagated_alists.append(prop_alist.copy()) else: alist.state = states.EXPLORED self.G.add_alist(alist) for mapOp in self.get_map_strategy(alist): self.decompose(alist, mapOp) return curr_propagated_alists