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)
        """                        
Ejemplo n.º 3
0
    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)

        """                        
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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