Exemplo n.º 1
0
class TestAutomata(unittest.TestCase):

    test_unit = None
    state_name = "testState"
    transition_letter = "s"
    from_state_id = 42
    to_state_id = 91

    def setUp(self):
        unittest.TestCase.setUp(self)
        self.test_unit = Automata()

    def test_add_and_get_state(self):
        self.assertIsNone(self.test_unit.get_state(self.state_name))
        self.test_unit.add_state(self.state_name)
        state = self.test_unit.get_state(self.state_name)
        self.assertIsNotNone(state)
        self.assertIs(state.name, self.state_name)

    def test_add_initial_state(self):
        self.test_unit.add_initial_state(self.state_name)
        self.assertTrue(self.test_unit.get_state(self.state_name).initial)

    def test_add_accepting_state(self):
        self.test_unit.add_accepting_state(self.state_name)
        self.assertTrue(self.test_unit.get_state(self.state_name).accepting)

    def test_add_transition(self):
        self.assertIsNone(self.test_unit.get_transition_by_from_state_id(self.from_state_id))
        self.test_unit.add_transition(self.transition_letter, self.from_state_id, self.to_state_id)
        transition = self.test_unit.get_transition_by_from_state_id(self.from_state_id)
        self.assertIsNotNone(transition)
        self.assertIs(transition.from_state_id, self.from_state_id)
        self.assertIs(transition.to_state_id, self.to_state_id)
        self.assertIs(transition.letter, self.transition_letter)

    def test_accepts_rejects_single_char(self):
        # q0 - a -> (q1)
        self.test_unit.add_initial_state('q0')
        self.test_unit.add_accepting_state('q1')
        self.test_unit.add_transition('a', 'q0', 'q1')

        self.assertTrue(self.test_unit.accepts('a'))
        self.assertFalse(self.test_unit.accepts('b'))

    def test_accepts_rejects_three_chars(self):
        # q0 - a -> (q1)
        # (q1) - b -> q0
        self.test_unit.add_initial_state('q0')
        self.test_unit.add_accepting_state('q1')
        self.test_unit.add_transition('a', 'q0', 'q1')
        self.test_unit.add_transition('b', 'q1', 'q0')

        self.assertTrue(self.test_unit.accepts('aba'))
        self.assertFalse(self.test_unit.accepts('ab'))
Exemplo n.º 2
0
    def empty_stack(self, stack):
        merge_nfa = None

        while stack.length() < 1:
            #lo tomamos como join
            nfa2 = stack.pop()
            nfa1 = stack.pop()
            initial = nfa2.get_initial_state()
            final = nfa1.get_final_state()
            #print("INIT", initial)
            #print("FINAL", final)
            for state in nfa2.arr_states():
                #print("STATE", state)
                if (state.get_start() == initial):

                    state.set_start(final)

            for state in nfa1.arr_states():
                if (state.get_start() == final):

                    state.set_start(initial)
            merge_nfa = Automata([], [], nfa1.get_initial_state(),
                                 nfa2.get_final_state(), [])

            opsNfa2 = nfa2.arr_states()
            opsNfa1 = nfa1.arr_states()

            merged = opsNfa2 + opsNfa1

            for transition in merged:
                if (transition.get_transition() != None):
                    merge_nfa.add_state(transition)

        if not merge_nfa:
            merge_nfa = self.opStack.pop()

        self.opStack.add(merge_nfa)

        return stack
Exemplo n.º 3
0
from Automata import Automata

myAutomata = Automata()
myAutomata.add_initial_state('q0')
myAutomata.add_state('q1')
myAutomata.add_accepting_state('q2')

# q0 - a -> q1
myAutomata.add_transition('a', 'q0', 'q1')
# q1 - b -> (q2)
myAutomata.add_transition('b', 'q1', 'q2')

words = {'ab', 'ba', 'aa', 'bb'}

for word in words:
    if myAutomata.accepts(word):
        print word + " is accepted.\n"
    else:
        print word + " is not accepted.\n"
