def joinhelper(self, leftMemory, rightMemory, sharedVars, matchedValues, results, switched=False): #all shared variable values matched if sharedVars: bindings = dict() #do this until we run out of shared variables to compare for lmk in leftMemory: #print "lmk:", lmk if lmk in rightMemory: #match on shared variable, continue to next level #leftMemory and rightMemory are nested dictionaries self.joinhelper(leftMemory[lmk], rightMemory[lmk], sharedVars[1:], matchedValues + [lmk], results, switched) elif matchedValues: if leftMemory: for lm, ljust in keysToList(leftMemory): #Both memories are nonempty if rightMemory: for rm, rjust in keysToList(rightMemory): """if switched: row = matchedValues + rm + lm else:""" row = matchedValues + lm + rm results.append([row, []]) self.add(row, []) else: #Left memory is nonempty, right is empty row = matchedValues + lm results.append([row, []]) self.add(row, []) elif rightMemory: for rm, rjust in keysToList(rightMemory): #Left memory is empty, right is nonempty row = matchedValues + rm results.append([row, []]) self.add(row, []) return results
def getRows(self): """I return the rows of the BetaNode, one row at a time.""" rows = keysToList(self.betaNode.ind) for r in rows: yield r
def join(self, useBindings=False): """ print "\n\n" print "self key:", self.getkey() print "join left:", self.lnode.pattern #for row in keysToList(self.lnode.ind): # print "left row",row[0] print "memory size of left node:", len(keysToList(self.lnode.ind)) print "left key:", self.lnode.getkey() print "" print "join right:", self.rnode.pattern # for row in keysToList(self.rnode.ind): # print "right row",row[0] print "memory size of right node:", len(keysToList(self.rnode.ind)) print "right key:", self.rnode.getkey() switched = False t = time.time() if len(keysToList(self.rnode.ind)) < len(keysToList(self.lnode.ind)): print "switched" switched = True print "keysToList time:", time.time() - t """ from builtins import builtinp if self.lnode == self.rnode: from builtins import builtinp, funcBuiltinp if builtinp(self.lnode): self.builtinInput = self.lnode.getInputNode() #problem is, here builtin input is empty return self.evalBuiltins(returnBindings=useBindings) else: self.pattern = self.lnode.vars if self.lnode.ind: return keysToList(self.lnode.ind) else: return [] elif self.hasBuiltins(): return self.evalBuiltins(returnBindings=useBindings) else: #right node is always an alpha node, #left one is an alphanode in the first join, beta node aftewards #compare the memory of both nodes, we want the smaller one to the left # if isListVarNode(self.rnode): rows = keysToList(self.lnode.ind) for row in rows: row = row[0] #print "rows:", row #print "left node key:", self.lnode.getkey() #left node key does not correspond to the bindings #bindings = self.lnode.getbindings(row) #get the bindings according to its own key, above line didnt work bindings = dict() key = self.getkey() try: for i, v in enumerate(key): bindings[v] = row[i] except: print "bindings=%s" % bindings print "row=%s" % row print "v=%s" % v print "i=%s" % i raise #copy the values for the variable in pattern.o if self.rnode.pattern.o in bindings: #copy it back to the original node - easiest way is to add it as a fact #also add bindings for the bnodes in subj for var in self.rnode.vars: if isinstance(var, Exivar): self.rnode.add( Fact(convertBNodeToFact(var), self.rnode.pattern.p, bindings[self.rnode.pattern.o])) #print "fact added:",convertBNodeToFact(var), self.rnode.pattern.p, bindings[self.rnode.pattern.o] elif isinstance(self.rnode.pattern.s, Exivar): print "something wrong happened - %s was supposed to be bound", self.rnode.pattern.s if isinstance(self.lnode, AlphaNode): key = self.lnode.svars elif isinstance(self.lnode, BetaNode): if not Set(self.lnode.vars).intersection(Set(self.rnode.vars)): key = list() else: #regenerate key here? was using self.svars before but was buggy key = self.getSharedVars(self.lnode, self.rnode) joinResults = list() if not key: #no shared variables and no matched values, so store and return the union #of the two memories """if switched: leftMemory = keysToList(self.rnode.ind) rightMemory = keysToList(self.lnode.ind) else:""" leftMemory = keysToList(self.lnode.ind) rightMemory = keysToList(self.rnode.ind) for lm, ljust in leftMemory: for rm, rjust in rightMemory: """if switched: row = rm + lm else:""" row = lm + rm joinResults.append([row, []]) ####NOTE -- Need to add justification (proof tracing) for this case self.add(row, []) else: t = time.time() """if switched: joinResults = self.joinhelper(self.rnode.ind, self.lnode.ind, key, [], [], switched) else:""" joinResults = self.joinhelper(self.lnode.ind, self.rnode.ind, key, [], []) print "joinhelper time:", time.time() - t return joinResults
def evalBuiltins(self, returnBindings=False): t = time.time() """I evaluate my attached builtins nodes.""" from builtins import builtinp, funcBuiltinp #Three cases to handle: left is a builtin and right is a plain anode, #left is a plain anode and right is a builtin, or both the left #and right are builtins evaldRows = list() builtinNodes = list() if builtinp(self.lnode): builtinNodes.append(self.lnode) if builtinp(self.rnode): builtinNodes.append(self.rnode) for bi in builtinNodes: inputNode = bi.getInputNode() builtinInput = keysToList(inputNode.ind) for row in builtinInput: row = row[0] #Needed since row[1] is the justification set #print row #print bi.pattern bindings = inputNode.getbindings(row, useBuiltin=bi) #need to check and substitute bi.pattern.s and bi.pattern.o for possible bindings here #check and substitute if subj or obj are lists, they also might have variables in the lists subjInput = convertBNodeToFact(bi.pattern.s) objInput = convertBNodeToFact(bi.pattern.o) if isinstance(bi.pattern.s, Variable): if bi.pattern.s in bindings: subjInput = convertBNodeToFact(bindings[bi.pattern.s]) if isinstance(bi.pattern.o, Variable): if bi.pattern.o in bindings: objInput = convertBNodeToFact(bindings[bi.pattern.o]) if subjInput in py_lists: subjInput = [ self.bindPossibleVar(x, bindings) for x in py_lists[subjInput] ] if objInput in py_lists: objInput = [ self.bindPossibleVar(x, bindings) for x in py_lists[objInput] ] # print "builtin", bi, subjInput, objInput result = bi.evaluate(subjInput, objInput) if result: #hack: append the bindings if it's log:includes if bi.pattern.p == INCLUDES: bindings[bi.pattern.s] = subjInput bindings[bi.pattern.o] = objInput row.append(subjInput) row.append(objInput) #a bit inefficient if returnBindings: evaldRows.append(bindings) else: evaldRows.append([row, []]) #Empty justification for now #add to memory -- ##NOTE: Need to add justification (proof tracing) for data resulting ##from builtins #print "row after bindings", row #if it's a functional builtin, it's different - need to return result and store in memory if funcBuiltinp(self.lnode) or funcBuiltinp(self.rnode): #have no idea why it works row.append(result) #print "row added in evalbuiltins:", row #add this fact self.add(row) #print "___row:", row else: #print "___row:", row self.add(row) #print "evaldRows:", evaldRows print "evalBultins time:", time.time() - t return evaldRows
def join(self, useBindings=False): """ print "\n\n" print "self key:", self.getkey() print "join left:", self.lnode.pattern #for row in keysToList(self.lnode.ind): # print "left row",row[0] print "memory size of left node:", len(keysToList(self.lnode.ind)) print "left key:", self.lnode.getkey() print "" print "join right:", self.rnode.pattern # for row in keysToList(self.rnode.ind): # print "right row",row[0] print "memory size of right node:", len(keysToList(self.rnode.ind)) print "right key:", self.rnode.getkey() switched = False t = time.time() if len(keysToList(self.rnode.ind)) < len(keysToList(self.lnode.ind)): print "switched" switched = True print "keysToList time:", time.time() - t """ from builtins import builtinp if self.lnode == self.rnode: from builtins import builtinp, funcBuiltinp if builtinp(self.lnode): self.builtinInput = self.lnode.getInputNode() #problem is, here builtin input is empty return self.evalBuiltins(returnBindings=useBindings) else: self.pattern = self.lnode.vars if self.lnode.ind: return keysToList(self.lnode.ind) else: return [] elif self.hasBuiltins(): return self.evalBuiltins(returnBindings=useBindings) else: #right node is always an alpha node, #left one is an alphanode in the first join, beta node aftewards #compare the memory of both nodes, we want the smaller one to the left # if isListVarNode(self.rnode): rows = keysToList(self.lnode.ind) for row in rows: row = row[0] #print "rows:", row #print "left node key:", self.lnode.getkey() #left node key does not correspond to the bindings #bindings = self.lnode.getbindings(row) #get the bindings according to its own key, above line didnt work bindings = dict() key = self.getkey() try: for i, v in enumerate(key): bindings[v] = row[i] except: print "bindings=%s" % bindings print "row=%s" % row print "v=%s" % v print "i=%s" % i raise #copy the values for the variable in pattern.o if self.rnode.pattern.o in bindings: #copy it back to the original node - easiest way is to add it as a fact #also add bindings for the bnodes in subj for var in self.rnode.vars: if isinstance(var, Exivar): self.rnode.add(Fact(convertBNodeToFact(var), self.rnode.pattern.p, bindings[self.rnode.pattern.o])) #print "fact added:",convertBNodeToFact(var), self.rnode.pattern.p, bindings[self.rnode.pattern.o] elif isinstance(self.rnode.pattern.s, Exivar): print "something wrong happened - %s was supposed to be bound", self.rnode.pattern.s if isinstance(self.lnode, AlphaNode): key = self.lnode.svars elif isinstance(self.lnode, BetaNode): if not Set(self.lnode.vars).intersection(Set(self.rnode.vars)): key = list() else: #regenerate key here? was using self.svars before but was buggy key = self.getSharedVars(self.lnode, self.rnode) joinResults = list() if not key: #no shared variables and no matched values, so store and return the union #of the two memories """if switched: leftMemory = keysToList(self.rnode.ind) rightMemory = keysToList(self.lnode.ind) else:""" leftMemory = keysToList(self.lnode.ind) rightMemory = keysToList(self.rnode.ind) for lm, ljust in leftMemory: for rm, rjust in rightMemory: """if switched: row = rm + lm else:""" row = lm + rm joinResults.append([row, []]) ####NOTE -- Need to add justification (proof tracing) for this case self.add(row, []) else: t = time.time() """if switched: joinResults = self.joinhelper(self.rnode.ind, self.lnode.ind, key, [], [], switched) else:""" joinResults = self.joinhelper(self.lnode.ind, self.rnode.ind, key, [], []) print "joinhelper time:", time.time() - t return joinResults
def evalBuiltins(self, returnBindings=False): t = time.time() """I evaluate my attached builtins nodes.""" from builtins import builtinp, funcBuiltinp #Three cases to handle: left is a builtin and right is a plain anode, #left is a plain anode and right is a builtin, or both the left #and right are builtins evaldRows = list() builtinNodes = list() if builtinp(self.lnode): builtinNodes.append(self.lnode) if builtinp(self.rnode): builtinNodes.append(self.rnode) for bi in builtinNodes: inputNode = bi.getInputNode() builtinInput = keysToList(inputNode.ind) for row in builtinInput: row = row[0] #Needed since row[1] is the justification set #print row #print bi.pattern bindings = inputNode.getbindings(row, useBuiltin=bi) #need to check and substitute bi.pattern.s and bi.pattern.o for possible bindings here #check and substitute if subj or obj are lists, they also might have variables in the lists subjInput = convertBNodeToFact(bi.pattern.s) objInput = convertBNodeToFact(bi.pattern.o) if isinstance(bi.pattern.s, Variable): if bi.pattern.s in bindings: subjInput = convertBNodeToFact(bindings[bi.pattern.s]) if isinstance(bi.pattern.o, Variable): if bi.pattern.o in bindings: objInput = convertBNodeToFact(bindings[bi.pattern.o]) if subjInput in py_lists: subjInput = [self.bindPossibleVar(x, bindings) for x in py_lists[subjInput]] if objInput in py_lists: objInput = [self.bindPossibleVar(x, bindings) for x in py_lists[objInput]] # print "builtin", bi, subjInput, objInput result = bi.evaluate(subjInput, objInput) if result: #hack: append the bindings if it's log:includes if bi.pattern.p == INCLUDES: bindings[bi.pattern.s]= subjInput bindings[bi.pattern.o]= objInput row.append(subjInput) row.append(objInput) #a bit inefficient if returnBindings: evaldRows.append(bindings) else: evaldRows.append([row, []]) #Empty justification for now #add to memory -- ##NOTE: Need to add justification (proof tracing) for data resulting ##from builtins #print "row after bindings", row #if it's a functional builtin, it's different - need to return result and store in memory if funcBuiltinp(self.lnode) or funcBuiltinp(self.rnode): #have no idea why it works row.append(result) #print "row added in evalbuiltins:", row #add this fact self.add(row) #print "___row:", row else: #print "___row:", row self.add(row) #print "evaldRows:", evaldRows print "evalBultins time:", time.time() - t return evaldRows