// convert {:Ebasic} to {:Ebasic n}
        void NameEnvironmentConstraints(Program program)
        {
            procsWithEnvAssumptions = new HashSet <string>();

            var cnt     = 0;
            var AddAttr = new Action <Implementation, Cmd>((impl, cmd) =>
            {
                var acmd = cmd as AssumeCmd;
                if (acmd == null)
                {
                    return;
                }
                if (!QKeyValue.FindBoolAttribute(acmd.Attributes, AvnAnnotations.EnvironmentAssumptionAttr))
                {
                    return;
                }

                acmd.Attributes = BoogieUtil.removeAttr(AvnAnnotations.EnvironmentAssumptionAttr, acmd.Attributes);
                acmd.Attributes = new QKeyValue(Token.NoToken, AvnAnnotations.EnvironmentAssumptionAttr, new List <object> {
                    Expr.Literal(cnt)
                }, acmd.Attributes);
                cnt++;
                procsWithEnvAssumptions.Add(impl.Name);
            });

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var block in impl.Blocks)
                {
                    block.Cmds.Iter(c => AddAttr(impl, c));
                }
            }
        }
예제 #2
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            var nArgs = node.Args.Select(x => base.VisitExpr(x)).ToList();

            node.Args = nArgs;
            var fcall = node.Fun as FunctionCall;

            if (fcall != null && fcall.Func.HasAttribute(ExprMatchVisitor.BoogieKeyWords.MkUniqueFn))
            {
                var formals = new List <Variable>();
                fcall.Func.InParams.Iter(a =>
                {
                    var z = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, a.Name, a.TypedIdent.Type), true);
                    formals.Add(z);
                });
                var r = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "r", fcall.Func.OutParams[0].TypedIdent.Type), false);

                var f = new Function(Token.NoToken, fcall.FunctionName + "__" + uniqFuncs.Count,
                                     formals, r);
                //inherit all attributes other than mkUniqueFn
                f.Attributes = BoogieUtil.removeAttr(ExprMatchVisitor.BoogieKeyWords.MkUniqueFn, fcall.Func.Attributes);
                f.Body       = fcall.Func.Body;
                uniqFuncs.Add(f);
                program.AddTopLevelDeclaration(f);
                node.Fun = new FunctionCall(f);
            }
            return(node);
        }
예제 #3
0
        static void MarkEntryPoint(Program program, string proc)
        {
            // remove existing entrypoints
            program.TopLevelDeclarations.OfType <NamedDeclaration>()
            .Iter(decl => decl.Attributes = BoogieUtil.removeAttr("entrypoint", decl.Attributes));

            program.TopLevelDeclarations.OfType <Implementation>()
            .Where(impl => impl.Name == proc)
            .Iter(impl => impl.Proc.AddAttribute("entrypoint"));
        }
        // Adds a new main:
        //   assertsPassed := true;
        //   call main();
        //   assert assertsPassed;
        string addMain(CBAProgram program)
        {
            var dup      = new FixedDuplicator();
            var origMain = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, program.mainProcName);
            var newMain  = dup.VisitImplementation(origMain);
            var newProc  = dup.VisitProcedure(origMain.Proc);

            newMain.Name += "_SeqInstr";
            newProc.Name += "_SeqInstr";
            newMain.Proc  = newProc;

            var mainIns = new List <Expr>();

            foreach (Variable v in newMain.InParams)
            {
                mainIns.Add(Expr.Ident(v));
            }
            var mainOuts = new List <IdentifierExpr>();

            foreach (Variable v in newMain.OutParams)
            {
                mainOuts.Add(Expr.Ident(v));
            }

            var callMain = new CallCmd(Token.NoToken, program.mainProcName, mainIns, mainOuts);

            callMain.Proc = origMain.Proc;

            var cmds = new List <Cmd>();

            cmds.Add(BoogieAstFactory.MkVarEqConst(assertsPassed, true));
            cmds.Add(callMain);
            cmds.Add(new AssertCmd(Token.NoToken, Expr.Ident(assertsPassed)));

            var blk = new Block(Token.NoToken, "start", cmds, new ReturnCmd(Token.NoToken));

            newMain.Blocks = new List <Block>();
            newMain.Blocks.Add(blk);

            program.AddTopLevelDeclaration(newProc);
            program.AddTopLevelDeclaration(newMain);

            program.mainProcName = newMain.Name;

            // Set entrypoint
            origMain.Attributes      = BoogieUtil.removeAttr("entrypoint", origMain.Attributes);
            origMain.Proc.Attributes = BoogieUtil.removeAttr("entrypoint", origMain.Proc.Attributes);

            newMain.AddAttribute("entrypoint");

            return(newMain.Name);
        }
예제 #5
0
        public void VisitImplementation(Implementation impl)
        {
            // callee -> id
            var cnt = new Dictionary <string, int>();

            foreach (var block in impl.Blocks)
            {
                var callcnt = 0;
                for (int i = 0; i < block.Cmds.Count; i++)
                {
                    var cc = block.Cmds[i] as CallCmd;
                    if (cc == null)
                    {
                        continue;
                    }

                    if (!cnt.ContainsKey(cc.callee))
                    {
                        cnt[cc.callee] = 0;
                    }

                    var uniqueId = useGlobalCounter ? counter : cnt[cc.callee];
                    var attr     = new List <object>();
                    attr.Add(new LiteralExpr(Token.NoToken, Microsoft.BaseTypes.BigNum.FromInt(uniqueId)));

                    cc.Attributes = BoogieUtil.removeAttr("si_old_unique_call", cc.Attributes);
                    var oldAttr = BoogieUtil.getAttr("si_unique_call", cc.Attributes);
                    if (oldAttr != null)
                    {
                        cc.Attributes = BoogieUtil.removeAttr("si_unique_call", cc.Attributes);
                        var newattr = new QKeyValue(Token.NoToken, "si_old_unique_call", oldAttr, null);
                        if (cc.Attributes == null)
                        {
                            cc.Attributes = newattr;
                        }
                        else
                        {
                            cc.Attributes.AddLast(newattr);
                        }
                    }

                    cc.Attributes = new QKeyValue(Token.NoToken, "si_unique_call", attr, cc.Attributes);
                    callIdToLocation.Add(Tuple.Create(impl.Name, cc.callee, uniqueId), Tuple.Create(block.Label, callcnt));

                    cnt[cc.callee]++;

                    callcnt++;
                    counter++;
                }
            }
        }
예제 #6
0
        private static bool MatchParams(ref QKeyValue toMatchAnyParamsAttributes, ref int anyParamsPosition,
                                        Dictionary <Declaration, Expr> paramSubstitution, List <Variable> toMatchInParams, List <Variable> toMatchProcInParams, List <Variable> dwfInParams, List <Variable> dwfProcInParams, bool matchPtrs)
        {
            // match procedure parameters
            for (var i = 0; i < toMatchInParams.Count; i++)
            {
                if (i == toMatchInParams.Count - 1 &&
                    BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.AnyParams, toMatchProcInParams[i].Attributes))
                {
                    toMatchAnyParamsAttributes = toMatchInParams[i].Attributes;
                    if (toMatchAnyParamsAttributes != null)
                    {
                        toMatchAnyParamsAttributes.Next = toMatchProcInParams[i].Attributes;
                    }
                    else
                    {
                        toMatchAnyParamsAttributes = toMatchProcInParams[i].Attributes;
                    }
                    toMatchAnyParamsAttributes = BoogieUtil.removeAttr(ExprMatchVisitor.BoogieKeyWords.AnyParams, toMatchAnyParamsAttributes);

                    //TODO the type may also be constrained

                    anyParamsPosition = i;
                    //don't add it to the substitution
                    continue;
                }

                // not anyParams and param counts don't match..
                if (i >= dwfInParams.Count)
                {
                    return(false);
                }
                // param types don't match
                if (!toMatchInParams[i].TypedIdent.Type.Equals(dwfInParams[i].TypedIdent.Type))
                {
                    return(false);
                }

                // if {:#MatchPtrs} attribute is present, check if pointer references match
                if (matchPtrs)
                {
                    if (!MatchPtrs(toMatchProcInParams[i], dwfProcInParams[i]))
                    {
                        return(false);
                    }
                }

                paramSubstitution.Add(toMatchInParams[i], new IdentifierExpr(Token.NoToken, dwfInParams[i]));
            }
            return(true);
        }
