/* decomp.
Decomposition and recomposition - experimental version for Cardan
Alan Bundy 13.5.81 */

/* Decomposition */
decomp(E-F,L) :- !, decomp(E+($F),L).

decomp(($($E)),L) :- !, decomp(E,L).
decomp($(E+F),L) :- !, decomp(($E)+($F),L).
decomP($(E-F),L) :- !, decomp(($E)+F,L).

decomp(E+(X+Y),L) :- !, decomp(E+X+Y,L).
decomp(E+X+Y,[+,Y|L]) :- !, decomp(E+X,[+|L]).
decomp(E+X,[+,X,E]) :- !.

decomp((X*Y)^($1),L) :- !, decomp(X^($1)*Y^($1),L).
/* decomp(E^2,L) :- !, decomp(E*E,L).
decomp(E^3,L) :- !, decomp(E*E*E,L).
decomp(E^4,L) :- !, decomp(E*E*E*E,L).
*/

decomp(X*(Y*E),L) :- !, decomp(X*Y*E,L).
decomp(E*X*Y,[*,Y|L]) :- !, decomp(E*X,[*|L]).
decomp(E*Y,[*,Y,E]) :- !.

decomp((E&X)&Y,L) :- !, decomp(E&X&Y,L).
decomp(Y&E&X,[&,Y|L]) :- !, decomp(E&X,[&|L]).
decomp(X&E,[&,X,E]) :- !.

decomp((E v X) v Y,L) :- !, decomp(E v X v Y,L).
decomp(Y v E v X,[ v ,Y|L]) :- !, decomp(E v X,[ v |L]).
decomp(X v E,[ v ,X,E]) :- !.


decomp(E,F) :- E=..F, !.


recomp(E,[+,E]) :- !.
recomp(E,[+,[]|L]) :- !,recomp(E,[+|L]).
recomp(E+X,[+,X|L]) :- !, recomp(E,[+|L]).
recomp(0,[+]) :- !.

recomp(E,[*,E]) :- !.
recomp(E*X,[*,X|L]) :- !, recomp(E,[*|L]).
recomp(1,[*]) :- !.

recomp(E,[&,E]) :- !.
recomp(X&E,[&,X|L]) :- !, recomp(E,[&|L]).
recomp(true,[&]) :- !.

recomp(E,[ v ,E]) :- !.
recomp(X v E,[ v ,X|L]) :- !, recomp(E,[ v |L]).
recomp(false,[ v ]) :- !.


recomp(E,F) :- E=..F, !.
