1 mar. 2008

Prolog

Prolog sigue el paradigma lógico, la cual esta basada en la sintaxis de la lógica de primer orden, que fuera propuesta por Frege y después modificada por Peano y Russell.
Kurt Goedel y Jacques Herbrand estudiaron la noción de computabilidad basada en derivaciones, Herbrand en su tesis de doctorado discutió principios importantes para el algoritmo de unificación, en 1965 Alan Robinson introdujo el principio de resolución, la noción de unificación y un algoritmo de unificación. Usando el algoritmo de resolución se pueden probar teoremas de la lógica de primer orden .Alain Colmerauer trabajo en los lenguajes de programación para el procesamiento del lenguaje natural , basados en la prueba automática de teoremas esto originó la creación de Prolog en 1973, Prolog puede ser visto como una realización de la idea de los programas lógicos, aunque en sus orígenes tenía como principal propósito procesar el lenguaje natural, pronto fue usado como un lenguaje de propósito general.
Las raíces de Prolog están claramente en la Lógica , y quizá esto impidió que tuviera una gran aceptación en la comunidad de Ciencias de la Computación, pues había un importante auge en el paradigma imperativo con Pascal en aquella época, y en inteligencia artificial se había adoptado a Lisp, tiempo después esto cambio y Prolog tomó mayor auge.
El algoritmo de unificación, y de resolución son fundamentales en Prolog.

Características del paradigma de programación lógica (Prolog)
  • Los computos toman lugar sobre el dominio de todos los términos definidos sobre un alfabeto universal
  • La asignación de valores a variables se lleva acabo por medio de la substitución
  • El flujo de control se provee con el mecanismo de backtracking automatico.
A mi me gusta mucho Prolog, me ayudó mucho para darme cuenta de otros estilos de programación y para enteder la recursión. Cuando se programa en Prolog las cosas se ven de manera distinta, para empezar porque no hay ni asignación ni ciclos(fors, whiles etc). Lo malo es que es sensible al orden en los algoritmos recursivos, lo cual puede hacer que aunque el prgrama este bien escrito (lógicamente) se quede en un ciclo infinito. Yo recomiendo Prolog es un bonito lenguaje de programación, claro es usado principalmente en la academia y en la investigación.

Pongo la solución al problema de la cebra, programada en Prolog, como se verá es muy sencilla.

% member(X,Xs):- X es miembro de Xs.

member(X,[X|Xs]).
member(X,[_|Ys]):- member(X,Ys).

% street([C1,C2,C3,C4,C5]):- C1,C2,C3,C4,C5, son las casas respectivamente.
% se cumple si se cumplen las siguientes condiciones.


street([C1,C2,C3,C4,C5]):-


member([roja,ingles,_,_,_,_],[C1,C2,C3,C4,C5]),
member([_,español,_,_,perro,_],[C1,C2,C3,C4,C5]),
member([verde,_,_,cafe,_,_],[C1,C2,C3,C4,C5]),
member([_,ucraniano,_,te,_,_],[C1,C2,C3,C4,C5]),

member([marfil,_,_,_,_,N],[C1,C2,C3,C4,C5]),
member([verde,_,_,_,_,s(N)],[C1,C2,C3,C4,C5]),

member([_,_,porsche,_,caracoles,_],[C1,C2,C3,C4,C5]),
member([amarilla,_,maserati,_,_,_],[C1,C2,C3,C4,C5]),
member([_,_,_,leche,_,s(s(s(0)))],[C1,C2,C3,C4,C5]),


member([_,noruego,_,_,_,s(0)],[C1,C2,C3,C4,C5]),
member([_,_,_,_,_,s(s(s(s(0))))],[C1,C2,C3,C4,C5]),
member([_,_,_,_,_,s(s(s(s(s(0)))))],[C1,C2,C3,C4,C5]),

C1=[_,_,_,_,_,s(0)],
C2=[_,_,_,_,_,s(s(0))],
C3=[_,_,_,_,_,s(s(s(0)))],
C4=[_,_,_,_,_,s(s(s(s(0))))],
C5=[_,_,_,_,_,s(s(s(s(s(0)))))],

member([_,_,saab,_,_,s(R)],[C1,C2,C3,C4,C5]),
member([_,_,_,_,zorro,R],[C1,C2,C3,C4,C5]),

member([_,_,maserati,_,_,T],[C1,C2,C3,C4,C5]),
member([_,_,_,_,caballo,s(T)],[C1,C2,C3,C4,C5]),

member([_,_,honda,naranja,_,_],[C1,C2,C3,C4,C5]),
member([_,japones,jaguar,_,_,_],[C1,C2,C3,C4,C5]),


