Advertisement
tomasfdel

IIA TP Prolog

Apr 10th, 2019
389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 10.89 KB | None | 0 0
  1. /*
  2. ---------------------------------------------------------
  3. |   TRABAJO PRACTICO N° 2 - SISTEMA EXPERTO EN PROLOG   |
  4. |       INTRODUCCION A LA INTELIGENCIA ARTIFICIAL       |
  5. |                      LCC 2019                         |
  6. |                                                       |
  7. |         Ignacio Sebastián Moliné ~ M-6466/1           |
  8. |         Tomás Fernández de Luco  ~ F-3443/6           |
  9. ---------------------------------------------------------
  10.  
  11. INTRODUCCIÓN:
  12. Este código en Prolog es un sistema experto cuya finalidad es la de reconocer distintos
  13. ejemplares y familias de corales mediante preguntas al usuario sobre cualidades conocidas.
  14.  
  15. Se utilizarán las siguientes reglas de clasificación:
  16.  -- Lophilia Pertusa es un espécimen de coral, de esqueleto duro,
  17.     que habita en zonas profundas, no es utilizado en joyería, tiene forma de árbol y su color es blanco.
  18.  -- Corallium Rubrum (el coral rojo) es un espécimen de coral, de esqueleto duro,
  19.     que habita en zonas profundas, es utilizado en joyería, tiene forma de árbol y su color es rojo.
  20.  -- Favia (el coral cerebro) es una familia de corales, de esqueleto duro,
  21.     que habita en zonas poco profundas, no es utilizado en joyería, tiene forma de esfera y su color es verde.
  22.  -- Fungia Fungites (el coral plato) es una familia de corales, de esqueleto duro,
  23.     que habita en zonas poco profundas, no es utilizado en joyería, tiene forma de seta y su color es violeta.
  24.  -- Antipathes Dichotoma (el coral negro) es una familia de corales, de esqueleto blando,
  25.     que habita en zonas profundas, utilizado en joyería, realiza fotosombra, tiene forma de arbusto y su color es verde.
  26.  -- Dendroneptya (el coral árbol) es una familia de corales, de esqueleto blando,
  27.     que habita en zonas poco profundas, no es utilizado en joyería, tiene forma de árbol y su color es rojo.
  28.  -- Sarcopython (el coral cuero) es una familia de corales, de esqueleto blando,
  29.     que habita en zonas poco profundas, no es utilizado en joyería, tiene forma de seta y su color es verde.
  30.  -- Gorgonia Ventalina es un espécimen de la familia Gorgoniidae y su color es violeta.
  31.  -- Gorgonia Mariae es un espécimen de la familia Gorgoniidae y su color es blanco.
  32.  
  33. Para las distintas categorías y propiedades:
  34.  -- Gorgoniidae: Es un coral blando, que habita en zonas poco profundas,
  35.     realiza fotosíntesis y tiene forma de abanico.
  36.  -- Duro: Propiedad del coral. Esqueleto de formación pétrea.
  37.  -- Blando: Propiedad del coral. Equeleto de formación proteínica.
  38.  -- Joyería: Utilizado como matería prima para joyería.
  39.  -- No joyería: No utilizado como materia prima para joyería.
  40.  -- Profundo: Que habita en zonas de profundidades mayores a 30 metros.
  41.  -- No profundo: Que habita en zonas de profundidaes menores a 30 metros.
  42.  -- Solar: Que recibe luz solar, y realiza fotosíntesis.
  43.  -- No solar: Que no recibe luz solar, y realiza fotosombra.
  44.  -- Color: Propiedad del coral. Color mayoritario del coral.
  45.  -- Forma: Propiedad del coral. Forma general del coral.
  46.  
  47. El comando para ejecutar el programa es:
  48. ~ coral.
  49.  
  50. Las consultas se contestan con 's.' o 'n.', o con 'N.' siendo N el n° de la opción correspondiente.
  51. En caso de ingresar una opción no valida, el programa alertará al usuario y volvera a consultar por una propiedad.
  52.  
  53. "texto para aprender"
  54.  
  55. */
  56.  
  57.  
  58. % --- Predicados con los que se clasifican a los corales. ---
  59. duro :- satisface('es duro').
  60. blando :- not(satisface('es duro')).
  61.  
  62. joyeria :- satisface('es usado en joyería').
  63. no_joyeria :- not(satisface('es usado en joyería')).
  64.  
  65. profundo :- satisface('habita a más de 30 metros de profundidad').
  66. no_profundo :- not(satisface('habita a más de 30 metros de profundidad')).
  67.  
  68. solar :- satisface('recibe luz solar para fotosíntesis').
  69. no_solar :- not(satisface('recibe luz solar para fotosíntesis')).
  70.  
  71. % Preficados con lista de opciones posibles.
  72. color(Color) :- satisface_mult('¿De qué color es el coral buscado?', Color, [rojo, violeta, blanco, verde]).
  73. forma(Forma) :- satisface_mult('¿Qué forma tiene el coral buscado?', Forma, [árbol, seta, esfera, arbusto, abanico]).
  74.  
  75. % Predicado para la familia de las Gorgonias.
  76. gorgoniidae :- blando, no_profundo, solar, forma(abanico).
  77. % ---
  78.  
  79.  
  80.  
  81. % --- Verificación para predicados del tipo Si / No. ---
  82. % si/1 y no/1 almacenarán la información de las propiedades que pueden o no cumplir los corales.
  83. :- dynamic si/1,no/1.
  84.  
  85.  
  86. % Revisa si ya se sabe si un coral cumple o no con una propiedad.
  87. % En caso de no tener esa información en la base de conocimiento, la pregunta para agregarla.
  88. satisface(Atributo) :- si(Atributo) -> true;
  89.                                        (no(Atributo) -> fail;
  90.                                                         pregunta(Atributo)).
  91.  
  92.  
  93. % Pregunta si un coral cumple o no con un atributo dado y agrega la respuesta a la base de conocimiento.
  94. % Si la opción no es válida, alertará al usuario de ello y preguntará otra vez.
  95. pregunta(Atributo) :- write('¿El coral buscado '), write(Atributo), write('? (s/n): '), read(Resp), nl,
  96.                       (Resp == s -> assertz(si(Atributo));
  97.                                     (Resp == n -> assertz(no(Atributo)), fail;
  98.                                                   write('Respuesta incorrecta, intente otra vez.'), nl, pregunta(Atributo))).
  99. % ---
  100.  
  101.  
  102.  
  103. % --- Verificación para predicados con una lista de opciones posibles. ---
  104. % si/2 y no/2 almacenarán la información de qué opción cumple un predicado de una lista de atributos posibles.
  105. :- dynamic si/2, no/2.
  106.  
  107.  
  108. % Revisa si ya se sabe si un coral cumple con una opción específica de un atributo de opción múltiple dado.
  109. % En caso de no tener esa información en la base de conocimiento, la pregunta para agregarla.
  110. satisface_mult(Atributo, Buscado, Opciones) :- si(Atributo, Buscado) -> true;
  111.                                                                         (no(Atributo, Buscado) -> fail;
  112.                                                                                                   pregunta_mult(Atributo, Buscado, Opciones)).
  113.  
  114.  
  115. % Imprime la pregunta de opción múltiple, junto con el listado de posibilidades.
  116. % Agrega la información relevante a la base de conocimiento y revisa si la elección
  117. % coincide con el valor buscado inicialmente.
  118. pregunta_mult(Atributo, Buscado, Opciones) :- write(Atributo), nl,
  119.                                               opciones_mult(Opciones, 1),
  120.                                               respuesta_mult(Atributo, Opciones, Respuesta),
  121.                                               aprender_mult(Atributo, Opciones, Respuesta),
  122.                                               Buscado == Respuesta.
  123.                                              
  124.                                              
  125. % Convierte un átomo en una versión imprimible, con la primera letra en may                                            
  126. convertir(Atomo, Print) :- atom_chars(Atomo, Lista),
  127.                            [NotCapitalized | Tail] = Lista,
  128.                            upcase_atom(NotCapitalized, Capitalized),
  129.                            atomic_list_concat([Capitalized | Tail], Print).                                            
  130.  
  131.  
  132. % Toma un listado de opciones y las va imprimieno en distintos renglones, numeradas a partir de 1.
  133. opciones_mult([], _).
  134. opciones_mult([H | T], Numero) :- write(Numero), write('- '), convertir(H, HPrint), write(HPrint), write('.'), nl,
  135.                                   NuevoValor is Numero + 1, opciones_mult(T, NuevoValor).
  136.  
  137.  
  138. % Pide un número que corresponda a alguno de los de las opciones previamente impresas.
  139. % Si la opción no es válida, alertará al usuario de ello y preguntará otra vez.
  140. respuesta_mult(Atributo, Opciones, Respuesta) :- write('Su respuesta: '), read(Elegida),
  141.                                                  (verificar_mult(Opciones, Elegida, Resultado, 1) -> Respuesta = Resultado;
  142.                                                                                                      write('Respuesta inválida. Intente de nuevo.'), nl,
  143.                                                                                                      respuesta_mult(Atributo, Opciones, Respuesta)).
  144.  
  145.  
  146. % Dado un listado de opciones y un valor, revisa que dicho valor corresponda a un índice válido de la lista.
  147. % Si es así, instancia Resultado al valor de dicho índice. Si no, falla.
  148. verificar_mult([], _, _, _) :- fail.
  149. verificar_mult([H | T], Elegida, Resultado, Numero) :- Numero == Elegida -> Resultado = H;
  150.                                                                             NuevoValor is Numero + 1, verificar_mult(T, Elegida, Resultado, NuevoValor).
  151.  
  152.  
  153. % Agrega a la base de conocimiento que la opción previamente elegida para un atributo vale.
  154. % Además, dice que todas las demás opciones para dicho atributo no valen.
  155. aprender_mult(_, [], _).
  156. aprender_mult(Atributo, [H | T], Respuesta) :- (H == Respuesta -> assertz(si(Atributo, H));
  157.                                                                   assertz(no(Atributo, H))),
  158.                                                aprender_mult(Atributo, T, Respuesta).
  159. % ---
  160.  
  161.  
  162.  
  163. % Elimina todos los datos aprendidos durante la ejecución para poder volver a ejecutar el sistema.
  164. borraResp :- retractall(si(_)), retractall(no(_)), retractall(si(_, _)), retractall(no(_, _)).
  165.  
  166. % Inicia la ejecución del sistema experto.
  167. coral :- adivina(Coral), !, write('El coral buscado es: '), write(Coral), write('.'), nl, borraResp.
  168.  
  169.  
  170.  
  171. % --- Predicados para cada una de las especies de corales. ---
  172. lophilia_pertusa :- duro, profundo, no_joyeria, forma(árbol), color(blanco).
  173. corallium_rubrum :- duro, profundo, joyeria, forma(árbol), color(rojo).
  174. favia :- duro, no_profundo, no_joyeria, forma(esfera), color(blanco).
  175. fungia_fungites :- duro, no_profundo, no_joyeria, forma(seta), color(violeta).
  176. antipathes_dichotoma :- blando, profundo, joyeria, no_solar, forma(arbusto), color(verde).
  177. dendronepthya :- blando, no_profundo, no_joyeria, forma(árbol), color(rojo).
  178. sarcopython :- blando, no_profundo, no_joyeria, forma(seta), color(verde).
  179.  
  180. gorgonia_ventalina :- gorgoniidae, color(violeta).
  181. gorgonia_mariae :- gorgoniidae, color(blanco).
  182. % ---
  183.  
  184.  
  185.  
  186. % Predicado que retorna el nombre de un coral que satisfaga las propiedades preguntadas.
  187. % En caso de no existir, advierte que es desconocido por el sistema.
  188. adivina('Lophilia Pertusa') :- lophilia_pertusa.
  189. adivina('Corallium Rubrum, el coral rojo') :- corallium_rubrum.
  190. adivina('Favia, el coral cerebro') :- favia.
  191. adivina('Fungia fungites, el coral plato') :- fungia_fungites.
  192. adivina('Antipathes dichotoma, el coral negro') :- antipathes_dichotoma.
  193. adivina('Dendronepthya, el coral árbol') :- dendronepthya.
  194. adivina('Sarcopython, el coral cuero') :- sarcopython.
  195. adivina('Gorgonia Ventalina') :- gorgonia_ventalina.
  196. adivina('Gorgonia Mariae') :- gorgonia_mariae.
  197. adivina('Desconocido').
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement