Пример #1
0
        public STb <FUNC, TERM, SORT> Minimize()
        {
            var s = stb.Solver;

            var alphaSort = s.MkOptionSort(stb.InputSort);
            var autoSort  = s.MkTupleSort(alphaSort, stb.OutputListSort, stb.RegisterSort, stb.RegisterSort);
            var autoVar   = s.MkVar(3, autoSort);

            var autoInput      = s.MkProj(0, autoVar);
            var autoSomeInput  = s.MkGetSomeValue(autoInput);
            var autoOutputList = s.MkProj(1, autoVar);
            var autoOldReg     = s.MkProj(2, autoVar);
            var autoNewReg     = s.MkProj(3, autoVar);

            Func <TERM, TERM> finalSubstitute    = (t) => s.ApplySubstitution(t, stb.RegVar, autoOldReg);
            Func <TERM, TERM> nonFinalSubstitute = (t) => finalSubstitute(s.ApplySubstitution(t, stb.InputVar, autoSomeInput));

            int acceptingState = stb.States.Max() + 1;
            int errorState     = stb.States.Max() + 2;
            var moves          = new List <Move <TERM> >();

            foreach (var state in stb.States)
            {
                var nonFinalConds = new List <TERM>();
                foreach (var nonFinal in st.GetNonFinalMovesFrom(state))
                {
                    var rule  = nonFinal.Label;
                    var conds = new List <TERM>();
                    conds.Add(s.MkIsSome(autoInput));
                    conds.Add(nonFinalSubstitute(rule.Guard));
                    var outputList = autoOutputList;
                    foreach (var yield in rule.Output)
                    {
                        conds.Add(s.MkIsCons(outputList));
                        conds.Add(s.MkEq(s.MkFirstOfList(outputList), nonFinalSubstitute(yield)));
                        outputList = s.MkRestOfList(outputList);
                    }
                    conds.Add(s.MkIsNil(outputList));
                    conds.Add(s.MkEq(autoNewReg, nonFinalSubstitute(rule.Update)));
                    var cond = s.MkAnd(conds);
                    moves.Add(Move <TERM> .Create(state, nonFinal.TargetState, cond));
                    nonFinalConds.Add(cond);
                }
                var finalConds = new List <TERM>();
                foreach (var rule in st.GetFinalRules(state))
                {
                    var conds = new List <TERM>();
                    conds.Add(s.MkIsNone(autoInput));
                    conds.Add(finalSubstitute(rule.Guard));
                    var outputList = autoOutputList;
                    foreach (var yield in rule.Output)
                    {
                        conds.Add(s.MkIsCons(outputList));
                        conds.Add(s.MkEq(s.MkFirstOfList(outputList), finalSubstitute(yield)));
                        outputList = s.MkRestOfList(outputList);
                    }
                    conds.Add(s.MkIsNil(outputList));
                    var cond = s.MkAnd(conds);
                    moves.Add(Move <TERM> .Create(state, acceptingState, cond));
                    finalConds.Add(cond);
                }
            }
            //moves.Add(Move<TERM>.Create(errorState, errorState, s.True));
            var auto = Automaton <TERM> .Create(stb.Solver, stb.InitialState, new int[] { acceptingState }, moves);

            auto.CheckDeterminism(stb.Solver);
            var blocks = auto.BookkeepingMinimize(stb.Solver);

            Func <STbRule <TERM>, STbRule <TERM> > redirect = null;

            redirect = r =>
            {
                switch (r.RuleKind)
                {
                case STbRuleKind.Undef:
                    return(r);

                case STbRuleKind.Base:
                    return(new BaseRule <TERM>(r.Yields, r.Register, blocks[r.State].GetRepresentative()));

                case STbRuleKind.Ite:
                    var t = redirect(r.TrueCase);
                    var f = redirect(r.FalseCase);
                    return(new IteRule <TERM>(r.Condition, t, f));

                default:
                    throw new NotImplementedException();
                }
            };

            var minimized = new STb <FUNC, TERM, SORT>(stb.Solver, stb.Name + "_min", stb.InputSort, stb.OutputSort, stb.RegisterSort, stb.InitialRegister,
                                                       blocks[stb.InitialState].GetRepresentative());
            var representatives = new HashSet <int>();

            foreach (var state in stb.States)
            {
                representatives.Add(blocks[state].GetRepresentative());
            }
            foreach (var state in representatives)
            {
                minimized.AssignRule(state, redirect(stb.GetRuleFrom(state)).CollapseRedundantITEs(s));
                minimized.AssignFinalRule(state, redirect(stb.GetFinalRuleFrom(state)).CollapseRedundantITEs(s));
            }
            return(minimized);
        }