Esempio n. 1
0
 public static void endProgVerification()
 {
     Debug.Assert(verifyingProg);
     verifyingProg = false;
     BoogieVerify.setTimeOut(0);
     Stats.ProgCallTreeSize         = BoogieVerify.CallTreeSize;
     Stats.programVerificationTime += (DateTime.Now - startTime);
 }
Esempio n. 2
0
        // Prune away non-candidates, verify using the rest
        static BoogieVerify.ReturnStatus PruneAndRun(PersistentProgram inp, HashSet <string> candidates, out HashSet <string> assignment, ref int inlined)
        {
            var program = inp.getProgram();

            program.Typecheck();

            program = BoogieUtil.ReResolve(program);

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

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

            // Run Houdini
            var ot = CommandLineOptions.Clo.ProverKillTime;

            CommandLineOptions.Clo.ProverKillTime = HoudiniTimeout;
            assignment = CoreLib.HoudiniInlining.RunHoudini(program, true);
            CommandLineOptions.Clo.ProverKillTime = ot;
            //Console.WriteLine("  >> Contracts: {0}", assignment.Count);

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

            CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment);
            //BoogieUtil.PrintProgram(program, "si_query" + IterCnt + ".bpl");

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

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

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

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

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

            return(rstatus);
        }
Esempio n. 3
0
        public static void RunOnce(PersistentProgram inprog, bool printcontracts)
        {
            var program = inprog.getProgram();

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

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

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

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

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

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

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

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

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

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

            if (printcontracts)
            {
                foreach (var tup in contracts)
                {
                    Console.WriteLine("{0}: {1}", tup.Key, tup.Value);
                }
            }
        }
Esempio n. 4
0
        public static void beginProgVerification()
        {
            Debug.Assert(!verifyingPath && !verifyingProg);
            verifyingProg = true;

            Stats.programVerificationQueries++;

            // Set timeout
            BoogieVerify.setTimeOut(GlobalConfig.getTimeLeft());

            BoogieVerify.options = progVerifyOptions;

            // AL: adding logging
            //CommandLineOptions.Clo.ProverLogFilePath = "logProg";
            startTime = DateTime.Now;
        }
