Пример #1
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>");
        }