#
# UnivariatePowerSeries(R);
#
# The univariate power series category over the ring R
#
# Author: Dominik Gruntz 1991
#
UnivariatePowerSeries := proc() local R,P,`?`;

    R := args[1];
    if not hasCategory(R,Ring) then ERROR(`1st argument must be a Ring`) fi;

    if nargs = 2 then P := args[2] else P := newCategory() fi;
    addCategory( P, UnivariatePowerSeries );
    if hasCategory(R,Field) then 
       P := DifferentialField(TranscendentalFunctions(P)) 
    else 
       P := Ring(P) 
    fi;

    env := ['_R' = R, '_P' = P];

    # Definition:
    # ===========
    # Constants:
    defOperation( Variable,        	Name,	P );
    defOperation( CoefficientRing, 	Ring, 	P );

    # Functions:
    defOperation( `^`,	       {[P,Integer]	&-> P,
    				[P,P] 		&-> P,
    				[P,Rational]	&-> P},		P );
    				
    defOperation( `R*`,   	[R,P] 		&-> P, 		P );

    defOperation( order,  	P          	&-> Integer, 	P ); # infinity
    defOperation( Lorder,  	P           	&-> Integer, 	P );
# first nonzero coeff
    defOperation( Series, 	List(R,Integer) &-> P, 	 	P );
    defOperation( Coeff,   	[P,Integer] 	&-> R, 	 	P );

    defOperation( Shift,   	[P,Integer] 	&-> P, 	 	P );
    defOperation( Monomial,        {[]          	&-> P, 
    			  	Integer     	&-> P}, 	P );
    defOperation( Constant,  	R           	&-> P, 	 	P );

    if hasCategory(R, Field) then
       defOperation( `R/`, 		[P,R]	 	&-> P,		P );
    fi;


    # Implementation:
    # ===============
    # Constants:
    P[CoefficientRing] := R;
    P[Variable] 	   := `?`;
    P[Characteristic]  := 0;

    if hasCategory(R, Field) then
       # defOperation( `R/`, [P,R] &-> P, P );
       P[`R/`] := subs(env, proc(s,r);
    		_P[`R*`](_R[Inv](r), s)
    	      end):
    fi;
    
    op(P);
end:

save `UPS.m`;
quit
