示例#1
0
 public IEnumerable <Move <Sequence <T> > > EnumerateRelevantMoves()
 {
     foreach (var entry in witnessMap)
     {
         if (entry.Key.Item1 != entry.Key.Item2) //ignore loops
         {
             if (!entry.Value.IsEmpty)
             {
                 yield return(Move <Sequence <T> > .Create(entry.Key.Item1, entry.Key.Item2, entry.Value));
             }
             else //represent empty sequences as epsilons
             {
                 yield return(Move <Sequence <T> > .Epsilon(entry.Key.Item1, entry.Key.Item2));
             }
         }
     }
     foreach (var pushes in pushMap)
     {
         foreach (var trans in pushes.Value)
         {
             yield return(Move <Sequence <T> > .Epsilon(trans.Item1, trans.Item2));
         }
     }
 }
示例#2
0
        public Automaton <S> GetAtom(Automaton <S> psi)
        {
            if (!IsAtomic)
            {
                throw new AutomataException(AutomataExceptionKind.BooleanAlgebraIsNotAtomic);
            }

            if (psi.IsEmpty)
            {
                return(psi);
            }

            var path  = new List <S>(psi.ChoosePathToSomeFinalState(new Chooser()));
            var moves = new List <Move <S> >();

            for (int i = 0; i < path.Count; i++)
            {
                moves.Add(Move <S> .Create(i, i + 1, solver.GetAtom(path[i])));
            }

            var atom = Automaton <S> .Create(solver, 0, new int[] { path.Count }, moves);

            return(atom);
        }
示例#3
0
        /// <summary>
        /// Builds an end of line anchor automaton ($ in multiline mode)
        /// </summary>
        /// <param name="newLineCond">condition that is true only for a newline character</param>
        public Automaton <S> MkEol(S newLineCond)
        {
            if (!isEnd)
            {
                throw new AutomataException(AutomataExceptionKind.MisplacedEndAnchor);
            }

            if (isBeg)
            {
                return(MkFull());
            }

            var st          = this.MkStateId();
            var st1         = this.MkStateId();
            var minStateId2 = this.MkStateId();

            Automaton <S> fa = Automaton <S> .Create(this.solver, st, new int[] { st, st1 },
                                                     new Move <S>[] {
                Move <S> .Create(st, st1, newLineCond),
                Move <S> .Create(st1, st1, solver.True)
            });

            return(fa);
        }
示例#4
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();
        }
示例#5
0
        public STb <F, T, S> Mk(string regex, params string[] parseInfo)
        {
            if (parseInfo.Length % 2 != 0)
            {
                throw new AutomataException(AutomataExceptionKind.InvalidArguments);
            }

            var K    = parseInfo.Length / 2;
            var args = new Tuple <string, string> [K];

            for (int i = 0; i < parseInfo.Length; i += 2)
            {
                args[i / 2] = new Tuple <string, string>(parseInfo[i], parseInfo[i + 1]);
            }

            bool isLoop;
            var  patternAutomataPairs = solver.CharSetProvider.ConvertCaptures(regex, out isLoop);
            var  captureAutomata      = new Dictionary <string, Automaton <BDD> >();

            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;
                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);
                }
                else if (args[i].Item2 == "int")
                {
                    argSorts[i] = solver.MkBitVecSort(32);
                }
                else if (args[i].Item2 == "last")
                {
                    argSorts[i] = solver.CharSort;
                }
                else if (args[i].Item2 == "length")
                {
                    argSorts[i] = solver.MkBitVecSort(32);
                }
                else if (args[i].Item2 == "bool")
                {
                    argSorts[i] = solver.BoolSort;
                }
                else
                {
                    throw new AutomataException(AutomataExceptionKind.InvalidArguments);
                }
            }

            var regSort = solver.MkTupleSort(argSorts);
            var initReg = solver.MkTuple(Array.ConvertAll(argSorts, s => (s.Equals(solver.BoolSort) ? solver.False : solver.MkNumeral(0, solver.MkBitVecSort(32)))));
            var regVar  = solver.MkVar(1, regSort);
            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>();
            Func <int, int, int> MkState = (n, q) => {
                int p;
                var nq = new Tuple <int, int>(n, q);
                if (stateIdMap.TryGetValue(nq, out p))
                {
                    return(p);
                }
                else
                {
                    p              = nextStateId;
                    nextStateId   += 1;
                    stateIdMap[nq] = p;
                    return(p);
                }
            };

            var allMoves = new List <Move <Pair <BDD, T> > >();
            var bv32     = solver.MkBitVecSort(32);

            Func <T, T> AddZeros = (c) =>
            {
                uint k = (uint)(32 - (int)solver.CharSetProvider.Encoding);
                if (k == 0)
                {
                    return(c);
                }
                else
                {
                    return(solver.MkZeroExt(k, c));
                }
            };

            Func <int, T> ToInt = (i) =>
            {
                var elems = new T[K];
                for (int j = 0; j < K; j++)
                {
                    if (i == j)
                    {
                        elems[j] = solver.MkBvAdd(solver.MkBvMul(solver.MkNumeral(10, bv32), solver.MkProj(j, regVar)), solver.MkBvSub(AddZeros(inpVar), solver.MkNumeral((int)'0', bv32)));
                    }
                    else
                    {
                        elems[j] = solver.MkProj(j, regVar);
                    }
                }
                var res = solver.MkTuple(elems);
                return(res);
            };

            Func <int, T> ToLen = (i) =>
            {
                var elems = new T[K];
                for (int j = 0; j < K; j++)
                {
                    if (i == j)
                    {
                        elems[j] = solver.MkBvAdd(solver.MkNumeral(1, bv32), solver.MkProj(j, regVar));
                    }
                    else
                    {
                        elems[j] = solver.MkProj(j, regVar);
                    }
                }
                var res = solver.MkTuple(elems);
                return(res);
            };

            Func <int, T> KeepLast = (i) =>
            {
                var elems = new T[K];
                for (int j = 0; j < K; j++)
                {
                    if (i == j)
                    {
                        elems[j] = inpVar;
                    }
                    else
                    {
                        elems[j] = solver.MkProj(j, regVar);
                    }
                }
                var res = solver.MkTuple(elems);
                return(res);
            };

            Func <int, bool, T> AssignBool = (i, b) =>
            {
                var elems = new T[K];
                for (int j = 0; j < K; j++)
                {
                    if (i == j)
                    {
                        elems[j] = (b ? solver.True : solver.False);
                    }
                    else
                    {
                        elems[j] = solver.MkProj(j, regVar);
                    }
                }
                var res = solver.MkTuple(elems);
                return(res);
            };


            for (int i = 0; i < patternAutomataPairs.Length; i++)
            {
                var aut = patternAutomataPairs[i].Item2;
                if (patternAutomataPairs[i].Item1 == "")
                {
                    foreach (var m in aut.GetMoves())
                    {
                        allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, regVar)));
                    }
                }
                else if (captureSortName[patternAutomataPairs[i].Item1] == "int")
                {
                    foreach (var m in aut.GetMoves())
                    {
                        allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, ToInt(captureSortPos[patternAutomataPairs[i].Item1]))));
                    }
                }
                else if (captureSortName[patternAutomataPairs[i].Item1] == "length")
                {
                    foreach (var m in aut.GetMoves())
                    {
                        allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, ToLen(captureSortPos[patternAutomataPairs[i].Item1]))));
                    }
                }
                else if (captureSortName[patternAutomataPairs[i].Item1] == "last")
                {
                    foreach (var m in aut.GetMoves())
                    {
                        allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, KeepLast(captureSortPos[patternAutomataPairs[i].Item1]))));
                    }
                }
                else if (captureSortName[patternAutomataPairs[i].Item1] == "bool")
                {
                    var boolAcceptor = solver.CharSetProvider.Convert("^((T|t)rue|(F|f)alse)$").Intersect(patternAutomataPairs[i].Item2, solver.CharSetProvider).Minimize(solver.CharSetProvider);

                    if (boolAcceptor.IsEmpty)
                    {
                        throw new AutomataException(AutomataExceptionKind.CaptureIsInfeasibleAsBoolean);
                    }

                    patternAutomataPairs[i] = new Tuple <string, Automaton <BDD> >(patternAutomataPairs[i].Item1, boolAcceptor);

                    var _t = solver.CharSetProvider.MkCharSetFromRanges('t', 't', 'T', 'T');
                    var _f = solver.CharSetProvider.MkCharSetFromRanges('f', 'f', 'F', 'F');
                    foreach (var m in boolAcceptor.GetMoves())
                    {
                        if (m.SourceState == boolAcceptor.InitialState)
                        {
                            if (solver.CharSetProvider.IsSatisfiable(solver.CharSetProvider.MkAnd(_t, m.Label)))
                            {
                                allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, AssignBool(captureSortPos[patternAutomataPairs[i].Item1], true))));
                            }
                            else if (solver.CharSetProvider.IsSatisfiable(solver.CharSetProvider.MkAnd(_f, m.Label)))
                            {
                                allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, AssignBool(captureSortPos[patternAutomataPairs[i].Item1], false))));
                            }
                        }
                        else
                        {
                            allMoves.Add(Move <Pair <BDD, T> > .Create(MkState(i, m.SourceState), MkState(i, m.TargetState), new Pair <BDD, T>(m.Label, regVar)));
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            for (int i = 0; i < patternAutomataPairs.Length - 1; i++)
            {
                foreach (var q in patternAutomataPairs[i].Item2.GetFinalStates())
                {
                    allMoves.Add(Move <Pair <BDD, T> > .Epsilon(MkState(i, q), MkState(i + 1, patternAutomataPairs[i + 1].Item2.InitialState)));
                }
            }

            var L = patternAutomataPairs.Length - 1;

            var finalStates = new List <int>();

            foreach (var f in patternAutomataPairs[L].Item2.GetFinalStates())
            {
                finalStates.Add(MkState(L, f));
            }

            var tmpAutE = Automaton <Pair <BDD, T> > .Create(null, MkState(0, patternAutomataPairs[0].Item2.InitialState), finalStates, allMoves);

            Func <Pair <BDD, T>, Pair <BDD, T>, Pair <BDD, T> > error = (f1, f2) =>
            {
                throw new AutomataException(AutomataExceptionKind.InternalError);
            };

            var tmpAut = tmpAutE.RemoveEpsilons(error);

            tmpAut.isDeterministic = true;

            var name = "";

            foreach (var pair in args)
            {
                name = (name == "" ? pair.Item2 : name + "_" + pair.Item2);
            }
            var STB = Automaton2STb(tmpAut, name, regSort, initReg, isLoop);

            return(STB);
        }
