コード例 #1
0
        // returns the state reached from currState when reading c
        private static int GetNextState(int currState, char c, Automaton <BDD> dfa, CharSetSolver solver)
        {
            foreach (var move in dfa.GetNonepsilonMovesFrom(currState))
            {
                if (solver.IsSatisfiable(solver.MkAnd(move.Label, solver.MkCharConstraint(false, c))))
                {
                    return(move.TargetState);
                }
            }

            return(-1);
        }
コード例 #2
0
        internal static void ComputeModels(
            string currStr, int currState,
            Automaton <BDD> dfa, List <int> finalStates, HashSet <char> alphabet, CharSetSolver solver,
            List <string> positive, List <string> negative)
        {
            if (currStr.Length >= 8)
            {
                return;
            }

            if (currState == -1 || !finalStates.Contains(currState))
            {
                negative.Add(currStr);
            }
            else
            {
                positive.Add(currStr);
            }

            foreach (char ch in alphabet)
            {
                if (currState == -1)
                {
                    ComputeModels(currStr + ch, currState, dfa, finalStates, alphabet, solver, positive, negative);
                }
                else
                {
                    bool found = false;
                    foreach (var move in dfa.GetMovesFrom(currState))
                    {
                        if (solver.IsSatisfiable(solver.MkAnd(move.Label, solver.MkCharConstraint(false, ch))))
                        {
                            found = true;
                            ComputeModels(currStr + ch, move.TargetState, dfa, finalStates, alphabet, solver, positive, negative);
                            break;
                        }
                    }
                    if (!found)
                    {
                        ComputeModels(currStr + ch, -1, dfa, finalStates, alphabet, solver, positive, negative);
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Based on paper
        /// Order-n correction for regular langauges, http://dl.acm.org/citation.cfm?id=360995
        /// </summary>
        /// <param name="str">input string</param>
        /// <param name="automaton">dfa for which you want to compute the distance</param>
        /// <param name="solver">character solver</param>
        /// <param name="bound">depth of search for max string insertion</param>
        /// <param name="distance">outputs the distance</param>
        /// <returns>the closest string to str in automaton</returns>
        public static string GetClosestElement(string str, Automaton<BDD> automaton, CharSetSolver solver, int bound, out int distance, bool checkDeterminism = true)
        {
            //bound = Math.Min(bound, str.Length);

            var input = str.ToCharArray();
            var chars = new HashSet<char>(input);
            var maxl = input.Length+1;

            if(automaton.IsEmpty)
                throw new AutomataException("automaton must be nonempty");
            if (checkDeterminism && !automaton.IsDeterministic)
                throw new AutomataException("automaton must be deterministic");

            //Compute P(T,S) L(T,S,c)
            var lstates= automaton.States.ToList();
            lstates.Sort();
            var states = lstates.ToArray();
            var stToInd = new Dictionary<int, int>(states.Length+1);
            for (int i = 0; i < states.Length; i++)
                stToInd[states[i]] = i;

            var Pold = new int[states.Length, states.Length];
            var P1 = new bool[states.Length, states.Length]; //Records the transition relation
            var Pnew = new int[states.Length, states.Length];
            var Lold=new Dictionary<char,bool[,]>();
            var Lnew = new Dictionary<char, bool[ ,]>();

            #region Initialize P L
            foreach (var c in chars)
            {
                Lold[c] = new bool[states.Length, states.Length];
                Lnew[c] = new bool[states.Length, states.Length];
            }
            foreach (var stT in automaton.States)
            {
                var T = stToInd[stT];
                foreach (var stS in automaton.States)
                {
                    var S = stToInd[stS];
                    if (T == S)
                    {
                        Pold[S, T] = 0;
                        char wit;
                        P1[S, T] = MoveFromStoT(stS, stT, automaton, solver, out wit);
                        foreach (var c in chars)
                            if (P1[S, T] && MoveFromStoTContainsC(c, stS, stT, automaton, solver))
                                Lold[c][S, T] = true;
                            else
                                Lold[c][S, T] = false;
                    }
                    else
                    {
                        char wit;
                        if (MoveFromStoT(stS, stT, automaton, solver, out wit))
                        {
                            Pold[S, T] = 1;
                            P1[S, T] = true;
                            foreach (var c in chars)
                                if (MoveFromStoTContainsC(c, stS, stT, automaton, solver))
                                    Lold[c][S, T] = true;
                                else
                                    Lold[c][S, T] = false;
                        }
                        else
                        {
                            Pold[S, T] = int.MaxValue;
                            P1[S, T] = false;
                            foreach (var c in chars)
                                Lold[c][S, T] = false;
                        }
                    }
                }
            }
            #endregion
            //solver.ShowGraph(automaton,"as");

            //Inductive step
            for(int k=1;k<=bound;k++){
                foreach (var stT in automaton.States)
                {
                    var T = stToInd[stT];
                    foreach (var stS in automaton.States)
                    {
                        var S = stToInd[stS];

                        if (Pold[S, T] == int.MaxValue)
                        {
                            bool found=false;
                            foreach (var move in automaton.GetMovesFrom(stS))
                            {
                                var stk = move.TargetState;
                                var K = stToInd[stk];
                                if (Pold[K, T] != int.MaxValue)
                                    if (P1[S, K])
                                    {
                                        found = true;
                                        Pnew[S, T] = Pold[K, T] + 1;
                                        foreach (var c in chars)
                                            Lnew[c][S, T] = Lold[c][K, T] || solver.IsSatisfiable(solver.MkAnd(move.Label,solver.MkCharConstraint(c)));
                                    }
                            }
                            if (!found)
                            {
                                Pnew[S, T] = Pold[S, T];
                                foreach (var c in chars)
                                    Lnew[c][S, T] = Lold[c][S, T];
                            }
                        }
                        else
                        {
                            Pnew[S, T] = Pold[S, T];
                            foreach (var c in chars)
                                Lnew[c][S, T] = Lold[c][S, T];
                        }
                    }

                }
                Pold = Pnew;
                Pnew=new int[states.Length, states.Length];
                foreach (var c in chars)
                    Lold[c] = Lnew[c];

                Lnew = new Dictionary<char, bool[,]>();
                foreach (var c in chars)
                    Lnew[c] = new bool[states.Length, states.Length];

            }

            //Initialize table for value 0
            Pair<int, int>[,] F = new Pair<int, int>[maxl, automaton.StateCount];
            foreach (var st in automaton.States)
            {
                var T = stToInd[st];
                if (st == automaton.InitialState)
                    F[0, T] = new Pair<int, int>(0, -1);
                else
                    F[0, T] = new Pair<int, int>(int.MaxValue, -1);
            }

            //solver.ShowGraph(automaton,"aa");
            //Dynamic programming loop
            List<int> stateList = new List<int>();
            for (int j = 1; j < maxl; j++)
            {
                var aj = input[j - 1];
                foreach (var stT in automaton.States)
                {
                    var T = stToInd[stT];
                    int min = int.MaxValue;
                    int minSt = -1;
                    foreach (var stS in automaton.States)
                    {
                        var S = stToInd[stS];

                        var pts = Pold[S, T];
                        if (pts != int.MaxValue)
                        {
                            var ltsc = Lold[aj][S, T] ? 1 : 0;
                            int vts = pts == 0 ? 1 - ltsc : pts - ltsc;
                            var fjm1t = F[j - 1, S];
                            int expr = fjm1t.First + vts;

                            if (fjm1t.First == int.MaxValue || vts == int.MaxValue)
                                expr = int.MaxValue;
                            else
                                if (expr <= min)
                                {
                                    min = expr;
                                    minSt = S;
                                    if (min == 0)
                                        break;
                                }
                        }
                    }
                    F[j, T] = new Pair<int, int>(min, minSt);
                }
            }

            //Iteration over final states
            int minAcc = int.MaxValue;
            int minState = -1;
            foreach (var st in automaton.GetFinalStates())
            {
                var S = stToInd[st];
                if (F[input.Length, S].First < minAcc)
                {
                    minAcc = F[input.Length, S].First;
                    minState = F[input.Length, S].Second;
                    minState = S;
                }
            }
            var minString ="";
            int curr = minState;
            int strindex = input.Length;
            while (strindex > 0)
            {
                var f = F[strindex, curr];
                var aj = input[strindex-1];

                var pts = Pold[f.Second,curr];
                var ltsc = Lold[aj][f.Second,curr] ? 1 : 0;
                string vts = pts == 0 ? ((ltsc == 1)? aj.ToString():"") : ((ltsc == 1) ? ShortStringStoTwithC(aj, states[f.Second], states[curr], automaton, bound, solver) : ShortStringStoT(states[f.Second], states[curr], automaton, bound, solver));

                minString = vts + minString;

                curr = f.Second;
                strindex--;
            }

            distance=minAcc;
            return minString;
        }
コード例 #4
0
 //check if delta(S,T,c) exists
 static bool MoveFromStoTContainsC(char c, int S, int T, Automaton<BDD> aut, CharSetSolver solver, out char witness)
 {
     var ccond = solver.MkCharConstraint(c);
     foreach (var move in aut.GetMovesFrom(S))
         if (move.TargetState == T)
         {
             if (solver.IsSatisfiable(solver.MkAnd(move.Label, ccond)))
             {
                 witness = c;
                 return true;
             }
             else
                 foreach (var w in solver.GenerateAllCharacters(move.Label, false))
                 {
                     witness = w;
                     return true;
                 }
         }
     witness = c;
     return false;
 }
コード例 #5
0
 //check if delta(S,T,c) exists
 static bool MoveFromStoTContainsC(char c, int S, int T, Automaton<BDD> aut, CharSetSolver solver)
 {
     var ccond = solver.MkCharConstraint(c);
     foreach(var move in aut.GetMovesFrom(S))
         if (move.TargetState == T)
             if (solver.IsSatisfiable(solver.MkAnd(move.Label, ccond)))
                 return true;
     return false;
 }
コード例 #6
0
        internal static void ComputeModels(
            string currStr, int currState,
            Automaton<BDD> dfa, List<int> finalStates, HashSet<char> alphabet, CharSetSolver solver,
            List<string> positive, List<string> negative)
        {
            if (currStr.Length >= 8)
                return;

            if (currState == -1 || !finalStates.Contains(currState))
                negative.Add(currStr);
            else
                positive.Add(currStr);

            foreach (char ch in alphabet)
            {
                if (currState == -1)
                    ComputeModels(currStr + ch, currState, dfa, finalStates, alphabet, solver, positive, negative);
                else
                {
                    bool found = false;
                    foreach (var move in dfa.GetMovesFrom(currState))
                    {
                        if (solver.IsSatisfiable(solver.MkAnd(move.Label, solver.MkCharConstraint(false, ch))))
                        {
                            found = true;
                            ComputeModels(currStr + ch, move.TargetState, dfa, finalStates, alphabet, solver, positive, negative);
                            break;
                        }
                    }
                    if (!found)
                        ComputeModels(currStr + ch, -1, dfa, finalStates, alphabet, solver, positive, negative);
                }
            }
        }
コード例 #7
0
        // returns the state reached from currState when reading c
        private static int GetNextState(int currState, char c, Automaton<BDD> dfa, CharSetSolver solver)
        {
            foreach (var move in dfa.GetNonepsilonMovesFrom(currState))
                if (solver.IsSatisfiable(solver.MkAnd(move.Label, solver.MkCharConstraint(false, c))))
                    return move.TargetState;

            return -1;
        }
コード例 #8
0
        // looks for an edit at depth "depth" 
        // returns false and null in bestScript if no edit is found at depth "depth"
        // returns false and not null in bestScript if found
        // returns true if timeout
        internal static bool GetDFAEditScriptTimeout(
            Automaton<BDD> dfa1, Automaton<BDD> dfa2,
            HashSet<char> al, CharSetSolver solver,
            List<long> editScriptHash, List<DFAEdit> editList,
            int depth, long timeout, Stopwatch sw,
            Pair<IEnumerable<string>, IEnumerable<string>> tests,
            double dfa1density,
            int totalCost,
            DFAEditScript bestScript, Dictionary<int, int> stateNamesMapping)
        {
            // check timer
            if (sw.ElapsedMilliseconds > timeout)
                return true;

            //Compute worst case distance, call finalScript with this value?
            int dist = (dfa1.StateCount + dfa2.StateCount) * (al.Count + 1);

            //Stop if no more moves left
            if (depth == 0)
            {
                if (DFAUtilities.ApproximateMNEquivalent(tests, dfa1density, dfa2, al, solver) && dfa2.IsEquivalentWith(dfa1, solver))
                    //check if totalCost < finalScript cost and replace if needed
                    if (bestScript.script == null || totalCost < bestScript.GetCost())
                        bestScript.script = ObjectCopier.Clone<List<DFAEdit>>(editList);
                return false;
            }

            DFAEdit edit = null;

            #region Flip one move target state
            foreach (var move in dfa2.GetMoves())
            {
                //Creaty copy of the moves without current move
                var movesWithoutCurrMove = dfa2.GetMoves().ToList();
                movesWithoutCurrMove.Remove(move);

                //Redirect every ch belonging to move condition
                foreach (var c in solver.GenerateAllCharacters(move.Label, false))
                {
                    long hash = IntegerUtil.PairToInt(move.SourceState, c - 97) + dfa2.StateCount;

                    if (CanAdd(hash, editScriptHash))
                    {
                        editScriptHash.Insert(0, hash);

                        //Local copy of moves
                        var newMoves = movesWithoutCurrMove.ToList();
                        var newMoveCondition = solver.MkCharConstraint(false, c);

                        #region Remove ch from current move
                        var andCond = solver.MkAnd(move.Label, solver.MkNot(newMoveCondition));
                        //add back move without ch iff satisfiable
                        if (solver.IsSatisfiable(andCond))
                            newMoves.Add(new Move<BDD>(move.SourceState, move.TargetState, andCond));
                        #endregion

                        #region Redirect c to a different state
                        foreach (var state in dfa2.States)
                            if (state != move.TargetState)
                            {
                                var newMovesComplete = newMoves.ToList();
                                newMovesComplete.Add(new Move<BDD>(move.SourceState, state, newMoveCondition));
                                var dfa2new = Automaton<BDD>.Create(dfa2.InitialState, dfa2.GetFinalStates(), newMovesComplete);

                                edit = new DFAEditMove(stateNamesMapping[move.SourceState], stateNamesMapping[state], c);
                                editList.Insert(0, edit);
                                if (GetDFAEditScriptTimeout(dfa1, dfa2new, al, solver, editScriptHash, editList, depth - 1, timeout, sw, tests, dfa1density, totalCost + edit.GetCost(), bestScript, stateNamesMapping))
                                    return true;
                                editList.RemoveAt(0);
                            }
                        #endregion

                        editScriptHash.RemoveAt(0);

                    }
                }
            }
            #endregion

            #region Flip one state from fin to non fin
            foreach (var state in dfa2.States)
            {
                if (CanAdd(state, editScriptHash))
                {
                    //flip its final non final status
                    editScriptHash.Insert(0, state);

                    var newFinalStates = new HashSet<int>(dfa2.GetFinalStates());
                    Automaton<BDD> dfa2new = null;
                    if (dfa2.GetFinalStates().Contains(state))
                    {
                        edit = new DFAEditState(stateNamesMapping[state], false);
                        editList.Insert(0, edit);
                        newFinalStates.Remove(state);
                        dfa2new = Automaton<BDD>.Create(dfa2.InitialState, newFinalStates, dfa2.GetMoves());
                    }
                    else
                    {
                        edit = new DFAEditState(stateNamesMapping[state], true);
                        editList.Insert(0, edit);
                        newFinalStates.Add(state);
                        dfa2new = Automaton<BDD>.Create(dfa2.InitialState, newFinalStates, dfa2.GetMoves());
                    }

                    if (GetDFAEditScriptTimeout(dfa1, dfa2new, al, solver, editScriptHash, editList, depth - 1, timeout, sw, tests, dfa1density, totalCost + edit.GetCost(), bestScript, stateNamesMapping))
                        return true;

                    editScriptHash.RemoveAt(0);
                    editList.RemoveAt(0);
                }
            }
            #endregion

            return false;
        }
コード例 #9
0
        // looks for an edit at depth "depth"
        // returns false and null in bestScript if no edit is found at depth "depth"
        // returns false and not null in bestScript if found
        // returns true if timeout
        internal static bool GetDFAEditScriptTimeout(
            Automaton <BDD> dfa1, Automaton <BDD> dfa2,
            HashSet <char> al, CharSetSolver solver,
            List <long> editScriptHash, List <DFAEdit> editList,
            int depth, long timeout, Stopwatch sw,
            Pair <IEnumerable <string>, IEnumerable <string> > tests,
            double dfa1density,
            int totalCost,
            DFAEditScript bestScript, Dictionary <int, int> stateNamesMapping)
        {
            // check timer
            if (sw.ElapsedMilliseconds > timeout)
            {
                return(true);
            }

            //Compute worst case distance, call finalScript with this value?
            int dist = (dfa1.StateCount + dfa2.StateCount) * (al.Count + 1);

            //Stop if no more moves left
            if (depth == 0)
            {
                if (DFAUtilities.ApproximateMNEquivalent(tests, dfa1density, dfa2, al, solver) && dfa2.IsEquivalentWith(dfa1, solver))
                {
                    //check if totalCost < finalScript cost and replace if needed
                    if (bestScript.script == null || totalCost < bestScript.GetCost())
                    {
                        bestScript.script = ObjectCopier.Clone <List <DFAEdit> >(editList);
                    }
                }
                return(false);
            }

            DFAEdit edit = null;

            #region Flip one move target state
            foreach (var move in dfa2.GetMoves())
            {
                //Creaty copy of the moves without current move
                var movesWithoutCurrMove = dfa2.GetMoves().ToList();
                movesWithoutCurrMove.Remove(move);

                //Redirect every ch belonging to move condition
                foreach (var c in solver.GenerateAllCharacters(move.Label, false))
                {
                    long hash = IntegerUtil.PairToInt(move.SourceState, c - 97) + dfa2.StateCount;

                    if (CanAdd(hash, editScriptHash))
                    {
                        editScriptHash.Insert(0, hash);

                        //Local copy of moves
                        var newMoves         = movesWithoutCurrMove.ToList();
                        var newMoveCondition = solver.MkCharConstraint(false, c);

                        #region Remove ch from current move
                        var andCond = solver.MkAnd(move.Label, solver.MkNot(newMoveCondition));
                        //add back move without ch iff satisfiable
                        if (solver.IsSatisfiable(andCond))
                        {
                            newMoves.Add(new Move <BDD>(move.SourceState, move.TargetState, andCond));
                        }
                        #endregion

                        #region Redirect c to a different state
                        foreach (var state in dfa2.States)
                        {
                            if (state != move.TargetState)
                            {
                                var newMovesComplete = newMoves.ToList();
                                newMovesComplete.Add(new Move <BDD>(move.SourceState, state, newMoveCondition));
                                var dfa2new = Automaton <BDD> .Create(dfa2.InitialState, dfa2.GetFinalStates(), newMovesComplete);

                                edit = new DFAEditMove(stateNamesMapping[move.SourceState], stateNamesMapping[state], c);
                                editList.Insert(0, edit);
                                if (GetDFAEditScriptTimeout(dfa1, dfa2new, al, solver, editScriptHash, editList, depth - 1, timeout, sw, tests, dfa1density, totalCost + edit.GetCost(), bestScript, stateNamesMapping))
                                {
                                    return(true);
                                }
                                editList.RemoveAt(0);
                            }
                        }
                        #endregion

                        editScriptHash.RemoveAt(0);
                    }
                }
            }
            #endregion

            #region Flip one state from fin to non fin
            foreach (var state in dfa2.States)
            {
                if (CanAdd(state, editScriptHash))
                {
                    //flip its final non final status
                    editScriptHash.Insert(0, state);

                    var             newFinalStates = new HashSet <int>(dfa2.GetFinalStates());
                    Automaton <BDD> dfa2new        = null;
                    if (dfa2.GetFinalStates().Contains(state))
                    {
                        edit = new DFAEditState(stateNamesMapping[state], false);
                        editList.Insert(0, edit);
                        newFinalStates.Remove(state);
                        dfa2new = Automaton <BDD> .Create(dfa2.InitialState, newFinalStates, dfa2.GetMoves());
                    }
                    else
                    {
                        edit = new DFAEditState(stateNamesMapping[state], true);
                        editList.Insert(0, edit);
                        newFinalStates.Add(state);
                        dfa2new = Automaton <BDD> .Create(dfa2.InitialState, newFinalStates, dfa2.GetMoves());
                    }

                    if (GetDFAEditScriptTimeout(dfa1, dfa2new, al, solver, editScriptHash, editList, depth - 1, timeout, sw, tests, dfa1density, totalCost + edit.GetCost(), bestScript, stateNamesMapping))
                    {
                        return(true);
                    }

                    editScriptHash.RemoveAt(0);
                    editList.RemoveAt(0);
                }
            }
            #endregion

            return(false);
        }