/// <summary> /// Performs the entire ARMC verification algorithm. /// </summary> /// <returns>Verification result, i.e. whether property holds.</returns> /// <param name="counterexample">Counterexample (if encountered, i.e. <code>false</code> returned).</param> /// <remarks>Termination not guaranteed, consider setting timeout in configuration.</remarks> public bool Verify(out Counterexample <SYMBOL> counterexample) { stopwatch.Reset(); while (true) { bool?result = VerifyStep(out counterexample); if (result.HasValue) { return((bool)result); } if (timeout > 0 && stopwatch.ElapsedTicks > timeout) { throw ARMCException.Timeout(); } loops++; } }
/// <summary> /// Print the counterexample (SSAs). /// </summary> /// <param name="counterexample">Counterexample.</param> /// <param name="directory">Output directory path.</param> public void PrintCounterexample(Counterexample <SYMBOL> counterexample, string directory) { int i = 0; foreach (var pair in counterexample.Ms) { SSA <SYMBOL> m = pair.Item1; SSA <SYMBOL> mAlpha = pair.Item2; PrintAutomaton(m, directory, "M" + i.ToString()); if (mAlpha != null) { PrintAutomaton(mAlpha, directory, "M" + i.ToString() + "+"); } i++; } i = 0; foreach (SSA <SYMBOL> x in counterexample.Xs) { PrintAutomaton(x, directory, "X" + i.ToString()); i++; } }
/// <summary> /// Performs one step (inner loop) of ARMC. /// </summary> /// <returns>Verification result, or <code>null</code> if undecided.</returns> /// <param name="counterexample">Counterexample (if encountered, i.e. <code>false</code> returned).</param> public bool?VerifyStep(out Counterexample <SYMBOL> counterexample) { var ssas = new Stack <Tuple <SSA <SYMBOL>, SSA <SYMBOL> > >(); SSA <SYMBOL> m; SSA <SYMBOL> ml; SSA <SYMBOL> mAlpha = null; SSA <SYMBOL> x; var xs = new Stack <SSA <SYMBOL> >(); int i = 0; int l = 0; string ext = "." + format.ToString().ToLower(); string dir = Path.Combine(outputDir, "armc-loop-" + loops.ToString()); stopwatch.Start(); if (printAutomata) { Directory.CreateDirectory(dir); abstr.Print(dir, this); } counterexample = null; m = init; if (printAutomata) { PrintAutomaton(m, dir, "M0"); } while (true) { if (verbose) { Log("\r" + loops.ToString() + "." + i.ToString()); } if (i > 0 && !SSA <SYMBOL> .ProductIsEmpty(m, bad)) { if (verbose) { LogLine(": counterexample encountered"); } l = i; x = m & bad; x.Name = "<i>X</i><sub>" + l.ToString() + "</sub>"; if (printAutomata) { PrintAutomaton(x, dir, "X" + l.ToString()); } ml = m; xs.Push(x); break; } mAlpha = abstr.Collapse(m).Determinize().Minimize(); mAlpha.Name = "<i>M</i><sub>" + i.ToString() + "</sub><sup>α</sup>"; if (printAutomata) { PrintAutomaton(mAlpha, dir, "M" + i.ToString() + "+"); } if (i > 0 && mAlpha == ssas.Peek().Item2) { stopwatch.Stop(); if (verbose) { LogLine(": fixpoint reached"); LogLine("time = " + stopwatch.Elapsed.ToString()); } return(true); } if (timeout > 0 && stopwatch.ElapsedTicks > timeout) { stopwatch.Stop(); if (verbose) { LogLine(": timeout (" + stopwatch.Elapsed.ToString() + ")"); } throw ARMCException.Timeout(); } ssas.Push(Tuple.Create(m, mAlpha)); i++; m = tau.Apply(mAlpha).Determinize().Minimize(); m.Name = "<i>M</i><sub>" + i.ToString() + "</sub>"; if (printAutomata) { PrintAutomaton(m, dir, "M" + i.ToString()); } } bool spurious = false; foreach (var pair in ssas) { m = pair.Item1; mAlpha = pair.Item2; i--; if (verbose) { Log("\r" + loops.ToString() + "." + l.ToString() + "-" + i.ToString()); } x = (tauInv.Apply(x) & mAlpha).Determinize().Minimize(); x.Name = "<i>X</i><sub>" + i.ToString() + "</sub>"; xs.Push(x); if (printAutomata) { PrintAutomaton(x, dir, "X" + i.ToString()); } if (SSA <SYMBOL> .ProductIsEmpty(x, m)) { spurious = true; break; } } stopwatch.Stop(); if (spurious) { if (verbose) { LogLine(": counterexample is spurious"); } abstr.Refine(m, x); return(null); } else { if (verbose) { LogLine(": counterexample is real"); LogLine("time = " + stopwatch.Elapsed.ToString()); } List <Tuple <SSA <SYMBOL>, SSA <SYMBOL> > > ms = ssas.ToList(); ms.Reverse(); ms.Add(new Tuple <SSA <SYMBOL>, SSA <SYMBOL> >(ml, null)); counterexample = new Counterexample <SYMBOL> { Ms = ms, Xs = xs.ToList() }; return(false); } }