Last active
January 16, 2017 14:37
-
-
Save dvdblk/2d9648b5b39be6c3b0b242c96f66c941 to your computer and use it in GitHub Desktop.
Creates a union from two DFA's
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 | |
3 | |
1 | |
2 | |
1 2 | |
2 3 3 | |
2 2 2 | |
3 3 3 | |
3 | |
3 | |
1 | |
1 | |
2 | |
3 2 3 | |
2 2 2 | |
3 3 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class State: | |
def __init__(self, identifier): | |
self.identifier = str(identifier) | |
self.transition_funcs = {} | |
def __str__(self): | |
return self.identifier | |
def add_transition(self, withChar, to): | |
self.transition_funcs[withChar] = to | |
class DFA: | |
def __init__(self, alphabet_count): | |
self.states = [] | |
self.alphabet = list(map(chr, range(97, 97+alphabet_count))) | |
self.initial_state = None | |
self.accepting_states = [] | |
def add_state(self, state, initial = False, accepting = False): | |
self.states.append(state) | |
if initial: | |
self.initial_state = state | |
if accepting: | |
self.accepting_states.append(state) | |
def output_DFA(self): | |
print(len(self.states)) | |
print(len(self.alphabet)) | |
print(self.initial_state.identifier) | |
print(len(self.accepting_states)) | |
print(" ".join(map(str, self.accepting_states))) | |
for i in range(len(self.states)): | |
self.print_state(i) | |
def print_state(self, nr): | |
result = "" | |
for letter in self.alphabet: | |
result = result + self.states[nr].transition_funcs[letter] + " " | |
print(result) | |
if __name__ == "__main__": | |
dfa_array = [] | |
#read file and create DFA's from input file | |
with open("zadani02.aut", "r") as input_file: | |
def rl(no_strip = False): | |
read = input_file.readline | |
if no_strip: | |
return read() | |
return read().rstrip('\n') | |
for _ in range(2): | |
number_of_states = int(rl()) | |
alphabet_count = int(rl()) | |
initial_state = int(rl()) | |
accepting_states_count = int(rl()) | |
accepting_states = list(map(int, rl().split())) | |
# only 1 accepting state DFA fix... | |
accepting_states_dict = dict(map(lambda x: (x+1,True) if x+1 in accepting_states else (x+1,False), range(0,number_of_states))) | |
dfa = DFA(alphabet_count) | |
for i in range(1,number_of_states+1): | |
row = rl().split() | |
state = State(i) | |
for j in range(alphabet_count): | |
state.add_transition(dfa.alphabet[j], row[j]) | |
dfa.add_state(state, i == initial_state, accepting_states_dict[i]) | |
dfa_array.append(dfa) | |
#dfa.output_DFA() | |
line = rl(True) | |
if not line: break | |
# compute their union... | |
unified_dfa = DFA(len(dfa_array[0].alphabet)) | |
current_state = 1 | |
unified_temp_states_queue = [(dfa_array[0].initial_state.identifier+"-"+dfa_array[1].initial_state.identifier,current_state)] | |
unified_states = {} | |
while unified_temp_states_queue: | |
top_item = unified_temp_states_queue.pop(0) | |
if top_item[0] not in unified_states: | |
state = State(top_item[1]) | |
current_state = top_item[1] | |
# get the new state from 2 input DFA's | |
states_to_be_unified = top_item[0].split("-") | |
first = dfa_array[0].states[int(states_to_be_unified[0])-1] | |
second = dfa_array[1].states[int(states_to_be_unified[1])-1] | |
for letter in dfa_array[0].alphabet: | |
first_to = first.transition_funcs[letter] | |
second_to = second.transition_funcs[letter] | |
result = first_to +"-"+ second_to | |
if result not in [itm[0] for itm in unified_temp_states_queue]: | |
current_state += 1 | |
unified_temp_states_queue.append((result, current_state)) | |
state.add_transition(letter, result) | |
unified_states[top_item[0]] = top_item[1] | |
is_initial = (dfa_array[0].initial_state == first) or (dfa_array[1].initial_state == second) | |
is_accepting = (first in dfa_array[0].accepting_states) or (second in dfa_array[1].accepting_states) | |
unified_dfa.add_state(state, is_initial, is_accepting) | |
# and rename states | |
for state in unified_dfa.states: | |
for letter in state.transition_funcs: | |
state.transition_funcs[letter] = str(unified_states[state.transition_funcs[letter]]) | |
unified_dfa.output_DFA() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment