% Examen de "Programación Declarativa" (Abril de 2000) % Apellidos: % Nombre: %============================================================================== %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Definir la relación fact_rev(X,N) que reciba como dato de % entrada el número X y devuelva el número N mayor que cero si el factorial de % N es X y devuelva "No" si X no corresponde con el factorial de ningún % número. Por ejemplo, % ?- fact_rev(120,N). % N = 5 % ?- fact_rev(80,N). % No %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% f(1,1). f(N,X) :- N > 1, N1 is N-1, f(N1,X1), X is X1 * N, asserta(f(N,X) :- !). fact_rev(X,N) :- f_aux(X,1,N). f_aux(X,Cand,N) :- f(Cand,N1), N1 < X, C1 is Cand + 1, f_aux(X,C1,N). f_aux(X,N,N) :- f(N,X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 2: Supongamos que A1 y A2 son animales (representados por % átomos). Diremos que el "animal" A3 es un cruce de A1 y A2 si existe un % sufijo propio de A1 que coincide con un prefijo propio de A2 y A3 se obtiene % de A1 y A2 superponiendo la parte común. (Un prefijo o sufijo es propio si no % es el vacío ni el total). Por ejemplo de "tortuga" y "gato" obtenemos % "tortugato". % % Definir la relación combinaciones(L1,L2) que reciba como entrada una lista de % "animales" y devuelva la lista L2 formada por todos los posibles cruces. Por % ejemplo, % ?- combinacion([tortuga,gato,asno,oso],L). % L = [asnoso, gatortuga, gatoso, ososo, tortugasno, tortugato] ; % No %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% combinacion(L1,L2) :- setof(C,combina(L1,C),L2). combina(L,C) :- member(X1,L), member(X2,L), name(X1,N1), name(X2,N2), append([_|_],[Y2|Z2],N1), append([Y2|Z2],[Y3|Z3],N2), append(N1,[Y3|Z3],NC), name(C,NC). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 3: Se dice que dos números X e Y son amigos cuando X es igual a la % suma de los divisores de Y (exceptuando al propio Y) y viceversa. Por % ejemplo, 6 es amigo de sí mismo puesto que los divisores de 6 (exceptuando al % 6) son 1, 2 y 3 y 6=1+2+3. Igualmente 28 es amigo de sí mismo, puesto que % 28=1+2+4+7+14. % % Se pide definir la relación amigos(X,Y) que devuelva dos números amigos % menores de 300. Por ejemplo, % ?- amigos(X,Y). % X=6 % Y=6; % X=28 % Y=28; % X=220 % Y=284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% amigos(X,Y) :- between(1,300,X), between(1,300,Y), divisores(X,Div_x), suma_lista(Div_x,Y), divisores(Y,Div_y), suma_lista(Div_y,X). suma_lista([],0) :-!. suma_lista([X|L],N) :- suma_lista(L,N1), N is X + N1. divisores(X,Lista_divisores) :- X1 is X-1, setof(D,(between(1,X1,D), 0 is X mod D),Lista_divisores).