Ejemplo n.º 1
0
        /* Collapse method ignores this in favour of more efficient alternative */
        public override bool StatesAreEquivalent(SSA <SYMBOL> m, int q1, int q2)
        {
            Func <int, SSA <SYMBOL> > stateLang = forward ? (Func <int, SSA <SYMBOL> >)m.ForwardStateLanguage : m.BackwardStateLanguage;
            SSA <SYMBOL> m1 = stateLang(q1);
            SSA <SYMBOL> m2 = stateLang(q2);

            foreach (SSA <SYMBOL> pa in predicateAutomata)
            {
                stateLang = forward ? (Func <int, SSA <SYMBOL> >)pa.ForwardStateLanguage : pa.BackwardStateLanguage;
                foreach (int state in pa.States)
                {
                    SSA <SYMBOL> p = stateLang(state);
                    if (SSA <SYMBOL> .ProductIsEmpty(p, m1) != SSA <SYMBOL> .ProductIsEmpty(p, m2))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks if the intersection of L(M1) and L(M2) is an empty language.
        /// </summary>
        public static bool ProductIsEmpty(SSA <SYMBOL> m1, SSA <SYMBOL> m2)
        {
            List <Predicate <SYMBOL> > witness;

            return(SSA <SYMBOL> .ProductIsEmpty(m1, m2, out witness));
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
0
        public override void Refine(SSA <SYMBOL> m, SSA <SYMBOL> x)
        {
            int offset = predicateAutomata.Sum(pred => pred.States.Count());

            x = x.RemoveEpsilons().Normalize(offset);

            predicateAutomata.Add(x);

            if (heuristic.HasValue)
            {
                var xStates = new Set <int>(x.States);

                /* find important states (appear in labels) */
                Dictionary <int, Set <int> > labels = MakeLabels(m);
                var importantStates = new Set <int>();
                foreach (int mState in m.States)
                {
                    foreach (int xState in labels[mState])
                    {
                        if (xState < offset || xState >= xStates.Count + offset)
                        {
                            continue;
                        }
                        importantStates.Add(xState);
                    }
                }

                if (((Config.PredHeuristic)heuristic) == Config.PredHeuristic.KeyStates)
                {
                    /* try to find one key state among important states */
                    foreach (int state in importantStates)
                    {
                        /* try ignoring all but one state */
                        ignoredLabels += xStates;
                        ignoredLabels.Remove(state);
                        /* check if the collapsed automaton still intersects */
                        if (SSA <SYMBOL> .ProductIsEmpty(Collapse(m), x))
                        {
                            return;
                        }
                        /* failed, restore temporarily ignored states */
                        ignoredLabels -= xStates;
                    }

                    /* couldn't find just one key state, try to find two */
                    foreach (int state1 in importantStates)
                    {
                        foreach (int state2 in importantStates.Where(s => s != state1))
                        {
                            ignoredLabels += xStates;
                            ignoredLabels.Remove(state1);
                            ignoredLabels.Remove(state2);
                            if (SSA <SYMBOL> .ProductIsEmpty(Collapse(m), x))
                            {
                                return;
                            }
                            ignoredLabels -= xStates;
                        }
                    }

                    /* fall back on important states heuristic */
                }

                /* ignore all unimportant states */
                ignoredLabels += xStates - importantStates;
            }
        }
Ejemplo n.º 5
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();
            }
        }