예제 #1
0
        public void GenerateMembersTest()
        {
            foreach (var encoding in new BitWidth[] {
                BitWidth.BV7, BitWidth.BV8, BitWidth.BV16
            })
            {
                CharSetSolver solver = new CharSetSolver(encoding);
                var           ranges = new char[][] {
                    new char[] { 'a', 'c' },
                    new char[] { '0', '5' },
                    new char[] { 'e', 'h' },
                    new char[] { '6', '9' },
                };
                BDD s = solver.MkRangesConstraint(false, ranges);

                var members = new List <char>(solver.GenerateAllCharacters(s, false));

                Assert.AreEqual <int>(17, members.Count, "wrong number of members in the range [a-ce-h0-9]");
                Assert.AreEqual <char>('0', members[0], "the smallest character in the range must be '0'");
                Assert.AreEqual <char>('h', members[16], "the largest character in the range must be 'h'");

                var membersInReverse = new List <char>(solver.GenerateAllCharacters(s, true));

                Assert.AreEqual <int>(17, membersInReverse.Count, "wrong number of members in the range [a-ce-h0-9]");
                Assert.AreEqual <char>('h', membersInReverse[0], "the first character in the reverse enumeration must be 'h'");
                Assert.AreEqual <char>('0', membersInReverse[16], "the last character in the reverse enumeration must be '0'");
            }
        }
예제 #2
0
        public void GenerateMembersTest2()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);
            var           ranges = new char[][] {
                new char[] { 'a', 'c' },
                new char[] { '\u5555', '\u55A5' },
                new char[] { 'e', 'h' },
                new char[] { '\u55A0', '\u55AA' },
            };
            BDD s = solver.MkRangesConstraint(false, ranges);

            s.ToDot("bug.dot");

            var r  = solver.ToRanges(s);
            var s2 = solver.MkCharSetFromRanges(r);

            var members  = new List <char>(solver.GenerateAllCharacters(s2, false));
            var smallest = (char)solver.GetMin(s2);

            Assert.AreEqual <int>(93, members.Count, "wrong number of members in the range [a-ce-h\\u5555-\\u55AA]");
            Assert.AreEqual <char>('a', members[0], "the smallest character in the range must be 'a'");
            Assert.AreEqual <char>('\u55AA', members[members.Count - 1], "the largest character in the range must be '\\u55AA'");

            var membersInReverse = new List <char>(solver.GenerateAllCharacters(s, true));

            Assert.AreEqual <int>(93, membersInReverse.Count, "wrong number of members in the range [a-ce-h\\u5555-\\u55AA]");
            Assert.AreEqual <char>('\u55AA', membersInReverse[0], "the first character in the reverse enumeration must be '\\u55AA'");
            Assert.AreEqual <char>('a', membersInReverse[membersInReverse.Count - 1], "the last character in the reverse enumeration must be 'a'");
        }
        private void InitializeUnicodeCategoryDefinitions()
        {
            if (encoding == BitWidth.BV7)
            {
                for (int i = 0; i < 30; i++)
                {
                    if (UnicodeCategoryRanges.ASCIIBdd[i] == null)
                    {
                        catConditionsBDD[i] = solverBDD.False;
                    }
                    else
                    {
                        catConditionsBDD[i] = solverBDD.DeserializeCompact(UnicodeCategoryRanges.ASCIIBdd[i]);
                    }
                }
                whiteSpaceConditionBDD = solverBDD.DeserializeCompact(UnicodeCategoryRanges.ASCIIWhitespaceBdd);

                wordLetterConditionBDD = solverBDD.DeserializeCompact(UnicodeCategoryRanges.ASCIIWordCharacterBdd);
            }
            else if (encoding == BitWidth.BV8)
            {
                for (int i = 0; i < 30; i++)
                {
                    if (UnicodeCategoryRanges.CP437Bdd[i] == null)
                    {
                        catConditionsBDD[i] = solverBDD.False;
                    }
                    else
                    {
                        catConditionsBDD[i] = solverBDD.DeserializeCompact(UnicodeCategoryRanges.CP437Bdd[i]);
                    }
                }
                whiteSpaceConditionBDD = solverBDD.DeserializeCompact(UnicodeCategoryRanges.CP437WhitespaceBdd);
                wordLetterConditionBDD = solverBDD.DeserializeCompact(UnicodeCategoryRanges.CP437WordCharacterBdd);
            }
            else
            {
                for (int i = 0; i < 30; i++)
                {
                    catConditionsBDD[i] = solverBDD.DeserializeCompact(UnicodeCategoryRanges.UnicodeBdd[i]);
                }
                whiteSpaceConditionBDD = solverBDD.DeserializeCompact(UnicodeCategoryRanges.UnicodeWhitespaceBdd);
                wordLetterConditionBDD = solverBDD.DeserializeCompact(UnicodeCategoryRanges.UnicodeWordCharacterBdd);
            }
            #region create corresponding ranges
            for (int i = 0; i < 30; i++)
            {
                catConditions[i] = new HashSet <char>(solverBDD.GenerateAllCharacters(catConditionsBDD[i], false));
            }
            whiteSpaceCondition = new HashSet <char>(solverBDD.GenerateAllCharacters(whiteSpaceConditionBDD, false));
            wordLetterCondition = new HashSet <char>(solverBDD.GenerateAllCharacters(wordLetterConditionBDD, false));
            #endregion
        }
        public static void printDFA(Automaton <BDD> dfa, HashSet <char> alphabet, StringBuilder sb)
        {
            var newDfa = normalizeDFA(dfa).First;

            CharSetSolver solver = new CharSetSolver(BitWidth.BV64);

            sb.Append("alphabet:");
            foreach (var ch in alphabet)
            {
                sb.Append(" " + ch);
            }
            sb.AppendLine();

            sb.AppendLine(string.Format("{0} states", newDfa.StateCount));

            sb.Append("final states:");
            foreach (var st in newDfa.GetFinalStates())
            {
                sb.Append(" " + st);
            }
            sb.AppendLine();

            foreach (var move in newDfa.GetMoves())
            {
                List <char> chars = move.Label == null? new List <char>() : solver.GenerateAllCharacters(move.Label, false).ToList();
                chars.Sort();
                foreach (var ch in chars)
                {
                    sb.AppendLine(string.Format("{0},{1},{2}", move.SourceState, move.TargetState, ch));
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Returns true iff the DFA is not complete or not a DFA (misses transitions)
        /// </summary>
        /// <param name="dfa"></param>
        /// <param name="al"></param>
        /// <param name="solver"></param>
        /// <returns></returns>
        public static bool ContainsSyntacticMistake(Automaton <BDD> dfa, HashSet <char> al,
                                                    CharSetSolver solver, HashSet <int> missingEdges)
        {
            bool mistake = false;
            var  dfaNorm = DFAUtilities.normalizeDFA(dfa).First;

            foreach (var state in dfaNorm.States)
            {
                HashSet <char> alCopy = new HashSet <char>(al);
                foreach (var move in dfaNorm.GetMovesFrom(state))
                {
                    foreach (var c in solver.GenerateAllCharacters(move.Label, false))
                    {
                        if (!alCopy.Contains(c))
                        {
                            int hash = (int)(Math.Pow(2, move.SourceState) + Math.Pow(3, c - 97)) + dfaNorm.StateCount;
                            mistake = true;
                        }
                        alCopy.Remove(c);
                    }
                }
                if (alCopy.Count > 0)
                {
                    mistake = true;
                }
            }
            return(mistake);
        }
        // Accessory methods for strings
        #region Accessory methods for strings
        internal static List <string> getSimplePrefixes(Automaton <BDD> dfa, CharSetSolver solver)
        {
            List <string> strings = new List <string>();

            foreach (var path in getSimplePaths(dfa))
            {
                var currStrs = new List <string>();
                currStrs.Add("");
                var p = new List <int>(path);
                p.RemoveAt(0);
                int prevNode = dfa.InitialState;
                foreach (int node in p)
                {
                    foreach (var move in dfa.GetMovesFrom(prevNode))
                    {
                        if (node == move.TargetState)
                        {
                            var newStrs = new List <string>();
                            foreach (var el in solver.GenerateAllCharacters(move.Label, false))
                            {
                                foreach (var str in currStrs)
                                {
                                    newStrs.Add(str + el);
                                    strings.Add(str + el);
                                }
                            }
                            currStrs = new List <string>(newStrs);
                            break;
                        }
                    }
                    prevNode = node;
                }
            }
            return(strings);
        }
        private static void getPathStrings(Automaton <BDD> dfa, CharSetSolver solver, List <int> path, string currStr, HashSet <string> strings, int prevState)
        {
            List <int> path1     = new List <int>(path);
            var        currState = path1.ElementAt(0);

            path1.RemoveAt(0);

            foreach (var move in dfa.GetMovesFrom(prevState))
            {
                if (move.TargetState == currState)
                {
                    foreach (char c in solver.GenerateAllCharacters(move.Label, false))
                    {
                        if (path1.Count == 0)
                        {
                            strings.Add(currStr + c);
                        }
                        else
                        {
                            getPathStrings(dfa, solver, path1, currStr + c, strings, currState);
                        }
                    }
                }
            }
        }
        internal static string GenerateShortTerm(Automaton <BDD> dfa, CharSetSolver solver)
        {
            if (dfa.IsEmpty)
            {
                return(null);
            }

            Dictionary <int, string> shortStr = new Dictionary <int, string>();

            HashSet <int> reachedStates = new HashSet <int>();
            List <int>    toExplore     = new List <int>();


            reachedStates.Add(dfa.InitialState);
            toExplore.Add(dfa.InitialState);
            shortStr.Add(dfa.InitialState, "");
            var finSts = dfa.GetFinalStates();

            if (finSts.Contains(dfa.InitialState))
            {
                return("");
            }

            string sCurr = ""; char condC = 'a';

            while (toExplore.Count != 0)
            {
                var current = toExplore.First();
                toExplore.RemoveAt(0);
                shortStr.TryGetValue(current, out sCurr);

                var reachableFromCurr = dfa.GetMovesFrom(current);
                foreach (var move in reachableFromCurr)
                {
                    if (!reachedStates.Contains(move.TargetState))
                    {
                        reachedStates.Add(move.TargetState);
                        toExplore.Add(move.TargetState);

                        foreach (var v in solver.GenerateAllCharacters(move.Label, false))
                        {
                            condC = v;
                            break;
                        }
                        shortStr.Add(move.TargetState, sCurr + condC);
                        if (finSts.Contains(move.TargetState))
                        {
                            return(sCurr + condC);
                        }
                    }
                }
            }
            return(null);
        }
예제 #9
0
        //[TestMethod]
        public void TestIgnoreCaseTransformer()
        {
            CharSetSolver         solver = new CharSetSolver();
            int                   t      = System.Environment.TickCount;
            IgnoreCaseTransformer ic     = new IgnoreCaseTransformer(solver);

            //simple test first:
            //BDD a2c = solver.MkRangeConstraint('a', 'c');
            //BDD a2cA2C = ic.Apply(a2c);
            //BDD a2cA2C_expected = a2c.Or(solver.MkRangeConstraint('A', 'C'));
            //Assert.AreEqual<BDD>(a2cA2C, a2cA2C_expected);
            //
            //comprehensive test:
            //
            //test that the whole array is correct:
            // Microsoft.Automata.Generated.IgnoreCaseRelation.ignorecase
            //  (generated by:)
            //
            // IgnoreCaseRelationGenerator.Generate(
            //    "Microsoft.Automata.Generated",
            //    "IgnoreCaseRelation",
            //    @"C:\GitHub\AutomataDotNet\Automata\src\Automata\Internal\Generated");
            //
            //test that all characters in it are truly equivalent wrt the igore-case option of regex
            //
            for (int i = 0; i <= 0xFFFF; i++)
            {
                char c = (char)i;
                if (ic.IsInDomain(c))
                {
                    BDD cC = ic.Apply(solver.MkCharConstraint(c));
                    foreach (char d in solver.GenerateAllCharacters(cC))
                    {
                        Assert.IsTrue(Regex.IsMatch(d.ToString(), "^(?i:" + StringUtility.Escape(c) + ")$"));
                    }
                }
            }
            //
            //second, test that all characters outside the domain are only equivalent (up-to-case) to themsevles
            //
            // for some reson this does not succeed, ??? some characters, e.g. '\xF7', are
            // equivalent to some other characters in the below test, but not when tested individually
            // there is a bug in Regex.IsMatch with ignore-case combined with intervals
            //
            //for (int i = 2; i <= 0xFFFD; i++)
            //{
            //    char c = (char)i;
            //    if (!ic.IsInDomain(c))
            //    {
            //        if (Regex.IsMatch(c.ToString(), @"^([\0-" + StringUtility.Escape((char)(i - 1)) + StringUtility.Escape((char)(i + 1)) + @"-\uFFFF])$", RegexOptions.IgnoreCase))
            //            Console.WriteLine(StringUtility.Escape(c));
            //    }
            //}
        }
예제 #10
0
 public void TestIgnoreCaseTransformer()
 {
     CharSetSolver solver = new CharSetSolver();
     int t = System.Environment.TickCount;
     IgnoreCaseTransformer ic = new IgnoreCaseTransformer(solver);
     //simple test first:
     BDD a2c = solver.MkRangeConstraint('a', 'c');
     BDD a2cA2C = ic.Apply(a2c);
     BDD a2cA2C_expected = a2c.Or(solver.MkRangeConstraint('A', 'C'));
     Assert.AreEqual<BDD>(a2cA2C, a2cA2C_expected);
     //
     //comprehensive test:
     //
     //test that the whole array is correct:
     // Microsoft.Automata.Internal.Generated.IgnoreCaseRelation.ignorecase
     //  (generated by:)
     //
     // IgnoreCaseRelationGenerator.Generate(
     //    "Microsoft.Automata.Internal.Generated",
     //    "IgnoreCaseRelation",
     //    @"C:\GitHub\AutomataDotNet\Automata\src\Automata\Internal\Generated");
     //
     //test that all characters in it are truly equivalent wrt the igore-case option of regex
     //
     for (int i = 0; i <= 0xFFFF; i++)
     {
         char c = (char)i;
         if (ic.IsInDomain(c))
         {
             BDD cC = ic.Apply(solver.MkCharConstraint(c));
             foreach (char d in solver.GenerateAllCharacters(cC))
             {
                 Assert.IsTrue(Regex.IsMatch(d.ToString(), "^(?i:" + StringUtility.Escape(c) + ")$"));
             }
         }
     }
     //
     //second, test that all characters outside the domain are only equivalent (up-to-case) to themsevles
     //
     // for some reson this does not succeed, ??? some characters, e.g. '\xF7', are
     // equivalent to some other characters in the below test, but not when tested individually
     // there is a bug in Regex.IsMatch with ignore-case combined with intervals
     //
     //for (int i = 2; i <= 0xFFFD; i++)
     //{
     //    char c = (char)i;
     //    if (!ic.IsInDomain(c))
     //    {
     //        if (Regex.IsMatch(c.ToString(), @"^([\0-" + StringUtility.Escape((char)(i - 1)) + StringUtility.Escape((char)(i + 1)) + @"-\uFFFF])$", RegexOptions.IgnoreCase))
     //            Console.WriteLine(StringUtility.Escape(c));
     //    }
     //}
 }
예제 #11
0
        public List <Transduction> AvailableMoves()
        {
            IEnumerable <Move <BvSet> > movesFromCurrent = moveAutomaton.GetMovesFrom(currentState);
            BvSet       availableMoves = solver.MkAnd(solver.MkCharConstraint(true, '2'), solver.MkCharConstraint(true, '3'));
            List <char> charl;

            foreach (Move <BvSet> m in movesFromCurrent)
            {
                charl          = solver.GenerateAllCharacters(m.Condition, false).ToList();
                availableMoves = solver.MkOr(m.Condition, availableMoves);
            }
            List <Transduction> movel = new List <Transduction>();
            IEnumerable <char>  chare = solver.GenerateAllCharacters(availableMoves, false);

            //charl = chare.ToList();
            foreach (Char c in chare)
            {
                movel.Add(TransductionUtil.ToMove(c));
            }

            return(movel);
        }
예제 #12
0
        public Automaton<BDD> getDFA(HashSet<char> alphabet, CharSetSolver solver)
        {            
            //Predicate representing the alphabet
            var alphPred = solver.False;
            foreach (var ch in alphabet)
                alphPred = solver.MkOr(solver.MkCharConstraint(false, ch), alphPred);
            
            var dfa1 =  this.Normalize(solver).PushQuantifiers().getDFA(new List<string>(), alphPred, solver);

            var moves = new List<Move<BDD>>();
            foreach (var move in dfa1.GetMoves())
                foreach (var ch in solver.GenerateAllCharacters(solver.MkAnd(move.Label,alphPred),false))                
                    moves.Add(new Move<BDD>(move.SourceState,move.TargetState,solver.MkCharConstraint(false,ch)));

            return Automaton<BDD>.Create(dfa1.InitialState,dfa1.GetFinalStates(),moves,true,true).Determinize(solver).Minimize(solver);
        }
예제 #13
0
        public void TestDecisionTreePrecomputeEverything()
        {
            var css       = new CharSetSolver();
            var regex     = new Regex("abc[^a-i]");
            var sr        = css.RegexConverter.ConvertToSymbolicRegex(regex, true);
            var partition = sr.ComputeMinterms();

            Assert.AreEqual <int>(5, partition.Length);
            var dt = DecisionTree.Create(css, partition, 0xFFFF);

            for (int i = 0; i < partition.Length; i++)
            {
                foreach (var c in css.GenerateAllCharacters(partition[i]))
                {
                    Assert.AreEqual(i, dt.GetId(c));
                }
            }
            Assert.IsTrue(dt.Tree == null);
        }
예제 #14
0
        internal override void ToMonaString(StringBuilder sb, CharSetSolver solver)
        {
            var addOr = false;

            foreach (var bv in solver.GenerateAllCharacters(pred, false))
            {
                if (addOr)
                {
                    sb.Append(" | ");
                }
                else
                {
                    addOr = true;
                }

                string s = BitVecUtil.GetIntBinaryString(bv);
                sb.Append("(");
                var c = s[0];
                if (c == '1')
                {
                    sb.AppendFormat("is_{0}({1})", c, set);
                }
                else
                {
                    sb.AppendFormat("~is_{0}({1})", c, set);
                }
                for (int i = 1; i < s.Length; i++)
                {
                    sb.Append(" & ");
                    c = s[i];
                    if (c == '1')
                    {
                        sb.AppendFormat("is_{0}({1})", c, set);
                    }
                    else
                    {
                        sb.AppendFormat("~is_{0}({1})", c, set);
                    }
                }
                sb.Append(")");
            }
        }
        internal static List <string> getSimpleSuffixes(Automaton <BDD> dfa, CharSetSolver solver)
        {
            if (!dfa.IsEpsilonFree)
            {
                return(new List <string>());
            }

            List <string> strings = new List <string>();

            foreach (var path in getSimplePaths(dfa))
            {
                var currStrs = new List <string>();
                currStrs.Add("");
                var p = new List <int>(path);
                p.Reverse();
                int prevNode = p.ElementAt(0);
                p.RemoveAt(0);

                foreach (int node in p)
                {
                    foreach (var move in dfa.GetMovesTo(prevNode))
                    {
                        if (node == move.SourceState)
                        {
                            var newStrs = new List <string>();
                            foreach (var el in solver.GenerateAllCharacters(move.Label, false))
                            {
                                foreach (var str in currStrs)
                                {
                                    newStrs.Add(el + str);
                                    strings.Add(el + str);
                                }
                            }
                            currStrs = new List <string>(newStrs);
                            break;
                        }
                    }
                    prevNode = node;
                }
            }
            return(strings);
        }
예제 #16
0
        public void TestDecisionTreePrecomputeExtendedASCII()
        {
            var css       = new CharSetSolver();
            var regex     = new Regex("(?i:abc[^a-i])");
            var sr        = css.RegexConverter.ConvertToSymbolicRegex(regex, true);
            var partition = sr.ComputeMinterms();

            Assert.AreEqual <int>(5, partition.Length);
            var dt = DecisionTree.Create(css, partition, 0xFF);

            for (int i = 0; i < partition.Length; i++)
            {
                foreach (var c in css.GenerateAllCharacters(partition[i]))
                {
                    Assert.AreEqual(i, dt.GetId(c));
                }
            }
            //there is a special unicode 'i' character that is equivalent to i with ignore-case option
            //that forms a separate character class here
            Assert.IsFalse(dt.Tree.IsLeaf);
        }
예제 #17
0
        public Automaton <BDD> getDFA(HashSet <char> alphabet, CharSetSolver solver)
        {
            //Predicate representing the alphabet
            var alphPred = solver.False;

            foreach (var ch in alphabet)
            {
                alphPred = solver.MkOr(solver.MkCharConstraint(false, ch), alphPred);
            }

            var dfa1 = this.Normalize(solver).PushQuantifiers().getDFA(new List <string>(), alphPred, solver);

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

            foreach (var move in dfa1.GetMoves())
            {
                foreach (var ch in solver.GenerateAllCharacters(solver.MkAnd(move.Label, alphPred), false))
                {
                    moves.Add(new Move <BDD>(move.SourceState, move.TargetState, solver.MkCharConstraint(false, ch)));
                }
            }

            return(Automaton <BDD> .Create(dfa1.InitialState, dfa1.GetFinalStates(), moves, true, true).Determinize(solver).Minimize(solver));
        }
        internal static List<string> getSimpleSuffixes(Automaton<BDD> dfa, CharSetSolver solver)
        {
            if (!dfa.IsEpsilonFree)
                return new List<string>();

            List<string> strings = new List<string>();
            foreach (var path in getSimplePaths(dfa))
            {
                var currStrs = new List<string>();
                currStrs.Add("");
                var p = new List<int>(path);
                p.Reverse();
                int prevNode = p.ElementAt(0);
                p.RemoveAt(0);

                foreach (int node in p)
                {
                    foreach (var move in dfa.GetMovesTo(prevNode))
                    {
                        if (node == move.SourceState)
                        {
                            var newStrs = new List<string>();
                            foreach (var el in solver.GenerateAllCharacters(move.Label, false))
                                foreach (var str in currStrs)
                                {
                                    newStrs.Add(el + str);
                                    strings.Add(el + str);
                                }
                            currStrs = new List<string>(newStrs);
                            break;
                        }
                    }
                    prevNode = node;
                }

            }
            return strings;

        }
 // gets string that forms the loop path given as a list of states
 private static void getPathStrings(Automaton<BDD> dfa, CharSetSolver solver, List<int> path, string currStr, HashSet<string> strings, int prevState)
 {
     List<int> path1 = new List<int>(path);
     var currState = path1.ElementAt(0);
     path1.RemoveAt(0);
     
     foreach (var move in dfa.GetMovesFrom(prevState))
         if (move.TargetState == currState)
         {
             if (move.Label == null)
             {
                 if (path1.Count == 0)
                     strings.Add(currStr);
                 else
                     getPathStrings(dfa, solver, path1, currStr, strings, currState);
             }
             else
                 foreach (char c in solver.GenerateAllCharacters(move.Label, false))
                     if (path1.Count == 0)
                         strings.Add(currStr + c);
                     else
                         getPathStrings(dfa, solver, path1, currStr + c, strings, currState);
         }
             
 }
        internal static string GenerateShortTerm(Automaton<BDD> dfa, CharSetSolver solver)
        {
            if (dfa.IsEmpty)
                return null;

            Dictionary<int, string> shortStr = new Dictionary<int, string>();

            HashSet<int> reachedStates = new HashSet<int>();
            List<int> toExplore = new List<int>();


            reachedStates.Add(dfa.InitialState);
            toExplore.Add(dfa.InitialState);
            shortStr.Add(dfa.InitialState, "");
            var finSts = dfa.GetFinalStates();
            if (finSts.Contains(dfa.InitialState))
                return "";

            string sCurr = ""; char condC = 'a';
            while (toExplore.Count != 0)
            {
                var current = toExplore.First();
                toExplore.RemoveAt(0);
                shortStr.TryGetValue(current, out sCurr);

                var reachableFromCurr = dfa.GetMovesFrom(current);
                foreach (var move in reachableFromCurr)
                {
                    if (!reachedStates.Contains(move.TargetState))
                    {
                        reachedStates.Add(move.TargetState);
                        toExplore.Add(move.TargetState);

                        if (move.Label == null)
                        {
                            shortStr.Add(move.TargetState, sCurr);
                        }
                        else
                        {
                            foreach (var v in solver.GenerateAllCharacters(move.Label, false))
                            {
                                condC = v;
                                break;
                            }
                            shortStr.Add(move.TargetState, sCurr + condC);
                        }
                        if (finSts.Contains(move.TargetState))
                        {
                            return sCurr + condC;
                        }

                    }
                }
            }
            return null;
        }
예제 #21
0
        public void ConvertUTF16BDDtoUTF8Test_Helper(string testClass)
        {
            var css = new CharSetSolver();

            var bdd = css.MkCharSetFromRegexCharClass(testClass);

            var ascii = bdd & css.MkCharSetFromRange('\0', '\x7F');

            var onebyte_encodings = bdd & ascii;

            var threebyte_encodings = Microsoft.Automata.Utilities.UTF8Encoding.Extract3ByteUTF8Encodings(bdd);

            var twobyte_encodings = Microsoft.Automata.Utilities.UTF8Encoding.Extract2ByteUTF8Encodings(bdd);

            HashSet <Sequence <byte> > utf8_encoding_actual = new HashSet <Sequence <byte> >();

            foreach (var c in css.GenerateAllCharacters(onebyte_encodings))
            {
                utf8_encoding_actual.Add(new Sequence <byte>((byte)c));
            }

            List <Move <BDD> > moves = new List <Move <BDD> >();
            int q = 2;

            moves.Add(Move <BDD> .Create(0, 1, onebyte_encodings));
            for (int i = 0; i < twobyte_encodings.Length; i += 1)
            {
                moves.Add(Move <BDD> .Create(0, q, twobyte_encodings[i].Item1));
                moves.Add(Move <BDD> .Create(q, 1, twobyte_encodings[i].Item2));
                q += 1;
                foreach (var first_byte in css.GenerateAllCharacters(twobyte_encodings[i].Item1))
                {
                    foreach (var second_byte in css.GenerateAllCharacters(twobyte_encodings[i].Item2))
                    {
                        utf8_encoding_actual.Add(new Sequence <byte>((byte)first_byte, (byte)second_byte));
                    }
                }
            }

            foreach (var triple in threebyte_encodings)
            {
                foreach (var pair in triple.Item2)
                {
                    moves.Add(Move <BDD> .Create(0, q, triple.Item1));
                    moves.Add(Move <BDD> .Create(q, q + 1, pair.Item1));
                    moves.Add(Move <BDD> .Create(q + 1, 1, pair.Item2));
                    q += 2;
                    foreach (var first_byte in css.GenerateAllCharacters(triple.Item1))
                    {
                        foreach (var second_byte in css.GenerateAllCharacters(pair.Item1))
                        {
                            foreach (var third_byte in css.GenerateAllCharacters(pair.Item2))
                            {
                                utf8_encoding_actual.Add(new Sequence <byte>((byte)first_byte, (byte)second_byte, (byte)third_byte));
                            }
                        }
                    }
                }
            }

            HashSet <Sequence <byte> > utf8_encoding_expected = new HashSet <Sequence <byte> >();

            for (int i = 0; i <= 0xFFFF; i++)
            {
                char c = (char)i;
                if (!char.IsSurrogate(c))
                {
                    if (Regex.IsMatch(c.ToString(), "^" + testClass + "$"))
                    {
                        var bytes = new Sequence <byte>(System.Text.UnicodeEncoding.UTF8.GetBytes(new char[] { c }));
                        utf8_encoding_expected.Add(bytes);
                    }
                }
            }

            //Automaton<BDD> aut = Automaton<BDD>.Create(css, 0, new int[] { 1 }, moves).Determinize().Minimize();
            //aut.ShowGraph();


            bool encoding_ok = utf8_encoding_expected.IsSubsetOf(utf8_encoding_actual) &&
                               utf8_encoding_actual.IsSubsetOf(utf8_encoding_expected);

            Assert.IsTrue(encoding_ok, "incorrectly ecoded character class: " + testClass);
        }
예제 #22
0
        public void GenerateMembersTest()
        {
            foreach (var encoding in new BitWidth[]{
                BitWidth.BV7, BitWidth.BV8, BitWidth.BV16})
            {
                CharSetSolver solver = new CharSetSolver(encoding);
                var ranges = new char[][] {
                new char[] { 'a', 'c' },
                new char[] {'0', '5'},
                new char[] { 'e', 'h' },
                new char[] {'6', '9'},};
                BDD s = solver.MkRangesConstraint(false, ranges);

                var members = new List<char>(solver.GenerateAllCharacters(s, false));

                Assert.AreEqual<int>(17, members.Count, "wrong number of members in the range [a-ce-h0-9]");
                Assert.AreEqual<char>('0', members[0], "the smallest character in the range must be '0'");
                Assert.AreEqual<char>('h', members[16], "the largest character in the range must be 'h'");

                var membersInReverse = new List<char>(solver.GenerateAllCharacters(s, true));

                Assert.AreEqual<int>(17, membersInReverse.Count, "wrong number of members in the range [a-ce-h0-9]");
                Assert.AreEqual<char>('h', membersInReverse[0], "the first character in the reverse enumeration must be 'h'");
                Assert.AreEqual<char>('0', membersInReverse[16], "the last character in the reverse enumeration must be '0'");
            }
        }
예제 #23
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;
 }
        // returns an array where a[n] is the number of paths of length n
        private static double[] GetPathsUpToN(Automaton <BDD> dfa, HashSet <char> al, CharSetSolver solver, int n)
        {
            var normDfa1 = DFAUtilities.normalizeDFA(dfa).First;

            int length = 0;

            double[] totPaths    = new double[n + 1];
            var      finalStates = normDfa1.GetFinalStates();

            double[] pathNum = new double[normDfa1.StateCount];
            pathNum[0]  = 1;
            totPaths[0] = finalStates.Contains(0) ? 1 : 0;
            for (int i = 1; i < pathNum.Length; i++)
            {
                pathNum[i] = 0;
            }


            while (length < n)
            {
                double[] oldPathNum = pathNum.ToArray();
                for (int i = 0; i < pathNum.Length; i++)
                {
                    pathNum[i] = 0;
                }

                length++;
                foreach (var state in normDfa1.States)
                {
                    if (oldPathNum[state] > 0)
                    {
                        foreach (var move in normDfa1.GetMovesFrom(state))
                        {
                            int size = 0;
                            //Check if epsilon transition
                            if (move.Label == null)
                            {
                                size = 1;
                            }
                            else
                            {
                                foreach (var v in solver.GenerateAllCharacters(move.Label, false))
                                {
                                    size++;
                                }
                            }

                            pathNum[move.TargetState] += oldPathNum[state] * size;
                        }
                    }
                }

                //totPaths[length] = totPaths[length - 1];
                foreach (var state in finalStates)
                {
                    totPaths[length] += pathNum[state];
                }
            }

            return(totPaths);
        }
        // Accessory methods for strings
        #region Accessory methods for strings
        internal static List<string> getSimplePrefixes(Automaton<BDD> dfa, CharSetSolver solver)
        {
            List<string> strings = new List<string>();
            foreach (var path in getSimplePaths(dfa))
            {
                var currStrs = new List<string>();
                currStrs.Add("");
                var p = new List<int>(path);
                p.RemoveAt(0);
                int prevNode = dfa.InitialState;
                foreach (int node in p)
                {
                    foreach (var move in dfa.GetMovesFrom(prevNode))
                    {
                        if (node == move.TargetState)
                        {
                            var newStrs = new List<string>();
                            foreach (var el in solver.GenerateAllCharacters(move.Label, false))
                                foreach (var str in currStrs)
                                {
                                    newStrs.Add(str + el);
                                    strings.Add(str + el);
                                }
                            currStrs = new List<string>(newStrs);
                            break;
                        }
                    }
                    prevNode = node;
                }

            }
            return strings;
        }
예제 #26
0
        internal override void ToMonaString(StringBuilder sb, CharSetSolver solver)
        {
            var addOr = false;
            foreach (var bv in solver.GenerateAllCharacters(pred, false))
            {
                if (addOr)
                    sb.Append(" | ");
                else
                    addOr = true;

                string s = BitVecUtil.GetIntBinaryString(bv);
                sb.Append("(");
                var c = s[0];
                if (c == '1')
                    sb.AppendFormat("is_{0}({1})", c, set);
                else
                    sb.AppendFormat("~is_{0}({1})", c, set);
                for (int i = 1; i < s.Length; i++)
                {
                    sb.Append(" & ");
                    c = s[i];
                    if (c == '1')
                        sb.AppendFormat("is_{0}({1})", c, set);
                    else
                        sb.AppendFormat("~is_{0}({1})", c, set);
                }
                sb.Append(")");                
            }
        }
        private static Dictionary<char, BDD> ComputeIgnoreCaseDistionary(CharSetSolver solver)
        {
            var ignoreCase = new Dictionary<char, BDD>();
            for (uint i = 0; i <= 0xFFFF; i++)
            {
                char c = (char)i;
                char cU = char.ToUpper(c); // (char.IsLetter(char.ToUpper(c)) ? char.ToUpper(c) : c);
                char cL = char.ToLower(c); // (char.IsLetter(char.ToLower(c)) ? char.ToLower(c) : c);
                if (c != cU || c != cL || cU != cL)
                {
                    //make sure that the regex engine considers c as being equivalent to cU and cL, else ignore c
                    //in some cases c != cU but the regex engine does not consider the chacarters equivalent wrt the ignore-case option.
                    //These characters are:
                    //c=\xB5,cU=\u039C
                    //c=\u0131,cU=I
                    //c=\u017F,cU=S
                    //c=\u0345,cU=\u0399
                    //c=\u03C2,cU=\u03A3
                    //c=\u03D0,cU=\u0392
                    //c=\u03D1,cU=\u0398
                    //c=\u03D5,cU=\u03A6
                    //c=\u03D6,cU=\u03A0
                    //c=\u03F0,cU=\u039A
                    //c=\u03F1,cU=\u03A1
                    //c=\u03F5,cU=\u0395
                    //c=\u1E9B,cU=\u1E60
                    //c=\u1FBE,cU=\u0399
                    if (System.Text.RegularExpressions.Regex.IsMatch(cU.ToString() + cL.ToString(), "^(?i:" + StringUtility.Escape(c) + ")+$"))
                    {
                        BDD equiv = solver.False;

                        if (ignoreCase.ContainsKey(c))
                            equiv = equiv.Or(ignoreCase[c]);
                        if (ignoreCase.ContainsKey(cU))
                            equiv = equiv.Or(ignoreCase[cU]);
                        if (ignoreCase.ContainsKey(cL))
                            equiv = equiv.Or(ignoreCase[cL]);

                        equiv = equiv.Or(solver.MkCharSetFromRange(c, c)).Or(solver.MkCharSetFromRange(cU, cU)).Or(solver.MkCharSetFromRange(cL, cL));

                        foreach (char d in solver.GenerateAllCharacters(equiv))
                            ignoreCase[d] = equiv;
                    }
                    //else
                    //{
                    //    outp += "c=" + StringUtility.Escape(c) + "," + "cU=" + StringUtility.Escape(cU);
                    //    Console.WriteLine("c=" + StringUtility.Escape(c) + "," + "cL=" + StringUtility.Escape(cL) + "," + "cU=" + StringUtility.Escape(cU));
                    //}
                }
            }
            return ignoreCase;
        }
예제 #28
0
        public void GenerateMembersTest2()
        {
            CharSetSolver solver = new CharSetSolver(BitWidth.BV16);
            var ranges = new char[][] {
                new char[] { 'a', 'c' },
                new char[] {'\u5555', '\u55A5'},
                new char[] { 'e', 'h' },
                new char[] {'\u55A0', '\u55AA'},
            };
            BDD s = solver.MkRangesConstraint(false, ranges);
            s.ToDot("bug.dot");

            var r = solver.ToRanges(s);
            var s2 = solver.MkCharSetFromRanges(r);

            var members = new List<char>(solver.GenerateAllCharacters(s2, false));
            var smallest = (char)solver.GetMin(s2);

            Assert.AreEqual<int>(93, members.Count, "wrong number of members in the range [a-ce-h\\u5555-\\u55AA]");
            Assert.AreEqual<char>('a', members[0], "the smallest character in the range must be 'a'");
            Assert.AreEqual<char>('\u55AA', members[members.Count - 1], "the largest character in the range must be '\\u55AA'");

            var membersInReverse = new List<char>(solver.GenerateAllCharacters(s, true));

            Assert.AreEqual<int>(93, membersInReverse.Count, "wrong number of members in the range [a-ce-h\\u5555-\\u55AA]");
            Assert.AreEqual<char>('\u55AA', membersInReverse[0], "the first character in the reverse enumeration must be '\\u55AA'");
            Assert.AreEqual<char>('a', membersInReverse[membersInReverse.Count-1], "the last character in the reverse enumeration must be 'a'");
        }
        // returns an array where a[n] is the number of paths of length n
        private static double[] GetPathsUpToN(Automaton<BDD> dfa, HashSet<char> al, CharSetSolver solver, int n)
        {
            var normDfa1 = DFAUtilities.normalizeDFA(dfa).First;

            int length = 0;

            double[] totPaths = new double[n + 1];
            var finalStates = normDfa1.GetFinalStates();

            double[] pathNum = new double[normDfa1.StateCount];
            pathNum[0] = 1;
            totPaths[0] = finalStates.Contains(0) ? 1 : 0;
            for (int i = 1; i < pathNum.Length; i++)
                pathNum[i] = 0;


            while (length < n)
            {
                double[] oldPathNum = pathNum.ToArray();
                for (int i = 0; i < pathNum.Length; i++)
                    pathNum[i] = 0;

                length++;
                foreach (var state in normDfa1.States)
                    if (oldPathNum[state] > 0)
                        foreach (var move in normDfa1.GetMovesFrom(state))
                        {
                            int size = 0;
                            //Check if epsilon transition
                            if (move.Label == null)
                                size = 1;
                            else
                                foreach (var v in solver.GenerateAllCharacters(move.Label, false))
                                    size++;

                            pathNum[move.TargetState] += oldPathNum[state] * size;
                        }

                //totPaths[length] = totPaths[length - 1];
                foreach (var state in finalStates)
                    totPaths[length] += pathNum[state];
            }

            return totPaths;
        }
예제 #30
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);
        }
        public static void printDFA(Automaton<BDD> dfa, HashSet<char> alphabet, StringBuilder sb)
        {
            var newDfa = normalizeDFA(dfa).First;

            CharSetSolver solver = new CharSetSolver(BitWidth.BV64);

            sb.Append("alphabet:");
            foreach (var ch in alphabet)
                sb.Append(" " + ch);
            sb.AppendLine();

            sb.AppendLine(string.Format("{0} states", newDfa.StateCount));

            sb.Append("final states:");
            foreach (var st in newDfa.GetFinalStates())
                sb.Append(" " + st);
            sb.AppendLine();
            
            foreach (var move in newDfa.GetMoves())
            {

                List<char> chars = move.Label==null? new List<char>() : solver.GenerateAllCharacters(move.Label, false).ToList();
                chars.Sort();
                foreach (var ch in chars)
                {
                    sb.AppendLine(string.Format("{0},{1},{2}", move.SourceState, move.TargetState, ch));
                }
            }
        }