示例#6
0
 /// <summary>
 ///  Make a move that corresponds to a final rule. This is indicated by IsFinal=true of the condition of the move.
 /// </summary>
 /// <param name="finalState">final state</param>
 /// <param name="finalCondition">guard of the final outputs</param>
 /// <param name="finalYields">final outputs</param>
 /// <returns>a move from final state to final state that represents the final outputs yielded from the final state</returns>
 public Move <Rule <TERM> > MkFinalOutput(int finalState, TERM finalCondition, params TERM[] finalYields)
 {
     return(Move <Rule <TERM> > .Create(finalState, finalState, Rule <TERM> .MkFinal(finalCondition, finalYields)));
 }
示例#7
0
 /// <summary>
 /// Make a move that corresponds to a nonfinal rule. This is indicated by IsFinal=false of the label of the move.
 /// </summary>
 /// <param name="source">source state of the move</param>
 /// <param name="target">target state of the move</param>
 /// <param name="guard">guard of the rule</param>
 /// <param name="update">update of the rule</param>
 /// <param name="yields">sequence of output yields of the rule</param>
 /// <returns>nonfinal move from source to target</returns>
 public Move <Rule <TERM> > MkRule(int source, int target, TERM guard, TERM update, params TERM[] yields)
 {
     return(Move <Rule <TERM> > .Create(source, target, Rule <TERM> .Mk(guard, update, yields)));
 }
示例#8
0
 public override IEnumerable <Move <Rule <TERM> > > EnumerateMoves(IContextCore <TERM> solver, int source, TERM guard)
 {
     yield return(Move <Rule <TERM> > .Create(source, state, Rule <TERM> .Mk(guard, register, yields.ToArray())));
 }
        /// <summary>
        /// Builds an automaton that accepts all words.
        /// </summary>
        public Automaton <S> MkFull()
        {
            var st = this.MkStateId();

            return(Automaton <S> .Create(this.solver, st, new int[] { st }, new Move <S>[] { Move <S> .Create(st, st, solver.True) }));
        }
示例#10
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);
        }
