// precondition: pathProgram has a single implementation
        // Suppress an assertion (that failed in the pathProgram) and
        // return its token
        public AssertToken SuppressAssert(Program pathProgram)
        {
            var impl = pathProgram.TopLevelDeclarations.OfType <Implementation>()
                       .First();

            var tokenId = -1;

            foreach (var acmd in impl.Blocks[0].Cmds.OfType <PredicateCmd>())
            {
                tokenId = QKeyValue.FindIntAttribute(acmd.Attributes, "avn", -1);
                if (tokenId == -1)
                {
                    continue;
                }
                break;
            }

            Debug.Assert(tokenId != -1);
            var token = new AssertToken(tokenId);

            SuppressToken(token);

            BoogieUtil.DoModSetAnalysis(currProg);

            suppressedTokens.Add(token);

            return(token);
        }
예제 #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;
        }
        // Unsuppress assertions (inverse of SuppressAllButOneProcedure)
        public void Unsuppress()
        {
            foreach (var token in tempSuppressedTokens)
            {
                if (suppressedTokens.Contains(token))
                {
                    continue;
                }
                UnsuppressToken(token);
            }
            tempSuppressedTokens = new HashSet <AssertToken>();

            BoogieUtil.DoModSetAnalysis(currProg);
        }
예제 #4
0
        public override CBAProgram runCBAPass(CBAProgram p)
        {
            // Type information is needed in some cases. For instance, the Command
            // Mem[x] := untracked-expr is converted to havoc temp; Mem[x] := temp. Here
            // we need the type of "untracked-expr" or of "Mem[x]"
            if (p.Typecheck() != 0)
            {
                p.Emit(new TokenTextWriter("error.bpl"));
                throw new InternalError("Type errors");
            }
            vslice.VisitProgram(p as Program);
            BoogieUtil.DoModSetAnalysis(p);

            return(p);
        }
