DFA en python

This commit is contained in:
Vladimir Lemus 2021-08-04 09:32:16 -05:00
parent 8e9707ea3a
commit fb36a5c2b3
2 changed files with 165 additions and 1 deletions

98
DFA.py Normal file
View File

@ -0,0 +1,98 @@
"""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 : {}.\nLos 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
transition_dict = {el : {el_2 : 'REJECT' for el_2 in self.SIGMA} for el in self.Q}
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 : {}\tALFABETO DE ENTRADA : {}\tSIGUIENTE ESTADO : ".format(key, input_alphabet))
print("\nFUNCIÓN DE TRANSICIÓN Q X SIGMA -> Q")
print("ESTADO ACTUAL\tALFABETO DE ENTRADA\tPRÓ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 : {}\tSÍ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("\nAutómata Finito Determinista (DFA).")
machine = DFA()
while(check):
choice = int(input("\nElige la opción:\n1. Correr el DFA con la cadena de entrada\n2. Cambiar el DFA\n3. Salir \nDa 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

View File

@ -1,3 +1,69 @@
# dfa-python
Código para construir autómatas finitos deterministas en python.
Código para construir autómatas finitos deterministas en python. Adaptado del original de **Vijaya Gajanan** (https://medium.com/swlh/automata-theory-in-python-part-1-deterministic-finite-automata-95d7c4a711f5).
La operación es interactiva, pidiendo los estados, el alfabeto, estado de enrada y estados de salida, al igual que la tabla de transiciones.
>Autómata Finito Determinista (DFA).
>Da la lista de estados separados por espacio:
Introduce los nombres de los estados, por ejemplo: q0 q1 q2 (*presiona enter*)
Al no poner los espacios el programa lo interpretará como un único estado.
>Estados : ['q0', 'q1', 'q2']
>Da el alfabeto de entrada separado por espacios:
De la misma manera introduce los símbolos del alfabeto, por ejemplo: 0 1
>Alfabeto : ['0', '1']
>Da la transición para el estado q0. De ser necesario, usa 'RECHAZO'.
>ESTADO ACTUAL : q0 ALFABETO DE ENTRADA : 0 SIGUIENTE ESTADO :
Introduce el estado siguiente a partir del estado q0 al leer un '0'.
Este proceso se repite para todos los estados y todos los símbolos del alfabeto. El programa no cuenta con un proceso para confirmar que los estados dados estén en la lista, es algo que debe mejorarse. De dar estados fuera del conjunto hasta el final aparecerá un error.
A partir de los valores dados se construye la tabla de transiciones:
>FUNCIÓN DE TRANSICIÓN Q X SIGMA -> Q
>ESTADO ACTUAL ALFABETO DE ENTRADA PRÓXIMO ESTADO
>q0 0 q1
>q0 1 q0
>q1 0 q2
>q1 1 q2
>q2 0 q1
>q2 1 q0
Enseguida se pide el estado inicial, como es un autómata finito determinista recuerda que sólo acepta un estado inicial.
>Da el estado inicial:
Posteriormente pedirá los estados finales.
>Da el o los estados de aceptación (separados por espacio):
Una vez introducidos revisará que los estados proporcionados estén en la lista de estados dado, de no ser así volverá a pedir el estado inicial y el o los de salida.
Si los estados están en el conjunto se pide elegir la opción:
>Elige la opción:
>1. Correr el DFA con la cadena de entrada
>2. Cambiar el DFA
>3. Salir
Para correr el autómata dado se elige la opción 1, la opción 2 en caso de haber cometido un error permite definir de nuevo el autómata (desde cero), para no hacer nada más y salir se elige la opción 3 (por supuesto que en cualquier momento del proceso se puede hacer Ctrl-c).
>Da Opción : 1
>Da la cadena de entrada : 1001
>ESTADO ACTUAL : q0 SÍMBOLO DE ENTRADA : 1 PRÓXIMO ESTADO : q0
>ESTADO ACTUAL : q0 SÍMBOLO DE ENTRADA : 0 PRÓXIMO ESTADO : q1
>ESTADO ACTUAL : q1 SÍMBOLO DE ENTRADA : 0 PRÓXIMO ESTADO : q2
>ESTADO ACTUAL : q2 SÍMBOLO DE ENTRADA : 1 PRÓXIMO ESTADO : q0
Al final aparecerá la palabra **ACEPTADA** o **RECHAZADA** de acuerdo a si se llega a un estado de aceptación o uno de rechazo.
Hay detalles por mejorar, no he probado que pasa al dar el estado como rechazo. Tomen la idea y adáptenla a su gusto y necesidades.