예제 #1
0
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_check_intersection():
    # Declare NFAs
    enfa0 = EpsilonNFA()
    enfa1 = EpsilonNFA()

    # Declare the states
    states = [State("q" + str(x)) for x in range(7)]

    # Declare the symbols
    epsilon = Epsilon()
    symb_a = Symbol("a")
    symb_b = Symbol("b")
    symb_c = Symbol("c")

    # epsilonNFA 0
    # Add a start state
    enfa0.add_start_state(states[0])

    # Add a final state
    enfa0.add_final_state(states[1])

    # Add the transitions
    enfa0.add_transition(states[0], symb_a, states[1])
    enfa0.add_transition(states[1], symb_a, states[1])

    # epsilonNFA 1
    # Add a start states
    enfa1.add_start_state(states[0])
    enfa1.add_final_state(states[4])

    # Add a final states
    enfa1.add_final_state(states[5])
    enfa1.add_final_state(states[6])

    # Add the transitions
    enfa1.add_transition(states[0], symb_a, states[1])
    enfa1.add_transition(states[0], symb_b, states[2])
    enfa1.add_transition(states[0], symb_c, states[3])

    enfa1.add_transition(states[1], symb_a, states[4])
    enfa1.add_transition(states[2], symb_b, states[5])
    enfa1.add_transition(states[3], symb_c, states[6])

    # Now enfa0 accepts a* \ {epsilon}
    #     enfa1 accepts aa, bb, cc

    # Intersection of enfa0 and enfa1
    enfa_res = enfa0.get_intersection(enfa1)

    # Check if a word is accepted
    assert enfa_res.accepts([symb_a, symb_a]), "Should accept aa"

    # Check non-correct words
    assert not enfa_res.accepts([epsilon]), "Accepts empty word, but it mustn't"
    assert not enfa_res.accepts([symb_a, symb_a, symb_a]), "Accepts aaa, but it mustn't"
    assert not enfa_res.accepts([symb_a]), "Accepts a, but it mustn't"
    assert not enfa_res.accepts([symb_b, symb_b]), "Accepts bb, but it mustn't"
    assert not enfa_res.accepts([symb_c, symb_c]), "Accepts cc, but it mustn't"
예제 #3
0
 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())
예제 #4
0
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
예제 #5
0
 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])
예제 #6
0
 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]))
예제 #7
0
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)
예제 #8
0
 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())
예제 #9
0
def test_enfa_intersection():
    # Building example automatons
    enfa0 = EpsilonNFA()
    state0 = State(0)
    state1 = State(1)
    state2 = State(2)
    symb_a = Symbol("a")
    symb_b = Symbol("b")
    symb_c = Symbol("c")
    enfa0.add_start_state(state0)
    enfa0.add_final_state(state2)
    enfa0.add_transition(state0, symb_a, state0)
    enfa0.add_transition(state0, symb_b, state1)
    enfa0.add_transition(state1, symb_c, state2)

    enfa1 = EpsilonNFA()
    state3 = State(3)
    state4 = State(4)
    state5 = State(5)
    enfa1.add_start_state(state3)
    enfa1.add_final_state(state5)
    enfa1.add_transition(state3, symb_a, state4)
    enfa1.add_transition(state4, symb_b, state5)
    enfa1.add_transition(state5, symb_c, state5)

    # getting intersection
    enfa = enfa0 & enfa1

    assert not enfa.accepts([symb_b])
    assert not enfa.accepts([symb_a])
    assert not enfa.accepts([])
    assert not enfa.accepts([symb_a, symb_a, symb_b, symb_c])
    assert not enfa.accepts([symb_a, symb_b, symb_c, symb_c])
    assert enfa.accepts([symb_a, symb_b, symb_c])
예제 #10
0
 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]))
예제 #11
0
 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([]))
예제 #12
0
    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()
예제 #13
0
 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)
예제 #14
0
 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
예제 #15
0
 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 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
예제 #17
0
 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")
예제 #18
0
 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)
예제 #19
0
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
예제 #20
0
 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]))
예제 #21
0
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)
예제 #22
0
 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]))
예제 #23
0
 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())
예제 #24
0
 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))
예제 #25
0
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
예제 #26
0
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()
예제 #27
0
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
예제 #28
0
    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"]])