25
TUTORIAL DE PROLOG ( Ver 3.47) Indice INTRODUCCIÓN. CAPÍTULO 1. COMO CORRER PROLOG. 1.1 Comienzo. 1.2 Lectura de Archivos con Programas. 1.3 Ingreso de Cláusulas a la Terminal. 1.4 Directivas: Preguntas y Comandos. 1.5 Errores de Sintaxis. 1.6 Predicados no definidos. 1.7 Ejecución de Programas e Interrupción de éstos. 1.8 Salida del Intérprete. 1.9 Ejecuciones Anidadas - Break y Abort. 1.10 Guardando y Recuperando Estados de Programas. 1.11 Inicialización. 1.12 Entrandas a Prolog. CAPÍTULO 2. DEPURACIÓN. 2.1 El Modelo de Flujo del Procedimiento Box Control. 2.2 Predicados Básicos de Depuracion . 2.3 Rastreo. 2.4 Spy-Points. 2.5 Formato de los Mensajes de Depuración. 2.6 Opciones Disponibles Durante la Depuración. 2.7 Consultar Durante la Depuración. CAPÍTULO 3. COMPILACIÓN. 3.1 Llamando al Compilador

Tutorial de Prolog

Embed Size (px)

DESCRIPTION

prolog

Citation preview

Page 1: Tutorial de Prolog

TUTORIAL DE PROLOG

( Ver 3.47)

Indice

INTRODUCCIÓN.

CAPÍTULO 1. COMO CORRER PROLOG.

1.1 Comienzo.

1.2 Lectura de Archivos con Programas.

1.3 Ingreso de Cláusulas a la Terminal.

1.4 Directivas: Preguntas y Comandos.

1.5 Errores de Sintaxis.

1.6 Predicados no definidos.

1.7 Ejecución de Programas e Interrupción de éstos.

1.8 Salida del Intérprete.

1.9 Ejecuciones Anidadas - Break y Abort.

1.10 Guardando y Recuperando Estados de Programas.

1.11 Inicialización.

1.12 Entrandas a Prolog.

CAPÍTULO 2. DEPURACIÓN.

2.1 El Modelo de Flujo del Procedimiento Box Control.

2.2 Predicados Básicos de Depuracion .

2.3 Rastreo.

2.4 Spy-Points.

2.5 Formato de los Mensajes de Depuración.

2.6 Opciones Disponibles Durante la Depuración.

2.7 Consultar Durante la Depuración.

CAPÍTULO 3. COMPILACIÓN.

3.1 Llamando al Compilador

Page 2: Tutorial de Prolog

3.2 Declaraciones Públicas.

3.3 Mezclando Código Compilado y Código Interpretado.

3.4 Declaraciones de Modo.

3.5 Indexación.

3.6 Optimización de la Cola de Recursión.

3.7 Limitaciones Practicas.

CAPÍTULO 4. CONSTRUCCION DE PROCEDIMIENTOS.

4.1 Etradas / Salidas.

4.1.1 Lectura de Programas.

4.1.2 Manejo de Archivos.

4.1.2.1 Un Ejemplo.

4.1.3 Entrada y Salida de Terminos.

4.1.4 Entrada / Salida de Caracteres.

4.2 Aritmética.

4.3 Comparación de Terminos.

4.4 Ventajas.

4.5 Controles Extras.

4.6 Informacion Acerca del Estado de los Programas.

4.7 Meta-logica.

4.8 Modificación de los Programas.

4.9 Base de Datos Interna.

4.10 Sets.

4.11 Compilando Programas.

4.12 Depurando.

4.13 Clausulas de Gramática.

4.14 Ambiente.

INTRODUCCIÓN.

Prolog es un lenguaje de programación simple pero poderoso desarrollado en la Universidad de

Page 3: Tutorial de Prolog

Marsella como una herramienta práctica para programación lógica. Desde el punto de vista del

usario, la ventaja principal es la facilidad para programar, ya que se pueden escribir rapidamente ycon pocos errores, programas claramente leíbles.

Para una introducción al Prolog, se recomienda que se consulte el libro de Closkin y Mellish (81), sin

embargo, para beneficio de aquellos que no tiene acceso al libro y para aquellos que tienenconocimientos anteriores de lógica, se encuentra un sumario del lenguaje en el apéndice I de esta

obra.

Este manual describe el Sistema Prolog que fue desarrollado en el Departamento de InteligenciaArtificial de la Universidad de Edimburgo expresamente para el DECsystem-10. Este sistema se

compone de un intérprete y un compilador, ambos escritos también en Prolog. A nivel del usuario, elcompilador se puede considerar como un procedimiento integrado en el sistema que puede ser

llamado por el intérprete.

Ya compilado, un procedimiento se puede correr a una velocidad de 10 a 20 veces más rápida, asícomo su almacenamiento también se ve reducido. Sin embargo, se recomienda que los usuariosnuevos ganen experiencia con el intérprete antes de intenten usar el compilador. El interprete facilita

el desarrollo y la prueba de programas así como también provee facilidades muy poderosas para ladepuración del código.

Ciertos aspectos del Prolog no se han previsto en la instalación, por ejemplo el tipo de monitor en el

que se va a usar, aspecto que lleva muchos de los procedimientos con los que el sistema cuenta. Estemanual describe la instalación de la versión de Edimburgo bajo TOPS-10, versión 7.01, los usuarios de

otro tipo de instalación se pueden referir al apéndice III.

Este manual se basa en la obra "User's Guide to DECsystem-10 Prolog" de L.M. Pereira, F.C.N.Pereira y D.H.D. Warren. Parte del capítulo 2 se tomo del libro de Byrd, (80). Comentarios muy utiles

que se presentan en este manual fueron reslizados por Lawrence Byrd, Luis Jenkins, RichardO'Keefe, Fernando Pereira, Robert Rae y Leon Sterling.

El sistema Prolog es mantenido por el Departmento de Inteligencia Artificial y el Engineering Board

Computing Committee del Science and Engineering Research Council.

Regresar al Indice

CAPÍTULO 1. COMO CORRER PROLOG.

