public void MkRegexFromAutomatonOf_3_Divisibility() { var solver = new CharSetSolver(BitWidth.BV7); var _0 = solver.MkCharConstraint('a'); var _3 = solver.MkCharConstraint('d'); var _03 = solver.MkOr(_0, _3); var _1 = solver.MkCharConstraint('b'); var _2 = solver.MkCharConstraint('c'); var moves = new Move <BDD>[] { Move <BDD> .Create(0, 0, _03), Move <BDD> .Create(0, 1, _2), Move <BDD> .Create(0, 2, _1), Move <BDD> .Create(1, 1, _03), Move <BDD> .Create(1, 0, _1), Move <BDD> .Create(1, 2, _2), Move <BDD> .Create(2, 2, _03), Move <BDD> .Create(2, 0, _2), Move <BDD> .Create(2, 1, _1) }; var aut = Automaton <BDD> .Create(solver, 0, new int[] { 0 }, moves); //solver.ShowGraph(aut, "div3a"); string regex = solver.ConvertToRegex(aut).Replace("[ad]", "(a|d)").Replace("[b]", "b").Replace("[c]", "c"); var aut2 = solver.Convert(regex).Determinize().MinimizeHopcroft(); // solver.ShowGraph(aut2, "div3b"); bool equiv = aut.IsEquivalentWith(aut2); Assert.IsTrue(equiv); //binary version of the regex string regex01 = regex.Replace("a", "00").Replace("b", "01").Replace("c", "10").Replace("d", "11"); var bits30 = solver.Convert("^[01]{10,30}\\z"); var aut01_ = solver.Convert(regex01).Determinize(); //solver.ShowGraph(aut01_, "aut01_"); var aut01 = aut01_.MinimizeHopcroft(); //solver.ShowGraph(aut01, "aut01"); string regex01small = solver.ConvertToRegex(aut01); aut01 = aut01.Intersect(bits30); //genarate some random paths in this automaton and check that the binary representation is a numer that is divisible by 3. for (int i = 0; i < 1000; i++) { string sample = solver.ChooseString(aut01.ChoosePathToSomeFinalState(solver.Chooser)); int m = 0; for (int j = sample.Length - 1; j >= 0; j--) { if (sample[j] == '0') { m = m << 1; } else { m = (m << 1) | 1; } } bool div3 = ((m % 3) == 0); Assert.IsTrue(div3); } }
private static void LDiffExperimentBDD(BitWidth encoding) { var solver = new CharSetSolver(encoding); var converter = solver; string[] regexes = SampleRegexes.regexes; long timeout = 60 * Microsoft.Automata.Internal.Utilities.HighTimer.Frequency; //1 minute int nonemptyCnt = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { string regexA = regexes[i]; string regexB = regexes[j]; long start = Microsoft.Automata.Internal.Utilities.HighTimer.Now; var A = converter.Convert(regexA, System.Text.RegularExpressions.RegexOptions.None); var B = converter.Convert(regexB, System.Text.RegularExpressions.RegexOptions.None); try { List <BDD> witness; bool isNonempty; isNonempty = Automaton <BDD> .CheckDifference(A, B, (int)timeout, out witness); if (isNonempty) { nonemptyCnt += 1; string s = solver.ChooseString(witness); Assert.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(s, regexA), s + " must be a member of " + regexA); Assert.IsFalse(System.Text.RegularExpressions.Regex.IsMatch(s, regexB), s + " must not be a member of " + regexB); } } catch (TimeoutException) { Console.WriteLine("Timeout {0},{1}", i, j); } } } Assert.AreEqual <int>(30, nonemptyCnt, "unexpected number of nonempty differences"); }