Вы находитесь на странице: 1из 5

[white paper]

Programacin lgica
Un recorrido por la programacin lgica y uno de sus lenguajes ms representativos: Prolog, clsico de la inteligencia artificial, que se aplica de mltiples formas en el desarrollo de software comercial.
a programacin lgica, junto con la funcional, forma parte de lo que se conoce como programacin declarativa. En los lenguajes tradicionales, la programacin consiste en indicar cmo resolver un problema mediante sentencias; en la programacin lgica, se trabaja de una forma descriptiva, estableciendo relaciones entre entidades, indicando no cmo, sino qu hacer. La ecuacin de Robert Kowalski (Universidad de Edimburgo) establece la idea esencial de la programacin lgica: algoritmos = lgica + control. Es decir, un algoritmo se construye especificando conocimiento en un lenguaje formal (lgica de primer orden), y el problema se resuelve mediante un mecanismo de inferencia (control) que acta sobre aqul.

> Los functores son identificadores que empiezan con minscula, seguidos de una lista de parmetros (trminos) entre parntesis, separados por comas. Las sentencias son reglas o clusulas. Hay hechos, reglas con cabeza y cola, y consultas. > Un hecho establece una relacin entre objetos, y es la forma ms sencilla de sentencia. Por ejemplo:
humano (socrates). ama (juan,mara)

Prolog
El lenguaje Prolog, principal representante del paradigma, se basa en un subconjunto de la lgica de primer orden (restriccin de la forma clausal de la lgica denominada clusulas de Horn). Philippe Roussel y Alain Colmerauer (Universidad de AixMarseille) lo crearon en 1972, y su base terica se debe en gran parte a Kowalski.

Estructuras bsicas
Prolog cuenta con dos tipos de estructuras: trminos y sentencias. Los trminos pueden ser constantes, variables o functores: > Las constantes, representadas por una cadena de caracteres, pueden ser nmeros o cualquier cadena que comience en minscula. > Las variables son cadenas que comienzan con una letra mayscula.

Se establece que Scrates es humano y que Juan ama a Mara. > Una regla permite definir nuevas relaciones a partir de otras ya existentes. Si queremos establecer que todo humano es mortal, en lgica estndar escribiramos V(x)(humano(x)=>mortal(x)), mientras que en Prolog escribimos:
mortal(X):-humano(X).

Poste 1

Poste 2

Poste 3

> Esto se lee: X (variable) es mortal si X es humano. El smbolo :- significa si o, si lo leemos de derecha a izquierda, entonces o implica. En esta regla, mortal(X) es la cabeza, y humano(X) es el cuerpo. > Para entender el concepto de consulta, veamos un ejemplo. En lgica estndar: > V(x)(humano(x)=>mortal(x)) > humano(socrates) > entonces mortal (socrates) > Partiendo de que los humanos son mortales y de que Scrates es humano, deducimos que Scrates es mortal. Para realizar esa deduccin en Prolog, hay que preguntar si es mortal Scrates, o quin es mortal. Si del programa lgico (conjunto de hechos y reglas) se deduce que Scrates es mortal, entonces sa ser la respuesta que obtendremos. Veamos el programa:

[Figura 1] Problema y resolucin de las torres de Hanoi.

58

users.code

GERARDO ROSSEL Investigador del CAETI. grossel@computer.org


mortal(X):-humano(X). humano(Scrates).

Listas
Prolog manipula listas con una facilidad sintctica que simplifica la programacin: una lista es un par ordenado, donde un elemento es un trmino (la cabeza), y el otro puede ser un trmino, una lista o la lista vaca (la cola). Las listas van entre corchetes, y la cabeza se separa de la cola con el smbolo pipe; la lista vaca se indica con dos corchetes separados por un espacio. Haciendo un abuso de notacin, tambin es posible enumerar todos los elementos de la lista separndolos con comas. Por ejemplo, la lista 1, 2, socrates, a, platon se escribe en Prolog de estas dos maneras:
[1|[2|[socrates|[a|[platon|[]]]]]] [1, 2, socrates, a, platon]

Para preguntar interactivamente, los ambientes de Prolog tienen un listener, un intrprete de lnea de comando cuyo prompt es un signo de pregunta. Se introduce una sentencia (eventualmente con variables), y Prolog intentar demostrarla (usando un algoritmo de inferencia llamado SLD-Resolution, basado en la regla de resolucin de Robinson), buscando adems constantes que puedan reemplazar las variables de la pregunta. Las preguntas de nuestro ejemplo seran:
?- mortal(Scrates). Yes. ?- mortal(X) X = socrates

