martes, 26 de junio de 2007

Características del lenguaje prolog

Ejecución de los programas:
Para la ejecución de los programas de Prolog, proponemos el Ciao-Prolog, http://www.clip.dia.fi.upm.es/Software/Ciao/index.html#ciao
el cual tiene un shell que permite ejecutar objetivos.

El shell es una aplicación que esta incluida dentro del Ciao-Prolog con el nombre de ciaosh, y al ejecutarla aparece el siguiente mensaje:

Ciao-Prolog 1.9 #44: Mon Dec 30 16:47:15 2002
?-

El símbolo? nos indica la zona donde podemos escribir los objetivos a ejecutar.

Por ejemplo:

Ciao-Prolog 1.9 #44: Mon Dec 30 16:47:15 2002
?- f(X) = f(3).

X = 3 ?

Para ejecutar el objetivo es necesario teclear punto al final y teclear ENTER.
A continuación, el shel nos dice si los objetivos tiene éxito o no y como quedan instanciadas las variables. Después aparece un signo de interrogación, lo cual nos indica que le podemos pedir otra solución tecleando un punto y como (;) y pulsando ENTER.

Para cargar un programa en Ciao-Prolog es como sigue:


?- Consutl( ‘Programa.pl’ ).

Yes
?-

Observe que el nombre de fichero se escribe entre comillas simples. En caso de que se quiera ejecutar a los programas desde una carpeta, por ejemplo curso, seria:

?- Consutl( ‘c:/curso/Programa.pl’ ).

Yes
?-


Para salir del shell basta teclear el predicado halt.
?- halt.




2.2.1. Declaración de hechos y reglas

Como ya se dijo una regla al estilo prolog se representa como:

Predicado (Argumento1, Argumento2,.....)

Pc(Arg,..) si P1(Arg,.....) y P2(Arg,.....) y .......

Ahora bien la sintaxis correcta en Prolog seria

Pc (Arg,.....) :- P1(Arg,......) , P2(Arg,.....) , P3(Arg,....)........
(la cual es la sintaxis estándar que viene DEC 10 Prolog)

Algunos lenguajes aceptan también la siguiente sintaxis

Pc(Arg,.....) if P1(Arg,....) and P2(Arg,....) and ..........

Donde a cada regla se le llama cláusula
Y tendremos que para:
Pc :- Pi
Pc: Cabeza de la cláusula
Pi: Cuerpo de la cláusula
:- Cuello de la cláusula.

Sean los siguientes ejemplos de hechos o predicados:
progenitor (juan, luis).
progenitor (maria, luis).
progenitor (luis, jose).
progenitor (luis, ana).
progenitor (ana, elena).


Ahora si se preguntaran al compilador Prolog

? – progenitor (juan, luis).
yes.

Pero si fuera

? – progenitor (juan, sofia)
no

Seria la respuesta, ya que no existe ningún hecho que confirme la pregunta.

Si quiseramos saber todos los descendiente de Luis

?- progenitor (luis, X).
X= Jose
X= Ana

José y Ana son los descendientes de Luis

Ahora vamos a definir una regla o cláusula, hasta ahora solo hemos definidos hechos.
Veamos la regla abuelo:
abuelo(X,Y) :- progenitor(X,Z) , progenitor(Z, Y) , masculino (X).
Nos hizo falta un predicado que no estaba definido (masculino), por lo que necesitamos incluir nuevos hechos.
masculino(juan).
masculino(jose).
masculino(luis).
femenino(ana).
femenino(maria).
femenino(elena).
Ahora mi base de conocimientos esta compuesta por la regla Abuelo y los hechos progenitor, masculino y femenino.
Y si quisiera incluir la regla hermano.
hermano(X,Y) :- progenitor(Z,X), progenitor(Z,Y), masculino(X).
O la regla madre:
madre(X,Y) :- progenitor(X,Y), femenino(X).


Estructura de datos

Variables: Un nombre de variable puede ser cualquier sucesión de caracteres alfanuméricos que comience con una letra “mayúscula” o un subrayado (permite representar variables anónimas).
Ejemplo: Balonm X, _ , _39
Puede utilizarse la variable anónima ( _ ) cuando no interesan los valores de ese termino.
Hallar ( _, X, Y, _) Prolog solo devolverá los valores del 2do. Y 3er. Argumento. El primero y cuarto no se imprimen.
Las variables pueden unificarse con cualquier termino.

