Desenvolvimento de Um Programa Interpretador e Resolvedor para Máquinas de Estado Finito Adriana Postal 1, Ana Paula Fredrich 1, Cassiano Cesar Casagrande 1, Evaristo Wychoski Benfatti 1, Josué Pereira de Castro 1, Pablo Andretta Jaskowiak 1 1 UNIOESTE - Universidade Estadual do Oeste do Paraná Grupo de Pesquisa em Algoritmos Rua Universitária, 2069. Jardim Universitário. Caixa Postal 711 - CEP 85819-110 Cascavel, PR apostal@unioeste.br, paulinha_f_sh@yahoo.com.br, cccasagrande_info@yahoo.com.br evaristowb@hotmail.com, j_p_castro@yahoo.com.br, eslaxe@hotmail.com Resumo. Neste artigo apresentamos o protótipo do PIRAMIDE Programa Interpretador e Resolvedor de Autômatos e MáquInas De Estados finitos, um sistema que está em desenvolvimento e que tem o objetivo de auxiliar o ensino de Teoria da Computação nos cursos de Ciência da Computação. Até o momento, o sistema possui dois módulos implementados: o simulador e o resolvedor de de Autômatos Finitos. 1. Introdução Nos dias atuais a computação permeia todos os ramos da vida moderna, tornando-se por isso indispensável. O sucesso prático da Ciência da Computação baseia-se em seus fundamentos matemáticos e teóricos. Tais fundamentos tem como objetivo responder a algumas perguntas fundamentais, tais como: O que é um algoritmo? O que pode e o que não pode ser computado? Quando um algoritmo deve ser considerado praticamente factível? Tais questionamentos tem sido feitos por pesquisadores desde os primórdios da computação, com o objetivo de explorar os limites teóricos e práticos da computação [Lewis and Papadimitriou 2000]. O propósito da disciplina de Teoria da Computação (TC), é estudar os modelos e os paradigmas fundamentais que sustentam a Ciência da Computação. Este estudo é de suma importância para qualquer profissional da área por várias razões, entre elas: grande parte da Ciência da Computação é baseada nesses paradigmas; os computadores atuais são baseados nestes modelos e paradigmas; por fim, o estudo destes modelos ajuda a identificar os limites da computação. Entretanto, existe uma característica importante que deve ser levada em conta no ensino dessas idéias e modelos: eles são matemáticos por natureza embora um computador seja inegavelmente um objeto físico, suas abstrações mais úteis são claramente matemáticas e assim o são, necessariamente, as técnicas utilizadas para argumentar sobre elas. Além disso, tarefas computacionais práticas requerem garantias estritas que só a matemática oferece (por exemplo, precisamos garantir que nossos compiladores traduzem corretamente um programa) [Lewis and Papadimitriou 2000]. Devido a esta característica, aliada à falta de uma maturidade matemática por parte dos estudantes, o ensino de Teoria da Computação torna-se difícil: estes estudantes encontram, com freqüência,
grande dificuldade para aprender os modelos matemáticos ensinados na disciplina, e que são a base de toda a Ciência da Computação. Com o intuito de amenizar as dificuldades encontradas pelos estudantes, em 2004 propomos a criação de um Ambiente de Apoio ao Ensino de Teoria da Computação, batizado de LabTeC (Laboratório de Teoria da Computação). O primeiro passo para a criação deste ambiente, foi modelar e implementar o Módulo Resolvedor de Autômatos Finitos [Welter et al. 2005], utilizando algoritmos genéticos [Mitchell 1997][Koza 1992], e que foi aperfeiçoado em 2005, onde o módulo do resolvedor de autômatos finitos foi melhorado [Postal et al. 2007], originando um novo sistema de simulação, o PIRAMIDE Programa Interpretador e Resolvedor de Autômatos e MáquInas De Estados finitos. Agora, nossa meta é a implementação de dois novos simuladores para este sistema: um simulador de autômatos de pilha e um simulador de Máquina de Turing. Este artigo está organizado da seguinte forma: na seção 2, descreveremos os objetivos do sistema e quais etapas estão previstas; na seção 3, descreveremos os módulos já implementados: o simulador de Autômatos Finitos (seção 3.2) e o resolvedor de Autômatos (3.3), além dos testes realizados para estes módulos (3.4). Por fim, a seção 4 mostrará os serão os próximos passos para este sistema. 2. Objetivos do Sistema Autômatos Finitos são uma das áreas mais importantes da computação teórica, pois representam os modelos básicos de máquinas computacionais, sobre os quais assentam-se as bases da moderna Ciência da Computação. Outras áreas do conhecimento, tais como a engenharia de controle e automação e a engenharia elétrica também se utilizam de modelos de autômatos para modelar soluções para problemas em suas respectivas áreas. Para um aluno de Ciência da Computação os modelos de autômatos são importantes não apenas como fundamento, mas também uma ferramenta importante para a compreensão de outras áreas, como projeto de linguagens de programação e construção de compiladores, métodos de especificação formal baseados em linguagens formais, dentre outras. Apesar de sua importância, ensinar um aluno a pensar em autômatos pode ser uma tarefa tão difícil quanto ensinar a programar. Desta forma, qualquer ferramenta que auxilie o aluno a aprender pode ser um bom aliado do professor. Neste artigo apresentamos uma ferramenta computacional, ainda em desenvolvimento mas já com seu primeiro protótipo implementado, projetada para ser uma ferramenta de auxílio no processo de ensino-aprendizagem de modelos de autômatos. O sistema foi dividido em: Simuladores/Resolvedores de Máquinas de Estados Finitos: Autômatos Finitos (AFs) determinísticos (AFDs) e não-determinísticos (AFNs); Autômatos de Pilha (APs); Máquinas de Turing (MTs). Minimização de AFs; Transformação de AFN para AFD; Chat.
Até o presente momento, o sistema é composto de um módulo simulador de AFs, que permite que o aluno possa construir e simular seus autômatos, analisando o comportamento destes, e de um módulo resolvedor, capaz de gerar modelos de AFs a partir de exemplos de entradas que o autômato deveria aceitar e de exemplos que ele deveria rejeitar. Estes modelos são criados através de um algoritmo evolucionário, enquanto que a simulação dos modelos é feita por um módulo baseado em programação lógica e construído em linguagem Prolog, configurando assim um sistema híbrido lógico-evolucionário. 3. Software Desenvolvido 3.1. Desenvolvimento Java-Prolog No desenvolvimento deste software, foram utilizadas duas linguagens de programação, a linguagem orientada a objetos Java e a linguagem lógica Prolog. O Prolog é utilizado na implementação de um algoritmo que simule AFs determinísticos e não determinísticos, ou seja, um algoritmo simulador de AFs que aceita ou rejeita strings de entrada dado a especificação de um AF. A implementação deste algoritmo em uma linguagem com Java, C ou Pascal é complexo e demanda grande tempo de programação [Palazzo 1997]. Para integrar as duas linguagens de programação, utilizou se o interpretador Amzi! Prolog versão 6.2, que disponibiliza a Logic Server API (composta por classes desenvolvidas em Java e DLLs), esta API oferece os meios necessários e suficientes para realizar o interfaceamento entre as linguagens [Deitel and Deitel 2003]. A Logic Server API oferece suporte para que programas desenvolvidos em Java executem programas desenvolvidos em Amzi! Prolog. Mas o contrário não ocorre, ou seja, programas escritos em Amzi! Prolog não possuem autonomia para executar programas escritos em Java. O Sistema agrupa em um mesmo programa o Simulador e o Resolvedor de Autômatos Finitos. A seguir é fornecida uma descrição mais detalhada dos dois módulos do sistema. 3.2. Simulador O simulador é um ambiente integrado, que possui um editor de Autômatos Finitos, como mostra a figura 1. Seu objetivo é permitir o desenvolvimento rápido e prático de AFs determinísticos e não determinísticos, possibilitando também a realização de testes. O simulador foi desenvolvido utilizando tecnologias oriundas de duas linguagens de programação: a linguagem Java, que contribuiu para o desenvolvimento da interface gráfica, e a linguagem Prolog que atua como motor de inferência para calcular se uma dada string é aceita ou rejeitada pelo autômato desenvolvido na ferramenta. 3.3. Resolvedor O resolvedor de autômatos finitos foi construído utilizando-se Programação Evolucionária (PE) [Spears et al. 1993] e utilizou o esquema apresentado em [Postal et al. 2007]. Para adicionar um problema a ser resolvido, o usuário deve adicionar strings que o autômato deve rejeitar, e strings que o mesmo deve aceitar, além de adicionar o alfabeto sobre o qual o autômato deve reconhecer as strings. Com base nesses dados fornecidos pelo usuário o PE tentará obter uma resposta. Sendo assim, as strings de aceitação e rejeição
Figura 1. Janela do Simulador devem cobrir as diversas possibilidades de geração da expressão regular, pois elas serão a especificação da mesma. Após a definição do problema, o usuário pode salvar o mesmo para posterior utilização com extensão.prob. O usuário pode modificar parâmetros para a execução do algoritmo, os quais são: taxa de mutação, número de gerações, tamanho de população, tamanho da população da função de otimização (caso o usuário selecione a opção de otimização) 1, e reaproveitamento de população. A figura 2 mostra a tela de configuração do PE. Figura 2. Tela de Configuração do PE 1 Maiores informações sobre a geração da população inicial com função de otimização em [Postal et al. 2007].
3.4. Testes Realizados e Considerações No atual estágio, foram realizados testes com o Resolvedor descrito acima, os quais consideraram as quatro situações abaixo: Geração da população inicial com função de otimização e reutilização da população (COCR); Geração da população inicial com função de otimização e sem reutilização da população (COSR); Geração da população inicial aleatória e reutilização da população (SOCR); Geração da população inicial aleatória e sem reutilização da população (SOSR). Para cada caso descrito acima, foram utilizados os seguintes parâmetros genéticos, os quais foram obtidos através de testes empíricos: Número de gerações: 110; Número de indivíduos de cada população: 60; Taxa de mutação: 100%. Além destes, outros parâmetros relevantes são: Número de indivíduos da função de inicialização otimizada: 200; Reaproveitamento de população a cada 10 gerações nos casos em que há reaproveitamento. Nestes testes, levou-se em consideração a solução obtida em cada caso de teste. Nestes testes, o conjunto foi formado por 26 problemas (solucionáveis por AFs e representáveis por Expressões Regulares), cada problema definiu 25 strings que deveriam ser aceitas e 25 strings que deveriam ser rejeitadas. Para cada caso de teste associado a um problema foram realizadas 10 execuções. Deste modo, para cada um dos quatro casos de teste foram realizados 260 testes. A figura 3(a) apresenta uma distribuição dos maiores fitness obtidos em cada teste realizado, dado um caso de teste. Dos 260 testes realizados, o caso de teste que apresentou melhor desempenho foi o COCR que obteve 107 soluções ótimas (fitness 100%), ou seja, em torno de 41.15% das soluções. O caso de teste SOCR obteve 101 soluções ótimas (38.84% das soluções). Já a figura 3(b) apresenta um gráfico que contém o número de problemas que obtiveram pelo menos uma solução ótima, dado um caso de teste. O caso de teste COCR encontrou pelo menos uma solução ótima para 23 dos 26 problemas existentes (88.46%). Já o caso de teste SOCR solucionou 21 problemas (80.76%). Os quatro casos de testes que foram utilizados apresentaram desempenhos distintos. Os casos de teste que utilizaram o esquema de reaproveitamento obtiveram os melhores resultados. O esquema de otimização da população inicial proporcionou uma leve melhora nos resultados. Para o caso de teste com melhor desempenho, 41.15% das execuções obtiveram resultados ótimos, sendo que 78.84% das execuções obtiveram valores de fitness maiores ou iguais a 95%. Com isto pode-se afirmar que o Resolvedor descrito neste trabalho apresentou resultados mais significativos se comparado com o trabalho realizado em [Welter et al. 2005], no qual as soluções raramente encontravam uma solução ótima para um dado problema. 4. Considerações Finais A implementação do primeiro módulo do PIRAMIDE mostrou ser capaz de simular corretamente os autômatos finitos apresentados à ele, sendo também capaz de gerar soluções
(a) Comparativo entre os casos de teste (b) Problemas com solução ótima em cada caso de teste Figura 3. Testes Realizados úteis a partir das cadeias de entrada que devem ser reconhecidas. Este sucesso nos incentivou a continuar o desenvolvimento do sistema, desenvolvendo simuladores e resolvedores para os outros principais modelos de máquinas de estado finito: autômatos de pilha e máquinas de Turing. As etapas subseqüentes do desenvolvimento do Projeto PIRAMIDE serão as seguintes: Implementação dos Simuladores/Resolvedores para APs e MTs: para este passo, o grupo já possui um protótipo de simulador de AP (uma pilha e determinístico), o qual está em fase de testes, para que possa ser integrado ao sistema. Após esta integração, o grupo iniciará o estudo e a implementação dos protótipos do simulador de MTs e dos dois resolvedores propostos. Minimização de AFs: Os autômatos produzidos pelo resolvedor, são, até o presente momento, disponibilizados ao usuário na forma em que o algoritmo genético os encontra, muitas vezes, tais soluções são pouco didáticas se comparadas a soluções desenvolvidas até mesmo por uma pessoa com pouco conhecimento de autômatos e expressões regulares. Para melhorar a apresentação das soluções obtidas, podese realizar a implementação de Minimização dos Autômatos, o que faria com que os mesmos fossem disponibilizados em sua forma mínima, facilitando seu entendimento. Transformação de AFN para AFD: outro recurso interessante seria a adição da operação de transformação de um AFN para AFD, sendo que este é um passo necessário para a minimização, esta transformação seria útil tanto para o resolvedor, quanto
para o simulador, onde o usuário poderia criar um AFN, simulá-lo, e posteriormente transformá-lo em um AFD, e obter sua forma mínima. Chat: neste passo, será implementado um ambiente tipo chat (bate-papo), onde os usuários poderão se comunicar por mensagens de texto, possibilitando interação e troca de conhecimento. Este ambiente tem a finalidade de permitir que, se algum usuário do sistema (aluno, professor) tiver dúvidas ou sugestões sobre os problemas ou sobre a teoria da disciplina, o mesmo possa pedir ajuda ou dar sugestão para outro usuário que estiver on-line através de mensagens de texto. Um primeiro protótipo para este ambiente foi apresentado em [Pereira et al. 2006]. A idéia é portar este protótipo para Java e integrá-lo ao PIRAMIDE, com os mesmos objetivos. Referências Deitel, H. and Deitel, P. J. (2003). Java Como Programar. Bookman, Porto Alegre, 4 edition. Koza, J. R. (1992). Genetic Programming: On the Programming of Computers by Means of Natural Selection. Bradford Book, Cambridge, Massachusetts. Lewis, H. R. and Papadimitriou, C. H. (2000). Elementos da Teoria da Computação. Bookman, Porto Alegre, 2 edition. Mitchell, M. (1997). An Introduction to Genetic Algorithms. MIT Press, London, England, 3 edition. Palazzo, L. A. M. (1997). Introdução a Programação Prolog. Editora UCPEL (Editora da Universidade Católica de Pelotas), Pelotas. Pereira, L. M., Postal, A., and de Castro, J. P. (2006). Um ambiente simulador para máquinas de estados finitos. In II Encontro Paranaense de Informática Educacional ENINED2006, Foz do Iguaçu - PR. Postal, A., Casagrande, C. C., Benfatti, E. W., de Castro, J. P., and Jaskowiak, P. A. (2007). Um sistema híbrido lógico-evolucionário para geração e simulação de autômatos finitos. In Encontro Paranaense de Computação II EPAC, Cascavel - PR. Spears, W. M., Jong, K. A. D., Bhck, T., Fogel, D. B., and Gaffs, H. D. (1993). An overview of evolutionary computation. In European Conference on Machine Learning. Welter, R., Postal, A., and de Castro, J. P. (2005). Módulo resolvedor de autômatos finitos para um ambiente de apoio ao ensino de teoria da computação utilizando algoritmos genéticos. In Encontro Paranaense de Computação EPAC 2005, Cascavel - PR.