예제 #5
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);
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #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)));
            }

            // 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)));

            // 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));
            }

            //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.ReResolve(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
        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);
        }
        public override CBAProgram runCBAPass(CBAProgram program)
        {
            // Add blanks
            blanksInfo = AddBlanks(program);

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

            if (!Options.TraceSlicing)
            {
                // Remove source line annotations
                sourceInfo = cba.PrintSdvPath.DeleteSourceInfo(program);
            }
            else
            {
                sourceInfo = null;
            }

            // Remove print info
            //printInfo = cba.PrintSdvPath.DeletePrintCmds(program);

            // Compress
            compressBlocks.VisitProgram(program);

            // name Ebasic
            NameEnvironmentConstraints(program);

            // Instrument assertions
            int tokenId = 0;

            origMainName = program.mainProcName;

            CBAProgram ret = null;

            if (!Options.DeepAsserts)
            {
                // Do error-bit instrumentation
                var impls = BoogieUtil.nameImplMapping(program);
                var pwa   = cba.SequentialInstrumentation.procsWithAsserts(program);

                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    var instrumented = new List <Block>();
                    foreach (var blk in impl.Blocks)
                    {
                        var currCmds  = new List <Cmd>();
                        var currLabel = blk.Label;

                        assertInstrInfo.addTrans(impl.Name, blk.Label, blk.Label);
                        var incnt = -1;
                        foreach (Cmd cmd in blk.Cmds)
                        {
                            incnt++;

                            // instrument assert
                            if (cmd is AssertCmd && !BoogieUtil.isAssertTrue(cmd))
                            {
                                currCmds.Add(BoogieAstFactory.MkVarEqExpr(assertsPassed, (cmd as AssertCmd).Expr));

                                var token = new AssertToken(tokenId);
                                originalAssertions.Add(token, cmd as AssertCmd);
                                tokenLocation.Add(token, Tuple.Create(impl.Name, currLabel));
                                procToTokens.InitAndAdd(impl.Name, token);

                                addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds);

                                currLabel = addInstr(instrumented, currCmds, currLabel, tokenId);
                                tokenId++;
                                currCmds = new List <Cmd>();

                                continue;
                            }

                            // procedure call
                            if (cmd is CallCmd && pwa.Contains((cmd as CallCmd).callee))
                            {
                                currCmds.Add(cmd);
                                addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds);
                                currLabel = addInstr(instrumented, currCmds, currLabel, -1);
                                currCmds  = new List <Cmd>();
                                continue;
                            }

                            currCmds.Add(cmd);
                            addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds);
                        }

                        instrumented.Add(new Block(Token.NoToken, currLabel, currCmds, blk.TransferCmd));
                    }

                    impl.Blocks = instrumented;
                }

                program.AddTopLevelDeclaration(assertsPassed);
                var newMain = addMain(program);

                BoogieUtil.DoModSetAnalysis(program);

                // Set inline attribute
                // free requires assertsPassed == true;
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    impl.Proc.Requires.Add(new Requires(true, Expr.Ident(assertsPassed)));
                }

                // convert free ensures e to:
                //  free ensures assertsPassed == false || e
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()
                         .Where(impl => pwa.Contains(impl.Name)))
                {
                    foreach (Ensures ens in impl.Proc.Ensures)
                    {
                        ens.Condition = Expr.Or(Expr.Not(Expr.Ident(assertsPassed)), ens.Condition);
                    }
                }

                currProg = program;
                ret      = new CBAProgram(program, newMain, 0);
            }
            else
            {
                // Use Deep-assert instrumentation
                da = new cba.DeepAssertRewrite();

                // First, tag assertions with tokens
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    foreach (var blk in impl.Blocks)
                    {
                        foreach (var cmd in blk.Cmds.OfType <AssertCmd>())
                        {
                            if (BoogieUtil.isAssertTrue(cmd))
                            {
                                continue;
                            }

                            var token = new AssertToken(tokenId);
                            cmd.Attributes = new QKeyValue(Token.NoToken, "avn", new List <object> {
                                Expr.Literal(tokenId)
                            },
                                                           cmd.Attributes);
                            originalAssertions.Add(token, cmd);
                            tokenLocation.Add(token, Tuple.Create(impl.Name, blk.Label));
                            procToTokens.InitAndAdd(impl.Name, token);
                            tokenId++;
                        }
                    }
                }

                // Second, do the rewrite
                var t1     = new PersistentProgram(program, program.mainProcName, program.contextBound);
                var t2     = da.run(t1);
                var daprog = t2.getCBAProgram();

                // Third, revisit the assertions and remember their location
                // in the output program. This is a bit of a hack. The "tokenLocation"
                // of a token is the pair (p1,b1) where p1 is the procedure the assertion
                // originally came from and b1 is the block in the new main that contains
                // that assertion.
                var main = BoogieUtil.findProcedureImpl(daprog.TopLevelDeclarations, daprog.mainProcName);
                foreach (var block in main.Blocks)
                {
                    foreach (var cmd in block.Cmds.OfType <AssertCmd>())
                    {
                        var tok = QKeyValue.FindIntAttribute(cmd.Attributes, "avn", -1);
                        if (tok < 0)
                        {
                            continue;
                        }
                        var token = new AssertToken(tok);

                        Debug.Assert(tokenLocation.ContainsKey(token));
                        var oldloc = tokenLocation[token];
                        tokenLocation[token] = Tuple.Create(oldloc.Item1, block.Label);
                    }
                }

                currProg = daprog;
                ret      = daprog;
            }

            return(ret);
        }
예제 #11
0
파일: Min.cs 프로젝트: zvonimir/corral
        public static bool ApplyTemplates(HashSet <int> templates)
        {
            var commonGlobals = Minimize.FindCommonGlobals();
            var ret           = false;

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

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

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

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

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

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

                var newconstants = new HashSet <Constant>();

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

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

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

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

                        ret = true;
                        templateToConstants[t]++;

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

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

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

            return(ret);
        }