Пример #1
0
        /// <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++;
            }
        }
Пример #2
0
        /// <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>&alpha;</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);
            }
        }
Пример #3
0
        /// <summary>
        /// ARMC constructor.
        /// </summary>
        /// <param name="init">SSA representing initial states.</param>
        /// <param name="bad">SSA representing bad states.</param>
        /// <param name="taus">SSTs whose composition represents transition.</param>
        /// <param name="config">Configuration.</param>
        public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL>[] taus, Config config)
        {
            /* merge alphabets */
            Set <SYMBOL> alphabet = init.Alphabet + bad.Alphabet + taus.Select(tau => tau.Alphabet).Aggregate(Set <SYMBOL> .Union);

            init.Alphabet = alphabet;
            bad.Alphabet  = alphabet;
            for (int i = 0; i < taus.Length; i++)
            {
                taus[i].Alphabet = alphabet;
            }

            if (config.PredicateLanguages == config.FiniteLengthLanguages)  // sanity check
            {
                throw ConfigException.AbstractionNotChosen();
            }

            this.init = init;
            this.bad  = bad;
            this.tau  = SST <SYMBOL> .Union(taus);

            this.tauInv = tau.Invert();
            this.abstr  = config.PredicateLanguages ?
                          (Abstraction <SYMBOL>) new PredicateAbstraction <SYMBOL>(config, init, bad, taus) :
                          new FiniteLengthAbstraction <SYMBOL>(config, init, bad, taus);
            this.verbose       = config.Verbose;
            this.printAutomata = config.PrintAutomata;
            this.outputDir     = config.OutputDirectory;
            this.format        = config.AutomataFormat;
            this.imgExt        = (config.ImageFormat == null) ? "" : config.ImageFormat.ToString();
            this.timeout       = config.Timeout.Ticks;
            this.stopwatch     = new Stopwatch();
            this.loops         = 0;

            if (outputDir != "")
            {
                /* clear output directory */
                DirectoryInfo dirInfo = Directory.CreateDirectory(outputDir);
                foreach (FileInfo fi in dirInfo.EnumerateFiles())
                {
                    fi.Delete();
                }
                foreach (DirectoryInfo di in dirInfo.EnumerateDirectories())
                {
                    di.Delete(true);
                }
            }

            if (printAutomata)
            {
                /* print input automata and configuration */
                string dir = Path.Combine(outputDir, "armc-input");
                Directory.CreateDirectory(dir);
                PrintAutomaton(init, dir, "init");
                PrintAutomaton(bad, dir, "bad");
                PrintAutomaton(tau, dir, "tau");
                if (taus.Length > 1)  // no point in only printing tau1
                {
                    for (int i = 0; i < taus.Length; i++)
                    {
                        PrintAutomaton(taus[i], dir, "tau" + (i + 1).ToString());
                    }
                }
                PrintAutomaton(tauInv, dir, "tau-inv");
                config.Write(Path.Combine(dir, "armc.properties"));
            }

            if (config.ComputationDirection == Config.Direction.Backward)
            {
                /* reverse direction, i.e. check if tauInv*(bad) & init is empty */
                this.init   = bad;
                this.bad    = init;
                this.tauInv = tau;
                this.tau    = tau.Invert();
            }

            if (!SSA <SYMBOL> .ProductIsEmpty(init, bad))    // no point in further verification
            {
                if (printAutomata)
                {
                    string dir = Path.Combine(outputDir, "armc-counterexample");
                    Directory.CreateDirectory(dir);
                    PrintAutomaton(init & bad, dir, "initXbad");
                }
                throw ARMCException.InitialPropertyViolation();
            }
        }