Vous êtes sur la page 1sur 7

Paradigmas de Programación.

Año 2006

EJERCICIOS RESUELTOS DE PROLOG


Ejercicio N° 1

Dado el grafo dirigido representado en la siguiente figura:


b c

a d
e

Una representación para el mismo en Prolog podría consistir en una lista que contenga dos sublistas:
una representando el conjunto de nodos (o vértices) y otra representando el conjunto de arcos, donde
cada arco es a su vez una lista de dos elementos, el nodo inicial y el final. Por ejemplo:

(A) [[a b c d e] [[a b] [b c] [b d] [c e] [d a] [d e] [e a]]]

Otra representación válida consiste en una lista de listas, donde cada sublista contiene como elementos
un nodo y una lista de los nodos hacia los cuales éste está conectado, por ejemplo:

(B) [[a [b]] [b [c d]] [c [e]] [d [a e]] [e [a]]]

Note que el elemento [d [a e]] representa la existencia de los arcos [d a] y [d e] en la representación


anterior.

Una tercera representación, basada en la idea de (B), considera que cada sublista contiene el nodo en
primer lugar seguido de la lista de nodos con los cuales está conectado (sin colocar estos dentro de otra
lista), por ejemplo:

(C) [[a b] [b c d] [c e] [d a e] [e a]]

(Note que esta representación es más sencilla que la anterior)

Se le pide que desarrolle predicados que permitan obtener:


a) la representación (A) de un grafo dado en la representación (B) ... y viceversa.
b) la representación (A) de un grafo dado en la representación (C) ... y viceversa.
c) la representación (B) de un grafo dado en la representación (C) ... y viceversa.

Resolución:

La transformación entre la representación (A) y otra tal como (B) no puede definirse con un único
predicado que brinde ambos servicios, por lo cual será necesario definir cada sentido de la consulta en
forma separada.

% Pasar de (A) ---> (B)


pasarAB([Nodos, Arcos], Resultado):-
pasarAB_sublista(Nodos, Arcos, Resultado).

pasarAB_sublista([],_,[]).
pasarAB_sublista([Nodo|Ns], Arcos, [[Nodo, Conectados]|Rs]):-
pasarAB_arcos(Nodo, Arcos, Conectados), pasarAB_sublista(Ns, Arcos, Rs).

Ejercicios Resueltos Prolog 1


Paradigmas de Programación. Año 2006

pasarAB_arcos(_, [], []).


pasarAB_arcos(N1, [[N1,N2]|As], [N2|Ns]):-
pasarAB_arcos(N1, As, Ns).
pasarAB_arcos(N1, [[N2,_]|As], Ns):-
N1 \= N2, pasarAB_arcos(N1, As, Ns).

% Pasar de (A) ---> (C)


pasarAC(GrafoA, GrafoC):-
pasarAB(GrafoA, GrafoB),
pasarBC(GrafoB, GrafoC).

% Pasar de (B) ---> (C)


pasarBC([], []).
pasarBC([[Nodo,Conectados]|Xs], [[Nodo|Conectados]|Ys]):-
pasarBC(Xs, Ys).

% Pasar de (B) ---> (A)


pasarBA(Grafo, [Nodos, Arcos]):-
pasarBA_armar(Grafo, Nodos, Arcos).

pasarBA_armar([], [], []).


pasarBA_armar([[Nodo, Conectados]|Rs], [Nodo|Ns], Arcos):-
pasarBA_arcos(Nodo, Conectados, ArcosNodo),
pasarBA_armar(Rs, Ns, As),
concatenar(ArcosNodo, As, Arcos).

pasarBA_arcos(_N, [], []).


pasarBA_arcos(N, [C|Cs], [[N,C]|Rs]):-
pasarBA_arcos(N, Cs, Rs).

% Pasar de (C) ---> (A)


pasarCA(GrafoC, GrafoA):-
pasarCB(GrafoC, GrafoB),
pasarBA(GrafoB, GrafoA).

% Pasar de (C) ---> (B)


pasarCB(GrafoC, GrafoB):-
pasarBC(GrafoB, GrafoC).

concatenar([], L, L).
concatenar([X|Xs], Y, [X|Zs]):- concatenar(Xs, Y, Zs).

grafoA( [[a,b,c,d,e],[[a,b],[b,c],[b,d],[c,e],[d,a],[d,e],[e,a]]] ).
grafoB( [[a,[b]],[b,[c,d]],[c,[e]],[d,[a,e]],[e,[a]]] ).
grafoC( [[a,b],[b,c,d],[c,e],[d,a,e],[e,a]] ).

Consultas (trabajando siempre con el grafo de la figura)

En general: ? – grafoX( X ), pasarXY( X, Y ).


donde X e Y serán A, B o C, según el caso que se desee probar.

Ejercicios Resueltos Prolog 2


Paradigmas de Programación. Año 2006

Ejemplos:

?– grafoA( A ), pasarAB( A, B ).
A = [[a, b, c, d, e], [[a, b], [b, c], [b, d], [c, e], [d, a], [d, e], [e, a]]]
B = [[a, [b]], [b, [c, d]], [c, [e]], [d, [a, e]], [e, [a]]] ;
No

?– grafoB( B ), pasarBC( B, C ).
B = [[a, [b]], [b, [c, d]], [c, [e]], [d, [a, e]], [e, [a]]]
C = [[a, b], [b, c, d], [c, e], [d, a, e], [e, a]] ;
No

?– grafoC( C ), pasarCA( C, A ).
C = [[a, b], [b, c, d], [c, e], [d, a, e], [e, a]]
A = [[a, b, c, d, e], [[a, b], [b, c], [b, d], [c, e], [d, a], [d, e], [e, a]]] ;
No

Ejercicio N° 2

Realizar un predicado invertir que dada una lista de listas de longitud 2 o mayor, evalúe True si el
segundo argumento es otra lista cuyos elementos están invertidos.

invertir([[a, 1], [a, 2], [b, 1], [b, 2]], [[2, b], [1, b], [2, a], [1, a]]) True

Las listas que deben ser tratadas no se deben limitar a una profundidad de dos niveles de paréntesis. Se
deben considerar listas de cualquier nivel de anidamiento.

Resolución:

concatenar([], L, L).
concatenar([X|Xs], Y, [X|Zs]):- concatenar(Xs, Y, Zs).

invertir([], []).
invertir([X|Y], A):-
atomic(X), invertir(Y, B), concatenar(B, [X], A).
invertir([X|Y], A):-
not(atomic(X)), invertir(X, X1), invertir(Y, B), concatenar(B, [X1], A).

Ejemplos de consultas:

?– invertir([[a, 1], [a, 2], [b, 1], [b, 2]], [[2, b], [1, b], [2, a], [1, a]]).
Yes

?– invertir([[r,o,m,a], [n,e,u,q,u,e,n], [h,o,n,o,l,u,l,u]], X).


X = [[u, l, u, l, o, n, o, h], [n, e, u, q, u, e, n], [a, m, o, r]] ;
No

?– invertir([[a, [b, [c], d, [e, f, [g, h], i, j], [k]], l, m]], X).
X = [[m, l, [[k], [j, i, [h, g], f, e], d, [c], b], a]] ;
No

Ejercicios Resueltos Prolog 3


Paradigmas de Programación. Año 2006

Ejercicio N° 3

Se desea desarrollar un programa Prolog que permita intercalar los elementos de dos listas
considerando longitudes distintas para cada tramo de intercalación. Es decir, para cada lista se indicará
la cantidad de elementos de la misma que se intercalarán sucesivamente para formar la lista resultante,
por ejemplo:

intercala([a1, a2, a3, a4, a5, a6], [b1, b2, b3, b4], 3, 2, [a1, a2, a3, b1, b2, a4, a5, a6, b3, b4]).
True
intercala([a1, a2, a3, a4], [b1, b2], 4, 1, X).
X = [b1, a1, a2, a3, a4, b2]

