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)
Example #2
0
    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)
Example #3
0
def analyzeFunction(theFunction, patternIndex, variables, inPatternVariables=None, fakeVariables = None, realToFakeMap = None, vIndex = None, fakeNames = None):
    '''
    Analyze a FunctionCall inside a Test-CE to replace variables name with fake names
    an bound locations to improve reuse of test-nodes (normalize variables names) 
    
    @param theFunction: a function call to replace
    @type theFunction: types.FunctionCall
    @param patternIndex: the index of the test-pattern in the chain of ce
    @type patternIndex: int
    @param variables: a dict of variable name => VariableReferences
    @type variables: dict
    @param fakeVariables: a dict of fake variables references or None (to make a new one)
    @type fakeVariables: dict
    @param realToFakeMap: a map of real variables names to fake ones
    @type realToFakeMap: dict
    @param vIndex: the index for fake variables name generation
    @type vIndex: int
    '''
    
    inPatternVariables = [] if inPatternVariables is None else inPatternVariables
    aNewFunctionCallArgs = []
    fakeVariables = {} if fakeVariables is None else fakeVariables
    fakeNames = {} if fakeNames is None else fakeNames
    realToFakeMap = {} if realToFakeMap is None else realToFakeMap
    vIndex = [] if vIndex is None else vIndex;
    
    if isinstance(theFunction, types.FunctionCall):
        
        assert isinstance(theFunction, types.FunctionCall)
        
        for aArg in theFunction.funcArgs:
            
            # globals are resolved at function-call execution time
            if isinstance(aArg, (types.SingleFieldVariable, types.MultiFieldVariable)):
                # i've already created a fake_var for this var?
                if not realToFakeMap.has_key(aArg.evaluate()) :
                
                    # where i found the variable first?
                    mainReference = getVar(aArg.evaluate(), variables, inPatternVariables)
                    
                    if mainReference is False:
                        raise MyClipsException("Variable %s found in the expression %s was referenced in CE #%d before being defined."%(
                                aArg.evaluate(),
                                theFunction.toClipsStr(),
                                patternIndex
                            ))
                    
                    varReference = VariableReference()
                    varReference.reference = mainReference
                    varReference.relPatternIndex = mainReference.patternIndex - patternIndex
                    
                    theFakeName = "%"+str(len(vIndex))
                    vIndex.append(None)
                    
                    theFakeVar = aArg.__class__(types.Symbol(theFakeName)) 
                    
                    fakeVariables[theFakeVar.evaluate()] = varReference
                    realToFakeMap[aArg.evaluate()] = theFakeVar.evaluate()
                    fakeNames[aArg.evaluate()] = theFakeVar 
                
                else:
                    theFakeVar = fakeNames[aArg.evaluate()]
                     
                
                # replace the variable name with a fake name
                #aArg.content = theFakeName
                aNewFunctionCallArgs.append(theFakeVar)
                
            elif isinstance(aArg, types.FunctionCall):
                
                # recursion: replace arguments inside the function call
                # fakeReferences are ignored because the dict is automatically
                # updated by the recursion.
                aInnerNewFunctionCall, _ = analyzeFunction(aArg, patternIndex, variables, inPatternVariables, fakeVariables, realToFakeMap, vIndex, fakeNames)
                
                # replace the old function call with a new one with fake variables
                #theFunction.funcArgs[iArg] = aInnerNewFunctionCall
                aNewFunctionCallArgs.append(aInnerNewFunctionCall)
                
            else:
                aNewFunctionCallArgs.append(aArg)
    
        # get the current scope and backup it
        _tmp_scope = theFunction.scope.modules.currentScope
        # then change it to the original function call scope
        theFunction.scope.modules.changeCurrentScope(theFunction.scope.moduleName)
        # create the new function call
        newFunctionCall = types.FunctionCall(theFunction.funcName, theFunction.scope.modules, aNewFunctionCallArgs)
        # then restore the previous scope
        theFunction.scope.modules.changeCurrentScope(_tmp_scope.moduleName)
    
        return (newFunctionCall, fakeVariables)
    
    else: raise TypeError("AnalyzeFunction require a FunctionCall as first argument")
Example #4
0
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)