El Prolog para el DECsystem-10 ofrece al usuario un ambiente de programación con herramientas

para construir programas, depurarlos siguiendo su ejecución a cada paso y modificar partes de los

programas sin tener que volver a comenzar todo el proceso desde el último error.

El texto en un programa en Prolog se crea en un archivo o en un número de archivos usando cualquier

editor de texto estándar. El intérprete de Prolog puede ser instruido para que lea los programas

contenidos en estos archivos. A esta operación se le llama consultar el archivo.

Page 4: Tutorial de Prolog

Regresar al Indice

1.1 Comienzo

Para correr el intérprete de Prolog, se deberá teclear el siguiente comando:

.r prolog

El intérprete responde con un mensaje de identificación y el indicador "| ?- " se presentará cuando el

sistema esté listo para aceptar cualquier entrada, así, la pantalla se verá como sigue:

Edinburgh DEC-10 Prolog version 3.47

University of Edinburgh, September 1982

| ?-

En este momento el intérprete estará ya esperando que el usuario ingrese cualquier comando por

ejemplo: una pregunta o una orden (ver sección 1.4). No se pueden introducir cláusulasinmediatamente (ver sección 1.3). Este estado se llama nivel alto del intérprete. Mientras que se

teclea un comando, el indicador permanecerá de la siguiente manera:

"| ".

El indicador "?-" aparecerá solamente en la primera línea.

Regresar al Indice

1.2 Lectura de archivos con programas

Un programa esta compuesto por una secuencia de cláusulas que se pueden intercalar con directivas

para el intérprete. Las cláusulas de un procedimiento no necesariamente tienen que ser consecutivas,

pero si es necesario recordar que el orden relativo es muy importante.

Para Ingresar un programa desde un archivo, sólo se tiene que teclear el nombre del archivo dentro

de corchetes y seguidos de un ENTER:

| ?- [archivo] ENTER

Esta orden le dice al intérprete que tiene que leer (consultar) el programa. La especificación del

archivo tiene que ser un átomo de Prolog, también puede contener especificación de dispositivos y/o

una extensión, pero no se debe incluir la ruta de ubicación. Notese que es necesario que todas estasespecificaciones se coloquen dentro de comillas, por ejemplo:

Page 5: Tutorial de Prolog

| ?- ['dska:myfile.pl'].

Después de haber tecleado esto el archivo será leído,

Así las cláusulas que se han guardado en un archivo están listas para ser leídas e interpretadas,

mientras que las directivas son ejecutadas al momento de ser leídas. Cuando se encuentra el fin del

archivo, el intérprete pone en pantalla el tiempo que se ha gastado en la lectura y el número depalabras ocupadas por el programa. Cuando este mensaje se despliegue quiere decir que el comando

se ha ejecutado con éxito.

También se pueden combinar varios archivos de la siguiente manera:

| ?- [miprograma,archivos_extras,archivos_de_tests].

En este caso los tres archivos serán leídos.

Si un nombre de archivo se antecede del signo "menos" (-), por ejemplo:

| ?- [-tests,-fixes].

Entonces este archivo o estos archivos serán releídos. La diferencia entre la lectura simple y la

releída es que cuando un archivo es leído entonces todas las cláusulas en el archivo se añaden a la

base de datos interna de Prolog, mientras que si se lee el archivo dos veces, entonces se tendrá unacopia doble de todas las cláusulas.

Sin embargo, si un archivo es releído entonces las cláusulas de todos los procedimientos en el archivo

reemplazarán a cualquier cláusula existente anteriormente. La reconsulta es útil para indicarle aProlog las correcciones que se realizan a los programas.

Regresar al Indice

1.3 Ingreso de las cláusulas a la terminal

Las cláusulas se puede ingresar directamente en la terminal pero esto es recomendado solamentecuando éstas no se necesitan permanentemente y cuando son pocas. Para ingresar cláusulas desde la

terminal, se debe dar el comando especial: give the special command:

| ?- [user].

|

y el indicador "| " mostrara que el intérprete está ahora en el estado de espera de cláusulas odirectivas. Para ingresar al nivel más alto del intérprete se deberá teclear Contro + Z (^Z). Este es el

equivalente al fin de archivo de archivo temporal virtual llamado ‘user’

Page 6: Tutorial de Prolog

Regresar al Indice

1.4 Directivas: Preguntas y comandos

Las directivas pueden ser preguntas y/o comandos. Ambas pueden ser formas de dirigir al sistema

para alcanzar alguna o algunas metas. En el siguiente ejemplo, la función de pertenencia a una lista sedefina como sigue:

member(X,[X|_]).

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

(Notese que las variables sin valor asignado se representan como "_".)

La sintáxis completa para una pregunta es "?-" seguida por una secuencia de metas, por ejemplo:

?- member(b,[a,b,c]).

Al nivel más alto del intérprete (en el que el indicador es como este: "| ?- "), una pregunta se puede

teclear abreviando el "?-" que de hecho ya está incluído en el indicador. Así, en el nivel más alto, una

pregunta se vería de la siguiente manera:

| ?- member(b,[a,b,c]).

Recuerde que los términos en Prolog deben terminar con el punto ".", por lo que el Prolog no

ejecutará nada hasta que Usted haya tecleado este punto y un ENTER al final de la pregunta.

Si la meta que se ha especificado en la pregunta puede ser satisfecha, y si no hay variables aconsiderar como en este ejemplo, entonces el sistema responde:

yes

Y la ejecución de la pregunta ha terminado.

Si en la pregunta se incluyen variables, entonces el valor final de cada variable es desplegado

(excepto para las variables anónimas). Así la pregunta:

| ?- member(X,[a,b,c]).

Podría ser respondida como:

X = a

En este momento el intérprete estará esperando que el usuario introduzca un ENTER o un punto "."Seguido de un ENTER. Si se teclea solamente ENTER, termina la pregunta y el sistema responde

"yes". Sin embargo, si se teclea ".", el sistema realiza un backtracking y busca soluciones

alternativas. Si no hay soluciones alternativas entonces el sistema responde:

Page 7: Tutorial de Prolog

no

La salida para algunas preguntas como la que se muestra abajo, donde un número precede a un "_"

significa un nombre generado por el sistema para una variable, por ejemplo:

| ?- member(X,[tom,dick,harry]).

X = tom ;

X = dick ;

X = harry ;

no

| ?- member(X,[a,b,f(Y,c)]), member(X,[f(b,Z),d]).

X = f(b,c),

Y = b,

Z = c

yes

| ?- member(X,[f(_),g]).

X = f(_52)

yes

| ?-

En el caso de los comandos, son similares a las preguntas excepto porque:

1. Las variables asociadas con un valor no se muestran cuando la ejecución del comando tiene

éxito.

2. No existe la posibilidad de hacer backtracking para encontrar otras alternativas.

Los comandos inician con el símbolo ":-" . A nivel alto del intérprete simplemente basta con iniciarcon el indicador "| ?- ". Cualquier salida pretendida debe ser programada explícitamente, por ejemplo,

en el comando:

:- member(3,[1,2,3]), write(ok).

Dirije al sistema para que verifique si el número 3 pertenece a la lista [1,2,3], y a que redirija la salida

hacia la variable "ok" si así es. La ejecución de un comando termina cuando todas las metas en el

comando se han ejecutado de manera exitosa. No se muestran soluciones alternativas. Si no seencuentra solución entonces el sistema indica:

Page 8: Tutorial de Prolog

?

como una advertencia.

El uso principal de los comandos (en oposición al uso de las preguntas) es permitir a los archivos el

contener las directivas que llaman a varios procedimientos, para los cuales el usuario no requiere

salida impresa. En estos casos solo se requiere llamar a los procedimientos por su efecto, por

ejemplo, si no quiere tener interacción con el intérprete durante la lectura de un archivo. Un ejemplomuy útil es el uso de una directiva que consulte una lista completa de archivos.

:- [ bits, bobs, main, tests, data, junk ].

Si un comando como este se encuentra contenido en el archivo 'myprog' entonces, teclear lo siguiente

sería la forma más rápida para cargar el programa entero:

| ?- [myprog].

Cuando se interactúa al nivel más alto del intérprete de Prolog, la distinción entre comandos y

preguntas es normalmente muy importante. A este nivel se teclean las preguntas en forma normal.

Solo si se lee de un archivo, entonces para realizar varias metas se deben usar comandos, por

ejemplo; una directiva en un archivo debe ser precedida por un ":-", de otra manera serían tratados

como cláusulas.

Regresar al Indice

1.5 Errores de sintáxis

Los errores de sintaxis se detectan durante la lectura. Cada cláusula o directiva, o en generalcualquier término leido de un archivo o de la terminal, que provoca una falla, es desplegado en la

terminal tan pronto como es leído por el sistema. Una marca indica el punto en la cadena de símbolos

en donde al parser ha fallando en su análisis, por ejemplo:

member(X,X:L).

Implica que el parser muestre:

*** syntax error ***

member(X,X

*** here *** : L).

Si el operador "." No ha sido declarado como operado infijo.

Notese que no se muestran comentarios que especifiquen el tipo de error. Si usted tiene duda acerca

de qué cláusula contiene el error, puede usar el predicado:

Page 9: Tutorial de Prolog

listing/1

Para enlistar todas las cláusulas que han sido eficientemente leídas, por ejemplo:

| ?- listing(member).

Regresar al Indice

1.6 Predicados no definidos.

El sistema puede ocasionalmente también darse cuenta de que se han llamado a predicados que no

tienen cláusulas, el estado de esta facilidad de identificación puede ser:

- 'trace', que causa que este tipo de errores sean desplegados en la terminal y que el proceso de

depuración muestre la última vez que ha ocurrido.

O,

- 'fail', que causa que estos predicados fallen (este es el estado por default)

El predicado evaluable:

unknown(OldState,NewState)

unifica a OldState con el estado actual y coloca a State como Newstate. Este falla si los argumentos

no son los apropiados. La depuración de predicados evaluables imprime el valor de este estado a lo

largo de otras informaciones. Es importante notar que se lleva casi un 70% más de tiempo correr al

intérprete en esta modalidad. Se espera que esta facilidad se pueda mejorar en el futuro.

Regresar al Indice

1.7 Ejecución de programas e interrupción de éstos.

La ejecución de un programa se incia cuando se le da al intérprete una directiva en la cual se

continenen llamadas a uno de los procedimientos del programa.

Sólo cuando la ejecución de una directiva se ha realizado por completo es cuando el intérprete va por

otra directiva. Sin embargo, uno puede interrumpir la ejecución normal de ésta al presionar ^C

mientras el sistema está corriendo. Esta interrupción tiene el efecto de suspender la ejecución y sedespliega el siguiente mensaje:

function (H for help):

En este momento el intérprete acepta comando de una sola letra, que correspondan con ciertas

Page 10: Tutorial de Prolog

acciones. Para ejecutar una acción simplemente se deberá teclear el carácter correpondiente (en

minúsculas) seguido de un ENTER. Los posibles comandos son:

a aborta el comando actual tan pronto como sea posible

b detiene la ejecución (ver apartado 1.9)

c continuar la ejecución

e Salir de prolog y cerrar todos los archivos

g manejar posibilidad de recobrar aspectos ya borrados con anterioridad

h Lista todos los comandos disponibles

m Sale a nivel Monitorl (puede teclear Monitor o CONTINUE)

n desactiva el comando trace

t activa el comando trace

Notese que no es posible romper la ejecución directamente desde el código compilado, cada una de

las opciones "a", "b" y "t" piden que el intérprete realice una acción, por lo que la acción se seguirá

realizando hasta que el código compilado devuelva en mando al intérprete.

Note también que la opción ("a") no saca al usuario cuando esta en modo [user] es decir insertando

cláusulas desde la terminal. Tiene que teclear ^Z para parar este proceso o teclear ("e") para poder

salir de Prolog.

