<div class="notebook"> <div class="nb-cell html" name="htm8"> <h1 align="center">Tutorial de Prolog - Universidad Nacional de Colombia - 2019-2</h1> </div> <div class="nb-cell html" name="htm9"> <p align="center"> <img src="https://camo.githubusercontent.com/60bbbdf4fe36938bee8b1ead8268a206bc504ee9/687474703a2f2f7777772e7377692d70726f6c6f672e6f72672f69636f6e732f737769706c2e706e67"> </p> </div> <div class="nb-cell markdown" name="md20"> ## 1. Conociendo Prolog </div> <div class="nb-cell markdown" name="md22"> La programación lógica es un estilo muy diferente de la programación convencional. Un lenguaje de programación lógica es un sistema de notación para escribir declaraciones lógicas junto con algoritmos especificados para implementar reglas de inferencia. El lenguaje más influyente dentro de este paradigma es Prolog. Su nombre se deriva de: **Pro** gramming in **Log** ic </div> <div class="nb-cell markdown" name="md21"> Prolog fue desarrollado por cientificos Europeos de la computación a principios de los años setenta para fines de investigación en automatización de pruebas de teoremas matemáticos, sin embargo, es un lenguaje de propósito general que actualmente es usado para desarrollar aplicaciones complejas relacionadas con inteligencia artificial. </div> <div class="nb-cell markdown" name="md23"> Los programas en prolog están basados en lógica matemática para formar conclusiones válidas en base a evidencia disponible. Su gran ventaja es el uso de computación simbolica en lugar de númerica. </div> <div class="nb-cell markdown" name="md24"> Los programas en Prolog sólo poseen dos componentes: - Hechos - Reglas El usuario (programador) genera una serie de preguntas conocidas como _querys_ u _objetivos_ a los cuales el programa responderá usando las reglas y hechos que tiene disponible en su definición. </div> <div class="nb-cell markdown" name="md4"> ## Comandos basicos </div> <div class="nb-cell query" name="q17"> halt. </div> <div class="nb-cell markdown" name="md7"> Sale del entorno Prolog. </div> <div class="nb-cell query" name="q18"> help(halt). </div> <div class="nb-cell markdown" name="md5"> Solicita ayuda al entorno. </div> <div class="nb-cell program" name="p9"> likes(mary,food). likes(mary,wine). likes(john,wine). likes(john,mary). </div> <div class="nb-cell query" name="q19"> listing. </div> <div class="nb-cell markdown" name="md6"> Muestra la lista de todos los predicados de la base de conocimiento. </div> <div class="nb-cell markdown" name="md18"> ## 2. Hechos y Reglas Un hecho corresponde a aquella sentencia de orden más simple en Prolog, es un predicado cuyo valor siempre es verdadero, puede ser entendido como un axioma sobre el que se van a basar posteriormente nuestras contrucciones. Por su parte las reglas corresponden a las consultas o inferencias que se realizan en base a los hechos, dando como resultado un predicado cuyo valor puede ser tanto verdadero como falso de acuerdo a los argumentos recibidos, ejemplo: </div> <div class="nb-cell markdown" name="md8"> **Nota:** Todo hecho debe terminar con un punto. </div> <div class="nb-cell program" name="p10"> student(cristian). student(jhonathan). is_student(X):-student(X). </div> <div class="nb-cell markdown" name="md55"> ':-' es el operador de implicación. 'is_student(X)' implica que 'student(X)' sea verdadero. </div> <div class="nb-cell html" name="htm5"> <h2>Consultas</h2> <p></p>Es el mecanismo por el cual Prolog extrae el conocimiento del programa haciendo llamados a predicados con argumentos concretos. Son expresiones logicas que son evaluadas de acuerdo a los hechos y reglas definidos. <p></p>Para plantear una consulta en Prolog, el usuario simplemente prueba ésta, para ver si es verdadera. Si la prueba es positiva, Prolog contesta: YES, de lo contrario responde NO, o también se usa TRUE o FALSE. <p></p>Una consulta estará constituida por una o varias metas que Prolog deberá resolver. El intérprete de Prolog nos devuelve más soluciones si utilizamos el punto y coma (or) “;”. El operador de conjunción es la coma. <p></p>Cuando no existen más soluciones que unifiquen con el objetivo, el intérprete contesta No. </div> <div class="nb-cell query" name="q14"> student(X). </div> <div class="nb-cell query" name="q3"> is_student(cristian). </div> <div class="nb-cell query" name="q4"> is_student(fabio). </div> <div class="nb-cell markdown" name="md42"> ### Base de Conocimiento Cargar un programa simplemente hace que las cláusulas (hechos o reglas) se coloquen en un área de almacenamiento llamada la base de datos o base de conocimiento de Prolog. Introducir una secuencia de uno o más objetivos hace que el sistema busque y use las cláusulas necesarias para evaluar los objetivos. Una vez colocadas en la base de datos, las cláusulas generalmente permanecen allí hasta el usuario sale del sistema Prolog y, por lo tanto, puede usarse para evaluar otros objetivos. El programa puede cargarse para su uso por el sistema usando el predicado incorporado 'consultar'. Ej: </div> <div class="nb-cell query" name="q15"> consult('prog1.pl'). </div> <div class="nb-cell markdown" name="md43"> Siempre que exista el archivo prog1.pl y el programa sea sintácticamente correcto, es decir contiene cláusulas válidas, el objetivo tendrá éxito y como efecto secundario producirá una o más líneas de salida para confirmar que el programa se ha leído correctamente. </div> <div class="nb-cell markdown" name="md10"> ## 3. Términos Los _data objects_ en Prolog son llamados términos. Existen tres tipos diferentes: Números, átomos y variables. </div> <div class="nb-cell markdown" name="md16"> ### 3.1. Números </div> <div class="nb-cell markdown" name="md44"> Todas las versiones de Prolog permiten el uso de enteros. Éstos son escritos cómo una secuencia de números del 0 al 9, opcionalmente precedidos de un signo más (+) o un menos (-). </div> <div class="nb-cell program" name="p11"> 623 -47 +5 025 </div> <div class="nb-cell markdown" name="md45"> La mayoría de versiones de Prolog soportan la notación de números con puntos decimales. Sólo se admite un punto en cualquier posición excepto cuando precede a un signo más (+) o un menos (-) </div> <div class="nb-cell markdown" name="md1"> </div> <div class="nb-cell program" name="p12"> 6.43 -.245 +256. </div> <div class="nb-cell markdown" name="md17"> ### 3.2. Átomos </div> <div class="nb-cell markdown" name="md46"> Los átomos son constantes que no tienen valores númericos. Hay tres formas diferentes en las cuales se pueden definir. </div> <div class="nb-cell markdown" name="md47"> #### 3.2.1 A Cómo una secuencia de una o más letras en mayúsculas o minúsculas, números y underscores. Debe empezar con una letra en minúscula. </div> <div class="nb-cell program" name="p13"> john today_is_Tuesday fred_jones a32_BCD </div> <div class="nb-cell markdown" name="md48"> #### 3.2.2 B Cómo una secuencia de carácteres entre comillas simples, incluyendo espacios y letras en mayúscula. </div> <div class="nb-cell program" name="p14"> 'Today is Tuesday' 'today-is-Friday' '32abc' </div> <div class="nb-cell markdown" name="md49"> #### 3.2.3 C Cómo una secuencia de uno o más caracteres especiales de los siguientes: + - * / > < = & # @ </div> <div class="nb-cell program" name="p15"> +++ >= > +- </div> <div class="nb-cell markdown" name="md11"> ### 3.3. Variables Las variables en Prolog no son variables en el sentido habitual, son variables lógicas. El nombre de una variable se denota por cualquier secuencia de una o más letras (mayusculas o minúsculas), números y guiones bajos, comenzando con una letra mayúscula o guion bajo, por ejemplo: </div> <div class="nb-cell program" name="p8"> X Author Person_A _123A </div> <div class="nb-cell markdown" name="md25"> #### 3.3.1. Variables en objetivos Se pueden interpretar como 'encontrar valores de las variables que satisfacen el objetivo'. Ej: </div> <div class="nb-cell program" name="p17"> dog(fido). dog(pluto). cat(felix). cat(garfield). animal(X):-dog(X). chases(X,Y):- dog(X),cat(Y), write(X),write(' chases '),write(Y),nl. /* chases is a predicate with two arguments*/ </div> <div class="nb-cell query" name="q6"> animal(A). </div> <div class="nb-cell markdown" name="md26"> Se puede leer como: encontrar un valor para A, tal que, A sea un animal. </div> <div class="nb-cell query" name="q7"> chases(X,Y). </div> <div class="nb-cell markdown" name="md27"> Significa: Encontrar valores de las varibles X y Y que satisfagan la condicion de X persigue a Y. </div> <div class="nb-cell markdown" name="md58"> #### Predicados predefinidos Prolog tiene una serie de predicados predefinidos, los cuales pueden ser vistos como procedimientos o funciones predefinidas, tales como: write, read, nl y not. </div> <div class="nb-cell markdown" name="md28"> #### 3.3.2. Alcance lexico de las variables El alcance de una variable se limita a la clausula en la que aparece. Esto quiere decir que cualquier otra ocurencia de una variable con el mismo nombre en otra clausula no tendra nada que ver con las anteriores. </div> <div class="nb-cell markdown" name="md29"> #### 3.3.3. Variables cuantificadas universalmente Si una variable aparece en el encabezado de una regla o hecho, se esta indicando que la regla o hecho se aplica a todos los valores posibles de la variable. Ej: </div> <div class="nb-cell program" name="p4"> person(frances,wilson,female,28,architect). person(fred,jones,male,62,doctor). person(paul,smith,male,45,plumber). person(martin,williams,male,23,chemist). person(mary,jones,female,24,programmer). person(martin,johnson,male,47,solicitor). man(A):-person(A,B,male,C,D). </div> <div class="nb-cell markdown" name="md30"> La última cláusula es una regla, definida utilizando el predicado de persona, que también tiene la interpretación de, 'para todo A, A es un hombre si A es una persona cuyo el sexo es masculino'. </div> <div class="nb-cell query" name="q27"> man(X). </div> <div class="nb-cell markdown" name="md31"> #### 3.3.4. Variables anónimas </div> <div class="nb-cell markdown" name="md32"> Para saber si hay una cláusula correspondiente a alguien llamado Paul en el base de datos, solo es necesario ingresar un objetivo como: </div> <div class="nb-cell query" name="q8"> person(paul,Surname,Sex,Age,Occupation). </div> <div class="nb-cell markdown" name="md33"> Esto se puede reemplazar por: </div> <div class="nb-cell query" name="q9"> person(paul,_,_,_,_). </div> <div class="nb-cell markdown" name="md34"> El caracter '_' denota una variable especial, llamada variable anónima. Esto se usa para expresar que la variable puede tener cualquier valor. Si solo el apellido de cualquier persona llamada Paul es de interés, puede encontrarlo al hacer que las otras tres variables sean anónimas en un objetivo: </div> <div class="nb-cell query" name="q10"> person(paul,Surname,_,_,_). </div> <div class="nb-cell markdown" name="md13"> ### 3.4. Términos compuestos Un término compuesto comienza con un atomo, llamado 'functor' y es seguido por una secuencia de argumentos encerrados entre parentesis y separados por comas. Su forma general es: Functor(t1,t2,t3,...,tn) (n>=1) Ej: likes(dog(henry),Y) pred3(alpha,beta,gamma,Q) pred(A,B,likes(X,Y),-4,pred2(3,pred3(alpha,beta,gamma,Q))) </div> <div class="nb-cell markdown" name="md15"> Cada argummento de un término compuesto debe ser un término: likes(paul,prolog) read(X) dog(henry) cat(X) </div> <div class="nb-cell markdown" name="md14"> ### 3.5. Listas Las listas corresponde al igual que en muchos otros lenguajes a una estructura simple de datos, la cual se representa como una serie de elementos separados por coma dentro de parentesis cuadrados. Un elemento de una lista puede ser cualquier clase de término, incluyendo, términos compuestos e incluso otras listas. Ej: </div> <div class="nb-cell program" name="p3"> [dog,cat,y,mypred(A,b,c),[p,q,R],z] [[john,28],[mary,56,teacher],robert,parent(victoria,albert),[a,b,[c,d,e],f],29] [[portsmouth,edinburgh,london,dover],[portsmouth,london,edinburgh],[glasgow]] </div> <div class="nb-cell query" name="q28"> X = [1,2,3]. </div> <div class="nb-cell markdown" name="md12"> Para denotar una lista vacia, se realiza de la siguiente manera: </div> <div class="nb-cell query" name="q29"> E = []. </div> <div class="nb-cell markdown" name="md19"> Las listas en Prolog se conforman de una cabeza (Head) y una cola (Tail) las cuales pueden ser accedidas haciendo uso de la sintaxis [H|T] donde H y T son las variables a las que se espera se retorne los valores de la cabeza y la cola respectivamente. </div> <div class="nb-cell query" name="q5"> [H|T] = [1, 2, 3]. </div> <div class="nb-cell markdown" name="md35"> ## 4. ¿Cómo se evaluan los objetivos? El sistema Prolog intenta satisfacer cada objetivo a su vez, trabajando de izquierda a derecha. Cuando el objetivo involucra variables, p. posee (X, Y), esto generalmente implica vincularlos a valores, p. X a John e Y a Fido. Si todos los objetivos tienen éxito a su vez, toda la secuencia de objetivos tiene éxito. El sistema generará los valores de todos los variables que se utilizan en la secuencia de objetivos y cualquier otra salida de texto como un efecto secundario del cumplimiento de los objetivos (write (X) y nl). Ej: </div> <div class="nb-cell program" name="p18"> owns(john,fido). dog(rufo). dog(fido). </div> <div class="nb-cell query" name="q11"> owns(X,Y),dog(Y),write(X),nl. </div> <div class="nb-cell markdown" name="md36"> ### Unificación Dado un objetivo para evaluar, Prolog recorre todas las clausulas en el orden en que fueron declaradas hasta que encuentra una en donde se cumple. Si no se encuentra el objetivo falla. </div> <div class="nb-cell markdown" name="md37"> Prolog utiliza una forma muy general de emparejamiento conocida como unificación, que generalmente implica que una o más variables reciben valores para formar dos términos de llamado idénticos. Esto se conoce como vincular las variables a los valores. Por ejemplo, los términos dog(X) y dog(fido) pueden unificarse uniendo la variable X al átomo fido, es decir, dar a X el valor fido. Los términos owns(john, fido) y owns(P, Q) pueden ser unificados mediante la unión de las variables P y Q a los átomos de John y Fido, respectivamente. </div> <div class="nb-cell query" name="q35"> dog(Y). </div> <div class="nb-cell markdown" name="md56"> Prolog aplica la resolución de forma estrictamente lineal, reemplaza los objetivos de izquierda a derecha y considera las cláusulas en la base de datos en orden de arriba a abajo. Los sub-objetivos también se consideran inmediatamente una vez que se configuran. Por lo tanto, esta estrategia de búsqueda da como resultado una búsqueda profunda en un árbol de posibles opciones. </div> <div class="nb-cell query" name="q34"> dog(Y),owns(john,Y) </div> <div class="nb-cell markdown" name="md54"> ### Backtracking Es el mecanismo por el cual Prolog busca satisfacer un objetivo compuesto, recordando los momentos en donde habia mas de una solución para poder dar marcha atrás y seguir la ejecución utilizando otra alternativa si la solución inicial falla. </div> <div class="nb-cell markdown" name="md38"> ## 5. Operadores Prolog también proporciona facilidades para hacer aritmética usando una notación similar a la del álgebra básica. Esto se logra utilizando el predicado incorporado 'is', que está predefinido como un operador infijo y, por lo tanto, se escribe entre dos argumentos. </div> <div class="nb-cell markdown" name="md39"> 'Is' funciona como un operador de asignación. Evaluar el objetivo X is -6.5 hará que X esté vinculado al número 6.5 y que el objetivo tenga éxito. </div> <div class="nb-cell markdown" name="md41"> El segundo argumento puede ser un número o una expresión aritmética. </div> <div class="nb-cell query" name="q12"> X is 10.5+4.7*2. </div> <div class="nb-cell query" name="q13"> Y is 10, Z is Y + 1. </div> <div class="nb-cell html" name="htm1"> <h2> 6. Expresiones</h2> <p>Cualquier predicado definido por el usuario con un argumento (un predicado unario) puede ser convertido a un operador de prefijo. Esto permite que el functor se escriba antes de argumento sin paréntesis</p> <p>Alternativamente, un predicado unario puede convertirse en un operador postfix. Esta permite que el functor se escriba después del argumento. La notación del operador también se puede usar con reglas para facilitar la legibilidad.</p> </div> <div class="nb-cell html" name="htm2"> <h3>6.1. Operadores de comparacion de expresiones</h3> <p>Comparar dos expresiones se realiza mediante su representación lexicográfica.</p> <p>Una estructura es menor que otra si:</p> <ul> <li>Tiene menor número de argumentos.</li> <li>De acuerdo al functor.</li> <li>Por los argumentos en orden</li> </ul> <p>Los operadores que se pueden usar para compararar expresiones y estructuras son:</p> <ul> <li><p>X=Y: Unificación, X es igual Y</p></li> <li><p>X\=Y: Su opuesto, no unifican</p></li> <li><p>X==Y: Igualdad</p></li> <li><p>X/==Y: Desigualdad</p></li> <li><p>@>lexicograficamente: Mayor lexicograficamente que</p></li> <li><p>@<: Menor lexicograficamente que</p></li> <li><p>@>=: Mayor o igual lexicograficamente que</p></li> <li><p>@<=: Menor o igual lexicograficamente que</p></li> </ul> </div> <div class="nb-cell html" name="htm3"> <h3>6.2. Operadores relacionales</h3> <p>Se utilizan para comparar el valor de dos expresiones aritméticas. El objetivo tiene éxito si el valor de la primera expresión es igual, no igual a, mayor que, mayor o igual que, menor o menor que o igual al valor de la segunda expresión, respectivamente. Ambos argumentos deben ser números, variables ligadas o expresiones aritméticas.</p> <p>Los operadores relacionales que estan disponibles en Prolog son:</p> <ul> <li><p>X is Y: Unificacion</p></li> <li><p>X =:= Y: Igualdad</p></li> <li><p>X =/= Y: Desigualdad</p></li> <li><px>Y>: Mayor que<p></p></px></li> <li><px>Y<: Menor que<p></p></px></li> <li><p>X>=Y: Mayor o igual que</p></li> <li><p>X<=Y: Menor o igual que</p></li> </ul> </div> <div class="nb-cell query" name="q24"> X is 2. </div> <div class="nb-cell query" name="q25"> 2*2 = 5. </div> <div class="nb-cell query" name="q26"> 4 > 7. </div> <div class="nb-cell html" name="htm4"> <h3>6.3. Operadores aritmeticos</h3> <p>Prolog también proporciona facilidades para hacer aritmética usando una notación similar a la que ya será familiar para muchos usuarios de álgebra básica.</p> <p>Además de los números, las variables y los operadores, las expresiones aritméticas pueden incluir funciones aritméticas, escritas con sus argumentos entre paréntesis (es decir, no como operadores).</p> <p>Cualquier variable que aparezca en una expresión aritmética ya debe estar vinculada (como resultado de evaluar un objetivo anterior) y sus valores deben ser numéricos. Siempre que lo sean, el objetivo siempre tendrá éxito y la variable que forma el primer argumento estará vinculada al valor de la expresión aritmética. De lo contrario, aparecerá un mensaje de error.</p> <p>Los operadores y funciones aritmeticas que estan disponibles en Prolog son:</p> <ul> <li><p>X+Y: Suma</p></li> <li><p>X-Y: Resta</p></li> <li><p>X*Y: Producto</p></li> <li><p>X/Y: Division</p></li> <li><p>X//Y: Cociente entero</p></li> <li><p>X mod Y: Modulo</p></li> <li><p>X^Y: Potencia</p></li> <li><p>-X: Valor negativa de</p></li> <li><p>abs(X): Valor absoluto</p></li> <li><p>sin(X): Seno</p></li> <li><p>cos(X): Coseno</p></li> <li><p>max(X,Y): Maximo valor de X e Y</p></li> <li><p>round(X): Valor redondeado</p></li> <li><p>sqrt(X): Raiz cuadrada</p></li> </ul> </div> <div class="nb-cell query" name="q21"> X is sqrt(49) </div> <div class="nb-cell query" name="q22"> X is round(2.5) </div> <div class="nb-cell query" name="q23"> X is max(2.94, 3.0) </div> <div class="nb-cell markdown" name="md50"> ### 6.4. Operadores de listas </div> <div class="nb-cell html" name="htm11"> <p>Prolog permite operar sobre las listas, consultar alguna propiedad o realizar modificaciones sobre esta. Los operadores sobre listas son: </p> <ul> <li><p>[X,Y,Z]=[a,1,b]: Unificacion</p></li> <li><p>member(X,[X,Y,Z]): X ∈ [X,Y,Z]</p></li> <li><p>append(X,Y,result): X U Y</p></li> <li><p>length(X,result): longitud de X</p></li> <li><p>sort(X,Y): Comprueba si la lista X esta ordenada con respecto a la lista Y</p></li> <li><p>is_list([X,Y]): Comprueba si el elemento es una lista</p></li></ul> </div> <div class="nb-cell query" name="q20"> [a,b,c]=[1,2,3] </div> <div class="nb-cell query" name="q31"> member(a,[1,a,&]) </div> <div class="nb-cell query" name="q32"> sort([1,1,1,2,5,6],[1,2,5,6]) </div> <div class="nb-cell markdown" name="md53"> ## 8. Recursión ### Loops El predicado del bucle se define en términos de sí mismo. La segunda cláusula se puede pensar de como: 'para recorrer desde N, primero escriba el valor de N, luego reste uno para dar M, luego bucle de M '. Este proceso claramente necesita ser terminado y esto se logra mediante la primera cláusula: 'cuando el argumento es cero, no haga nada (y, por lo tanto, pare)'. La primera La cláusula puede considerarse como una condición de terminación para la recursión. </div> <div class="nb-cell program" name="p5"> loop(0). loop(N):-N>0,write('The value is: '),write(N),nl, M is N-1,loop(M). </div> <div class="nb-cell query" name="q30"> loop(6). </div> <div class="nb-cell program" name="p6"> go2:-loop2(start). loop2(end). loop2(X):-X\=end,write('Type end to end: '),read(Word), write('Input was '),write(Word),nl,loop2(Word). </div> <div class="nb-cell query" name="q33"> go2. </div> <div class="nb-cell markdown" name="md57"> ## 9. Estructuras de control ### If else if A then B else C </div> <div class="nb-cell program" name="p7"> student(cristian). student(jhonathan). if_else(X) :- student(X), write(X),write(' is a student '). if_else(X) :- not(student(X)), write(X),write(' is not a student '). </div> <div class="nb-cell query" name="q36"> if_else(cristian). </div> <div class="nb-cell query" name="q37"> if_else(fido). </div> <div class="nb-cell html" name="htm6"> <h2>10. Aplicaciones</h2> <p>(Parrafo, comentario sobre sus aplicaciones más comunes)</p> <ul> <li>Prolog se puede utilizar para resolver, básicamente, cualquier tipo de problema.</li> <li>Gestión de Juegos</li> <li>RFuzzy para reconocer las emociones humanas</li> <li>Inteligencia de los robots</li> <li>Inteligencia Artificial y Sistemas Expertos</li> <li>Construir bases de conocimientos basados en la lógica</li> <li>Construcción de Compiladores e Intérpretes</li> <li>Reconocimiento del Lenguaje Natural</li> <li>Analisis y medición de redes sociales</li> <li>Sistemas de soporte electrónico para doctores</li> </ul> </div> <div class="nb-cell markdown" name="md40"> ## Ejercicios prácticos. A continuación se tratará la implementación del algoritmo merge sort, la solución del problema de la Torre de Hanoi y la definición de un sistema experto en Prolog. </div> <div class="nb-cell markdown" name="md2"> ### Merge sort </div> <div class="nb-cell markdown" name="md51"> Merge sort es uno de los algoritmos de ordenamiento más utilizado, en la siguiente sección se presenta una implementación top-down del mismo. Recordemos cómo funciona, se basa en la técnica divide y venceras así que primeramente si la longitud de la lista desordenada de elementos es 0 o 1, entonces ya esta ordenado, si no entonces se divide en dos sublists de aproximadamente la mitad del tamaño y se ordena cada sublista recursivamente las cuales se mezclan en una sola para dar como resultado una lista ordenada en orden O(nlog(n)) </div> <div class="nb-cell program" name="p1"> % Base Cases merge_sort([],[]). merge_sort([X],[X]). % Recursion merge_sort(List,Sorted):- List=[_,_|_],divide(List,L1,L2), merge_sort(L1,Sorted1),merge_sort(L2,Sorted2), merge(Sorted1,Sorted2,Sorted). % merge, takes two list and merge them into one merge([],L,L). merge(L,[],L). merge([X|T1],[Y|T2],[X|T]):-X=<Y,merge(T1,[Y|T2],T). merge([X|T1],[Y|T2],[Y|T]):-X>Y,merge([X|T1],T2,T). % divide, takes a list and divide into two separate list of equal size divide(L,L1,L2):-length(L, Len), splitlist(L, L1, L2, Len//2). splitlist(L, [], L, 0). splitlist([H|T], [H|A], B, N) :- Nminus1 is N-1, splitlist(T, A, B, Nminus1). </div> <div class="nb-cell query" name="q1"> merge_sort([1, 4, -5, 2, 8], L). </div> <div class="nb-cell markdown" name="md9"> ### Problema Torres de Hanoi Uso de recursividad, variables anonimas, expresiones y operadores. El problema consiste en: - Hay un stack de N discos están organizados del más grande al más pequeño, de abajo hacia arriba en una barilla. - Hay otras dos varillas que no tienen discos, una es nuestro objetivo donde queremos pasar los discos de forma ordenada y la otra nos va a servir de auxiliar. - Queremos el mínimo número de movimientos para mover el stack de la varilla inicial a la varilla objetivo. </div> <div class="nb-cell html" name="htm10"> <p>El problema se puede resolver por medio de recursividad, por lo cual lo separaremos en tres casos.</p> <img src="https://scontent.fbog3-1.fna.fbcdn.net/v/t1.0-9/74331425_10213133045435611_7275978687403524096_n.jpg?_nc_cat=107&_nc_oc=AQk1qB2eo9NcQSUoYpUQmDuus4EndEk_ZkCdgCEDelYeREkjJjQhPS7Toap17IAzlGY&_nc_ht=scontent.fbog3-1.fna&oh=f471e34589659007c586b31d00e77370&oe=5E5720B4"> <br> <span>Tomado de: <a href="http://alumni.cs.ucr.edu/~vladimir/cs171/prolog_3.pdf">Prolog, Universidad de California</a></span> </div> <div class="nb-cell program" name="p16"> hanoi(1, X, Y, _):- % base case write('Move top disk from '), write(X), write(' to '), write(Y), nl. hanoi(N, X, Y, Z):- % recursion N>1, M is N-1, hanoi(M, X, Z, Y), hanoi(1, X, Y, _), hanoi(M, Z, Y, X). </div> <div class="nb-cell query" name="q16"> hanoi(3, left,right,center). </div> <div class="nb-cell markdown" name="md3"> ### Sistema experto para identificación de fallas mecánicas </div> <div class="nb-cell markdown" name="md52"> Los sistemas expertos utilizados en inteligencia artificial son software que emula el comportamiento de un experto humano en la solución de un problema. Los sistemas expertos funcionan de manera que almacenan conocimientos concretos para un campo determinado y solucionan los problemas, utilizando esos conocimientos, mediante deducción lógica de conclusiones. Con ellos se busca una mejora en calidad y rapidez de respuestas dando así lugar a una mejora de la productividad del experto. Este sistema experto se encarga de detectar posibles fallas mecanicas en un automovil, esto a partir de preguntas de sintomas o problemas que posee el automovil, finalmente se encarga de dar una guia para solucionar la posible falla que se ha encontrado. </div> <div class="nb-cell program" name="p2"> %Identificacion de fallas mecanicas %Start with ?- go. iniciar:- fallas(Falla), write('la falla es: '), write(Falla), nl, undo. %fallas que deben ser evaluadas fallas('hacer un cambio de aceite: primero abra el cofre y ubique la figura del carter, el motor debe estar tibio antes de proceder, despues ubicar la valvula de purgacion debajo del motor y colocar una cubeta debajo, abrir la valvula y drenar el aceite antiguo, vea su manual de usuario para saber cuantos litros de aceite necesita su coche despues de drenar el aceite cierre la valvula y abra el carter para rellenar con el nuevo aceite y tapar el carter'):-aceite,!. fallas('realizar una alineacion y balanceo: la solucion para esto es llavar el auto a un taller para que alinien y balancen las llantas del auto'):-suspension,!. fallas('verificar el estado actual de la bateria: primero abra el cofre y ubique la bateria del coche verifique si estan bien conctados los cables, arranque el coche, si no arranca entonces la bateria esta muerta para esto recarguela pase corriente con otro coche, en caso de no tener exito debera reemplazar la bateria'):-electronico,!. fallas('llego la hora de cambiar tus pastillas de freno: si se escucha un chillido agudo al frenar es tiempo de cambiar las pastillas de los frenos, para ello hay que levantar con un gato hidraulico el lado del freno donde se va a cambiar, con una llave inglesa y una matraca aflojar los cubre pastillas y sacar las patillas antiguas y reponerlas con las nuevas, colocar todo en su lugar y bla bla bla. '):-frenos,!. fallas('posiblemente tu auto pasara a mejor vida: esta luz puede indicar varias fallas en el sistema de la ECU, las pricipales son fallas de sensores, servicio de motor, catalizador, etc. si se cuenta con un escaner automotriz puede borrarse la falla pero esto no arregla el problema, para ello acuda con su mecanico certificado por los aliens.'):-computadora,!. fallas('seguro subes demaciado el volumen: primero debes ubicar la bocina que no se escucha despues quitar o desatornillar el caparcete que protege la bocina y verificar que la bocina este bien conectado o tenga un cable quemado, dado uno de los casos deberas cambiar el cable o remplazar la bocina. Otro caso es verificar el estereo del auto si estan bien conectados los cables'):-sonido,!. fallas('sin resultados! si los problemas persisten utilice un dispositivo alienigena con mas ram y 12 nucleos cpu:/'). %Identificaciones de las posibles fallas aceite:- pregunta('tienes problemas de motor?'), pregunta('su automovil gasta mas combustible de lo debido?'), pregunta('su motor se escucha muy ruidoso? '), pregunta('tiene problemas para arrancar el veiculo en frio?'), pregunta('siente que su motor tiene menos fuerza que antes? '). suspension:- pregunta('tienes problemas de la suspension?'), pregunta('tiene su volante neutral y el auto gira?'), pregunta('ha notado que alguna llanta se desgasta mas? '), pregunta('su volante se mueve bastante y tiembla?'). electronico:- pregunta('tienes problemas electricos?'), pregunta('sus faros titilan o encienden con poca fuerza?'), pregunta('el estereo no enciende?'), pregunta('el auto emite un crack cuando lo enciende?'), pregunta('el auto no enciende de ninguna manera?'), pregunta('su bateria es muy vieja?'). frenos:- pregunta('tienes problemas con tus frenos?'), pregunta('cuando frenas escuchas un chillido agudo?'), pregunta('al frenar siente que tarda mas? '). computadora:- pregunta('la luz check egine se encendio en tu tablero?'), pregunta('la luz se mantiene encendida todo el tiempo?'). sonido:- pregunta('tienes problemas con alguna bocina?'), pregunta('la bocina no se escucha nada?'), pregunta('tu auto tiene suficiente bateria?'). %Preguntar al usuario sobre los problemas del vehiculo %Si el usuario dice si, se sigue haciendo las preguntas %de a misma rama, de lo contrario pasa a la siguiente rama :-dynamic si/1,no/1. preguntar(Problema) :-write(Problema), read(Respuesta), nl, ( (Respuesta == si ; Respuesta == s) -> assert(si(Problema)) ; assert(no(Problema)), fail). %Se verifica la respuesta pregunta(S):-(si(S)->true; (no(S)->false; preguntar(S))). %limpiar todos los hechos creados por el assert undo :- retract(yes(_)),fail. undo :- retract(no(_)),fail. undo. </div> <div class="nb-cell query" name="q2"> iniciar. </div> <div class="nb-cell html" name="htm7"> <hr> <p> Creado por: <br> Cristian Alejandro Mantilla Duque<br> Jhonathan Sandoval Velasco<br> Johnathan Andres Leon Rodriguez<br> Laura Angélica Cárdenas Vargas<br> </p> </div> </div>