Generación de Código e Inteligencia Artificial

A finales de los setenta y principios de los ochenta (ya en el siglo pasado ;-)) estuve aprendiendo de todo sobre programación, lenguajes de programación y ciencia de la computación en general. Eran los días de COBOL, BCPL, ensamblador de IBM/360, JCL (Job Control Language), tarjetas perforadas, sistemas operativos Pick, Algol/W, Fortran, PL/I, y C (mi preferido) (en CP/M, DOS, Unix/Xenix). Uno de mis temas preferidos (entonces y ahora) era la Inteligencia Artificial, un término amplio (aún más en estos días). Esos días fueron la época dorada de los sistemas expertos (recuerdo Mycin, EMycin, el configurador automático de DEC, y otros). En ese entonces, estuve escribiendo montones de código C, entonces, como programador perezoso que soy, comencé a escribir mis propios utilitarios en C para generar más programas C ;-). Desde entonces que tengo na idea:

La Generación de Código debe ser una aplicación de Inteligencia Artificial

Hacia finales de los ochenta, principio de los noventas, el monto de código a escribir para tener una aplicación profesional fue disminuyendo (nuevas IDEs, “wizards” y librerías). Pero fue un estado transitorio: la complejidad impuesta por el mercado, por los requerimientos de los clientes, la aparición de aplicaciones en línea, concurrencia en todo, nuevas tecnologías y lenguajes (Windows, GUIs…) todo conspiró para el aumento del esfuerzo que debe ser empleado para cualquier aplicación no trivial. Abracé a Java a mitad de los 90, y luego a .NET en 2001. Grandes librerías de clase, nuevos trucos, estilos arquitectónicos, patrones, JSP, JSF, MVC, ASP.NET, Javascript, Ajax, algo de PHP, computación distribuida, capas físicas, escalabilidad, seguridad, rendimiento, …. De nuevo, el desarrollode software se transformó en ámbito complejo. Y ahora, tenemos mobile, Android, Windows Phone 7, ASP.NET MVC, nuevos JDKs, JVMs, lenguajes dinámicos… Podría continuar enumerando tecnologías sin por siempre… ;-)

Por eso, al comienzo de este siglo, decidí comenzar my proyecto de generación de código, AjGenesis. Primero, éste es el proceso actual que uso en mis proyectos:

(Jeje… Ok, son un desarrollador, no un diseñador ;-))

Los modelos de partida (a la izquierda) son de libre definición: uno puede usar el modelo que quiera y le convenga, no están “fijos”. Esta es una decisión clave: yo quiero que podamos tener la libertad para comenzar con cualquier modelo que elijamos como base para nuestra generación de código. Pero es importante destacar: debe haber un MODEL. No es sólo generación de código: lo que propugno es GENERACION DE CODIGO DESDE UN O VARIOS MODELOS. Usualmente, tengo un modelo abstracto, como:

<Project>
	<Name>AjApp</Name>
	<Description>Building an Application using AjGenesis</Description>
	<Model>
		<Entities>
			<Entity Source="Entities/Customer.xml"/>
			<Entity Source="Entities/Supplier.xml"/>
		</Entities>
	</Model>
</Project>


y uno o más modelos dependientes de la tecnología como:



<Technology>
	<Programming>
		<Dialect>CSharp4NhMvc</Dialect>
	</Programming>
	<Database>
		<Dialect>MsSql</Dialect>
		<Name>AjTestNh</Name>
		<Host>.\SQLEXPRESS</Host>
	</Database>
	<NHibernate>
		<Dialect>NHibernate.Dialect.MsSql2000Dialect</Dialect>
	</NHibernate>
</Technology>


(más información en mis AjGenesis posts (en inglés) y mis posts (en español)). Los modelos se pueden escribir en XML o en texto. O podemos usar nuestros propios modelos (ver Models for Code Generation in AjGenesis, Modelos para Generación de Código en AjGenesis). Los artefactos de texto pueden ser Java, C#, VB.NET, Ruby, cualquiera que necesitemos. Como ejemplo de lo flexible que es este “approach”: cuando comencé con los ejemplos de AjGenesis generé PHP y JSP 1.x. Desde entonces, prácticamente sin cambiar esencialmente el proceso, pude generar para PHP (nuevas versiones), Java, JSP 2.x, Hibernate, NHibernate, ASP.NET 1.x, ASP.NET 2.x, ASP.NET MVC… Pude adaptarme a cualquier tecnología basada en código. Para conseguir tal flexibilidad, no hay IDE asociada en el proyecto. Tiene una interfaz espartana, pero me gusta. Me permite ir explorando nuevos caminos, sin estar anclado a una IDEA, aunque hace menos atractivo su uso.



Desde su concepción, adopté un lenguaje dinámico, AjBasic, para soportar tareas y “templates” (plantillas): yo no quería SOLAMENTE un motor de transformaciones, de un modelo a código mediante plantillas. Quería tener el poder de un lenguaje GENERAL, pero que a la vez permita manejar obj.Propiedad, sobre un objeto no tipado de antemano: los objetos son tan maleables como los modelos iniciales, que son tratados accedidos como objetos. ¿Por qué un lenguaje general, y no uno que sólo soporte algún if y for a nivel de templates? PARA SOPORTAR LA EXTENSIBILIDAD, más allá de la expansión de plantillas. Y para poder acceder a toda la librería .NET (uno no debe desperdiciar una librería de clases cuando la encuentra). Y ¿para qué más? Sorpresa! Para ….. soportar Inteligencia Artificial!



Afirmo:



La Generación de Código desde un Modelo puede ser implementada como un Sistema Experto, y entonces, es una clara aplicación para Inteligencia Artificial



Gráficamente:





Podemos ver a los desarrolladores de software como expertos humanos. Podemos “destilar” su experiencia y colocarla en sistemas expertos, agregdos al proceso de generación de código. Algunos ejemplos:



- Un sistema experto peude usar un motor de reglas para tomar decisiones, pequeñas, medianas o grandes. Una pequeña: “El reporte web puede tener muchas filas, necesitamos paginación, filtro, y ordenar por tales columnas, que son las más importantes para este dominio… “. Y entonces, alguna parte del sistema parte recomendaría: “Sí! Podemos usar JQuery y JQuery.UI, hacer filtro del lado del servidor, servir los datos desde este acceso Ajax… etc…”… y otra parte (sí, el sistema experto podría ser “multi-mente” ;-)) diría “No! Necesitamos filtro del lado del servidor, y necesitamos estas consultas y servicios para cumplirlos, y estos puntos de acceso Ajax y … “ ¿Se capta la idea?



Una micro-decisión que empleé el año pasado en un proyecto real: algunas entidades en el modelo abstracto fueron marcadas con el atributo “massive” (masiva) indicando: “tenemos gran cantidad de instancias de la entidad X en el sistema”. Entonces, cuando en la interfaz de usario necesitamos seleccionar una de esas entidades X, en vez de presentar una lista desplegable, el motor de generación de código (con lenguaje general que decide con if, funciones y rutinas) colocó una caja de texto de búsqueda, con auto-complete, y un servicio Ajax en el servidor.



Podría usar para el modelo abstracto una ontología de base sobre la cual poder hacer inferencias y tomar decisiones. Ejemplo:



- Cada entidad puede ser: una persona, una compañía, un lugar, un bien físico, un evento, un documento. Entonces, el sistema experto podría inferir: un lugar físico tiene una dirección; un bien físico debe ser guardado en un lugar físico; un documento X debe ser necesario para representar el movimiento de un bien físico de un lugar a otro; una persona puede ser un empleado; cada empleado tiene seguridad social… etc…. etc.. Entonces, cuando necesitamos un reporte de los eventos X, podemos inferir: los necesitamos ordenados por fecha, agrupados por lugar físico, etc..… etc… Tal documento tiene un total de moneda, sería interesante tener reportes agrupados por distintos criterios (por ejemplo, por parte involucrada en ese documento, un cliente, una compañía, una persona). Y por mes. Ah! Y necesitamos un gráfico de torta, y … y así, así… ;-)



Podría agregar un motor de reglas para tomar algunas de estas decisiones, con reglas tipo “si la entidad X es masiva y la interfaz de usuario es web y podemos usar JQuery entonces… “. O reglas como: “si la entidad X hereda de la entidad Y y necesitamos persistencia, podemos adoptar la estrategia tabla-por-jerarquía. O tal vez alguna otra parte del sistema experto recomiendo tabla-por-clase-concreta. Y de ahí, generar los mapeos, la base de datos”. O: “esta entidad X es un documento que tiene una fecha; necesitamos agregar un índice sobre esta columna fecha/hora”. Es una forma de poner explícitamente las razones por las que tomamos decisiones como ésa cada día. Actualmente, en el proceso de AjGenesis, muchas de esas decisiones están en las tareas y en pistas que quedan en los modelos abstractos y de tecnologías. Pero bien podrían colocarse a nivel del sistema experto.



Como gran panorama, la generación de código desde un modelo involucra:



- Tenemos este punto de partida: modelos abstractos, modelos técnicos (con restriccionos como “este sistema lo necesitamos en ASP.NET MVC 3”)



- Esta es el entregable esperado (algún sistema ya armado parcialmente, que sirvió como prueba de concepto de las tecnologías que vamos a usar)



- Y tenemos todo este conocimiento experto destilado de la experiencia de nuestros desarralloradores, buenas prácticas, patrones…  Y con todo esto podemos ir desde el comienzo hasta el final esperado, aprovechando el conocimiento acumulado, configuraciones de ORM, librerías de inyección de dependencias, patrones de UI, patrones de implementación, conocimiento en la creación de bases de datos normalizadas, etc..



El desarrollo de software y su arquitectura está relacionados con:



- Conocer lo que necesitamos obtener
- Conocer cuales son los problemas a resolver (persistencia, concurrencia, seguridad, rendimiento, traza, interfaz usable por el usuario, etc…)
- Conocer cuales son las soluciones disponibles (base de datos relacionales, bases NoSQL, lenguajes de programación, librerías de clases, frameworks, tecnologías de interfaz de usuario, patrones de todo tipo…)



La generación de código desde un modelo tiene (para mí un gran) beneficio: pone en claro la existencia, SEPARACION y RELACIONES entre todos los puntos de arriba. En general, aprendemos todo eso pero centrados en una o dos tecnologías. Y cada problema viene mezclado con su solución. Y cada decisión nos viene “acoplada” a detalles técnicos, nos entretenemos en cada árbol, sin poder ver el bosque.



Otro camino a explorar (que inicialmente lo quise explorar para AjGo, mi código de soporte para investigar formas de jugar al Go): el uso de agentes expertos. ¿Qué significa “agente experto” en ésta, mi jerga? Mi visión: tener módulos, agentes que pueden ser agregados y removidos sin mayor esfuerzo, que puedan resolver problemas. Alguien podría desarrollar un agente experto en JavaServer Faces. Podría ser que alguien tenga un agente especialista en el nuevo ASP.NET MVC 6.6, o en el JSF 17.2, o en el nuevo “SuperDuperOpenSourceUIThatIsTheNextBigThingHere”. No impoirta, siempre podemos adoptar NUEVAS SOLUCIONES a PROBLEMAS SIMILARES (ingresar la factura en una interfaz, consultar el estado de tal tema, realizar operaciones), habiendo destilado el nuevo conocimiento y “envasádolo” en un nuevo agente experto.



Ok, todas estas son razones para un (¿próximo?) AjRules ;-). Y la justificación de mi trabajo con AjLisp (see here) y algo del código de un viejo AjProlog a ser portado a .NET (ver algo en AjCodeKatas).



Otros posts relacionados con el tema:



Modelos, decisiones, Inteligencia Artificial en AjGenesis
Sobre la Generación de Código



Imagen tomada de Artificial Intelligence, Introduction & Application (Part I)



Nos leemos!



Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

This entry was posted in 2643, 3036, 3463, 6145. Bookmark the permalink.

One Response to Generación de Código e Inteligencia Artificial

  1. mago says:

    no entiendo nada

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>