#
#--> MacaulayExponentVector(x:list(name))
#
# Macaulay exponent vector representation -- integer
# This code defines a mapping from N the non-negative integers to
# monomials in n variables in the total degree ordering.
# This yields fast monomial comparisons, slow multiplication of monomials.
# Author MBM: 1989
#
MacaulayExponentVector := proc(x) local P,n,env; option remember;

	P := ExponentVector(x);
	P[DomainName] := MacaulayExponentVector;
	n := nops(x);


	env := ['D' = P, 'N' = n];

	P[tdeg] := proc(n,m) local k,s,t;
    		if m = 0 or n = 1 then m,0
    		else
			s := 1;
			for k do
	    		t := iquo((n+k)*s,k);
	    		if t > m then RETURN(k,m-s) else s := t fi
			od
    		fi
	    end;

	P[Vect2List] := subs(env, proc(m) option remember;
		[D[itov1](N,D[tdeg](N,m))] end);

	P[itov1] := subs(env, proc(n,t,m) local r;
    		if n = 1 then t else 
			r := D[tdeg](n-1,m); t-r[1],D[itov1](n-1,r) fi
		end);

	P[List2Vect] := subs(env, proc(x) local i,m,n,t; option remember;
		n := nops(x);
		t := convert(x,`+`);
		m := 0;
		for i while t > 0 do
	    	m := m + D[degt](n,t);
	    	t := t - x[i];
	    	n := n - 1
		od;
		m
	end);

	P[degt] := proc(n,t) local k,m;
		# compute binomial(n+t-1,n)
		m := 1;
		for k to t-1 do m := iquo(m*(n+k),k) od;
		m
	end;


	P[0] := 0;
	P[`=`] := `=`;
	P[`<>=`] := proc(a,b) if a = b then 0 elif a < b then -1 else 1 fi end;
	P[Type] := proc(x) type(x,nonnegint) end;
	op(P)
end:

save `Macaulay.m`;
quit
