from collections import namedtuple MT = namedtuple("MT", "inicial aceitação rejeição transição") def imprime(situação): palavra_esq, estado, palavra_dir = situação L = len(palavra_esq) + len(palavra_dir) posição_cabeça = (2*len(palavra_esq))+6 linha_cima = '─┬'*(L+5) + '─' prefixo = '…│❑│❑' posfixo = '│❑│❑│…' linha_baixo = '─┴'*(L+5) + '─' conteúdo = '' for s in (palavra_esq + palavra_dir): if s == 'B': s = '❑' conteúdo += f'│{s}' print(linha_cima) print(f'{prefixo}{conteúdo}{posfixo}') print(linha_baixo) print(f'{" "*posição_cabeça}⬑{estado}') def passo(situação, transição): palavra_esq, estado, palavra_dir = situação # palavra_esq = palavra_esq.lstrip('B') # palavra_dir = palavra_dir.rstrip('B') if not palavra_dir: símbolo = 'B' else: símbolo = palavra_dir[0] novo_símbolo, novo_estado, direção = transição(símbolo, estado) esq = {'←', 'e'} dir = {'→', 'd'} if direção in esq: if palavra_esq: último_esq = palavra_esq[-1] else: último_esq = 'B' return (palavra_esq[:-1], novo_estado, (último_esq + novo_símbolo + palavra_dir[1:])) elif direção in dir: return palavra_esq + novo_símbolo, novo_estado, palavra_dir[1:] else: # cabeça fica parada return palavra_esq, novo_estado, novo_símbolo + palavra_dir[1:] def executa(palavra_inicial, máquina, passo_a_passo=True): estado_inicial, terminais_aceitação, terminais_rejeição = máquina[:3] if isinstance(máquina[-1], dict): transição = transição_dic(máquina[-1]) else: transição = máquina[-1] situação = ('', estado_inicial, palavra_inicial) passos = 0 while True: passos += 1 print(f'{passos}.') imprime(situação) if situação[1] in terminais_aceitação: print("Fim da execução: aceitação") return if situação[1] in terminais_rejeição: print("Fim da execução: rejeição") return if passo_a_passo: input("Pressione para continuar...") try: situação = passo(situação, transição) except Exception: print("TELA AZUL(não há transição válida)") return def transição_dic(D): return lambda s, e: D[(s, e)] # ============ # = EXEMPLOS = # ============ dic_ancn = { ('0', 'procura_fronteira') : ('0', 'procura_fronteira', '→'), ('1', 'procura_fronteira') : ('1', 'procura_0_não_marcado', '←'), ('X', 'procura_0_não_marcado'): ('X', 'procura_0_não_marcado', '←'), ('0', 'procura_0_não_marcado'): ('X', 'procura_1_não_marcado', '→'), ('B', 'procura_0_não_marcado'): ('B', 'tudo_X?', '→'), ('X', 'procura_1_não_marcado'): ('X', 'procura_1_não_marcado', '→'), ('1', 'procura_1_não_marcado'): ('X', 'procura_0_não_marcado', '←'), ('X', 'tudo_X?') : ('X', 'tudo_X?', '→'), ('B', 'tudo_X?') : ('B', 'sucesso', '→'), } MT_ancn = MT(inicial='procura_fronteira', aceitação={'sucesso'}, rejeição=set(), transição=dic_ancn) def delta_ex1(x, q): if x == 'B' and q == 'q_I': return ('B', 'q_I', '→') MT_ex1 = MT(inicial='q_I', aceitação=set(), rejeição=set(), transição=delta_ex1) def delta_ex2(simbolo, estado): if simbolo == 'x' and estado == 'q_I': return ('x', 'q_I', '→') if simbolo == 'y' and estado == 'q_I': return ('y', 'q_F', '⟳') MT_ex2 = MT(inicial='q_I', aceitação={'q_F'}, rejeição=set(), transição=delta_ex2) MT_rejeita_se_tem_0 = MT( inicial = 'inicial', aceitação = {'aceita'}, rejeição = {'rejeita'}, transição = { ('0', 'inicial'): ('0', 'rejeita', '⟳'), ('1', 'inicial'): ('1', 'inicial', '→'), ('B', 'inicial'): ('B', 'aceita', '⟳'), } ) MT_par = MT( inicial = 'inicial', aceitação = {'aceita'}, rejeição = {'rejeita'}, transição = { ('0', 'inicial') : ('0', 'inicial', '→'), ('1', 'inicial') : ('1', 'inicial', '→'), ('B', 'inicial') : ('B', 'le_ultimo', '←'), ('0', 'le_ultimo'): ('0', 'aceita', '⟳'), ('1', 'le_ultimo'): ('1', 'rejeita', '⟳'), ('B', 'le_ultimo'): ('B', 'rejeita', '⟳'), } ) MT_0n1n2n = MT( inicial = 'procura0', aceitação = {'aceita'}, rejeição = {'rejeita'}, transição = { ('B', 'procura0') : ('B', 'aceita', '⟳'), ('0', 'procura0') : ('Z', 'procura1', '→'), ('Z', 'procura0') : ('Z', 'procura0', '→'), ('U', 'procura0') : ('U', 'procura0', '→'), ('D', 'procura0') : ('D', 'procura0', '→'), ('1', 'procura0') : ('1', 'rejeita', '⟳'), ('2', 'procura0') : ('2', 'rejeita', '⟳'), ('0', 'procura1') : ('0', 'procura1', '→'), ('Z', 'procura1') : ('Z', 'procura1', '→'), ('U', 'procura1') : ('U', 'procura1', '→'), ('1', 'procura1') : ('U', 'procura2', '→'), ('B', 'procura1') : ('B', 'rejeita', '⟳'), ('2', 'procura1') : ('2', 'rejeita', '⟳'), ('D', 'procura1') : ('D', 'rejeita', '⟳'), ('1', 'procura2') : ('1', 'procura2', '→'), ('U', 'procura2') : ('U', 'procura2', '→'), ('D', 'procura2') : ('D', 'procura2', '→'), ('2', 'procura2') : ('D', 'volta_início', '←'), ('B', 'volta_início') : ('B', 'procura0', '→'), ('0', 'volta_início') : ('0', 'volta_início', '←'), ('1', 'volta_início') : ('1', 'volta_início', '←'), ('2', 'volta_início') : ('2', 'volta_início', '←'), ('Z', 'volta_início') : ('Z', 'volta_início', '←'), ('U', 'volta_início') : ('U', 'volta_início', '←'), ('D', 'volta_início') : ('D', 'volta_início', '←'),})