Programaión Orientada a la Inteligenia Artiial NO se permite NINGÚN material auxiliar NI aluladora Advertenias: Deben responderse en hojas Poner el nombre en todas separadas Curso: 3o Tiempo: 2h. las uestiones de LISP y PROLOG. las hojas. Se valorará espeialmente el estilo, la adeuada dou- mentaión del ódigo, que el examen esté ompensado y que no inluya errores oneptuales importantes. Original. Septiembre 2008 PROBLEMA 1 (lisp). VALORACIÓN 2.50 Dado un árbol dirigido on un oste numério asoiado a ada uno de sus aros, ree una funión Lisp COSTES que alule los ostes para llegar del nodo raíz a ada uno de los nodos del árbol. Por ejemplo: > (ostes '((B E 3) (C D 2) (C A 1) (C B 2))) ((C 0) (A 1) (B 2) (D 2) (E 5)) SOLUCIÓN, por Severino Fernández Galán (defun ostes (arbol) ;; Calula los ostes desde ada nodo de un arbol dirigido hasta el nodo raiz. (let (resultado) (dolist (nodo (nodos arbol) resultado) (setf resultado (ons (list nodo (oste-desde-nodo-raiz nodo arbol)) resultado))))) (defun nodos (arbol) ;; Halla los nodos de un arbol dirigido. (let (resultado) (dolist (aro arbol resultado) (when (not (member (first aro) resultado)) (setf resultado (ons (first aro) resultado))) (when (not (member (seond aro) resultado)) (setf resultado (ons (seond aro) resultado)))))) (defun oste-desde-nodo-raiz (nodo arbol) ;; Calula el oste desde el nodo raiz de un arbol dirigido a un nodo de arbol. ;; Para el alulo se parte del nodo y se asiende haia el nodo raiz. (ond ((eq nodo (nodo-raiz arbol)) 0) (t (+ (oste-aro-entrante nodo arbol) (oste-desde-nodo-raiz (padre nodo arbol) arbol))))) (defun nodo-raiz (arbol) ;; Calula el nodo raiz de un arbol dirigido dado. (dolist (aro arbol) (when (nodo-sin-padre (first aro) arbol) 1 (return (first aro))))) (defun nodo-sin-padre (nodo arbol) ;; Determina si un nodo de un arbol dirigido no tiene padre. (let ((resultado t)) (dolist (aro arbol resultado) (when (eq nodo (seond aro)) (setf resultado nil) (return))))) (defun oste-aro-entrante (nodo arbol) ;; Calula el oste asoiado al aro uyo nodo hijo es el nodo dado en ;; el arbol dirigido dado. (dolist (aro arbol) (when (eq nodo (seond aro)) (return (third aro))))) (defun padre (nodo arbol) ;; Halla el nodo padre de un nodo en el arbol dirigido dado. (when (not (eq nodo (nodo-raiz arbol))) (dolist (aro arbol) (when (eq nodo (seond aro)) (return (first aro)))))) PROBLEMA 2 (lisp). VALORACIÓN 2.50 Dada una lista de n números enteros, ree una funión Lisp que devuelva el k -ésimo entero menor de la lista, on 1 ≤ k ≤ n. Ayúdese para ello de un array unidimensional de longitud k y no utilie ningún omando Lisp para ordenaión. A modo de ejemlo: > (k-esimo-menor 5 '(1 6 3 4 2 5)) 5 > (k-esimo-menor 2 '(4 6 1)) 4 > (k-esimo-menor 3 '(4 2 0)) 4 SOLUCIÓN, por Severino Fernández Galán (defun k-esimo-menor (k lista) ;; Calula el k-esimo menor entero de una lista de enteros. (let ((array (make-array (list k)))) (dolist (entero lista) (introduir-por-orden entero array)) (aref array (1- k)))) 2 (defun introduir-por-orden (entero array &optional (indie 0)) ;; Dado un array que almaena enteros de menor a mayor, atualiza ;; el array on la introduion de un nuevo entero. (ond ((= indie (array-dimension array 0)) ; Entero mayor que los enteros del array nil) ((null (aref array indie)) ; Array todavia no lleno (setf (aref array indie) entero)) ((> (aref array indie) entero) ; Posiion para el entero enontrada (dotimes (i (- (- (array-dimension array 0) indie) 1)) (setf (aref array (1- (- (array-dimension array 0) i))) (aref array (1- (1- (- (array-dimension array 0) i)))))) (setf (aref array indie) entero)) (t ; Siguiente posiion (introduir-por-orden entero array (1+ indie))))) PROBLEMA 3 (prolog). VALORACIÓN 2.00 El siguiente ódigo Prolog ontiene errores. Teniendo en uenta que la nalidad del programa, mediante el prediado nombres/0, onsiste en obtener todos los nombres guardados en el sistema mediante el prediado nombre/1: 1. Enumere los errores justiadamente (0.50 puntos). 2. Esriba el programa orreto (0.25 puntos). 3. Explique el funionamiento y esriba la salida produida por la onsulta ?- nombres., tanto para el programa on errores omo para el programa orreto (0.75 puntos). %%Código on errores repetir :- repetir. repetir. nombre(pedro). nombre(ana). nombre(juan). nombre(lola). nombres :- repetir, nombre(X), write(X), nl, fail. SOLUCIÓN, por Félix Hernández del Olmo 1.- El error fundamental onsiste en utilizar el prediado repetir de la forma implementada, que en todo aso habría que odiar de la siguiente manera: 3 repetir. repetir :- repetir. 2.- Existen varias formas de orregir el programa. Aquí van dos, uno on el prediado repetir y otro sin diho prediado. En todo aso, se podría llegar a onsiderar mejor la segunda, ya que no es dependiente de los nombres inluidos. %%Corregido on "repetir" nombre(pedro). nombre(jose). nombre(juan). nombre(lola). nombres :- repetir, nombre(X),write(X),nl,X=lola. %%Corregido sin "repetir" nombre(pedro). nombre(jose). nombre(juan). nombre(lola). nombres :- nombre(X),write(X),nl,fail. 3.- La salida en el programa on errores es dependiente de la implementaión, ya que es un bule innito. En el programa orregido, en el primero obtendríamos: pedro jose juan lola yes. En el segundo: pedro jose juan lola no. PROBLEMA 4 (prolog). VALORACIÓN 3.00 Represente el árbol binario del dibujo en una estrutura de datos Prolog mediante la utilizaión del prediado arbol_binario(Nodo,RamaIzquierda,RamaDereha) de manera reursiva. Para trabajar on este árbol posteriormente en el programa, lo almaenaremos armando el prediado arbol(<arbol>). en la base de datos Prolog (donde <arbol> no es sino el árbol representado anteriormente). 4 h i a s c b gw t Con lo anterior, se desea reorrer el arbol nodo a nodo dejando onstania del amino seguido en una lista. El reorrido se realizará mediante una búsqueda en amplitud. Para ello, debemos onstruir el prediado amplitud/2. El primer argumento de este prediado debe ser una lista de árboles binarios (representados omo se india en el párrafo anterior). El segundo argumento será una lista onteniendo el amino reorrido. Por ejemplo, ?- arbol(X),amplitud([X℄,[h,i,,a,b,s,w,g,t℄). X=...<arbol>... Yes Se pide, 1. El programa ompleto: prediados arbol/1 y amplitud/2. 2. Compruebe la onsistenia del programa onstruido mediante la traza no exhaustiva del ejemplo anterior. SOLUCIÓN, por Félix Hernández del Olmo %arbol_binario(nodo,rama_izquierda,rama_dereha). arbol(arbol_binario(h,arbol_binario(i,a,b),arbol_binario(,s,arbol_binario(w,g,t)))). %amplitud(ListaArboles,Lista). amplitud([arbol_binario(Nodo,RI,RD)|Arboles℄,[Nodo|Resto℄) :append(Arboles,[RI℄,Arboles1), append(Arboles1,[RD℄,Arboles2), amplitud(Arboles2,Resto). amplitud([A|RestoArbol℄,[A|RestoLista℄) :- atom(A),amplitud(RestoArbol,RestoLista). amplitud([℄,[℄). 5