% SELECCION
/*
  Entrada: 
    L: lista de datos 

  Salida
   R: lista ordenada de datos (orden creciente)

  Descripción 
       En cada paso, el elemento mínimo de la parte sin ordenar (parte final) se coloca en la parte ordenada (parte inicial) de la lista.
  
  Ejemplo    

  	Ordenado  | No ordenado 
    	        | 5 1 4 3 2
  	1         | 5 4 3 2
  	1 2       | 5 4 3
  	1 2 3     | 5 4
  	1 2 3 4   | 5
  	1 2 3 4 5 |

*/

% Lista vacía
seleccion([],[]):-!.

% Lista con elementos
seleccion(Lista, [Min|Cola]) :-
  % Se obtiene el mínimo 
	minimo(Lista,Min),
	% Se borra (une vez) el mínimo de la lista
	borrar(Min, Lista, Lista1),
	% Se ordena el resto de la lista
	seleccion(Lista1, Cola).
	% La solución final se construye en el parámetro de salida: [Min|Cola]


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
  Predicado auxiliar: borrar(X,L,R)

  Entrada: 
    X: datos
    L: lista de datos 

  Salida
   R: lista de datos sin la primera aparición de X en L

  Descripción
   Borra el elemento X de una lista: solamente se borra la primera aparición de X

  Ejemplo
   ?- borrar(3,[1,2,3,4,3,1],R).
      R = [1, 2, 4, 3, 1].
*/
% Lista vacía
borrar(_,[],[]):-!.

% El elemento a borrar se encuentra en la cabeza de la lista
borrar(X,[X|Cola],Cola):-!.

% El elemento a borrar no se encuentra en la cabeza de la lista
borrar(X,[Y|Cola1],[Y|Cola2]):- 
  !,
	borrar(X,Cola1,Cola2).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
   Predicado auxiliar: minimo(L,R)

  Entrada: 
    L: lista de datos no vacía

  Salida
    R: mínimo de L

  Descripción
     Obtiene el mínimo de una lista no vacía

  Ejemplo
   ?- minimo([5,4,1,3,2],R).
      R = 1
*/
% Lista con un elemento
minimo([X],X):-!.

% Lista con más de elemento: 
minimo([X|Cola],Minimo) :- 
  % Se obtiene el mínimo de la cola: Y
	minimo(Cola,Y),
	% Se compara Y con el primero elemento X de la lista
  % El símbolo @ también permite comparaciones de datos no numéricos 
	(
			X @=< Y -> Minimo = X;
			true    -> Minimo = Y  
	).