%%%************************************************************************
%%% INTELIGENCIA ARTIFICIAL II.                                 CURSO 01-02
%%% EXAMEN PRÁCTICO                                     Árboles de decisión
%%%************************************************************************

%%% Dada la relación:
%% asociado(E, Arbol) :- Arbol es un árbol de decisión asociado a E.

%% Descomentar las siguientes asociaciones de objetos y árboles (o definir
%% otras para hacer pruebas).
%%

%% asociado(e1, ad(si(a1=verdadero),
%% 		   entonces(ad(si(a2=verdadero),
%% 			       entonces(verdadero), si_no(falso))),
%% 		   si_no(ad(si(a3=verdadero),
%% 			    entonces(falso), si_no(verdadero))))).
 
%% asociado(e2, ad(si(a3=falso),
%% 		   entonces(ad(si(a1=verdadero),
%% 			       entonces(verdadero), si_no(falso))),
%% 		   si_no(verdadero))).
 
%% asociado(e3, falso).

%% combinaciones(+E, ?L) :- L es una lista de listas. Cada una de dichas
%%     listas representa a un conjunto de pares de Atributos y Valores que
%%     hacen verdadero el objeto E por su árbol de decisión asociado. En
%%     caso de no existir ninguna combinación que haga verdadero E debe
%%     devolver el símbolo fallo.

%%% SOLUCIÓN:

combinaciones(E, R) :-
	asociado(E, Arbol),
	findall(L, recorre(Arbol, L), R), !.

combinaciones(E, fallo).

%%

recorre(verdadero, []).
recorre(ad(si(T), entonces(A1), si_no(_A2)), [T|L]) :-
	recorre(A1, L).
recorre(ad(si(T), entonces(_A1), si_no(A2)), [OT|L]) :-
	opuesto(T, OT), recorre(A2, L).

opuesto(A=verdadero, A=falso).
opuesto(A=falso, A=verdadero).

%% Otra posibilidad es:

% combinaciones(E, R) :-
% 	asociado(E, Arbol),
% 	recorre(Arbol, L), interpreta(L, R).

% interpreta([], fallo) :- !.
% interpreta([[]], []) :- !.
% interpreta(L, L).

% recorre(falso, []).
% recorre(verdadero, [[]]).
% recorre(ad(si(T), entonces(A1), si_no(A2)), L) :-
% 	recorre(A1, L1), recorre(A2, L2),
% 	opuesto(T, OT),
% 	une_a(L1, T, NL1), une_a(L2, OT, NL2),
% 	append(NL1, NL2, L).

% une_a(L, T, NL) :-
% 	findall([T|X], member(X, L), NL).

% opuesto(A=verdadero, A=falso).
% opuesto(A=falso, A=verdadero).
% 

%%%************************************************************************
%% Ejemplo de sesión:
%%
%% ?- combinaciones(e1, L).
%%
%% L = [[a1=verdadero, a2=verdadero], [a1=falso, a3=falso]] 
%%
%% Yes
%% ?- combinaciones(e2, L).
%%
%% L = [[a3=falso, a1=verdadero], [a3=verdadero]] 
%%
%% Yes
%% ?- combinaciones(e3, L).
%%
%% L = fallo 
%%
%% Yes
%%%************************************************************************