Las segundas lneas son las respuestas de Prolog: primero, afirmando que s, Scrates es mortal; despus, contestando Scrates al preguntar quin es mortal. Si agregamos ms conocimiento a nuestro programa lgico (por ejemplo, que Platn es mortal), podemos pedir ms respuestas. Si luego de obtener Scrates escribimos un punto y coma (as pedimos ms), nos responder Platn. Cuando Prolog no tenga ms respuestas, nos dir que No; esa negativa no significa que lo que preguntemos sea falso, sino que no lo conoce o no puede demostrarlo. Es decir que si preguntamos, por ejemplo, si Arqumedes es mortal, la respuesta ser que no, pero porque nuestro programa no cuenta con el conocimiento suficiente. Esto se denomina negacin por falla.
?- mortal(X) X = socrates; X = platon; No

Para comprender un poco mejor el poder de la programacin declarativa, comparemos un algoritmo que determina si un elemento se encuentra en una lista en un lenguaje declarativo (por ejemplo, Pascal) y en Prolog. En Pascal:
function member(item:Integer; L:Array of Integer):Boolean; var i:Integer; begin i:=0; while((i <= length(L)) and (L[i] <> item)) do begin i := i+1; end; Result := item = L[i]; end;

Este modo interactivo es muy til para prueba y prototipacin, pero dependiendo de la implementacin Prolog en particular, es posible realizar invocaciones desde otros ambientes, o ejecutar un programa Prolog que tenga un predicado main (que ser el que se intentar probar). Para facilitar el desarrollo de aplicaciones, Prolog cuenta con un conjunto de caractersticas que ensucian de alguna manera su pureza en lo que hace al paradigma, pero que lo vuelven utilizable. Hablamos, por ejemplo, de escritura por pantalla, pedido de datos al usuario y otros elementos especficos de control del mecanismo de inferencia (el predicado de corte es el ms conocido).

Para saber si un elemento es parte de una lista, en Prolog slo declaramos que es su cabeza o es parte de su cola.
member(X,[X|Xs]). member(X,[Y|Ys]) :- member(X,Ys).

El predicado member (parte del estndar de Prolog) dice que un elemento (representado por la variable X) es miembro de una lista si es la cabeza de ella (la cabeza de la lista [X|Xs] es X), y tambin que un elemento es miembro de una lista si es miembro de la cola (la cola de la lista [Y|Ys] es Ys, que es,

Operadores
MATEMATICOS Suma + Resta * Multiplicacin / Divisin (retorna siempre en punto flotante) // Divisin entera (trunca) mod Resto de divisin ** Potenciacin RELACIONALES > Mayor que < Menor que >= Mayor o igual que =< Menor o igual que =:= Aritmticamente igual =\= Aritmticamente diferente

59

[white paper - Programacin lgica]


a su vez, una lista, un trmino o la lista vaca, segn definimos anteriormente). En un caso indicamos cmo determinar que un elemento es parte de la lista, mientras que en el otro declaramos qu significa que un elemento sea parte de la lista. En esta ltima situacin, el motor de inferencia se encargar de responder cuando preguntemos.

Las torres de Hanoi


Este problema puede mostrar la potencia del paradigma lgico. Se comienza ordenando los discos de mayor a menor (de abajo hacia arriba) sobre un eje, y se trata de llevarlos a otro (del primero al ltimo) para que queden de la misma forma. Es posible desplazar los discos de a uno (siempre tomando el de arriba), y nunca puede ubicarse un disco sobre otro de menor dimetro. La [Figura 1] muestra los estados inicial y final, luego de realizar los movimientos. Existen tres postes, y uno de ellos se usa como auxiliar (con slo dos sera imposible). Se trata, entonces, de hacer un programa que pueda mover N discos desde el poste 1 hasta el poste 3, usando el poste 2 como auxiliar. Para lograrlo, establecemos una regla cuya cabeza sea el predicado Hanoi con un parmetro indicando la cantidad de discos por mover; en el cuerpo de la regla pondremos el predicado mover con los parmetros: cantidad de discos (N), desde dnde (poste 1), hasta dnde (poste 3) y qu usaremos como auxiliar (poste 2).
hanoi(N) :- mover(N, poste1, poste3, poste2).

Operadores aritmticos y relacionales


El predicado igual (=) compara dos trminos, y es verdadero solamente cuando ambos son idnticos o cuando alguna sustitucin de variables los hace idnticos (es ms correcto decir cuando unifican). Las siguientes consultas nos dan un ejemplo:
?- 1 = 1. yes ?- 1 = 2. no ?- 2 = 1+1. no ?- a=A. A = a ; No

