예제 #1
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("usage: SmackInst.exe infile.bpl outfile.bpl [options]");
                return;
            }

            if (args.Any(a => a == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            if (args.Any(a => a == "/initMem"))
            {
                initMem = true;
            }


            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;


            // Read the input file
            var program = BoogieUtil.ReadAndResolve(args[0]);

            // Process it
            program = Process(program);

            // write the output
            BoogieUtil.PrintProgram(program, args[1]);
        }
예제 #2
0
        public void Unify(string outfile)
        {
            // Gather all maps
            AllMaps = new HashSet <string>();

            program.TopLevelDeclarations
            .OfType <GlobalVariable>()
            .Where(g => g.TypedIdent.Type.IsMap && (g.TypedIdent.Type as MapType).Result.IsInt)
            .Iter(g => AllMaps.Add(g.Name));

            // Fix Cmds
            program.TopLevelDeclarations
            .OfType <Implementation>()
            .Iter(impl =>
                  impl.Blocks.Iter(block =>
                                   block.Cmds
                                   .OfType <Cmd>().Iter(cmd => Visit(cmd))));

            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(p => VisitEnsuresSeq(p.Ensures));
            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(p => VisitRequiresSeq(p.Requires));

            var impls = new HashSet <string>();

            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl => impls.Add(impl.Name));

            program.TopLevelDeclarations.OfType <Procedure>()
            .Where(p => impls.Contains(p.Name))
            .Iter(p => p.Modifies = new List <IdentifierExpr>());
            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(p => VisitIdentifierExprSeq(p.Modifies));

            // Remove globals
            var newDecls = new List <Declaration>();

            foreach (var decl in program.TopLevelDeclarations)
            {
                var glob = decl as GlobalVariable;
                if (glob == null || !AllMaps.Contains(glob.Name))
                {
                    newDecls.Add(decl);
                }
            }

            program.TopLevelDeclarations = newDecls;
            program.AddTopLevelDeclaration(U);

            // print program
            BoogieUtil.DoModSetAnalysis(program);
            BoogieUtil.PrintProgram(program, outfile);

            program = null;
        }
예제 #3
0
        //TODO: collect some stats about the instrumentation, mb some debugging output??

        private static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl");
                return;
            }

            if (args.Any(s => s == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;

            // read the boogie program that is to be instrumented
            var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false);

            // parse the property file
            var         propLines = File.ReadLines(args[0]);
            string      globalDeclarations;
            List <Rule> rules;

            CreateRulesFromProperty(propLines, out globalDeclarations, out rules);

            // GlobalDeclarations: add the global declarations from the property to the Boogie program
            Program dummyProg;

            Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg);
            boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations);

            //resolve the program with the new declarations which may include funcs and procs with bodies
            boogieProgram.Resolve();

            // CmdRule: find insertions sites (Commands), insert code there
            InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>());

            // InsertAtBeginningRule: find insertion sites (Procedures), insert code there
            InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>());

            // make functions with {:mkUniqueFn} unique
            (new MkUniqueFnVisitor(boogieProgram)).Visit(boogieProgram);

            //augment the CorralExtraInit procedure (perform this after Matching/instrumentation)
            AugmentCorralExtraInit(boogieProgram);

            string outputFile = args[2];

            BoogieUtil.PrintProgram(boogieProgram, outputFile);

            Stats.printStats();
        }
예제 #4
0
        public static void RunOnce(PersistentProgram inprog, bool printcontracts)
        {
            var program = inprog.getProgram();

            program.Typecheck();
            BoogieUtil.PrintProgram(program, "hi_query.bpl");

            Console.WriteLine("Running HoudiniLite");
            var assignment = CoreLib.HoudiniInlining.RunHoudini(program, true);

            Console.WriteLine("Inferred {0} contracts", assignment.Count);

            // Read the program again, add contracts
            program = inprog.getProgram();
            program.Typecheck();

            var contracts =
                CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment);

            BoogieUtil.PrintProgram(program, "si_query.bpl");

            // Run SI
            var err = new List <BoogieErrorTrace>();

            var rstatus = BoogieVerify.Verify(program, out err, true);

            Console.WriteLine("SI Return status: {0}", rstatus);
            if (err == null || err.Count == 0)
            {
                Console.WriteLine("program verified");
            }
            else
            {
                foreach (var trace in err.OfType <BoogieAssertErrorTrace>())
                {
                    Console.WriteLine("{0} did not verify", trace.impl.Name);
                    //if (!config.noTrace) trace.cex.Print(0, Console.Out);
                }
            }

            Console.WriteLine(string.Format("Procedures Inlined: {0}", BoogieVerify.CallTreeSize));
            Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2")));

            if (printcontracts)
            {
                foreach (var tup in contracts)
                {
                    Console.WriteLine("{0}: {1}", tup.Key, tup.Value);
                }
            }
        }
예제 #5
0
        BoogieVerify.ReturnStatus PruneAndRun(PersistentProgram inp, HashSet <string> candidates, out HashSet <string> assignment, ref int inlined)
        {
            IterCnt++;

            var program = inp.getProgram();

            program.Typecheck();

            // Remove non-candidates
            CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, candidates, true);
            program.RemoveTopLevelDeclarations(decl => (decl is Constant) && QKeyValue.FindBoolAttribute(decl.Attributes, "existential") &&
                                               !candidates.Contains((decl as Constant).Name));

            BoogieUtil.PrintProgram(program, "hi_query" + IterCnt + ".bpl");

            // Run Houdini
            assignment = CoreLib.HoudiniInlining.RunHoudini(program, true);
            Console.WriteLine("  >> Contracts: {0}", assignment.Count);

            // Read the program again, add contracts
            program = inp.getProgram();
            program.Typecheck();

            CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment);

            BoogieUtil.PrintProgram(program, "si_query" + IterCnt + ".bpl");

            // Run SI
            var err = new List <BoogieErrorTrace>();

            // Set bound
            BoogieVerify.options.maxInlinedBound = 0;
            if (inlined != 0)
            {
                BoogieVerify.options.maxInlinedBound = PerfMetric(inlined);
            }

            var rstatus = BoogieVerify.Verify(program, out err, true);

            Console.WriteLine(string.Format("  >> Procedures Inlined: {0}", BoogieVerify.CallTreeSize));
            //Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2")));

            inlined = BoogieVerify.CallTreeSize + 1;
            BoogieVerify.options.CallTree = new HashSet <string>();
            BoogieVerify.CallTreeSize     = 0;
            BoogieVerify.verificationTime = TimeSpan.Zero;


            return(rstatus);
        }
