Example #1
0
        /// <summary>
        /// Write the automaton in dgml format into the textwriter.
        /// </summary>
        public void Write <S>(IAutomaton <S> fa)
        {
            var nonEpsilonMoves = new Dictionary <(int, int), List <S> >();
            var epsilonmoves    = new List <Move <S> >();

            var nonEpsilonStates = new HashSet <int>();

            foreach (Move <S> move in fa.GetMoves())
            {
                if (move.IsEpsilon)
                {
                    epsilonmoves.Add(move);
                }
                else
                {
                    nonEpsilonStates.Add(move.SourceState);
                    var p = (move.SourceState, move.TargetState);
                    if (!nonEpsilonMoves.TryGetValue(p, out List <S>?rules))
                    {
                        rules = new List <S>();
                        nonEpsilonMoves[p] = rules;
                    }

                    Debug.Assert(move.Label is not null);
                    rules.Add(move.Label);
                }
            }

            _tw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            _tw.WriteLine("<DirectedGraph xmlns=\"http://schemas.microsoft.com/vs/2009/dgml\" ZoomLevel=\"1.5\" GraphDirection=\"TopToBottom\" >");
            _tw.WriteLine("<Nodes>");
            _tw.WriteLine("<Node Id=\"dfa\" Label=\" \" Group=\"Collapsed\" Category=\"DFA\" DFAInfo=\"{0}\" />", GetDFAInfo(fa));
            _tw.WriteLine("<Node Id=\"dfainfo\" Category=\"DFAInfo\" Label=\"{0}\"/>", GetDFAInfo(fa));
            if (_onlyDFAinfo)
            {
                _tw.WriteLine("</Nodes>");
            }
            else
            {
                foreach (int state in fa.GetStates())
                {
                    _tw.WriteLine("<Node Id=\"{0}\" Label=\"{0}\" Category=\"State\" Group=\"{1}\" StateInfo=\"{2}\">", state, _hideStateInfo ? "Collapsed" : "Expanded", GetStateInfo(fa, state));
                    if (state == fa.InitialState)
                    {
                        _tw.WriteLine("<Category Ref=\"InitialState\" />");
                    }
                    if (fa.IsFinalState(state))
                    {
                        _tw.WriteLine("<Category Ref=\"FinalState\" />");
                    }
                    _tw.WriteLine("</Node>");
                    _tw.WriteLine("<Node Id=\"{0}info\" Label=\"{1}\" Category=\"StateInfo\"/>", state, GetStateInfo(fa, state));
                }
                _tw.WriteLine("</Nodes>");
                _tw.WriteLine("<Links>");
                _tw.WriteLine("<Link Source=\"dfa\" Target=\"{0}\" Label=\"{1}\" Category=\"StartTransition\" />", fa.InitialState, fa.DescribeStartLabel());
                _tw.WriteLine("<Link Source=\"dfa\" Target=\"dfainfo\" Label=\"\" Category=\"Contains\" />");

                foreach (Move <S> move in epsilonmoves)
                {
                    _tw.WriteLine("<Link Source=\"{0}\" Target=\"{1}\" Category=\"EpsilonTransition\" />", move.SourceState, move.TargetState);
                }

                foreach (KeyValuePair <(int, int), List <S> > move in nonEpsilonMoves)
                {
                    _tw.WriteLine(GetNonFinalRuleInfo(fa, move.Key.Item1, move.Key.Item2, move.Value));
                }

                foreach (int state in fa.GetStates())
                {
                    _tw.WriteLine("<Link Source=\"{0}\" Target=\"{0}info\" Category=\"Contains\" />", state);
                }

                _tw.WriteLine("</Links>");
                WriteCategoriesAndStyles();
            }
            _tw.WriteLine("</DirectedGraph>");
        }