Puede parecer extrao que la consulta 2 = 1+1 nos arroje un no como respuesta; en realidad, la constante 2 no unifica con el predicado + con dos argumentos 1 y 1. Para estas comparaciones, y para conseguir asignaciones, se usa el predicado is:
?- 2 is 1+1. yes ?- X is 1+2. X = 3 ; no ?- 1 is X+2. Error

En el primer caso, 1 + 1 es 2, el is responde yes. En el segundo, responde que X=3 es la sustitucin adecuada a X = 1+2; al pedir otra respuesta (con el punto y coma), no la encuentra. El ltimo ejemplo es un error: al usar is, la parte derecha debe estar instanciada. El estndar establece que en otro caso es un error, aunque algunas distribuciones de Prolog responden no. En la tabla [Operadores] vemos otras posibilidades.

Luego debemos especificar mover, para lo cual usaremos dos reglas. Trabajar en Prolog nos exige pensamiento recursivo: podemos decir que, para mover N discos desde el poste 1 al 3 usando el 2 como auxiliar: > deben moverse N-1 discos del poste 1 al poste 2, usando el 3 como auxiliar; > debe moverse el disco restante al poste 3, quedando en el poste correcto;

Editor de reglas si.. entonces

Respuestas

> luego hay que mover N-1 discos del poste 2 al poste 3 usando el 1 como auxiliar. Asumimos que es fcil mover N-1 discos, pero podemos aplicar este razonamiento y quedarnos con N-2, y as sucesiva o recursivamente. Esto se implementa en una regla:
mover(N,A,B,C) :M is N-1, mover(M,A,C,B), escribir_mov(A,B), mover(M,C,B,A).

Componente lgico Programa lgico especfico

Traductor

Motor Prolog

Base lgica precio(x):=hora(y,3)...

Tablas en base de datos

No olvidar el caso base: cuando no hay discos para mover, no hay que hacer nada. Esa es justamente la regla que aqu necesitamos:
mover(0,_,_,_).

[Figura 2] Reglas de negocios y Prolog.

