/*
 * ej-02-02.pl
 *
 * Escribir un programa que permita obtener la lista de atomos de una 
 * lista dada.  Por ejemplo:
 *
 * | ?- listaAtomos( [1,[[2,a],3],[4]], [1,2,a,3,4] ).
 * true.
 *
 * | ?- listaAtomos( [[[5,s],[p,q]],r,[2]], X ).
 * X = [5,s,p,q,r,2].
 */


atomo(X) :- atom(X).
atomo(X) :- number(X).

listaAtomos([], []).

listaAtomos([X|Xs], [X|Ys]) :-
	atomo(X),
	listaAtomos(Xs, Ys).

listaAtomos([X|Xs], Y) :-
	\+(atomo(X)),
	listaAtomos(X,AtomosX),
	append(AtomosX, Xs, Z),
	listaAtomos(Z, Y).

p1 :-  listaAtomos( [1,[[2,a],3],[4]], [1,2,a,3,4] ).

p2 :- listaAtomos( [[[5,s],[p,q]],r,[2]], X ),
	write(X).


/*
 * atom/1 es un predicado ISO que acierta cuanto el termino que es
 * su argumento es un atomo
 *
 * number(Term) succeeds if Term is currently instantiated
 * to an integer or a floating point number.
 *
 * El predicado append/3 no es ISO, pero es muy popular:
 * append(?list, ?list, ?list)
 * append(List1, List2, List12) succeeds if the concatenation of
 * the list List1 and the list List2 is the list List12.
 * This predicate is re-executable on backtracking (e.g. if List12
 * is instantiated and both List1 and List2 are variable).
 * 
 * \+ Goal succeeds if call(Goal) fails and fails otherwise.
 * This built-in predicate gives negation by failure.
 * (\+)/1 es un predicado ISO
 */
