laboratorio inteligencia artificial

13
LABORATORIO NRO 02 1 1 PROLOG Prolog1: Hechos y Reglas 1. El siguiente fragmento incluye un conjunto de declaraciones básicas sobre una familia y una regla que indica si X es progenitor de Y: progenitor(fernando ,juan). progenitor(luisa ,juan). progenitor(luisa ,maria). progenitor(luisa ,diego). progenitor(fernando ,pepe). progenitor (pepe , pedro ). progenitor(pedro ,ana). progenitor (pedro , belen ). hombre(juan ). hombre(fernando ). hombre ( pepe ) . hombre( diego ). hombre(pedro ). mujer( luisa ). mujer ( pepa ) . mujer( belen ). mujer(ana). Compilar el programa y realizar las siguientes consultas: a) Se cumple que fernando es el progenitor de pepe? b) Hay alguien que sea progenitor de ana? c)Hay alguien que sea progenitor de fernando? d) Hay alguien que sea a la vez progenitor de pepe y de juan? 2. Los siguientes fragmentos declaran una regla que indica si X es el padre de Y, y una regla que indica si X es abuelo de Y: padre(X,Y):progenitor (X,Y) ,hombre(X). abuelo( X, Y) : progenitor ( X, Z ) , progenitor ( Z , Y ) , hombre ( X ) . Declarar reglas familiares para: a) madre b) hermano c) hijo

Upload: alexander-choquenaira-florez

Post on 05-Dec-2015

8 views

Category:

Documents


12 download

DESCRIPTION

Laboratorio Practico de I.A.

TRANSCRIPT

Page 1: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 1

1

PROLOG

Prolog1: Hechos y Reglas 1. El siguiente fragmento incluye un conjunto de declaraciones básicas sobre una familia y una regla que indica si X es progenitor de Y: progenitor(fernando ,juan). progenitor(luisa ,juan). progenitor(luisa ,maria). progenitor(luisa ,diego). progenitor(fernando ,pepe). progenitor (pepe , pedro ). progenitor(pedro ,ana). progenitor (pedro , belen ). hombre(juan ). hombre(fernando ). hombre ( pepe ) . hombre( diego ). hombre(pedro ). mujer( luisa ). mujer ( pepa ) . mujer( belen ). mujer(ana). Compilar el programa y realizar las siguientes consultas:

a) Se cumple que fernando es el progenitor de pepe? b) Hay alguien que sea progenitor de ana? c) Hay alguien que sea progenitor de fernando? d) Hay alguien que sea a la vez progenitor de pepe y de juan?

2. Los siguientes fragmentos declaran una regla que indica si X es el padre de Y, y una regla que indica si X es abuelo de Y: padre(X,Y):−progenitor (X,Y) ,hombre(X). abuelo( X, Y) : − progenitor ( X, Z ) , progenitor ( Z , Y ) , hombre ( X ) . Declarar reglas familiares para:

a) madre b) hermano c) hijo

Page 2: Laboratorio Inteligencia Artificial

Escuela Prof. De Ingeniería de Sistemas – UNSA- M.Sc. Carlo Corrales

2

d) hermana e) abuela f) tio

3. Definir un predicado que indique si X es un antepasado de Y

Prolog2: Listas Una lista está vacia o está compuesta por un primer elemento (head) y una cola la cual es una lista además.. En Prolog representamos la lista vacia por el átomo [] y una lista no vacía por el término [H|T] donde H denota la cabeza y T denota la cola. 1.01 (*) Encontrar el ultimo elemento de una lista. Ejemplo: ?- my_last(X,[a,b,c,d]). X = d 1.02 (*) Encontrar el penultimo elemento de una lista. 1.03 (*) Encontrar el K-esimo elemento de una lista. El primer elemento en la lista es el número 1. Ejemplo: ?- element_at(X,[a,b,c,d,e],3). X = c 1.04 (*) Encontrar el número de elementos de una lista. 1.05 (*) Invertir una lista. 1.06 (*) Descubrir si una lista es un palindrome. Un palindrome puede ser leido de adelante hacia atras o atrás hacia adelante ; p.e. [x,a,m,a,x]. 1.07 (**) Aplanar una lista de listas. Transformar una lista, posiblemente manteniendo listas como elementos dentro de una lista plana, reemplazando cada lista con

Page 3: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 3

3

