예제 #1
0
        // Verify that the trace is a valid counterexample (i.e., it returns an assertion-failure counterexample
        // upon verification.
        // Returns a program that consists of a single implementation with a single basic
        // block that contains the trace.
        public bool verifyTrace(out Program newProg)
        {
            // Currently, this only works for intraprocedural traces
            Debug.Assert(acex.calleeCounterexamples.Count == 0);

            HashSet <string> calledProcs;
            Implementation   traceImpl = getImplementation(out calledProcs);

            newProg = new Program();

            // The set of called procedures should only be ones
            // that do not have an implementation
            foreach (Declaration decl in prog.TopLevelDeclarations)
            {
                if (decl is GlobalVariable)
                {
                    newProg.AddTopLevelDeclaration(decl);
                }
                else if (decl is Procedure)
                {
                    Procedure tmp = decl as Procedure;
                    if (calledProcs.Contains(tmp.Name))
                    {
                        newProg.AddTopLevelDeclaration(decl);
                    }
                    else if (tmp.Name == impl.Name)
                    {
                        Procedure pex = new Procedure(Token.NoToken, tmp.Name + "_cex", tmp.TypeParameters, tmp.InParams,
                                                      tmp.OutParams, tmp.Requires, tmp.Modifies, tmp.Ensures, tmp.Attributes);
                        newProg.AddTopLevelDeclaration(pex);
                    }
                }
                else if (decl is Implementation)
                {
                    Implementation tmp = decl as Implementation;
                    Debug.Assert(!calledProcs.Contains(tmp.Name));
                }
                else
                {
                    // Just add the other guys (axioms, functions, etc.)
                    newProg.AddTopLevelDeclaration(decl);
                }
            }

            newProg.AddTopLevelDeclaration(traceImpl);

            newProg = BoogieUtil.ReResolve(newProg, "cex.bpl");
            Program newProgCopy = BoogieUtil.ReadAndResolve("cex.bpl");
            // (We need to create a copy because Boogie.Verify changes the input program)

            var errors = new List <BoogieErrorTrace>();
            var ret    = BoogieVerify.Verify(newProgCopy, out errors);

            if (ret != BoogieVerify.ReturnStatus.NOK)
            {
                return(false);
            }

            return(true);
        }
예제 #2
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]);
        }
예제 #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
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: SplitRMT.exe file.bpl");
                return;
            }

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

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

            // check input
            foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>())
            {
                if (proc.Requires.Any(req => !req.Free))
                {
                    Console.WriteLine("Error: non-free requires not yet supported");
                    return;
                }
            }

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

            if (eplist.Count() != 1)
            {
                Console.WriteLine("Error: Unique entrypoint not found");
                return;
            }

            var main = eplist.First();

            Console.WriteLine("Entrypoint: {0}", main.Name);

            // entrypoint + all assumes
            MarkAllAssumes(program, args[0]);

            // split on asserted postconditions
            var cnt = Split(program, args[0]);

            Console.WriteLine("Produced {0} file(s) after splitting", cnt);
        }
예제 #5
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]);
            }
        }
예제 #6
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();
        }
예제 #7
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();
        }