示例#11
0
        /// <summary>
        /// Concertize the SFA by including at most k characters in the label.
        /// </summary>
        /// <param name="k">upper limit on the number of included characters in the output automaton, when 0 or negative then include all elements</param>
        /// <returns></returns>
        public Automaton <BDD> Concretize(int k = 0)
        {
            //if (k <= 0)
            //    throw new AutomataException(AutomataExceptionKind.InvalidArgument);

            var mem = new Dictionary <TERM, BDD>();

            var concrete_moves = new List <Move <BDD> >();

            var moveMap = new Dictionary <Tuple <int, int>, BDD>();
            Action <int, int, BDD> AddMove = (from, to, guard) =>
            {
                BDD pred;
                var key = new Tuple <int, int>(from, to);
                if (moveMap.TryGetValue(key, out pred))
                {
                    pred = solver.CharSetProvider.MkOr(pred, guard);
                }
                else
                {
                    pred = guard;
                }
                moveMap[key] = pred;
            };

            Predicate <TERM> IsGround = t =>
            {
                foreach (var v in solver.GetVars(t))
                {
                    return(false);
                }
                return(true);
            };

            foreach (var move in automaton.GetMoves())
            {
                if (move.IsEpsilon)
                {
                    concrete_moves.Add(Move <BDD> .Epsilon(move.SourceState, move.TargetState));
                    continue;
                }
                BDD set;
                if (mem.TryGetValue(move.Label, out set))
                {
                    AddMove(move.SourceState, move.TargetState, set);
                    //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, set));
                    continue;
                }
                if (k > 0)
                {
                    if (IsGround(move.Label))  //must be satisfiable so same as true
                    {
                        set             = solver.CharSetProvider.MkRangeConstraint((char)0, (char)(k - 1));
                        mem[move.Label] = set;
                        AddMove(move.SourceState, move.TargetState, set);
                        //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, set));
                        continue;
                    }
                    var elems = new List <uint>();
                    foreach (var v in solver.MainSolver.FindAllMembers(move.Label))
                    {
                        elems.Add(solver.GetNumeralUInt(v.Value));
                        if (elems.Count == k)
                        {
                            break;
                        }
                    }
                    set             = solver.CharSetProvider.MkSetFromElements(elems, ((int)solver.CharSetProvider.Encoding) - 1);
                    mem[move.Label] = set;
                    AddMove(move.SourceState, move.TargetState, set);
                    //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, set));
                }
                else
                {
                    BDD cond = solver.ConvertToCharSet(solver.CharSetProvider, move.Label);
                    if (cond != null)
                    {
                        throw new AutomataException(AutomataExceptionKind.ConditionCannotBeConvertedToCharSet);
                    }

                    mem[move.Label] = cond;
                    AddMove(move.SourceState, move.TargetState, cond);
                    //concrete_moves.Add(Move<BvSet>.M(move.SourceState, move.TargetState, cond));
                }
            }
            foreach (var entry in moveMap)
            {
                concrete_moves.Add(Move <BDD> .Create(entry.Key.Item1, entry.Key.Item2, entry.Value));
            }

            var res = Automaton <BDD> .Create(this.solver.CharSetProvider, this.automaton.InitialState, this.automaton.GetFinalStates(), concrete_moves);

            return(res);
        }
