示例#1
0
 public static ConstantFactory Get()
 {
     if (instance == null)
     {
         instance = new ConstantFactory();
     }
     return(instance);
 }
示例#2
0
        public static bool InjectUninterpreted(Procedure left, Procedure right, Config cfg, CallGraph cg, List <Declaration> ufDeclarations, bool asserts = false)
        {
            if (left == null || right == null | ufDeclarations == null)
            {
                return(true);
            }

            int i, j;

            var leftNode  = cg.NodeOfName(left.Name);
            var rightNode = cg.NodeOfName(right.Name);

            if (leftNode == null)
            {
                Log.Out(Log.Error, "No callgraph node found for " + left.Name + "!");
                return(true);
            }
            if (rightNode == null)
            {
                Log.Out(Log.Error, "No callgraph node found for " + right.Name + "!");
                return(true);
            }
            if (left.InParams.Count != right.InParams.Count)
            {
                return(true);
            }

            //use read and write sets to compute globals into UF
            var globalsIn = leftNode.ReadSetGlobals;

            foreach (var v in rightNode.ReadSetGlobals)
            {
                if (!globalsIn.Contains(v))
                {
                    globalsIn.Add(v);
                }
            }
            var globalsLeftOut =
                leftNode.WriteSetGlobals;
            var globalsRightOut =
                rightNode.WriteSetGlobals;

            ParamMap paramMap = cfg.FindProcedure(left.Name, right.Name);

            //use formals of left, right to compute formals into UF
            //inParams is the union of the left, right inparams
            var rightInParams = new List <Variable>(right.InParams);
            var leftInParams  = new List <Variable>(left.InParams);
            //map the left variables to their right correspondents
            var leftVRenamer       = new VariableRenamer(paramMap, rightInParams);
            var leftInParamsMapped = leftVRenamer.VisitVariableSeq(new List <Variable>(leftInParams));
            var inParams           = new List <Variable>(rightInParams);

            foreach (Variable v in leftInParamsMapped)
            {
                if (!inParams.Contains(v))
                {
                    inParams.Add(v);
                }
            }

            //outParams is the intersection fo the left, right outparams
            var leftOutParamsO  = new List <Variable>(left.OutParams);
            var rightOutParamsO = new List <Variable>(right.OutParams);

            //add globals to outputs
            leftOutParamsO.AddRange(globalsLeftOut.ToVariableSeq());
            rightOutParamsO.AddRange(globalsRightOut.ToVariableSeq());
            //map the left variables to their right correspondents again
            leftVRenamer.AddDecls(rightOutParamsO);
            var leftOutParamsMapped = leftVRenamer.VisitVariableSeq(new List <Variable>(leftOutParamsO));


            var outParams = new List <Variable>();

            foreach (Variable v in leftOutParamsMapped)
            {
                if (rightOutParamsO.Contains(v))
                {
                    outParams.Add(v);
                }
            }

            //append globals to inputs
            int numNonGlobals = inParams.Count;

            inParams.AddRange(globalsIn.Map(x => x as Variable).ToVariableSeq());

            //instrumentation
            if (BadGlobalState.MaxUFArgs < inParams.Count)
            {
                BadGlobalState.MaxUFArgs = inParams.Count;
            }
            BadGlobalState.SumUFArgs += inParams.Count;
            BadGlobalState.NumUFs++;

            //now we have all the formals for the functions..
            //we build UFs for the left in the case that the two are not found equiv. the map is not used
            Dictionary <Variable, Function> formalToFunLeft, formalToFunRight;

            MakeUFs(leftOutParamsMapped.Append(rightOutParamsO), inParams, UFofFunctionName(right.Name, ""), ufDeclarations, out formalToFunRight);
            MakeUFs(leftOutParamsO, inParams, UFofFunctionName(left.Name, ""), ufDeclarations, out formalToFunLeft);

            //build arguments for the left side
            var leftArgsArray = new Expr[inParams.Count];

            leftArgsArray.InitNull();
            for (i = 0; i < leftInParamsMapped.Count; i++)
            {
                for (j = 0; j < inParams.Count; j++)
                {
                    if (leftInParamsMapped[i] == inParams[j])
                    {
                        leftArgsArray[j] = Expr.Ident(left.InParams[i]);
                    }
                }
            }
            for (i = 0; i < numNonGlobals; i++)
            {
                if (leftArgsArray[i] == null)
                {
                    leftArgsArray[i] = Expr.Ident(ConstantFactory.Get().Make(inParams[i]));
                }
            }

            //build arguments for the right side
            var rightArgsArray = new Expr[inParams.Count];

            rightArgsArray.InitNull();
            for (i = 0; i < rightInParams.Count; i++)
            {
                rightArgsArray[i] = Expr.Ident(right.InParams[i]);
            }
            for (i = rightInParams.Count; i < numNonGlobals; i++)
            {
                rightArgsArray[i] = Expr.Ident(ConstantFactory.Get().Make(inParams[i]));
            }

            //finally, build the argument expressions for the globals
            for (i = numNonGlobals; i < inParams.Count; i++)
            {
                leftArgsArray[i] = rightArgsArray[i] =
                    new OldExpr(Token.NoToken, Expr.Ident(globalsIn[i - numNonGlobals]));
            }

            var leftArgs  = leftArgsArray.ToExprSeq();
            var rightArgs = rightArgsArray.ToExprSeq();

            List <Ensures> leftEnsures, rightEnsures;

            MakeUFPostconditions(formalToFunRight, leftOutParamsMapped, leftOutParamsO, leftArgs, out leftEnsures);
            MakeUFPostconditions(formalToFunRight, rightOutParamsO, rightOutParamsO, rightArgs, out rightEnsures);

            //left.Ensures = leftEnsures;
            //right.Ensures = rightEnsures;

            //add to the list of pre/post conditions
            left.Ensures.AddRange(leftEnsures);
            right.Ensures.AddRange(rightEnsures);

            return(false);
        }