Пример #1
0
        public static string GetFastProg(TreeTransducer aut, string accName)
        {
            StringBuilder sb = new StringBuilder();
            FastGen       fg = new FastGen(aut.TT.Z);

            fg.ToFast(aut.InputAlphabet, sb);
            fg.ToFast("fastacc", aut, sb, true);
            return(sb.ToString());
            //foreach (var td in fti.treeDefinitions)
            //{
            //    var tcd = td.Value;
            //    var aut = tcd.acceptors[accName];
            //    var tokenSource = new CancellationTokenSource();
            //    CancellationToken token = tokenSource.Token;

            //    TreeTransducer detAut = null;

            //    var task = Task.Factory.StartNew(() =>
            //    {
            //        aut.IsDeterminstic();
            //        if(complete)
            //            detAut = aut.Determinize();
            //        else
            //            detAut = aut.DeterminizeWithoutCompletion().RemoveUselessStates();
            //    }, token);


            //    if (!task.Wait(Program.timeOut, token))
            //    {
            //        Console.WriteLine("The Task timed out!");
            //        return null;
            //    }
            //    else
            //    {
            //        StringBuilder sb = new StringBuilder();
            //        FastGen fg = new FastGen(detAut.TT.Z);
            //        fg.ToFast(td.Value.alphabet.alph, sb);
            //        fg.ToFast("fastacc", detAut, sb, true);
            //        return sb.ToString();
            //    }
            //}
            //return null;
        }
Пример #2
0
        public void TestFastGeneration()
        {
            Z3Provider Z = new Z3Provider();

            Sort color = Z.MkEnumSort("Color", "blue", "green", "red");

            string enum_sort_name = color.Name.ToString();

            Assert.AreEqual <string>("Color", enum_sort_name);
            Assert.AreEqual <string>("green", Z.GetEnumElement("Color", "green").FuncDecl.Name.ToString());

            FuncDecl[] fields = new FuncDecl[5];
            FuncDecl   mkTuple;
            Sort       attrSort = Z.MkTupleSort("$", new string[] { "i", "b", "e", "s", "r" }, new Sort[] { Z.IntSort, Z.BoolSort, color, Z.StringSort, Z.RealSort }, out mkTuple, out fields);


            string tuple_sort_name       = attrSort.Name.ToString();
            string tuple_contructor_name = mkTuple.Name.ToString();

            Assert.AreEqual <string>("$", tuple_sort_name);
            Assert.AreEqual <string>("$", tuple_contructor_name);

            Assert.AreEqual <string>("i", fields[0].Name.ToString());
            Assert.AreEqual <string>("b", fields[1].Name.ToString());
            Assert.AreEqual <string>("e", fields[2].Name.ToString());


            Assert.AreEqual <string>("Int", Z.GetRange(fields[0]).Name.ToString());
            Assert.AreEqual <string>("Bool", Z.GetRange(fields[1]).Name.ToString());
            Assert.AreEqual <string>("Color", Z.GetRange(fields[2]).Name.ToString());

            var A = (Z.TT.MkRankedAlphabet("A", attrSort, new string[] { "zero", "one", "two" }, new int[] { 0, 1, 2 }));


            Expr _i_plus_1 = Z.MkApp(mkTuple, Z.MkAdd(Z.MkProj(0, A.AttrVar), Z.MkInt(1)), Z.True,
                                     Z.MkIte(Z.MkGe(Z.MkProj(0, A.AttrVar), Z.MkInt(4)), Z.GetEnumElement("Color", "green"), Z.GetEnumElement("Color", "blue")), Z.MkProj(3, A.AttrVar), Z.MkAdd(Z.MkProj(4, A.AttrVar), Z.MkNumeral("9/3", Z.RealSort)));

            Expr _i_plus_1_foo = Z.MkApp(mkTuple, Z.MkAdd(Z.MkProj(0, A.AttrVar), Z.MkInt(1)), Z.True,
                                         Z.MkIte(Z.MkGe(Z.MkProj(0, A.AttrVar), Z.MkInt(4)), Z.GetEnumElement("Color", "green"), Z.GetEnumElement("Color", "blue")), Z.MkListFromString("foo", Z.CharacterSort), Z.MkNumeral("5.06", Z.RealSort));

            var proj      = Z.GetTupleField(attrSort, 0);
            var proj_term = Z.MkApp(proj, _i_plus_1);

            var proj_term2 = Z.MkProj(0, _i_plus_1);


            var r1 = Z.TT.MkTreeRule(A, A, 0, "two", Z.MkGe(Z.MkProj(0, A.AttrVar), Z.MkInt(2)),
                                     A.MkTree("two", _i_plus_1, A.MkTree("one", _i_plus_1, A.MkTrans(A, 0, 1)),
                                              A.MkTree("two", _i_plus_1, A.MkTrans(A, 0, 2), A.MkTrans(A, 1, 2))));

            var r2 = Z.TT.MkTreeRule(A, A, 1, "two", Z.MkLe(Z.MkProj(0, A.AttrVar), Z.MkInt(5)),
                                     A.MkTree("two", _i_plus_1, A.MkTree("one", _i_plus_1, A.MkTrans(A, 0, 1)),
                                              A.MkTree("two", _i_plus_1, A.MkTrans(A, 0, 1), A.MkTrans(A, 1, 2))));

            var r3 = Z.TT.MkTreeRule(A, A, 1, "one", Z.True, A.MkTree("zero", _i_plus_1));

            var r4 = Z.TT.MkTreeRule(A, A, 0, "one", Z.True, A.MkTree("zero", _i_plus_1_foo));
            var r5 = Z.TT.MkTreeRule(A, A, 0, "zero", Z.True, A.MkTree("zero", _i_plus_1_foo));

            var T = Z.TT.MkTreeAutomaton(0, A, A, new TreeRule[] { r1, r2, r3, r4, r5 });

            var D = T.ComputeDomainAcceptor();

            var sb      = new StringBuilder();
            var fastgen = new FastGen(Z);

            fastgen.ToFast(enum_sort_name, sb);
            fastgen.ToFast(A, sb);
            fastgen.ToFast("A", T, sb, false);
            fastgen.GetStateName = (x => "p_" + x);
            fastgen.ToFast("A", D, sb, true);

            Console.WriteLine(sb.ToString());
        }
        public static string GetFastProg(TreeTransducer aut, string accName)
        {
            StringBuilder sb = new StringBuilder();
            FastGen fg = new FastGen(aut.TT.Z);
            fg.ToFast(aut.InputAlphabet, sb);
            fg.ToFast("fastacc", aut, sb, true);
            return sb.ToString();
            //foreach (var td in fti.treeDefinitions)
            //{
            //    var tcd = td.Value;
            //    var aut = tcd.acceptors[accName];
            //    var tokenSource = new CancellationTokenSource();
            //    CancellationToken token = tokenSource.Token;

            //    TreeTransducer detAut = null;

            //    var task = Task.Factory.StartNew(() =>
            //    {
            //        aut.IsDeterminstic();
            //        if(complete)
            //            detAut = aut.Determinize();
            //        else
            //            detAut = aut.DeterminizeWithoutCompletion().RemoveUselessStates();
            //    }, token);

            //    if (!task.Wait(Program.timeOut, token))
            //    {
            //        Console.WriteLine("The Task timed out!");
            //        return null;
            //    }
            //    else
            //    {
            //        StringBuilder sb = new StringBuilder();
            //        FastGen fg = new FastGen(detAut.TT.Z);
            //        fg.ToFast(td.Value.alphabet.alph, sb);
            //        fg.ToFast("fastacc", detAut, sb, true);
            //        return sb.ToString();
            //    }
            //}
            //return null;
        }
        //Generate result from query
        private static bool GenerateQueryResult(QueryDef query, Dictionary<string, Def> defs, FastTransducerInstance fti)
        {
            string msg = "";
            switch (query.id.Kind)
            {
                case (Tokens.CONTAINS):
                    {
                        ContainsQueryDef ct = query as ContainsQueryDef;

                        IEnumerable<Expr> t = null;
                        if (ct.expr.kind == FExpKind.Var)
                        {
                            foreach (var treeDef in fti.treeDefinitions)
                                if (treeDef.Value.trees.TryGetValue(ct.expr.token.text, out t))
                                    break;
                        }
                        else
                        {
                            throw new FastException(FastExceptionKind.InternalError);
                        }

                        TreeTransducer lang = OperationTranGen.getTreeAutomatonFromExpr(ct.language, fti, defs);

                        var results = lang.Apply(t).ToList();
                        var containsRes = results.Count>0;

                        msg = string.Format("'{0}' is{1} a member of the language '{2}'", ct.expr, containsRes ? "" : " not", ct.language);
                        if (ct.isAssert)
                        {
                            if (containsRes == ct.assertTrue)
                                return true;
                            else
                                throw new FastAssertException(msg,ct.func.name.line, ct.func.name.position);
                        }
                        break;
                    }
                case (Tokens.TYPECHECK):
                    {
                        TypecheckQueryDef ct = query as TypecheckQueryDef;

                        TreeTransducer input = OperationTranGen.getTreeAutomatonFromExpr(ct.input, fti, defs);
                        TreeTransducer output = OperationTranGen.getTreeAutomatonFromExpr(ct.output, fti, defs);
                        TreeTransducer trans = OperationTranGen.getTreeAutomatonFromExpr(ct.trans, fti, defs);

                        //Preimage of outputcomplement doesn't interesect input
                        var ocomp = output.Complement();
                        var preim = trans.RestrictRange(ocomp).ComputeDomainAcceptor();
                        var badinp = preim.Intersect(input);
                        bool typechecks = badinp.IsEmpty;

                        //For assertions
                        var sb = new StringBuilder();
                        if (!typechecks)
                        {
                            var badInput = badinp.GenerateWitness();
                            FastGen fg = new FastGen(z3p);
                            sb.Append("\n ---> input '");
                            fg.ToFastExpr(badInput, sb, false);
                            sb.Append("' produces output '");
                            // take first bad output
                            foreach (var v in trans.Apply(new Expr[] { badInput }))
                                if(output.Apply(new Expr[] { v })!=null)
                                {
                                    fg.ToFastExpr(v, sb, false);
                                    break;
                                }
                            sb.Append("'");
                        }
                        msg = string.Format("'{0}' has{3} type '{1}' -> '{2}'{4}",
                            ct.trans, ct.input, ct.output, typechecks ? "" : " not",sb.ToString());
                        if (ct.isAssert)
                        {
                            if (typechecks == ct.assertTrue)
                                return true;
                            else
                                throw new FastAssertException(msg, ct.func.name.line, ct.func.name.position);
                        }
                        break;
                    }
                case (Tokens.ID):
                case (Tokens.PRINT):
                    {
                        DisplayQueryDef dt = query as DisplayQueryDef;
                        StringBuilder sb = new StringBuilder();
                        FastGen fastgen = new FastGen(z3p);

                        var toPrintDef = defs[dt.toPrintVar];
                        switch (toPrintDef.kind)
                        {
                            case DefKind.Alphabet:
                            case DefKind.Const:
                            case DefKind.Function:
                            case DefKind.Enum:
                                {
                                    toPrintDef.PrettyPrint(sb);
                                    msg = string.Format("'{0}': {1}", dt.toPrintVar, sb);
                                    break;
                                }
                            case DefKind.Lang:
                                {
                                    LangDef td = toPrintDef as LangDef;
                                    var trans = fti.treeDefinitions[td.domain.name.text].acceptors[dt.toPrintVar];
                                    fastgen.ToFast(dt.toPrintVar,trans, sb,true);
                                    msg = string.Format("{0}", sb);
                                    break;
                                }
                            case DefKind.Trans:
                                {
                                    TransDef td = toPrintDef as TransDef;
                                    var trans = fti.treeDefinitions[td.domain.name.text].transducers[dt.toPrintVar];
                                    fastgen.ToFast(dt.toPrintVar,trans, sb,false);
                                    msg = string.Format("{0}", sb);
                                    break;
                                }
                            case DefKind.Def:
                                {
                                    DefDef df = toPrintDef as DefDef;
                                    switch(df.ddkind){
                                        case DefDefKind.Lang:
                                            {
                                                LangDefDef td = df as LangDefDef;
                                                var trans = fti.treeDefinitions[td.domain.name.text].acceptors[dt.toPrintVar];
                                                fastgen.ToFast(dt.toPrintVar, trans, sb, true);
                                                msg = string.Format("{0}", sb);
                                                break;
                                            }
                                        case DefDefKind.Trans:
                                            {
                                                TransDefDef td = df as TransDefDef;
                                                var trans = fti.treeDefinitions[td.domain.name.text].transducers[dt.toPrintVar];
                                                fastgen.ToFast(dt.toPrintVar, trans, sb, false);
                                                msg = string.Format("{0}", sb);
                                                break;
                                            }
                                        case DefDefKind.Tree:
                                            {
                                                TreeDef td = df as TreeDef;
                                                var trees = new List<Expr>(fti.treeDefinitions[td.domain.name.text].trees[dt.toPrintVar]);
                                                var counter = 1;
                                                if(trees.Count==0){
                                                    msg = string.Format("'{0}' does not contain any tree", dt.toPrintVar);
                                                    break;
                                                }
                                                sb.AppendLine(string.Format("'{0}': [", dt.toPrintVar));
                                                foreach (var tree in trees)
                                                {
                                                    sb.AppendFormat("\t{0}) ",counter);
                                                    fastgen.ToFastExpr(tree, sb, false);
                                                    sb.AppendLine();
                                                    counter++;
                                                }
                                                sb.Append("]");
                                                msg += sb.ToString();
                                                break;
                                            }
                                    }
                                    break;
                                }
                        }
                        break;
                    }
                case (Tokens.STRING):
                    {
                        StringQueryDef ie = query as StringQueryDef;
                        msg = ie.message;
                        break;
                    }
                case (Tokens.IS_EMPTY_TRANS):
                case (Tokens.IS_EMPTY_LANG):
                    {
                        IsEmptyQueryDef ie = query as IsEmptyQueryDef;

                        if (ie.isTrans)
                        {
                            IsEmptyTransQueryDef te = ie as IsEmptyTransQueryDef;
                            TreeTransducer trans = OperationTranGen.getTreeAutomatonFromExpr(te.trans, fti, defs);

                            if (trans.IsEmpty)
                                msg = string.Format("The transformation '{0}' is empty", te.trans);
                            else
                            {
                                FastGen fg = new FastGen(z3p);
                                StringBuilder sb = new StringBuilder();
                                var tre = trans.ComputeDomainAcceptor().GenerateWitness();
                                fg.ToFastExpr(tre, sb, false);
                                msg = string.Format("The transformation '{0}' is not empty\n ---> '{0}' accepts the tree '{1}'", te.trans, sb.ToString());
                            }
                            //For assertions
                            if (te.isAssert)
                            {
                                if (trans.IsEmpty == te.assertTrue)
                                    return true;
                                else
                                    throw new FastAssertException(msg, te.func.name.line, te.func.name.position);
                            }

                        }
                        else
                        {
                            IsEmptyLangQueryDef te = ie as IsEmptyLangQueryDef;
                            TreeTransducer lang = OperationTranGen.getTreeAutomatonFromExpr(te.lang, fti, defs);

                            if (lang.IsEmpty)
                            {
                                msg = string.Format("The transformation '{0}' is empty", te.lang);
                            }
                            else
                            {
                                FastGen fg = new FastGen(z3p);
                                StringBuilder sb = new StringBuilder();
                                var tre = lang.GenerateWitness();
                                fg.ToFastExpr(tre, sb, false);
                                msg = string.Format("The language '{0}' is not empty\n ---> '{0}' accepts the tree '{1}'", te.lang, sb.ToString());
                            }

                            if (te.isAssert)
                            {
                                if (lang.IsEmpty == te.assertTrue)
                                    return true;
                                else
                                    throw new FastAssertException(msg, te.func.name.line, te.func.name.position);
                            }
                        }
                        break;
                    }
                case (Tokens.EQ_TRANS):
                case (Tokens.EQ_LANG):
                    {
                        EquivQueryDef ie = query as EquivQueryDef;

                        if (ie.isTransEquiv)
                        {
                            TransEquivQueryDef te = ie as TransEquivQueryDef;
                            TreeTransducer trans1 = OperationTranGen.getTreeAutomatonFromExpr(te.trans1, fti, defs);
                            TreeTransducer trans2 = OperationTranGen.getTreeAutomatonFromExpr(te.trans2, fti, defs);

                            throw new FastException(FastExceptionKind.NotImplemented);

                            //if (te.isAssert)
                            //{
                            //    if (lang.IsEmpty == te.assertTrue)
                            //        return true;
                            //    else
                            //        throw new FastAssertException(ct.func.name.line, ct.func.name.position);
                            //}
                            //msg = string.Format("The transformation '{0}' is{1} empty", te.trans, trans.IsEmpty ? "" : " not");
                        }
                        else
                        {
                            StringBuilder sb = new StringBuilder();
                            FastGen fg = new FastGen(z3p);
                            StringBuilder msgBd = new StringBuilder();
                            LangEquivQueryDef te = ie as LangEquivQueryDef;
                            TreeTransducer lang1 = OperationTranGen.getTreeAutomatonFromExpr(te.lang1, fti, defs);
                            TreeTransducer lang2 = OperationTranGen.getTreeAutomatonFromExpr(te.lang2, fti, defs);

                            var areEquiv = false;
                            string counterex ="";
                            //var lang1m = lang1.MinimizeMoore();
                            TreeTransducer lang1_compl = lang1.Complement();
                            TreeTransducer lang = lang1_compl.Intersect(lang2);
                            if (lang.IsEmpty)
                            {
                                lang = lang2.Complement().Intersect(lang1);
                                areEquiv = lang.IsEmpty;
                                if (!areEquiv)
                                {
                                    fg.ToFastExpr(lang.GenerateWitness(), sb, false);
                                    counterex = string.Format("---> the language '{0}' contains the tree '{1}' while '{2}' doesn't.", te.lang1, sb.ToString(), te.lang2);
                                }
                            }
                            else
                            {
                                var tre = lang.GenerateWitness();
                                fg.ToFastExpr(tre, sb, false);
                                counterex = string.Format("---> the language '{0}' contains the tree '{1}' while '{2}' doesn't.", te.lang2, sb.ToString(),te.lang1);
                            }

                            msgBd.AppendFormat("The language '{0}' is{1} equivalent to language '{2}':", te.lang1, lang.IsEmpty ? "" : " not",te.lang2);
                            if (!areEquiv)
                            {
                                msgBd.AppendLine();
                                msgBd.Append(counterex);
                            }
                            msg = msgBd.ToString();

                            //Assertion case
                            if (te.isAssert)
                            {
                                if (areEquiv == te.assertTrue)
                                    return true;
                                else
                                    throw new FastAssertException(msg, te.func.name.line, te.func.name.position);
                            }
                        }
                        break;
                    }
                case (Tokens.GEN_CSHARP):
                    {
                        GenCodeQueryDef cge = query as GenCodeQueryDef;
                        StringBuilder sb = new StringBuilder();

                        switch (cge.language)
                        {
                            case PLang.CSharp:
                                fti.ToFast(sb);
                                FastPgm pgm = Parser.ParseFromString(sb.ToString());
                                sb = new StringBuilder();
                                sb.AppendLine("generated C# [");
                                CsharpGenerator.GenerateCode(pgm, sb);
                                sb.AppendLine("]");
                                msg = sb.ToString();
                                break;
                            case PLang.Javascript:
                                throw new FastException(FastExceptionKind.NotImplemented);
                        }
                        break;
                    }
                default:
                    throw new FastException(FastExceptionKind.InternalError);
            }
            fti.fastLog.WriteLog(LogLevel.Minimal, msg);
            fti.queryRes.Add(new QueryResult(msg));
            return true;
        }
 /// <summary>
 /// Generates the corresponding Fast code
 /// </summary>
 /// <param name="sb">string builder to append the generated code</param>
 public void ToFast(StringBuilder sb)
 {
     FastGen fastgen = new FastGen(z3p);
     foreach (var en in enums)
         fastgen.ToFast(en.name, sb);
     foreach (var td in treeDefinitions)
     {
         fastgen.ToFast(td.Value.alphabet.alph, sb);
         foreach (var ac in td.Value.acceptors)
             fastgen.ToFast(ac.Key, ac.Value, sb,true);
         foreach (var tr in td.Value.transducers)
             fastgen.ToFast(tr.Key, tr.Value, sb,false);
         foreach (var tree in td.Value.trees)
             fastgen.ToFastTree(tree.Key, td.Value.alphabet, tree.Value, sb);
     }
 }
