def test_ComparisonNotEqual_RelPatternIndex(self): varLoc = VariableLocation("bla", 0, "aSlot", True, 0) bindLoc = VariableLocation("bla", patternIndex=0, slotName="aSlot", fromBegin=True, beginIndex=0) ref1 = VariableReference(relPatternIndex=-2) ref2 = VariableReference(relPatternIndex=0) varLoc.toVarReference(ref1) varLoc.toVarReference(ref2) ref1.reference = bindLoc ref2.reference = bindLoc self.assertNotEqual(ref1, ref2)
def _makeNetwork(self, node, patterns, prevPatterns=0, variables=None): variables = {} if variables is None else variables for patternCE in patterns: # get the pattern type: if isinstance(patternCE, (types.TemplatePatternCE, types.AssignedPatternCE, types.OrderedPatternCE)): # if patternCE is assigned, i need to propagate # alpha creation with the inner pattern, # not with the main assigned. # i use the assigned only to store info about variable # use old way to store variables coordinates, waiting for a new one if isinstance(patternCE, types.AssignedPatternCE): variables[ patternCE.variable.evaluate()] = VariableLocation( patternCE.variable.evaluate(), prevPatterns, fullFact=True) patternCE = patternCE.pattern inPatternVariables = [] alphaTests, joinTests = analysis.analyzePattern( patternCE, prevPatterns, variables, inPatternVariables) # merge inPatternVariables to variables variables.update( dict([(var.name, var) for var in inPatternVariables])) # requires a simple alpha circuit, # then a join + beta node if needed (beta join circuit) alphaMemory = self._makeAlphaCircuit(alphaTests) node = self._makeBetaJoinCircuit(node, alphaMemory, joinTests) prevPatterns += 1 elif isinstance(patternCE, types.NotPatternCE): # need to check inside the pattern # if inside a not-ce there is a and-ce # i need to build a ncc if isinstance(patternCE.pattern, types.AndPatternCE): # that's it: ncc required # this build the normal circuit lastNccCircuitNode, circuitPatternCount = self._makeNetwork( node, patternCE.pattern.patterns, prevPatterns, variables) node = self._makeBetaNccCircuit( node, lastNccCircuitNode, circuitPatternCount - prevPatterns) # inner conditions already appended by recursive call # but i have to add a +1 for the (not (...)) #avoidAppend = True prevPatterns = circuitPatternCount + 1 elif isinstance(patternCE.pattern, types.NotPatternCE): inPatternVariables = [] alphaTests, joinTests = analysis.analyzePattern( patternCE.pattern.pattern, prevPatterns, variables, inPatternVariables) alphaMemory = self._makeAlphaCircuit(alphaTests) node = self._makeBetaExistsCircuit(node, alphaMemory) prevPatterns += 1 else: # a simple negative join node is required inPatternVariables = [] # add 1 to pattern index because the values are in the inner not pattern # so the (not (condition)) count as 2 alphaTests, joinTests = analysis.analyzePattern( patternCE.pattern, prevPatterns, variables, inPatternVariables) # merge inPatternVariables to variables #variables.update(dict([(var.name, var) for var in inPatternVariables])) # requires a simple alpha circuit, # then a join + beta node if needed (beta join circuit) alphaMemory = self._makeAlphaCircuit(alphaTests) node = self._makeBetaNegativeJoinCircuit( node, alphaMemory, joinTests) prevPatterns += 1 elif isinstance(patternCE, types.TestPatternCE): # a special filter must be applied to # the circuit node = self._makeBetaTestCircuit(node, patternCE, prevPatterns, variables) prevPatterns += 1 elif isinstance(patternCE, types.ExistsPatternCE): inPatternVariables = [] alphaTests, joinTests = analysis.analyzePattern( patternCE.pattern, prevPatterns, variables, inPatternVariables) alphaMemory = self._makeAlphaCircuit(alphaTests) node = self._makeBetaExistsCircuit(node, alphaMemory) prevPatterns += 1 # or and and ce must not be supported here # after lhs normalization # or-ce could be only at top level # of the lhs and are managed from the # addRule method (each or clause cause a new network circuit # and a new sub-pnode linked to a main one # and-ce could be only after a not-ce or the main or-ce # (managed by addRule method) # and are managed as a ncc circuit return node, prevPatterns
def _analyzeTerm(atomLocation, aTerm, variables, inPatternVariables): ''' Analyze a types.Term and create a list of pattern tests and join tests to describe the term @param atomLocation: the location of the term inside the LHS @param aTerm: a types.Term element @param variables: a dict of varName => VarLocation(s) in previous patterns @param inPatternVariables: a list of VarLocations in the current pattern ''' alphaTests = [] joinTests = [] isNegative = True if isinstance(aTerm, types.NegativeTerm) else False # dewrap: aTerm from a Term object to Term's content aTerm = aTerm.term if isinstance(aTerm, (types.MultiFieldVariable, types.SingleFieldVariable)): varLocation = VariableLocation.fromAtomLocation(aTerm.evaluate(), atomLocation) # check the main location of the variable # but if it's the same of this location, ignore the cc mainReference = getVar(aTerm.evaluate(), variables, inPatternVariables) if mainReference is not False: # create a reference to this variable varReference = VariableReference() varLocation.toVarReference(varReference) varReference.reference = mainReference varReference.isNegative = isNegative # calcolate the relPatternIndex if varLocation.patternIndex is not None: if mainReference.patternIndex is not None: varReference.relPatternIndex = mainReference.patternIndex - varLocation.patternIndex else: # TODO verificare!!!! varReference.relPatternIndex = 0 - varLocation.patternIndex else: varReference.relPatternIndex = 0 # make a new join test joinTests.append(VariableBindingTest(varReference)) else: # unknown variable! inPatternVariables.append(varLocation) elif isinstance(aTerm, types.BaseParsedType): # a pattern test is required, but created by _makeAlphaNetwork. so ignore # remove patternIndex location from the atomLocation # because alpha tests are always on the wme from the right atomLocationCopy = copy(atomLocation) atomLocationCopy.patternIndex = None aAlphaTest = ConstantValueAtIndexTest(atomLocationCopy, aTerm) alphaTests.append(aAlphaTest if not isNegative else NegativeAlphaTest(aAlphaTest)) elif isinstance(aTerm, types.FunctionCall): # well... this is a special case. This must be converted in a # (test (function-call)) _newFunc, _fakeVar = analyzeFunction(aTerm, atomLocation.patternIndex, variables, inPatternVariables) joinTests.append(DynamicFunctionTest(_newFunc, _fakeVar)) # unnamed multifield and single field are ignored return (alphaTests, joinTests)