예제 #6
0
        // Check that assert and return only appear together
        private static void RemoveAsserts(Program program)
        {
            var mains = program.TopLevelDeclarations
                        .OfType <Implementation>()
                        .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"));

            foreach (var main in mains)
            {
                foreach (var blk in main.Blocks)
                {
                    var isReturn  = (blk.TransferCmd is ReturnCmd);
                    var assertPos = -2;
                    for (int i = 0; i < blk.Cmds.Count; i++)
                    {
                        if (BoogieUtil.isAssertTrue(blk.Cmds[i]))
                        {
                            continue;
                        }

                        if (blk.Cmds[i] is AssertCmd)
                        {
                            assertPos = i;
                            break;
                        }
                    }

                    if (!isReturn && assertPos != -2)
                    {
                        BoogieUtil.PrintProgram(program, "error.bpl");
                        throw new InternalError("assert is not followed by return");
                    }

                    if (isReturn)
                    {
                        if (assertPos != blk.Cmds.Count - 1)
                        {
                            //throw new InternalError("return is not preceeded by an assert");
                            blk.Cmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                        }
                        else
                        {
                            var assertcmd = blk.Cmds[assertPos] as AssertCmd;
                            blk.Cmds[assertPos] = new AssumeCmd(Token.NoToken, Expr.Not(assertcmd.Expr),
                                                                new QKeyValue(Token.NoToken, "OldAssert", new List <object>(), null));
                        }
                    }
                }
            }
        }
예제 #7
0
        // Return a new copy of the program
        public override Program getProgram()
        {
            var startTime = DateTime.Now;

            FixedDuplicator dup = new FixedDuplicator();
            Program         ret = dup.VisitProgram(program);

            if (ret.Resolve() != 0 || ret.Typecheck() != 0)
            {
                BoogieUtil.PrintProgram(ret, "error.bpl");
                throw new InternalError("Illegal program given to PersistentProgram");
            }

            persistenceCost += (DateTime.Now - startTime);
            return(ret);
        }
예제 #8
0
        static void doHwswLevelMatch(string infile, string outfile)
        {
            var program = BoogieUtil.ParseProgram(infile);

            foreach (var decl in program.TopLevelDeclarations)
            {
                var impl = decl as Implementation;
                if (impl == null)
                {
                    continue;
                }
                doHwswLevelMatch(impl);
            }

            BoogieUtil.PrintProgram(program, outfile);
        }
예제 #9
0
        static int Split(Program program, string filename)
        {
            var cnt = 1;

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                if (impl.Proc.Ensures.Any(ens => !ens.Free))
                {
                    var p = SplitOnProcedure(program, impl.Name);
                    MarkEntryPoint(p, impl.Name);
                    BoogieUtil.PrintProgram(p, filename.Replace(".bpl", string.Format("_split_{0}.bpl", cnt++)));
                }
            }

            return(cnt);
        }
예제 #10
0
파일: Program.cs 프로젝트: zvonimir/corral
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("BctMemInst.exe input.bpl output.bpl [args]");
                return;
            }

            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;
            CommandLineOptions.Clo.DoModSetAnalysis  = true;

            var input = BoogieUtil.ReadAndResolve(args[0]);

            var output = Process(input);

            if (output != null)
            {
                BoogieUtil.PrintProgram(output, args[1]);
            }
        }
예제 #11
0
        //TODO: collect some stats about the instrumentation, mb some debugging output??

        private static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl");
                return;
            }

            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;

            // read the boogie program that is to be instrumented
            var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false);

            // parse the property file
            var         propLines = File.ReadLines(args[0]);
            string      globalDeclarations;
            List <Rule> rules;

            CreateRulesFromProperty(propLines, out globalDeclarations, out rules);

            // GlobalDeclarations: add the global declarations from the property to the Boogie program
            Program dummyProg;

            Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg);
            boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations);

            // CmdRule: find insertions sites (Commands), insert code there
            InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>());

            // InsertAtBeginningRule: find insertion sites (Procedures), insert code there
            InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>());

            string outputFile = args[2];

            BoogieUtil.PrintProgram(boogieProgram, outputFile);

            Stats.printStats();
        }
예제 #12
0
        public Program run(Program node)
        {
            globalsRead = new HashSet <string>();

            // Typecheck -- needed for variable abstraction
            if (node.Typecheck() != 0)
            {
                BoogieUtil.PrintProgram(node, "error.bpl");
                throw new InternalError("Type errors");
            }

            // Go through all procedures and implementations (slice locals)
            var TopLevelDeclarations = node.TopLevelDeclarations.ToList();

            for (int i = 0; i < TopLevelDeclarations.Count; i++)
            {
                if (TopLevelDeclarations[i] is Implementation)
                {
                    TopLevelDeclarations[i] = processImplementation(TopLevelDeclarations[i] as Implementation);
                }
                else if (TopLevelDeclarations[i] is Procedure)
                {
                    processProcedure(TopLevelDeclarations[i] as Procedure);
                }
            }
            node.TopLevelDeclarations = TopLevelDeclarations;

            if (onlyLocals)
            {
                return(node);
            }


            sliceGlobals = new VariableSlicing(VarSet.ToVarSet(globalsRead, node), gtinfo);
            node         = sliceGlobals.VisitProgram(node);
            BoogieUtil.DoModSetAnalysis(node);

            return(node);
        }
예제 #13
0
 static void MarkAllAssumes(Program program, string filename)
 {
     program = SplitOnProcedure(program, "");
     BoogieUtil.PrintProgram(program, filename.Replace(".bpl", "_split_0.bpl"));
 }
예제 #14
0
        static void Main(string[] args)
        {
            System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Batch;

            if (args.Length < 2 || !args[0].EndsWith(".bpl") || !args[1].EndsWith(".bpl"))
            {
                Console.WriteLine("Usage: AvHarnessInstrumentation infile.bpl outfile.bpl [options]");
                return;
            }

            SetOptions(args);

            // Initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;
            BoogieUtil.InitializeBoogie("");
            ProgTransformation.PersistentProgramIO.useDuplicator = true;

            var sw = new Stopwatch();

            sw.Start();

            if (Options.killAfter > 0)
            {
                var timer = new System.Timers.Timer(Options.killAfter * 1000);
                timer.Elapsed += (sender, e) => HandleTimer(sw);
                timer.Start();
            }

            try
            {
                // Get the program, install the harness and do basic instrumentation
                var inprog = GetProgram(args[0]);


                Utils.Print(string.Format("#Procs : {0}", inprog.TopLevelDeclarations.OfType <Implementation>().Count()), Utils.PRINT_TAG.AV_STATS);
                Utils.Print(string.Format("#EntryPoints : {0}", harnessInstrumentation.entrypoints.Count), Utils.PRINT_TAG.AV_STATS);
                Utils.Print(string.Format("#AssertsBeforeAA : {0}", AssertCountVisitor.Count(inprog)), Utils.PRINT_TAG.AV_STATS);

                if (Options.delayAA)
                {
                    PruneRedundantEntryPoints(inprog);
                    BoogieUtil.PrintProgram(inprog, args[1]);
                }
                else
                {
                    var program = new PersistentProgram(inprog, AvnAnnotations.CORRAL_MAIN_PROC, 0);

                    // Run alias analysis
                    Stats.resume("alias.analysis");
                    Console.WriteLine("Running alias analysis");
                    program = RunAliasAnalysis(program);
                    Stats.stop("alias.analysis");

                    var assertCnt = AssertCountVisitor.Count(program.getProgram());
                    Utils.Print(string.Format("#AssertsAfterAA : {0}", assertCnt), Utils.PRINT_TAG.AV_STATS);

                    // run Houdini pass
                    if (Options.HoudiniPass)
                    {
                        Utils.Print("Running Houdini Pass");
                        program   = RunHoudiniPass(program);
                        assertCnt = AssertCountVisitor.Count(program.getProgram());
                        Utils.Print(string.Format("#Asserts : {0}", assertCnt), Utils.PRINT_TAG.AV_STATS);
                    }

                    if (assertCnt == 0)
                    {
                        // program has been proved correct
                        // Write a trivial program
                        System.IO.File.WriteAllLines(args[1], new string[]
                        {
                            "procedure {:entrypoint} {:NoVerificationNecessary} dummy() { }"
                        });
                    }
                    else
                    {
                        program.writeToFile(args[1]);
                    }
                }
            }
            catch (Exception e)
            {
                //stacktrace containts source locations, confuses regressions that looks for AV_OUTPUT
                Utils.Print(String.Format("AngelicVerifier failed with: {0}", e.Message), Utils.PRINT_TAG.AV_OUTPUT);
                Utils.Print(String.Format("AngelicVerifier failed with: {0}", e.Message + e.StackTrace), Utils.PRINT_TAG.AV_DEBUG);
            }
            finally
            {
                Stats.printStats();
                Utils.Print(string.Format("TotalTime(ms) : {0}", sw.ElapsedMilliseconds), Utils.PRINT_TAG.AV_STATS);
            }
        }
예제 #15
0
파일: Program.cs 프로젝트: smackers/corral
        //TODO: collect some stats about the instrumentation, mb some debugging output??

        private static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl [options]");
                Console.WriteLine("\t /pruneMethodsWithFilePathPrefix:<absolutePath> Prune implementations whose path has this prefix");
                Console.WriteLine("\t /removeAssertsIfNoCallWithPrefix:<prefixString> Cleanup asserts if no methods prefixed with <prefixString> (e.g. ProbeFor) are present in the module");

                return;
            }

            if (args.Any(s => s == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            var pruneFilePaths = new HashSet <string>();

            args
            .Where(s => s.StartsWith("/pruneMethodsWithFilePathPrefix:"))
            .Iter(s => pruneFilePaths.Add(s.Substring("/pruneMethodsWithFilePathPrefix:".Length)));


            string cleanupPrefixString    = null;
            var    removeAssertConditions = args.Where(x => x.StartsWith("/removeAssertsIfNoCallWithPrefix:"));

            if (removeAssertConditions.Count() == 1)
            {
                cleanupPrefixString = removeAssertConditions.First().Substring("/removeAssertsIfNoCallWithPrefix:".Length);
            }
            else if (removeAssertConditions.Count() > 1)
            {
                Console.WriteLine("Expecting exactly one \"/removeAssertsIfNoCallWithPrefix:\" flag");
                return;
            }

            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;

            // read the boogie program that is to be instrumented
            var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false);

            // parse the property file
            var         propLines = File.ReadLines(args[0]);
            string      globalDeclarations;
            List <Rule> rules;

            CreateRulesFromProperty(propLines, out globalDeclarations, out rules);

            // GlobalDeclarations: add the global declarations from the property to the Boogie program
            Program dummyProg;

            Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg);
            boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations);

            //resolve the program with the new declarations which may include funcs and procs with bodies
            boogieProgram.Resolve();

            // CmdRule: find insertions sites (Commands), insert code there
            InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>());

            // InsertAtBeginningRule: find insertion sites (Procedures), insert code there
            InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>());

            // make functions with {:mkUniqueFn} unique
            (new MkUniqueFnVisitor(boogieProgram)).Visit(boogieProgram);

            //augment the CorralExtraInit procedure (perform this after Matching/instrumentation)
            AugmentCorralExtraInit(boogieProgram);

            // prune methods that match PruneFilePaths
            if (pruneFilePaths.Count() > 0)
            {
                PruneMethodsWithPaths(boogieProgram, pruneFilePaths);
            }

            // cleanup asserts if no method with prefix is present
            if (cleanupPrefixString != null)
            {
                PerformCleanupIfNoCallWithPrefix(boogieProgram, cleanupPrefixString);
            }


            string outputFile = args[2];

            BoogieUtil.PrintProgram(boogieProgram, outputFile);

            Stats.printStats();
        }