예제 #32
0
        private static Dictionary <char, BDD> ComputeIgnoreCaseDistionary(CharSetSolver solver)
        {
            var ignoreCase = new Dictionary <char, BDD>();

            for (uint i = 0; i <= 0xFFFF; i++)
            {
                char c  = (char)i;
                char cU = char.ToUpper(c); // (char.IsLetter(char.ToUpper(c)) ? char.ToUpper(c) : c);
                char cL = char.ToLower(c); // (char.IsLetter(char.ToLower(c)) ? char.ToLower(c) : c);
                if (c != cU || c != cL || cU != cL)
                {
                    //make sure that the regex engine considers c as being equivalent to cU and cL, else ignore c
                    //in some cases c != cU but the regex engine does not consider the chacarters equivalent wrt the ignore-case option.
                    //These characters are:
                    //c=\xB5,cU=\u039C
                    //c=\u0131,cU=I
                    //c=\u017F,cU=S
                    //c=\u0345,cU=\u0399
                    //c=\u03C2,cU=\u03A3
                    //c=\u03D0,cU=\u0392
                    //c=\u03D1,cU=\u0398
                    //c=\u03D5,cU=\u03A6
                    //c=\u03D6,cU=\u03A0
                    //c=\u03F0,cU=\u039A
                    //c=\u03F1,cU=\u03A1
                    //c=\u03F5,cU=\u0395
                    //c=\u1E9B,cU=\u1E60
                    //c=\u1FBE,cU=\u0399
                    if (System.Text.RegularExpressions.Regex.IsMatch(cU.ToString() + cL.ToString(), "^(?i:" + StringUtility.Escape(c) + ")+$"))
                    {
                        BDD equiv = solver.False;

                        if (ignoreCase.ContainsKey(c))
                        {
                            equiv = equiv.Or(ignoreCase[c]);
                        }
                        if (ignoreCase.ContainsKey(cU))
                        {
                            equiv = equiv.Or(ignoreCase[cU]);
                        }
                        if (ignoreCase.ContainsKey(cL))
                        {
                            equiv = equiv.Or(ignoreCase[cL]);
                        }

                        equiv = equiv.Or(solver.MkCharSetFromRange(c, c)).Or(solver.MkCharSetFromRange(cU, cU)).Or(solver.MkCharSetFromRange(cL, cL));

                        foreach (char d in solver.GenerateAllCharacters(equiv))
                        {
                            ignoreCase[d] = equiv;
                        }
                    }
                    //else
                    //{
                    //    outp += "c=" + StringUtility.Escape(c) + "," + "cU=" + StringUtility.Escape(cU);
                    //    Console.WriteLine("c=" + StringUtility.Escape(c) + "," + "cL=" + StringUtility.Escape(cL) + "," + "cU=" + StringUtility.Escape(cU));
                    //}
                }
            }
            return(ignoreCase);
        }
        // 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;
        }