예제 #7
0
        private void addInlineAttribute(CBAProgram p)
        {
            foreach (var impl in p.TopLevelDeclarations.OfType <Implementation>())
            {
                if (QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"))
                {
                    continue;
                }

                var proc    = impl.Proc;
                var newattr = BoogieUtil.removeAttr("inline", proc.Attributes);

                Expr num = Expr.Literal(bound);
                var  val = new List <object>();
                val.Add(num);

                proc.Attributes = new QKeyValue(Token.NoToken, "inline", val, newattr);
            }
        }
예제 #8
0
        static Program GetProgram(string filename)
        {
            var init = GetInputProgram(filename);

            if (Options.addInitialization)
            {
                ComputeandInitializeUninitializedLocals(init);
            }

            // Do some instrumentation for the input program
            if (Options.markAssumesAsSlic)
            {
                // Mark all assumes as "slic"
                var AddAnnotation = new Action <AssumeCmd>(ac =>
                {
                    ac.Attributes = new QKeyValue(Token.NoToken, "slic", new List <object>(), ac.Attributes);
                });
                init.TopLevelDeclarations.OfType <Implementation>()
                .Iter(impl => impl.Blocks
                      .Iter(blk => blk.Cmds.OfType <AssumeCmd>()
                            .Iter(AddAnnotation)));
            }

            // Only keep assertions in assertProc procedures
            if (Options.assertProcs != null)
            {
                (new Instrumentations.PruneNonAssertProcs(Options.assertProcs)).Visit(init);
            }

            // Inline procedures supplied with {:inline} annotation
            cba.Driver.InlineProcedures(init);

            // Remove {:inline} impls
            init.RemoveTopLevelDeclarations(decl => (decl is Implementation) &&
                                            (BoogieUtil.checkAttrExists("inline", decl.Attributes) ||
                                             BoogieUtil.checkAttrExists("inline", (decl as Implementation).Proc.Attributes)));

            // Restrict entrypoints to those provided explicitly (overrides any other way to providing entryPoints)
            if (Options.entryPointProcs != null)
            {
                //only consider the user provided entry points in command line
                Options.useHarnessTag          = false;
                Options.useProvidedEntryPoints = true;
                init.TopLevelDeclarations.OfType <NamedDeclaration>()
                .Iter(d => d.Attributes = BoogieUtil.removeAttr("entrypoint", d.Attributes));
            }
            var matchesEntryPointExclude = new Func <string, bool>(s =>
            {
                return(Options.entryPointExcludes.Any(t => new System.Text.RegularExpressions.Regex(t).IsMatch(s)));
            });

            //when both entryPointProcs == null and entryPointExcludes == null, it should not add any entrypointProcs
            if (Options.entryPointProcs != null || Options.entryPointExcludes != null)
            {
                init.TopLevelDeclarations.OfType <NamedDeclaration>()
                .Where(d => d is Procedure || d is Implementation)
                .Where(d => Options.entryPointProcs == null || Options.entryPointProcs.Contains(d.Name))
                .Where(d => (Options.entryPointExcludes == null || !matchesEntryPointExclude(d.Name)))
                .Iter(d => d.AddAttribute("entrypoint"));
            }
            // Add {:entrypoint} to procs with {:harness}
            if (Options.useHarnessTag)
            {
                foreach (var decl in init.TopLevelDeclarations.OfType <NamedDeclaration>()
                         .Where(d => QKeyValue.FindBoolAttribute(d.Attributes, "harness")))
                {
                    decl.AddAttribute("entrypoint");
                }
            }

            // inlining introduces havoc statements; lets just delete them (TODO: make inlining not introduce redundant havoc statements)
            //foreach (var impl in init.TopLevelDeclarations.OfType<Implementation>())
            //{
            //    impl.Blocks.Iter(blk =>
            //        blk.Cmds.RemoveAll(cmd => cmd is HavocCmd));
            //}
            ReplaceHavocsWithNonDet(init);

            //Instrument to create the harness
            harnessInstrumentation = new Instrumentations.HarnessInstrumentation(init, AvnAnnotations.CORRAL_MAIN_PROC, Options.useProvidedEntryPoints);
            harnessInstrumentation.DoInstrument();

            //resolve+typecheck wo bothering about modSets
            CommandLineOptions.Clo.DoModSetAnalysis = true;
            init = BoogieUtil.ReResolveInMem(init);
            CommandLineOptions.Clo.DoModSetAnalysis = false;

            // Update mod sets
            BoogieUtil.DoModSetAnalysis(init);

            if (Options.AddMapSelectNonNullAssumptions)
            {
                (new Instrumentations.AssertMapSelectsNonNull()).Visit(init);
            }


            BoogieUtil.pruneProcs(init, AvnAnnotations.CORRAL_MAIN_PROC);

            if (Options.deadCodeDetect)
            {
                // Tag branches as reachable
                var tup = InstrumentBranches.Run(init, AvnAnnotations.CORRAL_MAIN_PROC, Options.UseAliasAnalysisForAngelicAssertions, false);
                init = tup.Item1;
                // TODO: inject this information into the program itself
                DeadCodeBranchesDependencyInfo = tup.Item2;
            }

            return(init);
        }
예제 #9
0
파일: Program.cs 프로젝트: zvonimir/corral
        static void Main(string[] args)
        {
            con = new Context();

            string
                inFileName           = null,
                unrolledFileName     = null,
                tidRewrittenFileName = null,
                expandedFileName     = null,
                annotatedFileName    = null,
                splitFileName        = null,
                yieldedFileName      = null,
                instantiatedFileName = null,
                finalFileName        = null,
                mhpFileName          = null,
                hmifFileName         = null;

            dbg = false;

            inFileName = parseCommandLine(args);

            string[] parts = inFileName.Split('.');
            if (parts.Count() == 1)
            {
                unrolledFileName     = inFileName + "_unrolled";
                hmifFileName         = inFileName + "_hmif";
                expandedFileName     = inFileName + "_expanded";
                tidRewrittenFileName = inFileName + "_tidRewritten";
                annotatedFileName    = inFileName + "_annotated";
                splitFileName        = inFileName + "_split";
                yieldedFileName      = inFileName + "_yielded";
                finalFileName        = inFileName + "_final";
                mhpFileName          = inFileName + "_mhp";
                instantiatedFileName = inFileName + "_inst";
            }
            else
            {
                string name = parts[0];
                unrolledFileName     = name + "_unrolled";
                hmifFileName         = name + "_hmif";
                expandedFileName     = name + "_expanded";
                annotatedFileName    = name + "_annotated";
                splitFileName        = name + "_split";
                yieldedFileName      = name + "_yielded";
                finalFileName        = name + "_final";
                mhpFileName          = name + "_mhp";
                instantiatedFileName = name + "_inst";
                tidRewrittenFileName = name + "_tidRewritten";
                for (int i = 1; i < parts.Count(); ++i)
                {
                    unrolledFileName     += "." + parts[i];
                    hmifFileName         += "." + parts[i];
                    expandedFileName     += "." + parts[i];
                    annotatedFileName    += "." + parts[i];
                    splitFileName        += "." + parts[i];
                    yieldedFileName      += "." + parts[i];
                    finalFileName        += "." + parts[i];
                    tidRewrittenFileName += "." + parts[i];
                    mhpFileName          += "." + parts[i];
                    instantiatedFileName += "." + parts[i];
                }
            }

            var tmpFileName = "og__tmp.bpl";

            ExecutionEngine.printer = new ConsolePrinter();
            //CommanLineOptions will control how boogie parses the program and gives us the IR
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.Parse(new string[] { });
            CommandLineOptions.Clo.PrintInstrumented         = true;
            CommandLineOptions.Clo.StratifiedInliningVerbose = 2;
            CommandLineOptions.Clo.UseArrayTheory            = true;
            CommandLineOptions.Clo.TypeEncodingMethod        = CommandLineOptions.TypeEncoding.Monomorphic;

            Program program;

            program = BoogieUtil.ReadAndOnlyResolve(inFileName);

            // TODO: assert that no procedure can be called in both sync and async mode!


            // Find entrypoint and initialize con
            var entry = program.TopLevelDeclarations.OfType <Procedure>()
                        .Where(proc => QKeyValue.FindBoolAttribute(proc.Attributes, "entrypoint"))
                        .FirstOrDefault();

            if (entry == null)
            {
                Console.WriteLine("Warning: No entrypoint given");
                con.entryFunc = null;
            }
            else
            {
                con.entryFunc = entry.Name;
            }

            // Remove unreachable procedures
            BoogieUtil.pruneProcs(program, con.entryFunc);

            // Extract loops
            if (extractLoops)
            {
                program.ExtractLoops();
            }

            BoogieUtil.DoModSetAnalysis(program);

            if (pruneAsserts)
            {
                program = og.GuardAsserts(program);
            }

            if (injectYields)
            {
                program = og.InsertYields(program);
            }

            if (instantiateTemplates)
            {
                var inst = new TemplateInstantiator(program);
                inst.Instantiate(program);
                program = BoogieUtil.ReResolve(program, dbg ? instantiatedFileName : tmpFileName);
            }

            var sp   = new SplitThreads(con, dbg);
            var hmif = new HowManyInstanceFinder(con, dbg);

            var split = new Converter <Program, Program>(sp.split);
            var findHowManyInstances = new Converter <Program, Program>(hmif.Compute);

            if (entry != null && splitThreads)
            {
                if (dbg)
                {
                    Console.WriteLine("Splitting procedures on thread entry: {0}", splitFileName);
                }

                program = split(program);
                program = BoogieUtil.ReResolve(program, dbg ? hmifFileName : tmpFileName);

                program = findHowManyInstances(program);
                program = BoogieUtil.ReResolve(program, dbg ? splitFileName : tmpFileName);
            }

            // Get rid of corral_yield
            program = og.RemoveCorralYield(program, con.yieldProc);


            var yieldedProgram = new ProgTransformation.PersistentProgram(program);

            if (dbg)
            {
                Console.WriteLine("Instrumenting: {0}", annotatedFileName);
            }

            if (!noTid)
            {
                program = og.InstrumentTid(program);
            }

            program = og.InstrumentAtomicBlocks(program);

            if (instrumentPermissions)
            {
                program = og.InstrumentPermissions(program);
            }

            program = BoogieUtil.ReResolve(program, dbg ? annotatedFileName : tmpFileName);

            CommandLineOptions.Clo.ContractInfer     = true;
            CommandLineOptions.Clo.AbstractHoudini   = absDomain;
            CommandLineOptions.Clo.UseProverEvaluate = true;
            CommandLineOptions.Clo.ModelViewFile     = "z3model";
            Microsoft.Boogie.Houdini.AbstractDomainFactory.Initialize(program);

            // First, do sequential
            var answer = DoInference(program, InferenceMode.SEQUENTIAL, annotatedFileName, expandedFileName);

            program = BoogieUtil.ReadAndOnlyResolve(dbg ? annotatedFileName : tmpFileName);

            // prune "true" functions
            var progFuncs = new Dictionary <string, Function>();

            program.TopLevelDeclarations.OfType <Function>()
            .Iter(f => progFuncs.Add(f.Name, f));

            var truefuncs = new List <Function>();

            foreach (var f in answer)
            {
                if (f.Body is LiteralExpr && (f.Body as LiteralExpr).IsTrue)
                {
                    truefuncs.Add(f);
                    var actualf = progFuncs[f.Name];
                    actualf.Attributes = BoogieUtil.removeAttr("existential", actualf.Attributes);
                    actualf.Body       = Expr.True;
                }
            }
            Console.WriteLine("Sequential check pruned away {0} functions, {1} remain", truefuncs.Count, answer.Count() - truefuncs.Count);

            // now do concurrent
            answer = DoInference(program, InferenceMode.CONCURRENT, annotatedFileName, expandedFileName);
            answer = answer.Concat(truefuncs);

            var provedAsserts = new Dictionary <string, bool>();

            answer.Where(func => QKeyValue.FindBoolAttribute(func.Attributes, "assertGuard"))
            .Iter(func => {
                var le = func.Body as LiteralExpr;
                System.Diagnostics.Debug.Assert(le != null);
                provedAsserts.Add(func.Name, le.IsFalse);
            });

            // remove injected existential functions
            answer = answer.Where(func => !QKeyValue.FindBoolAttribute(func.Attributes, "chignore") &&
                                  !QKeyValue.FindBoolAttribute(func.Attributes, "assertGuard"));

            if (printAssignment)
            {
                using (var tt = new TokenTextWriter(Console.Out))
                    answer.ToList().Iter(func => func.Emit(tt, 0));
            }


            if (dbg)
            {
                Console.WriteLine("Injecting invariants back into the original program: {0}", finalFileName);
            }

            program = yieldedProgram.getProgram();

            // remove existential functions
            program.RemoveTopLevelDeclarations(decl => (decl is Function) && QKeyValue.FindBoolAttribute((decl as Function).Attributes, "existential"));
            program.AddTopLevelDeclarations(answer);

            program = og.PruneProvedAsserts(program, f => provedAsserts[f]);

            // Remove ensures and requires
            program = og.RemoveRequiresAndEnsures(program);
            // Remove tid func
            program = og.RemoveThreadIdFunc(program);
            using (Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter(finalFileName))
                program.Emit(writer);
        }
예제 #10
0
            private void CreateMainProcedure(Function reach)
            {
                //blocks
                List <Block>    mainBlocks = new List <Block>();
                List <Variable> locals     = new List <Variable>();

                HashSet <Constant> blockCallConsts = new HashSet <Constant>();

                foreach (Implementation impl in prog.TopLevelDeclarations.Where(x => x is Implementation))
                {
                    // skip this impl if it is not marked as an entrypoint
                    if (useProvidedEntryPoints && !QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "entrypoint"))
                    {
                        continue;
                    }

                    impl.Attributes      = BoogieUtil.removeAttr("entrypoint", impl.Attributes);
                    impl.Proc.Attributes = BoogieUtil.removeAttr("entrypoint", impl.Proc.Attributes);

                    // skip initialization procedure
                    if (QKeyValue.FindBoolAttribute(impl.Attributes, AvnAnnotations.InitialializationProcAttr) ||
                        QKeyValue.FindBoolAttribute(impl.Proc.Attributes, AvnAnnotations.InitialializationProcAttr))
                    {
                        continue;
                    }

                    entrypoints.Add(impl.Name);

                    //allocate params
                    var args = new List <Variable>();
                    var rets = new List <Variable>();


                    impl.OutParams.ForEach(v => rets.Add(BoogieAstFactory.MkLocal(v.Name + "_" + impl.Name, v.TypedIdent.Type)));
                    if (Options.allocateParameters)
                    {
                        // use impl.Proc here to pickup scalar/pointer attributes
                        impl.Proc.InParams.ForEach(v =>
                        {
                            var l = BoogieAstFactory.MkLocal(v.Name + "_" + impl.Name, v.TypedIdent.Type);
                            // We are delibrately dropping the attributes so that
                            // all parameters are initialized by allocation
                            //l.Attributes = v.Attributes;
                            args.Add(l);
                        });
                        locals.AddRange(args);
                    }
                    else
                    {
                        impl.Proc.InParams.ForEach(v =>
                        {
                            var g = BoogieAstFactory.MkGlobal(v.Name + "_" + impl.Name, v.TypedIdent.Type);
                            //g.Attributes = v.Attributes;
                            args.Add(g);
                        });
                        globalParams.AddRange(args);
                    }


                    locals.AddRange(rets);

                    //call
                    var blockCallConst = new Constant(Token.NoToken,
                                                      new TypedIdent(Token.NoToken, "__block_call_" + impl.Name, btype.Bool), false);
                    blockCallConsts.Add(blockCallConst);
                    blockEntryPointConstants[blockCallConst.Name] = impl.Name;
                    impl2BlockingConstant[impl.Name] = blockCallConst;
                    var blockCallAssumeCmd = new AssumeCmd(Token.NoToken, IdentifierExpr.Ident(blockCallConst));

                    var cmds = new List <Cmd>();
                    cmds.Add(blockCallAssumeCmd);
                    if (Options.allocateParameters) // allocate parameters if option is enabled
                    {
                        var argMallocCmds = AllocatePointersAsUnknowns(args);
                        cmds.AddRange(argMallocCmds);
                    }

                    // The beginning of an entry point must be reachable: assume reach(true);
                    cmds.Add(new AssumeCmd(Token.NoToken, new NAryExpr(Token.NoToken,
                                                                       new FunctionCall(reach), new List <Expr> {
                        Expr.True
                    })));

                    var callCmd = new CallCmd(Token.NoToken, impl.Name, args.ConvertAll(x => (Expr)IdentifierExpr.Ident(x)),
                                              rets.ConvertAll(x => IdentifierExpr.Ident(x)));
                    callCmd.Attributes = new QKeyValue(Token.NoToken, AvUtil.AvnAnnotations.AvhEntryPointAttr, new List <object>(), callCmd.Attributes);

                    cmds.Add(callCmd);
                    //succ
                    var txCmd = new ReturnCmd(Token.NoToken);
                    var blk   = BoogieAstFactory.MkBlock(cmds, txCmd);
                    mainBlocks.Add(blk);
                }
                foreach (Procedure proc in prog.TopLevelDeclarations.OfType <Procedure>())
                {
                    proc.Attributes = BoogieUtil.removeAttr("entrypoint", proc.Attributes);
                }
                // add global variables to prog
                // globals.Iter(x => prog.AddTopLevelDeclaration(x));
                //add the constants to the prog
                blockCallConsts.Iter(x => prog.AddTopLevelDeclaration(x));
                //TODO: get globals of type refs/pointers and maps
                var initCmd = (AssumeCmd)BoogieAstFactory.MkAssume(Expr.True);

                var globalCmds = new List <Cmd>()
                {
                    initCmd
                };
                //add call to corralExtraInit
                var init = Instrumentations.GetEnvironmentAssumptionsProc(prog);

                if (init != null && !Options.DelayInitialization)
                {
                    globalCmds.Add(BoogieAstFactory.MkCall(init, new List <Expr>(), new List <Variable>()));
                }

                // Dont initialize Boogie instrumentation variables
                prog.GlobalVariables
                .Where(g => g.Name == "alloc" || BoogieUtil.checkAttrExists(AvnAnnotations.AllocatorVarAttr, g.Attributes))
                .Where(g => !BoogieUtil.checkAttrExists("scalar", g.Attributes))
                .Iter(g => g.AddAttribute("scalar"));

                // initialize globals
                prog.GlobalVariables
                .Where(g => g.Name != "alloc" && !BoogieUtil.checkAttrExists(AvnAnnotations.AllocatorVarAttr, g.Attributes))
                .Iter(g => g.Attributes = BoogieUtil.removeAttrs(new HashSet <string> {
                    "scalar", "pointer"
                }, g.Attributes));

                globalCmds.AddRange(AllocatePointersAsUnknowns(prog.GlobalVariables.Select(x => (Variable)x).ToList()));

                if (init != null && Options.DelayInitialization)
                {
                    globalCmds.Add(BoogieAstFactory.MkCall(init, new List <Expr>(), new List <Variable>()));
                }

                // globals for parameters
                prog.AddTopLevelDeclarations(globalParams);

                //first block
                var transferCmd =
                    mainBlocks.Count > 0 ? (TransferCmd)(new GotoCmd(Token.NoToken, mainBlocks)) : (TransferCmd)(new ReturnCmd(Token.NoToken));
                Block blkStart = new Block(Token.NoToken, "CorralMainStart", globalCmds, transferCmd);
                var   blocks   = new List <Block>();

                blocks.Add(blkStart);
                blocks.AddRange(mainBlocks);
                var mainProcImpl = BoogieAstFactory.MkImpl(AvnAnnotations.CORRAL_MAIN_PROC, new List <Variable>(), new List <Variable>(), locals, blocks);

                mainProcImpl[0].AddAttribute("entrypoint");
                prog.AddTopLevelDeclarations(mainProcImpl);
            }