示例#1
0
        public STb <FUNC, TERM, SORT> Compose()
        {
            var stack         = new SimpleStack <Tuple <int, int> >();
            int stateId       = 1;
            var stateIdMap    = new Dictionary <Tuple <int, int>, int>();
            var revStateIdMap = new Dictionary <int, Tuple <int, int> >();
            var q0A_x_q0B     = new Tuple <int, int>(A.InitialState, B.InitialState);

            stack.Push(q0A_x_q0B);
            stateIdMap[q0A_x_q0B] = 0;
            revStateIdMap[0]      = q0A_x_q0B;

            Func <int, int, int> ComposeStates = (x, y) =>
            {
                var xy = new Tuple <int, int>(x, y);
                int q;
                if (stateIdMap.TryGetValue(xy, out q))
                {
                    return(q);
                }
                else
                {
                    q                = stateId;
                    stateId         += 1;
                    stateIdMap[xy]   = q;
                    revStateIdMap[q] = xy;
                    stack.Push(xy);
                    return(q);
                }
            };
            var A2B = new STb <FUNC, TERM, SORT>(solver, A.Name + "2" + B.Name, A.InputSort, B.OutputSort, regSort, JoinRegs(A.InitialRegister, B.InitialRegister), 0);

            //create normal composed rules
            while (stack.IsNonempty)
            {
                var qA_x_qB = stack.Pop();
                var qA      = qA_x_qB.Item1;
                var qB      = qA_x_qB.Item2;
                var ruleA   = A.GetRuleFrom(qA);
                if (ruleA.IsNotUndef)
                {
                    var qAB_rule = Comp(solver.True, ruleA, qB, ComposeStates, false);
                    A2B.AssignRule(stateIdMap[qA_x_qB], qAB_rule);
                }
                else
                {
                    A2B.AssignRule(stateIdMap[qA_x_qB], UndefRule <TERM> .Default);
                }
            }
            foreach (var qAB in A2B.States)
            {
                var qA_x_qB = revStateIdMap[qAB];
                var qA      = qA_x_qB.Item1;
                var qB      = qA_x_qB.Item2;
                var ruleA   = A.GetFinalRuleFrom(qA);
                if (ruleA.IsNotUndef)
                {
                    var qAB_Frule = Comp(solver.True, ruleA, qB, (p, q) => qAB, true);
                    A2B.AssignFinalRule(qAB, qAB_Frule);
                }
            }

            A2B.EliminateDeadends();


            //Func<Rule<TERM>, Rule<TERM>> ReplaceWithEpsilon = (r) =>
            //    {

            //    };

            //var aut = A2B.ToST(true).automaton.RelpaceAllGuards(ReplaceWithEpsilon);


            return(A2B);
        }