Código fonte de src.tm

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from .reader import Reader

[documentos]class Tm(): """Classe que representa uma máquina de Turing determinística para computação de funções numéricas.""" def __init__(self, filename): """ :param filename: Nome do arquivo de entrada. :type filename: str """ reader = Reader(filename) self.Q, self.S, self.q0, self.tape = reader.read_file() self.transitions = {} self.make_transitions() self.actual = self.q0 self.position = 0
[documentos] def make_transitions(self): """Método que cria dicionário de dicionários para armazenamento das transições de cada estado. A estrutura é dada no seguinte formato abaixo: - { ``estado_i``: { ``simbolo_leitura_j``: (``proximo_estado_k``, ``simbolo_escrita_k``, ``direcao_k``), ...}, ...} Por exemplo: - {'q0': {'B': ('q1', '1', 'R'), ...}, 'q1': {'1', ...}, ... 'qn': { ...}} """ for state in self.Q: self.transitions[state] = {} for source, in_symbol, destination, out_symbol, direction, _ in self.S: if source == state: self.transitions[state][in_symbol] = [destination, out_symbol, direction]
[documentos] def show_tape(self): """Método que imprime o estado atual e a configuração da fita.""" print("".join([self.tape[:self.position], "{", self.actual, "}", \ self.tape[self.position:]]))
[documentos] def compute(self): """Método que executa uma computação na máquina de Turing, alterando -*ou não*- o estado atual, escrevendo um símbolo e movendo a cabeça de leitura para esquerda ou direita. """ self.show_tape() destination, out_symbol, direction = self.get_transition() self.write_actual(out_symbol) self.actual = destination if direction == 'R': self.move_right() else: self.move_left()
[documentos] def get_transition(self): """Método que retorna a transição que o estado atual irá realizar lendo o símbolo atual. :return: (*List*) Lista de ``str`` contendo uma transição no formato lista['``qi``', '``ri``', '``D``'], onde: - ``qi``: Estado destino; - ``ri``: Símbolo a ser escrito; - ``D``: Direção a mover a cabeça de leitura (*L* ou *R*) """ return self.transitions[self.actual][self.read_actual()]
[documentos] def clean_right(self): """Método que remove símbolo branco (*'B'*) excedente à direita da fita da máquina de Turing.""" if self.tape[-1] == 'B' and self.tape[-2] == 'B': self.tape = self.tape[:len(self.tape)-1]
[documentos] def move_left(self): """Método que move a cabeça de leitura para esquerda.""" #self.clean_right() try: self.position -= 1 if self.position == -1: raise Exception("Movimento inválido!") except Exception as error: sys.exit('Erro encontrado: ' + str(error))
[documentos] def move_right(self): """Método que move a cabeça de leitura para direita.""" self.position += 1 if self.position == len(self.tape): self.tape = "".join([self.tape, 'B'])
[documentos] def write_actual(self, value): """Método que realiza a escrita na posição onde a cabeça de leitura se encontra. :param value: Valor a ser escrito na posição atual :type value: str """ input_list = list(self.tape) input_list[self.position] = value self.tape = "".join(input_list) # Caso da escrita na "última" posição da fita com símbolo diferente de 'B' if self.position == len(self.tape) - 1 and not self.tape[self.position] == 'B': self.tape = "".join([self.tape, 'B'])
[documentos] def read_actual(self): """Método que retorna o símbolo da posição onde está a cabeça de leitura. :return: (*str*) Símbolo da fita na posição que a cabeça de leitura se encontra. """ return self.tape[self.position]