Example #1
0
    public override Outcome CheckOutcomeCore(ErrorHandler handler, int taskID = -1)
    {  
      Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
      
      var result = Outcome.Undetermined;

      if (Process == null)
        return result;

      try {
        currentErrorHandler = handler;
        FlushProverWarnings();

        int errorLimit;
        if (CommandLineOptions.Clo.ConcurrentHoudini) {
          Contract.Assert(taskID >= 0);
          errorLimit = CommandLineOptions.Clo.Cho[taskID].ProverCCLimit;
        } else {
          errorLimit = CommandLineOptions.Clo.ProverCCLimit;
        }

        if (errorLimit < 1)
          errorLimit = 1;

        int errorsLeft = errorLimit;

        var globalResult = Outcome.Undetermined;

        while (true) {
          string[] labels = null;
          bool popLater = false;

          try {
            errorsLeft--;
            
            result = GetResponse();

            var reporter = handler as VC.VCGen.ErrorReporter;
            // TODO(wuestholz): Is the reporter ever null?
            if (usingUnsatCore && result == Outcome.Valid && reporter != null && 0 < NamedAssumes.Count)
            {
              if (usingUnsatCore)
              {
                UsedNamedAssumes = new HashSet<string>();
                SendThisVC("(get-unsat-core)");
                var resp = Process.GetProverResponse();
                if (resp.Name != "")
                {
                  UsedNamedAssumes.Add(resp.Name);
                  if (CommandLineOptions.Clo.PrintNecessaryAssumes)
                  {
                    reporter.AddNecessaryAssume(resp.Name.Substring("aux$$assume$$".Length));
                  }
                }
                foreach (var arg in resp.Arguments)
                {
                  UsedNamedAssumes.Add(arg.Name);
                  if (CommandLineOptions.Clo.PrintNecessaryAssumes)
                  {
                    reporter.AddNecessaryAssume(arg.Name.Substring("aux$$assume$$".Length));
                  }
                }
              }
              else
              {
                UsedNamedAssumes = null;
              }
            }

            if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout && result == Outcome.TimeOut)
            {
              #region Run timeout diagnostics

              if (CommandLineOptions.Clo.TraceDiagnosticsOnTimeout)
              {
                Console.Out.WriteLine("Starting timeout diagnostics with initial time limit {0}.", options.TimeLimit);
              }

              SendThisVC("; begin timeout diagnostics");

              var start = DateTime.UtcNow;
              var unverified = new SortedSet<int>(ctx.TimeoutDiagnosticIDToAssertion.Keys);
              var timedOut = new SortedSet<int>();
              int frac = 2;
              int queries = 0;
              int timeLimitPerAssertion = 0 < options.TimeLimit ? (options.TimeLimit / 100) * CommandLineOptions.Clo.TimeLimitPerAssertionInPercent : 1000;
              while (true)
              {
                int rem = unverified.Count;
                if (rem == 0)
                {
                  if (0 < timedOut.Count)
                  {
                    result = CheckSplit(timedOut, ref popLater, options.TimeLimit, timeLimitPerAssertion, ref queries);
                    if (result == Outcome.Valid)
                    {
                      timedOut.Clear();
                    }
                    else if (result == Outcome.TimeOut)
                    {
                      // Give up and report which assertions were not verified.
                      var cmds = timedOut.Select(id => ctx.TimeoutDiagnosticIDToAssertion[id]);

                      if (cmds.Any())
                      {
                        handler.OnResourceExceeded("timeout after running diagnostics", cmds);
                      }
                    }
                  }
                  else
                  {
                    result = Outcome.Valid;
                  }
                  break;
                }

                // TODO(wuestholz): Try out different ways for splitting up the work (e.g., randomly).
                var cnt = Math.Max(1, rem / frac);
                // It seems like assertions later in the control flow have smaller indexes.
                var split = new SortedSet<int>(unverified.Where((val, idx) => (rem - idx - 1) < cnt));
                Contract.Assert(0 < split.Count);
                var splitRes = CheckSplit(split, ref popLater, timeLimitPerAssertion, timeLimitPerAssertion, ref queries);
                if (splitRes == Outcome.Valid)
                {
                  unverified.ExceptWith(split);
                  frac = 1;
                }
                else if (splitRes == Outcome.Invalid)
                {
                  result = splitRes;
                  break;
                }
                else if (splitRes == Outcome.TimeOut)
                {
                  if (2 <= frac && (4 <= (rem / frac)))
                  {
                    frac *= 4;
                  }
                  else if (2 <= (rem / frac))
                  {
                    frac *= 2;
                  }
                  else
                  {
                    timedOut.UnionWith(split);
                    unverified.ExceptWith(split);
                    frac = 1;
                  }
                }
                else
                {
                  break;
                }
              }

              unverified.UnionWith(timedOut);

              var end = DateTime.UtcNow;

              SendThisVC("; end timeout diagnostics");

              if (CommandLineOptions.Clo.TraceDiagnosticsOnTimeout)
              {
                Console.Out.WriteLine("Terminated timeout diagnostics after {0:F0} ms and {1} prover queries.", end.Subtract(start).TotalMilliseconds, queries);
                Console.Out.WriteLine("Outcome: {0}", result);
                Console.Out.WriteLine("Unverified assertions: {0} (of {1})", unverified.Count, ctx.TimeoutDiagnosticIDToAssertion.Keys.Count);

                string filename = "unknown";
                var assertion = ctx.TimeoutDiagnosticIDToAssertion.Values.Select(t => t.Item1).FirstOrDefault(a => a.tok != null && a.tok != Token.NoToken && a.tok.filename != null);
                if (assertion != null)
                {
                  filename = assertion.tok.filename;
                }
                File.AppendAllText("timeouts.csv", string.Format(";{0};{1};{2:F0};{3};{4};{5};{6}\n", filename, options.TimeLimit, end.Subtract(start).TotalMilliseconds, queries, result, unverified.Count, ctx.TimeoutDiagnosticIDToAssertion.Keys.Count));
              }

              #endregion
            }

            if (globalResult == Outcome.Undetermined)
              globalResult = result;
            
            if (result == Outcome.Invalid || result == Outcome.TimeOut || result == Outcome.OutOfMemory) {
              IList<string> xlabels;
              if (CommandLineOptions.Clo.UseLabels) {
                labels = GetLabelsInfo();
                if (labels == null)
                {
                  xlabels = new string[] { };
                }
                else
                {
                  xlabels = labels.Select(a => a.Replace("@", "").Replace("+", "")).ToList();
                }
              }
              else if(CommandLineOptions.Clo.SIBoolControlVC) {
                  labels = new string[0];
                  xlabels = labels;
              } else {
                labels = CalculatePath(handler.StartingProcId());
                xlabels = labels;
              }
                Model model = (result == Outcome.TimeOut || result == Outcome.OutOfMemory) ? null :
                    GetErrorModel();
              handler.OnModel(xlabels, model, result);
            }
            
            if (labels == null || !labels.Any() || errorsLeft == 0) break;
          } finally {
            if (popLater)
            {
              SendThisVC("(pop 1)");
            }
          }

          if (CommandLineOptions.Clo.UseLabels) {
            var negLabels = labels.Where(l => l.StartsWith("@")).ToArray();
            var posLabels = labels.Where(l => !l.StartsWith("@"));
            Func<string, string> lbl = (s) => SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(s));
            if (!options.MultiTraces)
              posLabels = Enumerable.Empty<string>();
            var conjuncts = posLabels.Select(s => "(not " + lbl(s) + ")").Concat(negLabels.Select(lbl)).ToArray();
            string expr = conjuncts.Length == 1 ? conjuncts[0] : ("(or " + conjuncts.Concat(" ") + ")"); ;
            if (!conjuncts.Any())
            {
              expr = "false";
            }
            SendThisVC("(assert " + expr + ")");
            SendCheckSat();
          }
          else {
            string source = labels[labels.Length - 2];
            string target = labels[labels.Length - 1];
            SendThisVC("(assert (not (= (ControlFlow 0 " + source + ") (- " + target + "))))");
            SendCheckSat();
          }
        }

        FlushLogFile();

        if (CommandLineOptions.Clo.RestartProverPerVC && Process != null)
          Process.NeedsRestart = true;

        return globalResult;

      } finally {
        currentErrorHandler = null;
      }
    }