Example #2
0
        /// <summary>
        /// Write the automaton in dgml format.
        /// </summary>
        /// <param name="fa">the automaton to write</param>
        /// <param name="tw">text writer for the output</param>
        public static void AutomatonToDgml <S>(int k, IAutomaton <S> fa, string name, System.IO.TextWriter tw, Func <S, string> describeS = null)
        {
            ITransducer <S> faf          = fa as ITransducer <S>;
            bool            isTransducer = (faf != null);
            Func <S, bool>  isfinal      = lab => { return(isTransducer ? faf.IsFinalRule(lab) : false); };

            var finalMoves    = new Dictionary <int, List <S> >();
            var nonFinalMoves = new Dictionary <Tuple <int, int>, List <S> >();
            var epsilonmoves  = new List <Move <S> >();

            var nonEpsilonStates            = new HashSet <int>();
            Func <int, bool> IsEpsilonState = (s => !nonEpsilonStates.Contains(s));

            foreach (var move in fa.GetMoves())
            {
                if (move.IsEpsilon)
                {
                    epsilonmoves.Add(move);
                }

                else if (isfinal(move.Label) &&
                         !(faf.IsGuardTrue(move.Label) && faf.GetYieldsLength(move.Label) == 0))
                {
                    List <S> rules;
                    if (!finalMoves.TryGetValue(move.SourceState, out rules))
                    {
                        rules = new List <S>();
                        finalMoves[move.SourceState] = rules;
                    }
                    rules.Add(move.Label);
                }
                else if (!isfinal(move.Label))
                {
                    nonEpsilonStates.Add(move.SourceState);
                    List <S> rules;
                    var      p = new Tuple <int, int>(move.SourceState, move.TargetState);
                    if (!nonFinalMoves.TryGetValue(p, out rules))
                    {
                        rules            = new List <S>();
                        nonFinalMoves[p] = rules;
                    }
                    rules.Add(move.Label);
                }
            }

            tw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            tw.WriteLine("<DirectedGraph xmlns=\"http://schemas.microsoft.com/vs/2009/dgml\" ZoomLevel=\"1.5\" GraphDirection=\"TopToBottom\" >");
            tw.WriteLine("<Nodes>");
            tw.WriteLine("<Node Id=\"init\" Label=\"{0}\" Stroke=\"white\" Background=\"white\"/>", name);
            foreach (int state in fa.GetStates())
            {
                if (state == fa.InitialState && fa.IsFinalState(state))
                {
                    tw.WriteLine("<Node Id=\"{0}\" Label=\"{1}\" Category=\"State\" >", state, fa.DescribeState(state));
                    if (!finalMoves.ContainsKey(state))
                    {
                        //if (IsEpsilonState(state))
                        //    tw.WriteLine("<Category Ref=\"EpsilonState\" />");
                        //else
                        tw.WriteLine("<Category Ref=\"FinalState\" />");
                    }
                    //tw.WriteLine("<Category Ref=\"InitialState\" />");
                    tw.WriteLine("</Node>");
                    if (finalMoves.ContainsKey(state))
                    {
                        tw.WriteLine("<Node Id=\"f{0}\" Label=\" \" Category=\"State\" >", state);
                        tw.WriteLine("<Category Ref=\"FinalState\" />");
                        tw.WriteLine("<Category Ref=\"SinkState\" />");
                        tw.WriteLine("</Node>");
                    }
                }
                else if (state == fa.InitialState)
                {
                    tw.WriteLine("<Node Id=\"{0}\" Label=\"{1}\" Category=\"State\" >", state, fa.DescribeState(state));
                    tw.WriteLine("<Category Ref=\"InitialState\" />");
                    tw.WriteLine("</Node>");
                }
                else if (fa.IsFinalState(state))
                {
                    tw.WriteLine("<Node Id=\"{0}\" Label=\"{1}\" Category=\"State\" >", state, fa.DescribeState(state));
                    if (!finalMoves.ContainsKey(state))
                    {
                        //if (IsEpsilonState(state))
                        //    tw.WriteLine("<Category Ref=\"EpsilonState\" />");
                        //else
                        tw.WriteLine("<Category Ref=\"FinalState\" />");
                    }
                    tw.WriteLine("</Node>");
                    if (finalMoves.ContainsKey(state))
                    {
                        tw.WriteLine("<Node Id=\"f{0}\" Label=\" \" Category=\"State\" >", state);
                        tw.WriteLine("<Category Ref=\"FinalState\" />");
                        tw.WriteLine("<Category Ref=\"SinkState\" />");
                        tw.WriteLine("</Node>");
                    }
                }
                else
                {
                    tw.WriteLine("<Node Id=\"{0}\" Label=\"{1}\" Category=\"State\" />", state, fa.DescribeState(state));
                }
            }
            tw.WriteLine("</Nodes>");
            tw.WriteLine("<Links>");
            tw.WriteLine("<Link Source=\"init\" Target=\"{0}\" Label=\"{1}\" Category=\"StartTransition\" />", fa.InitialState, fa.DescribeStartLabel());
            foreach (var move in epsilonmoves)
            {
                tw.WriteLine("<Link Source=\"{0}\" Target=\"{1}\" Category=\"EpsilonTransition\" />", move.SourceState, move.TargetState);
            }

            foreach (var move in nonFinalMoves)
            {
                tw.WriteLine(GetNonFinalRuleInfo(k, fa, faf, move.Key.Item1, move.Key.Item2, move.Value, describeS));
            }

            foreach (var move in finalMoves)
            {
                tw.WriteLine(GetFinalRuleInfo(k, faf, move.Key, move.Value));
            }

            tw.WriteLine("</Links>");
            WriteCategoriesAndStyles(tw);
            tw.WriteLine("</DirectedGraph>");
        }