예제 #34
0
 //check if delta(S,T,c) exists
 static bool MoveFromStoT(int S, int T, Automaton<BDD> aut, CharSetSolver solver, out char witness)
 {
     foreach (var move in aut.GetMovesFrom(S))
         if (move.TargetState == T)
         {
             foreach(var w in solver.GenerateAllCharacters(move.Label,false)){
                 witness=w;
                 return true;
             }
         }
     witness = 'a';
     return false;
 }
예제 #35
0
        private static Dictionary <char, BDD> ComputeIgnoreCaseDictionary(CharSetSolver solver, CultureInfo culture)
        {
            CultureInfo originalCulture = CultureInfo.CurrentCulture;

            try
            {
                CultureInfo.CurrentCulture = culture;

                var ignoreCase = new Dictionary <char, BDD>();

                for (uint i = 0; i <= 0xFFFF; i++)
                {
                    char c      = (char)i;
                    char cUpper = char.ToUpper(c);
                    char cLower = char.ToLower(c);

                    if (cUpper == cLower)
                    {
                        continue;
                    }

                    // c may be different from both cUpper as well as cLower.
                    // Make sure that the regex engine considers c as being equivalent to cUpper and cLower, else ignore c.
                    // In some cases c != cU but the regex engine does not consider the chacarters equivalent wrt the ignore-case option.
                    if (Regex.IsMatch($"{cUpper}{cLower}", $"^(?i:\\u{i:X4}\\u{i:X4})$"))
                    {
                        BDD equiv = solver.False;

                        if (ignoreCase.ContainsKey(c))
                        {
                            equiv = solver.Or(equiv, ignoreCase[c]);
                        }

                        if (ignoreCase.ContainsKey(cUpper))
                        {
                            equiv = solver.Or(equiv, ignoreCase[cUpper]);
                        }

                        if (ignoreCase.ContainsKey(cLower))
                        {
                            equiv = solver.Or(equiv, ignoreCase[cLower]);
                        }

                        // Make sure all characters are included initially or when some is still missing
                        equiv = solver.Or(equiv, solver.Or(solver.CreateCharSetFromRange(c, c), solver.Or(solver.CreateCharSetFromRange(cUpper, cUpper), solver.CreateCharSetFromRange(cLower, cLower))));

                        // Update all the members with their case-invariance equivalence classes
                        foreach (char d in solver.GenerateAllCharacters(equiv))
                        {
                            ignoreCase[d] = equiv;
                        }
                    }
                }

                return(ignoreCase);
            }
            finally
            {
                CultureInfo.CurrentCulture = originalCulture;
            }
        }