sus elementos recursivamente. Ejemplo: ?- my_flatten([a, [b, [c, d], e]], X). X = [a, b, c, d, e] Tip: Use los predicados predefinidos is_list y append 1.08 (**) Eliminar duplicados consecutivos de una lista de elementos. Si una lista contiene elementos repetidos, serán reemplazados con una copia Simple del elemento. El orden de los elementos no debe cambiar. Ejemplo: ?- compress([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X). X = [a,b,c,a,d,e] 1.09 (**) Empaquetar duplicados consecutivos de una lista de elementos dentro de sublistas. Si una lista contiene elementos repetidos, deben ser reemplazados en sublistas separadas. Ejemplo: ?- pack([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X). X = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]] 1.10 (*) Llevar la cuenta de los elementos repetidos en una lista. Use el resultado del problema 1.09 para implementar el llevar la cuenta de los elementos repetidos en una lista, como método de compression de datos. Los duplicados consecutivos son contados como términos [N,E] donde N es el número de duplicados del elemento E. Ejemplo: ?- encode([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X). X = [[4,a],[1,b],[2,c],[2,a],[1,d][4,e]] 1.11 (*) Llevar la cuenta de los elementos repetidos, menos los que sean únicos. Modifica el resultado del problema 1.10 de tal manera que si un elemento no tiene duplicados, éste es simplemente copiado en la lista resultado. Solo los elementos con duplicados son transferidos

Page 4: Laboratorio Inteligencia Artificial

Escuela Prof. De Ingeniería de Sistemas – UNSA- M.Sc. Carlo Corrales

4

como terminos [N,E]. Ejemplo: ?- encode_modified([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X). X = [[4,a],b,[2,c],[2,a],d,[4,e]] 1.12 (**) Decodificar el llevar la cuenta de elementos repetidos. Dado el algoritmo de llevar la cuenta, generado en el problema 1.11, Construye su version descomprimida. 1.13 (**) Ejecutar el llevar la cuenta de elementos repetidos de una lista (solución directa) Implementa la compresion de datos de llevar cuenta de elementos repetidos directamente. Es decir, no crear explicitamente las sublistas conteniendo los duplicados, como en el problema 1.09, sino solo contarlos. Como en el problema 1.11, simplifica la lista resultado reemplazando los terminus simples [1,X] por X. Ejemplo: ?- encode_direct([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X). X = [[4,a],b,[2,c],[2,a],d,[4,e]] 1.14 (*) Duplicar elementos de una lista. Ejemplo: ?- dupli([a,b,c,c,d],X). X = [a,a,b,b,c,c,c,c,d,d] 1.15 (**) Duplicar los elementos de una lista un nro determinado de veces. Ejemplo: ?- dupli([a,b,c],3,X). X = [a,a,a,b,b,b,c,c,c] Cual es el resultado de la meta?: ?- dupli(X,3,Y). 1.16 (**) Elimina cada N-esimo elemento de la lista. Ejemplo: ?- drop([a,b,c,d,e,f,g,h,i,k],3,X). X = [a,b,d,e,g,h,k] 1.17 (*) Divide una lista en 2 partes; dada la longitud de la primera parte

Page 5: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 5

5

No uses ningun predicado predefinido. Ejemplo: ?- split([a,b,c,d,e,f,g,h,i,k],3,L1,L2). L1 = [a,b,c] L2 = [d,e,f,g,h,i,k] 1.18 (**) Divide un trozo de una lista. Dados 2 indices, I y K, la division es la lista que contiene los elementos entre el i-esimo y el k-esimo elemento de la lista original (ambos límites incluidos). Empieza a contra los elementos en 1. Ejemplo: ?- slice([a,b,c,d,e,f,g,h,i,k],3,7,L). L = [c,d,e,f,g] 1.19 (**) Rota una lista N lugares a la izquierda. Ejemplos: ?- rotate([a,b,c,d,e,f,g,h],3,X). X = [d,e,f,g,h,a,b,c] ?- rotate([a,b,c,d,e,f,g,h],-2,X). X = [g,h,a,b,c,d,e,f] Tip: Usa el predicado predefinido length y append, asi como el resultado del problema 1.17. 1.20 (*) Elimina el K-esimo elemento de una lista. Ejemplo: ?- remove_at(X,[a,b,c,d],2,R). X = b R = [a,c,d] 1.21 (*) Inserta un elemento en una posicion dada dentro de una lista. Ejemplo: ?- insert_at(alfa,[a,b,c,d],2,L). L = [a,alfa,b,c,d] 1.22 (*) Crea una lista que contenga todos los nros enteros dentro de un rango. Ejemplo:

Page 6: Laboratorio Inteligencia Artificial

Escuela Prof. De Ingeniería de Sistemas – UNSA- M.Sc. Carlo Corrales

6

?- range(4,9,L). L = [4,5,6,7,8,9] 1.23 (**) Extraer un nro dado de elementos seleccionados al azar de una lista. Los items seleccionados deben ser colocados en la lista resultado. Ejemplo: ?- rnd_select([a,b,c,d,e,f,g,h],3,L). L = [e,d,a] Tip: Use el generador de nros aleatorios random y los resultados del problema 1.20. 1.24 (*) Lotto: Dibuje N diferentes nros aleatorios de un conjunto 1..M. Los nros seleccionados deben ser colocados en la lista resultado. Ejemplo: ?- rnd_select(6,49,L). L = [23,1,17,33,21,37] Tip: Combine las soluciones de los problemas 1.22 y 1.23. 1.25 (*) Genere una permutacion aleatoria de elementos de una lista. Ejemplo: ?- rnd_permu([a,b,c,d,e,f],L). L = [b,a,d,c,e,f] Tip: Use la solucion del problema 1.23. 1.26 (**) Genere las combinaciones de K distintos objectos escogidos de N elementos de una lista. En cuantas formas puede un comité de 3 ser escogido de un grupo de 12 personas? Todos sabemos que hay C(12,3) = 220 posibilidades (C(N,K) denota el conocido coeficiente polinomial). Para los matemáticos este resultado puede ser maravilloso. Pero nosotros queremos generar todas las posibilidades (via backtracking). Ejemplo: ?- combination(3,[a,b,c,d,e,f],L). L = [a,b,c] ; L = [a,b,d] ;

Page 7: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 7

7

L = [a,b,e] ; ... 1.27 (**) Agrupe los elementos de un conjunto en subconjuntos disjuntos. a) En cuantas maneras puede un grupo de 9 trabajar en 3 subgrupos disjuntos de 2, 3 y 4 personas? Escribe un predicado que genere todas las posibilidades via backtracking. Ejemplo: ?- group3([aldo,beat,carla,david,evi,flip,gary,hugo,ida],G1,G2,G3). G1 = [aldo,beat], G2 = [carla,david,evi], G3 = [flip,gary,hugo,ida] ... b) Generalice el predicate de la parte a) de tal forma que podamos especificar una lista de tamaños de grupos y el predicado retorne una lista de grupos. Ejemplo: ?- group([aldo,beat,carla,david,evi,flip,gary,hugo,ida],[2,2,5],Gs). Gs = [[aldo,beat],[carla,david],[evi,flip,gary,hugo,ida]] ... Note que no queremos permutaciones de miembros del grupo; es decir [[aldo,beat],...] es la misma solucion que [[beat,aldo],...]. Sin embargo, hacemos una diferencia entre [[aldo,beat],[carla,david],...] y [[carla,david],[aldo,beat],...]. Encontraras mas sobre problemas combinatorios en un buen libro de matematicas discretas bajo el término “coeficientes multinomiales”. 1.28 (**) Ordenar una lista de listas de acuerdo a la longitud de las sublistas a) Suponemos que una lista (InList) contiene elementos que son tambien listas. El objetivo es ordenar los elementos de InList de acuerdo a su longitud. Por ejemplo, las listas cortas al inicio, las mas largas luego, o vice versa. Ejemplo: ?- lsort([[a,b,c],[d,e],[f,g,h],[d,e],[i,j,k,l],[m,n],[o]],L). L = [[o], [d, e], [d, e], [m, n], [a, b, c], [f, g, h], [i, j, k, l]]