El carcter _ representa variables annimas (en este caso no nos importa con qu postes

60

users.code

[white paper - Programacin lgica]


Enlaces relacionados
AMBIENTES PROLOG: > Amzi! Prolog: www.amzi.com > SWI Prolog: www.swi-prolog.org > VisualProlog: www.visual-prolog.com > Logic Programming Associates: www.lpa.co.uk > GNU Prolog: gprolog.inria.fr RECURSOS > Libro en ingls: cblpc0142.leeds.ac.uk/~paul/prologbook > Association for Logic Programming (ALP): www.cs.kuleuven.ac.be/%7Edtai/projects/ALP > Blog en espaol: programacionlogica.blogspot.com

Reglas de negocios y Prolog


Uno de los aspectos crticos en el desarrollo de aplicaciones empresariales es el de la programacin de reglas de negocio. Existen numerosos trabajos acerca de la mejor forma de modelarlas: el problema se relaciona con el tipo de conocimiento que requieren. Tenemos tres tipos: > Factual. Puede ser modelado e implementado como datos (por ejemplo, filas en una tabla relacional). Establece hechos. > Procedural. Serie de pasos para resolver problemas. > Lgico. Representa un conjunto de reglas para modelar relaciones entre objetos (por ejemplo, en una aplicacin de tarifas telefnicas, seran las relaciones entre horarios, distancia, descuentos, plan del usuario, tiempo de duracin, costo de la llamada, etc.). Los dos primeros tipos de conocimiento pueden modelarse e implementarse simplemente con las herramientas tradicionales de bases de datos y lenguajes imperativos (C#, Java, Smalltalk, Eiffel, etc.), pero ni el paradigma de orientacin a objetos provee una semntica adecuada para modelar conocimiento lgico. Este tipo no es fcil de representar en un esquema tradicional: no es suficiente una base de datos, dado que las relaciones son demasiado complejas para una tabla. Tampoco es adecuado el modelo procedural, ya que fuerza a transformar relaciones lgicas en secuencias de instrucciones (en este ltimo aspecto, hay que diferenciar un conjunto de reglas si-entonces de un conjunto de instrucciones de un lenguaje procedural if-then; en la primera no hay sentido de secuencia explcito; en la segunda, s). Prolog, as como otras extensiones especficas, es adecuado para modelar este tipo de conocimiento lgico. Una implementacin eficiente de dicho conocimiento lgico puede requerir un paso intermedio: modelar primero reglas de negocio en un formato claro para los encargados de establecerlas (alguna sintaxis tipo si-entonces) y luego trasladarlas automticamente a un programa lgico que use las facilidades del motor de inferencias. Vemoslo grficamente en la [Figura 2].

trabajamos, ya que no hay discos). Usamos, adems, un predicado auxiliar que escriba por pantalla el movimiento actual (se usa write, que es una facilidad extra lgica, y nl, que significa new line). El resultado final:
% Torres de Hanoi % hanoi(N) :- mover(N, poste1, poste3, poste2). mover(0,_,_,_). mover(N,A,B,C) :M is N-1, mover(M,A,C,B), escribir_mov(A,B), mover(M,C,B,A). escribir_mov(Desde,Hasta) :write('mover desde: '), write( Desde ), write(' hasta: '), write(Hasta), nl.

Programa (Java, JSP, ASP, ASP.NET, VB, Delphi, Excel, API, C#, etc.)

Extensiones Amzi! (LSX, Acceso a base de datos, Sockets, etc.)

Integracin total: lgica para .NET y Java


Para que el uso de programas lgicos pueda aplicarse al desarrollo de software moderno, es necesario que sean verdaderos componentes lgicos que puedan utilizarse desde entornos como .NET, JSP, Delphi, Java, etc. Muchas implementaciones actuales de Prolog proveen mecanismos para invocar programas Prolog desde otros ambientes. El entorno Amzi! Prolog + Logic Server brinda una integracin total multiplataforma (ver [Figura 3]) con los ambientes ms conocidos. Adems, podemos invocar desde Prolog rutinas hechas en otros lenguajes, mediante predicados extendidos (as Prolog puede actualizar, por ejemplo, el estado de un botn en pantalla habilitndolo o no dependiendo de un complejo conjunto de relaciones lgicas). Naturalmente, existen diversos IDEs muy completos para el desarrollo de programas Prolog: el Amzi! utiliza Eclipse, muy conocido por la comunidad Java.

Amzi! Logic Server Extensiones propias (LSX, callback a Delphi/.NET/Java, etc.)

Base lgica

[Figura 3] Interaccin a travs de Amzi! Logic Server.

62

users.code

Conclusiones
Hemos presentado las caractersticas principales de la programacin lgica encarnadas en su principal representante: Prolog. Luego del mpetu inicial con que cont, hoy se la puede ver como un paradigma adecuado para determinados dominios, como sistemas expertos y reglas de negocios. Integrndolo con ambientes de desarrollo, podemos dotar a nuestras aplicaciones de inteligencia y flexibilidad. Existen ampliaciones con soporte para otras lgicas, como la difusa, para la programacin con restricciones, soporte de paralelismo y concurrencia, etc. G

Ejemplo: Java y Prolog


Veamos un caso real de utilizacin de Prolog en una aplicacin Java: se trata de una compaa que brinda servicios para manejar el financiamiento de propiedades. El centro de sus servicios es una aplicacin web que permite a sus clientes buscar la mejor solucin para un prstamo hipotecario. El mdulo de cotizaciones fue desarrollado utilizando 5000 lneas de cdigo Java y varias tablas de una base de datos; es el ms crtico y el que soporta el mayor peso de las reglas de negocio. Era necesario cambiarlo todo el tiempo para adaptarse a nuevas reglas y factores de tasacin. A esto se agregaba un largo ciclo de afirmacin de calidad, dado que la modificacin de cdigo procedural para realizar las adaptaciones era proclive a producir errores nuevos. Se precisaba una solucin con menos errores y que permitiera una rpida adaptacin a nuevas reglas: se reemplaz el mdulo de tasaciones, construyendo un mdulo lgico con Amzi!, y en dos meses las 5000 lneas Java y las 18 tablas de la base haban dado lugar a slo 500 lneas Prolog. La base lgica resultante estaba casi libre de errores, y el ciclo de modificacin/prueba se redujo en gran forma. El resto de la aplicacin sigue en Java, aunque se planea migrar mdulos particularmente complejos.

Gerardo Rossel es Licenciado en Ciencias de la Computacin y doctorando de la Facultad de Ciencias Exactas y Naturales de la UBA. Es docente e investigador (a cargo del Grupo de Investigacin y Desarrollo de Agentes y Sistemas Inteligentes del CAETI) en la Facultad de Tecnologa Informtica de la UAI. En el campo profesional, donde acta desde hace ms de quince aos, es Chief Scientist y responsable de ingeniera en Uppersoft Ingeniera de Software, representante de Amzi! Prolog en Sudamrica, y se especializa en inteligencia artificial, desarrollo de software (.NET y J2EE) y el diseo por contratos. Adems, es consultor de proyectos especiales para Omnisis S.A.

Вам также может понравиться