Indice Lección 1 Lección 2 Lección 3 Lección 4 Lección 5

Guía de Ejercicios en Prolog

Lección 3 - Manipulación de la Base de Datos y Archivos

Carga la siguiente base de datos de países con sus respectivas capitales.

 

:- dynamic capital_of/2.

capital_of(suiza, berna).
capital_of(chile, santiago).
capital_of(eeuu, washington).
capital_of(estados_unidos, washington).
capital_of(italia, roma).
capital_of(francia, paris).
capital_of(austria, viena).
capital_of(alemania, berlin).
capital_of(españa, madrid).
capital_of(peru, lima).
capital_of(mexico, cuidad_de_mexico).
      

1.- read/1 permite leer expresiones Prolog desde el teclado. Intenta lo siguiente: verifica las respuestas que te entrega Prolog para las siguientes entradas.

hola.
'hola que tal'.
hola que tal.
hola(hermano).
Hola.
f(X) :- g(Y). 
      

¿Puedes explicar a qué se deben las respuestas de Prolog?

2.- Veamos cómo un programa Prolog es capaz de aquirir nuevas cláusulas en tiempo de ejecución.

?- capital_of(hawaii, X).
      

Como puedes ver, no se pudo unificar la variable X. Ahora, prueba con

?- listing.
      

¿Qué ocurre? listing muestra todas las cláusulas que conforman el programa en memoria. Ahora prueba

?- listing(capital_of).
      

Ésto sólo muestra aquellas cláusulas asociadas al predicado indicado como parámetro.

Se pueden incluir más cláusulas a la base de datos mediante el predicado assert/1:

?- assert(capital_of(hawaii, honolulu)).
      

Sin embargo, ésto sólo funciona para predicados que han sido marcados como dínamicos mediante el predicado dynamic/1.

Ojo, pues en Prolog dos predicados con el mismo functor (i.e. el nombre del predicado) son distintos si tienen aridad (i.e. nombre de argumentos) distintos. Es algo similar a lo que le llaman la firma de una función en Java por ejemplo. En consecuencia, a(X) y a(X,Y) son distintos predicados (a/1 y a/2 respectivamente, según la notación Prolog).

El predicado capital_of/2 ha sido declarado previamente como dinámico. Puedes verificarlo ejecutando listing. Un predicado que no es dinámico es estático. Los predicados estáticos no pueden ser alterados en tiempo de ejecución.

Prolog internamente compila las cláusulas estáticas para mejorar la eficiencia. Es por esta razón que debe hacerse la diferencia.

Ahora, si preguntas por

?- capital_of(hawaii, X).
      

debiera resultar la unificación de la variable en forma exitosa.

3.- Obsevemos que assert agrega la cláusula al final de la lista de predicados del mismo nombre. Existe tambien asserta/1 y assertz/1, que agregan la cláusula al comienzo y al final respectivamente.

Agrega dos cláusulas nuevas a la base de datos, y verifica luego que éstas fueron efectivamente incluídas. ¿Qué ocurre si agregas una clásula con un predicado nuevo, por ejemplo, assert(hola)? Verifica consultando por listing(hola).

retract/1 permite eliminar una cláusula de la base de datos.

?- retract(capital_of(hawaii, honolulu)).
      

Existen más predicados que permiten inspeccionar el estado de la base de datos, inclusive para construir y ejecutar dinámicamente predicados en tiempo de ejecución. Para mayor información, puedes revisar la base de datos.

4.- Ahora veamos algunos predicados de manejo sencillo de archivos. Éstos son: see/1, seen/1, tell/1 y told/1.

see('mi_archivo') abre el archivo 'mi_archivo' y lo establece como fuente de los comandos de lectura, tales como read/1. Para cerrarlo, aplicar seen/0.

Por otro lado, tell('mi_archivo') abre al archivo 'mi_archivo' y redirige la escritura hacia él, análogo a see. Para cerrar al archivo, aplicar told/0.

?- tell('mi_archivo'), write('andrea.'), nl, write('javier.'), nl, told.
      

Tras ejecutar la consulta anterior, revisa si existe el archivo 'mi_archivo' y si su contenido es el esperado.

Ahora, vuelve a leer los datos escritos mediante:

?- see('mi_archivo'), read(X), read(Y).
      

¿Qué habría ocurrido si se hubiese escrito write('andrea') en vez de write('andrea.')?

Intenta escribir el contenido de la base de datos actualmente residente en memoria dentro de algún archivo. Verifica que ésto haya funcionado bien abriendo el archivo y revisando su contenido.

5.- Ahora carga el programa 'learner.pl' y ejecuta start. Juega un rato con él. Para finalizarlo, ingresa stop.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% File learner.pl                                                              %
% Un pequeño programa que modifica su propia base de conocimientos.            %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

start :- consult('bdc.pl'),
         nl,
         write('Escribe los nombres completamente en minúsculas,'), nl,
         write('seguidos de un punto.'), nl,
         nl,
         process_a_query.

process_a_query :- write('País? '),
                   read(Pais),
                   answer(Pais).

% Si el usuario ingresa "stop.", entonces grabar la nueva
% base de conocimientos y salir.
answer(stop) :- write('Grabando la base de conocimientos...'), nl,
                tell('bdc.pl'),
                listing(capital_of),
                told,
                write('Listo.'), nl.

% Si el país ya está en la base de conocimientos, entonces retornar
% el nombre de su capital.
answer(Pais) :- capital_of(Pais, Ciudad),
                write('La capital de '),
                write(Pais),
                write(' es '),
                write(Ciudad), nl,
                nl,
                process_a_query.

% Si el país no está en la base de conocimientos, entonces pedir
% el nombre de la capital e ingresar este fact a la base.
answer(Pais) :- \+ capital_of(Pais, Ciudad),
                write('No conozco la capital de ese país.'), nl,
                write('Por favor, dime cual es.'), nl,
                write('Capital? '),
                read(Ciudad),
                write('Gracias.'), nl, nl,
                assert(capital_of(Pais, Ciudad)),
                process_a_query.
      

Revisa el programa y explica cómo funciona. Modifícalo, de manera que al ingresar delete, el programa borre un país de la base de datos, tal como indica el siguiente diálogo:

...
País? chile.
La capital de chile es santiago

País? delete.
Qué país deseas borrar? chile.
Se borró chile.

País? chile.
No conozco la capital de ese país.
...