Atomos: Son constantes textuales. Pueden tener letras, dígitos o símbolos, comenzando con letras “minúsculas”. Si comienza con letra “mayúscula” o un dígito, entonces hay que encerrarlos entre apóstrofes.
Ejemplo: tenis, ‘23’, ‘París’
Los átomos siempre se unifican con átomos del mismo nombre.

Enteros: Los enteros siempre unifican con enteros del mismo valor.
Ejemplo: -2, 0, 313

Reales: Los números en Prolog no tienen limite de precisión o rango. Están limitados únicamente por la memoria disponible.
Ejemplos: 0.5 , 55.3 , -83.021
Los siguientes casos son erróneos:
5. , .5

Cadenas: Las cadenas son constantes textuales utilizadas para manipular textos en forma eficiente. Se escriben como caracteres ASCII.
Ejemplo: “Pedro vive en: “ , “El numero de tarjeta es: “
Las cadenas se unifican con otras cadenas idénticas. Las cadenas y los átomos no se unifican.


Estructura: Es una colección de objetos agrupados bajo un nombre (functor), donde
Ti = functor (A1, A2, A3,......) y unifica si los functores cazan y los argumentos son iguales.
Ejemplo: h1 = mamiferos( perro, gato, caballo)
Y h2 = mortales( mamiferos, peces, aves)
Lo cual se puede unificar como: mortales(mamiferos(perro,gato,caballo), peces, aves)

Lista: Es una colección de objetos (al igual que la estructura) agrupados en secuencia.
L = [a, b, c]. Donde siempre se extrae el primer elemento y se incluye también por el principio.
Ejemplo: Para extraer un elemento de L
L = [X ¦ R] donde ¦ es el constructor de lista
Y se obtiene X = a y R = [b, c] con X y R como variables no instanciadas
Otro ejemplo:
X = 1 y R = [2, 3]
P = [X ¦ 2, 3]
Se obtiene: P = [1, 2, 3]


Unificación de términos

La unificación es el mecanismo mediante el cual las variables toman valores. Una variable puede tomar cualquier valor de los definidos anteriormente y en ese caso se dice que la variable esta instanciada y las variables no instanciadas, son aquellas que no han tomado aun valor alguno.

Los argumentos en la unificacion cazan de la siguente forma:

Ejemplos:
?- X = 3 X unifica con el entero 3 ( y a partir de este momento queda instanciada con ese valor).
?- 5 = 5 da verdadero
?- f(X, 3) = f(5, Y) donde la variable X unifica con el entero 3 y la Y con el 5. Quedando ambas variables instanciadas con sus respectivos valores.

Estructura.