예제 #8
0
파일: Program.cs 프로젝트: zvonimir/corral
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: RunEE file.bpl options");
                return;
            }

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

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

            if (program.TopLevelDeclarations.OfType <Implementation>().Count() != 1)
            {
                Console.WriteLine("Error: input program must have exactly one implementation");
            }

            var flags = "";

            for (int i = 1; i < args.Length; i++)
            {
                if (args[i] == "/break")
                {
                    System.Diagnostics.Debugger.Launch();
                    continue;
                }
                flags += args[i] + " ";
            }

            ExplainError.STATUS                 status;
            Dictionary <string, string>         complexObj;
            HashSet <List <Expr> >              preDisjuncts;
            List <Tuple <string, int, string> > eeSlicedSourceLines;

            var explain = ExplainError.Toplevel.Go(program.TopLevelDeclarations.OfType <Implementation>().First(),
                                                   program, ExplainErrorTimeout, ExplainErrorFilters, flags, null, new HashSet <AssumeCmd>(),
                                                   out status, out complexObj, out preDisjuncts, out eeSlicedSourceLines);

            if (status == ExplainError.STATUS.SUCCESS && explain.Count > 0)
            {
                var aliasingExplanation = "";

                for (int i = 0; i < explain.Count; i++)
                {
                    if (i == 0)
                    {
                        aliasingExplanation += "\n    ";
                    }
                    else
                    {
                        aliasingExplanation += "\nor  ";
                    }

                    aliasingExplanation += explain[i].TrimEnd(' ', '\t').Replace(' ', '_').Replace("\t", "_and_");
                }

                if (complexObj.Any())
                {
                    aliasingExplanation += "\nwhere";
                    foreach (var tup in complexObj)
                    {
                        var str = string.Format("   {0} = {1}", tup.Value, tup.Key);
                        aliasingExplanation += "^" + str.Replace(' ', '_');
                    }
                }
                Console.WriteLine("EE returned SUCCESS");
                Console.WriteLine("{0}", aliasingExplanation);
            }
            else
            {
                Console.WriteLine("EE returned status: {0}", status);
            }
        }
예제 #9
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);
        }
예제 #10
0
파일: Program.cs 프로젝트: smackers/corral
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: HoudiniLite.exe file.bpl [options]");
                return;
            }
            var file       = args[0];
            var boogieArgs = "";
            var check      = false;
            var dual       = false;

            for (int i = 1; i < args.Length; i++)
            {
                if (args[i] == "/break")
                {
                    System.Diagnostics.Debugger.Launch();
                    continue;
                }
                if (args[i] == "/check")
                {
                    check = true;
                    continue;
                }
                if (args[i] == "/dual")
                {
                    dual = true;
                    continue;
                }
                boogieArgs += args[i] + " ";
            }
            Initalize(boogieArgs);
            if (dual)
            {
                HoudiniInlining.DualHoudini = true;
            }

            var sw = new Stopwatch();

            sw.Start();

            var assignment = new HashSet <string>();

            try
            {
                assignment = HoudiniInlining.RunHoudini(BoogieUtil.ReadAndResolve(file), true);
            }
            catch (DualHoudiniFail e)
            {
                Console.WriteLine("DualHoudini failed to prove anything useful: {0}", e.Message);
            }

            sw.Stop();

            Console.WriteLine("HoudiniLite took: {0} seconds", sw.Elapsed.TotalSeconds.ToString("F2"));
            HoudiniStats.Print();
            Console.WriteLine("Num true = {0}", assignment.Count);
            if (CommandLineOptions.Clo.PrintAssignment)
            {
                Console.WriteLine("True assignment: {0}", assignment.Concat(" "));
            }

            if (check)
            {
                sw.Restart();

                CommandLineOptions.Install(new CommandLineOptions());
                CommandLineOptions.Clo.PrintInstrumented = true;
                CommandLineOptions.Clo.UseSubsumption    = CommandLineOptions.SubsumptionOption.Never;
                CommandLineOptions.Clo.ContractInfer     = true;
                BoogieUtil.InitializeBoogie(boogieArgs);

                var actual = RunBoogieHoudini(BoogieUtil.ReadAndResolve(file));

                sw.Stop();

                Console.WriteLine("Houdini took: {0} seconds", sw.Elapsed.TotalSeconds.ToString("F2"));

                if (!assignment.Equals(actual))
                {
                    Console.WriteLine("Constants proved by us but not houdini: {0}", assignment.Difference(actual).Concat(" "));
                    Console.WriteLine("Constants proved by houdini but not us: {0}", actual.Difference(assignment).Concat(" "));
                }
            }
        }
