<div class="notebook"> <div class="nb-cell markdown" name="md1"> # Tutorial Prolog El siguiente notebook explicara lo que necesitas saber sobre el lenguaje de programación Prolog y algunos ejemplos practicos. ### Desarollado: - Luis Fernado Castro Peralta - Wilson Andres Piravaguen ### Contenido 1. Introducción a Prolog 2. Elementos del lenguaje - Átomos - Números - Variables - Listas - Operadores 4. Hechos 5. Reglas 6. Aplicaciones ### 1. Introducción a Prolog Fue ideado a principios de los años 70 en la Universidad de Aix-Marseille I(Marsella, Francia) por Alain Colmerauer y Phillip Rousell, este último lo nombró Prolog por PROgrammation en LOGique. #### Principales Características: **Lenguaje declarativo:** Se desarrolla especificando declaraciones de condiciones, proposiciones, afirmaciones o restricciones que describen un problema. No se especifican las instrucciones necesarias para solucionar el problema(Algoritmo Paso a Paso), esto último se realiza mediante mecanismo internos de inferencia a partir de las declaraciones hechas. **Lógica de primer orden:** Es un sistema formal diseñado para estudiar la inferencia en los lenguajes de primer orden, estos lenguajes se caracterizan por el uso de predicados y de cuantificadores. **Predicados:** Son sentencias que pueden ser verdaderas o falsas según los valores de sus variables. **Cuantificadores:** Expresiones que señalan los elementos que conforman un conjunto dado que cumple con un determinada propiedad. ### 2. Elementos del lenguaje Prolog al ser un lenguaje declarativo sus programas son compuestos por **cláusulas** las cuales pueden ser **hechos** o **reglas**. Prolog reconoce el tipo de un objeto en el programa por medio de su forma sintáctica, estos tipos son: - Átomos - Números - Variables - Listas #### Átomos: Prolog define los átomos como una unidad de datos mínima a la cual refieren los hechos, los átomos pueden construirse de 3 formas: - Cadenas de letras, dígitos y el carácter '_', empezando con una letra minúscula </div> <div class="nb-cell program" name="p1"> % conejo Es un atomo animal(conejo). % Conejo No es un atomo animal(Conejo). </div> <div class="nb-cell markdown" name="md2"> - Cadenas de caracteres especiales: </div> <div class="nb-cell program" name="p2"> % Es un atomo cualquier combinación de estos caracteres especial(#-+$&/=?¡¿<>.:^). </div> <div class="nb-cell markdown" name="md3"> - Cadenas de caracteres encerradas en “”. </div> <div class="nb-cell program" name="p3"> % Es un atomo animal("conejo"). </div> <div class="nb-cell markdown" name="md7"> #### Números: En Prolog se incluyen representaciones para los números enteros y números reales. Ejemplos de números aceptados: </div> <div class="nb-cell program" name="p7"> numero(345). % Entero negativo(-15). % Negativo real(1.4142365). % Real </div> <div class="nb-cell markdown" name="md4"> #### Variables: Las variables en Prolog pueden tomar el valor de uno o más átomos en el proceso de una consulta. Son cadenas de letras, dígitos y el signo '_'. Estas empiezan con una letra mayúscula o el símbolo '_'. </div> <div class="nb-cell program" name="p4"> padre(jose, manuel). % jose es padre de manuel hijo(X) :- padre(Y,X). % X es un hijo si tiene padre </div> <div class="nb-cell markdown" name="md5"> Prolog utiliza el concepto de variable anónima para aquellas variables las cuales no es necesario asignarles un valor para concretar un hecho, se representan con “_”: </div> <div class="nb-cell program" name="p5"> padre(jose, manuel). % jose es padre de manuel hijo(X) :- padre(_,X). % X es un hijo si tiene padre, no importa quién sea el padre </div> <div class="nb-cell query" name="q1"> hijo(manuel). </div> <div class="nb-cell markdown" name="md6"> Las variables son de entorno local (hechos o reglas), y pueden ser asignadas con el operador IS: </div> <div class="nb-cell program" name="p6"> doble(X, RESULTADO) :- RESULTADO is X*2. % Regla para calcular el doble de un numero </div> <div class="nb-cell query" name="q2"> doble(5, RESULTADO). </div> <div class="nb-cell markdown" name="md8"> #### Listas: Prolog provee de base la estructura de lista, esta se define como elementos entre [] separados con , </div> <div class="nb-cell program" name="p8"> eslista([ 1 , item , [lista, “lista”] , Variable ]) </div> <div class="nb-cell markdown" name="md9"> Aunque se representa como una lista, esta estructura solo puede ser accedida a su primer elemento (cabeza) y al resto de la lista como un solo elemento (cola). </div> <div class="nb-cell program" name="p9"> primer_elemento_par( [ H | _ ] ) :- X is (H mod 2 ) , X = 0. </div> <div class="nb-cell query" name="q3"> primer_elemento_par([1,5,6]). </div> <div class="nb-cell query" name="q4"> primer_elemento_par([2,3,4]). </div> <div class="nb-cell markdown" name="md23"> Calcular el maximo elementos de una lista. </div> <div class="nb-cell program" name="p14"> max(A,B,A) :- A >= B. max(A,B,B) :- A < B. maxl([H],H). % Maximo de una lista maxl([H|T],M):- maxl(T,M1), max(M1,H,M). </div> <div class="nb-cell query" name="q13"> maxl([1, 23, 10, 15, 7], H). </div> <div class="nb-cell markdown" name="md16"> Hallar la longitud de una lista. </div> <div class="nb-cell program" name="p15"> longitud([], 0). longitud([_|T], N) :- longitud(T, N1), N is N1 + 1. </div> <div class="nb-cell query" name="q14"> longitud([1, 23, 10, 15, 7], H). </div> <div class="nb-cell markdown" name="md10"> #### Operadores: Prolog reconoce los siguientes operadores aritméticos, listados en el orden de prioridad de ejecución. - + suma - - resta - * multiplicación - / división - // división entera - MOD módulo - ^ potencia </div> <div class="nb-cell markdown" name="md11"> Prolog soporta los siguientes operadores relacionales: - == igual que - > mayor que - < menor que - >= mayor o igual que - <= menor o igual que - \== diferente que - IS evaluador de expresión - SEED generador de números aleatorios </div> <div class="nb-cell markdown" name="md12"> ### 3. Hechos Son Mecanismos para representar propiedades y relaciones de objetos. Estos son tomados como verdaderos para todo el programa. </div> <div class="nb-cell program" name="p10"> futbolista(messi). animal(canario). padre(jose, manuel). </div> <div class="nb-cell markdown" name="md24"> Al realizar una consulta prolog va a buscar en la base de conocimiento definida algun hecho que haga matching con esta, en caso de encontrar algun matching retorna true o en caso contrario false. </div> <div class="nb-cell query" name="q5"> % falso futbolista(canario). </div> <div class="nb-cell query" name="q6"> % verdadero animal(canario). </div> <div class="nb-cell markdown" name="md13"> ### 4. Reglas Cuando un hecho necesita obtener la verdad a partir de otros hechos se usan la reglas, estas definen las condiciones para que un predicado sea cierto. </div> <div class="nb-cell program" name="p11"> padre(tom,sergio). padre(nicolas,tom). hijo(X,Y) :- padre(Y,X). abuelo(X,Y) :- padre(X,Z), padre(Z,Y). </div> <div class="nb-cell query" name="q7"> % falso hijo(nicolas, sergio). </div> <div class="nb-cell query" name="q8"> % verdadero abuelo(nicolas, sergio). </div> <div class="nb-cell markdown" name="md14"> Ejemplos de conjuncion y disyuncion en las reglas. </div> <div class="nb-cell program" name="p12"> padre(tom,sergio). padre(tom,matias). padre(nicolas,tom). madre(maria,sergio). madre(maria,matias). % La conjuncion utiliza el operador , hermano(X,Y) :- padre(Z,X) , padre(Z,Y) , X \== Y. % La disyuncion utiliza el operador ; hijo(X,Y) :- padre(Y,X) ; madre(Y,X). </div> <div class="nb-cell query" name="q9"> hermano(sergio,matias). </div> <div class="nb-cell query" name="q10"> hijo(matias,maria). </div> <div class="nb-cell markdown" name="md15"> Prolog permite el llamado recursivo de sus reglas, por ejemplo para calcular el factorial de un numero: </div> <div class="nb-cell program" name="p13"> factorial(0,1). % Caso Base factorial(X,Y) :- N is X-1 , factorial(N,Z) , Y is X*Z. </div> <div class="nb-cell query" name="q11"> factorial(3, RESULTADO). </div> <div class="nb-cell markdown" name="md17"> ### 5. Aplicaciones Una de las aplicaciones que tiene prolog es el de implementar sistemas expertos el cual es un sistema que provee una solución a los problemas en rangos específicos de conocimiento tan cercanas como un humano experto lo pudiese hacer, en prolog se pueden implementar con ayuda de los hechos conocidos por un experto humano. Vamos a ver cada parte del sistema y que funcion cumple. La primera parte, la regla evaluar es la cual inicia el proceso, está a su vez llama a hipotesis, para luego de evaluarla escribir en consola la solución que considera correcta según los datos que tiene disponibles. </div> <div class="nb-cell program" name="p16"> evaluar:- hipotesis(Enfermedad), write('Creo que el paciente tiene '), write(Enfermedad), nl, write('Tener cuidado!'), deshacer. </div> <div class="nb-cell markdown" name="md18"> En la regla "hipotesis" se enumeran las enfermedades las cuales puede diagnosticar el sistema experto </div> <div class="nb-cell program" name="p17"> /*Hipotesis que deberia ser probada*/ hipotesis(resfriado) :- resfriado. hipotesis(gripe) :- gripe. hipotesis(tifoidea) :- tifoidea. hipotesis(sarampion) :- sarampion. hipotesis(malaria) :- malaria. hipotesis(desconocido). /* sin diagnostico*/ </div> <div class="nb-cell markdown" name="md19"> Cada enfermedad tiene una regla la cual liga los síntomas con la respectiva enfermedad, además de mostrar los respectivos medicamentos recomendados </div> <div class="nb-cell program" name="p18"> /*Reglas de identificacion*/ resfriado :- verificar(dolor_cabeza), verificar(nariz_moqueda), verificar(estornudo), verificar(dolor_garganta), write('Consejos y Sugerencias:'), nl, write('1: Tylenol'), nl, write('2: Panadol'), nl, write('3: Aerosol nasal'), nl, write('Por favor use ropa de abrigo porque'), nl. </div> <div class="nb-cell markdown" name="md20"> Cada regla de enfermedad usa "verificar" para reconocer si se sabe si el usuario tiene o no un síntoma en específico, el hecho "si(sintoma)" no se encuentra en la base de conocimiento del sistema entonces se hace el llamado a la regla "preguntar(síntoma) </div> <div class="nb-cell program" name="p19"> /*Como se verifica */ verificar(S) :- (si(S)-> true ; (no(S)-> fail ; preguntar(S))). </div> <div class="nb-cell markdown" name="md21"> La regla auxiliar "preguntar" sirve para recibir los datos del usuario, esta hace uso de la regla assert que trae prolog por defecto para poder añadir nuevos hechos a la base de conocimiento del sistema. </div> <div class="nb-cell program" name="p20"> /* Como se hacen las preguntas */ preguntar(Pregunta) :- write('El paciente tiene los siguentes sintomas:'), write(Pregunta), write('? '), read(Respuesta), nl, ( (Respuesta == si)-> assert(si(Pregunta)) ; assert(no(Pregunta)), fail). </div> <div class="nb-cell markdown" name="md22"> Pueden probar el sistema haciendo la consulta “evaluar” en la consola. </div> <div class="nb-cell program" data-background="true" name="p21"> % Codigo Completo evaluar:- hipotesis(Enfermedad), write('Creo que el paciente tiene '), write(Enfermedad), nl, write('Tener cuidado!'), deshacer. /*Hipotesis que deberia ser probada*/ hipotesis(resfriado) :- resfriado. hipotesis(gripe) :- gripe. hipotesis(tifoidea) :- tifoidea. hipotesis(sarampion) :- sarampion. hipotesis(malaria) :- malaria. hipotesis(desconocido). /* sin diagnostico*/ /*Reglas de identificacion*/ resfriado :- verificar(dolor_cabeza), verificar(nariz_moqueda), verificar(estornudo), verificar(dolor_garganta), write('Consejos y Sugerencias:'), nl, write('1: Tylenol'), nl, write('2: Panadol'), nl, write('3: Aerosol nasal'), nl, write('Por favor use ropa de abrigo porque'), nl. gripe :- verificar(fiebre), verificar(dolor_cabeza), verificar(escalofrio), verificar(dolor_cuerpo), write('Consejos y Sugerencias:'), nl, write('1: Tamigripe/tableta'), nl, write('2: panadol/tableta'), nl, write('3: Zanamivir/tableta'), nl, write('Por favor tome un baño tibio y haga gárgaras de sal porque'), nl. tifoidea :- verificar(dolor_cabeza), verificar(dolor_abdominal), verificar(bajo_apetito), verificar(fiebre), write('Consejos y Sugerencias:'), nl, write('1: Chloramphenicol/tableta'), nl, write('2: Amoxicillin/tableta'), nl, write('3: Ciprofloxacin/tableta'), nl, write('4: Azithromycin/tableta'), nl, write('Please do complete bed rest and take soft Diet Because'), nl. sarampion :- verificar(fiebre), verificar(nariz_moqueda), verificar(erupcion), verificar(conjuntivitis), write('Consejos y Sugerencias:'), nl, write('1: Tylenol/tableta'), nl, write('2: Aleve/tableta'), nl, write('3: Advil/tableta'), nl, write('4: Vitamina A'), nl, write('Por favor, descanse y use más líquido porque'), nl. malaria :- verificar(fiebre), verificar(sudoracion), verificar(dolor_cabeza), verificar(nausea), verificar(vomito), verificar(diarrea), write('Consejos y Sugerencias:'), nl, write('1: Aralen/tableta'), nl, write('2: Qualaquin/tableta'), nl, write('3: Plaquenil/tableta'), nl, write('4: Mefloquine'), nl, write('Por favor, no duerma al aire libre y cubra toda su piel porque'), nl. /* Como se hacen las preguntas */ preguntar(Pregunta) :- write('El paciente tiene los siguientes sintomas:'), write(Pregunta), write('? '), read(Respuesta), nl, ((Respuesta == si) -> assert(si(Pregunta)); assert(no(Pregunta)), fail). :- dynamic si/1,no/1. /*Como se verifica */ verificar(S) :- (si(S)->true ; (no(S)->fail ; preguntar(S))). /* deshacer all si/no assertions*/ deshacer :- retract(si(_)),fail. deshacer :- retract(no(_)),fail. deshacer. </div> <div class="nb-cell query" name="q12"> evaluar </div> </div>