public static void endProgVerification() { Debug.Assert(verifyingProg); verifyingProg = false; BoogieVerify.setTimeOut(0); Stats.ProgCallTreeSize = BoogieVerify.CallTreeSize; Stats.programVerificationTime += (DateTime.Now - startTime); }
// 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); }
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); } } }
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; }
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); }
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); } }
// 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); }