Propietario(juan,libro)
Lo que quiere decir que: Juan es propietario de un libro
Ahora si quisiéramos decir: Juan es propietario del libro la edad de oro de José Marti.
Propietario (juan, libro(“Edad de oro”, “Jose Marti”))
O mejor: Propietario(Nombre, libro(Titulo, autor(Nombre, Apellido)))
Y seria: Propietario( juan, libro(“Edad de oro”, autor (Jose, Marti)))
Esta representación tiene la ventaja que nos permite hacer búsquedas de cualquier objeto que posea Juan.
Ejemplo:
Propietario(juan, radio)
Propietario(juan, televisor)
Propietario(juan, libro(“Ismaelillo”, autor(Jose, Marti)))
Propietario(juan, libro(“Don Quijote”,autor(Miguel, Cervantes))

A la pregunta
?- Propietario (juan, Y) nos dará todas las propiedades que posee Juan
?- propietario (juan, libro) dará todos los libros que posee Juan.
?- porpietario(juan, libro(X, autor(jose, marti))) dara todos los libros que posee Juan cuyo autor sea José Marti.


Ejemplo, sean los hechos:

padre(pedro, luis).
padre(juan,mario).
padre(luis, jose).
padre(mario, marco).

Y la regla:
abuelo(X,Y) :- padre(X,Z), padre(Z,Y).

Se puede preguntar:
? - abuelo(X,Y) Todos los abuelos que existen para ese Universo
? - abuelo(juan, X) Quienes son los nietos de Juan
? - abuelo(X, jose) Quien es el abuelo de Jose (de acuerdo a la base de hechos solo puede haber un abuelo).
? - abuelo(juan, jose) Comprobar si Juan es el abuelo de Jose.


Veamos como unifican los términos para abuelo(X, jose)

?- abuelo(X, jose)

Lo primer que hará será tratar de demostrar que el objetivo abuelo se cumple, para ellos buscara una cláusula (regla), que será abuelo(X,Y) :-
Y luego unificaran los términos la variable X con la variable X y el átomo ‘jose’ con la variable Y.
Después se pasa al cuerpo de la cláusula :- padre(X,Z), padre(Z,Y).
Convirtiéndose padre(X,Z) en el objetivo a demostrar.
Para ello seleccionara el primer predicado (hecho) padre.
Padre(pedro,luis) y unificara los términos X con pedro y Z con luis
Y se pasa a ejecutar el otro predicado contenido en el cuerpo de la cláusula.
Padre(Z, Y) donde Z viene instanciada con el valor ‘luis’ y la Y viene con el valor ‘jose’
O sea buscara un padre(luis, jose).
Y como este predicado existe en la base de hecho de los padres.
Dará X = luis.

Mecanismo de control. El retroceso

Sean los siguientes hechos o predicados
padre(juan, pedro).
padre(juan, ramon).
padre(juan, luis).
padre(luis, francisco).
padre (jose, nicolas).

Y la regla o clausula
hermano(X, Y) :- padre(Z, X) , padre(Z, Y), diferente(X, Y).
diferente(X, Y) :- X \== Y.

Probar que:

?- hermano(pedro, X), padre(X, francisco).

Observen que se esta pidiendo demostrar dos objetivos. Probar que Pedro es hermano
de alguien (X) y que ese alguien es padre de Francisco.

1. Hay que demostrar que los objetivos se cumplen.
2. Analizar para que valores de las variables los objetivos se hacen ciertos.

Se probo que Pedro y Ramón son hermanos pero ahora falta demostrar el otro objetivo: Ramón padre de Francisco.
Para ello prolog deber retroceder hasta el objetivo hermano e instanciar la variable X con el átomo ramon, y pasar el objetivo padre

Por lo que prolog deberá retroceder nuevamente al objetivo hermano y comienza nuevamente el proceso de buscar otro hermano para Pedro

Prolog va marcando los hechos (padres) que ya utilizo en su demostración (con los que fracaso) y escoge otros, siempre que no se indique otra cosa escogerá los predicados de la base de hechos de forma consecutiva.


La recursividad

Veamos ahora uno de los mecanismos más complejos de estos tipos de lenguajes: la recursividad.

Primero vamos a tratar de entender el algoritmo y luego veremos un ejemplo practico.
Sea la regla:
f(X, Y) :- h(X, X1), f(X1, Y1), g(Y,Y1).
y los hechos:
f(3,3). (criterio de parada).
h(0,1)
h(1,2)
h(2,3)
g(3,2)
g(2,1)
g(1,0)

Que pasaría si le preguntáramos lo siguiente:

?- f(X, Y)


Veamos un ejemplo:

Hallar el factorial de 4
4! = 1 x 2 x 3 x 4 = 24
Esto es igual a
4! = 4 x 3!
3! = 3 x 2!
2! = 2 x 1!
O sea:
N! = N(N-1)!
(N-1)! = (N-1)(N-2)!
Por lo que podemos definir una función recurrente como sigue.
Fact(n) = n . Fact(n-1)

Veamos el programa en Prolog
% Se le asigna a la variable N1 el resultado de la expresión N – 1. (esto es un comentario)
resta(N, N1) :- N1 is –(N,1).
% Se le asigna a la variable F el resultado de la expresión N * F1.
mult(N, F1, F) :- F is *(N, F1).
fact(1,1).
fact(N,F) :- resta(N, N1), fact(N1,F1), mult(N, F1, F).

Observen que para la asignación se utilizo IS, ya que el signo(=) lo que hace es unificar
O sea si digo: X = 3+4, la variable X unificara con la estructura +(3, 4). Por lo que el valor de X no será 7, sino la expresión 3 + 4. Si quiere asignarle a X el valor de la expresión seria: X is 3 + 4. Y ahora, si el valor de X es 7.

1 comentario:

Unknown dijo...

Saludos. Me encuentro en Colombia y estoy comenzando a dar la asignatura IA, y me gustaria saber si dispone de la version 5.2 de prolog que es la que nuestro profesor nos pide, ya que no la he podido descargar. Y el profesor nos dijo que la ultima version no la usaremos.
Le agradeceria si es posible comunicarme de algun link donde lo pueda descargar o si es posible contactarlo a usted para el envio del mismo...
gracias