예제 #11
0
파일: Min.cs 프로젝트: zvonimir/corral
        public static void ReadFiles(IEnumerable <string> files, HashSet <string> keepPatterns)
        {
            foreach (var f in files)
            {
                Program program;
                try
                {
                    program = BoogieUtil.ReadAndResolve(f);
                }
                catch (cba.Util.InvalidProg)
                {
                    continue;
                }
                CheckRMT(program);

                fileToKeepConstants.Add(f, new HashSet <string>());

                // Add annotations
                foreach (var p in keepPatterns)
                {
                    var re = new Regex(p);
                    program.TopLevelDeclarations.OfType <Constant>()
                    .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, "existential") && re.IsMatch(c.Name))
                    .Iter(c =>
                    {
                        c.AddAttribute(Driver.MustKeepAttr);
                        fileToKeepConstants[f].Add(c.Name);
                    });
                }

                // Prune, according to annotations
                DropConstants(program, new HashSet <string>(
                                  program.TopLevelDeclarations.OfType <Constant>()
                                  .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, Driver.DropAttr))
                                  .Select(c => c.Name)));

                var allconstants = new Dictionary <string, Constant>();
                program.TopLevelDeclarations.OfType <Constant>()
                .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, "existential"))
                .Iter(c => allconstants.Add(c.Name, c));

                // Normalize expressions
                if (!SimplifyExpr.SimplifyToCNF)
                {
                    program.TopLevelDeclarations.OfType <Implementation>()
                    .Iter(impl => impl.Proc.Ensures.Iter(ens => SimplifyExpr.SimplifyEnsures(ens, allconstants)));
                }
                else
                {
                    var constants = new HashSet <string>(allconstants.Keys);
                    program.TopLevelDeclarations.OfType <Implementation>()
                    .Iter(impl => impl.Proc.Ensures = SimplifyExpr.SimplifyEnsures(impl.Proc.Ensures, allconstants));
                    allconstants.Where(tup => !constants.Contains(tup.Key))
                    .Iter(tup => program.AddTopLevelDeclaration(tup.Value));
                }
                // Remove constants that don't hold -- optimization
                HashSet <string> consts = new HashSet <string>(allconstants.Keys);
                HashSet <string> assignment;
                int perf = 0;

                if (Driver.InitBound > 0)
                {
                    perf = Driver.InitBound;
                }

                var ret = PruneAndRun(new PersistentProgram(program), consts, out assignment, ref perf);

                if (ret != BoogieVerify.ReturnStatus.OK)
                {
                    Console.WriteLine("Warning: Program {0} doesn't have an initial inductive proof", f);
                    continue;
                }

                // anything not in assignment can be dropped
                DropConstants(program, consts.Difference(assignment));
                consts.Difference(assignment).Iter(s => allconstants.Remove(s));
                fileToKeepConstants[f].IntersectWith(assignment);

                Console.WriteLine("File {0} defines {1} constants ({2} dropped)", f, assignment.Count, consts.Count - assignment.Count);

                // initial perf
                fileToPerf.Add(f, perf);

                // create template map
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    foreach (var ens in impl.Proc.Ensures.Where(e => !e.Free))
                    {
                        string constantName = null;
                        Expr   expr         = null;
                        var    isloop       = QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "LoopProcedure");

                        var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant(
                            ens.Condition, allconstants.Keys, out constantName, out expr);

                        if (!match)
                        {
                            continue;
                        }
                        if (fileToKeepConstants[f].Contains(constantName))
                        {
                            continue;
                        }

                        var priorTemplateId = QKeyValue.FindIntAttribute(ens.Attributes, "template", -1);
                        var temp            = SimplifyExpr.ExprToTemplateGeneral(expr);
                        if (strToTemplate.ContainsKey(temp))
                        {
                            // template for it exists
                            addTemplate(strToTemplate[temp], f, constantName, Tuple.Create(isloop, expr));
                        }
                        else
                        {
                            // create new template
                            strToTemplate.Add(temp, TemplateCounterStart + strToTemplate.Count);
                            addTemplate(strToTemplate[temp], f, constantName, Tuple.Create(isloop, expr));
                        }
                        if (priorTemplateId != -1)
                        {
                            priorFullyInstantiatedTemplates.Add(strToTemplate[temp]);
                        }
                    }
                }

                // stash the program
                fileToProg.Add(f, new PersistentProgram(program));
            }

            templateToStr = new Dictionary <int, string>();
            strToTemplate.Iter(tup => templateToStr.Add(tup.Value, tup.Key));

            Console.WriteLine("Found {0} templates", templateMap.Count);

            if (dbg)
            {
                foreach (var tup in templateMap)
                {
                    Console.WriteLine("Template {0} :: {1}", tup.Key, templateToStr[tup.Key]);
                    foreach (var tup2 in tup.Value)
                    {
                        Console.WriteLine("  File {0}", tup2.Key);
                        tup2.Value.Iter(c => Console.WriteLine("    Candidate {0}", c));
                    }
                }
            }
        }
