Beispiel #1
0
 /// <summary>
 /// ARMC constructor.
 /// </summary>
 /// <param name="config">Configuration.</param>
 public ARMC(Config config)
     : this(SSA <SYMBOL> .Parse(config.InitFilePath),
            SSA <SYMBOL> .Parse(config.BadFilePath),
            config.TauFilePaths.Select(path => SST <SYMBOL> .Parse(path)).ToArray(),
            config)
 {
 }
Beispiel #2
0
        /// <summary>
        /// Compose transducers T1 and T2, resulting in transducer equivalent to applying T2 after T1.
        /// </summary>
        public static SST <SYMBOL> Compose(SST <SYMBOL> tau1, SST <SYMBOL> tau2)
        {
            if (tau1.Algebra != tau2.Algebra)
            {
                throw SSTException.IncompatibleAlphabets();
            }

            LabelAlgebra <SYMBOL> algebra = tau1.Algebra;
            var stack       = new Stack <Tuple <int, int> >();
            var finalStates = new List <int>();
            var moves       = new List <Move <Label <SYMBOL> > >();
            var stateDict   = new Dictionary <Tuple <int, int>, int>();
            int id          = 0;

            var init = new Tuple <int, int>(tau1.InitialState, tau2.InitialState);

            stateDict[init] = id++;
            stack.Push(init);

            while (stack.Count > 0)
            {
                Tuple <int, int> sourcePair = stack.Pop();
                int state1 = sourcePair.Item1;
                int state2 = sourcePair.Item2;

                foreach (Move <Label <SYMBOL> > move1 in tau1.GetMovesFrom(state1))
                {
                    foreach (Move <Label <SYMBOL> > move2 in tau2.GetMovesFrom(state2))
                    {
                        Label <SYMBOL> newLabel = algebra.Combine(move1.Label, move2.Label);
                        if (!algebra.IsSatisfiable(newLabel))
                        {
                            continue;
                        }

                        var targetPair = new Tuple <int, int>(move1.TargetState, move2.TargetState);
                        int targetState;
                        if (!stateDict.TryGetValue(targetPair, out targetState))
                        {
                            stateDict[targetPair] = targetState = id++;
                            stack.Push(targetPair);
                            if (tau1.IsFinalState(move1.TargetState) && tau2.IsFinalState(move2.TargetState))
                            {
                                finalStates.Add(targetState);
                            }
                        }
                        moves.Add(new Move <Label <SYMBOL> >(stateDict[sourcePair], targetState, newLabel));
                    }
                }
            }

            return(new SST <SYMBOL>(0, finalStates, moves));
        }
Beispiel #3
0
        public PredicateAbstraction(Config config, SSA <SYMBOL> init = null, SSA <SYMBOL> bad = null, SST <SYMBOL>[] taus = null)
        {
            var initPreds = new List <SSA <SYMBOL> >();

            /* add Init? */
            if (config.InitialPredicate == Config.InitPred.Init || config.InitialPredicate == Config.InitPred.Both)
            {
                initPreds.Add(init ?? SSA <SYMBOL> .Parse(config.InitFilePath));
            }
            /* add Bad? */
            if (config.InitialPredicate == Config.InitPred.Bad || config.InitialPredicate == Config.InitPred.Both)
            {
                initPreds.Add(bad ?? SSA <SYMBOL> .Parse(config.BadFilePath));
            }

            /* add transducer domains and/or ranges? */
            SST <SYMBOL>[] ssts = taus ?? config.TauFilePaths.Select(path => SST <SYMBOL> .Parse(path)).ToArray();
            if (config.IncludeGuard)
            {
                foreach (SST <SYMBOL> sst in ssts)
                {
                    initPreds.Add(sst.Domain());
                }
            }
            if (config.IncludeAction)
            {
                foreach (SST <SYMBOL> sst in ssts)
                {
                    initPreds.Add(sst.Range());
                }
            }

            /* ensure that the automata contain no epsilon transitions and have disjunct sets of states */
            predicateAutomata = new Set <SSA <SYMBOL> >();
            int offset = 0;

            foreach (SSA <SYMBOL> pred in initPreds)
            {
                SSA <SYMBOL> normPred = pred.RemoveEpsilons().Normalize(offset);
                predicateAutomata.Add(normPred);
                offset += normPred.States.Count();
            }

            forward       = (config.LanguageDirection == Config.Direction.Forward);
            heuristic     = config.Heuristic;
            ignoredLabels = new Set <int>();  // remains empty if no heuristic used
        }
Beispiel #4
0
        /// <summary>
        /// Constructs transducer that models the inverse relation.
        /// </summary>
        public SST <SYMBOL> Invert()
        {
            var result = new SST <SYMBOL>(automaton.RelpaceAllGuards(label => label.Invert()));

            if (Name != null)
            {
                string marker = "<sup>-1</sup>";
                if (Name.EndsWith(marker))
                {
                    result.Name = Name.Substring(0, Name.Length - marker.Length);
                }
                else
                {
                    result.Name = Name + marker;
                }
            }
            if (StateNames != null)
            {
                result.StateNames = new Dictionary <int, string>(StateNames);
            }
            return(result);
        }
Beispiel #5
0
 /// <summary>
 /// ARMC constructor.
 /// </summary>
 /// <param name="init">SSA representing initial states.</param>
 /// <param name="bad">SSA representing bad states.</param>
 /// <param name="tau">SST representing transition.</param>
 /// <param name="config">Configuration.</param>
 public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL> tau, Config config)
     : this(init, bad, new SST <SYMBOL>[] { tau }, config)
 {
 }
Beispiel #6
0
 /// <summary>
 /// ARMC constructor.
 /// </summary>
 /// <param name="init">SSA representing initial states.</param>
 /// <param name="bad">SSA representing bad states.</param>
 /// <param name="tau">SST representing transition.</param>
 /// <param name="configFileName">Configuration file path.</param>
 public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL> tau, string configFileName)
     : this(init, bad, new SST <SYMBOL>[] { tau }, new Config(configFileName))
 {
 }
Beispiel #7
0
 /// <summary>
 /// ARMC constructor.
 /// </summary>
 /// <param name="init">SSA representing initial states.</param>
 /// <param name="bad">SSA representing bad states.</param>
 /// <param name="tau">SST representing transition.</param>
 public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL> tau)
     : this(init, bad, new SST <SYMBOL>[] { tau }, new Config())
 {
 }
Beispiel #8
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();
            }
        }