#
# DenseUnivariatePolynomial(R,x)
#
# A dense univarite polynomial domain R[x] where R is a ring
# Representation is a Maple list of coefficients
#
# Author: MBM 1989
#
DenseUnivariatePolynomial := proc() local x,P,R,env; option remember;

	R := args[1];
	P := UnivariatePolynomial(R);
	if nargs = 2 then x := args[2]; P[Variable] := x fi;
	if nargs = 2 and not type(x,{name,function})
		then ERROR(`2nd argument must be a name or function`) fi;

	P[DomainName] := DenseUnivariatePolynomial;
	env := ['C' = R, 'D' = P];

	# Rep := List of coefficients
	P[Type] := subs(env, proc(a) local x;
		if not type(a,list) or nops(a) = 0 then RETURN(false) fi;
		for x in a do if not C[Type](x) then RETURN(false) fi od;
		true
	    end);

	if hasProperties(R,{UniquelyRepresented,CannonicalForm}) then
		P[`=`] := <evalb(x=y)>;
		addProperties(P,{CannonicalForm,UniquelyRepresented})
	fi;

	P[0] := [R[0]];
	P[1] := [R[1]];
	P[Degree] := proc(x) nops(x) - 1 end;
	P[Ldegree] := subs(env, proc(a) local i;
		for i to nops(a) do if a[i] <> C[0] then RETURN(i-1) fi od;
		0 
	    end);
	P[Lcoeff] := proc(a) a[nops(a)] end;
        P[Tcoeff] := subs(env, proc(a) local i;
                for i to nops(a) do if a[i] <> C[0] then RETURN(a[i]) fi od;
                C[0]
            end);
	P[Coeff] := subs(env, proc(a,i)
		if i+1 > nops(a) then C[0] else a[i+1] fi
	    end);
	P[Polynom] := subs(env, proc(x) local i,k,n;
		n := nops(x); for k from n by -1 to 1 while x[k] = C[0] do od;
		if k=0 then [C[0]] elif k=n then x else [x[1..k]] fi
	    end);
	P[Constant] := proc(c) [c] end;
	P[SetCoeffs] := proc(x) {op(x)} end;
	P[ListCoeffs] := proc(x) x end;
	op(P)

end:

save `DUP.m`;
quit
