domingo, 12 de octubre de 2014

Realizando cambios...

Buenos días. Hace casi once meses que no publico nada pero entre el trabajo y los estudios no he tenido mucho tiempo para una de mis aficiones,  programar.

Lo primero disculparme de los continuos cambios en el código ya funcional.  Un programador profesional antes de ponerse a escribir código, habrá pasado meses modelando su aplicación con un estudio previo de todas las clases y métodos que le irán haciendo falta.  De esta manera tendrá las ideas más claras y sabrá que quiere exactamente al desarrollar su código y no estará realizando cambios estructurales como en mi caso y el tiempo invertido en ese estudio previo lo verá pronto recompensado.

Pero yo en este proyecto no quiero aplicarlo. Precisamente pretendo explicar razonadamente y mediante fallo y error el por qué del código. De este modo el lector se sentirá más integrado al ir formándose en él la estructura y concepto del proyecto a la vez que en mí, cosa bien distinta sería si simplemente me dedicara a explicar un código ya finalizado.

Después de toda esta parrafada estos son los cambios más importantes:

Repartición del peso del autómata

La aplicación poseía sólo un gran autómata que reconocía los comandos, números matemáticos y secuencias de palabras. El problema de esto eran los símbolos, es decir, trabaja con números, letras otros símbolos y cada vez que se le añade otra ER realiza su tabla de transiciones para todos estos símbolos independientemente de que la nueva ER los use.

Al terminar de desarrollar los autómatas propuse repartir el peso en otros autómatas según los símbolos. Lo llevé a cabo:

- Autómata Comandos
- Autómata Matemático
- Autómata Alfabético
- Autómata Otros Símbolos
- Autómata Relaciones Sintácticas
- Autómata Dinámico

De este modo las ER que comienzan por # al autómata de comandos, las que empiezan por $ al de relaciones sintácticas, números y símbolos matemáticas al matemático, las ER que representan palabras al alfabético y los que contienen otros símbolos como los interrogantes,  exclamaciones, etcétera,  al de otros símbolos.

El dinámico estaría destinado a las ER que introduciría el usuario en tiempo de ejecución.

Al cargar los autómatas tardaba un poco y algo de ahorro en memoria, pero no muy significativo. Encontré más inconvenientes que ventajas:

- Para comprobar una ER se ha de ir haciéndolo secuencialmente por todos los autómatas para que en el peor de los casos no pertenezca a ningún autómata después de realizar seis consultas.

- Las ER ya pertenecientes autómata no pueden ser utilizadas en otro autómata distinto y si quiere hacerse ha de duplicarse la ER recursivamente volviendo el problema.

- Se pierde el dinamismo para introducir nuevas ER en tiempo de ejecución.

He optado por el camino intermedio:

- Autómata Comandos
- Autómata Relaciones Sintácticas
- Autómata General

De este modo se conserva el dinamismo mediante el autómata general siendo los otros dos estáticos.

Base de datos para guardar la información

Desde el principio mantuve la política de no usar una base de datos simplemente por admitir que sería un desperdicio al no aprovechar su potencial en sus consultas, concurrencia, etcétera y sólo utilizarlo como almacén.

Pero tras mucho deliberar, al final he cedido. Por dos razones:

- Tener la información organizada en una única base de datos en lugar de numerosos ficheros .dat con dicha información sin ninguna estructura.

- Visualización de los datos que se van almacenando para comprobar que todo va como debe de hacerlo.

Aún así sólo me limitaré a cargar los datos al iniciar el programa y a actualizar las tablas al finalizar, sin realizar consultas o actualizaciones en tiempo de ejecución ya que el que debe organizar la información con el programa en marcha, es la propia aplicación.

Esto conlleva la modificación del todo el código que cargaban y guardaban las listas de cadenas.

Eliminación de función de cadena

Una misma palabra puede funcionar como determinante en unos casos o como pronombre en otros, por ejemplo. La palabra morfológicamente hablando es la misma, es al darle un sentido sintáctico cuando adquiere su funcionalidad.  Para evitar reiteración de cadenas y lo peor de todo, con su función sin definir en muchos casos esperando a la fase sintáctica, he optado por quitar ese parámetro. Más adelante se le dará su funcionalidad de otro modo.

Reorganización de tipos: subtipos

Un número natural, un número entero o incluso un número fraccionario tiene en común que es un número pudiéndose tratar del mismo modo en muchos casos.

Extendiendo este concepto al resto de palabras, la mayoría de tipos pueden clasificarse mejor en subtipos.

Trabajo laborioso al tener que modificar las cadenas, listas e incluso las interfaces.

Replanteamiento de los números

He separado la representación de un número matemáticamente hablando de su cardinal.

Un número matemáticos no tiene género.

Dos cardinales pueden representar el mismo número matemáticos y ser distintos:

- Cardinal: Uno, número matemático: 1
- Cardinal: Una, número matemático: 1
- Cardinal: Un, número matemático: 1

Tres cardinales naturales hacen referencia a un mismo número natural,  esto significa que un cardinal natural se refiere a un único número natural y un número natural puede ser referido por varios cardinales naturales.

La diferencia entre estos cardinales es el género.

La cosa se puede conplicar más si pensamos que 1/1, 2/2, tres entre tres, etcétera también representan a 1.

Voy a intentar explicar cómo trabaja con los números naturales y sus correspondientes cardinales naturales:

Número natural: lo abrevio con N.
Cardinal natural: con C.

- Un N tiene una lista L de Cadenas que le hacen referencia.

- Un C tiene un número matemático (en este caso natural) único al que se refiere,  además del género y número.

Algoritmo para la inserción de un natural:

1. Buscar N en la estructura de datos por si ya estuviera tratado con anterioridad.
1.1. En el caso de que exista se recupera y será con este con el que trabajaremos en los siguientes pasos.

1.2. Y en el supuesto de que no exista, se crea e inserta en la estructura de datos y se trabajará con éste.

2. Se calcula el C para el género Masculino, otro Femenino y el Neutro.  Para simplificar la explicación no se va a distinguir entre estos, pero todo lo que se haga con C se hará por triplicado.

3. Buscar C en la estructura general de datos.

3.1. De forma idéntica que con N, si C existe se trabajará con ese objeto.

3.2. Y si no existe, se crea, se inserta y se trabaja con el nuevo.

4. Referenciado entre N y C:

4.1. C (número matemático) ← N

4.2. Si en la lista de N no hay referencia a C entonces Lista (N)← C

Algoritmo para la inserción de un cardinal natural:

1. Independientemente del género de C obtenemos su N.

2. Con N se puede usar directamente el algoritmo anterior.

Este concepto se amplía con el resto de tipos de números y cardinales. Aunque se complica, la base es la misma.

No hay comentarios:

Publicar un comentario