public void TestStateDistinguisher_EnumerateAllDistinguishingSequences() { var solver = ContextFreeGrammar.GetContext(); var regex = "^([0-9]{4,}|[3-9][0-9]{2}|2[5-9][0-9])$"; string[] regexes = File.ReadAllLines(regexesFile); var nfa = solver.Convert(regex).RemoveEpsilons(); var dfa = nfa.Determinize();//.MakeTotal(); var mfa = dfa.Minimize(); var dist = new StateDistinguisher <BDD>(dfa, x => (char)x.GetMin(), false); int minimalStateCount = mfa.StateCount; var distinguishers = new Dictionary <Tuple <int, int>, List <ConsList <BDD> > >(); foreach (int p in mfa.GetStates()) { foreach (int q in mfa.GetStates()) { if (p != q) { var pq = (p < q ? new Tuple <int, int>(p, q) : new Tuple <int, int>(q, p)); if (!distinguishers.ContainsKey(pq)) { distinguishers[pq] = new List <ConsList <BDD> >(dist.EnumerateAllDistinguishingSequences(p, q)); } } } } Assert.AreEqual <int>((mfa.StateCount * (mfa.StateCount - 1)) / 2, distinguishers.Count); }
public void TestStateDistinguisherH() { var solver = new CharSetSolver(); var A = solver.Convert("A").Determinize().RemoveEpsilons(); var B = solver.Convert("B.*B").Determinize().RemoveEpsilons(); var AB = A.Intersect(B); var states = new List <int>(AB.GetStates()); var dist = new StateDistinguisher <BDD>(AB); //check suffix-closedness var ABMin = AB.Minimize(); var diststr = dist.GetAllDistinguishingSequences(); //here we know that the minimization algorithm keeps the same state ids Func <int, int, Tuple <int, int> > MkPair = (x, y) => (x <= y ? new Tuple <int, int>(x, y) : new Tuple <int, int>(y, x)); foreach (var p in ABMin.States) { foreach (var q in ABMin.States) { if (p != q) { var d = dist.GetDistinguishingSequence(p, q); Assert.IsTrue(d != null); //check that d distinguishes p from q var p1 = p; var q1 = q; for (int i = 0; i < d.Length; i++) { p1 = AB.GetTargetState(p1, d[i]); q1 = AB.GetTargetState(q1, d[i]); } Assert.IsTrue(AB.IsFinalState(p1) != AB.IsFinalState(q1)); } } } }
public void TestStateDistinguisher_BugRepo() { var solver = new CharSetSolver(); var regex = @"^v.g+\\.w{2,3}/v\\?d[w-]{3}"; var A = solver.Convert(regex).Determinize(); var states = new List <int>(A.GetStates()); var dist = new StateDistinguisher <BDD>(A); var AMin = A.Minimize(); ValidateDistinguishers(A, AMin, dist, 0, regex); }
public void TestStateDistinguisher_BugRepo2() { var solver = new CharSetSolver(); var regex = @"(^(?:\w\:)?(?:/|\\\\){1}[^/|\\]*(?:/|\\){1})"; var A = solver.Convert(regex).Determinize(); var states = new List <int>(A.GetStates()); var dist = new StateDistinguisher <BDD>(A); var distmap = new List <Tuple <Tuple <int, int>, List <ConsList <BDD> > > >(dist.EnumerateAllDistinguishingSequences()); var AMin = A.Minimize(); ValidateDistinguishers(A, AMin, dist, 0, regex); }
public void TestStateDistinguisherH2_Concrete() { var solver = ContextFreeGrammar.GetContext(); var regex = "^([0-9]{4,}|[3-9][0-9]{2}|2[5-9][0-9])$"; var nfa = solver.Convert(regex).RemoveEpsilons(); var dfa = nfa.Determinize();//.MakeTotal(); var mfa = dfa.Minimize(); var dist = new StateDistinguisher <BDD>(dfa, x => (char)x.GetMin()); int minimalStateCount = mfa.StateCount; var witnesses = dist.GetAllDistinguishingStrings(); AssertIsSuffixClosed(witnesses); //var w = dist.GetDistinguishingSequence(1, 10); int distinguisherCount = witnesses.Length; Assert.IsTrue(distinguisherCount < minimalStateCount + 1); }
public void TestStateDistinguisher_HardCases() { string[] regexes = hardcases; var dfas = new List <Automaton <BDD> >(); int timeoutcount = 0; int k = hardcases.Length - 1; //where to start int K = 1; // hardcases.Length; //how many regexes to consider List <string> regexes_used = new List <string>(); while (dfas.Count < K) { var solver = new CharSetSolver(); var ascii = solver.Convert("^[\0-\x7F]*$"); var regex = regexes[k++]; var nfa = solver.Convert(regex).RemoveEpsilons().Intersect(ascii); try { var dfa = nfa.Determinize(1000); dfas.Add(dfa); regexes_used.Add(regex); } catch (TimeoutException) { timeoutcount += 1; } } int totalMininmalStateCount = 0; int totalDistinguisherCount = 0; var dist = new StateDistinguisher <BDD> [K]; var mfas = new Automaton <BDD> [K]; for (int i = 0; i < K; i++) { mfas[i] = dfas[i].Minimize(); dist[i] = new StateDistinguisher <BDD>(dfas[i], x => (char)x.GetMin()); ValidateDistinguishers(dfas[i], mfas[i], dist[i], i, regexes_used[i]); totalMininmalStateCount += mfas[i].StateCount; totalDistinguisherCount += dist[i].GetAllDistinguishingSequences().Length; } Console.WriteLine(((double)totalDistinguisherCount) / ((double)totalMininmalStateCount)); }
public void TestStateDistinguisherH2() { var solver = ContextFreeGrammar.GetContext(); var regex = "^([0-9]{4,}|[3-9][0-9]{2}|2[5-9][0-9])$"; string[] regexes = File.ReadAllLines(regexesFile); var nfa = solver.Convert(regex).RemoveEpsilons(); var dfa = nfa.Determinize();//.MakeTotal(); var mfa = dfa.Minimize(); var dist = new StateDistinguisher <BDD>(dfa); int minimalStateCount = mfa.StateCount; var witnesses = dist.GetAllDistinguishingSequences(); AssertIsSuffixClosed(witnesses); //var w = dist.GetDistinguishingSequence(1, 10); int distinguisherCount = witnesses.Length; Assert.IsTrue(distinguisherCount < minimalStateCount + 1); CheckAllStatePairDistinguishers(dfa, mfa, dist); }
private static void CheckAllStatePairDistinguishers(Automaton <BDD> dfa, Automaton <BDD> mfa, StateDistinguisher <BDD> dist) { foreach (var p in mfa.GetStates()) { foreach (var q in mfa.GetStates()) { if (p != q) { var d = dist.GetDistinguishingSequence(p, q); int q1; int p1; bool ok_q = dfa.TryGetTargetState(q, out q1, d.ToArray()); bool ok_p = dfa.TryGetTargetState(p, out p1, d.ToArray()); Assert.IsTrue(ok_q || ok_p); if (ok_q && ok_p) { Assert.IsTrue(dfa.IsFinalState(q1) != dfa.IsFinalState(p1)); } } } } }
private static void ValidateDistinguishers(Automaton <BDD> aut, Automaton <BDD> autMin, StateDistinguisher <BDD> dist, int i, string regex) { var distseqs = dist.GetAllDistinguishingSequences(); if (distseqs.Length > autMin.StateCount) { Console.WriteLine(string.Format("{0}, {1}, {2}", i, distseqs.Length - autMin.StateCount, regex)); } foreach (var p in autMin.States) { foreach (var q in autMin.States) { if (p != q) { var d = dist.GetDistinguishingSequence(p, q); Assert.IsTrue(d != null); //check that d distinguishes p from q int p1; int q1; //aut may be partial, if false is returned it means that the implicit sink state was reached bool pok = aut.TryGetTargetState(p, out p1, d.ToArray()); bool qok = aut.TryGetTargetState(q, out q1, d.ToArray()); Assert.IsTrue(pok || qok); if (!pok) { Assert.IsTrue(aut.IsFinalState(q1)); } else if (!qok) { Assert.IsTrue(aut.IsFinalState(p1)); } else { Assert.IsTrue(aut.IsFinalState(q1) != aut.IsFinalState(p1)); } } } } }