-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautomato.py
executable file
·135 lines (113 loc) · 5.18 KB
/
automato.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
import argparse
import re
from collections import defaultdict
class Automato(object):
# initialization states, transition maps
def __init__(self, start_state, transitions, final_states):
self.start_state = list(str(start_state))
self.curr_state = list(str(start_state))
self.final_states = list(map(str, final_states))
self.state_map = defaultdict(dict)
for trans in transitions:
self.state_map[trans[0]][trans[2]] = []
for trans in transitions:
self.state_map[trans[0]][trans[2]].append(trans[4])
# perform initial check for epsilon transitions
def init_states_check(self):
if '@' in self.state_map[self.curr_state[0]]:
self.curr_state.extend(self.state_map[self.curr_state[0]]['@'])
return self
def change_of_state(self, event):
next_state = []
for state in self.curr_state:
# case we have epsilon transitions
if '@' in self.state_map[state]:
next_state.extend(self.state_map[state]['@'])
# for a standard event make a new set of current states
if event in self.state_map[state]:
next_state.extend(self.state_map[state][event])
# remove dublicate states from the current states set
self.curr_state = next_state
unique_current_states = set(self.curr_state)
self.curr_state = list(unique_current_states)
return self
# this kind of implementation can just ignore the number of final states and number of transitions.
# so we can use a smaller input file
def readfile(filename):
integers_regex = re.compile('\d+')
transitions_regex = re.compile('\d [0-9a-z@] \d')
input = open(filename, 'r')
num_of_states = int(input.readline())
start_state = int(input.readline())
num_of_final_states = int(input.readline())
final_states = integers_regex.findall(input.readline())
final_states = list(map(int, final_states))
num_of_events = int(input.readline())
transitions = []
for i, line in enumerate(input):
transitions.append(str(transitions_regex.findall(line)[0]))
return_vector = str(start_state), final_states, transitions
return return_vector;
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("input_file")
args = parser.parse_args()
start_state, final_states, transitions = readfile(args.input_file)
automato = Automato(start_state, transitions, final_states)
automato = automato.init_states_check()
print('Initial State(s): {}'.format(', '.join(automato.curr_state)))
# List for terminate or continue the program
prompt_list = ['YES', 'yes', 'y', 'Y', 'No', 'no', 'N', 'n']
yes_prompt_list = ['YES', 'yes', 'y', 'Y']
no_prompt_list = ['No', 'no', 'N', 'n']
question = 'YES'
word = ''
while question in prompt_list:
print('Please insert a word to the automato:')
del word
word = input()
valid = True
for event in word:
prev_state = automato.curr_state
automato.change_of_state(event)
if not automato.curr_state:
print('Not a valid word. State set is empty'.format(automato.curr_state))
# switch to false in order to stop iteration when a
# state was reached that there were no transitions possible
# for the current event
valid = False
break
else:
print('Transition from state(s) {} in states {}'.format(', '.join(prev_state),
', '.join(automato.curr_state)))
# Case deadlock, state with no feasible transitions, terminate automato
if not valid:
print("You want to continue? Type yes for another try or no for termination:")
question = input()
while question not in prompt_list:
print("You want to continue? Type yes for another try or no for termination:")
question = input()
if question in no_prompt_list:
break
else:
automato.curr_state = list(str(start_state))
automato = automato.init_states_check()
continue
final_states_set = set(automato.curr_state).intersection(set(automato.final_states))
final_states = list(final_states_set)
if not final_states:
print('Automato finished in state(s) {} that is not final.'.format(', '.join(automato.curr_state)))
else:
print('Valid word. Automato finished in states {}'.format(', '.join(final_states)))
print("You want to continue? Type yes for another try or no for termination:")
question = input()
while question not in prompt_list:
print("You want to continue? Type yes for another try or no for termination:")
question = input()
if question in no_prompt_list:
break
else:
# reset the automato to the starting state
automato.curr_state = list(str(start_state))
automato = automato.init_states_check()