def listToPython(self, id, alphaNodes, py_list): if not alphaNodes: return py_list node_first = [ node for node in alphaNodes if convertBNodeToFact(node.pattern.s) == id and node.pattern.p == FIRST ] #it's tricky here because the subj might be a variable if node_first: if isinstance(node_first[0].pattern.o, Exivar): return self.listToPython( convertBNodeToFact(node_first[0].pattern.o), alphaNodes, py_list) elif isinstance(node_first[0].pattern.o, Variable): py_list.append(node_first[0].pattern.o) # append variable node_rest = [ node for node in alphaNodes if convertBNodeToFact(node.pattern.s) == id and node.pattern.p == REST ] if node_rest: if node_rest[0].pattern.o == NIL: return py_list else: return self.listToPython( convertBNodeToFact(node_rest[0].pattern.o), alphaNodes, py_list) else: return py_list
def generateDependencies(self): from builtins import funcBuiltinp for a in self.nodes: if funcBuiltinp(a): #means that object is a variable, look for dependencies on that var. for x in self.nodes: if x != a and a.pattern.o in [x.pattern.s, x.pattern.o]: a.dependents.append(x) #rdf:rest should always be before rdf:first elif a.pattern.p == REST: for x in self.nodes: if x.pattern.p == FIRST and x.pattern.s == a.pattern.s: a.dependents.append(x) for a in self.nodes: if funcBuiltinp(a): # (?x ?a) math:sum z. we want to have x and a bound before evaluating math:sum. #so, look for the variables in the list, and see where they occur in the nodes set, then add dependencies #first, generate the variables from the list vars = self.listToPython(convertBNodeToFact(a.pattern.s), self.nodes, []) #now add dependencies for x in self.nodes: if x.pattern.p == FIRST and x.pattern.o in vars: x.dependents.append(a) """
def generateDependencies(self): from builtins import funcBuiltinp for a in self.nodes: if funcBuiltinp(a): #means that object is a variable, look for dependencies on that var. for x in self.nodes: if x != a and a.pattern.o in [x.pattern.s, x.pattern.o]: a.dependents.append(x) #rdf:rest should always be before rdf:first elif a.pattern.p == REST: for x in self.nodes: if x.pattern.p == FIRST and x.pattern.s == a.pattern.s: a.dependents.append(x) for a in self.nodes: if funcBuiltinp(a): # (?x ?a) math:sum z. we want to have x and a bound before evaluating math:sum. #so, look for the variables in the list, and see where they occur in the nodes set, then add dependencies #first, generate the variables from the list vars = self.listToPython(convertBNodeToFact(a.pattern.s), self.nodes, []) #now add dependencies for x in self.nodes: if x.pattern.p==FIRST and x.pattern.o in vars: x.dependents.append(a) """
def listToPython(self, id, alphaNodes, py_list): if not alphaNodes: return py_list node_first = [node for node in alphaNodes if convertBNodeToFact(node.pattern.s)==id and node.pattern.p==FIRST] #it's tricky here because the subj might be a variable if node_first: if isinstance(node_first[0].pattern.o, Exivar): return self.listToPython(convertBNodeToFact(node_first[0].pattern.o), alphaNodes, py_list) elif isinstance(node_first[0].pattern.o, Variable): py_list.append(node_first[0].pattern.o) # append variable node_rest = [node for node in alphaNodes if convertBNodeToFact(node.pattern.s)==id and node.pattern.p==REST] if node_rest: if node_rest[0].pattern.o == NIL: return py_list else: return self.listToPython(convertBNodeToFact(node_rest[0].pattern.o), alphaNodes, py_list) else: return py_list
def addFacts(self, facts, initialSet=False): #facts = Set """Adds a set of facts to the AlphaNodes.""" if initialSet: self.initialFacts = Set(facts) else: pass #self.initialFacts = self.totalFacts #not an initial set, then initialFacts would be the old total facts if not self.rete.alphaIndex: print "No alpha nodes in store!" return False #add facts for every list-related pattern with bnodes for alphaNode in self.rete.alphaNodeStore: #if the alphanode includes bnodes (list related) then add a matching fact if (alphaNode.pattern.p in [FIRST, REST, INCLUDES]) or (alphaNode.pattern.p==TYPE and alphaNode.pattern.o==LIST): #add a fact subj = convertBNodeToFact(alphaNode.pattern.s) obj = convertBNodeToFact(alphaNode.pattern.o) if not isinstance(subj, Variable) and not isinstance(obj, Variable): #add it to the set of initial facts or the alphanode? #add the fact directly to the alphanode for now, dont have to do the matching #self.initialFacts.add(Fact(subj, alphaNode.pattern.p, obj)) #alphaNode.add(Fact(subj, alphaNode.pattern.p, obj)) #print "adding fact" #print subj, alphaNode.pattern.p, obj facts.add(Fact(subj, alphaNode.pattern.p, obj)) #following code is converting and adding python lists in dictionary py_lists #for the rules triples that are list related for alphaNode in self.rete.alphaNodeStore: #print alphaNode if (alphaNode.pattern.p == FIRST and not isinstance(alphaNode.pattern.s, Univar) ): #print "bnode:", convertBNodeToFact(alphaNode.pattern.s) py_list = aNodeListToPython(convertBNodeToFact(alphaNode.pattern.s), self.rete.alphaNodeStore.nodes, []) #py_list = listToPython(convertBNodeToFact(alphaNode.pattern.s), self.rete.alphaNodeStore.nodes, self.initialFacts.union(facts),[]) py_lists[convertBNodeToFact(alphaNode.pattern.s)] = py_list #print "py_lists:", py_lists status = False #this code does the same for the facts for f in self.initialFacts: if f.p==FIRST: py_list = factListToPython(convertBNodeToFact(f.s), self.initialFacts.union(facts),[]) py_lists[convertBNodeToFact(f.s)] = py_list #print "py_lists:", py_lists self.totalFacts.add(f) #add only to relevant alpha nodes alphaMatches = self.rete.alphaIndex.match(f) for anode in alphaMatches: if anode.add(f): status = True for f in facts.difference(self.initialFacts): #if this fact is of type list, add it to the dict if f.p==TYPE and f.o==LIST: py_list = factListToPython(convertBNodeToFact(f.s), self.initialFacts.union(facts),[]) py_lists[convertBNodeToFact(f.s)] = py_list #print "py_lists:", py_lists self.totalFacts.add(f) #add only to relevant alpha nodes alphaMatches = self.rete.alphaIndex.match(f) for anode in alphaMatches: #print "new fact added:", f #print "_to alpha node added:", anode.pattern #do not add the fact if the bnode does not match #this is to take care of: _:xsdiuh rdf:first ?y or _:sdfds rdf:rest _:dsfdsf if (anode.pattern.p in [REST, FIRST]) or (anode.pattern.p==TYPE and anode.pattern.o==LIST): if isinstance(anode.pattern.s, Exivar) and convertBNodeToFact(anode.pattern.s)==f.s: if anode.add(f): status = True else: if anode.add(f): status = True #if isinstance(anode.pattern.s, Exivar) and convertBNodeToFact(anode.pattern.s)==f.s: # if anode.add(f): # status = True #elif not isinstance(anode.pattern.s, Exivar): # if anode.add(f): # status = True return status #bool(alphaMatches) #true if any alpha nodes matched
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 addFacts(self, facts, initialSet=False): #facts = Set """Adds a set of facts to the AlphaNodes.""" if initialSet: self.initialFacts = Set(facts) else: pass #self.initialFacts = self.totalFacts #not an initial set, then initialFacts would be the old total facts if not self.rete.alphaIndex: print "No alpha nodes in store!" return False #add facts for every list-related pattern with bnodes for alphaNode in self.rete.alphaNodeStore: #if the alphanode includes bnodes (list related) then add a matching fact if (alphaNode.pattern.p in [ FIRST, REST, INCLUDES ]) or (alphaNode.pattern.p == TYPE and alphaNode.pattern.o == LIST): #add a fact subj = convertBNodeToFact(alphaNode.pattern.s) obj = convertBNodeToFact(alphaNode.pattern.o) if not isinstance(subj, Variable) and not isinstance( obj, Variable): #add it to the set of initial facts or the alphanode? #add the fact directly to the alphanode for now, dont have to do the matching #self.initialFacts.add(Fact(subj, alphaNode.pattern.p, obj)) #alphaNode.add(Fact(subj, alphaNode.pattern.p, obj)) #print "adding fact" #print subj, alphaNode.pattern.p, obj facts.add(Fact(subj, alphaNode.pattern.p, obj)) #following code is converting and adding python lists in dictionary py_lists #for the rules triples that are list related for alphaNode in self.rete.alphaNodeStore: #print alphaNode if (alphaNode.pattern.p == FIRST and not isinstance(alphaNode.pattern.s, Univar)): #print "bnode:", convertBNodeToFact(alphaNode.pattern.s) py_list = aNodeListToPython( convertBNodeToFact(alphaNode.pattern.s), self.rete.alphaNodeStore.nodes, []) #py_list = listToPython(convertBNodeToFact(alphaNode.pattern.s), self.rete.alphaNodeStore.nodes, self.initialFacts.union(facts),[]) py_lists[convertBNodeToFact(alphaNode.pattern.s)] = py_list #print "py_lists:", py_lists status = False #this code does the same for the facts for f in self.initialFacts: if f.p == FIRST: py_list = factListToPython(convertBNodeToFact(f.s), self.initialFacts.union(facts), []) py_lists[convertBNodeToFact(f.s)] = py_list #print "py_lists:", py_lists self.totalFacts.add(f) #add only to relevant alpha nodes alphaMatches = self.rete.alphaIndex.match(f) for anode in alphaMatches: if anode.add(f): status = True for f in facts.difference(self.initialFacts): #if this fact is of type list, add it to the dict if f.p == TYPE and f.o == LIST: py_list = factListToPython(convertBNodeToFact(f.s), self.initialFacts.union(facts), []) py_lists[convertBNodeToFact(f.s)] = py_list #print "py_lists:", py_lists self.totalFacts.add(f) #add only to relevant alpha nodes alphaMatches = self.rete.alphaIndex.match(f) for anode in alphaMatches: #print "new fact added:", f #print "_to alpha node added:", anode.pattern #do not add the fact if the bnode does not match #this is to take care of: _:xsdiuh rdf:first ?y or _:sdfds rdf:rest _:dsfdsf if (anode.pattern.p in [ REST, FIRST ]) or (anode.pattern.p == TYPE and anode.pattern.o == LIST): if isinstance(anode.pattern.s, Exivar) and convertBNodeToFact( anode.pattern.s) == f.s: if anode.add(f): status = True else: if anode.add(f): status = True #if isinstance(anode.pattern.s, Exivar) and convertBNodeToFact(anode.pattern.s)==f.s: # if anode.add(f): # status = True #elif not isinstance(anode.pattern.s, Exivar): # if anode.add(f): # status = True return status #bool(alphaMatches) #true if any alpha nodes matched
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