member([azul,_,_,_,_,s(P)],[C1,C2,C3,C4,C5]),
member([_,noruego,_,_,_,P],[C1,C2,C3,C4,C5]).


Para instalar prolog, en Ubuntu, poner en una terminal: sudo apt-get install swi-prolog

Para probar el programa: copiar el código y guardarlo en un archivo con extensio .pl
En una terminal poner: prolog nombreArchivo.pl, después escribir: street(A,B,C,D,E). (ojo con el punto al final) y la salida será algo como lo siguiente:

?- street([A,B,C,D,E]).

A = [amarilla, noruego, maserati, _G560, zorro, s(0)]
B = [azul, ucraniano, saab, te, caballo, s(s(0))]
C = [roja, ingles, porsche, leche, caracoles, s(s(s(0)))]
D = [marfil, español, honda, naranja, perro, s(s(s(s(...))))]
E = [verde, japones, jaguar, cafe, _G396, s(s(s(s(...))))]


Por lo tanto: el Noruego bebe agua y la cebra vive con el japonés


10 comentarios:

NetDoc dijo...

Hola, pues estoy intentando probar el prolog en ubuntu, hice lo que publicas de hacer el archivo y correrlo pero obtengo un error de sintaxis que me indica que el primer parentesis de (A,B,C,D,E) es un token no válido. Alguna idea?

Eduardo Pacheco (PAGE) dijo...

Cuando marca error de sintaxis por lo regular es cuando se esta escribiendo mal la consulta, asegurate de que la consulta lleve el punto al final, es decir

street(A,B,C,D,E).

Otra cosa que se me ocurre es que no haya cargado bien el archivo, para asegurarte que lo haya cargado correctamente puedes hacer (dentro de prolog):

[Tuarchivo].

y luego hacer la consulta.

Angelfire dijo...

A mi me sale es este error:
ERROR: toplevel: Undefined procedure: street/1 (DWIM could not correct goal)

Alguna solucion?

muchas gracias

Eduardo Pacheco (PAGE) dijo...

Sí, probé y también me marcó ese error. al parecer no carga bien el archivo si desde la terminal ejecutas: prolog archivo.pl . Así que es mejor que intentes cargar el archivo desde el prompt de prolog con [archivo].
Haciendo esto ya de puedes usar el predicado street sin ningun problema.

Angelfire dijo...

Si, gracias eduardo, ya me mostró la respuesta.

Ahora tengo otra preguntica, en mi caso todos los predicados son negados, por ejemplo:
1. José no viajará alrededor del mundo.
2.La señora Martinez no vive en bogotá.

De que manera expreso ese predicado? :S

Todos los ejemplos que veo en internet son afirmaciones.

Eduardo Pacheco (PAGE) dijo...

Por ejemplo si tienes:

pepe vive en bogota
jorge no vive en bogota
rodrigo vive en bogota

tienes los siguientes hechos en prolog :

vivebogota(pepe).
vivebogota(rodrigo).

Si preguntas al interprete de prolog:
?- vivebogota(jorge).

La respuesta esperada es No, y pues esa será la respuesta que obtengas, ya que no pusiste como un hecho que jorge viviera en bogota. De alguna manera una forma de decir que no, es no diciendo que si... eso es por la forma en que prolog maneja la negación, si no puede decidir que si entonces decide que no.

Otra forma que se me ocurre es que pongas algo del estilo:

vivebogota(X) :- not(X == jorge).

Patri dijo...

Hola!! como van, tengo este error
ERROR: toplevel: Undefined procedure: (?-)/1 (DWIM could not correct goal)
Probe con todo lo que comentaron anteriormente y no se solciona nada, ya no se que hacer. Estoy usando el swi-prolog con el editor JprologEditor, Por favor, agradecere su ayuda.

Eduardo Pacheco (PAGE) dijo...

No conozco el jprologEditor, pero por el mesaje que te esta lanzando al parecer algo no esta bien definido, verifica que estes llamando bien el predicado que hayas definido, verifica que todo este definido.

Patri dijo...

Hola, garcias por responde. Otro erro q tengo al llamar al archivo [acti1]
ERROR: source_sink `acti1' does not exist

Alguna idea de como solucionarlo. Gracias!! buen blog.

Eduardo Pacheco (PAGE) dijo...

lo único que se me ocurre al ver el mensaje de error es que o estas llamando al archivo fuente mal o que no esta en el directorio en el que busca el interprete por default, que por lo regular es desde donde lo invocas... prueba pasarle la ruta donde se encuentra el archivo.

ga