Page 8: Laboratorio Inteligencia Artificial

Escuela Prof. De Ingeniería de Sistemas – UNSA- M.Sc. Carlo Corrales

8

b) Nuevamente, suponemos que una lista (InList) contienen elementos que son tambien listas. Pero esta vez el objetivo es ordenar los elementos de InList de acuerdo a su frecuencia de longitud; es decir, por defecto, donde ordenar es realizado ascendentemente, las listas con longitudes mas escasas son colocados al inicio, otras con longitudes más frecuentes vendras luego. Ejemplo: ?- lfsort([[a,b,c],[d,e],[f,g,h],[d,e],[i,j,k,l],[m,n],[o]],L). L = [[i, j, k, l], [o], [a, b, c], [f, g, h], [d, e], [d, e], [m, n]] Note que en el ejemplo anterior, las primeras 2 listas en el resultado L tienen logitudes de 4 y 1, ambas longitudes aparecen solamente una vez. La 3ra y 4ta listas tienen longitud 3, hay 2 listas de su longitud. Y finalmente las 3 listas tienen longitud 2. Esta es la cantidad de elementos mas frecuentes. Prolog3: Aritmética 2.01 (**) Determinar si un número entero dado es primo. Ejemplo: ?- is_prime(7). Yes 2.02 (**) Determinar los factores primos de un entero positivo dado. Construya una lista plana que contenga los factores primos en órden ascendente. Ejemplo: ?- prime_factors(315, L). L = [3,3,5,7] 2.03 (**) Determinar los factores primos de un entero positivo dado (2). Construya una lista que contenga los factores primos y su multiplicidad. Ejemplo: ?- prime_factors_mult(315, L).

