Rev 131 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/usr/bin/env python# Copyright: Ira W. Snyder# Start Date: 2005-10-08# End Date:# License: Public Domain## Changelog Follows:################################################################################## IMPORTANT NOTES################################################################################################################################################################import sys, stringclass nfa:"""Implements a Non-Deterministic Finite Automaton"""def __init__(self):self.trans_func = {}self.num_states = 0self.final_states = []self.initial_state = 0def __state_in_range(self, state):"""Check if a given state is in the acceptable range"""try:temp = int(state)except (TypeError, ValueError):return Falseif temp >= 0 and temp < self.num_states:return Truereturn Falsedef __input_num_states(self):"""Get the number of states this automaton will have"""done = Falsewhile not done:num_states = raw_input('How many states in this automaton: ')try:self.num_states = int(num_states)done = Trueexcept (TypeError, ValueError):print 'Bad input, not an integer, try again'def __input_final_states(self):"""Get final states for this automaton"""print 'Enter final states on one line, seperated by spaces'done = Falsewhile not done:final_states = raw_input('Final states: ')bad_data = Falsefor i in final_states.split():if not self.__state_in_range(i):print 'State %s out of range. All input discarded.' % (i, )print 'Try again please'bad_data = Truebreak# if we left the for loop with bad dataif bad_data:continue# all data is goodfor i in final_states.split():self.final_states.append(int(i))done = Truedef __input_all_edges(self):"""Read all of the edges for this automaton"""print 'Edges take the form "from HERE, by LETTER, to THERE"'print 'Enter something like: "1 a 1" to represent the following'print 'from q1, by a, go to q1'print 'Conditions:'print '1. Blank line to end'print '2. ^ is the empty string'done = Falsewhile not done:edge = raw_input('Edge: ')if len(edge) == 0:done = Truecontinueif len(edge.split()) != 3:print 'Bad edge entered'continue(cur_st, letter, next_st) = edge.split()if self.__state_in_range(cur_st) and self.__state_in_range(next_st):new_state = Falsetry:self.trans_func[(int(cur_st), letter)]except KeyError:new_state = Trueif new_state:self.trans_func[(int(cur_st), letter)] = [int(next_st)]else:self.trans_func[(int(cur_st), letter)].append(int(next_st))else:print 'Invalid current or next state entered'continuedef __input_automaton(self):"""Read this entire automaton's input"""self.__input_num_states()self.__input_final_states()self.__input_all_edges()def main_menu(self):self.__input_automaton()print self.trans_funcprint self.num_statesprint self.final_statesprint self.initial_stateprint 'E(0): %s' % (self.__E(0), )print 'E(1): %s' % (self.__E(1), )def __next_states(self, state, letter):next = []try:next = self.trans_func[(state, letter)]except KeyError:passreturn nextdef __E(self, state, storage=[], visited=[]):# If nothing was inputted for the null string from this state# return itself only (as a list)if len(self.__next_states(state, '^')) == 0:print 'stop rec: %s' % ([state], )return [state]for i in self.__next_states(state, '^'):print 'next state: %s -- storage: %s -- visited: %s' % (i, storage, visited)if i not in storage and i not in visited:storage.append(state) #add yourself to the listvisited.append(i)print 'making the call: (%s, %s, %s)' % (i, storage, visited)storage.extend(self.__E(i, storage, visited))return storagedef output_dfa(self):#stuff herepassif __name__ == '__main__':automaton = nfa()automaton.main_menu()