示例#1
0
        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;
        }
示例#2
0
文件: Pipeline.cs 项目: ggrov/tacny
        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;
        }
示例#3
0
文件: Util.cs 项目: ggrov/tacny
        /// <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
            }
        }
示例#4
0
文件: Pipeline.cs 项目: ggrov/tacny
        /// <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
            }
        }
示例#5
0
        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;
            }
              }
        }
示例#6
0
        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();
        }
示例#7
0
        /// <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;
        }
示例#8
0
        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;
              }
        }
示例#9
0
        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
        }
示例#10
0
        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;
        }
示例#11
0
        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;
        }
示例#12
0
        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;
        }
示例#13
0
 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;
   }
 }
示例#14
0
 public void WriteTrailer(PipelineStatistics stats)
 {
 }
示例#15
0
    /// <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
      }
    }
示例#16
0
        /// <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;
        }
示例#17
0
 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);
 }
示例#18
0
        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;
            }
              }
        }
示例#19
0
        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);
        }
示例#20
0
    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;
    }