Introducción a PROLOG

 Autor: Daniel Penagos (Modificado por Johann Camilo Olarte D.)

Contenido: 

  1. Generalidades sobre Prolog.
    1. Formas Mínimas en Prolog.
    2. Las Relaciones.
    3. Predicados, Hechos y Reglas.
    4. Listas.
  2. Práctica 0.
  3. Práctica 1.
  4. Práctica 2.
  5. Práctica 3.
  6. Práctica 4.
  7. Vínculos.

 

 

GENERALIDADES SOBRE PROLOG:

 

La programación lógica surge hacia 1979 donde Kowalski establece el enunciado del patrón de programación lógica:

            Algoritmo + lógica + control

La programación lógica involucra:

            El uso de hechos y reglas y la construcción de deducciones para procesar consultas.

 

Formas Mínimas en Prolog:

Corresponden a las formas más sencillas de información manipulada por Prolog:

  1. Los átomos de información.: una cadena de texto que empieza por letra minúscula o un valor numérico con signo opcional
  2. Las variables: Son cadenas de texto que empiezan por una letra mayúscula o  por el signo _ (underscore).

 

Las Relaciones:

Con las formas mínimas anteriormente descritas se pueden construir las relaciones, base del conocimiento en Prolog.

Ejemplos de relaciones:

           padre(pepe, maria). // en esta relación se denota una existencia de parentesco entre pepe y maria, prolog en este punto no conoce

                                                           //quien es el padre de quien, somos nosotros quienes le damos esa interpretación, prolog solamente se encarga de

                                                           //crear una relación en su base del conocimiento.                                                        

 

   Obsérvese la sintaxis de la relación descrita:

 

Al tener por ejemplo dentro de nuestra base del conocimiento, los siguientes hechos:

sucesor(1,2).

sucesor(2,3).

sucesor(3,4).

sucesor(4,5).

sucesor(5,6).

sucesor(6,7).

Podemos realizar consultas como las siguientes:

sucesor(X,6).

sucesor(2,Y).

sucesor(X,Y).

 

            Nótese como los átomos de información que se desean consultar han sido reemplazados por variables (letra inicial en mayúscula); en este punto Prolog busca dentro de su base del conocimiento un hecho que haga emparejamiento con la información suministrada en la consulta. Primero, busca una predicado (nombre de la relación) llamado sucesor, luego hace una comparación entre la información que se tiene (6), para llenar la variable X con la información almacenada en el hecho, así, prolog responde X=5. De la misma forma ocurre con la segunda consulta; en la tercera no existe información para hacer emparejamiento en la base del conocimiento, por lo tanto el responderá con el primer hecho que tenga ese predicado.

Responderá:

X = 1

Y = 2;

En este punto tenemos dos opciones: quedar satisfechos con la respuesta que prolog nos ha suministrado oprimiendo enter o solicitarle consultas sobre otros posibles emparejamientos, para la cual debemos oprimir punto y coma (;).
 

Es también posible construir en prolog consultas complejas con los operadores AND(,), OR(;) y NOT(not) de la siguiente forma:

legusta(pepe,pesca).

legusta(maria,bailar).

legusta(ana,pesca).

legusta(pepe,musica).

legusta(maria,musica).

legusta(ana,bailar).

 

  Se pueden realizar las siguientes preguntas sobre la base de información:

            - ¿Le gusta la música a Pepe y a Maria? :         ?-legusta(pepe,musica),legusta(maria,musica).

            - ¿Le gusta bailar a Pepe o a Maria le gusta la música?:           ?-legusta(pepe,musica);legusta(maria,musica).

            - ¿Le gusta bailar a Pepe y a Maria no le gusta la música?:      ?-legusta(pepe,musica),not(legusta(maria,musica)).

 

            Para que estas consultas funcionen de forma adecuada es necesario no dejar espacios entre los operadores.

 

Predicados, Hechos y Reglas:

En este caso la relación  padre(pepe, maria).  se asume como un hecho, pues no está involucrando variables en su definición; al nombre de la relación se le llama predicado.

Mas formalmente un predicado es un conjunto de hechos o reglas que tienen un mismo nombre y la misma cantidad de objetos relacionados, si se trata de reglas, en nombre de la conclusión es el mismo y  el número de objetos relacionados es también el mismo.

Una regla es una sola conclusión seguida por el signo :-  el cual hace la vez de SI condicional, seguida por una o mas relaciones de condición.

Por ejemplo:

 

sucesor(1,2).

sucesor(2,3).

sucesor(3,4).

sucesor(4,5).

sucesor(5,6).

sucesor(6,7).

suma(1,X,R):-sucesor(X,R).

suma(N,X,R):-sucesor(M,N),suma(M,X,R1),sucesor(R1,R).

Aquí podemos apreciar como suma es una regla que depende en gran medida de la condición sucesor. En la segunda regla de suma se observa que existe mas de una condición, por tanto estas van separadas por coma; podemos observar también que se realiza una operación recursiva. Esta misma sentencia traducida en un lenguaje de programación como Java quedaría:

int suma(int N, int X, int R)
{
      if ( N == 1 )
      {
            sucesor(X,R);
      }
      else
      {
            sucesor(M,N);
            suma(M,X,R1);
            sucesor(R1,R2);
      }
}

