Como en todos los lenguajes, en Prolog existe la posibilidad de manejar entrada/salida, esto es, ficheros, pantalla, impresoras, etc. Todo ello se hace a trav�s de streams (concepto id�ntico al de otros lenguajes).
Los streams son buffers para escribir y/o leer de dispositivos como el teclado, la pantalla, el disco, etc. De modo que consideramos tres tipos de streams:
- Streams de entrada (lectura).
- Streams de salida (escritura).
- Streams de entrada y salida (h�bridos).
Existen dos grupos de predicados para manejar streams:
- Aquellos donde el stream se indica expl�citamente. Se suelen utilizar para manipular ficheros y sockets.
- Aquellos donde el stream es �mplicito. Manipulan la entrada y salida standard, lo que habitualmente supone el teclado y la pantalla.
�Entrada/Salida standard
Cada vez que ejecutamos un programa, �ste tiene predefinidos tres streams correspondientes a la entrada, salida y error standard. Los siguientes predicados sirven para conocer cuales son dichos streams:
Predicado | Modo de uso | Descripci�n |
current_output/1 | current_output(-Stream) | Retorna el stream asociado a la salida standard |
current_input/1 | current_input(-Stream) | Retorna el stream asociado a la entrada standard |
Un programa siempre puede cambiar dichos streams para que se dirijan a otros dispositivos. El nuevo stream debe obtenerse mediante alguno de los predicados que veremos m�s tarde.
Predicado | Modo de uso | Descripci�n |
set_output/1 | set_output(+Stream) | Cambia el stream asociado a la salida standard |
set_input/1 | set_input(+Stream) | Cambia el stream asociado a la entrada standard |
�Entrada standard
El predicado estrella para leer de la entrada standard es read/1 cuyo modo de uso es read(-Term). Dicho predicado es capaz �nicamente de leer t�rminos que estar�n separados unos de otros por un punto (.) y un salto de l�nea, igual que cuando tecleamos en el top-level shell.
Cuando ya no hay m�s t�rminos para leer en la entrada standard, el predicado retorna el t�rmino end_of_file/0.
Si leer t�rminos no es lo nuestro, simpre podemos leer caracteres uno a uno mediante el predicado get/1. Su modo de uso es get(-Char) y retorna el c�digo ASCII del caracter leido. Cuando ya no hay m�s caracteres retorna -1.
�Salida standard
Para escribir en la salida standard disponemos del predicado write/1 que recibe un t�rmino como argumento. An�logamente a la entrada standard, el predicado put/1 escribe caracteres simples, recibiendo como argumento el codigo ASCII correspondiente.
Adicionalmente existen los predicados display/1 cuyo efecto es el mismo que write/1, y el predicado nl/0 que escribe un salto de l�nea en la salida standard.
�Ejemplo
Este es un programa que lee n�meros de la entrada standard (separados por punto) hasta que se encuentra alg�n t�rmino que no sea un n�mero. Entonces suma todos los n�meros y escribe el resultado por la salida standard.
sumar_lista([],Parcial,Parcial). sumar_lista([Num|Resto],Parcial,Result) :- NParcial is Num+Parcial, sumar_lista(Resto,NParcial,Result). leer_numero(Num) :- read(Num), number(Num). suma :- suma_aux([]). suma_aux(Lista) :- leer_numero(Num), suma_aux([Num|Lista]). suma_aux(Lista) :- sumar_lista(Lista,0,Result), nl, display('LA SUMA ES : '), display(Result), nl.
�Entrada/Salida expl�cita
A diferencia de la entrada/salida standard, estos predicados podr�an no estar predefinidos, en tal caso deben ser importados previamente. La biblioteca a importar puede variar de un entorno de desarrollo a otro, por lo que debe consultar la documentaci�n correspondiente. El modo de importar bibliotecas tambi�n var�a de un sistema a otro.
� El predicado read_term/3
Modo de uso: read_term(+Stream,-Termino,+Opciones).
Este predicado sirve para leer t�rminos del stream indicado. Su peculiaridad radica en que podemos indicar algunas opciones sobre como leer el t�rmino. El argumento Opciones consiste en una lista (posiblemente vac�a) de t�rminos que pueden ser cualquiera de los siguientes:
- variables(-ListaVariables). Unifica ListaVariables con la lista de variables libres que aparecen en el t�rmino leido.
- variable_names(-ListaNombres). Unifica ListaNombres con una lista de terminos cero-arios que representan los nombres de las variables libres que aparecen en el t�rmino leido.
- Otras opciones dependen del entorno de desarrollo usado. Consulte la documentaci�n asociada.
Recuerde que, cuando ocurre el evento de fin de fichero, este predicado retorna el t�rmino end_of_file/0.
�Ejemplo
?- current_input(I),read_term(I,Term,[variables(L1),variable_names(L2)]). |: t(A,b(C,A)). I = user_input, L1 = [_A,_B], L2 = ['A'=_A,'C'=_B], Term = t(_A,b(_B,_A)) ? yes ?-
�El predicado write_term/3
Modo de uso: write_term(+Stream,+Termino,+Opciones).
Este predicado es similar al anterior puesto que nos permite escribir un t�rmino en un stream controlando una serie de opciones. El argumento Opciones debe ser instanciado a una l�sta (posiblemente vac�a) de t�rminos que se encontrar�n entre alguno de los siguientes:
- quoted(true). Aquellos functores que contengan "caracteres raros" (no alfanum�ricos) ser�n escritos entre comillas simples. Esta opci�n es muy importante si los t�rminos van a ser leidos posteriormente con read_term/3 o similar.
- ignore_ops(true). Normalmente, aquellos functores que esten declarados como operadores se escriben de manera infija o postfija seg�n corresponda. Con esta opci�n obligamos a que siempre se escriban de manera prefija. Por ejemplo, a+b se escribir�a forzosamente como +(a,b).
- Otras opciones dependen del entorno de desarrollo usado. Consulte la documentaci�n asociada.
�Ejemplo
?- current_output(O),write_term(O,'1�y�2'+Z,[quoted(true),ignore_ops(true)]). +('1 y 2',_347) O = user_output ? yes ?-
�Ficheros
Para manipular ficheros solamente necesitamos abrirlos y/o cerrarlos. Cuando abrimos un fichero obtenemos un stream que podemos manejar mediante los predicados anteriormente descritos.
�Apertura de ficheros
Se hace mediante el predicado open/3, con el modo de uso open(+Fichero,+Modo,-Stream). Fichero es un t�rmino cero-ario con la ruta del fichero (normalmente entre comillas simples). Modo puede ser uno de estos t�rminos:
- read/0. Abrir en modo de solamente lectura.
- write/0. Abrir en modo de solamente escritura. Si el fichero contiene datos, se truncan.
- append/0. Abrir en modo de solamente escritura. El fichero no se trunca, los nuevos datos se a�aden al final.
�Cierre de ficheros
Para ello existe el predicado close/1, cuyo modo de uso es close(+Stream). El stream queda invalidado una vez que se cierra el fichero. Este predicado vuelca a disco los contenidos del buffer antes de cerrarlo. Si deseamos hacer esto sin cerrar el fichero, disponemos del predicado flush_output/1.
�Culturilla
- Cuando read/1 intenta leer un t�rmino pero se encuentra con un error sint�ctico (el t�rmino est� mal construido), emite un mensaje de error y el predicado falla. Afortunadamente, hay medios para cambiar este comportamiento, que veremos m�s adelante.
- Nada impide que read/1 lea un t�rmino que contenga variables libres. Tenga en cuenta que dichas variables ser�n siempre distintas a las variables del programa en ejecuci�n y de las variables le�das en llamadas anteriores a read/1, independientemente del nombre que se les ponga a dichas variables. Naturalmente, si una variable aparece dos veces en el mismo t�rmino leido, en efecto se tratar� de la misma variable.
- Cuando la entrada standard es el teclado e intentamos leer de �l, Prolog muestra un s�mbolo de "prompt" para indicarnos que est� preparado para que tecleemos. Dicho s�mbolo tiene este curioso aspecto: �
� Copyright 2000-2001
Angel Fern�ndez Pineda.