Déterminisation des automates


Introduction

Un automate non-déterministe n'est pas toujours utilisable en pratique car il demande pour la reconnaissance un calcul assez complexe et plus lent que pour un automate déterministe. Ainsi, dans certains cas, il est utile de transformer un automate non-déterministe en un automate déterministe équivalent. On a vu pour la reconnaissance que l'on manipulait en fait des ensembles d'états et non des états. La théorie montre que l'on peut créer un nouvel automate déterministe, cette fois-ci, dont les états sont les ensembles obtenus lors de la reconnaissance et qui reconnait le même language que l'automate initial. C'est ce que nous nous proposons de faire dans ce TD. Dans un premier temps, nous n'examinerons que les automates sans e-transitions, puis nous écrirons un programme qui supprime ces transitions lorsqu'il y en a.

1   Déterminisons les automates

Reprenons la représentation introduite au premier TD :
type ('a,'b) automate = { init : 'a list ;
    term : 'a list ; trans : ('a * 'b * 'a) list};;
L'algorithme que nous allons employer est le suivant : en partant de l'ensemble des états initiaux, on calcule d'abord tous les ensembles d'états que l'on peut atteindre à partir de celui-ci et par toutes les lettres de l'alphabet, puis on recommence sur les nouveaux états obtenus jusqu'à ne plus trouver de nouveaux états. Il faut donc à chaque étape traiter une liste d'états (qui est un état du nouvel automate), ajouter les nouveaux états obtenus à une liste qui contient les états déjà vus ainsi qu'à une liste qui contient les états restants à traiter, jusqu'à ce que cette dernière liste soit vide. Pour traiter une liste d'état, plutôt que d'utiliser la fonction image, nous allons le faire en un seul parcours de la liste des transitions : à chaque nouvelle transition, on ajoute l'état dans une liste de type ('b * ('a list)) list, ('a étant le type des états de l'automate et 'b étant le type de ces lettres), qui contient les transitions trouvées au départ de l'état en cours de traitement. Ensuite, on parcourt cette liste et on ajoute les nouvelles transitions à la liste des transitions du nouvel automate et les nouveaux états créés à la liste des états déjà vus et à la liste des états restants.
Question 1   Créer une fonction qui calcule la liste de type ('b * ('a list)) list contenant les transitions trouvés au départ une liste d'états données :

nouv_trans : 'a list -> ('a * 'b * 'c) list -> ('b * 'c list) list
'a list est la liste d'états et ('a * 'b * 'c) list la liste des transitions de l'automate.
Question 2   Créer la fonction qui déterminise un automate :

determinise : ('a, 'b) automate -> ('a list, 'b) automate
Je rappelle que les états finaux de l'automate obtenu sont les états qui contiennent au moins un état final de l'automate de départ.

2   Les e-transitions

Dans certains cas, il est utile d'ajouter un type particulier de transition qui ``reconnaissent'' le mot vide e.
Question 3   A partir du type automate, créer un type automate_e permettant de coder les e-transitions.
Question 4   En s'insprirant de la fonction image pour les automates non-déterministes, créer une fonction cloture qui donne la cloture d'une liste d'états : cloture : ('a, 'b) automate_e -> 'a list -> 'a list
Question 5   A partir des fonctions image et cloture, créer une fonction image_e prennant en compte les e-transitions : image_e: ('a,'b) automate_e -> 'a list -> 'b -> 'a list
Question 6   Montrer que l'on peut enlever les e-transitions dans un automate non-déterministe (c'est à dire obtenir un automate non-déterministe sans e-transitions qui reconnait le même language) et écrire la fonction réalisant cette opération. ote_e: ('a,'b) automate_e -> ('a,'b) automate

This document was translated from LATEX by HEVEA.