/* equate
Specialize general polynomial
Alan Bundy 31.3.81 */


/* specialize general polynomial by removing coefficients */
/*--------------------------------------------------------*/

specialize(GenBag,X,SpecBag,Y,NewCoeffs) :-
	degree(GenBag,N), N1 is N-1,
	trace('Trying to specialize polynomial to eliminate %t^%t
term and reduce coefficient of %t^%t to 1\n\n',[X,N1,X,N],0),
	spec(N,N1,GenBag,SpecBag,NewCoeffs),
	gensym(y,Y).


/* specialize bag */

spec(N,N1,[],[],[]) :- !.	% basis

spec(N,N1,[pair(N,C)|GBag],[pair(N,1)|SBag],NCs) :- !,	% leading coeff set to 1
	spec(N,N1,GBag,SBag,NCs).

spec(N,N1,[pair(N1,C)|GBag],SBag,NCs) :- !,		% 2nd term dropped
	spec(N,N1,GBag,SBag,NCs).

spec(N,N1,[pair(M,GC)|GBag],[pair(M,SC)|SBag],[SC|NCs]) :- !,
	gensym(c,SC),					% other terms retained
	spec(N,N1,GBag,SBag,NCs).


/* Degree of Polynomial */

degree([],0) :- !.		% basis

degree([pair(N1,C)|Bag],N) :- !,		% step
	degree(Bag,N2), max(N1,N2,N).


/* maximum of two numbers */

max(N1,N2,N1) :-
	N1 >= N2, !.

max(N1,N2,N2).



/* Equate coefficients of two polynomials */
/*----------------------------------------*/

equate_coeffs(SNF,SUnk,TNF,TUnk,Subst,Eqns) :-
	make_poly(TUnk,TNF,TEqn),
	trace('Formed equation %t\n\n',[TEqn],0),
	subst_mesg(Subst,TEqn,TEqn1),
	trace('Equating coefficients of %t\n\n',[SUnk],0),
	poly_norm(SUnk,TEqn1,TNF1),
	pair_off(SNF,TNF1,Eqns).


/* Form equations by equating coefficients */

pair_off([],[],[]) :- !.		% both empty

pair_off([],TNF,Eqns) :- !,		% SNF empty
	maplist(eq_zero,TNF,Eqns).

pair_off([pair(N,SC)|SNF1], TNF, [SC=TC|Eqns]) :-
	select(pair(N,TC),TNF,TNF1), !,			% pair off
	pair_off(SNF1,TNF1,Eqns).			% recurse

pair_off([pair(N,SC)|SNF], TNF, [SC=0|Eqns]) :- !,	% no pair
	pair_off(SNF,TNF,Eqns).				% recurse

/* set coefficient equal to zero */
eq_zero(pair(N,TC), TC=0).