Exemplo n.º 4
0
    def evalPostfix(self, tokens):
        """
        Definimos las reglas segun: 
        https://medium.com/swlh/visualizing-thompsons-construction-algorithm-for-nfas-step-by-step-f92ef378581b 
        """

        for i in range(0, len(tokens)):

            currentToken = tokens[i]
            if currentToken.get_type() == "SYMBOL" and currentToken.get_value(
            ) == "&":
                #Regla #1:
                #0 -> {1: "&"}
                trans1 = Transition(start=self.stateCounter,
                                    transition=currentToken.get_value(),
                                    end=self.stateCounter + 1)
                self.stateCounter += 1
                #1 -> {} y es final.
                trans2 = Transition(start=self.stateCounter,
                                    transition=None,
                                    end=None)
                self.stateCounter += 1

                #estados, alfabeto, estado inicial, estado final, funcion de transicion
                au = Automata([], [], trans1.get_start(), trans2.get_start(),
                              [])
                au.add_state(trans1)
                au.add_state(trans2)
                #print(au)
                #print("DONE &")
                self.opStack.add(au)

            elif currentToken.get_type(
            ) == "SYMBOL" and currentToken.get_value() != "&":
                #Regla #2:
                #0 -> {1: "B"}
                trans1 = Transition(start=self.stateCounter,
                                    transition=currentToken.get_value(),
                                    end=self.stateCounter + 1)
                self.stateCounter += 1
                #1 -> {} y es final.
                trans2 = Transition(start=self.stateCounter,
                                    transition=None,
                                    end=None)
                self.stateCounter += 1

                #estados, alfabeto, estado inicial, estado final, funcion de transicion
                au = Automata([], [], trans1.get_start(), trans2.get_start(),
                              [])
                au.add_state(trans1)
                au.add_state(trans2)
                #print(au)
                #print("DONE SYMB")
                self.opStack.add(au)

            #sea una operacion
            elif currentToken.get_type() != "SYMBOL":

                #regla #3: OR
                if currentToken.get_type() == BuilderEnum.OR.value:
                    #sacamos del stack
                    nfa2 = self.opStack.pop()

                    nfa1 = self.opStack.pop()

                    #armado de nfa base.
                    #TRANSICIONES
                    transitionInitial1 = Transition(
                        start=self.stateCounter,
                        transition="&",
                        end=nfa1.get_initial_state())
                    transitionInitial2 = Transition(
                        start=self.stateCounter,
                        transition="&",
                        end=nfa2.get_initial_state())
                    self.stateCounter += 1
                    transitionFinal1 = Transition(start=nfa1.get_final_state(),
                                                  transition="&",
                                                  end=self.stateCounter)
                    transitionFinal2 = Transition(start=nfa2.get_final_state(),
                                                  transition="&",
                                                  end=self.stateCounter)
                    self.stateCounter += 1

                    #Sacamos todas las transiciones del elem1 y elem2
                    arr2 = nfa2.arr_states()  #array
                    arr1 = nfa1.arr_states()  #array
                    #unificamos los nfa
                    unifiedArray = arr2 + arr1
                    newTrans = [
                        transitionInitial1, transitionInitial2,
                        transitionFinal1, transitionFinal2
                    ]
                    finalTrans = unifiedArray + newTrans

                    or_nfa = Automata([], [], transitionInitial1.get_start(),
                                      transitionFinal1.get_end(), [])
                    # me devuelve un array de States.
                    for transition in finalTrans:
                        if (transition.get_transition() != None):
                            or_nfa.add_state(transition)

                    #print(or_nfa)
                    #print("DONE OR, to: \n", nfa2, "\n", nfa1 )
                    self.opStack.add(or_nfa)

                #REGLA KLEENE
                if currentToken.get_type() == BuilderEnum.KLEENE.value:
                    nfa = self.opStack.pop()

                    #encontramos estados finales e iniciales:
                    final = nfa.get_final_state()
                    initial = nfa.get_initial_state()
                    #transicion de final a inicial del nfa preexistente
                    finalMod = Transition(start=final,
                                          transition="&",
                                          end=initial)

                    #estado inicial de nfa preexistente a nuevo estado de trans
                    initialState = Transition(self.stateCounter, "&", initial)

                    self.stateCounter += 1

                    finalState = Transition(self.stateCounter, None, None)
                    initialEnd = Transition(initialState.get_start(), "&",
                                            finalState.get_start())
                    #transicion de nfa final a final de nuevo nfa
                    finalTofinal = Transition(start=final,
                                              transition="&",
                                              end=finalState.get_start())

                    self.stateCounter += 1

                    kleene_nfa = Automata([], [], initialState.get_start(),
                                          finalState.get_start(), [])
                    arr1 = nfa.arr_states()
                    unifiedArray = arr1
                    newTrans = [
                        initialState, initialEnd, finalState, finalTofinal,
                        finalMod
                    ]
                    finalTrans = unifiedArray + newTrans

                    for transition in finalTrans:
                        if (transition.get_transition() != None):
                            kleene_nfa.add_state(transition)

                    #print("DONE KLEENE to \n", nfa)
                    self.opStack.add(kleene_nfa)

                if currentToken.get_type() == BuilderEnum.PLUS.value:
                    nfa = self.opStack.pop()

                    #encontramos estados finales e iniciales:
                    final = nfa.get_final_state()
                    initial = nfa.get_initial_state()

                    target_symbol = None
                    for fn in nfa.arr_states():
                        if initial == fn.get_start():
                            target_symbol = fn.get_transition()
                            break

                    midState = Transition(self.stateCounter,
                                          transition="&",
                                          end=initial)
                    self.stateCounter += 1

                    cycle_state = Transition(self.stateCounter,
                                             transition=target_symbol,
                                             end=midState.get_start())
                    self.stateCounter += 1

                    #transicion de final a inicial del nfa preexistente
                    finalMod = Transition(start=final,
                                          transition="&",
                                          end=initial)

                    #estado inicial de nfa preexistente a nuevo estado de trans

                    finalState = Transition(self.stateCounter, None, None)
                    self.stateCounter += 1
                    initialState = Transition(midState.get_start(), "&",
                                              finalState.get_start())

                    #transicion de nfa final a final de nuevo nfa
                    finalTofinal = Transition(start=final,
                                              transition="&",
                                              end=finalState.get_start())

                    plus_nfa = Automata([], [], cycle_state.get_start(),
                                        finalState.get_start(), [])
                    arr1 = nfa.arr_states()
                    unifiedArray = arr1
                    newTrans = [
                        initialState, finalState, finalTofinal, midState,
                        cycle_state, finalMod
                    ]
                    finalTrans = unifiedArray + newTrans

                    for transition in finalTrans:
                        if (transition.get_transition() != None):
                            plus_nfa.add_state(transition)

                    #print("DONE PLUS to: \n", nfa)
                    self.opStack.add(plus_nfa)

                if currentToken.get_type() == BuilderEnum.CONCAT.value:
                    nfa2 = self.opStack.pop()
                    nfa1 = self.opStack.pop()

                    initial = nfa2.get_initial_state()
                    final = nfa1.get_final_state()
                    #print("INIT", initial)
                    #print("FINAL", final)
                    for state in nfa2.arr_states():
                        #print("STATE", state)
                        if (state.get_start() == initial):
                            state.set_start(final)

                    for state in nfa1.arr_states():
                        if (state.get_start() == final):
                            state.set_start(initial)
                    merge_nfa = Automata([], [], nfa1.get_initial_state(),
                                         nfa2.get_final_state(), [])

                    opsNfa2 = nfa2.arr_states()
                    opsNfa1 = nfa1.arr_states()

                    merged = opsNfa2 + opsNfa1

                    for transition in merged:
                        if (transition.get_transition() != None):
                            merge_nfa.add_state(transition)

                    #print(merge_nfa)
                    #print("DONE CONCAT to \n", nfa1, "\n", nfa2 )
                    self.opStack.add(merge_nfa)

        #opstack is ready to be exported
        return self.opStack