/*
 * Guia 3 - Ejercicio 1
 *
 * Una subsecuencia monotona creciente es un subconjunto de numeros que 
 * son estrictamente crecientes desde la cabeza hacia la cola (en el 
 * caso de una lista).  Esta definicion no requiere que los numeros sean 
 * adyacentes en la lista.  Por ejemplo, dada la siguiente lista:
 *
 *                 ( 2 4 8 3 100 93 50 55 89 3 1 )
 *
 * las siguientes subsecuencias son crecientes:
 *
 * (2 4 8 100); (2 4 8 50 55); (3 50 55 89); etc.
 *
 * Se le solicita que defina en Prolog un predicado
 *
 *     subsec(+lista_flotantes, ?lista_flotantes)
 *     subsec(Secuencia, Subsec)
 *
 * el cual unifica si Subsec es una subsecuencia monotona creciente en 
 * Secuencia.  Por ejemplo:
 *
 * | ?- subsec([2,4,8,3,100,93,50,55,89,3,1], [3,50,55]).
 * yes
 *
 * | ?- subsec([2,4,8,3,100,93,50,55,89,3,1], [2,4,8,100]).
 * yes
 *
 * | ?- subsec([2,4,8,3,100,93,50,55,89,3,1], [3,4,8,93]).
 * no
 *
 * | ?- subsec([2,4,8,3,100,93,50,55,89,3,1], S).
 * S = [2,4,8,100] ;
 * S = ...
 * ...
 */

/* ------------------------------------------------------
 * preparo las pruebas que voy a hacer sobre el predicado mientras lo 
 * depuro: 
 */

/* secuencia(+lista_flotantes) -- es una secuencia para hacer las 
 * pruebas de subsec/2
 */
secuencia([2,4,8,3,100,93,50,55,89,3,1]).

/* cada subsecuencia que se va a probar y el resultado esperado en cada 
 * caso
 * *** agregar la subsecuencia/1 a la prueba.
 */

prueba_subsec_1([2,4,8,100],  'acerto').
prueba_subsec_2([2,4,8,50,55], 'acerto').
prueba_subsec_3([3,50,55,89], 'acerto').
prueba_subsec_4([3,4,8,93], 'fallo').

prueba_cte(S2, Esperado) :- secuencia(S1), 
	write('prueba 1: subsec('), 
	write(S1), 
	write(', '),
	write(S2),
	write(') -> esperado='),
	write(Esperado),
	write('/real='),
	subsec(S1,S2), !,
	write('acerto'),
	nl.

prueba_cte(_,_) :- write('fallo'), nl.

prueba_1 :- prueba_subsec_1(S, ResultadoEsperado),
	prueba_cte(S, ResultadoEsperado).

prueba_2 :- prueba_subsec_2(S, ResultadoEsperado),
	prueba_cte(S, ResultadoEsperado).

prueba_3 :- prueba_subsec_3(S, ResultadoEsperado),
	prueba_cte(S, ResultadoEsperado).

prueba_4 :- prueba_subsec_4(S, ResultadoEsperado),
	prueba_cte(S, ResultadoEsperado).

prueba_generacion :- 
	secuencia(Sec),
	write('inicio de resultados:'), nl,
	subsec(Sec, Subsec),
	write(Subsec), nl, fail.
prueba_generacion :- write('fin de resultados'), nl.




/* ------------------------------------------------------
 * el predicado solicitado
 */

subsec([X|_], [X]).		/* un elemento de la lista es una */
                        /*   subsecuencia creciente       */

subsec([_|Xs], Y) :-	/* si elimino el primer elemento, */
	subsec(Xs,Y).		/* puedo armar una subsecuencia   */
	                    /* creciente con el resto         */

subsec([X|Xs], [X|Ys]) :-	 /* un elemento estará en la   */
	subsec(Xs,Ys),			 /* subsecuencia ssi es menor  */
	minimo(Ys,Ymin),         /* a todos los que siguen     */
	X < Ymin.

/* ------------------------------------------------------
 * minimo(+lista_numeros, -el_minimo). -- calcula el minimo de 
 *                                        una lista de números
 */
minimo([X], X) :- !.

minimo([X|Xs], X) :-
	minimo(Xs, Y),
	X =< Y.

minimo([X|Xs], Y) :-
	minimo(Xs, Y),
	X > Y.


/* EOF ej-01.pl */
