예제 #1
0
 def test_epsilon(self):
     """ Generic tests for epsilon """
     eps0 = Epsilon()
     eps1 = Epsilon()
     symb = Symbol(0)
     self.assertEqual(eps0, eps1)
     self.assertNotEqual(eps0, symb)
예제 #2
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]))
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"
예제 #4
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())
예제 #5
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]))
예제 #6
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
예제 #7
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()
예제 #8
0
    def add_transitions(self, member, enter_state, exit_state):
        self.prefix += 1
        
        if member == None:
            self.add_transition(enter_state, Epsilon(), exit_state)
            return
        
        if member["type"] == "BLANK":
            self.add_transition(enter_state, Epsilon(), exit_state)

        if member["type"] == "SYMBOL":
            if member["name"][0] == "_" and member["name"] not in self.externals:
                self.add_transitions(self.node_types[member["name"]], enter_state, exit_state)
            else:
                symbol = Symbol(member["name"])
                self.add_transition(enter_state, symbol, exit_state)

        if member["type"] == "STRING":
            symbol = Symbol(member["value"])
            self.add_transition(enter_state, symbol, exit_state)
#             memb = regex_to_member(member["value"])
#             self.add_transitions(memb, enter_state, exit_state)

        if member["type"] == "PATTERN":
#             symbol = Symbol("regex:"+member["value"])
            memb = regex_to_member(member["value"])
            self.add_transitions(memb, enter_state, exit_state)
#             self.add_transition(enter_state, symbol, exit_state)

        if member["type"] in ["FIELD", "PREC","PREC_LEFT","PREC_RIGHT","ALIAS", "TOKEN"]:
            self.add_transitions(member["content"], enter_state, exit_state)

        if member["type"] == "SEQ":
            prev_state = enter_state
            for i, SEQ_member in enumerate(member["members"]):
                next_state = State(f"SEQ{self.prefix}_St_{i}")

                self.add_transitions(SEQ_member, prev_state, next_state)
                prev_state = next_state
            self.add_transition(next_state, Epsilon(), exit_state)

        if member["type"] == "CHOICE":
            for i, CHOICE_member in enumerate(member["members"]):
                choice_state = State(f"CH{self.prefix}_St_{i}")
                self.add_transitions(CHOICE_member, enter_state, choice_state)
                self.add_transition(choice_state, Epsilon(), exit_state)

        if member["type"] == "REPEAT":
            self.add_transition(enter_state, Epsilon(), exit_state)
            self.add_transition(exit_state, Epsilon(), enter_state)
            self.add_transitions(member["content"], enter_state, exit_state)

        if member["type"] == "REPEAT1":
            self.add_transition(exit_state, Epsilon(), enter_state)
            self.add_transitions(member["content"], enter_state, exit_state)        
예제 #9
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])
예제 #10
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]))
예제 #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_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))
예제 #13
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
예제 #14
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)
예제 #15
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")
예제 #16
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())
예제 #17
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
예제 #18
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"]])
예제 #19
0
 def test_invalid_epsilon(self):
     """ Tests invalid transition """
     transition_function = TransitionFunction()
     with self.assertRaises(InvalidEpsilonTransition):
         transition_function.add_transition("1", Epsilon(), "2")
 def test_epsilon_refused(self):
     dfa = NondeterministicFiniteAutomaton()
     state0 = State(0)
     state1 = State(1)
     with self.assertRaises(InvalidEpsilonTransition):
         dfa.add_transition(state0, Epsilon(), state1)