Si se trata de abortar un programa con ^C y accidentalmente se llegara al nivel Monitor, (quizá

porque se apretó ^C demasiadas veces), deberá teclear CONTINUE para regresar a la interrupción

^C.

Regresar al Indice

1.8 Salida del intérprete

Para salir del intérprete y regresar al nivel monitor, deberá teclear ^Z a nivel alto del intérprete, o

llamar al procedimiento "halt" (pre-cargado por default), o usar el comando "e" (exit) seguido de una

interrupción ^C. ^Z es diferentes de los otros dos métodos de salida, ya que imprime algunas

estadísticas. Es posible regresar usando el comando del Monitor CONTINUE después de ^Z, si se

arrepiente de haber querido salir.

Regresar al Indice

Page 11: Tutorial de Prolog

1.9 Ejecuciones anidadas, Break y Abort.

El sistema prolog integra una manera de suspender la ejecución de un programa e introducir nuevas

directivas o cambiar metas a nivel alto del intérprete. Esto se logra si se llama a un predicado

evaluable Break o tecleando "b" despues de una interrupción con ^C ( ver sección 1.7).

Esto causa que el intérprete suspenda la ejecución inmediatamente, a lo que el interprete contestará

[ Break (level 1) ]

Que quiere decir que se ha parado desde el nivel Break y que se pueden introducir preguntas de la

misma manera en que se había hecho desde el nivel alto del intérprete.

El intérprete indica el nivel Break en el que el sistema se encuentra (por ejemplo, en Breaks

anidados), imprimiendo el nivel de Break después de un yes o un no final a las preguntas. Por ejemplo,

a nivel Break 2, se podría ver la respuesta así: uld look like:

| ?- true.

[2] yes | ?-

Un ^Z cierra la interrupción que se había realizado y se reaundan las tareas. Una ejecución

suspendida se puede abortar usando la directiva:

| ?- abort.

Dentro de un break.

En este caso no se necesitaa un ^Z para cerrar el break; Todos los niveles break se descartarán y se

llega automáticamente al nivel más alto del intérprete.

Regresar al Indice

1.10 Guardado y restauración de estados de programas

Una vez que el programa ha sido leído, el intérprete tendrá disponible toda la información que sea

necesaria para su ejecución, esta información se llama estado de programa.

El estado de un programa se puede grabar en disco para ejecuciones posteriores. Para guardar un

programa en un archivo, realice la siguiente directiva:

| ?- save(file).

Este predicado se puede llamar en cualquier momento, por ejemplo, puede ser muy útil a fin de

guardar los estados de un programa inmediatos.

Cuando el programa ha sido guardado en un archivo, la siguiente directiva recuperaría el estado de un

Page 12: Tutorial de Prolog

programa:

| ?- restore(file).

Después de esta ejecución el programa entonces podrá ser regresado exactamente al mismo punto en

que se dejó al momento de salvarlo la ´´ultima vez.

| ?- save(myprog), write('programa restaurado').

Así, al ejecutarse esta orden con el mensaje propio del usuario, se obtendrá el mensaje "programa

restaurado", por ejemplo.

Notese que cuando una versión de Prolog nueva se instala, todos los programas grabados se vuelvenobsoletos.

Regresar al Indice

1.11 Inicialización

Cuando prolog inicia busca un archivo llamado 'prolog.bin' en la ruta default del usuario. Si se

encuentra este archivo entonces se asume que el estado de un programa se ha restaurado. El efectoes el mismo que si se hubiera tecleado:

| ?- restore('prolog.bin').

Si no se encuentra este archivo, entonces se busca en forma similar, el archivo 'prolog.ini'. Si seencuentra este archivo, sería lo mismo que haber tecleado:

| ?- ['prolog.ini'].

La idea de este archivo es que el usuario pueda tener aquí los procedimientos y directivas que se usanusualmente de manera que no se tengan que teclear cada vez que se necesiten.

El archivo 'prolog.bin' parece ser que es útil cuando se usa con el plsys(run(_,_)) que permite correrotros programas desde dentro de Prolog. Esta facilidad permite también regresar al mismo punto si se

corrió prolog desde otros programas. En este caso, el predicado evaluable save/2 debe ser usadopaara salvar el estado del programa dentro de 'prolog.bin'.

Regresar al Indice

1.12 Entrada a prolog

Cuando se entra a prolog directamente en una interacción con la terminal, se escribeautoimaticamente el archivo 'prolog.log' en modo append. Esto es, si ya existe el archivo, en el

Page 13: Tutorial de Prolog

directorio del usuario, entonces la nueva información se añade, si no es así, y el archivo no existe,entonces el archivo se crea.

Sugerencias o comentarios: e-mail: [email protected]

CAPÍTULO 2 DEPURACIÓN

Este capítulo describe las facilidades de depuración que están disponibles en el intérprete de Prolog,

el propósito de estas facilidades es proveer información concerniente al control del flujo del programa,las principales facilidades del paquete de depuración son las siguientes:

- El Procedure_Box, modelo de ejecución de prolog que permite visualizar con fines de control elflujo del programa, especialmente durante un backtracking. El control de flujo se considera unnivel de procedimiento más que un procedimiento a nivel de cláusulas individuales.

- La habilidad para rastrear el programa o un grupo selectivo de puntos de este. Puntos espíasque pueden ser procedimientos básicos o princiapales, en los que el programa deberá tener para

que el usuario pueda interactuar con el sistema.

- La posibilidad de contar con opciones de control y de iformación, disponibles durante ladepuración.

Regresar al Indice

2.1 El modelo de flujo del procedimiento Box Control

Durante la depuración de un programa se imprimen una secuencia de metas defectuosas a fin de

mostrar el estado que el programa ha alcanzado durante esta ejecución. Sin embargo, para poderentender qué es lo que ocurre, es necesrio entender primero cuándo y por que el interprete imprime

las metas. Como en otros lenguajes de programación, existen puntos principales de interés como losprocedimientos de entrada y regreso, pero en Prolog, existe el backtracking que tiene unacomplejidad adicional. Una de las principales confusiones para los novatos es que los programadores