Page 9: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 9

9

L = [[3,2],[5,1],[7,1]] Tip: La solucion del problema 1.10 puede ser de ayuda. 2.04 (*) Una lista de números primos. Dado un rango de enteros por sus límites inferior y superior, construya una lista de todos los números primos en este rango. 2.05 (**) La conjetura de Goldbach. La conjetura de Goldbach dice que cada número positivo par mayor a 2 es la suma de 2 números primos. Ejemplo: 28 = 5 + 23. Es uno de los más Famosos hechos en la teoria de números que no ha podido ser probado en el caso general. Ha sido numéricamente confirmado hasta un número bastante grande (mucho mayor que lo que podemos calcular con el Prolog). Escribir un predicado para allar 2 nros primos que sumen un número entero par dado. Ejemplo: ?- goldbach(28, L). L = [5,23] 2.06 (**) Una lista de las composiciones Goldbach. Dado un rango de enteros por sus límites inferior y superior, imprimir una lista de todos los números pares y su composición Goldbach. Ejemplo: ?- goldbach_list(9,20). 10 = 3 + 7 12 = 5 + 7 14 = 3 + 11 16 = 3 + 13 18 = 5 + 13 20 = 3 + 17 En la mayoría de los casos, si un número par está escrito como la suma de 2 números primos, uno de ellos es bastante pequeño. Raramente los primos son ambos grandes mayores digamos que 50. Trata de hallar cuantos de esos casos hay en el rango de 1..2000. Ejemplo (para un límite de 50): ?- goldbach_list(1,2000,50). 992 = 73 + 919

Page 10: Laboratorio Inteligencia Artificial

Escuela Prof. De Ingeniería de Sistemas – UNSA- M.Sc. Carlo Corrales

10

1382 = 61 + 1321 1856 = 67 + 1789 1928 = 61 + 1867 2.07 (**) Determinar el MCD de 2 enteros positivos. Use el algoritmo de Euclides. Ejemplo: ?- gcd(36, 63, G). G = 9 Defina gcd como una función aritmética; así puedes usarla de esta manera: ?- G is gcd(36,63). G = 9 2.08 (*) Determinar si 2 números enteros positivos son coprimos. Dos números son coprimos si su MCD es 1. Ejemplo: ?- coprime(35, 64). Yes 2.09 (**) Calcular la función totient de Euler phi(m). La función de Euler's es definida como el número de enteros positivos r (1 <= r < m) que son coprimos con m. Ejemplo: m = 10: r = 1,3,7,9; así phi(m) = 4. Note el caso especial: phi(1) = 1. ?- Phi is totient_phi(10). Phi = 4 Descubra cual es el valor de phi(m) si m es un número primo. La función totient de Euler juega un importante rol en uno de los más amplios métodos criptográficos de clave pública (RSA). En este ejercicio debes usar el método más primitivo para calcular esta función. Hay una manera interesante que deberías usar al resolver el problema 2.10. 2.10 (**) Calcula la función totient de Euler phi(m) (2). Mira el problema 2.09 para la definición de la función totient de Euler. Si la lista de factores primos de un número m es conocida en la forma del problema 2.03 entonces la función phi(m) puede ser

Page 11: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 11

11