예제 #12
0
        static void Main(string[] args)
        {
            Console.CancelKeyPress += Console_CancelKeyPress;

            if (args.Length < 1)
            {
                Console.WriteLine("ProofMin file(s).bpl [options]");
                return;
            }

            var boogieArgs     = "";
            var once           = false;
            var printcontracts = false;
            var keepPatterns   = new HashSet <string>();
            var filePatterns   = new HashSet <string>();

            for (int i = 0; i < args.Length; i++)
            {
                if (!args[i].StartsWith("/") && args[i].EndsWith(".bpl"))
                {
                    filePatterns.Add(args[i]);
                    continue;
                }

                if (args[i].StartsWith("/files:"))
                {
                    filePatterns.UnionWith(
                        System.IO.File.ReadAllLines(args[i].Substring("/files:".Length)));
                    continue;
                }

                if (args[i] == "/break")
                {
                    System.Diagnostics.Debugger.Launch();
                    continue;
                }
                if (args[i] == "/once")
                {
                    once = true;
                    continue;
                }
                if (args[i] == "/noSI")
                {
                    Minimize.useSI   = false;
                    Minimize.usePerf = 2.0;
                    continue;
                }
                if (args[i] == "/dbg")
                {
                    dbg          = true;
                    Minimize.dbg = true;
                    continue;
                }
                if (args[i] == "/printAssignment")
                {
                    printcontracts = true;
                    continue;
                }

                if (args[i].StartsWith("/keep:"))
                {
                    keepPatterns.Add(args[i].Substring("/keep:".Length));
                    continue;
                }

                if (args[i].StartsWith("/initBound:"))
                {
                    InitBound = Int32.Parse(args[i].Substring("/initBound:".Length));
                    continue;
                }

                if (args[i] == "/perf")
                {
                    Minimize.usePerf = 2.0;
                    continue;
                }

                if (args[i] == "/cnf")
                {
                    SimplifyExpr.SimplifyToCNF = true;
                    continue;
                }

                if (args[i].StartsWith("/perf:"))
                {
                    Minimize.usePerf = double.Parse(args[i].Substring("/perf:".Length));
                    continue;
                }

                boogieArgs += args[i] + " ";
            }

            // Initialize Boogie
            boogieArgs += " /typeEncoding:m /weakArrayTheory /errorLimit:1 ";
            Initalize(boogieArgs);

            // Get the input files
            var files = new HashSet <string>();

            foreach (var fp in filePatterns)
            {
                var fname   = System.IO.Path.GetFileName(fp);
                var dirname = System.IO.Path.GetDirectoryName(fp);
                if (dirname == "")
                {
                    dirname = ".";
                }
                files.UnionWith(System.IO.Directory.GetFiles(dirname, fname));
            }

            if (files.Count == 0)
            {
                Console.WriteLine("No files given");
                return;
            }
            Console.WriteLine("Found {0} files", files.Count);

            if (once)
            {
                Debug.Assert(files.Count() == 1);
                RunOnce(new PersistentProgram(BoogieUtil.ReadAndResolve(files.First(), true)), printcontracts);
                return;
            }

            Minimize.sw.Start();
            Minimize.ReadFiles(files, keepPatterns);

            Dictionary <int, int> templateToPerfDelta = new Dictionary <int, int>();
            HashSet <int>         min = new HashSet <int>();

            var dropped            = new HashSet <int>();
            var ApplyTemplatesDone = false;

            do
            {
                do
                {
                    Dictionary <int, int> t2d;
                    var min2 = Minimize.FindMin(dropped, out t2d);

                    // dropped
                    var templates = new HashSet <int>(Minimize.templateToStr.Keys);
                    dropped = templates.Difference(min2);

                    // merge perf
                    foreach (var tup in t2d)
                    {
                        if (!templateToPerfDelta.ContainsKey(tup.Key))
                        {
                            templateToPerfDelta.Add(tup.Key, tup.Value);
                        }
                        else
                        {
                            templateToPerfDelta[tup.Key] += tup.Value;
                        }
                    }

                    Console.WriteLine("Obtained minimal templates, at size {0}", min2.Count);

                    if (min.SetEquals(min2))
                    {
                        Console.WriteLine("Reached fixpoint; we're done");
                        break;
                    }

                    min = min2;

                    Console.WriteLine("Contemplating re-running with broken down templates");

                    var rerun = false;
                    Minimize.candidateToCost = new Dictionary <int, int>();
                    var newTemplates = new HashSet <int>();
                    min2.Iter(t => { var b = Minimize.PruneDisjuncts(t, ref newTemplates); rerun |= b; });

                    if (!rerun)
                    {
                        Console.WriteLine("Nothing to break; we're done");
                        break;
                    }

                    dropped.ExceptWith(newTemplates);
                    Console.WriteLine("Rerunning Minimization");
                } while (true);

                if (ApplyTemplatesDone)
                {
                    break;
                }
                ApplyTemplatesDone = true;

                // compute common set of globals
                var rr = Minimize.ApplyTemplates(min.Difference(Minimize.priorFullyInstantiatedTemplates));
                if (!rr)
                {
                    break;
                }
            } while (true);

            foreach (var c in min)
            {
                Console.WriteLine("Template to origin info for {0} : {1}", c, Minimize.templateToStr[c]);
                if (!Minimize.templateToOriginExpr.ContainsKey(c) || Minimize.templateToOriginExpr[c].Count == 0)
                {
                    continue;
                }
                foreach (var tup in Minimize.templateToOriginExpr[c])
                {
                    Console.WriteLine("  {0}{1}", tup.Item1 ? "{:loop} " : "", tup.Item2.ToString());
                }
            }


            foreach (var c in min)
            {
                var    gen = Minimize.templateToStr[c];
                string ret = gen;
                if (Minimize.templateToOriginExpr.ContainsKey(c) && Minimize.templateToOriginExpr[c].Count != 0)
                {
                    var isloop = Minimize.templateToOriginExpr[c].All(tup => tup.Item1);
                    var exprs  = Minimize.templateToOriginExpr[c].Select(tup => SimplifyExpr.ExprToTemplateSpecific(tup.Item2, isloop));
                    ret = exprs.First();
                    ret = exprs.All(s => s == ret) ? ret : gen;
                    ret = isloop ? string.Format("{{:loop}} {0}", ret) : ret;
                }
                Console.WriteLine("Additional contract required: {0}", ret);
            }

            foreach (var tup in templateToPerfDelta)
            {
                if (tup.Value <= 2)
                {
                    continue;
                }
                Console.WriteLine("Contract to pref: {0} {1}", tup.Value, Minimize.templateToStr[tup.Key]);
            }

            Console.WriteLine("Cache hits on calls to PruneAndRun: {0} / {1}", Minimize.CacheHit, Minimize.IterCnt);
        }
예제 #13
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]);
        }