tiene que enfrentar la cuestión de qué es lo que está ocurriendo en el momento en que una meta fallay el sistema inicia repentinamente el backtracking. El modelo Box de Prolog permite que el flujo del

programa posibilite identificar cualquier punto en la ejecución en términos de localización en el textodel programa. Este modelo provee las bases para la depuración de un programa.

Examinando a fondo un procedimiento se tiene:

*--------------------------------------* Call | | Exit ---------> + descendant(X,Y) :- offspring(X,Y). + ---------> | | |descendant(X,Z) :- | <--------- + offspring(X,Y), descendant(Y,Z). + <--------- Fail | | Redo *------------------

--------------------*

Page 14: Tutorial de Prolog

La primer cláusula establece que Y es descendiente de X si Y es resulatdo de X, y la segunda cláusula

establece que Z es descendiente de X si Y lo es de X y si Z es descendiente de Y. En el diagrama, unacaja se ha dibujada al rededor de todo el procedimiento y se han estipulado flechas para establecer elflujo de control con entradas y salidas de esta caja. Existen cuatro flechas por examinar durante el

flujo:

Call que representa la llamada inicial del procedimiento. Cuando una meta es de la forma

descendant(X,Y) se requiere que el centro pase a través de la caja para ver un componente quehaga matching y que de satisfacción a alguna de las submetas en el cuerpo de la cláusula. Este

procedimiento es independiente del matching posible que se de, por ejemplo, en la primeraetapa se llama y el matching tiene lugar. Podemos imaginar textualmente el movimiento delcódigo cuando se llega a una llamada de descendencia en alguna parte del código.

Exit. Esta flecha representa un regreso exitoso del procedimiento. Este ocurre cuando la metainicial ha sido unificada con uno de los componentes clausales y cualquiera de las submetas ha

sido satisfecha. El control entonces pasa por el puerto de salida de la caja de descendencia.Textualmente se para el código siguiente por descendencia y se regresa por el camino por

donde se llegó.

Redo. Esta flecha indica que la meta subsiguiente ha fallado y que el sistema hace backtrackingen un intento de encontrar alternativas a soluciones previas. El control pasa a través del puerto

Redo de la caja de descendencia. Se hace un intento entonces por resatisfacer una de lassubmetas componentes en el cuerpo de la última cláusula en la que se ha tenido éxito, si esto

falla, se hace un completo, nuevo, matching con la cláusula original al cuerpo de una nuevacláusula, textualmente se sigue la parte anterior de código de la manera en que se ha idobuscando nuevas formas de obtener éxito descomponiendo ésta en otras cláusulas y siguiendo

así mientras que sea necesario.

Fail. Esta flecha representa una falla en la meta inicial, que puede ocurrir si no existe un

matching efectivo con alguna cláusula o si las submetas establecidas nunca son satisfechas, o sicualquiera de las soluciones producidas es rechazada siempre por el proceso posterior. El

control pasa entonces por la caja de descendencia en el puerto Fail y el sistema continua enbacktracking. Textuelmente el sistema se mueve hacia atrás en el código que ha llamado esteprocedimiento y se continua moviendose hacia atrás buscando puntos de elección.

En términos de este modelo, la información que nosotros obtenemos acerca de esta caja deprocedimiento, es sólo acerca del flujo de control que se da a lo largo de estos cuatro puertos. Esto

significa que a este nivel no importa con cual cláusula se hace matching y como se da satisfacción alas submetas, sino más bien como quisieramos conocer la meta inicial y la final tienen efecto.

Note que la caja que se ha dibujado para cercar el procedimiento tiene que ser vista como una caja de

invocación, esto es, que hay una caja diferente para cada procedimiento, obviamente con algunosprocesos recurrentes en todos los procedimiento, con diferentes llamadas y salidas en el flujo de

control, pero estas para diferentes invocaciones. Por ello se les de una entero único de identificación acada una de estas cajas.

Page 15: Tutorial de Prolog

Regresar al Indice

2.2 Predicados básicos de depuración.

El intérprete proporciona un rango de predicados evaluables para el control de las facilidades de

evaluación, lo más basicos son los siguientes:

debug que coloca al modo Debug en On (usualmente está en off) a fin de tener un rango ampliode control en el flujo de información disponible desde el principio. Cuando el debug está en off,

el sistema no recuerda los llamados hechos a procedimientos anteriormente, sino que solamenterecuerda las invocasiones que se están ejecutando. Se puede llamar a medias de una ejecución

despues de haber dado un ^C ( ver el comando trace) pero la información anterior no estarádisponible.

nodebug Pone adebug en off, y si existen puntos espías, éstos serán borrados.state. Muestra el estado de debug.

Regresar al Indice

2.3 Rastreo

El siguiente comando evaluable puede ser usado a fin de tener un control más efectivo del programaque se va a depurar.

trace coloca el switch debug en on, si es que no se ha hecho ya, y asegura que el siguientetiempo de control, se despliegará un mensaje y se le pedirá al usuario que interactue con el

sistema. El efecto del rastreo tembién puede ser logrados tecleando un "t" después de unainterrupción con ^C.leash(Mode) coloca el Leashing_Mode en forma de modo, donde modo puede tener cualquiera

de los siguientes valores:full - prompt on Call, Exit, Redo y Fail

tight - prompt on Call, Redo y Failhalf - prompt on Call y Redo

loose - prompt y Calloff - never prompt

o cualquiera otra combinación de estos y de los puertos descritos en la sección 4.12

El valor inicial del modo es "half", se puede cambiar si se modofica el archivo "prolog.ini".

Regresar al Indice

Page 16: Tutorial de Prolog

2.4 Spy-points

Para programas extensos o de cualquier extensión es practicamente imposible que el programadorsiga paso a paso todo lo que esta ocurriendo en cada módulo o en cada meta o submeta. Es por elloque se posibilita la tarea de formular puntos espías que permiten mantener un control exacto

solamente en puntos clave elejidos por el usuario para el control total del programa y su curso.

La selección del modo que se realice no tiene ingerencia alguna en los puntos espías que se han

elegido por parte del usuario.

