/*
 * ej-05a.pl
 *
 * Dado el grafo dirigido representado por la siguiente figura:
 *
 *
 *       +------> b ----------> c -------+
 *       |        |                      |
 *       |        |                      |
 *       |        |                      |
 *       |        +-> d ----------> e  <-+
 *       |            |             |
 *       |            |             |
 *   +-> a <----------+             |
 *   |                              |
 *   +------------------------------+
 *
 * 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 nodo 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 la 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 éstos
 * 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
 */


grafo_a( [ [a,b,c,d,e], [[a,b],[b,c],[b,d],[c,e],[d,a],[d,e],[e,a]] ] ).
grafo_b( [ [a,[b]], [b,[c,d]], [c,[e]], [d,[a,e]], [e,[a]] ] ).
grafo_c( [ [a,b], [b,c,d], [c,e], [d,a,e], [e,a] ] ).

prueba_a_b :-
	grafo_a(A), grafo_b(B),
	a_b(A,A_transformado),
	write(A), nl, write(A_transformado), nl, write(B).
	
prueba_b_a :-
	grafo_a(A), grafo_b(B),
	a_b(B_transformado,B),
	write(B), nl, write(B_transformado), nl, write(A).
	
prueba_a_c :-
	grafo_a(A), grafo_c(C),
	a_c(A,A_transformado),
	write(A), nl, write(A_transformado), nl, write(C).
	
prueba_c_a :-
	grafo_a(A), grafo_c(C),
	a_c(C_transformado,C),
	write(C), nl, write(C_transformado), nl, write(A).
	
prueba_b_c :-
	grafo_b(B), grafo_c(C),
	b_c(B,B_transformado),
	write(B), nl, write(B_transformado), nl, write(C).
	
prueba_c_b :-
	grafo_b(B), grafo_c(C),
	b_c(C_transformado,C),
	write(C), nl, write(C_transformado), nl, write(B).
	
/* ----------------------------------------------- */
/* Pasar de A <---> C */

a_c(G1, G3) :-
	a_b(G1, G2),
	b_c(G2, G3).

/* ----------------------------------------------- */
/* Pasar de B <---> C */

b_c([], []) :- !.

b_c([X|Xs], [Y|Ys]) :-
	b_c_uno(X,Y),
	b_c(Xs,Ys).

b_c_uno([Nodo|[Conectados]], Resultado) :-
	append([Nodo], Conectados, Resultado).

/* ----------------------------------------------- */
/* Pasar de A ---> B */

a_b([Nodos,Arcos], Resultado) :-
	a_b_aux(Nodos, Arcos, Resultado).



a_b_aux([], _, []).

a_b_aux([N|Ns], Arcos, [R|Rs]) :-
	a_b_uno(N, Arcos, R),
	a_b_aux(Ns, Arcos, Rs).



a_b_uno(N, Arcos, [N|[Conectados]]) :-
	a_b_uno_aux(N, Arcos, Conectados).



a_b_uno_aux(_, [], []).

a_b_uno_aux(N1, [[N1,N2]|As], [N2|Ns] ) :-
	a_b_uno_aux(N1, As, Ns).

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


/* EOF ej-05a.pl */