Esempio n. 5
0
        static int Main(string[] args)
        {
            CommandLineOptions.Install(new CommandLineOptions());
            int argc = args.Length;

            if (argc < 4)
            {
                System.Console.WriteLine("Boogiewrapper.exe a.bpl EQ LEFT RIGHT [v1name] [v2name] [bvdfriendly]");
                System.Console.WriteLine("\t   EQ: name of the combined procedure to be verified");
                System.Console.WriteLine("\t   RIGHT: name of the right procedure");
                System.Console.WriteLine("\t   RIGHT: name of the right procedure");
                System.Console.WriteLine("\t   viname: optional prefix of the left/right procedure (when not checking EQ_v1.foo__xx__v2.foo)");
                System.Console.WriteLine("\t   bvdfriendly: optional instrument the input file to add some captureStates for bvd to display (no checking)");
                return(-1);
            }
            string fileName = args[0];
            string funcName = args[1];

            //TODO: Make it aware of the other Boogie options
            var boogieOptions = " -doModSetAnalysis -printInstrumented -z3multipleErrors -typeEncoding:m -timeLimit:" + Options.Timeout + " -removeEmptyBlocks:0 -printModel:1 -printModelToFile:model.dmp " + Options.BoogieUserOpts;

            SDiff.Boogie.Process.InitializeBoogie(boogieOptions);

            Program prog = BoogieUtils.ParseProgram(args[0]);

            if (prog == null)
            {
                Log.Out(Log.Verifier, "Parse Error!!! in   " + args[1]);
                return(-1);
            }
            if (BoogieUtils.ResolveAndTypeCheckThrow(prog, args[0]))
            {
                return(-1);
            }
            //code duplication

            //Not having "-printInstrumented" just prints the old version of hte program!!!!
            if (args.Length == 7 && args[6] == "/bvdfriendly")
            {
                //System.Diagnostics.Debugger.Break();
                var     bvdI  = new BvdInstrument();
                Program prog1 = bvdI.VisitProgram(prog);
                if (BoogieUtils.ResolveAndTypeCheckThrow(prog, fileName))
                {
                    return(-1);
                }
                Util.DumpBplAST(prog, "merged_bvd.bpl");
                return(-1);
            }

            var newProg = prog;

            VC.ConditionGeneration vcgen = BoogieVerify.InitializeVC(newProg);
            var newDict = SDiff.Boogie.Process.BuildProgramDictionary(newProg.TopLevelDeclarations.ToList());

            //RS: Uncomment this
            var newEq = (Implementation)newDict.Get(funcName + "$IMPL");
            SDiffCounterexamples SErrors;
            List <Model>         errModelList;

            var Result = BoogieVerify.VerifyImplementation(vcgen, newEq, newProg, out SErrors, out errModelList);

            switch (Result)
            {
            case VerificationResult.Error:
                Log.Out(Log.Verifier, "Result: Error");
                break;

            case VerificationResult.Verified:
                Log.Out(Log.Verifier, "Result: Verified");
                break;

            case VerificationResult.OutOfMemory:
                Log.Out(Log.Verifier, "Result: OutOfMemory");
                return(-2);

            //break;
            case VerificationResult.TimeOut:
                Log.Out(Log.Verifier, "Result: TimeOut");
                return(-3);

            // break;
            default:
                Log.Out(Log.Verifier, "Result: Unhandled");
                return(-4);
            }
            Implementation n1, n2;

            GetImplementations(newDict, funcName, out n1, out n2, args[2], args[3]);

            var outputVars = new List <Variable>();

            foreach (Variable v in n1.OutParams)
            {
                outputVars.Add(newDict.Get(v.Name + "$VAR") as Variable);
            }
            foreach (Variable v in n2.OutParams)
            {
                outputVars.Add(newDict.Get(v.Name + "$VAR") as Variable);
            }


            var globals = new List <Variable>();

            foreach (IdentifierExpr ie in newEq.Proc.Modifies)
            {
                globals.Add(ie.Decl);
            }


            if (SErrors != null)
            {
                //somewhat misnamed...
                if (Options.DumpBeforeVerifying)
                {
                    Log.Out(Log.SymEx, "Dumping procedure under verification");
                    newEq.Emit(Log.LogWriter, 0);
                }
                if (Options.DoSymEx)
                {
                    if (Options.PreciseDifferentialInline)
                    {
                        IEnumerable <Declaration> consts = prog.TopLevelDeclarations.Where(x => x is Constant);
                        if (args.Length < 6)
                        {
                            BoogieVerify.ProcessCounterexamplesWOSymbolicOut(SErrors, globals, newEq.LocVars, null, null, consts.ToList(), errModelList);
                        }
                        else
                        {
                            BoogieVerify.ProcessCounterexamplesWOSymbolicOut(SErrors, globals, newEq.LocVars, null, null, consts.ToList(), errModelList, args[4], args[5]);
                        }
                    }
                    else
                    {
                        BoogieVerify.ProcessCounterexamples(SErrors, globals, outputVars, newProg, null, null);
                    }
                }
            }

            return(SErrors == null ? 0 : SErrors.Count);
        }
Esempio n. 6
0
        public static int RVTRunVerificationTask(SDiff.VerificationTask vt, VC.ConditionGeneration vcgen, Program prog,
                                                 HashSet <int> inlinedFns1, HashSet <int> inlinedFns2, out bool crashed)
        {
            Log.Out(Log.Verifier, "Verifying " + vt.Eq.Name);

            crashed = false;


            var attList = new List <Object>(1);

            attList.Add(Expr.Literal(1));

            //save attributes
            var sqkLeft   = vt.Left.Attributes;
            var sqkpLeft  = vt.Left.Proc.Attributes;
            var sqkRight  = vt.Right.Attributes;
            var sqkpRight = vt.Right.Proc.Attributes;

            //save postconditions
            var leftPosts  = vt.Left.Proc.Ensures;
            var rightPosts = vt.Right.Proc.Ensures;

            //Keep the postconditions correpsonding to the
            //free ensures (out == uf_Foo(inp))
            //vt.Left.Proc.Ensures = new List<Ensures>();
            //vt.Right.Proc.Ensures = new List<Ensures>();

            //inline procedures under analysis
            vt.Left.Attributes
                = Util.MkInlinedAttribute(attList);
            vt.Left.Proc.Attributes = vt.Left.Attributes;

            vt.Right.Attributes
                = Util.MkInlinedAttribute(attList);
            vt.Right.Proc.Attributes = vt.Right.Attributes;

            vt.Left.OriginalBlocks   = vt.Left.Blocks;
            vt.Left.OriginalLocVars  = vt.Left.LocVars;
            vt.Right.OriginalBlocks  = vt.Right.Blocks;
            vt.Right.OriginalLocVars = vt.Right.LocVars;


            IEnumerable <Declaration> procImplPIter = prog.TopLevelDeclarations.Where(x => x is Implementation);

            List <Implementation> inlinedImpls = new List <Implementation>();

            foreach (Implementation currentProcImpl in procImplPIter)
            {
                bool match = false;
                int  indx  = -1;
                if (fnNameToIndex1.ContainsKey(currentProcImpl.Proc.Name))
                {
                    match = true;
                    indx  = fnNameToIndex1[currentProcImpl.Proc.Name];
                }
                else if (fnNameToIndex2.ContainsKey(currentProcImpl.Proc.Name))
                {
                    match = true;
                    indx  = fnNameToIndex2[currentProcImpl.Proc.Name];
                }

                //Inline if present in
                if (match && (inlinedFns1.Contains(indx) || inlinedFns2.Contains(indx)))
                {
                    inlinedImpls.Add(currentProcImpl);
                    currentProcImpl.Attributes      = Util.MkInlinedAttribute(attList);
                    currentProcImpl.Proc.Attributes = Util.MkInlinedAttribute(attList);

                    //RUN INLINER OVER EQ FUNCTION
                    currentProcImpl.OriginalBlocks  = currentProcImpl.Blocks;
                    currentProcImpl.OriginalLocVars = currentProcImpl.LocVars;
                }
            }

            //RUN INLINER OVER EQ FUNCTION
            // prog = EQ program
            // vt.Eq = EQ_f_f' procedure with f, f' having {inline} tags
            Inliner.ProcessImplementation(prog, vt.Eq);

            if (Options.TraceVerify)
            {
                Log.Out(Log.Normal, "Ready to verify:");
                Log.LogEmit(Log.Normal, prog.Emit);
            }

            // To print the EQ files in

            Util.DumpBplAST(prog, vt.Eq.Name + "_out.bpl");
            // prog = SDiff.Boogie.Process.ParseProgram(vt.Eq.Name + "_out.bpl");

            if (BoogieUtils.ResolveAndTypeCheckThrow(prog, Options.MergedProgramOutputFile))
            {
                return(1);
            }

            Implementation newEq   = vt.Eq;
            var            newProg = prog;

            vcgen = BoogieVerify.InitializeVC(newProg);
            //SDiff.Boogie.Process.ResolveAndTypeCheck(newProg, "");
            var newDict = SDiff.Boogie.Process.BuildProgramDictionary(newProg.TopLevelDeclarations.ToList());
            //newEq = (Implementation)newDict.Get(vt.Eq.Name + "$IMPL");



            SDiffCounterexamples SErrors;
            List <Model>         errModelList;


            //Clear up the state since it might call the same procedure twice



            vt.Result = BoogieVerify.VerifyImplementation(vcgen, newEq, newProg, out SErrors, out errModelList);

            switch (vt.Result)
            {
            case SDiff.VerificationResult.Error:
                Log.Out(Log.Verifier, "Result: Error");
                break;

            case SDiff.VerificationResult.Verified:
                Log.Out(Log.Verifier, "Result: Verified");
                break;

            default:
                Log.Out(Log.Verifier, "Result: Unhandled");
                crashed = true;
                break;
            }

            //restore postconditions IN THE OLD IN-MEMORY PROGRAM
            vt.Left.Proc.Ensures  = leftPosts;
            vt.Right.Proc.Ensures = rightPosts;

            //remove the inline annotation IN THE OLD IN-MEMORY PROGRAM
            vt.Left.Attributes       = sqkLeft;
            vt.Left.Proc.Attributes  = sqkpLeft;
            vt.Right.Attributes      = sqkRight;
            vt.Right.Proc.Attributes = sqkpRight;

            //remove the inline annotation in the Inlined Procedures
            foreach (Implementation currentProcImpl in procImplPIter)
            {
                if (inlinedImpls.Contains(currentProcImpl))
                {
                    currentProcImpl.Attributes      = null;
                    currentProcImpl.Proc.Attributes = null;
                }
            }

            if (vt.Result == SDiff.VerificationResult.Verified)
            {
                return(1);
            }
            else
            {
                return(0);
            }
        }
