FUNDACIÓN UNIVERSITARIA KONRAD LORENZ FACULTAD DE MATEMÁTICAS E INGENIERÍA PROGRAMA DE INGENIERÍA DE SISTEMAS SISTEMAS BASADOS EN EL CONOCIMIENTO I MAYO DE 2007

Prof. Pervys Rengifo Rengifo ALGUNOS EJEMPLOS EXPLICADOS DE MANEJO DE ARCHIVOS EN WINPROLOG Por: Felipe Forero Lozano1

1. Función que imprime los elementos de una lista uno a uno. prlist([]) :- !. prlist([Head|Tail]) :tab(4), print(Head), nl, prlist(Tail). De manera recursiva, prlist imprime miembro a miembro los elementos de una lista ingresada, en el caso base, prlist([]) :- ! Cuando la lista es vacía, no hace nada; en los otros casos, cuando la lista tiene miembros, prlist([Head|Tail]) :tab(4), print(Head), nl, prlist(Tail). Por medio de [Head|Tail], dividimos la lista de tal manera que en Head se almacena el primer miembro y en Tail la lista de los demás elementos. De esta manera, cada vez q se llame a la función, esta imprime el primer miembro de la lista que recibe y llama de nuevo la función con el resto de la lista, hasta que esta sea vacía, que es cuando entra en el caso base. Por ejemplo:

1

Estudiantes de Octavo semestre del Programa de Ingeniería de Sistemas de la Fundación Universitaria Konrad Lorenz, FUKL, http://www.fukl.edu

2. Función que imprime una lista en un archivo. imprime_lista(_Fichero, []). imprime_lista(Fichero, [C|R]) :-tell(Fichero), write( C), nl, imprime_lista(Fichero, R), told. De la misma manera que la funcion anterior, esta se llama recursivamente, separando el primer elemento para imprimirlo, y llamar la funcion con el resto de la lista. Por medio de la funcion tell, cambiamos el Stream de salida, que por defecto es user, que es la consola de WinProlog. Al usar la funcion tell, hacemos que las salidas sean escritas en el archivo que sea especificado en el parámetro que recibe. imprime_lista(Fichero, [C|R]) :-tell(Fichero), luego de esto, hacemos que se escriba el primer elemento de la lista recibida write( C), y llamamos de nuevo la funcion después de un salto de línea nl, imprime_lista(Fichero, R), told. Con told, hacemos que el Stream de salida sea de nuevo user. Ejemplo:

Y en el archivo tendremos:

Como se puede observar, para representar una lista en prolog, esta debe ir entre [], y cada elemento debe ir separado por comas. El nombre del archivo debe ir entre comillas sencillas, y con la extensión, además, se puede especificar la ruta completa, usando “c:\....\....txt”. Si en el parámetro del fichero, escribimos la palabra “user”, nos referimos a la consola de prolog, por la tanto, la salida seria como lo es normalmente, en la consola.

3. Predicado que una lista y la escribe en un archivo. prueba_fich :write('Introduzca una lista: '), nl, read(Lista), open('prueba.txt',write), imprime_lista('prueba.txt', Lista), write('la lista se ha escrito en el fichero prueba.txt'), close('prueba.txt'). Esta utiliza la funcion ya creada imprime_lista, primero lee la lista por la consola, luego crea el archivo, en modo de escritura, y llama la funcion para imprimir la lista en este archivo, seguido de esto, saca un aviso de confirmación, y cierra el archivo. La entrada de la lista debe seguir la sintaxis que ya explicamos en párrafos anteriores Ejemplo:

Y en el archivo:

4. Función que lee el contenido de un archivo y lo imprime en pantalla de la consola. listfile(File):- see(File), repeat, read_write. read_write:eof, !, seen. read_write:eread(Terms, Vars), ewrite(Terms, Vars), write('.'), nl, fail. En la primera línea, listfile(File):- see(File), repeat, read_write. En el parámetro de la función, recibimos el nombre del archivo que se va a abrir, y por medio de see, hacemos que la entrada de datos no sea por medio de la consola sino que sea por medio del archivo. Luego llamamos la función read_write, read_write:eread(Terms, Vars), ewrite(Terms, Vars), write('.'), nl, fail. Por medio de eread y ewrite, leemos elemento a elemento de la entrada que este caso es el archivo, y la escribimos en la consola, ya que no hemos cambiado ese parámetro. En el archivo, las líneas deben estar con la sintaxis que exige prolog en la entrada de datos, para que este pueda reconocerlo como un valor. Ejemplo: Archivo de entrada:

Ejecución de la función:

5. Escribir en un archivo. Como ya lo vimos, para escribir en un archivo, cambiamos el Stream de salida, que por defecto es la consola de prolog, y ponemos en su lugar, el nombre del archivo en donde queremos guardar. escr:-tell('pruebasss.pl'), write('eksgdfhdfhk'), told, close('pruebasss.pl'). Las funciones de tell y see, deben ser cerradas de nuevo por medio de told y seen respectivamente. 6. Copiar un archivo en otro. prolog_copy(Archivo1, Archivo2):see(Archivo1), tell(Archivo2), repeat, read(Term), (Term\=end_of_file -> writeq(Term), write('.'), nl, fail ;seen, told). Por medio de los predicados tell y see, cambiamos la entrada y la salida por los archivos de entrada y de salida. Leemos término a término por medio de las sentencias repeat y fail, repeat, read(Term), (Term\=end_of_file

-> writeq(Term), write('.'), nl, fail

Entre las cuales se evalúa si se llego al final del archivo, si es asi, cierra la entrada y la salida con told y seen, y si no, repite el ciclo, escribiendo en el archivo de salida, lo que lea del de entrada.

Ejemplo:

El archivo de origen debe estar con sintaxis apropiada para prolog, es decir con puntos al final de cada dato y con un salto de línea entre cada uno de estos:

Y el archivo de salida:

7. Ejemplo de Repeat. ejemplo_repeat:repeat(19), write('Marthe'), nl, fail. Este predicado repite esta acción 19 veces, por medio del predicado repeat(19), acompañado de a palabra fail, que obliga a prolog a realizar de nuevo la acción desde repeat. Ejemplo:

8. Modificación del prolog_copy. prolog_copy:repeat, read(Term), (Term\=end_of_file -> writeq(Term), write('.'), nl, fail ; true). En esta versión, no se especifica la entrada ni la salida, entonces lo que hace es pedir datos por la consola e imprimirlos en la consola. Podría modificarse para que uno de las dos acciones las haga de un archivo. El predicado empieza con un ciclo, dentro de este se lee e termino en Term, y se evalúa si no es el fin del archivo prolog_copy:repeat, read(Term), (Term\=end_of_file Si no es así, se imprime el término y se repite de nuevo el ciclo, pero si es el final del archivo, se sale del ciclo: -> writeq(Term), write('.'), nl, fail

; true). Ejemplo:

9. Predicado que lee un archivo, y mira cuales de los términos leídos satisface la regla likes de la base de conocimiento. likes(mary,carol). likes(mary,john). go:-see('names.pl'), repeat, read(X), ( X=end_of_file, write('Finished reading file'), nl, ! ; likes(mary,X), write('Mary likes '), write(X), nl, fail ), seen. Lo primero que se hace es cambiar el origen de la entrada de la consola al archivo, por medio del predicado see. Luego iniciamos un ciclo de lectura de los términos del archivo. see('names.pl'), repeat, read(X), al leer cada X, si llegamos al final del archivo, rompemos el ciclo, y si no, se evalúa la regla de la base con el término que se leyó del archivo, y se lee otro termino del archivo. Al final, se cierra la entrada por medio del predicado seen. ( X=end_of_file, write('Finished reading file'), nl, ! ; likes(mary,X), write('Mary likes '), write(X), nl,

fail ), seen.

Ejemplo:

En el archivo de entrada, cada término debe estar en una línea, finalizando con punto para que puedan ser leídos como términos por Prolog:

10. Predicado que escribe una cadena en un archivo. escriba(Cadena, Archivo):-write(Cadena)~>Archivo,close(Archivo). Ejemplo:

11. Predicado que lee datos de un archivo, y los copia en otro con un comentario al final indicando el numero de línea. numero_lineas(NumLinea):-at_end_of_file. % SE ESTÁ AL FINAL DE LA LÍNEA,ESCRIBE EL NÚMNERO DE LA LÍNEA numero_lineas(NumLinea):at_end_of_line, write('% Línea Número'), write(NumLinea), skip_line, nl, Nuevo_numero_linea is NumLinea+1, numero_lineas(Nuevo_numero_linea).

numero_lineas(NumLinea):get0(X), put(X), numero_lineas(NumLinea). copiar(Archivo1,Archivo2):see(Archivo1), tell(Archivo2),numero_lineas(1),seen,told. Esto se realiza por medio de una función recursiva, que se define de la siguiente manera: Si es el fin del archivo no hace nada. numero_lineas(NumLinea):-at_end_of_file. Si esta al final de la línea, escribe un comentario con el número de la línea, y salta a la siguiente línea de entrada numero_lineas(NumLinea):at_end_of_line, write('% Línea Número'), write(NumLinea), skip_line, nl, ahora, incrementa el contador del numero de línea, y llama de nuevo la función. Nuevo_numero_linea is NumLinea+1, numero_lineas(Nuevo_numero_linea). En otro caso, si no esta en el final del archivo, o en el final de una línea, lee un carácter del archivo de entrada y lo escribe en el de salida, y vuelve a llamar la función. numero_lineas(NumLinea):get0(X), put(X), numero_lineas(NumLinea). La función principal, recibe como parámetros los dos archivos, el de entrada y el de salida respectivamente, los configura como entrada y salida con tell y see, y llama la función que realiza la copia de los archivos. copiar(Archivo1,Archivo2):see(Archivo1), tell(Archivo2),numero_lineas(1),seen,told. Ejemplo:

Archivo de origen:

Archivo de salida:

Sign up to vote on this title
UsefulNot useful