示例#1
0
 def dot_construct(automata_1, automata_2):
     [automata_1, m1] = automata_1.copy(1)
     [automata_2, m2] = automata_2.copy(m1)
     state1 = 1
     state2 = m2 - 1
     dot = Automata()
     dot.set_start_state(state1)
     dot.add_final_states(state2)
     dot.add_transition(automata_1.final_states[0], automata_2.start_state,
                        Automata.empty())
     dot.add_transitions(automata_1.transitions)
     dot.add_transitions(automata_2.transitions)
     return dot
示例#2
0
 def star_construct(automata_1):
     [automata_1, m1] = automata_1.copy(2)
     state1 = 1
     state2 = m1
     star = Automata()
     star.set_start_state(state1)
     star.add_final_states(state2)
     star.add_transition(star.start_state, automata_1.start_state,
                         Automata.empty())
     star.add_transition(star.start_state, star.final_states[0],
                         Automata.empty())
     star.add_transition(automata_1.final_states[0], star.final_states[0],
                         Automata.empty())
     star.add_transition(automata_1.final_states[0], automata_1.start_state,
                         Automata.empty())
     star.add_transitions(automata_1.transitions)
     return star
示例#3
0
 def plus_construct(automata_1, automata_2):
     [automata_1, m1] = automata_1.copy(2)
     [automata_2, m2] = automata_2.copy(m1)
     state1 = 1
     state2 = m2
     plus = Automata()
     plus.set_start_state(state1)
     plus.add_final_states(state2)
     plus.add_transition(plus.start_state, automata_1.start_state,
                         Automata.empty())
     plus.add_transition(plus.start_state, automata_2.start_state,
                         Automata.empty())
     plus.add_transition(automata_1.final_states[0], plus.final_states[0],
                         Automata.empty())
     plus.add_transition(automata_2.final_states[0], plus.final_states[0],
                         Automata.empty())
     plus.add_transitions(automata_1.transitions)
     plus.add_transitions(automata_2.transitions)
     return plus
示例#4
0
 def basic_structure(alphabet):
     fa = Automata()
     fa.set_start_state(1)
     fa.add_final_states(2)
     fa.add_transition(1, 2, alphabet)
     return fa
    def construct(self, nfa):
        nfa = self.remove_empty(nfa)
        nfa = self.completion(nfa)

        if self.check_deterministic(nfa):
            return nfa

        q = []
        dfa = Automata(alphabets=nfa.alphabets)
        dfa.set_start_state(nfa.start_state)

        nfa_transitions = dict()
        dfa_transitions = dict()

        for from_state, to_states in nfa.transitions.items():
            for to_state, trans in nfa.transitions[from_state].items():
                transition_symbol = list(trans)[0]
                if (from_state, transition_symbol) not in nfa_transitions:
                    nfa_transitions[(from_state,
                                     transition_symbol)] = [to_state]
                else:
                    nfa_transitions[(from_state,
                                     transition_symbol)].append(to_state)

        q.append((0, ))

        for dfa_state in q:
            for alphabet in nfa.alphabets:
                if len(dfa_state) == 1 and (dfa_state[0],
                                            alphabet) in nfa_transitions:
                    dfa_transitions[(dfa_state, alphabet)] = nfa_transitions[(
                        dfa_state[0], alphabet)]
                    q_new = dfa_transitions[(dfa_state, alphabet)]
                    if tuple(q_new) not in q:
                        q.append(tuple(q_new))
                else:
                    destinations = []
                    final_destination = []

                    for nfa_state in dfa_state:
                        if (nfa_state, alphabet
                            ) in nfa_transitions and nfa_transitions[(
                                nfa_state, alphabet)] not in destinations:
                            destinations.append(nfa_transitions[(nfa_state,
                                                                 alphabet)])

                    if not destinations:
                        final_destination.append(None)
                    else:
                        for destination in destinations:
                            for value in destination:
                                if value not in final_destination:
                                    final_destination.append(value)

                    dfa_transitions[(dfa_state, alphabet)] = final_destination

                    if tuple(final_destination) not in q:
                        q.append(tuple(final_destination))

        for key in dfa_transitions:
            dfa.add_transition(q.index(tuple(key[0])),
                               q.index(tuple(dfa_transitions[key])), key[1])

        for q_state in q:
            for nfa_final_state in nfa.final_states:
                if nfa_final_state in q_state:
                    dfa.add_final_states(q.index(q_state))

        return dfa
    def remove_empty(self, nfa):
        #generate states
        new_states = []
        for state in nfa.states:
            state_group = nfa.get_empty_by_state(state)
            inclusion = False
            for new_state in new_states:
                if state_group & new_state[1] == state_group:
                    inclusion = True
                    break
            if not inclusion:
                new_states.append((state, state_group))

        #generate transitions
        transitions = []
        for state in new_states:
            original_state = state[0]
            new_state = state[1]
            for state_ in new_states:
                if state_ != state:
                    for s in state_[1]:
                        if s in nfa.transitions and original_state in nfa.transitions[
                                s]:
                            alphabet = deepcopy(
                                nfa.transitions[s][original_state])
                            if len(alphabet) > 0:
                                alphabet = alphabet.pop()
                                if alphabet != Automata.empty():
                                    transitions.append(
                                        (state_[1], alphabet, new_state))

        #generate loop transitions
        for state in new_states:
            new_state = state[1]
            for state_ in new_state:
                for s in new_state:
                    if state_ in nfa.transitions and s in nfa.transitions[
                            state_]:

                        alphabet = deepcopy(nfa.transitions[state_][s])
                        if len(alphabet) > 0:
                            alphabet = alphabet.pop()
                            if alphabet != Automata.empty():
                                transitions.append(
                                    (new_state, alphabet, new_state))

        #map states
        map_states = dict()
        for i, state in enumerate(new_states):
            map_states[",".join(map(str, list(state[1])))] = i

        #map transitions
        transitions_ = []
        for transition in transitions:
            transitions_.append(
                (map_states[",".join(map(str,
                                         list(transition[0])))], transition[1],
                 map_states[",".join(map(str, list(transition[2])))]))
        transitions = transitions_

        new_nfa = Automata(alphabets=nfa.alphabets)
        #set start state
        for state in new_states:
            new_state = state[1]
            if nfa.start_state in new_state:
                new_nfa.set_start_state(map_states[",".join(
                    map(str, list(new_state)))])
                break
        #set final states:
        for state in new_states:
            new_state = state[1]
            for final_state in nfa.final_states:
                if final_state in new_state:
                    new_nfa.add_final_states(map_states[",".join(
                        map(str, list(new_state)))])

        #add transitions
        for transition in transitions:
            state1 = transition[0]
            alphabet = transition[1]
            state2 = transition[2]
            new_nfa.add_transition(state1, state2, alphabet)

        return new_nfa