2021-08-04 16:32:16 +02:00
""" Autómata finito determinista """
#Código adaptado del original de Vijaya Gajanan
#https://medium.com/swlh/automata-theory-in-python-part-1-deterministic-finite-automata-95d7c4a711f5
class DFA :
def __init__ ( self ) :
#Se inicia el objeto DFA
self . Q = self . populate_states ( )
self . SIGMA = self . populate_alphabet ( )
self . DELTA = self . populate_transition_function ( )
self . START_STATE , self . ACCEPT_STATES = self . set_start_accept ( )
self . CURRENT_STATE = None
def set_start_accept ( self ) :
#Toma el estado inicial (START_SATATE) y los estados de aceptación (ACCEPT_STATE) dado por el usuario y checa si pertenecen al conjunto de estados
while ( True ) :
start = input ( " Da el estado inicial: " )
accept = input ( " Da el o los estados de aceptación (separados por espacio): " ) . split ( )
#Se asegura que el estado inicial y de aceptación estén en el conjunto
if ( start in self . Q ) and ( set ( accept ) . issubset ( set ( self . Q ) ) ) :
return start , accept
else :
print ( " Por favor da estados que estén en tu conjunto de estados Q : {} . \n Los estados de aceptación deben ser un subconjunto de Q \n " . format ( self . Q ) )
def populate_states ( self ) :
#Toma los estados dados por el usuario (Q)
Q_input = input ( " Da la lista de estados separados por espacio: " ) . split ( )
print ( " Estados : {} " . format ( Q_input ) )
return Q_input
def populate_alphabet ( self ) :
#Toma el alfabeto dado por el usuario (SIGMA)
SIGMA_input = input ( " Da el alfabeto de entrada separado por espacios: " ) . split ( )
print ( " Alfabeto : {} " . format ( SIGMA_input ) )
return SIGMA_input
def populate_transition_function ( self ) :
#Crea la función de transición (Q X SIGMA -> Q) y la imprime
2021-08-04 17:44:33 +02:00
transition_dict = { el : { el_2 : ' RECHAZO ' for el_2 in self . SIGMA } for el in self . Q }
2021-08-04 16:32:16 +02:00
for key , dict_value in transition_dict . items ( ) :
print ( " Da la transición para el estado {} . De ser necesario, usa ' RECHAZO ' . " . format ( key ) )
for input_alphabet , transition_state in dict_value . items ( ) :
transition_dict [ key ] [ input_alphabet ] = input ( " ESTADO ACTUAL : {} \t ALFABETO DE ENTRADA : {} \t SIGUIENTE ESTADO : " . format ( key , input_alphabet ) )
print ( " \n FUNCIÓN DE TRANSICIÓN Q X SIGMA -> Q " )
print ( " ESTADO ACTUAL \t ALFABETO DE ENTRADA \t PRÓXIMO ESTADO " )
for key , dict_value in transition_dict . items ( ) :
for input_alphabet , transition_state in dict_value . items ( ) :
print ( " {} \t \t {} \t \t {} " . format ( key , input_alphabet , transition_state ) )
return transition_dict
def run_state_transition ( self , input_symbol ) :
#Toma el estado actual y va al siguinete estado de acuerdo al símbolo de entrada
if ( self . CURRENT_STATE == ' RECHAZO ' ) :
return False
print ( " ESTADO ACTUAL : {} \t SÍMBOLO DE ENTRADA : {} \t PRÓXIMO ESTADO : {} " . format ( self . CURRENT_STATE , input_symbol , self . DELTA [ self . CURRENT_STATE ] [ input_symbol ] ) )
self . CURRENT_STATE = self . DELTA [ self . CURRENT_STATE ] [ input_symbol ]
return self . CURRENT_STATE
def check_if_accept ( self ) :
#Checa si el estado actual es de aceptación
if self . CURRENT_STATE in self . ACCEPT_STATES :
return True
else :
return False
def run_machine ( self , in_string ) :
#Corre la máquina con la cadena de entrada
self . CURRENT_STATE = self . START_STATE
for ele in in_string :
check_state = self . run_state_transition ( ele )
#Checa si el estado no es RECHAZO
if ( check_state == ' RECHAZO ' ) :
return False
return self . check_if_accept ( )
if __name__ == " __main__ " :
check = True
print ( " \n Autómata Finito Determinista (DFA). " )
machine = DFA ( )
while ( check ) :
choice = int ( input ( " \n Elige la opción: \n 1. Correr el DFA con la cadena de entrada \n 2. Cambiar el DFA \n 3. Salir \n Da Opción : " ) )
if ( choice == 2 ) :
machine = DFA ( )
elif ( choice == 1 ) :
input_string = list ( input ( " Da la cadena de entrada : " ) )
print ( " ACEPTADA " if machine . run_machine ( input_string ) else " RECHAZADA " )
else :
check = False