Beispiel #1
0
 private BranchingRule <TERM> EvalB(ConsList <TERM> inputs, int qA, TERM regA, TERM pathCond, int qB, TERM regB, Func <int, int, int> stateComposer, Sequence <TERM> outputFromB, bool isFinal)
 {
     if (inputs == null)
     {
         int qAB = stateComposer(qA, qB);
         if (isFinal)
         {
             var fr = B.GetFinalRuleFrom(qB);
             if (fr.IsNotUndef)
             {
                 return(this.CreateFinalComposedRule(pathCond, qAB, outputFromB, fr, regB));
             }
             else
             {
                 return(UndefRule <TERM> .Default);
             }
         }
         else
         {
             TERM regAB = (regA.Equals(regVar_1) && regB.Equals(regVar_2) ? regVar : JoinRegs(regA, regB));
             var  res   = new BaseRule <TERM>(outputFromB, regAB, qAB);
             return(res);
         }
     }
     else
     {
         return(EvalB_Rule(B.GetRuleFrom(qB), qA, regA, pathCond, inputs, regB, stateComposer, outputFromB, isFinal));
     }
 }
Beispiel #2
0
        int TotalIteRules(STb <FuncDecl, Expr, Sort> stb)
        {
            int count = 0;

            foreach (var state in stb.States)
            {
                var rule = stb.GetRuleFrom(state);
                count += IteRules(rule);
            }
            return(count);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
        static public ComputationTree ToComputationTrees(STb <FuncDecl, Expr, Sort> stb, bool includeOutput)
        {
            var ctx = ((Z3Provider)stb.Solver).Z3;

            var states         = stb.States.Select((State, Index) => new { State, Index, Name = "S" + State });
            var csEnumSort     = ctx.IntSort;
            var outputListSort = stb.OutputListSort as ListSort;
            var resultSort     = ctx.MkTupleSort(ctx.MkSymbol(stb.Name + "#STATE"),
                                                 new[] { ctx.MkSymbol("#CS"), ctx.MkSymbol("#OUT"), ctx.MkSymbol("#VARS") },
                                                 new[] { csEnumSort, outputListSort, stb.RegisterSort });
            var csField       = resultSort.FieldDecls[0];
            var outputField   = resultSort.FieldDecls[1];
            var registerField = resultSort.FieldDecls[2];

            var inputVar       = stb.Solver.MkVar(0, stb.InputSort);
            var registerVar    = stb.Solver.MkVar(1, stb.RegisterSort);
            var computationVar = stb.Solver.MkVar(2, resultSort);

            var csProjection       = csField.Apply(computationVar);
            var outputProjection   = outputField.Apply(computationVar);
            var registerProjection = registerField.Apply(computationVar);

            Func <int, Expr[], Expr, Expr> createResult = (state, yields, register) =>
            {
                Expr output;

                if (includeOutput)
                {
                    output = yields.Length == 0 ? outputProjection : ctx.MkFuncDecl("Append", new Sort[] { outputListSort, outputListSort }, outputListSort).Apply(
                        outputProjection, ctx.MkFuncDecl("List", yields.Select(x => x.Sort).ToArray(), outputListSort).Apply(yields));
                }
                else
                {
                    output = outputProjection;
                }
                var result = resultSort.MkDecl.Apply(
                    ctx.MkInt(state),
                    output,
                    register != null ? register : registerProjection);
                return(result.Substitute(registerVar, registerProjection));
            };

            ComputationNode ruleNode;
            var             stateComps = stb.States.Select(State => new { State, Computation = ToComputationTree(ctx, stb.GetRuleFrom(State), registerVar, registerProjection, createResult) }).ToList();

            if (stateComps.Count == 0)
            {
                ruleNode = new UndefinedNode();
            }
            else
            {
                ruleNode = new SwitchNode(stateComps.Select(x => ctx.MkEq(csProjection, ctx.MkInt(x.State))).ToArray(), stateComps.Select(x => x.Computation).ToArray());
            }

            ComputationNode finalNode;
            var             finalComps = stb.States.Where(s => stb.IsFinalState(s))
                                         .Select(State => new { State, Computation = ToComputationTree(ctx, stb.GetFinalRuleFrom(State), registerVar, registerProjection, createResult) }).ToList();

            if (finalComps.Count == 0)
            {
                finalNode = new UndefinedNode();
            }
            else
            {
                finalNode = new SwitchNode(finalComps.Select(x => ctx.MkEq(csProjection, ctx.MkInt(x.State))).ToArray(), finalComps.Select(x => x.Computation).ToArray());
            }

            var initialState = resultSort.MkDecl.Apply(
                ctx.MkInt(stb.InitialState),
                outputListSort.Nil,
                stb.InitialRegister);

            return(new ComputationTree
            {
                Move = ruleNode,
                Finish = finalNode,
                InitialState = initialState,
                EnumSorts = new EnumSort[] { },
            });
        }