示例#12
0
        public static CsAutomaton <S> CreateFrom(CountingAutomaton <S> ca)
        {
            var productmoves = new List <Move <CsPred <S> > >();
            var counters     = ca.counters;
            var alg          = new CsAlgebra <S>(((CABA <S>)ca.Algebra).builder.solver, counters);

            foreach (var move in ca.GetMoves())
            {
                var ccond = alg.TrueCsConditionSeq;
                if (ca.IsCountingState(move.SourceState))
                {
                    var counter = ca.GetCounter(move.SourceState);
                    var cid     = counter.CounterId;
                    if (move.Label.Item2.First.OperationKind == CounterOp.EXIT ||
                        move.Label.Item2.First.OperationKind == CounterOp.EXIT_SET0 ||
                        move.Label.Item2.First.OperationKind == CounterOp.EXIT_SET1)
                    {
                        if (counter.LowerBound == counter.UpperBound && !ca.HasMovesTo(move.SourceState, move.Label.Item1.Element))
                        {
                            ccond = ccond.And(cid, CsCondition.HIGH);
                        }
                        else if (counter.LowerBound > 0)
                        {
                            ccond = ccond.And(cid, CsCondition.CANEXIT);
                        }
                        else
                        {
                            ccond.And(cid, CsCondition.NONEMPTY);
                        }
                    }
                    else
                    {
                        if (move.Label.Item2.First.OperationKind != CounterOp.INCR)
                        {
                            throw new AutomataException(AutomataExceptionKind.InternalError);
                        }

                        if (counter.LowerBound == counter.UpperBound && !ca.HasMovesTo(move.SourceState, move.Label.Item1.Element))
                        {
                            ccond = ccond.And(cid, CsCondition.LOW);
                        }
                        else
                        {
                            ccond = ccond.And(cid, CsCondition.CANLOOP);
                        }
                    }
                }
                if (ccond.IsSatisfiable)
                {
                    var pmove = Move <CsPred <S> > .Create(move.SourceState, move.TargetState, alg.MkPredicate(move.Label.Item1.Element, ccond));

                    productmoves.Add(pmove);
                }
            }
            var prodaut = Automaton <CsPred <S> > .Create(alg, ca.InitialState, ca.GetFinalStates(), productmoves);

            PowerSetStateBuilder sb;
            var det = prodaut.Determinize(out sb);

            //add predicate that all counters associated with the state are nonempty
            var counterFilter = new Dictionary <int, CsConditionSeq>();

            foreach (var state in det.GetStates())
            {
                var stateCounterFilter = alg.TrueCsConditionSeq;
                foreach (var q in sb.GetMembers(state))
                {
                    if (ca.IsCountingState(q))
                    {
                        stateCounterFilter = stateCounterFilter.And(ca.GetCounter(q).CounterId, CsCondition.NONEMPTY);
                    }
                }
                counterFilter[state] = stateCounterFilter;
            }

            var csmoves = new List <Move <CsLabel <S> > >();

            //make disjunction of the guards of transitions with same update sequence
            var trans = new Dictionary <Tuple <int, int>, Dictionary <CsUpdateSeq, CsPred <S> > >();

            foreach (var dmove in det.GetMoves())
            {
                foreach (var prodcond in dmove.Label.GetSumOfProducts())
                {
                    var upd = CsUpdateSeq.MkNOOP(ca.NrOfCounters);
                    foreach (var q in sb.GetMembers(dmove.SourceState))
                    {
                        upd = upd | ca.GetCounterUpdate(q, prodcond.Item2, prodcond.Item1);
                    }
                    //make sure all counter guards are nonempty
                    //determinization may create EMPTY counter conditions that are unreachable
                    //while all counters associated with a state are always nonempty
                    var counterGuard = prodcond.Item1 & counterFilter[dmove.SourceState];
                    if (counterGuard.IsSatisfiable)
                    {
                        #region replace set with incr if possible
                        for (int i = 0; i < upd.Length; i++)
                        {
                            var guard_i = counterGuard[i];
                            if (guard_i == CsCondition.HIGH)
                            {
                                var upd_i = upd[i];
                                switch (upd_i)
                                {
                                case CsUpdate.SET0:
                                    upd = upd.Set(i, CsUpdate.INCR0);
                                    break;

                                case CsUpdate.SET1:
                                    upd = upd.Set(i, CsUpdate.INCR1);
                                    break;

                                case CsUpdate.SET01:
                                    upd = upd.Set(i, CsUpdate.INCR01);
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                        #endregion

                        var guard     = alg.MkPredicate(prodcond.Item2, counterGuard);
                        var statepair = new Tuple <int, int>(dmove.SourceState, dmove.TargetState);
                        Dictionary <CsUpdateSeq, CsPred <S> > labels;
                        if (!trans.TryGetValue(statepair, out labels))
                        {
                            labels           = new Dictionary <CsUpdateSeq, CsPred <S> >();
                            trans[statepair] = labels;
                        }
                        CsPred <S> pred;
                        if (!labels.TryGetValue(upd, out pred))
                        {
                            pred = guard;
                        }
                        else
                        {
                            pred = guard | pred;
                        }
                        labels[upd] = pred;
                    }
                    else
                    {
                        ;
                    }
                }
            }

            Func <S, string> pp = ((CABA <S>)ca.Algebra).builder.solver.PrettyPrint;
            foreach (var entry in trans)
            {
                var s = entry.Key.Item1;
                var t = entry.Key.Item2;
                foreach (var label in entry.Value)
                {
                    var upd = label.Key;
                    var psi = label.Value;
                    csmoves.Add(Move <CsLabel <S> > .Create(s, t, CsLabel <S> .MkTransitionLabel(psi, upd, pp)));
                }
            }

            var csa_aut = Automaton <CsLabel <S> > .Create(null, det.InitialState, det.GetFinalStates(), csmoves, true, true);

            var fs = new HashSet <int>(ca.GetFinalStates());

            var csa = new CsAutomaton <S>(alg, csa_aut, sb, ca.countingStates, fs);

            return(csa);
        }
示例#13
0
        /// <summary>
        /// Explores the PDA and converts it into an automaton,
        /// only stacks up to bounded depth are considered.
        /// </summary>
        /// <param name="stackDepth">upper bound on reached stack depth, nonpositive value means unbounded and may cause nontermination</param>
        public Automaton <T> Explore(int stackDepth = 0)
        {
            var moves       = new List <Move <T> >();
            var stateMap    = new Dictionary <Tuple <int, Sequence <S> >, int>();
            var configMap   = new Dictionary <int, Tuple <int, Sequence <S> > >();
            var finalStates = new HashSet <int>();

            int q0          = 0;
            var config0     = new Tuple <int, Sequence <S> >(this.automaton.InitialState, new Sequence <S>(this.initialStackSymbol));
            int nextStateId = 1;

            stateMap[config0] = q0;
            configMap[q0]     = config0;
            if (automaton.IsFinalState(this.automaton.InitialState))
            {
                finalStates.Add(q0);
            }

            var movemap = new Dictionary <Tuple <int, int>, T>();
            Action <int, int, T> AddMove = (source, target, pred) =>
            {
                var key = new Tuple <int, int>(source, target);
                T   psi;
                if (movemap.TryGetValue(key, out psi))
                {
                    movemap[key] = this.terminalAlgebra.MkOr(psi, pred);
                }
                else
                {
                    movemap[key] = pred;
                }
            };

            var frontier = new SimpleStack <int>();

            frontier.Push(q0);
            while (frontier.IsNonempty)
            {
                int q      = frontier.Pop();
                var config = configMap[q];
                foreach (var move in automaton.GetMovesFrom(config.Item1))
                {
                    if (stackDepth < 1 || (config.Item2.Length - 1 + move.Label.PushSymbols.Length) <= stackDepth)
                    {
                        var pop  = move.Label.PopSymbol;
                        var push = move.Label.PushSymbols;
                        if (config.Item2.First.Equals(pop))
                        {
                            var targetConfig = new Tuple <int, Sequence <S> >(move.TargetState, push.Append(config.Item2.Rest()));
                            int target;
                            if (!stateMap.TryGetValue(targetConfig, out target))
                            {
                                target = nextStateId++;
                                stateMap[targetConfig] = target;
                                configMap[target]      = targetConfig;
                                frontier.Push(target);
                                if (automaton.IsFinalState(move.TargetState))
                                {
                                    finalStates.Add(target);
                                }
                            }
                            Move <T> newmove;
                            if (move.Label.InputIsEpsilon)
                            {
                                newmove = Move <T> .Epsilon(q, target);

                                moves.Add(newmove);
                            }
                            else
                            {
                                //accumulate predicates for transitions
                                AddMove(q, target, move.Label.Input);
                            }
                        }
                    }
                }
            }

            foreach (var entry in movemap)
            {
                moves.Add(Move <T> .Create(entry.Key.Item1, entry.Key.Item2, entry.Value));
            }

            var res = Automaton <T> .Create(this.terminalAlgebra, q0, finalStates, moves, false, true);

            return(res);
        }
示例#14
0
        PushdownAutomaton <S, T> Intersect1(IMinimalAutomaton <T> nfa)
        {
            //depth first product construction, PDA may have epsilon moves
            var stateIdMap  = new Dictionary <Pair, int>();
            int nextStateId = 1;
            var stack       = new SimpleStack <Pair>();
            var moves       = new List <Move <PushdownLabel <S, T> > >();
            var states      = new List <int>();
            var finalstates = new List <int>();

            #region  GetState: push the pair to stack if the state id was new and update final states as needed
            Func <Pair, int> GetState = (pair) =>
            {
                int id;
                if (!stateIdMap.TryGetValue(pair, out id))
                {
                    id               = nextStateId;
                    nextStateId     += 1;
                    stateIdMap[pair] = id;
                    stack.Push(pair);
                    states.Add(id);
                    if (this.automaton.IsFinalState(pair.Item1) && nfa.IsFinalState(pair.Item2))
                    {
                        finalstates.Add(id);
                    }
                }
                return(id);
            };
            #endregion

            var initPair  = new Pair(this.automaton.InitialState, nfa.InitialState);
            int initState = GetState(initPair);

            #region compute the product transitions with depth-first search
            while (stack.IsNonempty)
            {
                var sourcePair = stack.Pop();
                var source     = stateIdMap[sourcePair];
                var pda_state  = sourcePair.Item1;
                var aut_state  = sourcePair.Item2;
                foreach (var pda_move in this.automaton.GetMovesFrom(pda_state))
                {
                    if (pda_move.IsEpsilon || pda_move.Label.InputIsEpsilon)
                    {
                        var targetPair = new Pair(pda_move.TargetState, aut_state);
                        int target     = GetState(targetPair);
                        moves.Add(Move <PushdownLabel <S, T> > .Create(source, target, pda_move.Label));
                    }
                    else
                    {
                        //assuming here that the automaton does not have epsilons
                        foreach (var aut_move in nfa.GetMovesFrom(aut_state))
                        {
                            if (aut_move.IsEpsilon)
                            {
                                throw new AutomataException(AutomataExceptionKind.AutomatonIsNotEpsilonfree);
                            }

                            var cond = nfa.Algebra.MkAnd(aut_move.Label, pda_move.Label.Input);
                            //if the joint condition is not satisfiable then the
                            //joint move does effectively not exist
                            if (nfa.Algebra.IsSatisfiable(cond))
                            {
                                var targetPair = new Pair(pda_move.TargetState, aut_move.TargetState);
                                int target     = GetState(targetPair);
                                var label      = new PushdownLabel <S, T>(cond, pda_move.Label.PushAndPop);
                                var jointmove  = Move <PushdownLabel <S, T> > .Create(source, target, label);

                                moves.Add(jointmove);
                            }
                        }
                    }
                }
            }
            #endregion

            //note: automaton creation eliminates unreachable states and deadend states from the product
            var productAutom = Automaton <PushdownLabel <S, T> > .Create(null, initState, finalstates, moves, true, true);

            var product = new PushdownAutomaton <S, T>(nfa.Algebra, productAutom, this.stackSymbols, this.initialStackSymbol);
            return(product);
        }
示例#15
0
        public static ThreeAutomaton <S> MkProduct(ThreeAutomaton <S> aut1, ThreeAutomaton <S> aut2, IBooleanAlgebra <S> solver, bool inters)
        {
            var a = aut1.MakeTotal();
            var b = aut2.MakeTotal();

            var stateIdMap = new Dictionary <Tuple <int, int>, int>();
            var initPair   = new Tuple <int, int>(a.InitialState, b.InitialState);
            var frontier   = new Stack <Tuple <int, int> >();

            frontier.Push(initPair);
            stateIdMap[initPair] = 0;

            var delta = new Dictionary <int, List <Move <S> > >();

            delta[0] = new List <Move <S> >();
            var states = new List <int>();

            states.Add(0);

            var accStates = new List <int>();
            var rejStates = new List <int>();

            if (inters)
            {
                if (a.IsFinalState(a.InitialState) && b.IsFinalState(b.InitialState))
                {
                    accStates.Add(0);
                }
                else
                if (a.IsRejectingState(a.InitialState) || b.IsRejectingState(b.InitialState))
                {
                    rejStates.Add(0);
                }
            }
            else
            {
                if (a.IsRejectingState(a.InitialState) && b.IsRejectingState(b.InitialState))
                {
                    rejStates.Add(0);
                }
                else
                if (a.IsFinalState(a.InitialState) || b.IsFinalState(b.InitialState))
                {
                    accStates.Add(0);
                }
            }

            int n = 1;

            while (frontier.Count > 0)
            {
                var currPair       = frontier.Pop();
                int source         = stateIdMap[currPair];
                var outTransitions = delta[source];

                foreach (var t1 in a.GetMovesFrom(currPair.Item1))
                {
                    foreach (var t2 in b.GetMovesFrom(currPair.Item2))
                    {
                        var cond = solver.MkAnd(t1.Label, t2.Label);
                        if (!solver.IsSatisfiable(cond))
                        {
                            continue; //ignore the unsatisfiable move
                        }
                        Tuple <int, int> targetPair = new Tuple <int, int>(t1.TargetState, t2.TargetState);
                        int target;
                        if (!stateIdMap.TryGetValue(targetPair, out target))
                        {
                            //state has not yet been found
                            target = n;
                            n     += 1;
                            stateIdMap[targetPair] = target;
                            states.Add(target);
                            delta[target] = new List <Move <S> >();
                            frontier.Push(targetPair);

                            if (inters)
                            {
                                if (a.IsFinalState(t1.TargetState) && b.IsFinalState(t2.TargetState))
                                {
                                    accStates.Add(target);
                                }
                                else
                                if (a.IsRejectingState(t1.TargetState) || b.IsRejectingState(t2.TargetState))
                                {
                                    rejStates.Add(target);
                                }
                            }
                            else
                            {
                                if (a.IsRejectingState(t1.TargetState) && b.IsRejectingState(t2.TargetState))
                                {
                                    rejStates.Add(target);
                                }
                                else
                                if (a.IsFinalState(t1.TargetState) || b.IsFinalState(t2.TargetState))
                                {
                                    accStates.Add(target);
                                }
                            }
                        }
                        outTransitions.Add(Move <S> .Create(source, target, cond));
                    }
                }
            }

            var incomingTransitions = new Dictionary <int, List <Move <S> > >();

            foreach (int state in states)
            {
                incomingTransitions[state] = new List <Move <S> >();
            }
            foreach (int state in states)
            {
                foreach (Move <S> t in delta[state])
                {
                    incomingTransitions[t.TargetState].Add(t);
                }
            }


            return(ThreeAutomaton <S> .Create(aut1.algebra, 0, rejStates, accStates, EnumerateMoves(delta)));
        }
 /// <summary>
 /// Builds an automaton equivalent to the regex (),
 /// Same as MkSeq().
 /// </summary>
 public Automaton <S> MkEmptyWord()
 {
     if (isBeg || isEnd)
     {  //may start or end with any characters since no anchor is used
         var st = this.MkStateId();
         return(Automaton <S> .Create(this.solver, st, new int[] { st }, new Move <S>[] { Move <S> .Create(st, st, solver.True) }));
     }
     else //an intermediate empty string is just an epsilon transition
     {
         return(this.epsilon);
     }
 }
示例#17
0
        /// <summary>
        /// Extension of standard minimization of FAs, use timeout.
        /// </summary>
        ThreeAutomaton <S> MinimizeClassical(IBooleanAlgebra <S> solver, int timeout)
        {
            var fa = this.MakeTotal();

            Equivalence E = new Equivalence();

            //initialize E, all nonfinal states are equivalent
            //and all final states are equivalent and all dontcare are equivalent
            List <int> stateList = new List <int>(fa.States);

            for (int i = 0; i < stateList.Count; i++)
            {
                //E.Add(stateList[i], stateList[i]);
                for (int j = 0; j < stateList.Count; j++)
                {
                    int  p        = stateList[i];
                    int  q        = stateList[j];
                    bool pIsFinal = fa.IsFinalState(p);
                    bool qIsFinal = fa.IsFinalState(q);
                    if (pIsFinal == qIsFinal)
                    {
                        if (pIsFinal)
                        {
                            E.Add(p, q);
                        }
                        else
                        {
                            bool pIsRej = fa.IsRejectingState(p);
                            bool qIsRej = fa.IsRejectingState(q);
                            if (pIsRej == qIsRej)
                            {
                                E.Add(p, q);
                            }
                        }
                    }
                }
            }

            //refine E
            bool       continueRefinement = true;
            List <int> statesList         = new List <int>(fa.States);

            while (continueRefinement)
            {
                continueRefinement = false;
                for (int i = 0; i < statesList.Count; i++)
                {
                    for (int j = 0; j < statesList.Count; j++)
                    {
                        Tuple <int, int> pq = new Tuple <int, int>(statesList[i], statesList[j]);
                        if (E.Contains(pq))
                        {
                            if (pq.Item1 != pq.Item2 && AreDistinguishable(fa, E, pq, solver))
                            {
                                E.Remove(pq);
                                continueRefinement = true;
                            }
                        }
                    }
                }
            }

            //create id's for equivalence classes
            Dictionary <int, int> equivIdMap = new Dictionary <int, int>();
            List <int>            mfaStates  = new List <int>();

            foreach (Tuple <int, int> pq in E)
            {
                int equivId;
                if (equivIdMap.TryGetValue(pq.Item1, out equivId))
                {
                    equivIdMap[pq.Item2] = equivId;
                }
                else if (equivIdMap.TryGetValue(pq.Item2, out equivId))
                {
                    equivIdMap[pq.Item1] = equivId;
                }
                else
                {
                    equivIdMap[pq.Item1] = pq.Item1;
                    equivIdMap[pq.Item2] = pq.Item1;
                    mfaStates.Add(pq.Item1);
                }
            }
            //remaining states map to themselves
            foreach (int state in fa.States)
            {
                if (!equivIdMap.ContainsKey(state))
                {
                    equivIdMap[state] = state;
                    mfaStates.Add(state);
                }
            }

            int mfaInitialState = equivIdMap[fa.InitialState];

            //group together transition conditions for transitions on equivalent states
            Dictionary <Tuple <int, int>, S> combinedConditionMap = new Dictionary <Tuple <int, int>, S>();

            foreach (int state in fa.States)
            {
                int fromStateId = equivIdMap[state];
                foreach (Move <S> trans in fa.GetMovesFrom(state))
                {
                    int toStateId = equivIdMap[trans.TargetState];
                    S   cond;
                    var p = new Tuple <int, int>(fromStateId, toStateId);
                    if (combinedConditionMap.TryGetValue(p, out cond))
                    {
                        combinedConditionMap[p] = solver.MkOr(cond, trans.Label);
                    }
                    else
                    {
                        combinedConditionMap[p] = trans.Label;
                    }
                }
            }

            //form the transitions of the mfa
            List <Move <S> > mfaTransitions = new List <Move <S> >();

            foreach (var kv in combinedConditionMap)
            {
                mfaTransitions.Add(Move <S> .Create(kv.Key.Item1, kv.Key.Item2, kv.Value));
            }


            //accepting states and rejecting
            HashSet <int> mfaAccStates = new HashSet <int>();
            HashSet <int> mfaRejStates = new HashSet <int>();

            foreach (int state in acceptingStateSet)
            {
                mfaAccStates.Add(equivIdMap[state]);
            }
            foreach (int state in rejectingStateSet)
            {
                mfaRejStates.Add(equivIdMap[state]);
            }

            return(ThreeAutomaton <S> .Create(algebra, mfaInitialState, mfaRejStates, mfaAccStates, mfaTransitions));
        }
示例#18
0
            void AddPop(int source, int target, S label, T input)
            {
                var input_seq = (object.Equals(input, default(T)) ? Sequence <T> .Empty : new Sequence <T>(input));

                this.popMap[label].Add(Move <Sequence <T> > .Create(source, target, input_seq));
            }