Debe tenerse en cuenta que cada lista incluya la cantidad de elementos necesaria para ser intercalada
correctamente y que cualquiera de ellas puede intercalar el tramo inicial o el tramo final.

Resolución:

intercala(L1, L2, N1, N2, R):- intercalar_lista(L1, L2, N1, N2, R).
intercala(L1, L2, N1, N2, R):- intercalar_lista(L2, L1, N2, N1, R).

intercalar_lista([], [], _N1, _N2, []).


intercalar_lista(L1, L2, N1, N2, Result):-
concatenar(PreL1, RestoL1, L1),
largo(PreL1, N1),
intercalar_lista(L2, RestoL1, N2, N1, X),
concatenar(PreL1, X, Result).

% las listas deben tener al menos 1 elemento:


largo([_X], 1).
largo([_X|Xs], N):- largo(Xs, N2), N is N2 + 1.

Ejemplos de consultas:

?– intercala([a1, a2, a3, a4, a5, a6], [b1, b2, b3, b4], 3, 2, [a1, a2, a3, b1, b2, a4, a5, a6, b3, b4]).
Yes

?– intercala([a1, a2, a3, a4, a5, a6], [b1, b2, b3, b4], 2, N, X).
N = 2, X = [a1, a2, b1, b2, a3, a4, b3, b4, a5, a6] ;
N = 1, X = [b1, a1, a2, b2, a3, a4, b3, a5, a6, b4] ;
No

?– intercala([a1, a2, a3, a4], [b1, b2], N, 1, X).


N = 2, X = [a1, a2, b1, a3, a4, b2] ;
N = 2, X = [b1, a1, a2, b2, a3, a4] ;
N = 4, X = [b1, a1, a2, a3, a4, b2] ;
No

Ejercicios Resueltos Prolog 4


Paradigmas de Programación. Año 2006

Ejercicio N° 4

Un árbol n-ario es un árbol donde cada nodo puede tener cero o más descendientes. Dado un árbol de
este tipo, cuyas aristas tendrán un costo asociado, se pretende desarrollar un predicado en Prolog que
permita obtener un camino valido desde la raíz hasta un nodo hoja y el costo total asociado al mismo.
Por ejemplo:

a
3 4
2

b c d
3 5

e f

En este árbol el camino desde el nodo raíz ‘a’ hasta el nodo ‘f’ tiene costo 2+5=7.
Para representar el árbol se utilizará la función:
arbol(r, ListaHijos, ListaCostos)
en donde ListaHijos = [h1, h2, ..., hn]
y ListaCostos = [c1, c2, ..., cn], siendo ci el costo asociado a la arista que une r con hi.

Se le solicita que defina el predicado camino(Arbol, Camino, Costo)


Según el ejemplo anterior debe verificarse la siguiente consulta:

?- camino(arbol(a, [ arbol(b, [], []),


arbol(c, [arbol(e, [], []), arbol(f, [], [])], [3, 5]),
arbol(d, [], []) ],
[ 3, 2, 4 ]), L, C).

L = [a, b], C = 3 ;
L = [a, c, e], C = 3 ;
L = [a, c, f], C = 7 ;
L = [a, d], C = 4 ;
no.

Donde la expresión remarcada representa el árbol dado.


Nota: observe que un nodo hoja tendrá la forma: arbol(N, [], [])

Resolución:

camino(arbol(Raiz, [], []), [Raiz], 0).


camino(arbol(Raiz, Hijos, Costos), [Raiz|L], CostoTotal):-
hijo(Hijos, Costos, Hijo, CostoHijo),
camino(Hijo, L, CostoL),
CostoTotal is CostoHijo + CostoL.

hijo([Hijo|_], [Costo|_], Hijo, Costo).


hijo([_|Hs], [_|Cs], Hijo, Costo):- hijo(Hs, Cs, Hijo, Costo).

Ejercicios Resueltos Prolog 5


Paradigmas de Programación. Año 2006

Ejercicio N° 5

Dos grafos son isomorfos si tienen la misma cantidad de nodos y tipos de relaciones,
independientemente de los valores de nodos.

Por ejemplo:

b d 5 6

a 4
f 3
e 2

c 1

Los dos grafos anteriores son isomorfos, ya que tienen la misma cantidad de nodos y los mismos tipos
de relaciones entre nodos, independientemente de los valores de nodos. La tabla siguiente muestra lo
dicho:

Nodos grafo 1 Relaciones grafo 1 Nodos grafo 2 Relaciones grafo 2


A (a, b) (a, e) 1 (1,2) (1, 5)
B (b, a) 2 (2,1)
C (c, f) 3 (3, 6)
D (d, e) (d ,f) 4 (4, 5) (4, 6)
E (e, a) (e, d) 5 (5, 1) (5, 4)
F (f, d) (f, c) 6 (6, 4) (6, 3)

Se le solicita que defina el predicado nodosIsomorfos(Grafo1, Grafo2, ListaParesNodos), en donde


Grafo1 y Grafo2 son dos grafos isomorfos, y ListaParesNodos es la lista de pares de nodos
equivalentes entre ambos grafos.

La representación para los grafos deberá ser por medio de una lista de la forma:

[ [nodo-1, nodo-2, .., nodo-n], [arista1, arista2 ,…, aristaN] ]

donde arista es un par : [nodo-x, nodo-y]

Resolución:

nodosIsomorfos([Nodos1, Aristas1], [Nodos2, Aristas2], ListaParesNodos):-


longitud(Nodos1, LongNodos), longitud(Nodos2, LongNodos),
longitud(Aristas1, LongAristas), longitud(Aristas2, LongAristas),
permutacion(Nodos2, P),
mapeo(Nodos1, P, ListaParesNodos),
reemplazar(Aristas1, ListaParesNodos, AristasP),
conjuntosIguales(AristasP, Aristas2).

permutacion([], []).
permutacion(Xs,[Z|Zs]):- desarma(Z, Xs, Ys), permutacion(Ys, Zs).
desarma(X, [X|Xs], Xs).
desarma(X, [Y|Ys], [Y|Zs]):- desarma(X, Ys, Zs).

mapeo([], [], []).


mapeo([X|Xs], [Y|Ys], [[X, Y]|R]):- mapeo(Xs, Ys, R).

Ejercicios Resueltos Prolog 6


Paradigmas de Programación. Año 2006

reemplazar([], _ListaPares, []).


reemplazar([[X, Y]|Z], ListaPares, [[R, S]|T]):-
miembro([X, R], ListaPares),
miembro([Y, S], ListaPares),
reemplazar(Z, ListaPares, T).

conjuntosIguales([], []).
conjuntosIguales([X|Xs], Y):-
desarma(X, Y, R),
conjuntosIguales(Xs, R).

miembro(X, [X|_]).
miembro(X, [_|Y]):- miembro(X, Y).

longitud([], 0).
longitud([_|Y], N):- longitud(Y, N2), N is N2 + 1.

Ejemplos de consultas:

?– nodosIsomorfos([[a,b,c], [[a,b],[b,c]]], [[1,2,3],[[2,3],[3,1]]], P).


P = [[a, 2], [b, 3], [c, 1]] ;
No

?– nodosIsomorfos([[a,b,c,d], [[a,b],[b,c],[b,d]]], [[1,2,3,4],[[2,3],[3,1],[3,4]]], P).


P = [[a, 2], [b, 3], [c, 1], [d, 4]] ;
P = [[a, 2], [b, 3], [c, 4], [d, 1]] ;
No

?– nodosIsomorfos([[a,b,c,d,e,f],[[b,a],[a,e],[e,d],[d,f],[f,c]]],
[[1,2,3,4,5,6],[[6,5],[5,4],[4,3],[3,1],[1,2]]], ListaPares).
ListaPares = [[a, 5], [b, 6], [c, 2], [d, 3], [e, 4], [f, 1]] ;
No

Ejercicios Resueltos Prolog 7

Vous aimerez peut-être aussi