====== Automates de Localisation ====== ===== Implantation Informatique ===== La mise en oeuvre informatique est basée sur les files, les états et les [[m1ilc:search_fsm|]]. Opérations de base pour les files : * FILE_VIDE() crée puis retourne (un pointeur sur) une file vide * FILE_EST_VIDE(F) retourne vrai si la file F est vide et faux sinon * ENFILER(F,x) ajoute l'élément x en queue de la file F (c'est une file, pas une pile) * TETE(F) retourne l'élément situé en tête de la file F **sans l'enlever** * DEFILER(F) supprime l'élément en tête de la file F * DEFILEMENT(F) retourne l'élément en tête de la file F et le supprime de la file (''TETE(F);DEFILER(F);'') * LONGUEUR(F) retourne le nombre d'éléments dans la file F ==== Les états ==== Un automate comporte un ensemble A des états "acceptants"; ici on considère qu'un état y appartenant a l'attribut //terminal//. Un automate a aussi une application T: Q\times \Sigma \rightarrow Q dite les transitions. Ici on considère que les états figurant dans les transitions de qi sont ses successeurs (//Succ//). On propose deux opérations standard sur les états : * NOUVEL_ETAT() : crée puis retourne (un pointeur sur) un état non terminal d'ensemble des successeurs étiquetés vide. * CIBLE(p,a) : retourne un état sachant l'état p et l'étiquette a, ou la valeur spéciale NIL si une telle étiquette n'existe pas. Autrement dit, s'il existe un état q tel que (a,q) ∈ Succ[p]-- T(q,a)=p -- alors c'est lui. ===== Arbre d'un dictionnaire ===== Soient X⊆ A* un __dictionnaire__ sur A, c'est à dire un langage fini non vide ne contenant pas le mode vide ε, et y ∈ A* le texte dans lequel on cherche à localiser toutes les occurrences de mots de X. L'automate A(X) déterministe, appelé arbre du dictionnaire de X, reconnaissant X est défini de la façon suivante : * Préf(X) : l'ensemble des états * ε : état initial * X : l'ensemble des états terminaux (acceptant) * flèches (transitions) sont de la forme :(u,a,ua) ((pourquoi 'u,a,ua' et non 'u,a,v'?)) ==== ARBRE(X) : Construction de l'automate A(X) ==== - M <- NOUVEL_AUTOMATE() : un état q0 sans successeurs initialement - pour chaque mot x ∈ X faire - t <- initial[M] : t est un état - pour chaque lettre a de x faire - p <- CIBLE(t,a) : la lettre est-elle successeur - si p = NIL alors - p <- NOUVEL_ETAT() - Succ[t] <- Succ[] ∪ {(a,p)} - t <- p - terminal[t] <- vrai - retourner M Pour chaque mot de X, on repars de la racine ε et suit l'arbre de parent en fils tant qu'on retrouve la lettre suivant du mot dans un noeud fils. Lorsqu'on ne trouve plus un fils correspondant à la lettre, on on crée un et poursuit le développement de l'arbre à partir de lui (on crée des fils successivement pour chacune des lettres restant de x). === Exemple/Exercice === Automate A(X) reconnaissant {aa, abaaa, abab } ε | \ a ?! / \ a b | | \ # a ?! / \ a b / | | ?! a # | # - x <- 'aa' - p <- CIBLE(racine, a) - p == NIL - p <- NOUVEL_ETAT() - Succ[racine] ∪= ('a', p) - t <- p ===== Localisation de Plusieurs Mots ===== Un automate D(X) déterministe det complet permet de reconnaître le langage A*X. Ses états sont les préfixes des mots de X. Ainsi, lors d'une lecture séquentielle du texte y, il suffit de ne retenir que **le plus long des suffixes de la partie de texte déjà lue qui est un préfixe d'un mot de X**. D(X) n'est pas minimal en général mais il est relativement simple à construire. Il est aussi à la base des différentes variantes d'automates. D(X) possède les mêmes états que A(X) et le même état initial. Il contient les états terminaux et les flèches de A(X). === Automate-dictionnaire === Afin de formaliser l'automate de localisation du dictionnaire X ⊆ A* on introduit la fonction * h : A* -> Préf(X) définie par * h(u) = plus long suffixe de u qui appartient à Préf(X), pour tout mot u ∈ A* === L'automate D(X) est déterministe et complet === * comme A(X) * Préf(X) = ensemble des états * ε = état initial * nouveautés : * terminaux (acceptants) = Préf(X) ∩ A* X * flèches sont de la forme (u, a, h(ua)) === Proposition === La fonction h satisfait les propriétés suivantes : - u ∈ A* X <=> h(u) ∈ A* X pour tout u ∈ A* - h(ε) = ε - h(ua) ) h(h(u)a) pour tout (u,a) ∈ A* × A == Preuve == 1. On pose u ∈ A* X. * => u = vx avec v ∈ A* et x ∈ X * => x Suff h(u), par définition de h * => h(u) ∈ A* X. * Réciproquement on pose h(u) ∈ A* X. * => u ∈ A* X. parce que h(u) Suff u etc. FIXME : à completer ==== Construction de l'automate-dictionnaire ==== ==== Localisation des occurrences ==== ==== Implantation par matrice de transition ==== L'automate D(X) étant complet, il est possible d'implanter sa fonction de transition par sa matrice de transition (algorithme non donné). ===== Automate avec fonction de suppléance ===== ===== Automate avec optimisation de la fonction de suppléance ===== ===== Implantation avec successeur par défaut =====