Los puntos espías son conjuntos de establecimientos de variables y de predicados evaluables otambién de operadores estándares.

spy X Coloca en On el modo de los puntos espías, se puede usar en cualquier predicado o punto delprograma en una oración evaluable o en una directiva establecida previamente.

nospy X Funciona de manera similar a spy X pero en esta caso x es un conjunto de puntos espíasdefinidos previamente y removidos.

Regresar al Indice

2.5 Formato de los mensaje de depuración.

Se puede ver el formato que tienen exactamente y a profundidad los mensajes de error, esto permitirarealizar de una manera más eficiente las tareas de depuración de programas al posibilitar el

conocimiento de los simbolos usados en cada mensaje como este

** (23) 6 Call : foo(hello,there,_123) ?

"**" indica que es un spy-point. Si este punto no es un conjunto de puntos espías predefinidosentonces el puntero se convierte en un ">". Que da las siguientes posibles combinaciones:

"**" un spy-point.

"*>" un spy point con un skip la ultima vez que se estuvo en la caja

" >" No es un sapy point pero si hubo un skip la ultima vez que se estuvo en la caja

" " No es un spy point.

Notese que en esta caso las acciones son rastreadas a fin de mantener un centro exacto en eldepurado durante el establecimiento de este tipo de mensajes.

Regresar al Indice

Page 17: Tutorial de Prolog

2.6 Opciones disponibles durante la depuración

Esta sección describe las opciones particulares que estan disponibles cuando el sistema te muestradespues de algun mensaje de depuracion. Todas las opciones son una letra como nemonico, y algunas

pueden ser opcionales seguidas de un entero decimal. Algunas opciones solo requieren el terminador.

La unica opcion que se hace necesaria de recordar es "h" y un ENTER, ya que es la función que

despliegará a las siguientes funciones:

<cr> creep c creep

<lf> leap l leap

<esc> skip s skip

x back to choice point q quasi skip

r retry r <n> retry goal n f fail f <n> fail goal n

; redo

a abort e salir de Prolog

h help p imprime una meta

w escribe meta d despliega una meta

g imprime ancestros g <n> ultimo n ancestros

@ comando accept b break

[ consult user n nodebug

Las primeras tres opciones son decisiones de control basicas ya que son las más frecuentementeusadas, cada una puede ser llamada con una sola tecla c <cr> Creep

Causa que el intérprete se vaya de un solo paso al siguiente puerto e imprima un mensaje. Si el puerto

esta atascado se le pedira al usuario acciones posteriores, de otra manera el procedimientocontinuará hasta terminar en la terminal.

l <lf> Leap

Causa que el intérprete regrese ala ejecución del programa, solo para cuando un punto espía se haencontrado, o cuando el programa termina

s <esc> Skip

Es válido solamente en el puerto Redo, brinca sobre una ejecución entera o un procedimiento. El uso

de esta directiva de compilación garantiza que el control será devuelto a la caja de control despues de

Page 18: Tutorial de Prolog

la ejecución dentro de la caja. Cuando se da un cuasibrinco o cuasiskip en donde no se ignoran los

puntos espías, la opción "t" después de un ^C desabilitará las máscaras.

q Quasi-skip

Es como skip, excepto porque este brinco no oculta a los puntos espías para la depuración. Si existe

un punto espía en la ejecución de una meta, entonces el control regresa al punto en donde la acción sedebe realizar.

x Back to choice point

Da la posibilidad de hacer un fail rápio, llevando al programa al punto real de decisión anterior.Cuando el usuario sabe que algo hará fail, puede anticipar el punto de decisión y verificarlo

rapidamente sin tener que repetir el proceso completo. Si se da una secuencia de Fails seguidos deuna secuencia de Redos (o si la secuencia está vacía) se tienen mensajes estándares (como los

mostrados anteriormente) excepto para los primeros dos caracteres donde será "=>". Cuando sellama a la acción exit, la operación de salida ocurriá normalmente.

r Retry

Se puede usar en cualquiera de los cuatro puertos, aunque el puerto call no tenga efecto en realidad.Esto permite reestablecer la invocación cuando por ejemplo, el usuario se ha dado cuenta de que ha

obtenido resultados algo raros. El estado de la ejecución es exactamente el mismo que el alcanzadodurante la ejecución normal original. Si se proporciona un entero con el comando retry entonces se

tomará como una especificación de que el sistema trate de invocar al puerto y no a la caja actual, porsupuesto que a un puerto designado por el usuario. Desafortunadamente el proceso no puede sergarantizado. Se puede suplir con cuts (!) al interior del programa. Un mensaje de error "[ ** JUMP **

]" se despliegará en la terminal para indicar que es lo que ha ocurrido.

f Fail

es similar al retry ya que transfiere el contro al puerto fail desde la caja actual, en una posición endonde se estpá cercado a hacer un backtracking

; Redo

Puede ser llamado en una salida y forzar a mover al puesrto Redo

a Abort

Causa que se aborte la ejecución actual. Todas las ejecuciones se mantienen hasta que el usuario seasegura de que no las necesita conforme sube al mas alto nivel del intérprete (es equivalente alpredicado evaluable abort)

e Exit from Prolog

Causa una salida irreversible del sistema de prolog, de regreso al Monitor (esta directiva es

equivalente a Halt)

Page 19: Tutorial de Prolog

h Help

Despliega la tabla de opciones marcada arriba

p Print goal

Reimprime la meta actual usando print

w Write goal

Escribe la meta actual en la terminal usando write. Esto puede ser muy útil cuando la lista temporal derutinas no hace lo que se espera de ella

d Display goal

Despliega la meta en turno, usando display (ver Write arriba).

g Print ancestor goals

Provee al usuario de una lista de las metas o submetas que ya se han cumplido en la ejecución de un

programa, el orden se da en forma jerarquica hacia arriba de la secuencia que ha sido llamada. Usalos ancestros de cada predicado evaluable (ver pág 42). Si se proporciona un entero con esta directiva

entonces se despliegan n antecesores desde el punto en que el usuario ha dado la directiva.

@ Accept command

Permite llamar arbitrariamente a metas de Prolog, es un break de un solo paso muy efectivo, (ver masadelante). El mensaje inicial "| :- " saldrá en la terminal y el comando entonces se lee desde laterminal y se ejecuta como si el usuario estuviera en el nivel más alto.

b Break

Llama al predicado evaluable break, pone al interprete al nivel mas alto con la ejecución aparte del

modulo actual, cuando se finaliza el modo break (^Z) el sistema pregunta en que punto se hizo elrompimiento, y una nueva ejecución se separa de la suspendida, los números de invocación comienzana partir de 1 desde su invocación.

[ Consult user Permite insertar clausulas y regresar a donde se estaba, es lo mismo que usar "@"seguida de "[user].".

n noebug

Desactiva el modo debug, lo pone en Off, es la forma correcta de apagar el debug desde el modo derastreo. No se puede usar "@" o "b" porque siempre activa el debug desde el regreso.

Regresar al Indice

Page 20: Tutorial de Prolog

2.7 Consultar de nuevo durante la depuración.

Es posible y a veces es útil reconsultar o releer un archivo a medias de la ejecución de un programa.Sin embargo, esto puede ocasionar que el sistema funcione de una manera impredecible debido a lassiguientes circunstancias: un procedimiento se ha ejecutado con éxito, se ha redefinido por una

consulta y después se ha reactivado por un backtracking. Cuendo el backtracking ocurre, todas lasclausulas nuevas apaarecerán en el intérprete como posibilidades de alternativa de solución aún

cuando se hayan usado ya clausulas o predicados exactamente iguales, así grandes cantidades deprocedimientos no deseados ocasionarían backtracking. Este problema se evita si se hace el consult

desde el pueto del procedimiento que será redefinido.

Sugerencias o comentarios: e-mail: [email protected]

CAPITULO 3. COMPILACIÓN

El compilador Prolog DECsystem-10 produce código más compacto y eficiente, el cual funciona de 10

a 20 veces más rápido que el interprete de código y requiere mucho menos almacenamiento en tiempode ejecución. Los programas compilados con Prolog, son comparados en eficiencia, con programasdesarrollados en LISP ( con el compilador LISP DECsystem-10 ), para realizar las mismas funciones.

En contra de esto, la desventaja es que la compilación es varias veces más lenta que la "consulta" ymucha de la ayuda proporcionada por el depurador, como el seguimiento, no es aplicable al código

compilado.

Regresar al Indice

3.1 Llamando al Compilador.

Para compilar el programa se usa la siguiente sentencia :

|? compile (Archivos).

donde "Archivos" es cualquier nombre de archivo ( incluyendo el archivo ‘user’ ), o una lista de los

nombres de los archivos que se desean compilar. Con esta instrucción, los procedimientos contenidosen dichos archivos serán compilados. A continuación se muestra un ejemplo con varios archivos :

|? compile ( [dbase, 'extras.pl,' user] ).

Exteriormente, el efecto de "compile" es mucho muy parecido al de "reconsult". Si las cláusulas paraalgunos predicados aparecen en más de un archivo, el juego posterior de dichas cláusulas, sobre-

escribe el anterior. La división del programa en archivos separados no implica ninguna estructuramodular ( ningún procedimiento compilado puede llamar a cualquier otro ).

Page 21: Tutorial de Prolog

Regresar al Indice

3.2 Declaraciones Públicas.

Para hacer que un procedimiento compilado sea accesible por el interprete de código ( incluyendo

directivas ) es necesario declarar dicho procedimiento como público, lo cual se realiza con el comandosiguiente del compilador :

:- public Predicates.

donde "Predicates" es una especificación del predicado, en la forma : Nombre / Arity , o tambiénpuede ser una conjunción de especificaciones semejantes, por ejemplo :

:- public concatenate/3, member/2, ordered/1, go/0.

Las declaraciones públicas pueden aparecer en cualquier parte dentro de un archivo compilado; no esnecesario que las declaraciones públicas procedan a el correspondiente procedimiento, ni tampoco

que estén dentro del mismo archivo.

Regresar al Indice

3.3 Mezclando Código Compilado y Código Interpretado.

Para predicados públicos un procedimiento compilado sobre-escribe cualquier versión interpretadaprevia ( cf. reconsult ). De la misma forma una reconsulta subsecuente de la versión interpretadasobre-escribirá la versión compilada.

Es posible tener un procedimiento compilado con el mismo nombre y arity, así como muchos ydiferentes procedimientos interpretados. Suponiendo que el procedimiento compilado no fue declarado

para ser público, los dos procedimientos nunca intervendrán el uno con el otro, es decir, el códigocompilado utilizará la versión compilada mientras que el interpretador de código usará la versión

interpretada.

Cuando una versión compilado se hace presente y sobre-escribe un procedimiento interpretado, ésteúltimo es reemplazado por la cláusula :

P :- incore(P).

donde "P" es el objetivo más general para el predicado y "encore" es un predicado evaluable

estándar ( análogo a "call" ), por medio del cual son accesibles todos los procedimientos compiladospara los predicados públicos.

Hay dos formas en que el código compilado puede utilizar procedimientos interpretados :

Page 22: Tutorial de Prolog

Si no hay cláusulas compiladas para el predicado, el procedimiento interpretado es llamado

automáticamente.La sentencia : call( P ) , siempre llama al interprete. Es importante hacer notar, que esto implicaque deseamos llamar procedimientos compilados con "call" , deben ser declarados como

públicos.

Para aclarar lo anterior vamos a ver un ejemplo :

Primero compilamos el siguiente archivo: :- public f/1, g/1.

f(a).

g(X) :- f(X).

g(X) :- h(X).

No hay cláusulas para h/1. Después consultamos lo siguiente :

f(b).

h(c).

Ahora, si nosotros llamamos a " f "obtendremos :

?- f(X).

X = a ;

X = b ;

no

Esto es, nosotros usamos tanto las cláusulas compiladas, como las interpretadas para " f ". De

cualquier modo si llamamos a " g " :

?- g(X).

X = a ;

X = c ; no

podemos observar que " g " solo llama la versión compilada de " f ", así que la solución : X = b , no

es encontrada. La segunda cláusula para " g " llama a " h ", y como no hay cláusulas compiladaspara " h " esta llamada es pasada al interprete, el cual encuentra una solución : X = c.

Regresar al Indice

Page 23: Tutorial de Prolog

3.4 Declaraciones de Modo.

Cuando un programa va a ser compilado es conveniente incluir declaraciones de modo, las cualesinforman al compilador que ciertos procedimientos serán usados en forma restringida, es decir, que

algunos argumentos en la llamada siempre serán "entrada", mientras que otros siempre serán"salida". Esta información habilita al compilador para ser capaz de generar código más compacto y

hacer un mejor uso del almacenamiento en tiempo de ejecución. Las declaraciones de modo tambiénayudan a que otras personas comprendan la operación del programa.

Una declaración de modo es indicada con una directiva del compilador de la forma :

:- mode P(M).

donde "P" es el nombre de un procedimiento y "M" especifica los "modos" de sus argumentos. M

consiste de cierto número de "elementos de modo" ( elementos que indican el modo deseado para los

argumentos ), separados por comas, una para cada posición de los argumentos del predicadointeresado. Los elementos de modo pueden ser de cualquiera de los 3 tipos siguientes :

Modo + : Especifica que el argumento correspondiente en cualquier llamada al procedimientosiempre será "entrada".Modo - : Indica que el argumento nunca será "entrada", es decir, siempre será "salida".

Modo ? : Indica que no hay restricción en la forma del argumento. Por ejemplo, una declaraciónde modo como :

:- mode concatenate(?,?,?).

es equivalente a omitir completamente la declaración.

Por ejemplo, si tenemos un procedimiento llamado "encadenar" y los dos argumentos primeros,

siempre serán "entradas", podemos dar la siguiente declaración de modo :

:- mode encadenar(+,+,?).

En el caso de que en el procedimiento anterior el tercer argumento siempre será "salida", podemosreforzar la declaración de modo como sigue :

:- mode encadenar(+,+,-).

Además, esta permitido combinar varias declaraciones de modo en un solo comando, por ejemplo :

:- mode encadenar(+,+,-), mode miembro(+,?), mode orden(+).

Para que una declaración de modo tenga efecto debe aparecer antes de las cláusulas delprocedimiento correspondiente. Cuando una declaración de modo es violada por una llamada a unprocedimiento, la forma precisa como reacciona depende de el objetivo y la cabecera de la cláusula.

La llamada puede ser realizada con éxito como si no hubiera una declaración de modo o puede causarun mensaje de error y fracasar. Como el resultado preciso depende de los cambios en las versionesfuturas del sistema, el usuario debió asumir que todas las declaraciones de modo que son violadas

Page 24: Tutorial de Prolog

causaran un mensaje de error.

Las declaraciones de modo son ignoradas por el interprete.

Regresar al Indice

3.5 Indexación.

En contraste con el interprete, las cláusulas de un procedimiento compilado son indexadas de acuerdoal "functor" principal del primer argumento especificado en la cabecera de la cláusula. Esto significaque el subconjunto de cláusulas, son emparejadas con un determinado objetivo, hasta que el primerpaso de la unificación interesada, sea hallada muy rápidamente, prácticamente en un tiempo constante

( un tiempo independiente del número de cláusulas ). Esto puede ser muy importante donde hay ungran número de cláusulas en un procedimiento.

La indexación también mejora la capacidad del sistema de Prolog para detectar la determinacia, lacual es importante en la conservación del espacio de trabajo.

Regresar al Indice

3.6 Optimización de la cola de Recursión.

El compilador incorpora "Optimización de la cola de recursión" para mejorar la velocidad y laeficiencia del espacio de procedimientos determinados. Cuando la ejecución alcanza el último objetivoen una cláusula que pertenece a un procedimiento, y provee que no hay puntos de retroseguimientorestantes, todo el espacio de trabajo asignado a los procedimientos locales es reclamado ANTES definalizar la llamada y cualquier estructura que fue creada es eliminada. Esto significa que el programa

puede realizar varias recursiones sin necesidad de exceder el limite en el espacio.

Por ejemplo :

cycle(State) :- transform(State,State1), cycle(State1).

donde "transform" es un procedimiento determinado, puede continuarse ejecutando indefinidamente,previendo que cada estructura individual "State", no sea demasiado larga. El procedimiento "cycle"

es equivalente a un lazo iterativo de in lenguaje convencional.

Para lograr la ventaja de la optimización de la cola recursiva, debemos asegurarnos que Prolog puedareconocer que el procedimiento es determinado en el punto donde la llamada recursiva toma lugar.Dicho en otra forma, el sistema debe ser capaz de detectar que no hay otras soluciones que deben serencontradas para el objetivo actual, mediante subsecuente retroseguimiento. En general esto esta

envuelto en la indexación del compilador Prolog DEC-10 y / o el uso de corte.

Page 25: Tutorial de Prolog

Regresar al Indice

3.7 Limitaciones Practicas.

Algunas consideraciones que debemos tomar en cuenta son :

Hay que tener presente que el espacio ocupado por el código compilado, cuando esreemplazado, no es reclamado.

Hacer que un predicado sea público, nos lleva a generar una cantidad significante de códigoextra. Además este código es regenerado cada vez que el compilador es llamado ( con lo cual elespacio ocupado por el código anterior no es reclamado ). Debido a esto, es conveniente,cuando sea posible, incluir en una sola llamada al compilador, todos los archivos que se desea

sean compilados.La ejecución del código compilado no puede ser "rota" o "abortada", lo cual si s posible con elcódigo interpretado. Una respuesta a la petición para "abortar", realizada con CTRL+C, solotiene efecto en la siguiente entrada de un procedimiento interpretado.

Se puede notar que hay una pausa despreciable en el inicio y terminación de la compilación. Esto se

debe a que el compilador reside en una capa separada, la cual debe ser intercambiada.

Sugerencias o comentarios: e-mail: [email protected]