Example #2
0
        public override Outcome CheckOutcomeCore(ErrorHandler handler, int taskID = -1)
        {
            Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);

              var result = Outcome.Undetermined;

              if (Process == null)
            return result;

              try {
            currentErrorHandler = handler;
            FlushProverWarnings();

            var errorsLeft = CommandLineOptions.Clo.ProverCCLimit;

            if (CommandLineOptions.Clo.ConcurrentHoudini) {
              Contract.Assert(taskID >= 0);
              errorsLeft = CommandLineOptions.Clo.Cho[taskID].ProverCCLimit;
            }

            if (errorsLeft < 1)
              errorsLeft = 1;

            var globalResult = Outcome.Undetermined;

            while (true) {
              errorsLeft--;
              string[] labels = null;

              result = GetResponse();
              if (globalResult == Outcome.Undetermined)
            globalResult = result;

              if (result == Outcome.Invalid || result == Outcome.TimeOut || result == Outcome.OutOfMemory) {
            IList<string> xlabels;
            if (CommandLineOptions.Clo.UseLabels) {
              labels = GetLabelsInfo();
              if (labels == null)
              {
                xlabels = new string[] { };
              }
              else
              {
                xlabels = labels.Select(a => a.Replace("@", "").Replace("+", "")).ToList();
              }
            }
            else {
              labels = CalculatePath(handler.StartingProcId());
              xlabels = labels;
            }
              Model model = (result == Outcome.TimeOut || result == Outcome.OutOfMemory) ? null :
                  GetErrorModel();
            handler.OnModel(xlabels, model);
              }

              if (labels == null || !labels.Any() || errorsLeft == 0) break;

              if (CommandLineOptions.Clo.UseLabels) {
            var negLabels = labels.Where(l => l.StartsWith("@")).ToArray();
            var posLabels = labels.Where(l => !l.StartsWith("@"));
            Func<string, string> lbl = (s) => SMTLibNamer.QuoteId(SMTLibNamer.LabelVar(s));
            if (!options.MultiTraces)
              posLabels = Enumerable.Empty<string>();
            var conjuncts = posLabels.Select(s => "(not " + lbl(s) + ")").Concat(negLabels.Select(lbl)).ToArray();
            string expr = conjuncts.Length == 1 ? conjuncts[0] : ("(or " + conjuncts.Concat(" ") + ")"); ;
            if (!conjuncts.Any())
            {
              expr = "false";
            }
            SendThisVC("(assert " + expr + ")");
            SendThisVC("(check-sat)");
              }
              else {
            string source = labels[labels.Length - 2];
            string target = labels[labels.Length - 1];
            SendThisVC("(assert (not (= (ControlFlow 0 " + source + ") (- " + target + "))))");
            SendThisVC("(check-sat)");
              }
            }

            FlushLogFile();

            if (CommandLineOptions.Clo.RestartProverPerVC && Process != null)
              Process.NeedsRestart = true;

            return globalResult;

              } finally {
            currentErrorHandler = null;
              }
        }