Exemplo n.º 1
0
        string PrintBoogie(BoogieProgram program)
        {
            var result = new StringWriter();
            var writer = new TokenTextWriter(result);

            program.Emit(writer);
            return(result.ToString());
        }
Exemplo n.º 2
0
Arquivo: Utils.cs Projeto: townie/esh
 public static void PrintProgram(Program program, string path = null)
 {
     var ttw = path == null ? new TokenTextWriter(Console.Out, true) : new TokenTextWriter(path, true);
     program.Emit(ttw);
     ttw.Close();
     // re-read to see there are no parse errors
     Program writtenProgram;
     if (path != null && !ParseProgram(path, out writtenProgram))
         ErrorAndDie($"Created program {path} with parse errors.");
 }
Exemplo n.º 3
0
        /// <summary>
        /// Writes the program to a temp file.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="program">The program.</param>
        /// <returns>The temp file path.</returns>
        public static string WriteFile(string filePath, Microsoft.Boogie.Program program)
        {
            string tempFile = filePath.Replace(".cbpl", ".temp.cbpl");

            if (File.Exists(tempFile))
            {
                File.Delete(tempFile);
            }

            using (TokenTextWriter writer = new TokenTextWriter(tempFile, true))
                program.Emit(writer);
            return(tempFile);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Deep clone the program.
        /// </summary>
        private static Program DeepCloneProgram(Program program)
        {
            var oldPrintInstrumented = DafnyOptions.O.PrintInstrumented;
            var oldPrintFile         = DafnyOptions.O.PrintFile;

            DafnyOptions.O.PrintInstrumented = true;
            DafnyOptions.O.PrintFile         = "-";
            var textRepresentation = Utils.CaptureConsoleOutput(
                () => program.Emit(new TokenTextWriter(Console.Out)));

            Microsoft.Boogie.Parser.Parse(textRepresentation, "", out var copy);
            DafnyOptions.O.PrintInstrumented = oldPrintInstrumented;
            DafnyOptions.O.PrintFile         = oldPrintFile;
            return(copy);
        }
Exemplo n.º 5
0
 public static void PrintBplFile(string filename, Program program, bool allowPrintDesugaring, bool setTokens = true, bool pretty = false)
 {
     Contract.Requires(program != null);
       Contract.Requires(filename != null);
       bool oldPrintDesugaring = CommandLineOptions.Clo.PrintDesugarings;
       if (!allowPrintDesugaring)
       {
     CommandLineOptions.Clo.PrintDesugarings = false;
       }
       using (TokenTextWriter writer = filename == "-" ?
                               new TokenTextWriter("<console>", Console.Out, setTokens, pretty) :
                               new TokenTextWriter(filename, setTokens, pretty))
       {
     if (CommandLineOptions.Clo.ShowEnv != CommandLineOptions.ShowEnvironment.Never)
     {
       writer.WriteLine("// " + CommandLineOptions.Clo.Version);
       writer.WriteLine("// " + CommandLineOptions.Clo.Environment);
     }
     writer.WriteLine();
     program.Emit(writer);
       }
       CommandLineOptions.Clo.PrintDesugarings = oldPrintDesugaring;
 }
Exemplo n.º 6
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;
        }
Exemplo n.º 7
0
        /// <summary>
        /// The entry point of the program.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            int?statusCode = null;

            try
            {
                // standard command line options for Boogie
                CommandLineOptions.Install(new GRCommandLineOptions());
                if (!CommandLineOptions.Clo.Parse(args))
                {
                    return;
                }

                CommandLineOptions.Clo.PrintUnstructured    = 2;
                CommandLineOptions.Clo.DoModSetAnalysis     = true;
                CommandLineOptions.Clo.PruneInfeasibleEdges = true;

                if (!CommandLineOptions.Clo.Files.Any())
                {
                    throw new Exception("An input file must be provided!");
                }
                else if (CommandLineOptions.Clo.Files.Count > 1)
                {
                    throw new Exception("GPURepair can work on only one file at a time!");
                }

                Logger.FileName        = CommandLineOptions.Clo.Files.First();
                Logger.DetailedLogging = ((GRCommandLineOptions)CommandLineOptions.Clo).DetailedLogging;

                ClauseLogger.FileName   = CommandLineOptions.Clo.Files.First();
                ClauseLogger.LogCLauses = ((GRCommandLineOptions)CommandLineOptions.Clo).LogClauses;

                Barrier.LoopDepthWeight   = ((GRCommandLineOptions)CommandLineOptions.Clo).LoopDepthWeight;
                Barrier.GridBarrierWeight = ((GRCommandLineOptions)CommandLineOptions.Clo).GridBarrierWeight;

                Dictionary <string, bool> assignments;

                // repair the program
                Solver.SolverType solverType = ((GRCommandLineOptions)CommandLineOptions.Clo).SolverType;
                bool disableInspection       = ((GRCommandLineOptions)CommandLineOptions.Clo).DisableInspection;
                bool useAxioms = ((GRCommandLineOptions)CommandLineOptions.Clo).UseAxioms;

                Repairer repairer = new Repairer(Logger.FileName, disableInspection, useAxioms);
                Microsoft.Boogie.Program program = repairer.Repair(solverType, out assignments);

                SummaryGenerator     generator = new SummaryGenerator();
                IEnumerable <string> changes   = generator.GenerateSummary(assignments,
                                                                           Logger.FileName.Replace(".cbpl", ".summary"));

                Logger.Log($"Changes;{changes.Count()}");
                Console.WriteLine("Number of changes required: {0}.", changes.Count());

                if (changes.Any())
                {
                    using (TokenTextWriter writer = new TokenTextWriter(Logger.FileName.Replace(".cbpl", ".fixed.cbpl"), true))
                        program.Emit(writer);
                }
            }
            catch (Exception ex)
            {
                Logger.Log($"ExceptionMessage;{ex.Message}");
                Console.Error.WriteLine(ex.Message);

                if (ex is AssertionException)
                {
                    statusCode = 201;
                }
                else if (ex is RepairException)
                {
                    statusCode = 202;
                }
                else if (ex is NonBarrierException)
                {
                    statusCode = 203;
                }
                else if (ex is SummaryGeneratorException)
                {
                    statusCode = 204;
                }
            }

            if (statusCode != null)
            {
                Environment.Exit(statusCode.Value);
            }
        }
Exemplo n.º 8
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;
        }