Ejemplo n.º 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));
     }
 }
Ejemplo n.º 2
0
        public STb <F, T, S> Mk(string regex, params Tuple <string, STb <F, T, S> >[] args)
        {
            var  K = args.Length;
            bool isLoop;
            var  patternAutomataPairs = solver.CharSetProvider.ConvertCaptures(regex, out isLoop);
            var  captureAutomata      = new Dictionary <string, Automaton <BDD> >();
            var  stbs = new Dictionary <string, STb <F, T, S> >();

            foreach (var arg in args)
            {
                if (stbs.ContainsKey(arg.Item1) || string.IsNullOrEmpty(arg.Item1))
                {
                    throw new AutomataException(AutomataExceptionKind.InvalidArguments);
                }
                stbs[arg.Item1] = arg.Item2;
            }
            foreach (var pair in patternAutomataPairs)
            {
                if (pair.Item1 != "")
                {
                    captureAutomata[pair.Item1] = pair.Item2;
                }
            }

            var captureSortPos  = new Dictionary <string, int>();
            var captureSortName = new Dictionary <string, string>();

            for (int i = 0; i < args.Length; i += 1)
            {
                captureSortName[args[i].Item1] = args[i].Item2.OutputSort.ToString();
                captureSortPos[args[i].Item1]  = i;
            }

            if (Array.Exists(patternAutomataPairs, pair => (pair.Item1 != "" && !captureSortName.ContainsKey(pair.Item1))))
            {
                throw new AutomataException(AutomataExceptionKind.InvalidArguments);
            }

            S[] argSorts = new S[K];
            for (int i = 0; i < K; i++)
            {
                if (!captureAutomata.ContainsKey(args[i].Item1))
                {
                    throw new AutomataException(AutomataExceptionKind.InvalidArguments);
                }
                if (!args[i].Item2.OutputSort.Equals(args[i].Item2.RegisterSort))
                {
                    throw new AutomataException(AutomataExceptionKind.InvalidArguments);
                }
                argSorts[i] = args[i].Item2.OutputSort;
            }

            var regSort = solver.MkTupleSort(argSorts);
            var regVar  = solver.MkVar(1, regSort);
            var initReg = solver.MainSolver.FindOneMember(solver.MkEq(regVar, regVar)).Value;
            var inpVar  = solver.MkVar(0, solver.CharSort);

            var stb = new STb <F, T, S>(solver, "stb", solver.CharSort, regSort, regSort, initReg, 0);

            var nextStateId = 0;
            var stateIdMap  = new Dictionary <Tuple <int, int, int>, int>();
            Func <int, int, int, int> MkState = (n, q1, q2) =>
            {
                int p;
                var nq = new Tuple <int, int, int>(n, q1, q2);
                if (stateIdMap.TryGetValue(nq, out p))
                {
                    return(p);
                }
                else
                {
                    p              = nextStateId;
                    nextStateId   += 1;
                    stateIdMap[nq] = p;
                    return(p);
                }
            };

            var resSTB = new STb <F, T, S>(solver, "STB", solver.CharSort, solver.CharSort, solver.UnitSort, solver.UnitConst, 0);

            resSTB.AssignRule(0, new BaseRule <T>(new Sequence <T>(solver.MkCharVar(0)), solver.UnitConst, 0));
            resSTB.AssignFinalRule(0, new BaseRule <T>(Sequence <T> .Empty, solver.UnitConst, 0));

            for (int i = 0; i < patternAutomataPairs.Length; i++)
            {
                var aut = patternAutomataPairs[i].Item2;

                if (patternAutomataPairs[i].Item1 == "")
                {
                    var autSTMoves = new List <Move <Rule <T> > >();
                    foreach (var move in aut.GetMoves())
                    {
                        //move cannot be epsilon here
                        var cond = solver.ConvertFromCharSet(move.Label);
                        autSTMoves.Add(Move <Rule <T> > .Create(move.SourceState, move.TargetState, Rule <T> .Mk(cond, solver.UnitConst)));
                    }
                    foreach (var f in aut.GetFinalStates())
                    {
                        //collect guards of all moves exitingfrom f
                        var allGuardsFromF = solver.CharSetProvider.False;
                        foreach (var fmove in aut.GetMovesFrom(f))
                        {
                            allGuardsFromF = solver.CharSetProvider.MkOr(allGuardsFromF, fmove.Label);
                        }
                        var elseFromF = solver.ConvertFromCharSet(solver.CharSetProvider.MkNot(allGuardsFromF));
                        autSTMoves.Add(Move <Rule <T> > .Create(f, f, Rule <T> .Mk(elseFromF, solver.UnitConst, solver.MkCharVar(0))));
                        autSTMoves.Add(Move <Rule <T> > .Create(f, f, Rule <T> .MkFinal(solver.True)));
                    }

                    var autST = ST <F, T, S> .Create(solver, patternAutomataPairs[i].Item1, solver.UnitConst, solver.CharSort,
                                                     solver.CharSort, solver.UnitSort, aut.InitialState, autSTMoves);

                    var autSTb = autST.ToSTb();
                    resSTB = resSTB.Compose(autSTb);
                }
                else
                {
                    var stb1 = stbs[patternAutomataPairs[i].Item1];
                    if (!stb1.InputSort.Equals(solver.CharSort))
                    {
                        throw new AutomataException(AutomataExceptionKind.InvalidArguments);
                    }

                    var autSTMoves = new List <Move <Rule <T> > >();
                    foreach (var move in aut.GetMoves())
                    {
                        //move cannot be epsilon here
                        var cond = solver.ConvertFromCharSet(move.Label);
                        autSTMoves.Add(Move <Rule <T> > .Create(move.SourceState, move.TargetState, Rule <T> .Mk(cond, solver.UnitConst, inpVar)));
                    }
                    foreach (var f in aut.GetFinalStates())
                    {
                        autSTMoves.Add(Move <Rule <T> > .Create(f, f, Rule <T> .MkFinal(solver.True)));
                    }

                    var autST = ST <F, T, S> .Create(solver, patternAutomataPairs[i].Item1, solver.UnitConst, solver.CharSort,
                                                     solver.CharSort, solver.UnitSort, aut.InitialState, autSTMoves);

                    var autSTb = autST.ToSTb();

                    var stb2 = autSTb.Compose(stb1);

                    foreach (var f in stb.States)
                    {
                        var frule = stb.GetFinalRuleFrom(f);
                        if (frule.IsNotUndef)
                        {
                            //var frule1 =
                        }
                    }
                }
            }

            throw new NotImplementedException();
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 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[] { },
            });
        }