INTRODUCCIÓN A LA TEORÍA DE AUTÓMATAS Y LENGUAJES

Anuncio
INTRODUCCIÓN A LA TEORÍA DE
AUTÓMATAS Y LENGUAJES FORMALES
Práctica 1
1. Introducción.
2. Listas.
2.1 Sintaxis.
2.2 Operaciones con listas.
2.3 Operadores lógicos y relacionales
3. Programación
3.1 Funciones simples
3.2 Programación procedural
3.2.1 Módulos
3.2.2 Estructuras condicionales y de repetición
4. Actividades
4.1 Actividades relacionadas con el manejo de Mathematica
4.2 Actividades relacionadas con la teoría de lenguajes formales
5. Soluciones a algunos ejercicios propuestos
1. Introducción.
El lenguaje de programación escogido para las prácticas es Mathematica [Wolfram,91]. En las
implementaciones que se van a llevar a cabo, hay que manejar objetos abstractos como son los
autómatas y las gramáticas, sobre los que se realizarán una serie de transformaciones. Tanto unos
como otras pueden ser concebidos como estructuras más complejas realizadas en base a otras más
sencillas. El interés de las prácticas no estriba en conseguir implementaciones eficientes, sino en
utilizar un lenguaje que facilite la construcción de estos objetos abstractos y el manejo de los
mismos. Teniendo en cuenta todos estos aspectos, veamos a continuación algunas de las
características de Mathematica que lo hacen adecuado para su uso en dichas prácticas.
Mathematica es un paquete de desarrollo para aplicaciones de tipo general en las que los aspectos de
desarrollo matemático, algebraico, numérico, simbólico y gráfico juegan un papel preponderante.
Mathematica está diseñado para tratar tanto cálculos matemáticos, así como aquellos cálculos
numéricos tradicionalmente llevados a cabo en FORTRAN. La mayoría de funciones especiales de la
física matemática y funciones matriciales, ya están construidas en Mathematica. Además, tiene una
extensa capacidad gráfica para la visualización de los resultados de los cálculos.
La aplicaciones de Mathematica engloban prácticamente todas las áreas de investigación y desarrollo
tanto en investigaciones científicas, de ingeniería, económicas, arquitectura, etc. Dentro de estas
mismas áreas se pueden utilizar tanto como herramienta de trabajo como herramienta docente para
aquellas materias que conlleven un alta carga de desarrollo matemático.
Mathematica como lenguaje de programación se diferencia del FORTRAN o C o PASCAL, por una
parte por su habilidad en el tratamiento de expresiones matemáticas, números, expresiones
simbólicas, etc., y por otra en que es un lenguaje interpretado. Como consecuencia de ser
interpretado, un cálculo tarda más tiempo en ejecutarse que en un lenguaje compilado, sin embargo,
el escribir un programa en Mathematica requiere una fracción del tiempo necesario para escribir el
mismo programa en C, y lo que es más importante, permite concentrar los esfuerzos en los detalles
conceptuales y no en los de implementación.
El sistema Mathematica es interactivo, lo cual significa que no hay que compilar programas. En
lugar de eso, los cálculos se hacen típicamente ejecutando una línea cada vez, y por tanto, los
resultados intermedios pueden verse inmediatamente. Mathematica es potente, puede usarse para
realizar grandes cálculos interactivos, evitando los típicos errores algebraicos, y los resultados se
pueden comprobar al instante. El lenguaje Mathematica es conciso, cálculos complicados pueden ser
escritos en pocas líneas (aunque hay que controlar las limitaciones de memoria del ordenador usado).
Es también flexible, pueden establecerse conexiones con otros programas ya existentes, etc..
Mathematica está siendo desarrollado por Wolfram Research, Inc. Actualmente está disponible en
prácticamente todas las plataformas de ordenadores. Los códigos se pueden transportar en ficheros
ASCII o en ficheros Mathematica Notebook, si se trabaja con versiones compatibles.
En esta primera práctica se pretende introducir algunos conceptos elementales del lenguaje asociado
a la aplicación Mathematica, así como el desarrollo de aplicaciones relacionadas con palabras y
lenguajes empleando esta herramienta.
2. Listas.
Quizá la estructura de datos más importante en Mathematica (y, sin duda la que nosotros
emplearemos más) es la lista. Se pueden emplear listas tanto para las palabras de los lenguajes con
los que trabajemos, como para las transiciones de los autómatas que reconozcan dichos lenguajes.
2.1. Sintaxis
list1 = {a, b, {c, d}} asigna a la variable "list1" la lista con primer elemento "a", segundo "b" y
tercero la lista {c, d}".
El elemento i-ésimo de una lista se referencia como nombre[[i]]. Así, list1[[3]] es {c, d}.
2.2. Operaciones con listas
Notas:
l
Las mayoría de las operaciones no actualizan las listas a menos que se asignen a una variable.
l
Mathematica es sensible a las mayúsculas. No es lo mismo Table que table.
En lo sucesivo, l1, l2... designarán listas, x, y... designarán elementos o variables, mientras que m,
n... designarán enteros positivos.
l
Las funciones definidas a continuación admiten variantes no especificadas aquí para no hacer
demasiado larga esta exposición. Solo se indica alguno de los usos más frecuentes. Para conocer
todas las posibilidades se puede teclear ?Nombre.
Sintaxis
Table[f(x), {x,n}]
Range[m]
Length[ l1]
Position[l1,x]
Join [l1, l2]
Union[l1, l2]
Intersection[l1, l2]
Complement[l1, l2]
Sort[l1]
Reverse[l1]
RotateRight[l1]
RotateLeft[l1]
First[l1]
Rest[l1]
Drop[l1, n]
Take[l1, n]
Append[l1, x]
Prepend[l1, x]
AppendTo[l1, x],
PrependTo[l1, x]
Delete[l1,n]
Select[l1, condición]
l1 /. izq -> dcha
Significado
Devuelve la lista {f(1), f(2)...f(n)}
Devuelve una lista con los m primeros
números naturales.
Devuelve la longitud de la lista.
Devuelve una lista con las posiciones de x en
l1. (¡cuidado !)
Concatena dos listas.
Devuelve una lista con los elementos que se
encuentran en l1 o l2 y los ordena.
Devuelve una lista con los elementos que se
encuentran en l1 y l2
Lista con los elementos de l1 que no estan en
l2.
Devuelve l1 ordenada de menor a mayor (no
actualiza l1).
Devuelve el reverso de l1.
Devuelve l1 con los elementos desplazados
un lugar a la derecha (el último pasa a ser el
primero).
Idéntico al anterior pero desplazando hacia la
izquierda
Devuelve el primer elemento de la lista.
Lista l1 sin el primer elemento.
Devuelve la lista sin los primeros n
elementos.
Devuelve los primeros n elementos de la lista.
Añade el elemento x al final.
Añade el elemento x al comienzo.
Idénticas a las anteriores pero actualizan la
lista.
Elimina el elemento n-ésimo de la lista.
Lista con los elementos de l1 que cumplen
condición.
Sustituye en l1 los elementos que se llaman
izq por dcha).
Pueden ser de utilidad las siguientes funciones de Mathematica:
Cases[lista, patrón]: Devuelve una lista con los elementos de lista que concuerdan con patrón.
Ejemplo 3
lista={{a,a},{b,a},{b,b},{a,b}}
Cases[lista,{a,_} ]
{{a,a},{a,b}}.
2.3. Operadores lógicos y relacionales
Son operadores que dan como resultado True o False:
Operación
Negación
Conjunción
Disyunción
Igualdad
No igualdad
Operador
!
&&
||
==
=!=
Además están los conocidos: >, <, >=, <=.
MemberQ[l1,x] : Devuelve True si x pertenece a l1 y False si no.
3.- Programación
Mathematica lleva incorporado un lenguaje de programaci ón propio que permite incorporar
funciones para realizar tareas específicas al mismo nivel que las funciones predefinidas.
Al ser un intérprete, el modo de trabajo puede ser totalmente interactivo; Así si ejecutamos la
expresión For[i = 1, i < 10, i++, Print[i]] se escriben en pantalla los dígitos del 1 al 9 (se ha
introducido la sentencia For cuya sintaxis es totalmente idéntica a la que tiene en C).
3.1.- Funciones simples
La forma mas sencilla de definir una función es n_función[var_]:=valor.
Ejemplos:
f[x_]:=x^2. A partir de este momento, si se teclea f[n], Mathematica devuelve el valor n2 .
g[x_,y_]:=2x + y (función de dos variables).
valab[x_]:=If[ x > 0, x, -x]; (se ha definido el valor absoluto de un número. Esta función lo es a
todos los efectos, se puede dibujar con Plot[valab[x], {x,-3,3}]. De paso se ha introducido la función
If, cuya sintaxis es If[condición, verdad, falso]).
kron[x_,y_]:= If[x==y, 1, 0]; (delta de Kronecker).
3.2.-Programación procedural
3.2.1.-Módulos
El concepto de módulo es totalmente parecido al de procedure en Pascal. Su esquema genérico es :
nombre[parámetros] : = Module [{variables locales separadas por comas},
Acciones (separadas por ;);
Return[nvar] (si el módulo devuelve un valor)
]
Ejemplo
Módulo que toma como entrada un número positivo n y devuelve la suma de los n primeros números
enteros.
suma[n_Integer]:=Module[{i,suma1},
suma1=0;
For[i =1,i <= n,i++,suma1 = suma1 + i];
Return[suma1];
]
Para ejecutarlo se escribiría por ejemplo suma[3] (que dar á como resultado 6).
3.2.2.- Estructuras condicionales y de repetición
Condicional
Sintaxis
If[condición, sent_verdad,
sent_falso]
Estructuras de repetición
Sintaxis
Do[sentencias,
{var,com,fin}]
Se ejecuta repetidamente sentencias desde var = com hasta var = fin. Por defecto el incremento de la
variable es 1. Se puede utilizar alternativamente{var, com, fin, paso}
Sintaxis
For[comienzo, test,
incremento, sentencias]
Se evalúa comienzo y se ejecutan sentencias e incremento hasta que test falla.
Sintaxis
While[condición,
sentencias]
Se ejecuta sentencias mientras condición es cierta.
4.- Actividades
4.1.- Actividades relacionadas con el manejo de
Mathematica
Listas
Para trabajar con listas es cómodo disponer de una función que las genere autom áticamente.
Haremos uso de las funciones Random[ ] y Table[ ].
Random[Integer,{imin,imax}] devuelve un número entero pseudoaleatorio comprendido entre los
enteros imin e imax.
Ejemplo: Random[Integer,{0,9}] devuelve un dígito.
l = Table[ Random[Integer,{imin,imax}],{n}] devuelve una lista de n números y los asigna a la
variable l. Si no se desea ver la lista por pantalla hay que terminar la expresión con ";".
Bucles simples
Ejercicio
Simulación de la función Length
La expresión Length[l], donde l es una lista, devuelve la longitud de l. Se pide, sin el uso de la
función Length, un fragmento de programa iterativo que simule dicha función.
Ayudas:
l
l
l
La lista vacía se representa mediante {}.
l = Rest[l] asigna a la variable l (que es una lista) la lista l sin el primer elemento.
Se recuerda la estructura repetitiva While[condición,expresiones]. Hay que tener cuidado en
no entrar en un bucle sin fin. En caso de hacerlo, Alt + "." aborta la ejecución.
Nota: Las palabras de un lenguaje se representarán mediante listas, por lo que el fragmento anterior
puede servir para calcular la longitud de una palabra de forma iterativa. La definición recursiva (ver
libro de apuntes, página 7) se puede transcribir casi literalmente con el siguiente programa recursivo:
long[{}]:=0;
long[l_]:=1+long[Rest[l]];
Una vez ejecutado este fragmento, ejecútese por ejemplo long[{a,b,a,a}].
Ejercicio
Escriba un fragmento de programa que suprima los elementos repetidos de una lista dejando el
primero de cada uno de ellos.
Ejercicio
Escriba un fragmento de programa que, dados una lista y dos enteros i y j, devuelva la lista con los
elementos de las posiciones i y j intercambiados.
Bucles anidados
Ejecute el siguiente programa y estúdielo detenidamente:
For[i=1, i<=4, i++,
Print["i___: ", i];
For[j=i+1, j<=5, j++,
Print["j : ", j]
]
]
Módulos.
Por defecto, todas las variables definidas en Mathematica son globales. Para evitar interferencias y
para generalizar las funciones que se definen se emplean los módulos. Por ejemplo, el programa
escrito como ejemplo de bucles anidados se puede introducir en un módulo de la siguiente manera:
imprime[m_Integer]:=Module [{i,j},
For[i=1, i<=m-1, i++,
Print["i___: ", i];
For[j=i+1, j<=m, j++,
Print["j : ", j]
] (*del For j*)
] (*del For i*)
] (*del módulo*)
Una vez ejecutado el módulo anterior, la función "imprime" está disponible en la sesión de
Mathematica. Ejecute por ejemplo imprime[5] .
Ejercicio
Escríbanse módulos para todos los fragmentos realizados anteriormente.
4.2. - Actividades relacionadas con la teoría de lenguajes
formales
En lo que sigue, una palabra se representa como una una lista de símbolos sobre un determinado
alfabeto. Así la palabra x=abbaca, se representará como {a,b,b,a,c,a}; la palabra vacía se representa
como la lista de longitud 0, es decir, {}.
Un lenguaje finito es un conjunto finito de palabras. Por tanto, un lenguaje se representa como una
lista cuyos elementos (palabras) son listas. Por ejemplo, el lenguaje L={abba, bb }, se representará
como {{a,b,b,a},{b,b}}; el lenguaje vacío se representa como {}.
Escribid módulos Mathematica que realicen los siguientes cálculos
Ejercicio 1
Con entrada una palabra x y un símbolo a, calcular |x|a (número de ocurrencias de a en x).
Ejercicio 2
Con entrada una palabra x y un entero positivo n, obtenga xn .
Ejercicio 3
Conjunto de prefijos de una palabra x.
Ejercicio 4
Conjunto de segmentos de una palabra x.
Ejercicio 5
Conjunto de segmentos de longitud k (k>0) de una palabra x.
Ejercicio 6
Producto de lenguajes finitos.
Ejercicio 7
Con entrada un lenguaje finito L y un entero n>0 calcular Ln .
Ejercicio 8
Palabras de longitud n sobre un alfabeto de entrada .(una manera posible consiste en usar la solución
a 6),
Ejercicio 9
Desarrollar una función que, dados un alfabeto de entrada y un número n, obtenga todas las palabras
de longitud menor o igual que n sobre ese alfabeto.
Ejercicio 10
Modificar el programa anterior obtenido a partir de la solución a 9 para obtener solamente las
palabras de longitud n. Puede ser una forma alternativa de resolver 8.
Ejercicio 11
Palabras de longitud n sobre un alfabeto que son palíndromos.
Ejercicio 12
Con entrada una palabra x, y un homomorfismo h, calcular h(x). Si, por ejemplo, se tiene un
homomorfismo h(a)=010, h(b)= λ , h se puede representar por una lista
halfa={{a,{0,1,0}},{b,{}}}
Ejercicio 13
Con entrada una palabra x, y una sustitución finita σ , calcular σ (x). Si, por ejemplo, se tiene una
sustitución, σ (a)={010,11}, σ (b)= {λ ,110,0} σ se puede representar por una lista
salfa={{a,{{0,1,0},{1,1}}},{b,{{},{1,1,0},{0}}}}.
Ejercicio 14
Dado un alfabeto Σ en el que se asume un orden en los símbolos y una palabra x sobre dicho
alfabeto, calcular la siguiente palabra en orden lexicográfico.
Ejercicio 15
Función que con entrada una palabra x, calcule f(x) definido como sigue:
Si |x|<2, f(x)=x
Si no, si x=aby, f(x)=af(y)b
5.- Soluciones a algunos ejercicios propuestos
Solución al ejercicio 1
frec[pal_,sim_]:=Length[Position[pal,sim]]
Solución al ejercicio 4
seg[pal_]:=Module[{l,i,j,w},
l={{}};
For[i=1,i<=Length[pal],i++,
For[j=i,j<=Length[pal],j++,
w=Take[pal,{i,j}];
l=Union[Append[l,w]]
]
];
Return[l]
]
Solución al ejercicio 9
Lo que se presenta no es un programa. A partir de este algoritmo, el alumno, mediante un traducción
casi literal a Mathematica, podrá obtener un programa.
Módulo_listar[n :Entero, Alfabeto :lista]
listado = {cadena_vacia};
auxiliar = {cadena_vacia};
Para i=1 hasta n hacer
auxiliar2 = ∅;
Para j = 1 hasta Longitud de auxiliar hacer
Para k = 1 hasta Longitud de Alfabeto hacer
nuevapal = prolongar la palabra j de auxiliar con el símbolo k del
Alfabeto ;
auxiliar2 = Añadir a auxiliar2 la palabra nuevapal;
listado = Añadir a listado la palabra nuevapal ;
FinPara
FinPara
auxiliar = auxiliar2 ;
FinPara
Resultado : listado
Fin Módulo
Solución al ejercicio 12
(w es la palabra e imag el homomorfismo):
h[w_,imag_]:=Module[{hw,i,l},
hw=w;
For[i=1,i<=Length[w],i++,
l=Cases[imag,{w[[i]],_}];
hw[[i]]=l[[1,2]]
];
hw=Flatten[hw];
Return[hw]
]
Bibliografía
[Wolfram,91]. S. Wolfram. Mathematica : A System for doing mathematica by computer. Addison
Wesley, 1991.
Descargar