예제 #16
0
        static void Main(string[] args)
        {
            // Initialize
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;

            // Find necessary files
            if (!LocateFiles())
            {
                return;
            }

            var files    = new HashSet <string>();
            var pminargs = "";

            foreach (var arg in args)
            {
                if (arg == "/break")
                {
                    System.Diagnostics.Debugger.Launch();
                    continue;
                }

                if (arg.StartsWith("/"))
                {
                    pminargs += arg + " ";
                    continue;
                }

                // Fetch file names
                var fname   = System.IO.Path.GetFileName(arg);
                var dirname = System.IO.Path.GetDirectoryName(arg);
                if (dirname == "")
                {
                    dirname = ".";
                }
                files.UnionWith(System.IO.Directory.GetFiles(dirname, fname));
            }

            // create proofbench directory
            if (!Directory.Exists(proofbench))
            {
                Directory.CreateDirectory(proofbench);
            }
            else
            {
                Util.CleanDirectory(proofbench);
            }

            // Run duality, get proofs
            var cnt = 0;

            foreach (var file in files)
            {
                var proof = RunDuality(file);
                if (proof == null)
                {
                    continue;
                }
                BoogieUtil.PrintProgram(proof, Path.Combine(proofbench, string.Format("pf{0}.bpl", cnt++)));
            }

            Console.WriteLine("Obtained {0} proofs", cnt);
            Console.WriteLine("Running Proof Minimization");

            var res =
                Util.run(Environment.CurrentDirectory, proofMinExe, string.Format("{0} {1} /perf", Path.Combine(proofbench, "*.bpl"), pminargs));

            File.WriteAllLines("proofmin_out.txt", res);

            var templates = ParseOutput(res);

            Console.WriteLine("Inferred annotations: ");
            templates.Iter(t => Console.WriteLine("  {0}", t));
        }
예제 #17
0
        public static ReturnStatus Verify(Program program,
                                          bool needErrorTraces,
                                          out List <BoogieErrorTrace> allErrors,
                                          out List <string> timedOut,
                                          bool isCBA = false)
        {
            ReturnStatus ret = ReturnStatus.OK;

            allErrors = new List <BoogieErrorTrace>();
            timedOut  = new List <string>();
            Debug.Assert(program != null);

            // Make a copy of the input program
            var duper    = new FixedDuplicator(true);
            var origProg = new Dictionary <string, Implementation>();

            if (needErrorTraces)
            {
                foreach (var decl in program.TopLevelDeclarations)
                {
                    if (decl is Implementation)
                    {
                        var origImpl = duper.VisitImplementation(decl as Implementation);
                        origProg.Add(origImpl.Name, origImpl);
                    }
                }
            }

            if (removeAsserts)
            {
                RemoveAsserts(program);
            }

            // Set options
            options.Set();

            // save RB
            var rb = CommandLineOptions.Clo.RecursionBound;

            if (BoogieVerify.irreducibleLoopUnroll >= 0)
            {
                CommandLineOptions.Clo.RecursionBound = BoogieVerify.irreducibleLoopUnroll;
            }

            // Do loop extraction
            var extractionInfo = program.ExtractLoops();

            // restore RB
            CommandLineOptions.Clo.RecursionBound = rb;

            // set bounds
            if (options.extraRecBound != null)
            {
                options.extraRecBound.Iter(tup =>
                {
                    var impl = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, tup.Key);
                    if (impl != null)
                    {
                        impl.AddAttribute(BoogieVerify.ExtraRecBoundAttr, Expr.Literal(tup.Value));
                    }
                });
            }

            #region Save program to disk
            if (shuffleProgram)
            {
                BoogieUtil.PrintProgram(program, "last_query.bpl");
                program = BoogieUtil.ReadAndResolve("last_query.bpl");
            }

            if (options.printProg)
            {
                Debug.Assert(options.progFileName != null, "Invalid options");
                BoogieUtil.PrintProgram(program, options.progFileName);
            }
            #endregion

            var origBlocks = new Dictionary <string, Tuple <Block, Implementation> >();

            // ---------- Infer invariants --------------------------------------------------------

            // Abstract interpretation -> Always use (at least) intervals, if not specified otherwise (e.g. with the "/noinfer" switch)
            //Microsoft.Boogie.AbstractInterpretation.AbstractInterpretation.RunAbstractInterpretation(program);

            //// ---------- Verify ----------------------------------------------------------------

            var mains = new List <Implementation>(
                program.TopLevelDeclarations
                .OfType <Implementation>()
                .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint")));


            VC.VCGen vcgen = null;
            try
            {
                Debug.Assert(CommandLineOptions.Clo.StratifiedInlining > 0);
                if (options.newStratifiedInlining)
                {
                    if (options.newStratifiedInliningAlgo.ToLower() == "duality")
                    {
                        Microsoft.Boogie.SMTLib.Factory.UseInterpolation = true;
                    }
                    vcgen = new CoreLib.StratifiedInlining(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, null);
                }
                else
                // vcgen = new VC.StratifiedVCGen(options.CallTree != null, options.CallTree, options.procsToSkip, options.extraRecBound, program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List<Checker>());


                if (!useDuality || !isCBA || !needErrorTraces || options.StratifiedInlining > 1 || mains.Count > 1)
                {
                    vcgen = new VC.StratifiedVCGen(options.CallTree != null, options.CallTree, program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>());
                }
                else
                {
                    CommandLineOptions.Clo.FixedPointMode   = CommandLineOptions.FixedPointInferenceMode.Corral;
                    CommandLineOptions.Clo.FixedPointEngine = "duality";
                    vcgen = new Microsoft.Boogie.FixedpointVC(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>(), options.extraRecBound);
                }
            }
            catch (ProverException e)
            {
                Log.WriteLine(Log.Error, "ProverException: {0}", e.Message);
                return(ReturnStatus.OK);
            }

            if (!mains.Any())
            {
                throw new InternalError("No entrypoint found");
            }

            if (mains.Count > 1)
            {
                Console.WriteLine("Verifying {0} impls", mains.Count);
            }

            foreach (var impl in mains)
            {
                if (PrintImplsBeingVerified)
                {
                    Log.WriteLine(Log.Verbose, "Verifying implementation " + impl.Name);
                }

                List <Counterexample> errors;

                VC.VCGen.Outcome outcome;

                try
                {
                    var start = DateTime.Now;

                    outcome = vcgen.VerifyImplementation(impl, out errors);

                    var end = DateTime.Now;

                    TimeSpan elapsed = end - start;
                    Log.WriteLine(Log.Debug, string.Format("  [{0} s]  ", elapsed.TotalSeconds));

                    verificationTime += elapsed;
                    if (recordTempTime)
                    {
                        tempTime += elapsed;
                    }
                }
                catch (VC.VCGenException e)
                {
                    throw new InternalError("VCGenException: " + e.Message);
                    //errors = null;
                    //outcome = VC.VCGen.Outcome.Inconclusive;
                }
                catch (UnexpectedProverOutputException upo)
                {
                    throw new InternalError("Unexpected prover output: " + upo.Message);
                    //errors = null;
                    //outcome = VC.VCGen.Outcome.Inconclusive;
                }

                switch (outcome)
                {
                case VC.VCGen.Outcome.Correct:
                    break;

                case VC.VCGen.Outcome.Errors:
                    break;

                case VC.VCGen.Outcome.ReachedBound:
                    ret = ReturnStatus.ReachedBound;
                    break;

                case VC.VCGen.Outcome.Inconclusive:
                    throw new InternalError("z3 says inconclusive");

                case VC.VCGen.Outcome.OutOfMemory:
                    // wipe out any counterexamples
                    timedOut.Add(impl.Name); errors = new List <Counterexample>();
                    break;

                case VC.VCGen.Outcome.OutOfResource:
                case VC.VCGen.Outcome.TimedOut:
                    // wipe out any counterexamples
                    timedOut.Add(impl.Name); errors = new List <Counterexample>();
                    break;

                default:
                    throw new InternalError("z3 unknown response");
                }

                Log.WriteLine(Log.Debug, outcome.ToString());

                Log.WriteLine(Log.Debug, (errors == null ? 0 : errors.Count) + " counterexamples.");
                if (errors != null)
                {
                    ret = ReturnStatus.NOK;
                }

                // Print model
                if (errors != null && errors.Count > 0 && errors[0].Model != null && CommandLineOptions.Clo.ModelViewFile != null)
                {
                    var model = errors[0].Model;
                    var cnt   = 0;
                    model.States.Iter(st =>
                    {
                        if (st.Name.StartsWith("corral"))
                        {
                            st.ChangeName(st.Name + "_" + cnt.ToString()); cnt++;
                        }
                    });

                    using (var wr = new StreamWriter(CommandLineOptions.Clo.ModelViewFile, false))
                    {
                        model.Write(wr);
                    }
                }

                if (errors != null && needErrorTraces)
                {
                    for (int i = 0; i < errors.Count; i++)
                    {
                        //errors[i].Print(1, Console.Out);

                        // Map the trace across loop extraction
                        if (vcgen is VC.VCGen)
                        {
                            errors[i] = (vcgen as VC.VCGen).extractLoopTrace(errors[i], impl.Name, program, extractionInfo);
                        }

                        if (errors[i] is AssertCounterexample)
                        {
                            // Special treatment for assert counterexamples for CBA: Reconstruct
                            // trace in the input program.
                            ReconstructImperativeTrace(errors[i], impl.Name, origProg);
                            allErrors.Add(new BoogieAssertErrorTrace(errors[i] as AssertCounterexample, origProg[impl.Name], program));
                        }
                        else
                        {
                            allErrors.Add(new BoogieErrorTrace(errors[i], origProg[impl.Name], program));
                        }
                    }
                }
            }

            //PutBackAsserts(program);

            if (vcgen is StratifiedVCGen)
            {
                CallTreeSize = (vcgen as StratifiedVCGen).numInlined;
                vcSize       = (vcgen as StratifiedVCGen).vcsize;
                if (options.CallTree != null)
                {
                    options.CallTree            = VC.StratifiedVCGen.callTree;
                    VC.StratifiedVCGen.callTree = null;
                }
            }
            else if (vcgen is CoreLib.StratifiedInlining)
            {
                procsHitRecBound = (vcgen as CoreLib.StratifiedInlining).procsHitRecBound;
                CallTreeSize     = (vcgen as CoreLib.StratifiedInlining).stats.numInlined;
                vcSize           = (vcgen as CoreLib.StratifiedInlining).stats.vcSize;
                if (options.CallTree != null)
                {
                    options.CallTree = (vcgen as CoreLib.StratifiedInlining).GetCallTree();
                }
            }
            else
            {
                CallTreeSize = 0;
            }

            vcgen.Close();
            CommandLineOptions.Clo.TheProverFactory.Close();

            return(ret);
        }
예제 #18
0
        // Assumptions:
        //  - Program has no recursion
        public static HashSet <string> FindLeastToVerify(Program program, HashSet <string> boolVars)
        {
            Debug.Assert(program != null);

            RemoveAsserts(program);

            if (options.printProg)
            {
                BoogieUtil.PrintProgram(program, options.progFileName);
            }

            //// ---------- Verify ----------------------------------------------------------------
            Debug.Assert(CommandLineOptions.Clo.StratifiedInlining > 0);

            VC.StratifiedVCGenBase vcgen = null;
            try
            {
                if (options.newStratifiedInlining)
                {
                    vcgen = new CoreLib.StratifiedInlining(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, null);
                }
                else
                {
                    vcgen = new VC.StratifiedVCGen(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>());
                }
            }
            catch (ProverException)
            {
                Log.WriteLine(Log.Error, "ProverException: {0}");
                return(new HashSet <string>());
            }

            var mains = program.TopLevelDeclarations
                        .OfType <Implementation>()
                        .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"));

            if (mains.Count() != 1)
            {
                throw new InternalError("Wrong number of entrypoints for FindLeastToverify");
            }

            var main = mains.First();

            VC.VCGen.Outcome outcome;
            //HashSet<string> minVars = new HashSet<string>();

            try
            {
                var start = DateTime.Now;

                outcome = vcgen.FindLeastToVerify(main, ref boolVars);

                var end = DateTime.Now;

                TimeSpan elapsed = end - start;
                Log.WriteLine(Log.Debug, string.Format("  [{0} s]  ", elapsed.TotalSeconds));

                verificationTime += elapsed;
                if (recordTempTime)
                {
                    tempTime += elapsed;
                }
            }
            catch (VC.VCGenException e)
            {
                throw new InternalError("VCGenException: " + e.Message);
                //errors = null;
                //outcome = VC.VCGen.Outcome.Inconclusive;
            }
            catch (UnexpectedProverOutputException upo)
            {
                throw new InternalError("Unexpected prover output: " + upo.Message);
                //errors = null;
                //outcome = VC.VCGen.Outcome.Inconclusive;
            }

            switch (outcome)
            {
            case VC.VCGen.Outcome.Correct:
                break;

            case VC.VCGen.Outcome.Errors:
                Debug.Assert(false);
                break;

            case VC.VCGen.Outcome.ReachedBound:
                Debug.Assert(false);
                break;

            case VC.VCGen.Outcome.Inconclusive:
                throw new InternalError("z3 says inconclusive");

            case VC.VCGen.Outcome.OutOfMemory:
                throw new InternalError("z3 out of memory");

            case VC.VCGen.Outcome.OutOfResource:
            case VC.VCGen.Outcome.TimedOut:
                throw new InternalError("z3 timed out");

            default:
                throw new InternalError("z3 unknown response");
            }
            Debug.Assert(outcome == VC.VCGen.Outcome.Correct);

            vcgen.Close();
            CommandLineOptions.Clo.TheProverFactory.Close();
            return(boolVars);
        }
