diff --git a/books/bookvol10.4.pamphlet b/books/bookvol10.4.pamphlet
index 73f8cfd..b926659 100644
--- a/books/bookvol10.4.pamphlet
+++ b/books/bookvol10.4.pamphlet
@@ -1015,6 +1015,226 @@ AlgebraicIntegration(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ALGMANIP AlgebraicManipulations}
+\pagehead{AlgebraicManipulations}{ALGMANIP}
+\pagepic{ps/v104algebraicmanipulations.ps}{ALGMANIP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ALGMANIP AlgebraicManipulations>>=
+)abbrev package ALGMANIP AlgebraicManipulations
+++ Author: Manuel Bronstein
+++ Date Created: 28 Mar 1988
+++ Date Last Updated: 5 August 1993
+++ Description:
+++ AlgebraicManipulations provides functions to simplify and expand
+++ expressions involving algebraic operators.
+++ Keywords: algebraic, manipulation.
+AlgebraicManipulations(R, F): Exports == Implementation where
+  R : IntegralDomain
+  F : Join(Field, ExpressionSpace) with
+    numer  : $ -> SparseMultivariatePolynomial(R, Kernel $)
+	++ numer(x) \undocumented
+    denom  : $ -> SparseMultivariatePolynomial(R, Kernel $)
+	++ denom(x) \undocumented
+    coerce : SparseMultivariatePolynomial(R, Kernel $) -> $
+	++ coerce(x) \undocumented
+
+  N  ==> NonNegativeInteger
+  Z  ==> Integer
+  OP ==> BasicOperator
+  SY ==> Symbol
+  K  ==> Kernel F
+  P  ==> SparseMultivariatePolynomial(R, K)
+  RF ==> Fraction P
+  REC ==> Record(ker:List K, exponent: List Z)
+  ALGOP ==> "%alg"
+  NTHR  ==> "nthRoot"
+
+  Exports ==> with
+    rootSplit: F -> F
+      ++ rootSplit(f) transforms every radical of the form
+      ++ \spad{(a/b)**(1/n)} appearing in f into \spad{a**(1/n) / b**(1/n)}.
+      ++ This transformation is not in general valid for all
+      ++ complex numbers \spad{a} and b.
+    ratDenom  : F -> F
+      ++ ratDenom(f) rationalizes the denominators appearing in f
+      ++ by moving all the algebraic quantities into the numerators.
+    ratDenom  : (F, F) -> F
+      ++ ratDenom(f, a) removes \spad{a} from the denominators in f
+      ++ if \spad{a} is an algebraic kernel.
+    ratDenom  : (F, List F) -> F
+      ++ ratDenom(f, [a1,...,an]) removes the ai's which are
+      ++ algebraic kernels from the denominators in f.
+    ratDenom  : (F, List K) -> F
+      ++ ratDenom(f, [a1,...,an]) removes the ai's which are
+      ++ algebraic from the denominators in f.
+    ratPoly  : F -> SparseUnivariatePolynomial F
+      ++ ratPoly(f) returns a polynomial p such that p has no
+      ++ algebraic coefficients, and \spad{p(f) = 0}.
+    if R has Join(OrderedSet, GcdDomain, RetractableTo Integer)
+      and F has FunctionSpace(R) then
+        rootPower  : F -> F
+          ++ rootPower(f) transforms every radical power of the form
+          ++ \spad{(a**(1/n))**m} into a simpler form if \spad{m} and
+          ++ \spad{n} have a common factor.
+        rootProduct: F -> F
+          ++ rootProduct(f) combines every product of the form
+          ++ \spad{(a**(1/n))**m * (a**(1/s))**t} into a single power
+          ++ of a root of \spad{a}, and transforms every radical power
+          ++ of the form \spad{(a**(1/n))**m} into a simpler form.
+        rootSimp   : F -> F
+          ++ rootSimp(f) transforms every radical of the form
+          ++ \spad{(a * b**(q*n+r))**(1/n)} appearing in f into
+          ++ \spad{b**q * (a * b**r)**(1/n)}.
+          ++ This transformation is not in general valid for all
+          ++ complex numbers b.
+        rootKerSimp: (OP, F, N) -> F
+          ++ rootKerSimp(op,f,n) should be local but conditional.
+
+  Implementation ==> add
+    import PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,P,F)
+
+    innerRF    : (F, List K) -> F
+    rootExpand : K -> F
+    algkernels : List K -> List K
+    rootkernels: List K -> List K
+
+    dummy := kernel(new()$SY)$K
+
+    ratDenom x                == innerRF(x, algkernels tower x)
+    ratDenom(x:F, l:List K):F == innerRF(x, algkernels l)
+    ratDenom(x:F, y:F)        == ratDenom(x, [y])
+    ratDenom(x:F, l:List F)   == ratDenom(x, [retract(y)@K for y in l]$List(K))
+    algkernels l              == select_!(has?(operator #1, ALGOP), l)
+    rootkernels l             == select_!(is?(operator #1, NTHR::SY), l)
+
+    ratPoly x ==
+      numer univariate(denom(ratDenom inv(dummy::P::F - x))::F, dummy)
+
+    rootSplit x ==
+      lk := rootkernels tower x
+      eval(x, lk, [rootExpand k for k in lk])
+
+    rootExpand k ==
+      x  := first argument k
+      n  := second argument k
+      op := operator k
+      op(numer(x)::F, n) / op(denom(x)::F, n)
+
+-- all the kernels in ll must be algebraic
+    innerRF(x, ll) ==
+      empty?(l := sort_!(#1 > #2, kernels x)$List(K)) or
+        empty? setIntersection(ll, tower x) => x
+      lk := empty()$List(K)
+      while not member?(k := first l, ll) repeat
+        lk := concat(k, lk)
+        empty?(l := rest l) =>
+          return eval(x, lk, [map(innerRF(#1, ll), kk) for kk in lk])
+      q := univariate(eval(x, lk,
+                 [map(innerRF(#1, ll), kk) for kk in lk]), k, minPoly k)
+      map(innerRF(#1, ll), q) (map(innerRF(#1, ll), k))
+
+    if R has Join(OrderedSet, GcdDomain, RetractableTo Integer)
+     and F has FunctionSpace(R) then
+      import PolynomialRoots(IndexedExponents K, K, R, P, F)
+
+      sroot  : K -> F
+      inroot : (OP, F, N) -> F
+      radeval: (P, K) -> F
+      breakup: List K -> List REC
+
+      if R has RadicalCategory then
+        rootKerSimp(op, x, n) ==
+          (r := retractIfCan(x)@Union(R, "failed")) case R =>
+             nthRoot(r::R, n)::F
+          inroot(op, x, n)
+      else
+        rootKerSimp(op, x, n) == inroot(op, x, n)
+
+-- l is a list of nth-roots, returns a list of records of the form
+-- [a**(1/n1),a**(1/n2),...], [n1,n2,...]]
+-- such that the whole list covers l exactly
+      breakup l ==
+        empty? l => empty()
+        k := first l
+        a := first(arg := argument(k := first l))
+        n := retract(second arg)@Z
+        expo := empty()$List(Z)
+        others := same := empty()$List(K)
+        for kk in rest l repeat
+          if (a = first(arg := argument kk)) then
+            same := concat(kk, same)
+            expo := concat(retract(second arg)@Z, expo)
+          else others := concat(kk, others)
+        ll := breakup others
+        concat([concat(k, same), concat(n, expo)], ll)
+
+      rootProduct x ==
+        for rec in breakup rootkernels tower x repeat
+          k0 := first(l := rec.ker)
+          nx := numer x; dx := denom x
+          if empty? rest l then x := radeval(nx, k0) / radeval(dx, k0)
+          else
+            n  := lcm(rec.exponent)
+            k  := kernel(operator k0, [first argument k0, n::F], height k0)$K
+            lv := [monomial(1, k, (n quo m)::N) for m in rec.exponent]$List(P)
+            x  := radeval(eval(nx, l, lv), k) / radeval(eval(dx, l, lv), k)
+        x
+
+      rootPower x ==
+        for k in rootkernels tower x repeat
+          x := radeval(numer x, k) / radeval(denom x, k)
+        x
+
+-- replaces (a**(1/n))**m in p by a power of a simpler radical of a if
+-- n and m have a common factor
+      radeval(p, k) ==
+        a := first(arg := argument k)
+        n := (retract(second arg)@Integer)::NonNegativeInteger
+        ans:F := 0
+        q := univariate(p, k)
+        while (d := degree q) > 0 repeat
+          term :=
+--            one?(g := gcd(d, n)) => monomial(1, k, d)
+            ((g := gcd(d, n)) = 1) => monomial(1, k, d)
+            monomial(1, kernel(operator k, [a,(n quo g)::F], height k), d quo g)
+          ans := ans + leadingCoefficient(q)::F * term::F
+          q := reductum q
+        leadingCoefficient(q)::F + ans
+
+      inroot(op, x, n) ==
+--        one? x => x
+        (x = 1) => x
+--        (x ^= -1) and (one?(num := numer x) or (num = -1)) =>
+        (x ^= -1) and (((num := numer x) = 1) or (num = -1)) =>
+          inv inroot(op, (num * denom x)::F, n)
+        (u := isExpt(x, op)) case "failed" => kernel(op, [x, n::F])
+        pr := u::Record(var:K, exponent:Integer)
+        q := pr.exponent /$Fraction(Z)
+                                (n * retract(second argument(pr.var))@Z)
+        qr := divide(numer q, denom q)
+        x  := first argument(pr.var)
+        x ** qr.quotient * rootKerSimp(op,x,denom(q)::N) ** qr.remainder
+
+      sroot k ==
+        pr := froot(first(arg := argument k),(retract(second arg)@Z)::N)
+        pr.coef * rootKerSimp(operator k, pr.radicand, pr.exponent)
+
+      rootSimp x ==
+        lk := rootkernels tower x
+        eval(x, lk, [sroot k for k in lk])
+
+@
+<<ALGMANIP.dotabb>>=
+"ALGMANIP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ALGMANIP"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"ALGMANIP" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package ALGFACT AlgFactor}
 \pagehead{AlgFactor}{ALGFACT}
 \pagepic{ps/v104algfactor.ps}{ALGFACT}{1.00}
@@ -2807,6 +3027,129 @@ AnyFunctions1(S:Type): with
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ASSOCEQ AssociatedEquations}
+\pagehead{AssociatedEquations}{ASSOCEQ}
+\pagepic{ps/v104associatedequations.ps}{ASSOCEQ}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ASSOCEQ AssociatedEquations>>=
+)abbrev package ASSOCEQ AssociatedEquations
+++ Author: Manuel Bronstein
+++ Date Created: 10 January 1994
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{AssociatedEquations} provides functions to compute the
+++ associated equations needed for factoring operators
+AssociatedEquations(R, L):Exports == Implementation where
+  R: IntegralDomain
+  L: LinearOrdinaryDifferentialOperatorCategory R
+ 
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  MAT ==> Matrix R
+  REC ==> Record(minor: List PI, eq: L, minors: List List PI, ops: List L)
+ 
+  Exports ==> with
+    associatedSystem: (L, PI) -> Record(mat: MAT, vec:Vector List PI)
+      ++ associatedSystem(op, m) returns \spad{[M,w]} such that the
+      ++ m-th associated equation system to L is \spad{w' = M w}.
+    uncouplingMatrices: MAT -> Vector MAT
+      ++ uncouplingMatrices(M) returns \spad{[A_1,...,A_n]} such that if
+      ++ \spad{y = [y_1,...,y_n]} is a solution of \spad{y' = M y}, then
+      ++ \spad{[$y_j',y_j'',...,y_j^{(n)}$] = $A_j y$} for all j's.
+    if R has Field then
+        associatedEquations: (L, PI) -> REC
+          ++ associatedEquations(op, m) returns \spad{[w, eq, lw, lop]}
+          ++ such that \spad{eq(w) = 0} where w is the given minor, and
+          ++ \spad{lw_i = lop_i(w)} for all the other minors.
+ 
+  Implementation ==> add
+    makeMatrix: (Vector MAT, N) -> MAT
+ 
+    diff:L := D()
+ 
+    makeMatrix(v, n) == matrix [parts row(v.i, n) for i in 1..#v]
+ 
+    associatedSystem(op, m) ==
+      eq: Vector R
+      S := SetOfMIntegersInOneToN(m, n := degree(op)::PI)
+      w := enumerate()$S
+      s := size()$S
+      ww:Vector List PI := new(s, empty())
+      M:MAT := new(s, s, 0)
+      m1 := (m::Integer - 1)::PI
+      an := leadingCoefficient op
+      a:Vector(R) := [- (coefficient(op, j) exquo an)::R for j in 0..n - 1]
+      for i in 1..s repeat
+          eq := new(s, 0)
+          wi := w.i
+          ww.i := elements wi
+          for k in 1..m1 repeat
+              u := incrementKthElement(wi, k::PI)$S
+              if u case S then eq(lookup(u::S)) := 1
+          if member?(n, wi) then
+              for j in 1..n | a.j ^= 0 repeat
+                  u := replaceKthElement(wi, m, j::PI)
+                  if u case S then
+                    eq(lookup(u::S)) := (odd? delta(wi, m, j::PI) => -a.j; a.j)
+          else
+              u := incrementKthElement(wi, m)$S
+              if u case S then eq(lookup(u::S)) := 1
+          setRow_!(M, i, eq)
+      [M, ww]
+ 
+    uncouplingMatrices m ==
+      n := nrows m
+      v:Vector MAT := new(n, zero(1, 0)$MAT)
+      v.1 := mi := m
+      for i in 2..n repeat v.i := mi := map(diff #1, mi) + mi * m
+      [makeMatrix(v, i) for i in 1..n]
+ 
+    if R has Field then
+        import PrecomputedAssociatedEquations(R, L)
+ 
+        makeop:    Vector R -> L
+        makeeq:    (Vector List PI, MAT, N, N) -> REC
+        computeIt: (L, PI, N) -> REC
+ 
+        makeeq(v, m, i, n) ==
+          [v.i, makeop row(m, i) - 1, [v.j for j in 1..n | j ^= i],
+                                    [makeop row(m, j) for j in 1..n | j ^= i]]
+ 
+        associatedEquations(op, m) ==
+          (u := firstUncouplingMatrix(op, m)) case "failed" => computeIt(op,m,1)
+          (v := inverse(u::MAT)) case "failed" => computeIt(op, m, 2)
+          S := SetOfMIntegersInOneToN(m, degree(op)::PI)
+          w := enumerate()$S
+          s := size()$S
+          ww:Vector List PI := new(s, empty())
+          for i in 1..s repeat ww.i := elements(w.i)
+          makeeq(ww, v::MAT, 1, s)
+ 
+        computeIt(op, m, k) ==
+          rec := associatedSystem(op, m)
+          a := uncouplingMatrices(rec.mat)
+          n := #a
+          for i in k..n repeat
+            (u := inverse(a.i)) case MAT => return makeeq(rec.vec,u::MAT,i,n)
+          error "associatedEquations: full degenerate case"
+ 
+        makeop v ==
+          op:L := 0
+          for i in 1..#v repeat op := op + monomial(v i, i)
+          op
+
+@
+<<ASSOCEQ.dotabb>>=
+"ASSOCEQ" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ASSOCEQ"]
+"IVECTOR" [color="#88FF44",href="bookvol10.3.pdf#nameddest=IVECTOR"]
+"ASSOCEQ" -> "IVECTOR"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PMPRED AttachPredicates}
 \pagehead{AttachPredicates}{PMPRED}
 \pagepic{ps/v104attachpredicates.ps}{PMPRED}{1.00}
@@ -11031,7 +11374,219 @@ ElementaryFunctionDefiniteIntegration(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package SIGNEF ElementaryFunctionSign}
+\pagehead{ElementaryFunctionSign}{SIGNEF}
+\pagepic{ps/v104elementaryfunctionsign.ps}{SIGNEF}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package SIGNEF ElementaryFunctionSign>>=
+)abbrev package SIGNEF ElementaryFunctionSign
+++ Author: Manuel Bronstein
+++ Date Created: 25 Aug 1989
+++ Date Last Updated: 4 May 1992
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: elementary function, sign
+++ Examples:
+++ References:
+++ Description:
+++   This package provides functions to determine the sign of an
+++   elementary function around a point or infinity.
+ElementaryFunctionSign(R,F): Exports == Implementation where
+  R : Join(IntegralDomain,OrderedSet,RetractableTo Integer,_
+           LinearlyExplicitRingOver Integer,GcdDomain)
+  F : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+            FunctionSpace R)
+
+  N  ==> NonNegativeInteger
+  Z  ==> Integer
+  SY ==> Symbol
+  RF ==> Fraction Polynomial R
+  ORF ==> OrderedCompletion RF
+  OFE ==> OrderedCompletion F
+  K  ==> Kernel F
+  P  ==> SparseMultivariatePolynomial(R, K)
+  U  ==> Union(Z, "failed")
+  FS2 ==> FunctionSpaceFunctions2
+  POSIT ==> "positive"
+  NEGAT ==> "negative"
+
+  Exports ==> with
+    sign: F -> U
+      ++ sign(f) returns the sign of f if it is constant everywhere.
+    sign: (F, SY, OFE) -> U
+      ++ sign(f, x, a) returns the sign of f as x nears \spad{a}, from both
+      ++ sides if \spad{a} is finite.
+    sign: (F, SY, F, String) -> U
+      ++ sign(f, x, a, s) returns the sign of f as x nears \spad{a} from below
+      ++ if s is "left", or above if s is "right".
+
+  Implementation ==> add
+    import ToolsForSign R
+    import RationalFunctionSign(R)
+    import PowerSeriesLimitPackage(R, F)
+    import TrigonometricManipulations(R, F)
+
+    smpsign : P -> U
+    sqfrSign: P -> U
+    termSign: P -> U
+    kerSign : K -> U
+    listSign: (List P,Z) -> U
+    insign  : (F,SY,OFE, N) -> U
+    psign   : (F,SY,F,String, N) -> U
+    ofesign : OFE -> U
+    overRF  : OFE -> Union(ORF, "failed")
+
+    sign(f, x, a) ==
+      not real? f => "failed"
+      insign(f, x, a, 0)
+
+    sign(f, x, a, st) ==
+      not real? f => "failed"
+      psign(f, x, a, st, 0)
+
+    sign f ==
+      not real? f => "failed"
+      (u := retractIfCan(f)@Union(RF,"failed")) case RF => sign(u::RF)
+      (un := smpsign numer f) case Z and (ud := smpsign denom f) case Z =>
+        un::Z * ud::Z
+      --abort if there are any variables
+      not empty? variables f => "failed"
+      -- abort in the presence of algebraic numbers
+      member?(coerce("rootOf")::Symbol,map(name,operators f)$ListFunctions2(BasicOperator,Symbol)) => "failed"
+      -- In the last resort try interval evaluation where feasible.
+      if R has ConvertibleTo Float then
+        import Interval(Float)
+        import Expression(Interval Float)
+        mapfun : (R -> Interval(Float)) := interval(convert(#1)$R)
+        f2 : Expression(Interval Float) := map(mapfun,f)$FS2(R,F,Interval(Float),Expression(Interval Float))
+        r : Union(Interval(Float),"failed") := retractIfCan f2
+        if r case "failed" then  return "failed"
+        negative? r => return(-1)
+        positive? r => return 1
+        zero? r => return 0
+        "failed"
+      "failed"
+
+    overRF a ==
+      (n := whatInfinity a) = 0 =>
+        (u := retractIfCan(retract(a)@F)@Union(RF,"failed")) _
+               case "failed" => "failed"
+        u::RF::ORF
+      n * plusInfinity()$ORF
+
+    ofesign a ==
+      (n := whatInfinity a) ^= 0 => convert(n)@Z
+      sign(retract(a)@F)
+
+    insign(f, x, a, m) ==
+      m > 10 => "failed"                 -- avoid infinite loops for now
+      (uf := retractIfCan(f)@Union(RF,"failed")) case RF and
+                   (ua := overRF a) case ORF => sign(uf::RF, x, ua::ORF)
+      eq : Equation OFE := equation(x :: F :: OFE,a)
+      (u := limit(f,eq)) case "failed" => "failed"
+      u case OFE =>
+        (n := whatInfinity(u::OFE)) ^= 0 => convert(n)@Z
+        (v := retract(u::OFE)@F) = 0 =>
+          (s := insign(differentiate(f, x), x, a, m + 1)) case "failed"
+                                                             => "failed"
+          - s::Z * n
+        sign v
+      (u.leftHandLimit case "failed") or
+         (u.rightHandLimit case "failed") => "failed"
+      (ul := ofesign(u.leftHandLimit::OFE))  case "failed" => "failed"
+      (ur := ofesign(u.rightHandLimit::OFE)) case "failed" => "failed"
+      (ul::Z) = (ur::Z) => ul
+      "failed"
+
+    psign(f, x, a, st, m) ==
+      m > 10 => "failed"                 -- avoid infinite loops for now
+      f = 0 => 0
+      (uf := retractIfCan(f)@Union(RF,"failed")) case RF and
+           (ua := retractIfCan(a)@Union(RF,"failed")) case RF =>
+            sign(uf::RF, x, ua::RF, st)
+      eq : Equation F := equation(x :: F,a)
+      (u := limit(f,eq,st)) case "failed" => "failed"
+      u case OFE =>
+        (n := whatInfinity(u::OFE)) ^= 0 => convert(n)@Z
+        (v := retract(u::OFE)@F) = 0 =>
+          (s := psign(differentiate(f,x),x,a,st,m + 1)) case "failed"=>
+            "failed"
+          direction(st) * s::Z
+        sign v
+
+    smpsign p ==
+      (r := retractIfCan(p)@Union(R,"failed")) case R => sign(r::R)
+      (u := sign(retract(unit(s := squareFree p))@R)) case "failed" =>
+        "failed"
+      ans := u::Z
+      for term in factorList s | odd?(term.xpnt) repeat
+        (u := sqfrSign(term.fctr)) case "failed" => return "failed"
+        ans := ans * u::Z
+      ans
+
+    sqfrSign p ==
+      (u := termSign first(l := monomials p)) case "failed" => "failed"
+      listSign(rest l, u::Z)
+
+    listSign(l, s) ==
+      for term in l repeat
+        (u := termSign term) case "failed" => return "failed"
+        not(s = u::Z) => return "failed"
+      s
+
+    termSign term ==
+      (us := sign leadingCoefficient term) case "failed" => "failed"
+      for var in (lv := variables term) repeat
+        odd? degree(term, var) =>
+          empty? rest lv and (vs := kerSign first lv) case Z =>
+                                                   return(us::Z * vs::Z)
+          return "failed"
+      us::Z
+
+    kerSign k ==
+      has?(op := operator k, "NEGAT") => -1
+      has?(op, "POSIT") or is?(op,  "pi"::SY) or is?(op,"exp"::SY) or
+                           is?(op,"cosh"::SY) or is?(op,"sech"::SY) => 1
+      empty?(arg := argument k) => "failed"
+      (s := sign first arg) case "failed" =>
+        is?(op,"nthRoot" :: SY) =>
+          even?(retract(second arg)@Z) => 1
+          "failed"
+        "failed"
+      is?(op,"log" :: SY) =>
+        s::Z < 0 => "failed"
+        sign(first arg - 1)
+      is?(op,"tanh" :: SY) or is?(op,"sinh" :: SY) or
+                     is?(op,"csch" :: SY) or is?(op,"coth" :: SY) => s
+      is?(op,"nthRoot" :: SY) =>
+        even?(retract(second arg)@Z) =>
+          s::Z < 0 => "failed"
+          s
+        s
+      "failed"
+
+@
+<<SIGNEF.dotabb>>=
+"SIGNEF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=SIGNEF"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"SIGNRF" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package EFSTRUC ElementaryFunctionStructurePackage}
+\pagehead{ElementaryFunctionStructurePackage}{EFSTRUC}
+\pagepic{ps/v104elementaryfunctionstructurepackage.ps}{EFSTRUC}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
 <<package EFSTRUC ElementaryFunctionStructurePackage>>=
 )abbrev package EFSTRUC ElementaryFunctionStructurePackage
 ++ Risch structure theorem
@@ -11426,6 +11981,14 @@ ElementaryFunctionStructurePackage(R,F): Exports == Implementation where
       normalize(f, x) == rtNormalize(rischNormalize(realElementary(f,x),x).func)
 
 @
+<<EFSTRUC.dotabb>>=
+"EFSTRUC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=EFSTRUC"]
+"ACF" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACF"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"EFSTRUC" -> "ACF"
+"EFSTRUC" -> "FS"
+
+@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package EFULS ElementaryFunctionsUnivariateLaurentSeries}
 \pagehead{ElementaryFunctionsUnivariateLaurentSeries}{EFULS}
@@ -15667,6 +16230,64 @@ e04AgentsPackage(): E == I where
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter F}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package FACTFUNC FactoredFunctions}
+\pagehead{FactoredFunctions}{FACTFUNC}
+\pagepic{ps/v104factoredfunctions.ps}{FACTFUNC}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package FACTFUNC FactoredFunctions>>=
+)abbrev package FACTFUNC FactoredFunctions
+++ Author: Manuel Bronstein
+++ Date Created: 2 Feb 1988
+++ Date Last Updated: 25 Jun 1990
+++ Description: computes various functions on factored arguments.
+-- not visible to the user
+FactoredFunctions(M:IntegralDomain): Exports == Implementation where
+  N ==> NonNegativeInteger
+
+  Exports ==> with
+    nthRoot: (Factored M,N) -> Record(exponent:N,coef:M,radicand:List M)
+      ++ nthRoot(f, n) returns \spad{(p, r, [r1,...,rm])} such that
+      ++ the nth-root of f is equal to \spad{r * pth-root(r1 * ... * rm)},
+      ++ where r1,...,rm are distinct factors of f,
+      ++ each of which has an exponent smaller than p in f.
+    log : Factored M -> List Record(coef:N, logand:M)
+      ++ log(f) returns \spad{[(a1,b1),...,(am,bm)]} such that
+      ++ the logarithm of f is equal to \spad{a1*log(b1) + ... + am*log(bm)}.
+
+  Implementation ==> add
+    nthRoot(ff, n) ==
+      coeff:M       := 1
+--      radi:List(M)  := (one? unit ff => empty(); [unit ff])
+      radi:List(M)  := (((unit ff) = 1) => empty(); [unit ff])
+      lf            := factors ff
+      d:N :=
+        empty? radi => gcd(concat(n, [t.exponent::N for t in lf]))::N
+        1
+      n             := n quo d
+      for term in lf repeat
+        qr    := divide(term.exponent::N quo d, n)
+        coeff := coeff * term.factor ** qr.quotient
+        not zero?(qr.remainder) =>
+          radi := concat_!(radi, term.factor ** qr.remainder)
+      [n, coeff, radi]
+
+    log ff ==
+      ans := unit ff
+      concat([1, unit ff],
+             [[term.exponent::N, term.factor] for term in factors ff])
+
+@
+<<FACTFUNC.dotabb>>=
+"FACTFUNC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=FACTFUNC"]
+"ALGEBRA" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ALGEBRA"]
+"FACTFUNC" -> "ALGEBRA"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package FR2 FactoredFunctions2}
 <<FactoredFunctions2.input>>=
 -- fr.spad.pamphlet FactoredFunctions2.input
@@ -27775,6 +28396,2880 @@ GroebnerSolve(lv,F,R) : C == T
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESS Guess}
+The packages defined in this file enable {Axiom} to guess formulas for
+sequences of, for example, rational numbers or rational functions, given the
+first few terms.  It extends and complements Christian Krattenthaler's
+program Rate and the relevant parts of Bruno Salvy and Paul Zimmermann's
+GFUN.
+\pagehead{Guess}{GUESS}
+\pagepic{ps/v104guess.ps}{GUESS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESS Guess>>=
+)abbrev package GUESS Guess
+++ Author: Martin Rubey
+++ Description: This package implements guessing of sequences. Packages for the
+++ most common cases are provided as \spadtype{GuessInteger},
+++ \spadtype{GuessPolynomial}, etc.
+Guess(F, S, EXPRR, R, retract, coerce): Exports == Implementation where
+    F: Field                                 -- zB.: FRAC POLY PF 5
+-- in F we interpolate und check 
+
+    S: GcdDomain
+
+-- in guessExpRat I would like to determine the roots of polynomials in F. When
+-- F is a quotientfield, I can get rid of the denominator.  In this case F is
+-- roughly QFCAT S
+
+    R: Join(OrderedSet, IntegralDomain)      -- zB.: FRAC POLY INT
+
+-- results are given as elements of EXPRR
+--    EXPRR: Join(ExpressionSpace, IntegralDomain,
+    EXPRR: Join(FunctionSpace Integer, IntegralDomain,
+                RetractableTo R, RetractableTo Symbol, 
+                RetractableTo Integer, CombinatorialOpsCategory,
+                PartialDifferentialRing Symbol) with
+              _* : (%,%) -> %
+              _/ : (%,%) -> %
+              _*_* : (%,%) -> %
+              numerator : % -> %
+              denominator : % -> %
+              ground? : % -> Boolean
+
+                                             -- zB.: EXPR INT
+-- EXPR FRAC POLY INT is forbidden. Thus i cannot just use EXPR R
+
+-- EXPRR exists, in case at some point there is support for EXPR PF 5.
+
+
+-- the following I really would like to get rid of
+
+    retract: R -> F                          -- zB.: i+->i
+    coerce: F -> EXPRR                       -- zB.: i+->i
+-- attention: EXPRR ~= EXPR R
+
+    LGOPT ==> List GuessOption
+    GOPT0 ==> GuessOptionFunctions0
+
+    NNI ==> NonNegativeInteger
+    PI ==> PositiveInteger
+    EXPRI ==> Expression Integer
+    GUESSRESULT ==> List Record(function: EXPRR, order: NNI)
+
+    UFPSF ==> UnivariateFormalPowerSeries F
+    UFPS1 ==> UnivariateFormalPowerSeriesFunctions
+
+    UFPSS ==> UnivariateFormalPowerSeries S
+
+    SUP ==> SparseUnivariatePolynomial
+
+    UFPSSUPF ==> UnivariateFormalPowerSeries SUP F
+
+    FFFG ==> FractionFreeFastGaussian
+    FFFGF ==> FractionFreeFastGaussianFractions
+
+-- CoeffAction
+    DIFFSPECA ==> (NNI, NNI, SUP S) -> S
+
+    DIFFSPECAF ==> (NNI, NNI, UFPSSUPF) -> SUP F
+
+    DIFFSPECAX ==> (NNI, Symbol, EXPRR) -> EXPRR
+
+-- the diagonal of the C-matrix
+    DIFFSPECC ==> NNI -> List S
+
+
+    HPSPEC ==> Record(guessStream:  UFPSF -> Stream UFPSF,
+                      degreeStream: Stream NNI,
+                      testStream:   UFPSSUPF -> Stream UFPSSUPF, 
+                      exprStream:   (EXPRR, Symbol) -> Stream EXPRR,
+                      A:  DIFFSPECA,
+                      AF: DIFFSPECAF,
+                      AX: DIFFSPECAX,
+                      C:  DIFFSPECC)
+
+-- note that empty?(guessStream.o) has to return always. In other words, if the
+-- stream is finite, empty? should recognize it.
+
+    DIFFSPECN ==> EXPRR -> EXPRR             -- eg.: i+->q^i
+
+    GUESSER ==> (List F, LGOPT) -> GUESSRESULT
+
+    FSUPS ==> Fraction SUP S
+    FSUPF ==> Fraction SUP F
+
+    V ==> OrderedVariableList(['a1, 'A])
+    POLYF ==> SparseMultivariatePolynomial(F, V)
+    FPOLYF ==> Fraction POLYF
+    FSUPFPOLYF ==> Fraction SUP FPOLYF
+    POLYS ==> SparseMultivariatePolynomial(S, V)
+    FPOLYS ==> Fraction POLYS
+    FSUPFPOLYS ==> Fraction SUP FPOLYS
+
+@
+The following should be commented out when not debugging, see also
+Section~\ref{sec:Hermite-Pade}.
+
+<<package GUESS Guess>>=
+    --@<<implementation: Guess - Hermite-Pade - Types for Operators>>
+    -- EXT ==> (Integer, V, V) -> FPOLYS
+    -- EXTEXPR ==> (Symbol, F, F) -> EXPRR
+@
+
+<<package GUESS Guess>>=
+    Exports == with
+
+        guess: List F -> GUESSRESULT
+          ++ \spad{guess l} applies recursively \spadfun{guessRec} and
+          ++ \spadfun{guessADE} to the successive differences and quotients of
+          ++ the list. Default options as described in
+          ++ \spadtype{GuessOptionFunctions0} are used.
+
+        guess: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guess(l, options)} applies recursively \spadfun{guessRec}
+          ++ and \spadfun{guessADE} to the successive differences and quotients
+          ++ of the list. The given options are used.
+
+        guess: (List F, List GUESSER, List Symbol) -> GUESSRESULT
+          ++ \spad{guess(l, guessers, ops)} applies recursively the given
+          ++ guessers to the successive differences if ops contains the symbol
+          ++ guessSum and quotients if ops contains the symbol guessProduct to
+          ++ the list. Default options as described in
+          ++ \spadtype{GuessOptionFunctions0} are used.
+
+        guess: (List F, List GUESSER, List Symbol, LGOPT) -> GUESSRESULT
+          ++ \spad{guess(l, guessers, ops)} applies recursively the given
+          ++ guessers to the successive differences if ops contains the symbol
+          ++ \spad{guessSum} and quotients if ops contains the symbol
+          ++ \spad{guessProduct} to the list. The given options are used.
+
+        guessExpRat: List F -> GUESSRESULT
+          ++ \spad{guessExpRat l} tries to find a function of the form 
+          ++ n+->(a+b n)^n r(n), where r(n) is a rational function, that fits
+          ++ l. 
+
+        guessExpRat: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessExpRat(l, options)} tries to find a function of the
+          ++ form n+->(a+b n)^n r(n), where r(n) is a rational function, that
+          ++ fits l. 
+
+        guessBinRat: List F -> GUESSRESULT
+          ++ \spad{guessBinRat(l, options)} tries to find a function of the
+          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
+          ++ function, that fits l. 
+
+        guessBinRat: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessBinRat(l, options)} tries to find a function of the
+          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
+          ++ function, that fits l. 
+
+        if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+            guessExpRat: Symbol -> GUESSER
+              ++ \spad{guessExpRat q} returns a guesser that tries to find a
+              ++ function of the form n+->(a+b q^n)^n r(q^n), where r(q^n) is a
+              ++ q-rational function, that fits l.
+
+            guessBinRat: Symbol -> GUESSER
+              ++ \spad{guessBinRat q} returns a guesser that tries to find a
+              ++ function of the form n+->qbinomial(a+b n, n) r(n), where r(q^n) is a
+              ++ q-rational function, that fits l.
+
+        guessHP: (LGOPT -> HPSPEC) -> GUESSER
+          ++ \spad{guessHP f} constructs an operation that applies Hermite-Pade
+          ++ approximation to the series generated by the given function f.
+
+        guessADE: List F -> GUESSRESULT
+          ++ \spad{guessADE l} tries to find an algebraic differential equation
+          ++ for a generating function whose first Taylor coefficients are
+          ++ given by l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}.
+
+        guessADE: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessADE(l, options)} tries to find an algebraic
+          ++ differential equation for a generating function whose first Taylor
+          ++ coefficients are given by l, using the given options.
+
+        guessAlg: List F -> GUESSRESULT
+          ++ \spad{guessAlg l} tries to find an algebraic equation for a
+          ++ generating function whose first Taylor coefficients are given by
+          ++ l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessADE}(l, maxDerivative == 0).
+
+        guessAlg: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessAlg(l, options)} tries to find an algebraic equation
+          ++ for a generating function whose first Taylor coefficients are
+          ++ given by l, using the given options. It is equivalent to
+          ++ \spadfun{guessADE}(l, options) with \spad{maxDerivative == 0}.
+
+        guessHolo: List F -> GUESSRESULT
+          ++ \spad{guessHolo l} tries to find an ordinary linear differential
+          ++ equation for a generating function whose first Taylor coefficients
+          ++ are given by l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessADE}\spad{(l, maxPower == 1)}.
+
+        guessHolo: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessHolo(l, options)} tries to find an ordinary linear
+          ++ differential equation for a generating function whose first Taylor
+          ++ coefficients are given by l, using the given options. It is
+          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
+          ++ \spad{maxPower == 1}.
+
+        guessPade: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessPade(l, options)} tries to find a rational function
+          ++ whose first Taylor coefficients are given by l, using the given
+          ++ options. It is equivalent to \spadfun{guessADE}\spad{(l,
+          ++ maxDerivative == 0, maxPower == 1, allDegrees == true)}.
+
+        guessPade: List F -> GUESSRESULT
+          ++ \spad{guessPade(l, options)} tries to find a rational function
+          ++ whose first Taylor coefficients are given by l, using the default
+          ++ options described in \spadtype{GuessOptionFunctions0}. It is
+          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
+          ++ \spad{maxDerivative == 0, maxPower == 1, allDegrees == true}.
+
+        guessRec: List F -> GUESSRESULT
+          ++ \spad{guessRec l} tries to find an ordinary difference equation
+          ++ whose first values are given by l, using the default options
+          ++ described in \spadtype{GuessOptionFunctions0}.
+
+        guessRec: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessRec(l, options)} tries to find an ordinary difference
+          ++ equation whose first values are given by l, using the given
+          ++ options. 
+
+        guessPRec: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessPRec(l, options)} tries to find a linear recurrence
+          ++ with polynomial coefficients whose first values are given by l,
+          ++ using the given options. It is equivalent to
+          ++ \spadfun{guessRec}\spad{(l, options)} with \spad{maxPower == 1}.
+
+        guessPRec: List F -> GUESSRESULT
+          ++ \spad{guessPRec l} tries to find a linear recurrence with
+          ++ polynomial coefficients whose first values are given by l, using
+          ++ the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessRec}\spad{(l, maxPower == 1)}. 
+
+        guessRat: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessRat(l, options)} tries to find a rational function
+          ++ whose first values are given by l, using the given options. It is
+          ++ equivalent to \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower
+          ++ == 1, allDegrees == true)}.
+
+        guessRat: List F -> GUESSRESULT
+          ++ \spad{guessRat l} tries to find a rational function whose first
+          ++ values are given by l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower == 1,
+          ++ allDegrees == true)}.
+
+        diffHP: LGOPT -> HPSPEC
+          ++ \spad{diffHP options} returns a specification for Hermite-Pade
+          ++ approximation with the differential operator
+
+        shiftHP: LGOPT -> HPSPEC
+          ++ \spad{shiftHP options} returns a specification for Hermite-Pade
+          ++ approximation with the shift operator
+
+        if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+            shiftHP: Symbol -> (LGOPT -> HPSPEC)
+              ++ \spad{shiftHP options} returns a specification for
+              ++ Hermite-Pade approximation with the $q$-shift operator
+
+            diffHP: Symbol -> (LGOPT -> HPSPEC)
+              ++ \spad{diffHP options} returns a specification for Hermite-Pade
+              ++ approximation with the  $q$-dilation operator
+
+            guessRec: Symbol -> GUESSER
+              ++ \spad{guessRec q} returns a guesser that finds an ordinary
+              ++ q-difference equation whose first values are given by l, using
+              ++ the given options.
+
+            guessPRec: Symbol -> GUESSER
+              ++ \spad{guessPRec q} returns a guesser that tries to find
+              ++ a linear q-recurrence with polynomial coefficients whose first
+              ++ values are given by l, using the given options. It is
+              ++ equivalent to \spadfun{guessRec}\spad{(q)} with 
+              ++ \spad{maxPower == 1}.
+
+            guessRat: Symbol -> GUESSER
+              ++ \spad{guessRat q} returns a guesser that tries to find a
+              ++ q-rational function whose first values are given by l, using
+              ++ the given options. It is equivalent to \spadfun{guessRec} with
+              ++ \spad{(l, maxShift == 0, maxPower == 1, allDegrees == true)}.
+
+            guessADE: Symbol -> GUESSER
+              ++ \spad{guessADE q} returns a guesser that tries to find an
+              ++ algebraic differential equation for a generating function whose
+              ++ first Taylor coefficients are given by l, using the given
+              ++ options.
+
+        --@<<debug exports: Guess>>
+@
+
+<<debug exports: Guess>>=
+--termAsUFPSF: (UFPSF, List Integer, DIFFSPECS, DIFFSPEC1) -> UFPSF
+--termAsUFPSF2: (UFPSF, List Integer, DIFFSPECS, DIFFSPEC1) -> UFPSF
+--termAsEXPRR: (EXPRR, Symbol, List Integer, DIFFSPECX, DIFFSPEC1X) -> EXPRR
+--termAsUFPSSUPF: (UFPSSUPF, List Integer, DIFFSPECSF, DIFFSPEC1F) -> UFPSSUPF
+--termAsUFPSSUPF2: (UFPSSUPF, List Integer, DIFFSPECSF, DIFFSPEC1F) -> UFPSSUPF
+--
+--ShiftSXGF: (EXPRR, Symbol, NNI) -> EXPRR
+--ShiftAXGF: (NNI, Symbol, EXPRR) -> EXPRR
+--
+--FilteredPartitionStream: LGOPT -> Stream List Integer
+--
+--guessInterpolate: (List SUP F, List NNI, HPSPEC) -> Matrix SUP S
+testInterpolant: (List SUP S, List F, List UFPSSUPF, List EXPRR, List EXPRR, _
+                  NNI, HPSPEC, Symbol, BasicOperator, LGOPT) _
+                  -> Union("failed", Record(function: EXPRR, order: NNI))
+
+--checkResult: (EXPRR, Symbol, Integer, List F, LGOPT) -> NNI
+--
+--guessBinRatAux: (Symbol, List F, DIFFSPECN, EXT, EXTEXPR,
+--                 List Integer, LGOPT) -> List EXPRR
+--guessBinRatAux0: (List F, DIFFSPECN, EXT, EXTEXPR,
+--                  LGOPT) -> GUESSRESULT
+--binExt: EXT
+--binExtEXPR: EXTEXPR
+--defaultD: DIFFSPECN
+
+@
+
+<<package GUESS Guess>>=
+    Implementation == add
+        <<implementation: Guess>>
+@
+
+<<implementation: Guess>>=
+
+-- We have to put this chunk at the beginning, because otherwise it will take
+-- very long to compile.
+
+<<implementation: Guess - guessExpRat - Order and Degree>>
+
+<<implementation: Guess - Utilities>>
+<<implementation: Guess - guessExpRat>>
+<<implementation: Guess - guessBinRat>>
+<<implementation: Guess - Hermite-Pade>>
+<<implementation: Guess - guess>>
+@
+
+\subsection{general utilities}
+
+<<implementation: Guess - Utilities>>=
+checkResult(res: EXPRR, n: Symbol, l: Integer, list: List F, 
+            options: LGOPT): NNI ==
+    for i in l..1 by -1 repeat
+        den := eval(denominator res, n::EXPRR, (i-1)::EXPRR)
+        if den = 0 then return i::NNI
+        num := eval(numerator res, n::EXPRR, (i-1)::EXPRR)
+        if list.i ~= retract(retract(num/den)@R)
+        then return i::NNI
+    0$NNI
+
+SUPS2SUPF(p: SUP S): SUP F ==
+  if F is S then 
+    p pretend SUP(F)
+  else if F is Fraction S then
+    map(coerce(#1)$Fraction(S), p)
+      $SparseUnivariatePolynomialFunctions2(S, F)
+  else error "Type parameter F should be either equal to S or equal _
+              to Fraction S"
+
+@
+%$
+
+\subsection{guessing rational functions with an exponential term}
+
+<<implementation: Guess - guessExpRat>>=
+<<implementation: Guess - guessExpRat - Utilities>>
+<<implementation: Guess - guessExpRat - Main>>
+@
+
+\subsubsection{Utilities}
+
+\paragraph{conversion routines}
+
+<<implementation: Guess - guessExpRat - Utilities>>=
+F2FPOLYS(p: F): FPOLYS ==
+  if F is S then 
+    p::POLYF::FPOLYF pretend FPOLYS
+  else if F is Fraction S then
+    numer(p)$Fraction(S)::POLYS/denom(p)$Fraction(S)::POLYS
+  else error "Type parameter F should be either equal to S or equal _
+               to Fraction S"
+
+MPCSF ==> MPolyCatFunctions2(V, IndexedExponents V, 
+                                IndexedExponents V, S, F,
+                                POLYS, POLYF)
+
+SUPF2EXPRR(xx: Symbol, p: SUP F): EXPRR ==
+  zero? p => 0
+  (coerce(leadingCoefficient p))::EXPRR * (xx::EXPRR)**degree p
+     + SUPF2EXPRR(xx, reductum p)
+
+FSUPF2EXPRR(xx: Symbol, p: FSUPF): EXPRR ==
+  (SUPF2EXPRR(xx, numer p)) / (SUPF2EXPRR(xx, denom p))
+
+
+POLYS2POLYF(p: POLYS): POLYF ==
+  if F is S then 
+    p pretend POLYF
+  else if F is Fraction S then
+    map(coerce(#1)$Fraction(S), p)$MPCSF
+  else error "Type parameter F should be either equal to S or equal _
+              to Fraction S"
+
+SUPPOLYS2SUPF(p: SUP POLYS, a1v: F, Av: F): SUP F ==
+  zero? p => 0
+  lc: POLYF := POLYS2POLYF leadingCoefficient(p)
+  monomial(retract(eval(lc, [index(1)$V, index(2)$V]::List V, 
+                            [a1v, Av])),
+           degree p) 
+    + SUPPOLYS2SUPF(reductum p, a1v, Av)
+
+
+SUPFPOLYS2FSUPPOLYS(p: SUP FPOLYS): Fraction SUP POLYS  ==
+  cden := splitDenominator(p)
+         $UnivariatePolynomialCommonDenominator(POLYS, FPOLYS,SUP FPOLYS)
+
+  pnum: SUP POLYS 
+       := map(retract(#1 * cden.den)$FPOLYS, p)
+             $SparseUnivariatePolynomialFunctions2(FPOLYS, POLYS)
+  pden: SUP POLYS := (cden.den)::SUP POLYS
+
+  pnum/pden
+
+
+POLYF2EXPRR(p: POLYF): EXPRR ==
+  map(convert(#1)@Symbol::EXPRR, coerce(#1)@EXPRR, p)
+     $PolynomialCategoryLifting(IndexedExponents V, V, 
+                                F, POLYF, EXPRR)
+
+-- this needs documentation. In particular, why is V appearing here?
+GF ==> GeneralizedMultivariateFactorize(SingletonAsOrderedSet,
+                                        IndexedExponents V, F, F,
+                                        SUP F)
+
+-- does not work:
+--                                                     6
+--   WARNING (genufact): No known algorithm to factor ? , trying square-free.
+
+-- GF ==> GenUFactorize F
+@
+
+\paragraph{mimicking $q$-analoga}
+
+<<implementation: Guess - guessExpRat - Utilities>>=
+defaultD: DIFFSPECN
+defaultD(expr: EXPRR): EXPRR == expr
+
+-- applies n+->q^n or whatever DN is to i
+DN2DL: (DIFFSPECN, Integer) -> F
+DN2DL(DN, i) == retract(retract(DN(i::EXPRR))@R)
+
+<<implementation: Guess - guessExpRat - evalResultant>>
+<<implementation: Guess - guessExpRat - substitute>>
+@
+
+\subsubsection{reducing the degree of the polynomials}
+
+The degree of [[poly3]] is governed by $(a_0+x_m a_1)^{x_m}$. Therefore, we
+substitute $A-x_m a1$ for $a_0$, which reduces the degree in $a_1$ by
+$x_m-x_{i+1}$.
+
+<<implementation: Guess - guessExpRat - substitute>>=
+p(xm: Integer, i: Integer, va1: V, vA: V, basis: DIFFSPECN): FPOLYS == 
+    vA::POLYS::FPOLYS + va1::POLYS::FPOLYS _ 
+                       * F2FPOLYS(DN2DL(basis, i) - DN2DL(basis, xm))
+
+p2(xm: Integer, i: Symbol, a1v: F, Av: F, basis: DIFFSPECN): EXPRR == 
+    coerce(Av) + coerce(a1v)*(basis(i::EXPRR) - basis(xm::EXPRR))
+
+@
+
+<<not interesting implementation: Guess - guessExpRat - substitute>>=
+p(xm: Integer, i: Integer, va1: V, vA: V, basis: DIFFSPECN): FPOLYS == 
+    vA::POLYS::FPOLYS + (i-xm)*va1::POLYS::FPOLYS
+
+p2(xm: Integer, i: Symbol, a1v: F, Av: F, basis: DIFFSPECN): EXPRR == 
+    coerce(Av) + coerce(a1v)*(i::EXPRR - xm::EXPRR)
+
+@
+
+\subsubsection{Order and Degree}
+
+The following expressions for order and degree of the resultants [[res1]] and
+[[res2]] in [[guessExpRatAux]] were first guessed -- partially with the aid of
+[[guessRat]], and then proven to be correct.
+
+<<implementation: Guess - guessExpRat - Order and Degree>>=
+ord1(x: List Integer, i: Integer): Integer == 
+    n := #x - 3 - i
+    x.(n+1)*reduce(_+, [x.j for j in 1..n], 0) + _
+        2*reduce(_+, [reduce(_+, [x.k*x.j for k in 1..j-1], 0) _
+                      for j in 1..n], 0)
+
+ord2(x: List Integer, i: Integer): Integer == 
+    if zero? i then
+        n := #x - 3 - i
+        ord1(x, i) + reduce(_+, [x.j for j in 1..n], 0)*(x.(n+2)-x.(n+1))
+    else
+        ord1(x, i)
+
+deg1(x: List Integer, i: Integer): Integer == 
+    m := #x - 3 
+    (x.(m+3)+x.(m+1)+x.(1+i))*reduce(_+, [x.j for j in 2+i..m], 0) + _
+        x.(m+3)*x.(m+1) + _
+        2*reduce(_+, [reduce(_+, [x.k*x.j for k in 2+i..j-1], 0) _
+                      for j in 2+i..m], 0)
+
+deg2(x: List Integer, i: Integer): Integer == 
+    m := #x - 3
+    deg1(x, i) + _
+        (x.(m+3) + reduce(_+, [x.j for j in 2+i..m], 0)) * _
+        (x.(m+2)-x.(m+1))
+
+@
+
+[[evalResultant]] evaluates the resultant of [[p1]] and [[p2]] at [[d-o+1]]
+points, so that we can recover it by interpolation.
+
+<<implementation: Guess - guessExpRat - evalResultant>>=
+evalResultant(p1: POLYS, p2: POLYS, o: Integer, d: Integer, va1: V, vA: V)_
+: List S == 
+    res: List S := []
+    d1 := degree(p1, va1)
+    d2 := degree(p2, va1)
+    lead: S
+    for k in 1..d-o+1 repeat
+        p1atk := univariate eval(p1, vA, k::S)
+        p2atk := univariate eval(p2, vA, k::S)
+
+@
+
+It may happen, that the leading coefficients of one or both of the polynomials
+changes, when we evaluate it at $k$. In this case, we need to correct this by
+multiplying with the corresponding power of the leading coefficient of the
+other polynomial.
+
+Consider the Sylvester matrix of the original polynomials. We want to evaluate
+it at $A=k$. If the first few leading coefficients of $p2$ vanish, the first
+few columns of the Sylvester matrix have triangular shape, with the leading
+coefficient of $p1$ on the diagonal. The same thing happens, if we exchange the
+roles of $p1$ and $p2$, only that we have to take care of the sign, too.
+
+<<implementation: Guess - guessExpRat - evalResultant>>=
+        d1atk := degree p1atk
+        d2atk := degree p2atk
+
+--      output("k: " string(k))$OutputPackage
+--      output("d1: " string(d1) " d1atk: " string(d1atk))$OutputPackage
+--      output("d2: " string(d2) " d2atk: " string(d2atk))$OutputPackage
+
+
+        if d2atk < d2 then
+            if  d1atk < d1
+            then lead := 0$S
+            else lead := (leadingCoefficient p1atk)**((d2-d2atk)::NNI)
+        else
+            if  d1atk < d1
+            then lead := (-1$S)**d2 * (leadingCoefficient p2atk)**((d1-d1atk)::NNI)
+            else lead := 1$S
+
+        if zero? lead 
+        then res := cons(0, res)
+        else res := cons(lead * (resultant(p1atk, p2atk)$SUP(S) exquo _
+                                (k::S)**(o::NNI))::S, 
+                         res)
+
+@
+%$
+
+Since we also have an lower bound for the order of the resultant, we need to
+evaluate it only at $d-o+1$ points. Furthermore, we can divide by $k^o$ and
+still obtain a polynomial.
+
+<<implementation: Guess - guessExpRat - evalResultant>>=
+    reverse res
+
+@
+
+\subsubsection{The main routine}
+
+<<implementation: Guess - guessExpRat - Main>>=
+guessExpRatAux(xx: Symbol, list: List F, basis: DIFFSPECN, 
+               xValues: List Integer, options: LGOPT): List EXPRR ==
+
+    a1: V := index(1)$V
+    A: V := index(2)$V
+
+    len: NNI := #list
+    if len < 4 then return []
+               else len := (len-3)::NNI
+
+    xlist := [F2FPOLYS DN2DL(basis, xValues.i) for i in 1..len]
+    x1 := F2FPOLYS DN2DL(basis, xValues.(len+1))
+    x2 := F2FPOLYS DN2DL(basis, xValues.(len+2))
+    x3 := F2FPOLYS DN2DL(basis, xValues.(len+3))
+
+@
+
+We try to fit the data $(s1,s2,\dots)$ to the model $(a+b n)^n y(n)$, $r$ being
+a rational function. To obtain $y$, we compute $y(n)=s_n*(a+b n)^{-n}$.
+
+<<implementation: Guess - guessExpRat - Main>>=
+    y: NNI -> FPOLYS := 
+        F2FPOLYS(list.#1) * _
+        p(last xValues, (xValues.#1)::Integer, a1, A, basis)**_
+            (-(xValues.#1)::Integer)
+
+    ylist: List FPOLYS := [y i for i in 1..len]
+
+    y1 := y(len+1)
+    y2 := y(len+2)
+    y3 := y(len+3)
+
+    res := []::List EXPRR
+    if maxDegree(options)$GOPT0 = -1
+    then maxDeg := len-1
+    else maxDeg := min(maxDegree(options)$GOPT0, len-1)
+
+    for i in 0..maxDeg repeat
+        if debug(options)$GOPT0 then
+            output(hconcat("degree ExpRat "::OutputForm, i::OutputForm))
+                $OutputPackage
+
+@
+
+\begin{verbatim}
+  Shouldn't we use the algorithm over [[POLYS]] here? Strange enough, for
+  polynomial interpolation, it is faster, but for rational interpolation
+  \emph{much} slower. This should be investigated.
+\end{verbatim}
+
+\begin{verbatim}
+  It seems that [[maxDeg]] bounds the degree of the denominator, rather than
+  the numerator? This is now added to the documentation of [[maxDegree]], it
+  should make sense.
+\end{verbatim}
+
+<<implementation: Guess - guessExpRat - Main>>=
+        if debug(options)$GOPT0 then 
+            systemCommand("sys date +%s")$MoreSystemCommands
+            output("interpolating..."::OutputForm)$OutputPackage
+
+        ri: FSUPFPOLYS
+           := interpolate(xlist, ylist, (len-1-i)::NNI) _
+                         $FFFG(FPOLYS, SUP FPOLYS)
+
+-- for experimental fraction free interpolation
+--        ri: Fraction SUP POLYS
+--           := interpolate(xlist, ylist, (len-1-i)::NNI) _
+--                         $FFFG(POLYS, SUP POLYS)
+
+        if debug(options)$GOPT0 then 
+--            output(hconcat("xlist: ", xlist::OutputForm))$OutputPackage
+--            output(hconcat("ylist: ", ylist::OutputForm))$OutputPackage
+--            output(hconcat("ri: ", ri::OutputForm))$OutputPackage
+            systemCommand("sys date +%s")$MoreSystemCommands
+            output("polynomials..."::OutputForm)$OutputPackage
+
+        poly1: POLYS := numer(elt(ri, x1)$SUP(FPOLYS) - y1)
+        poly2: POLYS := numer(elt(ri, x2)$SUP(FPOLYS) - y2)
+        poly3: POLYS := numer(elt(ri, x3)$SUP(FPOLYS) - y3)
+
+-- for experimental fraction free interpolation
+--        ri2: FSUPFPOLYS := map(#1::FPOLYS, numer ri)                           _
+--                           $SparseUnivariatePolynomialFunctions2(POLYS, FPOLYS)_ 
+--                          /map(#1::FPOLYS, denom ri)                           _
+--                           $SparseUnivariatePolynomialFunctions2(POLYS, FPOLYS)
+--
+--        poly1: POLYS := numer(elt(ri2, x1)$SUP(FPOLYS) - y1)
+--        poly2: POLYS := numer(elt(ri2, x2)$SUP(FPOLYS) - y2)
+--        poly3: POLYS := numer(elt(ri2, x3)$SUP(FPOLYS) - y3)
+
+        n:Integer := len - i
+        o1: Integer := ord1(xValues, i)
+        d1: Integer := deg1(xValues, i)
+        o2: Integer := ord2(xValues, i)
+        d2: Integer := deg2(xValues, i)
+
+-- another compiler bug: using i as iterator here makes the loop break
+
+        if debug(options)$GOPT0 then 
+            systemCommand("sys date +%s")$MoreSystemCommands
+            output("interpolating resultants..."::OutputForm)$OutputPackage
+
+        res1: SUP S
+             := newton(evalResultant(poly1, poly3, o1, d1, a1, A))
+                      $NewtonInterpolation(S)
+
+        res2: SUP S
+             := newton(evalResultant(poly2, poly3, o2, d2, a1, A))
+                      $NewtonInterpolation(S)
+
+        if debug(options)$GOPT0 then 
+--            res1: SUP S := univariate(resultant(poly1, poly3, a1))
+--            res2: SUP S := univariate(resultant(poly2, poly3, a1))
+--            if res1 ~= res1res or res2 ~= res2res then
+--            output(hconcat("poly1 ", poly1::OutputForm))$OutputPackage
+--                output(hconcat("poly2 ", poly2::OutputForm))$OutputPackage
+--            output(hconcat("poly3 ", poly3::OutputForm))$OutputPackage
+--                output(hconcat("res1 ", res1::OutputForm))$OutputPackage
+--                output(hconcat("res2 ", res2::OutputForm))$OutputPackage
+            output("n/i: " string(n) " " string(i))$OutputPackage
+            output("res1 ord: " string(o1) " " string(minimumDegree res1))
+                  $OutputPackage
+            output("res1 deg: " string(d1) " " string(degree res1))
+                  $OutputPackage
+            output("res2 ord: " string(o2) " " string(minimumDegree res2))
+                  $OutputPackage
+            output("res2 deg: " string(d2) " " string(degree res2))
+                  $OutputPackage
+
+        if debug(options)$GOPT0 then 
+            systemCommand("sys date +%s")$MoreSystemCommands
+            output("computing gcd..."::OutputForm)$OutputPackage
+
+-- we want to solve over F
+-- for polynomial domains S this seems to be very costly!     
+        res3: SUP F := SUPS2SUPF(primitivePart(gcd(res1, res2)))
+
+        if debug(options)$GOPT0 then 
+            systemCommand("sys date +%s")$MoreSystemCommands
+            output("solving..."::OutputForm)$OutputPackage
+
+-- res3 is a polynomial in A=a0+(len+3)*a1
+-- now we have to find the roots of res3
+
+        for f in factors factor(res3)$GF | degree f.factor = 1 repeat 
+-- we are only interested in the linear factors
+             if debug(options)$GOPT0 then 
+                 output(hconcat("f: ", f::OutputForm))$OutputPackage
+
+             Av: F := -coefficient(f.factor, 0)
+                     / leadingCoefficient f.factor
+
+-- FIXME: in an earlier version, we disregarded vanishing Av
+--        maybe we intended to disregard vanishing a1v? Either doesn't really
+--        make sense to me right now.
+
+             evalPoly := eval(POLYS2POLYF poly3, A, Av)
+             if zero? evalPoly 
+             then evalPoly := eval(POLYS2POLYF poly1, A, Av)
+-- Note that it really may happen that poly3 vanishes when specializing
+-- A. Consider for example guessExpRat([1,1,1,1]).
+
+-- FIXME: We check poly1 below, too. I should work out in what cases poly3
+-- vanishes.
+
+             for g in factors factor(univariate evalPoly)$GF 
+                      | degree g.factor = 1 repeat
+                 if debug(options)$GOPT0 then 
+                     output(hconcat("g: ", g::OutputForm))$OutputPackage
+
+                 a1v: F := -coefficient(g.factor, 0)
+                          / leadingCoefficient g.factor
+
+-- check whether poly1 and poly2 really vanish. Note that we could have found
+-- an extraneous solution, since we only computed the gcd of the two
+-- resultants.
+
+                 t1 := eval(POLYS2POLYF poly1, [a1, A]::List V, 
+                                               [a1v, Av]::List F)
+                 if zero? t1 then  
+                     t2 := eval(POLYS2POLYF poly2, [a1, A]::List V, 
+                                                   [a1v, Av]::List F)
+                     if zero? t2 then
+
+                         ri1: Fraction SUP POLYS 
+                             := SUPFPOLYS2FSUPPOLYS(numer ri)
+                              / SUPFPOLYS2FSUPPOLYS(denom ri)
+
+-- for experimental fraction free interpolation
+--                         ri1: Fraction SUP POLYS := ri
+
+                         numr: SUP F := SUPPOLYS2SUPF(numer ri1, a1v, Av)
+                         denr: SUP F := SUPPOLYS2SUPF(denom ri1, a1v, Av)
+
+                         if not zero? denr then
+                             res4: EXPRR := eval(FSUPF2EXPRR(xx, numr/denr), 
+                                                 kernel(xx), 
+                                                 basis(xx::EXPRR))
+                                           *p2(last xValues, _
+                                               xx, a1v, Av, basis)_
+                                            **xx::EXPRR
+                             res := cons(res4, res)
+                         else if zero? numr and debug(options)$GOPT0 then
+                             output("numerator and denominator vanish!")
+                                   $OutputPackage
+
+-- If we are only interested in one solution, we do not try other degrees if we
+-- have found already some solutions. I.e., the indentation here is correct.
+
+        if not null(res) and one(options)$GOPT0 then return res
+
+    res
+
+guessExpRatAux0(list: List F, basis: DIFFSPECN, options: LGOPT): GUESSRESULT ==
+    if zero? safety(options)$GOPT0 then
+        error "Guess: guessExpRat does not support zero safety"
+-- guesses Functions of the Form (a1*n+a0)^n*rat(n)
+    xx := indexName(options)$GOPT0
+
+-- restrict to safety
+
+    len: Integer := #list
+    if len-safety(options)$GOPT0+1 < 0 then return []
+
+    shortlist: List F := first(list, (len-safety(options)$GOPT0+1)::NNI)
+
+-- remove zeros from list
+
+    zeros: EXPRR := 1
+    newlist: List F
+    xValues: List Integer
+
+    i: Integer := -1
+    for x in shortlist repeat
+        i := i+1
+        if x = 0 then 
+            zeros := zeros * (basis(xx::EXPRR) - basis(i::EXPRR))
+
+    i := -1
+    for x in shortlist repeat
+        i := i+1
+        if x ~= 0 then
+            newlist := cons(x/retract(retract(eval(zeros, xx::EXPRR, 
+                                                          i::EXPRR))@R),
+                            newlist)
+            xValues := cons(i, xValues)
+
+    newlist := reverse newlist
+    xValues := reverse xValues
+
+    res: List EXPRR 
+        := [eval(zeros * f, xx::EXPRR, xx::EXPRR) _
+            for f in guessExpRatAux(xx, newlist, basis, xValues, options)]
+
+    reslist := map([#1, checkResult(#1, xx, len, list, options)], res)
+                  $ListFunctions2(EXPRR, Record(function: EXPRR, order: NNI))
+
+    select(#1.order < len-safety(options)$GOPT0, reslist)
+
+guessExpRat(list : List F): GUESSRESULT ==
+    guessExpRatAux0(list, defaultD, [])
+
+guessExpRat(list: List F, options: LGOPT): GUESSRESULT ==
+    guessExpRatAux0(list, defaultD, options)
+
+if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+    guessExpRat(q: Symbol): GUESSER ==
+        guessExpRatAux0(#1, q::EXPRR**#1, #2)
+
+@
+
+\subsection{guessing rational functions with a binomial term}
+
+\begin{verbatim}
+  It is not clear whether one should take the model
+  \begin{equation*}
+    \binom{a+bn}{n}q(n),
+  \end{equation*}
+  which includes rational functions, or
+  \begin{equation*}
+    (a+bn)(a+bn+1)\dots (a+bn+n)q(n).
+  \end{equation*}
+  which includes rational functions times $n!$. We choose the former, since
+  dividing by $n!$ is a common normalisation. The question remains whether we
+  should do the same for [[guessExpRat]].
+\end{verbatim}
+
+
+<<implementation: Guess - guessBinRat>>=
+
+EXT ==> (Integer, V, V) -> FPOLYS
+EXTEXPR ==> (Symbol, F, F) -> EXPRR
+
+binExt: EXT
+binExt(i: Integer, va1: V, vA: V): FPOLYS == 
+    numl: List POLYS := [(vA::POLYS) + i * (va1::POLYS) - (l::POLYS) _
+                         for l in 0..i-1]
+    num: POLYS := reduce(_*, numl, 1)
+
+    num/(factorial(i)::POLYS)
+
+binExtEXPR: EXTEXPR
+binExtEXPR(i: Symbol, a1v: F, Av: F): EXPRR == 
+    binomial(coerce Av + coerce a1v * (i::EXPRR), i::EXPRR)
+
+
+guessBinRatAux(xx: Symbol, list: List F, 
+               basis: DIFFSPECN, ext: EXT, extEXPR: EXTEXPR,
+               xValues: List Integer, options: LGOPT): List EXPRR ==
+
+    a1: V := index(1)$V
+    A: V := index(2)$V
+
+    len: NNI := #list
+    if len < 4 then return []
+               else len := (len-3)::NNI
+
+    xlist := [F2FPOLYS DN2DL(basis, xValues.i) for i in 1..len]
+    x1 := F2FPOLYS DN2DL(basis, xValues.(len+1))
+    x2 := F2FPOLYS DN2DL(basis, xValues.(len+2))
+    x3 := F2FPOLYS DN2DL(basis, xValues.(len+3))
+
+@
+
+We try to fit the data $(s1,s2,\dots)$ to the model $\binom{a+b n}{n} y(n)$,
+$r$ being a rational function. To obtain $y$, we compute
+$y(n)=s_n*\binom{a+bn}{n}^-1$.
+
+<<implementation: Guess - guessBinRat>>=
+    y: NNI -> FPOLYS := 
+        F2FPOLYS(list.#1) / _
+        ext((xValues.#1)::Integer, a1, A)
+
+    ylist: List FPOLYS := [y i for i in 1..len]
+
+    y1 := y(len+1)
+    y2 := y(len+2)
+    y3 := y(len+3)
+
+    res := []::List EXPRR
+    if maxDegree(options)$GOPT0 = -1
+    then maxDeg := len-1
+    else maxDeg := min(maxDegree(options)$GOPT0, len-1)
+
+    for i in 0..maxDeg repeat
+--        if debug(options)$GOPT0 then
+--            output(hconcat("degree BinRat "::OutputForm, i::OutputForm))
+--                $OutputPackage
+
+@
+
+\begin{verbatim}
+  Shouldn't we use the algorithm over [[POLYS]] here? Strange enough, for
+  polynomial interpolation, it is faster, but for rational interpolation
+  \emph{much} slower. This should be investigated.
+\end{verbatim}
+
+\begin{verbatim}
+  It seems that [[maxDeg]] bounds the degree of the denominator, rather than
+  the numerator? This is now added to the documentation of [[maxDegree]], it
+  should make sense.
+\end{verbatim}
+
+<<implementation: Guess - guessBinRat>>=
+--        if debug(options)$GOPT0 then 
+--            output("interpolating..."::OutputForm)$OutputPackage
+
+        ri: FSUPFPOLYS
+           := interpolate(xlist, ylist, (len-1-i)::NNI) _
+                         $FFFG(FPOLYS, SUP FPOLYS)
+
+--        if debug(options)$GOPT0 then 
+--            output(hconcat("ri ", ri::OutputForm))$OutputPackage
+
+        poly1: POLYS := numer(elt(ri, x1)$SUP(FPOLYS) - y1)
+        poly2: POLYS := numer(elt(ri, x2)$SUP(FPOLYS) - y2)
+        poly3: POLYS := numer(elt(ri, x3)$SUP(FPOLYS) - y3)
+
+--        if debug(options)$GOPT0 then
+--            output(hconcat("poly1 ", poly1::OutputForm))$OutputPackage
+--            output(hconcat("poly2 ", poly2::OutputForm))$OutputPackage
+--            output(hconcat("poly3 ", poly3::OutputForm))$OutputPackage
+
+
+        n:Integer := len - i
+        res1: SUP S := univariate(resultant(poly1, poly3, a1))
+        res2: SUP S := univariate(resultant(poly2, poly3, a1))
+        if debug(options)$GOPT0 then
+--            output(hconcat("res1 ", res1::OutputForm))$OutputPackage
+--            output(hconcat("res2 ", res2::OutputForm))$OutputPackage
+
+--            if res1 ~= res1res or res2 ~= res2res then
+--            output(hconcat("poly1 ", poly1::OutputForm))$OutputPackage
+--                output(hconcat("poly2 ", poly2::OutputForm))$OutputPackage
+--            output(hconcat("poly3 ", poly3::OutputForm))$OutputPackage
+--                output(hconcat("res1 ", res1::OutputForm))$OutputPackage
+--                output(hconcat("res2 ", res2::OutputForm))$OutputPackage
+--            output("n/i: " string(n) " " string(i))$OutputPackage
+            output("res1 ord: " string(minimumDegree res1))
+                  $OutputPackage
+            output("res1 deg: " string(degree res1))
+                  $OutputPackage
+            output("res2 ord: " string(minimumDegree res2))
+                  $OutputPackage
+            output("res2 deg: " string(degree res2))
+                  $OutputPackage
+
+        if debug(options)$GOPT0 then 
+            output("computing gcd..."::OutputForm)$OutputPackage
+
+-- we want to solve over F            
+        res3: SUP F := SUPS2SUPF(primitivePart(gcd(res1, res2)))
+
+--        if debug(options)$GOPT0 then 
+--            output(hconcat("res3 ", res3::OutputForm))$OutputPackage
+
+-- res3 is a polynomial in A=a0+(len+3)*a1
+-- now we have to find the roots of res3
+
+        for f in factors factor(res3)$GF | degree f.factor = 1 repeat 
+-- we are only interested in the linear factors
+--             if debug(options)$GOPT0 then 
+--                 output(hconcat("f: ", f::OutputForm))$OutputPackage
+
+             Av: F := -coefficient(f.factor, 0)
+                     / leadingCoefficient f.factor
+
+--             if debug(options)$GOPT0 then 
+--                 output(hconcat("Av: ", Av::OutputForm))$OutputPackage
+
+-- FIXME: in an earlier version, we disregarded vanishing Av
+--        maybe we intended to disregard vanishing a1v? Either doesn't really
+--        make sense to me right now.
+
+             evalPoly := eval(POLYS2POLYF poly3, A, Av)
+             if zero? evalPoly 
+             then evalPoly := eval(POLYS2POLYF poly1, A, Av)
+-- Note that it really may happen that poly3 vanishes when specializing
+-- A. Consider for example guessExpRat([1,1,1,1]).
+
+-- FIXME: We check poly1 below, too. I should work out in what cases poly3
+-- vanishes.
+
+             for g in factors factor(univariate evalPoly)$GF 
+                      | degree g.factor = 1 repeat
+--                 if debug(options)$GOPT0 then 
+--                     output(hconcat("g: ", g::OutputForm))$OutputPackage
+
+                 a1v: F := -coefficient(g.factor, 0)
+                          / leadingCoefficient g.factor
+
+--                 if debug(options)$GOPT0 then 
+--                     output(hconcat("a1v: ", a1v::OutputForm))$OutputPackage
+
+-- check whether poly1 and poly2 really vanish. Note that we could have found
+-- an extraneous solution, since we only computed the gcd of the two
+-- resultants.
+
+                 t1 := eval(POLYS2POLYF poly1, [a1, A]::List V, 
+                                               [a1v, Av]::List F)
+
+--                 if debug(options)$GOPT0 then 
+--                     output(hconcat("t1: ", t1::OutputForm))$OutputPackage
+
+                 if zero? t1 then  
+                     t2 := eval(POLYS2POLYF poly2, [a1, A]::List V, 
+                                                   [a1v, Av]::List F)
+
+--                     if debug(options)$GOPT0 then 
+--                         output(hconcat("t2: ", t2::OutputForm))$OutputPackage
+
+                     if zero? t2 then
+
+                         ri1: Fraction SUP POLYS 
+                             := SUPFPOLYS2FSUPPOLYS(numer ri)
+                              / SUPFPOLYS2FSUPPOLYS(denom ri)
+
+--                         if debug(options)$GOPT0 then 
+--                             output(hconcat("ri1: ", ri1::OutputForm))$OutputPackage
+
+                         numr: SUP F := SUPPOLYS2SUPF(numer ri1, a1v, Av)
+                         denr: SUP F := SUPPOLYS2SUPF(denom ri1, a1v, Av)
+
+--                         if debug(options)$GOPT0 then 
+--                             output(hconcat("numr: ", numr::OutputForm))$OutputPackage
+--                             output(hconcat("denr: ", denr::OutputForm))$OutputPackage
+
+                         if not zero? denr then
+                             res4: EXPRR := eval(FSUPF2EXPRR(xx, numr/denr), 
+                                                 kernel(xx), 
+                                                 basis(xx::EXPRR))
+                                           * extEXPR(xx, a1v, Av)
+
+--                             if debug(options)$GOPT0 then 
+--                                 output(hconcat("res4: ", res4::OutputForm))$OutputPackage
+
+                             res := cons(res4, res)
+                         else if zero? numr and debug(options)$GOPT0 then
+                             output("numerator and denominator vanish!")
+                                   $OutputPackage
+
+-- If we are only interested in one solution, we do not try other degrees if we
+-- have found already some solutions. I.e., the indentation here is correct.
+
+        if not null(res) and one(options)$GOPT0 then return res
+
+    res
+
+guessBinRatAux0(list: List F,
+                basis: DIFFSPECN, ext: EXT, extEXPR: EXTEXPR,
+                options: LGOPT): GUESSRESULT ==
+
+    if zero? safety(options)$GOPT0 then
+        error "Guess: guessBinRat does not support zero safety"
+-- guesses Functions of the form binomial(a+b*n, n)*rat(n)
+    xx := indexName(options)$GOPT0
+
+-- restrict to safety
+
+    len: Integer := #list
+    if len-safety(options)$GOPT0+1 < 0 then return []
+
+    shortlist: List F := first(list, (len-safety(options)$GOPT0+1)::NNI)
+
+-- remove zeros from list
+
+    zeros: EXPRR := 1
+    newlist: List F
+    xValues: List Integer
+
+    i: Integer := -1
+    for x in shortlist repeat
+        i := i+1
+        if x = 0 then 
+            zeros := zeros * (basis(xx::EXPRR) - basis(i::EXPRR))
+
+    i := -1
+    for x in shortlist repeat
+        i := i+1
+        if x ~= 0 then
+            newlist := cons(x/retract(retract(eval(zeros, xx::EXPRR, 
+                                                          i::EXPRR))@R),
+                            newlist)
+            xValues := cons(i, xValues)
+
+    newlist := reverse newlist
+    xValues := reverse xValues
+
+    res: List EXPRR 
+        := [eval(zeros * f, xx::EXPRR, xx::EXPRR) _
+            for f in guessBinRatAux(xx, newlist, basis, ext, extEXPR, xValues, _
+                                    options)]
+
+    reslist := map([#1, checkResult(#1, xx, len, list, options)], res)
+                  $ListFunctions2(EXPRR, Record(function: EXPRR, order: NNI))
+
+    select(#1.order < len-safety(options)$GOPT0, reslist)
+
+guessBinRat(list : List F): GUESSRESULT ==
+    guessBinRatAux0(list, defaultD, binExt, binExtEXPR, [])
+
+guessBinRat(list: List F, options: LGOPT): GUESSRESULT ==
+    guessBinRatAux0(list, defaultD, binExt, binExtEXPR, options)
+
+
+if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+    qD: Symbol -> DIFFSPECN
+    qD q == (q::EXPRR)**#1
+
+
+    qBinExtAux(q: Symbol, i: Integer, va1: V, vA: V): FPOLYS == 
+        fl: List FPOLYS 
+             := [(1$FPOLYS - _
+                  va1::POLYS::FPOLYS * (vA::POLYS::FPOLYS)**(i-1) * _
+                  F2FPOLYS(q::F)**l) / (1-F2FPOLYS(q::F)**l) _ 
+                 for l in 1..i]
+        reduce(_*, fl, 1)
+
+    qBinExt: Symbol -> EXT
+    qBinExt q == qBinExtAux(q, #1, #2, #3)
+
+    qBinExtEXPRaux(q: Symbol, i: Symbol, a1v: F, Av: F): EXPRR == 
+        l: Symbol := 'l
+        product((1$EXPRR - _
+                 coerce a1v * (coerce Av) ** (coerce i - 1$EXPRR) * _
+                 (q::EXPRR) ** coerce(l)) / _
+                (1$EXPRR - (q::EXPRR) ** coerce(l)), _
+                equation(l, 1$EXPRR..i::EXPRR))
+
+    qBinExtEXPR: Symbol -> EXTEXPR
+    qBinExtEXPR q == qBinExtEXPRaux(q, #1, #2, #3)
+
+    guessBinRat(q: Symbol): GUESSER ==
+        guessBinRatAux0(#1, qD q, qBinExt q, qBinExtEXPR q, #2)_
+
+@
+
+
+\subsection{Hermite Pad\'e interpolation}\label{sec:Hermite-Pade}
+
+<<implementation: Guess - Hermite-Pade>>=
+<<implementation: Guess - Hermite-Pade - Types for Operators>>
+<<implementation: Guess - Hermite-Pade - Streams>>
+<<implementation: Guess - Hermite-Pade - Operators>>
+<<implementation: Guess - Hermite-Pade - Utilities>>
+<<implementation: Guess - guessHPaux>>
+<<implementation: Guess - guessHP>>
+@
+
+\subsubsection{Types for Operators}
+<<implementation: Guess - Hermite-Pade - Types for Operators>>=
+-- some useful types for Ore operators that work on series
+
+-- the differentiation operator
+DIFFSPECX ==> (EXPRR, Symbol, NonNegativeInteger) -> EXPRR
+                                               -- eg.: f(x)+->f(q*x)
+                                               --      f(x)+->D(f, x)
+DIFFSPECS ==> (UFPSF, NonNegativeInteger) -> UFPSF
+                                               -- eg.: f(x)+->f(q*x)
+
+DIFFSPECSF ==> (UFPSSUPF, NonNegativeInteger) -> UFPSSUPF
+                                               -- eg.: f(x)+->f(q*x)
+
+-- the constant term for the inhomogeneous case
+
+DIFFSPEC1 ==> UFPSF
+
+DIFFSPEC1F ==> UFPSSUPF
+
+DIFFSPEC1X ==> Symbol -> EXPRR
+
+@
+
+\subsubsection{Streams}\label{sec:streams}
+
+In this section we define some functions that provide streams for
+[[HermitePade]].
+
+The following three functions transform a partition [[l]] into a product of
+derivatives of [[f]], using the given operators. We need to provide the same
+functionality for expressions, series and series with a transcendental element.
+Only for expressions we do not provide a version using the Hadamard product,
+although it would be quite easy to define an appropriate operator on
+expressions.
+
+A partition $(\lambda_1^{p_1},\lambda_2^{p_2},\dots)$ is transformed into the
+expression $(f^{(\lambda_1-1)})^{p_1}(f^{(\lambda_2-1)})^{p_2}\cdots$, i.e.,
+the size of the part is interpreted as derivative, the exponent as power.
+
+<<implementation: Guess - Hermite-Pade - Streams>>=
+termAsEXPRR(f: EXPRR, xx: Symbol, l: List Integer, 
+            DX: DIFFSPECX, D1X: DIFFSPEC1X): EXPRR ==
+    if empty? l then D1X(xx)
+    else
+        ll: List List Integer := powers(l)$Partition
+
+        fl: List EXPRR := [DX(f, xx, (first part-1)::NonNegativeInteger)
+                           ** second(part)::NNI for part in ll]
+        reduce(_*, fl)
+
+termAsUFPSF(f: UFPSF, l: List Integer, DS: DIFFSPECS, D1: DIFFSPEC1): UFPSF ==
+    if empty? l then D1
+    else
+        ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+        fl: List UFPSF := [DS(f, (first part -1)::NonNegativeInteger) _
+                           ** second(part)::NNI for part in ll]
+
+        reduce(_*, fl)
+
+-- returns \prod f^(l.i), but using the Hadamard product
+termAsUFPSF2(f: UFPSF, l: List Integer, 
+             DS: DIFFSPECS, D1: DIFFSPEC1): UFPSF ==
+    if empty? l then D1
+    else
+        ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+        fl: List UFPSF 
+            := [map(#1** second(part)::NNI, DS(f, (first part -1)::NNI)) _
+                for part in ll]
+
+        reduce(hadamard$UFPS1(F), fl)
+
+
+termAsUFPSSUPF(f: UFPSSUPF, l: List Integer, 
+                     DSF: DIFFSPECSF, D1F: DIFFSPEC1F): UFPSSUPF ==
+    if empty? l then D1F
+    else
+        ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+        fl: List UFPSSUPF
+           := [DSF(f, (first part -1)::NonNegativeInteger)
+               ** second(part)::NNI for part in ll]
+
+        reduce(_*, fl)
+
+
+-- returns \prod f^(l.i), but using the Hadamard product
+termAsUFPSSUPF2(f: UFPSSUPF, l: List Integer, 
+                DSF: DIFFSPECSF, D1F: DIFFSPEC1F): UFPSSUPF ==
+    if empty? l then D1F
+    else
+        ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+        fl: List UFPSSUPF 
+           := [map(#1 ** second(part)::NNI, DSF(f, (first part -1)::NNI)) _
+               for part in ll]
+
+        reduce(hadamard$UFPS1(SUP F), fl)
+
+@
+%$
+
+It is not clear whether we should \lq prefer\rq\ shifting and differentiation over
+powering. Currently, we produce the stream
+\[
+  \begin{array}{rrrrrrrrr}
+    \emptyset& 1& 11 & 2 & 111& 2 1 & 3  & 1111\\
+            1& f& f^2& f'& f^3& f f'& f''& f^4 &\dots  
+  \end{array}
+\]
+
+Maybe it would be better to produce
+\[
+  \begin{array}{rrrrrrrrr}
+    \emptyset& 1& 2&  11 & 3  & 21  & 111& 4\\
+    1& f& f'& f^2& f''& f f'& f^3& f''' &\dots 
+  \end{array}
+\]
+instead, i.e., to leave the partitions unconjugated. Note however, that
+shifting and differentiation decrease the number of valid terms, while powering
+does not.
+
+Note that we conjugate all partitions at the very end of the following
+procedure\dots
+
+<<implementation: Guess - Hermite-Pade - Streams>>=
+FilteredPartitionStream(options: LGOPT): Stream List Integer ==
+    maxD := 1+maxDerivative(options)$GOPT0
+    maxP := maxPower(options)$GOPT0
+
+    if maxD > 0 and maxP > -1 then
+        s := partitions(maxD, maxP)$PartitionsAndPermutations
+    else
+        s1: Stream Integer := generate(inc, 1)$Stream(Integer)
+        s2: Stream Stream List Integer 
+           := map(partitions(#1)$PartitionsAndPermutations, s1)
+                 $StreamFunctions2(Integer, Stream List Integer)
+        s3: Stream List Integer 
+           := concat(s2)$StreamFunctions1(List Integer)
+
+--        s := cons([],
+--                  select(((maxD = 0) or (first #1 <= maxD)) _
+--                     and ((maxP = -1) or (# #1 <= maxP)), s3))
+
+        s := cons([],
+                  select(((maxD = 0) or (# #1 <= maxD)) _
+                     and ((maxP = -1) or (first #1 <= maxP)), s3))
+
+    s := conjugates(s)$PartitionsAndPermutations
+    if homogeneous(options)$GOPT0 then rest s else s
+
+-- for functions
+ADEguessStream(f: UFPSF, partitions: Stream List Integer, 
+               DS: DIFFSPECS, D1: DIFFSPEC1): Stream UFPSF ==
+    map(termAsUFPSF(f, #1, DS, D1), partitions)
+       $StreamFunctions2(List Integer, UFPSF)
+
+-- for coefficients, i.e., using the Hadamard product
+ADEguessStream2(f: UFPSF, partitions: Stream List Integer, 
+                DS: DIFFSPECS, D1: DIFFSPEC1): Stream UFPSF ==
+    map(termAsUFPSF2(f, #1, DS, D1), partitions)
+       $StreamFunctions2(List Integer, UFPSF)
+
+@
+%$
+
+The entries of the following stream indicate how many terms we loose when
+applying one of the power and shift or differentiation operators. More
+precisely, the $n$\textsuperscript{th} entry of the stream takes into account
+all partitions up to index $n$. Thus, the entries of the stream are weakly
+increasing.
+
+<<implementation: Guess - Hermite-Pade - Streams>>=       
+ADEdegreeStream(partitions: Stream List Integer): Stream NNI ==
+    scan(0, max((if empty? #1 then 0 else (first #1 - 1)::NNI), #2),
+         partitions)$StreamFunctions2(List Integer, NNI)
+
+ADEtestStream(f: UFPSSUPF, partitions: Stream List Integer, 
+              DSF: DIFFSPECSF, D1F: DIFFSPEC1F): Stream UFPSSUPF ==
+    map(termAsUFPSSUPF(f, #1, DSF, D1F), partitions)
+       $StreamFunctions2(List Integer, UFPSSUPF)
+
+ADEtestStream2(f: UFPSSUPF, partitions: Stream List Integer, 
+              DSF: DIFFSPECSF, D1F: DIFFSPEC1F): Stream UFPSSUPF ==
+    map(termAsUFPSSUPF2(f, #1, DSF, D1F), partitions)
+       $StreamFunctions2(List Integer, UFPSSUPF)
+
+ADEEXPRRStream(f: EXPRR, xx: Symbol, partitions: Stream List Integer, 
+               DX: DIFFSPECX, D1X: DIFFSPEC1X): Stream EXPRR ==
+    map(termAsEXPRR(f, xx, #1, DX, D1X), partitions)
+       $StreamFunctions2(List Integer, EXPRR)
+
+@
+\subsubsection{Operators}
+
+We need to define operators that transform series for differentiation and
+shifting. We also provide operators for $q$-analogs. The functionality
+corresponding to powering and taking the Hadamard product if provided by the
+streams, see Section~\ref{sec:streams}.
+
+We have to provide each operator in three versions: 
+\begin{itemize}
+\item for expressions,
+\item for series, and
+\item for series with an additional transcendental element.
+\end{itemize}
+
+The latter makes it possible to detect lazily whether a computed coefficient of
+a series is valid or not.
+
+Furthermore, we have to define for each operator how to extract the coefficient
+of $x^k$ in $z^l f(x)$, where multiplication with $z$ is defined depending on
+the operator. Again, it is necessary to provide this functionality for
+expressions, series and series with a transcendental element.
+
+Finally, we define a function that returns the diagonal elements $c_{k,k}$ in
+the expansion $\langle x^k\rangle z f(x) = \sum_{i=0}^k c_{k,i} \langle x^i\rangle f(x)$,
+and an expression that represents the constant term for the inhomogeneous case.
+
+\paragraph{The Differentiation Setting} In this setting, we have $z f(x) := x
+f(x)$. 
+
+<<implementation: Guess - Hermite-Pade - Operators>>=
+diffDX: DIFFSPECX
+diffDX(expr, x, n) == D(expr, x, n)
+
+diffDS: DIFFSPECS
+diffDS(s, n) == D(s, n)
+
+diffDSF: DIFFSPECSF
+diffDSF(s, n) == 
+-- I have to help the compiler here a little to choose the right signature...
+    if SUP F has _*: (NonNegativeInteger, SUP F) -> SUP F
+    then D(s, n)
+
+@
+
+The next three functions extract the coefficient of $x^k$ in $z^l f(x)$. Only,
+for expressions, we rather need $\sum_{k\ge0} \langle x^k\rangle z^l f(x)$,
+i.e., the function itself, which is by definition equal to $x^l f(x)$.
+
+<<implementation: Guess - Hermite-Pade - Operators>>=
+diffAX: DIFFSPECAX
+diffAX(l: NNI, x: Symbol, f: EXPRR): EXPRR ==
+    (x::EXPRR)**l * f
+
+diffA: DIFFSPECA
+diffA(k: NNI, l: NNI, f: SUP S): S ==
+    DiffAction(k, l, f)$FFFG(S, SUP S)
+
+diffAF: DIFFSPECAF
+diffAF(k: NNI, l: NNI, f: UFPSSUPF): SUP F ==
+    DiffAction(k, l, f)$FFFG(SUP F, UFPSSUPF)
+
+diffC: DIFFSPECC
+diffC(total: NNI): List S == DiffC(total)$FFFG(S, SUP S)
+
+diff1X: DIFFSPEC1X
+diff1X(x: Symbol)== 1$EXPRR
+
+diffHP options == 
+    if displayAsGF(options)$GOPT0 then
+        partitions := FilteredPartitionStream options
+        [ADEguessStream(#1, partitions, diffDS, 1$UFPSF), _
+         ADEdegreeStream partitions, _
+         ADEtestStream(#1, partitions, diffDSF, 1$UFPSSUPF), _
+         ADEEXPRRStream(#1, #2, partitions, diffDX, diff1X), _
+         diffA, diffAF, diffAX, diffC]$HPSPEC
+    else
+        error "Guess: guessADE supports only displayAsGF"
+
+@
+
+\paragraph{$q$-dilation} In this setting, we also have $z f(x) := x f(x)$,
+therefore we can reuse some of the functions of the previous paragraph.
+Differentiation is defined by $D_q f(x, q) = f(qx, q)$.
+
+<<implementation: Guess - Hermite-Pade - Operators>>=
+if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+    qDiffDX(q: Symbol, expr: EXPRR, x: Symbol, n: NonNegativeInteger): EXPRR ==
+        eval(expr, x::EXPRR, (q::EXPRR)**n*x::EXPRR)
+
+    qDiffDS(q: Symbol, s: UFPSF, n: NonNegativeInteger): UFPSF ==
+        multiplyCoefficients((q::F)**((n*#1)::NonNegativeInteger), s)
+
+    qDiffDSF(q: Symbol, s: UFPSSUPF, n: NonNegativeInteger): UFPSSUPF ==
+        multiplyCoefficients((q::F::SUP F)**((n*#1)::NonNegativeInteger), s)
+
+    diffHP(q: Symbol): (LGOPT -> HPSPEC) == 
+        if displayAsGF(#1)$GOPT0 then
+            partitions := FilteredPartitionStream #1
+            [ADEguessStream(#1, partitions, qDiffDS(q, #1, #2), 1$UFPSF), _
+             repeating([0$NNI])$Stream(NNI), _
+             ADEtestStream(#1, partitions, qDiffDSF(q, #1, #2), 1$UFPSSUPF), _
+             ADEEXPRRStream(#1, #2, partitions, qDiffDX(q, #1, #2, #3), diff1X), _
+             diffA, diffAF, diffAX, diffC]$HPSPEC
+        else
+            error "Guess: guessADE supports only displayAsGF"
+
+@
+
+\paragraph{Shifting} The shift operator transforms a sequence $u(k)$ into
+$u(k+1)$. We also provide operators [[ShiftSXGF]], [[ShiftAXGF]] that act on
+the power series, as long as no powering is involved. In this case, shifting
+transforms $f(x)$ into $\frac{f(x)-f(0)}{x}$.
+
+Multiplication with $z$ transforms the coefficients $u(n)$ of the series into
+$z u(n) := n u(n)$. The description in terms of power series is given by
+$xDf(x)$.
+
+% The coefficients of $x^n$ are $1, f(n), f(n+1), f(n)^2, f(n)f(n+1),\dots$
+% What does this remark mean?
+<<implementation: Guess - Hermite-Pade - Operators>>=
+ShiftSX(expr: EXPRR, x: Symbol, n: NNI): EXPRR == 
+    eval(expr, x::EXPRR, x::EXPRR+n::EXPRR)
+
+ShiftSXGF(expr: EXPRR, x: Symbol, n: NNI): EXPRR == 
+    if zero? n then expr
+    else
+        l := [eval(D(expr, x, i)/factorial(i)::EXPRR, x::EXPRR, 0$EXPRR)_
+              *(x::EXPRR)**i for i in 0..n-1]
+        (expr-reduce(_+, l))/(x::EXPRR**n)
+
+ShiftSS(s:UFPSF, n:NNI): UFPSF == 
+    ((quoByVar #1)**n)$MappingPackage1(UFPSF) (s)
+
+ShiftSF(s:UFPSSUPF, n: NNI):UFPSSUPF == 
+    ((quoByVar #1)**n)$MappingPackage1(UFPSSUPF) (s)
+
+@
+%$
+
+As before, next three functions extract the coefficient of $x^k$ in $z^l f(x)$.
+
+<<implementation: Guess - Hermite-Pade - Operators>>=
+ShiftAX(l: NNI, n: Symbol, f: EXPRR): EXPRR == 
+    n::EXPRR**l * f
+
+ShiftAXGF(l: NNI, x: Symbol, f: EXPRR): EXPRR == 
+-- I need to help the compiler here, unfortunately
+      if zero? l then f
+      else
+          s := [stirling2(l, i)$IntegerCombinatoricFunctions(Integer)::EXPRR _
+                * (x::EXPRR)**i*D(f, x, i) for i in 1..l]
+          reduce(_+, s)
+
+ShiftA(k: NNI, l: NNI, f: SUP S): S == 
+    ShiftAction(k, l, f)$FFFG(S, SUP S)
+
+ShiftAF(k: NNI, l: NNI, f: UFPSSUPF): SUP F == 
+    ShiftAction(k, l, f)$FFFG(SUP F, UFPSSUPF)
+
+ShiftC(total: NNI): List S == 
+    ShiftC(total)$FFFG(S, SUP S)
+
+shiftHP options == 
+    partitions := FilteredPartitionStream options
+    if displayAsGF(options)$GOPT0 then
+        if maxPower(options)$GOPT0 = 1 then
+            [ADEguessStream(#1, partitions, ShiftSS, (1-monomial(1,1))**(-1)),_
+             ADEdegreeStream partitions, _
+             ADEtestStream(#1, partitions, ShiftSF, (1-monomial(1,1))**(-1)), _
+             ADEEXPRRStream(#1, #2, partitions, ShiftSXGF, 1/(1-#1::EXPRR)), _
+             ShiftA, ShiftAF, ShiftAXGF, ShiftC]$HPSPEC
+       else
+            error "Guess: no support for the Shift operator with displayAsGF _
+                   and maxPower>1"
+    else
+        [ADEguessStream2(#1, partitions, ShiftSS, (1-monomial(1,1))**(-1)), _
+         ADEdegreeStream partitions, _
+         ADEtestStream2(#1, partitions, ShiftSF, (1-monomial(1,1))**(-1)), _
+         ADEEXPRRStream(#1, #2, partitions, ShiftSX, diff1X), _
+         ShiftA, ShiftAF, ShiftAX, ShiftC]$HPSPEC
+
+@
+
+\paragraph{$q$-Shifting} The $q$-shift also transforms $u(n)$ into $u(n+1)$,
+and we can reuse the corresponding functions of the previous paragraph.
+However, this time multiplication with $z$ is defined differently: the
+coefficient of $x^k$ in $z u(n)$ is $q^n u(n)$. We do not define the
+corresponding functionality for power series.
+
+%The coefficients of $x^n$ are $1, f(n), f(n+1), f(n)^2, f(n)f(n+1),\dots$
+% What does this remark mean?
+<<implementation: Guess - Hermite-Pade - Operators>>=
+if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+    qShiftAX(q: Symbol, l: NNI, n: Symbol, f: EXPRR): EXPRR == 
+        (q::EXPRR)**(l*n::EXPRR) * f
+
+    qShiftA(q: Symbol, k: NNI, l: NNI, f: SUP S): S ==
+        qShiftAction(q::S, k, l, f)$FFFG(S, SUP S)
+
+    qShiftAF(q: Symbol, k: NNI, l: NNI, f: UFPSSUPF): SUP F ==
+        qShiftAction(q::F::SUP(F), k, l, f)$FFFG(SUP F, UFPSSUPF)
+
+    qShiftC(q: Symbol, total: NNI): List S == 
+        qShiftC(q::S, total)$FFFG(S, SUP S)
+
+    shiftHP(q: Symbol): (LGOPT -> HPSPEC) == 
+        partitions := FilteredPartitionStream #1
+        if displayAsGF(#1)$GOPT0 then
+            error "Guess: no support for the qShift operator with displayAsGF"
+        else
+            [ADEguessStream2(#1, partitions, ShiftSS, _
+                             (1-monomial(1,1))**(-1)), _
+             ADEdegreeStream partitions, _
+             ADEtestStream2(#1, partitions, ShiftSF, _
+                            (1-monomial(1,1))**(-1)), _
+             ADEEXPRRStream(#1, #2, partitions, ShiftSX, diff1X), _
+             qShiftA(q, #1, #2, #3), qShiftAF(q, #1, #2, #3), _
+             qShiftAX(q, #1, #2, #3), qShiftC(q, #1)]$HPSPEC
+
+@
+%$
+\paragraph{Extend the action to polynomials}
+
+The following operation uses the given action of $z$ on a function to multiply
+a $f$ with a polynomial.
+
+<<implementation: Guess - Hermite-Pade - Operators>>=
+makeEXPRR(DAX: DIFFSPECAX, x: Symbol, p: SUP F, expr: EXPRR): EXPRR ==
+    if zero? p then 0$EXPRR
+    else
+        coerce(leadingCoefficient p)::EXPRR * DAX(degree p, x, expr) _
+        + makeEXPRR(DAX, x, reductum p, expr)
+
+@
+%$
+
+\subsubsection{Utilities}
+
+[[list2UFPSF]] and [[list2UFPSSUPF]] transform the list passed to the guessing
+functions into a series. One might be tempted to transform the list into a
+polynomial instead, but the present approach makes computing powers and
+derivatives much cheaper, since, because of laziness, only coefficients that
+are actually used are computed.
+
+The second of the two procedures augments the list with a transcendental
+element. This way we can easily check whether a coefficient is valid or not: if
+it contains the transcendental element, it depends on data we do not have. In
+other words, this transcendental element simply represents the $O(x^d)$, when
+$d$ is the number of elements in the list.
+
+<<implementation: Guess - Hermite-Pade - Utilities>>=
+list2UFPSF(list: List F): UFPSF == series(list::Stream F)$UFPSF
+
+list2UFPSSUPF(list: List F): UFPSSUPF == 
+    l := [e::SUP(F) for e in list for i in 0..]::Stream SUP F
+    series(l)$UFPSSUPF + monomial(monomial(1,1)$SUP(F), #list)$UFPSSUPF
+
+@
+
+[[SUPF2SUPSUPF]] interprets each coefficient as a univariate polynomial.
+
+<<implementation: Guess - Hermite-Pade - Utilities>>=
+SUPF2SUPSUPF(p: SUP F): SUP SUP F ==
+    map(#1::SUP F, p)$SparseUnivariatePolynomialFunctions2(F, SUP F)
+
+@
+
+[[getListSUPF]] returns the first [[o]] elements of the stream, each truncated
+after degree [[deg]]. 
+
+<<implementation: Guess - Hermite-Pade - Utilities>>=
+UFPSF2SUPF(f: UFPSF, deg: NNI): SUP F == 
+    makeSUP univariatePolynomial(f, deg)
+
+getListSUPF(s: Stream UFPSF, o: NNI, deg: NNI): List SUP F ==
+    map(UFPSF2SUPF(#1, deg), entries complete first(s, o))
+       $ListFunctions2(UFPSF, SUP F)
+
+S2EXPRR(s: S): EXPRR ==
+    if F is S then 
+        coerce(s pretend F)@EXPRR
+    else if F is Fraction S then
+        coerce(s::Fraction(S))@EXPRR
+    else error "Type parameter F should be either equal to S or equal _
+                to Fraction S"
+
+<<implementation: Guess - guessInterpolate>>
+<<implementation: Guess - guessInterpolate2>>
+<<implementation: Guess - testInterpolant>>
+@
+%$
+
+[[guessInterpolate]] calls the appropriate [[generalInterpolation]] from
+[[FFFG]], for one vector of degrees, namely [[eta]].
+
+<<implementation: Guess - guessInterpolate>>=
+guessInterpolate(guessList: List SUP F, eta: List NNI, D: HPSPEC)
+                : Matrix SUP S ==
+    if F is S then 
+        vguessList: Vector SUP S := vector(guessList pretend List(SUP(S)))
+        generalInterpolation((D.C)(reduce(_+, eta)), D.A, 
+                             vguessList, eta)$FFFG(S, SUP S)
+    else if F is Fraction S then
+        vguessListF: Vector SUP F := vector(guessList)
+        generalInterpolation((D.C)(reduce(_+, eta)), D.A, 
+                             vguessListF, eta)$FFFGF(S, SUP S, SUP F)
+
+    else error "Type parameter F should be either equal to S or equal _
+                to Fraction S"
+@
+
+[[guessInterpolate2]] calls the appropriate [[generalInterpolation]] from
+[[FFFG]], for all degree vectors with given [[sumEta]] and [[maxEta]].
+
+<<implementation: Guess - guessInterpolate2>>=
+guessInterpolate2(guessList: List SUP F, 
+                  sumEta: NNI, maxEta: NNI, 
+                  D: HPSPEC): Stream Matrix SUP S ==
+    if F is S then 
+        vguessList: Vector SUP S := vector(guessList pretend List(SUP(S)))
+        generalInterpolation((D.C)(sumEta), D.A, 
+                             vguessList, sumEta, maxEta)
+                            $FFFG(S, SUP S)
+    else if F is Fraction S then
+        vguessListF: Vector SUP F := vector(guessList)
+        generalInterpolation((D.C)(sumEta), D.A, 
+                             vguessListF, sumEta, maxEta)
+                            $FFFGF(S, SUP S, SUP F)
+
+    else error "Type parameter F should be either equal to S or equal _
+                to Fraction S"
+@
+
+[[testInterpolant]] checks whether p is really a solution.
+<<implementation: Guess - testInterpolant>>=
+testInterpolant(resi: List SUP S, 
+                list: List F,
+                testList: List UFPSSUPF, 
+                exprList: List EXPRR,
+                initials: List EXPRR,
+                guessDegree: NNI,
+                D: HPSPEC, 
+                dummy: Symbol, op: BasicOperator, options: LGOPT)
+               : Union("failed", Record(function: EXPRR, order: NNI)) ==
+@
+
+First we make sure it is not a solution we should have found already. Note that
+we cannot check this if [[maxDegree]] is set, in which case some initial
+solutions may have been overlooked.
+
+<<implementation: Guess - testInterpolant>>=
+    ((maxDegree(options)$GOPT0 = -1) and 
+     (allDegrees(options)$GOPT0 = false) and 
+     zero?(last resi)) 
+     => return "failed"
+@
+
+Then we check all the coefficients that should be valid.  We want the zero
+solution only, if the function is really zero. Without this test, every
+sequence ending with zero is interpreted as the zero sequence, since the factor
+in front of the only non-vanishing term can cancel everything else.
+
+<<implementation: Guess - testInterpolant>>=
+    nonZeroCoefficient: Integer := 0
+
+    for i in 1..#resi repeat
+        if not zero? resi.i then
+            if zero? nonZeroCoefficient then
+                nonZeroCoefficient := i
+            else 
+                nonZeroCoefficient := 0
+                break
+@
+
+We set [[nonZeroCoefficient]] to the only non zero coefficient or, if there are
+several, it is $0$. It should not happen that all coefficients in [[resi]]
+vanish.
+\begin{verbatim}
+  Check that not all coefficients in [[resi]] can vanish simultaneously.
+\end{verbatim}
+
+<<implementation: Guess - testInterpolant>>=
+    if not zero? nonZeroCoefficient then
+        (freeOf?(exprList.nonZeroCoefficient, name op)) => return "failed"
+
+        for e in list repeat
+            if not zero? e then return "failed"
+@
+
+We first deal with the case that there is only one non-vanishing coefficient in
+[[resi]]. If the only expression in [[exprList]] whose coefficient does not
+vanish does not contain the name of the generating function, or if there is a
+non-zero term in [[list]], we reject the proposed solution.
+
+<<implementation: Guess - testInterpolant>>=
+    else
+        resiSUPF := map(SUPF2SUPSUPF SUPS2SUPF #1, resi)
+                       $ListFunctions2(SUP S, SUP SUP F)
+
+        iterate? := true;
+        for d in guessDegree+1.. repeat
+            c: SUP F := generalCoefficient(D.AF, vector testList, 
+                                           d, vector resiSUPF)
+                                          $FFFG(SUP F, UFPSSUPF)
+
+            if not zero? c then 
+                iterate? := ground? c
+                break
+
+        iterate? => return "failed"
+@
+
+Here we check for each degree [[d]] larger than [[guessDegree]] whether the
+proposed linear combination vanishes. When the first coefficient that does not
+vanish contains the transcendental element we accept the linear combination as
+a solution.
+
+Finally, it seems that we have found a solution. Now we cancel the greatest
+common divisor of the equation. Note that this may take quite some time, it
+seems to be quicker to check [[generalCoefficient]] with the original [[resi]].
+
+If [[S]] is a [[Field]], the [[gcd]] will always be $1$.  Thus, in this case we
+make the result monic.
+
+<<implementation: Guess - testInterpolant>>=
+    g: SUP S
+    if S has Field 
+    then g := leadingCoefficient(find(not zero? #1, reverse resi)::SUP(S))::SUP(S)
+    else g := gcd resi
+    resiF := map(SUPS2SUPF((#1 exquo g)::SUP(S)), resi)
+                $ListFunctions2(SUP S, SUP F)
+
+
+    if debug(options)$GOPT0 then 
+        output(hconcat("trying possible solution ", resiF::OutputForm))
+              $OutputPackage
+
+-- transform each term into an expression
+
+    ex: List EXPRR := [makeEXPRR(D.AX, dummy, p, e) _
+                       for p in resiF for e in exprList]
+
+-- transform the list of expressions into a sum of expressions
+
+    res: EXPRR
+    if displayAsGF(options)$GOPT0 then 
+        res := evalADE(op, dummy, variableName(options)$GOPT0::EXPRR, 
+                       indexName(options)$GOPT0::EXPRR,
+                       numerator reduce(_+, ex), 
+                       reverse initials)
+                      $RecurrenceOperator(Integer, EXPRR)
+        ord: NNI := 0
+-- FIXME: checkResult doesn't really work yet for generating functions
+    else 
+        res := evalRec(op, dummy, indexName(options)$GOPT0::EXPRR, 
+                       indexName(options)$GOPT0::EXPRR,
+                       numerator reduce(_+, ex), 
+                       reverse initials)
+                      $RecurrenceOperator(Integer, EXPRR)
+        ord: NNI := checkResult(res, indexName(options)$GOPT0, _
+                                #list, list, options)
+
+
+    [res, ord]$Record(function: EXPRR, order: NNI)
+
+@
+
+\subsubsection{The main routine}
+
+The following is the main guessing routine, called by all others -- except
+[[guessExpRat]].
+
+<<implementation: Guess - guessHPaux>>=
+guessHPaux(list: List F, D: HPSPEC, options: LGOPT): GUESSRESULT ==
+    reslist: GUESSRESULT := []
+
+    listDegree := #list-1-safety(options)$GOPT0
+    if listDegree < 0 then return reslist
+@
+%$
+
+\sloppypar We do as if we knew only the coefficients up to and including degree
+[[listDegree-safety]]. Thus, if we have less elements of the sequence than
+[[safety]], there remain no elements for guessing.  Originally we demanded to
+have at least two elements for guessing.  However, we want to be able to induce
+from $[c,c]$ that the function equals $c$ with [[safety]] one. This is
+important if we apply, for example, [[guessRat]] recursively. In this case,
+[[listDegree]] equals zero.
+
+<<implementation: Guess - guessHPaux>>=
+    a := functionName(options)$GOPT0
+    op := operator a
+    x := variableName(options)$GOPT0
+    dummy := new$Symbol
+
+    initials: List EXPRR := [coerce(e)@EXPRR for e in list]
+
+@
+%$
+
+We need to create several streams. Let $P$ be the univariate power series whose
+first few elements are given by [[list]]. As an example, consider the
+differentiation setting. In this case, the elements of [[guessS]] consist of
+$P$ differentiated and taken to some power. The elements of [[degreeS]] are
+integers, that tell us how many terms less than in [[list]] are valid in the
+corresponding element of [[guessS]]. The elements of [[testS]] are very similar
+to those of [[guessS]], with the difference that they are derived from $P$ with
+an transcendental element added, which corresponds to $O(x^d)$. Finally, the
+elements of [[exprS]] contain representations of the transformations applied to
+$P$ as expressions.
+
+\begin{verbatim}
+  I am not sure whether it is better to get rid of denominators in [[list]]
+  here or, as I currently do it, only in [[generalInterpolation$FFFG]]. %$
+  If we clear them at here, we cannot take advantage of factors that may appear
+  only after differentiating or powering.
+\end{verbatim}
+
+
+<<implementation: Guess - guessHPaux>>=
+    guessS  := (D.guessStream)(list2UFPSF list)
+    degreeS := D.degreeStream
+    testS   := (D.testStream)(list2UFPSSUPF list)
+    exprS   := (D.exprStream)(op(dummy::EXPRR)::EXPRR, dummy)
+@
+
+We call the number of terms of the linear combination its \emph{order}.  We
+consider linear combinations of at least two terms, since otherwise the
+function would have to vanish identically\dots
+
+When proceeding in the stream [[guessS]], it may happen that we loose valid
+terms. For example, when trying to find a linear ordinary differential
+equation, we are looking for a linear combination of $f, f^\prime,
+f^{\prime\prime}, \dots$. Suppose [[listDegree]] equals $2$, i.e. we have
+\begin{verbatim}
+  f                &= l_0 + l_1 x + l_2 x^2\\
+  f^\prime         &= l_1 + 2l_2 x\\
+  f^{\prime\prime} &= 2l_2.    
+\end{verbatim}
+Thus, each time we differentiate the series, we loose one term for guessing.
+Therefore, we cannot use the coefficient of $x^2$ of $f^{\prime\prime}$ for
+generating a linear combination. [[guessDegree]] contains the degree up to
+which all the generated series are correct, taking into account [[safety]].
+
+<<implementation: Guess - guessHPaux>>=
+    iterate?: Boolean := false -- this is necessary because the compiler
+                               -- doesn't understand => "iterate" properly
+                               -- the latter just leaves the current block, it
+                               -- seems 
+    for o in 2.. repeat
+        empty? rest(guessS, (o-1)::NNI) => break
+        guessDegree: Integer := listDegree-(degreeS.o)::Integer
+        guessDegree < 0 => break
+        if debug(options)$GOPT0 then 
+            output(hconcat("Trying order ", o::OutputForm))$OutputPackage
+            output(hconcat("guessDegree is ", guessDegree::OutputForm))
+                  $OutputPackage
+@ 
+%$"
+
+We now have to distinguish between the case where we try all combination of
+degrees and the case where we try only an (nearly) evenly distributed vector of
+degrees.
+
+In the first case, [[guessInterpolate2]] is going to look at all degree vectors
+with [[o]] elements with total degree [[guessDegree+1]].  We give up as soon as
+the order [[o]] is greater than the number of available terms plus one. In the
+extreme case, i.e., when [[o=guessDegree+2]], we allow for example constant
+coefficients for all terms of the linear combination. It seems that it is a bit
+arbitrary at what point we stop, however, we would like to be consistent with
+the evenly distributed case.
+
+<<implementation: Guess - guessHPaux>>=
+        if allDegrees(options)$GOPT0 then
+            (o > guessDegree+2) => return reslist
+
+            maxEta: Integer := 1+maxDegree(options)$GOPT0
+            if maxEta = 0 
+            then maxEta := guessDegree+1
+        else
+@
+
+In the second case, we first compute the number of parameters available for
+determining the coefficient polynomials. We have to take care of the fact, that
+HermitePade produces solutions with sum of degrees being one more than the sum
+of elements in [[eta]].
+
+<<implementation: Guess - guessHPaux>>=
+            maxParams := divide(guessDegree::NNI+1, o)
+            if debug(options)$GOPT0 
+            then output(hconcat("maxParams: ", maxParams::OutputForm))
+                       $OutputPackage
+@
+
+If we do not have enough parameters, we give up. We allow for at most one zero
+entry in the degree vector, because then there is one column that allows at
+least a constant term in each entry.
+
+<<implementation: Guess - guessHPaux>>=
+            if maxParams.quotient = 0 and maxParams.remainder < o-1 
+            then return reslist
+@
+
+If [[maxDegree]] is set, we skip the first few partitions, unless we cannot
+increase the order anymore.
+\begin{verbatim}
+  I have no satisfactory way to determine whether we can increase the order or
+  not.
+\end{verbatim}
+
+<<implementation: Guess - guessHPaux>>=
+            if ((maxDegree(options)$GOPT0 ~= -1) and
+                (maxDegree(options)$GOPT0 < maxParams.quotient)) and
+                not (empty? rest(guessS, o) or
+                     ((newGuessDegree := listDegree-(degreeS.(o+1))::Integer)
+                          < 0) or
+                      (((newMaxParams := divide(newGuessDegree::NNI+1, o+1))
+                          .quotient = 0) and
+                       (newMaxParams.remainder < o)))
+            then iterate? := true
+            else if ((maxDegree(options)$GOPT0 ~= -1) and
+                     (maxParams.quotient > maxDegree(options)$GOPT0))
+                 then
+                     guessDegree := o*(1+maxDegree(options)$GOPT0)-2
+                     eta: List NNI
+                         := [(if i < o    _
+                               then maxDegree(options)$GOPT0 + 1   _
+                               else maxDegree(options)$GOPT0)::NNI _
+                             for i in 1..o]
+                 else eta: List NNI
+                          := [(if i <= maxParams.remainder   _
+                               then maxParams.quotient + 1   _
+                               else maxParams.quotient)::NNI for i in 1..o]
+@
+
+We distribute the parameters as evenly as possible.  Is it better to have
+higher degrees at the end or at the beginning?
+
+It remains to prepare [[guessList]], which is the list of [[o]] power series
+polynomials truncated after degree [[guessDegree]]. Then we can call
+HermitePade.
+
+\begin{verbatim}
+  [[maxDegree]] should be handled differently, maybe: we should only pass as
+  many coefficients to [[FFFG]] as [[maxDegree]] implies! That is, if we cannot
+  increase the order anymore, we should decrease [[guessDegree]] to %
+  $o\cdot [[maxDegree]] - 2$ and set [[eta]] accordingly.  I might have to take
+  care of [[allDegrees]], too.
+\end{verbatim}
+
+<<implementation: Guess - guessHPaux>>=
+        if iterate? 
+        then 
+            iterate? := false
+            if debug(options)$GOPT0 then output("iterating")$OutputPackage
+        else 
+            guessList: List SUP F    := getListSUPF(guessS, o, guessDegree::NNI)
+            testList:  List UFPSSUPF := entries complete first(testS, o)
+            exprList:  List EXPRR    := entries complete first(exprS, o)
+
+            if debug(options)$GOPT0 then 
+                output("The list of expressions is")$OutputPackage
+                output(exprList::OutputForm)$OutputPackage
+
+            if allDegrees(options)$GOPT0 then
+                MS: Stream Matrix SUP S := guessInterpolate2(guessList, 
+                                                             guessDegree::NNI+1,
+                                                             maxEta::NNI, D)
+                repeat
+                    (empty? MS) => break
+                    M := first MS
+
+                    for i in 1..o repeat
+                        res := testInterpolant(entries column(M, i), 
+                                               list,
+                                               testList, 
+                                               exprList,
+                                               initials,
+                                               guessDegree::NNI, 
+                                               D, dummy, op, options)
+
+                        (res case "failed") => "iterate"
+
+                        if not member?(res, reslist) 
+                        then reslist := cons(res, reslist)
+
+                        if one(options)$GOPT0 then return reslist 
+
+                    MS := rest MS
+            else
+                M: Matrix SUP S := guessInterpolate(guessList, eta, D)
+
+                for i in 1..o repeat
+                    res := testInterpolant(entries column(M, i), 
+                                           list,
+                                           testList, 
+                                           exprList,
+                                           initials,
+                                           guessDegree::NNI, 
+                                           D, dummy, op, options)
+                    (res case "failed") => "iterate"
+
+                    if not member?(res, reslist) 
+                    then reslist := cons(res, reslist)
+
+                    if one(options)$GOPT0 then return reslist 
+
+    reslist
+
+@
+
+\begin{verbatim}
+  The duplicated block at the end should really go into [[testInterpolant]], I
+  guess. Furthermore, it would be better to remove duplicates already there.
+\end{verbatim}
+
+\subsubsection{Specialisations}
+
+For convenience we provide some specialisations that cover the most common
+situations.
+
+\paragraph{generating functions}
+
+<<implementation: Guess - guessHP>>=
+guessHP(D: LGOPT -> HPSPEC): GUESSER == guessHPaux(#1, D #2, #2)
+
+guessADE(list: List F, options: LGOPT): GUESSRESULT == 
+    opts: LGOPT := cons(displayAsGF(true)$GuessOption, options)
+    guessHPaux(list, diffHP opts, opts)
+
+guessADE(list: List F): GUESSRESULT == guessADE(list, [])
+
+guessAlg(list: List F, options: LGOPT) == 
+    guessADE(list, cons(maxDerivative(0)$GuessOption, options))
+
+guessAlg(list: List F): GUESSRESULT == guessAlg(list, [])
+
+guessHolo(list: List F, options: LGOPT): GUESSRESULT ==
+    guessADE(list, cons(maxPower(1)$GuessOption, options))
+
+guessHolo(list: List F): GUESSRESULT == guessHolo(list, [])
+
+guessPade(list: List F, options: LGOPT): GUESSRESULT ==
+    opts := append(options, [maxDerivative(0)$GuessOption, 
+                             maxPower(1)$GuessOption, 
+                             allDegrees(true)$GuessOption])
+    guessADE(list, opts)
+
+guessPade(list: List F): GUESSRESULT == guessPade(list, [])
+@
+
+\paragraph{$q$-generating functions}
+
+<<implementation: Guess - guessHP>>=
+if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+    guessADE(q: Symbol): GUESSER ==
+        opts: LGOPT := cons(displayAsGF(true)$GuessOption, #2)
+        guessHPaux(#1, (diffHP q)(opts), opts)
+
+@
+%$
+
+\paragraph{coefficients}
+
+<<implementation: Guess - guessHP>>=
+guessRec(list: List F, options: LGOPT): GUESSRESULT == 
+      opts: LGOPT := cons(displayAsGF(false)$GuessOption, options)
+      guessHPaux(list, shiftHP opts, opts)
+
+guessRec(list: List F): GUESSRESULT == guessRec(list, [])
+
+guessPRec(list: List F, options: LGOPT): GUESSRESULT ==
+      guessRec(list, cons(maxPower(1)$GuessOption, options))
+
+guessPRec(list: List F): GUESSRESULT == guessPRec(list, [])
+
+guessRat(list: List F, options: LGOPT): GUESSRESULT ==
+      opts := append(options, [maxShift(0)$GuessOption, 
+                               maxPower(1)$GuessOption, 
+                               allDegrees(true)$GuessOption])
+      guessRec(list, opts)
+
+guessRat(list: List F): GUESSRESULT == guessRat(list, [])
+
+@
+%$
+
+\paragraph{$q$-coefficients}
+
+<<implementation: Guess - guessHP>>=
+if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+    guessRec(q: Symbol): GUESSER ==
+        opts: LGOPT := cons(displayAsGF(false)$GuessOption, #2)
+        guessHPaux(#1, (shiftHP q)(opts), opts)
+
+    guessPRec(q: Symbol): GUESSER ==
+        opts: LGOPT := append([displayAsGF(false)$GuessOption, 
+                               maxPower(1)$GuessOption], #2)
+        guessHPaux(#1, (shiftHP q)(opts), opts)
+
+    guessRat(q: Symbol): GUESSER ==
+        opts := append(#2, [displayAsGF(false)$GuessOption, 
+                            maxShift(0)$GuessOption, 
+                            maxPower(1)$GuessOption, 
+                            allDegrees(true)$GuessOption])
+        guessHPaux(#1, (shiftHP q)(opts), opts)
+
+@
+%$
+
+\subsection{[[guess]] -- applying operators recursively}
+
+The main observation made by Christian Krattenthaler in designing his program
+Rate is the following: it occurs frequently that although a sequence of
+numbers is not generated by a rational function, the sequence of successive
+quotients is.
+
+We slightly extend upon this idea, and apply recursively one or both of the two
+following operators:
+\begin{description}
+\item[$\Delta_n$] the differencing operator, transforming $f(n)$ into
+  $f(n)-f(n-1)$, and
+\item[$Q_n$] the operator that transforms $f(n)$ into $f(n)/f(n-1)$.
+\end{description}
+
+<<implementation: Guess - guess>>=
+guess(list: List F, guessers: List GUESSER, ops: List Symbol, 
+      options: LGOPT): GUESSRESULT ==
+    maxLevel := maxLevel(options)$GOPT0
+    xx := indexName(options)$GOPT0
+    if debug(options)$GOPT0 then
+        output(hconcat("guessing level ", maxLevel::OutputForm))
+              $OutputPackage
+        output(hconcat("guessing ", list::OutputForm))$OutputPackage
+    res: GUESSRESULT := []
+    len := #list :: PositiveInteger
+    if len <= 1 then return res
+
+    for guesser in guessers repeat
+        res := append(guesser(list, options), res)
+
+        if debug(options)$GOPT0 then
+            output(hconcat("res ", res::OutputForm))$OutputPackage
+
+        if one(options)$GOPT0 and not empty? res then return res
+
+    if (maxLevel = 0) then return res
+
+    if member?('guessProduct, ops) and not member?(0$F, list) then
+        prodList: List F := [(list.(i+1))/(list.i) for i in 1..(len-1)]
+
+        if not every?(one?, prodList) then
+            var: Symbol := subscript('p, [len::OutputForm])
+            prodGuess := 
+                [[coerce(list.(guess.order+1)) 
+                  * product(guess.function, _
+                            equation(var, _
+                                     (guess.order)::EXPRR..xx::EXPRR-1)), _
+                  guess.order] _
+                 for guess in guess(prodList, guessers, ops,  
+                                    append([indexName(var)$GuessOption,
+                                            maxLevel(maxLevel-1)
+                                                    $GuessOption],
+                                           options))$%]
+
+            if debug(options)$GOPT0 then
+                output(hconcat("prodGuess "::OutputForm, 
+                               prodGuess::OutputForm))
+                      $OutputPackage
+
+            for guess in prodGuess 
+                    | not any?(guess.function = #1.function, res) repeat
+                res := cons(guess, res)
+
+    if one(options)$GOPT0 and not empty? res then return res
+
+    if member?('guessSum, ops) then
+        sumList: List F := [(list.(i+1))-(list.i) for i in 1..(len-1)]
+
+        if not every?(#1=sumList.1, sumList) then
+            var: Symbol := subscript('s, [len::OutputForm])
+            sumGuess := 
+                [[coerce(list.(guess.order+1)) _
+                  + summation(guess.function, _
+                              equation(var, _
+                                       (guess.order)::EXPRR..xx::EXPRR-1)),_
+                  guess.order] _
+                 for guess in guess(sumList, guessers, ops,
+                                    append([indexName(var)$GuessOption,
+                                            maxLevel(maxLevel-1)
+                                                    $GuessOption],
+                                           options))$%]
+
+            for guess in sumGuess 
+                    | not any?(guess.function = #1.function, res) repeat
+                res := cons(guess, res)
+
+    res
+
+guess(list: List F): GUESSRESULT == 
+    guess(list, [guessADE$%, guessRec$%], ['guessProduct, 'guessSum], [])
+
+guess(list: List F, options: LGOPT): GUESSRESULT == 
+    guess(list, [guessADE$%, guessRat$%], ['guessProduct, 'guessSum], 
+          options)
+
+guess(list: List F, guessers: List GUESSER, ops: List Symbol)
+     : GUESSRESULT == 
+    guess(list, guessers, ops, [])
+
+@
+<<GUESS.dotabb>>=
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"RECOP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=RECOP"]
+"GUESS" -> "RECOP"  
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESSAN GuessAlgebraicNumber}
+\pagehead{GuessAlgebraicNumber}{GUESSAN}
+\pagepic{ps/v104guessalgebraicnumber.ps}{GUESSAN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESSAN GuessAlgebraicNumber>>=
+)abbrev package GUESSAN GuessAlgebraicNumber
+++ Description:
+++ This package exports guessing of sequences of rational functions
+GuessAlgebraicNumber() == Guess(AlgebraicNumber, AlgebraicNumber, 
+                           Expression Integer, 
+                           AlgebraicNumber,
+                           id$MappingPackage1(AlgebraicNumber), 
+                           coerce$Expression(Integer))
+
+@
+<<GUESSAN.dotabb>>=
+"GUESSAN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESSAN"]
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"GUESSAN" -> "GUESS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESSF GuessFinite}
+\pagehead{GuessFinite}{GUESSF}
+\pagepic{ps/v104guessfinite.ps}{GUESSF}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESSF GuessFinite>>=
+)abbrev package GUESSF GuessFinite
+++ Description:
+++ This package exports guessing of sequences of numbers in a finite field
+GuessFinite(F:Join(FiniteFieldCategory, ConvertibleTo Integer)) ==
+  Guess(F, F, Expression Integer, Integer, coerce$F,
+        F2EXPRR$GuessFiniteFunctions(F))
+
+@
+<<GUESSF.dotabb>>=
+"GUESSF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESSF"]
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"GUESSF1" -> "GUESS" 
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESSF1 GuessFiniteFunctions}
+\pagehead{GuessFiniteFunctions}{GUESSF1}
+\pagepic{ps/v104guessfinitefunctions.ps}{GUESSF1}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESSF1 GuessFiniteFunctions>>=
+)abbrev package GUESSF1 GuessFiniteFunctions
+++ Description:
+++ This package exports guessing of sequences of numbers in a finite field
+GuessFiniteFunctions(F:Join(FiniteFieldCategory, ConvertibleTo Integer)):
+  Exports == Implementation where
+
+    EXPRR ==> Expression Integer
+
+    Exports == with
+
+      F2EXPRR: F -> EXPRR
+
+    Implementation == add
+
+      F2EXPRR(p: F): EXPRR == convert(p)@Integer::EXPRR
+
+@
+<<GUESSF1.dotabb>>=
+"GUESSF1" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESSF1"]
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"GUESSF1" -> "GUESS" 
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESSINT GuessInteger}
+\pagehead{GuessInteger}{GUESSINT}
+\pagepic{ps/v104guessinteger.ps}{GUESSINT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESSINT GuessInteger>>=
+-- concerning algebraic functions, it may make sense to look at A.J.van der
+-- Poorten, Power Series Representing Algebraic Functions, Section 6.
+)abbrev package GUESSINT GuessInteger
+++ Description:
+++ This package exports guessing of sequences of rational numbers
+GuessInteger() == Guess(Fraction Integer, Integer, Expression Integer, 
+                     Fraction Integer,
+                     id$MappingPackage1(Fraction Integer), 
+                     coerce$Expression(Integer))
+
+@
+<<GUESSINT.dotabb>>=
+"GUESSINT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESSINT"]
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"GUESSINT" -> "GUESS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GOPT0 GuessOptionFunctions0}
+\pagehead{GuessOptionFunctions0}{GOPT0}
+\pagepic{ps/v104guessoptionfunctions0.ps}{GOPT0}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GOPT0 GuessOptionFunctions0>>=
+)abbrev package GOPT0 GuessOptionFunctions0
+++ Author: Martin Rubey 
+++ Description: GuessOptionFunctions0 provides operations that extract the
+++ values of options for \spadtype{Guess}.
+GuessOptionFunctions0(): Exports == Implementation where 
+
+  LGOPT ==> List GuessOption
+
+  Exports == SetCategory with
+
+    maxLevel: LGOPT -> Integer
+      ++ maxLevel returns the specified maxLevel or -1 as default.
+
+    maxPower: LGOPT -> Integer
+      ++ maxPower returns the specified maxPower or -1 as default.
+
+    maxDerivative: LGOPT -> Integer
+      ++ maxDerivative returns the specified maxDerivative or -1 as default.
+
+    maxShift: LGOPT -> Integer
+      ++ maxShift returns the specified maxShift or -1 as default.
+
+    maxDegree: LGOPT -> Integer
+      ++ maxDegree returns the specified maxDegree or -1 as default.
+
+    allDegrees: LGOPT -> Boolean
+      ++ allDegrees returns whether all possibilities of the degree vector
+      ++ should be tried, the default being false.
+
+    safety: LGOPT -> NonNegativeInteger
+      ++ safety returns the specified safety or 1 as default.
+
+    one: LGOPT -> Boolean
+      ++ one returns whether we need only one solution, default being true.
+
+    homogeneous: LGOPT -> Boolean
+      ++ homogeneous returns whether we allow only homogeneous algebraic
+      ++ differential equations, default being false
+
+    functionName: LGOPT -> Symbol
+      ++ functionName returns the name of the function given by the algebraic
+      ++ differential equation, default being f
+
+    variableName: LGOPT -> Symbol
+      ++ variableName returns the name of the variable used in by the
+      ++ algebraic differential equation, default being x
+
+    indexName: LGOPT -> Symbol
+      ++ indexName returns the name of the index variable used for the
+      ++ formulas, default being n
+
+    displayAsGF: LGOPT -> Boolean
+      ++ displayAsGF specifies whether the result is a generating function
+      ++ or a recurrence. This option should not be set by the user, but rather
+      ++ by the HP-specification, therefore, there is no default.
+
+    debug: LGOPT -> Boolean
+      ++ debug returns whether we want additional output on the progress,
+      ++ default being false
+
+  Implementation == add
+
+    maxLevel l ==
+      if (opt := option(l, "maxLevel" :: Symbol)) case "failed" then
+        -1
+      else 
+        retract(opt :: Any)$AnyFunctions1(Integer)
+
+    maxDerivative l ==
+      if (opt := option(l, "maxDerivative" :: Symbol)) case "failed" then
+        -1
+      else 
+        retract(opt :: Any)$AnyFunctions1(Integer)
+
+    maxShift l == maxDerivative l
+
+    maxDegree l ==
+      if (opt := option(l, "maxDegree" :: Symbol)) case "failed" then
+        -1
+      else 
+        retract(opt :: Any)$AnyFunctions1(Integer)
+
+    allDegrees l ==
+      if (opt := option(l, "allDegrees" :: Symbol)) case "failed" then
+        false
+      else 
+        retract(opt :: Any)$AnyFunctions1(Boolean)
+
+    maxPower l ==
+      if (opt := option(l, "maxPower" :: Symbol)) case "failed" then
+        -1
+      else 
+        retract(opt :: Any)$AnyFunctions1(Integer)
+
+    safety l ==
+      if (opt := option(l, "safety" :: Symbol)) case "failed" then
+        1$NonNegativeInteger
+      else
+        retract(opt :: Any)$AnyFunctions1(Integer)::NonNegativeInteger
+
+    one l ==
+      if (opt := option(l, "one" :: Symbol)) case "failed" then
+        true
+      else 
+        retract(opt :: Any)$AnyFunctions1(Boolean)
+
+    debug l ==
+      if (opt := option(l, "debug" :: Symbol)) case "failed" then
+        false
+      else 
+        retract(opt :: Any)$AnyFunctions1(Boolean)
+
+    homogeneous l ==
+      if (opt := option(l, "homogeneous" :: Symbol)) case "failed" then
+        false
+      else 
+        retract(opt :: Any)$AnyFunctions1(Boolean)
+
+    variableName l ==
+      if (opt := option(l, "variableName" :: Symbol)) case "failed" then
+        "x" :: Symbol
+      else 
+        retract(opt :: Any)$AnyFunctions1(Symbol)
+
+    functionName l ==
+      if (opt := option(l, "functionName" :: Symbol)) case "failed" then
+        "f" :: Symbol
+      else 
+        retract(opt :: Any)$AnyFunctions1(Symbol)
+
+    indexName l ==
+      if (opt := option(l, "indexName" :: Symbol)) case "failed" then
+        "n" :: Symbol
+      else 
+        retract(opt :: Any)$AnyFunctions1(Symbol)
+
+    displayAsGF l ==
+      if (opt := option(l, "displayAsGF" :: Symbol)) case "failed" then
+        error "GuessOption: displayAsGF not set"
+      else 
+        retract(opt :: Any)$AnyFunctions1(Boolean)
+
+@
+<<GOPT0.dotabb>>=
+"GOPT0" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GOPT0"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"GOPT0" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESSP GuessPolynomial}
+\pagehead{GuessPolynomial}{GUESSP}
+\pagepic{ps/v104guesspolynomial.ps}{GUESSP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESSP GuessPolynomial>>=
+)abbrev package GUESSP GuessPolynomial
+++ Description:
+++ This package exports guessing of sequences of rational functions
+GuessPolynomial() == Guess(Fraction Polynomial Integer, Polynomial Integer, 
+                           Expression Integer, 
+                           Fraction Polynomial Integer,
+                           id$MappingPackage1(Fraction Polynomial Integer), 
+                           coerce$Expression(Integer))
+
+@
+<<GUESSP.dotabb>>=
+"GUESSP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESSP"]
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"GUESSP" -> "GUESS" 
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GUESSUP GuessUnivariatePolynomial}
+\pagehead{GuessUnivariatePolynomial}{GUESSUP}
+\pagepic{ps/v104guessunivariatepolynomial.ps}{GUESSUP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GUESSUP GuessUnivariatePolynomial>>=
+)abbrev package GUESSUP GuessUnivariatePolynomial
+++ Description:
+++ This package exports guessing of sequences of univariate rational functions
+GuessUnivariatePolynomial(q: Symbol): Exports == Implementation where
+
+    UP ==> MyUnivariatePolynomial(q, Integer)
+    EXPRR ==> MyExpression(q, Integer)
+    F ==> Fraction UP
+    S ==> UP
+    NNI ==> NonNegativeInteger
+    LGOPT ==> List GuessOption
+    GUESSRESULT ==> List Record(function: EXPRR, order: NNI)
+    GUESSER ==> (List F, LGOPT) -> GUESSRESULT
+
+    Exports == with
+
+        guess: List F -> GUESSRESULT
+          ++ \spad{guess l} applies recursively \spadfun{guessRec} and
+          ++ \spadfun{guessADE} to the successive differences and quotients of
+          ++ the list. Default options as described in
+          ++ \spadtype{GuessOptionFunctions0} are used.
+
+        guess: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guess(l, options)} applies recursively \spadfun{guessRec}
+          ++ and \spadfun{guessADE} to the successive differences and quotients
+          ++ of the list. The given options are used.
+
+        guess: (List F, List GUESSER, List Symbol) -> GUESSRESULT
+          ++ \spad{guess(l, guessers, ops)} applies recursively the given
+          ++ guessers to the successive differences if ops contains the symbol
+          ++ guessSum and quotients if ops contains the symbol guessProduct to
+          ++ the list. Default options as described in
+          ++ \spadtype{GuessOptionFunctions0} are used.
+
+        guess: (List F, List GUESSER, List Symbol, LGOPT) -> GUESSRESULT
+          ++ \spad{guess(l, guessers, ops)} applies recursively the given
+          ++ guessers to the successive differences if ops contains the symbol
+          ++ \spad{guessSum} and quotients if ops contains the symbol
+          ++ \spad{guessProduct} to the list. The given options are used.
+
+        guessExpRat: List F -> GUESSRESULT
+          ++ \spad{guessExpRat l} tries to find a function of the form 
+          ++ n+->(a+b n)^n r(n), where r(n) is a rational function, that fits
+          ++ l. 
+
+        guessExpRat: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessExpRat(l, options)} tries to find a function of the
+          ++ form n+->(a+b n)^n r(n), where r(n) is a rational function, that
+          ++ fits l. 
+
+        guessBinRat: List F -> GUESSRESULT
+          ++ \spad{guessBinRat(l, options)} tries to find a function of the
+          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
+          ++ function, that fits l. 
+
+        guessBinRat: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessBinRat(l, options)} tries to find a function of the
+          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
+          ++ function, that fits l. 
+
+--        if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+        guessExpRat: Symbol -> GUESSER
+          ++ \spad{guessExpRat q} returns a guesser that tries to find a
+          ++ function of the form n+->(a+b q^n)^n r(q^n), where r(q^n) is a
+          ++ q-rational function, that fits l.
+
+        guessBinRat: Symbol -> GUESSER
+          ++ \spad{guessBinRat q} returns a guesser that tries to find a
+          ++ function of the form n+->qbinomial(a+b n, n) r(n), where r(q^n) is a
+          ++ q-rational function, that fits l.
+
+-------------------------------------------------------------------------------
+
+        guessHP: (LGOPT -> HPSPEC) -> GUESSER
+          ++ \spad{guessHP f} constructs an operation that applies Hermite-Pade
+          ++ approximation to the series generated by the given function f.
+
+        guessADE: List F -> GUESSRESULT
+          ++ \spad{guessADE l} tries to find an algebraic differential equation
+          ++ for a generating function whose first Taylor coefficients are
+          ++ given by l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}.
+
+        guessADE: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessADE(l, options)} tries to find an algebraic
+          ++ differential equation for a generating function whose first Taylor
+          ++ coefficients are given by l, using the given options.
+
+        guessAlg: List F -> GUESSRESULT
+          ++ \spad{guessAlg l} tries to find an algebraic equation for a
+          ++ generating function whose first Taylor coefficients are given by
+          ++ l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessADE}(l, maxDerivative == 0).
+
+        guessAlg: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessAlg(l, options)} tries to find an algebraic equation
+          ++ for a generating function whose first Taylor coefficients are
+          ++ given by l, using the given options. It is equivalent to
+          ++ \spadfun{guessADE}(l, options) with \spad{maxDerivative == 0}.
+
+        guessHolo: List F -> GUESSRESULT
+          ++ \spad{guessHolo l} tries to find an ordinary linear differential
+          ++ equation for a generating function whose first Taylor coefficients
+          ++ are given by l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessADE}\spad{(l, maxPower == 1)}.
+
+        guessHolo: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessHolo(l, options)} tries to find an ordinary linear
+          ++ differential equation for a generating function whose first Taylor
+          ++ coefficients are given by l, using the given options. It is
+          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
+          ++ \spad{maxPower == 1}.
+
+        guessPade: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessPade(l, options)} tries to find a rational function
+          ++ whose first Taylor coefficients are given by l, using the given
+          ++ options. It is equivalent to \spadfun{guessADE}\spad{(l,
+          ++ maxDerivative == 0, maxPower == 1, allDegrees == true)}.
+
+        guessPade: List F -> GUESSRESULT
+          ++ \spad{guessPade(l, options)} tries to find a rational function
+          ++ whose first Taylor coefficients are given by l, using the default
+          ++ options described in \spadtype{GuessOptionFunctions0}. It is
+          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
+          ++ \spad{maxDerivative == 0, maxPower == 1, allDegrees == true}.
+
+        guessRec: List F -> GUESSRESULT
+          ++ \spad{guessRec l} tries to find an ordinary difference equation
+          ++ whose first values are given by l, using the default options
+          ++ described in \spadtype{GuessOptionFunctions0}.
+
+        guessRec: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessRec(l, options)} tries to find an ordinary difference
+          ++ equation whose first values are given by l, using the given
+          ++ options. 
+
+        guessPRec: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessPRec(l, options)} tries to find a linear recurrence
+          ++ with polynomial coefficients whose first values are given by l,
+          ++ using the given options. It is equivalent to
+          ++ \spadfun{guessRec}\spad{(l, options)} with \spad{maxPower == 1}.
+
+        guessPRec: List F -> GUESSRESULT
+          ++ \spad{guessPRec l} tries to find a linear recurrence with
+          ++ polynomial coefficients whose first values are given by l, using
+          ++ the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessRec}\spad{(l, maxPower == 1)}. 
+
+        guessRat: (List F, LGOPT) -> GUESSRESULT
+          ++ \spad{guessRat(l, options)} tries to find a rational function
+          ++ whose first values are given by l, using the given options. It is
+          ++ equivalent to \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower
+          ++ == 1, allDegrees == true)}.
+
+        guessRat: List F -> GUESSRESULT
+          ++ \spad{guessRat l} tries to find a rational function whose first
+          ++ values are given by l, using the default options described in
+          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+          ++ \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower == 1,
+          ++ allDegrees == true)}.
+
+        diffHP: LGOPT -> HPSPEC
+          ++ \spad{diffHP options} returns a specification for Hermite-Pade
+          ++ approximation with the differential operator
+
+        shiftHP: LGOPT -> HPSPEC
+          ++ \spad{shiftHP options} returns a specification for Hermite-Pade
+          ++ approximation with the shift operator
+
+--        if F has RetractableTo Symbol and S has RetractableTo Symbol then
+
+        shiftHP: Symbol -> (LGOPT -> HPSPEC)
+          ++ \spad{shiftHP options} returns a specification for
+          ++ Hermite-Pade approximation with the $q$-shift operator
+
+        diffHP: Symbol -> (LGOPT -> HPSPEC)
+          ++ \spad{diffHP options} returns a specification for Hermite-Pade
+          ++ approximation with the  $q$-dilation operator
+
+        guessRec: Symbol -> GUESSER
+          ++ \spad{guessRec q} returns a guesser that finds an ordinary
+          ++ q-difference equation whose first values are given by l, using
+          ++ the given options.
+
+        guessPRec: Symbol -> GUESSER
+          ++ \spad{guessPRec q} returns a guesser that tries to find
+          ++ a linear q-recurrence with polynomial coefficients whose first
+          ++ values are given by l, using the given options. It is
+          ++ equivalent to \spadfun{guessRec}\spad{(q)} with 
+          ++ \spad{maxPower == 1}.
+
+        guessRat: Symbol -> GUESSER
+          ++ \spad{guessRat q} returns a guesser that tries to find a
+          ++ q-rational function whose first values are given by l, using
+          ++ the given options. It is equivalent to \spadfun{guessRec} with
+          ++ \spad{(l, maxShift == 0, maxPower == 1, allDegrees == true)}.
+
+        guessADE: Symbol -> GUESSER
+          ++ \spad{guessADE q} returns a guesser that tries to find an
+          ++ algebraic differential equation for a generating function whose
+          ++ first Taylor coefficients are given by l, using the given
+          ++ options.
+
+-------------------------------------------------------------------------------
+
+    Implementation == Guess(Fraction UP, UP,
+                            MyExpression(q, Integer),
+                            Fraction UP,
+                            id$MappingPackage1(Fraction UP),
+                            coerce$MyExpression(q, Integer))
+@
+<<GUESSUP.dotabb>>=
+"GUESSUP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESSUP"]
+"GUESS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GUESS"]
+"GUESSUP" -> "GUESS" 
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter H}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package HB HallBasis}
@@ -27884,6 +31379,242 @@ HallBasis() : Export == Implement where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package HEUGCD HeuGcd}
+\pagehead{HeuGcd}{HEUGCD}
+\pagepic{ps/v104heugcd.ps}{HEUGCD}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package HEUGCD HeuGcd>>=
+)abbrev package HEUGCD HeuGcd
+++ Author: P.Gianni
+++ Date Created:
+++ Date Last Updated: 13 September 94
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides the functions for the heuristic integer gcd.
+++ Geddes's algorithm,for univariate polynomials with integer coefficients
+HeuGcd (BP):C == T
+ where
+  BP       :   UnivariatePolynomialCategory Integer
+  Z        ==> Integer
+  ContPrim ==> Record(cont:Z,prim:BP)
+
+
+  C == with
+     gcd          : List BP  -> BP
+       ++ gcd([f1,..,fk]) = gcd of the polynomials fi.
+       ++
+       ++X gcd([671*671*x^2-1,671*671*x^2+2*671*x+1])
+       ++X gcd([7*x^2+1,(7*x^2+1)^2])
+
+     gcdprim      : List BP  -> BP
+       ++ gcdprim([f1,..,fk]) = gcd of k PRIMITIVE univariate polynomials
+     gcdcofact    : List BP  -> List BP
+       ++ gcdcofact([f1,..fk]) = gcd and cofactors of k univariate polynomials.
+     gcdcofactprim: List BP  -> List BP
+       ++ gcdcofactprim([f1,..fk]) = gcd and cofactors of k
+       ++ primitive polynomials.
+     content      : List BP  -> List Z
+       ++ content([f1,..,fk]) = content of a list of univariate polynonials
+     lintgcd      : List  Z  -> Z
+       ++ lintgcd([a1,..,ak]) = gcd of a list of integers
+
+  T == add
+
+    PI    ==> PositiveInteger
+    NNI   ==> NonNegativeInteger
+    Cases ==> Union("gcdprim","gcd","gcdcofactprim","gcdcofact")
+    import ModularDistinctDegreeFactorizer BP
+
+    --local functions
+    localgcd     :        List BP       -> List BP
+    constNotZero :           BP         -> Boolean
+    height       :           BP         -> PI
+    genpoly      :         (Z,PI)       -> BP
+    negShiftz    :         (Z,PI)       -> Z
+    internal     :     (Cases,List BP ) -> List BP
+    constcase    : (List NNI ,List BP ) -> List BP
+    lincase      : (List NNI ,List BP ) -> List BP
+    myNextPrime  :        ( Z , NNI )   -> Z
+
+    bigPrime:= prevPrime(2**26)$IntegerPrimesPackage(Integer)
+
+    myNextPrime(val:Z,bound:NNI) : Z == nextPrime(val)$IntegerPrimesPackage(Z)
+
+    constNotZero(f : BP ) : Boolean == (degree f = 0) and ^(zero? f)
+
+    negShiftz(n:Z,Modulus:PI):Z ==
+      n < 0 => n:= n+Modulus
+      n > (Modulus quo 2) => n-Modulus
+      n
+
+    --compute the height of a polynomial
+    height(f:BP):PI ==
+      k:PI:=1
+      while f^=0 repeat
+           k:=max(k,abs(leadingCoefficient(f)@Z)::PI)
+           f:=reductum f
+      k
+
+    --reconstruct the polynomial from the value-adic representation of
+    --dval.
+    genpoly(dval:Z,value:PI):BP ==
+      d:=0$BP
+      val:=dval
+      for i in 0..  while (val^=0) repeat
+        val1:=negShiftz(val rem value,value)
+        d:= d+monomial(val1,i)
+        val:=(val-val1) quo value
+      d
+
+    --gcd of a list of integers
+    lintgcd(lval:List(Z)):Z ==
+      empty? lval => 0$Z
+      member?(1,lval) => 1$Z
+      lval:=sort(#1<#2,lval)
+      val:=lval.first
+      for val1 in lval.rest while ^(val=1) repeat val:=gcd(val,val1)
+      val
+
+    --content for a list of univariate polynomials
+    content(listf:List BP ):List(Z) ==
+      [lintgcd coefficients f for f in listf]
+
+    --content of a list of polynomials with the relative primitive parts
+    contprim(listf:List BP ):List(ContPrim) ==
+       [[c:=lintgcd coefficients f,(f exquo c)::BP]$ContPrim  for f in listf]
+
+    -- one polynomial is constant, remark that they are primitive
+    -- but listf can contain the zero polynomial
+    constcase(listdeg:List NNI ,listf:List BP ): List BP  ==
+      lind:=select(constNotZero,listf)
+      empty? lind =>
+        member?(1,listdeg) => lincase(listdeg,listf)
+        localgcd listf
+      or/[n>0 for n in listdeg] => cons(1$BP,listf)
+      lclistf:List(Z):= [leadingCoefficient f for f in listf]
+      d:=lintgcd(lclistf)
+      d=1 =>  cons(1$BP,listf)
+      cons(d::BP,[(lcf quo d)::BP for lcf in lclistf])
+
+    testDivide(listf: List BP, g:BP):Union(List BP, "failed") ==
+      result:List BP := []
+      for f in listf repeat
+        if (f1:=f exquo g) case "failed" then return "failed"
+        result := cons(f1::BP,result)
+      reverse!(result)
+
+    --one polynomial is linear, remark that they are primitive
+    lincase(listdeg:List NNI ,listf:List BP ):List BP  ==
+      n:= position(1,listdeg)
+      g:=listf.n
+      result:=[g]
+      for f in listf repeat
+        if (f1:=f exquo g) case "failed" then return cons(1$BP,listf)
+        result := cons(f1::BP,result)
+      reverse(result)
+
+    IMG := InnerModularGcd(Z,BP,67108859,myNextPrime)
+
+    mindegpol(f:BP, g:BP):BP ==
+      degree(g) < degree (f) => g
+      f
+
+    --local function for the gcd among n PRIMITIVE univariate polynomials
+    localgcd(listf:List BP ):List BP  ==
+      hgt:="min"/[height(f) for f in listf|^zero? f]
+      answr:=2+2*hgt
+      minf := "mindegpol"/[f for f in listf|^zero? f]
+      (result := testDivide(listf, minf)) case List(BP) =>
+           cons(minf, result::List BP)
+      if degree minf < 100 then for k in 1..10 repeat
+        listval:=[f answr for f in listf]
+        dval:=lintgcd(listval)
+        dd:=genpoly(dval,answr)
+        contd:=content(dd)
+        d:=(dd exquo contd)::BP
+        result:List BP :=[d]
+        flag : Boolean := true
+        for f in listf while flag repeat
+          (f1:=f exquo d) case "failed" => flag:=false
+          result := cons (f1::BP,result)
+        if flag then return reverse(result)
+        nvalue:= answr*832040 quo 317811
+        if ((nvalue + answr) rem 2) = 0 then nvalue:=nvalue+1
+        answr:=nvalue::PI
+      gg:=modularGcdPrimitive(listf)$IMG
+      cons(gg,[(f exquo gg) :: BP for f in listf])
+
+    --internal function:it evaluates the gcd and avoids duplication of
+    --code.
+    internal(flag:Cases,listf:List BP ):List BP  ==
+      --special cases
+      listf=[] => [1$BP]
+      (nlf:=#listf)=1 => [first listf,1$BP]
+      minpol:=1$BP
+      -- extract a monomial gcd
+      mdeg:= "min"/[minimumDegree f for f in listf]
+      if mdeg>0 then
+        minpol1:= monomial(1,mdeg)
+        listf:= [(f exquo minpol1)::BP for f in listf]
+        minpol:=minpol*minpol1
+      -- make the polynomials primitive
+      Cgcd:List(Z):=[]
+      contgcd : Z := 1
+      if (flag case "gcd") or (flag case "gcdcofact") then
+        contlistf:List(ContPrim):=contprim(listf)
+        Cgcd:= [term.cont for term in contlistf]
+        contgcd:=lintgcd(Cgcd)
+        listf:List BP :=[term.prim for term in contlistf]
+        minpol:=contgcd*minpol
+      listdeg:=[degree f for f in listf ]
+      f:= first listf
+      if positiveRemainder(leadingCoefficient(f), bigPrime) ~= 0 then
+        for g in rest listf repeat
+          lcg := leadingCoefficient(g)
+          if positiveRemainder(lcg, bigPrime) = 0 then
+            leave
+          f:=gcd(f,g,bigPrime)
+          if degree f = 0 then return cons(minpol,listf)
+      ans:List BP :=
+         --one polynomial is constant
+         member?(0,listdeg) => constcase(listdeg,listf)
+         --one polynomial is linear
+         member?(1,listdeg) => lincase(listdeg,listf)
+         localgcd(listf)
+      (result,ans):=(first ans*minpol,rest ans)
+      if (flag case "gcdcofact") then
+        ans:= [(p quo contgcd)*q for p in Cgcd for q in ans]
+      cons(result,ans)
+
+    --gcd among n PRIMITIVE univariate polynomials
+    gcdprim (listf:List BP ):BP == first internal("gcdprim",listf)
+
+    --gcd and cofactors for n PRIMITIVE univariate polynomials
+    gcdcofactprim(listf:List BP ):List BP  == internal("gcdcofactprim",listf)
+
+    --gcd for n generic univariate polynomials.
+    gcd(listf:List BP ): BP  ==  first internal("gcd",listf)
+
+    --gcd and cofactors for n generic univariate polynomials.
+    gcdcofact (listf:List BP ):List BP == internal("gcdcofact",listf)
+
+@
+<<HEUGCD.dotabb>>=
+"HEUGCD" [color="#FF4488",href="bookvol10.4.pdf#nameddest=HEUGCD"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"HEUGCD" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter I}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package IDECOMP IdealDecompositionPackage}
@@ -29863,6 +33594,219 @@ factor t6
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ZLINDEP IntegerLinearDependence}
+<<IntegerLinearDependence.input>>=
+-- lindep.spad.pamphlet IntegerLinearDependence.input
+)spool IntegerLinearDependence.output
+)set message test on
+)set message auto off
+)clear all
+--S 1
+M := SQMATRIX(2,INT)
+--R 
+--R
+--R   (1)  SquareMatrix(2,Integer)
+--R                                                                 Type: Domain
+--E 1
+
+--S 2
+m1: M := squareMatrix matrix [ [1, 2], [0, -1] ]
+--R 
+--R
+--R        +1   2 +
+--R   (2)  |      |
+--R        +0  - 1+
+--R                                                Type: SquareMatrix(2,Integer)
+--E 2
+
+--S 3
+m2: M := squareMatrix matrix [ [2, 3], [1, -2] ]
+--R 
+--R
+--R        +2   3 +
+--R   (3)  |      |
+--R        +1  - 2+
+--R                                                Type: SquareMatrix(2,Integer)
+--E 3
+
+--S 4
+m3: M := squareMatrix matrix [ [3, 4], [2, -3] ]
+--R 
+--R
+--R        +3   4 +
+--R   (4)  |      |
+--R        +2  - 3+
+--R                                                Type: SquareMatrix(2,Integer)
+--E 4
+
+--S 5
+linearlyDependentOverZ? vector [m1, m2, m3]
+--R 
+--R
+--R   (5)  true
+--R                                                                Type: Boolean
+--E 5
+
+--S 6
+c := linearDependenceOverZ vector [m1, m2, m3]
+--R 
+--R
+--R   (6)  [1,- 2,1]
+--R                                              Type: Union(Vector Integer,...)
+--E 6
+
+--S 7
+c.1 * m1 + c.2 * m2 + c.3 * m3
+--R 
+--R
+--R        +0  0+
+--R   (7)  |    |
+--R        +0  0+
+--R                                                Type: SquareMatrix(2,Integer)
+--E 7
+
+--S 8
+solveLinearlyOverQ(vector [m1, m3], m2)
+--R 
+--R
+--R         1 1
+--R   (8)  [-,-]
+--R         2 2
+--R                                     Type: Union(Vector Fraction Integer,...)
+--E 8
+)spool
+)lisp (bye)
+@
+<<IntegerLinearDependence.help>>=
+====================================================================
+IntegerLinearDependence examples
+====================================================================
+
+The elements v1,...,vN of a module M over a ring R are said to be 
+linearly dependent over R if there exist c1,...,cN in R, not all 0, 
+such that c1 v1 + ...  cN vNn = 0.  If such ci's exist, they form 
+what is called a linear dependence relation over R for the vi's.
+
+The package IntegerLinearDependence provides functions for testing
+whether some elements of a module over the integers are linearly
+dependent over the integers, and to find the linear dependence
+relations, if any.
+
+Consider the domain of two by two square matrices with integer entries.
+
+  M := SQMATRIX(2,INT)
+    SquareMatrix(2,Integer)
+                      Type: Domain
+
+Now create three such matrices.
+
+  m1: M := squareMatrix matrix [ [1, 2], [0, -1] ]
+     +1   2 +
+     |      |
+     +0  - 1+
+                      Type: SquareMatrix(2,Integer)
+
+  m2: M := squareMatrix matrix [ [2, 3], [1, -2] ]
+    +2   3 +
+    |      |
+    +1  - 2+
+                      Type: SquareMatrix(2,Integer)
+
+  m3: M := squareMatrix matrix [ [3, 4], [2, -3] ]
+    +3   4 +
+    |      |
+    +2  - 3+
+                      Type: SquareMatrix(2,Integer)
+
+This tells you whether m1, m2 and m3 are linearly dependent over the integers.
+
+  linearlyDependentOverZ? vector [m1, m2, m3]
+    true
+                      Type: Boolean
+
+Since they are linearly dependent, you can ask for the dependence relation.
+
+  c := linearDependenceOverZ vector [m1, m2, m3]
+    [1,- 2,1]
+                      Type: Union(Vector Integer,...)
+
+This means that the following linear combination should be 0.
+
+  c.1 * m1 + c.2 * m2 + c.3 * m3
+    +0  0+
+    |    |
+    +0  0+
+                      Type: SquareMatrix(2,Integer)
+
+When a given set of elements are linearly dependent over R, this also 
+means that at least one of them can be rewritten as a linear combination 
+of the others with coefficients in the quotient field of R.
+
+To express a given element in terms of other elements, use the operation
+solveLinearlyOverQ.
+
+  solveLinearlyOverQ(vector [m1, m3], m2)
+     1 1
+    [-,-]
+     2 2
+                      Type: Union(Vector Fraction Integer,...)
+
+See Also:
+o )show IntegerLinearDependence
+o $AXIOM/doc/src/algebra/lindep.spad.dvi
+
+@
+\pagehead{IntegerLinearDependence}{ZLINDEP}
+\pagepic{ps/v104integerlineardependence.ps}{ZLINDEP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ZLINDEP IntegerLinearDependence>>=
+)abbrev package ZLINDEP IntegerLinearDependence
+++ Test for linear dependence over the integers
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Test for linear dependence over the integers.
+IntegerLinearDependence(R): Exports == Implementation where
+  R: LinearlyExplicitRingOver Integer
+
+  Z ==> Integer
+
+  Exports ==> with
+    linearlyDependentOverZ?: Vector R -> Boolean
+      ++ \spad{linearlyDependentOverZ?([v1,...,vn])} returns true if the
+      ++ vi's are linearly dependent over the integers, false otherwise.
+    linearDependenceOverZ  : Vector R -> Union(Vector Z, "failed")
+      ++ \spad{linearlyDependenceOverZ([v1,...,vn])} returns
+      ++ \spad{[c1,...,cn]} if
+      ++ \spad{c1*v1 + ... + cn*vn = 0} and not all the ci's are 0, "failed"
+      ++ if the vi's are linearly independent over the integers.
+    solveLinearlyOverQ     : (Vector R, R) ->
+                                      Union(Vector Fraction Z, "failed")
+      ++ \spad{solveLinearlyOverQ([v1,...,vn], u)} returns \spad{[c1,...,cn]}
+      ++ such that \spad{c1*v1 + ... + cn*vn = u},
+      ++ "failed" if no such rational numbers ci's exist.
+
+  Implementation ==> add
+    import LinearDependence(Z, R)
+
+    linearlyDependentOverZ? v == linearlyDependent? v
+    linearDependenceOverZ   v == linearDependence v
+    solveLinearlyOverQ(v, c)  == solveLinear(v, c)
+
+@
+<<ZLINDEP.dotabb>>=
+"ZLINDEP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ZLINDEP"]
+"PID" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PID"]
+"OAGROUP" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OAGROUP"]
+"ZLINDEP" -> "PID"
+"ZLINDEP" -> "OAGROUP"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PRIMES IntegerPrimesPackage}
 We've expanded the list of small primes to include those between 1 and 10000.
 \pagehead{IntegerPrimesPackage}{PRIMES}
@@ -31465,6 +35409,115 @@ IrrRepSymNatPackage(): public == private where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package INVLAPLA InverseLaplaceTransform}
+\pagehead{InverseLaplaceTransform}{INVLAPLA}
+\pagepic{ps/v104inverselaplacetransform.ps}{INVLAPLA}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package INVLAPLA InverseLaplaceTransform>>=
+)abbrev package INVLAPLA InverseLaplaceTransform
+++ Inverse Laplace transform
+++ Author: Barry Trager
+++ Date Created: 3 Sept 1991
+++ Date Last Updated: 3 Sept 1991
+++ Description: This package computes the inverse Laplace Transform.
+InverseLaplaceTransform(R, F): Exports == Implementation where
+  R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+           RetractableTo Integer, LinearlyExplicitRingOver Integer)
+  F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
+           SpecialFunctionCategory, AlgebraicallyClosedFunctionSpace R)
+
+  SE  ==> Symbol
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  K   ==> Kernel F
+  UP  ==> SparseUnivariatePolynomial F
+  RF  ==> Fraction UP
+
+  Exports ==> with
+    inverseLaplace: (F, SE, SE) -> Union(F,"failed")
+      ++ inverseLaplace(f, s, t) returns the Inverse
+      ++ Laplace transform of \spad{f(s)}
+      ++ using t as the new variable or "failed" if unable to find
+      ++ a closed form.
+      ++ Handles only rational \spad{f(s)}.
+
+  Implementation ==> add
+
+    -- local ops --
+    ilt : (F,Symbol,Symbol) -> Union(F,"failed")
+    ilt1 : (RF,F) -> F
+    iltsqfr : (RF,F) -> F
+    iltirred: (UP,UP,F) -> F
+    freeOf?: (UP,Symbol) -> Boolean
+
+    inverseLaplace(expr,ivar,ovar) == ilt(expr,ivar,ovar)
+
+    freeOf?(p:UP,v:Symbol) ==
+      "and"/[freeOf?(c,v) for c in coefficients p]
+
+    ilt(expr,var,t) ==
+      expr = 0 => 0
+      r := univariate(expr,kernel(var))
+
+      -- Check that r is a rational function such that degree of
+      -- the numarator is lower that degree of denominator
+      not(numer(r) quo denom(r) = 0) => "failed"
+      not( freeOf?(numer r,var) and freeOf?(denom r,var)) => "failed"
+
+      ilt1(r,t::F)
+
+    hintpac := TranscendentalHermiteIntegration(F, UP)
+
+    ilt1(r,t) ==
+      r = 0 => 0
+      rsplit := HermiteIntegrate(r, differentiate)$hintpac
+      -t*ilt1(rsplit.answer,t) + iltsqfr(rsplit.logpart,t)
+
+    iltsqfr(r,t) ==
+       r = 0 => 0
+       p:=numer r
+       q:=denom r
+     --  ql := [qq.factor for qq in factors factor q]
+       ql := [qq.factor for qq in factors squareFree q]
+       # ql = 1 => iltirred(p,q,t)
+       nl := multiEuclidean(ql,p)::List(UP)
+       +/[iltirred(a,b,t) for a in nl for b in ql]
+
+    -- q is irreducible, monic, degree p < degree q
+    iltirred(p,q,t) ==
+      degree q = 1 =>
+        cp := coefficient(p,0)
+        (c:=coefficient(q,0))=0 => cp
+        cp*exp(-c*t)
+      degree q = 2 =>
+        a := coefficient(p,1)
+        b := coefficient(p,0)
+        c:=(-1/2)*coefficient(q,1)
+        d:= coefficient(q,0)
+        e := exp(c*t)
+        b := b+a*c
+        d := d-c**2
+        d > 0 =>
+            alpha:F := sqrt d
+            e*(a*cos(t*alpha) + b*sin(t*alpha)/alpha)
+        alpha :F := sqrt(-d)
+        e*(a*cosh(t*alpha) + b*sinh(t*alpha)/alpha)
+      roots:List F := zerosOf q
+      q1 := differentiate q
+      +/[p(root)/q1(root)*exp(root*t) for root in roots]
+
+@
+<<INVLAPLA.dotabb>>=
+"INVLAPLA" [color="#FF4488",href="bookvol10.4.pdf#nameddest=INVLAPLA"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"INVLAPLA" -> "ACFS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter J}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -31612,6 +35665,706 @@ Kovacic(F, UP): Exports == Impl where
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter L}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LAPLACE LaplaceTransform}
+\pagehead{LaplaceTransform}{LAPLACE}
+\pagepic{ps/v104laplacetransform.ps}{LAPLACE}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LAPLACE LaplaceTransform>>=
+)abbrev package LAPLACE LaplaceTransform
+++ Laplace transform
+++ Author: Manuel Bronstein
+++ Date Created: 30 May 1990
+++ Date Last Updated: 13 December 1995
+++ Description: This package computes the forward Laplace Transform.
+LaplaceTransform(R, F): Exports == Implementation where
+  R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+           RetractableTo Integer, LinearlyExplicitRingOver Integer)
+  F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
+           AlgebraicallyClosedFunctionSpace R)
+
+  SE  ==> Symbol
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  K   ==> Kernel F
+  OFE ==> OrderedCompletion F
+  EQ  ==> Equation OFE
+
+  ALGOP       ==> "%alg"
+  SPECIALDIFF ==> "%specialDiff"
+
+  Exports ==> with
+    laplace: (F, SE, SE) -> F
+      ++ laplace(f, t, s) returns the Laplace transform of \spad{f(t)}
+      ++ using \spad{s} as the new variable.
+      ++ This is \spad{integral(exp(-s*t)*f(t), t = 0..%plusInfinity)}.
+      ++ Returns the formal object \spad{laplace(f, t, s)} if it cannot
+      ++ compute the transform.
+
+  Implementation ==> add
+    import IntegrationTools(R, F)
+    import ElementaryIntegration(R, F)
+    import PatternMatchIntegration(R, F)
+    import PowerSeriesLimitPackage(R, F)
+    import FunctionSpaceIntegration(R, F)
+    import TrigonometricManipulations(R, F)
+
+    locallaplace : (F, SE, F, SE, F) -> F
+    lapkernel    : (F, SE, F, F) -> Union(F, "failed")
+    intlaplace   : (F, F, F, SE, F) -> Union(F, "failed")
+    isLinear     : (F, SE) -> Union(Record(const:F, nconst:F), "failed")
+    mkPlus       : F -> Union(List F, "failed")
+    dvlap        : (List F, SE) -> F
+    tdenom       : (F, F) -> Union(F, "failed")
+    atn          : (F, SE) -> Union(Record(coef:F, deg:PI), "failed")
+    aexp         : (F, SE) -> Union(Record(coef:F, coef1:F, coef0:F), "failed")
+    algebraic?   : (F, SE) -> Boolean
+
+    oplap := operator("laplace"::Symbol, 3)$BasicOperator
+
+    laplace(f,t,s) == locallaplace(complexElementary(f,t),t,t::F,s,s::F)
+
+-- returns true if the highest kernel of f is algebraic over something
+    algebraic?(f, t) ==
+      l := varselect(kernels f, t)
+      m:N := reduce(max, [height k for k in l], 0)$List(N)
+      for k in l repeat
+         height k = m and has?(operator k, ALGOP) => return true
+      false
+
+-- differentiate a kernel of the form  laplace(l.1,l.2,l.3) w.r.t x.
+-- note that x is not necessarily l.3
+-- if x = l.3, then there is no use recomputing the laplace transform,
+-- it will remain formal anyways
+    dvlap(l, x) ==
+      l1 := first l
+      l2 := second l
+      x = (v := retract(l3 := third l)@SE) => - oplap(l2 * l1, l2, l3)
+      e := exp(- l3 * l2)
+      locallaplace(differentiate(e * l1, x) / e, retract(l2)@SE, l2, v, l3)
+
+-- returns [b, c] iff f = c * t + b
+-- and b and c do not involve t
+    isLinear(f, t) ==
+      ff := univariate(f, kernel(t)@K)
+      ((d := retractIfCan(denom ff)@Union(F, "failed")) case "failed")
+        or (degree(numer ff) > 1) => "failed"
+      freeOf?(b := coefficient(numer ff, 0) / d, t) and
+        freeOf?(c := coefficient(numer ff, 1) / d, t) => [b, c]
+      "failed"
+
+-- returns [a, n] iff f = a * t**n
+    atn(f, t) ==
+      if ((v := isExpt f) case Record(var:K, exponent:Integer)) then
+        w := v::Record(var:K, exponent:Integer)
+        (w.exponent > 0) and
+          ((vv := symbolIfCan(w.var)) case SE) and (vv::SE = t) =>
+            return [1, w.exponent::PI]
+      (u := isTimes f) case List(F) =>
+        c:F  := 1
+        d:N  := 0
+        for g in u::List(F) repeat
+          if (rec := atn(g, t)) case Record(coef:F, deg:PI) then
+            r := rec::Record(coef:F, deg:PI)
+            c := c * r.coef
+            d := d + r.deg
+          else c := c * g
+        zero? d => "failed"
+        [c, d::PI]
+      "failed"
+
+-- returns [a, c, b] iff f = a * exp(c * t + b)
+-- and b and c do not involve t
+    aexp(f, t) ==
+      is?(f, "exp"::SE) =>
+        (v := isLinear(first argument(retract(f)@K),t)) case "failed" =>
+           "failed"
+        [1, v.nconst, v.const]
+      (u := isTimes f) case List(F) =>
+        c:F := 1
+        c1 := c0 := 0$F
+        for g in u::List(F) repeat
+          if (r := aexp(g,t)) case Record(coef:F,coef1:F,coef0:F) then
+            rec := r::Record(coef:F, coef1:F, coef0:F)
+            c   := c * rec.coef
+            c0  := c0 + rec.coef0
+            c1  := c1 + rec.coef1
+          else c := c * g
+        zero? c0 and zero? c1 => "failed"
+        [c, c1, c0]
+      if (v := isPower f) case Record(val:F, exponent:Integer) then
+        w := v::Record(val:F, exponent:Integer)
+        (w.exponent ^= 1) and
+          ((r := aexp(w.val, t)) case Record(coef:F,coef1:F,coef0:F)) =>
+            rec := r::Record(coef:F, coef1:F, coef0:F)
+            return [rec.coef ** w.exponent, w.exponent * rec.coef1,
+                                            w.exponent * rec.coef0]
+      "failed"
+
+    mkPlus f ==
+      (u := isPlus numer f) case "failed" => "failed"
+      d := denom f
+      [p / d for p in u::List(SparseMultivariatePolynomial(R, K))]
+
+-- returns g if f = g/t
+    tdenom(f, t) ==
+      (denom f exquo numer t) case "failed" => "failed"
+      t * f
+
+    intlaplace(f, ss, g, v, vv) ==
+      is?(g, oplap) or ((i := integrate(g, v)) case List(F)) => "failed"
+      (u:=limit(i::F,equation(vv::OFE,plusInfinity()$OFE)$EQ)) case OFE =>
+        (l := limit(i::F, equation(vv::OFE, ss::OFE)$EQ)) case OFE =>
+          retractIfCan(u::OFE - l::OFE)@Union(F, "failed")
+        "failed"
+      "failed"
+
+    lapkernel(f, t, tt, ss) ==
+      (k := retractIfCan(f)@Union(K, "failed")) case "failed" => "failed"
+      empty?(arg := argument(k::K)) => "failed"
+      is?(op := operator k, "%diff"::SE) =>
+        not( #arg = 3) => "failed"
+        not(is?(arg.3, t)) => "failed"
+        fint := eval(arg.1, arg.2, tt)
+        s := name operator (kernels(ss).1)
+        ss * locallaplace(fint, t, tt, s, ss) - eval(fint, tt = 0)
+      not (empty?(rest arg)) => "failed"
+      member?(t, variables(a := first(arg) / tt)) => "failed"
+      is?(op := operator k, "Si"::SE) => atan(a / ss) / ss
+      is?(op, "Ci"::SE) => log((ss**2 + a**2) / a**2) / (2 * ss)
+      is?(op, "Ei"::SE) => log((ss + a) / a) / ss
+      -- digamma (or Gamma) needs SpecialFunctionCategory
+      -- which we do not have here
+      -- is?(op, "log"::SE) => (digamma(1) - log(a) - log(ss)) / ss
+      "failed"
+
+    -- Below we try to apply one of the texbook rules for computing
+    -- Laplace transforms, either reducing problem to simpler cases
+    -- or using one of known base cases
+    locallaplace(f, t, tt, s, ss) ==
+      zero? f => 0
+--      one? f  => inv ss
+      (f = 1)  => inv ss
+
+      -- laplace(f(t)/t,t,s) 
+      --              = integrate(laplace(f(t),t,v), v = s..%plusInfinity)
+      (x := tdenom(f, tt)) case F =>
+        g := locallaplace(x::F, t, tt, vv := new()$SE, vvv := vv::F)
+        (x := intlaplace(f, ss, g, vv, vvv)) case F => x::F
+        oplap(f, tt, ss)
+
+      -- Use linearity
+      (u := mkPlus f) case List(F) =>
+        +/[locallaplace(g, t, tt, s, ss) for g in u::List(F)]
+      (rec := splitConstant(f, t)).const ^= 1 =>
+        rec.const * locallaplace(rec.nconst, t, tt, s, ss)
+
+      -- laplace(t^n*f(t),t,s) = (-1)^n*D(laplace(f(t),t,s), s, n))
+      (v := atn(f, t)) case Record(coef:F, deg:PI) =>
+        vv := v::Record(coef:F, deg:PI)
+        is?(la := locallaplace(vv.coef, t, tt, s, ss), oplap) => oplap(f,tt,ss)
+        (-1$Integer)**(vv.deg) * differentiate(la, s, vv.deg)
+
+      -- Complex shift rule
+      (w := aexp(f, t)) case Record(coef:F, coef1:F, coef0:F) =>
+        ww := w::Record(coef:F, coef1:F, coef0:F)
+        exp(ww.coef0) * locallaplace(ww.coef,t,tt,s,ss - ww.coef1)
+
+      -- Try base cases
+      (x := lapkernel(f, t, tt, ss)) case F => x::F
+
+--    -- The following does not seem to help computing transforms, but
+--    -- quite frequently leads to loops, so I (wh) disabled it for now
+--    -- last chance option: try to use the fact that
+--    --    laplace(f(t),t,s) = s laplace(g(t),t,s) - g(0)  where dg/dt = f(t)
+--    elem?(int := lfintegrate(f, t)) and (rint := retractIfCan int) case F =>
+--        fint := rint :: F
+--        -- to avoid infinite loops, we don't call laplace recursively
+--        -- if the integral has no new logs and f is an algebraic function
+--        empty?(logpart int) and algebraic?(f, t) => oplap(fint, tt, ss)
+--        ss * locallaplace(fint, t, tt, s, ss) - eval(fint, tt = 0)
+      oplap(f, tt, ss)
+
+    setProperty(oplap,SPECIALDIFF,dvlap@((List F,SE)->F) pretend None)
+
+@
+<<LAPLACE.dotabb>>=
+"LAPLACE" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LAPLACE"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"LAPLACE" -> "ACFS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LEADCDET LeadingCoefDetermination}
+\pagehead{LeadingCoefDetermination}{LEADCDET}
+\pagepic{ps/v104leadingcoefdetermination.ps}{LEADCDET}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LEADCDET LeadingCoefDetermination>>=
+)abbrev package LEADCDET LeadingCoefDetermination
+++ Author : P.Gianni, May 1990
+++ Description:
+++ Package for leading coefficient determination in the lifting step.
+++ Package working for every R euclidean with property "F".
+LeadingCoefDetermination(OV,E,Z,P) : C == T
+ where
+  OV    :   OrderedSet
+  E     :   OrderedAbelianMonoidSup
+  Z     :   EuclideanDomain
+  BP        ==> SparseUnivariatePolynomial Z
+  P         :   PolynomialCategory(Z,E,OV)
+  NNI       ==> NonNegativeInteger
+  LeadFact  ==> Record(polfac:List(P),correct:Z,corrfact:List(BP))
+  ParFact   ==> Record(irr:P,pow:Integer)
+  FinalFact ==> Record(contp:Z,factors:List(ParFact))
+ 
+  C == with
+   polCase  : (Z,NNI,List(Z)) -> Boolean
+     ++ polCase(contprod, numFacts, evallcs), where contprod is the
+     ++ product of the content of the leading coefficient of
+     ++ the polynomial to be factored with the content of the
+     ++ evaluated polynomial, numFacts is the number of factors
+     ++ of the leadingCoefficient, and evallcs is the list of
+     ++ the evaluated factors of the leadingCoefficient, returns
+     ++ true if the factors of the leading Coefficient can be
+     ++ distributed with this valuation.
+   distFact : (Z,List(BP),FinalFact,List(Z),List(OV),List(Z)) ->
+                                              Union(LeadFact,"failed")
+     ++ distFact(contm,unilist,plead,vl,lvar,lval), where contm is
+     ++ the content of the evaluated polynomial, unilist is the list
+     ++ of factors of the evaluated polynomial, plead is the complete
+     ++ factorization of the leading coefficient, vl is the list
+     ++ of factors of the leading coefficient evaluated, lvar is the
+     ++ list of variables, lval is the list of values, returns a record
+     ++ giving the list of leading coefficients to impose on the univariate
+     ++ factors, 
+ 
+  T == add
+    distribute: (Z,List(BP),List(P),List(Z),List(OV),List(Z)) -> LeadFact
+    checkpow  : (Z,Z) -> NNI
+ 
+    polCase(d:Z,nk:NNI,lval:List(Z)):Boolean ==
+      -- d is the product of the content lc m (case polynomial)
+      -- and the cont of the polynomial evaluated
+      q:Z
+      distlist:List(Z) := [d]
+      for i in 1..nk repeat
+        q := unitNormal(lval.i).canonical
+        for j in 0..(i-1)::NNI repeat
+          y := distlist.((i-j)::NNI)
+          while y^=1  repeat
+            y := gcd(y,q)
+            q := q quo y
+          if q=1 then return false
+        distlist := append(distlist,[q])
+      true
+ 
+    checkpow(a:Z,b:Z) : NonNegativeInteger ==
+      qt: Union(Z,"failed")
+      for i in 0.. repeat
+        qt:= b exquo a
+        if qt case "failed" then return i
+        b:=qt::Z
+ 
+    distribute(contm:Z,unilist:List(BP),pl:List(P),vl:List(Z),
+                              lvar:List(OV),lval:List(Z)): LeadFact ==
+      d,lcp : Z
+      nf:NNI:=#unilist
+      for i in 1..nf repeat
+          lcp := leadingCoefficient (unilist.i)
+          d:= gcd(lcp,vl.i)
+          pl.i := (lcp quo d)*pl.i
+          d := vl.i quo d
+          unilist.i := d*unilist.i
+          contm := contm quo d
+      if contm ^=1 then for i in 1..nf repeat pl.i := contm*pl.i
+      [pl,contm,unilist]$LeadFact
+ 
+    distFact(contm:Z,unilist:List(BP),plead:FinalFact,
+             vl:List(Z),lvar:List(OV),lval:List(Z)):Union(LeadFact,"failed") ==
+      h:NonNegativeInteger
+      c,d : Z
+      lpol:List(P):=[]
+      lexp:List(Integer):=[]
+      nf:NNI := #unilist
+      vl := reverse vl --lpol and vl reversed so test from right to left
+      for fpl in plead.factors repeat
+       lpol:=[fpl.irr,:lpol]
+       lexp:=[fpl.pow,:lexp]
+      vlp:List(Z):= [1$Z for i in 1..nf]
+      aux : List(P) := [1$P for i in 1..nf]
+      for i in 1..nf repeat
+        c := contm*leadingCoefficient unilist.i
+        c=1 or c=-1  => "next i"
+        for k in 1..(# lpol) repeat
+          lexp.k=0 => "next factor"
+          h:= checkpow(vl.k,c)
+          if h ^=0 then
+           if h>lexp.k then return "failed"
+           lexp.k:=lexp.k-h
+           aux.i := aux.i*(lpol.k ** h)
+           d:= vl.k**h
+           vlp.i:= vlp.i*d
+           c:= c quo d
+        if contm=1 then vlp.i:=c
+      for k in 1..(# lpol) repeat if lexp.k ^= 0 then return "failed"
+      contm =1 => [[vlp.i*aux.i for i in 1..nf],1,unilist]$LeadFact
+      distribute(contm,unilist,aux,vlp,lvar,lval)
+
+@
+<<LEADCDET.dotabb>>=
+"LEADCDET" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LEADCDET"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"LEADCDET" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LINDEP LinearDependence}
+\pagehead{LinearDependence}{LINDEP}
+\pagepic{ps/v104lineardependence.ps}{LINDEP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LINDEP LinearDependence>>=
+)abbrev package LINDEP LinearDependence
+++ Test for linear dependence
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Test for linear dependence.
+LinearDependence(S, R): Exports == Implementation where
+  S: IntegralDomain
+  R: LinearlyExplicitRingOver S
+
+  Q ==> Fraction S
+
+  Exports ==> with
+    linearlyDependent?: Vector R -> Boolean
+      ++ \spad{linearlyDependent?([v1,...,vn])} returns true if
+      ++ the vi's are linearly dependent over S, false otherwise.
+    linearDependence  : Vector R -> Union(Vector S, "failed")
+      ++ \spad{linearDependence([v1,...,vn])} returns \spad{[c1,...,cn]} if
+      ++ \spad{c1*v1 + ... + cn*vn = 0} and not all the ci's are 0,
+      ++ "failed" if the vi's are linearly independent over S.
+    if S has Field then
+      solveLinear: (Vector R, R) -> Union(Vector S, "failed")
+        ++ \spad{solveLinear([v1,...,vn], u)} returns \spad{[c1,...,cn]}
+        ++ such that \spad{c1*v1 + ... + cn*vn = u},
+        ++ "failed" if no such ci's exist in S.
+    else
+      solveLinear: (Vector R, R) -> Union(Vector Q, "failed")
+        ++ \spad{solveLinear([v1,...,vn], u)} returns \spad{[c1,...,cn]}
+        ++ such that \spad{c1*v1 + ... + cn*vn = u},
+        ++ "failed" if no such ci's exist in the quotient field of S.
+
+  Implementation ==> add
+    aNonZeroSolution: Matrix S -> Union(Vector S, "failed")
+
+    aNonZeroSolution m ==
+      every?(zero?, v := first nullSpace m) => "failed"
+      v
+
+    linearlyDependent? v ==
+      zero?(n := #v) => true
+--      one? n => zero?(v(minIndex v))
+      (n = 1) => zero?(v(minIndex v))
+      positive? nullity reducedSystem transpose v
+
+    linearDependence v ==
+      zero?(n := #v) => empty()
+--      one? n =>
+      (n = 1) =>
+        zero?(v(minIndex v)) => new(1, 1)
+        "failed"
+      aNonZeroSolution reducedSystem transpose v
+
+    if S has Field then
+      solveLinear(v:Vector R, c:R):Union(Vector S, "failed") ==
+        zero? c => new(#v, 0)
+        empty? v => "failed"
+        sys := reducedSystem(transpose v, new(1, c))
+        particularSolution(sys.mat, sys.vec)$LinearSystemMatrixPackage(S,
+                                           Vector S, Vector S, Matrix S)
+
+    else
+      solveLinear(v:Vector R, c:R):Union(Vector Q, "failed") ==
+        zero? c => new(#v, 0)
+        empty? v => "failed"
+        sys := reducedSystem(transpose v, new(1, c))
+        particularSolution(map(#1::Q, sys.mat)$MatrixCategoryFunctions2(S,
+               Vector S,Vector S,Matrix S,Q,Vector Q,Vector Q,Matrix Q),
+                  map(#1::Q, sys.vec)$VectorFunctions2(S, Q)
+                                    )$LinearSystemMatrixPackage(Q,
+                                           Vector Q, Vector Q, Matrix Q)
+
+@
+<<LINDEP.dotabb>>=
+"LINDEP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LINDEP"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"LINDEP" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LODOF LinearOrdinaryDifferentialOperatorFactorizer}
+\pagehead{LinearOrdinaryDifferentialOperatorFactorizer}{LODOF}
+\pagepic{ps/v104linearordinarydifferentialoperatorfactorizer.ps}{LODOF}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LODOF LinearOrdinaryDifferentialOperatorFactorizer>>=
+)abbrev package LODOF LinearOrdinaryDifferentialOperatorFactorizer
+++ Author: Fritz Schwarz, Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{LinearOrdinaryDifferentialOperatorFactorizer} provides a
+++ factorizer for linear ordinary differential operators whose coefficients
+++ are rational functions.
+++ Keywords: differential equation, ODE, LODO, factoring
+LinearOrdinaryDifferentialOperatorFactorizer(F, UP): Exports == Impl where
+  F : Join(Field, CharacteristicZero,
+           RetractableTo Integer, RetractableTo Fraction Integer)
+  UP: UnivariatePolynomialCategory F
+ 
+  RF ==> Fraction UP
+  L  ==> LinearOrdinaryDifferentialOperator1 RF
+ 
+  Exports ==> with
+    factor: (L, UP -> List F) -> List L
+      ++ factor(a, zeros) returns the factorisation of a.
+      ++ \spad{zeros} is a zero finder in \spad{UP}.
+    if F has AlgebraicallyClosedField then
+      factor: L -> List L
+        ++ factor(a) returns the factorisation of a.
+      factor1: L -> List L
+        ++ factor1(a) returns the factorisation of a,
+        ++ assuming that a has no first-order right factor.
+ 
+  Impl ==> add
+    import RationalLODE(F, UP)
+    import RationalRicDE(F, UP)
+--  import AssociatedEquations RF
+ 
+    dd := D()$L
+ 
+    expsol     : (L, UP -> List F, UP -> Factored UP) -> Union(RF, "failed")
+    expsols    : (L, UP -> List F, UP -> Factored UP, Boolean) -> List RF
+    opeval     : (L, L) -> L
+    recurfactor: (L, L, UP -> List F, UP -> Factored UP, Boolean) -> List L
+    rfactor    : (L, L, UP -> List F, UP -> Factored UP, Boolean) -> List L
+    rightFactor: (L, NonNegativeInteger, UP -> List F, UP -> Factored UP)
+                                                          -> Union(L, "failed")
+    innerFactor: (L, UP -> List F, UP -> Factored UP, Boolean) -> List L
+ 
+    factor(l, zeros) == innerFactor(l, zeros, squareFree, true)
+ 
+    expsol(l, zeros, ezfactor) ==
+      empty?(sol := expsols(l, zeros, ezfactor, false)) => "failed"
+      first sol
+ 
+    expsols(l, zeros, ezfactor, all?) ==
+      sol := [differentiate(f)/f for f in ratDsolve(l, 0).basis | f ^= 0]
+      not(all? or empty? sol) => sol
+      concat(sol, ricDsolve(l, zeros, ezfactor))
+ 
+-- opeval(l1, l2) returns l1(l2)
+    opeval(l1, l2) ==
+      ans:L := 0
+      l2n:L := 1
+      for i in 0..degree l1 repeat
+        ans := ans + coefficient(l1, i) * l2n
+        l2n := l2 * l2n
+      ans
+      
+    recurfactor(l, r, zeros, ezfactor, adj?) ==
+      q := rightExactQuotient(l, r)::L
+      if adj? then q := adjoint q
+      innerFactor(q, zeros, ezfactor, true)
+ 
+    rfactor(op, r, zeros, ezfactor, adj?) ==
+--      degree r > 1 or not one? leadingCoefficient r =>
+      degree r > 1 or not ((leadingCoefficient r) = 1) =>
+        recurfactor(op, r, zeros, ezfactor, adj?)
+      op1 := opeval(op, dd - coefficient(r, 0)::L)
+      map_!(opeval(#1, r), recurfactor(op1, dd, zeros, ezfactor, adj?))
+ 
+-- r1? is true means look for 1st-order right-factor also
+    innerFactor(l, zeros, ezfactor, r1?) ==
+      (n := degree l) <= 1 => [l]
+      ll := adjoint l
+      for i in 1..(n quo 2) repeat
+        (r1? or (i > 1)) and ((u := rightFactor(l,i,zeros,ezfactor)) case L) =>
+           return concat_!(rfactor(l, u::L, zeros, ezfactor, false), u::L)
+        (2 * i < n) and ((u := rightFactor(ll, i, zeros, ezfactor)) case L) =>
+           return concat(adjoint(u::L), rfactor(ll, u::L, zeros,ezfactor,true))
+      [l]
+ 
+    rightFactor(l, n, zeros, ezfactor) ==
+--      one? n =>
+      (n = 1) =>
+        (u := expsol(l, zeros, ezfactor)) case "failed" => "failed"
+        D() - u::RF::L
+--    rec := associatedEquations(l, n::PositiveInteger)
+--    empty?(sol := expsols(rec.eq, zeros, ezfactor, true)) => "failed"
+      "failed"
+ 
+    if F has AlgebraicallyClosedField then
+      zro1: UP -> List F
+      zro : (UP, UP -> Factored UP) -> List F
+ 
+      zro(p, ezfactor) ==
+        concat [zro1(r.factor) for r in factors ezfactor p]
+ 
+      zro1 p ==
+        [zeroOf(map(#1, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
+                                             F, SparseUnivariatePolynomial F))]
+ 
+      if F is AlgebraicNumber then
+        import AlgFactor UP
+ 
+        factor l  == innerFactor(l, zro(#1, factor), factor, true)
+        factor1 l == innerFactor(l, zro(#1, factor), factor, false)
+ 
+      else
+        factor l  == innerFactor(l, zro(#1, squareFree), squareFree, true)
+        factor1 l == innerFactor(l, zro(#1, squareFree), squareFree, false)
+
+@
+<<LODOF.dotabb>>=
+"LODOF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LODOF"]
+"ACF" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACF"]
+"LODOF" -> "ACF"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LODOOPS LinearOrdinaryDifferentialOperatorsOps}
+\pagehead{LinearOrdinaryDifferentialOperatorsOps}{LODOOPS}
+\pagepic{ps/v104linearordinarydifferentialoperatorsops.ps}{LODOOPS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>=
+)abbrev package LODOOPS LinearOrdinaryDifferentialOperatorsOps
+++ Author: Manuel Bronstein
+++ Date Created: 18 January 1994
+++ Date Last Updated: 15 April 1994
+++ Description:
+++   \spad{LinearOrdinaryDifferentialOperatorsOps} provides symmetric
+++   products and sums for linear ordinary differential operators.
+-- Putting those operations here rather than defaults in LODOCAT allows
+-- LODOCAT to be defined independently of the derivative used.
+-- MB 1/94
+LinearOrdinaryDifferentialOperatorsOps(A, L): Exports == Implementation where
+    A: Field
+    L: LinearOrdinaryDifferentialOperatorCategory A
+
+    N  ==> NonNegativeInteger
+    V  ==> OrderlyDifferentialVariable Symbol
+    P  ==> DifferentialSparseMultivariatePolynomial(A, Symbol, V)
+
+    Exports ==> with
+          symmetricProduct: (L, L, A -> A) -> L
+            ++ symmetricProduct(a,b,D) computes an operator \spad{c} of
+            ++ minimal order such that the nullspace of \spad{c} is
+            ++ generated by all the products of a solution of \spad{a} by
+            ++ a solution of \spad{b}.
+            ++ D is the derivation to use.
+          symmetricPower: (L, N, A -> A) -> L
+            ++ symmetricPower(a,n,D) computes an operator \spad{c} of
+            ++ minimal order such that the nullspace of \spad{c} is
+            ++ generated by all the products of \spad{n} solutions
+            ++ of \spad{a}.
+            ++ D is the derivation to use.
+          directSum: (L, L, A -> A) -> L
+            ++ directSum(a,b,D) computes an operator \spad{c} of
+            ++ minimal order such that the nullspace of \spad{c} is
+            ++ generated by all the sums of a solution of \spad{a} by
+            ++ a solution of \spad{b}.
+            ++ D is the derivation to use.
+
+    Implementation ==> add
+          import IntegerCombinatoricFunctions
+
+          var1 := new()$Symbol
+          var2 := new()$Symbol
+
+          nonTrivial?: Vector A -> Boolean
+          applyLODO  : (L, V) -> P
+          killer     : (P, N, List V, List P, A -> A) -> L
+          vec2LODO   : Vector A -> L
+
+          nonTrivial? v == any?(#1 ^= 0, v)$Vector(A)
+          vec2LODO v    == +/[monomial(v.i, (i-1)::N) for i in 1..#v]
+
+          symmetricPower(l, m, diff) ==
+            u := var1::V; n := degree l
+            un := differentiate(u, n)
+            a  := applyLODO(inv(- leadingCoefficient l) * reductum l, u)
+            killer(u::P ** m, binomial(n + m - 1, n - 1)::N, [un], [a], diff)
+
+-- returns an operator L such that L(u) = 0, for a given differential
+-- polynomial u, given that the differential variables appearing in u
+-- satisfy some linear ode's
+-- m is a bound on the order of the operator searched.
+-- lvar, lval describe the substitution(s) to perform when differentiating
+--     the expression u (they encode the fact the the differential variables
+--     satisfy some differential equations, which can be seen as the rewrite
+--     rules   lvar --> lval)
+-- diff is the derivation to use
+          killer(u, m, lvar, lval, diff) ==
+            lu:List P := [u]
+            for q in 0..m repeat
+              mat := reducedSystem(matrix([lu])@Matrix(P))@Matrix(A)
+              (sol := find(nonTrivial?, l := nullSpace mat)) case Vector(A) =>
+                return vec2LODO(sol::Vector(A))
+              u := eval(differentiate(u, diff), lvar, lval)
+              lu := concat_!(lu, [u])
+            error "killer: no linear dependence found"
+
+          symmetricProduct(l1, l2, diff) ==
+            u  := var1::V;   v  := var2::V
+            n1 := degree l1; n2 := degree l2
+            un := differentiate(u, n1); vn := differentiate(v, n2)
+            a  := applyLODO(inv(- leadingCoefficient l1) * reductum l1, u)
+            b  := applyLODO(inv(- leadingCoefficient l2) * reductum l2, v)
+            killer(u::P * v::P, n1 * n2, [un, vn], [a, b], diff)
+
+          directSum(l1, l2, diff) ==
+            u  := var1::V;   v  := var2::V
+            n1 := degree l1; n2 := degree l2
+            un := differentiate(u, n1); vn := differentiate(v, n2)
+            a  := applyLODO(inv(- leadingCoefficient l1) * reductum l1, u)
+            b  := applyLODO(inv(- leadingCoefficient l2) * reductum l2, v)
+            killer(u::P + v::P, n1 + n2, [un, vn], [a, b], diff)
+
+          applyLODO(l, v) ==
+            p:P := 0
+            while l ^= 0 repeat
+              p := p + monomial(leadingCoefficient(l)::P,
+                                  differentiate(v, degree l), 1)
+              l := reductum l
+            p
+
+@
+<<LODOOPS.dotabb>>=
+"LODOOPS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LODOOPS"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"LODOOPS" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package LPEFRAC LinearPolynomialEquationByFractions}
 \pagehead{LinearPolynomialEquationByFractions}{LPEFRAC}
 \pagepic{ps/v104linearpolynomialequationbyfractions.ps}{LPEFRAC}{1.00}
@@ -31680,6 +36433,747 @@ LinearPolynomialEquationByFractions(R:PolynomialFactorizationExplicit): with
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LGROBP LinGroebnerPackage}
+\pagehead{LinGroebnerPackage}{LGROBP}
+\pagepic{ps/v104lingroebnerpackage.ps}{LGROBP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LGROBP LinGroebnerPackage>>=
+)abbrev package LGROBP LinGroebnerPackage
+++  Given a Groebner basis B with respect to the total degree ordering for
+++  a zero-dimensional ideal I, compute
+++  a Groebner basis with respect to the lexicographical ordering by using
+++  linear algebra.
+LinGroebnerPackage(lv,F) : C == T
+
+ where
+  Z      ==>  Integer
+  lv     :    List Symbol
+  F      :    GcdDomain
+
+  DP     ==>  DirectProduct(#lv,NonNegativeInteger)
+  DPoly  ==>  DistributedMultivariatePolynomial(lv,F)
+
+  HDP    ==>  HomogeneousDirectProduct(#lv,NonNegativeInteger)
+  HDPoly ==>  HomogeneousDistributedMultivariatePolynomial(lv,F)
+
+  OV     ==>  OrderedVariableList(lv)
+  NNI    ==>  NonNegativeInteger
+  LVals  ==>  Record(gblist : List DPoly,gvlist : List Z)
+  VF     ==>  Vector F
+  VV     ==>  Vector NNI
+  MF     ==>  Matrix F
+  cLVars ==>  Record(glbase:List DPoly,glval:List Z)
+
+  C == with
+
+     linGenPos    :           List HDPoly      -> LVals
+	++ linGenPos \undocumented
+     groebgen     :           List DPoly       -> cLVars
+	++ groebgen \undocumented
+     totolex      :           List HDPoly      -> List DPoly
+	++ totolex \undocumented
+     minPol       : (List HDPoly,List HDPoly,OV) -> HDPoly
+	++ minPol \undocumented
+     minPol       :        (List HDPoly,OV)     -> HDPoly
+	++ minPol \undocumented
+
+
+     computeBasis :        List HDPoly           -> List HDPoly
+	++ computeBasis \undocumented
+     coord        : (HDPoly,List HDPoly)         -> VF
+	++ coord \undocumented
+     anticoord    : (List F,DPoly,List DPoly)    -> DPoly
+	++ anticoord \undocumented
+     intcompBasis : (OV,List HDPoly,List HDPoly) -> List HDPoly
+	++ intcompBasis \undocumented
+     choosemon    :     (DPoly,List  DPoly)      -> DPoly
+	++ choosemon \undocumented
+     transform    :           DPoly              -> HDPoly
+	++ transform \undocumented
+
+
+  T == add
+
+    import GroebnerPackage(F,DP,OV,DPoly)
+    import GroebnerPackage(F,HDP,OV,HDPoly)
+    import GroebnerInternalPackage(F,HDP,OV,HDPoly)
+    import GroebnerInternalPackage(F,DP,OV,DPoly)
+
+    lvar :=[variable(yx)::OV for yx in lv]
+
+    reduceRow(M:MF, v : VF, lastRow: Integer, pivots: Vector(Integer)) : VF ==
+      a1:F := 1
+      b:F := 0
+      dim := #v
+      for j in 1..lastRow repeat -- scan over rows
+         mj := row(M,j)
+         k:=pivots(j)
+         b:=mj.k
+         vk := v.k
+         for kk in 1..(k-1) repeat
+            v(kk) := ((-b*v(kk)) exquo a1) :: F
+         for kk in k..dim repeat
+            v(kk) := ((vk*mj(kk)-b*v(kk)) exquo a1)::F
+         a1 := b
+      v
+
+    rRedPol(f:HDPoly, B:List HDPoly):Record(poly:HDPoly, mult:F) ==
+      gm := redPo(f,B)
+      gm.poly = 0 => gm
+      gg := reductum(gm.poly)
+      ggm := rRedPol(gg,B)
+      [ggm.mult*(gm.poly - gg) + ggm.poly, ggm.mult*gm.mult]
+
+----- transform the total basis B in lex basis -----
+    totolex(B : List HDPoly) : List DPoly ==
+      result:List DPoly :=[]
+      ltresult:List DPoly :=[]
+      vBasis:= computeBasis B
+      nBasis:List DPoly :=[1$DPoly]
+      ndim:=(#vBasis)::PositiveInteger
+      ndim1:NNI:=ndim+1
+      lm:VF
+      linmat:MF:=zero(ndim,2*ndim+1)
+      linmat(1,1):=1$F
+      linmat(1,ndim1):=1
+      pivots:Vector Integer := new(ndim,0)
+      pivots(1) := 1
+      firstmon:DPoly:=1$DPoly
+      ofirstmon:DPoly:=1$DPoly
+      orecfmon:Record(poly:HDPoly, mult:F) := [1,1]
+      i:NNI:=2
+      while (firstmon:=choosemon(firstmon,ltresult))^=1 repeat
+        if (v:=firstmon exquo ofirstmon) case "failed" then
+          recfmon:=rRedPol(transform firstmon,B)
+        else
+          recfmon:=rRedPol(transform(v::DPoly) *orecfmon.poly,B)
+          recfmon.mult := recfmon.mult * orecfmon.mult
+        cc := gcd(content recfmon.poly, recfmon.mult)
+        recfmon.poly := (recfmon.poly exquo cc)::HDPoly
+        recfmon.mult := (recfmon.mult exquo cc)::F
+        veccoef:VF:=coord(recfmon.poly,vBasis)
+        ofirstmon:=firstmon
+        orecfmon := recfmon
+        lm:=zero(2*ndim+1)
+        for j in 1..ndim repeat lm(j):=veccoef(j)
+        lm(ndim+i):=recfmon.mult
+        lm := reduceRow(linmat, lm, i-1, pivots)
+        if i=ndim1 then j:=ndim1
+        else
+          j:=1
+          while lm(j) = 0 and j< ndim1 repeat j:=j+1
+        if j=ndim1 then
+          cordlist:List F:=[lm(k) for k in ndim1..ndim1+(#nBasis)]
+          antc:=+/[c*b for c in reverse cordlist
+                       for b in concat(firstmon,nBasis)]
+          antc:=primitivePart antc
+          result:=concat(antc,result)
+          ltresult:=concat(antc-reductum antc,ltresult)
+        else
+          pivots(i) := j
+          setRow_!(linmat,i,lm)
+          i:=i+1
+          nBasis:=cons(firstmon,nBasis)
+      result
+
+---- Compute the univariate polynomial for x
+----oldBasis is a total degree Groebner basis
+    minPol(oldBasis:List HDPoly,x:OV) :HDPoly ==
+      algBasis:= computeBasis oldBasis
+      minPol(oldBasis,algBasis,x)
+
+---- Compute the univariate polynomial for x
+---- oldBasis is total Groebner, algBasis is the basis as algebra
+    minPol(oldBasis:List HDPoly,algBasis:List HDPoly,x:OV) :HDPoly ==
+      nvp:HDPoly:=x::HDPoly
+      f:=1$HDPoly
+      omult:F :=1
+      ndim:=(#algBasis)::PositiveInteger
+      ndim1:NNI:=ndim+1
+      lm:VF
+      linmat:MF:=zero(ndim,2*ndim+1)
+      linmat(1,1):=1$F
+      linmat(1,ndim1):=1
+      pivots:Vector Integer := new(ndim,0)
+      pivots(1) := 1
+      for i in 2..ndim1 repeat
+        recf:=rRedPol(f*nvp,oldBasis)
+        omult := recf.mult * omult
+        f := recf.poly
+        cc := gcd(content f, omult)
+        f := (f exquo cc)::HDPoly
+        omult := (omult exquo cc)::F
+        veccoef:VF:=coord(f,algBasis)
+        lm:=zero(2*ndim+1)
+        for j in 1..ndim repeat lm(j) := veccoef(j)
+        lm(ndim+i):=omult
+        lm := reduceRow(linmat, lm, i-1, pivots)
+        j:=1
+        while lm(j)=0 and j<ndim1 repeat j:=j+1
+        if j=ndim1 then return
+          g:HDPoly:=0
+          for k in ndim1..2*ndim+1 repeat
+            g:=g+lm(k) * nvp**((k-ndim1):NNI)
+          primitivePart g
+        pivots(i) := j
+        setRow_!(linmat,i,lm)
+
+----- transform a DPoly in a HDPoly -----
+    transform(dpol:DPoly) : HDPoly ==
+      dpol=0 => 0$HDPoly
+      monomial(leadingCoefficient dpol,
+               directProduct(degree(dpol)::VV)$HDP)$HDPoly +
+                                      transform(reductum dpol)
+
+----- compute the basis for the vector space determined by B -----
+    computeBasis(B:List HDPoly) : List HDPoly ==
+      mB:List HDPoly:=[monomial(1$F,degree f)$HDPoly for f in B]
+      result:List HDPoly := [1$HDPoly]
+      for var in lvar repeat
+        part:=intcompBasis(var,result,mB)
+        result:=concat(result,part)
+      result
+
+----- internal function for computeBasis -----
+    intcompBasis(x:OV,lr:List HDPoly,mB : List HDPoly):List HDPoly ==
+      lr=[] => lr
+      part:List HDPoly :=[]
+      for f in lr repeat
+        g:=x::HDPoly * f
+        if redPo(g,mB).poly^=0 then part:=concat(g,part)
+      concat(part,intcompBasis(x,part,mB))
+
+----- coordinate of f with respect to the basis B -----
+----- f is a reduced polynomial -----
+    coord(f:HDPoly,B:List HDPoly) : VF ==
+      ndim := #B
+      vv:VF:=new(ndim,0$F)$VF
+      while f^=0 repeat
+        rf := reductum f
+        lf := f-rf
+        lcf := leadingCoefficient f
+        i:Z:=position(monomial(1$F,degree lf),B)
+        vv.i:=lcf
+        f := rf
+      vv
+
+----- reconstruct the polynomial from its coordinate -----
+    anticoord(vv:List F,mf:DPoly,B:List DPoly) : DPoly ==
+      for f in B for c in vv repeat (mf:=mf-c*f)
+      mf
+
+----- choose the next monom -----
+    choosemon(mf:DPoly,nB:List DPoly) : DPoly ==
+      nB = [] => ((lvar.last)::DPoly)*mf
+      for x in reverse lvar repeat
+        xx:=x ::DPoly
+        mf:=xx*mf
+        if redPo(mf,nB).poly ^= 0 then return mf
+        dx := degree(mf,x)
+        mf := (mf exquo (xx ** dx))::DPoly
+      mf
+
+----- put B in general position, B is Groebner -----
+    linGenPos(B : List HDPoly) : LVals ==
+      result:List DPoly :=[]
+      ltresult:List DPoly :=[]
+      vBasis:= computeBasis B
+      nBasis:List DPoly :=[1$DPoly]
+      ndim:=#vBasis : PositiveInteger
+      ndim1:NNI:=ndim+1
+      lm:VF
+      linmat:MF:=zero(ndim,2*ndim+1)
+      linmat(1,1):=1$F
+      linmat(1,ndim1):=1
+      pivots:Vector Integer := new(ndim,0)
+      pivots(1) := 1
+      i:NNI:=2
+      rval:List Z :=[]
+      for ii in 1..(#lvar-1) repeat
+        c:Z:=0
+        while c=0 repeat c:=random()$Z rem 11
+        rval:=concat(c,rval)
+      nval:DPoly := (last.lvar)::DPoly -
+                (+/[r*(vv)::DPoly for r in rval for vv in lvar])
+      firstmon:DPoly:=1$DPoly
+      ofirstmon:DPoly:=1$DPoly
+      orecfmon:Record(poly:HDPoly, mult:F) := [1,1]
+      lx:= lvar.last
+      while (firstmon:=choosemon(firstmon,ltresult))^=1 repeat
+        if (v:=firstmon exquo ofirstmon) case "failed" then
+          recfmon:=rRedPol(transform(eval(firstmon,lx,nval)),B)
+        else
+          recfmon:=rRedPol(transform(eval(v,lx,nval))*orecfmon.poly,B)
+          recfmon.mult := recfmon.mult * orecfmon.mult
+        cc := gcd(content recfmon.poly, recfmon.mult)
+        recfmon.poly := (recfmon.poly exquo cc)::HDPoly
+        recfmon.mult := (recfmon.mult exquo cc)::F
+        veccoef:VF:=coord(recfmon.poly,vBasis)
+        ofirstmon:=firstmon
+        orecfmon := recfmon
+        lm:=zero(2*ndim+1)
+        for j in 1..ndim repeat lm(j):=veccoef(j)
+        lm(ndim+i):=recfmon.mult
+        lm := reduceRow(linmat, lm, i-1, pivots)
+        j:=1
+        while lm(j) = 0 and j<ndim1 repeat j:=j+1
+        if j=ndim1 then
+          cordlist:List F:=[lm(j) for j in ndim1..ndim1+(#nBasis)]
+          antc:=+/[c*b for c in reverse cordlist
+                       for b in concat(firstmon,nBasis)]
+          result:=concat(primitivePart antc,result)
+          ltresult:=concat(antc-reductum antc,ltresult)
+        else
+          pivots(i) := j
+          setRow_!(linmat,i,lm)
+          i:=i+1
+          nBasis:=concat(firstmon,nBasis)
+      [result,rval]$LVals
+
+----- given a basis of a zero-dimensional ideal,
+----- performs a random change of coordinates
+----- computes a Groebner basis for the lex ordering
+    groebgen(L:List DPoly) : cLVars ==
+      xn:=lvar.last
+      val := xn::DPoly
+      nvar1:NNI:=(#lvar-1):NNI
+      ll: List Z :=[random()$Z rem 11 for i in 1..nvar1]
+      val:=val+ +/[ll.i*(lvar.i)::DPoly for i in 1..nvar1]
+      LL:=[elt(univariate(f,xn),val) for f in L]
+      LL:=  groebner(LL)
+      [LL,ll]$cLVars
+
+@
+<<LGROBP.dotabb>>=
+"LGROBP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LGROBP"]
+"DIRPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=DIRPCAT"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"LGROBP" -> "DIRPCAT"
+"LGROBP" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LF LiouvillianFunction}
+\pagehead{LiouvillianFunction}{LF}
+\pagepic{ps/v104liouvillianfunction.ps}{LF}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LF LiouvillianFunction>>=
+)abbrev package LF LiouvillianFunction
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 10 August 1994
+++ Keywords: liouvillian, function, primitive, exponential.
+++ Examples:  )r LF INPUT
+++ Description:
+++   This package provides liouvillian functions over an integral domain.
+LiouvillianFunction(R, F): Exports == Implementation where
+  R:Join(OrderedSet, IntegralDomain)
+  F:Join(FunctionSpace R,RadicalCategory,TranscendentalFunctionCategory)
+
+  OP  ==> BasicOperator
+  PR  ==> Polynomial R
+  K   ==> Kernel F
+  SE  ==> Symbol
+  O   ==> OutputForm
+  INP ==> InputForm
+  INV ==> error "Invalid argument"
+
+  SPECIALDIFF ==> "%specialDiff"
+  SPECIALDISP ==> "%specialDisp"
+  SPECIALINPUT ==> "%specialInput"
+  SPECIALEQUAL ==> "%specialEqual"
+
+  Exports ==> with
+    belong? : OP -> Boolean
+      ++ belong?(op) checks if op is Liouvillian
+    operator: OP -> OP
+      ++ operator(op) returns the Liouvillian operator based on op
+    Ei      : F  -> F
+      ++ Ei(f) denotes the exponential integral
+    Si      : F  -> F
+      ++ Si(f) denotes the sine integral
+    Ci      : F  -> F
+      ++ Ci(f) denotes the cosine integral
+    li      : F  -> F
+      ++ li(f) denotes the logarithmic integral
+    erf     : F  -> F
+      ++ erf(f) denotes the error function
+    dilog   : F  -> F
+      ++ dilog(f) denotes the dilogarithm
+    integral: (F, SE) -> F
+      ++ integral(f,x) indefinite integral of f with respect to x.
+    integral: (F, SegmentBinding F) -> F
+      ++ integral(f,x = a..b) denotes the definite integral of f with
+      ++ respect to x from \spad{a} to b.
+
+  Implementation ==> add
+    iei        : F  -> F
+    isi        : F  -> F
+    ici        : F  -> F
+    ierf       : F  -> F
+    ili        : F  -> F
+    ili2       : F  -> F
+    iint       : List F -> F
+    eqint      : (K,K) -> Boolean
+    dvint      : (List F, SE) -> F
+    dvdint     : (List F, SE) -> F
+    ddint      : List F -> O
+    integrand  : List F -> F
+
+    dummy := new()$SE :: F
+
+    opint  := operator("integral"::Symbol)$CommonOperators
+    opdint := operator("%defint"::Symbol)$CommonOperators
+    opei   := operator("Ei"::Symbol)$CommonOperators
+    opli   := operator("li"::Symbol)$CommonOperators
+    opsi   := operator("Si"::Symbol)$CommonOperators
+    opci   := operator("Ci"::Symbol)$CommonOperators
+    opli2  := operator("dilog"::Symbol)$CommonOperators
+    operf  := operator("erf"::Symbol)$CommonOperators
+
+    Si x                == opsi x
+    Ci x                == opci x
+    Ei x                == opei x
+    erf x               == operf x
+    li  x               == opli x
+    dilog x             == opli2 x
+
+    belong? op     == has?(op, "prim")
+    isi x          == kernel(opsi, x)
+    ici x          == kernel(opci, x)
+    ierf x         == (zero? x => 0; kernel(operf, x))
+--    ili2 x         == (one? x => INV; kernel(opli2, x))
+    ili2 x         == ((x = 1) => INV; kernel(opli2, x))
+    integrand l    == eval(first l, retract(second l)@K, third l)
+    integral(f:F, x:SE) == opint [eval(f, k:=kernel(x)$K, dummy), dummy, k::F]
+
+    iint l ==
+      zero? first l => 0
+      kernel(opint, l)
+
+    ddint l ==
+      int(integrand(l)::O * hconcat("d"::SE::O, third(l)::O),
+                                    third(rest l)::O, third(rest rest l)::O)
+
+    eqint(k1,k2) == 
+      a1:=argument k1
+      a2:=argument k2
+      res:=operator k1 = operator k2
+      if not res then return res
+      res:= a1 = a2
+      if res then return res
+      res:= (a1.3 = a2.3) and (subst(a1.1,[retract(a1.2)@K],[a2.2]) = a2.1)
+
+    dvint(l, x) ==
+      k  := retract(second l)@K
+      differentiate(third l, x) * integrand l
+          + opint [differentiate(first l, x), second l, third l]
+
+
+    dvdint(l, x) ==
+      x = retract(y := third l)@SE => 0
+      k := retract(d := second l)@K
+      differentiate(h := third rest rest l,x) * eval(f := first l, k, h)
+        - differentiate(g := third rest l, x) * eval(f, k, g)
+             + opdint [differentiate(f, x), d, y, g, h]
+
+    integral(f:F, s: SegmentBinding F) ==
+      x := kernel(variable s)$K
+      opdint [eval(f,x,dummy), dummy, x::F, lo segment s, hi segment s]
+
+    ili x ==
+      x = 1 => INV
+      is?(x, "exp"::Symbol) => Ei first argument(retract(x)@K)
+      kernel(opli, x)
+
+    iei x ==
+      x = 0 => INV
+      is?(x, "log"::Symbol) => li first argument(retract(x)@K)
+      kernel(opei, x)
+
+    operator op ==
+      is?(op, "integral"::Symbol)   => opint
+      is?(op, "%defint"::Symbol)    => opdint
+      is?(op, "Ei"::Symbol)         => opei
+      is?(op, "Si"::Symbol)         => opsi
+      is?(op, "Ci"::Symbol)         => opci
+      is?(op, "li"::Symbol)         => opli
+      is?(op, "erf"::Symbol)        => operf
+      is?(op, "dilog"::Symbol)      => opli2
+      error "Not a Liouvillian operator"
+
+    evaluate(opei,   iei)$BasicOperatorFunctions1(F)
+    evaluate(opli,   ili)
+    evaluate(opsi,   isi)
+    evaluate(opci,   ici)
+    evaluate(operf,  ierf)
+    evaluate(opli2,  ili2)
+    evaluate(opint,  iint)
+    derivative(opsi, sin(#1) / #1)
+    derivative(opci, cos(#1) / #1)
+    derivative(opei, exp(#1) / #1)
+    derivative(opli, inv log(#1))
+    derivative(operf, 2 * exp(-(#1**2)) / sqrt(pi()))
+    derivative(opli2, log(#1) / (1 - #1))
+    setProperty(opint,SPECIALEQUAL,eqint@((K,K) -> Boolean) pretend None)
+    setProperty(opint,SPECIALDIFF,dvint@((List F,SE) -> F) pretend None)
+    setProperty(opdint,SPECIALDIFF,dvdint@((List F,SE)->F) pretend None)
+    setProperty(opdint, SPECIALDISP, ddint@(List F -> O) pretend None)
+
+    if R has ConvertibleTo INP then
+      inint : List F -> INP
+      indint: List F -> INP
+      pint  : List INP -> INP
+
+
+      pint l  == convert concat(convert("integral"::SE)@INP, l)
+      inint l == 
+        r2:= convert([convert("::"::SE)@INP,convert(third l)@INP,convert("Symbol"::SE)@INP]@List INP)@INP
+        pint [convert(integrand l)@INP, r2]
+
+      indint l ==
+        pint [convert(integrand l)@INP,
+              convert concat(convert("="::SE)@INP,
+                            [convert(third l)@INP,
+                             convert concat(convert("SEGMENT"::SE)@INP,
+                                            [convert(third rest l)@INP,
+                                             convert(third rest rest l)@INP])])]
+
+      setProperty(opint, SPECIALINPUT, inint@(List F -> INP) pretend None)
+      setProperty(opdint, SPECIALINPUT, indint@(List F -> INP) pretend None)
+
+@
+<<LF.dotabb>>=
+"LF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LF"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"LF" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LIST2 ListFunctions2}
+\pagehead{ListFunctions2}{LIST2}
+\pagepic{ps/v104listfunctions2.ps}{LIST2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LIST2 ListFunctions2>>=
+)abbrev package LIST2 ListFunctions2
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: map, reduce, scan
+++ Related Constructors: List
+++ Also See: ListFunctions3
+++ AMS Classification:
+++ Keywords: list, aggregate, map, reduce
+++ Description:
+++   \spadtype{ListFunctions2} implements utility functions that
+++   operate on two kinds of lists, each with a possibly different
+++   type of element.
+ListFunctions2(A:Type, B:Type): public == private where
+  LA     ==> List A
+  LB     ==> List B
+  O2     ==> FiniteLinearAggregateFunctions2(A, LA, B, LB)
+
+  public ==> with
+    scan:    ((A, B) -> B, LA, B) -> LB
+      ++ scan(fn,u,ident) successively uses the binary function
+      ++ \spad{fn} to reduce more and more of list \spad{u}.
+      ++ \spad{ident} is returned if the \spad{u} is empty.
+      ++ The result is a list of the reductions at each step. See
+      ++ \spadfun{reduce} for more information. Examples:
+      ++ \spad{scan(fn,[1,2],0) = [fn(2,fn(1,0)),fn(1,0)]} and
+      ++ \spad{scan(*,[2,3],1) = [2 * 1, 3 * (2 * 1)]}.
+    reduce:  ((A, B) -> B, LA, B) -> B
+      ++ reduce(fn,u,ident) successively uses the binary function
+      ++ \spad{fn} on the elements of list \spad{u} and the result
+      ++ of previous applications. \spad{ident} is returned if the
+      ++ \spad{u} is empty. Note the order of application in
+      ++ the following examples:
+      ++ \spad{reduce(fn,[1,2,3],0) = fn(3,fn(2,fn(1,0)))} and
+      ++ \spad{reduce(*,[2,3],1) = 3 * (2 * 1)}.
+    map:      (A -> B, LA) -> LB
+      ++ map(fn,u) applies \spad{fn} to each element of
+      ++ list \spad{u} and returns a new list with the results.
+      ++ For example \spad{map(square,[1,2,3]) = [1,4,9]}.
+
+  private ==> add
+    map(f, l)       == map(f, l)$O2
+    scan(f, l, b)   == scan(f, l, b)$O2
+    reduce(f, l, b) == reduce(f, l, b)$O2
+
+@
+<<LIST2.dotabb>>=
+"LIST2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LIST2"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"LIST2" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LIST3 ListFunctions3}
+\pagehead{ListFunctions3}{LIST3}
+\pagepic{ps/v104listfunctions3.ps}{LIST3}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LIST3 ListFunctions3>>=
+)abbrev package LIST3 ListFunctions3
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: map
+++ Related Constructors: List
+++ Also See: ListFunctions2
+++ AMS Classification:
+++ Keywords: list, aggregate, map
+++ Description:
+++   \spadtype{ListFunctions3} implements utility functions that
+++   operate on three kinds of lists, each with a possibly different
+++   type of element.
+ListFunctions3(A:Type, B:Type, C:Type): public == private where
+  LA     ==> List A
+  LB     ==> List B
+  LC     ==> List C
+
+  public ==> with
+    map: ( (A,B)->C, LA, LB) -> LC
+      ++ map(fn,list1, u2) applies the binary function \spad{fn}
+      ++ to corresponding elements of lists \spad{u1} and \spad{u2}
+      ++ and returns a list of the results (in the same order). Thus
+      ++ \spad{map(/,[1,2,3],[4,5,6]) = [1/4,2/4,1/2]}. The computation
+      ++ terminates when the end of either list is reached. That is,
+      ++ the length of the result list is equal to the minimum of the
+      ++ lengths of \spad{u1} and \spad{u2}.
+
+  private ==> add
+    map(fn : (A,B) -> C, la : LA, lb : LB): LC ==
+      empty?(la) or empty?(lb) => empty()$LC
+      concat(fn(first la, first lb), map(fn, rest la, rest lb))
+
+@
+<<LIST3.dotabb>>=
+"LIST3" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LIST3"]
+"TYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=TYPE"]
+"LIST3" -> "TYPE"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LIST2MAP ListToMap}
+\pagehead{ListToMap}{LIST2MAP}
+\pagepic{ps/v104listtomap.ps}{LIST2MAP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LIST2MAP ListToMap>>=
+)abbrev package LIST2MAP ListToMap
+++ Author: Manuel Bronstein
+++ Date Created: 22 Mar 1988
+++ Change History:
+++   11 Oct 1989   MB   ?
+++ Basic Operations: match
+++ Related Constructors: List
+++ Also See:
+++ AMS Classification:
+++ Keywords: mapping, list
+++ Description:
+++   \spadtype{ListToMap} allows mappings to be described by a pair of
+++   lists of equal lengths.  The image of an element \spad{x},
+++   which appears in position \spad{n} in the first list, is then
+++   the \spad{n}th element of the second list.  A default value or
+++   default function can be specified to be used when \spad{x}
+++   does not appear in the first list.  In the absence of defaults,
+++   an error will occur in that case.
+ListToMap(A:SetCategory, B:Type): Exports == Implementation where
+  LA  ==> List A
+  LB  ==> List B
+  AB  ==> (A -> B)
+
+  Exports ==> with
+    match: (LA, LB   ) -> AB
+      ++ match(la, lb) creates a map with no default source or target values
+      ++ defined by lists la and lb of equal length.
+      ++ The target of a source value \spad{x} in la is the
+      ++ value y with the same index lb.
+      ++ Error: if la and lb are not of equal length.
+      ++ Note: when this map is applied, an error occurs when
+      ++ applied to a value missing from la.
+    match: (LA, LB, A) -> B
+      ++ match(la, lb, a) creates a map
+      ++ defined by lists la and lb of equal length, where \spad{a} is used
+      ++ as the default source value if the given one is not in \spad{la}.
+      ++ The target of a source value \spad{x} in la is the
+      ++ value y with the same index lb.
+      ++ Error: if la and lb are not of equal length.
+    match: (LA, LB, B)    -> AB
+      ++ match(la, lb, b) creates a map
+      ++ defined by lists la and lb of equal length, where \spad{b} is used
+      ++ as the default target value if the given function argument is
+      ++ not in \spad{la}.
+      ++ The target of a source value \spad{x} in la is the
+      ++ value y with the same index lb.
+      ++ Error: if la and lb are not of equal length.
+    match: (LA, LB, A, B) -> B
+      ++ match(la, lb, a, b) creates a map
+      ++ defined by lists la and lb of equal length.
+      ++ and applies this map to a.
+      ++ The target of a source value \spad{x} in la is the
+      ++ value y with the same index lb.
+      ++ Argument b is the default target value if a is not in la.
+      ++ Error: if la and lb are not of equal length.
+    match: (LA, LB, AB)    -> AB
+      ++ match(la, lb, f) creates a map
+      ++ defined by lists la and lb of equal length.
+      ++ The target of a source value \spad{x} in la is the
+      ++ value y with the same index lb.
+      ++ Argument \spad{f} is used as the
+      ++ function to call when the given function argument is not in
+      ++ \spad{la}.
+      ++ The value returned is f applied to that argument.
+    match: (LA, LB, A, AB) -> B
+      ++ match(la, lb, a, f) creates a map
+      ++ defined by lists la and lb of equal length.
+      ++ and applies this map to a.
+      ++ The target of a source value \spad{x} in la is the
+      ++ value y with the same index lb.
+      ++ Argument \spad{f} is a default function to call if a is not in la.
+      ++ The value returned is then obtained by applying f to argument a.
+
+  Implementation ==> add
+    match(la, lb)             == match(la, lb, #1)
+    match(la:LA, lb:LB, a:A)  == lb.position(a, la)
+    match(la:LA, lb:LB, b:B)  == match(la, lb, #1, b)
+    match(la:LA, lb:LB, f:AB) == match(la, lb, #1, f)
+
+    match(la:LA, lb:LB, a:A, b:B) ==
+      (p := position(a, la)) < minIndex(la) => b
+      lb.p
+
+    match(la:LA, lb:LB, a:A, f:AB) ==
+      (p := position(a, la)) < minIndex(la) => f a
+      lb.p
+
+@
+<<LIST2MAP.dotabb>>=
+"LIST2MAP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LIST2MAP"]
+"FLAGG-" [color="#88FF44",href="bookvol10.3.pdf#nameddest=FLAGG"]
+"LIST2MAP" -> "FLAGG-"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter M}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package MCDEN MatrixCommonDenominator}
@@ -36865,6 +42359,116 @@ NewtonInterpolation F: Exports == Implementation where
 @
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package NCODIV NonCommutativeOperatorDivision}
+\pagehead{NonCommutativeOperatorDivision}{NCODIV}
+\pagepic{ps/v104noncommutativeoperatordivision.ps}{NCODIV}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package NCODIV NonCommutativeOperatorDivision>>=
+)abbrev package NCODIV NonCommutativeOperatorDivision
+++ Author: Jean Della Dora, Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: LinearOrdinaryDifferentialOperator
+++ Also See:
+++ AMS Classifications:
+++ Keywords: gcd, lcm, division, non-commutative
+++ Examples:
+++ References:
+++ Description:
+++   This package provides a division and related operations for
+++   \spadtype{MonogenicLinearOperator}s over a \spadtype{Field}.
+++   Since the multiplication is in general non-commutative,
+++   these operations all have left- and right-hand versions.
+++   This package provides the operations based on left-division.
+            -- [q,r] = leftDivide(a,b) means a=b*q+r
+
+NonCommutativeOperatorDivision(P, F): PDcat == PDdef  where
+    P: MonogenicLinearOperator(F)
+    F: Field
+
+    PDcat == with
+        leftDivide:   (P, P) -> Record(quotient: P, remainder: P)
+            ++ leftDivide(a,b) returns the pair \spad{[q,r]} such that
+            ++ \spad{a = b*q + r} and the degree of \spad{r} is
+            ++ less than the degree of \spad{b}.
+            ++ This process is called ``left division''.
+        leftQuotient:  (P, P) -> P
+            ++ leftQuotient(a,b) computes the pair \spad{[q,r]} such that
+            ++ \spad{a = b*q + r} and the degree of \spad{r} is
+            ++ less than the degree of \spad{b}.
+            ++ The value \spad{q} is returned.
+        leftRemainder:  (P, P) -> P
+            ++ leftRemainder(a,b) computes the pair \spad{[q,r]} such that
+            ++ \spad{a = b*q + r} and the degree of \spad{r} is
+            ++ less than the degree of \spad{b}.
+            ++ The value \spad{r} is returned.
+        leftExactQuotient:(P, P) -> Union(P, "failed")
+            ++ leftExactQuotient(a,b) computes the value \spad{q}, if it exists,
+            ++  such that \spad{a = b*q}.
+
+        leftGcd:   (P, P) -> P
+            ++ leftGcd(a,b) computes the value \spad{g} of highest degree
+            ++ such that
+            ++    \spad{a = aa*g}
+            ++    \spad{b = bb*g}
+            ++ for some values \spad{aa} and \spad{bb}.
+            ++ The value \spad{g} is computed using left-division.
+        leftLcm:   (P, P) -> P
+            ++ leftLcm(a,b) computes the value \spad{m} of lowest degree
+            ++ such that \spad{m = a*aa = b*bb} for some values
+            ++ \spad{aa} and \spad{bb}.  The value \spad{m} is
+            ++ computed using left-division.
+
+    PDdef == add
+        leftDivide(a, b) ==
+            q: P := 0
+            r: P := a
+            iv:F := inv leadingCoefficient b
+            while degree r >= degree b and r ^= 0 repeat
+                h := monomial(iv*leadingCoefficient r,
+              	                 (degree r - degree b)::NonNegativeInteger)$P
+                r := r - b*h
+                q := q + h
+            [q,r]
+
+        -- leftQuotient(a,b) is the quotient from left division, etc.
+        leftQuotient(a,b)   == leftDivide(a,b).quotient
+        leftRemainder(a,b)   == leftDivide(a,b).remainder
+        leftExactQuotient(a,b) ==
+             qr := leftDivide(a,b)
+             if qr.remainder = 0 then qr.quotient else "failed"
+        -- l = leftGcd(a,b) means  a = aa*l  b = bb*l.  Uses leftDivide.
+        leftGcd(a,b) ==
+             a = 0 =>b
+             b = 0 =>a
+             while degree b > 0 repeat (a,b) := (b, leftRemainder(a,b))
+             if b=0 then a else b
+        -- l = leftLcm(a,b) means  l = a*aa  l = b*bb   Uses leftDivide.
+        leftLcm(a,b) ==
+            a = 0 =>b
+            b = 0 =>a
+            b0 := b
+            u  := monomial(1,0)$P
+            v  := 0
+            while leadingCoefficient b ^= 0 repeat
+                qr     := leftDivide(a,b)
+                (a, b) := (b, qr.remainder)
+                (u, v) := (u*qr.quotient+v, u)
+            b0*u
+
+@
+<<NCODIV.dotabb>>=
+"NCODIV" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NCODIV"]
+"FIELD"  [color="#4488FF",href="bookvol10.2.pdf#nameddest=FIELD"]
+"NCODIV" -> "FIELD"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package NONE1 NoneFunctions1}
 \pagehead{NoneFunctions1}{NONE1}
 \pagepic{ps/v104nonefunctions1.ps}{NONE1}{1.00}
@@ -38003,6 +43607,797 @@ PolynomialAN2Expression():Target == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package POLYROOT PolynomialRoots}
+\pagehead{PolynomialRoots}{POLYROOT}
+\pagepic{ps/v104polynomialroots.ps}{POLYROOT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package POLYROOT PolynomialRoots>>=
+)abbrev package POLYROOT PolynomialRoots
+++ Author: Manuel Bronstein
+++ Date Created: 15 July 1988
+++ Date Last Updated: 10 November 1993
+++ Description: computes n-th roots of quotients of
+++ multivariate polynomials
+-- not visible to the user
+PolynomialRoots(E, V, R, P, F):Exports == Implementation where
+  E: OrderedAbelianMonoidSup
+  V: OrderedSet
+  R: IntegralDomain
+  P: PolynomialCategory(R, E, V)
+  F: Field with
+    numer : $ -> P
+	++ numer(x) \undocumented
+    denom : $ -> P
+	++ denom(x) \undocumented
+    coerce: P -> $
+	++ coerce(p) \undocumented
+
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  Q   ==> Fraction Z
+  REC ==> Record(exponent:N, coef:F, radicand:F)
+
+  Exports ==> with
+    rroot: (R, N) -> REC
+      ++ rroot(f, n) returns \spad{[m,c,r]} such
+      ++ that \spad{f**(1/n) = c * r**(1/m)}.
+    qroot : (Q, N) -> REC
+      ++ qroot(f, n) returns \spad{[m,c,r]} such
+      ++ that \spad{f**(1/n) = c * r**(1/m)}.
+    if R has GcdDomain then froot: (F, N) -> REC
+      ++ froot(f, n) returns \spad{[m,c,r]} such
+      ++ that \spad{f**(1/n) = c * r**(1/m)}.
+    nthr: (P, N) -> Record(exponent:N,coef:P,radicand:List P)
+	++ nthr(p,n) should be local but conditional
+
+  Implementation ==> add
+    import FactoredFunctions Z
+    import FactoredFunctions P
+
+    rsplit: List P -> Record(coef:R, poly:P)
+    zroot : (Z, N) -> Record(exponent:N, coef:Z, radicand:Z)
+
+    zroot(x, n) ==
+--      zero? x or one? x => [1, x, 1]
+      zero? x or (x = 1) => [1, x, 1]
+      s := nthRoot(squareFree x, n)
+      [s.exponent, s.coef, */s.radicand]
+
+    if R has imaginary: () -> R then
+      czroot: (Z, N) -> REC
+
+      czroot(x, n) ==
+        rec := zroot(x, n)
+        rec.exponent = 2 and rec.radicand < 0 =>
+          [rec.exponent, rec.coef * imaginary()::P::F, (-rec.radicand)::F]
+        [rec.exponent, rec.coef::F, rec.radicand::F]
+
+      qroot(x, n) ==
+        sn := czroot(numer x, n)
+        sd := czroot(denom x, n)
+        m  := lcm(sn.exponent, sd.exponent)::N
+        [m, sn.coef / sd.coef,
+                    (sn.radicand ** (m quo sn.exponent)) /
+                                (sd.radicand ** (m quo sd.exponent))]
+    else
+      qroot(x, n) ==
+        sn := zroot(numer x, n)
+        sd := zroot(denom x, n)
+        m  := lcm(sn.exponent, sd.exponent)::N
+        [m, sn.coef::F / sd.coef::F,
+                    (sn.radicand ** (m quo sn.exponent))::F /
+                                (sd.radicand ** (m quo sd.exponent))::F]
+
+    if R has RetractableTo Fraction Z then
+      rroot(x, n) ==
+        (r := retractIfCan(x)@Union(Fraction Z,"failed")) case "failed"
+          => [n, 1, x::P::F]
+        qroot(r::Q, n)
+
+    else
+      if R has RetractableTo Z then
+        rroot(x, n) ==
+          (r := retractIfCan(x)@Union(Z,"failed")) case "failed"
+            => [n, 1, x::P::F]
+          qroot(r::Z::Q, n)
+      else
+        rroot(x, n) == [n, 1, x::P::F]
+
+    rsplit l ==
+      r := 1$R
+      p := 1$P
+      for q in l repeat
+        if (u := retractIfCan(q)@Union(R, "failed")) case "failed"
+          then p := p * q
+          else r := r * u::R
+      [r, p]
+
+    if R has GcdDomain then
+      if R has RetractableTo Z then
+        nthr(x, n) ==
+          (r := retractIfCan(x)@Union(Z,"failed")) case "failed"
+             => nthRoot(squareFree x, n)
+          rec := zroot(r::Z, n)
+          [rec.exponent, rec.coef::P, [rec.radicand::P]]
+      else nthr(x, n) == nthRoot(squareFree x, n)
+
+      froot(x, n) ==
+--        zero? x or one? x => [1, x, 1]
+        zero? x or (x = 1) => [1, x, 1]
+        sn := nthr(numer x, n)
+        sd := nthr(denom x, n)
+        pn := rsplit(sn.radicand)
+        pd := rsplit(sd.radicand)
+        rn := rroot(pn.coef, sn.exponent)
+        rd := rroot(pd.coef, sd.exponent)
+        m := lcm([rn.exponent, rd.exponent, sn.exponent, sd.exponent])::N
+        [m, (sn.coef::F / sd.coef::F) * (rn.coef / rd.coef),
+             ((rn.radicand ** (m quo rn.exponent)) /
+                    (rd.radicand ** (m quo rd.exponent))) *
+                           (pn.poly ** (m quo sn.exponent))::F /
+                                    (pd.poly ** (m quo sd.exponent))::F]
+
+
+@
+<<POLYROOT.dotabb>>=
+"POLYROOT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=POLYROOT"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"POLYROOT" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LIMITPS PowerSeriesLimitPackage}
+\pagehead{PowerSeriesLimitPackage}{LIMITPS}
+\pagepic{ps/v104powerserieslimitpackage.ps}{LIMITPS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LIMITPS PowerSeriesLimitPackage>>=
+)abbrev package LIMITPS PowerSeriesLimitPackage
+++ Author: Clifton J. Williamson
+++ Date Created: 21 March 1989
+++ Date Last Updated: 30 March 1994
+++ Basic Operations:
+++ Related Domains: UnivariateLaurentSeries(FE,x,a),
+++   UnivariatePuiseuxSeries(FE,x,a),ExponentialExpansion(R,FE,x,a)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: limit, functional expression, power series
+++ Examples:
+++ References:
+++ Description:
+++   PowerSeriesLimitPackage implements limits of expressions
+++   in one or more variables as one of the variables approaches a
+++   limiting value.  Included are two-sided limits, left- and right-
+++   hand limits, and limits at plus or minus infinity.
+PowerSeriesLimitPackage(R,FE): Exports == Implementation where
+  R  : Join(GcdDomain,OrderedSet,RetractableTo Integer,_
+            LinearlyExplicitRingOver Integer)
+  FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+            FunctionSpace R)
+  Z       ==> Integer
+  RN      ==> Fraction Integer
+  RF      ==> Fraction Polynomial R
+  OFE     ==> OrderedCompletion FE
+  OPF     ==> OnePointCompletion FE
+  SY      ==> Symbol
+  EQ      ==> Equation
+  LF      ==> LiouvillianFunction
+  UTS     ==> UnivariateTaylorSeries
+  ULS     ==> UnivariateLaurentSeries
+  UPXS    ==> UnivariatePuiseuxSeries
+  EFULS   ==> ElementaryFunctionsUnivariateLaurentSeries
+  EFUPXS  ==> ElementaryFunctionsUnivariatePuiseuxSeries
+  FS2UPS  ==> FunctionSpaceToUnivariatePowerSeries
+  FS2EXPXP ==> FunctionSpaceToExponentialExpansion
+  Problem ==> Record(func:String,prob:String)
+  RESULT  ==> Union(OFE,"failed")
+  TwoSide ==> Record(leftHandLimit:RESULT,rightHandLimit:RESULT)
+  U       ==> Union(OFE,TwoSide,"failed")
+  SIGNEF  ==> ElementaryFunctionSign(R,FE)
+
+  Exports ==> with
+
+    limit: (FE,EQ OFE) -> U
+      ++ limit(f(x),x = a) computes the real limit \spad{lim(x -> a,f(x))}.
+
+    complexLimit: (FE,EQ OPF) -> Union(OPF, "failed")
+      ++ complexLimit(f(x),x = a) computes the complex limit
+      ++ \spad{lim(x -> a,f(x))}.
+
+    limit: (FE,EQ FE,String) -> RESULT
+      ++ limit(f(x),x=a,"left") computes the left hand real limit
+      ++ \spad{lim(x -> a-,f(x))};
+      ++ \spad{limit(f(x),x=a,"right")} computes the right hand real limit
+      ++ \spad{lim(x -> a+,f(x))}.
+
+  Implementation ==> add
+    import ToolsForSign(R)
+    import ElementaryFunctionStructurePackage(R,FE)
+
+    zeroFE:FE := 0
+    anyRootsOrAtrigs?   : FE -> Boolean
+    complLimit  : (FE,SY) -> Union(OPF,"failed")
+    okProblem?  : (String,String) -> Boolean
+    realLimit   : (FE,SY) -> U
+    xxpLimit    : (FE,SY) -> RESULT
+    limitPlus   : (FE,SY) -> RESULT
+    localsubst  : (FE,Kernel FE,Z,FE) -> FE
+    locallimit  : (FE,SY,OFE) -> U
+    locallimitcomplex : (FE,SY,OPF) -> Union(OPF,"failed")
+    poleLimit:(RN,FE,SY) -> U
+    poleLimitPlus:(RN,FE,SY) -> RESULT
+
+    noX?: (FE,SY) -> Boolean
+    noX?(fcn,x) == not member?(x,variables fcn)
+
+    constant?: FE -> Boolean
+    constant? fcn == empty? variables fcn
+
+    firstNonLogPtr: (FE,SY) -> List Kernel FE
+    firstNonLogPtr(fcn,x) ==
+      -- returns a pointer to the first element of kernels(fcn) which
+      -- has 'x' as a variable, which is not a logarithm, and which is
+      -- not simply 'x'
+      list := kernels fcn
+      while not empty? list repeat
+        ker := first list
+        not is?(ker,"log" :: Symbol) and member?(x,variables(ker::FE)) _
+               and not(x = name(ker)) =>
+          return list
+        list := rest list
+      empty()
+
+    finiteValueAtInfinity?: Kernel FE -> Boolean
+    finiteValueAtInfinity? ker ==
+      is?(ker,"erf" :: Symbol) => true
+      is?(ker,"sech" :: Symbol) => true
+      is?(ker,"csch" :: Symbol) => true
+      is?(ker,"tanh" :: Symbol) => true
+      is?(ker,"coth" :: Symbol) => true
+      is?(ker,"atan" :: Symbol) => true
+      is?(ker,"acot" :: Symbol) => true
+      is?(ker,"asec" :: Symbol) => true
+      is?(ker,"acsc" :: Symbol) => true
+      is?(ker,"acsch" :: Symbol) => true
+      is?(ker,"acoth" :: Symbol) => true
+      false
+
+    knownValueAtInfinity?: Kernel FE -> Boolean
+    knownValueAtInfinity? ker ==
+      is?(ker,"exp" :: Symbol) => true
+      is?(ker,"sinh" :: Symbol) => true
+      is?(ker,"cosh" :: Symbol) => true
+      false
+
+    leftOrRight: (FE,SY,FE) -> SingleInteger
+    leftOrRight(fcn,x,limVal) ==
+      -- function is called when limitPlus(fcn,x) = limVal
+      -- determines whether the limiting value is approached
+      -- from the left or from the right
+      (value := limitPlus(inv(fcn - limVal),x)) case "failed" => 0
+      (inf := whatInfinity(val := value :: OFE)) = 0 =>
+         error "limit package: internal error"
+      inf
+
+    specialLimit1: (FE,SY) -> RESULT
+    specialLimitKernel: (Kernel FE,SY) -> RESULT
+    specialLimitNormalize: (FE,SY) -> RESULT
+    specialLimit: (FE, SY) -> RESULT
+
+    specialLimit(fcn, x) ==
+      xkers := [k for k in kernels fcn | member?(x,variables(k::FE))]
+      #xkers = 1 => specialLimit1(fcn,x)
+      num := numerator fcn
+      den := denominator fcn
+      for k in xkers repeat
+        (fval := limitPlus(k::FE,x)) case "failed" =>
+            return specialLimitNormalize(fcn,x)
+        whatInfinity(val := fval::OFE) ^= 0 =>
+            return specialLimitNormalize(fcn,x)
+        (valu := retractIfCan(val)@Union(FE,"failed")) case "failed" =>
+            return specialLimitNormalize(fcn,x)
+        finVal := valu :: FE
+        num := eval(num, k, finVal)
+        den := eval(den, k, finVal)
+        den = 0 => return specialLimitNormalize(fcn,x)
+      (num/den) :: OFE :: RESULT
+
+    specialLimitNormalize(fcn,x) == -- tries to normalize result first
+      nfcn := normalize(fcn)
+      fcn ^= nfcn => limitPlus(nfcn,x)
+      xkers := [k for k in tower fcn | member?(x,variables(k::FE))]
+      # xkers ^= 2 => "failed"
+      expKers := [k for k in xkers | is?(k, "exp" :: Symbol)]
+      # expKers ^= 1 => "failed"
+    -- fcn is a rational function of x and exp(g(x)) for some rational function g
+      expKer := first expKers
+      (fval := limitPlus(expKer::FE,x)) case "failed" => "failed"
+      vv := new()$SY; eq : EQ FE := equation(expKer :: FE,vv :: FE)
+      cc := eval(fcn,eq)
+      expKerLim := fval :: OFE
+        -- following test for "failed" is needed due to compiler bug
+        -- limVal case OFE generates EQCAR(limVal, 1) which fails on atom "failed"
+      (limVal := locallimit(cc,vv,expKerLim)) case "failed" => "failed"
+      limVal case OFE =>
+         limm := limVal :: OFE
+         (lim := retractIfCan(limm)@Union(FE,"failed")) case "failed" =>
+               "failed" -- need special handling for directions at infinity
+         limitPlus(lim, x)
+      "failed"
+
+    -- limit of expression having only 1 kernel involving x
+    specialLimit1(fcn,x) ==
+      -- find the first interesting kernel in tower(fcn)
+      xkers := [k for k in kernels fcn | member?(x,variables(k::FE))]
+      #xkers ^= 1 => "failed"
+      ker := first xkers
+      vv := new()$SY; eq : EQ FE := equation(ker :: FE,vv :: FE)
+      cc := eval(fcn,eq)
+      member?(x,variables cc) => "failed"
+      (lim := specialLimitKernel(ker, x)) case "failed" => lim
+      argLim : OFE := lim :: OFE
+      (limVal := locallimit(cc,vv,argLim)) case "failed" => "failed"
+      limVal case OFE => limVal :: OFE
+      "failed"
+
+    -- limit of single kernel involving x
+    specialLimitKernel(ker,x) ==
+      is?(ker,"log" :: Symbol) =>
+          args := argument ker
+          empty? args => "failed" -- error "No argument"
+          not empty? rest args => "failed" -- error "Too many arugments"
+          arg := first args
+          -- compute limit(x -> 0+,arg)
+          (limm := limitPlus(arg,x)) case "failed" => "failed"
+          lim := limm :: OFE
+          (inf := whatInfinity lim) = -1 => "failed"
+          argLim : OFE :=
+            -- log(+infinity) = +infinity
+            inf = 1 => lim
+            -- now 'lim' must be finite
+            (li := retractIfCan(lim)@Union(FE,"failed") :: FE) = 0 =>
+              -- log(0) = -infinity
+              leftOrRight(arg,x,0) = 1 => minusInfinity()
+              return "failed"
+            log(li) :: OFE
+      -- kernel should be a function of one argument f(arg)
+      args := argument(ker)
+      empty? args => "failed"  -- error "No argument"
+      not empty? rest args => "failed" -- error "Too many arugments"
+      arg := first args
+      -- compute limit(x -> 0+,arg)
+      (limm := limitPlus(arg,x)) case "failed" => "failed"
+      lim := limm :: OFE
+      f := elt(operator ker,(var := new()$SY) :: FE)
+      -- compute limit(x -> 0+,f(arg))
+      -- case where 'lim' is finite
+      (inf := whatInfinity lim) = 0 =>
+         is?(ker,"erf" :: Symbol) => erf(retract(lim)@FE)$LF(R,FE) :: OFE
+         (kerValue := locallimit(f,var,lim)) case "failed" => "failed"
+         kerValue case OFE => kerValue :: OFE
+         "failed"
+      -- case where 'lim' is plus infinity
+      inf = 1 =>
+        finiteValueAtInfinity? ker =>
+          val : FE :=
+            is?(ker,"erf" :: Symbol) => 1
+            is?(ker,"sech" :: Symbol) => 0
+            is?(ker,"csch" :: Symbol) => 0
+            is?(ker,"tanh" :: Symbol) => 0
+            is?(ker,"coth" :: Symbol) => 0
+            is?(ker,"atan" :: Symbol) => pi()/(2 :: FE)
+            is?(ker,"acot" :: Symbol) => 0
+            is?(ker,"asec" :: Symbol) => pi()/(2 :: FE)
+            is?(ker,"acsc" :: Symbol) => 0
+            is?(ker,"acsch" :: Symbol) => 0
+            -- ker must be acoth
+            0
+          val :: OFE
+        knownValueAtInfinity? ker =>
+          lim -- limit(exp, cosh, sinh ,x=inf) = inf
+        "failed"
+      -- case where 'lim' is minus infinity
+      finiteValueAtInfinity? ker =>
+        val : FE :=
+          is?(ker,"erf" :: Symbol) => -1
+          is?(ker,"sech" :: Symbol) => 0
+          is?(ker,"csch" :: Symbol) => 0
+          is?(ker,"tanh" :: Symbol) => 0
+          is?(ker,"coth" :: Symbol) => 0
+          is?(ker,"atan" :: Symbol) => -pi()/(2 :: FE)
+          is?(ker,"acot" :: Symbol) => pi()
+          is?(ker,"asec" :: Symbol) => -pi()/(2 :: FE)
+          is?(ker,"acsc" :: Symbol) => -pi()
+          is?(ker,"acsch" :: Symbol) => 0
+          -- ker must be acoth
+          0
+        val :: OFE
+      knownValueAtInfinity? ker =>
+        is?(ker,"exp" :: Symbol) => (0@FE) :: OFE
+        is?(ker,"sinh" :: Symbol) => lim
+        is?(ker,"cosh" :: Symbol) => plusInfinity()
+        "failed"
+      "failed"
+
+    logOnlyLimit: (FE,SY) -> RESULT
+    logOnlyLimit(coef,x) ==
+      -- this function is called when the 'constant' coefficient involves
+      -- the variable 'x'. Its purpose is to compute a right hand limit
+      -- of an expression involving log x. Here log x is replaced by -1/v,
+      -- where v is a new variable. If the new expression no longer involves
+      -- x, then take the right hand limit as v -> 0+
+      vv := new()$SY
+      eq : EQ FE := equation(log(x :: FE),-inv(vv :: FE))
+      member?(x,variables(cc := eval(coef,eq))) => "failed"
+      limitPlus(cc,vv)
+
+    locallimit(fcn,x,a) ==
+      -- Here 'fcn' is a function f(x) = f(x,...) in 'x' and possibly
+      -- other variables, and 'a' is a limiting value.  The function
+      -- computes lim(x -> a,f(x)).
+      xK := retract(x::FE)@Kernel(FE)
+      (n := whatInfinity a) = 0 =>
+        realLimit(localsubst(fcn,xK,1,retract(a)@FE),x)
+      (u := limitPlus(eval(fcn,xK,n * inv(xK::FE)),x))
+                                                case "failed" => "failed"
+      u::OFE
+
+    localsubst(fcn, k, n, a) ==
+      a = 0 and n = 1 => fcn
+      eval(fcn,k,n * (k::FE) + a)
+
+    locallimitcomplex(fcn,x,a) ==
+      xK := retract(x::FE)@Kernel(FE)
+      (g := retractIfCan(a)@Union(FE,"failed")) case FE =>
+        complLimit(localsubst(fcn,xK,1,g::FE),x)
+      complLimit(eval(fcn,xK,inv(xK::FE)),x)
+
+    limit(fcn,eq,str) ==
+      (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+        error "limit:left hand side must be a variable"
+      x := xx :: SY; a := rhs eq
+      xK := retract(x::FE)@Kernel(FE)
+      limitPlus(localsubst(fcn,xK,direction str,a),x)
+
+    anyRootsOrAtrigs? fcn ==
+      -- determines if 'fcn' has any kernels which are roots
+      -- or if 'fcn' has any kernels which are inverse trig functions
+      -- which could produce series expansions with fractional exponents
+      for kernel in tower fcn repeat
+        is?(kernel,"nthRoot" :: Symbol) => return true
+        is?(kernel,"asin" :: Symbol) => return true
+        is?(kernel,"acos" :: Symbol) => return true
+        is?(kernel,"asec" :: Symbol) => return true
+        is?(kernel,"acsc" :: Symbol) => return true
+      false
+
+    complLimit(fcn,x) ==
+      -- computes lim(x -> 0,fcn) using a Puiseux expansion of fcn,
+      -- if fcn is an expression involving roots, and using a Laurent
+      -- expansion of fcn otherwise
+      lim : FE :=
+        anyRootsOrAtrigs? fcn =>
+          ppack := FS2UPS(R,FE,RN,_
+              UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
+              EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
+          pseries := exprToUPS(fcn,false,"complex")$ppack
+          pseries case %problem => return "failed"
+          if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
+          pole? upxs => return infinity()
+          coefficient(upxs,0)
+        lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
+                 EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
+        lseries := exprToUPS(fcn,false,"complex")$lpack
+        lseries case %problem => return "failed"
+        if pole?(uls := lseries.%series) then uls := map(normalize,uls)
+        pole? uls => return infinity()
+        coefficient(uls,0)
+      -- can the following happen?
+      member?(x,variables lim) =>
+        member?(x,variables(answer := normalize lim)) =>
+          error "limit: can't evaluate limit"
+        answer :: OPF
+      lim :: FE :: OPF
+
+    okProblem?(function,problem) ==
+      (function = "log") or (function = "nth root") =>
+        (problem = "series of non-zero order") or _
+               (problem = "negative leading coefficient")
+      (function = "atan") => problem = "branch problem"
+      (function = "erf") => problem = "unknown kernel"
+      problem = "essential singularity"
+
+    poleLimit(order,coef,x) ==
+      -- compute limit for function with pole
+      not member?(x,variables coef) =>
+        (s := sign(coef)$SIGNEF) case Integer =>
+          rtLim := (s :: Integer) * plusInfinity()
+          even? numer order => rtLim
+          even? denom order => ["failed",rtLim]$TwoSide
+          [-rtLim,rtLim]$TwoSide
+        -- infinite limit, but cannot determine sign
+        "failed"
+      error "limit: can't evaluate limit"
+
+    poleLimitPlus(order,coef,x) ==
+      -- compute right hand limit for function with pole
+      not member?(x,variables coef) =>
+        (s := sign(coef)$SIGNEF) case Integer =>
+          (s :: Integer) * plusInfinity()
+        -- infinite limit, but cannot determine sign
+        "failed"
+      (clim := specialLimit(coef,x)) case "failed" => "failed"
+      zero? (lim := clim :: OFE) =>
+        -- in this event, we need to determine if the limit of
+        -- the coef is 0+ or 0-
+        (cclim := specialLimit(inv coef,x)) case "failed" => "failed"
+        ss := whatInfinity(cclim :: OFE) :: Z
+        zero? ss =>
+          error "limit: internal error"
+        ss * plusInfinity()
+      t := whatInfinity(lim :: OFE) :: Z
+      zero? t =>
+        (tt := sign(coef)$SIGNEF) case Integer =>
+          (tt :: Integer) * plusInfinity()
+        -- infinite limit, but cannot determine sign
+        "failed"
+      t * plusInfinity()
+
+    realLimit(fcn,x) ==
+      -- computes lim(x -> 0,fcn) using a Puiseux expansion of fcn,
+      -- if fcn is an expression involving roots, and using a Laurent
+      -- expansion of fcn otherwise
+      lim : Union(FE,"failed") :=
+        anyRootsOrAtrigs? fcn =>
+          ppack := FS2UPS(R,FE,RN,_
+               UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
+               EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
+          pseries := exprToUPS(fcn,true,"real: two sides")$ppack
+          pseries case %problem =>
+            trouble := pseries.%problem
+            function := trouble.func; problem := trouble.prob
+            okProblem?(function,problem) =>
+              left :=
+                xK : Kernel FE := kernel x
+                fcn0 := eval(fcn,xK,-(xK :: FE))
+                limitPlus(fcn0,x)
+              right := limitPlus(fcn,x)
+              (left case "failed") and (right case "failed") =>
+                return "failed"
+              if (left case OFE) and (right case OFE) then
+                (left :: OFE) = (right :: OFE) => return (left :: OFE)
+              return([left,right]$TwoSide)
+            return "failed"
+          if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
+          pole? upxs =>
+            cp := coefficient(upxs,ordp := order upxs)
+            return poleLimit(ordp,cp,x)
+          coefficient(upxs,0)
+        lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
+                 EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
+        lseries := exprToUPS(fcn,true,"real: two sides")$lpack
+        lseries case %problem =>
+          trouble := lseries.%problem
+          function := trouble.func; problem := trouble.prob
+          okProblem?(function,problem) =>
+            left :=
+              xK : Kernel FE := kernel x
+              fcn0 := eval(fcn,xK,-(xK :: FE))
+              limitPlus(fcn0,x)
+            right := limitPlus(fcn,x)
+            (left case "failed") and (right case "failed") =>
+              return "failed"
+            if (left case OFE) and (right case OFE) then
+              (left :: OFE) = (right :: OFE) => return (left :: OFE)
+            return([left,right]$TwoSide)
+          return "failed"
+        if pole?(uls := lseries.%series) then uls := map(normalize,uls)
+        pole? uls =>
+          cl := coefficient(uls,ordl := order uls)
+          return poleLimit(ordl :: RN,cl,x)
+        coefficient(uls,0)
+      lim case "failed" => "failed"
+      member?(x,variables(lim :: FE)) =>
+        member?(x,variables(answer := normalize(lim :: FE))) =>
+          error "limit: can't evaluate limit"
+        answer :: OFE
+      lim :: FE :: OFE
+
+    xxpLimit(fcn,x) ==
+      -- computes lim(x -> 0+,fcn) using an exponential expansion of fcn
+      xpack := FS2EXPXP(R,FE,x,zeroFE)
+      xxp := exprToXXP(fcn,true)$xpack
+      xxp case %problem => "failed"
+      limitPlus(xxp.%expansion)
+
+    limitPlus(fcn,x) ==
+      -- computes lim(x -> 0+,fcn) using a generalized Puiseux expansion
+      -- of fcn, if fcn is an expression involving roots, and using a
+      -- generalized Laurent expansion of fcn otherwise
+      lim : Union(FE,"failed") :=
+        anyRootsOrAtrigs? fcn =>
+          ppack := FS2UPS(R,FE,RN,_
+               UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
+               EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
+          pseries := exprToGenUPS(fcn,true,"real: right side")$ppack
+          pseries case %problem =>
+            trouble := pseries.%problem
+            ff := trouble.func; pp := trouble.prob
+            (pp = "negative leading coefficient") => return "failed"
+            "failed"
+          -- pseries case %problem => return "failed"
+          if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
+          pole? upxs =>
+            cp := coefficient(upxs,ordp := order upxs)
+            return poleLimitPlus(ordp,cp,x)
+          coefficient(upxs,0)
+        lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
+                 EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
+        lseries := exprToGenUPS(fcn,true,"real: right side")$lpack
+        lseries case %problem =>
+          trouble := lseries.%problem
+          ff := trouble.func; pp := trouble.prob
+          (pp = "negative leading coefficient") => return "failed"
+          "failed"
+        -- lseries case %problem => return "failed"
+        if pole?(uls := lseries.%series) then uls := map(normalize,uls)
+        pole? uls =>
+          cl := coefficient(uls,ordl := order uls)
+          return poleLimitPlus(ordl :: RN,cl,x)
+        coefficient(uls,0)
+      lim case "failed" =>
+        (xLim := xxpLimit(fcn,x)) case "failed" => specialLimit(fcn,x)
+        xLim
+      member?(x,variables(lim :: FE)) =>
+        member?(x,variables(answer := normalize(lim :: FE))) =>
+          (xLim := xxpLimit(answer,x)) case "failed" => specialLimit(answer,x)
+          xLim
+        answer :: OFE
+      lim :: FE :: OFE
+
+    limit(fcn:FE,eq:EQ OFE) ==
+      (f := retractIfCan(lhs eq)@Union(FE,"failed")) case "failed" =>
+        error "limit:left hand side must be a variable"
+      (xx := retractIfCan(f)@Union(SY,"failed")) case "failed" =>
+        error "limit:left hand side must be a variable"
+      x := xx :: SY; a := rhs eq
+      locallimit(fcn,x,a)
+
+    complexLimit(fcn:FE,eq:EQ OPF) ==
+      (f := retractIfCan(lhs eq)@Union(FE,"failed")) case "failed" =>
+        error "limit:left hand side must be a variable"
+      (xx := retractIfCan(f)@Union(SY,"failed")) case "failed" =>
+        error "limit:left hand side must be a variable"
+      x := xx :: SY; a := rhs eq
+      locallimitcomplex(fcn,x,a)
+
+@
+<<LIMITPS.dotabb>>=
+"LIMITPS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LIMITPS"]
+"ULSCCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ULSCCAT"]
+"LIMITPS" -> "ULSCCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PREASSOC PrecomputedAssociatedEquations}
+\pagehead{PrecomputedAssociatedEquations}{PREASSOC}
+\pagepic{ps/v104precomputedassociatedequations.ps}{PREASSOC}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PREASSOC PrecomputedAssociatedEquations>>=
+)abbrev package PREASSOC PrecomputedAssociatedEquations
+++ Author: Manuel Bronstein
+++ Date Created: 13 January 1994
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{PrecomputedAssociatedEquations} stores some generic
+++ precomputations which speed up the computations of the
+++ associated equations needed for factoring operators.
+PrecomputedAssociatedEquations(R, L): Exports == Implementation where
+  R: IntegralDomain
+  L: LinearOrdinaryDifferentialOperatorCategory R
+ 
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  A   ==> PrimitiveArray R
+  U   ==> Union(Matrix R, "failed")
+ 
+  Exports ==> with
+    firstUncouplingMatrix: (L, PI) -> U
+      ++ firstUncouplingMatrix(op, m) returns the matrix A such that
+      ++ \spad{A w = (W',W'',...,W^N)} in the corresponding associated
+      ++ equations for right-factors of order m of op.
+      ++ Returns "failed" if the matrix A has not been precomputed for
+      ++ the particular combination \spad{degree(L), m}.
+ 
+  Implementation ==> add
+    A32:  L -> U
+    A42:  L -> U
+    A425: (A, A, A) -> List R
+    A426: (A, A, A) -> List R
+    makeMonic: L -> Union(A, "failed")
+ 
+    diff:L := D()
+ 
+    firstUncouplingMatrix(op, m) ==
+      n := degree op
+      n = 3 and m = 2 => A32 op
+      n = 4 and m = 2 => A42 op
+      "failed"
+        
+    makeMonic op ==
+      lc := leadingCoefficient op
+      a:A := new(n := degree op, 0)
+      for i in 0..(n-1)::N repeat
+        (u := coefficient(op, i) exquo lc) case "failed" => return "failed"
+        a.i := - (u::R)
+      a
+    
+    A32 op ==
+      (u := makeMonic op) case "failed" => "failed"
+      a := u::A
+      matrix [[0, 1, 0], [a.1, a.2, 1],
+              [diff(a.1) + a.1 * a.2 - a.0, diff(a.2) + a.2**2 + a.1, 2 * a.2]]
+ 
+    A42 op ==
+      (u := makeMonic op) case "failed" => "failed"
+      a := u::A
+      a':A := new(4, 0)
+      a'':A := new(4, 0)
+      for i in 0..3 repeat
+        a'.i := diff(a.i)
+        a''.i := diff(a'.i)
+      matrix [[0, 1, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0], [a.1,a.2,0,a.3,2::R,0],
+              [a'.1 + a.1 * a.3 - 2 * a.0, a'.2 + a.2 * a.3 + a.1, 3 * a.2,
+               a'.3 + a.3 ** 2 + a.2, 3 * a.3, 2::R],
+                A425(a, a', a''), A426(a, a', a'')]
+ 
+    A425(a, a', a'') ==
+      [a''.1 + 2 * a.1 * a'.3 + a.3 * a'.1 - 2 * a'.0 + a.1 * a.3 ** 2
+       - 3 * a.0 * a.3 + a.1 * a.2,
+        a''.2 + 2 * a.2 * a'.3 + a.3 * a'.2 + 2 * a'.1 + a.2 * a.3 ** 2
+         + a.1 * a.3 + a.2 ** 2 - 4 * a.0,
+          4 * a'.2 + 4 * a.2 * a.3 - a.1,
+           a''.3 + 3 * a.3 * a'.3 + 2 * a'.2 + a.3 ** 3 + 2 * a.2 * a.3 + a.1,
+            4 * a'.3 + 4 * a.3 ** 2 + 4 * a.2, 5 * a.3]
+              
+    A426(a, a', a'') ==
+      [diff(a''.1) + 3 * a.1 * a''.3 + a.3 * a''.1 - 2 * a''.0
+       + (3 * a'.1 + 5 * a.1 * a.3 - 7 * a.0) * a'.3 + 3 * a.1 * a'.2
+        + (a.3 ** 2 + a.2) * a'.1 - 3 * a.3 * a'.0 + a.1 * a.3 ** 3
+         - 4 * a.0 * a.3 ** 2 + 2 * a.1 * a.2 * a.3 - 4 * a.0 * a.2 + a.1 ** 2,
+          diff(a''.2) + 3 * a.2 * a''.3 + a.3 * a''.2 + 3 * a''.1
+           + (3*a'.2 + 5*a.2 * a.3 + 3 * a.1) * a'.3 + (a.3**2 + 4*a.2)*a'.2
+            + 2 * a.3 * a'.1 - 6 * a'.0 + a.2 * a.3 ** 3 + a.1 * a.3 ** 2
+             + (2 * a.2**2 - 8 * a.0) * a.3 + 2 * a.1 * a.2,
+              5 * a''.2 + 10 * a.2 * a'.3 + 5 * a.3 * a'.2 + a'.1
+               + 5 * a.2 * a.3 ** 2 - 4 * a.1 * a.3 + 5 * a.2**2 - 4 * a.0,
+                diff(a''.3) + 4 * a.3 * a''.3 + 3*a''.2 + 3 * a'.3**2
+                 + (6 * a.3**2 + 4 * a.2) * a'.3 + 5 * a.3 * a'.2 + 3 * a'.1
+                  + a.3**4 + 3 * a.2 * a.3**2 + 2 * a.1 * a.3 + a.2**2 - 4*a.0,
+                   5 * a''.3 + 15 * a.3 * a'.3 + 10 * a'.2 + 5 * a.3**3
+                    + 10 * a.2 * a.3, 9 * a'.3 + 9 * a.3**2 + 4 * a.2]
+
+@
+<<PREASSOC.dotabb>>=
+"PREASSOC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PREASSOC"]
+"OREPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OREPCAT"]
+"A1AGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=A1AGG"]
+"PREASSOC" -> "OREPCAT"
+"PREASSOC" -> "A1AGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PRIMARR2 PrimitiveArrayFunctions2}
 \pagehead{PrimitiveArrayFunctions2}{PRIMARR2}
 \pagepic{ps/v104primitivearrayfunctions2.ps}{PRIMARR2}{1.00}
@@ -39409,6 +45804,33 @@ SimpleAlgebraicExtensionAlgFactor(UP,SAE,UPA):Exports==Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package SIMPAN SimplifyAlgebraicNumberConvertPackage}
+\pagehead{SimplifyAlgebraicNumberConvertPackage}{SIMPAN}
+\pagepic{ps/v104simplifyalgebraicnumberconvertpackage.ps}{SIMPAN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>=
+)abbrev package SIMPAN SimplifyAlgebraicNumberConvertPackage
+++ Package to allow simplify to be called on AlgebraicNumbers
+++ by converting to EXPR(INT)
+SimplifyAlgebraicNumberConvertPackage(): with
+  simplify: AlgebraicNumber -> Expression(Integer)
+	++ simplify(an) applies simplifications to an
+ == add
+  simplify(a:AlgebraicNumber) ==
+    simplify(a::Expression(Integer))$TranscendentalManipulations(Integer, Expression Integer)
+
+@
+<<SIMPAN.dotabb>>=
+"SIMPAN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=SIMPAN"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"SIMPAN" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package SCACHE SortedCache}
 \pagehead{SortedCache}{SCACHE}
 \pagepic{ps/v104sortedcache.ps}{SCACHE}{1.00}
@@ -41761,6 +48183,437 @@ TranscendentalIntegration(F, UP): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package TRMANIP TranscendentalManipulations}
+\pagehead{TranscendentalManipulations}{TRMANIP}
+\pagepic{ps/v104transcendentalmanipulations.ps}{TRMANIP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package TRMANIP TranscendentalManipulations>>=
+)abbrev package TRMANIP TranscendentalManipulations
+++ Transformations on transcendental objects
+++ Author: Bob Sutor, Manuel Bronstein
+++ Date Created: Way back
+++ Date Last Updated: 22 January 1996, added simplifyLog MCD.
+++ Description:
+++   TranscendentalManipulations provides functions to simplify and
+++   expand expressions involving transcendental operators.
+++ Keywords: transcendental, manipulation.
+TranscendentalManipulations(R, F): Exports == Implementation where
+  R : Join(OrderedSet, GcdDomain)
+  F : Join(FunctionSpace R, TranscendentalFunctionCategory)
+
+  Z       ==> Integer
+  K       ==> Kernel F
+  P       ==> SparseMultivariatePolynomial(R, K)
+  UP      ==> SparseUnivariatePolynomial P
+  POWER   ==> "%power"::Symbol
+  POW     ==> Record(val: F,exponent: Z)
+  PRODUCT ==> Record(coef : Z, var : K)
+  FPR     ==> Fraction Polynomial R
+
+  Exports ==> with
+    expand     : F -> F
+      ++ expand(f) performs the following expansions on f:\begin{items}
+      ++ \item 1. logs of products are expanded into sums of logs,
+      ++ \item 2. trigonometric and hyperbolic trigonometric functions
+      ++ of sums are expanded into sums of products of trigonometric
+      ++ and hyperbolic trigonometric functions.
+      ++ \item 3. formal powers of the form \spad{(a/b)**c} are expanded into
+      ++ \spad{a**c * b**(-c)}.
+      ++ \end{items}
+    simplify   : F -> F
+      ++ simplify(f) performs the following simplifications on f:\begin{items}
+      ++ \item 1. rewrites trigs and hyperbolic trigs in terms
+      ++ of \spad{sin} ,\spad{cos}, \spad{sinh}, \spad{cosh}.
+      ++ \item 2. rewrites \spad{sin**2} and \spad{sinh**2} in terms
+      ++ of \spad{cos} and \spad{cosh},
+      ++ \item 3. rewrites \spad{exp(a)*exp(b)} as \spad{exp(a+b)}.
+      ++ \item 4. rewrites \spad{(a**(1/n))**m * (a**(1/s))**t} as a single
+      ++ power of a single radical of \spad{a}.
+      ++ \end{items}
+    htrigs     : F -> F
+      ++ htrigs(f) converts all the exponentials in f into
+      ++ hyperbolic sines and cosines.
+    simplifyExp: F -> F
+      ++ simplifyExp(f) converts every product \spad{exp(a)*exp(b)}
+      ++ appearing in f into \spad{exp(a+b)}.
+    simplifyLog : F -> F
+      ++ simplifyLog(f) converts every \spad{log(a) - log(b)} appearing in f
+      ++ into \spad{log(a/b)}, every \spad{log(a) + log(b)} into \spad{log(a*b)}
+      ++ and every \spad{n*log(a)} into \spad{log(a^n)}.
+    expandPower: F -> F
+      ++ expandPower(f) converts every power \spad{(a/b)**c} appearing
+      ++ in f into \spad{a**c * b**(-c)}.
+    expandLog  : F -> F
+      ++ expandLog(f) converts every \spad{log(a/b)} appearing in f into
+      ++ \spad{log(a) - log(b)}, and every \spad{log(a*b)} into
+      ++ \spad{log(a) + log(b)}..
+    cos2sec    : F -> F
+      ++ cos2sec(f) converts every \spad{cos(u)} appearing in f into
+      ++ \spad{1/sec(u)}.
+    cosh2sech  : F -> F
+      ++ cosh2sech(f) converts every \spad{cosh(u)} appearing in f into
+      ++ \spad{1/sech(u)}.
+    cot2trig   : F -> F
+      ++ cot2trig(f) converts every \spad{cot(u)} appearing in f into
+      ++ \spad{cos(u)/sin(u)}.
+    coth2trigh : F -> F
+      ++ coth2trigh(f) converts every \spad{coth(u)} appearing in f into
+      ++ \spad{cosh(u)/sinh(u)}.
+    csc2sin    : F -> F
+      ++ csc2sin(f) converts every \spad{csc(u)} appearing in f into
+      ++ \spad{1/sin(u)}.
+    csch2sinh  : F -> F
+      ++ csch2sinh(f) converts every \spad{csch(u)} appearing in f into
+      ++ \spad{1/sinh(u)}.
+    sec2cos    : F -> F
+      ++ sec2cos(f) converts every \spad{sec(u)} appearing in f into
+      ++ \spad{1/cos(u)}.
+    sech2cosh  : F -> F
+      ++ sech2cosh(f) converts every \spad{sech(u)} appearing in f into
+      ++ \spad{1/cosh(u)}.
+    sin2csc    : F -> F
+      ++ sin2csc(f) converts every \spad{sin(u)} appearing in f into
+      ++ \spad{1/csc(u)}.
+    sinh2csch  : F -> F
+      ++ sinh2csch(f) converts every \spad{sinh(u)} appearing in f into
+      ++ \spad{1/csch(u)}.
+    tan2trig   : F -> F
+      ++ tan2trig(f) converts every \spad{tan(u)} appearing in f into
+      ++ \spad{sin(u)/cos(u)}.
+    tanh2trigh : F -> F
+      ++ tanh2trigh(f) converts every \spad{tanh(u)} appearing in f into
+      ++ \spad{sinh(u)/cosh(u)}.
+    tan2cot    : F -> F
+      ++ tan2cot(f) converts every \spad{tan(u)} appearing in f into
+      ++ \spad{1/cot(u)}.
+    tanh2coth  : F -> F
+      ++ tanh2coth(f) converts every \spad{tanh(u)} appearing in f into
+      ++ \spad{1/coth(u)}.
+    cot2tan    : F -> F
+      ++ cot2tan(f) converts every \spad{cot(u)} appearing in f into
+      ++ \spad{1/tan(u)}.
+    coth2tanh  : F -> F
+      ++ coth2tanh(f) converts every \spad{coth(u)} appearing in f into
+      ++ \spad{1/tanh(u)}.
+    removeCosSq: F -> F
+      ++ removeCosSq(f) converts every \spad{cos(u)**2} appearing in f into
+      ++ \spad{1 - sin(x)**2}, and also reduces higher
+      ++ powers of \spad{cos(u)} with that formula.
+    removeSinSq: F -> F
+      ++ removeSinSq(f) converts every \spad{sin(u)**2} appearing in f into
+      ++ \spad{1 - cos(x)**2}, and also reduces higher powers of
+      ++ \spad{sin(u)} with that formula.
+    removeCoshSq:F -> F
+      ++ removeCoshSq(f) converts every \spad{cosh(u)**2} appearing in f into
+      ++ \spad{1 - sinh(x)**2}, and also reduces higher powers of
+      ++ \spad{cosh(u)} with that formula.
+    removeSinhSq:F -> F
+      ++ removeSinhSq(f) converts every \spad{sinh(u)**2} appearing in f into
+      ++ \spad{1 - cosh(x)**2}, and also reduces higher powers
+      ++ of \spad{sinh(u)} with that formula.
+    if R has PatternMatchable(R) and R has ConvertibleTo(Pattern(R)) and F has ConvertibleTo(Pattern(R)) and F has PatternMatchable R then
+      expandTrigProducts : F -> F
+        ++ expandTrigProducts(e) replaces \axiom{sin(x)*sin(y)} by
+        ++ \spad{(cos(x-y)-cos(x+y))/2}, \axiom{cos(x)*cos(y)} by
+        ++ \spad{(cos(x-y)+cos(x+y))/2}, and \axiom{sin(x)*cos(y)} by
+        ++ \spad{(sin(x-y)+sin(x+y))/2}.  Note that this operation uses
+        ++ the pattern matcher and so is relatively expensive.  To avoid
+        ++ getting into an infinite loop the transformations are applied
+        ++ at most ten times.
+
+  Implementation ==> add
+    import FactoredFunctions(P)
+    import PolynomialCategoryLifting(IndexedExponents K, K, R, P, F)
+    import
+      PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,P,F)
+
+    smpexp    : P -> F
+    termexp   : P -> F
+    exlog     : P -> F
+    smplog    : P -> F
+    smpexpand : P -> F
+    smp2htrigs: P -> F
+    kerexpand : K -> F
+    expandpow : K -> F
+    logexpand : K -> F
+    sup2htrigs: (UP, F) -> F
+    supexp    : (UP, F, F, Z) -> F
+    ueval     : (F, String, F -> F) -> F
+    ueval2    : (F, String, F -> F) -> F
+    powersimp : (P, List K) -> F
+    t2t       : F -> F
+    c2t       : F -> F
+    c2s       : F -> F
+    s2c       : F -> F
+    s2c2      : F -> F
+    th2th     : F -> F
+    ch2th     : F -> F
+    ch2sh     : F -> F
+    sh2ch     : F -> F
+    sh2ch2    : F -> F
+    simplify0 : F -> F
+    simplifyLog1 : F -> F
+    logArgs   : List F -> F
+
+    import F
+    import List F
+
+    if R has PatternMatchable R and R has ConvertibleTo Pattern R and F has ConvertibleTo(Pattern(R)) and F has PatternMatchable R then
+      XX : F := coerce new()$Symbol
+      YY : F := coerce new()$Symbol
+      sinCosRule : RewriteRule(R,R,F) :=
+        rule(cos(XX)*sin(YY),(sin(XX+YY)-sin(XX-YY))/2::F)
+      sinSinRule : RewriteRule(R,R,F) :=
+        rule(sin(XX)*sin(YY),(cos(XX-YY)-cos(XX+YY))/2::F)
+      cosCosRule : RewriteRule(R,R,F) :=
+        rule(cos(XX)*cos(YY),(cos(XX-YY)+cos(XX+YY))/2::F)
+      expandTrigProducts(e:F):F ==
+        applyRules([sinCosRule,sinSinRule,cosCosRule],e,10)$ApplyRules(R,R,F)
+
+    logArgs(l:List F):F ==
+      -- This function will take a list of Expressions (implicitly a sum) and
+      -- add them up, combining log terms.  It also replaces n*log(x) by
+      -- log(x^n).
+      import K
+      sum  : F := 0
+      arg  : F := 1
+      for term in l repeat
+        is?(term,"log"::Symbol) =>
+          arg := arg * simplifyLog(first(argument(first(kernels(term)))))
+        -- Now look for multiples, including negative ones.
+        prod : Union(PRODUCT, "failed") := isMult(term)
+        (prod case PRODUCT) and is?(prod.var,"log"::Symbol) =>
+            arg := arg * simplifyLog ((first argument(prod.var))**(prod.coef))
+        sum := sum+term
+      sum+log(arg)
+    
+    simplifyLog(e:F):F ==
+      simplifyLog1(numerator e)/simplifyLog1(denominator e)
+
+    simplifyLog1(e:F):F ==
+      freeOf?(e,"log"::Symbol) => e
+
+      -- Check for n*log(u)
+      prod : Union(PRODUCT, "failed") := isMult(e)
+      (prod case PRODUCT) and is?(prod.var,"log"::Symbol) =>
+        log simplifyLog ((first argument(prod.var))**(prod.coef))
+      
+      termList : Union(List(F),"failed") := isTimes(e)
+      -- I'm using two variables, termList and terms, to work round a
+      -- bug in the old compiler.
+      not (termList case "failed") =>
+        -- We want to simplify each log term in the product and then multiply
+        -- them together.  However, if there is a constant or arithmetic
+        -- expression (i.e. somwthing which looks like a Polynomial) we would
+        -- like to combine it with a log term.
+        terms :List F := [simplifyLog(term) for term in termList::List(F)]
+        exprs :List F := []
+        for i in 1..#terms repeat
+          if retractIfCan(terms.i)@Union(FPR,"failed") case FPR then
+            exprs := cons(terms.i,exprs)
+            terms := delete!(terms,i)
+        if not empty? exprs then
+          foundLog := false
+          i : NonNegativeInteger := 0
+          while (not(foundLog) and (i < #terms)) repeat
+            i := i+1
+            if is?(terms.i,"log"::Symbol) then
+              args : List F := argument(retract(terms.i)@K)
+              setelt(terms,i, log simplifyLog1(first(args)**(*/exprs)))
+              foundLog := true
+          -- The next line deals with a situation which shouldn't occur,
+          -- since we have checked whether we are freeOf log already.
+          if not foundLog then terms := append(exprs,terms)
+        */terms
+    
+      terms : Union(List(F),"failed") := isPlus(e)
+      not (terms case "failed") => logArgs(terms) 
+
+      expt : Union(POW, "failed") := isPower(e)
+--      (expt case POW) and not one? expt.exponent =>
+      (expt case POW) and not (expt.exponent = 1) =>
+        simplifyLog(expt.val)**(expt.exponent)
+    
+      kers : List K := kernels e
+--      not(one?(#kers)) => e -- Have a constant
+      not(((#kers) = 1)) => e -- Have a constant
+      kernel(operator first kers,[simplifyLog(u) for u in argument first kers])
+
+
+    if R has RetractableTo Integer then
+      simplify x == rootProduct(simplify0 x)$AlgebraicManipulations(R,F)
+
+    else simplify x == simplify0 x
+
+    expandpow k ==
+      a := expandPower first(arg := argument k)
+      b := expandPower second arg
+--      ne:F := (one? numer a => 1; numer(a)::F ** b)
+      ne:F := (((numer a) = 1) => 1; numer(a)::F ** b)
+--      de:F := (one? denom a => 1; denom(a)::F ** (-b))
+      de:F := (((denom a) = 1) => 1; denom(a)::F ** (-b))
+      ne * de
+
+    termexp p ==
+      exponent:F := 0
+      coef := (leadingCoefficient p)::P
+      lpow := select(is?(#1, POWER)$K, lk := variables p)$List(K)
+      for k in lk repeat
+        d := degree(p, k)
+        if is?(k, "exp"::Symbol) then
+          exponent := exponent + d * first argument k
+        else if not is?(k, POWER) then
+          -- Expand arguments to functions as well ... MCD 23/1/97
+          --coef := coef * monomial(1, k, d)
+          coef := coef * monomial(1, kernel(operator k,[simplifyExp u for u in argument k], height k), d)
+      coef::F * exp exponent * powersimp(p, lpow)
+
+    expandPower f ==
+      l := select(is?(#1, POWER)$K, kernels f)$List(K)
+      eval(f, l, [expandpow k for k in l])
+
+-- l is a list of pure powers appearing as kernels in p
+    powersimp(p, l) ==
+      empty? l => 1
+      k := first l                           -- k = a**b
+      a := first(arg := argument k)
+      exponent := degree(p, k) * second arg
+      empty?(lk := select(a = first argument #1, rest l)) =>
+        (a ** exponent) * powersimp(p, rest l)
+      for k0 in lk repeat
+        exponent := exponent + degree(p, k0) * second argument k0
+      (a ** exponent) * powersimp(p, setDifference(rest l, lk))
+
+    t2t x         == sin(x) / cos(x)
+    c2t x         == cos(x) / sin(x)
+    c2s x         == inv sin x
+    s2c x         == inv cos x
+    s2c2 x        == 1 - cos(x)**2
+    th2th x       == sinh(x) / cosh(x)
+    ch2th x       == cosh(x) / sinh(x)
+    ch2sh x       == inv sinh x
+    sh2ch x       == inv cosh x
+    sh2ch2 x      == cosh(x)**2 - 1
+    ueval(x, s,f) == eval(x, s::Symbol, f)
+    ueval2(x,s,f) == eval(x, s::Symbol, 2, f)
+    cos2sec x     == ueval(x, "cos", inv sec #1)
+    sin2csc x     == ueval(x, "sin", inv csc #1)
+    csc2sin x     == ueval(x, "csc", c2s)
+    sec2cos x     == ueval(x, "sec", s2c)
+    tan2cot x     == ueval(x, "tan", inv cot #1)
+    cot2tan x     == ueval(x, "cot", inv tan #1)
+    tan2trig x    == ueval(x, "tan", t2t)
+    cot2trig x    == ueval(x, "cot", c2t)
+    cosh2sech x   == ueval(x, "cosh", inv sech #1)
+    sinh2csch x   == ueval(x, "sinh", inv csch #1)
+    csch2sinh x   == ueval(x, "csch", ch2sh)
+    sech2cosh x   == ueval(x, "sech", sh2ch)
+    tanh2coth x   == ueval(x, "tanh", inv coth #1)
+    coth2tanh x   == ueval(x, "coth", inv tanh #1)
+    tanh2trigh x  == ueval(x, "tanh", th2th)
+    coth2trigh x  == ueval(x, "coth", ch2th)
+    removeCosSq x == ueval2(x, "cos", 1 - (sin #1)**2)
+    removeSinSq x == ueval2(x, "sin", s2c2)
+    removeCoshSq x== ueval2(x, "cosh", 1 + (sinh #1)**2)
+    removeSinhSq x== ueval2(x, "sinh", sh2ch2)
+    expandLog x   == smplog(numer x) / smplog(denom x)
+    simplifyExp x == (smpexp numer x) / (smpexp denom x)
+    expand x      == (smpexpand numer x) / (smpexpand denom x)
+    smpexpand p   == map(kerexpand, #1::F, p)
+    smplog p      == map(logexpand, #1::F, p)
+    smp2htrigs p  == map(htrigs(#1::F), #1::F, p)
+
+    htrigs f ==
+      (m := mainKernel f) case "failed" => f
+      op  := operator(k := m::K)
+      arg := [htrigs x for x in argument k]$List(F)
+      num := univariate(numer f, k)
+      den := univariate(denom f, k)
+      is?(op, "exp"::Symbol) =>
+        g1 := cosh(a := first arg) + sinh(a)
+        g2 := cosh(a) - sinh(a)
+        supexp(num,g1,g2,b:= (degree num)::Z quo 2)/supexp(den,g1,g2,b)
+      sup2htrigs(num, g1:= op arg) / sup2htrigs(den, g1)
+
+    supexp(p, f1, f2, bse) ==
+      ans:F := 0
+      while p ^= 0 repeat
+        g := htrigs(leadingCoefficient(p)::F)
+        if ((d := degree(p)::Z - bse) >= 0) then
+             ans := ans + g * f1 ** d
+        else ans := ans + g * f2 ** (-d)
+        p := reductum p
+      ans
+
+    sup2htrigs(p, f) ==
+      (map(smp2htrigs, p)$SparseUnivariatePolynomialFunctions2(P, F)) f
+
+    exlog p == +/[r.coef * log(r.logand::F) for r in log squareFree p]
+
+    logexpand k ==
+      nullary?(op := operator k) => k::F
+      is?(op, "log"::Symbol) =>
+         exlog(numer(x := expandLog first argument k)) - exlog denom x
+      op [expandLog x for x in argument k]$List(F)
+
+    kerexpand k ==
+      nullary?(op := operator k) => k::F
+      is?(op, POWER) => expandpow k
+      arg := first argument k
+      is?(op, "sec"::Symbol) => inv expand cos arg
+      is?(op, "csc"::Symbol) => inv expand sin arg
+      is?(op, "log"::Symbol) =>
+         exlog(numer(x := expand arg)) - exlog denom x
+      num := numer arg
+      den := denom arg
+      (b := (reductum num) / den) ^= 0 =>
+        a := (leadingMonomial num) / den
+        is?(op, "exp"::Symbol) => exp(expand a) * expand(exp b)
+        is?(op, "sin"::Symbol) =>
+           sin(expand a) * expand(cos b) + cos(expand a) * expand(sin b)
+        is?(op, "cos"::Symbol) =>
+           cos(expand a) * expand(cos b) - sin(expand a) * expand(sin b)
+        is?(op, "tan"::Symbol) =>
+          ta := tan expand a
+          tb := expand tan b
+          (ta + tb) / (1 - ta * tb)
+        is?(op, "cot"::Symbol) =>
+          cta := cot expand a
+          ctb := expand cot b
+          (cta * ctb - 1) / (ctb + cta)
+        op [expand x for x in argument k]$List(F)
+      op [expand x for x in argument k]$List(F)
+
+    smpexp p ==
+      ans:F := 0
+      while p ^= 0 repeat
+        ans := ans + termexp leadingMonomial p
+        p   := reductum p
+      ans
+
+    -- this now works in 3 passes over the expression:
+    --   pass1 rewrites trigs and htrigs in terms of sin,cos,sinh,cosh
+    --   pass2 rewrites sin**2 and sinh**2 in terms of cos and cosh.
+    --   pass3 groups exponentials together
+    simplify0 x ==
+      simplifyExp eval(eval(x,
+          ["tan"::Symbol,"cot"::Symbol,"sec"::Symbol,"csc"::Symbol,
+           "tanh"::Symbol,"coth"::Symbol,"sech"::Symbol,"csch"::Symbol],
+              [t2t,c2t,s2c,c2s,th2th,ch2th,sh2ch,ch2sh]),
+                ["sin"::Symbol, "sinh"::Symbol], [2, 2], [s2c2, sh2ch2])
+
+@
+<<TRMANIP.dotabb>>=
+"TRMANIP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=TRMANIP"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"TRMANIP" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package TRIMAT TriangularMatrixOperations}
 \pagehead{TriangularMatrixOperations}{TRIMAT}
 \pagepic{ps/v104triangularmatrixoperations.ps}{TRIMAT}{1.00}
@@ -42308,6 +49161,95 @@ TwoDimensionalPlotClipping(): Exports == Implementation where
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter U}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UFPS1 UnivariateFormalPowerSeriesFunctions}
+\pagehead{UnivariateFormalPowerSeriesFunctions}{UFPS1}
+\pagepic{ps/v104univariateformalpowerseriesfunctions.ps}{UFPS1}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UFPS1 UnivariateFormalPowerSeriesFunctions>>=
+)abbrev package UFPS1 UnivariateFormalPowerSeriesFunctions
+UnivariateFormalPowerSeriesFunctions(Coef: Ring): Exports == Implementation 
+  where
+
+    UFPS ==> UnivariateFormalPowerSeries Coef
+
+    Exports == with
+
+      hadamard: (UFPS, UFPS) -> UFPS
+
+    Implementation == add
+
+      hadamard(f, g) ==
+        series map(#1*#2, coefficients f, coefficients g)
+                  $StreamFunctions3(Coef, Coef, Coef) 
+
+@
+<<UFPS1.dotabb>>=
+"UFPS1" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UFPS1"]
+"UFPS" [color="#88FF44",href="bookvol10.3.pdf#nameddest=UFPS"]
+"UFPS1" -> "UFPS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ULS2 UnivariateLaurentSeriesFunctions2}
+\pagehead{UnivariateLaurentSeriesFunctions2}{ULS2}
+\pagepic{ps/v104univariatelaurentseriesfunctions2.ps}{ULS2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ULS2 UnivariateLaurentSeriesFunctions2>>=
+)abbrev package ULS2 UnivariateLaurentSeriesFunctions2
+++ Author: Clifton J. Williamson
+++ Date Created: 5 March 1990
+++ Date Last Updated: 5 March 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Laurent series, map
+++ Examples:
+++ References:
+++ Description: Mapping package for univariate Laurent series
+++   This package allows one to apply a function to the coefficients of
+++   a univariate Laurent series.
+UnivariateLaurentSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
+ Exports == Implementation where
+  Coef1 : Ring
+  Coef2 : Ring
+  var1: Symbol
+  var2: Symbol
+  cen1: Coef1
+  cen2: Coef2
+  ULS1  ==> UnivariateLaurentSeries(Coef1, var1, cen1)
+  ULS2  ==> UnivariateLaurentSeries(Coef2, var2, cen2)
+  UTS1  ==> UnivariateTaylorSeries(Coef1, var1, cen1)
+  UTS2  ==> UnivariateTaylorSeries(Coef2, var2, cen2)
+  UTSF2 ==> UnivariateTaylorSeriesFunctions2(Coef1, Coef2, UTS1, UTS2)
+
+  Exports ==> with
+    map: (Coef1 -> Coef2,ULS1) -> ULS2
+      ++ \spad{map(f,g(x))} applies the map f to the coefficients of the Laurent
+      ++ series \spad{g(x)}.
+
+  Implementation ==> add
+
+    map(f,ups) == laurent(degree ups, map(f, taylorRep ups)$UTSF2)
+
+@
+<<ULS2.dotabb>>=
+"ULS2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ULS2"]
+"MODULE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MODULE"]
+"SGROUP" [color="#4488FF",href="bookvol10.2.pdf#nameddest=SGROUP"]
+"ULS2" -> "LMODULE"
+"ULS2" -> "SGROUP"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package UPCDEN UnivariatePolynomialCommonDenominator}
 \pagehead{UnivariatePolynomialCommonDenominator}{UPCDEN}
 \pagepic{ps/v104univariatepolynomialcommondenominator.ps}{UPCDEN}{1.00}
@@ -42597,12 +49539,14 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package INTHERAL AlgebraicHermiteIntegration>>
 <<package INTALG AlgebraicIntegrate>>
 <<package INTAF AlgebraicIntegration>>
+<<package ALGMANIP AlgebraicManipulations>>
 <<package ALGFACT AlgFactor>>
 <<package INTPACK AnnaNumericalIntegrationPackage>>
 <<package OPTPACK AnnaNumericalOptimizationPackage>>
 <<package ODEPACK AnnaOrdinaryDifferentialEquationPackage>>
 <<package PDEPACK AnnaPartialDifferentialEquationPackage>>
 <<package ANY1 AnyFunctions1>>
+<<package ASSOCEQ AssociatedEquations>>
 <<package PMPRED AttachPredicates>>
 <<package AXSERV AxiomServer>>
 
@@ -42645,6 +49589,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package EP EigenPackage>>
 <<package EF ElementaryFunction>>
 <<package DEFINTEF ElementaryFunctionDefiniteIntegration>>
+<<package SIGNEF ElementaryFunctionSign>>
 <<package EFSTRUC ElementaryFunctionStructurePackage>>
 <<package EFULS ElementaryFunctionsUnivariateLaurentSeries>>
 <<package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries>>
@@ -42663,6 +49608,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package EXPR2UPS ExpressionToUnivariatePowerSeries>>
 <<package E04AGNT e04AgentsPackage>>
 
+<<package FACTFUNC FactoredFunctions>>
 <<package FR2 FactoredFunctions2>>
 <<package FRUTIL FactoredFunctionUtilities>>
 <<package FACUTIL FactoringUtilities>>
@@ -42713,8 +49659,17 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package GBINTERN GroebnerInternalPackage>>
 <<package GB GroebnerPackage>>
 <<package GROEBSOL GroebnerSolve>>
+<<package GUESS Guess>>
+<<package GUESSAN GuessAlgebraicNumber>>
+<<package GUESSF GuessFinite>>
+<<package GUESSF1 GuessFiniteFunctions>>
+<<package GUESSINT GuessInteger>>
+<<package GOPT0 GuessOptionFunctions0>>
+<<package GUESSP GuessPolynomial>>
+<<package GUESSUP GuessUnivariatePolynomial>>
 
 <<package HB HallBasis>>
+<<package HEUGCD HeuGcd>>
 
 <<package IDECOMP IdealDecompositionPackage>>
 <<package INFPROD0 InfiniteProductCharacteristicZero>>
@@ -42729,6 +49684,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package ITRIGMNP InnerTrigonometricManipulations>>
 <<package COMBINAT IntegerCombinatoricFunctions>>
 <<package INTFACT IntegerFactorizationPackage>>
+<<package ZLINDEP IntegerLinearDependence>>
 <<package PRIMES IntegerPrimesPackage>>
 <<package IROOT IntegerRoots>>
 <<package INTSLPE IntegerSolveLinearPolynomialEquation>>
@@ -42738,11 +49694,22 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package IR2F IntegrationResultToFunction>>
 <<package IRREDFFX IrredPolyOverFiniteField>>
 <<package IRSN IrrRepSymNatPackage>>
+<<package INVLAPLA InverseLaplaceTransform>>
 
 <<package KERNEL2 KernelFunctions2>>
 <<package KOVACIC Kovacic>>
 
+<<package LAPLACE LaplaceTransform>>
+<<package LEADCDET LeadingCoefDetermination>>
+<<package LINDEP LinearDependence>>
+<<package LODOF LinearOrdinaryDifferentialOperatorFactorizer>>
+<<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>
 <<package LPEFRAC LinearPolynomialEquationByFractions>>
+<<package LGROBP LinGroebnerPackage>>
+<<package LF LiouvillianFunction>>
+<<package LIST2 ListFunctions2>>
+<<package LIST3 ListFunctions3>>
+<<package LIST2MAP ListToMap>>
 
 <<package MCDEN MatrixCommonDenominator>>
 <<package MTHING MergeThing>>
@@ -42769,6 +49736,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package NAGC05 NagRootFindingPackage>>
 <<package NAGC06 NagSeriesSummationPackage>>
 <<package NEWTON NewtonInterpolation>>
+<<package NCODIV NonCommutativeOperatorDivision>>
 <<package NONE1 NoneFunctions1>>
 <<package NORMMA NormInMonogenicAlgebra>>
 <<package NFINTBAS NumberFieldIntegralBasis>>
@@ -42784,6 +49752,9 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package INTPM PatternMatchIntegration>>
 <<package PICOERCE PiCoercions>>
 <<package PAN2EXPR PolynomialAN2Expression>>
+<<package POLYROOT PolynomialRoots>>
+<<package LIMITPS PowerSeriesLimitPackage>>
+<<package PREASSOC PrecomputedAssociatedEquations>>
 <<package PRIMARR2 PrimitiveArrayFunctions2>>
 <<package INTPAF PureAlgebraicIntegration>>
 <<package PUSHVAR PushVariables>>
@@ -42802,6 +49773,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package SAERFFC SAERationalFunctionAlgFactor>>
 <<package FORMULA1 ScriptFormulaFormat1>>
 <<package SAEFACT SimpleAlgebraicExtensionAlgFactor>>
+<<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>
 <<package SCACHE SortedCache>>
 <<package STINPROD StreamInfiniteProduct>>
 <<package SUBRESP SubResultantPackage>>
@@ -42816,10 +49788,13 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package DRAWPT TopLevelDrawFunctionsForPoints>>
 <<package INTHERTR TranscendentalHermiteIntegration>>
 <<package INTTR TranscendentalIntegration>>
-p<<package TRIMAT TriangularMatrixOperations>>
+<<package TRMANIP TranscendentalManipulations>>
+<<package TRIMAT TriangularMatrixOperations>>
 <<package TRIGMNIP TrigonometricManipulations>>
 <<package CLIP TwoDimensionalPlotClipping>>
 
+<<package UFPS1 UnivariateFormalPowerSeriesFunctions>>
+<<package ULS2 UnivariateLaurentSeriesFunctions2>>
 <<package UPCDEN UnivariatePolynomialCommonDenominator>>
 
 <<package WFFINTBS WildFunctionFieldIntegralBasis>>
diff --git a/books/ps/v104algebraicmanipulations.ps b/books/ps/v104algebraicmanipulations.ps
new file mode 100644
index 0000000..ad4799b
--- /dev/null
+++ b/books/ps/v104algebraicmanipulations.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 132 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 96 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% ALGMANIP
+gsave
+[ /Rect [ 0 72 88 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ALGMANIP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 88 108 moveto
+2.93238e-14 108 lineto
+8.24688e-15 72 lineto
+88 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 88 108 moveto
+2.93238e-14 108 lineto
+8.24688e-15 72 lineto
+88 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 73 (ALGMANIP) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 17 0 71 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 71 36 moveto
+17 36 lineto
+17 1.06581e-14 lineto
+71 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 71 36 moveto
+17 36 lineto
+17 1.06581e-14 lineto
+71 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+36.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% ALGMANIP->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 44 72 moveto
+44 64 44 55 44 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 47.5001 46 moveto
+44 36 lineto
+40.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 47.5001 46 moveto
+44 36 lineto
+40.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 132 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104associatedequations.ps b/books/ps/v104associatedequations.ps
new file mode 100644
index 0000000..4f602e6
--- /dev/null
+++ b/books/ps/v104associatedequations.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 124 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 88 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% ASSOCEQ
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ASSOCEQ) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+3.02917e-14 108 lineto
+9.23914e-15 72 lineto
+80 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+3.02917e-14 108 lineto
+9.23914e-15 72 lineto
+80 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 65 (ASSOCEQ) alignedtext
+grestore
+% IVECTOR
+gsave
+[ /Rect [ 1 0 79 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=IVECTOR) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 79 36 moveto
+1 36 lineto
+1 1.06581e-14 lineto
+79 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 79 36 moveto
+1 36 lineto
+1 1.06581e-14 lineto
+79 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+9 13.9 moveto 62 (IVECTOR) alignedtext
+grestore
+% ASSOCEQ->IVECTOR
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 124 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104elementaryfunctionsign.ps b/books/ps/v104elementaryfunctionsign.ps
new file mode 100644
index 0000000..c61405a
--- /dev/null
+++ b/books/ps/v104elementaryfunctionsign.ps
@@ -0,0 +1,301 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 191 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 155 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% SIGNEF
+gsave
+[ /Rect [ 0 72 64 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=SIGNEF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 64 108 moveto
+1.92121e-14 108 lineto
+5.21978e-15 72 lineto
+64 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 64 108 moveto
+1.92121e-14 108 lineto
+5.21978e-15 72 lineto
+64 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 49 (SIGNEF) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 81 0 147 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 147 36 moveto
+81 36 lineto
+81 1.06581e-14 lineto
+147 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 147 36 moveto
+81 36 lineto
+81 1.06581e-14 lineto
+147 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+88.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% SIGNRF
+gsave
+0.000 0.000 1.000 nodecolor
+newpath 146 108 moveto
+82 108 lineto
+82 72 lineto
+146 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.000 0.000 1.000 nodecolor
+newpath 146 108 moveto
+82 108 lineto
+82 72 lineto
+146 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+89.5 85.9 moveto 49 (SIGNRF) alignedtext
+grestore
+% SIGNRF->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 114 72 moveto
+114 64 114 55 114 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 117.5 46 moveto
+114 36 lineto
+110.5 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 117.5 46 moveto
+114 36 lineto
+110.5 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 191 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104elementaryfunctionstructurepackage.ps b/books/ps/v104elementaryfunctionstructurepackage.ps
new file mode 100644
index 0000000..a11783d
--- /dev/null
+++ b/books/ps/v104elementaryfunctionstructurepackage.ps
@@ -0,0 +1,326 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 170 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 134 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% EFSTRUC
+gsave
+[ /Rect [ 24 72 102 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=EFSTRUC) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 102 108 moveto
+24 108 lineto
+24 72 lineto
+102 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 102 108 moveto
+24 108 lineto
+24 72 lineto
+102 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+32 85.9 moveto 62 (EFSTRUC) alignedtext
+grestore
+% ACF
+gsave
+[ /Rect [ 0 0 54 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13.5 13.9 moveto 27 (ACF) alignedtext
+grestore
+% EFSTRUC->ACF
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 54 72 moveto
+50 64 45 54 40 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 43.2598 43.7166 moveto
+36 36 lineto
+36.8631 46.5596 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 43.2598 43.7166 moveto
+36 36 lineto
+36.8631 46.5596 lineto
+closepath stroke
+grestore
+% FS
+gsave
+[ /Rect [ 72 0 126 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 126 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+126 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 126 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+126 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+91.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% EFSTRUC->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 72 72 moveto
+76 64 81 54 86 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 89.1369 46.5596 moveto
+90 36 lineto
+82.7402 43.7166 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 89.1369 46.5596 moveto
+90 36 lineto
+82.7402 43.7166 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 170 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104factoredfunctions.ps b/books/ps/v104factoredfunctions.ps
new file mode 100644
index 0000000..d9c4586
--- /dev/null
+++ b/books/ps/v104factoredfunctions.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 132 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 96 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% FACTFUNC
+gsave
+[ /Rect [ 0 72 88 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=FACTFUNC) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 88 108 moveto
+2.93238e-14 108 lineto
+8.24688e-15 72 lineto
+88 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 88 108 moveto
+2.93238e-14 108 lineto
+8.24688e-15 72 lineto
+88 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 73 (FACTFUNC) alignedtext
+grestore
+% ALGEBRA
+gsave
+[ /Rect [ 4 0 84 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ALGEBRA) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 84 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+84 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 84 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+84 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11.5 13.9 moveto 65 (ALGEBRA) alignedtext
+grestore
+% FACTFUNC->ALGEBRA
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 44 72 moveto
+44 64 44 55 44 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 47.5001 46 moveto
+44 36 lineto
+40.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 47.5001 46 moveto
+44 36 lineto
+40.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 132 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guess.ps b/books/ps/v104guess.ps
new file mode 100644
index 0000000..fb5df01
--- /dev/null
+++ b/books/ps/v104guess.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 106 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 70 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESS
+gsave
+[ /Rect [ 1 72 61 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 61 108 moveto
+1 108 lineto
+1 72 lineto
+61 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 61 108 moveto
+1 108 lineto
+1 72 lineto
+61 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8.5 85.9 moveto 45 (GUESS) alignedtext
+grestore
+% RECOP
+gsave
+[ /Rect [ 0 0 62 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=RECOP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 62 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+62 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 62 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+62 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 46 (RECOP) alignedtext
+grestore
+% GUESS->RECOP
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 31 72 moveto
+31 64 31 55 31 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 34.5001 46 moveto
+31 36 lineto
+27.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 34.5001 46 moveto
+31 36 lineto
+27.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 106 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guessalgebraicnumber.ps b/books/ps/v104guessalgebraicnumber.ps
new file mode 100644
index 0000000..46c14fd
--- /dev/null
+++ b/books/ps/v104guessalgebraicnumber.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 124 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 88 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESSAN
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESSAN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+3.02917e-14 108 lineto
+9.23914e-15 72 lineto
+80 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+3.02917e-14 108 lineto
+9.23914e-15 72 lineto
+80 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 65 (GUESSAN) alignedtext
+grestore
+% GUESS
+gsave
+[ /Rect [ 10 0 70 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 70 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+70 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 70 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+70 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 45 (GUESS) alignedtext
+grestore
+% GUESSAN->GUESS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 124 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guessfinite.ps b/books/ps/v104guessfinite.ps
new file mode 100644
index 0000000..c8495e1
--- /dev/null
+++ b/books/ps/v104guessfinite.ps
@@ -0,0 +1,301 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 204 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 168 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESSF
+gsave
+[ /Rect [ 0 72 68 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESSF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 53 (GUESSF) alignedtext
+grestore
+% GUESS
+gsave
+[ /Rect [ 93 0 153 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 153 36 moveto
+93 36 lineto
+93 1.06581e-14 lineto
+153 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 153 36 moveto
+93 36 lineto
+93 1.06581e-14 lineto
+153 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+100.5 13.9 moveto 45 (GUESS) alignedtext
+grestore
+% GUESSF1
+gsave
+0.000 0.000 1.000 nodecolor
+newpath 160 108 moveto
+86 108 lineto
+86 72 lineto
+160 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.000 0.000 1.000 nodecolor
+newpath 160 108 moveto
+86 108 lineto
+86 72 lineto
+160 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+93.5 85.9 moveto 59 (GUESSF1) alignedtext
+grestore
+% GUESSF1->GUESS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 123 72 moveto
+123 64 123 55 123 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 126.5 46 moveto
+123 36 lineto
+119.5 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 126.5 46 moveto
+123 36 lineto
+119.5 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 204 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guessfinitefunctions.ps b/books/ps/v104guessfinitefunctions.ps
new file mode 100644
index 0000000..b49f9c7
--- /dev/null
+++ b/books/ps/v104guessfinitefunctions.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 118 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 82 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESSF1
+gsave
+[ /Rect [ 0 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESSF1) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+2.00881e-14 108 lineto
+6.06806e-15 72 lineto
+74 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+2.00881e-14 108 lineto
+6.06806e-15 72 lineto
+74 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 59 (GUESSF1) alignedtext
+grestore
+% GUESS
+gsave
+[ /Rect [ 7 0 67 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 67 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+67 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 67 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+67 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 45 (GUESS) alignedtext
+grestore
+% GUESSF1->GUESS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 37 72 moveto
+37 64 37 55 37 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 40.5001 46 moveto
+37 36 lineto
+33.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 40.5001 46 moveto
+37 36 lineto
+33.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 118 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guessinteger.ps b/books/ps/v104guessinteger.ps
new file mode 100644
index 0000000..9037c95
--- /dev/null
+++ b/books/ps/v104guessinteger.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 128 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 92 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESSINT
+gsave
+[ /Rect [ 0 72 84 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESSINT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 84 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+84 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 84 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+84 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 68 (GUESSINT) alignedtext
+grestore
+% GUESS
+gsave
+[ /Rect [ 12 0 72 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 72 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 72 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 45 (GUESS) alignedtext
+grestore
+% GUESSINT->GUESS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 42 72 moveto
+42 64 42 55 42 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 45.5001 46 moveto
+42 36 lineto
+38.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 45.5001 46 moveto
+42 36 lineto
+38.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 128 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guessoptionfunctions0.ps b/books/ps/v104guessoptionfunctions0.ps
new file mode 100644
index 0000000..a472063
--- /dev/null
+++ b/books/ps/v104guessoptionfunctions0.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 104 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 68 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GOPT0
+gsave
+[ /Rect [ 0 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GOPT0) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+1.45335e-14 108 lineto
+5.55112e-16 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+1.45335e-14 108 lineto
+5.55112e-16 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 45 (GOPT0) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 3 0 57 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 57 36 moveto
+3 36 lineto
+3 1.06581e-14 lineto
+57 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 57 36 moveto
+3 36 lineto
+3 1.06581e-14 lineto
+57 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+10.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% GOPT0->ALIST
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 30 72 moveto
+30 64 30 55 30 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 33.5001 46 moveto
+30 36 lineto
+26.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 33.5001 46 moveto
+30 36 lineto
+26.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 104 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guesspolynomial.ps b/books/ps/v104guesspolynomial.ps
new file mode 100644
index 0000000..f5dfd55
--- /dev/null
+++ b/books/ps/v104guesspolynomial.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 112 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 76 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESSP
+gsave
+[ /Rect [ 0 72 68 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESSP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 53 (GUESSP) alignedtext
+grestore
+% GUESS
+gsave
+[ /Rect [ 4 0 64 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 64 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+64 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 64 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+64 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11.5 13.9 moveto 45 (GUESS) alignedtext
+grestore
+% GUESSP->GUESS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 112 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104guessunivariatepolynomial.ps b/books/ps/v104guessunivariatepolynomial.ps
new file mode 100644
index 0000000..104e635
--- /dev/null
+++ b/books/ps/v104guessunivariatepolynomial.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 122 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 86 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% GUESSUP
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESSUP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 78 108 moveto
+2.634e-14 108 lineto
+5.29438e-15 72 lineto
+78 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 78 108 moveto
+2.634e-14 108 lineto
+5.29438e-15 72 lineto
+78 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 63 (GUESSUP) alignedtext
+grestore
+% GUESS
+gsave
+[ /Rect [ 9 0 69 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GUESS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 69 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+69 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 69 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+69 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+16.5 13.9 moveto 45 (GUESS) alignedtext
+grestore
+% GUESSUP->GUESS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 39 72 moveto
+39 64 39 55 39 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 122 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104heugcd.ps b/books/ps/v104heugcd.ps
new file mode 100644
index 0000000..579156c
--- /dev/null
+++ b/books/ps/v104heugcd.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 118 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 82 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% HEUGCD
+gsave
+[ /Rect [ 0 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=HEUGCD) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+2.00881e-14 108 lineto
+6.06806e-15 72 lineto
+74 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+2.00881e-14 108 lineto
+6.06806e-15 72 lineto
+74 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 59 (HEUGCD) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 4 0 70 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 70 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+70 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 70 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+70 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% HEUGCD->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 37 72 moveto
+37 64 37 55 37 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 40.5001 46 moveto
+37 36 lineto
+33.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 40.5001 46 moveto
+37 36 lineto
+33.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 118 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104integerlineardependence.ps b/books/ps/v104integerlineardependence.ps
new file mode 100644
index 0000000..0f17f22
--- /dev/null
+++ b/books/ps/v104integerlineardependence.ps
@@ -0,0 +1,326 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 200 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 164 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% ZLINDEP
+gsave
+[ /Rect [ 34 72 106 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ZLINDEP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 106 108 moveto
+34 108 lineto
+34 72 lineto
+106 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 106 108 moveto
+34 108 lineto
+34 72 lineto
+106 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+41.5 85.9 moveto 57 (ZLINDEP) alignedtext
+grestore
+% PID
+gsave
+[ /Rect [ 0 0 54 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PID) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+16 13.9 moveto 22 (PID) alignedtext
+grestore
+% ZLINDEP->PID
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 59 72 moveto
+54 64 48 54 43 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 45.916 43.0418 moveto
+38 36 lineto
+39.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 45.916 43.0418 moveto
+38 36 lineto
+39.7969 46.4414 lineto
+closepath stroke
+grestore
+% OAGROUP
+gsave
+[ /Rect [ 72 0 156 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=OAGROUP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 156 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+156 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 156 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+156 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+80 13.9 moveto 68 (OAGROUP) alignedtext
+grestore
+% ZLINDEP->OAGROUP
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 81 72 moveto
+86 64 92 54 98 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 101.203 46.4414 moveto
+103 36 lineto
+95.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 101.203 46.4414 moveto
+103 36 lineto
+95.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 200 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104inverselaplacetransform.ps b/books/ps/v104inverselaplacetransform.ps
new file mode 100644
index 0000000..4f72a44
--- /dev/null
+++ b/books/ps/v104inverselaplacetransform.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 128 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 92 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% INVLAPLA
+gsave
+[ /Rect [ 0 72 84 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=INVLAPLA) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 84 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+84 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 84 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+84 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 68 (INVLAPLA) alignedtext
+grestore
+% ACFS
+gsave
+[ /Rect [ 15 0 69 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACFS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 69 36 moveto
+15 36 lineto
+15 1.06581e-14 lineto
+69 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 69 36 moveto
+15 36 lineto
+15 1.06581e-14 lineto
+69 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+24.5 13.9 moveto 35 (ACFS) alignedtext
+grestore
+% INVLAPLA->ACFS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 42 72 moveto
+42 64 42 55 42 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 45.5001 46 moveto
+42 36 lineto
+38.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 45.5001 46 moveto
+42 36 lineto
+38.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 128 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104laplacetransform.ps b/books/ps/v104laplacetransform.ps
new file mode 100644
index 0000000..983e56c
--- /dev/null
+++ b/books/ps/v104laplacetransform.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 122 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 86 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LAPLACE
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LAPLACE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 78 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+78 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 78 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+78 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 62 (LAPLACE) alignedtext
+grestore
+% ACFS
+gsave
+[ /Rect [ 12 0 66 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACFS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 66 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+66 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 66 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+66 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+21.5 13.9 moveto 35 (ACFS) alignedtext
+grestore
+% LAPLACE->ACFS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 39 72 moveto
+39 64 39 55 39 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 122 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104leadingcoefdetermination.ps b/books/ps/v104leadingcoefdetermination.ps
new file mode 100644
index 0000000..18e60df
--- /dev/null
+++ b/books/ps/v104leadingcoefdetermination.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 134 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 98 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LEADCDET
+gsave
+[ /Rect [ 0 72 90 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LEADCDET) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 90 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+90 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 90 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+90 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 74 (LEADCDET) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 12 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% LEADCDET->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 45 72 moveto
+45 64 45 55 45 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 48.5001 46 moveto
+45 36 lineto
+41.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 48.5001 46 moveto
+45 36 lineto
+41.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 134 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104lineardependence.ps b/books/ps/v104lineardependence.ps
new file mode 100644
index 0000000..da86ee8
--- /dev/null
+++ b/books/ps/v104lineardependence.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 110 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 74 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LINDEP
+gsave
+[ /Rect [ 1 72 65 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LINDEP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 65 108 moveto
+1 108 lineto
+1 72 lineto
+65 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 65 108 moveto
+1 108 lineto
+1 72 lineto
+65 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8.5 85.9 moveto 49 (LINDEP) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 0 0 66 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 66 36 moveto
+2.24404e-14 36 lineto
+8.44116e-15 1.06581e-14 lineto
+66 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 66 36 moveto
+2.24404e-14 36 lineto
+8.44116e-15 1.06581e-14 lineto
+66 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% LINDEP->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 33 72 moveto
+33 64 33 55 33 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 36.5001 46 moveto
+33 36 lineto
+29.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 36.5001 46 moveto
+33 36 lineto
+29.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 110 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104linearordinarydifferentialoperatorfactorizer.ps b/books/ps/v104linearordinarydifferentialoperatorfactorizer.ps
new file mode 100644
index 0000000..01536e6
--- /dev/null
+++ b/books/ps/v104linearordinarydifferentialoperatorfactorizer.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 106 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 70 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LODOF
+gsave
+[ /Rect [ 0 72 62 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LODOF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+2.26989e-14 108 lineto
+5.21631e-15 72 lineto
+62 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+2.26989e-14 108 lineto
+5.21631e-15 72 lineto
+62 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 47 (LODOF) alignedtext
+grestore
+% ACF
+gsave
+[ /Rect [ 4 0 58 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+58 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+58 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 27 (ACF) alignedtext
+grestore
+% LODOF->ACF
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 31 72 moveto
+31 64 31 55 31 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 34.5001 46 moveto
+31 36 lineto
+27.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 34.5001 46 moveto
+31 36 lineto
+27.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 106 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104linearordinarydifferentialoperatorsops.ps b/books/ps/v104linearordinarydifferentialoperatorsops.ps
new file mode 100644
index 0000000..f80a73f
--- /dev/null
+++ b/books/ps/v104linearordinarydifferentialoperatorsops.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 124 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 88 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LODOOPS
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LODOOPS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+3.02917e-14 108 lineto
+9.23914e-15 72 lineto
+80 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+3.02917e-14 108 lineto
+9.23914e-15 72 lineto
+80 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 65 (LODOOPS) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 13 0 67 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 67 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+67 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 67 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+67 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+20.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% LODOOPS->ALIST
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 124 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104lingroebnerpackage.ps b/books/ps/v104lingroebnerpackage.ps
new file mode 100644
index 0000000..3fa407a
--- /dev/null
+++ b/books/ps/v104lingroebnerpackage.ps
@@ -0,0 +1,326 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 202 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 166 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LGROBP
+gsave
+[ /Rect [ 46 72 116 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LGROBP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 116 108 moveto
+46 108 lineto
+46 72 lineto
+116 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 116 108 moveto
+46 108 lineto
+46 72 lineto
+116 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+53.5 85.9 moveto 55 (LGROBP) alignedtext
+grestore
+% DIRPCAT
+gsave
+[ /Rect [ 0 0 74 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=DIRPCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 74 36 moveto
+2.13163e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+74 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 74 36 moveto
+2.13163e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+74 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 58 (DIRPCAT) alignedtext
+grestore
+% LGROBP->DIRPCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 70 72 moveto
+65 64 59 54 53 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 55.916 43.0418 moveto
+48 36 lineto
+49.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 55.916 43.0418 moveto
+48 36 lineto
+49.7969 46.4414 lineto
+closepath stroke
+grestore
+% PFECAT
+gsave
+[ /Rect [ 92 0 158 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 158 36 moveto
+92 36 lineto
+92 1.06581e-14 lineto
+158 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 158 36 moveto
+92 36 lineto
+92 1.06581e-14 lineto
+158 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+99.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% LGROBP->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 92 72 moveto
+97 64 103 54 109 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 112.203 46.4414 moveto
+114 36 lineto
+106.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 112.203 46.4414 moveto
+114 36 lineto
+106.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 202 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104liouvillianfunction.ps b/books/ps/v104liouvillianfunction.ps
new file mode 100644
index 0000000..1017d68
--- /dev/null
+++ b/books/ps/v104liouvillianfunction.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 98 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 62 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LF
+gsave
+[ /Rect [ 0 72 54 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 54 108 moveto
+2.13163e-14 108 lineto
+3.55271e-15 72 lineto
+54 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 54 108 moveto
+2.13163e-14 108 lineto
+3.55271e-15 72 lineto
+54 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19 85.9 moveto 16 (LF) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 0 0 54 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% LF->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 27 72 moveto
+27 64 27 55 27 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 30.5001 46 moveto
+27 36 lineto
+23.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 30.5001 46 moveto
+27 36 lineto
+23.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 98 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104listfunctions2.ps b/books/ps/v104listfunctions2.ps
new file mode 100644
index 0000000..a090b69
--- /dev/null
+++ b/books/ps/v104listfunctions2.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 106 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 70 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LIST2
+gsave
+[ /Rect [ 4 72 58 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LIST2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 58 108 moveto
+4 108 lineto
+4 72 lineto
+58 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 58 108 moveto
+4 108 lineto
+4 72 lineto
+58 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13 85.9 moveto 36 (LIST2) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 0 0 62 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FLAGG) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+2.26989e-14 36 lineto
+5.21631e-15 1.06581e-14 lineto
+62 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+2.26989e-14 36 lineto
+5.21631e-15 1.06581e-14 lineto
+62 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% LIST2->FLAGG
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 31 72 moveto
+31 64 31 55 31 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 34.5001 46 moveto
+31 36 lineto
+27.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 34.5001 46 moveto
+31 36 lineto
+27.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 106 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104listfunctions3.ps b/books/ps/v104listfunctions3.ps
new file mode 100644
index 0000000..923468b
--- /dev/null
+++ b/books/ps/v104listfunctions3.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 98 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 62 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LIST3
+gsave
+[ /Rect [ 0 72 54 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LIST3) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 54 108 moveto
+2.13163e-14 108 lineto
+3.55271e-15 72 lineto
+54 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 54 108 moveto
+2.13163e-14 108 lineto
+3.55271e-15 72 lineto
+54 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+9 85.9 moveto 36 (LIST3) alignedtext
+grestore
+% TYPE
+gsave
+[ /Rect [ 0 0 54 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=TYPE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+54 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+9.5 13.9 moveto 35 (TYPE) alignedtext
+grestore
+% LIST3->TYPE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 27 72 moveto
+27 64 27 55 27 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 30.5001 46 moveto
+27 36 lineto
+23.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 30.5001 46 moveto
+27 36 lineto
+23.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 98 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104listtomap.ps b/books/ps/v104listtomap.ps
new file mode 100644
index 0000000..eb029f5
--- /dev/null
+++ b/books/ps/v104listtomap.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 126 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 90 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LIST2MAP
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LIST2MAP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+82 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+82 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 66 (LIST2MAP) alignedtext
+grestore
+% FLAGG-
+gsave
+[ /Rect [ 7 0 75 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=FLAGG) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 75 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+75 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 75 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+75 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+15 13.9 moveto 52 (FLAGG-) alignedtext
+grestore
+% LIST2MAP->FLAGG-
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 41 72 moveto
+41 64 41 55 41 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 44.5001 46 moveto
+41 36 lineto
+37.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 44.5001 46 moveto
+41 36 lineto
+37.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 126 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104noncommutativeoperatordivision.ps b/books/ps/v104noncommutativeoperatordivision.ps
new file mode 100644
index 0000000..b7fe433
--- /dev/null
+++ b/books/ps/v104noncommutativeoperatordivision.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 114 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 78 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% NCODIV
+gsave
+[ /Rect [ 0 72 70 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=NCODIV) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+70 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+70 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 54 (NCODIV) alignedtext
+grestore
+% FIELD
+gsave
+[ /Rect [ 8 0 62 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FIELD) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+62 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+62 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+15.5 13.9 moveto 39 (FIELD) alignedtext
+grestore
+% NCODIV->FIELD
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 35 72 moveto
+35 64 35 55 35 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 38.5001 46 moveto
+35 36 lineto
+31.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 38.5001 46 moveto
+35 36 lineto
+31.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 114 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104polynomialroots.ps b/books/ps/v104polynomialroots.ps
new file mode 100644
index 0000000..768d28f
--- /dev/null
+++ b/books/ps/v104polynomialroots.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 134 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 98 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% POLYROOT
+gsave
+[ /Rect [ 0 72 90 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=POLYROOT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 90 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+90 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 90 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+90 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 74 (POLYROOT) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 12 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% POLYROOT->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 45 72 moveto
+45 64 45 55 45 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 48.5001 46 moveto
+45 36 lineto
+41.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 48.5001 46 moveto
+45 36 lineto
+41.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 134 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104powerserieslimitpackage.ps b/books/ps/v104powerserieslimitpackage.ps
new file mode 100644
index 0000000..2aa6ac7
--- /dev/null
+++ b/books/ps/v104powerserieslimitpackage.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 122 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 86 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% LIMITPS
+gsave
+[ /Rect [ 4 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LIMITPS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+4 108 lineto
+4 72 lineto
+74 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+4 108 lineto
+4 72 lineto
+74 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+12 85.9 moveto 54 (LIMITPS) alignedtext
+grestore
+% ULSCCAT
+gsave
+[ /Rect [ 0 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ULSCCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.634e-14 36 lineto
+5.29438e-15 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.634e-14 36 lineto
+5.29438e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 63 (ULSCCAT) alignedtext
+grestore
+% LIMITPS->ULSCCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 39 72 moveto
+39 64 39 55 39 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 122 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104precomputedassociatedequations.ps b/books/ps/v104precomputedassociatedequations.ps
new file mode 100644
index 0000000..ecfefff
--- /dev/null
+++ b/books/ps/v104precomputedassociatedequations.ps
@@ -0,0 +1,326 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 202 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 166 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% PREASSOC
+gsave
+[ /Rect [ 40 72 126 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PREASSOC) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 126 108 moveto
+40 108 lineto
+40 72 lineto
+126 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 126 108 moveto
+40 108 lineto
+40 72 lineto
+126 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+47.5 85.9 moveto 71 (PREASSOC) alignedtext
+grestore
+% OREPCAT
+gsave
+[ /Rect [ 0 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=OREPCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.634e-14 36 lineto
+5.29438e-15 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.634e-14 36 lineto
+5.29438e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 63 (OREPCAT) alignedtext
+grestore
+% PREASSOC->OREPCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 72 72 moveto
+67 64 61 54 55 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 57.916 43.0418 moveto
+50 36 lineto
+51.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 57.916 43.0418 moveto
+50 36 lineto
+51.7969 46.4414 lineto
+closepath stroke
+grestore
+% A1AGG
+gsave
+[ /Rect [ 96 0 158 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=A1AGG) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 158 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+158 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 158 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+158 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+103.5 13.9 moveto 47 (A1AGG) alignedtext
+grestore
+% PREASSOC->A1AGG
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 94 72 moveto
+99 64 105 54 111 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 114.203 46.4414 moveto
+116 36 lineto
+108.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 114.203 46.4414 moveto
+116 36 lineto
+108.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 202 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104simplifyalgebraicnumberconvertpackage.ps b/books/ps/v104simplifyalgebraicnumberconvertpackage.ps
new file mode 100644
index 0000000..daba514
--- /dev/null
+++ b/books/ps/v104simplifyalgebraicnumberconvertpackage.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 110 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 74 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% SIMPAN
+gsave
+[ /Rect [ 0 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=SIMPAN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+2.13163e-14 108 lineto
+0 72 lineto
+66 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+2.13163e-14 108 lineto
+0 72 lineto
+66 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 50 (SIMPAN) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 6 0 60 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 60 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+60 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 60 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+60 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+25.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% SIMPAN->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 33 72 moveto
+33 64 33 55 33 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 36.5001 46 moveto
+33 36 lineto
+29.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 36.5001 46 moveto
+33 36 lineto
+29.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 110 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104transcendentalmanipulations.ps b/books/ps/v104transcendentalmanipulations.ps
new file mode 100644
index 0000000..459c74d
--- /dev/null
+++ b/books/ps/v104transcendentalmanipulations.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 122 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 86 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% TRMANIP
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=TRMANIP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 78 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+78 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 78 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+78 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 62 (TRMANIP) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 12 0 66 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 66 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+66 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 66 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+66 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+31.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% TRMANIP->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 39 72 moveto
+39 64 39 55 39 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 42.5001 46 moveto
+39 36 lineto
+35.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 122 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104univariateformalpowerseriesfunctions.ps b/books/ps/v104univariateformalpowerseriesfunctions.ps
new file mode 100644
index 0000000..fbad616
--- /dev/null
+++ b/books/ps/v104univariateformalpowerseriesfunctions.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 100 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 64 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% UFPS1
+gsave
+[ /Rect [ 0 72 56 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UFPS1) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 56 108 moveto
+1.42109e-14 108 lineto
+3.55271e-15 72 lineto
+56 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 56 108 moveto
+1.42109e-14 108 lineto
+3.55271e-15 72 lineto
+56 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 40 (UFPS1) alignedtext
+grestore
+% UFPS
+gsave
+[ /Rect [ 1 0 55 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=UFPS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 55 36 moveto
+1 36 lineto
+1 1.06581e-14 lineto
+55 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 55 36 moveto
+1 36 lineto
+1 1.06581e-14 lineto
+55 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11.5 13.9 moveto 33 (UFPS) alignedtext
+grestore
+% UFPS1->UFPS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 28 72 moveto
+28 64 28 55 28 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 31.5001 46 moveto
+28 36 lineto
+24.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 31.5001 46 moveto
+28 36 lineto
+24.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 100 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104univariatelaurentseriesfunctions2.ps b/books/ps/v104univariatelaurentseriesfunctions2.ps
new file mode 100644
index 0000000..3f5cbf8
--- /dev/null
+++ b/books/ps/v104univariatelaurentseriesfunctions2.ps
@@ -0,0 +1,346 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 249 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 213 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% ULS2
+gsave
+[ /Rect [ 57 72 111 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ULS2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 111 108 moveto
+57 108 lineto
+57 72 lineto
+111 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 111 108 moveto
+57 108 lineto
+57 72 lineto
+111 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+67.5 85.9 moveto 33 (ULS2) alignedtext
+grestore
+% SGROUP
+gsave
+[ /Rect [ 0 0 72 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=SGROUP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 56 (SGROUP) alignedtext
+grestore
+% ULS2->SGROUP
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 72 72 moveto
+67 64 60 54 54 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 56.8 41.9 moveto
+48 36 lineto
+51.2 46.1 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 56.8 41.9 moveto
+48 36 lineto
+51.2 46.1 lineto
+closepath stroke
+grestore
+% LMODULE
+gsave
+0.000 0.000 1.000 nodecolor
+newpath 174 36 moveto
+90 36 lineto
+90 1.06581e-14 lineto
+174 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.000 0.000 1.000 nodecolor
+newpath 174 36 moveto
+90 36 lineto
+90 1.06581e-14 lineto
+174 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+97.5 13.9 moveto 69 (LMODULE) alignedtext
+grestore
+% ULS2->LMODULE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 96 72 moveto
+101 64 108 54 114 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 116.8 46.1 moveto
+120 36 lineto
+111.2 41.9 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 116.8 46.1 moveto
+120 36 lineto
+111.2 41.9 lineto
+closepath stroke
+grestore
+% MODULE
+gsave
+[ /Rect [ 129 72 205 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MODULE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 205 108 moveto
+129 108 lineto
+129 72 lineto
+205 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 205 108 moveto
+129 108 lineto
+129 72 lineto
+205 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+136.5 85.9 moveto 61 (MODULE) alignedtext
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 249 152
+end
+restore
+%%EOF
diff --git a/changelog b/changelog
index 5319b92..59be0cc 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,53 @@
+20090201 tpd src/axiom-website/patches.html 20090201.02.tpd.patch
+20090201 tpd src/algebra/Makefile remove spad files
+20090201 tpd src/algebra/mantepse.spad removed
+20090201 tpd books/ps/v104guessunivariatepolynomial.ps added
+20090201 tpd books/ps/v104guesspolynomial.ps added
+20090201 tpd books/ps/v104guessfinite.ps added
+20090201 tpd books/ps/v104guessfinitefunctions.ps added
+20090201 tpd books/ps/v104guessalgebraicnumber.ps added
+20090201 tpd books/ps/v104guessinteger.ps added
+20090201 tpd books/ps/v104guess.ps added
+20090201 tpd books/ps/v104guessoptionfunctions0.ps added
+20090201 tpd books/ps/v104univariateformalpowerseriesfunctions.ps added
+20090201 tpd src/algebra/manip.spad removed
+20090201 tpd books/ps/v104transcendentalmanipulations.ps added
+20090201 tpd books/ps/v104simplifyalgebraicnumberconvertpackage.ps added
+20090201 tpd books/ps/v104algebraicmanipulations.ps added
+20090201 tpd books/ps/v104polynomialroots.ps added
+20090201 tpd books/ps/v104factoredfunctions.ps added
+20090201 tpd src/algebra/lodo.spad removed
+20090201 tpd books/ps/v104linearordinarydifferentialoperatorsops.ps added
+20090201 tpd src/algebra/lodop.spad removed
+20090201 tpd books/ps/v104noncommutativeoperatordivision.ps added
+20090201 tpd src/algebra/lodof.spad removed
+20090201 tpd books/ps/v104linearordinarydifferentialoperatorfactorizer.ps
+20090201 tpd books/ps/v104associatedequations.ps added
+20090201 tpd books/ps/v104precomputedassociatedequations.ps added
+20090201 tpd src/algebra/list.spad removed
+20090201 tpd books/ps/v104listtomap.ps added
+20090201 tpd books/ps/v104listfunctions3.ps added
+20090201 tpd books/ps/v104listfunctions2.ps added
+20090201 tpd src/algebra/listgcd.spad removed
+20090201 tpd books/ps/v104heugcd.ps added
+20090201 tpd src/algebra/liouv.spad removed
+20090201 tpd books/ps/v104liouvillianfunction.ps added
+20090201 tpd src/algebra/lingrob.spad removed
+20090201 tpd books/ps/v104lingroebnerpackage.ps removed
+20090201 tpd src/algebra/lindep.spad removed
+20090201 tpd books/ps/v104integerlineardependence.ps added
+20090201 tpd books/ps/v104lineardependence.ps added
+20090201 tpd src/algebra/limitps.spad removed
+20090201 tpd books/ps/v104elementaryfunctionstructurepackage.ps added
+20090201 tpd books/ps/v104elementaryfunctionsign.ps added
+20090201 tpd books/ps/v104powerserieslimitpackage.ps added
+20090201 tpd src/algebra/leadcdet.spad removed
+20090201 tpd books/ps/v104leadingcoefdetermination.ps added
+20090201 tpd src/algebra/laurent.spad removed
+20090201 tpd books/ps/v104univariatelaurentseriesfunctions2.ps added
+20090201 tpd src/algebra/laplace.spad removed
+20090201 tpd books/ps/v104inverselaplacetransform.ps added
+20090201 tpd books/ps/v104laplacetransform.ps added
 20090201 tpd src/axiom-website/patches.html 20090201.01.tpd.patch
 20090201 tpd src/algebra/Makefile remove spad files
 20090201 tpd src/algebra/kovacic.spad removed
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index 86d693d..df7d88f 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -15771,12 +15771,7 @@ We need to figure out which mlift.spad to keep.
 <<environment>>=
 
 SPADFILES= \
- ${OUTSRC}/laplace.spad ${OUTSRC}/laurent.spad ${OUTSRC}/leadcdet.spad \
- ${OUTSRC}/limitps.spad ${OUTSRC}/lindep.spad \
- ${OUTSRC}/lingrob.spad ${OUTSRC}/liouv.spad ${OUTSRC}/listgcd.spad \
- ${OUTSRC}/list.spad ${OUTSRC}/lodof.spad \
- ${OUTSRC}/lodop.spad ${OUTSRC}/lodo.spad \
- ${OUTSRC}/manip.spad ${OUTSRC}/mappkg.spad \
+ ${OUTSRC}/mappkg.spad \
  ${OUTSRC}/matfuns.spad ${OUTSRC}/mathml.spad \
  ${OUTSRC}/matstor.spad \
  ${OUTSRC}/mesh.spad ${OUTSRC}/mfinfact.spad \
@@ -15869,12 +15864,7 @@ DOCFILES= \
  ${DOC}/invnode.as.dvi ${DOC}/invrender.as.dvi \
  ${DOC}/invtypes.as.dvi ${DOC}/invutils.as.dvi  \
  ${DOC}/iviews.as.dvi \
- ${DOC}/laplace.spad.dvi ${DOC}/laurent.spad.dvi ${DOC}/leadcdet.spad.dvi \
- ${DOC}/limitps.spad.dvi ${DOC}/lindep.spad.dvi \
- ${DOC}/lingrob.spad.dvi ${DOC}/liouv.spad.dvi ${DOC}/listgcd.spad.dvi \
- ${DOC}/list.spad.dvi ${DOC}/lodof.spad.dvi \
- ${DOC}/lodop.spad.dvi ${DOC}/lodo.spad.dvi \
- ${DOC}/manip.spad.dvi ${DOC}/mappkg.spad.dvi \
+ ${DOC}/mappkg.spad.dvi \
  ${DOC}/matfuns.spad.dvi ${DOC}/mathml.spad.dvi \
  ${DOC}/matstor.spad.dvi \
  ${DOC}/mesh.spad.dvi ${DOC}/mfinfact.spad.dvi \
@@ -17065,15 +17055,15 @@ ${HELP}/Integer.help: ${BOOKS}/bookvol10.3.pamphlet
             >${INPUT}/Integer.input
 	@echo "Integer (INT)" >>${HELPFILE}
 
-${HELP}/IntegerLinearDependence.help: ${IN}/lindep.spad.pamphlet
+${HELP}/IntegerLinearDependence.help: ${BOOKS}/bookvol10.4.pamphlet
 	@echo 7034 create IntegerLinearDependence.help from \
-           ${IN}/lindep.spad.pamphlet
+           ${BOOKS}/bookvol10.4.pamphlet
 	@${TANGLE} -R"IntegerLinearDependence.help" \
-           ${IN}/lindep.spad.pamphlet \
+           ${BOOKS}/bookvol10.4.pamphlet \
            >${HELP}/IntegerLinearDependence.help
 	@cp ${HELP}/IntegerLinearDependence.help ${HELP}/ZLINDEP.help
 	@${TANGLE} -R"IntegerLinearDependence.input" \
-           ${IN}/lindep.spad.pamphlet \
+           ${BOOKS}/bookvol10.4.pamphlet \
             >${INPUT}/IntegerLinearDependence.input
 	@echo "IntegerLinearDependence (ZLINDEP)" >>${HELPFILE}
 
diff --git a/src/algebra/laplace.spad.pamphlet b/src/algebra/laplace.spad.pamphlet
deleted file mode 100644
index 76cc837..0000000
--- a/src/algebra/laplace.spad.pamphlet
+++ /dev/null
@@ -1,369 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra laplace.spad}
-\author{Manuel Bronstein, Barry Trager}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LAPLACE LaplaceTransform}
-<<package LAPLACE LaplaceTransform>>=
-)abbrev package LAPLACE LaplaceTransform
-++ Laplace transform
-++ Author: Manuel Bronstein
-++ Date Created: 30 May 1990
-++ Date Last Updated: 13 December 1995
-++ Description: This package computes the forward Laplace Transform.
-LaplaceTransform(R, F): Exports == Implementation where
-  R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
-           RetractableTo Integer, LinearlyExplicitRingOver Integer)
-  F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
-           AlgebraicallyClosedFunctionSpace R)
-
-  SE  ==> Symbol
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  K   ==> Kernel F
-  OFE ==> OrderedCompletion F
-  EQ  ==> Equation OFE
-
-  ALGOP       ==> "%alg"
-  SPECIALDIFF ==> "%specialDiff"
-
-  Exports ==> with
-    laplace: (F, SE, SE) -> F
-      ++ laplace(f, t, s) returns the Laplace transform of \spad{f(t)}
-      ++ using \spad{s} as the new variable.
-      ++ This is \spad{integral(exp(-s*t)*f(t), t = 0..%plusInfinity)}.
-      ++ Returns the formal object \spad{laplace(f, t, s)} if it cannot
-      ++ compute the transform.
-
-  Implementation ==> add
-    import IntegrationTools(R, F)
-    import ElementaryIntegration(R, F)
-    import PatternMatchIntegration(R, F)
-    import PowerSeriesLimitPackage(R, F)
-    import FunctionSpaceIntegration(R, F)
-    import TrigonometricManipulations(R, F)
-
-    locallaplace : (F, SE, F, SE, F) -> F
-    lapkernel    : (F, SE, F, F) -> Union(F, "failed")
-    intlaplace   : (F, F, F, SE, F) -> Union(F, "failed")
-    isLinear     : (F, SE) -> Union(Record(const:F, nconst:F), "failed")
-    mkPlus       : F -> Union(List F, "failed")
-    dvlap        : (List F, SE) -> F
-    tdenom       : (F, F) -> Union(F, "failed")
-    atn          : (F, SE) -> Union(Record(coef:F, deg:PI), "failed")
-    aexp         : (F, SE) -> Union(Record(coef:F, coef1:F, coef0:F), "failed")
-    algebraic?   : (F, SE) -> Boolean
-
-    oplap := operator("laplace"::Symbol, 3)$BasicOperator
-
-    laplace(f,t,s) == locallaplace(complexElementary(f,t),t,t::F,s,s::F)
-
--- returns true if the highest kernel of f is algebraic over something
-    algebraic?(f, t) ==
-      l := varselect(kernels f, t)
-      m:N := reduce(max, [height k for k in l], 0)$List(N)
-      for k in l repeat
-         height k = m and has?(operator k, ALGOP) => return true
-      false
-
--- differentiate a kernel of the form  laplace(l.1,l.2,l.3) w.r.t x.
--- note that x is not necessarily l.3
--- if x = l.3, then there is no use recomputing the laplace transform,
--- it will remain formal anyways
-    dvlap(l, x) ==
-      l1 := first l
-      l2 := second l
-      x = (v := retract(l3 := third l)@SE) => - oplap(l2 * l1, l2, l3)
-      e := exp(- l3 * l2)
-      locallaplace(differentiate(e * l1, x) / e, retract(l2)@SE, l2, v, l3)
-
--- returns [b, c] iff f = c * t + b
--- and b and c do not involve t
-    isLinear(f, t) ==
-      ff := univariate(f, kernel(t)@K)
-      ((d := retractIfCan(denom ff)@Union(F, "failed")) case "failed")
-        or (degree(numer ff) > 1) => "failed"
-      freeOf?(b := coefficient(numer ff, 0) / d, t) and
-        freeOf?(c := coefficient(numer ff, 1) / d, t) => [b, c]
-      "failed"
-
--- returns [a, n] iff f = a * t**n
-    atn(f, t) ==
-      if ((v := isExpt f) case Record(var:K, exponent:Integer)) then
-        w := v::Record(var:K, exponent:Integer)
-        (w.exponent > 0) and
-          ((vv := symbolIfCan(w.var)) case SE) and (vv::SE = t) =>
-            return [1, w.exponent::PI]
-      (u := isTimes f) case List(F) =>
-        c:F  := 1
-        d:N  := 0
-        for g in u::List(F) repeat
-          if (rec := atn(g, t)) case Record(coef:F, deg:PI) then
-            r := rec::Record(coef:F, deg:PI)
-            c := c * r.coef
-            d := d + r.deg
-          else c := c * g
-        zero? d => "failed"
-        [c, d::PI]
-      "failed"
-
--- returns [a, c, b] iff f = a * exp(c * t + b)
--- and b and c do not involve t
-    aexp(f, t) ==
-      is?(f, "exp"::SE) =>
-        (v := isLinear(first argument(retract(f)@K),t)) case "failed" =>
-           "failed"
-        [1, v.nconst, v.const]
-      (u := isTimes f) case List(F) =>
-        c:F := 1
-        c1 := c0 := 0$F
-        for g in u::List(F) repeat
-          if (r := aexp(g,t)) case Record(coef:F,coef1:F,coef0:F) then
-            rec := r::Record(coef:F, coef1:F, coef0:F)
-            c   := c * rec.coef
-            c0  := c0 + rec.coef0
-            c1  := c1 + rec.coef1
-          else c := c * g
-        zero? c0 and zero? c1 => "failed"
-        [c, c1, c0]
-      if (v := isPower f) case Record(val:F, exponent:Integer) then
-        w := v::Record(val:F, exponent:Integer)
-        (w.exponent ^= 1) and
-          ((r := aexp(w.val, t)) case Record(coef:F,coef1:F,coef0:F)) =>
-            rec := r::Record(coef:F, coef1:F, coef0:F)
-            return [rec.coef ** w.exponent, w.exponent * rec.coef1,
-                                            w.exponent * rec.coef0]
-      "failed"
-
-    mkPlus f ==
-      (u := isPlus numer f) case "failed" => "failed"
-      d := denom f
-      [p / d for p in u::List(SparseMultivariatePolynomial(R, K))]
-
--- returns g if f = g/t
-    tdenom(f, t) ==
-      (denom f exquo numer t) case "failed" => "failed"
-      t * f
-
-    intlaplace(f, ss, g, v, vv) ==
-      is?(g, oplap) or ((i := integrate(g, v)) case List(F)) => "failed"
-      (u:=limit(i::F,equation(vv::OFE,plusInfinity()$OFE)$EQ)) case OFE =>
-        (l := limit(i::F, equation(vv::OFE, ss::OFE)$EQ)) case OFE =>
-          retractIfCan(u::OFE - l::OFE)@Union(F, "failed")
-        "failed"
-      "failed"
-
-    lapkernel(f, t, tt, ss) ==
-      (k := retractIfCan(f)@Union(K, "failed")) case "failed" => "failed"
-      empty?(arg := argument(k::K)) => "failed"
-      is?(op := operator k, "%diff"::SE) =>
-        not( #arg = 3) => "failed"
-        not(is?(arg.3, t)) => "failed"
-        fint := eval(arg.1, arg.2, tt)
-        s := name operator (kernels(ss).1)
-        ss * locallaplace(fint, t, tt, s, ss) - eval(fint, tt = 0)
-      not (empty?(rest arg)) => "failed"
-      member?(t, variables(a := first(arg) / tt)) => "failed"
-      is?(op := operator k, "Si"::SE) => atan(a / ss) / ss
-      is?(op, "Ci"::SE) => log((ss**2 + a**2) / a**2) / (2 * ss)
-      is?(op, "Ei"::SE) => log((ss + a) / a) / ss
-      -- digamma (or Gamma) needs SpecialFunctionCategory
-      -- which we do not have here
-      -- is?(op, "log"::SE) => (digamma(1) - log(a) - log(ss)) / ss
-      "failed"
-
-    -- Below we try to apply one of the texbook rules for computing
-    -- Laplace transforms, either reducing problem to simpler cases
-    -- or using one of known base cases
-    locallaplace(f, t, tt, s, ss) ==
-      zero? f => 0
---      one? f  => inv ss
-      (f = 1)  => inv ss
-
-      -- laplace(f(t)/t,t,s) 
-      --              = integrate(laplace(f(t),t,v), v = s..%plusInfinity)
-      (x := tdenom(f, tt)) case F =>
-        g := locallaplace(x::F, t, tt, vv := new()$SE, vvv := vv::F)
-        (x := intlaplace(f, ss, g, vv, vvv)) case F => x::F
-        oplap(f, tt, ss)
-
-      -- Use linearity
-      (u := mkPlus f) case List(F) =>
-        +/[locallaplace(g, t, tt, s, ss) for g in u::List(F)]
-      (rec := splitConstant(f, t)).const ^= 1 =>
-        rec.const * locallaplace(rec.nconst, t, tt, s, ss)
-
-      -- laplace(t^n*f(t),t,s) = (-1)^n*D(laplace(f(t),t,s), s, n))
-      (v := atn(f, t)) case Record(coef:F, deg:PI) =>
-        vv := v::Record(coef:F, deg:PI)
-        is?(la := locallaplace(vv.coef, t, tt, s, ss), oplap) => oplap(f,tt,ss)
-        (-1$Integer)**(vv.deg) * differentiate(la, s, vv.deg)
-
-      -- Complex shift rule
-      (w := aexp(f, t)) case Record(coef:F, coef1:F, coef0:F) =>
-        ww := w::Record(coef:F, coef1:F, coef0:F)
-        exp(ww.coef0) * locallaplace(ww.coef,t,tt,s,ss - ww.coef1)
-
-      -- Try base cases
-      (x := lapkernel(f, t, tt, ss)) case F => x::F
-
---    -- The following does not seem to help computing transforms, but
---    -- quite frequently leads to loops, so I (wh) disabled it for now
---    -- last chance option: try to use the fact that
---    --    laplace(f(t),t,s) = s laplace(g(t),t,s) - g(0)  where dg/dt = f(t)
---    elem?(int := lfintegrate(f, t)) and (rint := retractIfCan int) case F =>
---        fint := rint :: F
---        -- to avoid infinite loops, we don't call laplace recursively
---        -- if the integral has no new logs and f is an algebraic function
---        empty?(logpart int) and algebraic?(f, t) => oplap(fint, tt, ss)
---        ss * locallaplace(fint, t, tt, s, ss) - eval(fint, tt = 0)
-      oplap(f, tt, ss)
-
-    setProperty(oplap,SPECIALDIFF,dvlap@((List F,SE)->F) pretend None)
-
-@
-\section{package INVLAPLA InverseLaplaceTransform}
-<<package INVLAPLA InverseLaplaceTransform>>=
-)abbrev package INVLAPLA InverseLaplaceTransform
-++ Inverse Laplace transform
-++ Author: Barry Trager
-++ Date Created: 3 Sept 1991
-++ Date Last Updated: 3 Sept 1991
-++ Description: This package computes the inverse Laplace Transform.
-InverseLaplaceTransform(R, F): Exports == Implementation where
-  R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
-           RetractableTo Integer, LinearlyExplicitRingOver Integer)
-  F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
-           SpecialFunctionCategory, AlgebraicallyClosedFunctionSpace R)
-
-  SE  ==> Symbol
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  K   ==> Kernel F
-  UP  ==> SparseUnivariatePolynomial F
-  RF  ==> Fraction UP
-
-  Exports ==> with
-    inverseLaplace: (F, SE, SE) -> Union(F,"failed")
-      ++ inverseLaplace(f, s, t) returns the Inverse
-      ++ Laplace transform of \spad{f(s)}
-      ++ using t as the new variable or "failed" if unable to find
-      ++ a closed form.
-      ++ Handles only rational \spad{f(s)}.
-
-  Implementation ==> add
-
-    -- local ops --
-    ilt : (F,Symbol,Symbol) -> Union(F,"failed")
-    ilt1 : (RF,F) -> F
-    iltsqfr : (RF,F) -> F
-    iltirred: (UP,UP,F) -> F
-    freeOf?: (UP,Symbol) -> Boolean
-
-    inverseLaplace(expr,ivar,ovar) == ilt(expr,ivar,ovar)
-
-    freeOf?(p:UP,v:Symbol) ==
-      "and"/[freeOf?(c,v) for c in coefficients p]
-
-    ilt(expr,var,t) ==
-      expr = 0 => 0
-      r := univariate(expr,kernel(var))
-
-      -- Check that r is a rational function such that degree of
-      -- the numarator is lower that degree of denominator
-      not(numer(r) quo denom(r) = 0) => "failed"
-      not( freeOf?(numer r,var) and freeOf?(denom r,var)) => "failed"
-
-      ilt1(r,t::F)
-
-    hintpac := TranscendentalHermiteIntegration(F, UP)
-
-    ilt1(r,t) ==
-      r = 0 => 0
-      rsplit := HermiteIntegrate(r, differentiate)$hintpac
-      -t*ilt1(rsplit.answer,t) + iltsqfr(rsplit.logpart,t)
-
-    iltsqfr(r,t) ==
-       r = 0 => 0
-       p:=numer r
-       q:=denom r
-     --  ql := [qq.factor for qq in factors factor q]
-       ql := [qq.factor for qq in factors squareFree q]
-       # ql = 1 => iltirred(p,q,t)
-       nl := multiEuclidean(ql,p)::List(UP)
-       +/[iltirred(a,b,t) for a in nl for b in ql]
-
-    -- q is irreducible, monic, degree p < degree q
-    iltirred(p,q,t) ==
-      degree q = 1 =>
-        cp := coefficient(p,0)
-        (c:=coefficient(q,0))=0 => cp
-        cp*exp(-c*t)
-      degree q = 2 =>
-        a := coefficient(p,1)
-        b := coefficient(p,0)
-        c:=(-1/2)*coefficient(q,1)
-        d:= coefficient(q,0)
-        e := exp(c*t)
-        b := b+a*c
-        d := d-c**2
-        d > 0 =>
-            alpha:F := sqrt d
-            e*(a*cos(t*alpha) + b*sin(t*alpha)/alpha)
-        alpha :F := sqrt(-d)
-        e*(a*cosh(t*alpha) + b*sinh(t*alpha)/alpha)
-      roots:List F := zerosOf q
-      q1 := differentiate q
-      +/[p(root)/q1(root)*exp(root*t) for root in roots]
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LAPLACE LaplaceTransform>>
-<<package INVLAPLA InverseLaplaceTransform>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/laurent.spad.pamphlet b/src/algebra/laurent.spad.pamphlet
deleted file mode 100644
index ef2fd1e..0000000
--- a/src/algebra/laurent.spad.pamphlet
+++ /dev/null
@@ -1,94 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra laurent.spad}
-\author{Clifton J. Williamson, Bill Burge}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package ULS2 UnivariateLaurentSeriesFunctions2}
-<<package ULS2 UnivariateLaurentSeriesFunctions2>>=
-)abbrev package ULS2 UnivariateLaurentSeriesFunctions2
-++ Author: Clifton J. Williamson
-++ Date Created: 5 March 1990
-++ Date Last Updated: 5 March 1990
-++ Basic Operations:
-++ Related Domains:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: Laurent series, map
-++ Examples:
-++ References:
-++ Description: Mapping package for univariate Laurent series
-++   This package allows one to apply a function to the coefficients of
-++   a univariate Laurent series.
-UnivariateLaurentSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
- Exports == Implementation where
-  Coef1 : Ring
-  Coef2 : Ring
-  var1: Symbol
-  var2: Symbol
-  cen1: Coef1
-  cen2: Coef2
-  ULS1  ==> UnivariateLaurentSeries(Coef1, var1, cen1)
-  ULS2  ==> UnivariateLaurentSeries(Coef2, var2, cen2)
-  UTS1  ==> UnivariateTaylorSeries(Coef1, var1, cen1)
-  UTS2  ==> UnivariateTaylorSeries(Coef2, var2, cen2)
-  UTSF2 ==> UnivariateTaylorSeriesFunctions2(Coef1, Coef2, UTS1, UTS2)
-
-  Exports ==> with
-    map: (Coef1 -> Coef2,ULS1) -> ULS2
-      ++ \spad{map(f,g(x))} applies the map f to the coefficients of the Laurent
-      ++ series \spad{g(x)}.
-
-  Implementation ==> add
-
-    map(f,ups) == laurent(degree ups, map(f, taylorRep ups)$UTSF2)
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package ULS2 UnivariateLaurentSeriesFunctions2>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/leadcdet.spad.pamphlet b/src/algebra/leadcdet.spad.pamphlet
deleted file mode 100644
index 7363526..0000000
--- a/src/algebra/leadcdet.spad.pamphlet
+++ /dev/null
@@ -1,167 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra leadcdet.spad}
-\author{Patrizia Gianni}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LEADCDET LeadingCoefDetermination}
-<<package LEADCDET LeadingCoefDetermination>>=
-)abbrev package LEADCDET LeadingCoefDetermination
-++ Author : P.Gianni, May 1990
-++ Description:
-++ Package for leading coefficient determination in the lifting step.
-++ Package working for every R euclidean with property "F".
-LeadingCoefDetermination(OV,E,Z,P) : C == T
- where
-  OV    :   OrderedSet
-  E     :   OrderedAbelianMonoidSup
-  Z     :   EuclideanDomain
-  BP        ==> SparseUnivariatePolynomial Z
-  P         :   PolynomialCategory(Z,E,OV)
-  NNI       ==> NonNegativeInteger
-  LeadFact  ==> Record(polfac:List(P),correct:Z,corrfact:List(BP))
-  ParFact   ==> Record(irr:P,pow:Integer)
-  FinalFact ==> Record(contp:Z,factors:List(ParFact))
- 
-  C == with
-   polCase  : (Z,NNI,List(Z)) -> Boolean
-     ++ polCase(contprod, numFacts, evallcs), where contprod is the
-     ++ product of the content of the leading coefficient of
-     ++ the polynomial to be factored with the content of the
-     ++ evaluated polynomial, numFacts is the number of factors
-     ++ of the leadingCoefficient, and evallcs is the list of
-     ++ the evaluated factors of the leadingCoefficient, returns
-     ++ true if the factors of the leading Coefficient can be
-     ++ distributed with this valuation.
-   distFact : (Z,List(BP),FinalFact,List(Z),List(OV),List(Z)) ->
-                                              Union(LeadFact,"failed")
-     ++ distFact(contm,unilist,plead,vl,lvar,lval), where contm is
-     ++ the content of the evaluated polynomial, unilist is the list
-     ++ of factors of the evaluated polynomial, plead is the complete
-     ++ factorization of the leading coefficient, vl is the list
-     ++ of factors of the leading coefficient evaluated, lvar is the
-     ++ list of variables, lval is the list of values, returns a record
-     ++ giving the list of leading coefficients to impose on the univariate
-     ++ factors, 
- 
-  T == add
-    distribute: (Z,List(BP),List(P),List(Z),List(OV),List(Z)) -> LeadFact
-    checkpow  : (Z,Z) -> NNI
- 
-    polCase(d:Z,nk:NNI,lval:List(Z)):Boolean ==
-      -- d is the product of the content lc m (case polynomial)
-      -- and the cont of the polynomial evaluated
-      q:Z
-      distlist:List(Z) := [d]
-      for i in 1..nk repeat
-        q := unitNormal(lval.i).canonical
-        for j in 0..(i-1)::NNI repeat
-          y := distlist.((i-j)::NNI)
-          while y^=1  repeat
-            y := gcd(y,q)
-            q := q quo y
-          if q=1 then return false
-        distlist := append(distlist,[q])
-      true
- 
-    checkpow(a:Z,b:Z) : NonNegativeInteger ==
-      qt: Union(Z,"failed")
-      for i in 0.. repeat
-        qt:= b exquo a
-        if qt case "failed" then return i
-        b:=qt::Z
- 
-    distribute(contm:Z,unilist:List(BP),pl:List(P),vl:List(Z),
-                              lvar:List(OV),lval:List(Z)): LeadFact ==
-      d,lcp : Z
-      nf:NNI:=#unilist
-      for i in 1..nf repeat
-          lcp := leadingCoefficient (unilist.i)
-          d:= gcd(lcp,vl.i)
-          pl.i := (lcp quo d)*pl.i
-          d := vl.i quo d
-          unilist.i := d*unilist.i
-          contm := contm quo d
-      if contm ^=1 then for i in 1..nf repeat pl.i := contm*pl.i
-      [pl,contm,unilist]$LeadFact
- 
-    distFact(contm:Z,unilist:List(BP),plead:FinalFact,
-             vl:List(Z),lvar:List(OV),lval:List(Z)):Union(LeadFact,"failed") ==
-      h:NonNegativeInteger
-      c,d : Z
-      lpol:List(P):=[]
-      lexp:List(Integer):=[]
-      nf:NNI := #unilist
-      vl := reverse vl --lpol and vl reversed so test from right to left
-      for fpl in plead.factors repeat
-       lpol:=[fpl.irr,:lpol]
-       lexp:=[fpl.pow,:lexp]
-      vlp:List(Z):= [1$Z for i in 1..nf]
-      aux : List(P) := [1$P for i in 1..nf]
-      for i in 1..nf repeat
-        c := contm*leadingCoefficient unilist.i
-        c=1 or c=-1  => "next i"
-        for k in 1..(# lpol) repeat
-          lexp.k=0 => "next factor"
-          h:= checkpow(vl.k,c)
-          if h ^=0 then
-           if h>lexp.k then return "failed"
-           lexp.k:=lexp.k-h
-           aux.i := aux.i*(lpol.k ** h)
-           d:= vl.k**h
-           vlp.i:= vlp.i*d
-           c:= c quo d
-        if contm=1 then vlp.i:=c
-      for k in 1..(# lpol) repeat if lexp.k ^= 0 then return "failed"
-      contm =1 => [[vlp.i*aux.i for i in 1..nf],1,unilist]$LeadFact
-      distribute(contm,unilist,aux,vlp,lvar,lval)
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LEADCDET LeadingCoefDetermination>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/limitps.spad.pamphlet b/src/algebra/limitps.spad.pamphlet
deleted file mode 100644
index a388417..0000000
--- a/src/algebra/limitps.spad.pamphlet
+++ /dev/null
@@ -1,768 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra limitps.spad}
-\author{Clifton J. Williamson, Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LIMITPS PowerSeriesLimitPackage}
-<<package LIMITPS PowerSeriesLimitPackage>>=
-)abbrev package LIMITPS PowerSeriesLimitPackage
-++ Author: Clifton J. Williamson
-++ Date Created: 21 March 1989
-++ Date Last Updated: 30 March 1994
-++ Basic Operations:
-++ Related Domains: UnivariateLaurentSeries(FE,x,a),
-++   UnivariatePuiseuxSeries(FE,x,a),ExponentialExpansion(R,FE,x,a)
-++ Also See:
-++ AMS Classifications:
-++ Keywords: limit, functional expression, power series
-++ Examples:
-++ References:
-++ Description:
-++   PowerSeriesLimitPackage implements limits of expressions
-++   in one or more variables as one of the variables approaches a
-++   limiting value.  Included are two-sided limits, left- and right-
-++   hand limits, and limits at plus or minus infinity.
-PowerSeriesLimitPackage(R,FE): Exports == Implementation where
-  R  : Join(GcdDomain,OrderedSet,RetractableTo Integer,_
-            LinearlyExplicitRingOver Integer)
-  FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
-            FunctionSpace R)
-  Z       ==> Integer
-  RN      ==> Fraction Integer
-  RF      ==> Fraction Polynomial R
-  OFE     ==> OrderedCompletion FE
-  OPF     ==> OnePointCompletion FE
-  SY      ==> Symbol
-  EQ      ==> Equation
-  LF      ==> LiouvillianFunction
-  UTS     ==> UnivariateTaylorSeries
-  ULS     ==> UnivariateLaurentSeries
-  UPXS    ==> UnivariatePuiseuxSeries
-  EFULS   ==> ElementaryFunctionsUnivariateLaurentSeries
-  EFUPXS  ==> ElementaryFunctionsUnivariatePuiseuxSeries
-  FS2UPS  ==> FunctionSpaceToUnivariatePowerSeries
-  FS2EXPXP ==> FunctionSpaceToExponentialExpansion
-  Problem ==> Record(func:String,prob:String)
-  RESULT  ==> Union(OFE,"failed")
-  TwoSide ==> Record(leftHandLimit:RESULT,rightHandLimit:RESULT)
-  U       ==> Union(OFE,TwoSide,"failed")
-  SIGNEF  ==> ElementaryFunctionSign(R,FE)
-
-  Exports ==> with
-
-    limit: (FE,EQ OFE) -> U
-      ++ limit(f(x),x = a) computes the real limit \spad{lim(x -> a,f(x))}.
-
-    complexLimit: (FE,EQ OPF) -> Union(OPF, "failed")
-      ++ complexLimit(f(x),x = a) computes the complex limit
-      ++ \spad{lim(x -> a,f(x))}.
-
-    limit: (FE,EQ FE,String) -> RESULT
-      ++ limit(f(x),x=a,"left") computes the left hand real limit
-      ++ \spad{lim(x -> a-,f(x))};
-      ++ \spad{limit(f(x),x=a,"right")} computes the right hand real limit
-      ++ \spad{lim(x -> a+,f(x))}.
-
-  Implementation ==> add
-    import ToolsForSign(R)
-    import ElementaryFunctionStructurePackage(R,FE)
-
-    zeroFE:FE := 0
-    anyRootsOrAtrigs?   : FE -> Boolean
-    complLimit  : (FE,SY) -> Union(OPF,"failed")
-    okProblem?  : (String,String) -> Boolean
-    realLimit   : (FE,SY) -> U
-    xxpLimit    : (FE,SY) -> RESULT
-    limitPlus   : (FE,SY) -> RESULT
-    localsubst  : (FE,Kernel FE,Z,FE) -> FE
-    locallimit  : (FE,SY,OFE) -> U
-    locallimitcomplex : (FE,SY,OPF) -> Union(OPF,"failed")
-    poleLimit:(RN,FE,SY) -> U
-    poleLimitPlus:(RN,FE,SY) -> RESULT
-
-    noX?: (FE,SY) -> Boolean
-    noX?(fcn,x) == not member?(x,variables fcn)
-
-    constant?: FE -> Boolean
-    constant? fcn == empty? variables fcn
-
-    firstNonLogPtr: (FE,SY) -> List Kernel FE
-    firstNonLogPtr(fcn,x) ==
-      -- returns a pointer to the first element of kernels(fcn) which
-      -- has 'x' as a variable, which is not a logarithm, and which is
-      -- not simply 'x'
-      list := kernels fcn
-      while not empty? list repeat
-        ker := first list
-        not is?(ker,"log" :: Symbol) and member?(x,variables(ker::FE)) _
-               and not(x = name(ker)) =>
-          return list
-        list := rest list
-      empty()
-
-    finiteValueAtInfinity?: Kernel FE -> Boolean
-    finiteValueAtInfinity? ker ==
-      is?(ker,"erf" :: Symbol) => true
-      is?(ker,"sech" :: Symbol) => true
-      is?(ker,"csch" :: Symbol) => true
-      is?(ker,"tanh" :: Symbol) => true
-      is?(ker,"coth" :: Symbol) => true
-      is?(ker,"atan" :: Symbol) => true
-      is?(ker,"acot" :: Symbol) => true
-      is?(ker,"asec" :: Symbol) => true
-      is?(ker,"acsc" :: Symbol) => true
-      is?(ker,"acsch" :: Symbol) => true
-      is?(ker,"acoth" :: Symbol) => true
-      false
-
-    knownValueAtInfinity?: Kernel FE -> Boolean
-    knownValueAtInfinity? ker ==
-      is?(ker,"exp" :: Symbol) => true
-      is?(ker,"sinh" :: Symbol) => true
-      is?(ker,"cosh" :: Symbol) => true
-      false
-
-    leftOrRight: (FE,SY,FE) -> SingleInteger
-    leftOrRight(fcn,x,limVal) ==
-      -- function is called when limitPlus(fcn,x) = limVal
-      -- determines whether the limiting value is approached
-      -- from the left or from the right
-      (value := limitPlus(inv(fcn - limVal),x)) case "failed" => 0
-      (inf := whatInfinity(val := value :: OFE)) = 0 =>
-         error "limit package: internal error"
-      inf
-
-    specialLimit1: (FE,SY) -> RESULT
-    specialLimitKernel: (Kernel FE,SY) -> RESULT
-    specialLimitNormalize: (FE,SY) -> RESULT
-    specialLimit: (FE, SY) -> RESULT
-
-    specialLimit(fcn, x) ==
-      xkers := [k for k in kernels fcn | member?(x,variables(k::FE))]
-      #xkers = 1 => specialLimit1(fcn,x)
-      num := numerator fcn
-      den := denominator fcn
-      for k in xkers repeat
-        (fval := limitPlus(k::FE,x)) case "failed" =>
-            return specialLimitNormalize(fcn,x)
-        whatInfinity(val := fval::OFE) ^= 0 =>
-            return specialLimitNormalize(fcn,x)
-        (valu := retractIfCan(val)@Union(FE,"failed")) case "failed" =>
-            return specialLimitNormalize(fcn,x)
-        finVal := valu :: FE
-        num := eval(num, k, finVal)
-        den := eval(den, k, finVal)
-        den = 0 => return specialLimitNormalize(fcn,x)
-      (num/den) :: OFE :: RESULT
-
-    specialLimitNormalize(fcn,x) == -- tries to normalize result first
-      nfcn := normalize(fcn)
-      fcn ^= nfcn => limitPlus(nfcn,x)
-      xkers := [k for k in tower fcn | member?(x,variables(k::FE))]
-      # xkers ^= 2 => "failed"
-      expKers := [k for k in xkers | is?(k, "exp" :: Symbol)]
-      # expKers ^= 1 => "failed"
-    -- fcn is a rational function of x and exp(g(x)) for some rational function g
-      expKer := first expKers
-      (fval := limitPlus(expKer::FE,x)) case "failed" => "failed"
-      vv := new()$SY; eq : EQ FE := equation(expKer :: FE,vv :: FE)
-      cc := eval(fcn,eq)
-      expKerLim := fval :: OFE
-        -- following test for "failed" is needed due to compiler bug
-        -- limVal case OFE generates EQCAR(limVal, 1) which fails on atom "failed"
-      (limVal := locallimit(cc,vv,expKerLim)) case "failed" => "failed"
-      limVal case OFE =>
-         limm := limVal :: OFE
-         (lim := retractIfCan(limm)@Union(FE,"failed")) case "failed" =>
-               "failed" -- need special handling for directions at infinity
-         limitPlus(lim, x)
-      "failed"
-
-    -- limit of expression having only 1 kernel involving x
-    specialLimit1(fcn,x) ==
-      -- find the first interesting kernel in tower(fcn)
-      xkers := [k for k in kernels fcn | member?(x,variables(k::FE))]
-      #xkers ^= 1 => "failed"
-      ker := first xkers
-      vv := new()$SY; eq : EQ FE := equation(ker :: FE,vv :: FE)
-      cc := eval(fcn,eq)
-      member?(x,variables cc) => "failed"
-      (lim := specialLimitKernel(ker, x)) case "failed" => lim
-      argLim : OFE := lim :: OFE
-      (limVal := locallimit(cc,vv,argLim)) case "failed" => "failed"
-      limVal case OFE => limVal :: OFE
-      "failed"
-
-    -- limit of single kernel involving x
-    specialLimitKernel(ker,x) ==
-      is?(ker,"log" :: Symbol) =>
-          args := argument ker
-          empty? args => "failed" -- error "No argument"
-          not empty? rest args => "failed" -- error "Too many arugments"
-          arg := first args
-          -- compute limit(x -> 0+,arg)
-          (limm := limitPlus(arg,x)) case "failed" => "failed"
-          lim := limm :: OFE
-          (inf := whatInfinity lim) = -1 => "failed"
-          argLim : OFE :=
-            -- log(+infinity) = +infinity
-            inf = 1 => lim
-            -- now 'lim' must be finite
-            (li := retractIfCan(lim)@Union(FE,"failed") :: FE) = 0 =>
-              -- log(0) = -infinity
-              leftOrRight(arg,x,0) = 1 => minusInfinity()
-              return "failed"
-            log(li) :: OFE
-      -- kernel should be a function of one argument f(arg)
-      args := argument(ker)
-      empty? args => "failed"  -- error "No argument"
-      not empty? rest args => "failed" -- error "Too many arugments"
-      arg := first args
-      -- compute limit(x -> 0+,arg)
-      (limm := limitPlus(arg,x)) case "failed" => "failed"
-      lim := limm :: OFE
-      f := elt(operator ker,(var := new()$SY) :: FE)
-      -- compute limit(x -> 0+,f(arg))
-      -- case where 'lim' is finite
-      (inf := whatInfinity lim) = 0 =>
-         is?(ker,"erf" :: Symbol) => erf(retract(lim)@FE)$LF(R,FE) :: OFE
-         (kerValue := locallimit(f,var,lim)) case "failed" => "failed"
-         kerValue case OFE => kerValue :: OFE
-         "failed"
-      -- case where 'lim' is plus infinity
-      inf = 1 =>
-        finiteValueAtInfinity? ker =>
-          val : FE :=
-            is?(ker,"erf" :: Symbol) => 1
-            is?(ker,"sech" :: Symbol) => 0
-            is?(ker,"csch" :: Symbol) => 0
-            is?(ker,"tanh" :: Symbol) => 0
-            is?(ker,"coth" :: Symbol) => 0
-            is?(ker,"atan" :: Symbol) => pi()/(2 :: FE)
-            is?(ker,"acot" :: Symbol) => 0
-            is?(ker,"asec" :: Symbol) => pi()/(2 :: FE)
-            is?(ker,"acsc" :: Symbol) => 0
-            is?(ker,"acsch" :: Symbol) => 0
-            -- ker must be acoth
-            0
-          val :: OFE
-        knownValueAtInfinity? ker =>
-          lim -- limit(exp, cosh, sinh ,x=inf) = inf
-        "failed"
-      -- case where 'lim' is minus infinity
-      finiteValueAtInfinity? ker =>
-        val : FE :=
-          is?(ker,"erf" :: Symbol) => -1
-          is?(ker,"sech" :: Symbol) => 0
-          is?(ker,"csch" :: Symbol) => 0
-          is?(ker,"tanh" :: Symbol) => 0
-          is?(ker,"coth" :: Symbol) => 0
-          is?(ker,"atan" :: Symbol) => -pi()/(2 :: FE)
-          is?(ker,"acot" :: Symbol) => pi()
-          is?(ker,"asec" :: Symbol) => -pi()/(2 :: FE)
-          is?(ker,"acsc" :: Symbol) => -pi()
-          is?(ker,"acsch" :: Symbol) => 0
-          -- ker must be acoth
-          0
-        val :: OFE
-      knownValueAtInfinity? ker =>
-        is?(ker,"exp" :: Symbol) => (0@FE) :: OFE
-        is?(ker,"sinh" :: Symbol) => lim
-        is?(ker,"cosh" :: Symbol) => plusInfinity()
-        "failed"
-      "failed"
-
-    logOnlyLimit: (FE,SY) -> RESULT
-    logOnlyLimit(coef,x) ==
-      -- this function is called when the 'constant' coefficient involves
-      -- the variable 'x'. Its purpose is to compute a right hand limit
-      -- of an expression involving log x. Here log x is replaced by -1/v,
-      -- where v is a new variable. If the new expression no longer involves
-      -- x, then take the right hand limit as v -> 0+
-      vv := new()$SY
-      eq : EQ FE := equation(log(x :: FE),-inv(vv :: FE))
-      member?(x,variables(cc := eval(coef,eq))) => "failed"
-      limitPlus(cc,vv)
-
-    locallimit(fcn,x,a) ==
-      -- Here 'fcn' is a function f(x) = f(x,...) in 'x' and possibly
-      -- other variables, and 'a' is a limiting value.  The function
-      -- computes lim(x -> a,f(x)).
-      xK := retract(x::FE)@Kernel(FE)
-      (n := whatInfinity a) = 0 =>
-        realLimit(localsubst(fcn,xK,1,retract(a)@FE),x)
-      (u := limitPlus(eval(fcn,xK,n * inv(xK::FE)),x))
-                                                case "failed" => "failed"
-      u::OFE
-
-    localsubst(fcn, k, n, a) ==
-      a = 0 and n = 1 => fcn
-      eval(fcn,k,n * (k::FE) + a)
-
-    locallimitcomplex(fcn,x,a) ==
-      xK := retract(x::FE)@Kernel(FE)
-      (g := retractIfCan(a)@Union(FE,"failed")) case FE =>
-        complLimit(localsubst(fcn,xK,1,g::FE),x)
-      complLimit(eval(fcn,xK,inv(xK::FE)),x)
-
-    limit(fcn,eq,str) ==
-      (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
-        error "limit:left hand side must be a variable"
-      x := xx :: SY; a := rhs eq
-      xK := retract(x::FE)@Kernel(FE)
-      limitPlus(localsubst(fcn,xK,direction str,a),x)
-
-    anyRootsOrAtrigs? fcn ==
-      -- determines if 'fcn' has any kernels which are roots
-      -- or if 'fcn' has any kernels which are inverse trig functions
-      -- which could produce series expansions with fractional exponents
-      for kernel in tower fcn repeat
-        is?(kernel,"nthRoot" :: Symbol) => return true
-        is?(kernel,"asin" :: Symbol) => return true
-        is?(kernel,"acos" :: Symbol) => return true
-        is?(kernel,"asec" :: Symbol) => return true
-        is?(kernel,"acsc" :: Symbol) => return true
-      false
-
-    complLimit(fcn,x) ==
-      -- computes lim(x -> 0,fcn) using a Puiseux expansion of fcn,
-      -- if fcn is an expression involving roots, and using a Laurent
-      -- expansion of fcn otherwise
-      lim : FE :=
-        anyRootsOrAtrigs? fcn =>
-          ppack := FS2UPS(R,FE,RN,_
-              UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
-              EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
-          pseries := exprToUPS(fcn,false,"complex")$ppack
-          pseries case %problem => return "failed"
-          if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
-          pole? upxs => return infinity()
-          coefficient(upxs,0)
-        lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
-                 EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
-        lseries := exprToUPS(fcn,false,"complex")$lpack
-        lseries case %problem => return "failed"
-        if pole?(uls := lseries.%series) then uls := map(normalize,uls)
-        pole? uls => return infinity()
-        coefficient(uls,0)
-      -- can the following happen?
-      member?(x,variables lim) =>
-        member?(x,variables(answer := normalize lim)) =>
-          error "limit: can't evaluate limit"
-        answer :: OPF
-      lim :: FE :: OPF
-
-    okProblem?(function,problem) ==
-      (function = "log") or (function = "nth root") =>
-        (problem = "series of non-zero order") or _
-               (problem = "negative leading coefficient")
-      (function = "atan") => problem = "branch problem"
-      (function = "erf") => problem = "unknown kernel"
-      problem = "essential singularity"
-
-    poleLimit(order,coef,x) ==
-      -- compute limit for function with pole
-      not member?(x,variables coef) =>
-        (s := sign(coef)$SIGNEF) case Integer =>
-          rtLim := (s :: Integer) * plusInfinity()
-          even? numer order => rtLim
-          even? denom order => ["failed",rtLim]$TwoSide
-          [-rtLim,rtLim]$TwoSide
-        -- infinite limit, but cannot determine sign
-        "failed"
-      error "limit: can't evaluate limit"
-
-    poleLimitPlus(order,coef,x) ==
-      -- compute right hand limit for function with pole
-      not member?(x,variables coef) =>
-        (s := sign(coef)$SIGNEF) case Integer =>
-          (s :: Integer) * plusInfinity()
-        -- infinite limit, but cannot determine sign
-        "failed"
-      (clim := specialLimit(coef,x)) case "failed" => "failed"
-      zero? (lim := clim :: OFE) =>
-        -- in this event, we need to determine if the limit of
-        -- the coef is 0+ or 0-
-        (cclim := specialLimit(inv coef,x)) case "failed" => "failed"
-        ss := whatInfinity(cclim :: OFE) :: Z
-        zero? ss =>
-          error "limit: internal error"
-        ss * plusInfinity()
-      t := whatInfinity(lim :: OFE) :: Z
-      zero? t =>
-        (tt := sign(coef)$SIGNEF) case Integer =>
-          (tt :: Integer) * plusInfinity()
-        -- infinite limit, but cannot determine sign
-        "failed"
-      t * plusInfinity()
-
-    realLimit(fcn,x) ==
-      -- computes lim(x -> 0,fcn) using a Puiseux expansion of fcn,
-      -- if fcn is an expression involving roots, and using a Laurent
-      -- expansion of fcn otherwise
-      lim : Union(FE,"failed") :=
-        anyRootsOrAtrigs? fcn =>
-          ppack := FS2UPS(R,FE,RN,_
-               UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
-               EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
-          pseries := exprToUPS(fcn,true,"real: two sides")$ppack
-          pseries case %problem =>
-            trouble := pseries.%problem
-            function := trouble.func; problem := trouble.prob
-            okProblem?(function,problem) =>
-              left :=
-                xK : Kernel FE := kernel x
-                fcn0 := eval(fcn,xK,-(xK :: FE))
-                limitPlus(fcn0,x)
-              right := limitPlus(fcn,x)
-              (left case "failed") and (right case "failed") =>
-                return "failed"
-              if (left case OFE) and (right case OFE) then
-                (left :: OFE) = (right :: OFE) => return (left :: OFE)
-              return([left,right]$TwoSide)
-            return "failed"
-          if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
-          pole? upxs =>
-            cp := coefficient(upxs,ordp := order upxs)
-            return poleLimit(ordp,cp,x)
-          coefficient(upxs,0)
-        lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
-                 EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
-        lseries := exprToUPS(fcn,true,"real: two sides")$lpack
-        lseries case %problem =>
-          trouble := lseries.%problem
-          function := trouble.func; problem := trouble.prob
-          okProblem?(function,problem) =>
-            left :=
-              xK : Kernel FE := kernel x
-              fcn0 := eval(fcn,xK,-(xK :: FE))
-              limitPlus(fcn0,x)
-            right := limitPlus(fcn,x)
-            (left case "failed") and (right case "failed") =>
-              return "failed"
-            if (left case OFE) and (right case OFE) then
-              (left :: OFE) = (right :: OFE) => return (left :: OFE)
-            return([left,right]$TwoSide)
-          return "failed"
-        if pole?(uls := lseries.%series) then uls := map(normalize,uls)
-        pole? uls =>
-          cl := coefficient(uls,ordl := order uls)
-          return poleLimit(ordl :: RN,cl,x)
-        coefficient(uls,0)
-      lim case "failed" => "failed"
-      member?(x,variables(lim :: FE)) =>
-        member?(x,variables(answer := normalize(lim :: FE))) =>
-          error "limit: can't evaluate limit"
-        answer :: OFE
-      lim :: FE :: OFE
-
-    xxpLimit(fcn,x) ==
-      -- computes lim(x -> 0+,fcn) using an exponential expansion of fcn
-      xpack := FS2EXPXP(R,FE,x,zeroFE)
-      xxp := exprToXXP(fcn,true)$xpack
-      xxp case %problem => "failed"
-      limitPlus(xxp.%expansion)
-
-    limitPlus(fcn,x) ==
-      -- computes lim(x -> 0+,fcn) using a generalized Puiseux expansion
-      -- of fcn, if fcn is an expression involving roots, and using a
-      -- generalized Laurent expansion of fcn otherwise
-      lim : Union(FE,"failed") :=
-        anyRootsOrAtrigs? fcn =>
-          ppack := FS2UPS(R,FE,RN,_
-               UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
-               EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
-          pseries := exprToGenUPS(fcn,true,"real: right side")$ppack
-          pseries case %problem =>
-            trouble := pseries.%problem
-            ff := trouble.func; pp := trouble.prob
-            (pp = "negative leading coefficient") => return "failed"
-            "failed"
-          -- pseries case %problem => return "failed"
-          if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
-          pole? upxs =>
-            cp := coefficient(upxs,ordp := order upxs)
-            return poleLimitPlus(ordp,cp,x)
-          coefficient(upxs,0)
-        lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
-                 EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
-        lseries := exprToGenUPS(fcn,true,"real: right side")$lpack
-        lseries case %problem =>
-          trouble := lseries.%problem
-          ff := trouble.func; pp := trouble.prob
-          (pp = "negative leading coefficient") => return "failed"
-          "failed"
-        -- lseries case %problem => return "failed"
-        if pole?(uls := lseries.%series) then uls := map(normalize,uls)
-        pole? uls =>
-          cl := coefficient(uls,ordl := order uls)
-          return poleLimitPlus(ordl :: RN,cl,x)
-        coefficient(uls,0)
-      lim case "failed" =>
-        (xLim := xxpLimit(fcn,x)) case "failed" => specialLimit(fcn,x)
-        xLim
-      member?(x,variables(lim :: FE)) =>
-        member?(x,variables(answer := normalize(lim :: FE))) =>
-          (xLim := xxpLimit(answer,x)) case "failed" => specialLimit(answer,x)
-          xLim
-        answer :: OFE
-      lim :: FE :: OFE
-
-    limit(fcn:FE,eq:EQ OFE) ==
-      (f := retractIfCan(lhs eq)@Union(FE,"failed")) case "failed" =>
-        error "limit:left hand side must be a variable"
-      (xx := retractIfCan(f)@Union(SY,"failed")) case "failed" =>
-        error "limit:left hand side must be a variable"
-      x := xx :: SY; a := rhs eq
-      locallimit(fcn,x,a)
-
-    complexLimit(fcn:FE,eq:EQ OPF) ==
-      (f := retractIfCan(lhs eq)@Union(FE,"failed")) case "failed" =>
-        error "limit:left hand side must be a variable"
-      (xx := retractIfCan(f)@Union(SY,"failed")) case "failed" =>
-        error "limit:left hand side must be a variable"
-      x := xx :: SY; a := rhs eq
-      locallimitcomplex(fcn,x,a)
-
-@
-\section{package SIGNEF ElementaryFunctionSign}
-<<package SIGNEF ElementaryFunctionSign>>=
-)abbrev package SIGNEF ElementaryFunctionSign
-++ Author: Manuel Bronstein
-++ Date Created: 25 Aug 1989
-++ Date Last Updated: 4 May 1992
-++ Basic Operations:
-++ Related Domains:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: elementary function, sign
-++ Examples:
-++ References:
-++ Description:
-++   This package provides functions to determine the sign of an
-++   elementary function around a point or infinity.
-ElementaryFunctionSign(R,F): Exports == Implementation where
-  R : Join(IntegralDomain,OrderedSet,RetractableTo Integer,_
-           LinearlyExplicitRingOver Integer,GcdDomain)
-  F : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
-            FunctionSpace R)
-
-  N  ==> NonNegativeInteger
-  Z  ==> Integer
-  SY ==> Symbol
-  RF ==> Fraction Polynomial R
-  ORF ==> OrderedCompletion RF
-  OFE ==> OrderedCompletion F
-  K  ==> Kernel F
-  P  ==> SparseMultivariatePolynomial(R, K)
-  U  ==> Union(Z, "failed")
-  FS2 ==> FunctionSpaceFunctions2
-  POSIT ==> "positive"
-  NEGAT ==> "negative"
-
-  Exports ==> with
-    sign: F -> U
-      ++ sign(f) returns the sign of f if it is constant everywhere.
-    sign: (F, SY, OFE) -> U
-      ++ sign(f, x, a) returns the sign of f as x nears \spad{a}, from both
-      ++ sides if \spad{a} is finite.
-    sign: (F, SY, F, String) -> U
-      ++ sign(f, x, a, s) returns the sign of f as x nears \spad{a} from below
-      ++ if s is "left", or above if s is "right".
-
-  Implementation ==> add
-    import ToolsForSign R
-    import RationalFunctionSign(R)
-    import PowerSeriesLimitPackage(R, F)
-    import TrigonometricManipulations(R, F)
-
-    smpsign : P -> U
-    sqfrSign: P -> U
-    termSign: P -> U
-    kerSign : K -> U
-    listSign: (List P,Z) -> U
-    insign  : (F,SY,OFE, N) -> U
-    psign   : (F,SY,F,String, N) -> U
-    ofesign : OFE -> U
-    overRF  : OFE -> Union(ORF, "failed")
-
-    sign(f, x, a) ==
-      not real? f => "failed"
-      insign(f, x, a, 0)
-
-    sign(f, x, a, st) ==
-      not real? f => "failed"
-      psign(f, x, a, st, 0)
-
-    sign f ==
-      not real? f => "failed"
-      (u := retractIfCan(f)@Union(RF,"failed")) case RF => sign(u::RF)
-      (un := smpsign numer f) case Z and (ud := smpsign denom f) case Z =>
-        un::Z * ud::Z
-      --abort if there are any variables
-      not empty? variables f => "failed"
-      -- abort in the presence of algebraic numbers
-      member?(coerce("rootOf")::Symbol,map(name,operators f)$ListFunctions2(BasicOperator,Symbol)) => "failed"
-      -- In the last resort try interval evaluation where feasible.
-      if R has ConvertibleTo Float then
-        import Interval(Float)
-        import Expression(Interval Float)
-        mapfun : (R -> Interval(Float)) := interval(convert(#1)$R)
-        f2 : Expression(Interval Float) := map(mapfun,f)$FS2(R,F,Interval(Float),Expression(Interval Float))
-        r : Union(Interval(Float),"failed") := retractIfCan f2
-        if r case "failed" then  return "failed"
-        negative? r => return(-1)
-        positive? r => return 1
-        zero? r => return 0
-        "failed"
-      "failed"
-
-    overRF a ==
-      (n := whatInfinity a) = 0 =>
-        (u := retractIfCan(retract(a)@F)@Union(RF,"failed")) _
-               case "failed" => "failed"
-        u::RF::ORF
-      n * plusInfinity()$ORF
-
-    ofesign a ==
-      (n := whatInfinity a) ^= 0 => convert(n)@Z
-      sign(retract(a)@F)
-
-    insign(f, x, a, m) ==
-      m > 10 => "failed"                 -- avoid infinite loops for now
-      (uf := retractIfCan(f)@Union(RF,"failed")) case RF and
-                   (ua := overRF a) case ORF => sign(uf::RF, x, ua::ORF)
-      eq : Equation OFE := equation(x :: F :: OFE,a)
-      (u := limit(f,eq)) case "failed" => "failed"
-      u case OFE =>
-        (n := whatInfinity(u::OFE)) ^= 0 => convert(n)@Z
-        (v := retract(u::OFE)@F) = 0 =>
-          (s := insign(differentiate(f, x), x, a, m + 1)) case "failed"
-                                                             => "failed"
-          - s::Z * n
-        sign v
-      (u.leftHandLimit case "failed") or
-         (u.rightHandLimit case "failed") => "failed"
-      (ul := ofesign(u.leftHandLimit::OFE))  case "failed" => "failed"
-      (ur := ofesign(u.rightHandLimit::OFE)) case "failed" => "failed"
-      (ul::Z) = (ur::Z) => ul
-      "failed"
-
-    psign(f, x, a, st, m) ==
-      m > 10 => "failed"                 -- avoid infinite loops for now
-      f = 0 => 0
-      (uf := retractIfCan(f)@Union(RF,"failed")) case RF and
-           (ua := retractIfCan(a)@Union(RF,"failed")) case RF =>
-            sign(uf::RF, x, ua::RF, st)
-      eq : Equation F := equation(x :: F,a)
-      (u := limit(f,eq,st)) case "failed" => "failed"
-      u case OFE =>
-        (n := whatInfinity(u::OFE)) ^= 0 => convert(n)@Z
-        (v := retract(u::OFE)@F) = 0 =>
-          (s := psign(differentiate(f,x),x,a,st,m + 1)) case "failed"=>
-            "failed"
-          direction(st) * s::Z
-        sign v
-
-    smpsign p ==
-      (r := retractIfCan(p)@Union(R,"failed")) case R => sign(r::R)
-      (u := sign(retract(unit(s := squareFree p))@R)) case "failed" =>
-        "failed"
-      ans := u::Z
-      for term in factorList s | odd?(term.xpnt) repeat
-        (u := sqfrSign(term.fctr)) case "failed" => return "failed"
-        ans := ans * u::Z
-      ans
-
-    sqfrSign p ==
-      (u := termSign first(l := monomials p)) case "failed" => "failed"
-      listSign(rest l, u::Z)
-
-    listSign(l, s) ==
-      for term in l repeat
-        (u := termSign term) case "failed" => return "failed"
-        not(s = u::Z) => return "failed"
-      s
-
-    termSign term ==
-      (us := sign leadingCoefficient term) case "failed" => "failed"
-      for var in (lv := variables term) repeat
-        odd? degree(term, var) =>
-          empty? rest lv and (vs := kerSign first lv) case Z =>
-                                                   return(us::Z * vs::Z)
-          return "failed"
-      us::Z
-
-    kerSign k ==
-      has?(op := operator k, "NEGAT") => -1
-      has?(op, "POSIT") or is?(op,  "pi"::SY) or is?(op,"exp"::SY) or
-                           is?(op,"cosh"::SY) or is?(op,"sech"::SY) => 1
-      empty?(arg := argument k) => "failed"
-      (s := sign first arg) case "failed" =>
-        is?(op,"nthRoot" :: SY) =>
-          even?(retract(second arg)@Z) => 1
-          "failed"
-        "failed"
-      is?(op,"log" :: SY) =>
-        s::Z < 0 => "failed"
-        sign(first arg - 1)
-      is?(op,"tanh" :: SY) or is?(op,"sinh" :: SY) or
-                     is?(op,"csch" :: SY) or is?(op,"coth" :: SY) => s
-      is?(op,"nthRoot" :: SY) =>
-        even?(retract(second arg)@Z) =>
-          s::Z < 0 => "failed"
-          s
-        s
-      "failed"
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LIMITPS PowerSeriesLimitPackage>>
-<<package SIGNEF ElementaryFunctionSign>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/lindep.spad.pamphlet b/src/algebra/lindep.spad.pamphlet
deleted file mode 100644
index 1aa4795..0000000
--- a/src/algebra/lindep.spad.pamphlet
+++ /dev/null
@@ -1,326 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra lindep.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LINDEP LinearDependence}
-<<package LINDEP LinearDependence>>=
-)abbrev package LINDEP LinearDependence
-++ Test for linear dependence
-++ Author: Manuel Bronstein
-++ Date Created: ???
-++ Date Last Updated: 14 May 1991
-++ Description: Test for linear dependence.
-LinearDependence(S, R): Exports == Implementation where
-  S: IntegralDomain
-  R: LinearlyExplicitRingOver S
-
-  Q ==> Fraction S
-
-  Exports ==> with
-    linearlyDependent?: Vector R -> Boolean
-      ++ \spad{linearlyDependent?([v1,...,vn])} returns true if
-      ++ the vi's are linearly dependent over S, false otherwise.
-    linearDependence  : Vector R -> Union(Vector S, "failed")
-      ++ \spad{linearDependence([v1,...,vn])} returns \spad{[c1,...,cn]} if
-      ++ \spad{c1*v1 + ... + cn*vn = 0} and not all the ci's are 0,
-      ++ "failed" if the vi's are linearly independent over S.
-    if S has Field then
-      solveLinear: (Vector R, R) -> Union(Vector S, "failed")
-        ++ \spad{solveLinear([v1,...,vn], u)} returns \spad{[c1,...,cn]}
-        ++ such that \spad{c1*v1 + ... + cn*vn = u},
-        ++ "failed" if no such ci's exist in S.
-    else
-      solveLinear: (Vector R, R) -> Union(Vector Q, "failed")
-        ++ \spad{solveLinear([v1,...,vn], u)} returns \spad{[c1,...,cn]}
-        ++ such that \spad{c1*v1 + ... + cn*vn = u},
-        ++ "failed" if no such ci's exist in the quotient field of S.
-
-  Implementation ==> add
-    aNonZeroSolution: Matrix S -> Union(Vector S, "failed")
-
-    aNonZeroSolution m ==
-      every?(zero?, v := first nullSpace m) => "failed"
-      v
-
-    linearlyDependent? v ==
-      zero?(n := #v) => true
---      one? n => zero?(v(minIndex v))
-      (n = 1) => zero?(v(minIndex v))
-      positive? nullity reducedSystem transpose v
-
-    linearDependence v ==
-      zero?(n := #v) => empty()
---      one? n =>
-      (n = 1) =>
-        zero?(v(minIndex v)) => new(1, 1)
-        "failed"
-      aNonZeroSolution reducedSystem transpose v
-
-    if S has Field then
-      solveLinear(v:Vector R, c:R):Union(Vector S, "failed") ==
-        zero? c => new(#v, 0)
-        empty? v => "failed"
-        sys := reducedSystem(transpose v, new(1, c))
-        particularSolution(sys.mat, sys.vec)$LinearSystemMatrixPackage(S,
-                                           Vector S, Vector S, Matrix S)
-
-    else
-      solveLinear(v:Vector R, c:R):Union(Vector Q, "failed") ==
-        zero? c => new(#v, 0)
-        empty? v => "failed"
-        sys := reducedSystem(transpose v, new(1, c))
-        particularSolution(map(#1::Q, sys.mat)$MatrixCategoryFunctions2(S,
-               Vector S,Vector S,Matrix S,Q,Vector Q,Vector Q,Matrix Q),
-                  map(#1::Q, sys.vec)$VectorFunctions2(S, Q)
-                                    )$LinearSystemMatrixPackage(Q,
-                                           Vector Q, Vector Q, Matrix Q)
-
-@
-\section{package ZLINDEP IntegerLinearDependence}
-<<IntegerLinearDependence.input>>=
--- lindep.spad.pamphlet IntegerLinearDependence.input
-)spool IntegerLinearDependence.output
-)set message test on
-)set message auto off
-)clear all
---S 1
-M := SQMATRIX(2,INT)
---R 
---R
---R   (1)  SquareMatrix(2,Integer)
---R                                                                 Type: Domain
---E 1
-
---S 2
-m1: M := squareMatrix matrix [ [1, 2], [0, -1] ]
---R 
---R
---R        +1   2 +
---R   (2)  |      |
---R        +0  - 1+
---R                                                Type: SquareMatrix(2,Integer)
---E 2
-
---S 3
-m2: M := squareMatrix matrix [ [2, 3], [1, -2] ]
---R 
---R
---R        +2   3 +
---R   (3)  |      |
---R        +1  - 2+
---R                                                Type: SquareMatrix(2,Integer)
---E 3
-
---S 4
-m3: M := squareMatrix matrix [ [3, 4], [2, -3] ]
---R 
---R
---R        +3   4 +
---R   (4)  |      |
---R        +2  - 3+
---R                                                Type: SquareMatrix(2,Integer)
---E 4
-
---S 5
-linearlyDependentOverZ? vector [m1, m2, m3]
---R 
---R
---R   (5)  true
---R                                                                Type: Boolean
---E 5
-
---S 6
-c := linearDependenceOverZ vector [m1, m2, m3]
---R 
---R
---R   (6)  [1,- 2,1]
---R                                              Type: Union(Vector Integer,...)
---E 6
-
---S 7
-c.1 * m1 + c.2 * m2 + c.3 * m3
---R 
---R
---R        +0  0+
---R   (7)  |    |
---R        +0  0+
---R                                                Type: SquareMatrix(2,Integer)
---E 7
-
---S 8
-solveLinearlyOverQ(vector [m1, m3], m2)
---R 
---R
---R         1 1
---R   (8)  [-,-]
---R         2 2
---R                                     Type: Union(Vector Fraction Integer,...)
---E 8
-)spool
-)lisp (bye)
-@
-<<IntegerLinearDependence.help>>=
-====================================================================
-IntegerLinearDependence examples
-====================================================================
-
-The elements v1,...,vN of a module M over a ring R are said to be 
-linearly dependent over R if there exist c1,...,cN in R, not all 0, 
-such that c1 v1 + ...  cN vNn = 0.  If such ci's exist, they form 
-what is called a linear dependence relation over R for the vi's.
-
-The package IntegerLinearDependence provides functions for testing
-whether some elements of a module over the integers are linearly
-dependent over the integers, and to find the linear dependence
-relations, if any.
-
-Consider the domain of two by two square matrices with integer entries.
-
-  M := SQMATRIX(2,INT)
-    SquareMatrix(2,Integer)
-                      Type: Domain
-
-Now create three such matrices.
-
-  m1: M := squareMatrix matrix [ [1, 2], [0, -1] ]
-     +1   2 +
-     |      |
-     +0  - 1+
-                      Type: SquareMatrix(2,Integer)
-
-  m2: M := squareMatrix matrix [ [2, 3], [1, -2] ]
-    +2   3 +
-    |      |
-    +1  - 2+
-                      Type: SquareMatrix(2,Integer)
-
-  m3: M := squareMatrix matrix [ [3, 4], [2, -3] ]
-    +3   4 +
-    |      |
-    +2  - 3+
-                      Type: SquareMatrix(2,Integer)
-
-This tells you whether m1, m2 and m3 are linearly dependent over the integers.
-
-  linearlyDependentOverZ? vector [m1, m2, m3]
-    true
-                      Type: Boolean
-
-Since they are linearly dependent, you can ask for the dependence relation.
-
-  c := linearDependenceOverZ vector [m1, m2, m3]
-    [1,- 2,1]
-                      Type: Union(Vector Integer,...)
-
-This means that the following linear combination should be 0.
-
-  c.1 * m1 + c.2 * m2 + c.3 * m3
-    +0  0+
-    |    |
-    +0  0+
-                      Type: SquareMatrix(2,Integer)
-
-When a given set of elements are linearly dependent over R, this also 
-means that at least one of them can be rewritten as a linear combination 
-of the others with coefficients in the quotient field of R.
-
-To express a given element in terms of other elements, use the operation
-solveLinearlyOverQ.
-
-  solveLinearlyOverQ(vector [m1, m3], m2)
-     1 1
-    [-,-]
-     2 2
-                      Type: Union(Vector Fraction Integer,...)
-
-See Also:
-o )show IntegerLinearDependence
-o $AXIOM/doc/src/algebra/lindep.spad.dvi
-
-@
-<<package ZLINDEP IntegerLinearDependence>>=
-)abbrev package ZLINDEP IntegerLinearDependence
-++ Test for linear dependence over the integers
-++ Author: Manuel Bronstein
-++ Date Created: ???
-++ Date Last Updated: 14 May 1991
-++ Description: Test for linear dependence over the integers.
-IntegerLinearDependence(R): Exports == Implementation where
-  R: LinearlyExplicitRingOver Integer
-
-  Z ==> Integer
-
-  Exports ==> with
-    linearlyDependentOverZ?: Vector R -> Boolean
-      ++ \spad{linearlyDependentOverZ?([v1,...,vn])} returns true if the
-      ++ vi's are linearly dependent over the integers, false otherwise.
-    linearDependenceOverZ  : Vector R -> Union(Vector Z, "failed")
-      ++ \spad{linearlyDependenceOverZ([v1,...,vn])} returns
-      ++ \spad{[c1,...,cn]} if
-      ++ \spad{c1*v1 + ... + cn*vn = 0} and not all the ci's are 0, "failed"
-      ++ if the vi's are linearly independent over the integers.
-    solveLinearlyOverQ     : (Vector R, R) ->
-                                      Union(Vector Fraction Z, "failed")
-      ++ \spad{solveLinearlyOverQ([v1,...,vn], u)} returns \spad{[c1,...,cn]}
-      ++ such that \spad{c1*v1 + ... + cn*vn = u},
-      ++ "failed" if no such rational numbers ci's exist.
-
-  Implementation ==> add
-    import LinearDependence(Z, R)
-
-    linearlyDependentOverZ? v == linearlyDependent? v
-    linearDependenceOverZ   v == linearDependence v
-    solveLinearlyOverQ(v, c)  == solveLinear(v, c)
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LINDEP LinearDependence>>
-<<package ZLINDEP IntegerLinearDependence>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/lingrob.spad.pamphlet b/src/algebra/lingrob.spad.pamphlet
deleted file mode 100644
index 29e2b34..0000000
--- a/src/algebra/lingrob.spad.pamphlet
+++ /dev/null
@@ -1,362 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra lingrob.spad}
-\author{The Axiom Team}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LGROBP LinGroebnerPackage}
-<<package LGROBP LinGroebnerPackage>>=
-)abbrev package LGROBP LinGroebnerPackage
-++  Given a Groebner basis B with respect to the total degree ordering for
-++  a zero-dimensional ideal I, compute
-++  a Groebner basis with respect to the lexicographical ordering by using
-++  linear algebra.
-LinGroebnerPackage(lv,F) : C == T
-
- where
-  Z      ==>  Integer
-  lv     :    List Symbol
-  F      :    GcdDomain
-
-  DP     ==>  DirectProduct(#lv,NonNegativeInteger)
-  DPoly  ==>  DistributedMultivariatePolynomial(lv,F)
-
-  HDP    ==>  HomogeneousDirectProduct(#lv,NonNegativeInteger)
-  HDPoly ==>  HomogeneousDistributedMultivariatePolynomial(lv,F)
-
-  OV     ==>  OrderedVariableList(lv)
-  NNI    ==>  NonNegativeInteger
-  LVals  ==>  Record(gblist : List DPoly,gvlist : List Z)
-  VF     ==>  Vector F
-  VV     ==>  Vector NNI
-  MF     ==>  Matrix F
-  cLVars ==>  Record(glbase:List DPoly,glval:List Z)
-
-  C == with
-
-     linGenPos    :           List HDPoly      -> LVals
-	++ linGenPos \undocumented
-     groebgen     :           List DPoly       -> cLVars
-	++ groebgen \undocumented
-     totolex      :           List HDPoly      -> List DPoly
-	++ totolex \undocumented
-     minPol       : (List HDPoly,List HDPoly,OV) -> HDPoly
-	++ minPol \undocumented
-     minPol       :        (List HDPoly,OV)     -> HDPoly
-	++ minPol \undocumented
-
-
-     computeBasis :        List HDPoly           -> List HDPoly
-	++ computeBasis \undocumented
-     coord        : (HDPoly,List HDPoly)         -> VF
-	++ coord \undocumented
-     anticoord    : (List F,DPoly,List DPoly)    -> DPoly
-	++ anticoord \undocumented
-     intcompBasis : (OV,List HDPoly,List HDPoly) -> List HDPoly
-	++ intcompBasis \undocumented
-     choosemon    :     (DPoly,List  DPoly)      -> DPoly
-	++ choosemon \undocumented
-     transform    :           DPoly              -> HDPoly
-	++ transform \undocumented
-
-
-  T == add
-
-    import GroebnerPackage(F,DP,OV,DPoly)
-    import GroebnerPackage(F,HDP,OV,HDPoly)
-    import GroebnerInternalPackage(F,HDP,OV,HDPoly)
-    import GroebnerInternalPackage(F,DP,OV,DPoly)
-
-    lvar :=[variable(yx)::OV for yx in lv]
-
-    reduceRow(M:MF, v : VF, lastRow: Integer, pivots: Vector(Integer)) : VF ==
-      a1:F := 1
-      b:F := 0
-      dim := #v
-      for j in 1..lastRow repeat -- scan over rows
-         mj := row(M,j)
-         k:=pivots(j)
-         b:=mj.k
-         vk := v.k
-         for kk in 1..(k-1) repeat
-            v(kk) := ((-b*v(kk)) exquo a1) :: F
-         for kk in k..dim repeat
-            v(kk) := ((vk*mj(kk)-b*v(kk)) exquo a1)::F
-         a1 := b
-      v
-
-    rRedPol(f:HDPoly, B:List HDPoly):Record(poly:HDPoly, mult:F) ==
-      gm := redPo(f,B)
-      gm.poly = 0 => gm
-      gg := reductum(gm.poly)
-      ggm := rRedPol(gg,B)
-      [ggm.mult*(gm.poly - gg) + ggm.poly, ggm.mult*gm.mult]
-
------ transform the total basis B in lex basis -----
-    totolex(B : List HDPoly) : List DPoly ==
-      result:List DPoly :=[]
-      ltresult:List DPoly :=[]
-      vBasis:= computeBasis B
-      nBasis:List DPoly :=[1$DPoly]
-      ndim:=(#vBasis)::PositiveInteger
-      ndim1:NNI:=ndim+1
-      lm:VF
-      linmat:MF:=zero(ndim,2*ndim+1)
-      linmat(1,1):=1$F
-      linmat(1,ndim1):=1
-      pivots:Vector Integer := new(ndim,0)
-      pivots(1) := 1
-      firstmon:DPoly:=1$DPoly
-      ofirstmon:DPoly:=1$DPoly
-      orecfmon:Record(poly:HDPoly, mult:F) := [1,1]
-      i:NNI:=2
-      while (firstmon:=choosemon(firstmon,ltresult))^=1 repeat
-        if (v:=firstmon exquo ofirstmon) case "failed" then
-          recfmon:=rRedPol(transform firstmon,B)
-        else
-          recfmon:=rRedPol(transform(v::DPoly) *orecfmon.poly,B)
-          recfmon.mult := recfmon.mult * orecfmon.mult
-        cc := gcd(content recfmon.poly, recfmon.mult)
-        recfmon.poly := (recfmon.poly exquo cc)::HDPoly
-        recfmon.mult := (recfmon.mult exquo cc)::F
-        veccoef:VF:=coord(recfmon.poly,vBasis)
-        ofirstmon:=firstmon
-        orecfmon := recfmon
-        lm:=zero(2*ndim+1)
-        for j in 1..ndim repeat lm(j):=veccoef(j)
-        lm(ndim+i):=recfmon.mult
-        lm := reduceRow(linmat, lm, i-1, pivots)
-        if i=ndim1 then j:=ndim1
-        else
-          j:=1
-          while lm(j) = 0 and j< ndim1 repeat j:=j+1
-        if j=ndim1 then
-          cordlist:List F:=[lm(k) for k in ndim1..ndim1+(#nBasis)]
-          antc:=+/[c*b for c in reverse cordlist
-                       for b in concat(firstmon,nBasis)]
-          antc:=primitivePart antc
-          result:=concat(antc,result)
-          ltresult:=concat(antc-reductum antc,ltresult)
-        else
-          pivots(i) := j
-          setRow_!(linmat,i,lm)
-          i:=i+1
-          nBasis:=cons(firstmon,nBasis)
-      result
-
----- Compute the univariate polynomial for x
-----oldBasis is a total degree Groebner basis
-    minPol(oldBasis:List HDPoly,x:OV) :HDPoly ==
-      algBasis:= computeBasis oldBasis
-      minPol(oldBasis,algBasis,x)
-
----- Compute the univariate polynomial for x
----- oldBasis is total Groebner, algBasis is the basis as algebra
-    minPol(oldBasis:List HDPoly,algBasis:List HDPoly,x:OV) :HDPoly ==
-      nvp:HDPoly:=x::HDPoly
-      f:=1$HDPoly
-      omult:F :=1
-      ndim:=(#algBasis)::PositiveInteger
-      ndim1:NNI:=ndim+1
-      lm:VF
-      linmat:MF:=zero(ndim,2*ndim+1)
-      linmat(1,1):=1$F
-      linmat(1,ndim1):=1
-      pivots:Vector Integer := new(ndim,0)
-      pivots(1) := 1
-      for i in 2..ndim1 repeat
-        recf:=rRedPol(f*nvp,oldBasis)
-        omult := recf.mult * omult
-        f := recf.poly
-        cc := gcd(content f, omult)
-        f := (f exquo cc)::HDPoly
-        omult := (omult exquo cc)::F
-        veccoef:VF:=coord(f,algBasis)
-        lm:=zero(2*ndim+1)
-        for j in 1..ndim repeat lm(j) := veccoef(j)
-        lm(ndim+i):=omult
-        lm := reduceRow(linmat, lm, i-1, pivots)
-        j:=1
-        while lm(j)=0 and j<ndim1 repeat j:=j+1
-        if j=ndim1 then return
-          g:HDPoly:=0
-          for k in ndim1..2*ndim+1 repeat
-            g:=g+lm(k) * nvp**((k-ndim1):NNI)
-          primitivePart g
-        pivots(i) := j
-        setRow_!(linmat,i,lm)
-
------ transform a DPoly in a HDPoly -----
-    transform(dpol:DPoly) : HDPoly ==
-      dpol=0 => 0$HDPoly
-      monomial(leadingCoefficient dpol,
-               directProduct(degree(dpol)::VV)$HDP)$HDPoly +
-                                      transform(reductum dpol)
-
------ compute the basis for the vector space determined by B -----
-    computeBasis(B:List HDPoly) : List HDPoly ==
-      mB:List HDPoly:=[monomial(1$F,degree f)$HDPoly for f in B]
-      result:List HDPoly := [1$HDPoly]
-      for var in lvar repeat
-        part:=intcompBasis(var,result,mB)
-        result:=concat(result,part)
-      result
-
------ internal function for computeBasis -----
-    intcompBasis(x:OV,lr:List HDPoly,mB : List HDPoly):List HDPoly ==
-      lr=[] => lr
-      part:List HDPoly :=[]
-      for f in lr repeat
-        g:=x::HDPoly * f
-        if redPo(g,mB).poly^=0 then part:=concat(g,part)
-      concat(part,intcompBasis(x,part,mB))
-
------ coordinate of f with respect to the basis B -----
------ f is a reduced polynomial -----
-    coord(f:HDPoly,B:List HDPoly) : VF ==
-      ndim := #B
-      vv:VF:=new(ndim,0$F)$VF
-      while f^=0 repeat
-        rf := reductum f
-        lf := f-rf
-        lcf := leadingCoefficient f
-        i:Z:=position(monomial(1$F,degree lf),B)
-        vv.i:=lcf
-        f := rf
-      vv
-
------ reconstruct the polynomial from its coordinate -----
-    anticoord(vv:List F,mf:DPoly,B:List DPoly) : DPoly ==
-      for f in B for c in vv repeat (mf:=mf-c*f)
-      mf
-
------ choose the next monom -----
-    choosemon(mf:DPoly,nB:List DPoly) : DPoly ==
-      nB = [] => ((lvar.last)::DPoly)*mf
-      for x in reverse lvar repeat
-        xx:=x ::DPoly
-        mf:=xx*mf
-        if redPo(mf,nB).poly ^= 0 then return mf
-        dx := degree(mf,x)
-        mf := (mf exquo (xx ** dx))::DPoly
-      mf
-
------ put B in general position, B is Groebner -----
-    linGenPos(B : List HDPoly) : LVals ==
-      result:List DPoly :=[]
-      ltresult:List DPoly :=[]
-      vBasis:= computeBasis B
-      nBasis:List DPoly :=[1$DPoly]
-      ndim:=#vBasis : PositiveInteger
-      ndim1:NNI:=ndim+1
-      lm:VF
-      linmat:MF:=zero(ndim,2*ndim+1)
-      linmat(1,1):=1$F
-      linmat(1,ndim1):=1
-      pivots:Vector Integer := new(ndim,0)
-      pivots(1) := 1
-      i:NNI:=2
-      rval:List Z :=[]
-      for ii in 1..(#lvar-1) repeat
-        c:Z:=0
-        while c=0 repeat c:=random()$Z rem 11
-        rval:=concat(c,rval)
-      nval:DPoly := (last.lvar)::DPoly -
-                (+/[r*(vv)::DPoly for r in rval for vv in lvar])
-      firstmon:DPoly:=1$DPoly
-      ofirstmon:DPoly:=1$DPoly
-      orecfmon:Record(poly:HDPoly, mult:F) := [1,1]
-      lx:= lvar.last
-      while (firstmon:=choosemon(firstmon,ltresult))^=1 repeat
-        if (v:=firstmon exquo ofirstmon) case "failed" then
-          recfmon:=rRedPol(transform(eval(firstmon,lx,nval)),B)
-        else
-          recfmon:=rRedPol(transform(eval(v,lx,nval))*orecfmon.poly,B)
-          recfmon.mult := recfmon.mult * orecfmon.mult
-        cc := gcd(content recfmon.poly, recfmon.mult)
-        recfmon.poly := (recfmon.poly exquo cc)::HDPoly
-        recfmon.mult := (recfmon.mult exquo cc)::F
-        veccoef:VF:=coord(recfmon.poly,vBasis)
-        ofirstmon:=firstmon
-        orecfmon := recfmon
-        lm:=zero(2*ndim+1)
-        for j in 1..ndim repeat lm(j):=veccoef(j)
-        lm(ndim+i):=recfmon.mult
-        lm := reduceRow(linmat, lm, i-1, pivots)
-        j:=1
-        while lm(j) = 0 and j<ndim1 repeat j:=j+1
-        if j=ndim1 then
-          cordlist:List F:=[lm(j) for j in ndim1..ndim1+(#nBasis)]
-          antc:=+/[c*b for c in reverse cordlist
-                       for b in concat(firstmon,nBasis)]
-          result:=concat(primitivePart antc,result)
-          ltresult:=concat(antc-reductum antc,ltresult)
-        else
-          pivots(i) := j
-          setRow_!(linmat,i,lm)
-          i:=i+1
-          nBasis:=concat(firstmon,nBasis)
-      [result,rval]$LVals
-
------ given a basis of a zero-dimensional ideal,
------ performs a random change of coordinates
------ computes a Groebner basis for the lex ordering
-    groebgen(L:List DPoly) : cLVars ==
-      xn:=lvar.last
-      val := xn::DPoly
-      nvar1:NNI:=(#lvar-1):NNI
-      ll: List Z :=[random()$Z rem 11 for i in 1..nvar1]
-      val:=val+ +/[ll.i*(lvar.i)::DPoly for i in 1..nvar1]
-      LL:=[elt(univariate(f,xn),val) for f in L]
-      LL:=  groebner(LL)
-      [LL,ll]$cLVars
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LGROBP LinGroebnerPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/liouv.spad.pamphlet b/src/algebra/liouv.spad.pamphlet
deleted file mode 100644
index 6be5415..0000000
--- a/src/algebra/liouv.spad.pamphlet
+++ /dev/null
@@ -1,246 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra liouv.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LF LiouvillianFunction}
-<<package LF LiouvillianFunction>>=
-)abbrev package LF LiouvillianFunction
-++ Author: Manuel Bronstein
-++ Date Created: 1987
-++ Date Last Updated: 10 August 1994
-++ Keywords: liouvillian, function, primitive, exponential.
-++ Examples:  )r LF INPUT
-++ Description:
-++   This package provides liouvillian functions over an integral domain.
-LiouvillianFunction(R, F): Exports == Implementation where
-  R:Join(OrderedSet, IntegralDomain)
-  F:Join(FunctionSpace R,RadicalCategory,TranscendentalFunctionCategory)
-
-  OP  ==> BasicOperator
-  PR  ==> Polynomial R
-  K   ==> Kernel F
-  SE  ==> Symbol
-  O   ==> OutputForm
-  INP ==> InputForm
-  INV ==> error "Invalid argument"
-
-  SPECIALDIFF ==> "%specialDiff"
-  SPECIALDISP ==> "%specialDisp"
-  SPECIALINPUT ==> "%specialInput"
-  SPECIALEQUAL ==> "%specialEqual"
-
-  Exports ==> with
-    belong? : OP -> Boolean
-      ++ belong?(op) checks if op is Liouvillian
-    operator: OP -> OP
-      ++ operator(op) returns the Liouvillian operator based on op
-    Ei      : F  -> F
-      ++ Ei(f) denotes the exponential integral
-    Si      : F  -> F
-      ++ Si(f) denotes the sine integral
-    Ci      : F  -> F
-      ++ Ci(f) denotes the cosine integral
-    li      : F  -> F
-      ++ li(f) denotes the logarithmic integral
-    erf     : F  -> F
-      ++ erf(f) denotes the error function
-    dilog   : F  -> F
-      ++ dilog(f) denotes the dilogarithm
-    integral: (F, SE) -> F
-      ++ integral(f,x) indefinite integral of f with respect to x.
-    integral: (F, SegmentBinding F) -> F
-      ++ integral(f,x = a..b) denotes the definite integral of f with
-      ++ respect to x from \spad{a} to b.
-
-  Implementation ==> add
-    iei        : F  -> F
-    isi        : F  -> F
-    ici        : F  -> F
-    ierf       : F  -> F
-    ili        : F  -> F
-    ili2       : F  -> F
-    iint       : List F -> F
-    eqint      : (K,K) -> Boolean
-    dvint      : (List F, SE) -> F
-    dvdint     : (List F, SE) -> F
-    ddint      : List F -> O
-    integrand  : List F -> F
-
-    dummy := new()$SE :: F
-
-    opint  := operator("integral"::Symbol)$CommonOperators
-    opdint := operator("%defint"::Symbol)$CommonOperators
-    opei   := operator("Ei"::Symbol)$CommonOperators
-    opli   := operator("li"::Symbol)$CommonOperators
-    opsi   := operator("Si"::Symbol)$CommonOperators
-    opci   := operator("Ci"::Symbol)$CommonOperators
-    opli2  := operator("dilog"::Symbol)$CommonOperators
-    operf  := operator("erf"::Symbol)$CommonOperators
-
-    Si x                == opsi x
-    Ci x                == opci x
-    Ei x                == opei x
-    erf x               == operf x
-    li  x               == opli x
-    dilog x             == opli2 x
-
-    belong? op     == has?(op, "prim")
-    isi x          == kernel(opsi, x)
-    ici x          == kernel(opci, x)
-    ierf x         == (zero? x => 0; kernel(operf, x))
---    ili2 x         == (one? x => INV; kernel(opli2, x))
-    ili2 x         == ((x = 1) => INV; kernel(opli2, x))
-    integrand l    == eval(first l, retract(second l)@K, third l)
-    integral(f:F, x:SE) == opint [eval(f, k:=kernel(x)$K, dummy), dummy, k::F]
-
-    iint l ==
-      zero? first l => 0
-      kernel(opint, l)
-
-    ddint l ==
-      int(integrand(l)::O * hconcat("d"::SE::O, third(l)::O),
-                                    third(rest l)::O, third(rest rest l)::O)
-
-    eqint(k1,k2) == 
-      a1:=argument k1
-      a2:=argument k2
-      res:=operator k1 = operator k2
-      if not res then return res
-      res:= a1 = a2
-      if res then return res
-      res:= (a1.3 = a2.3) and (subst(a1.1,[retract(a1.2)@K],[a2.2]) = a2.1)
-
-    dvint(l, x) ==
-      k  := retract(second l)@K
-      differentiate(third l, x) * integrand l
-          + opint [differentiate(first l, x), second l, third l]
-
-
-    dvdint(l, x) ==
-      x = retract(y := third l)@SE => 0
-      k := retract(d := second l)@K
-      differentiate(h := third rest rest l,x) * eval(f := first l, k, h)
-        - differentiate(g := third rest l, x) * eval(f, k, g)
-             + opdint [differentiate(f, x), d, y, g, h]
-
-    integral(f:F, s: SegmentBinding F) ==
-      x := kernel(variable s)$K
-      opdint [eval(f,x,dummy), dummy, x::F, lo segment s, hi segment s]
-
-    ili x ==
-      x = 1 => INV
-      is?(x, "exp"::Symbol) => Ei first argument(retract(x)@K)
-      kernel(opli, x)
-
-    iei x ==
-      x = 0 => INV
-      is?(x, "log"::Symbol) => li first argument(retract(x)@K)
-      kernel(opei, x)
-
-    operator op ==
-      is?(op, "integral"::Symbol)   => opint
-      is?(op, "%defint"::Symbol)    => opdint
-      is?(op, "Ei"::Symbol)         => opei
-      is?(op, "Si"::Symbol)         => opsi
-      is?(op, "Ci"::Symbol)         => opci
-      is?(op, "li"::Symbol)         => opli
-      is?(op, "erf"::Symbol)        => operf
-      is?(op, "dilog"::Symbol)      => opli2
-      error "Not a Liouvillian operator"
-
-    evaluate(opei,   iei)$BasicOperatorFunctions1(F)
-    evaluate(opli,   ili)
-    evaluate(opsi,   isi)
-    evaluate(opci,   ici)
-    evaluate(operf,  ierf)
-    evaluate(opli2,  ili2)
-    evaluate(opint,  iint)
-    derivative(opsi, sin(#1) / #1)
-    derivative(opci, cos(#1) / #1)
-    derivative(opei, exp(#1) / #1)
-    derivative(opli, inv log(#1))
-    derivative(operf, 2 * exp(-(#1**2)) / sqrt(pi()))
-    derivative(opli2, log(#1) / (1 - #1))
-    setProperty(opint,SPECIALEQUAL,eqint@((K,K) -> Boolean) pretend None)
-    setProperty(opint,SPECIALDIFF,dvint@((List F,SE) -> F) pretend None)
-    setProperty(opdint,SPECIALDIFF,dvdint@((List F,SE)->F) pretend None)
-    setProperty(opdint, SPECIALDISP, ddint@(List F -> O) pretend None)
-
-    if R has ConvertibleTo INP then
-      inint : List F -> INP
-      indint: List F -> INP
-      pint  : List INP -> INP
-
-
-      pint l  == convert concat(convert("integral"::SE)@INP, l)
-      inint l == 
-        r2:= convert([convert("::"::SE)@INP,convert(third l)@INP,convert("Symbol"::SE)@INP]@List INP)@INP
-        pint [convert(integrand l)@INP, r2]
-
-      indint l ==
-        pint [convert(integrand l)@INP,
-              convert concat(convert("="::SE)@INP,
-                            [convert(third l)@INP,
-                             convert concat(convert("SEGMENT"::SE)@INP,
-                                            [convert(third rest l)@INP,
-                                             convert(third rest rest l)@INP])])]
-
-      setProperty(opint, SPECIALINPUT, inint@(List F -> INP) pretend None)
-      setProperty(opdint, SPECIALINPUT, indint@(List F -> INP) pretend None)
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
--- SPAD files for the functional world should be compiled in the
--- following order:
---
---   op  kl  fspace  algfunc elemntry LIOUV expr
-
-<<package LF LiouvillianFunction>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/list.spad.pamphlet b/src/algebra/list.spad.pamphlet
deleted file mode 100644
index 4e2b7c4..0000000
--- a/src/algebra/list.spad.pamphlet
+++ /dev/null
@@ -1,230 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra list.spad}
-\author{Michael Monagon, Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LIST2 ListFunctions2}
-<<package LIST2 ListFunctions2>>=
-)abbrev package LIST2 ListFunctions2
-++ Author:
-++ Date Created:
-++ Change History:
-++ Basic Operations: map, reduce, scan
-++ Related Constructors: List
-++ Also See: ListFunctions3
-++ AMS Classification:
-++ Keywords: list, aggregate, map, reduce
-++ Description:
-++   \spadtype{ListFunctions2} implements utility functions that
-++   operate on two kinds of lists, each with a possibly different
-++   type of element.
-ListFunctions2(A:Type, B:Type): public == private where
-  LA     ==> List A
-  LB     ==> List B
-  O2     ==> FiniteLinearAggregateFunctions2(A, LA, B, LB)
-
-  public ==> with
-    scan:    ((A, B) -> B, LA, B) -> LB
-      ++ scan(fn,u,ident) successively uses the binary function
-      ++ \spad{fn} to reduce more and more of list \spad{u}.
-      ++ \spad{ident} is returned if the \spad{u} is empty.
-      ++ The result is a list of the reductions at each step. See
-      ++ \spadfun{reduce} for more information. Examples:
-      ++ \spad{scan(fn,[1,2],0) = [fn(2,fn(1,0)),fn(1,0)]} and
-      ++ \spad{scan(*,[2,3],1) = [2 * 1, 3 * (2 * 1)]}.
-    reduce:  ((A, B) -> B, LA, B) -> B
-      ++ reduce(fn,u,ident) successively uses the binary function
-      ++ \spad{fn} on the elements of list \spad{u} and the result
-      ++ of previous applications. \spad{ident} is returned if the
-      ++ \spad{u} is empty. Note the order of application in
-      ++ the following examples:
-      ++ \spad{reduce(fn,[1,2,3],0) = fn(3,fn(2,fn(1,0)))} and
-      ++ \spad{reduce(*,[2,3],1) = 3 * (2 * 1)}.
-    map:      (A -> B, LA) -> LB
-      ++ map(fn,u) applies \spad{fn} to each element of
-      ++ list \spad{u} and returns a new list with the results.
-      ++ For example \spad{map(square,[1,2,3]) = [1,4,9]}.
-
-  private ==> add
-    map(f, l)       == map(f, l)$O2
-    scan(f, l, b)   == scan(f, l, b)$O2
-    reduce(f, l, b) == reduce(f, l, b)$O2
-
-@
-\section{package LIST3 ListFunctions3}
-<<package LIST3 ListFunctions3>>=
-)abbrev package LIST3 ListFunctions3
-++ Author:
-++ Date Created:
-++ Change History:
-++ Basic Operations: map
-++ Related Constructors: List
-++ Also See: ListFunctions2
-++ AMS Classification:
-++ Keywords: list, aggregate, map
-++ Description:
-++   \spadtype{ListFunctions3} implements utility functions that
-++   operate on three kinds of lists, each with a possibly different
-++   type of element.
-ListFunctions3(A:Type, B:Type, C:Type): public == private where
-  LA     ==> List A
-  LB     ==> List B
-  LC     ==> List C
-
-  public ==> with
-    map: ( (A,B)->C, LA, LB) -> LC
-      ++ map(fn,list1, u2) applies the binary function \spad{fn}
-      ++ to corresponding elements of lists \spad{u1} and \spad{u2}
-      ++ and returns a list of the results (in the same order). Thus
-      ++ \spad{map(/,[1,2,3],[4,5,6]) = [1/4,2/4,1/2]}. The computation
-      ++ terminates when the end of either list is reached. That is,
-      ++ the length of the result list is equal to the minimum of the
-      ++ lengths of \spad{u1} and \spad{u2}.
-
-  private ==> add
-    map(fn : (A,B) -> C, la : LA, lb : LB): LC ==
-      empty?(la) or empty?(lb) => empty()$LC
-      concat(fn(first la, first lb), map(fn, rest la, rest lb))
-
-@
-\section{package LIST2MAP ListToMap}
-<<package LIST2MAP ListToMap>>=
-)abbrev package LIST2MAP ListToMap
-++ Author: Manuel Bronstein
-++ Date Created: 22 Mar 1988
-++ Change History:
-++   11 Oct 1989   MB   ?
-++ Basic Operations: match
-++ Related Constructors: List
-++ Also See:
-++ AMS Classification:
-++ Keywords: mapping, list
-++ Description:
-++   \spadtype{ListToMap} allows mappings to be described by a pair of
-++   lists of equal lengths.  The image of an element \spad{x},
-++   which appears in position \spad{n} in the first list, is then
-++   the \spad{n}th element of the second list.  A default value or
-++   default function can be specified to be used when \spad{x}
-++   does not appear in the first list.  In the absence of defaults,
-++   an error will occur in that case.
-ListToMap(A:SetCategory, B:Type): Exports == Implementation where
-  LA  ==> List A
-  LB  ==> List B
-  AB  ==> (A -> B)
-
-  Exports ==> with
-    match: (LA, LB   ) -> AB
-      ++ match(la, lb) creates a map with no default source or target values
-      ++ defined by lists la and lb of equal length.
-      ++ The target of a source value \spad{x} in la is the
-      ++ value y with the same index lb.
-      ++ Error: if la and lb are not of equal length.
-      ++ Note: when this map is applied, an error occurs when
-      ++ applied to a value missing from la.
-    match: (LA, LB, A) -> B
-      ++ match(la, lb, a) creates a map
-      ++ defined by lists la and lb of equal length, where \spad{a} is used
-      ++ as the default source value if the given one is not in \spad{la}.
-      ++ The target of a source value \spad{x} in la is the
-      ++ value y with the same index lb.
-      ++ Error: if la and lb are not of equal length.
-    match: (LA, LB, B)    -> AB
-      ++ match(la, lb, b) creates a map
-      ++ defined by lists la and lb of equal length, where \spad{b} is used
-      ++ as the default target value if the given function argument is
-      ++ not in \spad{la}.
-      ++ The target of a source value \spad{x} in la is the
-      ++ value y with the same index lb.
-      ++ Error: if la and lb are not of equal length.
-    match: (LA, LB, A, B) -> B
-      ++ match(la, lb, a, b) creates a map
-      ++ defined by lists la and lb of equal length.
-      ++ and applies this map to a.
-      ++ The target of a source value \spad{x} in la is the
-      ++ value y with the same index lb.
-      ++ Argument b is the default target value if a is not in la.
-      ++ Error: if la and lb are not of equal length.
-    match: (LA, LB, AB)    -> AB
-      ++ match(la, lb, f) creates a map
-      ++ defined by lists la and lb of equal length.
-      ++ The target of a source value \spad{x} in la is the
-      ++ value y with the same index lb.
-      ++ Argument \spad{f} is used as the
-      ++ function to call when the given function argument is not in
-      ++ \spad{la}.
-      ++ The value returned is f applied to that argument.
-    match: (LA, LB, A, AB) -> B
-      ++ match(la, lb, a, f) creates a map
-      ++ defined by lists la and lb of equal length.
-      ++ and applies this map to a.
-      ++ The target of a source value \spad{x} in la is the
-      ++ value y with the same index lb.
-      ++ Argument \spad{f} is a default function to call if a is not in la.
-      ++ The value returned is then obtained by applying f to argument a.
-
-  Implementation ==> add
-    match(la, lb)             == match(la, lb, #1)
-    match(la:LA, lb:LB, a:A)  == lb.position(a, la)
-    match(la:LA, lb:LB, b:B)  == match(la, lb, #1, b)
-    match(la:LA, lb:LB, f:AB) == match(la, lb, #1, f)
-
-    match(la:LA, lb:LB, a:A, b:B) ==
-      (p := position(a, la)) < minIndex(la) => b
-      lb.p
-
-    match(la:LA, lb:LB, a:A, f:AB) ==
-      (p := position(a, la)) < minIndex(la) => f a
-      lb.p
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LIST2 ListFunctions2>>
-<<package LIST3 ListFunctions3>>
-<<package LIST2MAP ListToMap>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/listgcd.spad.pamphlet b/src/algebra/listgcd.spad.pamphlet
deleted file mode 100644
index 8c74a22..0000000
--- a/src/algebra/listgcd.spad.pamphlet
+++ /dev/null
@@ -1,276 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra listgcd.spad}
-\author{Patrizia Gianni}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package HEUGCD HeuGcd}
-<<package HEUGCD HeuGcd>>=
-)abbrev package HEUGCD HeuGcd
-++ Author: P.Gianni
-++ Date Created:
-++ Date Last Updated: 13 September 94
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package provides the functions for the heuristic integer gcd.
-++ Geddes's algorithm,for univariate polynomials with integer coefficients
-HeuGcd (BP):C == T
- where
-  BP       :   UnivariatePolynomialCategory Integer
-  Z        ==> Integer
-  ContPrim ==> Record(cont:Z,prim:BP)
-
-
-  C == with
-     gcd          : List BP  -> BP
-       ++ gcd([f1,..,fk]) = gcd of the polynomials fi.
-       ++
-       ++X gcd([671*671*x^2-1,671*671*x^2+2*671*x+1])
-       ++X gcd([7*x^2+1,(7*x^2+1)^2])
-
-     gcdprim      : List BP  -> BP
-       ++ gcdprim([f1,..,fk]) = gcd of k PRIMITIVE univariate polynomials
-     gcdcofact    : List BP  -> List BP
-       ++ gcdcofact([f1,..fk]) = gcd and cofactors of k univariate polynomials.
-     gcdcofactprim: List BP  -> List BP
-       ++ gcdcofactprim([f1,..fk]) = gcd and cofactors of k
-       ++ primitive polynomials.
-     content      : List BP  -> List Z
-       ++ content([f1,..,fk]) = content of a list of univariate polynonials
-     lintgcd      : List  Z  -> Z
-       ++ lintgcd([a1,..,ak]) = gcd of a list of integers
-
-  T == add
-
-    PI    ==> PositiveInteger
-    NNI   ==> NonNegativeInteger
-    Cases ==> Union("gcdprim","gcd","gcdcofactprim","gcdcofact")
-    import ModularDistinctDegreeFactorizer BP
-
-    --local functions
-    localgcd     :        List BP       -> List BP
-    constNotZero :           BP         -> Boolean
-    height       :           BP         -> PI
-    genpoly      :         (Z,PI)       -> BP
-    negShiftz    :         (Z,PI)       -> Z
-    internal     :     (Cases,List BP ) -> List BP
-    constcase    : (List NNI ,List BP ) -> List BP
-    lincase      : (List NNI ,List BP ) -> List BP
-    myNextPrime  :        ( Z , NNI )   -> Z
-
-    bigPrime:= prevPrime(2**26)$IntegerPrimesPackage(Integer)
-
-    myNextPrime(val:Z,bound:NNI) : Z == nextPrime(val)$IntegerPrimesPackage(Z)
-
-    constNotZero(f : BP ) : Boolean == (degree f = 0) and ^(zero? f)
-
-    negShiftz(n:Z,Modulus:PI):Z ==
-      n < 0 => n:= n+Modulus
-      n > (Modulus quo 2) => n-Modulus
-      n
-
-    --compute the height of a polynomial
-    height(f:BP):PI ==
-      k:PI:=1
-      while f^=0 repeat
-           k:=max(k,abs(leadingCoefficient(f)@Z)::PI)
-           f:=reductum f
-      k
-
-    --reconstruct the polynomial from the value-adic representation of
-    --dval.
-    genpoly(dval:Z,value:PI):BP ==
-      d:=0$BP
-      val:=dval
-      for i in 0..  while (val^=0) repeat
-        val1:=negShiftz(val rem value,value)
-        d:= d+monomial(val1,i)
-        val:=(val-val1) quo value
-      d
-
-    --gcd of a list of integers
-    lintgcd(lval:List(Z)):Z ==
-      empty? lval => 0$Z
-      member?(1,lval) => 1$Z
-      lval:=sort(#1<#2,lval)
-      val:=lval.first
-      for val1 in lval.rest while ^(val=1) repeat val:=gcd(val,val1)
-      val
-
-    --content for a list of univariate polynomials
-    content(listf:List BP ):List(Z) ==
-      [lintgcd coefficients f for f in listf]
-
-    --content of a list of polynomials with the relative primitive parts
-    contprim(listf:List BP ):List(ContPrim) ==
-       [[c:=lintgcd coefficients f,(f exquo c)::BP]$ContPrim  for f in listf]
-
-    -- one polynomial is constant, remark that they are primitive
-    -- but listf can contain the zero polynomial
-    constcase(listdeg:List NNI ,listf:List BP ): List BP  ==
-      lind:=select(constNotZero,listf)
-      empty? lind =>
-        member?(1,listdeg) => lincase(listdeg,listf)
-        localgcd listf
-      or/[n>0 for n in listdeg] => cons(1$BP,listf)
-      lclistf:List(Z):= [leadingCoefficient f for f in listf]
-      d:=lintgcd(lclistf)
-      d=1 =>  cons(1$BP,listf)
-      cons(d::BP,[(lcf quo d)::BP for lcf in lclistf])
-
-    testDivide(listf: List BP, g:BP):Union(List BP, "failed") ==
-      result:List BP := []
-      for f in listf repeat
-        if (f1:=f exquo g) case "failed" then return "failed"
-        result := cons(f1::BP,result)
-      reverse!(result)
-
-    --one polynomial is linear, remark that they are primitive
-    lincase(listdeg:List NNI ,listf:List BP ):List BP  ==
-      n:= position(1,listdeg)
-      g:=listf.n
-      result:=[g]
-      for f in listf repeat
-        if (f1:=f exquo g) case "failed" then return cons(1$BP,listf)
-        result := cons(f1::BP,result)
-      reverse(result)
-
-    IMG := InnerModularGcd(Z,BP,67108859,myNextPrime)
-
-    mindegpol(f:BP, g:BP):BP ==
-      degree(g) < degree (f) => g
-      f
-
-    --local function for the gcd among n PRIMITIVE univariate polynomials
-    localgcd(listf:List BP ):List BP  ==
-      hgt:="min"/[height(f) for f in listf|^zero? f]
-      answr:=2+2*hgt
-      minf := "mindegpol"/[f for f in listf|^zero? f]
-      (result := testDivide(listf, minf)) case List(BP) =>
-           cons(minf, result::List BP)
-      if degree minf < 100 then for k in 1..10 repeat
-        listval:=[f answr for f in listf]
-        dval:=lintgcd(listval)
-        dd:=genpoly(dval,answr)
-        contd:=content(dd)
-        d:=(dd exquo contd)::BP
-        result:List BP :=[d]
-        flag : Boolean := true
-        for f in listf while flag repeat
-          (f1:=f exquo d) case "failed" => flag:=false
-          result := cons (f1::BP,result)
-        if flag then return reverse(result)
-        nvalue:= answr*832040 quo 317811
-        if ((nvalue + answr) rem 2) = 0 then nvalue:=nvalue+1
-        answr:=nvalue::PI
-      gg:=modularGcdPrimitive(listf)$IMG
-      cons(gg,[(f exquo gg) :: BP for f in listf])
-
-    --internal function:it evaluates the gcd and avoids duplication of
-    --code.
-    internal(flag:Cases,listf:List BP ):List BP  ==
-      --special cases
-      listf=[] => [1$BP]
-      (nlf:=#listf)=1 => [first listf,1$BP]
-      minpol:=1$BP
-      -- extract a monomial gcd
-      mdeg:= "min"/[minimumDegree f for f in listf]
-      if mdeg>0 then
-        minpol1:= monomial(1,mdeg)
-        listf:= [(f exquo minpol1)::BP for f in listf]
-        minpol:=minpol*minpol1
-      -- make the polynomials primitive
-      Cgcd:List(Z):=[]
-      contgcd : Z := 1
-      if (flag case "gcd") or (flag case "gcdcofact") then
-        contlistf:List(ContPrim):=contprim(listf)
-        Cgcd:= [term.cont for term in contlistf]
-        contgcd:=lintgcd(Cgcd)
-        listf:List BP :=[term.prim for term in contlistf]
-        minpol:=contgcd*minpol
-      listdeg:=[degree f for f in listf ]
-      f:= first listf
-      if positiveRemainder(leadingCoefficient(f), bigPrime) ~= 0 then
-        for g in rest listf repeat
-          lcg := leadingCoefficient(g)
-          if positiveRemainder(lcg, bigPrime) = 0 then
-            leave
-          f:=gcd(f,g,bigPrime)
-          if degree f = 0 then return cons(minpol,listf)
-      ans:List BP :=
-         --one polynomial is constant
-         member?(0,listdeg) => constcase(listdeg,listf)
-         --one polynomial is linear
-         member?(1,listdeg) => lincase(listdeg,listf)
-         localgcd(listf)
-      (result,ans):=(first ans*minpol,rest ans)
-      if (flag case "gcdcofact") then
-        ans:= [(p quo contgcd)*q for p in Cgcd for q in ans]
-      cons(result,ans)
-
-    --gcd among n PRIMITIVE univariate polynomials
-    gcdprim (listf:List BP ):BP == first internal("gcdprim",listf)
-
-    --gcd and cofactors for n PRIMITIVE univariate polynomials
-    gcdcofactprim(listf:List BP ):List BP  == internal("gcdcofactprim",listf)
-
-    --gcd for n generic univariate polynomials.
-    gcd(listf:List BP ): BP  ==  first internal("gcd",listf)
-
-    --gcd and cofactors for n generic univariate polynomials.
-    gcdcofact (listf:List BP ):List BP == internal("gcdcofact",listf)
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package HEUGCD HeuGcd>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/lodo.spad.pamphlet b/src/algebra/lodo.spad.pamphlet
deleted file mode 100644
index 939f355..0000000
--- a/src/algebra/lodo.spad.pamphlet
+++ /dev/null
@@ -1,158 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra lodo.spad}
-\author{Manuel Bronstein, Stephen M. Watt}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package LODOOPS LinearOrdinaryDifferentialOperatorsOps}
-<<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>=
-)abbrev package LODOOPS LinearOrdinaryDifferentialOperatorsOps
-++ Author: Manuel Bronstein
-++ Date Created: 18 January 1994
-++ Date Last Updated: 15 April 1994
-++ Description:
-++   \spad{LinearOrdinaryDifferentialOperatorsOps} provides symmetric
-++   products and sums for linear ordinary differential operators.
--- Putting those operations here rather than defaults in LODOCAT allows
--- LODOCAT to be defined independently of the derivative used.
--- MB 1/94
-LinearOrdinaryDifferentialOperatorsOps(A, L): Exports == Implementation where
-    A: Field
-    L: LinearOrdinaryDifferentialOperatorCategory A
-
-    N  ==> NonNegativeInteger
-    V  ==> OrderlyDifferentialVariable Symbol
-    P  ==> DifferentialSparseMultivariatePolynomial(A, Symbol, V)
-
-    Exports ==> with
-          symmetricProduct: (L, L, A -> A) -> L
-            ++ symmetricProduct(a,b,D) computes an operator \spad{c} of
-            ++ minimal order such that the nullspace of \spad{c} is
-            ++ generated by all the products of a solution of \spad{a} by
-            ++ a solution of \spad{b}.
-            ++ D is the derivation to use.
-          symmetricPower: (L, N, A -> A) -> L
-            ++ symmetricPower(a,n,D) computes an operator \spad{c} of
-            ++ minimal order such that the nullspace of \spad{c} is
-            ++ generated by all the products of \spad{n} solutions
-            ++ of \spad{a}.
-            ++ D is the derivation to use.
-          directSum: (L, L, A -> A) -> L
-            ++ directSum(a,b,D) computes an operator \spad{c} of
-            ++ minimal order such that the nullspace of \spad{c} is
-            ++ generated by all the sums of a solution of \spad{a} by
-            ++ a solution of \spad{b}.
-            ++ D is the derivation to use.
-
-    Implementation ==> add
-          import IntegerCombinatoricFunctions
-
-          var1 := new()$Symbol
-          var2 := new()$Symbol
-
-          nonTrivial?: Vector A -> Boolean
-          applyLODO  : (L, V) -> P
-          killer     : (P, N, List V, List P, A -> A) -> L
-          vec2LODO   : Vector A -> L
-
-          nonTrivial? v == any?(#1 ^= 0, v)$Vector(A)
-          vec2LODO v    == +/[monomial(v.i, (i-1)::N) for i in 1..#v]
-
-          symmetricPower(l, m, diff) ==
-            u := var1::V; n := degree l
-            un := differentiate(u, n)
-            a  := applyLODO(inv(- leadingCoefficient l) * reductum l, u)
-            killer(u::P ** m, binomial(n + m - 1, n - 1)::N, [un], [a], diff)
-
--- returns an operator L such that L(u) = 0, for a given differential
--- polynomial u, given that the differential variables appearing in u
--- satisfy some linear ode's
--- m is a bound on the order of the operator searched.
--- lvar, lval describe the substitution(s) to perform when differentiating
---     the expression u (they encode the fact the the differential variables
---     satisfy some differential equations, which can be seen as the rewrite
---     rules   lvar --> lval)
--- diff is the derivation to use
-          killer(u, m, lvar, lval, diff) ==
-            lu:List P := [u]
-            for q in 0..m repeat
-              mat := reducedSystem(matrix([lu])@Matrix(P))@Matrix(A)
-              (sol := find(nonTrivial?, l := nullSpace mat)) case Vector(A) =>
-                return vec2LODO(sol::Vector(A))
-              u := eval(differentiate(u, diff), lvar, lval)
-              lu := concat_!(lu, [u])
-            error "killer: no linear dependence found"
-
-          symmetricProduct(l1, l2, diff) ==
-            u  := var1::V;   v  := var2::V
-            n1 := degree l1; n2 := degree l2
-            un := differentiate(u, n1); vn := differentiate(v, n2)
-            a  := applyLODO(inv(- leadingCoefficient l1) * reductum l1, u)
-            b  := applyLODO(inv(- leadingCoefficient l2) * reductum l2, v)
-            killer(u::P * v::P, n1 * n2, [un, vn], [a, b], diff)
-
-          directSum(l1, l2, diff) ==
-            u  := var1::V;   v  := var2::V
-            n1 := degree l1; n2 := degree l2
-            un := differentiate(u, n1); vn := differentiate(v, n2)
-            a  := applyLODO(inv(- leadingCoefficient l1) * reductum l1, u)
-            b  := applyLODO(inv(- leadingCoefficient l2) * reductum l2, v)
-            killer(u::P + v::P, n1 + n2, [un, vn], [a, b], diff)
-
-          applyLODO(l, v) ==
-            p:P := 0
-            while l ^= 0 repeat
-              p := p + monomial(leadingCoefficient(l)::P,
-                                  differentiate(v, degree l), 1)
-              l := reductum l
-            p
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/lodof.spad.pamphlet b/src/algebra/lodof.spad.pamphlet
deleted file mode 100644
index daaedcb..0000000
--- a/src/algebra/lodof.spad.pamphlet
+++ /dev/null
@@ -1,385 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra lodof.spad}
-\author{Manuel Bronstein, Fritz Schwarz}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PREASSOC PrecomputedAssociatedEquations}
-<<package PREASSOC PrecomputedAssociatedEquations>>=
-)abbrev package PREASSOC PrecomputedAssociatedEquations
-++ Author: Manuel Bronstein
-++ Date Created: 13 January 1994
-++ Date Last Updated: 3 February 1994
-++ Description:
-++ \spadtype{PrecomputedAssociatedEquations} stores some generic
-++ precomputations which speed up the computations of the
-++ associated equations needed for factoring operators.
-PrecomputedAssociatedEquations(R, L): Exports == Implementation where
-  R: IntegralDomain
-  L: LinearOrdinaryDifferentialOperatorCategory R
- 
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  A   ==> PrimitiveArray R
-  U   ==> Union(Matrix R, "failed")
- 
-  Exports ==> with
-    firstUncouplingMatrix: (L, PI) -> U
-      ++ firstUncouplingMatrix(op, m) returns the matrix A such that
-      ++ \spad{A w = (W',W'',...,W^N)} in the corresponding associated
-      ++ equations for right-factors of order m of op.
-      ++ Returns "failed" if the matrix A has not been precomputed for
-      ++ the particular combination \spad{degree(L), m}.
- 
-  Implementation ==> add
-    A32:  L -> U
-    A42:  L -> U
-    A425: (A, A, A) -> List R
-    A426: (A, A, A) -> List R
-    makeMonic: L -> Union(A, "failed")
- 
-    diff:L := D()
- 
-    firstUncouplingMatrix(op, m) ==
-      n := degree op
-      n = 3 and m = 2 => A32 op
-      n = 4 and m = 2 => A42 op
-      "failed"
-        
-    makeMonic op ==
-      lc := leadingCoefficient op
-      a:A := new(n := degree op, 0)
-      for i in 0..(n-1)::N repeat
-        (u := coefficient(op, i) exquo lc) case "failed" => return "failed"
-        a.i := - (u::R)
-      a
-    
-    A32 op ==
-      (u := makeMonic op) case "failed" => "failed"
-      a := u::A
-      matrix [[0, 1, 0], [a.1, a.2, 1],
-              [diff(a.1) + a.1 * a.2 - a.0, diff(a.2) + a.2**2 + a.1, 2 * a.2]]
- 
-    A42 op ==
-      (u := makeMonic op) case "failed" => "failed"
-      a := u::A
-      a':A := new(4, 0)
-      a'':A := new(4, 0)
-      for i in 0..3 repeat
-        a'.i := diff(a.i)
-        a''.i := diff(a'.i)
-      matrix [[0, 1, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0], [a.1,a.2,0,a.3,2::R,0],
-              [a'.1 + a.1 * a.3 - 2 * a.0, a'.2 + a.2 * a.3 + a.1, 3 * a.2,
-               a'.3 + a.3 ** 2 + a.2, 3 * a.3, 2::R],
-                A425(a, a', a''), A426(a, a', a'')]
- 
-    A425(a, a', a'') ==
-      [a''.1 + 2 * a.1 * a'.3 + a.3 * a'.1 - 2 * a'.0 + a.1 * a.3 ** 2
-       - 3 * a.0 * a.3 + a.1 * a.2,
-        a''.2 + 2 * a.2 * a'.3 + a.3 * a'.2 + 2 * a'.1 + a.2 * a.3 ** 2
-         + a.1 * a.3 + a.2 ** 2 - 4 * a.0,
-          4 * a'.2 + 4 * a.2 * a.3 - a.1,
-           a''.3 + 3 * a.3 * a'.3 + 2 * a'.2 + a.3 ** 3 + 2 * a.2 * a.3 + a.1,
-            4 * a'.3 + 4 * a.3 ** 2 + 4 * a.2, 5 * a.3]
-              
-    A426(a, a', a'') ==
-      [diff(a''.1) + 3 * a.1 * a''.3 + a.3 * a''.1 - 2 * a''.0
-       + (3 * a'.1 + 5 * a.1 * a.3 - 7 * a.0) * a'.3 + 3 * a.1 * a'.2
-        + (a.3 ** 2 + a.2) * a'.1 - 3 * a.3 * a'.0 + a.1 * a.3 ** 3
-         - 4 * a.0 * a.3 ** 2 + 2 * a.1 * a.2 * a.3 - 4 * a.0 * a.2 + a.1 ** 2,
-          diff(a''.2) + 3 * a.2 * a''.3 + a.3 * a''.2 + 3 * a''.1
-           + (3*a'.2 + 5*a.2 * a.3 + 3 * a.1) * a'.3 + (a.3**2 + 4*a.2)*a'.2
-            + 2 * a.3 * a'.1 - 6 * a'.0 + a.2 * a.3 ** 3 + a.1 * a.3 ** 2
-             + (2 * a.2**2 - 8 * a.0) * a.3 + 2 * a.1 * a.2,
-              5 * a''.2 + 10 * a.2 * a'.3 + 5 * a.3 * a'.2 + a'.1
-               + 5 * a.2 * a.3 ** 2 - 4 * a.1 * a.3 + 5 * a.2**2 - 4 * a.0,
-                diff(a''.3) + 4 * a.3 * a''.3 + 3*a''.2 + 3 * a'.3**2
-                 + (6 * a.3**2 + 4 * a.2) * a'.3 + 5 * a.3 * a'.2 + 3 * a'.1
-                  + a.3**4 + 3 * a.2 * a.3**2 + 2 * a.1 * a.3 + a.2**2 - 4*a.0,
-                   5 * a''.3 + 15 * a.3 * a'.3 + 10 * a'.2 + 5 * a.3**3
-                    + 10 * a.2 * a.3, 9 * a'.3 + 9 * a.3**2 + 4 * a.2]
-
-@
-\section{package ASSOCEQ AssociatedEquations}
-<<package ASSOCEQ AssociatedEquations>>=
-)abbrev package ASSOCEQ AssociatedEquations
-++ Author: Manuel Bronstein
-++ Date Created: 10 January 1994
-++ Date Last Updated: 3 February 1994
-++ Description:
-++ \spadtype{AssociatedEquations} provides functions to compute the
-++ associated equations needed for factoring operators
-AssociatedEquations(R, L):Exports == Implementation where
-  R: IntegralDomain
-  L: LinearOrdinaryDifferentialOperatorCategory R
- 
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  MAT ==> Matrix R
-  REC ==> Record(minor: List PI, eq: L, minors: List List PI, ops: List L)
- 
-  Exports ==> with
-    associatedSystem: (L, PI) -> Record(mat: MAT, vec:Vector List PI)
-      ++ associatedSystem(op, m) returns \spad{[M,w]} such that the
-      ++ m-th associated equation system to L is \spad{w' = M w}.
-    uncouplingMatrices: MAT -> Vector MAT
-      ++ uncouplingMatrices(M) returns \spad{[A_1,...,A_n]} such that if
-      ++ \spad{y = [y_1,...,y_n]} is a solution of \spad{y' = M y}, then
-      ++ \spad{[$y_j',y_j'',...,y_j^{(n)}$] = $A_j y$} for all j's.
-    if R has Field then
-        associatedEquations: (L, PI) -> REC
-          ++ associatedEquations(op, m) returns \spad{[w, eq, lw, lop]}
-          ++ such that \spad{eq(w) = 0} where w is the given minor, and
-          ++ \spad{lw_i = lop_i(w)} for all the other minors.
- 
-  Implementation ==> add
-    makeMatrix: (Vector MAT, N) -> MAT
- 
-    diff:L := D()
- 
-    makeMatrix(v, n) == matrix [parts row(v.i, n) for i in 1..#v]
- 
-    associatedSystem(op, m) ==
-      eq: Vector R
-      S := SetOfMIntegersInOneToN(m, n := degree(op)::PI)
-      w := enumerate()$S
-      s := size()$S
-      ww:Vector List PI := new(s, empty())
-      M:MAT := new(s, s, 0)
-      m1 := (m::Integer - 1)::PI
-      an := leadingCoefficient op
-      a:Vector(R) := [- (coefficient(op, j) exquo an)::R for j in 0..n - 1]
-      for i in 1..s repeat
-          eq := new(s, 0)
-          wi := w.i
-          ww.i := elements wi
-          for k in 1..m1 repeat
-              u := incrementKthElement(wi, k::PI)$S
-              if u case S then eq(lookup(u::S)) := 1
-          if member?(n, wi) then
-              for j in 1..n | a.j ^= 0 repeat
-                  u := replaceKthElement(wi, m, j::PI)
-                  if u case S then
-                    eq(lookup(u::S)) := (odd? delta(wi, m, j::PI) => -a.j; a.j)
-          else
-              u := incrementKthElement(wi, m)$S
-              if u case S then eq(lookup(u::S)) := 1
-          setRow_!(M, i, eq)
-      [M, ww]
- 
-    uncouplingMatrices m ==
-      n := nrows m
-      v:Vector MAT := new(n, zero(1, 0)$MAT)
-      v.1 := mi := m
-      for i in 2..n repeat v.i := mi := map(diff #1, mi) + mi * m
-      [makeMatrix(v, i) for i in 1..n]
- 
-    if R has Field then
-        import PrecomputedAssociatedEquations(R, L)
- 
-        makeop:    Vector R -> L
-        makeeq:    (Vector List PI, MAT, N, N) -> REC
-        computeIt: (L, PI, N) -> REC
- 
-        makeeq(v, m, i, n) ==
-          [v.i, makeop row(m, i) - 1, [v.j for j in 1..n | j ^= i],
-                                    [makeop row(m, j) for j in 1..n | j ^= i]]
- 
-        associatedEquations(op, m) ==
-          (u := firstUncouplingMatrix(op, m)) case "failed" => computeIt(op,m,1)
-          (v := inverse(u::MAT)) case "failed" => computeIt(op, m, 2)
-          S := SetOfMIntegersInOneToN(m, degree(op)::PI)
-          w := enumerate()$S
-          s := size()$S
-          ww:Vector List PI := new(s, empty())
-          for i in 1..s repeat ww.i := elements(w.i)
-          makeeq(ww, v::MAT, 1, s)
- 
-        computeIt(op, m, k) ==
-          rec := associatedSystem(op, m)
-          a := uncouplingMatrices(rec.mat)
-          n := #a
-          for i in k..n repeat
-            (u := inverse(a.i)) case MAT => return makeeq(rec.vec,u::MAT,i,n)
-          error "associatedEquations: full degenerate case"
- 
-        makeop v ==
-          op:L := 0
-          for i in 1..#v repeat op := op + monomial(v i, i)
-          op
-
-@
-\section{package LODOF LinearOrdinaryDifferentialOperatorFactorizer}
-<<package LODOF LinearOrdinaryDifferentialOperatorFactorizer>>=
-)abbrev package LODOF LinearOrdinaryDifferentialOperatorFactorizer
-++ Author: Fritz Schwarz, Manuel Bronstein
-++ Date Created: 1988
-++ Date Last Updated: 3 February 1994
-++ Description:
-++ \spadtype{LinearOrdinaryDifferentialOperatorFactorizer} provides a
-++ factorizer for linear ordinary differential operators whose coefficients
-++ are rational functions.
-++ Keywords: differential equation, ODE, LODO, factoring
-LinearOrdinaryDifferentialOperatorFactorizer(F, UP): Exports == Impl where
-  F : Join(Field, CharacteristicZero,
-           RetractableTo Integer, RetractableTo Fraction Integer)
-  UP: UnivariatePolynomialCategory F
- 
-  RF ==> Fraction UP
-  L  ==> LinearOrdinaryDifferentialOperator1 RF
- 
-  Exports ==> with
-    factor: (L, UP -> List F) -> List L
-      ++ factor(a, zeros) returns the factorisation of a.
-      ++ \spad{zeros} is a zero finder in \spad{UP}.
-    if F has AlgebraicallyClosedField then
-      factor: L -> List L
-        ++ factor(a) returns the factorisation of a.
-      factor1: L -> List L
-        ++ factor1(a) returns the factorisation of a,
-        ++ assuming that a has no first-order right factor.
- 
-  Impl ==> add
-    import RationalLODE(F, UP)
-    import RationalRicDE(F, UP)
---  import AssociatedEquations RF
- 
-    dd := D()$L
- 
-    expsol     : (L, UP -> List F, UP -> Factored UP) -> Union(RF, "failed")
-    expsols    : (L, UP -> List F, UP -> Factored UP, Boolean) -> List RF
-    opeval     : (L, L) -> L
-    recurfactor: (L, L, UP -> List F, UP -> Factored UP, Boolean) -> List L
-    rfactor    : (L, L, UP -> List F, UP -> Factored UP, Boolean) -> List L
-    rightFactor: (L, NonNegativeInteger, UP -> List F, UP -> Factored UP)
-                                                          -> Union(L, "failed")
-    innerFactor: (L, UP -> List F, UP -> Factored UP, Boolean) -> List L
- 
-    factor(l, zeros) == innerFactor(l, zeros, squareFree, true)
- 
-    expsol(l, zeros, ezfactor) ==
-      empty?(sol := expsols(l, zeros, ezfactor, false)) => "failed"
-      first sol
- 
-    expsols(l, zeros, ezfactor, all?) ==
-      sol := [differentiate(f)/f for f in ratDsolve(l, 0).basis | f ^= 0]
-      not(all? or empty? sol) => sol
-      concat(sol, ricDsolve(l, zeros, ezfactor))
- 
--- opeval(l1, l2) returns l1(l2)
-    opeval(l1, l2) ==
-      ans:L := 0
-      l2n:L := 1
-      for i in 0..degree l1 repeat
-        ans := ans + coefficient(l1, i) * l2n
-        l2n := l2 * l2n
-      ans
-      
-    recurfactor(l, r, zeros, ezfactor, adj?) ==
-      q := rightExactQuotient(l, r)::L
-      if adj? then q := adjoint q
-      innerFactor(q, zeros, ezfactor, true)
- 
-    rfactor(op, r, zeros, ezfactor, adj?) ==
---      degree r > 1 or not one? leadingCoefficient r =>
-      degree r > 1 or not ((leadingCoefficient r) = 1) =>
-        recurfactor(op, r, zeros, ezfactor, adj?)
-      op1 := opeval(op, dd - coefficient(r, 0)::L)
-      map_!(opeval(#1, r), recurfactor(op1, dd, zeros, ezfactor, adj?))
- 
--- r1? is true means look for 1st-order right-factor also
-    innerFactor(l, zeros, ezfactor, r1?) ==
-      (n := degree l) <= 1 => [l]
-      ll := adjoint l
-      for i in 1..(n quo 2) repeat
-        (r1? or (i > 1)) and ((u := rightFactor(l,i,zeros,ezfactor)) case L) =>
-           return concat_!(rfactor(l, u::L, zeros, ezfactor, false), u::L)
-        (2 * i < n) and ((u := rightFactor(ll, i, zeros, ezfactor)) case L) =>
-           return concat(adjoint(u::L), rfactor(ll, u::L, zeros,ezfactor,true))
-      [l]
- 
-    rightFactor(l, n, zeros, ezfactor) ==
---      one? n =>
-      (n = 1) =>
-        (u := expsol(l, zeros, ezfactor)) case "failed" => "failed"
-        D() - u::RF::L
---    rec := associatedEquations(l, n::PositiveInteger)
---    empty?(sol := expsols(rec.eq, zeros, ezfactor, true)) => "failed"
-      "failed"
- 
-    if F has AlgebraicallyClosedField then
-      zro1: UP -> List F
-      zro : (UP, UP -> Factored UP) -> List F
- 
-      zro(p, ezfactor) ==
-        concat [zro1(r.factor) for r in factors ezfactor p]
- 
-      zro1 p ==
-        [zeroOf(map(#1, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
-                                             F, SparseUnivariatePolynomial F))]
- 
-      if F is AlgebraicNumber then
-        import AlgFactor UP
- 
-        factor l  == innerFactor(l, zro(#1, factor), factor, true)
-        factor1 l == innerFactor(l, zro(#1, factor), factor, false)
- 
-      else
-        factor l  == innerFactor(l, zro(#1, squareFree), squareFree, true)
-        factor1 l == innerFactor(l, zro(#1, squareFree), squareFree, false)
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
- 
--- Compile order for the differential equation solver:
--- oderf.spad  odealg.spad  nlode.spad  nlinsol.spad  riccati.spad
--- kovacic.spad  lodof.spad  odeef.spad
- 
-<<package PREASSOC PrecomputedAssociatedEquations>>
-<<package ASSOCEQ AssociatedEquations>>
-<<package LODOF LinearOrdinaryDifferentialOperatorFactorizer>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/lodop.spad.pamphlet b/src/algebra/lodop.spad.pamphlet
deleted file mode 100644
index 61ce08e..0000000
--- a/src/algebra/lodop.spad.pamphlet
+++ /dev/null
@@ -1,150 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra lodop.spad}
-\author{Stephen M. Watt, Jean Della Dora}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package NCODIV NonCommutativeOperatorDivision}
-<<package NCODIV NonCommutativeOperatorDivision>>=
-)abbrev package NCODIV NonCommutativeOperatorDivision
-++ Author: Jean Della Dora, Stephen M. Watt
-++ Date Created: 1986
-++ Date Last Updated: May 30, 1991
-++ Basic Operations:
-++ Related Domains: LinearOrdinaryDifferentialOperator
-++ Also See:
-++ AMS Classifications:
-++ Keywords: gcd, lcm, division, non-commutative
-++ Examples:
-++ References:
-++ Description:
-++   This package provides a division and related operations for
-++   \spadtype{MonogenicLinearOperator}s over a \spadtype{Field}.
-++   Since the multiplication is in general non-commutative,
-++   these operations all have left- and right-hand versions.
-++   This package provides the operations based on left-division.
-            -- [q,r] = leftDivide(a,b) means a=b*q+r
-
-NonCommutativeOperatorDivision(P, F): PDcat == PDdef  where
-    P: MonogenicLinearOperator(F)
-    F: Field
-
-    PDcat == with
-        leftDivide:   (P, P) -> Record(quotient: P, remainder: P)
-            ++ leftDivide(a,b) returns the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ This process is called ``left division''.
-        leftQuotient:  (P, P) -> P
-            ++ leftQuotient(a,b) computes the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ The value \spad{q} is returned.
-        leftRemainder:  (P, P) -> P
-            ++ leftRemainder(a,b) computes the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ The value \spad{r} is returned.
-        leftExactQuotient:(P, P) -> Union(P, "failed")
-            ++ leftExactQuotient(a,b) computes the value \spad{q}, if it exists,
-            ++  such that \spad{a = b*q}.
-
-        leftGcd:   (P, P) -> P
-            ++ leftGcd(a,b) computes the value \spad{g} of highest degree
-            ++ such that
-            ++    \spad{a = aa*g}
-            ++    \spad{b = bb*g}
-            ++ for some values \spad{aa} and \spad{bb}.
-            ++ The value \spad{g} is computed using left-division.
-        leftLcm:   (P, P) -> P
-            ++ leftLcm(a,b) computes the value \spad{m} of lowest degree
-            ++ such that \spad{m = a*aa = b*bb} for some values
-            ++ \spad{aa} and \spad{bb}.  The value \spad{m} is
-            ++ computed using left-division.
-
-    PDdef == add
-        leftDivide(a, b) ==
-            q: P := 0
-            r: P := a
-            iv:F := inv leadingCoefficient b
-            while degree r >= degree b and r ^= 0 repeat
-                h := monomial(iv*leadingCoefficient r,
-              	                 (degree r - degree b)::NonNegativeInteger)$P
-                r := r - b*h
-                q := q + h
-            [q,r]
-
-        -- leftQuotient(a,b) is the quotient from left division, etc.
-        leftQuotient(a,b)   == leftDivide(a,b).quotient
-        leftRemainder(a,b)   == leftDivide(a,b).remainder
-        leftExactQuotient(a,b) ==
-             qr := leftDivide(a,b)
-             if qr.remainder = 0 then qr.quotient else "failed"
-        -- l = leftGcd(a,b) means  a = aa*l  b = bb*l.  Uses leftDivide.
-        leftGcd(a,b) ==
-             a = 0 =>b
-             b = 0 =>a
-             while degree b > 0 repeat (a,b) := (b, leftRemainder(a,b))
-             if b=0 then a else b
-        -- l = leftLcm(a,b) means  l = a*aa  l = b*bb   Uses leftDivide.
-        leftLcm(a,b) ==
-            a = 0 =>b
-            b = 0 =>a
-            b0 := b
-            u  := monomial(1,0)$P
-            v  := 0
-            while leadingCoefficient b ^= 0 repeat
-                qr     := leftDivide(a,b)
-                (a, b) := (b, qr.remainder)
-                (u, v) := (u*qr.quotient+v, u)
-            b0*u
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
-<<package NCODIV NonCommutativeOperatorDivision>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/manip.spad.pamphlet b/src/algebra/manip.spad.pamphlet
deleted file mode 100644
index 2322ac7..0000000
--- a/src/algebra/manip.spad.pamphlet
+++ /dev/null
@@ -1,874 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra manip.spad}
-\author{Manuel Bronstein, Robert Sutor}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package FACTFUNC FactoredFunctions}
-<<package FACTFUNC FactoredFunctions>>=
-)abbrev package FACTFUNC FactoredFunctions
-++ Author: Manuel Bronstein
-++ Date Created: 2 Feb 1988
-++ Date Last Updated: 25 Jun 1990
-++ Description: computes various functions on factored arguments.
--- not visible to the user
-FactoredFunctions(M:IntegralDomain): Exports == Implementation where
-  N ==> NonNegativeInteger
-
-  Exports ==> with
-    nthRoot: (Factored M,N) -> Record(exponent:N,coef:M,radicand:List M)
-      ++ nthRoot(f, n) returns \spad{(p, r, [r1,...,rm])} such that
-      ++ the nth-root of f is equal to \spad{r * pth-root(r1 * ... * rm)},
-      ++ where r1,...,rm are distinct factors of f,
-      ++ each of which has an exponent smaller than p in f.
-    log : Factored M -> List Record(coef:N, logand:M)
-      ++ log(f) returns \spad{[(a1,b1),...,(am,bm)]} such that
-      ++ the logarithm of f is equal to \spad{a1*log(b1) + ... + am*log(bm)}.
-
-  Implementation ==> add
-    nthRoot(ff, n) ==
-      coeff:M       := 1
---      radi:List(M)  := (one? unit ff => empty(); [unit ff])
-      radi:List(M)  := (((unit ff) = 1) => empty(); [unit ff])
-      lf            := factors ff
-      d:N :=
-        empty? radi => gcd(concat(n, [t.exponent::N for t in lf]))::N
-        1
-      n             := n quo d
-      for term in lf repeat
-        qr    := divide(term.exponent::N quo d, n)
-        coeff := coeff * term.factor ** qr.quotient
-        not zero?(qr.remainder) =>
-          radi := concat_!(radi, term.factor ** qr.remainder)
-      [n, coeff, radi]
-
-    log ff ==
-      ans := unit ff
-      concat([1, unit ff],
-             [[term.exponent::N, term.factor] for term in factors ff])
-
-@
-\section{package POLYROOT PolynomialRoots}
-<<package POLYROOT PolynomialRoots>>=
-)abbrev package POLYROOT PolynomialRoots
-++ Author: Manuel Bronstein
-++ Date Created: 15 July 1988
-++ Date Last Updated: 10 November 1993
-++ Description: computes n-th roots of quotients of
-++ multivariate polynomials
--- not visible to the user
-PolynomialRoots(E, V, R, P, F):Exports == Implementation where
-  E: OrderedAbelianMonoidSup
-  V: OrderedSet
-  R: IntegralDomain
-  P: PolynomialCategory(R, E, V)
-  F: Field with
-    numer : $ -> P
-	++ numer(x) \undocumented
-    denom : $ -> P
-	++ denom(x) \undocumented
-    coerce: P -> $
-	++ coerce(p) \undocumented
-
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  Q   ==> Fraction Z
-  REC ==> Record(exponent:N, coef:F, radicand:F)
-
-  Exports ==> with
-    rroot: (R, N) -> REC
-      ++ rroot(f, n) returns \spad{[m,c,r]} such
-      ++ that \spad{f**(1/n) = c * r**(1/m)}.
-    qroot : (Q, N) -> REC
-      ++ qroot(f, n) returns \spad{[m,c,r]} such
-      ++ that \spad{f**(1/n) = c * r**(1/m)}.
-    if R has GcdDomain then froot: (F, N) -> REC
-      ++ froot(f, n) returns \spad{[m,c,r]} such
-      ++ that \spad{f**(1/n) = c * r**(1/m)}.
-    nthr: (P, N) -> Record(exponent:N,coef:P,radicand:List P)
-	++ nthr(p,n) should be local but conditional
-
-  Implementation ==> add
-    import FactoredFunctions Z
-    import FactoredFunctions P
-
-    rsplit: List P -> Record(coef:R, poly:P)
-    zroot : (Z, N) -> Record(exponent:N, coef:Z, radicand:Z)
-
-    zroot(x, n) ==
---      zero? x or one? x => [1, x, 1]
-      zero? x or (x = 1) => [1, x, 1]
-      s := nthRoot(squareFree x, n)
-      [s.exponent, s.coef, */s.radicand]
-
-    if R has imaginary: () -> R then
-      czroot: (Z, N) -> REC
-
-      czroot(x, n) ==
-        rec := zroot(x, n)
-        rec.exponent = 2 and rec.radicand < 0 =>
-          [rec.exponent, rec.coef * imaginary()::P::F, (-rec.radicand)::F]
-        [rec.exponent, rec.coef::F, rec.radicand::F]
-
-      qroot(x, n) ==
-        sn := czroot(numer x, n)
-        sd := czroot(denom x, n)
-        m  := lcm(sn.exponent, sd.exponent)::N
-        [m, sn.coef / sd.coef,
-                    (sn.radicand ** (m quo sn.exponent)) /
-                                (sd.radicand ** (m quo sd.exponent))]
-    else
-      qroot(x, n) ==
-        sn := zroot(numer x, n)
-        sd := zroot(denom x, n)
-        m  := lcm(sn.exponent, sd.exponent)::N
-        [m, sn.coef::F / sd.coef::F,
-                    (sn.radicand ** (m quo sn.exponent))::F /
-                                (sd.radicand ** (m quo sd.exponent))::F]
-
-    if R has RetractableTo Fraction Z then
-      rroot(x, n) ==
-        (r := retractIfCan(x)@Union(Fraction Z,"failed")) case "failed"
-          => [n, 1, x::P::F]
-        qroot(r::Q, n)
-
-    else
-      if R has RetractableTo Z then
-        rroot(x, n) ==
-          (r := retractIfCan(x)@Union(Z,"failed")) case "failed"
-            => [n, 1, x::P::F]
-          qroot(r::Z::Q, n)
-      else
-        rroot(x, n) == [n, 1, x::P::F]
-
-    rsplit l ==
-      r := 1$R
-      p := 1$P
-      for q in l repeat
-        if (u := retractIfCan(q)@Union(R, "failed")) case "failed"
-          then p := p * q
-          else r := r * u::R
-      [r, p]
-
-    if R has GcdDomain then
-      if R has RetractableTo Z then
-        nthr(x, n) ==
-          (r := retractIfCan(x)@Union(Z,"failed")) case "failed"
-             => nthRoot(squareFree x, n)
-          rec := zroot(r::Z, n)
-          [rec.exponent, rec.coef::P, [rec.radicand::P]]
-      else nthr(x, n) == nthRoot(squareFree x, n)
-
-      froot(x, n) ==
---        zero? x or one? x => [1, x, 1]
-        zero? x or (x = 1) => [1, x, 1]
-        sn := nthr(numer x, n)
-        sd := nthr(denom x, n)
-        pn := rsplit(sn.radicand)
-        pd := rsplit(sd.radicand)
-        rn := rroot(pn.coef, sn.exponent)
-        rd := rroot(pd.coef, sd.exponent)
-        m := lcm([rn.exponent, rd.exponent, sn.exponent, sd.exponent])::N
-        [m, (sn.coef::F / sd.coef::F) * (rn.coef / rd.coef),
-             ((rn.radicand ** (m quo rn.exponent)) /
-                    (rd.radicand ** (m quo rd.exponent))) *
-                           (pn.poly ** (m quo sn.exponent))::F /
-                                    (pd.poly ** (m quo sd.exponent))::F]
-
-
-@
-\section{package ALGMANIP AlgebraicManipulations}
-<<package ALGMANIP AlgebraicManipulations>>=
-)abbrev package ALGMANIP AlgebraicManipulations
-++ Author: Manuel Bronstein
-++ Date Created: 28 Mar 1988
-++ Date Last Updated: 5 August 1993
-++ Description:
-++ AlgebraicManipulations provides functions to simplify and expand
-++ expressions involving algebraic operators.
-++ Keywords: algebraic, manipulation.
-AlgebraicManipulations(R, F): Exports == Implementation where
-  R : IntegralDomain
-  F : Join(Field, ExpressionSpace) with
-    numer  : $ -> SparseMultivariatePolynomial(R, Kernel $)
-	++ numer(x) \undocumented
-    denom  : $ -> SparseMultivariatePolynomial(R, Kernel $)
-	++ denom(x) \undocumented
-    coerce : SparseMultivariatePolynomial(R, Kernel $) -> $
-	++ coerce(x) \undocumented
-
-  N  ==> NonNegativeInteger
-  Z  ==> Integer
-  OP ==> BasicOperator
-  SY ==> Symbol
-  K  ==> Kernel F
-  P  ==> SparseMultivariatePolynomial(R, K)
-  RF ==> Fraction P
-  REC ==> Record(ker:List K, exponent: List Z)
-  ALGOP ==> "%alg"
-  NTHR  ==> "nthRoot"
-
-  Exports ==> with
-    rootSplit: F -> F
-      ++ rootSplit(f) transforms every radical of the form
-      ++ \spad{(a/b)**(1/n)} appearing in f into \spad{a**(1/n) / b**(1/n)}.
-      ++ This transformation is not in general valid for all
-      ++ complex numbers \spad{a} and b.
-    ratDenom  : F -> F
-      ++ ratDenom(f) rationalizes the denominators appearing in f
-      ++ by moving all the algebraic quantities into the numerators.
-    ratDenom  : (F, F) -> F
-      ++ ratDenom(f, a) removes \spad{a} from the denominators in f
-      ++ if \spad{a} is an algebraic kernel.
-    ratDenom  : (F, List F) -> F
-      ++ ratDenom(f, [a1,...,an]) removes the ai's which are
-      ++ algebraic kernels from the denominators in f.
-    ratDenom  : (F, List K) -> F
-      ++ ratDenom(f, [a1,...,an]) removes the ai's which are
-      ++ algebraic from the denominators in f.
-    ratPoly  : F -> SparseUnivariatePolynomial F
-      ++ ratPoly(f) returns a polynomial p such that p has no
-      ++ algebraic coefficients, and \spad{p(f) = 0}.
-    if R has Join(OrderedSet, GcdDomain, RetractableTo Integer)
-      and F has FunctionSpace(R) then
-        rootPower  : F -> F
-          ++ rootPower(f) transforms every radical power of the form
-          ++ \spad{(a**(1/n))**m} into a simpler form if \spad{m} and
-          ++ \spad{n} have a common factor.
-        rootProduct: F -> F
-          ++ rootProduct(f) combines every product of the form
-          ++ \spad{(a**(1/n))**m * (a**(1/s))**t} into a single power
-          ++ of a root of \spad{a}, and transforms every radical power
-          ++ of the form \spad{(a**(1/n))**m} into a simpler form.
-        rootSimp   : F -> F
-          ++ rootSimp(f) transforms every radical of the form
-          ++ \spad{(a * b**(q*n+r))**(1/n)} appearing in f into
-          ++ \spad{b**q * (a * b**r)**(1/n)}.
-          ++ This transformation is not in general valid for all
-          ++ complex numbers b.
-        rootKerSimp: (OP, F, N) -> F
-          ++ rootKerSimp(op,f,n) should be local but conditional.
-
-  Implementation ==> add
-    import PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,P,F)
-
-    innerRF    : (F, List K) -> F
-    rootExpand : K -> F
-    algkernels : List K -> List K
-    rootkernels: List K -> List K
-
-    dummy := kernel(new()$SY)$K
-
-    ratDenom x                == innerRF(x, algkernels tower x)
-    ratDenom(x:F, l:List K):F == innerRF(x, algkernels l)
-    ratDenom(x:F, y:F)        == ratDenom(x, [y])
-    ratDenom(x:F, l:List F)   == ratDenom(x, [retract(y)@K for y in l]$List(K))
-    algkernels l              == select_!(has?(operator #1, ALGOP), l)
-    rootkernels l             == select_!(is?(operator #1, NTHR::SY), l)
-
-    ratPoly x ==
-      numer univariate(denom(ratDenom inv(dummy::P::F - x))::F, dummy)
-
-    rootSplit x ==
-      lk := rootkernels tower x
-      eval(x, lk, [rootExpand k for k in lk])
-
-    rootExpand k ==
-      x  := first argument k
-      n  := second argument k
-      op := operator k
-      op(numer(x)::F, n) / op(denom(x)::F, n)
-
--- all the kernels in ll must be algebraic
-    innerRF(x, ll) ==
-      empty?(l := sort_!(#1 > #2, kernels x)$List(K)) or
-        empty? setIntersection(ll, tower x) => x
-      lk := empty()$List(K)
-      while not member?(k := first l, ll) repeat
-        lk := concat(k, lk)
-        empty?(l := rest l) =>
-          return eval(x, lk, [map(innerRF(#1, ll), kk) for kk in lk])
-      q := univariate(eval(x, lk,
-                 [map(innerRF(#1, ll), kk) for kk in lk]), k, minPoly k)
-      map(innerRF(#1, ll), q) (map(innerRF(#1, ll), k))
-
-    if R has Join(OrderedSet, GcdDomain, RetractableTo Integer)
-     and F has FunctionSpace(R) then
-      import PolynomialRoots(IndexedExponents K, K, R, P, F)
-
-      sroot  : K -> F
-      inroot : (OP, F, N) -> F
-      radeval: (P, K) -> F
-      breakup: List K -> List REC
-
-      if R has RadicalCategory then
-        rootKerSimp(op, x, n) ==
-          (r := retractIfCan(x)@Union(R, "failed")) case R =>
-             nthRoot(r::R, n)::F
-          inroot(op, x, n)
-      else
-        rootKerSimp(op, x, n) == inroot(op, x, n)
-
--- l is a list of nth-roots, returns a list of records of the form
--- [a**(1/n1),a**(1/n2),...], [n1,n2,...]]
--- such that the whole list covers l exactly
-      breakup l ==
-        empty? l => empty()
-        k := first l
-        a := first(arg := argument(k := first l))
-        n := retract(second arg)@Z
-        expo := empty()$List(Z)
-        others := same := empty()$List(K)
-        for kk in rest l repeat
-          if (a = first(arg := argument kk)) then
-            same := concat(kk, same)
-            expo := concat(retract(second arg)@Z, expo)
-          else others := concat(kk, others)
-        ll := breakup others
-        concat([concat(k, same), concat(n, expo)], ll)
-
-      rootProduct x ==
-        for rec in breakup rootkernels tower x repeat
-          k0 := first(l := rec.ker)
-          nx := numer x; dx := denom x
-          if empty? rest l then x := radeval(nx, k0) / radeval(dx, k0)
-          else
-            n  := lcm(rec.exponent)
-            k  := kernel(operator k0, [first argument k0, n::F], height k0)$K
-            lv := [monomial(1, k, (n quo m)::N) for m in rec.exponent]$List(P)
-            x  := radeval(eval(nx, l, lv), k) / radeval(eval(dx, l, lv), k)
-        x
-
-      rootPower x ==
-        for k in rootkernels tower x repeat
-          x := radeval(numer x, k) / radeval(denom x, k)
-        x
-
--- replaces (a**(1/n))**m in p by a power of a simpler radical of a if
--- n and m have a common factor
-      radeval(p, k) ==
-        a := first(arg := argument k)
-        n := (retract(second arg)@Integer)::NonNegativeInteger
-        ans:F := 0
-        q := univariate(p, k)
-        while (d := degree q) > 0 repeat
-          term :=
---            one?(g := gcd(d, n)) => monomial(1, k, d)
-            ((g := gcd(d, n)) = 1) => monomial(1, k, d)
-            monomial(1, kernel(operator k, [a,(n quo g)::F], height k), d quo g)
-          ans := ans + leadingCoefficient(q)::F * term::F
-          q := reductum q
-        leadingCoefficient(q)::F + ans
-
-      inroot(op, x, n) ==
---        one? x => x
-        (x = 1) => x
---        (x ^= -1) and (one?(num := numer x) or (num = -1)) =>
-        (x ^= -1) and (((num := numer x) = 1) or (num = -1)) =>
-          inv inroot(op, (num * denom x)::F, n)
-        (u := isExpt(x, op)) case "failed" => kernel(op, [x, n::F])
-        pr := u::Record(var:K, exponent:Integer)
-        q := pr.exponent /$Fraction(Z)
-                                (n * retract(second argument(pr.var))@Z)
-        qr := divide(numer q, denom q)
-        x  := first argument(pr.var)
-        x ** qr.quotient * rootKerSimp(op,x,denom(q)::N) ** qr.remainder
-
-      sroot k ==
-        pr := froot(first(arg := argument k),(retract(second arg)@Z)::N)
-        pr.coef * rootKerSimp(operator k, pr.radicand, pr.exponent)
-
-      rootSimp x ==
-        lk := rootkernels tower x
-        eval(x, lk, [sroot k for k in lk])
-
-@
-\section{package SIMPAN SimplifyAlgebraicNumberConvertPackage}
-<<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>=
-)abbrev package SIMPAN SimplifyAlgebraicNumberConvertPackage
-++ Package to allow simplify to be called on AlgebraicNumbers
-++ by converting to EXPR(INT)
-SimplifyAlgebraicNumberConvertPackage(): with
-  simplify: AlgebraicNumber -> Expression(Integer)
-	++ simplify(an) applies simplifications to an
- == add
-  simplify(a:AlgebraicNumber) ==
-    simplify(a::Expression(Integer))$TranscendentalManipulations(Integer, Expression Integer)
-
-@
-\section{package TRMANIP TranscendentalManipulations}
-<<package TRMANIP TranscendentalManipulations>>=
-)abbrev package TRMANIP TranscendentalManipulations
-++ Transformations on transcendental objects
-++ Author: Bob Sutor, Manuel Bronstein
-++ Date Created: Way back
-++ Date Last Updated: 22 January 1996, added simplifyLog MCD.
-++ Description:
-++   TranscendentalManipulations provides functions to simplify and
-++   expand expressions involving transcendental operators.
-++ Keywords: transcendental, manipulation.
-TranscendentalManipulations(R, F): Exports == Implementation where
-  R : Join(OrderedSet, GcdDomain)
-  F : Join(FunctionSpace R, TranscendentalFunctionCategory)
-
-  Z       ==> Integer
-  K       ==> Kernel F
-  P       ==> SparseMultivariatePolynomial(R, K)
-  UP      ==> SparseUnivariatePolynomial P
-  POWER   ==> "%power"::Symbol
-  POW     ==> Record(val: F,exponent: Z)
-  PRODUCT ==> Record(coef : Z, var : K)
-  FPR     ==> Fraction Polynomial R
-
-  Exports ==> with
-    expand     : F -> F
-      ++ expand(f) performs the following expansions on f:\begin{items}
-      ++ \item 1. logs of products are expanded into sums of logs,
-      ++ \item 2. trigonometric and hyperbolic trigonometric functions
-      ++ of sums are expanded into sums of products of trigonometric
-      ++ and hyperbolic trigonometric functions.
-      ++ \item 3. formal powers of the form \spad{(a/b)**c} are expanded into
-      ++ \spad{a**c * b**(-c)}.
-      ++ \end{items}
-    simplify   : F -> F
-      ++ simplify(f) performs the following simplifications on f:\begin{items}
-      ++ \item 1. rewrites trigs and hyperbolic trigs in terms
-      ++ of \spad{sin} ,\spad{cos}, \spad{sinh}, \spad{cosh}.
-      ++ \item 2. rewrites \spad{sin**2} and \spad{sinh**2} in terms
-      ++ of \spad{cos} and \spad{cosh},
-      ++ \item 3. rewrites \spad{exp(a)*exp(b)} as \spad{exp(a+b)}.
-      ++ \item 4. rewrites \spad{(a**(1/n))**m * (a**(1/s))**t} as a single
-      ++ power of a single radical of \spad{a}.
-      ++ \end{items}
-    htrigs     : F -> F
-      ++ htrigs(f) converts all the exponentials in f into
-      ++ hyperbolic sines and cosines.
-    simplifyExp: F -> F
-      ++ simplifyExp(f) converts every product \spad{exp(a)*exp(b)}
-      ++ appearing in f into \spad{exp(a+b)}.
-    simplifyLog : F -> F
-      ++ simplifyLog(f) converts every \spad{log(a) - log(b)} appearing in f
-      ++ into \spad{log(a/b)}, every \spad{log(a) + log(b)} into \spad{log(a*b)}
-      ++ and every \spad{n*log(a)} into \spad{log(a^n)}.
-    expandPower: F -> F
-      ++ expandPower(f) converts every power \spad{(a/b)**c} appearing
-      ++ in f into \spad{a**c * b**(-c)}.
-    expandLog  : F -> F
-      ++ expandLog(f) converts every \spad{log(a/b)} appearing in f into
-      ++ \spad{log(a) - log(b)}, and every \spad{log(a*b)} into
-      ++ \spad{log(a) + log(b)}..
-    cos2sec    : F -> F
-      ++ cos2sec(f) converts every \spad{cos(u)} appearing in f into
-      ++ \spad{1/sec(u)}.
-    cosh2sech  : F -> F
-      ++ cosh2sech(f) converts every \spad{cosh(u)} appearing in f into
-      ++ \spad{1/sech(u)}.
-    cot2trig   : F -> F
-      ++ cot2trig(f) converts every \spad{cot(u)} appearing in f into
-      ++ \spad{cos(u)/sin(u)}.
-    coth2trigh : F -> F
-      ++ coth2trigh(f) converts every \spad{coth(u)} appearing in f into
-      ++ \spad{cosh(u)/sinh(u)}.
-    csc2sin    : F -> F
-      ++ csc2sin(f) converts every \spad{csc(u)} appearing in f into
-      ++ \spad{1/sin(u)}.
-    csch2sinh  : F -> F
-      ++ csch2sinh(f) converts every \spad{csch(u)} appearing in f into
-      ++ \spad{1/sinh(u)}.
-    sec2cos    : F -> F
-      ++ sec2cos(f) converts every \spad{sec(u)} appearing in f into
-      ++ \spad{1/cos(u)}.
-    sech2cosh  : F -> F
-      ++ sech2cosh(f) converts every \spad{sech(u)} appearing in f into
-      ++ \spad{1/cosh(u)}.
-    sin2csc    : F -> F
-      ++ sin2csc(f) converts every \spad{sin(u)} appearing in f into
-      ++ \spad{1/csc(u)}.
-    sinh2csch  : F -> F
-      ++ sinh2csch(f) converts every \spad{sinh(u)} appearing in f into
-      ++ \spad{1/csch(u)}.
-    tan2trig   : F -> F
-      ++ tan2trig(f) converts every \spad{tan(u)} appearing in f into
-      ++ \spad{sin(u)/cos(u)}.
-    tanh2trigh : F -> F
-      ++ tanh2trigh(f) converts every \spad{tanh(u)} appearing in f into
-      ++ \spad{sinh(u)/cosh(u)}.
-    tan2cot    : F -> F
-      ++ tan2cot(f) converts every \spad{tan(u)} appearing in f into
-      ++ \spad{1/cot(u)}.
-    tanh2coth  : F -> F
-      ++ tanh2coth(f) converts every \spad{tanh(u)} appearing in f into
-      ++ \spad{1/coth(u)}.
-    cot2tan    : F -> F
-      ++ cot2tan(f) converts every \spad{cot(u)} appearing in f into
-      ++ \spad{1/tan(u)}.
-    coth2tanh  : F -> F
-      ++ coth2tanh(f) converts every \spad{coth(u)} appearing in f into
-      ++ \spad{1/tanh(u)}.
-    removeCosSq: F -> F
-      ++ removeCosSq(f) converts every \spad{cos(u)**2} appearing in f into
-      ++ \spad{1 - sin(x)**2}, and also reduces higher
-      ++ powers of \spad{cos(u)} with that formula.
-    removeSinSq: F -> F
-      ++ removeSinSq(f) converts every \spad{sin(u)**2} appearing in f into
-      ++ \spad{1 - cos(x)**2}, and also reduces higher powers of
-      ++ \spad{sin(u)} with that formula.
-    removeCoshSq:F -> F
-      ++ removeCoshSq(f) converts every \spad{cosh(u)**2} appearing in f into
-      ++ \spad{1 - sinh(x)**2}, and also reduces higher powers of
-      ++ \spad{cosh(u)} with that formula.
-    removeSinhSq:F -> F
-      ++ removeSinhSq(f) converts every \spad{sinh(u)**2} appearing in f into
-      ++ \spad{1 - cosh(x)**2}, and also reduces higher powers
-      ++ of \spad{sinh(u)} with that formula.
-    if R has PatternMatchable(R) and R has ConvertibleTo(Pattern(R)) and F has ConvertibleTo(Pattern(R)) and F has PatternMatchable R then
-      expandTrigProducts : F -> F
-        ++ expandTrigProducts(e) replaces \axiom{sin(x)*sin(y)} by
-        ++ \spad{(cos(x-y)-cos(x+y))/2}, \axiom{cos(x)*cos(y)} by
-        ++ \spad{(cos(x-y)+cos(x+y))/2}, and \axiom{sin(x)*cos(y)} by
-        ++ \spad{(sin(x-y)+sin(x+y))/2}.  Note that this operation uses
-        ++ the pattern matcher and so is relatively expensive.  To avoid
-        ++ getting into an infinite loop the transformations are applied
-        ++ at most ten times.
-
-  Implementation ==> add
-    import FactoredFunctions(P)
-    import PolynomialCategoryLifting(IndexedExponents K, K, R, P, F)
-    import
-      PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,P,F)
-
-    smpexp    : P -> F
-    termexp   : P -> F
-    exlog     : P -> F
-    smplog    : P -> F
-    smpexpand : P -> F
-    smp2htrigs: P -> F
-    kerexpand : K -> F
-    expandpow : K -> F
-    logexpand : K -> F
-    sup2htrigs: (UP, F) -> F
-    supexp    : (UP, F, F, Z) -> F
-    ueval     : (F, String, F -> F) -> F
-    ueval2    : (F, String, F -> F) -> F
-    powersimp : (P, List K) -> F
-    t2t       : F -> F
-    c2t       : F -> F
-    c2s       : F -> F
-    s2c       : F -> F
-    s2c2      : F -> F
-    th2th     : F -> F
-    ch2th     : F -> F
-    ch2sh     : F -> F
-    sh2ch     : F -> F
-    sh2ch2    : F -> F
-    simplify0 : F -> F
-    simplifyLog1 : F -> F
-    logArgs   : List F -> F
-
-    import F
-    import List F
-
-    if R has PatternMatchable R and R has ConvertibleTo Pattern R and F has ConvertibleTo(Pattern(R)) and F has PatternMatchable R then
-      XX : F := coerce new()$Symbol
-      YY : F := coerce new()$Symbol
-      sinCosRule : RewriteRule(R,R,F) :=
-        rule(cos(XX)*sin(YY),(sin(XX+YY)-sin(XX-YY))/2::F)
-      sinSinRule : RewriteRule(R,R,F) :=
-        rule(sin(XX)*sin(YY),(cos(XX-YY)-cos(XX+YY))/2::F)
-      cosCosRule : RewriteRule(R,R,F) :=
-        rule(cos(XX)*cos(YY),(cos(XX-YY)+cos(XX+YY))/2::F)
-      expandTrigProducts(e:F):F ==
-        applyRules([sinCosRule,sinSinRule,cosCosRule],e,10)$ApplyRules(R,R,F)
-
-    logArgs(l:List F):F ==
-      -- This function will take a list of Expressions (implicitly a sum) and
-      -- add them up, combining log terms.  It also replaces n*log(x) by
-      -- log(x^n).
-      import K
-      sum  : F := 0
-      arg  : F := 1
-      for term in l repeat
-        is?(term,"log"::Symbol) =>
-          arg := arg * simplifyLog(first(argument(first(kernels(term)))))
-        -- Now look for multiples, including negative ones.
-        prod : Union(PRODUCT, "failed") := isMult(term)
-        (prod case PRODUCT) and is?(prod.var,"log"::Symbol) =>
-            arg := arg * simplifyLog ((first argument(prod.var))**(prod.coef))
-        sum := sum+term
-      sum+log(arg)
-    
-    simplifyLog(e:F):F ==
-      simplifyLog1(numerator e)/simplifyLog1(denominator e)
-
-    simplifyLog1(e:F):F ==
-      freeOf?(e,"log"::Symbol) => e
-
-      -- Check for n*log(u)
-      prod : Union(PRODUCT, "failed") := isMult(e)
-      (prod case PRODUCT) and is?(prod.var,"log"::Symbol) =>
-        log simplifyLog ((first argument(prod.var))**(prod.coef))
-      
-      termList : Union(List(F),"failed") := isTimes(e)
-      -- I'm using two variables, termList and terms, to work round a
-      -- bug in the old compiler.
-      not (termList case "failed") =>
-        -- We want to simplify each log term in the product and then multiply
-        -- them together.  However, if there is a constant or arithmetic
-        -- expression (i.e. somwthing which looks like a Polynomial) we would
-        -- like to combine it with a log term.
-        terms :List F := [simplifyLog(term) for term in termList::List(F)]
-        exprs :List F := []
-        for i in 1..#terms repeat
-          if retractIfCan(terms.i)@Union(FPR,"failed") case FPR then
-            exprs := cons(terms.i,exprs)
-            terms := delete!(terms,i)
-        if not empty? exprs then
-          foundLog := false
-          i : NonNegativeInteger := 0
-          while (not(foundLog) and (i < #terms)) repeat
-            i := i+1
-            if is?(terms.i,"log"::Symbol) then
-              args : List F := argument(retract(terms.i)@K)
-              setelt(terms,i, log simplifyLog1(first(args)**(*/exprs)))
-              foundLog := true
-          -- The next line deals with a situation which shouldn't occur,
-          -- since we have checked whether we are freeOf log already.
-          if not foundLog then terms := append(exprs,terms)
-        */terms
-    
-      terms : Union(List(F),"failed") := isPlus(e)
-      not (terms case "failed") => logArgs(terms) 
-
-      expt : Union(POW, "failed") := isPower(e)
---      (expt case POW) and not one? expt.exponent =>
-      (expt case POW) and not (expt.exponent = 1) =>
-        simplifyLog(expt.val)**(expt.exponent)
-    
-      kers : List K := kernels e
---      not(one?(#kers)) => e -- Have a constant
-      not(((#kers) = 1)) => e -- Have a constant
-      kernel(operator first kers,[simplifyLog(u) for u in argument first kers])
-
-
-    if R has RetractableTo Integer then
-      simplify x == rootProduct(simplify0 x)$AlgebraicManipulations(R,F)
-
-    else simplify x == simplify0 x
-
-    expandpow k ==
-      a := expandPower first(arg := argument k)
-      b := expandPower second arg
---      ne:F := (one? numer a => 1; numer(a)::F ** b)
-      ne:F := (((numer a) = 1) => 1; numer(a)::F ** b)
---      de:F := (one? denom a => 1; denom(a)::F ** (-b))
-      de:F := (((denom a) = 1) => 1; denom(a)::F ** (-b))
-      ne * de
-
-    termexp p ==
-      exponent:F := 0
-      coef := (leadingCoefficient p)::P
-      lpow := select(is?(#1, POWER)$K, lk := variables p)$List(K)
-      for k in lk repeat
-        d := degree(p, k)
-        if is?(k, "exp"::Symbol) then
-          exponent := exponent + d * first argument k
-        else if not is?(k, POWER) then
-          -- Expand arguments to functions as well ... MCD 23/1/97
-          --coef := coef * monomial(1, k, d)
-          coef := coef * monomial(1, kernel(operator k,[simplifyExp u for u in argument k], height k), d)
-      coef::F * exp exponent * powersimp(p, lpow)
-
-    expandPower f ==
-      l := select(is?(#1, POWER)$K, kernels f)$List(K)
-      eval(f, l, [expandpow k for k in l])
-
--- l is a list of pure powers appearing as kernels in p
-    powersimp(p, l) ==
-      empty? l => 1
-      k := first l                           -- k = a**b
-      a := first(arg := argument k)
-      exponent := degree(p, k) * second arg
-      empty?(lk := select(a = first argument #1, rest l)) =>
-        (a ** exponent) * powersimp(p, rest l)
-      for k0 in lk repeat
-        exponent := exponent + degree(p, k0) * second argument k0
-      (a ** exponent) * powersimp(p, setDifference(rest l, lk))
-
-    t2t x         == sin(x) / cos(x)
-    c2t x         == cos(x) / sin(x)
-    c2s x         == inv sin x
-    s2c x         == inv cos x
-    s2c2 x        == 1 - cos(x)**2
-    th2th x       == sinh(x) / cosh(x)
-    ch2th x       == cosh(x) / sinh(x)
-    ch2sh x       == inv sinh x
-    sh2ch x       == inv cosh x
-    sh2ch2 x      == cosh(x)**2 - 1
-    ueval(x, s,f) == eval(x, s::Symbol, f)
-    ueval2(x,s,f) == eval(x, s::Symbol, 2, f)
-    cos2sec x     == ueval(x, "cos", inv sec #1)
-    sin2csc x     == ueval(x, "sin", inv csc #1)
-    csc2sin x     == ueval(x, "csc", c2s)
-    sec2cos x     == ueval(x, "sec", s2c)
-    tan2cot x     == ueval(x, "tan", inv cot #1)
-    cot2tan x     == ueval(x, "cot", inv tan #1)
-    tan2trig x    == ueval(x, "tan", t2t)
-    cot2trig x    == ueval(x, "cot", c2t)
-    cosh2sech x   == ueval(x, "cosh", inv sech #1)
-    sinh2csch x   == ueval(x, "sinh", inv csch #1)
-    csch2sinh x   == ueval(x, "csch", ch2sh)
-    sech2cosh x   == ueval(x, "sech", sh2ch)
-    tanh2coth x   == ueval(x, "tanh", inv coth #1)
-    coth2tanh x   == ueval(x, "coth", inv tanh #1)
-    tanh2trigh x  == ueval(x, "tanh", th2th)
-    coth2trigh x  == ueval(x, "coth", ch2th)
-    removeCosSq x == ueval2(x, "cos", 1 - (sin #1)**2)
-    removeSinSq x == ueval2(x, "sin", s2c2)
-    removeCoshSq x== ueval2(x, "cosh", 1 + (sinh #1)**2)
-    removeSinhSq x== ueval2(x, "sinh", sh2ch2)
-    expandLog x   == smplog(numer x) / smplog(denom x)
-    simplifyExp x == (smpexp numer x) / (smpexp denom x)
-    expand x      == (smpexpand numer x) / (smpexpand denom x)
-    smpexpand p   == map(kerexpand, #1::F, p)
-    smplog p      == map(logexpand, #1::F, p)
-    smp2htrigs p  == map(htrigs(#1::F), #1::F, p)
-
-    htrigs f ==
-      (m := mainKernel f) case "failed" => f
-      op  := operator(k := m::K)
-      arg := [htrigs x for x in argument k]$List(F)
-      num := univariate(numer f, k)
-      den := univariate(denom f, k)
-      is?(op, "exp"::Symbol) =>
-        g1 := cosh(a := first arg) + sinh(a)
-        g2 := cosh(a) - sinh(a)
-        supexp(num,g1,g2,b:= (degree num)::Z quo 2)/supexp(den,g1,g2,b)
-      sup2htrigs(num, g1:= op arg) / sup2htrigs(den, g1)
-
-    supexp(p, f1, f2, bse) ==
-      ans:F := 0
-      while p ^= 0 repeat
-        g := htrigs(leadingCoefficient(p)::F)
-        if ((d := degree(p)::Z - bse) >= 0) then
-             ans := ans + g * f1 ** d
-        else ans := ans + g * f2 ** (-d)
-        p := reductum p
-      ans
-
-    sup2htrigs(p, f) ==
-      (map(smp2htrigs, p)$SparseUnivariatePolynomialFunctions2(P, F)) f
-
-    exlog p == +/[r.coef * log(r.logand::F) for r in log squareFree p]
-
-    logexpand k ==
-      nullary?(op := operator k) => k::F
-      is?(op, "log"::Symbol) =>
-         exlog(numer(x := expandLog first argument k)) - exlog denom x
-      op [expandLog x for x in argument k]$List(F)
-
-    kerexpand k ==
-      nullary?(op := operator k) => k::F
-      is?(op, POWER) => expandpow k
-      arg := first argument k
-      is?(op, "sec"::Symbol) => inv expand cos arg
-      is?(op, "csc"::Symbol) => inv expand sin arg
-      is?(op, "log"::Symbol) =>
-         exlog(numer(x := expand arg)) - exlog denom x
-      num := numer arg
-      den := denom arg
-      (b := (reductum num) / den) ^= 0 =>
-        a := (leadingMonomial num) / den
-        is?(op, "exp"::Symbol) => exp(expand a) * expand(exp b)
-        is?(op, "sin"::Symbol) =>
-           sin(expand a) * expand(cos b) + cos(expand a) * expand(sin b)
-        is?(op, "cos"::Symbol) =>
-           cos(expand a) * expand(cos b) - sin(expand a) * expand(sin b)
-        is?(op, "tan"::Symbol) =>
-          ta := tan expand a
-          tb := expand tan b
-          (ta + tb) / (1 - ta * tb)
-        is?(op, "cot"::Symbol) =>
-          cta := cot expand a
-          ctb := expand cot b
-          (cta * ctb - 1) / (ctb + cta)
-        op [expand x for x in argument k]$List(F)
-      op [expand x for x in argument k]$List(F)
-
-    smpexp p ==
-      ans:F := 0
-      while p ^= 0 repeat
-        ans := ans + termexp leadingMonomial p
-        p   := reductum p
-      ans
-
-    -- this now works in 3 passes over the expression:
-    --   pass1 rewrites trigs and htrigs in terms of sin,cos,sinh,cosh
-    --   pass2 rewrites sin**2 and sinh**2 in terms of cos and cosh.
-    --   pass3 groups exponentials together
-    simplify0 x ==
-      simplifyExp eval(eval(x,
-          ["tan"::Symbol,"cot"::Symbol,"sec"::Symbol,"csc"::Symbol,
-           "tanh"::Symbol,"coth"::Symbol,"sech"::Symbol,"csch"::Symbol],
-              [t2t,c2t,s2c,c2s,th2th,ch2th,sh2ch,ch2sh]),
-                ["sin"::Symbol, "sinh"::Symbol], [2, 2], [s2c2, sh2ch2])
-
-@
-\section{License}
-<<license>>=
---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.
-@
-<<*>>=
-<<license>>
-
--- SPAD files for the functional world should be compiled in the
--- following order:
---
---   op  kl  function  funcpkgs  MANIP  combfunc
---   algfunc  elemntry  constant  funceval  fe
-
-
-<<package FACTFUNC FactoredFunctions>>
-<<package POLYROOT PolynomialRoots>>
-<<package ALGMANIP AlgebraicManipulations>>
-<<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>
-<<package TRMANIP TranscendentalManipulations>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/mantepse.spad.pamphlet b/src/algebra/mantepse.spad.pamphlet
deleted file mode 100644
index b6c9ba3..0000000
--- a/src/algebra/mantepse.spad.pamphlet
+++ /dev/null
@@ -1,2851 +0,0 @@
-\documentclass{article}
-\usepackage{axiom,amsthm,amsmath}
-\newtheorem{ToDo}{ToDo}[section]
-
-\newcommand{\Axiom}{{\tt Axiom}}
-\newcommand{\Rate}{{\tt Rate}}
-\newcommand{\GFUN}{{\tt GFUN}}
-\begin{document}
-\title{mantepse.spad}
-\author{Martin Rubey}
-\maketitle
-\begin{abstract}
-  The packages defined in this file enable {\Axiom} to guess formulas for
-  sequences of, for example, rational numbers or rational functions, given the
-  first few terms.  It extends and complements Christian Krattenthaler's
-  program \Rate\ and the relevant parts of Bruno Salvy and Paul Zimmermann's
-  \GFUN.
-\end{abstract}
-\tableofcontents
-\section{package UFPS1 UnivariateFormalPowerSeriesFunctions}
-<<package UFPS1 UnivariateFormalPowerSeriesFunctions>>=
-)abbrev package UFPS1 UnivariateFormalPowerSeriesFunctions
-UnivariateFormalPowerSeriesFunctions(Coef: Ring): Exports == Implementation 
-  where
-
-    UFPS ==> UnivariateFormalPowerSeries Coef
-
-    Exports == with
-
-      hadamard: (UFPS, UFPS) -> UFPS
-
-    Implementation == add
-
-      hadamard(f, g) ==
-        series map(#1*#2, coefficients f, coefficients g)
-                  $StreamFunctions3(Coef, Coef, Coef) 
-
-@
-%$
-
-
-\section{package GOPT0 GuessOptionFunctions0}
-<<package GOPT0 GuessOptionFunctions0>>=
-)abbrev package GOPT0 GuessOptionFunctions0
-++ Author: Martin Rubey 
-++ Description: GuessOptionFunctions0 provides operations that extract the
-++ values of options for \spadtype{Guess}.
-GuessOptionFunctions0(): Exports == Implementation where 
-
-  LGOPT ==> List GuessOption
-
-  Exports == SetCategory with
-
-    maxLevel: LGOPT -> Integer
-      ++ maxLevel returns the specified maxLevel or -1 as default.
-
-    maxPower: LGOPT -> Integer
-      ++ maxPower returns the specified maxPower or -1 as default.
-
-    maxDerivative: LGOPT -> Integer
-      ++ maxDerivative returns the specified maxDerivative or -1 as default.
-
-    maxShift: LGOPT -> Integer
-      ++ maxShift returns the specified maxShift or -1 as default.
-
-    maxDegree: LGOPT -> Integer
-      ++ maxDegree returns the specified maxDegree or -1 as default.
-
-    allDegrees: LGOPT -> Boolean
-      ++ allDegrees returns whether all possibilities of the degree vector
-      ++ should be tried, the default being false.
-
-    safety: LGOPT -> NonNegativeInteger
-      ++ safety returns the specified safety or 1 as default.
-
-    one: LGOPT -> Boolean
-      ++ one returns whether we need only one solution, default being true.
-
-    homogeneous: LGOPT -> Boolean
-      ++ homogeneous returns whether we allow only homogeneous algebraic
-      ++ differential equations, default being false
-
-    functionName: LGOPT -> Symbol
-      ++ functionName returns the name of the function given by the algebraic
-      ++ differential equation, default being f
-
-    variableName: LGOPT -> Symbol
-      ++ variableName returns the name of the variable used in by the
-      ++ algebraic differential equation, default being x
-
-    indexName: LGOPT -> Symbol
-      ++ indexName returns the name of the index variable used for the
-      ++ formulas, default being n
-
-    displayAsGF: LGOPT -> Boolean
-      ++ displayAsGF specifies whether the result is a generating function
-      ++ or a recurrence. This option should not be set by the user, but rather
-      ++ by the HP-specification, therefore, there is no default.
-
-    debug: LGOPT -> Boolean
-      ++ debug returns whether we want additional output on the progress,
-      ++ default being false
-
-  Implementation == add
-
-    maxLevel l ==
-      if (opt := option(l, "maxLevel" :: Symbol)) case "failed" then
-        -1
-      else 
-        retract(opt :: Any)$AnyFunctions1(Integer)
-
-    maxDerivative l ==
-      if (opt := option(l, "maxDerivative" :: Symbol)) case "failed" then
-        -1
-      else 
-        retract(opt :: Any)$AnyFunctions1(Integer)
-
-    maxShift l == maxDerivative l
-
-    maxDegree l ==
-      if (opt := option(l, "maxDegree" :: Symbol)) case "failed" then
-        -1
-      else 
-        retract(opt :: Any)$AnyFunctions1(Integer)
-
-    allDegrees l ==
-      if (opt := option(l, "allDegrees" :: Symbol)) case "failed" then
-        false
-      else 
-        retract(opt :: Any)$AnyFunctions1(Boolean)
-
-    maxPower l ==
-      if (opt := option(l, "maxPower" :: Symbol)) case "failed" then
-        -1
-      else 
-        retract(opt :: Any)$AnyFunctions1(Integer)
-
-    safety l ==
-      if (opt := option(l, "safety" :: Symbol)) case "failed" then
-        1$NonNegativeInteger
-      else
-        retract(opt :: Any)$AnyFunctions1(Integer)::NonNegativeInteger
-
-    one l ==
-      if (opt := option(l, "one" :: Symbol)) case "failed" then
-        true
-      else 
-        retract(opt :: Any)$AnyFunctions1(Boolean)
-
-    debug l ==
-      if (opt := option(l, "debug" :: Symbol)) case "failed" then
-        false
-      else 
-        retract(opt :: Any)$AnyFunctions1(Boolean)
-
-    homogeneous l ==
-      if (opt := option(l, "homogeneous" :: Symbol)) case "failed" then
-        false
-      else 
-        retract(opt :: Any)$AnyFunctions1(Boolean)
-
-    variableName l ==
-      if (opt := option(l, "variableName" :: Symbol)) case "failed" then
-        "x" :: Symbol
-      else 
-        retract(opt :: Any)$AnyFunctions1(Symbol)
-
-    functionName l ==
-      if (opt := option(l, "functionName" :: Symbol)) case "failed" then
-        "f" :: Symbol
-      else 
-        retract(opt :: Any)$AnyFunctions1(Symbol)
-
-    indexName l ==
-      if (opt := option(l, "indexName" :: Symbol)) case "failed" then
-        "n" :: Symbol
-      else 
-        retract(opt :: Any)$AnyFunctions1(Symbol)
-
-    displayAsGF l ==
-      if (opt := option(l, "displayAsGF" :: Symbol)) case "failed" then
-        error "GuessOption: displayAsGF not set"
-      else 
-        retract(opt :: Any)$AnyFunctions1(Boolean)
-
-@
-
-\section{package GUESS Guess}
-<<package GUESS Guess>>=
-)abbrev package GUESS Guess
-++ Author: Martin Rubey
-++ Description: This package implements guessing of sequences. Packages for the
-++ most common cases are provided as \spadtype{GuessInteger},
-++ \spadtype{GuessPolynomial}, etc.
-Guess(F, S, EXPRR, R, retract, coerce): Exports == Implementation where
-    F: Field                                 -- zB.: FRAC POLY PF 5
--- in F we interpolate und check 
-
-    S: GcdDomain
-
--- in guessExpRat I would like to determine the roots of polynomials in F. When
--- F is a quotientfield, I can get rid of the denominator.  In this case F is
--- roughly QFCAT S
-
-    R: Join(OrderedSet, IntegralDomain)      -- zB.: FRAC POLY INT
-
--- results are given as elements of EXPRR
---    EXPRR: Join(ExpressionSpace, IntegralDomain,
-    EXPRR: Join(FunctionSpace Integer, IntegralDomain,
-                RetractableTo R, RetractableTo Symbol, 
-                RetractableTo Integer, CombinatorialOpsCategory,
-                PartialDifferentialRing Symbol) with
-              _* : (%,%) -> %
-              _/ : (%,%) -> %
-              _*_* : (%,%) -> %
-              numerator : % -> %
-              denominator : % -> %
-              ground? : % -> Boolean
-
-                                             -- zB.: EXPR INT
--- EXPR FRAC POLY INT is forbidden. Thus i cannot just use EXPR R
-
--- EXPRR exists, in case at some point there is support for EXPR PF 5.
-
-
--- the following I really would like to get rid of
-
-    retract: R -> F                          -- zB.: i+->i
-    coerce: F -> EXPRR                       -- zB.: i+->i
--- attention: EXPRR ~= EXPR R
-
-    LGOPT ==> List GuessOption
-    GOPT0 ==> GuessOptionFunctions0
-
-    NNI ==> NonNegativeInteger
-    PI ==> PositiveInteger
-    EXPRI ==> Expression Integer
-    GUESSRESULT ==> List Record(function: EXPRR, order: NNI)
-
-    UFPSF ==> UnivariateFormalPowerSeries F
-    UFPS1 ==> UnivariateFormalPowerSeriesFunctions
-
-    UFPSS ==> UnivariateFormalPowerSeries S
-
-    SUP ==> SparseUnivariatePolynomial
-
-    UFPSSUPF ==> UnivariateFormalPowerSeries SUP F
-
-    FFFG ==> FractionFreeFastGaussian
-    FFFGF ==> FractionFreeFastGaussianFractions
-
--- CoeffAction
-    DIFFSPECA ==> (NNI, NNI, SUP S) -> S
-
-    DIFFSPECAF ==> (NNI, NNI, UFPSSUPF) -> SUP F
-
-    DIFFSPECAX ==> (NNI, Symbol, EXPRR) -> EXPRR
-
--- the diagonal of the C-matrix
-    DIFFSPECC ==> NNI -> List S
-
-
-    HPSPEC ==> Record(guessStream:  UFPSF -> Stream UFPSF,
-                      degreeStream: Stream NNI,
-                      testStream:   UFPSSUPF -> Stream UFPSSUPF, 
-                      exprStream:   (EXPRR, Symbol) -> Stream EXPRR,
-                      A:  DIFFSPECA,
-                      AF: DIFFSPECAF,
-                      AX: DIFFSPECAX,
-                      C:  DIFFSPECC)
-
--- note that empty?(guessStream.o) has to return always. In other words, if the
--- stream is finite, empty? should recognize it.
-
-    DIFFSPECN ==> EXPRR -> EXPRR             -- eg.: i+->q^i
-
-    GUESSER ==> (List F, LGOPT) -> GUESSRESULT
-
-    FSUPS ==> Fraction SUP S
-    FSUPF ==> Fraction SUP F
-
-    V ==> OrderedVariableList(['a1, 'A])
-    POLYF ==> SparseMultivariatePolynomial(F, V)
-    FPOLYF ==> Fraction POLYF
-    FSUPFPOLYF ==> Fraction SUP FPOLYF
-    POLYS ==> SparseMultivariatePolynomial(S, V)
-    FPOLYS ==> Fraction POLYS
-    FSUPFPOLYS ==> Fraction SUP FPOLYS
-
-@
-
-The following should be commented out when not debugging, see also
-Section~\ref{sec:Hermite-Pade}.
-
-<<package GUESS Guess>>=
-    --@<<implementation: Guess - Hermite-Pade - Types for Operators>>
-    -- EXT ==> (Integer, V, V) -> FPOLYS
-    -- EXTEXPR ==> (Symbol, F, F) -> EXPRR
-@
-
-<<package GUESS Guess>>=
-    Exports == with
-
-        guess: List F -> GUESSRESULT
-          ++ \spad{guess l} applies recursively \spadfun{guessRec} and
-          ++ \spadfun{guessADE} to the successive differences and quotients of
-          ++ the list. Default options as described in
-          ++ \spadtype{GuessOptionFunctions0} are used.
-
-        guess: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guess(l, options)} applies recursively \spadfun{guessRec}
-          ++ and \spadfun{guessADE} to the successive differences and quotients
-          ++ of the list. The given options are used.
-
-        guess: (List F, List GUESSER, List Symbol) -> GUESSRESULT
-          ++ \spad{guess(l, guessers, ops)} applies recursively the given
-          ++ guessers to the successive differences if ops contains the symbol
-          ++ guessSum and quotients if ops contains the symbol guessProduct to
-          ++ the list. Default options as described in
-          ++ \spadtype{GuessOptionFunctions0} are used.
-
-        guess: (List F, List GUESSER, List Symbol, LGOPT) -> GUESSRESULT
-          ++ \spad{guess(l, guessers, ops)} applies recursively the given
-          ++ guessers to the successive differences if ops contains the symbol
-          ++ \spad{guessSum} and quotients if ops contains the symbol
-          ++ \spad{guessProduct} to the list. The given options are used.
-
-        guessExpRat: List F -> GUESSRESULT
-          ++ \spad{guessExpRat l} tries to find a function of the form 
-          ++ n+->(a+b n)^n r(n), where r(n) is a rational function, that fits
-          ++ l. 
-
-        guessExpRat: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessExpRat(l, options)} tries to find a function of the
-          ++ form n+->(a+b n)^n r(n), where r(n) is a rational function, that
-          ++ fits l. 
-
-        guessBinRat: List F -> GUESSRESULT
-          ++ \spad{guessBinRat(l, options)} tries to find a function of the
-          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
-          ++ function, that fits l. 
-
-        guessBinRat: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessBinRat(l, options)} tries to find a function of the
-          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
-          ++ function, that fits l. 
-
-        if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-            guessExpRat: Symbol -> GUESSER
-              ++ \spad{guessExpRat q} returns a guesser that tries to find a
-              ++ function of the form n+->(a+b q^n)^n r(q^n), where r(q^n) is a
-              ++ q-rational function, that fits l.
-
-            guessBinRat: Symbol -> GUESSER
-              ++ \spad{guessBinRat q} returns a guesser that tries to find a
-              ++ function of the form n+->qbinomial(a+b n, n) r(n), where r(q^n) is a
-              ++ q-rational function, that fits l.
-
-        guessHP: (LGOPT -> HPSPEC) -> GUESSER
-          ++ \spad{guessHP f} constructs an operation that applies Hermite-Pade
-          ++ approximation to the series generated by the given function f.
-
-        guessADE: List F -> GUESSRESULT
-          ++ \spad{guessADE l} tries to find an algebraic differential equation
-          ++ for a generating function whose first Taylor coefficients are
-          ++ given by l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}.
-
-        guessADE: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessADE(l, options)} tries to find an algebraic
-          ++ differential equation for a generating function whose first Taylor
-          ++ coefficients are given by l, using the given options.
-
-        guessAlg: List F -> GUESSRESULT
-          ++ \spad{guessAlg l} tries to find an algebraic equation for a
-          ++ generating function whose first Taylor coefficients are given by
-          ++ l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessADE}(l, maxDerivative == 0).
-
-        guessAlg: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessAlg(l, options)} tries to find an algebraic equation
-          ++ for a generating function whose first Taylor coefficients are
-          ++ given by l, using the given options. It is equivalent to
-          ++ \spadfun{guessADE}(l, options) with \spad{maxDerivative == 0}.
-
-        guessHolo: List F -> GUESSRESULT
-          ++ \spad{guessHolo l} tries to find an ordinary linear differential
-          ++ equation for a generating function whose first Taylor coefficients
-          ++ are given by l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessADE}\spad{(l, maxPower == 1)}.
-
-        guessHolo: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessHolo(l, options)} tries to find an ordinary linear
-          ++ differential equation for a generating function whose first Taylor
-          ++ coefficients are given by l, using the given options. It is
-          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
-          ++ \spad{maxPower == 1}.
-
-        guessPade: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessPade(l, options)} tries to find a rational function
-          ++ whose first Taylor coefficients are given by l, using the given
-          ++ options. It is equivalent to \spadfun{guessADE}\spad{(l,
-          ++ maxDerivative == 0, maxPower == 1, allDegrees == true)}.
-
-        guessPade: List F -> GUESSRESULT
-          ++ \spad{guessPade(l, options)} tries to find a rational function
-          ++ whose first Taylor coefficients are given by l, using the default
-          ++ options described in \spadtype{GuessOptionFunctions0}. It is
-          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
-          ++ \spad{maxDerivative == 0, maxPower == 1, allDegrees == true}.
-
-        guessRec: List F -> GUESSRESULT
-          ++ \spad{guessRec l} tries to find an ordinary difference equation
-          ++ whose first values are given by l, using the default options
-          ++ described in \spadtype{GuessOptionFunctions0}.
-
-        guessRec: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessRec(l, options)} tries to find an ordinary difference
-          ++ equation whose first values are given by l, using the given
-          ++ options. 
-
-        guessPRec: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessPRec(l, options)} tries to find a linear recurrence
-          ++ with polynomial coefficients whose first values are given by l,
-          ++ using the given options. It is equivalent to
-          ++ \spadfun{guessRec}\spad{(l, options)} with \spad{maxPower == 1}.
-
-        guessPRec: List F -> GUESSRESULT
-          ++ \spad{guessPRec l} tries to find a linear recurrence with
-          ++ polynomial coefficients whose first values are given by l, using
-          ++ the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessRec}\spad{(l, maxPower == 1)}. 
-
-        guessRat: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessRat(l, options)} tries to find a rational function
-          ++ whose first values are given by l, using the given options. It is
-          ++ equivalent to \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower
-          ++ == 1, allDegrees == true)}.
-
-        guessRat: List F -> GUESSRESULT
-          ++ \spad{guessRat l} tries to find a rational function whose first
-          ++ values are given by l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower == 1,
-          ++ allDegrees == true)}.
-
-        diffHP: LGOPT -> HPSPEC
-          ++ \spad{diffHP options} returns a specification for Hermite-Pade
-          ++ approximation with the differential operator
-
-        shiftHP: LGOPT -> HPSPEC
-          ++ \spad{shiftHP options} returns a specification for Hermite-Pade
-          ++ approximation with the shift operator
-
-        if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-            shiftHP: Symbol -> (LGOPT -> HPSPEC)
-              ++ \spad{shiftHP options} returns a specification for
-              ++ Hermite-Pade approximation with the $q$-shift operator
-
-            diffHP: Symbol -> (LGOPT -> HPSPEC)
-              ++ \spad{diffHP options} returns a specification for Hermite-Pade
-              ++ approximation with the  $q$-dilation operator
-
-            guessRec: Symbol -> GUESSER
-              ++ \spad{guessRec q} returns a guesser that finds an ordinary
-              ++ q-difference equation whose first values are given by l, using
-              ++ the given options.
-
-            guessPRec: Symbol -> GUESSER
-              ++ \spad{guessPRec q} returns a guesser that tries to find
-              ++ a linear q-recurrence with polynomial coefficients whose first
-              ++ values are given by l, using the given options. It is
-              ++ equivalent to \spadfun{guessRec}\spad{(q)} with 
-              ++ \spad{maxPower == 1}.
-
-            guessRat: Symbol -> GUESSER
-              ++ \spad{guessRat q} returns a guesser that tries to find a
-              ++ q-rational function whose first values are given by l, using
-              ++ the given options. It is equivalent to \spadfun{guessRec} with
-              ++ \spad{(l, maxShift == 0, maxPower == 1, allDegrees == true)}.
-
-            guessADE: Symbol -> GUESSER
-              ++ \spad{guessADE q} returns a guesser that tries to find an
-              ++ algebraic differential equation for a generating function whose
-              ++ first Taylor coefficients are given by l, using the given
-              ++ options.
-
-        --@<<debug exports: Guess>>
-@
-
-<<debug exports: Guess>>=
---termAsUFPSF: (UFPSF, List Integer, DIFFSPECS, DIFFSPEC1) -> UFPSF
---termAsUFPSF2: (UFPSF, List Integer, DIFFSPECS, DIFFSPEC1) -> UFPSF
---termAsEXPRR: (EXPRR, Symbol, List Integer, DIFFSPECX, DIFFSPEC1X) -> EXPRR
---termAsUFPSSUPF: (UFPSSUPF, List Integer, DIFFSPECSF, DIFFSPEC1F) -> UFPSSUPF
---termAsUFPSSUPF2: (UFPSSUPF, List Integer, DIFFSPECSF, DIFFSPEC1F) -> UFPSSUPF
---
---ShiftSXGF: (EXPRR, Symbol, NNI) -> EXPRR
---ShiftAXGF: (NNI, Symbol, EXPRR) -> EXPRR
---
---FilteredPartitionStream: LGOPT -> Stream List Integer
---
---guessInterpolate: (List SUP F, List NNI, HPSPEC) -> Matrix SUP S
-testInterpolant: (List SUP S, List F, List UFPSSUPF, List EXPRR, List EXPRR, _
-                  NNI, HPSPEC, Symbol, BasicOperator, LGOPT) _
-                  -> Union("failed", Record(function: EXPRR, order: NNI))
-
---checkResult: (EXPRR, Symbol, Integer, List F, LGOPT) -> NNI
---
---guessBinRatAux: (Symbol, List F, DIFFSPECN, EXT, EXTEXPR,
---                 List Integer, LGOPT) -> List EXPRR
---guessBinRatAux0: (List F, DIFFSPECN, EXT, EXTEXPR,
---                  LGOPT) -> GUESSRESULT
---binExt: EXT
---binExtEXPR: EXTEXPR
---defaultD: DIFFSPECN
-
-@
-
-<<package GUESS Guess>>=
-    Implementation == add
-        <<implementation: Guess>>
-@
-
-<<implementation: Guess>>=
-
--- We have to put this chunk at the beginning, because otherwise it will take
--- very long to compile.
-
-<<implementation: Guess - guessExpRat - Order and Degree>>
-
-<<implementation: Guess - Utilities>>
-<<implementation: Guess - guessExpRat>>
-<<implementation: Guess - guessBinRat>>
-<<implementation: Guess - Hermite-Pade>>
-<<implementation: Guess - guess>>
-@
-
-\subsection{general utilities}
-
-<<implementation: Guess - Utilities>>=
-checkResult(res: EXPRR, n: Symbol, l: Integer, list: List F, 
-            options: LGOPT): NNI ==
-    for i in l..1 by -1 repeat
-        den := eval(denominator res, n::EXPRR, (i-1)::EXPRR)
-        if den = 0 then return i::NNI
-        num := eval(numerator res, n::EXPRR, (i-1)::EXPRR)
-        if list.i ~= retract(retract(num/den)@R)
-        then return i::NNI
-    0$NNI
-
-SUPS2SUPF(p: SUP S): SUP F ==
-  if F is S then 
-    p pretend SUP(F)
-  else if F is Fraction S then
-    map(coerce(#1)$Fraction(S), p)
-      $SparseUnivariatePolynomialFunctions2(S, F)
-  else error "Type parameter F should be either equal to S or equal _
-              to Fraction S"
-
-@
-%$
-
-\subsection{guessing rational functions with an exponential term}
-
-<<implementation: Guess - guessExpRat>>=
-<<implementation: Guess - guessExpRat - Utilities>>
-<<implementation: Guess - guessExpRat - Main>>
-@
-
-\subsubsection{Utilities}
-
-\paragraph{conversion routines}
-
-<<implementation: Guess - guessExpRat - Utilities>>=
-F2FPOLYS(p: F): FPOLYS ==
-  if F is S then 
-    p::POLYF::FPOLYF pretend FPOLYS
-  else if F is Fraction S then
-    numer(p)$Fraction(S)::POLYS/denom(p)$Fraction(S)::POLYS
-  else error "Type parameter F should be either equal to S or equal _
-               to Fraction S"
-
-MPCSF ==> MPolyCatFunctions2(V, IndexedExponents V, 
-                                IndexedExponents V, S, F,
-                                POLYS, POLYF)
-
-SUPF2EXPRR(xx: Symbol, p: SUP F): EXPRR ==
-  zero? p => 0
-  (coerce(leadingCoefficient p))::EXPRR * (xx::EXPRR)**degree p
-     + SUPF2EXPRR(xx, reductum p)
-
-FSUPF2EXPRR(xx: Symbol, p: FSUPF): EXPRR ==
-  (SUPF2EXPRR(xx, numer p)) / (SUPF2EXPRR(xx, denom p))
-
-
-POLYS2POLYF(p: POLYS): POLYF ==
-  if F is S then 
-    p pretend POLYF
-  else if F is Fraction S then
-    map(coerce(#1)$Fraction(S), p)$MPCSF
-  else error "Type parameter F should be either equal to S or equal _
-              to Fraction S"
-
-SUPPOLYS2SUPF(p: SUP POLYS, a1v: F, Av: F): SUP F ==
-  zero? p => 0
-  lc: POLYF := POLYS2POLYF leadingCoefficient(p)
-  monomial(retract(eval(lc, [index(1)$V, index(2)$V]::List V, 
-                            [a1v, Av])),
-           degree p) 
-    + SUPPOLYS2SUPF(reductum p, a1v, Av)
-
-
-SUPFPOLYS2FSUPPOLYS(p: SUP FPOLYS): Fraction SUP POLYS  ==
-  cden := splitDenominator(p)
-         $UnivariatePolynomialCommonDenominator(POLYS, FPOLYS,SUP FPOLYS)
-
-  pnum: SUP POLYS 
-       := map(retract(#1 * cden.den)$FPOLYS, p)
-             $SparseUnivariatePolynomialFunctions2(FPOLYS, POLYS)
-  pden: SUP POLYS := (cden.den)::SUP POLYS
-
-  pnum/pden
-
-
-POLYF2EXPRR(p: POLYF): EXPRR ==
-  map(convert(#1)@Symbol::EXPRR, coerce(#1)@EXPRR, p)
-     $PolynomialCategoryLifting(IndexedExponents V, V, 
-                                F, POLYF, EXPRR)
-
--- this needs documentation. In particular, why is V appearing here?
-GF ==> GeneralizedMultivariateFactorize(SingletonAsOrderedSet,
-                                        IndexedExponents V, F, F,
-                                        SUP F)
-
--- does not work:
---                                                     6
---   WARNING (genufact): No known algorithm to factor ? , trying square-free.
-
--- GF ==> GenUFactorize F
-@
-
-\paragraph{mimicking $q$-analoga}
-
-<<implementation: Guess - guessExpRat - Utilities>>=
-defaultD: DIFFSPECN
-defaultD(expr: EXPRR): EXPRR == expr
-
--- applies n+->q^n or whatever DN is to i
-DN2DL: (DIFFSPECN, Integer) -> F
-DN2DL(DN, i) == retract(retract(DN(i::EXPRR))@R)
-
-<<implementation: Guess - guessExpRat - evalResultant>>
-<<implementation: Guess - guessExpRat - substitute>>
-@
-
-\subsubsection{reducing the degree of the polynomials}
-
-The degree of [[poly3]] is governed by $(a_0+x_m a_1)^{x_m}$. Therefore, we
-substitute $A-x_m a1$ for $a_0$, which reduces the degree in $a_1$ by
-$x_m-x_{i+1}$.
-
-<<implementation: Guess - guessExpRat - substitute>>=
-p(xm: Integer, i: Integer, va1: V, vA: V, basis: DIFFSPECN): FPOLYS == 
-    vA::POLYS::FPOLYS + va1::POLYS::FPOLYS _ 
-                       * F2FPOLYS(DN2DL(basis, i) - DN2DL(basis, xm))
-
-p2(xm: Integer, i: Symbol, a1v: F, Av: F, basis: DIFFSPECN): EXPRR == 
-    coerce(Av) + coerce(a1v)*(basis(i::EXPRR) - basis(xm::EXPRR))
-
-@
-
-<<not interesting implementation: Guess - guessExpRat - substitute>>=
-p(xm: Integer, i: Integer, va1: V, vA: V, basis: DIFFSPECN): FPOLYS == 
-    vA::POLYS::FPOLYS + (i-xm)*va1::POLYS::FPOLYS
-
-p2(xm: Integer, i: Symbol, a1v: F, Av: F, basis: DIFFSPECN): EXPRR == 
-    coerce(Av) + coerce(a1v)*(i::EXPRR - xm::EXPRR)
-
-@
-
-\subsubsection{Order and Degree}
-
-The following expressions for order and degree of the resultants [[res1]] and
-[[res2]] in [[guessExpRatAux]] were first guessed -- partially with the aid of
-[[guessRat]], and then proven to be correct.
-
-<<implementation: Guess - guessExpRat - Order and Degree>>=
-ord1(x: List Integer, i: Integer): Integer == 
-    n := #x - 3 - i
-    x.(n+1)*reduce(_+, [x.j for j in 1..n], 0) + _
-        2*reduce(_+, [reduce(_+, [x.k*x.j for k in 1..j-1], 0) _
-                      for j in 1..n], 0)
-
-ord2(x: List Integer, i: Integer): Integer == 
-    if zero? i then
-        n := #x - 3 - i
-        ord1(x, i) + reduce(_+, [x.j for j in 1..n], 0)*(x.(n+2)-x.(n+1))
-    else
-        ord1(x, i)
-
-deg1(x: List Integer, i: Integer): Integer == 
-    m := #x - 3 
-    (x.(m+3)+x.(m+1)+x.(1+i))*reduce(_+, [x.j for j in 2+i..m], 0) + _
-        x.(m+3)*x.(m+1) + _
-        2*reduce(_+, [reduce(_+, [x.k*x.j for k in 2+i..j-1], 0) _
-                      for j in 2+i..m], 0)
-
-deg2(x: List Integer, i: Integer): Integer == 
-    m := #x - 3
-    deg1(x, i) + _
-        (x.(m+3) + reduce(_+, [x.j for j in 2+i..m], 0)) * _
-        (x.(m+2)-x.(m+1))
-
-@
-
-[[evalResultant]] evaluates the resultant of [[p1]] and [[p2]] at [[d-o+1]]
-points, so that we can recover it by interpolation.
-
-<<implementation: Guess - guessExpRat - evalResultant>>=
-evalResultant(p1: POLYS, p2: POLYS, o: Integer, d: Integer, va1: V, vA: V)_
-: List S == 
-    res: List S := []
-    d1 := degree(p1, va1)
-    d2 := degree(p2, va1)
-    lead: S
-    for k in 1..d-o+1 repeat
-        p1atk := univariate eval(p1, vA, k::S)
-        p2atk := univariate eval(p2, vA, k::S)
-
-@
-
-It may happen, that the leading coefficients of one or both of the polynomials
-changes, when we evaluate it at $k$. In this case, we need to correct this by
-multiplying with the corresponding power of the leading coefficient of the
-other polynomial.
-
-Consider the Sylvester matrix of the original polynomials. We want to evaluate
-it at $A=k$. If the first few leading coefficients of $p2$ vanish, the first
-few columns of the Sylvester matrix have triangular shape, with the leading
-coefficient of $p1$ on the diagonal. The same thing happens, if we exchange the
-roles of $p1$ and $p2$, only that we have to take care of the sign, too.
-
-<<implementation: Guess - guessExpRat - evalResultant>>=
-        d1atk := degree p1atk
-        d2atk := degree p2atk
-
---      output("k: " string(k))$OutputPackage
---      output("d1: " string(d1) " d1atk: " string(d1atk))$OutputPackage
---      output("d2: " string(d2) " d2atk: " string(d2atk))$OutputPackage
-
-
-        if d2atk < d2 then
-            if  d1atk < d1
-            then lead := 0$S
-            else lead := (leadingCoefficient p1atk)**((d2-d2atk)::NNI)
-        else
-            if  d1atk < d1
-            then lead := (-1$S)**d2 * (leadingCoefficient p2atk)**((d1-d1atk)::NNI)
-            else lead := 1$S
-
-        if zero? lead 
-        then res := cons(0, res)
-        else res := cons(lead * (resultant(p1atk, p2atk)$SUP(S) exquo _
-                                (k::S)**(o::NNI))::S, 
-                         res)
-
-@
-%$
-
-Since we also have an lower bound for the order of the resultant, we need to
-evaluate it only at $d-o+1$ points. Furthermore, we can divide by $k^o$ and
-still obtain a polynomial.
-
-<<implementation: Guess - guessExpRat - evalResultant>>=
-    reverse res
-
-@
-
-\subsubsection{The main routine}
-
-<<implementation: Guess - guessExpRat - Main>>=
-guessExpRatAux(xx: Symbol, list: List F, basis: DIFFSPECN, 
-               xValues: List Integer, options: LGOPT): List EXPRR ==
-
-    a1: V := index(1)$V
-    A: V := index(2)$V
-
-    len: NNI := #list
-    if len < 4 then return []
-               else len := (len-3)::NNI
-
-    xlist := [F2FPOLYS DN2DL(basis, xValues.i) for i in 1..len]
-    x1 := F2FPOLYS DN2DL(basis, xValues.(len+1))
-    x2 := F2FPOLYS DN2DL(basis, xValues.(len+2))
-    x3 := F2FPOLYS DN2DL(basis, xValues.(len+3))
-
-@
-
-We try to fit the data $(s1,s2,\dots)$ to the model $(a+b n)^n y(n)$, $r$ being
-a rational function. To obtain $y$, we compute $y(n)=s_n*(a+b n)^{-n}$.
-
-<<implementation: Guess - guessExpRat - Main>>=
-    y: NNI -> FPOLYS := 
-        F2FPOLYS(list.#1) * _
-        p(last xValues, (xValues.#1)::Integer, a1, A, basis)**_
-            (-(xValues.#1)::Integer)
-
-    ylist: List FPOLYS := [y i for i in 1..len]
-
-    y1 := y(len+1)
-    y2 := y(len+2)
-    y3 := y(len+3)
-
-    res := []::List EXPRR
-    if maxDegree(options)$GOPT0 = -1
-    then maxDeg := len-1
-    else maxDeg := min(maxDegree(options)$GOPT0, len-1)
-
-    for i in 0..maxDeg repeat
-        if debug(options)$GOPT0 then
-            output(hconcat("degree ExpRat "::OutputForm, i::OutputForm))
-                $OutputPackage
-
-@
-
-\begin{ToDo}
-  Shouldn't we use the algorithm over [[POLYS]] here? Strange enough, for
-  polynomial interpolation, it is faster, but for rational interpolation
-  \emph{much} slower. This should be investigated.
-\end{ToDo}
-
-\begin{ToDo}
-  It seems that [[maxDeg]] bounds the degree of the denominator, rather than
-  the numerator? This is now added to the documentation of [[maxDegree]], it
-  should make sense.
-\end{ToDo}
-
-<<implementation: Guess - guessExpRat - Main>>=
-        if debug(options)$GOPT0 then 
-            systemCommand("sys date +%s")$MoreSystemCommands
-            output("interpolating..."::OutputForm)$OutputPackage
-
-        ri: FSUPFPOLYS
-           := interpolate(xlist, ylist, (len-1-i)::NNI) _
-                         $FFFG(FPOLYS, SUP FPOLYS)
-
--- for experimental fraction free interpolation
---        ri: Fraction SUP POLYS
---           := interpolate(xlist, ylist, (len-1-i)::NNI) _
---                         $FFFG(POLYS, SUP POLYS)
-
-        if debug(options)$GOPT0 then 
---            output(hconcat("xlist: ", xlist::OutputForm))$OutputPackage
---            output(hconcat("ylist: ", ylist::OutputForm))$OutputPackage
---            output(hconcat("ri: ", ri::OutputForm))$OutputPackage
-            systemCommand("sys date +%s")$MoreSystemCommands
-            output("polynomials..."::OutputForm)$OutputPackage
-
-        poly1: POLYS := numer(elt(ri, x1)$SUP(FPOLYS) - y1)
-        poly2: POLYS := numer(elt(ri, x2)$SUP(FPOLYS) - y2)
-        poly3: POLYS := numer(elt(ri, x3)$SUP(FPOLYS) - y3)
-
--- for experimental fraction free interpolation
---        ri2: FSUPFPOLYS := map(#1::FPOLYS, numer ri)                           _
---                           $SparseUnivariatePolynomialFunctions2(POLYS, FPOLYS)_ 
---                          /map(#1::FPOLYS, denom ri)                           _
---                           $SparseUnivariatePolynomialFunctions2(POLYS, FPOLYS)
---
---        poly1: POLYS := numer(elt(ri2, x1)$SUP(FPOLYS) - y1)
---        poly2: POLYS := numer(elt(ri2, x2)$SUP(FPOLYS) - y2)
---        poly3: POLYS := numer(elt(ri2, x3)$SUP(FPOLYS) - y3)
-
-        n:Integer := len - i
-        o1: Integer := ord1(xValues, i)
-        d1: Integer := deg1(xValues, i)
-        o2: Integer := ord2(xValues, i)
-        d2: Integer := deg2(xValues, i)
-
--- another compiler bug: using i as iterator here makes the loop break
-
-        if debug(options)$GOPT0 then 
-            systemCommand("sys date +%s")$MoreSystemCommands
-            output("interpolating resultants..."::OutputForm)$OutputPackage
-
-        res1: SUP S
-             := newton(evalResultant(poly1, poly3, o1, d1, a1, A))
-                      $NewtonInterpolation(S)
-
-        res2: SUP S
-             := newton(evalResultant(poly2, poly3, o2, d2, a1, A))
-                      $NewtonInterpolation(S)
-
-        if debug(options)$GOPT0 then 
---            res1: SUP S := univariate(resultant(poly1, poly3, a1))
---            res2: SUP S := univariate(resultant(poly2, poly3, a1))
---            if res1 ~= res1res or res2 ~= res2res then
---            output(hconcat("poly1 ", poly1::OutputForm))$OutputPackage
---                output(hconcat("poly2 ", poly2::OutputForm))$OutputPackage
---            output(hconcat("poly3 ", poly3::OutputForm))$OutputPackage
---                output(hconcat("res1 ", res1::OutputForm))$OutputPackage
---                output(hconcat("res2 ", res2::OutputForm))$OutputPackage
-            output("n/i: " string(n) " " string(i))$OutputPackage
-            output("res1 ord: " string(o1) " " string(minimumDegree res1))
-                  $OutputPackage
-            output("res1 deg: " string(d1) " " string(degree res1))
-                  $OutputPackage
-            output("res2 ord: " string(o2) " " string(minimumDegree res2))
-                  $OutputPackage
-            output("res2 deg: " string(d2) " " string(degree res2))
-                  $OutputPackage
-
-        if debug(options)$GOPT0 then 
-            systemCommand("sys date +%s")$MoreSystemCommands
-            output("computing gcd..."::OutputForm)$OutputPackage
-
--- we want to solve over F
--- for polynomial domains S this seems to be very costly!     
-        res3: SUP F := SUPS2SUPF(primitivePart(gcd(res1, res2)))
-
-        if debug(options)$GOPT0 then 
-            systemCommand("sys date +%s")$MoreSystemCommands
-            output("solving..."::OutputForm)$OutputPackage
-
--- res3 is a polynomial in A=a0+(len+3)*a1
--- now we have to find the roots of res3
-
-        for f in factors factor(res3)$GF | degree f.factor = 1 repeat 
--- we are only interested in the linear factors
-             if debug(options)$GOPT0 then 
-                 output(hconcat("f: ", f::OutputForm))$OutputPackage
-
-             Av: F := -coefficient(f.factor, 0)
-                     / leadingCoefficient f.factor
-
--- FIXME: in an earlier version, we disregarded vanishing Av
---        maybe we intended to disregard vanishing a1v? Either doesn't really
---        make sense to me right now.
-
-             evalPoly := eval(POLYS2POLYF poly3, A, Av)
-             if zero? evalPoly 
-             then evalPoly := eval(POLYS2POLYF poly1, A, Av)
--- Note that it really may happen that poly3 vanishes when specializing
--- A. Consider for example guessExpRat([1,1,1,1]).
-
--- FIXME: We check poly1 below, too. I should work out in what cases poly3
--- vanishes.
-
-             for g in factors factor(univariate evalPoly)$GF 
-                      | degree g.factor = 1 repeat
-                 if debug(options)$GOPT0 then 
-                     output(hconcat("g: ", g::OutputForm))$OutputPackage
-
-                 a1v: F := -coefficient(g.factor, 0)
-                          / leadingCoefficient g.factor
-
--- check whether poly1 and poly2 really vanish. Note that we could have found
--- an extraneous solution, since we only computed the gcd of the two
--- resultants.
-
-                 t1 := eval(POLYS2POLYF poly1, [a1, A]::List V, 
-                                               [a1v, Av]::List F)
-                 if zero? t1 then  
-                     t2 := eval(POLYS2POLYF poly2, [a1, A]::List V, 
-                                                   [a1v, Av]::List F)
-                     if zero? t2 then
-
-                         ri1: Fraction SUP POLYS 
-                             := SUPFPOLYS2FSUPPOLYS(numer ri)
-                              / SUPFPOLYS2FSUPPOLYS(denom ri)
-
--- for experimental fraction free interpolation
---                         ri1: Fraction SUP POLYS := ri
-
-                         numr: SUP F := SUPPOLYS2SUPF(numer ri1, a1v, Av)
-                         denr: SUP F := SUPPOLYS2SUPF(denom ri1, a1v, Av)
-
-                         if not zero? denr then
-                             res4: EXPRR := eval(FSUPF2EXPRR(xx, numr/denr), 
-                                                 kernel(xx), 
-                                                 basis(xx::EXPRR))
-                                           *p2(last xValues, _
-                                               xx, a1v, Av, basis)_
-                                            **xx::EXPRR
-                             res := cons(res4, res)
-                         else if zero? numr and debug(options)$GOPT0 then
-                             output("numerator and denominator vanish!")
-                                   $OutputPackage
-
--- If we are only interested in one solution, we do not try other degrees if we
--- have found already some solutions. I.e., the indentation here is correct.
-
-        if not null(res) and one(options)$GOPT0 then return res
-
-    res
-
-guessExpRatAux0(list: List F, basis: DIFFSPECN, options: LGOPT): GUESSRESULT ==
-    if zero? safety(options)$GOPT0 then
-        error "Guess: guessExpRat does not support zero safety"
--- guesses Functions of the Form (a1*n+a0)^n*rat(n)
-    xx := indexName(options)$GOPT0
-
--- restrict to safety
-
-    len: Integer := #list
-    if len-safety(options)$GOPT0+1 < 0 then return []
-
-    shortlist: List F := first(list, (len-safety(options)$GOPT0+1)::NNI)
-
--- remove zeros from list
-
-    zeros: EXPRR := 1
-    newlist: List F
-    xValues: List Integer
-
-    i: Integer := -1
-    for x in shortlist repeat
-        i := i+1
-        if x = 0 then 
-            zeros := zeros * (basis(xx::EXPRR) - basis(i::EXPRR))
-
-    i := -1
-    for x in shortlist repeat
-        i := i+1
-        if x ~= 0 then
-            newlist := cons(x/retract(retract(eval(zeros, xx::EXPRR, 
-                                                          i::EXPRR))@R),
-                            newlist)
-            xValues := cons(i, xValues)
-
-    newlist := reverse newlist
-    xValues := reverse xValues
-
-    res: List EXPRR 
-        := [eval(zeros * f, xx::EXPRR, xx::EXPRR) _
-            for f in guessExpRatAux(xx, newlist, basis, xValues, options)]
-
-    reslist := map([#1, checkResult(#1, xx, len, list, options)], res)
-                  $ListFunctions2(EXPRR, Record(function: EXPRR, order: NNI))
-
-    select(#1.order < len-safety(options)$GOPT0, reslist)
-
-guessExpRat(list : List F): GUESSRESULT ==
-    guessExpRatAux0(list, defaultD, [])
-
-guessExpRat(list: List F, options: LGOPT): GUESSRESULT ==
-    guessExpRatAux0(list, defaultD, options)
-
-if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-    guessExpRat(q: Symbol): GUESSER ==
-        guessExpRatAux0(#1, q::EXPRR**#1, #2)
-
-@
-
-\subsection{guessing rational functions with a binomial term}
-
-\begin{ToDo}
-  It is not clear whether one should take the model
-  \begin{equation*}
-    \binom{a+bn}{n}q(n),
-  \end{equation*}
-  which includes rational functions, or
-  \begin{equation*}
-    (a+bn)(a+bn+1)\dots (a+bn+n)q(n).
-  \end{equation*}
-  which includes rational functions times $n!$. We choose the former, since
-  dividing by $n!$ is a common normalisation. The question remains whether we
-  should do the same for [[guessExpRat]].
-\end{ToDo}
-
-
-<<implementation: Guess - guessBinRat>>=
-
-EXT ==> (Integer, V, V) -> FPOLYS
-EXTEXPR ==> (Symbol, F, F) -> EXPRR
-
-binExt: EXT
-binExt(i: Integer, va1: V, vA: V): FPOLYS == 
-    numl: List POLYS := [(vA::POLYS) + i * (va1::POLYS) - (l::POLYS) _
-                         for l in 0..i-1]
-    num: POLYS := reduce(_*, numl, 1)
-
-    num/(factorial(i)::POLYS)
-
-binExtEXPR: EXTEXPR
-binExtEXPR(i: Symbol, a1v: F, Av: F): EXPRR == 
-    binomial(coerce Av + coerce a1v * (i::EXPRR), i::EXPRR)
-
-
-guessBinRatAux(xx: Symbol, list: List F, 
-               basis: DIFFSPECN, ext: EXT, extEXPR: EXTEXPR,
-               xValues: List Integer, options: LGOPT): List EXPRR ==
-
-    a1: V := index(1)$V
-    A: V := index(2)$V
-
-    len: NNI := #list
-    if len < 4 then return []
-               else len := (len-3)::NNI
-
-    xlist := [F2FPOLYS DN2DL(basis, xValues.i) for i in 1..len]
-    x1 := F2FPOLYS DN2DL(basis, xValues.(len+1))
-    x2 := F2FPOLYS DN2DL(basis, xValues.(len+2))
-    x3 := F2FPOLYS DN2DL(basis, xValues.(len+3))
-
-@
-
-We try to fit the data $(s1,s2,\dots)$ to the model $\binom{a+b n}{n} y(n)$,
-$r$ being a rational function. To obtain $y$, we compute
-$y(n)=s_n*\binom{a+bn}{n}^-1$.
-
-<<implementation: Guess - guessBinRat>>=
-    y: NNI -> FPOLYS := 
-        F2FPOLYS(list.#1) / _
-        ext((xValues.#1)::Integer, a1, A)
-
-    ylist: List FPOLYS := [y i for i in 1..len]
-
-    y1 := y(len+1)
-    y2 := y(len+2)
-    y3 := y(len+3)
-
-    res := []::List EXPRR
-    if maxDegree(options)$GOPT0 = -1
-    then maxDeg := len-1
-    else maxDeg := min(maxDegree(options)$GOPT0, len-1)
-
-    for i in 0..maxDeg repeat
---        if debug(options)$GOPT0 then
---            output(hconcat("degree BinRat "::OutputForm, i::OutputForm))
---                $OutputPackage
-
-@
-
-\begin{ToDo}
-  Shouldn't we use the algorithm over [[POLYS]] here? Strange enough, for
-  polynomial interpolation, it is faster, but for rational interpolation
-  \emph{much} slower. This should be investigated.
-\end{ToDo}
-
-\begin{ToDo}
-  It seems that [[maxDeg]] bounds the degree of the denominator, rather than
-  the numerator? This is now added to the documentation of [[maxDegree]], it
-  should make sense.
-\end{ToDo}
-
-<<implementation: Guess - guessBinRat>>=
---        if debug(options)$GOPT0 then 
---            output("interpolating..."::OutputForm)$OutputPackage
-
-        ri: FSUPFPOLYS
-           := interpolate(xlist, ylist, (len-1-i)::NNI) _
-                         $FFFG(FPOLYS, SUP FPOLYS)
-
---        if debug(options)$GOPT0 then 
---            output(hconcat("ri ", ri::OutputForm))$OutputPackage
-
-        poly1: POLYS := numer(elt(ri, x1)$SUP(FPOLYS) - y1)
-        poly2: POLYS := numer(elt(ri, x2)$SUP(FPOLYS) - y2)
-        poly3: POLYS := numer(elt(ri, x3)$SUP(FPOLYS) - y3)
-
---        if debug(options)$GOPT0 then
---            output(hconcat("poly1 ", poly1::OutputForm))$OutputPackage
---            output(hconcat("poly2 ", poly2::OutputForm))$OutputPackage
---            output(hconcat("poly3 ", poly3::OutputForm))$OutputPackage
-
-
-        n:Integer := len - i
-        res1: SUP S := univariate(resultant(poly1, poly3, a1))
-        res2: SUP S := univariate(resultant(poly2, poly3, a1))
-        if debug(options)$GOPT0 then
---            output(hconcat("res1 ", res1::OutputForm))$OutputPackage
---            output(hconcat("res2 ", res2::OutputForm))$OutputPackage
-
---            if res1 ~= res1res or res2 ~= res2res then
---            output(hconcat("poly1 ", poly1::OutputForm))$OutputPackage
---                output(hconcat("poly2 ", poly2::OutputForm))$OutputPackage
---            output(hconcat("poly3 ", poly3::OutputForm))$OutputPackage
---                output(hconcat("res1 ", res1::OutputForm))$OutputPackage
---                output(hconcat("res2 ", res2::OutputForm))$OutputPackage
---            output("n/i: " string(n) " " string(i))$OutputPackage
-            output("res1 ord: " string(minimumDegree res1))
-                  $OutputPackage
-            output("res1 deg: " string(degree res1))
-                  $OutputPackage
-            output("res2 ord: " string(minimumDegree res2))
-                  $OutputPackage
-            output("res2 deg: " string(degree res2))
-                  $OutputPackage
-
-        if debug(options)$GOPT0 then 
-            output("computing gcd..."::OutputForm)$OutputPackage
-
--- we want to solve over F            
-        res3: SUP F := SUPS2SUPF(primitivePart(gcd(res1, res2)))
-
---        if debug(options)$GOPT0 then 
---            output(hconcat("res3 ", res3::OutputForm))$OutputPackage
-
--- res3 is a polynomial in A=a0+(len+3)*a1
--- now we have to find the roots of res3
-
-        for f in factors factor(res3)$GF | degree f.factor = 1 repeat 
--- we are only interested in the linear factors
---             if debug(options)$GOPT0 then 
---                 output(hconcat("f: ", f::OutputForm))$OutputPackage
-
-             Av: F := -coefficient(f.factor, 0)
-                     / leadingCoefficient f.factor
-
---             if debug(options)$GOPT0 then 
---                 output(hconcat("Av: ", Av::OutputForm))$OutputPackage
-
--- FIXME: in an earlier version, we disregarded vanishing Av
---        maybe we intended to disregard vanishing a1v? Either doesn't really
---        make sense to me right now.
-
-             evalPoly := eval(POLYS2POLYF poly3, A, Av)
-             if zero? evalPoly 
-             then evalPoly := eval(POLYS2POLYF poly1, A, Av)
--- Note that it really may happen that poly3 vanishes when specializing
--- A. Consider for example guessExpRat([1,1,1,1]).
-
--- FIXME: We check poly1 below, too. I should work out in what cases poly3
--- vanishes.
-
-             for g in factors factor(univariate evalPoly)$GF 
-                      | degree g.factor = 1 repeat
---                 if debug(options)$GOPT0 then 
---                     output(hconcat("g: ", g::OutputForm))$OutputPackage
-
-                 a1v: F := -coefficient(g.factor, 0)
-                          / leadingCoefficient g.factor
-
---                 if debug(options)$GOPT0 then 
---                     output(hconcat("a1v: ", a1v::OutputForm))$OutputPackage
-
--- check whether poly1 and poly2 really vanish. Note that we could have found
--- an extraneous solution, since we only computed the gcd of the two
--- resultants.
-
-                 t1 := eval(POLYS2POLYF poly1, [a1, A]::List V, 
-                                               [a1v, Av]::List F)
-
---                 if debug(options)$GOPT0 then 
---                     output(hconcat("t1: ", t1::OutputForm))$OutputPackage
-
-                 if zero? t1 then  
-                     t2 := eval(POLYS2POLYF poly2, [a1, A]::List V, 
-                                                   [a1v, Av]::List F)
-
---                     if debug(options)$GOPT0 then 
---                         output(hconcat("t2: ", t2::OutputForm))$OutputPackage
-
-                     if zero? t2 then
-
-                         ri1: Fraction SUP POLYS 
-                             := SUPFPOLYS2FSUPPOLYS(numer ri)
-                              / SUPFPOLYS2FSUPPOLYS(denom ri)
-
---                         if debug(options)$GOPT0 then 
---                             output(hconcat("ri1: ", ri1::OutputForm))$OutputPackage
-
-                         numr: SUP F := SUPPOLYS2SUPF(numer ri1, a1v, Av)
-                         denr: SUP F := SUPPOLYS2SUPF(denom ri1, a1v, Av)
-
---                         if debug(options)$GOPT0 then 
---                             output(hconcat("numr: ", numr::OutputForm))$OutputPackage
---                             output(hconcat("denr: ", denr::OutputForm))$OutputPackage
-
-                         if not zero? denr then
-                             res4: EXPRR := eval(FSUPF2EXPRR(xx, numr/denr), 
-                                                 kernel(xx), 
-                                                 basis(xx::EXPRR))
-                                           * extEXPR(xx, a1v, Av)
-
---                             if debug(options)$GOPT0 then 
---                                 output(hconcat("res4: ", res4::OutputForm))$OutputPackage
-
-                             res := cons(res4, res)
-                         else if zero? numr and debug(options)$GOPT0 then
-                             output("numerator and denominator vanish!")
-                                   $OutputPackage
-
--- If we are only interested in one solution, we do not try other degrees if we
--- have found already some solutions. I.e., the indentation here is correct.
-
-        if not null(res) and one(options)$GOPT0 then return res
-
-    res
-
-guessBinRatAux0(list: List F,
-                basis: DIFFSPECN, ext: EXT, extEXPR: EXTEXPR,
-                options: LGOPT): GUESSRESULT ==
-
-    if zero? safety(options)$GOPT0 then
-        error "Guess: guessBinRat does not support zero safety"
--- guesses Functions of the form binomial(a+b*n, n)*rat(n)
-    xx := indexName(options)$GOPT0
-
--- restrict to safety
-
-    len: Integer := #list
-    if len-safety(options)$GOPT0+1 < 0 then return []
-
-    shortlist: List F := first(list, (len-safety(options)$GOPT0+1)::NNI)
-
--- remove zeros from list
-
-    zeros: EXPRR := 1
-    newlist: List F
-    xValues: List Integer
-
-    i: Integer := -1
-    for x in shortlist repeat
-        i := i+1
-        if x = 0 then 
-            zeros := zeros * (basis(xx::EXPRR) - basis(i::EXPRR))
-
-    i := -1
-    for x in shortlist repeat
-        i := i+1
-        if x ~= 0 then
-            newlist := cons(x/retract(retract(eval(zeros, xx::EXPRR, 
-                                                          i::EXPRR))@R),
-                            newlist)
-            xValues := cons(i, xValues)
-
-    newlist := reverse newlist
-    xValues := reverse xValues
-
-    res: List EXPRR 
-        := [eval(zeros * f, xx::EXPRR, xx::EXPRR) _
-            for f in guessBinRatAux(xx, newlist, basis, ext, extEXPR, xValues, _
-                                    options)]
-
-    reslist := map([#1, checkResult(#1, xx, len, list, options)], res)
-                  $ListFunctions2(EXPRR, Record(function: EXPRR, order: NNI))
-
-    select(#1.order < len-safety(options)$GOPT0, reslist)
-
-guessBinRat(list : List F): GUESSRESULT ==
-    guessBinRatAux0(list, defaultD, binExt, binExtEXPR, [])
-
-guessBinRat(list: List F, options: LGOPT): GUESSRESULT ==
-    guessBinRatAux0(list, defaultD, binExt, binExtEXPR, options)
-
-
-if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-    qD: Symbol -> DIFFSPECN
-    qD q == (q::EXPRR)**#1
-
-
-    qBinExtAux(q: Symbol, i: Integer, va1: V, vA: V): FPOLYS == 
-        fl: List FPOLYS 
-             := [(1$FPOLYS - _
-                  va1::POLYS::FPOLYS * (vA::POLYS::FPOLYS)**(i-1) * _
-                  F2FPOLYS(q::F)**l) / (1-F2FPOLYS(q::F)**l) _ 
-                 for l in 1..i]
-        reduce(_*, fl, 1)
-
-    qBinExt: Symbol -> EXT
-    qBinExt q == qBinExtAux(q, #1, #2, #3)
-
-    qBinExtEXPRaux(q: Symbol, i: Symbol, a1v: F, Av: F): EXPRR == 
-        l: Symbol := 'l
-        product((1$EXPRR - _
-                 coerce a1v * (coerce Av) ** (coerce i - 1$EXPRR) * _
-                 (q::EXPRR) ** coerce(l)) / _
-                (1$EXPRR - (q::EXPRR) ** coerce(l)), _
-                equation(l, 1$EXPRR..i::EXPRR))
-
-    qBinExtEXPR: Symbol -> EXTEXPR
-    qBinExtEXPR q == qBinExtEXPRaux(q, #1, #2, #3)
-
-    guessBinRat(q: Symbol): GUESSER ==
-        guessBinRatAux0(#1, qD q, qBinExt q, qBinExtEXPR q, #2)_
-
-@
-
-
-\subsection{Hermite Pad\'e interpolation}\label{sec:Hermite-Pade}
-
-<<implementation: Guess - Hermite-Pade>>=
-<<implementation: Guess - Hermite-Pade - Types for Operators>>
-<<implementation: Guess - Hermite-Pade - Streams>>
-<<implementation: Guess - Hermite-Pade - Operators>>
-<<implementation: Guess - Hermite-Pade - Utilities>>
-<<implementation: Guess - guessHPaux>>
-<<implementation: Guess - guessHP>>
-@
-
-\subsubsection{Types for Operators}
-<<implementation: Guess - Hermite-Pade - Types for Operators>>=
--- some useful types for Ore operators that work on series
-
--- the differentiation operator
-DIFFSPECX ==> (EXPRR, Symbol, NonNegativeInteger) -> EXPRR
-                                               -- eg.: f(x)+->f(q*x)
-                                               --      f(x)+->D(f, x)
-DIFFSPECS ==> (UFPSF, NonNegativeInteger) -> UFPSF
-                                               -- eg.: f(x)+->f(q*x)
-
-DIFFSPECSF ==> (UFPSSUPF, NonNegativeInteger) -> UFPSSUPF
-                                               -- eg.: f(x)+->f(q*x)
-
--- the constant term for the inhomogeneous case
-
-DIFFSPEC1 ==> UFPSF
-
-DIFFSPEC1F ==> UFPSSUPF
-
-DIFFSPEC1X ==> Symbol -> EXPRR
-
-@
-
-\subsubsection{Streams}\label{sec:streams}
-
-In this section we define some functions that provide streams for
-[[HermitePade]].
-
-The following three functions transform a partition [[l]] into a product of
-derivatives of [[f]], using the given operators. We need to provide the same
-functionality for expressions, series and series with a transcendental element.
-Only for expressions we do not provide a version using the Hadamard product,
-although it would be quite easy to define an appropriate operator on
-expressions.
-
-A partition $(\lambda_1^{p_1},\lambda_2^{p_2},\dots)$ is transformed into the
-expression $(f^{(\lambda_1-1)})^{p_1}(f^{(\lambda_2-1)})^{p_2}\cdots$, i.e.,
-the size of the part is interpreted as derivative, the exponent as power.
-
-<<implementation: Guess - Hermite-Pade - Streams>>=
-termAsEXPRR(f: EXPRR, xx: Symbol, l: List Integer, 
-            DX: DIFFSPECX, D1X: DIFFSPEC1X): EXPRR ==
-    if empty? l then D1X(xx)
-    else
-        ll: List List Integer := powers(l)$Partition
-
-        fl: List EXPRR := [DX(f, xx, (first part-1)::NonNegativeInteger)
-                           ** second(part)::NNI for part in ll]
-        reduce(_*, fl)
-
-termAsUFPSF(f: UFPSF, l: List Integer, DS: DIFFSPECS, D1: DIFFSPEC1): UFPSF ==
-    if empty? l then D1
-    else
-        ll: List List Integer := powers(l)$Partition
-
--- first of each element of ll is the derivative, second is the power
-
-        fl: List UFPSF := [DS(f, (first part -1)::NonNegativeInteger) _
-                           ** second(part)::NNI for part in ll]
-
-        reduce(_*, fl)
-
--- returns \prod f^(l.i), but using the Hadamard product
-termAsUFPSF2(f: UFPSF, l: List Integer, 
-             DS: DIFFSPECS, D1: DIFFSPEC1): UFPSF ==
-    if empty? l then D1
-    else
-        ll: List List Integer := powers(l)$Partition
-
--- first of each element of ll is the derivative, second is the power
-
-        fl: List UFPSF 
-            := [map(#1** second(part)::NNI, DS(f, (first part -1)::NNI)) _
-                for part in ll]
-
-        reduce(hadamard$UFPS1(F), fl)
-
-
-termAsUFPSSUPF(f: UFPSSUPF, l: List Integer, 
-                     DSF: DIFFSPECSF, D1F: DIFFSPEC1F): UFPSSUPF ==
-    if empty? l then D1F
-    else
-        ll: List List Integer := powers(l)$Partition
-
--- first of each element of ll is the derivative, second is the power
-
-        fl: List UFPSSUPF
-           := [DSF(f, (first part -1)::NonNegativeInteger)
-               ** second(part)::NNI for part in ll]
-
-        reduce(_*, fl)
-
-
--- returns \prod f^(l.i), but using the Hadamard product
-termAsUFPSSUPF2(f: UFPSSUPF, l: List Integer, 
-                DSF: DIFFSPECSF, D1F: DIFFSPEC1F): UFPSSUPF ==
-    if empty? l then D1F
-    else
-        ll: List List Integer := powers(l)$Partition
-
--- first of each element of ll is the derivative, second is the power
-
-        fl: List UFPSSUPF 
-           := [map(#1 ** second(part)::NNI, DSF(f, (first part -1)::NNI)) _
-               for part in ll]
-
-        reduce(hadamard$UFPS1(SUP F), fl)
-
-@
-%$
-
-It is not clear whether we should \lq prefer\rq\ shifting and differentiation over
-powering. Currently, we produce the stream
-\begin{equation*}
-  \begin{array}{rrrrrrrrr}
-    \emptyset& 1& 11 & 2 & 111& 2 1 & 3  & 1111\\
-            1& f& f^2& f'& f^3& f f'& f''& f^4 &\dots  
-  \end{array}
-\end{equation*}
-
-Maybe it would be better to produce
-\begin{equation*}
-  \begin{array}{rrrrrrrrr}
-    \emptyset& 1& 2&  11 & 3  & 21  & 111& 4\\
-    1& f& f'& f^2& f''& f f'& f^3& f''' &\dots 
-  \end{array}
-\end{equation*}
-instead, i.e., to leave the partitions unconjugated. Note however, that
-shifting and differentiation decrease the number of valid terms, while powering
-does not.
-
-Note that we conjugate all partitions at the very end of the following
-procedure\dots
-
-<<implementation: Guess - Hermite-Pade - Streams>>=
-FilteredPartitionStream(options: LGOPT): Stream List Integer ==
-    maxD := 1+maxDerivative(options)$GOPT0
-    maxP := maxPower(options)$GOPT0
-
-    if maxD > 0 and maxP > -1 then
-        s := partitions(maxD, maxP)$PartitionsAndPermutations
-    else
-        s1: Stream Integer := generate(inc, 1)$Stream(Integer)
-        s2: Stream Stream List Integer 
-           := map(partitions(#1)$PartitionsAndPermutations, s1)
-                 $StreamFunctions2(Integer, Stream List Integer)
-        s3: Stream List Integer 
-           := concat(s2)$StreamFunctions1(List Integer)
-
---        s := cons([],
---                  select(((maxD = 0) or (first #1 <= maxD)) _
---                     and ((maxP = -1) or (# #1 <= maxP)), s3))
-
-        s := cons([],
-                  select(((maxD = 0) or (# #1 <= maxD)) _
-                     and ((maxP = -1) or (first #1 <= maxP)), s3))
-
-    s := conjugates(s)$PartitionsAndPermutations
-    if homogeneous(options)$GOPT0 then rest s else s
-
--- for functions
-ADEguessStream(f: UFPSF, partitions: Stream List Integer, 
-               DS: DIFFSPECS, D1: DIFFSPEC1): Stream UFPSF ==
-    map(termAsUFPSF(f, #1, DS, D1), partitions)
-       $StreamFunctions2(List Integer, UFPSF)
-
--- for coefficients, i.e., using the Hadamard product
-ADEguessStream2(f: UFPSF, partitions: Stream List Integer, 
-                DS: DIFFSPECS, D1: DIFFSPEC1): Stream UFPSF ==
-    map(termAsUFPSF2(f, #1, DS, D1), partitions)
-       $StreamFunctions2(List Integer, UFPSF)
-
-@
-%$
-
-The entries of the following stream indicate how many terms we loose when
-applying one of the power and shift or differentiation operators. More
-precisely, the $n$\textsuperscript{th} entry of the stream takes into account
-all partitions up to index $n$. Thus, the entries of the stream are weakly
-increasing.
-
-<<implementation: Guess - Hermite-Pade - Streams>>=       
-ADEdegreeStream(partitions: Stream List Integer): Stream NNI ==
-    scan(0, max((if empty? #1 then 0 else (first #1 - 1)::NNI), #2),
-         partitions)$StreamFunctions2(List Integer, NNI)
-
-ADEtestStream(f: UFPSSUPF, partitions: Stream List Integer, 
-              DSF: DIFFSPECSF, D1F: DIFFSPEC1F): Stream UFPSSUPF ==
-    map(termAsUFPSSUPF(f, #1, DSF, D1F), partitions)
-       $StreamFunctions2(List Integer, UFPSSUPF)
-
-ADEtestStream2(f: UFPSSUPF, partitions: Stream List Integer, 
-              DSF: DIFFSPECSF, D1F: DIFFSPEC1F): Stream UFPSSUPF ==
-    map(termAsUFPSSUPF2(f, #1, DSF, D1F), partitions)
-       $StreamFunctions2(List Integer, UFPSSUPF)
-
-ADEEXPRRStream(f: EXPRR, xx: Symbol, partitions: Stream List Integer, 
-               DX: DIFFSPECX, D1X: DIFFSPEC1X): Stream EXPRR ==
-    map(termAsEXPRR(f, xx, #1, DX, D1X), partitions)
-       $StreamFunctions2(List Integer, EXPRR)
-
-@
-\subsubsection{Operators}
-
-We need to define operators that transform series for differentiation and
-shifting. We also provide operators for $q$-analogs. The functionality
-corresponding to powering and taking the Hadamard product if provided by the
-streams, see Section~\ref{sec:streams}.
-
-We have to provide each operator in three versions: 
-\begin{itemize}
-\item for expressions,
-\item for series, and
-\item for series with an additional transcendental element.
-\end{itemize}
-
-The latter makes it possible to detect lazily whether a computed coefficient of
-a series is valid or not.
-
-Furthermore, we have to define for each operator how to extract the coefficient
-of $x^k$ in $z^l f(x)$, where multiplication with $z$ is defined depending on
-the operator. Again, it is necessary to provide this functionality for
-expressions, series and series with a transcendental element.
-
-Finally, we define a function that returns the diagonal elements $c_{k,k}$ in
-the expansion $\langle x^k\rangle z f(x) = \sum_{i=0}^k c_{k,i} \langle x^i\rangle f(x)$,
-and an expression that represents the constant term for the inhomogeneous case.
-
-\paragraph{The Differentiation Setting} In this setting, we have $z f(x) := x
-f(x)$. 
-
-<<implementation: Guess - Hermite-Pade - Operators>>=
-diffDX: DIFFSPECX
-diffDX(expr, x, n) == D(expr, x, n)
-
-diffDS: DIFFSPECS
-diffDS(s, n) == D(s, n)
-
-diffDSF: DIFFSPECSF
-diffDSF(s, n) == 
--- I have to help the compiler here a little to choose the right signature...
-    if SUP F has _*: (NonNegativeInteger, SUP F) -> SUP F
-    then D(s, n)
-
-@
-
-The next three functions extract the coefficient of $x^k$ in $z^l f(x)$. Only,
-for expressions, we rather need $\sum_{k\ge0} \langle x^k\rangle z^l f(x)$,
-i.e., the function itself, which is by definition equal to $x^l f(x)$.
-
-<<implementation: Guess - Hermite-Pade - Operators>>=
-diffAX: DIFFSPECAX
-diffAX(l: NNI, x: Symbol, f: EXPRR): EXPRR ==
-    (x::EXPRR)**l * f
-
-diffA: DIFFSPECA
-diffA(k: NNI, l: NNI, f: SUP S): S ==
-    DiffAction(k, l, f)$FFFG(S, SUP S)
-
-diffAF: DIFFSPECAF
-diffAF(k: NNI, l: NNI, f: UFPSSUPF): SUP F ==
-    DiffAction(k, l, f)$FFFG(SUP F, UFPSSUPF)
-
-diffC: DIFFSPECC
-diffC(total: NNI): List S == DiffC(total)$FFFG(S, SUP S)
-
-diff1X: DIFFSPEC1X
-diff1X(x: Symbol)== 1$EXPRR
-
-diffHP options == 
-    if displayAsGF(options)$GOPT0 then
-        partitions := FilteredPartitionStream options
-        [ADEguessStream(#1, partitions, diffDS, 1$UFPSF), _
-         ADEdegreeStream partitions, _
-         ADEtestStream(#1, partitions, diffDSF, 1$UFPSSUPF), _
-         ADEEXPRRStream(#1, #2, partitions, diffDX, diff1X), _
-         diffA, diffAF, diffAX, diffC]$HPSPEC
-    else
-        error "Guess: guessADE supports only displayAsGF"
-
-@
-
-\paragraph{$q$-dilation} In this setting, we also have $z f(x) := x f(x)$,
-therefore we can reuse some of the functions of the previous paragraph.
-Differentiation is defined by $D_q f(x, q) = f(qx, q)$.
-
-<<implementation: Guess - Hermite-Pade - Operators>>=
-if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-    qDiffDX(q: Symbol, expr: EXPRR, x: Symbol, n: NonNegativeInteger): EXPRR ==
-        eval(expr, x::EXPRR, (q::EXPRR)**n*x::EXPRR)
-
-    qDiffDS(q: Symbol, s: UFPSF, n: NonNegativeInteger): UFPSF ==
-        multiplyCoefficients((q::F)**((n*#1)::NonNegativeInteger), s)
-
-    qDiffDSF(q: Symbol, s: UFPSSUPF, n: NonNegativeInteger): UFPSSUPF ==
-        multiplyCoefficients((q::F::SUP F)**((n*#1)::NonNegativeInteger), s)
-
-    diffHP(q: Symbol): (LGOPT -> HPSPEC) == 
-        if displayAsGF(#1)$GOPT0 then
-            partitions := FilteredPartitionStream #1
-            [ADEguessStream(#1, partitions, qDiffDS(q, #1, #2), 1$UFPSF), _
-             repeating([0$NNI])$Stream(NNI), _
-             ADEtestStream(#1, partitions, qDiffDSF(q, #1, #2), 1$UFPSSUPF), _
-             ADEEXPRRStream(#1, #2, partitions, qDiffDX(q, #1, #2, #3), diff1X), _
-             diffA, diffAF, diffAX, diffC]$HPSPEC
-        else
-            error "Guess: guessADE supports only displayAsGF"
-
-@
-
-\paragraph{Shifting} The shift operator transforms a sequence $u(k)$ into
-$u(k+1)$. We also provide operators [[ShiftSXGF]], [[ShiftAXGF]] that act on
-the power series, as long as no powering is involved. In this case, shifting
-transforms $f(x)$ into $\frac{f(x)-f(0)}{x}$.
-
-Multiplication with $z$ transforms the coefficients $u(n)$ of the series into
-$z u(n) := n u(n)$. The description in terms of power series is given by
-$xDf(x)$.
-
-% The coefficients of $x^n$ are $1, f(n), f(n+1), f(n)^2, f(n)f(n+1),\dots$
-% What does this remark mean?
-<<implementation: Guess - Hermite-Pade - Operators>>=
-ShiftSX(expr: EXPRR, x: Symbol, n: NNI): EXPRR == 
-    eval(expr, x::EXPRR, x::EXPRR+n::EXPRR)
-
-ShiftSXGF(expr: EXPRR, x: Symbol, n: NNI): EXPRR == 
-    if zero? n then expr
-    else
-        l := [eval(D(expr, x, i)/factorial(i)::EXPRR, x::EXPRR, 0$EXPRR)_
-              *(x::EXPRR)**i for i in 0..n-1]
-        (expr-reduce(_+, l))/(x::EXPRR**n)
-
-ShiftSS(s:UFPSF, n:NNI): UFPSF == 
-    ((quoByVar #1)**n)$MappingPackage1(UFPSF) (s)
-
-ShiftSF(s:UFPSSUPF, n: NNI):UFPSSUPF == 
-    ((quoByVar #1)**n)$MappingPackage1(UFPSSUPF) (s)
-
-@
-%$
-
-As before, next three functions extract the coefficient of $x^k$ in $z^l f(x)$.
-
-<<implementation: Guess - Hermite-Pade - Operators>>=
-ShiftAX(l: NNI, n: Symbol, f: EXPRR): EXPRR == 
-    n::EXPRR**l * f
-
-ShiftAXGF(l: NNI, x: Symbol, f: EXPRR): EXPRR == 
--- I need to help the compiler here, unfortunately
-      if zero? l then f
-      else
-          s := [stirling2(l, i)$IntegerCombinatoricFunctions(Integer)::EXPRR _
-                * (x::EXPRR)**i*D(f, x, i) for i in 1..l]
-          reduce(_+, s)
-
-ShiftA(k: NNI, l: NNI, f: SUP S): S == 
-    ShiftAction(k, l, f)$FFFG(S, SUP S)
-
-ShiftAF(k: NNI, l: NNI, f: UFPSSUPF): SUP F == 
-    ShiftAction(k, l, f)$FFFG(SUP F, UFPSSUPF)
-
-ShiftC(total: NNI): List S == 
-    ShiftC(total)$FFFG(S, SUP S)
-
-shiftHP options == 
-    partitions := FilteredPartitionStream options
-    if displayAsGF(options)$GOPT0 then
-        if maxPower(options)$GOPT0 = 1 then
-            [ADEguessStream(#1, partitions, ShiftSS, (1-monomial(1,1))**(-1)),_
-             ADEdegreeStream partitions, _
-             ADEtestStream(#1, partitions, ShiftSF, (1-monomial(1,1))**(-1)), _
-             ADEEXPRRStream(#1, #2, partitions, ShiftSXGF, 1/(1-#1::EXPRR)), _
-             ShiftA, ShiftAF, ShiftAXGF, ShiftC]$HPSPEC
-       else
-            error "Guess: no support for the Shift operator with displayAsGF _
-                   and maxPower>1"
-    else
-        [ADEguessStream2(#1, partitions, ShiftSS, (1-monomial(1,1))**(-1)), _
-         ADEdegreeStream partitions, _
-         ADEtestStream2(#1, partitions, ShiftSF, (1-monomial(1,1))**(-1)), _
-         ADEEXPRRStream(#1, #2, partitions, ShiftSX, diff1X), _
-         ShiftA, ShiftAF, ShiftAX, ShiftC]$HPSPEC
-
-@
-
-\paragraph{$q$-Shifting} The $q$-shift also transforms $u(n)$ into $u(n+1)$,
-and we can reuse the corresponding functions of the previous paragraph.
-However, this time multiplication with $z$ is defined differently: the
-coefficient of $x^k$ in $z u(n)$ is $q^n u(n)$. We do not define the
-corresponding functionality for power series.
-
-%The coefficients of $x^n$ are $1, f(n), f(n+1), f(n)^2, f(n)f(n+1),\dots$
-% What does this remark mean?
-<<implementation: Guess - Hermite-Pade - Operators>>=
-if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-    qShiftAX(q: Symbol, l: NNI, n: Symbol, f: EXPRR): EXPRR == 
-        (q::EXPRR)**(l*n::EXPRR) * f
-
-    qShiftA(q: Symbol, k: NNI, l: NNI, f: SUP S): S ==
-        qShiftAction(q::S, k, l, f)$FFFG(S, SUP S)
-
-    qShiftAF(q: Symbol, k: NNI, l: NNI, f: UFPSSUPF): SUP F ==
-        qShiftAction(q::F::SUP(F), k, l, f)$FFFG(SUP F, UFPSSUPF)
-
-    qShiftC(q: Symbol, total: NNI): List S == 
-        qShiftC(q::S, total)$FFFG(S, SUP S)
-
-    shiftHP(q: Symbol): (LGOPT -> HPSPEC) == 
-        partitions := FilteredPartitionStream #1
-        if displayAsGF(#1)$GOPT0 then
-            error "Guess: no support for the qShift operator with displayAsGF"
-        else
-            [ADEguessStream2(#1, partitions, ShiftSS, _
-                             (1-monomial(1,1))**(-1)), _
-             ADEdegreeStream partitions, _
-             ADEtestStream2(#1, partitions, ShiftSF, _
-                            (1-monomial(1,1))**(-1)), _
-             ADEEXPRRStream(#1, #2, partitions, ShiftSX, diff1X), _
-             qShiftA(q, #1, #2, #3), qShiftAF(q, #1, #2, #3), _
-             qShiftAX(q, #1, #2, #3), qShiftC(q, #1)]$HPSPEC
-
-@
-%$
-\paragraph{Extend the action to polynomials}
-
-The following operation uses the given action of $z$ on a function to multiply
-a $f$ with a polynomial.
-
-<<implementation: Guess - Hermite-Pade - Operators>>=
-makeEXPRR(DAX: DIFFSPECAX, x: Symbol, p: SUP F, expr: EXPRR): EXPRR ==
-    if zero? p then 0$EXPRR
-    else
-        coerce(leadingCoefficient p)::EXPRR * DAX(degree p, x, expr) _
-        + makeEXPRR(DAX, x, reductum p, expr)
-
-@
-%$
-
-\subsubsection{Utilities}
-
-[[list2UFPSF]] and [[list2UFPSSUPF]] transform the list passed to the guessing
-functions into a series. One might be tempted to transform the list into a
-polynomial instead, but the present approach makes computing powers and
-derivatives much cheaper, since, because of laziness, only coefficients that
-are actually used are computed.
-
-The second of the two procedures augments the list with a transcendental
-element. This way we can easily check whether a coefficient is valid or not: if
-it contains the transcendental element, it depends on data we do not have. In
-other words, this transcendental element simply represents the $O(x^d)$, when
-$d$ is the number of elements in the list.
-
-<<implementation: Guess - Hermite-Pade - Utilities>>=
-list2UFPSF(list: List F): UFPSF == series(list::Stream F)$UFPSF
-
-list2UFPSSUPF(list: List F): UFPSSUPF == 
-    l := [e::SUP(F) for e in list for i in 0..]::Stream SUP F
-    series(l)$UFPSSUPF + monomial(monomial(1,1)$SUP(F), #list)$UFPSSUPF
-
-@
-
-[[SUPF2SUPSUPF]] interprets each coefficient as a univariate polynomial.
-
-<<implementation: Guess - Hermite-Pade - Utilities>>=
-SUPF2SUPSUPF(p: SUP F): SUP SUP F ==
-    map(#1::SUP F, p)$SparseUnivariatePolynomialFunctions2(F, SUP F)
-
-@
-
-[[getListSUPF]] returns the first [[o]] elements of the stream, each truncated
-after degree [[deg]]. 
-
-<<implementation: Guess - Hermite-Pade - Utilities>>=
-UFPSF2SUPF(f: UFPSF, deg: NNI): SUP F == 
-    makeSUP univariatePolynomial(f, deg)
-
-getListSUPF(s: Stream UFPSF, o: NNI, deg: NNI): List SUP F ==
-    map(UFPSF2SUPF(#1, deg), entries complete first(s, o))
-       $ListFunctions2(UFPSF, SUP F)
-
-S2EXPRR(s: S): EXPRR ==
-    if F is S then 
-        coerce(s pretend F)@EXPRR
-    else if F is Fraction S then
-        coerce(s::Fraction(S))@EXPRR
-    else error "Type parameter F should be either equal to S or equal _
-                to Fraction S"
-
-<<implementation: Guess - guessInterpolate>>
-<<implementation: Guess - guessInterpolate2>>
-<<implementation: Guess - testInterpolant>>
-@
-%$
-
-[[guessInterpolate]] calls the appropriate [[generalInterpolation]] from
-[[FFFG]], for one vector of degrees, namely [[eta]].
-
-<<implementation: Guess - guessInterpolate>>=
-guessInterpolate(guessList: List SUP F, eta: List NNI, D: HPSPEC)
-                : Matrix SUP S ==
-    if F is S then 
-        vguessList: Vector SUP S := vector(guessList pretend List(SUP(S)))
-        generalInterpolation((D.C)(reduce(_+, eta)), D.A, 
-                             vguessList, eta)$FFFG(S, SUP S)
-    else if F is Fraction S then
-        vguessListF: Vector SUP F := vector(guessList)
-        generalInterpolation((D.C)(reduce(_+, eta)), D.A, 
-                             vguessListF, eta)$FFFGF(S, SUP S, SUP F)
-
-    else error "Type parameter F should be either equal to S or equal _
-                to Fraction S"
-@
-
-[[guessInterpolate2]] calls the appropriate [[generalInterpolation]] from
-[[FFFG]], for all degree vectors with given [[sumEta]] and [[maxEta]].
-
-<<implementation: Guess - guessInterpolate2>>=
-guessInterpolate2(guessList: List SUP F, 
-                  sumEta: NNI, maxEta: NNI, 
-                  D: HPSPEC): Stream Matrix SUP S ==
-    if F is S then 
-        vguessList: Vector SUP S := vector(guessList pretend List(SUP(S)))
-        generalInterpolation((D.C)(sumEta), D.A, 
-                             vguessList, sumEta, maxEta)
-                            $FFFG(S, SUP S)
-    else if F is Fraction S then
-        vguessListF: Vector SUP F := vector(guessList)
-        generalInterpolation((D.C)(sumEta), D.A, 
-                             vguessListF, sumEta, maxEta)
-                            $FFFGF(S, SUP S, SUP F)
-
-    else error "Type parameter F should be either equal to S or equal _
-                to Fraction S"
-@
-
-[[testInterpolant]] checks whether p is really a solution.
-<<implementation: Guess - testInterpolant>>=
-testInterpolant(resi: List SUP S, 
-                list: List F,
-                testList: List UFPSSUPF, 
-                exprList: List EXPRR,
-                initials: List EXPRR,
-                guessDegree: NNI,
-                D: HPSPEC, 
-                dummy: Symbol, op: BasicOperator, options: LGOPT)
-               : Union("failed", Record(function: EXPRR, order: NNI)) ==
-@
-
-First we make sure it is not a solution we should have found already. Note that
-we cannot check this if [[maxDegree]] is set, in which case some initial
-solutions may have been overlooked.
-
-<<implementation: Guess - testInterpolant>>=
-    ((maxDegree(options)$GOPT0 = -1) and 
-     (allDegrees(options)$GOPT0 = false) and 
-     zero?(last resi)) 
-     => return "failed"
-@
-
-Then we check all the coefficients that should be valid.  We want the zero
-solution only, if the function is really zero. Without this test, every
-sequence ending with zero is interpreted as the zero sequence, since the factor
-in front of the only non-vanishing term can cancel everything else.
-
-<<implementation: Guess - testInterpolant>>=
-    nonZeroCoefficient: Integer := 0
-
-    for i in 1..#resi repeat
-        if not zero? resi.i then
-            if zero? nonZeroCoefficient then
-                nonZeroCoefficient := i
-            else 
-                nonZeroCoefficient := 0
-                break
-@
-
-We set [[nonZeroCoefficient]] to the only non zero coefficient or, if there are
-several, it is $0$. It should not happen that all coefficients in [[resi]]
-vanish.
-\begin{ToDo}
-  Check that not all coefficients in [[resi]] can vanish simultaneously.
-\end{ToDo}
-
-<<implementation: Guess - testInterpolant>>=
-    if not zero? nonZeroCoefficient then
-        (freeOf?(exprList.nonZeroCoefficient, name op)) => return "failed"
-
-        for e in list repeat
-            if not zero? e then return "failed"
-@
-
-We first deal with the case that there is only one non-vanishing coefficient in
-[[resi]]. If the only expression in [[exprList]] whose coefficient does not
-vanish does not contain the name of the generating function, or if there is a
-non-zero term in [[list]], we reject the proposed solution.
-
-<<implementation: Guess - testInterpolant>>=
-    else
-        resiSUPF := map(SUPF2SUPSUPF SUPS2SUPF #1, resi)
-                       $ListFunctions2(SUP S, SUP SUP F)
-
-        iterate? := true;
-        for d in guessDegree+1.. repeat
-            c: SUP F := generalCoefficient(D.AF, vector testList, 
-                                           d, vector resiSUPF)
-                                          $FFFG(SUP F, UFPSSUPF)
-
-            if not zero? c then 
-                iterate? := ground? c
-                break
-
-        iterate? => return "failed"
-@
-
-Here we check for each degree [[d]] larger than [[guessDegree]] whether the
-proposed linear combination vanishes. When the first coefficient that does not
-vanish contains the transcendental element we accept the linear combination as
-a solution.
-
-Finally, it seems that we have found a solution. Now we cancel the greatest
-common divisor of the equation. Note that this may take quite some time, it
-seems to be quicker to check [[generalCoefficient]] with the original [[resi]].
-
-If [[S]] is a [[Field]], the [[gcd]] will always be $1$.  Thus, in this case we
-make the result monic.
-
-<<implementation: Guess - testInterpolant>>=
-    g: SUP S
-    if S has Field 
-    then g := leadingCoefficient(find(not zero? #1, reverse resi)::SUP(S))::SUP(S)
-    else g := gcd resi
-    resiF := map(SUPS2SUPF((#1 exquo g)::SUP(S)), resi)
-                $ListFunctions2(SUP S, SUP F)
-
-
-    if debug(options)$GOPT0 then 
-        output(hconcat("trying possible solution ", resiF::OutputForm))
-              $OutputPackage
-
--- transform each term into an expression
-
-    ex: List EXPRR := [makeEXPRR(D.AX, dummy, p, e) _
-                       for p in resiF for e in exprList]
-
--- transform the list of expressions into a sum of expressions
-
-    res: EXPRR
-    if displayAsGF(options)$GOPT0 then 
-        res := evalADE(op, dummy, variableName(options)$GOPT0::EXPRR, 
-                       indexName(options)$GOPT0::EXPRR,
-                       numerator reduce(_+, ex), 
-                       reverse initials)
-                      $RecurrenceOperator(Integer, EXPRR)
-        ord: NNI := 0
--- FIXME: checkResult doesn't really work yet for generating functions
-    else 
-        res := evalRec(op, dummy, indexName(options)$GOPT0::EXPRR, 
-                       indexName(options)$GOPT0::EXPRR,
-                       numerator reduce(_+, ex), 
-                       reverse initials)
-                      $RecurrenceOperator(Integer, EXPRR)
-        ord: NNI := checkResult(res, indexName(options)$GOPT0, _
-                                #list, list, options)
-
-
-    [res, ord]$Record(function: EXPRR, order: NNI)
-
-@
-
-\subsubsection{The main routine}
-
-The following is the main guessing routine, called by all others -- except
-[[guessExpRat]].
-
-<<implementation: Guess - guessHPaux>>=
-guessHPaux(list: List F, D: HPSPEC, options: LGOPT): GUESSRESULT ==
-    reslist: GUESSRESULT := []
-
-    listDegree := #list-1-safety(options)$GOPT0
-    if listDegree < 0 then return reslist
-@
-%$
-
-\sloppypar We do as if we knew only the coefficients up to and including degree
-[[listDegree-safety]]. Thus, if we have less elements of the sequence than
-[[safety]], there remain no elements for guessing.  Originally we demanded to
-have at least two elements for guessing.  However, we want to be able to induce
-from $[c,c]$ that the function equals $c$ with [[safety]] one. This is
-important if we apply, for example, [[guessRat]] recursively. In this case,
-[[listDegree]] equals zero.
-
-<<implementation: Guess - guessHPaux>>=
-    a := functionName(options)$GOPT0
-    op := operator a
-    x := variableName(options)$GOPT0
-    dummy := new$Symbol
-
-    initials: List EXPRR := [coerce(e)@EXPRR for e in list]
-
-@
-%$
-
-We need to create several streams. Let $P$ be the univariate power series whose
-first few elements are given by [[list]]. As an example, consider the
-differentiation setting. In this case, the elements of [[guessS]] consist of
-$P$ differentiated and taken to some power. The elements of [[degreeS]] are
-integers, that tell us how many terms less than in [[list]] are valid in the
-corresponding element of [[guessS]]. The elements of [[testS]] are very similar
-to those of [[guessS]], with the difference that they are derived from $P$ with
-an transcendental element added, which corresponds to $O(x^d)$. Finally, the
-elements of [[exprS]] contain representations of the transformations applied to
-$P$ as expressions.
-
-\begin{ToDo}
-  I am not sure whether it is better to get rid of denominators in [[list]]
-  here or, as I currently do it, only in [[generalInterpolation$FFFG]]. %$
-  If we clear them at here, we cannot take advantage of factors that may appear
-  only after differentiating or powering.
-\end{ToDo}
-
-
-<<implementation: Guess - guessHPaux>>=
-    guessS  := (D.guessStream)(list2UFPSF list)
-    degreeS := D.degreeStream
-    testS   := (D.testStream)(list2UFPSSUPF list)
-    exprS   := (D.exprStream)(op(dummy::EXPRR)::EXPRR, dummy)
-@
-
-We call the number of terms of the linear combination its \emph{order}.  We
-consider linear combinations of at least two terms, since otherwise the
-function would have to vanish identically\dots
-
-When proceeding in the stream [[guessS]], it may happen that we loose valid
-terms. For example, when trying to find a linear ordinary differential
-equation, we are looking for a linear combination of $f, f^\prime,
-f^{\prime\prime}, \dots$. Suppose [[listDegree]] equals $2$, i.e. we have
-\begin{align*}
-  f                &= l_0 + l_1 x + l_2 x^2\\
-  f^\prime         &= l_1 + 2l_2 x\\
-  f^{\prime\prime} &= 2l_2.    
-\end{align*}
-Thus, each time we differentiate the series, we loose one term for guessing.
-Therefore, we cannot use the coefficient of $x^2$ of $f^{\prime\prime}$ for
-generating a linear combination. [[guessDegree]] contains the degree up to
-which all the generated series are correct, taking into account [[safety]].
-
-<<implementation: Guess - guessHPaux>>=
-    iterate?: Boolean := false -- this is necessary because the compiler
-                               -- doesn't understand => "iterate" properly
-                               -- the latter just leaves the current block, it
-                               -- seems 
-    for o in 2.. repeat
-        empty? rest(guessS, (o-1)::NNI) => break
-        guessDegree: Integer := listDegree-(degreeS.o)::Integer
-        guessDegree < 0 => break
-        if debug(options)$GOPT0 then 
-            output(hconcat("Trying order ", o::OutputForm))$OutputPackage
-            output(hconcat("guessDegree is ", guessDegree::OutputForm))
-                  $OutputPackage
-@ 
-%$"
-
-We now have to distinguish between the case where we try all combination of
-degrees and the case where we try only an (nearly) evenly distributed vector of
-degrees.
-
-In the first case, [[guessInterpolate2]] is going to look at all degree vectors
-with [[o]] elements with total degree [[guessDegree+1]].  We give up as soon as
-the order [[o]] is greater than the number of available terms plus one. In the
-extreme case, i.e., when [[o=guessDegree+2]], we allow for example constant
-coefficients for all terms of the linear combination. It seems that it is a bit
-arbitrary at what point we stop, however, we would like to be consistent with
-the evenly distributed case.
-
-<<implementation: Guess - guessHPaux>>=
-        if allDegrees(options)$GOPT0 then
-            (o > guessDegree+2) => return reslist
-
-            maxEta: Integer := 1+maxDegree(options)$GOPT0
-            if maxEta = 0 
-            then maxEta := guessDegree+1
-        else
-@
-
-In the second case, we first compute the number of parameters available for
-determining the coefficient polynomials. We have to take care of the fact, that
-HermitePade produces solutions with sum of degrees being one more than the sum
-of elements in [[eta]].
-
-<<implementation: Guess - guessHPaux>>=
-            maxParams := divide(guessDegree::NNI+1, o)
-            if debug(options)$GOPT0 
-            then output(hconcat("maxParams: ", maxParams::OutputForm))
-                       $OutputPackage
-@
-
-If we do not have enough parameters, we give up. We allow for at most one zero
-entry in the degree vector, because then there is one column that allows at
-least a constant term in each entry.
-
-<<implementation: Guess - guessHPaux>>=
-            if maxParams.quotient = 0 and maxParams.remainder < o-1 
-            then return reslist
-@
-
-If [[maxDegree]] is set, we skip the first few partitions, unless we cannot
-increase the order anymore.
-\begin{ToDo}
-  I have no satisfactory way to determine whether we can increase the order or
-  not.
-\end{ToDo}
-
-<<implementation: Guess - guessHPaux>>=
-            if ((maxDegree(options)$GOPT0 ~= -1) and
-                (maxDegree(options)$GOPT0 < maxParams.quotient)) and
-                not (empty? rest(guessS, o) or
-                     ((newGuessDegree := listDegree-(degreeS.(o+1))::Integer)
-                          < 0) or
-                      (((newMaxParams := divide(newGuessDegree::NNI+1, o+1))
-                          .quotient = 0) and
-                       (newMaxParams.remainder < o)))
-            then iterate? := true
-            else if ((maxDegree(options)$GOPT0 ~= -1) and
-                     (maxParams.quotient > maxDegree(options)$GOPT0))
-                 then
-                     guessDegree := o*(1+maxDegree(options)$GOPT0)-2
-                     eta: List NNI
-                         := [(if i < o    _
-                               then maxDegree(options)$GOPT0 + 1   _
-                               else maxDegree(options)$GOPT0)::NNI _
-                             for i in 1..o]
-                 else eta: List NNI
-                          := [(if i <= maxParams.remainder   _
-                               then maxParams.quotient + 1   _
-                               else maxParams.quotient)::NNI for i in 1..o]
-@
-
-We distribute the parameters as evenly as possible.  Is it better to have
-higher degrees at the end or at the beginning?
-
-It remains to prepare [[guessList]], which is the list of [[o]] power series
-polynomials truncated after degree [[guessDegree]]. Then we can call
-HermitePade.
-
-\begin{ToDo}
-  [[maxDegree]] should be handled differently, maybe: we should only pass as
-  many coefficients to [[FFFG]] as [[maxDegree]] implies! That is, if we cannot
-  increase the order anymore, we should decrease [[guessDegree]] to %
-  $o\cdot [[maxDegree]] - 2$ and set [[eta]] accordingly.  I might have to take
-  care of [[allDegrees]], too.
-\end{ToDo}
-
-<<implementation: Guess - guessHPaux>>=
-        if iterate? 
-        then 
-            iterate? := false
-            if debug(options)$GOPT0 then output("iterating")$OutputPackage
-        else 
-            guessList: List SUP F    := getListSUPF(guessS, o, guessDegree::NNI)
-            testList:  List UFPSSUPF := entries complete first(testS, o)
-            exprList:  List EXPRR    := entries complete first(exprS, o)
-
-            if debug(options)$GOPT0 then 
-                output("The list of expressions is")$OutputPackage
-                output(exprList::OutputForm)$OutputPackage
-
-            if allDegrees(options)$GOPT0 then
-                MS: Stream Matrix SUP S := guessInterpolate2(guessList, 
-                                                             guessDegree::NNI+1,
-                                                             maxEta::NNI, D)
-                repeat
-                    (empty? MS) => break
-                    M := first MS
-
-                    for i in 1..o repeat
-                        res := testInterpolant(entries column(M, i), 
-                                               list,
-                                               testList, 
-                                               exprList,
-                                               initials,
-                                               guessDegree::NNI, 
-                                               D, dummy, op, options)
-
-                        (res case "failed") => "iterate"
-
-                        if not member?(res, reslist) 
-                        then reslist := cons(res, reslist)
-
-                        if one(options)$GOPT0 then return reslist 
-
-                    MS := rest MS
-            else
-                M: Matrix SUP S := guessInterpolate(guessList, eta, D)
-
-                for i in 1..o repeat
-                    res := testInterpolant(entries column(M, i), 
-                                           list,
-                                           testList, 
-                                           exprList,
-                                           initials,
-                                           guessDegree::NNI, 
-                                           D, dummy, op, options)
-                    (res case "failed") => "iterate"
-
-                    if not member?(res, reslist) 
-                    then reslist := cons(res, reslist)
-
-                    if one(options)$GOPT0 then return reslist 
-
-    reslist
-
-@
-
-\begin{ToDo}
-  The duplicated block at the end should really go into [[testInterpolant]], I
-  guess. Furthermore, it would be better to remove duplicates already there.
-\end{ToDo}
-
-\subsubsection{Specialisations}
-
-For convenience we provide some specialisations that cover the most common
-situations.
-
-\paragraph{generating functions}
-
-<<implementation: Guess - guessHP>>=
-guessHP(D: LGOPT -> HPSPEC): GUESSER == guessHPaux(#1, D #2, #2)
-
-guessADE(list: List F, options: LGOPT): GUESSRESULT == 
-    opts: LGOPT := cons(displayAsGF(true)$GuessOption, options)
-    guessHPaux(list, diffHP opts, opts)
-
-guessADE(list: List F): GUESSRESULT == guessADE(list, [])
-
-guessAlg(list: List F, options: LGOPT) == 
-    guessADE(list, cons(maxDerivative(0)$GuessOption, options))
-
-guessAlg(list: List F): GUESSRESULT == guessAlg(list, [])
-
-guessHolo(list: List F, options: LGOPT): GUESSRESULT ==
-    guessADE(list, cons(maxPower(1)$GuessOption, options))
-
-guessHolo(list: List F): GUESSRESULT == guessHolo(list, [])
-
-guessPade(list: List F, options: LGOPT): GUESSRESULT ==
-    opts := append(options, [maxDerivative(0)$GuessOption, 
-                             maxPower(1)$GuessOption, 
-                             allDegrees(true)$GuessOption])
-    guessADE(list, opts)
-
-guessPade(list: List F): GUESSRESULT == guessPade(list, [])
-@
-
-\paragraph{$q$-generating functions}
-
-<<implementation: Guess - guessHP>>=
-if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-    guessADE(q: Symbol): GUESSER ==
-        opts: LGOPT := cons(displayAsGF(true)$GuessOption, #2)
-        guessHPaux(#1, (diffHP q)(opts), opts)
-
-@
-%$
-
-\paragraph{coefficients}
-
-<<implementation: Guess - guessHP>>=
-guessRec(list: List F, options: LGOPT): GUESSRESULT == 
-      opts: LGOPT := cons(displayAsGF(false)$GuessOption, options)
-      guessHPaux(list, shiftHP opts, opts)
-
-guessRec(list: List F): GUESSRESULT == guessRec(list, [])
-
-guessPRec(list: List F, options: LGOPT): GUESSRESULT ==
-      guessRec(list, cons(maxPower(1)$GuessOption, options))
-
-guessPRec(list: List F): GUESSRESULT == guessPRec(list, [])
-
-guessRat(list: List F, options: LGOPT): GUESSRESULT ==
-      opts := append(options, [maxShift(0)$GuessOption, 
-                               maxPower(1)$GuessOption, 
-                               allDegrees(true)$GuessOption])
-      guessRec(list, opts)
-
-guessRat(list: List F): GUESSRESULT == guessRat(list, [])
-
-@
-%$
-
-\paragraph{$q$-coefficients}
-
-<<implementation: Guess - guessHP>>=
-if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-    guessRec(q: Symbol): GUESSER ==
-        opts: LGOPT := cons(displayAsGF(false)$GuessOption, #2)
-        guessHPaux(#1, (shiftHP q)(opts), opts)
-
-    guessPRec(q: Symbol): GUESSER ==
-        opts: LGOPT := append([displayAsGF(false)$GuessOption, 
-                               maxPower(1)$GuessOption], #2)
-        guessHPaux(#1, (shiftHP q)(opts), opts)
-
-    guessRat(q: Symbol): GUESSER ==
-        opts := append(#2, [displayAsGF(false)$GuessOption, 
-                            maxShift(0)$GuessOption, 
-                            maxPower(1)$GuessOption, 
-                            allDegrees(true)$GuessOption])
-        guessHPaux(#1, (shiftHP q)(opts), opts)
-
-@
-%$
-
-\subsection{[[guess]] -- applying operators recursively}
-
-The main observation made by Christian Krattenthaler in designing his program
-\Rate\ is the following: it occurs frequently that although a sequence of
-numbers is not generated by a rational function, the sequence of successive
-quotients is.
-
-We slightly extend upon this idea, and apply recursively one or both of the two
-following operators:
-\begin{description}
-\item[$\Delta_n$] the differencing operator, transforming $f(n)$ into
-  $f(n)-f(n-1)$, and
-\item[$Q_n$] the operator that transforms $f(n)$ into $f(n)/f(n-1)$.
-\end{description}
-
-<<implementation: Guess - guess>>=
-guess(list: List F, guessers: List GUESSER, ops: List Symbol, 
-      options: LGOPT): GUESSRESULT ==
-    maxLevel := maxLevel(options)$GOPT0
-    xx := indexName(options)$GOPT0
-    if debug(options)$GOPT0 then
-        output(hconcat("guessing level ", maxLevel::OutputForm))
-              $OutputPackage
-        output(hconcat("guessing ", list::OutputForm))$OutputPackage
-    res: GUESSRESULT := []
-    len := #list :: PositiveInteger
-    if len <= 1 then return res
-
-    for guesser in guessers repeat
-        res := append(guesser(list, options), res)
-
-        if debug(options)$GOPT0 then
-            output(hconcat("res ", res::OutputForm))$OutputPackage
-
-        if one(options)$GOPT0 and not empty? res then return res
-
-    if (maxLevel = 0) then return res
-
-    if member?('guessProduct, ops) and not member?(0$F, list) then
-        prodList: List F := [(list.(i+1))/(list.i) for i in 1..(len-1)]
-
-        if not every?(one?, prodList) then
-            var: Symbol := subscript('p, [len::OutputForm])
-            prodGuess := 
-                [[coerce(list.(guess.order+1)) 
-                  * product(guess.function, _
-                            equation(var, _
-                                     (guess.order)::EXPRR..xx::EXPRR-1)), _
-                  guess.order] _
-                 for guess in guess(prodList, guessers, ops,  
-                                    append([indexName(var)$GuessOption,
-                                            maxLevel(maxLevel-1)
-                                                    $GuessOption],
-                                           options))$%]
-
-            if debug(options)$GOPT0 then
-                output(hconcat("prodGuess "::OutputForm, 
-                               prodGuess::OutputForm))
-                      $OutputPackage
-
-            for guess in prodGuess 
-                    | not any?(guess.function = #1.function, res) repeat
-                res := cons(guess, res)
-
-    if one(options)$GOPT0 and not empty? res then return res
-
-    if member?('guessSum, ops) then
-        sumList: List F := [(list.(i+1))-(list.i) for i in 1..(len-1)]
-
-        if not every?(#1=sumList.1, sumList) then
-            var: Symbol := subscript('s, [len::OutputForm])
-            sumGuess := 
-                [[coerce(list.(guess.order+1)) _
-                  + summation(guess.function, _
-                              equation(var, _
-                                       (guess.order)::EXPRR..xx::EXPRR-1)),_
-                  guess.order] _
-                 for guess in guess(sumList, guessers, ops,
-                                    append([indexName(var)$GuessOption,
-                                            maxLevel(maxLevel-1)
-                                                    $GuessOption],
-                                           options))$%]
-
-            for guess in sumGuess 
-                    | not any?(guess.function = #1.function, res) repeat
-                res := cons(guess, res)
-
-    res
-
-guess(list: List F): GUESSRESULT == 
-    guess(list, [guessADE$%, guessRec$%], ['guessProduct, 'guessSum], [])
-
-guess(list: List F, options: LGOPT): GUESSRESULT == 
-    guess(list, [guessADE$%, guessRat$%], ['guessProduct, 'guessSum], 
-          options)
-
-guess(list: List F, guessers: List GUESSER, ops: List Symbol)
-     : GUESSRESULT == 
-    guess(list, guessers, ops, [])
-
-@
-%$
-
-\section{package GUESSINT GuessInteger}
-<<package GUESSINT GuessInteger>>=
--- concerning algebraic functions, it may make sense to look at A.J.van der
--- Poorten, Power Series Representing Algebraic Functions, Section 6.
-)abbrev package GUESSINT GuessInteger
-++ Description:
-++ This package exports guessing of sequences of rational numbers
-GuessInteger() == Guess(Fraction Integer, Integer, Expression Integer, 
-                     Fraction Integer,
-                     id$MappingPackage1(Fraction Integer), 
-                     coerce$Expression(Integer))
-
-@
-
-\section{package GUESSF1 GuessFiniteFunctions}
-<<package GUESSF1 GuessFiniteFunctions>>=
-)abbrev package GUESSF1 GuessFiniteFunctions
-++ Description:
-++ This package exports guessing of sequences of numbers in a finite field
-GuessFiniteFunctions(F:Join(FiniteFieldCategory, ConvertibleTo Integer)):
-  Exports == Implementation where
-
-    EXPRR ==> Expression Integer
-
-    Exports == with
-
-      F2EXPRR: F -> EXPRR
-
-    Implementation == add
-
-      F2EXPRR(p: F): EXPRR == convert(p)@Integer::EXPRR
-
-@
-
-\section{package GUESSF GuessFinite}
-<<package GUESSF GuessFinite>>=
-)abbrev package GUESSF GuessFinite
-++ Description:
-++ This package exports guessing of sequences of numbers in a finite field
-GuessFinite(F:Join(FiniteFieldCategory, ConvertibleTo Integer)) ==
-  Guess(F, F, Expression Integer, Integer, coerce$F,
-        F2EXPRR$GuessFiniteFunctions(F))
-
-@
-
-\section{package GUESSP GuessPolynomial}
-<<package GUESSP GuessPolynomial>>=
-)abbrev package GUESSP GuessPolynomial
-++ Description:
-++ This package exports guessing of sequences of rational functions
-GuessPolynomial() == Guess(Fraction Polynomial Integer, Polynomial Integer, 
-                           Expression Integer, 
-                           Fraction Polynomial Integer,
-                           id$MappingPackage1(Fraction Polynomial Integer), 
-                           coerce$Expression(Integer))
-
-@
-
-\section{package GUESSAN GuessAlgebraicNumber}
-<<package GUESSAN GuessAlgebraicNumber>>=
-)abbrev package GUESSAN GuessAlgebraicNumber
-++ Description:
-++ This package exports guessing of sequences of rational functions
-GuessAlgebraicNumber() == Guess(AlgebraicNumber, AlgebraicNumber, 
-                           Expression Integer, 
-                           AlgebraicNumber,
-                           id$MappingPackage1(AlgebraicNumber), 
-                           coerce$Expression(Integer))
-
-@
-\section{package GUESSUP GuessUnivariatePolynomial}
-<<package GUESSUP GuessUnivariatePolynomial>>=
-)abbrev package GUESSUP GuessUnivariatePolynomial
-++ Description:
-++ This package exports guessing of sequences of univariate rational functions
-GuessUnivariatePolynomial(q: Symbol): Exports == Implementation where
-
-    UP ==> MyUnivariatePolynomial(q, Integer)
-    EXPRR ==> MyExpression(q, Integer)
-    F ==> Fraction UP
-    S ==> UP
-    NNI ==> NonNegativeInteger
-    LGOPT ==> List GuessOption
-    GUESSRESULT ==> List Record(function: EXPRR, order: NNI)
-    GUESSER ==> (List F, LGOPT) -> GUESSRESULT
-
-    Exports == with
-
-        guess: List F -> GUESSRESULT
-          ++ \spad{guess l} applies recursively \spadfun{guessRec} and
-          ++ \spadfun{guessADE} to the successive differences and quotients of
-          ++ the list. Default options as described in
-          ++ \spadtype{GuessOptionFunctions0} are used.
-
-        guess: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guess(l, options)} applies recursively \spadfun{guessRec}
-          ++ and \spadfun{guessADE} to the successive differences and quotients
-          ++ of the list. The given options are used.
-
-        guess: (List F, List GUESSER, List Symbol) -> GUESSRESULT
-          ++ \spad{guess(l, guessers, ops)} applies recursively the given
-          ++ guessers to the successive differences if ops contains the symbol
-          ++ guessSum and quotients if ops contains the symbol guessProduct to
-          ++ the list. Default options as described in
-          ++ \spadtype{GuessOptionFunctions0} are used.
-
-        guess: (List F, List GUESSER, List Symbol, LGOPT) -> GUESSRESULT
-          ++ \spad{guess(l, guessers, ops)} applies recursively the given
-          ++ guessers to the successive differences if ops contains the symbol
-          ++ \spad{guessSum} and quotients if ops contains the symbol
-          ++ \spad{guessProduct} to the list. The given options are used.
-
-        guessExpRat: List F -> GUESSRESULT
-          ++ \spad{guessExpRat l} tries to find a function of the form 
-          ++ n+->(a+b n)^n r(n), where r(n) is a rational function, that fits
-          ++ l. 
-
-        guessExpRat: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessExpRat(l, options)} tries to find a function of the
-          ++ form n+->(a+b n)^n r(n), where r(n) is a rational function, that
-          ++ fits l. 
-
-        guessBinRat: List F -> GUESSRESULT
-          ++ \spad{guessBinRat(l, options)} tries to find a function of the
-          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
-          ++ function, that fits l. 
-
-        guessBinRat: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessBinRat(l, options)} tries to find a function of the
-          ++ form n+->binomial(a+b n, n) r(n), where r(n) is a rational 
-          ++ function, that fits l. 
-
---        if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-        guessExpRat: Symbol -> GUESSER
-          ++ \spad{guessExpRat q} returns a guesser that tries to find a
-          ++ function of the form n+->(a+b q^n)^n r(q^n), where r(q^n) is a
-          ++ q-rational function, that fits l.
-
-        guessBinRat: Symbol -> GUESSER
-          ++ \spad{guessBinRat q} returns a guesser that tries to find a
-          ++ function of the form n+->qbinomial(a+b n, n) r(n), where r(q^n) is a
-          ++ q-rational function, that fits l.
-
--------------------------------------------------------------------------------
-
-        guessHP: (LGOPT -> HPSPEC) -> GUESSER
-          ++ \spad{guessHP f} constructs an operation that applies Hermite-Pade
-          ++ approximation to the series generated by the given function f.
-
-        guessADE: List F -> GUESSRESULT
-          ++ \spad{guessADE l} tries to find an algebraic differential equation
-          ++ for a generating function whose first Taylor coefficients are
-          ++ given by l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}.
-
-        guessADE: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessADE(l, options)} tries to find an algebraic
-          ++ differential equation for a generating function whose first Taylor
-          ++ coefficients are given by l, using the given options.
-
-        guessAlg: List F -> GUESSRESULT
-          ++ \spad{guessAlg l} tries to find an algebraic equation for a
-          ++ generating function whose first Taylor coefficients are given by
-          ++ l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessADE}(l, maxDerivative == 0).
-
-        guessAlg: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessAlg(l, options)} tries to find an algebraic equation
-          ++ for a generating function whose first Taylor coefficients are
-          ++ given by l, using the given options. It is equivalent to
-          ++ \spadfun{guessADE}(l, options) with \spad{maxDerivative == 0}.
-
-        guessHolo: List F -> GUESSRESULT
-          ++ \spad{guessHolo l} tries to find an ordinary linear differential
-          ++ equation for a generating function whose first Taylor coefficients
-          ++ are given by l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessADE}\spad{(l, maxPower == 1)}.
-
-        guessHolo: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessHolo(l, options)} tries to find an ordinary linear
-          ++ differential equation for a generating function whose first Taylor
-          ++ coefficients are given by l, using the given options. It is
-          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
-          ++ \spad{maxPower == 1}.
-
-        guessPade: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessPade(l, options)} tries to find a rational function
-          ++ whose first Taylor coefficients are given by l, using the given
-          ++ options. It is equivalent to \spadfun{guessADE}\spad{(l,
-          ++ maxDerivative == 0, maxPower == 1, allDegrees == true)}.
-
-        guessPade: List F -> GUESSRESULT
-          ++ \spad{guessPade(l, options)} tries to find a rational function
-          ++ whose first Taylor coefficients are given by l, using the default
-          ++ options described in \spadtype{GuessOptionFunctions0}. It is
-          ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
-          ++ \spad{maxDerivative == 0, maxPower == 1, allDegrees == true}.
-
-        guessRec: List F -> GUESSRESULT
-          ++ \spad{guessRec l} tries to find an ordinary difference equation
-          ++ whose first values are given by l, using the default options
-          ++ described in \spadtype{GuessOptionFunctions0}.
-
-        guessRec: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessRec(l, options)} tries to find an ordinary difference
-          ++ equation whose first values are given by l, using the given
-          ++ options. 
-
-        guessPRec: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessPRec(l, options)} tries to find a linear recurrence
-          ++ with polynomial coefficients whose first values are given by l,
-          ++ using the given options. It is equivalent to
-          ++ \spadfun{guessRec}\spad{(l, options)} with \spad{maxPower == 1}.
-
-        guessPRec: List F -> GUESSRESULT
-          ++ \spad{guessPRec l} tries to find a linear recurrence with
-          ++ polynomial coefficients whose first values are given by l, using
-          ++ the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessRec}\spad{(l, maxPower == 1)}. 
-
-        guessRat: (List F, LGOPT) -> GUESSRESULT
-          ++ \spad{guessRat(l, options)} tries to find a rational function
-          ++ whose first values are given by l, using the given options. It is
-          ++ equivalent to \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower
-          ++ == 1, allDegrees == true)}.
-
-        guessRat: List F -> GUESSRESULT
-          ++ \spad{guessRat l} tries to find a rational function whose first
-          ++ values are given by l, using the default options described in
-          ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
-          ++ \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower == 1,
-          ++ allDegrees == true)}.
-
-        diffHP: LGOPT -> HPSPEC
-          ++ \spad{diffHP options} returns a specification for Hermite-Pade
-          ++ approximation with the differential operator
-
-        shiftHP: LGOPT -> HPSPEC
-          ++ \spad{shiftHP options} returns a specification for Hermite-Pade
-          ++ approximation with the shift operator
-
---        if F has RetractableTo Symbol and S has RetractableTo Symbol then
-
-        shiftHP: Symbol -> (LGOPT -> HPSPEC)
-          ++ \spad{shiftHP options} returns a specification for
-          ++ Hermite-Pade approximation with the $q$-shift operator
-
-        diffHP: Symbol -> (LGOPT -> HPSPEC)
-          ++ \spad{diffHP options} returns a specification for Hermite-Pade
-          ++ approximation with the  $q$-dilation operator
-
-        guessRec: Symbol -> GUESSER
-          ++ \spad{guessRec q} returns a guesser that finds an ordinary
-          ++ q-difference equation whose first values are given by l, using
-          ++ the given options.
-
-        guessPRec: Symbol -> GUESSER
-          ++ \spad{guessPRec q} returns a guesser that tries to find
-          ++ a linear q-recurrence with polynomial coefficients whose first
-          ++ values are given by l, using the given options. It is
-          ++ equivalent to \spadfun{guessRec}\spad{(q)} with 
-          ++ \spad{maxPower == 1}.
-
-        guessRat: Symbol -> GUESSER
-          ++ \spad{guessRat q} returns a guesser that tries to find a
-          ++ q-rational function whose first values are given by l, using
-          ++ the given options. It is equivalent to \spadfun{guessRec} with
-          ++ \spad{(l, maxShift == 0, maxPower == 1, allDegrees == true)}.
-
-        guessADE: Symbol -> GUESSER
-          ++ \spad{guessADE q} returns a guesser that tries to find an
-          ++ algebraic differential equation for a generating function whose
-          ++ first Taylor coefficients are given by l, using the given
-          ++ options.
-
--------------------------------------------------------------------------------
-
-    Implementation == Guess(Fraction UP, UP,
-                            MyExpression(q, Integer),
-                            Fraction UP,
-                            id$MappingPackage1(Fraction UP),
-                            coerce$MyExpression(q, Integer))
-@
-
-
-\section{License}
-<<license>>=
---Copyright (c) 2006-2007, Martin Rubey <Martin.Rubey@univie.ac.at>
---
---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.
---
---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.
-@
-
-<<*>>=
-<<license>>
-
-<<package UFPS1 UnivariateFormalPowerSeriesFunctions>>
-<<package GOPT0 GuessOptionFunctions0>>
-<<package GUESS Guess>>
-<<package GUESSINT GuessInteger>>
-<<package GUESSAN GuessAlgebraicNumber>>
-<<package GUESSF1 GuessFiniteFunctions>>
-<<package GUESSF GuessFinite>>
-<<package GUESSP GuessPolynomial>>
-<<package GUESSUP GuessUnivariatePolynomial>>
-@
-\end{document}
diff --git a/src/axiom-website/patches.html b/src/axiom-website/patches.html
index ca10868..0214d1b 100644
--- a/src/axiom-website/patches.html
+++ b/src/axiom-website/patches.html
@@ -921,5 +921,7 @@ help documentation fixes and packages<br/>
 help documentation fixes and packages<br/>
 <a href="patches/20090201.01.tpd.patch">20090201.01.tpd.patch</a>
 bookvol10.4 add packages<br/>
+<a href="patches/20090201.02.tpd.patch">20090201.02.tpd.patch</a>
+bookvol10.4 add packages<br/>
  </body>
 </html>
