--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

)abbrev category PSCAT PowerSeriesCategory
++ Author: Clifton J. Williamson
++ Date Created: 21 December 1989
++ Date Last Updated: 25 February 1990
++ Basic Operations:
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords: power series
++ Examples:
++ References:
++ Description:
++   \spadtype{PowerSeriesCategory} is the most general power series
++   category with exponents in an ordered abelian monoid.
PowerSeriesCategory(Coef,Expon,Var): Category == Definition where
  Coef  : Ring
  Expon : OrderedAbelianMonoid
  Var   : OrderedSet
  I   ==> Integer
  RN  ==> Fraction Integer

  Definition ==> AbelianMonoidRing(Coef,Expon) with

    monomial: (%,Var,Expon) -> %
      ++ \spad{monomial(a,x,n)} computes \spad{a*x**n}.
    monomial: (%,List Var,List Expon) -> %
      ++ \spad{monomial(a,[x1,..,xk],[n1,..,nk])} computes
      ++ \spad{a * x1**n1 * .. * xk**nk}.
    leadingMonomial: % -> %
      ++ leadingMonomial(f) returns the monomial of \spad{f} of lowest order.
    leadingCoefficient: % -> Coef
      ++ leadingCoefficient(f) returns the coefficient of the lowest order
      ++ term of \spad{f}
    degree : % -> Expon
      ++ degree(f) returns the exponent of the lowest order term of \spad{f}.
    variables: % -> List Var
      ++ \spad{variables(f)} returns a list of the variables occuring in the
      ++ power series f.
    pole?: % -> Boolean
      ++ \spad{pole?(f)} determines if the power series f has a pole.
    complete: % -> %
      ++ \spad{complete(f)} causes all terms of f to be computed.
      ++ Note: this results in an infinite loop
      ++ if f has infinitely many terms.

   add
    n:I    * ps:% == (zero? n => 0; map(n * #1,ps))
    r:Coef * ps:% == (zero? r => 0; map(r * #1,ps))
    ps:% * r:Coef == (zero? r => 0; map(#1 * r,ps))
    - ps          == map(- #1,ps)

    if Coef has Algebra Fraction Integer then
      r:RN * ps:% == (zero? r => 0; map(r * #1,ps))
      ps:% * r:RN == (zero? r => 0; map(#1 * r,ps))

    if Coef has Field then
      ps:% / r:Coef == map(#1 / r,ps)

)abbrev category UPSCAT UnivariatePowerSeriesCategory
++ Author: Clifton J. Williamson
++ Date Created: 21 December 1989
++ Date Last Updated: 20 September 1993
++ Basic Operations:
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords:
++ Examples:
++ References:
++ Description:
++   \spadtype{UnivariatePowerSeriesCategory} is the most general
++   univariate power series category with exponents in an ordered
++   abelian monoid.
++   Note: this category exports a substitution function if it is
++   possible to multiply exponents.
++   Note: this category exports a derivative operation if it is possible
++   to multiply coefficients by exponents.
UnivariatePowerSeriesCategory(Coef,Expon): Category == Definition where
  Coef   : Ring
  Expon  : OrderedAbelianMonoid
  Term ==> Record(k:Expon,c:Coef)

  Definition ==> Join(PowerSeriesCategory(Coef,Expon,SingletonAsOrderedSet),_
                    Eltable(Expon,Coef)) with

    terms: % -> Stream Term
      ++ \spad{terms(f(x))} returns a stream of non-zero terms, where a
      ++ a term is an exponent-coefficient pair.  The terms in the stream
      ++ are ordered by increasing order of exponents.
    --series: Stream Term -> %
      --++ \spad{series(st)} creates a series from a stream of non-zero terms,
      --++ where a term is an exponent-coefficient pair.  The terms in the
      --++ stream should be ordered by increasing order of exponents.
    variable: % -> Symbol
      ++ \spad{variable(f)} returns the (unique) power series variable of
      ++ the power series f.
    center: % -> Coef
      ++ \spad{center(f)} returns the point about which the series f is
      ++ expanded.
    multiplyExponents: (%,PositiveInteger) -> %
      ++ \spad{multiplyExponents(f,n)} multiplies all exponents of the power
      ++ series f by the positive integer n.
    order: % -> Expon
      ++ \spad{order(f)} is the degree of the lowest order non-zero term in f.
      ++ This will result in an infinite loop if f has no non-zero terms.
    order: (%,Expon) -> Expon
      ++ \spad{order(f,n) = min(m,n)}, where m is the degree of the
      ++ lowest order non-zero term in f.
    truncate: (%,Expon) -> %
      ++ \spad{truncate(f,k)} returns a (finite) power series consisting of
      ++ the sum of all terms of f of degree \spad{<= k}.
    truncate: (%,Expon,Expon) -> %
      ++ \spad{truncate(f,k1,k2)} returns a (finite) power
      ++ series consisting of
      ++ the sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
    if Coef has coerce: Symbol -> Coef then
      if Coef has "**":(Coef,Expon) -> Coef then
        approximate: (%,Expon) -> Coef
          ++ \spad{approximate(f)} returns a truncated power series with the
          ++ series variable viewed as an element of the coefficient domain.
    extend: (%,Expon) -> %
      ++ \spad{extend(f,n)} causes all terms of f of degree <= n to be computed.
    if Expon has SemiGroup then Eltable(%,%)
    if Coef has "*": (Expon,Coef) -> Coef then
      DifferentialRing
      --!! DifferentialExtension Coef
      if Coef has PartialDifferentialRing Symbol then
        PartialDifferentialRing Symbol
    if Coef has "**": (Coef,Expon) -> Coef then
      eval: (%,Coef) -> Stream Coef
        ++ \spad{eval(f,a)} evaluates a power series at a value in the
        ++ ground ring by returning a stream of partial sums.

   add
    degree f == order f
    leadingCoefficient f == coefficient(f,order f)
    leadingMonomial f ==
      ord := order f
      monomial(coefficient(f,ord),ord)
    monomial(f:%,listVar:List SingletonAsOrderedSet,listExpon:List Expon) ==
      empty? listVar or not empty? rest listVar =>
        error "monomial: variable list must have exactly one entry"
      empty? listExpon or not empty? rest listExpon =>
        error "monomial: exponent list must have exactly one entry"
      f * monomial(1,first listExpon)
    monomial(f:%,v:SingletonAsOrderedSet,n:Expon) ==
      f * monomial(1,n)
    reductum f == f - leadingMonomial f
    variables f == list create()

)abbrev category UTSCAT UnivariateTaylorSeriesCategory
++ Author: Clifton J. Williamson
++ Date Created: 21 December 1989
++ Date Last Updated: 26 May 1994
++ Basic Operations:
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords: series, Taylor, linebacker
++ Examples:
++ References:
++ Description:
++   \spadtype{UnivariateTaylorSeriesCategory} is the category of Taylor
++   series in one variable.
UnivariateTaylorSeriesCategory(Coef): Category == Definition where
  Coef  : Ring
  I    ==> Integer
  L    ==> List
  NNI  ==> NonNegativeInteger
  OUT  ==> OutputForm
  RN   ==> Fraction Integer
  STTA ==> StreamTaylorSeriesOperations Coef
  STTF ==> StreamTranscendentalFunctions Coef
  STNC ==> StreamTranscendentalFunctionsNonCommutative Coef
  Term ==> Record(k:NNI,c:Coef)

  Definition ==> UnivariatePowerSeriesCategory(Coef,NNI) with

    series: Stream Term -> %
      ++ \spad{series(st)} creates a series from a stream of non-zero terms,
      ++ where a term is an exponent-coefficient pair.  The terms in the
      ++ stream should be ordered by increasing order of exponents.
    coefficients: % -> Stream Coef
      ++ \spad{coefficients(a0 + a1 x + a2 x**2 + ...)} returns a stream
      ++ of coefficients: \spad{[a0,a1,a2,...]}. The entries of the stream
      ++ may be zero.
    series: Stream Coef -> %
      ++ \spad{series([a0,a1,a2,...])} is the Taylor series
      ++ \spad{a0 + a1 x + a2 x**2 + ...}.
    quoByVar: % -> %
      ++ \spad{quoByVar(a0 + a1 x + a2 x**2 + ...)}
      ++ returns \spad{a1 + a2 x + a3 x**2 + ...}
      ++ Thus, this function substracts the constant term and divides by
      ++ the series variable.  This function is used when Laurent series
      ++ are represented by a Taylor series and an order.
    multiplyCoefficients: (I -> Coef,%) -> %
      ++ \spad{multiplyCoefficients(f,sum(n = 0..infinity,a[n] * x**n))}
      ++ returns \spad{sum(n = 0..infinity,f(n) * a[n] * x**n)}.
      ++ This function is used when Laurent series are represented by
      ++ a Taylor series and an order.
    polynomial: (%,NNI) -> Polynomial Coef
      ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
      ++ of all terms of f of degree \spad{<= k}.
    polynomial: (%,NNI,NNI) -> Polynomial Coef
      ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
      ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.

    if Coef has Field then
      **: (%,Coef) -> %
        ++ \spad{f(x) ** a} computes a power of a power series.
        ++ When the coefficient ring is a field, we may raise a series
        ++ to an exponent from the coefficient ring provided that the
        ++ constant coefficient of the series is 1.

    if Coef has Algebra Fraction Integer then
      integrate: % -> %
        ++ \spad{integrate(f(x))} returns an anti-derivative of the power
        ++ series \spad{f(x)} with constant coefficient 0.
        ++ We may integrate a series when we can divide coefficients
        ++ by integers.
      if Coef has integrate: (Coef,Symbol) -> Coef and _
         Coef has variables: Coef -> List Symbol then
        integrate: (%,Symbol) -> %
          ++ \spad{integrate(f(x),y)} returns an anti-derivative of the
          ++ power series \spad{f(x)} with respect to the variable \spad{y}.
      if Coef has TranscendentalFunctionCategory and _
         Coef has PrimitiveFunctionCategory and _
         Coef has AlgebraicallyClosedFunctionSpace Integer then
        integrate: (%,Symbol) -> %
          ++ \spad{integrate(f(x),y)} returns an anti-derivative of
          ++ the power series \spad{f(x)} with respect to the variable
          ++ \spad{y}.
      RadicalCategory
        --++ We provide rational powers when we can divide coefficients
        --++ by integers.
      TranscendentalFunctionCategory
        --++ We provide transcendental functions when we can divide
        --++ coefficients by integers.

   add

    zero? x ==
      empty? (coefs := coefficients x) => true
      (zero? frst coefs) and (empty? rst coefs) => true
      false

--% OutputForms

--  We provide defaulr output functions on UTSCAT using the functions
--  'coefficients', 'center', and 'variable'.

    factorials?: () -> Boolean
    -- check a global Lisp variable
    factorials?() == false

    termOutput: (I,Coef,OUT) -> OUT
    termOutput(k,c,vv) ==
    -- creates a term c * vv ** k
      k = 0 => c :: OUT
      mon := (k = 1 => vv; vv ** (k :: OUT))
--       if factorials?() and k > 1 then
--         c := factorial(k)$IntegerCombinatoricFunctions * c
--         mon := mon / hconcat(k :: OUT,"!" :: OUT)
      c = 1 => mon
      c = -1 => -mon
      (c :: OUT) * mon

    showAll?: () -> Boolean
    -- check a global Lisp variable
    showAll?() == true

    coerce(p:%):OUT ==
      empty? (uu := coefficients p) => (0$Coef) :: OUT
      var := variable p; cen := center p
      vv :=
        zero? cen => var :: OUT
        paren(var :: OUT - cen :: OUT)
      count : NNI := _$streamCount$Lisp
      l : L OUT := empty()
      n : NNI := 0
      while n <= count and not empty? uu repeat
        if frst(uu) ~= 0 then
          l := concat(termOutput(n :: I,frst uu,vv),l)
        uu := rst uu
        n := n + 1
      if showAll?() then
        n := count + 1
        while explicitEntries? uu and _
               not eq?(uu,rst uu) repeat
          if frst(uu) ~= 0 then
            l := concat(termOutput(n :: I,frst uu,vv),l)
          uu := rst uu
          n := n + 1
      l :=
        explicitlyEmpty? uu => l
        eq?(uu,rst uu) and frst uu = 0 => l
        concat(prefix("O" :: OUT,[vv ** (n :: OUT)]),l)
      empty? l => (0$Coef) :: OUT
      reduce("+",reverse! l)

    if Coef has Field then
      (x:%) ** (r:Coef) == series power(r,coefficients x)$STTA

    if Coef has Algebra Fraction Integer then
      if Coef has CommutativeRing then
        (x:%) ** (y:%)    == series(coefficients x **$STTF coefficients y)
        (x:%) ** (r:RN)   == series powern(r,coefficients x)$STTA

        exp x == series exp(coefficients x)$STTF
        log x == series log(coefficients x)$STTF

        sin x == series sin(coefficients x)$STTF
        cos x == series cos(coefficients x)$STTF
        tan x == series tan(coefficients x)$STTF
        cot x == series cot(coefficients x)$STTF
        sec x == series sec(coefficients x)$STTF
        csc x == series csc(coefficients x)$STTF

        asin x == series asin(coefficients x)$STTF
        acos x == series acos(coefficients x)$STTF
        atan x == series atan(coefficients x)$STTF
        acot x == series acot(coefficients x)$STTF
        asec x == series asec(coefficients x)$STTF
        acsc x == series acsc(coefficients x)$STTF

        sinh x == series sinh(coefficients x)$STTF
        cosh x == series cosh(coefficients x)$STTF
        tanh x == series tanh(coefficients x)$STTF
        coth x == series coth(coefficients x)$STTF
        sech x == series sech(coefficients x)$STTF
        csch x == series csch(coefficients x)$STTF

        asinh x == series asinh(coefficients x)$STTF
        acosh x == series acosh(coefficients x)$STTF
        atanh x == series atanh(coefficients x)$STTF
        acoth x == series acoth(coefficients x)$STTF
        asech x == series asech(coefficients x)$STTF
        acsch x == series acsch(coefficients x)$STTF

      else
        (x:%) ** (y:%) == series(coefficients x **$STNC coefficients y)

        (x:%) ** (r:RN) ==
          coefs := coefficients x
          empty? coefs =>
            positive? r => 0
            zero? r => error "0**0 undefined"
            error "0 raised to a negative power"
          not one? frst coefs =>
            error "**: constant coefficient should be 1"
          coefs := concat(0,rst coefs)
          onePlusX := monom(1,0)$STTA + $STTA monom(1,1)$STTA
          ratPow := powern(r,onePlusX)$STTA
          series compose(ratPow,coefs)$STTA

        exp x == series exp(coefficients x)$STNC
        log x == series log(coefficients x)$STNC

        sin x == series sin(coefficients x)$STNC
        cos x == series cos(coefficients x)$STNC
        tan x == series tan(coefficients x)$STNC
        cot x == series cot(coefficients x)$STNC
        sec x == series sec(coefficients x)$STNC
        csc x == series csc(coefficients x)$STNC

        asin x == series asin(coefficients x)$STNC
        acos x == series acos(coefficients x)$STNC
        atan x == series atan(coefficients x)$STNC
        acot x == series acot(coefficients x)$STNC
        asec x == series asec(coefficients x)$STNC
        acsc x == series acsc(coefficients x)$STNC

        sinh x == series sinh(coefficients x)$STNC
        cosh x == series cosh(coefficients x)$STNC
        tanh x == series tanh(coefficients x)$STNC
        coth x == series coth(coefficients x)$STNC
        sech x == series sech(coefficients x)$STNC
        csch x == series csch(coefficients x)$STNC

        asinh x == series asinh(coefficients x)$STNC
        acosh x == series acosh(coefficients x)$STNC
        atanh x == series atanh(coefficients x)$STNC
        acoth x == series acoth(coefficients x)$STNC
        asech x == series asech(coefficients x)$STNC
        acsch x == series acsch(coefficients x)$STNC

)abbrev category ULSCAT UnivariateLaurentSeriesCategory
++ Author: Clifton J. Williamson
++ Date Created: 21 December 1989
++ Date Last Updated: 20 September 1993
++ Basic Operations:
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords: series, Laurent
++ Examples:
++ References:
++ Description:
++   \spadtype{UnivariateLaurentSeriesCategory} is the category of
++   Laurent series in one variable.
UnivariateLaurentSeriesCategory(Coef): Category == Definition where
  Coef  : Ring
  I    ==> Integer
  NNI  ==> NonNegativeInteger
  Term ==> Record(k:I,c:Coef)

  Definition ==> UnivariatePowerSeriesCategory(Coef,Integer) with

    series: Stream Term -> %
      ++ \spad{series(st)} creates a series from a stream of non-zero terms,
      ++ where a term is an exponent-coefficient pair.  The terms in the
      ++ stream should be ordered by increasing order of exponents.
    multiplyCoefficients: (I -> Coef,%) -> %
      ++ \spad{multiplyCoefficients(f,sum(n = n0..infinity,a[n] * x**n)) =
      ++ sum(n = 0..infinity,f(n) * a[n] * x**n)}.
      ++ This function is used when Puiseux series are represented by
      ++ a Laurent series and an exponent.
    if Coef has IntegralDomain then
      rationalFunction: (%,I) -> Fraction Polynomial Coef
        ++ \spad{rationalFunction(f,k)} returns a rational function
        ++ consisting of the sum of all terms of f of degree <= k.
      rationalFunction: (%,I,I) -> Fraction Polynomial Coef
        ++ \spad{rationalFunction(f,k1,k2)} returns a rational function
        ++ consisting of the sum of all terms of f of degree d with
        ++ \spad{k1 <= d <= k2}.

    if Coef has Algebra Fraction Integer then
      integrate: % -> %
        ++ \spad{integrate(f(x))} returns an anti-derivative of the power
        ++ series \spad{f(x)} with constant coefficient 1.
        ++ We may integrate a series when we can divide coefficients
        ++ by integers.
      if Coef has integrate: (Coef,Symbol) -> Coef and _
         Coef has variables: Coef -> List Symbol then
        integrate: (%,Symbol) -> %
          ++ \spad{integrate(f(x),y)} returns an anti-derivative of the power
          ++ series \spad{f(x)} with respect to the variable \spad{y}.
      if Coef has TranscendentalFunctionCategory and _
         Coef has PrimitiveFunctionCategory and _
         Coef has AlgebraicallyClosedFunctionSpace Integer then
        integrate: (%,Symbol) -> %
          ++ \spad{integrate(f(x),y)} returns an anti-derivative of
          ++ the power series \spad{f(x)} with respect to the variable
          ++ \spad{y}.
      RadicalCategory
        --++ We provide rational powers when we can divide coefficients
        --++ by integers.
      TranscendentalFunctionCategory
        --++ We provide transcendental functions when we can divide
        --++ coefficients by integers.
    if Coef has Field then Field
        --++ Univariate Laurent series over a field form a field.
        --++ In fact, K((x)) is the quotient field of K[[x]].

)abbrev category UPXSCAT UnivariatePuiseuxSeriesCategory
++ Author: Clifton J. Williamson
++ Date Created: 21 December 1989
++ Date Last Updated: 20 September 1993
++ Basic Operations:
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords: series, Puiseux
++ Examples:
++ References:
++ Description:
++   \spadtype{UnivariatePuiseuxSeriesCategory} is the category of Puiseux
++   series in one variable.
UnivariatePuiseuxSeriesCategory(Coef): Category == Definition where
  Coef : Ring
  NNI  ==> NonNegativeInteger
  RN   ==> Fraction Integer
  Term ==> Record(k:RN,c:Coef)

  Definition ==> UnivariatePowerSeriesCategory(Coef,RN) with

    series: (NNI,Stream Term) -> %
      ++ \spad{series(n,st)} creates a series from a common denomiator and
      ++ a stream of non-zero terms, where a term is an exponent-coefficient
      ++ pair.  The terms in the stream should be ordered by increasing order
      ++ of exponents and \spad{n} should be a common denominator for the
      ++ exponents in the stream of terms.
    multiplyExponents: (%,Fraction Integer) -> %
      ++ \spad{multiplyExponents(f,r)} multiplies all exponents of the power
      ++ series f by the positive rational number r.

    if Coef has Algebra Fraction Integer then
      integrate: % -> %
        ++ \spad{integrate(f(x))} returns an anti-derivative of the power
        ++ series \spad{f(x)} with constant coefficient 1.
        ++ We may integrate a series when we can divide coefficients
        ++ by rational numbers.
      if Coef has integrate: (Coef,Symbol) -> Coef and _
         Coef has variables: Coef -> List Symbol then
        integrate: (%,Symbol) -> %
          ++ \spad{integrate(f(x),var)} returns an anti-derivative of the power
          ++ series \spad{f(x)} with respect to the variable \spad{var}.
      if Coef has TranscendentalFunctionCategory and _
         Coef has PrimitiveFunctionCategory and _
         Coef has AlgebraicallyClosedFunctionSpace Integer then
        integrate: (%,Symbol) -> %
          ++ \spad{integrate(f(x),y)} returns an anti-derivative of
          ++ the power series \spad{f(x)} with respect to the variable
          ++ \spad{y}.
      RadicalCategory
        --++ We provide rational powers when we can divide coefficients
        --++ by integers.
      TranscendentalFunctionCategory
        --++ We provide transcendental functions when we can divide
        --++ coefficients by integers.
    if Coef has Field then Field
        --++ Univariate Puiseux series over a field form a field.

)abbrev category MTSCAT MultivariateTaylorSeriesCategory
++ Author: Clifton J. Williamson
++ Date Created: 6 March 1990
++ Date Last Updated: 6 March 1990
++ Basic Operations:
++ Related Domains:
++ Also See:
++ AMS Classifications:
++ Keywords: multivariate, Taylor, series
++ Examples:
++ References:
++ Description:
++   \spadtype{MultivariateTaylorSeriesCategory} is the most general
++   multivariate Taylor series category.
MultivariateTaylorSeriesCategory(Coef,Var): Category == Definition where
  Coef  : Ring
  Var   : OrderedSet
  L   ==> List
  NNI ==> NonNegativeInteger

  Definition ==> Join(PartialDifferentialRing Var,_
                     PowerSeriesCategory(Coef,IndexedExponents Var,Var),_
                     InnerEvalable(Var,%),Evalable %) with
    coefficient: (%,Var,NNI) -> %
      ++ \spad{coefficient(f,x,n)} returns the coefficient of \spad{x^n} in f.
    coefficient: (%,L Var,L NNI) -> %
      ++ \spad{coefficient(f,[x1,x2,...,xk],[n1,n2,...,nk])} returns the
      ++ coefficient of \spad{x1^n1 * ... * xk^nk} in f.
    extend: (%,NNI) -> %
      ++ \spad{extend(f,n)} causes all terms of f of degree
      ++ \spad{<= n} to be computed.
    monomial: (%,Var,NNI) -> %
      ++ \spad{monomial(a,x,n)} returns  \spad{a*x^n}.
    monomial: (%,L Var,L NNI) -> %
      ++ \spad{monomial(a,[x1,x2,...,xk],[n1,n2,...,nk])} returns
      ++ \spad{a * x1^n1 * ... * xk^nk}.
    order: (%,Var) -> NNI
      ++ \spad{order(f,x)} returns the order of f viewed as a series in x
      ++ may result in an infinite loop if f has no non-zero terms.
    order: (%,Var,NNI) -> NNI
      ++ \spad{order(f,x,n)} returns \spad{min(n,order(f,x))}.
    polynomial: (%,NNI) -> Polynomial Coef
      ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
      ++ of all terms of f of degree \spad{<= k}.
    polynomial: (%,NNI,NNI) -> Polynomial Coef
      ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
      ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
    if Coef has Algebra Fraction Integer then
      integrate: (%,Var) -> %
        ++ \spad{integrate(f,x)} returns the anti-derivative of the power
        ++ series \spad{f(x)} with respect to the variable x with constant
        ++ coefficient 1.  We may integrate a series when we can divide
        ++ coefficients by integers.
      RadicalCategory
        --++ We provide rational powers when we can divide coefficients
        --++ by integers.
      TranscendentalFunctionCategory
        --++ We provide transcendental functions when we can divide
        --++ coefficients by integers.

