def test_count_below_bound_is_the_same(re, m, n): assume(rd.has_matches(re)) m, n = sorted((m, n)) count1 = rd.LanguageCounter(*rd.build_dfa(re)).count(m) count2 = rd.LanguageCounter(*rd.build_dfa(rd.bounded(re, n))).count(m) assert count1 == count2
def test_power_series_counts_language(re, i): dfa = rd.build_dfa(re) z, gfs = compute_generating_functions(*dfa) f = gfs[0] note(f) power_series = series(f, n=i + 1) counter = rd.LanguageCounter(*dfa) assert counter.count(i) == power_series.coeff(z, i)
def __init__(self, regex, seed=None): self.__random = Random(seed) self.__dfa = build_dfa(regex) symbol, gfs = (compute_generating_functions(*self.__dfa)) # Converting the generating functions to lambdas significantly speeds # up drawing. I'm not totally sure why? I suspect it might be partly # not going through arbitrary precision decimals, so this probably # comes at some cost to numeric stability. self.__generating_functions = [sympy.lambdify(symbol, g) for g in gfs] f = gfs[0] size = symbol * sympy.diff(f) / f self.expected_size = sympy.lambdify(symbol, size) self.__symbol = symbol self.__expected_size = size
def test_lexmin_of_mutated_regex_is_refutation(x, data): assume(rd.has_matches(x)) accepting, transitions = rd.build_dfa(x) j = data.draw(st.integers(0, len(accepting) - 1)) assume(transitions[j]) c = data.draw(st.sampled_from(sorted(transitions[j]))) transitions[j][c] = data.draw(st.integers(0, len(accepting) - 1)) y = rd.decompile_dfa(accepting, transitions) assume(rd.has_matches(y)) assume(not rd.equivalent(x, y)) w = rd.lexmin(symdiff(x, y)) assert w is not None assert w == rd.witness_difference(x, y)
def test_can_build_a_dfa(re): assume(rd.has_matches(re)) rd.build_dfa(re)
def test_no_refutation_for_decompilation(re): dec = rd.decompile_dfa(*rd.build_dfa(re)) assert rd.witness_difference(dec, re) is None
def test_decompilation(re): assume(rd.has_matches(re)) dfa = rd.build_dfa(re) rewritten = rd.decompile_dfa(*dfa) assert rd.equivalent(re, rewritten)
def test_trival_dfa_from_intersection(): assert rd.build_dfa( rd.intersection(rd.char(b'\x00'), rd.char(b'\x00\x01'))) == ( [False, True], [{0: 1}, {}] )
def test_two_phase_dfa(): re = rd.concatenate(rd.star(rd.char(0)), rd.star(rd.char(1))) accepting, transitions = rd.build_dfa(re) assert accepting == [True, True] assert transitions == [{0: 0, 1: 1}, {1: 1}]
def test_non_empty_star_dfa(): accepting, _ = rd.build_dfa(rd.nonempty(rd.star(rd.char(0)))) assert accepting == [False, True]
def to_basic(re): return rd.decompile_dfa(*rd.build_dfa(re))
def test_can_compute_a_generating_function(re): compute_generating_functions(*rd.build_dfa(re))