Pr´
actica N
o5 - Programaci´
on L´
ogica
Para resolver esta pr´actica, recomendamos usar el “SWI-Prolog”, de distribuci´on gratuita, que puede bajarse dehttp://www.swi-prolog.org.
No utilizar cut (!) ni predicados de ‘alto orden’ (comosetof). La ´unica excepci´on es elnot, que est´a per-mitido.
Los ejercicios marcados con el s´ımboloFconstituyen un subconjunto m´ınimo de ejercitaci´on. Sin embargo, aconsejamos fuertemente hacer todos los ejercicios.
Ejercicio 1F
A partir de los predicados binarios padre y esposo y de los predicados unarios hombre y mujer, definir en Prolog los predicados binarios: hijo, abuelo, progenitor, hermano,descendiente, tio. (Aclaraciones: si bien los nombres tienen g´enero masculino, los predicados binarios a definir deben admitir tanto mujeres como hombres. Se asume que no hay hijos extramatrimoniales.)
i. Considerar el ´arbol geneal´ogico de la siguiente figura. Dibuje el ´arbol de b´usqueda de Prolog para la consultaabuelo(Who, ron).
ii. Defina una nueva relaci´onprimo. ¿C´omo se puede definir una consulta para conocer todos los primos de ron?
iii. Considerar el agregado del siguiente hecho y regla: ancestro(X, X).
ancestro(X, Y) :- ancestro(Z, Y), progenitor(X, Z). y el ´arbol geneal´ogico del ´ıtem anterior.
a) Explicar la respuesta a la consultaancestro(bill, X).
b) Describir las circunstancias en las que puede ocurrir un loop infinito en Prolog.
c) Sugerir un soluci´on al problema hallado en los puntos anteriores reescribiendo el programa de ancestro.
Ejercicio 2F
Usando la definici´on de n´umero natural a partir decero ysucesor, definir un predicado unarionatural, tal quenatural(-X) siiXes un n´umero natural. Definir las siguientes relaciones entre n´umeros naturales:
i. moi(-X, +Y) siiXes menor o igual queY.
ii. producto(+X, +Y, -Z)siiZes el producto deXconY. iii. fact(+X, -F) siiFes el factorial deX.
iv. mod(+X, +Y, -Z)siiZes el resto de la divisi´on entrera entreXeY. Dar una definici´on recursiva y una no recursiva.
v. Definir un predicado unario que determine si un n´umero entero dado es primo. Tener en cuenta que el argumento siempre est´a instanciado.
Ejercicio 3
Sea el siguiente programa l´ogico: vecino(X, Y, [X|[Y|Ls]]).
vecino(X, Y, [W|Ls]) :- vecino(X, Y, Ls).
i. Mostrar el ´arbol de derivaci´on en Prolog para resolvervecino(5, Y, [5,6,5,3]), devolviendo todos los valores de Yque hacen que la meta se deduzca l´ogicamente del programa.
ii. Si se invierte el orden de las reglas, ¿los resultados son los mismos? ¿Y el orden de los resultados? Ejercicio 4F
Definir los siguientes predicados:
i. last(-L, -U), donde U es el ´ultimo elemento de la lista L. Definirlo en forma recursiva, y usando el predicado appenddefinido de la siguiente manera:
append([], X, X).
append( [H | T], Y, [H | Z]) :- append(T, Y, Z).
ii. reverse(+L, -L1), dondeL1contiene los mismos elementos queL, pero en orden inverso. Ejemplo:reverse([a,b,c], [c,b,a]).
Realizar una definici´on usandoappend, y otra sin usarlo. Mostrar el ´arbol de prueba para el ejemplo dado. iii. maxlista(+L, -M)yminlista(+L, -M), dondeMes el m´aximo/m´ınimo de la listaL.
iv. palindromo(+L, -L1), donde L1es un pal´ındromo construido a partir deL. Ejemplo:palindromo([a,b,c], [a,b,c,c,b,a]).
v. doble(-L, -L1), donde cada elemento deLaparece dos veces enL1. Ejemplo:doble([a,b,c], [a,a,b,b,c,c]).
vi. prefijo(-P, +L), dondePes prefijo de la listaL. vii. sufijo(-S, +L), dondeSes sufijo de la listaL. viii. sublista(-S, +L), dondeSes sublista deL.
ix. iesimo(-I, +L, -X), dondeXes elI-´esimo elemento de la listaL. Ejemplo:iesimo(2, [10, 20, 30, 40], 20).
Ejercicio 5F
Definir los siguientes predicados:
i. mezcla(L1, L2, L3), dondeL3es el resultado de intercalar uno a uno los elementos de las listasL1yL2. Si una lista tiene longitud menor, entonces el resto de la lista m´as larga es pasado sin cambiar. Verificar la reversibilidad, es decir si es posible obtenerL3a partir deL1yL2, y viceversa.
Ejemplo:mezcla([a,b,c], [d,e], [a,d,b,e,c]).
ii. split(N, L, L1, L2), donde L1tiene los Nprimeros elementos deL, y L2el resto. SiLtiene menos de Nelementos el predicado debe fallar. ¿Cu´an reversible es este predicado? Es decir, ¿qu´e elementos pueden estar indefinidos al momento de la invocaci´on?
iii. borrar(+ListaOriginal, +X, -ListaSinXs), que elimina todas las ocurrencias deXde la lista ListaOriginal.
Ejercicio 6
Considerando los predicadosappend,prefijoysufijoya definidos, realizar el ´arbol de b´usqueda para las siguientes consultas:
i. sufijo([a], L), prefijo(L, [a,b,c]). ii. sufijo([b], L), prefijo(L, [a,b,c]). Ejercicio 7F
Definir el predicadoaplanar(+Xs, -Ys), que es verdadero siiYscontiene los elementos de todos los niveles deXs, en el mismo orden de aparici´on. Los elementos deXsson enteros, ´atomos o nuevamente listas, de modo queXspuede tener una profundidad arbitraria. Por el contrario,Yses una lista de un solo nivel de profundidad.
Ejemplos:
?- aplanar([a, [3, b, []], [2]], [a, 3, b, 2]). ?- aplanar([[1, [2, 3], [a]], [[[]]]], [1, 2, 3, a]). Ejercicio 8
Definir los siguientes predicados:
i. ordenada(+L), que ser´a cierta si los elementos deLest´an ordenados en forma ascendente.
ii. quicksort(+L, -L1), dondeL1es el resultado de ordenarLpor el m´etodo dequicksort, que consiste en dividir aLen 2 sublistas con los menores y mayores al primer elemento, ordenar cada una de ellas y luego proceder a concatenarlas.
iii. inssort(+L, -L1), donde L1 es el resultado de ordenar L por el m´etodo de inserci´on, que consiste en insertar cada elemento en el lugar adecuado del resto de la lista ya ordenada.
Ejercicio 9
Definir un predicado rotar(+L, +N, -R), tal queRsea la lista L rotadaN posiciones (la rotaci´on se debe hacer hacia la derecha siN>0 y hacia la izquierda si N<0).
Ejemplos:
rotar([1, a, 2, b, 3], 3, X)debe dar como respuestaX = [2, b, 3, 1, a] rotar([1, a, 2, b, 3], -3, X)debe dar como respuestaX = [b, 3, 1, a, 2] Ejercicio 10
Definir un predicado que reciba una lista de n´umeros naturales y devuelva otra lista de n´umeros naturales, en la que cada n´umero n de la primera lista aparezca repetido n veces en forma consecutiva, respetando su orden de aparici´on. Considerar que la lista original siempre est´a instanciada.
Ejemplo: para la lista[2, 3, 1, 0, 2]la salida es[2, 2, 3, 3, 3, 1, 2, 2]. Ejercicio 11
Escribir en Prolog un predicado que devuelva la mediana de una lista (la mediana es el elemento que se halla en la posici´on del medio de dicha lista, tras ser ordenada). Utilizar los predicados definidos anteriormente. Considerar que la lista siempre est´a instanciada.
Ejercicio 12F
Escribir en Prolog los siguientes predicados:
pertenece(-X, -L), que es verdadero sii el elementoXse encuentra en la listaL.
interseccion(+X, +Y, -Z), tal queZes la intersecci´on sin repeticiones de las listasXeY, respetando en Zel orden en que aparecen los elementos en X.
Ejercicio 13F
Un ´arbol binario se representar´a en Prolog con: nil, si es vac´ıo.
bin(izq, v, der), dondeves el valor del nodo,izqes el sub´arbol izquierdo yderes el sub´arbol derecho. i. Definir predicados en Prolog para las operaciones comunes de ´arboles: vacio, raiz, altura y
cantidadNodos. Asumir siempre que el ´arbol est´a instanciado.
ii. Se define la profundidad de un nodo como la distancia desde la ra´ız hasta el mismo (la ra´ız tiene pro-fundidad 0). Definir un predicado hppque permita, dado un ´arbol binario instanciado, obtener la lista de todos los valores de las hojas que tengan profundidad par. Puede ocurrir que dos o m´as hojas distintas tengan el mismo valor, pero en la respuesta de hpplos valores no deben repetirse.
Ejemplo:
hpp( bin(bin(nil, 2, nil), 2, bin(bin(nil, 4, nil), 1, nil) ), L). L = [4];
No. Ejercicio 14F
Definir los siguientes predicados, utilizando la representaci´on de ´arbol binario definida en el ejercicio 13: i. aBB(+T), que ser´a verdadero siTes un ´arbol binario de b´usqueda.
ii. aBBInsertar(+X, +T1, -T2), dondeT2resulta de insertarXen orden en el ´arbolT1.
iii. ramas(+AB,-Ramas), que tenga ´exito si AB es un ´arbol binario y Ramas una lista de listas de elementos que representa las ramas del ´arbol (es decir, los caminos desde la ra´ız hacia las hojas).
iv. arbolConRamas(+Ramas,-AB), versi´on inversa del predicado anterior. Ejercicio 15F
Un ´arbol (a secas) de naturales se representar´a en Prolog con: hoja(V), donde V es un natural seg´un la representaci´on de Prolog.
nodo(V, Hijos), donde V es un natural seg´un la representaci´on de Prolog, e Hijos es una lista no vac´ıa de ´arboles de naturales.
Definir el predicadomayores(+Arbol, +Max)que dado un ´arbol de naturales (que podr´ıa contener variables en los nodos) devuelve verdadero si:
Los naturales que contiene el ´arbol son menores o iguales a Max (en caso de ser variables, deber´an instanciarse con valores en dicho rango).
El valor de cada nodo del ´arbol es mayor que la suma de los valores de sus hijos. Ejemplo:
mayores(
nodo(X, [hoja(0), nodo(1,[hoja(0), hoja(0)]), nodo(4,[hoja(1), hoja(0), nodo(1, [hoja(0)])])]),9 )
debe responder: X = 8;
X = 9; No
Ejercicio 16
Definir el predicadocombinador(+L,+D,+H,-XS), que debe dar verdadero cuandoXSes una lista de naturales de longitudL, y cada uno de sus elementosXSicumple queD≤XSi≤H. No se deben devolver soluciones repetidas.
Por ejemplo: combinador(2,3,5,X). X = [3,3] ; X = [3,4] ; X = [3,5] ; X = [4,3] ; X = [4,4] ; X = [4,5] ; X = [5,3] ; X = [5,4] ; X = [5,5] ; Ejercicio 17F
Un cuadrado semi-latino es una matriz cuadrada de naturales (incluido el cero) donde todas las filas de la matriz suman lo mismo. Por ejemplo:
1 3 0
2 2 0 todas las filas suman 4 1 1 2
Representamos la matriz como una lista de filas, donde cada fila es una lista de naturales. El ejemplo anterior se representar´ıa de la siguiente manera:[[1,3,0],[2,2,0],[1,1,2]].
Se pide definir el predicadocuadradoSemiLatino(N,XS). El par´ametroNdebeestar instanciado,no as´ı XS no puede estar instanciado. El predicado debe ir devolviendo matrices (utilizando la representaci´on antes mencionada), que sean cuadrados semi-latinos de dimensi´onN*N. Dichas matrices deben devolverse de manera ordenada: primero aqu´ellas cuyas filas suman 0, luego 1, luego 2, etc..
Ejemplo: cuadradoSemiLatino(2,X).devuelve: X = [[0, 0], [0, 0]] ; X = [[0, 1], [0, 1]] ; X = [[0, 1], [1, 0]] ; X = [[1, 0], [0, 1]] ; X = [[1, 0], [1, 0]] ; X = [[0, 2], [0, 2]] ; etc.
Para la implementaci´on decuadradoSemiLatinose cuenta con el siguiente predicado: desde(+A, -B).
desde(D, D).
desde(D, X) :- DD is D+1, desde(DD, X). Ejercicio 18F
Sea la estructuraCenso, y los siguientes predicados disponibles:
personas(+Censo, -Personas), que tiene ´exito cuando Personas contiene toda la lista de personas registradas por elCenso.
edad(+Censo, +Persona, -Edad), que tiene ´exito cuando la Persona tiene edadEdadseg´un el Censo. Definir el predicadopersonasEnPromedio(+Censo, +Edad, -Conjunto)que tenga ´exito cuandoConjunto sea una lista dePersonasdelCenso, cuyo promedio de edad sea menor aEdad.
Ejercicio 19(opcional) Torres de Hanoi
Se tienen tres estacas A, ByC, y Ndiscos de distintos tama˜nos, perforados en el centro. Los discos pueden apilarse en las estacas formando torres, y est´an ubicados inicialmente en la estaca A en orden decreciente de tama˜no. El problema consiste en mover los discos de A a C de tal manera que terminen ordenados como lo estaban originalmente. La tarea debe efectuarse bajo las siguientes restricciones:
En cada paso s´olo un disco puede moverse de una estaca a otra. Nunca puede ubicarse un disco sobre otro m´as peque˜no.