Vous êtes sur la page 1sur 15

INTELIGENCIA EN REDES DE COMUNICACIONES

INMACULADA LUENGO LÓPEZ


Mª ESTHER MARTÍN REBOLLO
IRC Práctica final

ÍNDICE

Introducción_______________________________________________3

Objetivo de la práctica _____________________________________3

Desarrollo de la práctica____________________________________4

Resultados obtenidos ______________________________________7

Aprendizaje _______________________________________________9

Código del programa______________________________________11

Bibliografía_______________________________________________15

Página 2 de 15
IRC Práctica final

Introducción

En esta práctica hemos decidido implementar un programa en PROLOG


para adivinar animales a partir de preguntas que se le van haciendo al usuario.

La decisión de utilizar PROLOG para el desarrollo de esta práctica se


debe a que es un lenguaje sencillo que proporciona una sintaxis para la
construcción de sistemas expertos (en nuestro caso un sistema experto que
identifique a los animales a partir de sus características).

PROLOG es un lenguaje lógico declarativo que se basa en cláusulas de


Horn. Sus principales características son que se trata de una programación
dinámica, y tanto las reglas como los objetivos, son también datos; y la asunción
de un mundo cerrado, todo lo que no figura explícitamente como un hecho y
tampoco se puede deducir es falso. Otra característica es que el orden de las
cláusulas cambia el resultado final.

En esta práctica vamos a analizar el problema de un árbol de decisión con


aprendizaje.

Objetivo de la práctica

El fin de esta práctica ha sido desarrollar un programa en PROLOG que


adivine el animal que ha pensado el usuario mediante el empleo de una serie de
preguntas sobre las características del mismo a las que el jugador debe responder
afirmativa o negativamente.

Para ello, hemos definido un conjunto de reglas que debe verificar cada
uno de los animales que el programa conoce y, a partir de estas reglas, se le
formularán al usuario preguntas sobre las características que tiene el animal que
ha pensado.

También se ha contemplado la posibilidad de que el programa aprenda


nuevos animales, que el usuario podría introducir cuando el programa no
adivinase el animal que éste había pensado. Para ello se debe introducir, además
de dicho animal, una pregunta que lo diferencie del animal que ha respondido
erróneamente el programa.

Página 3 de 15
IRC Práctica final

Desarrollo de la práctica

Para la implementación del programa deseado, en primer lugar nos


tendremos que plantear la estructura que va a tener nuestra lista de animales. Esta
estructura será un árbol, en el que en las hojas se encontraran los distintos
animales, y llegaremos a ellos por medios de las distintas características
diferenciadoras que tiene cada uno. Siendo una de las principales características
su clasificación en: reptiles, anfibios, mamíferos, aves y peces.

Para realizar esta clasificación se tienen que tener en cuenta que las
preguntas a realizar nos tienen que caracterizar una de las hojas frente a otra, y
así poder llegar a la hoja deseada sin ningún tipo de ambigüedad.

La lista de los animales que se han tenido en cuenta para el desarrollo de


esta práctica es: rana, salamandra, serpiente, tortuga, cocodrilo, jirafa, conejo,
hombre, oso, tigre, león, águila, pato, gallina, avestruz, pingüino, carpa y pez
espada.

En primer lugar, y para mostrar con mayor claridad el fundamento del


programa, mostramos el árbol que vamos a desarrollar:

Página 4 de 15
IRC Práctica final

Página 5 de 15
IRC Práctica final

Comenzamos analizando el código desarrollado. En primer lugar, vamos a


utilizar una función que se llamará sera(Animal), que determinará
principalmente el orden en el que se deben ir comprobando los distintos animales
(¿será una rana?...), de izquierda a derecha en la figura del árbol.

Para cada uno de los animales se realizarán las preguntas sobre las
características que debe cumplir, comenzando por el animal situado más a la
izquierda del árbol y por la pregunta del nodo raíz. Se seguirán verificando las
características para un mismo animal siempre que se responda afirmativamente a
las preguntas y se pasará a comprobar las características del animal siguiente (el
situado inmediatamente a la derecha del animal actual) cada vez que se responda
negativamente a una de las preguntas. De esta forma, cuando lleguemos a una
hoja del árbol el programa dará como solución un animal que cumpla todas las
preguntas anteriormente realizadas.

El animal que no cumpla ninguna de las características preguntadas será el


que está en la hoja situada más a la derecha del árbol, que en nuestro caso es el
pez espada, y no necesitará verificar ninguna condición, ya que simplemente es
el que no cumple ninguna de las anteriores.

Mediante estas reglas podremos realizar una primera clasificación de los


animales en anfibios, reptiles, mamíferos, aves y peces. Las características que
nos permiten clasificarlos dentro de estos grupos se harán aparte para que el
código del programa sea más claro y más general.

Ahora pasamos a comentar la función verificar(caracteristica) que ya


hemos nombrado anteriormente. En esta función decimos que si se cumple la
característica el resultado será true, y si no se cumple será fail, y pasamos a
llamar a la función preguntar(caracteristica).

En la función preguntar será donde realizaremos la pregunta sobre la


característica determinada a verificar y en la que almacenaremos la respuesta.
Según ésta sea afirmativa o negativa, avanzaremos hacia una u otra rama del
árbol. Esto lo implementaremos con la ayuda de la función assert, que nos
ayudara a ir almacenando las respuestas a las distintas características, para evitar
repetir al usuario preguntas ya realizadas anteriormente, como las relacionadas
con el tipo de animal (anfibio, reptil…), y así poder seguir avanzando en el árbol.

Debido a la utilización de la función assert en este punto, necesitaremos


que las funciones cumple y no_cumple, con las que la utilizamos sean
dinámicas. Además tendremos que borrar los valores almacenamos, con la ayuda

Página 6 de 15
IRC Práctica final

de la función retract, una vez que hayamos mostrado al usuario el animal


adivinado, para lo que llamaremos a la función borrar en la parte principal del
programa. Si olvidásemos realizar este borrado, en la siguiente ejecución
comenzaríamos directamente dando como animal adivinado el obtenido en el
caso anterior, sin haber realizado ninguna pregunta.

Además una vez adivinado el animal, se nos ofrecerá la oportunidad de


seguir jugando, en lugar de tener que volver a ejecutar el programa.

Resultados obtenidos

Ahora vamos a probar el funcionamiento de nuestro programa. Vamos a


pensar un animal de los que conoce, por ejemplo la jirafa. El programa nos irá
haciendo preguntas recorriendo el árbol de la siguiente forma:

Página 7 de 15
IRC Práctica final

Página 8 de 15
IRC Práctica final

La captura del programa obtenida es la siguiente:

Podemos ver que el programa va haciendo las preguntas en el orden


indicado en el árbol hasta adivinar que el animal que se había pensado era la
jirafa.

Aprendizaje

Nos hemos planteado también la posibilidad de que el programa pueda


aprender nuevos animales. Para implementarlo, hemos empleado la función
asserta que nos permite introducir nuevas reglas al principio de la base de datos.

El programa sólo podrá aprender cuando no acierte el animal que había


pensado el usuario. Por lo tanto, lo primero que tenemos que hacer una vez
identificado el animal por el programa es preguntarle si hemos acertado dicho
animal. De no ser así, tendremos que preguntarle al usuario cuál era el animal
que había pensado y que nos indique una característica de éste que permita al
programa diferenciarlo del animal que el había ofrecido como solución. Una vez
conocidos el animal y una característica que lo distinga, lo añadimos mediante la
función asserta. Esta nueva regla se tratará de igual forma que las definidas de
forma explícita en el programa.

Página 9 de 15
IRC Práctica final

Veamos un ejemplo de aprendizaje de nuestro programa. Para ello, hemos


pensado en el mono, que no está incluido en la base de datos del programa. La
captura del programa es la siguiente:

Ahora podemos comprobar que ha insertado mono en la base de datos:

Página 10 de 15
IRC Práctica final

Y además, que puede identificar este animal del ofrecido anteriormente


como solución:

En mayor inconveniente que tiene el método que hemos seguido es que ya


no nos permite realizar las preguntas en el orden inicial, pero no es demasiado
importante porque sigue adivinando correctamente los animales inicialmente
introducidos.

Código del programa


/* ADIVINO EL ANIMAL EN EL QUE ESTAS PENSANDO

Para empezar el juego, teclea: " ?- start." */

/*Comienza el juego*/

/*Para implementar el juego partiremos de un árbol en el que tendremos


todos los animales que podemos adivinar y las relaciones entre ellos*/

start :-
nl,
write('PARA ADIVINAR EL ANIMAL EN EL QUE ESTAS PENSANDO, '),
nl,
write('RESPONDE A LAS SIGUIENTES PREGUNTAS'),
nl,
nl,
sera(Animal),

/*En primer lugar llamamos a la función hipótesis.

Página 11 de 15
IRC Práctica final

Con esta función empezaremos en el nodo raíz e iremos avanzando


en el árbol */
/*Cuando lleguemos a una hoja del árbol, habremos encontrado la
respuesta*/
nl,
nl,
write('****************************************'),
nl,
write('Creo que el animal es '),
write(Animal),
nl,
write('****************************************'),
nl,
nl,

/*Aprendizaje de nuestro programa*/


/*Comprobamos si hemos acertado el animal*/

write('¿He acertado? (s/n) '),


read(Respuesta),
nl,

/*En el caso de no haber acertado, intentamos introducir una


regla para su aprendizaje*/