예제 #19
0
 // Write the program to a file
 public override void writeToFile(string fname)
 {
     BoogieUtil.PrintProgram(program, fname);
 }
예제 #20
0
        public override CBAProgram runCBAPass(CBAProgram p)
        {
            if (p.mode == ConcurrencyMode.FixedContext)
            {
                InstrumentationConfig.addRaiseException = false;
            }

            // Step1: Gather program information
            pinfo = new ProgramInfo(p.mainProcName, p, LanguageSemantics.assertNotReachableName());

            TidArithmetic.reset();
            if (pinfo.threadIdType.IsBv)
            {
                TidArithmetic.useIntArithmetic = false;
                p.AddTopLevelDeclaration(TidArithmetic.getBvAdd());
                p.AddTopLevelDeclaration(TidArithmetic.getBvGt());
            }
            else
            {
                TidArithmetic.useIntArithmetic = true;
            }

            // Step2: Set up a variable manager
            vmgr = new VariableManager(pinfo);

            // Step3: Set up the instrumentation policy

            // The globals not to instrument are:
            //   -- ones not modified by any procedure
            //   -- ones not shared
            //   -- ones to treat as thread-local
            HashSet <string> globalsToInstrument = new HashSet <string>();

            foreach (var g in pinfo.declaredGlobals)
            {
                string name = g.Key;
                if (!pinfo.modifiedGlobals.ContainsKey(name))
                {
                    continue;
                }
                if (!LanguageSemantics.isShared(name))
                {
                    continue;
                }
                if (pinfo.threadLocalGlobals.ContainsKey(name))
                {
                    continue;
                }
                globalsToInstrument.Add(name);
            }

            var rprocs = findRecursiveProcs(p);

            //foreach (var be in rprocs) Console.WriteLine("{0} -> {1}", be.Item1, be.Item2);

            policy =
                new InstrumentationPolicy(p.contextBound, globalsToInstrument, pinfo.procsWithImplementation, pinfo.asyncProcs, rprocs, p.mode);

            //policy.print(Log.getWriter(Log.Debug));

            // Step4: Split program declarations based on the instrumentation policy

            // skipping this step (not needed for basic CBA reduction)

            // Step5: Carry out the K-split instrumentation
            inst = new Instrumenter(policy, vmgr, pinfo, tinfo_instrument);
            List <Declaration> newDecls = inst.instrument(p.TopLevelDeclarations.ToList());

            foreach (var trp in inst.blocksWithFixedK)
            {
                blockExecutionContextMap.Add(trp.fst + "::" + trp.snd, trp.trd);
            }

            // Step6: Instrument main with initialization and the Checker
            Implementation mainProcImpl = BoogieUtil.findProcedureImpl(newDecls, p.mainProcName);

            inst.instrumentGivenMainImpl(mainProcImpl);

            // Step7: Instrument Async calls
            bool instrumentedAsync     = false;
            InstrumentAsyncCalls ainst = new InstrumentAsyncCalls(vmgr, pinfo, tinfo_async);

            foreach (var decl in newDecls)
            {
                if (decl is Implementation)
                {
                    ainst.VisitImplementation(decl as Implementation);
                    instrumentedAsync = instrumentedAsync || ainst.hasAsync;
                }
            }

            if (!instrumentedAsync)
            {
                Log.WriteLine(Log.Debug, "Warning: Did not find any async call");
            }

            // Step8: Set entrypoint
            mainProcImpl.AddAttribute("entrypoint");

            // Step9: Add new variable declarations
            newDecls.AddRange(vmgr.getNewDeclarations(policy.executionContextBound));
            newDecls.AddRange(BoogieAstFactory.newDecls);
            BoogieAstFactory.newDecls.Clear();

            // Thats it.

            Program ret = new Program();

            ret.TopLevelDeclarations = newDecls;

            if (InstrumentationConfig.printInstrumented)
            {
                // Re-resolve ret
                ProgTransformation.PersistentProgram tprog = new ProgTransformation.PersistentProgram(ret);
                var instrumented = tprog.getProgram();

                // Re-do the modsets -- make them as concise as possible.
                BoogieUtil.DoModSetAnalysis(instrumented);

                // Temporary fix for Boogie's bug while inlining calls
                // that have don't care expressions.
                RewriteCallDontCares rdc = new RewriteCallDontCares();
                rdc.VisitProgram(instrumented);

                BoogieUtil.PrintProgram(instrumented, InstrumentationConfig.instrumentedFile);

                throw new NormalExit("Printed " + InstrumentationConfig.instrumentedFile);
            }

            // Resolve the program (Do not typecheck because that does inlining).
            //BoogieUtil.PrintProgram(ret, "instrumented.bpl");
            //ret = BoogieUtil.ReadAndOnlyResolve("instrumented.bpl");
            if (p.mode == ConcurrencyMode.FixedContext)
            {
                InstrumentationConfig.addRaiseException = true;
            }

            p = new CBAProgram(ret, p.mainProcName, p.contextBound);

            return(p);
        }
