Esempio n. 1
0
        public static VarSet GetAllVars(Program p)
        {
            //List<GlobalVariable> globalDecls = BoogieUtil.GetGlobalVariables(p);
            var procedures      = BoogieUtil.GetProcedures(p);
            var implementations = BoogieUtil.GetImplementations(p);
            var allVars         = new VarSet();

            foreach (var proc in procedures)
            {
                var uses = new GlobalVarsUsed();
                uses.VisitRequiresSeq(proc.Requires);
                uses.VisitEnsuresSeq(proc.Ensures);
                // skip visiting modifies clause
                allVars.Add(new VarSet(uses.globalsUsed, proc.Name));
            }

            foreach (var impl in implementations)
            {
                var uses = new GlobalVarsUsed();
                uses.VisitBlockList(impl.Blocks);
                allVars.Add(new VarSet(uses.globalsUsed, impl.Name));
            }

            //globalDecls.Iterate(x => procedures.Iterate(y => allVars.Add(x.Name, y.Name)));
            //globalDecls.Iterate(x => implementations.Iterate(y => allVars.Add(x.Name, y.Name)));
            return(allVars);
        }
Esempio n. 2
0
        public bool hasOldGlobalVarsToInstrument(Absy exp)
        {
            GlobalVarsUsed usesg = new GlobalVarsUsed();

            usesg.Visit(exp);

            // If any used variable is also modified then return true
            if (usesg.oldVarsUsed.Any(x => globalsToInstrument.Contains(x)))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 3
0
        public bool hasModifiedGlobalVars(Absy exp)
        {
            Debug.Assert(infoGathered);

            GlobalVarsUsed usesg = new GlobalVarsUsed();

            usesg.Visit(exp);

            // If any used variable is also modified then return true
            if (usesg.Used.Any(x => modifiedGlobals.ContainsKey(x)))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 4
0
        public static bool ApplyTemplates(HashSet <int> templates)
        {
            var commonGlobals = Minimize.FindCommonGlobals();
            var ret           = false;

            // Prune away ones that don't have constants associated with them
            templates = new HashSet <int>(
                templates.Where(t => !templateMap[t].All(tup => tup.Value.SetEquals(fileToKeepConstants[tup.Key]))));

            // Prune away ones that don't talk about common globals
            templates = new HashSet <int>(
                templates.Where(t =>
            {
                var expr = SimplifyExpr.ToExpr(templateToStr[t]);
                var vu   = new GlobalVarsUsed();
                vu.VisitExpr(expr);
                return(vu.globalsUsed.IsSubsetOf(commonGlobals));
            }));

            var newFileToProg = new Dictionary <string, PersistentProgram>();

            var templateToConstants = new Dictionary <int, int>();

            templates.Iter(t => templateToConstants.Add(t, 0));

            foreach (var tup in fileToProg)
            {
                var program = tup.Value.getProgram();
                BoogieUtil.DoModSetAnalysis(program);
                var globals = new HashSet <string>(program.TopLevelDeclarations.OfType <GlobalVariable>().Select(g => g.Name));

                var newconstants = new HashSet <Constant>();

                foreach (var t in templates)
                {
                    var expr   = SimplifyExpr.ToExpr(templateToStr[t]);
                    var nonold = new GatherNonOldVariables();
                    nonold.VisitExpr(expr);

                    var mustmod = new HashSet <string>(nonold.variables);
                    mustmod.IntersectWith(globals);

                    foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                    {
                        var mod = new HashSet <string>(impl.Proc.Modifies.Select(ie => ie.Name));
                        if (!mustmod.IsSubsetOf(mod))
                        {
                            continue;
                        }

                        // create new constant
                        var nc = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "PMnewConst" + (NewConstCounter++),
                                                                            btype.Bool), false);
                        nc.AddAttribute("existential");
                        newconstants.Add(nc);
                        if (!templateMap[t].ContainsKey(tup.Key))
                        {
                            templateMap[t].Add(tup.Key, new HashSet <string>());
                        }
                        templateMap[t][tup.Key].Add(nc.Name);

                        ret = true;
                        templateToConstants[t]++;

                        impl.Proc.Ensures.Add(new Ensures(false, Expr.Imp(Expr.Ident(nc), expr)));
                    }
                }

                program.AddTopLevelDeclarations(newconstants);
                newFileToProg.Add(tup.Key, new PersistentProgram(program));
            }
            fileToProg = newFileToProg;

            foreach (var tup in templateToConstants)
            {
                Console.WriteLine("Applying template {0}: {1} ({2} constants created)", tup.Key, templateToStr[tup.Key], tup.Value);
            }

            return(ret);
        }
Esempio n. 5
0
        // This is the main place where the rewriting happens
        public override Block VisitBlock(Block block)
        {
            GlobalVarsUsed usesg = new GlobalVarsUsed();

            // The new list of commands that we will construct
            List <Cmd> lcmds = new List <Cmd>();

            foreach (Cmd cmd in block.Cmds)
            {
                if (!(cmd is CallCmd))
                {
                    lcmds.Add(cmd);
                    continue;
                }

                CallCmd ccmd = cmd as CallCmd;

                // If the call command doesn't have any don't cares, then no need
                // to instrument
                bool found = false;
                found = ccmd.Outs.Any(x => (x == null));
                found = found || ccmd.Ins.Any(x => (x == null));

                if (!found)
                {
                    lcmds.Add(cmd);
                    continue;
                }

                // Get ready to instrument

                // This is the list of locals to havoc (for the arguments)
                List <IdentifierExpr> havocArgs = new List <IdentifierExpr>();

                // Go through the arguments of the call
                for (int i = 0, n = ccmd.Ins.Count; i < n; i++)
                {
                    if (ccmd.Ins[i] == null)
                    {
                        Variable lvar = getNewLocal(ccmd.Proc.InParams[i].TypedIdent.Type);
                        havocArgs.Add(new IdentifierExpr(Token.NoToken, lvar));
                        ccmd.Ins[i] = Expr.Ident(lvar);
                    }
                }

                /*
                 * // havoc locals -- not needed; because locals are uninitialized
                 * if (havocArgs.Length != 0)
                 * {
                 *  lcmds.Add(new HavocCmd(Token.NoToken, havocArgs));
                 * }
                 */

                // Go through the return values
                for (int i = 0, n = ccmd.Outs.Count; i < n; i++)
                {
                    if (ccmd.Outs[i] == null)
                    {
                        Variable lvar = getNewLocal(ccmd.Proc.OutParams[i].TypedIdent.Type);
                        ccmd.Outs[i] = new IdentifierExpr(Token.NoToken, lvar);
                    }
                }

                // the new call command
                lcmds.Add(ccmd);
            }

            block.Cmds = lcmds;

            return(block);
        }