n autómata finito sirve para reconocer cierto tipo de lenguajes. Antes de definir formalmente el concepto de lenguaje aceptado por un AF necesitamos definir los conceptos de configuración y cálculo en un autómata finito.
La configuración de un autómata finito (sin importar el tipo) en cierto instante viene dada por el estado del autómata en ese instante y por la porción de cadena de entrada que le queda por leer o procesar. La porción de cadena leída hasta llegar al estado actual no tiene influencia en el comportamiento futuro de la máquina. En este sentido podemos decir que un AF es una máquina sin memoria externa; son los estados los que resumen de alguna forma la información procesada.
Formalmente una configuración de un AF es un elemento (q,w) ∈ (Q × V*). Algunos tipos de configuraciones especiales son:
Configuración inicial : (q0,w), donde q0 es el estado inicial y w la palabra de
entrada.
Configuración de parada: cualquier configuración en la que el autómata puede parar su ejecución, bien porque se haya procesado toda la entrada o bien porque se haya llegado a una situación donde no es aplicable ninguna transición.
Configuración de aceptación: (qF , λ), donde qF es un estado final del autómata.
Una vez alcanzada esta configuración el autómata puede aceptar la palabra. Si consideramos el conjunto de las configuraciones de un autómata finito, podemos definir una relación binaria ├ ⊆ (Q × V*) × (Q × V *) que llamaremos relación de cálculo en un paso.
Intuitivamente si dos configuraciones Ci y Cj están relacionadas mediante la
relación ├ y lo notamos como Ci ├ Cj , quiere decir que podemos pasar de la configuracin Ci a la Cj aplicando una sola transición y diremos que “la
configuración Ci alcanza en un paso la configuración Cj”.
Para definir formalmente la relación de cálculo en un paso ├, distinguiremos tres casos correspondientes a los tres tipos de autómatas que hemos visto:
Si tenemos un AFD, la relación de cálculo en un paso se define de la siguiente forma:
Si tenemos un AFND, la relación de cálculo en un paso la se define:
Cuando queramos distinguir el autómata M al que refiere la relación, se usaría ├M.
La clausura reflexiva y transitiva de la relación ├ es otra relación binaria
├ * ⊆ (Q × V*) × (Q × V *), que llamaremos relación de cálculo. Diremos que la “configuración Ci alcanza (en cero o más pasos) la configuración Cj”, y lo notamos
como Ci ├ * Cj , si se cumple una de las dos condiciones siguientes:
1. Ci = Cj , o bien,
2. ∃C0,C1, ...Cn, tal que C0 = Ci, Cn = Cj , y ∀ 0 ≤ k ≤ n−1 se cumple que Ck ├ Ck+1
A una secuencia del tipo C0 ├ C1 ├ . . . ├ Cn la llamaremos cálculo en n pasos,
abreviadamente C1├* n pasos Cn.
Ejemplo: Considerando el AFD de la figura 6 podemos decir que (q0, 01) ├ (q0, 1),
(q0, 1) ├ (q1, λ) y por tanto (q0, 01) ├* (q1, λ). También (q1, 101) ├ (q2, 01) y en
varios pasos (q2, 0011) ├*(q1, 1).
Por otra parte para el AFND de la figura 8 tenemos, por ejemplo, que (q0, abb) ├ (q0, bb) y también (q0, abb) ├ (q3, bb). Al ser el autómata no determinista vemos
que a partir de una misma configuración, en este caso (q0, abb), se puede llegar
en un paso de cálculo a dos o más configuraciones distintas. Esta situación no puede producirse en un AFD.
Para el AFND-λ de la figura 12 el cálculo (q1, bb) ├ (q2, bb) es un ejemplo donde
se produce una transición que implica un cambio de estado sin consumir símbolos de entrada. Esto es posible porque q2 ∈∆(q1, λ).
Si tenemos un autómata finito M = (Q, V, δ, q0, F), se define el lenguaje aceptado
por M y lo notamos L(M), como:
L(M) = {w ∈ V *| (q0,w) ├*(qF , λ) donde qF ∈ F}
Es decir, una palabra w Será aceptada por el autómata M, si partiendo de la configuración inicial con w en la cinta de entrada, el autómata es capaz de alcanzar una configuración de aceptación. Dependiendo del tipo de autómata de que se trate, ├*hará referencia a la clausura reflexiva y transitiva de la relación ├ en un AFD, en un AFND o en un AF con λ-transiciones.
En un autómata finito determinista, el hecho de que una palabra w sea aceptada por el autómata nos asegura que existe un único camino en el diagrama de transición que nos lleva del nodo etiquetado con el estado inicial al nodo etiquetado con el estado final y cada arco que se recorre en este camino ésta etiquetado con un símbolo de la palabra. Podríamos simular la ejecución de un autómata finito determinista mediante un programa que codifique la función de transición y simule los cambios de estado. Si |w| = n entonces el programa puede determinar si la palabra es aceptada o no en O(n).
En el caso de un AFND o un AFND-λ no podemos asegurar que exista un único camino en el diagrama que nos lleve del estado inicial a un estado final consumiendo los símbolos de la palabra. Incluso puede que para una palabra w ∈ L(M) podamos tener una camino que no acabe en estado final o que llegue a un estado desde el que no se pueda seguir leyendo símbolos. Esto es debido al no determinismo, que hace que los cálculos en estos autómatas no estén perfectamente determinados. Si quisiéramos simular un autómata no determinista para decidir si una palabra es aceptada o no, tendríamos que usar alguna técnica de retroceso o backtracking para explorar distintas posibilidades hasta encontrar un cálculo correcto que reconozca la palabra o determinar que la palabra no es aceptada si se han explorado todos los posibles cálculos y ninguno de ellos conduce a un estado final. Esto nos llevaría a un algoritmo de tiempo exponencial para reconocer una palabra. De ahí que a efectos prácticos, como en la construcción de analizadores léxicos o reconocimiento de patrones en un texto, lo deseable es tener un autómata finito determinista.
Ejemplo Recordemos los AFs ya vistos y veamos ahora cual es el lenguaje aceptado por ellos. El diagrama de la figura 8 correspondiente a un AFND permite ver que L(M) es el lenguaje descrito por la expresión regular (a + b)*(aa + bb)(a + b)* que consiste en aquellas cadenas sobre el alfabeto V = {a, b} que contienen al menos una ocurrencia de la subcadena aa o bb. Por ejemplo, la cadena abb es aceptada, ya que tenemos el cálculo:
(q0, abb) ├ (q0, bb) ├ (q1, b) ├ (q2, λ), y q2 ∈ F
Sin embargo podemos tener otro cálculo que no conduce a estado final: (q0, abb) ├ (q0, bb) ├ (q0, b) ├ (q1, λ), q1 /∈ F
e incluso un cálculo que no llega a consumir la palabra: (q0, abb) ├ (q3, bb) ├ (y no puede seguir)
A partir del diagrama del AFD de la figura 6 no es tan sencillo ver cual es el lenguaje aceptado. Pero, según se vera mas adelante con el teorema de kleene se tiene un método exacto para encontrar este lenguaje. En este caso el lenguaje aceptado es el descrito por la expresión regular (0 + 1 (10*1)*)* 1 (10*1)*