Obsérvese que en la segunda línea del bloque else se realiza un llamado recursivo al método suma, de forma tal, que se realiza la operación disminuyendo el valor de N hasta que este se hace 1, en el cual termina la recursividad y se origina la respuesta.

El anterior esquema de representación es muy limitado pues tenemos que especificar de manera explícita el sucesor de cada número. Un alternativa es especificar los números naturales de manera recursiva con la ayuda de funciones. En este caso usaremos dos funciones: cero, que es una función sin argumentos (una constante) y que representa el número 0, y suc(x) que representa el sucesor de x. De tal forma que el número tres se expresa como suc(suc(suc(cero))). El siguiente programa en Prolog define la suma usando esta notación:

suma (N,cero,N).

suma(N,suc(X),suc(R)):-suma(N,X,R).

Qué resultado tienen la evaluación de los siguientes predicados?

suma(suc(cero),suc(suc(cero)),X).
suma(X,Y,suc(suc(suc(suc(cero)))))

Listas

Una lista en prolog es una secuencia lineal de objetos, con la característica de que toda la manipulación de la secuencia se realiza por el extremo izquierdo, debido a la forma como se representa una lista generalizada.

Una lista vacía se representa de la siguiente manera:     []

Una lista generalizada, con un número de objetos distinto de 0 :   
          [X|Y]    // en esta lista se está declarando por lo menos un objeto X y una secuencia de objetos a la derecha de X, pudiendo ser incluso una lista vacía.

De igual manera, la lista   [X,Y|Z] contiene por lo menos dos objetos: X y Y, seguidos de una secuencia de objetos Z, la cual puede ser vacía.

La notación se extiende de esta manera, para una lista con por lo menos tres objetos, su representación sería la siguiente: [X,Y,Z|W]

 

Ejemplo de manipulación de listas: se quiere a una lista agregar otra lista al final, de esta forma, si la primera lista es [a,b,c] y  la segunda es [d,e,f], la lista resultante sería: [a,b,c,d,e,f].

 

El programa que realiza esto en prolog sería:

 

agregar([],L,L).

agregar([A|R],L,[A|T]):-agregar(R,L,T).

 

En este programa nuevamente vemos la recursión en la segunda línea: se va disminuyendo el tamaño de la primera lista hasta que este es cero, en cuyo caso finaliza la recursión y se origina una respuesta. Observamos que los elementos en la regla son: lista inicial, lista que se adiciona, lista final.

 

PRACTICA 0:

  1. Descargue e instale SWI-Prolog http://gollem.science.uva.nl/cgi-bin/nph-download/SWI-Prolog/w32pl5612.exe
  2. Ejecute la aplicación.
  3. Cree un nuevo archivo usando la opción File--New (use un nombre tal como prueba.pl)
  4. Digite:
    prueba(uno).
    prueba(dos).
  5. Guarde el archivo y salga del editor.
  6. Cargue el archivo usando la opción File--Consult
  7. En el prompt digite:
    prueba(X). <enter>
    ;

    ;
PRACTICA 1:

Desarrollar su árbol genealógico en prolog mediante la siguiente semántica:

padre(nombre_1,nombre_2).

padre(nombre_3,nombre_4).

¦

¦

De igual manera exprese también las siguientes relaciones usando reglas: hermano, hijo, tio, sobrino, primo, ancestro, etc.

De esta forma existirá información redundante en varios sentidos que deberá ser coherente.

 

Realice consultas sobre la información almacenada con preguntas complejas construidas con los operadores AND (,), OR(;) y NOT(not).

 

PRACTICA 2:

Desarrolle un programa en prolog que resuelva el factorial de un número,

?- factorial(5,S).
S = 120

Desarrolle un programa que calcule la suma de los primeros N cubos.

?- sumancubos(5,S).
S = 225

PRACTICA 3:

  1. Se tienen dos listas con el mismo número de objetos, escriba un programa en prolog que tome alternativamente elementos de ambas listas para construir una nueva lista con los elementos de ambas.
  2. Desarrolle un programa que invierta el orden de los elementos de una lista dada.

PRACTICA 4:

Defina un predicado producto(X,Y,Z) que sea verdadero si X*Y=Z. Haga dos implementaciones:

  1. Utilice el predicado sucesor presentado anteriormente.
  2. Utilice una función suc() y la constante cero para definir todos los números naturlaes de la siguiente forma: cero, suc(cero), suc(suc(cero)), etc.

VINCULOS DE INTERES:


 

Esta es la última versión de SWI-Prolog para Windows.

http://www.swi-prolog.org/

Tutorial de programación práctica en Prolog:

http://ftp.gnuab.org/pub/eresvago/ficheros/tutoriales/manual_prolog.pdf

En este vínculo se encuentran una serie de transparencias que ilustran los conceptos básicos de Prolog.

http://webepcc.unex.es/agomez/prolog.htm

Otro vínculo con información sobre conceptos básicos, (se recomiendan los archivos pdf Tema0,I,II,III,IV).

http://polaris.lcc.uma.es/~pacog/apuntes/pd/

Pdf con un buen tutorial y ejemplos de programas

http://euitio.trisquelmedia.net/apuntes/viejo/primero/logica/Programacion%20practica%20en%20prolog.zip

Programas de ejemplo:

http://www.lsi.upc.es/~bejar/docencia/tmia/tmia.laboratorio.html