def test_minimization(self): """ Tests the minimization algorithm """ enfa = get_enfa_example0_bis() symb_a = Symbol("a") symb_b = Symbol("b") enfa = enfa.minimize() self.assertTrue(enfa.is_deterministic()) self.assertEqual(len(enfa.states), 2) self.assertTrue(enfa.accepts([symb_a, symb_b])) self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) self.assertTrue(enfa.accepts([symb_b])) self.assertFalse(enfa.accepts([symb_a])) enfa = get_example_non_minimal() enfa = enfa.minimize() self.assertTrue(enfa.is_deterministic()) self.assertEqual(len(enfa.states), 3) self.assertTrue(enfa.accepts([symb_a, symb_b])) self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) self.assertFalse(enfa.accepts([symb_b])) self.assertFalse(enfa.accepts([symb_a])) enfa = EpsilonNFA() enfa = enfa.minimize() self.assertTrue(enfa.is_deterministic()) self.assertEqual(len(enfa.states), 0) self.assertFalse(enfa.accepts([]))
def test_cyclic(self): enfa = EpsilonNFA() state0 = State(0) state1 = State(1) symb_a = Symbol('a') enfa.add_start_state(state0) enfa.add_transition(state0, symb_a, state1) enfa.add_transition(state1, Epsilon(), state0) self.assertFalse(enfa.is_acyclic())
def test_complement(self): """ Tests the complement operation """ enfa = EpsilonNFA() state0 = State(0) state1 = State(1) state2 = State(2) symb_a = Symbol("a") enfa.add_start_state(state0) enfa.add_final_state(state2) enfa.add_transition(state0, Epsilon(), state1) enfa.add_transition(state1, symb_a, state2) enfa_comp = -enfa self.assertFalse(enfa_comp.accepts([symb_a]))
def test_iter(self): enfa = EpsilonNFA() state0 = State("0") state1 = State(1) symb_a = Symbol('a') enfa.add_start_state(state0) enfa.add_final_state(state1) enfa.add_transition(state0, symb_a, state1) enfa.add_transition(state1, Epsilon(), state0) counter = 0 for s_from, symb, s_to in enfa: counter += 1 self.assertIn((s_from, symb, s_to), enfa) self.assertNotIn((state1, symb_a, state1), enfa) self.assertIn(("0", "a", 1), enfa) self.assertEqual(counter, 2)
def get_enfa_example1(): """ Gives and example ENFA Accepts c """ enfa1 = EpsilonNFA() state2 = State(2) state3 = State(3) symb_c = Symbol("c") enfa1.add_start_state(state2) enfa1.add_final_state(state3) enfa1.add_transition(state2, symb_c, state3) return enfa1
def __init__(self, epsilon_nfa: EpsilonNFA): edges = [] dfa = epsilon_nfa.to_deterministic() state_to_idx = dict([(state, index) for index, state in enumerate(dfa.states)]) for state_from, transitions in epsilon_nfa.to_deterministic().to_dict( ).items(): for label, state_to in transitions.items(): edges.append( Edge(node_from=state_to_idx[state_from], node_to=state_to_idx[state_to], label=label)) self.dfa = dfa self.dfa_state_to_idx = state_to_idx start_states = [ self.dfa_state_to_idx[state] for state in self.dfa.start_states ] final_states = [ self.dfa_state_to_idx[state] for state in self.dfa.final_states ] super().__init__(edges, set(start_states), set(final_states))
def from_networkx(cls, graph): # TODO We lose the type of the node value if going through a dot file from pyformlang.finite_automaton import EpsilonNFA enfa = EpsilonNFA() for s_from in graph: for s_to in graph[s_from]: for transition in graph[s_from][s_to].values(): if "label" in transition: enfa.add_transition(s_from, transition["label"], s_to) for node in graph.nodes: if graph.nodes[node].get("is_start", False): enfa.add_start_state(node) if graph.nodes[node].get("is_final", False): enfa.add_final_state(node) return enfa
def to_automaton(self): nfa = EpsilonNFA() matrices = self.adj_matrices for start_state in self.start_states: nfa.add_start_state(State(start_state)) for final_state in self.final_states: nfa.add_final_state(State(final_state)) for word in matrices.keys(): matrix = matrices[word] symb = Symbol(word) for row, col in zip(matrix.rows, matrix.cols): nfa.add_transition(State(row), symb, State(col)) return nfa
def test_difference(self): """ Tests the intersection of two languages """ enfa0 = get_enfa_example0() enfa1 = get_enfa_example1() symb_a = Symbol("a") symb_b = Symbol("b") symb_c = Symbol("c") enfa = enfa0 - enfa1 self.assertTrue(enfa.accepts([symb_a, symb_b])) self.assertTrue(enfa.accepts([symb_b])) self.assertFalse(enfa.accepts([symb_c])) self.assertFalse(enfa.accepts([])) enfa2 = EpsilonNFA() state0 = State(0) enfa2.add_start_state(state0) enfa2.add_final_state(state0) enfa2.add_transition(state0, symb_b, state0) enfa = enfa0.get_difference(enfa2) self.assertTrue(enfa.accepts([symb_a, symb_b])) self.assertFalse(enfa.accepts([symb_b])) self.assertFalse(enfa.accepts([symb_c]))
def test_non_equivalent(self): enfa0 = EpsilonNFA() state0 = State("0") state1 = State(1) symb_a = Symbol('a') enfa0.add_start_state(state0) enfa0.add_final_state(state1) enfa0.add_transition(state0, symb_a, state1) enfa0.add_transition(state1, Epsilon(), state0) enfa1 = EpsilonNFA() enfa1.add_start_state(state0) enfa1.add_final_state(state1) enfa1.add_transition(state0, symb_a, state1) enfa1.add_transition(state1, symb_a, state0) self.assertFalse(enfa0.is_equivalent_to(enfa1))
def test_get_as_dict(self): enfa0 = EpsilonNFA() state0 = State("0") state1 = State(1) symb_a = Symbol('a') enfa0.add_start_state(state0) enfa0.add_final_state(state1) enfa0.add_transition(state0, symb_a, state1) enfa0.add_transition(state1, Epsilon(), state0) d_enfa = enfa0.to_dict() self.assertIn(state0, d_enfa) self.assertIn(symb_a, d_enfa[state0]) self.assertIn(state1, d_enfa[state0][symb_a])
def test_import_networkx(self): enfa = EpsilonNFA() state0 = State("0") state1 = State(1) symb_a = Symbol('a') enfa.add_start_state(state0) enfa.add_final_state(state1) enfa.add_transition(state0, symb_a, state1) enfa.add_transition(state1, Epsilon(), state0) graph = enfa.to_networkx() enfa_from_nx = EpsilonNFA.from_networkx(graph) self.assertTrue(enfa_from_nx.accepts([symb_a])) self.assertTrue(enfa_from_nx.accepts([symb_a, symb_a])) self.assertFalse(enfa_from_nx.accepts([]))
def test_example_doc(self): enfa = EpsilonNFA() state0 = State(0) state1 = State(1) symb_a = Symbol("0") symb_b = Symbol("1") enfa.add_start_state(state0) enfa.add_final_state(state1) enfa.add_transition(state0, symb_a, state0) enfa.add_transition(state1, symb_b, state0) enfa.add_transition(state1, symb_b, state1) # Turn a finite automaton into a regex... regex = enfa.to_regex() # And turn it back into an epsilon non deterministic automaton enfa2 = regex.to_epsilon_nfa()
def test_automata_intersection(): states = [State(str(i)) for i in range(4)] symb_a = Symbol('a') symb_b = Symbol('b') symb_c = Symbol('c') enfa_1 = EpsilonNFA() enfa_1.add_start_state(states[0]) enfa_1.add_transitions([ (states[0], symb_a, states[1]), (states[1], symb_b, states[2]), (states[2], symb_c, states[0]) ]) enfa_1.add_final_state(states[0]) enfa_2 = EpsilonNFA() enfa_2.add_start_state(states[0]) enfa_2.add_transitions([ (states[0], symb_a, states[1]), (states[1], symb_b, states[1]), (states[1], symb_c, states[2]) ]) enfa_2.add_final_state(states[2]) result = enfa_1 & enfa_2 expected = EpsilonNFA() expected.add_start_state(states[0]) expected.add_transitions([ (states[0], symb_a, states[1]), (states[1], symb_b, states[2]), (states[2], symb_c, states[3]) ]) expected.add_final_state(states[3]) assert result.is_equivalent_to(expected)
def test_export_networkx(self): enfa = EpsilonNFA() state0 = State("0") state1 = State(1) symb_a = Symbol('a') enfa.add_start_state(state0) enfa.add_final_state(state1) enfa.add_transition(state0, symb_a, state1) enfa.add_transition(state1, Epsilon(), state0) graph = enfa.to_networkx() self.assertTrue(isinstance(graph, networkx.MultiDiGraph)) self.assertTrue("0" in graph) self.assertTrue(("0", 1) in graph.edges) self.assertIn("a", [x["label"] for x in graph["0"][1].values()]) self.assertTrue(graph.nodes["0"]["is_start"]) self.assertFalse(graph.nodes["0"]["is_final"]) self.assertFalse(graph.nodes[1]["is_start"]) self.assertTrue(graph.nodes[1]["is_final"]) enfa.write_as_dot("enfa.dot")
def test_intersection(): state0 = State(0) state1 = State(1) state2 = State(2) symbol_a = Symbol("a") symbol_b = Symbol("b") symbol_c = Symbol("c") dfa0 = EpsilonNFA() dfa0.add_start_state(state0) dfa0.add_final_state(state2) dfa0.add_transition(state0, symbol_a, state1) dfa0.add_transition(state1, symbol_b, state1) dfa0.add_transition(state1, symbol_c, state2) dfa1 = EpsilonNFA() dfa1.add_start_state(state0) dfa1.add_final_state(state2) dfa1.add_transition(state0, symbol_a, state1) dfa1.add_transition(state1, symbol_b, state2) dfa1.add_transition(state1, symbol_c, state2) res = dfa0 & dfa1 check_correctness(res)
def test_to_fst(self): """ Tests to turn a ENFA into a FST """ enfa = EpsilonNFA() fst = enfa.to_fst() self.assertEqual(len(fst.states), 0) self.assertEqual(len(fst.final_states), 0) self.assertEqual(len(fst.start_states), 0) self.assertEqual(len(fst.input_symbols), 0) self.assertEqual(len(fst.output_symbols), 0) self.assertEqual(fst.get_number_transitions(), 0) state0 = State("q0") s0bis = State("q0bis") enfa.add_start_state(state0) enfa.add_start_state(s0bis) fst = enfa.to_fst() self.assertEqual(len(fst.states), 2) self.assertEqual(len(fst.final_states), 0) self.assertEqual(len(fst.start_states), 2) self.assertEqual(len(fst.input_symbols), 0) self.assertEqual(len(fst.output_symbols), 0) self.assertEqual(fst.get_number_transitions(), 0) sfinal = State("qfinal") sfinalbis = State("qfinalbis") enfa.add_final_state(sfinal) enfa.add_final_state(sfinalbis) fst = enfa.to_fst() self.assertEqual(len(fst.states), 4) self.assertEqual(len(fst.final_states), 2) self.assertEqual(len(fst.start_states), 2) self.assertEqual(len(fst.input_symbols), 0) self.assertEqual(len(fst.output_symbols), 0) self.assertEqual(fst.get_number_transitions(), 0) enfa.add_transition(state0, Symbol("a"), sfinal) enfa.add_transition(sfinal, Symbol("b"), sfinal) enfa.add_transition(state0, Symbol("c"), sfinalbis) fst = enfa.to_fst() self.assertEqual(len(fst.states), 4) self.assertEqual(len(fst.final_states), 2) self.assertEqual(len(fst.start_states), 2) self.assertEqual(len(fst.input_symbols), 3) self.assertEqual(len(fst.output_symbols), 3) self.assertEqual(fst.get_number_transitions(), 3) enfa.add_transition(state0, Epsilon(), sfinalbis) fst = enfa.to_fst() self.assertEqual(len(fst.states), 4) self.assertEqual(len(fst.final_states), 2) self.assertEqual(len(fst.start_states), 2) self.assertEqual(len(fst.input_symbols), 3) self.assertEqual(len(fst.output_symbols), 3) self.assertEqual(fst.get_number_transitions(), 4) trans0 = list(fst.translate(["a"])) self.assertEqual(trans0, [["a"]]) trans0 = list(fst.translate(["a", "b", "b"])) self.assertEqual(trans0, [["a", "b", "b"]]) trans0 = list(fst.translate(["b", "b"])) self.assertEqual(trans0, []) trans0 = list(fst.translate(["c"])) self.assertEqual(trans0, [["c"]])
def get_example_non_minimal(): """ A non minimal example a.a*.b""" enfa0 = EpsilonNFA() state0 = State(0) state3 = State(3) state4 = State(4) state5 = State(5) state6 = State(6) state1 = State(1) state2 = State(2) symb_a = Symbol("a") symb_b = Symbol("b") enfa0.add_start_state(state0) enfa0.add_final_state(state3) enfa0.add_final_state(state4) enfa0.add_transition(state0, symb_a, state1) enfa0.add_transition(state1, symb_a, state2) enfa0.add_transition(state2, symb_a, state5) enfa0.add_transition(state5, symb_a, state6) enfa0.add_transition(state6, symb_a, state1) enfa0.add_transition(state1, symb_b, state3) enfa0.add_transition(state2, symb_b, state4) enfa0.add_transition(state5, symb_b, state3) enfa0.add_transition(state6, symb_b, state4) return enfa0
def test_pda_intersection(): q0 = State("q0") q1 = State("q1") q2 = State("q2") q3 = State("q3") a = Symbol("a") b = Symbol("b") c = Symbol("c") epsilon_nfa_1 = EpsilonNFA(states={q0, q1, q2}, input_symbols={a, b}, start_state={q0}, final_states={q1, q2}) epsilon_nfa_1.add_transition(q0, a, q1) epsilon_nfa_1.add_transition(q1, b, q2) epsilon_nfa_2 = EpsilonNFA(states={q0, q1, q3}, input_symbols={a, c}, start_state={q0}, final_states={q1, q3}) epsilon_nfa_2.add_transition(q0, a, q1) epsilon_nfa_2.add_transition(q1, c, q3) expected_epsilon_nfa = EpsilonNFA(states={q0, q1}, input_symbols={a}, start_state={q0}, final_states={q1}) expected_epsilon_nfa.add_transition(q0, a, q1) actual_intersection = epsilon_nfa_1.get_intersection(epsilon_nfa_2) assert expected_epsilon_nfa.is_equivalent_to(actual_intersection)
def check_correctness(res: EpsilonNFA): assert res.accepts("ac"), "Word ac should be accepted" assert not res.accepts("ab"), "Word ab shouldn't be accepted" assert not res.accepts("abc"), "Word abc shouldn't be accepted"
def get_digits_enfa(): """ An epsilon NFA to recognize digits """ epsilon = Epsilon() plus = Symbol("+") minus = Symbol("-") point = Symbol(".") digits = [Symbol(x) for x in range(10)] states = [State("q" + str(x)) for x in range(6)] enfa = EpsilonNFA() enfa.add_start_state(states[0]) enfa.add_final_state(states[5]) enfa.add_transition(states[0], epsilon, states[1]) enfa.add_transition(states[0], plus, states[1]) enfa.add_transition(states[0], minus, states[1]) for digit in digits: enfa.add_transitions([(states[1], digit, states[1]), (states[1], digit, states[4]), (states[2], digit, states[3]), (states[3], digit, states[3])]) enfa.add_transitions([(states[1], point, states[2]), (states[4], point, states[3]), (states[3], epsilon, states[5])]) return enfa, digits, epsilon, plus, minus, point
def test_to_regex3(self): """ Tests the transformation to regex """ enfa = EpsilonNFA() state0 = State(0) state1 = State(1) symb_a = Symbol("0") symb_b = Symbol("1") enfa.add_start_state(state0) enfa.add_final_state(state1) enfa.add_transition(state0, symb_a, state0) enfa.add_transition(state1, symb_b, state0) enfa.add_transition(state1, symb_b, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() self.assertFalse(enfa2.accepts([symb_a])) self.assertFalse(enfa2.accepts([symb_a, symb_a])) self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b])) self.assertFalse( enfa2.accepts([symb_a, symb_a, symb_b, symb_b, symb_a])) self.assertFalse( enfa2.accepts([symb_a, symb_a, symb_b, symb_b, symb_a, symb_b])) self.assertFalse(enfa2.accepts([symb_b])) epsilon = Epsilon() enfa.add_transition(state0, epsilon, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() self.assertTrue(enfa.accepts([])) self.assertTrue(enfa.accepts([symb_a])) self.assertTrue(enfa2.accepts([symb_a])) self.assertTrue(enfa2.accepts([symb_a, symb_a])) self.assertTrue(enfa2.accepts([symb_a, symb_a, symb_b, symb_b])) self.assertTrue( enfa2.accepts([symb_a, symb_a, symb_b, symb_b, symb_a, symb_b])) self.assertTrue(enfa2.accepts([symb_b])) self.assertTrue(enfa2.accepts([])) enfa.remove_transition(state0, symb_a, state0) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() self.assertFalse(enfa2.accepts([symb_a])) self.assertFalse(enfa2.accepts([symb_a, symb_a])) self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b])) self.assertFalse( enfa2.accepts([symb_a, symb_a, symb_b, symb_b, symb_a])) self.assertFalse( enfa2.accepts([symb_a, symb_a, symb_b, symb_b, symb_a, symb_b])) self.assertTrue(enfa2.accepts([symb_b])) self.assertTrue(enfa2.accepts([])) enfa.remove_transition(state1, symb_b, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() self.assertTrue(enfa2.accepts([symb_b, symb_b])) enfa.add_transition(state0, symb_a, state0) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() self.assertTrue(enfa2.accepts([symb_a, symb_b]))
def test_eclose(self): """ Test of the epsilon closure """ states = [State(x) for x in range(8)] epsilon = Epsilon() symb_a = Symbol("a") symb_b = Symbol("b") enfa = EpsilonNFA() enfa.add_transition(states[1], epsilon, states[2]) enfa.add_transition(states[1], epsilon, states[4]) enfa.add_transition(states[2], epsilon, states[3]) enfa.add_transition(states[3], epsilon, states[6]) enfa.add_transition(states[5], epsilon, states[7]) enfa.add_transition(states[4], symb_a, states[5]) enfa.add_transition(states[5], symb_b, states[6]) self.assertEqual(len(enfa.eclose(states[1])), 5) self.assertEqual(len(enfa.eclose(states[2])), 3) self.assertEqual(len(enfa.eclose(states[5])), 2) self.assertEqual(len(enfa.eclose(states[6])), 1) self.assertEqual(len(list(enfa._transition_function.get_edges())), 7) self.assertEqual(enfa.remove_transition(states[1], epsilon, states[4]), 1) self.assertFalse(enfa.is_deterministic())
def test_to_regex(self): """ Tests the transformation to regex """ enfa = EpsilonNFA() state0 = State(0) state1 = State(1) state2 = State(2) symb_e = Symbol("e") symb_f = Symbol("f") symb_g = Symbol("g") enfa.add_start_state(state0) enfa.add_final_state(state2) enfa.add_transition(state0, symb_e, state1) enfa.add_transition(state1, symb_f, state2) enfa.add_transition(state0, symb_g, state2) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() self.assertTrue(enfa2.accepts([symb_e, symb_f])) self.assertTrue(enfa2.accepts([symb_g])) self.assertFalse(enfa2.accepts([])) self.assertFalse(enfa2.accepts([symb_e])) self.assertFalse(enfa2.accepts([symb_f])) enfa.add_final_state(state0) with self.assertRaises(ValueError) as _: enfa.get_regex_simple() regex = enfa.to_regex() enfa3 = regex.to_epsilon_nfa() self.assertTrue(enfa3.accepts([symb_e, symb_f])) self.assertTrue(enfa3.accepts([symb_g])) self.assertTrue(enfa3.accepts([])) self.assertFalse(enfa3.accepts([symb_e])) self.assertFalse(enfa3.accepts([symb_f])) enfa.remove_start_state(state0) regex = enfa.to_regex() enfa3 = regex.to_epsilon_nfa() self.assertFalse(enfa3.accepts([symb_e, symb_f])) self.assertFalse(enfa3.accepts([symb_g])) self.assertFalse(enfa3.accepts([])) self.assertFalse(enfa3.accepts([symb_e])) self.assertFalse(enfa3.accepts([symb_f])) enfa.add_start_state(state0) enfa.add_transition(state0, symb_f, state0) regex = enfa.to_regex() enfa3 = regex.to_epsilon_nfa() self.assertTrue(enfa3.accepts([symb_e, symb_f])) self.assertTrue(enfa3.accepts([symb_f, symb_e, symb_f])) self.assertTrue(enfa3.accepts([symb_g])) self.assertTrue(enfa3.accepts([symb_f, symb_f, symb_g])) self.assertTrue(enfa3.accepts([])) self.assertFalse(enfa3.accepts([symb_e])) self.assertTrue(enfa3.accepts([symb_f]))
def get_enfa_example0(): """ Gives an example ENFA Accepts a*b """ enfa0 = EpsilonNFA() state0 = State(0) state1 = State(1) state2 = State(2) symb_a = Symbol("a") symb_b = Symbol("b") enfa0.add_start_state(state0) enfa0.add_final_state(state2) enfa0.add_transition(state0, symb_a, state0) enfa0.add_transition(state0, Epsilon(), state1) enfa0.add_transition(state1, symb_b, state2) return enfa0
def test_intersection(self): """ Tests the intersection of two enfas """ enfa0 = get_enfa_example0() symb_a = Symbol("a") symb_b = Symbol("b") eps = Epsilon() enfa1 = EpsilonNFA() state0 = State(10) state1 = State(11) state2 = State(12) state3 = State(13) state4 = State(14) enfa1.add_start_state(state0) enfa1.add_final_state(state3) enfa1.add_final_state(state4) enfa1.add_transition(state0, eps, state1) enfa1.add_transition(state1, symb_a, state2) enfa1.add_transition(state2, eps, state3) enfa1.add_transition(state3, symb_b, state4) enfa = enfa0 & enfa1 self.assertEqual(len(enfa.start_states), 4) self.assertEqual(len(enfa.final_states), 2) self.assertEqual(len(enfa.symbols), 2) self.assertTrue(enfa.accepts([symb_a, symb_b])) self.assertFalse(enfa.accepts([symb_b])) self.assertFalse(enfa.accepts([symb_a])) self.assertFalse(enfa.accepts([])) self.assertFalse(enfa.accepts([symb_a, symb_a, symb_b]))
def get_enfa_example0_bis(): """ A non minimal NFA, equivalent to example0 """ enfa0 = EpsilonNFA() state3 = State(3) state4 = State(4) state0 = State(0) state1 = State(1) state2 = State(2) symb_a = Symbol("a") symb_b = Symbol("b") enfa0.add_start_state(state0) enfa0.add_final_state(state2) enfa0.add_final_state(state4) enfa0.add_transition(state0, symb_a, state0) enfa0.add_transition(state0, Epsilon(), state1) enfa0.add_transition(state1, symb_b, state2) # New part enfa0.add_transition(state0, Epsilon(), state3) enfa0.add_transition(state3, symb_a, state3) enfa0.add_transition(state3, symb_b, state4) return enfa0
def test_empty(self): """ Tests the emptiness of a finite automaton """ self.assertTrue(get_enfa_example0()) self.assertFalse(get_enfa_example1().is_empty()) enfa = EpsilonNFA() state0 = State(0) enfa.add_start_state(state0) self.assertTrue(enfa.is_empty()) state1 = State(1) symb_a = Symbol('a') enfa.add_transition(state0, symb_a, state1) self.assertTrue(enfa.is_empty()) enfa.add_final_state(state1) self.assertFalse(enfa.is_empty())
def test_remove_state(self): " Tests the remove of state " "" enfa = EpsilonNFA() state0 = State(0) state1 = State(1) state2 = State(2) symb02 = Symbol("a+b") symb01 = Symbol("c*") symb11 = Symbol("b+(c.d)") symb12 = Symbol("a.b.c") enfa.add_start_state(state0) enfa.add_final_state(state2) enfa.add_transition(state0, symb01, state1) enfa.add_transition(state0, symb02, state2) enfa.add_transition(state1, symb11, state1) enfa.add_transition(state1, symb12, state2) enfa.remove_all_basic_states() self.assertEqual(enfa.get_number_transitions(), 1) self.assertEqual(len(enfa.states), 2)
def graph_to_dfa(g: Graph): nfa = EpsilonNFA() state_count = 0 for tup in g: sub, pred, obj = map(str, tup) # nfa.add_transition(State(sub), Symbol(pred), State(obj)) nfa.add_start_state(State(sub)) nfa.add_start_state(State(obj)) nfa.add_final_state(State(sub)) nfa.add_final_state(State(obj)) nfa.add_transition(State(sub), Epsilon(), State(state_count)) for c in pred: nfa.add_transition(State(state_count), Symbol(c), State(state_count+1)) state_count += 1 nfa.add_transition(State(state_count), Epsilon(), State(obj)) return nfa.to_deterministic()