% Examen de "Programación Declarativa" (14 de Febrero de 2003) % Apellidos: % Nombre: %============================================================================== %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Definir la relación divisores_propios(+N,-L) que se verifique si % L es la lista ordenada de los divisores propios del número N. Por ejemplo, % ?- divisores_propios(42,L). % L = [1, 2, 3, 6, 7, 14, 21] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% divisores_propios(N,L) :- N1 is N -1, findall(X,(between(1,N1,X), 0 =:= N mod X),L). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 2: Definir la relación suma_divisores_propios(+N,-S) que se % verifique si S es la suma de los divisores propios del número N. Por ejemplo: % ?- suma_divisores_propios(42,S). % S = 54 % ?- suma_divisores_propios(1,S). % S = 0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% suma_divisores_propios(N,S) :- divisores_propios(N,L), suma_lista(L,S). suma_lista([],0). suma_lista([X|L],S) :- suma_lista(L,S1), S is X + S1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 3: Clasificamos los números naturales en tres tipos: % * N es de tipo a si N es mayor que la suma de sus divisores propios % * N es de tipo b si N es igual que la suma de sus divisores propios % * N es de tipo c si N es menor que la suma de sus divisores propios % Definir la relación tipo(+N,-T) que se verifique si T es el tipo del número % N. Por ejemplo, % ?- tipo(10,T). % T = a % ?- tipo(28,T). % T = b % ?- tipo(12,T). % T = c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tipo(N,T) :- suma_divisores_propios(N,S), tipo_aux(N,S,T). tipo_aux(N,S,a) :- N > S. tipo_aux(N,N,b). tipo_aux(N,S,c) :- N < S. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 4: Definir la relación clasifica(+N,-L) que se verifique si L es la % lista de tipos de los números comprendidos entre 1 y N. Por ejemplo, % ?- clasifica(20,L). % L = [a, a, a, a, a, b, a, a, a, a, a, c, a, a, a, a, a, c, a, c] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clasifica(N,L) :- findall(T,(between(1,N,X),tipo(X,T)),L). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 5: Definir la relación promedio(+N,-A,-B,-C) que se verifique si A, % B y C son las cantidades de números naturales menores o iguales que N de tipo % a, b y c, respectivamente. Por ejemplo: % ?- promedio(20,A,B,C). % A = 16 % B = 1 % C = 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% promedio(N,A,B,C) :- clasifica(N,L), promedio_aux(L,A,B,C). promedio_aux([],0,0,0). promedio_aux([a|L],A1,B,C) :- promedio_aux(L,A,B,C), A1 is A+1. promedio_aux([b|L],A,B1,C) :- promedio_aux(L,A,B,C), B1 is B+1. promedio_aux([c|L],A,B,C1) :- promedio_aux(L,A,B,C), C1 is C+1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 6: Definir la relación menor(+N,-X,-Y,-Z) que se verifique si X es % el menor número tal que la cantidad de números naturales menores o iguales % que X de tipo a es N, de tipo b es Y y de tipo c es Z. Por ejemplo, % ?- menor(20,X,Y,Z). % X = 25 % Y = 1 % Z = 4 % Calcular menor(100,X,Y,Z). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% menor(N,X,Y,Z) :- menor_aux(N,N,X,Y,Z). menor_aux(N,M,M,Y,Z) :- promedio(M,N,Y,Z). menor_aux(N,M,X,Y,Z) :- M1 is M+1, menor_aux(N,M1,X,Y,Z).