/* Listes différentielles */

append_dl(A - B, B - C, A - C).

ajouter(X, A-[X|B], A-B).

%oter(X, A-B, A-C) :- A\=B, C = [X | B].

aplatir([], []).
aplatir(X, [X]) :- atomic(X), X \=[].
aplatir([X|S],Y) :- aplatir(X, Y1), aplatir(S, Y2), append(Y1, Y2, Y).

aaplatir(X, Y) :- platir(X, [], Y).
platir([], X, X).
platir(X, A, [X|A]) :- atomic(X), X \=[].
platir([P|S], A, Y) :- platir(S, A, Z), platir(P, Z, Y).


apltir(U,V) :- flatten_dl(U, V-[]).
flatten_dl([], X-X).
flatten_dl(X, [X|T]-T) :- atomic(X), X \=[].
flatten_dl([X|S], Y-Z) :- flatten_dl(X, Y-Y1), flatten_dl(S, Y1-Z).


renverser(X, Y) :- renv_a(X, [], Y).
renv_a([], X, X).
renv_a([P|S], A, Y) :- renv_a(S, [P|A], Y).

rverse(A, B) :- reverse_dl(A, B-[]).
reverse_dl([], X-X).
reverse_dl([X|S], Y-Z) :- reverse_dl(S, Y-[X|Z]).


list_to_dlist([T|Q], DL - Z) :-
	DL\== Z,	% pour ne pas évaluer cette clause si l'appel est fait avec une dlist vide
	DL=[T|QDL],
	list_to_dlist(Q, QDL-Z).
list_to_dlist([], X-X) :-
	var(X).	% pour éviter la création d'un arbre infini au backtrack lors d'un appel dans le sens dlist --> list

	
%	Le test sur le paramètre de la dlist est nécessaire si l'on veut appeler
%	le prédicat dans tous les sens (exclusivité des clauses lorsque le premier
%	argument est une variable

