public static bool BoogieOnce(string baseFile, string moduleName, Bpl.Program boogieProgram, string programId, out PipelineStatistics stats, out PipelineOutcome oc) { if (programId == null) { programId = "main_program_id"; } programId += "_" + moduleName; string bplFilename; if (CommandLineOptions.Clo.PrintFile != null) { bplFilename = CommandLineOptions.Clo.PrintFile; } else { string baseName = cce.NonNull(Path.GetFileName(baseFile)); baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl")); bplFilename = Path.Combine(Path.GetTempPath(), baseName); } bplFilename = BoogieProgramSuffix(bplFilename, moduleName); stats = null; oc = BoogiePipelineWithRerun(boogieProgram, bplFilename, out stats, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? programId : null); return (oc == PipelineOutcome.Done || oc == PipelineOutcome.VerificationCompleted) && stats.ErrorCount == 0 && stats.InconclusiveCount == 0 && stats.TimeoutCount == 0 && stats.OutOfMemoryCount == 0; }
public PipelineOutcome VerifyProgram(Dafny.Program program, IList<string> fileNames, string programId, out PipelineStatistics stats, out List<ErrorInformation> errorList, out ErrorInformation errorInfo) { Microsoft.Boogie.Program boogieProgram; Translate(program, Thread.CurrentThread.Name, out boogieProgram); var po = BoogiePipeline(boogieProgram, fileNames, programId, out stats, out errorList); errorInfo = errorList.FirstOrDefault(); return po; }
/// <summary> /// Pipeline the boogie program to Dafny where it is valid /// </summary> /// <returns>Exit value</returns> public static Bpl.PipelineOutcome BoogiePipeline(Bpl.Program program, IList <string> fileNames, string programId, Bpl.ErrorReporterDelegate er, out Bpl.PipelineStatistics stats, out List <Bpl.ErrorInformation> errorList, Program tmpDafnyProgram = null) { Contract.Requires(program != null); Contract.Ensures(0 <= Contract.ValueAtReturn(out stats).InconclusiveCount&& 0 <= Contract.ValueAtReturn(out stats).TimeoutCount); Bpl.LinearTypeChecker ltc; Bpl.CivlTypeChecker ctc; string baseName = cce.NonNull(Path.GetFileName(fileNames[fileNames.Count - 1])); baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl")); string bplFileName = Path.Combine(Path.GetTempPath(), baseName); errorList = new List <Bpl.ErrorInformation>(); stats = new Bpl.PipelineStatistics(); Bpl.PipelineOutcome oc = Bpl.ExecutionEngine.ResolveAndTypecheck(program, bplFileName, out ltc, out ctc); switch (oc) { case Bpl.PipelineOutcome.ResolvedAndTypeChecked: Bpl.ExecutionEngine.EliminateDeadVariables(program); Bpl.ExecutionEngine.CollectModSets(program); Bpl.ExecutionEngine.CoalesceBlocks(program); Bpl.ExecutionEngine.Inline(program); errorList = new List <Bpl.ErrorInformation>(); var tmp = new List <Bpl.ErrorInformation>(); oc = Bpl.ExecutionEngine.InferAndVerify(program, stats, programId, errorInfo => { tmp.Add(errorInfo); er?.Invoke(new CompoundErrorInformation(errorInfo.Tok, errorInfo.Msg, errorInfo, tmpDafnyProgram)); }); errorList.AddRange(tmp); return(oc); default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected outcome } }
/// <summary> /// Pipeline the boogie program to Dafny where it is valid /// </summary> /// <returns>Exit value</returns> public PipelineOutcome BoogiePipeline(Bpl.Program program, IList<string> fileNames, string programId, out PipelineStatistics stats, out List<ErrorInformation> errorList) { Contract.Requires(program != null); Contract.Ensures(0 <= Contract.ValueAtReturn(out stats).InconclusiveCount && 0 <= Contract.ValueAtReturn(out stats).TimeoutCount); LinearTypeChecker ltc; CivlTypeChecker ctc; string baseName = cce.NonNull(Path.GetFileName(fileNames[fileNames.Count - 1])); baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl")); string bplFileName = Path.Combine(Path.GetTempPath(), baseName); errorList = new List<ErrorInformation>(); stats = new PipelineStatistics(); if (TacnyOptions.O.ParallelExecution) mut.WaitOne(); PipelineOutcome oc = ExecutionEngine.ResolveAndTypecheck(program, bplFileName, out ltc, out ctc); switch (oc) { case PipelineOutcome.ResolvedAndTypeChecked: ExecutionEngine.EliminateDeadVariables(program); ExecutionEngine.CollectModSets(program); ExecutionEngine.CoalesceBlocks(program); ExecutionEngine.Inline(program); errorList = new List<ErrorInformation>(); var tmp = new List<ErrorInformation>(); oc = ExecutionEngine.InferAndVerify(program, stats, programId, errorInfo => { tmp.Add(errorInfo); }); errorList.AddRange(tmp); if (TacnyOptions.O.ParallelExecution) mut.ReleaseMutex(); return oc; default: if (TacnyOptions.O.ParallelExecution) mut.ReleaseMutex(); return oc; //Contract.Assert(false); throw new cce.UnreachableException(); // unexpected outcome } }
public static void ProcessFiles(List<string> fileNames, bool lookForSnapshots = true, string programId = null) { Contract.Requires(cce.NonNullElements(fileNames)); if (programId == null) { programId = "main_program_id"; } if (CommandLineOptions.Clo.VerifySeparately && 1 < fileNames.Count) { foreach (var f in fileNames) { ProcessFiles(new List<string> { f }, lookForSnapshots, f); } return; } if (0 <= CommandLineOptions.Clo.VerifySnapshots && lookForSnapshots) { var snapshotsByVersion = LookForSnapshots(fileNames); foreach (var s in snapshotsByVersion) { ProcessFiles(new List<string>(s), false, programId); } return; } using (XmlFileScope xf = new XmlFileScope(CommandLineOptions.Clo.XmlSink, fileNames[fileNames.Count - 1])) { Program program = ParseBoogieProgram(fileNames, false); if (program == null) return; if (CommandLineOptions.Clo.PrintFile != null) { PrintBplFile(CommandLineOptions.Clo.PrintFile, program, false, true, CommandLineOptions.Clo.PrettyPrint); } LinearTypeChecker linearTypeChecker; CivlTypeChecker civlTypeChecker; PipelineOutcome oc = ResolveAndTypecheck(program, fileNames[fileNames.Count - 1], out linearTypeChecker, out civlTypeChecker); if (oc != PipelineOutcome.ResolvedAndTypeChecked) return; if (CommandLineOptions.Clo.PrintCFGPrefix != null) { foreach (var impl in program.Implementations) { using (StreamWriter sw = new StreamWriter(CommandLineOptions.Clo.PrintCFGPrefix + "." + impl.Name + ".dot")) { sw.Write(program.ProcessLoops(impl).ToDot()); } } } if (CommandLineOptions.Clo.StratifiedInlining == 0) { Concurrency.Transform(linearTypeChecker, civlTypeChecker); (new LinearEraser()).VisitProgram(program); if (CommandLineOptions.Clo.CivlDesugaredFile != null) { int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured; CommandLineOptions.Clo.PrintUnstructured = 1; PrintBplFile(CommandLineOptions.Clo.CivlDesugaredFile, program, false, false, CommandLineOptions.Clo.PrettyPrint); CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured; } } EliminateDeadVariables(program); CoalesceBlocks(program); Inline(program); var stats = new PipelineStatistics(); oc = InferAndVerify(program, stats, 1 < CommandLineOptions.Clo.VerifySnapshots ? programId : null); switch (oc) { case PipelineOutcome.Done: case PipelineOutcome.VerificationCompleted: printer.WriteTrailer(stats); break; default: break; } } }
public void WriteTrailer(PipelineStatistics stats) { Contract.Requires(stats != null); Contract.Requires(0 <= stats.VerifiedCount && 0 <= stats.ErrorCount && 0 <= stats.InconclusiveCount && 0 <= stats.TimeoutCount && 0 <= stats.OutOfMemoryCount); Console.WriteLine(); if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed) { Console.Write("{0} finished with {1} credible, {2} doomed{3}", CommandLineOptions.Clo.DescriptiveToolName, stats.VerifiedCount, stats.ErrorCount, stats.ErrorCount == 1 ? "" : "s"); } else { Console.Write("{0} finished with {1} verified, {2} error{3}", CommandLineOptions.Clo.DescriptiveToolName, stats.VerifiedCount, stats.ErrorCount, stats.ErrorCount == 1 ? "" : "s"); } if (stats.InconclusiveCount != 0) { Console.Write(", {0} inconclusive{1}", stats.InconclusiveCount, stats.InconclusiveCount == 1 ? "" : "s"); } if (stats.TimeoutCount != 0) { Console.Write(", {0} time out{1}", stats.TimeoutCount, stats.TimeoutCount == 1 ? "" : "s"); } if (stats.OutOfMemoryCount != 0) { Console.Write(", {0} out of memory", stats.OutOfMemoryCount); } Console.WriteLine(); Console.Out.Flush(); }
/// <summary> /// Given a resolved and type checked Boogie program, infers invariants for the program /// and then attempts to verify it. Returns: /// - Done if command line specified no verification /// - FatalError if a fatal error occurred, in which case an error has been printed to console /// - VerificationCompleted if inference and verification completed, in which the out /// parameters contain meaningful values /// </summary> public static PipelineOutcome InferAndVerify(Program program, PipelineStatistics stats, string programId = null, ErrorReporterDelegate er = null, string requestId = null) { Contract.Requires(program != null); Contract.Requires(stats != null); Contract.Ensures(0 <= Contract.ValueAtReturn(out stats.InconclusiveCount) && 0 <= Contract.ValueAtReturn(out stats.TimeoutCount)); if (requestId == null) { requestId = FreshRequestId(); } var start = DateTime.UtcNow; #region Do some pre-abstract-interpretation preprocessing on the program // Doing lambda expansion before abstract interpretation means that the abstract interpreter // never needs to see any lambda expressions. (On the other hand, if it were useful for it // to see lambdas, then it would be better to more lambda expansion until after infererence.) if (CommandLineOptions.Clo.ExpandLambdas) { LambdaHelper.ExpandLambdas(program); //PrintBplFile ("-", program, true); } #endregion #region Infer invariants using Abstract Interpretation // Always use (at least) intervals, if not specified otherwise (e.g. with the "/noinfer" switch) if (CommandLineOptions.Clo.UseAbstractInterpretation) { if (!CommandLineOptions.Clo.Ai.J_Intervals && !CommandLineOptions.Clo.Ai.J_Trivial) { // use /infer:j as the default CommandLineOptions.Clo.Ai.J_Intervals = true; } } Microsoft.Boogie.AbstractInterpretation.NativeAbstractInterpretation.RunAbstractInterpretation(program); #endregion #region Do some post-abstract-interpretation preprocessing on the program (e.g., loop unrolling) if (CommandLineOptions.Clo.LoopUnrollCount != -1) { program.UnrollLoops(CommandLineOptions.Clo.LoopUnrollCount, CommandLineOptions.Clo.SoundLoopUnrolling); } Dictionary<string, Dictionary<string, Block>> extractLoopMappingInfo = null; if (CommandLineOptions.Clo.ExtractLoops) { extractLoopMappingInfo = program.ExtractLoops(); } if (CommandLineOptions.Clo.PrintInstrumented) { program.Emit(new TokenTextWriter(Console.Out, CommandLineOptions.Clo.PrettyPrint)); } #endregion if (!CommandLineOptions.Clo.Verify) { return PipelineOutcome.Done; } #region Run Houdini and verify if (CommandLineOptions.Clo.ContractInfer) { return RunHoudini(program, stats, er); } #endregion #region Select and prioritize implementations that should be verified var impls = program.Implementations.Where( impl => impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification); // operate on a stable copy, in case it gets updated while we're running Implementation[] stablePrioritizedImpls = null; if (0 < CommandLineOptions.Clo.VerifySnapshots) { OtherDefinitionAxiomsCollector.Collect(program.Axioms); DependencyCollector.Collect(program); stablePrioritizedImpls = impls.OrderByDescending( impl => impl.Priority != 1 ? impl.Priority : Cache.VerificationPriority(impl)).ToArray(); } else { stablePrioritizedImpls = impls.OrderByDescending(impl => impl.Priority).ToArray(); } #endregion if (1 < CommandLineOptions.Clo.VerifySnapshots) { CachedVerificationResultInjector.Inject(program, stablePrioritizedImpls, requestId, programId, out stats.CachingActionCounts); } #region Verify each implementation var outputCollector = new OutputCollector(stablePrioritizedImpls); var outcome = PipelineOutcome.VerificationCompleted; try { var cts = new CancellationTokenSource(); RequestIdToCancellationTokenSource.AddOrUpdate(requestId, cts, (k, ov) => cts); var tasks = new Task[stablePrioritizedImpls.Length]; // We use this semaphore to limit the number of tasks that are currently executing. var semaphore = new SemaphoreSlim(CommandLineOptions.Clo.VcsCores); // Create a task per implementation. for (int i = 0; i < stablePrioritizedImpls.Length; i++) { var taskIndex = i; var id = stablePrioritizedImpls[taskIndex].Id; CancellationTokenSource old; if (ImplIdToCancellationTokenSource.TryGetValue(id, out old)) { old.Cancel(); } ImplIdToCancellationTokenSource.AddOrUpdate(id, cts, (k, ov) => cts); var t = new Task((dummy) => { try { if (outcome == PipelineOutcome.FatalError) { return; } if (cts.Token.IsCancellationRequested) { cts.Token.ThrowIfCancellationRequested(); } VerifyImplementation(program, stats, er, requestId, extractLoopMappingInfo, stablePrioritizedImpls, taskIndex, outputCollector, Checkers, programId); ImplIdToCancellationTokenSource.TryRemove(id, out old); } finally { semaphore.Release(); } }, cts.Token, TaskCreationOptions.None); tasks[taskIndex] = t; } // Execute the tasks. int j = 0; for (; j < stablePrioritizedImpls.Length && outcome != PipelineOutcome.FatalError; j++) { try { semaphore.Wait(cts.Token); } catch (OperationCanceledException) { break; } tasks[j].Start(TaskScheduler.Default); } // Don't wait for tasks that haven't been started yet. tasks = tasks.Take(j).ToArray(); Task.WaitAll(tasks); } catch (AggregateException ae) { ae.Handle(e => { var pe = e as ProverException; if (pe != null) { printer.ErrorWriteLine(Console.Out, "Fatal Error: ProverException: {0}", e); outcome = PipelineOutcome.FatalError; return true; } var oce = e as OperationCanceledException; if (oce != null) { return true; } return false; }); } finally { CleanupCheckers(requestId); } cce.NonNull(CommandLineOptions.Clo.TheProverFactory).Close(); outputCollector.WriteMoreOutput(); if (1 < CommandLineOptions.Clo.VerifySnapshots && programId != null) { program.FreezeTopLevelDeclarations(); programCache.Set(programId, program, policy); } if (0 <= CommandLineOptions.Clo.VerifySnapshots && CommandLineOptions.Clo.TraceCachingForBenchmarking) { var end = DateTime.UtcNow; if (TimePerRequest.Count == 0) { FirstRequestStart = start; } TimePerRequest[requestId] = end.Subtract(start); StatisticsPerRequest[requestId] = stats; var printTimes = true; Console.Out.WriteLine(CachedVerificationResultInjector.Statistics.Output(printTimes)); Console.Out.WriteLine("Statistics per request as CSV:"); var actions = string.Join(", ", Enum.GetNames(typeof(VC.ConditionGeneration.CachingAction))); Console.Out.WriteLine("Request ID{0}, Error, E (C), Inconclusive, I (C), Out of Memory, OoM (C), Timeout, T (C), Verified, V (C), {1}", printTimes ? ", Time (ms)" : "", actions); foreach (var kv in TimePerRequest.OrderBy(kv => ExecutionEngine.AutoRequestId(kv.Key))) { var s = StatisticsPerRequest[kv.Key]; var cacs = s.CachingActionCounts; var c = cacs != null ? ", " + cacs.Select(ac => string.Format("{0,3}", ac)).Concat(", ") : ""; var t = printTimes ? string.Format(", {0,8:F0}", kv.Value.TotalMilliseconds) : ""; Console.Out.WriteLine("{0,-19}{1}, {2,2}, {3,2}, {4,2}, {5,2}, {6,2}, {7,2}, {8,2}, {9,2}, {10,2}, {11,2}{12}", kv.Key, t, s.ErrorCount, s.CachedErrorCount, s.InconclusiveCount, s.CachedInconclusiveCount, s.OutOfMemoryCount, s.CachedOutOfMemoryCount, s.TimeoutCount, s.CachedTimeoutCount, s.VerifiedCount, s.CachedVerifiedCount, c); } if (printTimes) { Console.Out.WriteLine(); Console.Out.WriteLine("Total time (ms) since first request: {0:F0}", end.Subtract(FirstRequestStart).TotalMilliseconds); } } #endregion if (SecureVCGen.outfile != null) SecureVCGen.outfile.Close(); return outcome; }
private static void UpdateStatistics(PipelineStatistics stats, VC.VCGen.Outcome outcome, List<Counterexample> errors, bool wasCached) { Contract.Requires(stats != null); switch (outcome) { default: Contract.Assert(false); // unexpected outcome throw new cce.UnreachableException(); case VCGen.Outcome.ReachedBound: Interlocked.Increment(ref stats.VerifiedCount); if (wasCached) { Interlocked.Increment(ref stats.CachedVerifiedCount); } break; case VCGen.Outcome.Correct: Interlocked.Increment(ref stats.VerifiedCount); if (wasCached) { Interlocked.Increment(ref stats.CachedVerifiedCount); } break; case VCGen.Outcome.TimedOut: Interlocked.Increment(ref stats.TimeoutCount); if (wasCached) { Interlocked.Increment(ref stats.CachedTimeoutCount); } break; case VCGen.Outcome.OutOfMemory: Interlocked.Increment(ref stats.OutOfMemoryCount); if (wasCached) { Interlocked.Increment(ref stats.CachedOutOfMemoryCount); } break; case VCGen.Outcome.Inconclusive: Interlocked.Increment(ref stats.InconclusiveCount); if (wasCached) { Interlocked.Increment(ref stats.CachedInconclusiveCount); } break; case VCGen.Outcome.Errors: if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed) { Interlocked.Increment(ref stats.ErrorCount); if (wasCached) { Interlocked.Increment(ref stats.CachedErrorCount); } } else { Interlocked.Add(ref stats.ErrorCount, errors.Count); if (wasCached) { Interlocked.Add(ref stats.CachedErrorCount, errors.Count); } } break; } }
private static void VerifyImplementation(Program program, PipelineStatistics stats, ErrorReporterDelegate er, string requestId, Dictionary<string, Dictionary<string, Block>> extractLoopMappingInfo, Implementation[] stablePrioritizedImpls, int index, OutputCollector outputCollector, List<Checker> checkers, string programId) { Implementation impl = stablePrioritizedImpls[index]; VerificationResult verificationResult = null; var output = new StringWriter(); printer.Inform("", output); // newline printer.Inform(string.Format("Verifying {0} ...", impl.Name), output); int priority = 0; var wasCached = false; if (0 < CommandLineOptions.Clo.VerifySnapshots) { var cachedResults = Cache.Lookup(impl, out priority); if (cachedResults != null && priority == Priority.SKIP) { if (CommandLineOptions.Clo.XmlSink != null) { CommandLineOptions.Clo.XmlSink.WriteStartMethod(impl.Name, cachedResults.Start); } printer.Inform(string.Format("Retrieving cached verification result for implementation {0}...", impl.Name), output); if (CommandLineOptions.Clo.VerifySnapshots < 3 || cachedResults.Outcome == ConditionGeneration.Outcome.Correct) { verificationResult = cachedResults; wasCached = true; } } } if (!wasCached) { #region Verify the implementation verificationResult = new VerificationResult(requestId, impl, programId); using (var vcgen = CreateVCGen(program, checkers)) { vcgen.CachingActionCounts = stats.CachingActionCounts; verificationResult.ProofObligationCountBefore = vcgen.CumulativeAssertionCount; verificationResult.Start = DateTime.UtcNow; if (CommandLineOptions.Clo.XmlSink != null) { CommandLineOptions.Clo.XmlSink.WriteStartMethod(impl.Name, verificationResult.Start); } try { if (CommandLineOptions.Clo.inferLeastForUnsat != null) { var svcgen = vcgen as VC.StratifiedVCGen; Contract.Assert(svcgen != null); var ss = new HashSet<string>(); foreach (var c in program.Constants) { if (!c.Name.StartsWith(CommandLineOptions.Clo.inferLeastForUnsat)) continue; ss.Add(c.Name); } verificationResult.Outcome = svcgen.FindLeastToVerify(impl, ref ss); verificationResult.Errors = new List<Counterexample>(); output.WriteLine("Result: {0}", string.Join(" ", ss)); } else { verificationResult.Outcome = vcgen.VerifyImplementation(impl, out verificationResult.Errors, requestId); if (CommandLineOptions.Clo.ExtractLoops && verificationResult.Errors != null) { var vcg = vcgen as VCGen; if (vcg != null) { for (int i = 0; i < verificationResult.Errors.Count; i++) { verificationResult.Errors[i] = vcg.extractLoopTrace(verificationResult.Errors[i], impl.Name, program, extractLoopMappingInfo); } } } } } catch (VCGenException e) { var errorInfo = errorInformationFactory.CreateErrorInformation(impl.tok, String.Format("{0} (encountered in implementation {1}).", e.Message, impl.Name), requestId, "Error"); errorInfo.BoogieErrorCode = "BP5010"; errorInfo.ImplementationName = impl.Name; printer.WriteErrorInformation(errorInfo, output); if (er != null) { lock (er) { er(errorInfo); } } verificationResult.Errors = null; verificationResult.Outcome = VCGen.Outcome.Inconclusive; } catch (UnexpectedProverOutputException upo) { printer.AdvisoryWriteLine("Advisory: {0} SKIPPED because of internal error: unexpected prover output: {1}", impl.Name, upo.Message); verificationResult.Errors = null; verificationResult.Outcome = VCGen.Outcome.Inconclusive; } verificationResult.ProofObligationCountAfter = vcgen.CumulativeAssertionCount; verificationResult.End = DateTime.UtcNow; } #endregion #region Cache the verification result if (0 < CommandLineOptions.Clo.VerifySnapshots && !string.IsNullOrEmpty(impl.Checksum)) { Cache.Insert(impl, verificationResult); } #endregion } #region Process the verification results and statistics ProcessOutcome(verificationResult.Outcome, verificationResult.Errors, TimeIndication(verificationResult), stats, output, impl.TimeLimit, er, verificationResult.ImplementationName, verificationResult.ImplementationToken, verificationResult.RequestId, wasCached); ProcessErrors(verificationResult.Errors, verificationResult.Outcome, output, er, impl); if (CommandLineOptions.Clo.XmlSink != null) { CommandLineOptions.Clo.XmlSink.WriteEndMethod(verificationResult.Outcome.ToString().ToLowerInvariant(), verificationResult.End, verificationResult.End - verificationResult.Start); } outputCollector.Add(index, output); outputCollector.WriteMoreOutput(); if (verificationResult.Outcome == VCGen.Outcome.Errors || CommandLineOptions.Clo.Trace) { Console.Out.Flush(); } #endregion }
private static PipelineOutcome RunAbstractHoudini(Program program, PipelineStatistics stats, ErrorReporterDelegate er) { Contract.Requires(stats != null); //CommandLineOptions.Clo.PrintErrorModel = 1; CommandLineOptions.Clo.UseProverEvaluate = true; CommandLineOptions.Clo.ModelViewFile = "z3model"; CommandLineOptions.Clo.UseArrayTheory = true; CommandLineOptions.Clo.TypeEncodingMethod = CommandLineOptions.TypeEncoding.Monomorphic; Houdini.AbstractDomainFactory.Initialize(program); var domain = Houdini.AbstractDomainFactory.GetInstance(CommandLineOptions.Clo.AbstractHoudini); // Run Abstract Houdini var abs = new Houdini.AbsHoudini(program, domain); var absout = abs.ComputeSummaries(); ProcessOutcome(absout.outcome, absout.errors, "", stats, Console.Out, CommandLineOptions.Clo.ProverKillTime, er); ProcessErrors(absout.errors, absout.outcome, Console.Out, er); //Houdini.PredicateAbs.Initialize(program); //var abs = new Houdini.AbstractHoudini(program); //abs.computeSummaries(new Houdini.PredicateAbs(program.TopLevelDeclarations.OfType<Implementation>().First().Name)); return PipelineOutcome.Done; }
private static PipelineOutcome RunStagedHoudini(Program program, PipelineStatistics stats, ErrorReporterDelegate er) { Houdini.HoudiniSession.HoudiniStatistics houdiniStats = new Houdini.HoudiniSession.HoudiniStatistics(); Houdini.StagedHoudini stagedHoudini = new Houdini.StagedHoudini(program, houdiniStats, ProgramFromFile); Houdini.HoudiniOutcome outcome = stagedHoudini.PerformStagedHoudiniInference(); if (CommandLineOptions.Clo.PrintAssignment) { Console.WriteLine("Assignment computed by Houdini:"); foreach (var x in outcome.assignment) { Console.WriteLine(x.Key + " = " + x.Value); } } if (CommandLineOptions.Clo.Trace) { int numTrueAssigns = 0; foreach (var x in outcome.assignment) { if (x.Value) numTrueAssigns++; } Console.WriteLine("Number of true assignments = " + numTrueAssigns); Console.WriteLine("Number of false assignments = " + (outcome.assignment.Count - numTrueAssigns)); Console.WriteLine("Prover time = " + houdiniStats.proverTime.ToString("F2")); Console.WriteLine("Unsat core prover time = " + houdiniStats.unsatCoreProverTime.ToString("F2")); Console.WriteLine("Number of prover queries = " + houdiniStats.numProverQueries); Console.WriteLine("Number of unsat core prover queries = " + houdiniStats.numUnsatCoreProverQueries); Console.WriteLine("Number of unsat core prunings = " + houdiniStats.numUnsatCorePrunings); } foreach (Houdini.VCGenOutcome x in outcome.implementationOutcomes.Values) { ProcessOutcome(x.outcome, x.errors, "", stats, Console.Out, CommandLineOptions.Clo.ProverKillTime, er); ProcessErrors(x.errors, x.outcome, Console.Out, er); } return PipelineOutcome.Done; }
private static PipelineOutcome RunMLHoudini(Program program, PipelineStatistics stats, ErrorReporterDelegate er, string filename) { Contract.Requires(stats != null); //CommandLineOptions.Clo.PrintErrorModel = 1; CommandLineOptions.Clo.UseProverEvaluate = true; CommandLineOptions.Clo.ModelViewFile = "z3model"; CommandLineOptions.Clo.UseArrayTheory = true; CommandLineOptions.Clo.TypeEncodingMethod = CommandLineOptions.TypeEncoding.Monomorphic; // Run Abstract Houdini var mlice = new Houdini.MLHoudini(program, CommandLineOptions.Clo.MLHoudini, filename); var mliceout = mlice.ComputeSummaries(); ProcessOutcome(mliceout.outcome, mliceout.errors, "", stats, Console.Out, CommandLineOptions.Clo.ProverKillTime, er); ProcessErrors(mliceout.errors, mliceout.outcome, Console.Out, er); return PipelineOutcome.Done; }
public static void Compile(string fileName, ReadOnlyCollection<string> otherFileNames, Program dafnyProgram, PipelineOutcome oc, PipelineStatistics stats, bool verified) { var resultFileName = DafnyOptions.O.DafnyPrintCompiledFile ?? fileName; switch (oc) { case PipelineOutcome.VerificationCompleted: ExecutionEngine.printer.WriteTrailer(stats); if ((DafnyOptions.O.Compile && verified && CommandLineOptions.Clo.ProcsToCheck == null) || DafnyOptions.O.ForceCompile) CompileDafnyProgram(dafnyProgram, resultFileName, otherFileNames); break; case PipelineOutcome.Done: ExecutionEngine.printer.WriteTrailer(stats); if (DafnyOptions.O.ForceCompile) CompileDafnyProgram(dafnyProgram, resultFileName, otherFileNames); break; default: // error has already been reported to user break; } }
public void WriteTrailer(PipelineStatistics stats) { }
/// <summary> /// Resolve, type check, infer invariants for, and verify the given Boogie program. /// The intention is that this Boogie program has been produced by translation from something /// else. Hence, any resolution errors and type checking errors are due to errors in /// the translation. /// The method prints errors for resolution and type checking errors, but still returns /// their error code. /// </summary> static PipelineOutcome BoogiePipelineWithRerun(Bpl.Program/*!*/ program, string/*!*/ bplFileName, out PipelineStatistics stats, string programId) { Contract.Requires(program != null); Contract.Requires(bplFileName != null); Contract.Ensures(0 <= Contract.ValueAtReturn(out stats).InconclusiveCount && 0 <= Contract.ValueAtReturn(out stats).TimeoutCount); stats = new PipelineStatistics(); LinearTypeChecker ltc; CivlTypeChecker ctc; PipelineOutcome oc = ExecutionEngine.ResolveAndTypecheck(program, bplFileName, out ltc, out ctc); switch (oc) { case PipelineOutcome.Done: return oc; case PipelineOutcome.ResolutionError: case PipelineOutcome.TypeCheckingError: { ExecutionEngine.PrintBplFile(bplFileName, program, false, false, CommandLineOptions.Clo.PrettyPrint); Console.WriteLine(); Console.WriteLine("*** Encountered internal translation error - re-running Boogie to get better debug information"); Console.WriteLine(); List<string/*!*/>/*!*/ fileNames = new List<string/*!*/>(); fileNames.Add(bplFileName); Bpl.Program reparsedProgram = ExecutionEngine.ParseBoogieProgram(fileNames, true); if (reparsedProgram != null) { ExecutionEngine.ResolveAndTypecheck(reparsedProgram, bplFileName, out ltc, out ctc); } } return oc; case PipelineOutcome.ResolvedAndTypeChecked: ExecutionEngine.EliminateDeadVariables(program); ExecutionEngine.CollectModSets(program); ExecutionEngine.CoalesceBlocks(program); ExecutionEngine.Inline(program); return ExecutionEngine.InferAndVerify(program, stats, programId); default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected outcome } }
/// <summary> /// Given a resolved and type checked Boogie program, infers invariants for the program /// and then attempts to verify it. Returns: /// - Done if command line specified no verification /// - FatalError if a fatal error occurred, in which case an error has been printed to console /// - VerificationCompleted if inference and verification completed, in which the out /// parameters contain meaningful values /// </summary> public static PipelineOutcome InferAndVerify(Program program, PipelineStatistics stats, string filename, ErrorReporterDelegate er = null, string requestId = "unknown") { Contract.Requires(program != null); Contract.Requires(stats != null); Contract.Ensures(0 <= Contract.ValueAtReturn(out stats.InconclusiveCount) && 0 <= Contract.ValueAtReturn(out stats.TimeoutCount)); if (requestId == null) { requestId = "unknown"; } RequestIdToCancellationTokenSources[requestId] = new List<CancellationTokenSource>(); #region Infer invariants using Abstract Interpretation // Always use (at least) intervals, if not specified otherwise (e.g. with the "/noinfer" switch) if (CommandLineOptions.Clo.UseAbstractInterpretation) { if (!CommandLineOptions.Clo.Ai.J_Intervals && !CommandLineOptions.Clo.Ai.J_Trivial) { // use /infer:j as the default CommandLineOptions.Clo.Ai.J_Intervals = true; } } Microsoft.Boogie.AbstractInterpretation.NativeAbstractInterpretation.RunAbstractInterpretation(program); #endregion #region Do some preprocessing on the program (e.g., loop unrolling, lambda expansion) if (CommandLineOptions.Clo.LoopUnrollCount != -1) { program.UnrollLoops(CommandLineOptions.Clo.LoopUnrollCount, CommandLineOptions.Clo.SoundLoopUnrolling); } Dictionary<string, Dictionary<string, Block>> extractLoopMappingInfo = null; if (CommandLineOptions.Clo.ExtractLoops) { extractLoopMappingInfo = program.ExtractLoops(); } if (CommandLineOptions.Clo.PrintInstrumented) { program.Emit(new TokenTextWriter(Console.Out)); } if (CommandLineOptions.Clo.ExpandLambdas) { LambdaHelper.ExpandLambdas(program); //PrintBplFile ("-", program, true); } #endregion if (!CommandLineOptions.Clo.Verify) { return PipelineOutcome.Done; } #region Run Houdini and verify if (CommandLineOptions.Clo.ContractInfer) { return RunHoudini(program, stats, er, filename); } #endregion #region Select and prioritize implementations that should be verified var impls = program.TopLevelDeclarations.OfType<Implementation>().Where( impl => impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification); // operate on a stable copy, in case it gets updated while we're running Implementation[] stablePrioritizedImpls = null; if (CommandLineOptions.Clo.VerifySnapshots) { impls.Iter(impl => { impl.DependenciesChecksum = DependencyCollector.DependenciesChecksum(impl); }); stablePrioritizedImpls = impls.OrderByDescending( impl => impl.Priority != 1 ? impl.Priority : Cache.VerificationPriority(impl)).ToArray(); } else { stablePrioritizedImpls = impls.OrderByDescending(impl => impl.Priority).ToArray(); } #endregion #region Verify each implementation var outputCollector = new OutputCollector(stablePrioritizedImpls); var outcome = PipelineOutcome.VerificationCompleted; var tasks = new Task[stablePrioritizedImpls.Length]; for (int i = 0; i < stablePrioritizedImpls.Length && outcome != PipelineOutcome.FatalError; i++) { var taskIndex = i; var id = stablePrioritizedImpls[i].Id; CancellationTokenSource src; if (ImplIdToCancellationTokenSource.TryGetValue(id, out src)) { src.Cancel(); } src = new CancellationTokenSource(); RequestIdToCancellationTokenSources[requestId].Add(src); ImplIdToCancellationTokenSource[id] = src; var t = Task.Factory.StartNew((dummy) => { VerifyImplementation(program, stats, er, requestId, extractLoopMappingInfo, stablePrioritizedImpls, taskIndex, outputCollector, Checkers, src.Token); ImplIdToCancellationTokenSource.Remove(id); }, src.Token, TaskCreationOptions.LongRunning); tasks[taskIndex] = t; } try { Task.WaitAll(tasks); } catch (AggregateException ae) { ae.Handle(e => { var pe = e as ProverException; if (pe != null) { printer.ErrorWriteLine(Console.Out, "Fatal Error: ProverException: {0}", e); outcome = PipelineOutcome.FatalError; return true; } var oce = e as OperationCanceledException; if (oce != null) { return true; } return false; }); } finally { CleanupCheckers(requestId); } cce.NonNull(CommandLineOptions.Clo.TheProverFactory).Close(); outputCollector.WriteMoreOutput(); #endregion return outcome; }
private static void WriteStatss(Dictionary<string, PipelineStatistics> statss) { var statSum = new PipelineStatistics(); foreach (var stats in statss) { statSum.VerifiedCount += stats.Value.VerifiedCount; statSum.ErrorCount += stats.Value.ErrorCount; statSum.TimeoutCount += stats.Value.TimeoutCount; statSum.OutOfMemoryCount += stats.Value.OutOfMemoryCount; statSum.CachedErrorCount += stats.Value.CachedErrorCount; statSum.CachedInconclusiveCount += stats.Value.CachedInconclusiveCount; statSum.CachedOutOfMemoryCount += stats.Value.CachedOutOfMemoryCount; statSum.CachedTimeoutCount += stats.Value.CachedTimeoutCount; statSum.CachedVerifiedCount += stats.Value.CachedVerifiedCount; statSum.InconclusiveCount += stats.Value.InconclusiveCount; } ExecutionEngine.printer.WriteTrailer(statSum); }
public static void ProcessFiles(List<string> fileNames, bool lookForSnapshots = true) { Contract.Requires(cce.NonNullElements(fileNames)); if (CommandLineOptions.Clo.VerifySeparately && 1 < fileNames.Count) { foreach (var f in fileNames) { ProcessFiles(new List<string> { f }, lookForSnapshots); } return; } if (CommandLineOptions.Clo.VerifySnapshots && lookForSnapshots) { var snapshotsByVersion = new List<List<string>>(); for (int version = 0; true; version++) { var nextSnapshot = new List<string>(); foreach (var name in fileNames) { var versionedName = name.Replace(Path.GetExtension(name), ".v" + version + Path.GetExtension(name)); if (File.Exists(versionedName)) { nextSnapshot.Add(versionedName); } } if (nextSnapshot.Any()) { snapshotsByVersion.Add(nextSnapshot); } else { break; } } foreach (var s in snapshotsByVersion) { ProcessFiles(new List<string>(s), false); } return; } using (XmlFileScope xf = new XmlFileScope(CommandLineOptions.Clo.XmlSink, fileNames[fileNames.Count - 1])) { Program program = ParseBoogieProgram(fileNames, false); if (program == null) return; if (CommandLineOptions.Clo.PrintFile != null) { PrintBplFile(CommandLineOptions.Clo.PrintFile, program, false); } LinearTypeChecker linearTypeChecker; MoverTypeChecker moverTypeChecker; PipelineOutcome oc = ResolveAndTypecheck(program, fileNames[fileNames.Count - 1], out linearTypeChecker, out moverTypeChecker); if (oc != PipelineOutcome.ResolvedAndTypeChecked) return; if (CommandLineOptions.Clo.PrintCFGPrefix != null) { foreach (var impl in program.TopLevelDeclarations.OfType<Implementation>()) { using (StreamWriter sw = new StreamWriter(CommandLineOptions.Clo.PrintCFGPrefix + "." + impl.Name + ".dot")) { sw.Write(program.ProcessLoops(impl).ToDot()); } } } EliminateDeadVariables(program); CollectModSets(program); CoalesceBlocks(program); if (CommandLineOptions.Clo.StratifiedInlining == 0) { Concurrency.Transform(linearTypeChecker, moverTypeChecker); var eraser = new LinearEraser(); eraser.VisitProgram(program); if (CommandLineOptions.Clo.OwickiGriesDesugaredOutputFile != null) { int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured; CommandLineOptions.Clo.PrintUnstructured = 1; PrintBplFile(CommandLineOptions.Clo.OwickiGriesDesugaredOutputFile, program, false, false); CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured; } } Inline(program); var stats = new PipelineStatistics(); oc = InferAndVerify(program, stats, fileNames.ElementAt(0)); switch (oc) { case PipelineOutcome.Done: case PipelineOutcome.VerificationCompleted: printer.WriteTrailer(stats); break; default: break; } } }
private static void ProcessOutcome(VC.VCGen.Outcome outcome, List<Counterexample> errors, string timeIndication, PipelineStatistics stats, TextWriter tw, int timeLimit, ErrorReporterDelegate er = null, string implName = null, IToken implTok = null, string requestId = null, bool wasCached = false) { Contract.Requires(stats != null); UpdateStatistics(stats, outcome, errors, wasCached); printer.Inform(timeIndication + OutcomeIndication(outcome, errors), tw); ReportOutcome(outcome, er, implName, implTok, requestId, tw, timeLimit, errors); }
public static bool Boogie(IList<string> dafnyFileNames, Bpl.Program boogieProgram, string programId, out PipelineStatistics stats, out PipelineOutcome oc) { if (programId == null) { programId = "main_program_id"; } string bplFilename; if (CommandLineOptions.Clo.PrintFile != null) { bplFilename = CommandLineOptions.Clo.PrintFile; } else { string baseName = cce.NonNull(Path.GetFileName(dafnyFileNames[dafnyFileNames.Count - 1])); baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl")); bplFilename = Path.Combine(Path.GetTempPath(), baseName); } stats = null; oc = BoogiePipelineWithRerun(boogieProgram, bplFilename, out stats, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? programId : null); return stats.ErrorCount == 0 && stats.InconclusiveCount == 0 && stats.TimeoutCount == 0 && stats.OutOfMemoryCount == 0; }