#
#--> MapleExponentVector(x:list(name), ordering:{plex,tdeg})
#
# Maple exponent vector representation
# Author MBM: 1992
#
MapleExponentVector := proc(x, ordering) local P,n,env; option remember;

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

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

	P[Vect2List] := subs(env, proc(m) local v;
		[seq( degree(m,v), v=D[Variables])]
	end);

	P[List2Vect] := subs(env, proc(x) local i,v;
		v := D[Variables];
		convert([ seq(v[i]^x[i], i=1..N) ], `*`)
	end);

	P[Output] := x -> x;
	P[Input] := subs(env, proc(t) local c, x;
		c := traperror( lcoeff(t,D[Variables],x) );
		if c = lasterror or t <> x then RETURN(FAIL) fi;
		t
	end);
	P[Type] := subs(env, proc(x)
		type(x,monomial) and lcoeff(x,D[Variables]) = 1
	end);

	P[0] := 1;
	P[`+`] := proc() convert([args],`*`) end;
	P[`=`] := eval(`=`);
	P[Gcd] := gcd;
	P[Lcm] := lcm;

	if nargs=1 or ordering = `tdeg` then
		P[`<>=`] := subs(env, proc(a,b) `Maple/tdeg`(D, a, b) end);
	elif ordering = `plex` then
		P[`<>=`] := subs(env, proc(a,b) `Maple/plex`(D, a, b) end);
	elif ordering = `tdeginv` then
		P[`<>=`] := subs(env, proc(a,b) `Maple/tdeginv`(D, a, b) end);
	else 
		ERROR(`unknown ordering: `,ordering);
	fi;

	P[TotalDegree] := proc(a) degree(a) end;
	P[Degree] := subs(env, proc(a,i)
		if i < 1 or i > N then ERROR(`index out of range`) fi;
		degree(a, D[Variables][i])
	end);
	
	P[Div] := proc(a,b) local q; q := a/b; if denom(q)<>1 then FAIL else q fi end:

	op(P)
end:

`Maple/tdeg` := proc(D, a, b) local N, i,m,n,v;
	m := degree(a); n := degree(b);
	if m < n then RETURN(-1) elif m > n then RETURN(1) fi;
	N := D[Dim]; v := D[Variables];
	for i to N do
	    m := degree(a,v[i]); n := degree(b,v[i]);
	    if m < n then RETURN(-1) elif m > n then RETURN(1) fi;
	od;
	RETURN(0)
end:

`Maple/plex` := proc(D, a, b) local N, i,m,n,v;
	N := D[Dim]; v := D[Variables];
	for i to N do
	    m := degree(a,v[i]); n := degree(b,v[i]);
	    if m < n then RETURN(-1) elif m > n then RETURN(1) fi;
	od;
	RETURN(0)
end:

`Maple/tdeginv` := proc(D, a, b) local N, i, m, n, v;
	m := degree(a); n := degree(b);
	if m < n then RETURN(-1) elif m > n then RETURN(1) fi;
	N := D[Dim]; v := D[Variables];
	for i from N by -1 to 1 do
	    m := degree(a,v[i]); n := degree(b,v[i]);
	    if m < n then RETURN(1) elif m > n then RETURN(-1) fi;
	od;
	RETURN(0)
end:


save `Maple.m`;
quit