Пример #6
0
        public void TestFastGeneration()
        {
            Z3Provider Z = new Z3Provider();

            Sort color = Z.MkEnumSort("Color", "blue", "green", "red");

            string enum_sort_name = color.Name.ToString();
            Assert.AreEqual<string>("Color", enum_sort_name);
            Assert.AreEqual<string>("green", Z.GetEnumElement("Color", "green").FuncDecl.Name.ToString());

            FuncDecl[] fields = new FuncDecl[5];
            FuncDecl mkTuple;
            Sort attrSort = Z.MkTupleSort("$", new string[] { "i", "b", "e", "s", "r" }, new Sort[] { Z.IntSort, Z.BoolSort, color, Z.StringSort, Z.RealSort }, out mkTuple, out fields);

            string tuple_sort_name = attrSort.Name.ToString();
            string tuple_contructor_name = mkTuple.Name.ToString();

            Assert.AreEqual<string>("$", tuple_sort_name);
            Assert.AreEqual<string>("$", tuple_contructor_name);

            Assert.AreEqual<string>("i", fields[0].Name.ToString());
            Assert.AreEqual<string>("b", fields[1].Name.ToString());
            Assert.AreEqual<string>("e", fields[2].Name.ToString());

            Assert.AreEqual<string>("Int", Z.GetRange(fields[0]).Name.ToString());
            Assert.AreEqual<string>("Bool", Z.GetRange(fields[1]).Name.ToString());
            Assert.AreEqual<string>("Color", Z.GetRange(fields[2]).Name.ToString());

            var A = (Z.TT.MkRankedAlphabet("A", attrSort, new string[] { "zero", "one", "two" }, new int[] { 0, 1, 2 }));

            Expr _i_plus_1 = Z.MkApp(mkTuple, Z.MkAdd(Z.MkProj(0, A.AttrVar), Z.MkInt(1)), Z.True,
                Z.MkIte(Z.MkGe(Z.MkProj(0, A.AttrVar), Z.MkInt(4)), Z.GetEnumElement("Color", "green"), Z.GetEnumElement("Color", "blue")), Z.MkProj(3, A.AttrVar), Z.MkAdd(Z.MkProj(4, A.AttrVar), Z.MkNumeral("9/3", Z.RealSort)));

            Expr _i_plus_1_foo = Z.MkApp(mkTuple, Z.MkAdd(Z.MkProj(0, A.AttrVar), Z.MkInt(1)), Z.True,
            Z.MkIte(Z.MkGe(Z.MkProj(0, A.AttrVar), Z.MkInt(4)), Z.GetEnumElement("Color", "green"), Z.GetEnumElement("Color", "blue")), Z.MkListFromString("foo", Z.CharacterSort), Z.MkNumeral("5.06", Z.RealSort));

            var proj = Z.GetTupleField(attrSort, 0);
            var proj_term = Z.MkApp(proj, _i_plus_1);

            var proj_term2 = Z.MkProj(0, _i_plus_1);

            var r1 = Z.TT.MkTreeRule(A, A, 0, "two", Z.MkGe(Z.MkProj(0, A.AttrVar), Z.MkInt(2)),
                A.MkTree("two", _i_plus_1, A.MkTree("one", _i_plus_1, A.MkTrans(A, 0, 1)),
                                           A.MkTree("two", _i_plus_1, A.MkTrans(A, 0, 2), A.MkTrans(A, 1, 2))));

            var r2 = Z.TT.MkTreeRule(A, A, 1, "two", Z.MkLe(Z.MkProj(0, A.AttrVar), Z.MkInt(5)),
               A.MkTree("two", _i_plus_1, A.MkTree("one", _i_plus_1, A.MkTrans(A, 0, 1)),
                                          A.MkTree("two", _i_plus_1, A.MkTrans(A, 0, 1), A.MkTrans(A, 1, 2))));

            var r3 = Z.TT.MkTreeRule(A, A, 1, "one", Z.True, A.MkTree("zero", _i_plus_1));

            var r4 = Z.TT.MkTreeRule(A, A, 0, "one", Z.True, A.MkTree("zero", _i_plus_1_foo));
            var r5 = Z.TT.MkTreeRule(A, A, 0, "zero", Z.True, A.MkTree("zero", _i_plus_1_foo));

            var T = Z.TT.MkTreeAutomaton(0, A, A, new TreeRule[] { r1, r2, r3, r4, r5 });

            var D = T.ComputeDomainAcceptor();

            var sb = new StringBuilder();
            var fastgen = new FastGen(Z);
            fastgen.ToFast(enum_sort_name, sb);
            fastgen.ToFast(A, sb);
            fastgen.ToFast("A", T, sb, false);
            fastgen.GetStateName = (x => "p_" + x);
            fastgen.ToFast("A", D, sb, true);

            Console.WriteLine(sb.ToString());
        }