/* 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#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,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,[#,E]) :- !.
recomp(X#E,[#,X|L]) :- !, recomp(E,[#|L]).
recomp(false,[#]) :- !.


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