calculada eficientemente como sigue: Sea [[p1,m1],[p2,m2],[p3,m3],...] la lista de factores primos (y sus multiplicidades) de un número dado m. Entonces phi(m) puede ser calculado con la siguiente fórmula: phi(m) = (p1 - 1) * p1**(m1 - 1) * (p2 - 1) * p2**(m2 - 1) * (p3 - 1) * p3**(m3 - 1) * ... Note que a**b indica a elevado a la potencia de b. 2.11 (*) Compare los 2 metodos de calcular la funcion totient de Euler. Use las soluciones de los problemas 2.09 y 2.10 para comparar los algoritmos. Tome el número de inferencias lógicas como una medida de eficiencia. Trate de calcular phi(10090) como Ejemplo. Prolog4: Lógica y Códigos 3.01 (**) Tablas de Verdad para expresiones lógicas. Definir predicados and/2, or/2, nand/2, nor/2, xor/2, impl/2 y equ/2 (para equivalencias lógicas) los cuales se satisfacen o fallan de acuerdo al resultado de sus respectivas operaciones; por ejemplo and(A,B) será satisfecha, si y solo si ambos A y B se satisfacen. Note que A y B pueden ser metas de Prolog (no solo las constantes true y fail). Una expression lógica en 2 variables puede ser escrito en notación prefija, como en el siguiente ejemplo: and(or(A,B),nand(A,B)). Ahora, escribe un predicado table/3 el cual imprima la tabla de verdad de una expresión lógica dada en 2 variables. Ejemplo: ?- table(A,B,and(A,or(A,B))). true true true true fail true

Page 12: Laboratorio Inteligencia Artificial

Escuela Prof. De Ingeniería de Sistemas – UNSA- M.Sc. Carlo Corrales

12

fail true fail fail fail fail 3.02 (*) Tablas de verdad para expresiones lógicas (2). Continuar con el problema 3.01 definiendo and/2, or/2, etc como operadores. Esto permite escribir las expresiones lógicas en una manera más natural, como en el ejemplo: A and (A or not B). Definir el operador de precedencia como es usual, es decir como es en Java. Ejemplo: ?- table(A,B, A and (A or not B)). true true true true fail true fail true fail fail fail fail 3.03 (**) Tablas de verdad para expresiones lógicas (3). Generalizar el problema 3.02 en tal manera que las expresiones lógicas puedan contener cualquier número de variables lógicas. Definir table/2 de tal manera que table(List,Expr) imprima la tabla de verdad para la expresión Expr, la cual contiene las variables lógicas enumeradas en una Lista. Ejemplo: ?- table([A,B,C], A and (B or C) equ A and B or A and C). true true true true true true fail true true fail true true true fail fail true fail true true true fail true fail true fail fail true true fail fail fail true 3.04 (**) El código Gray. Un código Gray de n-bit es una secuencia de cadenas de n-bits construido de acuerdo a ciertas reglas. Por Ejemplo, n = 1: C(1) = ['0','1']. n = 2: C(2) = ['00','01','11','10']. n = 3: C(3) = ['000','001','011','010','110','111','101','100'].

Page 13: Laboratorio Inteligencia Artificial

LABORATORIO NRO 02 13

13

Descubrir las reglas de construcción y escribir un predicado con las siguientes especificaciones: % gray(N,C) :- C es el código Gray de N-bits Se puede aplicar el método de "result caching" para hacer el predicado más eficiente, cuando se usará repetidamente? 3.05 (***) El Código Huffman. Primero que todo, estudiar un buen libro de matemáticas discretas o algoritmos para una descripción detallada del código Huffman, o consulta Wikipedia Suponemos un conjunto de símbolos con sus frecuencias, dada como una lista de terminos fr(S,F). Ejemplo: [fr(a,45),fr(b,13),fr(c,12),fr(d,16),fr(e,9),fr(f,5)]. Nuestro objetivo es construir una lista de términos hc(S,C), donde C es el Código Huffman para el símbolo S. En nuestro Ejemplo, el resultado puede ser Hs = [hc(a,'0'), hc(b,'101'), hc(c,'100'), hc(d,'111'), hc(e,'1101'), hc(f,'1100')] [hc(a,'01'),...etc.]. La tarea debe ser implementar el predicado huffman/2 definido de la siguiente manera: % huffman(Fs,Hs) :- Hs es la tabla de códigos Huffman para la tabla de frecuencias Fs.