예제 #21
0
            public void Run()
            {
                Implementation impl;
                var            rd = "";

                while (true)
                {
                    if (!impls.TryTake(out impl))
                    {
                        break;
                    }

                    while (!resources.TryTake(out rd))
                    {
                        Thread.Sleep(100);
                    }

                    sem.WaitOne();

                    var wd = Path.Combine(rd, impl.Name); // create new directory for each entrypoint

                    Directory.CreateDirectory(wd);        // create new directory for each entrypoint
                    RemoteExec.CleanDirectory(wd);
                    var     pruneFile = Path.Combine(wd, "pruneSlice.bpl");
                    Program newprogram;

                    // lock because Parsing a program is not thread-safe
                    lock (fslock)
                    {
                        BoogieUtil.PrintProgram(program, pruneFile);           // dump original program (so that each entrypoint has its own copy of program)
                        newprogram = BoogieUtil.ReadAndOnlyResolve(pruneFile); // entrypoint's copy of the program
                    }

                    // slice the program by entrypoints
                    Program shallowP = pruneDeepProcs(newprogram, ref edges, impl.Name, approximationDepth, implNames);
                    BoogieUtil.pruneProcs(shallowP,
                                          shallowP.TopLevelDeclarations.OfType <Procedure>()
                                          .Where(proc => BoogieUtil.checkAttrExists("entrypoint", proc.Attributes))
                                          .Select(proc => proc.Name)
                                          .FirstOrDefault());

                    File.Delete(pruneFile);
                    lock (fslock)
                    {
                        BoogieUtil.PrintProgram(shallowP, pruneFile); // dump sliced program
                    }

                    sem.Release();

                    if (Driver.createEntryPointBplsOnly)
                    {
                        Console.WriteLine("Skipping AVN run for {0} given /createEntrypointBplsOnly", impl.Name);
                        resources.Add(rd);
                        continue;
                    }
                    if (!remotedirs.Contains(rd))
                    {
                        Console.WriteLine("Running entrypoint {0} locally {{", impl.Name);

                        if (deadlineReached)
                        {
                            return;
                        }

                        // spawn the job -- local
                        var output = RemoteExec.run(wd, avnPath, string.Format("\"{0}\" {1}", pruneFile, avnArgs));

                        lock (fslock)
                        {
                            // delete temp files
                            if (!keepFiles)
                            {
                                var files = System.IO.Directory.GetFiles(wd, "*.bpl");
                                foreach (var f in files)
                                {
                                    System.IO.File.Delete(f);
                                }
                            }

                            using (StreamWriter sw = new StreamWriter(Path.Combine(wd, "stdout.txt")))
                                output.Iter(s => sw.WriteLine("{0}", s));
                        }

                        Console.WriteLine("Running entrypoint {0} locally }}", impl.Name);
                    }
                    else
                    {
                        // spawn the job -- remote
                        if (psexecPath == null)
                        {
                            throw new FileNotFoundException("Cannot find PSEXEC!");
                        }

                        // find the name of the machine from the remote folder name
                        var machine    = "";
                        var remoteroot = RemoteExec.GetRemoteFolder(rd, out machine);

                        Console.WriteLine("Running entrypoint {0} on {1} {{", impl.Name, machine);

                        // psexec machine -w remoteroot\impl remoteroot\fastavn\fastavn.exe remoteroot args
                        wd = Path.Combine(remoteroot, impl.Name);
                        var cmd = string.Format("{0} -w {1} {2} {3} {4}", machine, wd, Path.Combine(remoteroot, "fastavn", "AngelicVerifierNull.exe"),
                                                "pruneSlice.bpl", avnArgs);
                        //Console.WriteLine("PSEXEC Running: {0}", cmd);

                        if (deadlineReached)
                        {
                            return;
                        }

                        var output = RemoteExec.run(Directory.GetCurrentDirectory(), psexecPath, cmd);

                        lock (fslock)
                        {
                            // delete temp files
                            var td = Path.Combine(rd, impl.Name);
                            if (debug)
                            {
                                Console.WriteLine("Getting files in directory: {0}", td);
                            }
                            var files = System.IO.Directory.GetFiles(td, "*.bpl");
                            foreach (var f in files)
                            {
                                if (debug)
                                {
                                    Console.WriteLine("Deleting {0}", f);
                                }
                                System.IO.File.Delete(f);
                            }

                            // copy the results back
                            var ld = Path.Combine(Directory.GetCurrentDirectory(), impl.Name);
                            Directory.CreateDirectory(ld);
                            RemoteExec.CleanDirectory(ld);
                            RemoteExec.CopyFolder(rd, Directory.GetCurrentDirectory(), impl.Name, true);

                            using (StreamWriter sw = new StreamWriter(Path.Combine(ld, "stdout.txt")))
                                output.Iter(s => sw.WriteLine("{0}", s));
                        }

                        Console.WriteLine("Running entrypoint {0} on {1} }}", impl.Name, machine);
                    }

                    lock (fslock)
                    {
                        // collect and merge bugs
                        var bugs = collectBugs(Path.Combine(Directory.GetCurrentDirectory(), impl.Name, bugReportFileName));
                        bugs.Iter(b =>
                        {
                            if (!mergedBugs.ContainsKey(b))
                            {
                                mergedBugs[b] = 0;
                            }
                            mergedBugs[b] += 1;
                        });
                        Utils.Print(string.Format("Bugs found so far: {0}", mergedBugs.Count));

                        resources.Add(rd);
                    }
                }
            }
예제 #22
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("usage: SmackInst.exe infile.bpl outfile.bpl [options]");
                return;
            }

            if (args.Any(a => a == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            if (args.Any(a => a == "/initMem"))
            {
                initMem = true;
            }

            if (args.Any(a => a == "/replaceRoot"))
            {
                replaceRoot = true;
            }

            args.Where(a => a.StartsWith("/oldRoot:"))
            .Iter(a => oldRoot = a.Substring("/oldRoot:".Length));

            args.Where(a => a.StartsWith("/newRoot:"))
            .Iter(a => newRoot = a.Substring("/newRoot:".Length));

            if (args.Any(a => a == "/count"))
            {
                count = true;
            }

            if (args.Any(a => a == "/onlyCount"))
            {
                onlyCount = true;
            }

            if (args.Any(a => a == "/checkNULL"))
            {
                checkNULL = true;
            }

            if (args.Any(a => a == "/checkUAF"))
            {
                checkUAF = true;
            }

            if (args.Any(a => a == "/printCallGraph"))
            {
                printCallGraph = true;
            }

            if (args.Any(a => a == "/detectDeadCode"))
            {
                detectDeadCode = true;
            }

            if (args.Any(a => a == "/checkMemorySafety"))
            {
                checkMemSafety = true;
            }

            if (args.Any(a => a == "/visualizeHeap"))
            {
                visualizeHeap = true;
            }
            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;
            CommandLineOptions.Clo.DoModSetAnalysis  = true;


            // Read the input file
            var program = BoogieUtil.ReadAndResolve(args[0], false);

            // SMACK does not add globals to modify clauses
            //BoogieUtil.DoModSetAnalysis(program);

            if (checkMemSafety)
            {
                Procedure checkProc = program.TopLevelDeclarations.OfType <Procedure>().Where(x => x.Name == "__SMACK_check_memory_safety").FirstOrDefault();
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    if (impl.Name == "__SMACK_check_memory_safety")
                    {
                        continue;
                    }
                    if (impl.Name.StartsWith("__SMACK_static_init"))
                    {
                        continue;
                    }
                    foreach (var block in impl.Blocks)
                    {
                        //var block = impl.Blocks.FirstOrDefault();
                        var newCmds = new List <Cmd>();
                        foreach (var cmd in block.cmds)
                        {
                            if (cmd is AssignCmd)
                            {
                                var asnCmd = cmd as AssignCmd;
                                var rhs    = asnCmd.Rhss.FirstOrDefault();
                                if (rhs is NAryExpr)
                                {
                                    var fcExpr = rhs as NAryExpr;
                                    if (fcExpr.Fun.FunctionName.StartsWith("$load") || fcExpr.Fun.FunctionName.StartsWith("$store"))
                                    {
                                        char[] delim = { '.' };
                                        var    type  = fcExpr.Fun.FunctionName.Split(delim)[1];
                                        var    size  = 0;
                                        if (type == "ref")
                                        {
                                            size = 8;
                                        }
                                        else
                                        {
                                            size = Int32.Parse(type.Substring(1)) / 8;
                                        }
                                        var ptr = fcExpr.Args[1];
                                        //Console.WriteLine(ptr.ToString());
                                        var sizeExpr  = Expr.Ident(size.ToString(), btype.Int);
                                        var paramList = new List <Expr>();
                                        paramList.Add(ptr);
                                        paramList.Add(sizeExpr);
                                        var callCmd = new CallCmd(Token.NoToken, "__SMACK_check_memory_safety", paramList, new List <IdentifierExpr>());
                                        newCmds.Add(callCmd);
                                    }
                                }
                            }
                            if (cmd is CallCmd)
                            {
                                var callCmd = cmd as CallCmd;
                                if (callCmd.callee.StartsWith("corral_fix_context_"))
                                {
                                    continue;
                                }
                            }
                            if (cmd is AssertCmd)
                            {
                                continue;
                            }
                            newCmds.Add(cmd);
                        }
                        block.cmds = newCmds;
                    }
                }
                BoogieUtil.PrintProgram(program, args[1]);
                return;
            }

            if (visualizeHeap)
            {
                Procedure printProc = program.TopLevelDeclarations.OfType <Procedure>().Where(x => x.Name == "boogie_si_record_ref").FirstOrDefault();
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    if (impl.Name.StartsWith("__SMACK_static_init"))
                    {
                        continue;
                    }
                    foreach (var block in impl.Blocks)
                    {
                        //var block = impl.Blocks.FirstOrDefault();
                        var newCmds = new List <Cmd>();
                        foreach (var cmd in block.cmds)
                        {
                            if (cmd is AssignCmd)
                            {
                                var asnCmd = cmd as AssignCmd;
                                var rhs    = asnCmd.Rhss.FirstOrDefault();
                                if (rhs is NAryExpr)
                                {
                                    var fcExpr = rhs as NAryExpr;
                                    if (fcExpr.Fun.FunctionName.StartsWith("$load"))
                                    {
                                        var region = fcExpr.Args[0];
                                        if (region.ToString().Equals("$M.0"))
                                        {
                                            var         val       = asnCmd.Lhss.FirstOrDefault().AsExpr;
                                            var         ptr       = fcExpr.Args[1];
                                            List <Expr> paramList = new List <Expr>();
                                            paramList.Add(val);
                                            var           callCmd = new CallCmd(Token.NoToken, "boogie_si_record_ref", paramList, new List <IdentifierExpr>());
                                            List <Object> attrib  = new List <Object>();
                                            attrib.Add(val.ToString());
                                            callCmd.Attributes = new QKeyValue(Token.NoToken, "cexpr", attrib, callCmd.Attributes);
                                            newCmds.Add(cmd);
                                            newCmds.Add(callCmd);
                                            continue;
                                        }
                                    }
                                    if (fcExpr.Fun.FunctionName.StartsWith("$store"))
                                    {
                                        var region = fcExpr.Args[0];
                                        if (region.ToString().Equals("$M.0"))
                                        {
                                            var         val       = fcExpr.Args[2];
                                            List <Expr> paramList = new List <Expr>();
                                            paramList.Add(val);
                                            var           callCmd = new CallCmd(Token.NoToken, "boogie_si_record_ref", paramList, new List <IdentifierExpr>());
                                            List <Object> attrib  = new List <Object>();
                                            attrib.Add(val.ToString());
                                            callCmd.Attributes = new QKeyValue(Token.NoToken, "cexpr", attrib, callCmd.Attributes);
                                            newCmds.Add(callCmd);
                                        }
                                    }
                                }
                            }
                            newCmds.Add(cmd);
                        }
                        block.cmds = newCmds;
                    }
                }
                BoogieUtil.PrintProgram(program, args[1]);
                return;
            }

            if (printCallGraph)
            {
                PrintCallGraphToDot(program, "i386_immediate", "callgraph.dot");
                return;
            }

            // Preprocess program: count lines + replace Root
            program = preProcess(program, count || onlyCount, oldRoot, newRoot);

            if (onlyCount)
            {
                return;
            }

            // Process it
            program = Process(program);

            // write the output
            BoogieUtil.PrintProgram(program, args[1]);
        }