( (Respuesta == s)
->

borrar,
seguir_jugando ;

write('¿Qué animal es? '),


read(Respuesta1),
nl,

write('Dime una pregunta para '),


write(Respuesta1),
write(' que lo diferencie de '),
write(Animal),
write(': '),
read(Respuesta2),
nl,
nl,

asserta( (sera(Respuesta1) :- Animal, verificar(Respuesta2)) ) ,

borrar,
seguir_jugando).

/* Hipótesis de animales que se van a comprobar */

sera(rana) :- rana, !.
sera(salamandra) :- salamandra, !.
sera(serpiente) :- serpiente, !.
sera(tortuga) :- tortuga, !.
sera(cocodrilo) :- cocodrilo, !.
sera(jirafa) :- jirafa, !.
sera(conejo) :- conejo, !.
sera(hombre) :- hombre, !.

Página 12 de 15
IRC Práctica final

sera(oso) :- oso, !.
sera(tigre) :- tigre, !.
sera(leon) :- leon, !.
sera(aguila) :- aguila, !.
sera(pato) :- pato, !.
sera(gallina) :- gallina, !.
sera(avestruz) :- avestruz, !.
sera(pinguino) :- pinguino, !.
sera(carpa) :- carpa, !.
sera(pez_espada):- pez_espada.

/* Reglas con las que identificaremos los distintos animales */

/*Anfibios*/

rana :- sangre_fria,
anfibio,
verificar(salta).

salamandra :- sangre_fria,
anfibio.

/*Reptiles*/

serpiente :- sangre_fria,
verificar(se_arrastra).

tortuga :- sangre_fria,
verificar(tiene_caparazon).

cocodrilo :- sangre_fria.

/*Mamíferos*/

jirafa :- mamifero,
herbivoro,
verificar(tiene_cuello_largo).

conejo :- mamifero,
herbivoro.

hombre :- mamifero,
omnivoro,
verificar(razona).

oso :- mamifero,
omnivoro.

tigre :- mamifero,
verificar(tiene_rayas).

leon :- mamifero.

/*Aves*/

Página 13 de 15
IRC Práctica final

aguila :- ave,
voladora,
verificar(es_ave_rapaz).

pato :- ave,
voladora.

gallina :- ave,
verificar(es_domestico).

avestruz :- ave,
verificar(corre_veloz).

pinguino :- ave.

/*Peces*/

carpa :- verificar(vive_rio).
pez_espada.

/* Reglas con las que clasificaremos los animales en: anfibios,


reptiles, mamíferos, aves y peces */
/* Para ello utilizaremos la función verificar */

sangre_fria :- verificar(tiene_sangre_fria).
anfibio :- verificar(vive_tierra_y_agua).
mamifero :- verificar(tiene_pelo).
herbivoro :- verificar(es_herbivoro).
omnivoro :- verificar(es_omnivoro).
ave :- verificar(tiene_alas).
voladora :- verificar(vuela).

/* Función verificar, desde aquí llamaremos a la función que


preguntara por cada característica */

verificar(S) :-
(cumple(S)
->
true ;
(no_cumple(S)
->
fail ;
preguntar(S))).

/* Para avanzar por el árbol, se irán realizando preguntas con las


distintas características. Esto lo haremos con la función preguntar*/

preguntar(Pregunta) :-

write('¿Tiene el animal la siguiente característica: '),


write(Pregunta),
write('? (s/n) '),

Página 14 de 15
IRC Práctica final

read(Respuesta),
nl,

/*Avanzamos en función de la respuesta a la característica, hacia


una rama u otra del árbol */
/*Con assert, guardamos el camino seguido */

( (Respuesta == s)
->
assert(cumple(Pregunta)) ;
assert(no_cumple(Pregunta)), fail).

seguir_jugando :-

/*Ofrecemos la oportunidad de volver a jugar otra vez*/

write('¿Quieres seguir jugando? '),


read(Respuesta3),
( (Respuesta3 == s)
->
start ;
nl,
nl,
write('ESPERO QUE HAYAS DISFRUTADO JUGANDO CONMIGO'),
nl,
nl,
write('ADIOS'),
nl).

/*Hace dinámicas las funciones que se van a añadir con assert*/


:- dynamic cumple/1,no_cumple/1,sera/1,verificar/1.

/* Borramos todos los valores almacenados con assert que indican el


camino seguido en el árbol */

borrar :- retract(cumple(_)),fail.
borrar :- retract(no_cumple(_)),fail.
borrar.

Bibliografía
- Prolog
Francis Giannesini, Henry Kanoui y otros.
Ed. Addison-Wesley Iberoamericana, 1989

- Manual online de swi-prolog


Jan Wielemaker

- Principles of programming languages XXI


Wael Aboelsaadat

Página 15 de 15

Vous aimerez peut-être aussi