Esempio n. 7
0
        // Prune away non-candidates, verify using the rest
        static BoogieVerify.ReturnStatus PruneAndRun(HashSet <int> candidateTemplates, out Dictionary <string, int> perf, out HashSet <string> filesVerified, out string fileFailed)
        {
            perf = new Dictionary <string, int>();

            filesVerified = new HashSet <string>();
            fileFailed    = null;

            var rest = new HashSet <string>(fileToProg.Keys);

            rest.ExceptWith(PreviousRunFailures);

            foreach (var file in PreviousRunFailures.Concat <string>(rest))
            {
                var program = fileToProg[file].getProgram();
                program.Typecheck();

                // all constants
                var allconstants = new HashSet <string>(
                    program.TopLevelDeclarations.OfType <Constant>()
                    .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, "existential"))
                    .Select(c => c.Name));

                // candidate constants
                var candidates = new HashSet <string>();
                candidateTemplates.Where(t => templateMap[t].ContainsKey(file))
                .Iter(t => candidates.UnionWith(templateMap[t][file]));

                // to keep
                var keep = fileToKeepConstants[file].Intersection(allconstants);

                var cache_try = new HashSet <string>(candidates.Concat(keep));

                IterCnt++;

                if (PreviousRun.ContainsKey(file))
                {
                    var cache_entry = PreviousRun[file];
                    if (cache_try.Count == cache_entry.Item1.Count &&
                        cache_entry.Item1.SetEquals(cache_try))
                    {
                        CacheHit++;
                        filesVerified.Add(file);
                        perf[file] = cache_entry.Item2;
                        continue;
                    }
                }

                // drop
                DropConstants(program, allconstants.Difference(candidates.Union(keep)));

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

                // Read the program again, add contracts
                program = fileToProg[file].getProgram();
                program.Typecheck();

                // Enforce the assignment back into the program
                CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment);

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

                // Set bound
                BoogieVerify.options.maxInlinedBound = 0;
                if (fileToPerf[file] != 0)
                {
                    BoogieVerify.options.maxInlinedBound = PerfMetric(fileToPerf[file]);
                }

                var rstatus = BoogieVerify.Verify(program, out err, true);
                if (dbg)
                {
                    Console.WriteLine(string.Format("  >> Procedures Inlined: {0} / {1}", BoogieVerify.CallTreeSize, BoogieVerify.options.maxInlinedBound));
                    Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2")));
                }

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

                if (rstatus != BoogieVerify.ReturnStatus.OK)
                {
                    fileFailed = file;
                    PreviousRunFailures.Add(file);
                    return(BoogieVerify.ReturnStatus.NOK);
                }

                perf[file] = procs_inlined;
                filesVerified.Add(file);

                // cache
                if (rstatus == BoogieVerify.ReturnStatus.OK)
                {
                    PreviousRun[file] = Tuple.Create(cache_try, procs_inlined);
                }
            }

            return(BoogieVerify.ReturnStatus.OK);
        }
        public static Dictionary <string, int> Compute(CBAProgram program, int max, List <string> Annotations, BoogieVerifyOptions options)
        {
            var loopBounds = new Dictionary <string, int>();

            Initialize(Annotations);
            maxBound = max;
            var start = DateTime.Now;

            // remove non-free ensures and requires
            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(proc => proc.Ensures = proc.Ensures.Filter(en => en.Free));
            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(proc => proc.Requires = proc.Requires.Filter(en => en.Free));
            // remove assertions
            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl => impl.Blocks
                  .Iter(blk => blk.Cmds = blk.Cmds.Map(c =>
            {
                var ac = c as AssertCmd;
                if (ac == null)
                {
                    return(c);
                }
                return(new AssumeCmd(ac.tok, /*ac.Expr*/ Expr.True, ac.Attributes));
            })));
            // delete yield
            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl => impl.Blocks
                  .Iter(blk => blk.Cmds.RemoveAll(c => c is YieldCmd)));

            // Call graph
            ComputeCallGraph(program);

            // Gather the set of implementations with "loop" inside their name
            var allLoopImpls = new List <Implementation>();

            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl => { if (impl.Name.Contains("loop"))
                            {
                                allLoopImpls.Add(impl);
                            }
                  });

            // Prune to the right form
            var loopImpls = allLoopImpls.Filter(CheckImpl);

            #region Process user annotations

            // Include user anntations
            var allLoops = new HashSet <string>();
            loopImpls.Iter(impl => allLoops.Add(impl.Name));
            foreach (var sp in UserAnnotations
                     .Where(s => s.StartsWith("LB:"))
                     .Select(s => s.Split(':'))
                     .Where(sp => sp.Length == 3))
            {
                // grab bound
                var bound = 0;
                if (!Int32.TryParse(sp[2], out bound))
                {
                    continue;
                }

                // grab proc
                if (!allLoops.Contains(sp[1]))
                {
                    continue;
                }

                loopBounds[sp[1]] = bound;
                Console.WriteLine("LB: Loop {0} requires minimum {1} iterations (annotated)", sp[1], bound);
            }
            loopImpls = loopImpls.Filter(impl => !loopBounds.ContainsKey(impl.Name));
            #endregion

            if (loopImpls.Count == 0)
            {
                return(loopBounds);
            }

            // Prepare query
            var query = PrepareQuery(loopImpls, program);

            // Set general options
            BoogieVerify.options = options;

            // Set rec. bound
            var oldBound = CommandLineOptions.Clo.RecursionBound;
            CommandLineOptions.Clo.RecursionBound = maxBound;

            // Query
            var allErrors = new List <BoogieErrorTrace>();
            BoogieVerify.Verify(query, out allErrors);
            foreach (var trace in allErrors)
            {
                var loopName = QKeyValue.FindStringAttribute(trace.impl.Attributes, "LB_Mapping");
                var bound    = RecBound(loopName, trace.cex, trace.impl.Name);
                if (bound <= 1)
                {
                    continue;
                }
                loopBounds.Add(loopName, bound);
                Console.WriteLine("LB: Loop {0} requires minimum {1} iterations", loopName, bound);
            }

            CommandLineOptions.Clo.RecursionBound = oldBound;
            timeTaken = (DateTime.Now - start);

            return(loopBounds);
        }