예제 #36
0
        //check if delta(S,T,c) exists
        static string ShortStringStoTwithC(char c, int S, int T, Automaton<BDD> aut, int limit, CharSetSolver solver)
        {
            var pair = new Pair<int, int>(S, T);
            if (S == T)
                return "";

            var aut1 = Automaton<BDD>.Create(solver, S, new int[] { T }, aut.GetMoves());
            var autR = solver.Convert(System.Text.RegularExpressions.Regex.Escape(c.ToString()));

            var contst = aut1.Intersect(autR).Determinize().Minimize();
            var finst= contst.GetFinalStates();
            var strings = new Dictionary<int, string>();
            strings[contst.InitialState] = "";
            Dictionary<int,int> dist = new Dictionary<int,int>();
            HashSet<int> visited = new HashSet<int>();
            List<int> toVisit = new List<int>();
            visited.Add(contst.InitialState);
            toVisit.Add(contst.InitialState);
            dist[contst.InitialState] = 0;
            while (toVisit.Count > 0)
            {
                var curr = toVisit[0];
                toVisit.RemoveAt(0);
                if(dist[curr]<=limit)
                    foreach (var move in contst.GetMovesFrom(curr))
                        if (!visited.Contains(move.TargetState))
                        {
                            dist[move.TargetState] = dist[move.SourceState] + 1;
                            visited.Add(move.TargetState);
                            toVisit.Add(move.TargetState);
                            char wit='a';
                            foreach(var w in solver.GenerateAllCharacters(move.Label,false)){
                                wit=w;
                                break;
                            }
                            strings[move.TargetState] = strings[move.SourceState] + wit;
                            if (finst.Contains(move.TargetState))
                            {
                                return strings[move.TargetState];
                            }
                        }
            }

            throw new AutomataException("this code shouldn't be reachable");
        }
 /// <summary>
 /// Returns true iff the DFA is not complete or not a DFA (misses transitions)
 /// </summary>
 /// <param name="dfa"></param>
 /// <param name="al"></param>
 /// <param name="solver"></param>
 /// <returns></returns>
 public static bool ContainsSyntacticMistake(Automaton<BDD> dfa, HashSet<char> al,
     CharSetSolver solver, HashSet<int> missingEdges)
 {
     bool mistake = false;
     var dfaNorm = DFAUtilities.normalizeDFA(dfa).First;
     foreach (var state in dfaNorm.States)
     {
         HashSet<char> alCopy = new HashSet<char>(al);
         foreach (var move in dfaNorm.GetMovesFrom(state))
         {
             foreach (var c in solver.GenerateAllCharacters(move.Label, false))
             {
                 if (!alCopy.Contains(c))
                 {
                     int hash = (int)(Math.Pow(2, move.SourceState) + Math.Pow(3, c - 97)) + dfaNorm.StateCount;
                     mistake = true;
                 }
                 alCopy.Remove(c);
             }
         }
         if (alCopy.Count > 0)
             mistake=true;
     }
     return mistake;
 }