def test_renamed_and_eq_01(self): alphabet = {'0', '1'} qa = automaton.State('a') qb = automaton.State('b') qc = automaton.State('c') qd = automaton.State('d') qe = automaton.State('e') qf = automaton.State('f') dfa = automaton.DFA(alphabet, qa) dfa.add_transition(qa, qb, '0') dfa.add_transition(qa, qc, '1') dfa.add_transition(qb, qa, '0') dfa.add_transition(qb, qd, '1') dfa.add_transition(qc, qe, '0') dfa.add_transition(qc, qf, '1') dfa.add_transition(qd, qe, '0') dfa.add_transition(qd, qf, '1') dfa.add_transition(qe, qe, '0') dfa.add_transition(qe, qf, '1') dfa.add_transition(qf, qf, '0') dfa.add_transition(qf, qf, '1') dfa.accept_states.update({qc, qd, qe}) dfa = dfa.minimize() q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') expected_dfa = automaton.DFA(alphabet, q0) expected_dfa.add_transition(q0, q1, '1') expected_dfa.add_transition(q0, q0, '0') expected_dfa.add_transition(q1, q2, '1') expected_dfa.add_transition(q1, q1, '0') expected_dfa.add_transition(q2, q2, '1') expected_dfa.add_transition(q2, q2, '0') expected_dfa.accept_states.add(q1) self.assertEqual(expected_dfa, dfa)
def test_active_nlstar_07(self): """ try to let NL* learn the regular language A. A is a regular language over the alphabet {0, 1} where each string contains 101 as a substring. """ q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') expected_dfa = automaton.DFA({'0', '1'}, start_state=q1) expected_dfa.add_transition(q1, q1, '0') expected_dfa.add_transition(q1, q2, '1') expected_dfa.add_transition(q2, q2, '1') expected_dfa.add_transition(q2, q3, '0') expected_dfa.add_transition(q3, q1, '0') expected_dfa.add_transition(q3, q4, '1') expected_dfa.add_transition(q4, q4, '0') expected_dfa.add_transition(q4, q4, '1') expected_dfa.accept_states.add(q4) teacher = oracle.ActiveOracle(expected_dfa) nlstar = algorithms.NLSTAR({'0', '1'}, teacher) nfa = nlstar.learn() dfa = nfa.to_dfa() self.assertEqual(expected_dfa.rename_states(), dfa.rename_states())
def test_active_nlstar_11(self): """ try to let NL* learn the regular language L. L is a regular language over the alphabet {a, b} where for every string in L contains exactly two a's. """ q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q0, 'b') expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q1, q1, 'b') expected_dfa.add_transition(q1, q2, 'a') expected_dfa.add_transition(q2, q2, 'b') expected_dfa.add_transition(q2, q3, 'a') expected_dfa.add_transition(q3, q3, 'a') expected_dfa.add_transition(q3, q3, 'b') expected_dfa.accept_states.add(q2) teacher = oracle.ActiveOracle(expected_dfa) nlstar = algorithms.NLSTAR({'a', 'b'}, teacher) nfa = nlstar.learn() dfa = nfa.to_dfa() self.assertEqual(expected_dfa, dfa)
def test_active_nlstar_06(self): """ try to let NL* learn the regular language A. A is a regular language over the alphabet {0, 1} where each string contains an odd number of 1s """ q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'0', '1'}, start_state=q0) expected_dfa.add_transition(q0, q0, '0') expected_dfa.add_transition(q0, q1, '1') expected_dfa.add_transition(q1, q1, '0') expected_dfa.add_transition(q1, q0, '1') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) nlstar = algorithms.NLSTAR({'0', '1'}, teacher) nfa = nlstar.learn() self.assertEqual(2, len(nfa._states)) self.assertEqual(1, len(nfa._accept_states)) self.assertEqual(expected_dfa, nfa.to_dfa())
def test_active_lstar_05(self): """ Try to let L* learn the regular language A. A is a language over the alphabet sigma = {a}, that accepts all strings with an odd number of a's. """ q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'a'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q1, q0, 'a') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a'}, teacher) dfa = lstar.learn() self.assertEqual(2, len(dfa.states)) self.assertEqual(1, len(dfa.accept_states)) s_plus = set() s_minus = set() for i in range(1, 21, 2): s_plus.add('a' * i) s_minus.add('a' * (i - 1)) for s in s_plus: self.assertTrue(dfa.parse_string(s)[1]) for s in s_minus: self.assertFalse(dfa.parse_string(s)[1])
def _build_automaton(self, ot: utils.ObservationTable) -> automaton.DFA: """ Builds an automaton from the observation table. :param ot: The data to build the dfa from. :type ot: ObservationTable :return: The dfa built from the observation table. :rtype: DFA """ self._logger.info('Building DFA from the table.') dfa = automaton.DFA(self._alphabet) for u in self._red: for v in ot.ot.keys(): if u == v: continue if len(v) < len(u) and ot.get_row(v) != ot.get_row(u): dfa.states.add(automaton.State(u)) for u in dfa.states: if ot.entry_exists(u.name, ''): if ot.get(u.name, '') == 1: dfa.accept_states.add(u) elif ot.get(u.name, '') == 0: dfa.reject_states.add(u) for a in self._alphabet: for w in dfa.states: if ot.get_row(u.name + a) == ot.get_row(w.name): dfa.add_transition(u, w, a) return dfa.rename_states()
def test_automaton_02(self): start_state = automaton.State('') q1 = automaton.State('1') q2 = automaton.State('2') dfa = automaton.DFA({'a', 'b'}, start_state) dfa.add_transition(start_state, start_state, 'a') dfa.add_transition(start_state, q1, 'b') dfa.add_transition(q1, q2, 'a') dfa.add_transition(q1, q2, 'b') self.assertEqual(3, len(dfa.states)) self.assertEqual(2, len(dfa._transitions.keys())) self.assertTrue(dfa.transition_exists(start_state, 'a')) self.assertTrue(dfa.transition_exists(start_state, 'b')) self.assertTrue(dfa.transition_exists(q1, 'a')) self.assertFalse(dfa.transition_exists(q2, 'a')) self.assertFalse(dfa.transition_exists(q2, 'b')) q, a = dfa.find_transition_to_q(start_state) self.assertEqual('a', a) self.assertEqual(start_state, q) q, a = dfa.find_transition_to_q(q2) self.assertEqual('a', a) self.assertEqual(q1, q)
def test_minimize_01(self): alphabet = {'0', '1'} q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') q5 = automaton.State('5') dfa = automaton.DFA(alphabet, q0) dfa.add_transition(q0, q3, '0') dfa.add_transition(q0, q1, '1') dfa.add_transition(q1, q2, '0') dfa.add_transition(q1, q5, '1') dfa.add_transition(q2, q2, '0') dfa.add_transition(q2, q5, '1') dfa.add_transition(q3, q4, '1') dfa.add_transition(q3, q0, '0') dfa.add_transition(q4, q2, '0') dfa.add_transition(q4, q5, '1') dfa.add_transition(q5, q5, '0') dfa.add_transition(q5, q5, '1') dfa.accept_states.update({q1, q2, q4}) minimized_dfa = dfa.minimize() self.assertEqual(3, len(minimized_dfa.states)) self.assertEqual(1, len(minimized_dfa.accept_states))
def test_active_lstar_08(self): """ try to let L* learn the regular language A. A is a regular language over the alphabet {0, 1} where each string contains an even number of 0's and an even number of 1's. """ q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q1) expected_dfa.add_transition(q1, q2, 'b') expected_dfa.add_transition(q1, q4, 'a') expected_dfa.add_transition(q2, q1, 'b') expected_dfa.add_transition(q2, q3, 'a') expected_dfa.add_transition(q3, q2, 'a') expected_dfa.add_transition(q3, q4, 'b') expected_dfa.add_transition(q4, q3, 'b') expected_dfa.add_transition(q4, q1, 'a') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a', 'b'}, teacher) dfa = lstar.learn() self.assertTrue(expected_dfa, dfa)
def _build_automaton(self, ot: utils.ObservationTable) -> automaton.DFA: """ Builds an automaton from the observation table. :type ot: ObservationTable :return: Automaton built from the observation table :rtype: Automaton """ dfa = automaton.DFA(self._alphabet) states = {automaton.State(i) for i in self._red} we = utils.break_strings_in_two(self._red) for w, e in we: we = w + e if we in self._red and ot.entry_exists(w, e): val = ot.get(w, e) state = automaton.State(we) if val == 1: dfa.accept_states.add(state) states.add(state) elif val == 0: dfa.reject_states.add(state) states.add(state) for w in states: for a in self._alphabet: for u in self._red: wa = w.name + a if ot.row_exists(u) and ot.row_exists(wa) and \ ot.get_row(u) == ot.get_row(wa): dfa.add_transition(w, automaton.State(u), a) return dfa
def test_active_lstar_01(self): q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q0, q2, 'b') expected_dfa.add_transition(q1, q3, 'a') expected_dfa.add_transition(q1, q4, 'b') expected_dfa.add_transition(q2, q3, 'a') expected_dfa.add_transition(q2, q3, 'b') expected_dfa.add_transition(q4, q2, 'a') expected_dfa.add_transition(q4, q3, 'b') expected_dfa.add_transition(q3, q3, 'a') expected_dfa.add_transition(q3, q3, 'b') expected_dfa.accept_states.update({q0, q1, q2, q4}) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a', 'b'}, teacher) dfa = lstar.learn()
def test_active_lstar_09(self): """ try to let L* learn the regular language L. L is a regular language over the alphabet {a, b, c} where every string in L is an even length. """ q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'a', 'b', 'c'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q0, q1, 'b') expected_dfa.add_transition(q0, q1, 'c') expected_dfa.add_transition(q1, q0, 'a') expected_dfa.add_transition(q1, q0, 'b') expected_dfa.add_transition(q1, q0, 'c') expected_dfa.accept_states.add(q0) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a', 'b', 'c'}, teacher) dfa = lstar.learn() self.assertEqual(expected_dfa, dfa.rename_states())
def test_active_lstar_06(self): """ try to let L* learn the regular language A. A is a regular language over the alphabet {0, 1} where each string contains an odd number of 1s """ q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'0', '1'}, start_state=q0) expected_dfa.add_transition(q0, q0, '0') expected_dfa.add_transition(q0, q1, '1') expected_dfa.add_transition(q1, q1, '0') expected_dfa.add_transition(q1, q0, '1') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'0', '1'}, teacher) dfa = lstar.learn() s_plus = set() s_minus = {''} for i in self._combinations({'0', '1'}, 7): if i.count('1') % 2 == 1: s_plus.add(i) else: s_minus.add(i) for s in s_plus: self.assertTrue(dfa.parse_string(s)[1]) for s in s_minus: self.assertFalse(dfa.parse_string(s)[1])
def test_active_nlstar_05(self): """ Try to let NL* learn the regular language A. A is a language over the alphabet sigma = {a}, that accepts all strings with an odd number of a's. """ q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'a'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q1, q0, 'a') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) nlstar = algorithms.NLSTAR({'a'}, teacher) nfa = nlstar.learn() self.assertEqual(2, len(nfa._states)) self.assertEqual(1, len(nfa._accept_states)) self.assertEqual(expected_dfa, nfa.to_dfa())
def test_active_lstar_10(self): """ try to let L* learn the regular language L. L is a regular language over the alphabet {a, b} where for every string in L, we have the following property, the characters at an even position should be a, the characters at an odd position can be a or b. The empty string is not accepted by the language. """ q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q0, q1, 'b') expected_dfa.add_transition(q1, q2, 'b') expected_dfa.add_transition(q1, q3, 'a') expected_dfa.add_transition(q2, q2, 'a') expected_dfa.add_transition(q2, q2, 'b') expected_dfa.add_transition(q3, q1, 'a') expected_dfa.add_transition(q3, q1, 'b') expected_dfa.accept_states.update({q1, q3}) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a', 'b'}, teacher) dfa = lstar.learn() s_plus = set() s_minus = set() for i in self._combinations({'a', 'b'}, 8): if i == '': s_minus.add(i) continue cpy = list(i[:]) for idx in range(len(i)): if idx % 2 == 1: cpy[idx] = 'a' s_plus.add(''.join(cpy)) if all([i[q] == 'a' for q in range(1, len(i), 2)]): s_plus.add(i) else: s_minus.add(i) for s in s_plus: self.assertTrue(dfa.parse_string(s)[1]) for s in s_minus: self.assertFalse(dfa.parse_string(s)[1])
def test_dfa_01(self): dfa = automaton.DFA({'a', 'b'}) self.assertTrue(automaton.State('') in dfa.states) dfa.add_transition(automaton.State(''), automaton.State('a'), 'a') self.assertTrue(dfa.transition_exists(automaton.State(''), 'a')) self.assertEqual(automaton.State('a'), dfa.transition(automaton.State(''), 'a')) try: dfa.add_transition(automaton.State(''), automaton.State('a'), 'c') self.fail('Automaton should throw ValueError when trying to add' 'transition with letter that is not in the alphabet!') except ValueError: self.assertTrue(True)
def test_active_lstar_02(self): q0 = automaton.State('0') expected_dfa = automaton.DFA({'a'}, start_state=q0) expected_dfa.add_transition(q0, q0, 'a') expected_dfa.accept_states.add(q0) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a'}, teacher) dfa = lstar.learn() self.assertEqual(1, len(dfa.states)) self.assertEqual(1, len(dfa.accept_states)) self.assertTrue(dfa.parse_string('a' * 1000)[1])
def test_active_lstar_11(self): """ try to let L* learn the regular language L. L is a regular language over the alphabet {a, b} where for every string in L contains exactly two a's. """ q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q0, 'b') expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q1, q1, 'b') expected_dfa.add_transition(q1, q2, 'a') expected_dfa.add_transition(q2, q2, 'b') expected_dfa.add_transition(q2, q3, 'a') expected_dfa.add_transition(q3, q3, 'a') expected_dfa.add_transition(q3, q3, 'b') expected_dfa.accept_states.add(q2) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a', 'b'}, teacher) dfa = lstar.learn() s_plus = set() s_minus = set() for i in self._combinations({'a', 'b'}, 11): if i.count('a') == 2: s_plus.add(i) else: s_minus.add(i) for s in s_minus: self.assertFalse(dfa.parse_string(s)[1]) self.assertEqual(expected_dfa, dfa)
def test_active_lstar_07(self): """ try to let L* learn the regular language A. A is a regular language over the alphabet {0, 1} where each string contains 101 as a substring. """ q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') expected_dfa = automaton.DFA({'0', '1'}, start_state=q1) expected_dfa.add_transition(q1, q1, '0') expected_dfa.add_transition(q1, q2, '1') expected_dfa.add_transition(q2, q2, '1') expected_dfa.add_transition(q2, q3, '0') expected_dfa.add_transition(q3, q1, '0') expected_dfa.add_transition(q3, q4, '1') expected_dfa.add_transition(q4, q4, '0') expected_dfa.add_transition(q4, q4, '1') expected_dfa.accept_states.add(q4) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'0', '1'}, teacher) dfa = lstar.learn() s_plus = set() s_minus = {''} for i in self._combinations({'0', '1'}, 10): if len(i) < 3: continue if '101' in i: s_plus.add(i) else: s_minus.add(i) for s in s_plus: self.assertTrue(dfa.parse_string(s)[1]) for s in s_minus: self.assertFalse(dfa.parse_string(s)[1])
def test_active_lstar_04(self): q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q0, q1, 'b') expected_dfa.add_transition(q1, q1, 'a') expected_dfa.add_transition(q1, q1, 'b') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a', 'b'}, teacher) dfa = lstar.learn() self.assertEqual(2, len(dfa.states)) self.assertEqual(1, len(dfa.accept_states))
def test_active_nlstar_01(self): q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q0, q2, 'b') expected_dfa.add_transition(q1, q3, 'a') expected_dfa.add_transition(q1, q4, 'b') expected_dfa.add_transition(q2, q3, 'a') expected_dfa.add_transition(q2, q3, 'b') expected_dfa.add_transition(q4, q2, 'a') expected_dfa.add_transition(q4, q3, 'b') expected_dfa.add_transition(q3, q3, 'a') expected_dfa.add_transition(q3, q3, 'b') expected_dfa.accept_states.update({q0, q1, q2, q4}) teacher = oracle.ActiveOracle(expected_dfa) nlstar = algorithms.NLSTAR({'a', 'b'}, teacher) nfa = nlstar.learn() self.assertTrue(nfa.parse_string('')[1]) self.assertTrue(nfa.parse_string('a')[1]) self.assertTrue(nfa.parse_string('ab')[1]) self.assertTrue(nfa.parse_string('aba')[1]) self.assertFalse(nfa.parse_string('aa')[1]) self.assertFalse(nfa.parse_string('abb')[1]) self.assertFalse(nfa.parse_string('ba')[1]) self.assertFalse(nfa.parse_string('bb')[1])
def test_active_lstar_03(self): """ Try to let L* learn Kleene plus. The alphabet is sigma = {a} and the language accepts every string with 1 or more a's. """ q0 = automaton.State('0') q1 = automaton.State('1') expected_dfa = automaton.DFA({'a'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q1, q1, 'a') expected_dfa.accept_states.add(q1) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'a'}, teacher) dfa = lstar.learn() self.assertEqual(2, len(dfa.states)) self.assertEqual(1, len(dfa.accept_states))
def test_active_nlstar_10(self): """ try to let NL* learn the regular language L. L is a regular language over the alphabet {a, b} where for every string in L, we have the following property, the characters at an even position should be a, the characters at an odd position can be a or b. The empty string is not accepted by the language. """ q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0) expected_dfa.add_transition(q0, q1, 'a') expected_dfa.add_transition(q0, q1, 'b') expected_dfa.add_transition(q1, q2, 'b') expected_dfa.add_transition(q1, q3, 'a') expected_dfa.add_transition(q2, q2, 'a') expected_dfa.add_transition(q2, q2, 'b') expected_dfa.add_transition(q3, q1, 'a') expected_dfa.add_transition(q3, q1, 'b') expected_dfa.accept_states.update({q1, q3}) teacher = oracle.ActiveOracle(expected_dfa) nlstar = algorithms.NLSTAR({'a', 'b'}, teacher) nfa = nlstar.learn() dfa = nfa.to_dfa() self.assertEqual(expected_dfa.rename_states(), dfa.rename_states())
def test_minimize_02(self): alphabet = {'0', '1'} qa = automaton.State('a') qb = automaton.State('b') qc = automaton.State('c') qd = automaton.State('d') qe = automaton.State('e') qf = automaton.State('f') dfa = automaton.DFA(alphabet, qa) dfa.add_transition(qa, qb, '0') dfa.add_transition(qa, qc, '1') dfa.add_transition(qb, qa, '0') dfa.add_transition(qb, qd, '1') dfa.add_transition(qc, qe, '0') dfa.add_transition(qc, qf, '1') dfa.add_transition(qd, qe, '0') dfa.add_transition(qd, qf, '1') dfa.add_transition(qe, qe, '0') dfa.add_transition(qe, qf, '1') dfa.add_transition(qf, qf, '0') dfa.add_transition(qf, qf, '1') dfa.accept_states.update({qc, qd, qe}) minimized_dfa = dfa.minimize() self.assertEqual(3, len(minimized_dfa.states)) self.assertEqual(1, len(minimized_dfa.accept_states))
def test_active_lstar_12(self): q0 = automaton.State('0') q1 = automaton.State('1') q2 = automaton.State('2') q3 = automaton.State('3') q4 = automaton.State('4') q5 = automaton.State('5') q6 = automaton.State('6') q7 = automaton.State('7') expected_dfa = automaton.DFA({'a', '1', '#'}, start_state=q0) expected_dfa.add_transition(q0, q1, '#') expected_dfa.add_transition(q0, q2, '1') expected_dfa.add_transition(q0, q3, 'a') expected_dfa.add_transition(q1, q1, '#') expected_dfa.add_transition(q1, q4, '1') expected_dfa.add_transition(q1, q5, 'a') expected_dfa.add_transition(q2, q2, '1') expected_dfa.add_transition(q2, q4, '#') expected_dfa.add_transition(q2, q6, 'a') expected_dfa.add_transition(q3, q3, 'a') expected_dfa.add_transition(q3, q5, '#') expected_dfa.add_transition(q3, q6, '1') expected_dfa.add_transition(q4, q4, '1') expected_dfa.add_transition(q4, q4, '#') expected_dfa.add_transition(q4, q7, 'a') expected_dfa.add_transition(q5, q5, '#') expected_dfa.add_transition(q5, q5, 'a') expected_dfa.add_transition(q5, q7, '1') expected_dfa.add_transition(q6, q6, '1') expected_dfa.add_transition(q6, q6, 'a') expected_dfa.add_transition(q6, q7, '#') expected_dfa.add_transition(q7, q7, '1') expected_dfa.add_transition(q7, q7, 'a') expected_dfa.add_transition(q7, q7, '#') expected_dfa.accept_states.add(q7) teacher = oracle.ActiveOracle(expected_dfa) lstar = algorithms.LSTAR({'#', '1', 'a'}, teacher) dfa = lstar.learn() self.assertEqual(8, len(dfa.states)) self.assertEqual(1, len(dfa.accept_states)) self.assertTrue(dfa.parse_string('#1a')[1]) self.assertTrue(dfa.parse_string('a#1')[1]) self.assertFalse(dfa.parse_string('#1')[1]) self.assertFalse(dfa.parse_string('a')[1]) self.assertEqual(expected_dfa, dfa)
def test_remove_dead_states_01(self): alphabet = {'a', 'b', 'c'} dfa = automaton.DFA(alphabet) dfa.add_transition(automaton.State(''), automaton.State('2'), 'a') dfa.add_transition(automaton.State(''), automaton.State('3'), 'b') dfa.add_transition(automaton.State(''), automaton.State('3'), 'c') dfa.add_transition(automaton.State('3'), automaton.State('3'), 'a') dfa.add_transition(automaton.State('3'), automaton.State('3'), 'b') dfa.add_transition(automaton.State('3'), automaton.State(''), 'c') dfa.add_transition(automaton.State('2'), automaton.State('4'), 'a') dfa.add_transition(automaton.State('2'), automaton.State('4'), 'b') dfa.add_transition(automaton.State('2'), automaton.State('4'), 'c') dfa.add_transition(automaton.State('4'), automaton.State('2'), 'a') dfa.add_transition(automaton.State('4'), automaton.State('2'), 'b') dfa.add_transition(automaton.State('4'), automaton.State('2'), 'c') dfa.add_transition(automaton.State('5'), automaton.State('4'), 'a') dfa.add_transition(automaton.State('5'), automaton.State('4'), 'b') dfa.add_transition(automaton.State('5'), automaton.State('6'), 'c') dfa.states.add(automaton.State('7')) dfa.accept_states.update({automaton.State(''), automaton.State('6')}) dfa.reject_states.update( {automaton.State('3'), automaton.State('4'), automaton.State('7')}) minimized_dfa = dfa.remove_dead_states() self.assertEqual(4, len(minimized_dfa.states)) self.assertSetEqual({automaton.State('')}, minimized_dfa.accept_states) self.assertSetEqual( {automaton.State('3'), automaton.State('4')}, minimized_dfa.reject_states) expected_transition_table = { automaton.State(''): OrderedDict({ 'a': automaton.State('2'), 'b': automaton.State('3'), 'c': automaton.State('3') }), automaton.State('3'): OrderedDict({ 'a': automaton.State('3'), 'b': automaton.State('3'), 'c': automaton.State('') }), automaton.State('2'): OrderedDict({ 'a': automaton.State('4'), 'b': automaton.State('4'), 'c': automaton.State('4') }), automaton.State('4'): OrderedDict({ 'a': automaton.State('2'), 'b': automaton.State('2'), 'c': automaton.State('2') }) } transitions = minimized_dfa._transitions self.assertSetEqual(set(map(str, expected_transition_table.keys())), set(map(str, transitions.keys()))) for k in expected_transition_table.keys(): for a in expected_transition_table[k].keys(): self.assertEqual(expected_transition_table[k][a], transitions[k][a])