% Soluciones del segundo examen de laboratorio (Diciembre de 2005) % ============================================================================== % Notas: % (1) Se valorá la correción, simplicidad y eficiencia de las soluciones. % (2) Hay que comentar todos los procedimientos auxiliares que se usen que no % sean predefinidos del sistema. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% § Examen 2a %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Definir la relación nombre_y_apellido(?C1,?C2) que se verifique % si C2 es la cadena formada po el nombre y apellidos de C1 (donde está en el % formato de apellidos y nombre separados por coma). Por ejemplo, % ?- nombre_y_apellido('NADIE PRIMERO, JUAN A.',X). % X = 'JUAN A. NADIE PRIMERO' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nombre_y_apellido(C1,C2) :- name(C1,L1), append(Lapellidos,[44,32|Lnombre],L1), append(Lnombre,[32|Lapellidos],L2), name(C2,L2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Definir la relación transforma(+F1,+F2) que se verifique si F2 % es el fichero obtenido a partir del F1 donde las líneas de F1 representan % alumnos mediante términos de la forma % alumno('NADIE PRIMERO, JUAN ANTONIO'). % y las líneas de F2 representa los mismos alumnos con el formato % 1 JUAN ANTONIO NADIE PRIMERO % Por ejemplo, si el contenido de 'lista.pl' es % alumno('NADIE PRIMERO, JUAN ANTONIO'). % alumno('PEREZ GARCIA, ANA'). % como consecuencia de la consulta % ?- transforma('lista.pl','lista.txt'). % Yes % se crea el fichero 'lista.txt' cuyo contenido es % 1 JUAN ANTONIO NADIE PRIMERO % 2 ANA PEREZ GARCIA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% transforma(F1,F2) :- see(F1), tell(F2), procesa(1). procesa(N) :- read(alumno(A1)), nombre_y_apellido(A1,A2), write(N), write(' '), write(A2), nl, N1 is N+1, procesa(N1). procesa(_) :- seen, told. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% § Examen 2b %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Definir la relación átomo_a_lista(+A,-L) que se verifique si L % es la lista de carácteres del átomo A. Por ejemplo, % ?- átomo_a_lista(hola,L). % L = [h, o, l, a] % ?- átomo_a_lista('Buena Suerte',L). % L = ['B', u, e, n, a, ' ', 'S', u, e, r, t, e] % ?- átomo_a_lista('SE 3254 AX',L). % L = ['S', 'E', ' ', 3, 2, 5, 4, ' ', 'A', 'X'] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% átomo_a_lista(A,L) :- name(A,L1), maplist(código_a_carácter,L1,L). código_a_carácter(N,C) :- name(C,[N]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 2: Una matrícula es perfecta si los números que contienen pueden % ordenarse de manera creciente sin huecos ni repeticiones. Por ejemplo, % 'SE 3254 AX' es una matrícula perfecta. Definir la relación % matrícula_perfecta(+M) que se verifique si M es una matrícula perfecta. Por % ejemplo, % ?- matrícula_perfecta('SE 3254 AX'). % Yes % ?- matrícula_perfecta('3254 AXA'). % Yes % ?- matrícula_perfecta('3224 AXA'). % No % ?- matrícula_perfecta('3254 AXA 61'). % Yes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% matrícula_perfecta(M) :- átomo_a_lista(M,L1), findall(X,(member(X,L1), number(X)),L2), length(L2,N), setof(X,(member(X,L1), number(X)),[I|L3]), length([I|L3],N), reverse([I|L3],[F|_]), F is I+N-1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% § Examen 2c %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Las conectivas lógicas son - (negación), & (conjunción), v % (disyunción), => (condicional) y <=> (equivalencia). La precedencia entre las % conectivas es -, &, v, => y <=>. Las conectivas binarias asocian por la % derecha. Por ejemplo, % ?- p & -q v r => s = ((p & -q) v r) => s. % Yes % ?- p & -q v r => s = (p & (-q v r)) => s. % No % ?- p & q & r = p & (q & r). % Yes % ?- p & q & r = (p & q) & r. % No % La declaración de los operadores que representan las conectivas es :- op(610, fy, -). % negación :- op(620, xfy,&). % conjunción :- op(630, xfy,v). % disyunción :- op(640, xfy,=>). % condicional :- op(650, xfy,<=>). % equivalencia % Definir la relación simbolos_formula(+F,?U) que se verifique si U es el % conjunto de los símbolos proposicionales de la fórmula F. Por ejemplo, % ?- simbolos_formula((p v q) & (-q v r), U). % U = [p, q, r] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Primera versión: simbolos_formula_1(F,U) :- simbolos_formula_aux(F,U1), sort(U1,U). simbolos_formula_aux(F,[F]) :- atom(F). simbolos_formula_aux(-F,U) :- simbolos_formula_aux(F,U). simbolos_formula_aux(F,U) :- F =.. [_Op,A,B], simbolos_formula_aux(A,UA), simbolos_formula_aux(B,UB), append(UA,UB,U). % Segunda versión: simbolos_formula_2(F,U) :- setof(A,simbolo_formula(A,F),U). simbolo_formula(F,F) :- atom(F). simbolo_formula(A,F) :- F =.. [_Op|L], member(G,L), simbolo_formula(A,G). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 2: Los valores de verdad se representan por los símbolos 1 % (verdadero) y 0 (falso). valor_de_verdad(0). valor_de_verdad(1). % % Las funciones de verdad se definen mediante la relación % funcion_de_verdad(+Op, +V1, -V) que se verifica si Op(V1)) = V funcion_de_verdad(-, 1, 0). funcion_de_verdad(-, 0, 1). % y la relación funcion_de_verdad(+Op, +V1, +V2, -V) que se verifica si % Op(V1,V2)=V. funcion_de_verdad(v, 0, 0, 0) :- !. funcion_de_verdad(v, _, _, 1). funcion_de_verdad(&, 1, 1, 1) :- !. funcion_de_verdad(&, _, _, 0). funcion_de_verdad(=>, 1, 0, 0) :- !. funcion_de_verdad(=>, _, _, 1). funcion_de_verdad(<=>, X, X, 1) :- !. funcion_de_verdad(<=>, _, _, 0). % % Las interpretaciones son listas de pares formados por un símbolo % proposicional y un valor de verdad. Por ejemplo, [(p,1),(r,0),(u,1)] % representa una interpretación. % % Definir la relación valor(+F, +I, -V) que se verifique si el valor de la % fórmula F en la interpretación I es V. Por ejemplo, % ?- valor((p v q) & (-q v r), [(p,1),(q,0),(r,1)], V). % V = 1 % ?- valor((p v q) & (-q v r), [(p,0),(q,0),(r,1)], V). % V = 0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% valor(F, I, V) :- memberchk((F,V), I). valor(-A, I, V) :- valor(A, I, VA), funcion_de_verdad(-, VA, V). valor(F, I, V) :- F =.. [Op, A, B], valor(A, I, VA), valor(B, I, VB), funcion_de_verdad(Op, VA, VB, V). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% § Examen 2d %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Definir la relación menor(+N,+P,-M) que se verifique si M es el % menor elemento mayor o igual que N que cumple la propiedad P. Por ejemplo, si % se ha definido la relación múltiplo_de_3(X) :- X mod 3 =:= 0. % entonces, % ?- menor(10,múltiplo_de_3,X). % X = 12 ; % No %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% menor(N,P,N) :- apply(P,[N]), !. menor(N,P,M) :- N1 is N+1, menor(N1,P,M), !. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 2: Definir la relación productos(L1,L2,L3) que se verifique si L1 % es una lista de 3 elementos, L2 de dos elementos y L3 de cuatro % elementos; el conjunto de los elementos de las listas L1, L2 y L3 coincide % con el conjunto de las cifras 1, 2, 3, 4, 5, 6, 7, 8 y 9; y el producto del % número cuyas cifras son los elementos de L1 multiplicado por el de L2 da el % representado por L3. Por ejemplo, % ?- productos(L1,L2,L3). % L1 = [1, 3, 8] % L2 = [4, 2] % L3 = [5, 7, 9, 6] ; % L1 = [1, 5, 7] % L2 = [2, 8] % L3 = [4, 3, 9, 6] % Yes % ya que % 138 * 42 = 5796 % 157 * 28 = 4396 % ¿Cuántos productos de este tipo existen? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% productos([A1,A2,A3],[B1,B2],[C1,C2,C3,C4]) :- permutación([1,2,3,4,5,6,7,8,9],[A1,A2,A3,B1,B2,C1,C2,C3,C4]), (100*A1+10*A2+A3) * (10*B1+B2) =:= 1000*C1+100*C2+10*C3+C4. % permutación(+L1,-L2) % se verifica si L2 es una permutación de L1. Por ejemplo, % ?- permutación([a,b,c],L). % L = [a, b, c] ; % L = [a, c, b] ; % L = [b, a, c] ; % L = [b, c, a] ; % L = [c, a, b] ; % L = [c, b, a] ; % No permutación([],[]). permutación(L1,[X|L2]) :- select(X,L1,L3), permutación(L3,L2). % ?- findall(L1-L2-L3,productos(L1,L2,L3),_L), length(_L,N). % N = 7